code wiki / (root) / nx_uxf_decode.nx

nx_uxf_decode.nx source

↩ module page · 61 lines · 2739 B

1// nx_uxf_decode.nx -- UXF arc R1c-2: the TOLERANT-READER decoder for canon_cid's NXR1 2// canonical form (ADDITIVE; canon_cid stays encode-only and untouched -- Rule 19/3). 3// 4// Canonical layout (from nx_canon_cid): magic "NXR1" | u32be nfields | 5// per field: u32be klen | key | u32be vlen | value. 6// The decoder parses EVERY field back into (key,value) pointer arrays -- it does NOT filter 7// by a "known-key" set, so fields a consumer doesn't understand are PRESERVED, not dropped. 8// Re-encoding the decoded fields reproduces identical canonical bytes => identical CID. 9// That is the house-of-cards fix (Law-4): new data never breaks an old reader, because the 10// reader round-trips unknown fields intact. Defensive at the boundary (Rule 12): malformed 11// framing -> negative verdict, never OOB. No hardware writes (Rule 26). license_tier: ORIGINAL 12import "nx_syscalls.nx" 13import "nx_canon_cid.nx" 14const K_MAGIC_16777216: i64 = 16777216 15const K_MAGIC_65536: i64 = 65536 16 17// read a big-endian u32 at off (multiplication form -- no reliance on '<<'). 18func ud_r32(p: *u8, off: i64) -> i64 { 19 return ((p[off] as i64) * K_MAGIC_16777216) + ((p[off + 1] as i64) * K_MAGIC_65536) + ((p[off + 2] as i64) * 256) + (p[off + 3] as i64) 20} 21 22// decode NXR1 bytes -> out_keys[]/out_vals[] (null-terminated copies, i64 ptrs as canon_encode wants). 23// returns nfields (>=0), or negative on malformed: (0-1) short, (0-2) bad magic, (0-3) bad count, (0-4) truncated. 24func canon_decode(bytes: *u8, n: i64, out_keys: *i64, out_vals: *i64, maxf: i64) -> i64 { 25 if n < 8 { return 0 - 1 } 26 if bytes[0] != (78 as u8) { return 0 - 2 } // N 27 if bytes[1] != (88 as u8) { return 0 - 2 } // X 28 if bytes[2] != (82 as u8) { return 0 - 2 } // R 29 if bytes[3] != (49 as u8) { return 0 - 2 } // 1 30 let nf: i64 = ud_r32(bytes, 4) 31 if nf < 0 { return 0 - 3 } 32 if nf > maxf { return 0 - 3 } 33 var o: i64 = 8 34 var i: i64 = 0 35 while i < nf { 36 if (o + 4) > n { return 0 - 4 } 37 let kl: i64 = ud_r32(bytes, o) 38 o = o + 4 39 if kl < 0 { return 0 - 4 } 40 if (o + kl) > n { return 0 - 4 } 41 let kbuf: *u8 = sys_mmap(kl + 1) 42 var t: i64 = 0 43 while t < kl { kbuf[t] = bytes[o + t]; t = t + 1 } 44 kbuf[kl] = 0 as u8 45 o = o + kl 46 if (o + 4) > n { return 0 - 4 } 47 let vl: i64 = ud_r32(bytes, o) 48 o = o + 4 49 if vl < 0 { return 0 - 4 } 50 if (o + vl) > n { return 0 - 4 } 51 let vbuf: *u8 = sys_mmap(vl + 1) 52 t = 0 53 while t < vl { vbuf[t] = bytes[o + t]; t = t + 1 } 54 vbuf[vl] = 0 as u8 55 o = o + vl 56 out_keys[i] = kbuf as i64 57 out_vals[i] = vbuf as i64 58 i = i + 1 59 } 60 return nf 61}