code wiki / _hdl_build / nx_cbx_pages_gate.nx

nx_cbx_pages_gate.nx source

↩ module page · 336 lines · 17048 B

1import "nx_gate_base.nx" 2// nx_cbx_pages_gate.nx -- HANDOFF-CHAIN GATE for the CBX format-fix (natural sort + per-page magic gate 3// + rar4/rar5 STORE + container sniffing). NO-FAKE-GREEN: the gate CRAFTS byte-exact fixture archives 4// (zip with out-of-order page names + __MACOSX AppleDouble junk + a text file wearing .jpg; rar4 STORE; 5// rar5 STORE; a ZIP renamed .cbr), EXECS the real built extractor (/tmp/nx_cbx_pages.sov.elf), then 6// asserts page ORDER BY CONTENT (page000 bytes must be PAGEONE, ...) and honest skip behavior. 7// Stale outputs are UNLINKED before each exec so a leftover cbx.json can never fake a green. 8// license_tier: ORIGINAL 9import "nx_syscalls.nx" 10 11func grow(name: *u8, ok: i64) -> i64 { if ok==1 { gw(" PASS " as *u8) } else { gw(" FAIL " as *u8) } gw(name); gw(" 12" as *u8); return ok } 13func g_w(fd: i64, s: *u8) -> i64 { sys_write(fd, s, g_slen(s)); return 0 } 14func g_n(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(fd,"-" as *u8,1)}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 } 15func g_p(s: *u8) -> i64 { g_w(1, s); return 0 } 16func g_pn(v: i64) -> i64 { g_n(1, v); return 0 } 17func g_cat(dst: *u8, off: i64, s: *u8) -> i64 { var i: i64=0; while s[i]!=(0 as u8){dst[off+i]=s[i];i=i+1} return off+i } 18 19func find_sub(hay: *u8, hl: i64, needle: *u8) -> i64 { 20 let nl: i64 = g_slen(needle) 21 if nl == 0 { return 0-1 } 22 var i: i64 = 0 23 while i + nl <= hl { 24 var k: i64 = 0 25 var hit: i64 = 1 26 while k < nl { if hay[i+k] != needle[k] { hit = 0; k = nl } else { k = k + 1 } } 27 if hit == 1 { return i } 28 i = i + 1 29 } 30 return 0-1 31} 32 33func wle16(b: *u8, o: i64, v: i64) -> i64 { b[o] = (v & 255) as u8; b[o+1] = ((v >> 8) & 255) as u8; return o + 2 } 34func wle32(b: *u8, o: i64, v: i64) -> i64 { b[o] = (v & 255) as u8; b[o+1] = ((v >> 8) & 255) as u8; b[o+2] = ((v >> 16) & 255) as u8; b[o+3] = ((v >> 24) & 255) as u8; return o + 4 } 35func wraw(b: *u8, o: i64, s: *u8, n: i64) -> i64 { var i: i64=0; while i<n { b[o+i]=s[i]; i=i+1 } return o+n } 36 37// unlinkat(AT_FDCWD, p, 0) -- stale-output scrub (idempotent; ENOENT harmless) 38func rmf(p: *u8) -> i64 { __syscall(263, 0-100, p, 0, 0, 0, 0); return 0 } 39 40// ---- zip fixture emitters (stored, crc=0 -- the extractor never checks crc) ---- 41// local file header + data; returns new offset 42func zlfh(b: *u8, o: i64, nm: *u8, d: *u8, dn: i64) -> i64 { 43 let nl: i64 = g_slen(nm) 44 var p: i64 = o 45 b[p]=0x50 as u8; b[p+1]=0x4b as u8; b[p+2]=0x03 as u8; b[p+3]=0x04 as u8; p=p+4 46 p = wle16(b,p,20); p = wle16(b,p,0); p = wle16(b,p,0) // ver, flags, method=0 47 p = wle16(b,p,0); p = wle16(b,p,0); p = wle32(b,p,0) // time, date, crc 48 p = wle32(b,p,dn); p = wle32(b,p,dn) // csize, usize 49 p = wle16(b,p,nl); p = wle16(b,p,0) // fnlen, extralen 50 p = wraw(b,p,nm,nl) 51 p = wraw(b,p,d,dn) 52 return p 53} 54// central-dir entry; returns new offset 55func zcde(b: *u8, o: i64, nm: *u8, dn: i64, lho: i64) -> i64 { 56 let nl: i64 = g_slen(nm) 57 var p: i64 = o 58 b[p]=0x50 as u8; b[p+1]=0x4b as u8; b[p+2]=0x01 as u8; b[p+3]=0x02 as u8; p=p+4 59 p = wle16(b,p,20); p = wle16(b,p,20); p = wle16(b,p,0); p = wle16(b,p,0) // vermade, verneed, flags, method 60 p = wle16(b,p,0); p = wle16(b,p,0); p = wle32(b,p,0) // time, date, crc 61 p = wle32(b,p,dn); p = wle32(b,p,dn) // csize, usize 62 p = wle16(b,p,nl); p = wle16(b,p,0); p = wle16(b,p,0) // fnlen, extra, comment 63 p = wle16(b,p,0); p = wle16(b,p,0); p = wle32(b,p,0) // disk, iattr, eattr 64 p = wle32(b,p,lho) 65 p = wraw(b,p,nm,nl) 66 return p 67} 68func zeocd(b: *u8, o: i64, nent: i64, cdoff: i64, cdsize: i64) -> i64 { 69 var p: i64 = o 70 b[p]=0x50 as u8; b[p+1]=0x4b as u8; b[p+2]=0x05 as u8; b[p+3]=0x06 as u8; p=p+4 71 p = wle16(b,p,0); p = wle16(b,p,0); p = wle16(b,p,nent); p = wle16(b,p,nent) 72 p = wle32(b,p,cdsize); p = wle32(b,p,cdoff); p = wle16(b,p,0) 73 return p 74} 75 76// ---- rar4 STORE fixture: marker + per-file block (method 0x30) ---- 77func r4file(b: *u8, o: i64, nm: *u8, d: *u8, dn: i64) -> i64 { 78 let nl: i64 = g_slen(nm) 79 var p: i64 = o 80 p = wle16(b,p,0) // head_crc (unchecked) 81 b[p] = 0x74 as u8; p = p + 1 // type = file 82 p = wle16(b,p,0) // flags = 0 (not dir, not enc, not large) 83 p = wle16(b,p,32+nl) // hsize 84 p = wle32(b,p,dn); p = wle32(b,p,dn) // pack, unp 85 b[p] = 0 as u8; p = p + 1 // host_os 86 p = wle32(b,p,0); p = wle32(b,p,0) // file_crc, ftime 87 b[p] = 20 as u8; p = p + 1 // unp_ver 88 b[p] = 0x30 as u8; p = p + 1 // method = stored 89 p = wle16(b,p,nl) // namesize 90 p = wle32(b,p,0) // attr 91 p = wraw(b,p,nm,nl) 92 p = wraw(b,p,d,dn) 93 return p 94} 95 96// ---- rar5 STORE fixture: marker + per-file block (all vints single-byte: values < 128) ---- 97func r5file(b: *u8, o: i64, nm: *u8, d: *u8, dn: i64) -> i64 { 98 let nl: i64 = g_slen(nm) 99 var p: i64 = o 100 p = wle32(b,p,0) // header crc (unchecked) 101 b[p] = (9+nl) as u8; p = p + 1 // vint hsize = type..name inclusive 102 b[p] = 2 as u8; p = p + 1 // vint type = file 103 b[p] = 2 as u8; p = p + 1 // vint flags = data area present 104 b[p] = dn as u8; p = p + 1 // vint data_size (dn < 128) 105 b[p] = 0 as u8; p = p + 1 // vint file_flags 106 b[p] = dn as u8; p = p + 1 // vint unpacked 107 b[p] = 0 as u8; p = p + 1 // vint attr 108 b[p] = 0 as u8; p = p + 1 // vint cinfo (method bits 7..9 = 0 = store) 109 b[p] = 1 as u8; p = p + 1 // vint host_os 110 b[p] = nl as u8; p = p + 1 // vint name_len 111 p = wraw(b,p,nm,nl) 112 p = wraw(b,p,d,dn) 113 return p 114} 115 116func put_file(path: *u8, b: *u8, n: i64) -> i64 { 117 let fd: i64 = sys_openat_wr(path, 0x1a4) 118 if fd < 0 { return 0-1 } 119 sys_write(fd, b, n) 120 sys_close(fd) 121 return 0 122} 123 124// exec the real extractor on a fixture; returns wait4 status (0 = clean exit 0) 125func run_x(fixture: *u8, slug: *u8) -> i64 { 126 // stale-output scrub: a leftover cbx.json/page must never fake a green 127 let sp: *u8 = sys_mmap(512) 128 var so: i64 = g_cat(sp, 0, "knowledge/staging/media/reader/" as *u8) 129 so = g_cat(sp, so, slug) 130 let base: i64 = so 131 so = g_cat(sp, base, "/cbx.json" as *u8); sp[so] = 0 as u8; rmf(sp) 132 so = g_cat(sp, base, "/page000.jpg" as *u8); sp[so] = 0 as u8; rmf(sp) 133 so = g_cat(sp, base, "/page001.jpg" as *u8); sp[so] = 0 as u8; rmf(sp) 134 so = g_cat(sp, base, "/page002.jpg" as *u8); sp[so] = 0 as u8; rmf(sp) 135 so = g_cat(sp, base, "/page003.jpg" as *u8); sp[so] = 0 as u8; rmf(sp) 136 137 // ARTIFACT-TRUTH verdict: sys_wait4's status word proved UNRELIABLE on this lane (zero-filled st 138 // faked green once; poisoned st faked red next). The media server itself never trusts it -- it 139 // checks the produced file after waiting. Same here: the scrub above deleted cbx.json, so its 140 // EXISTENCE after the run is the truth. Retry x3: degraded WSL drops forks. 141 let jp: *u8 = sys_mmap(512) 142 var jo: i64 = g_cat(jp, 0, "knowledge/staging/media/reader/" as *u8) 143 jo = g_cat(jp, jo, slug) 144 jo = g_cat(jp, jo, "/cbx.json" as *u8); jp[jo] = 0 as u8 145 var rc: i64 = 0-1 146 var att: i64 = 0 147 while att < 3 { 148 if rc != 0 { 149 let pid: i64 = sys_fork() 150 if pid == 0 { 151 let av: *i64 = sys_mmap(64) as *i64 152 av[0] = "/tmp/nx_cbx_pages.sov.elf" as *u8 as i64 153 av[1] = fixture as i64 154 av[2] = slug as i64 155 av[3] = 0 156 sys_execve("/tmp/nx_cbx_pages.sov.elf" as *u8, av, 0 as *i64) 157 sys_exit(127) 158 } 159 if pid > 0 { 160 let st: *i64 = sys_mmap(8) as *i64 161 sys_wait4(pid, st, 0) 162 } 163 let tf: i64 = sys_openat_rd(jp) 164 if tf >= 0 { sys_close(tf); rc = 0 } 165 else { rc = 0-1; g_p(" [gate] no cbx.json att=" as *u8); g_pn(att); g_p("\n" as *u8); sys_sleep_ms(300) } 166 } 167 att = att + 1 168 } 169 return rc 170} 171 172// read a produced file and check it CONTAINS tag; 1/0 173func page_has(slug: *u8, fname: *u8, tag: *u8) -> i64 { 174 let sp: *u8 = sys_mmap(512) 175 var so: i64 = g_cat(sp, 0, "knowledge/staging/media/reader/" as *u8) 176 so = g_cat(sp, so, slug) 177 so = g_cat(sp, so, "/" as *u8) 178 so = g_cat(sp, so, fname); sp[so] = 0 as u8 179 let lb: *i64 = sys_mmap(16) as *i64 180 let d: *u8 = sys_read_file(sp, lb) 181 if (d as i64) == 0 { return 0 } 182 if find_sub(d, lb[0], tag) >= 0 { return 1 } 183 return 0 184} 185 186// cnt[0]=pass cnt[1]=fail (NishiLang: no top-level vars -- counters ride a pointer) 187func chk(cnt: *i64, ok: i64, label: *u8) -> i64 { 188 if ok == 1 { cnt[0] = cnt[0] + 1; g_p(" PASS " as *u8) } else { cnt[1] = cnt[1] + 1; g_p(" FAIL " as *u8) } 189 g_w(1, label); g_p("\n" as *u8) 190 return 0 191} 192 193func g_atoi(s: *u8) -> i64 { var v: i64=0; var i: i64=0; while s[i]!=(0 as u8){ let c: i64=s[i] as i64; if c>=48 { if c<=57 { v=v*10+(c-48) } } i=i+1 } return v } 194func g_itoa(v: i64, out: *u8) -> i64 { let t: *u8=sys_mmap(28); var m: i64=v; var k: i64=0; if m==0{t[0]=48 as u8;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{out[i]=t[k-1-i];i=i+1}; out[k]=0 as u8; return k } 195 196// SELF-EXEC CHAIN to the next stage: execve REPLACES the process, resetting the runtime's fork budget. 197// (Empirically this lane only completes ~2 fork+exec cycles per process -- the 3rd child dies silently 198// before its first write. One fixture per process stays inside that; counters ride argv.) 199func selfexec(self: *u8, stage: i64, cnt: *i64) -> i64 { 200 let s1: *u8 = sys_mmap(28); g_itoa(stage, s1) 201 let s2: *u8 = sys_mmap(28); g_itoa(cnt[0], s2) 202 let s3: *u8 = sys_mmap(28); g_itoa(cnt[1], s3) 203 let av: *i64 = sys_mmap(64) as *i64 204 av[0] = self as i64 205 av[1] = s1 as i64 206 av[2] = s2 as i64 207 av[3] = s3 as i64 208 av[4] = 0 209 sys_execve(self, av, 0 as *i64) 210 g_p("CBX-GATE-RED selfexec-failed\n" as *u8) 211 sys_exit(9) 212 return 9 213} 214 215func main(argc: i64, argv: *i64) -> i64 { 216 var stage: i64 = 1 217 let cnt: *i64 = sys_mmap(16) as *i64 218 cnt[0] = 0; cnt[1] = 0 219 if argc >= 4 { 220 stage = g_atoi(argv[1] as *u8) 221 cnt[0] = g_atoi(argv[2] as *u8) 222 cnt[1] = g_atoi(argv[3] as *u8) 223 } 224 let self: *u8 = argv[0] as *u8 225 226 // distinct real-magic page payloads (ff d8 = JPEG SOI) + a liar (text wearing .jpg) + apple junk 227 let j1: *u8 = sys_mmap(32); j1[0]=0xff as u8; j1[1]=0xd8 as u8; g_cat(j1, 2, "NXPAGEONE" as *u8) 228 let j2: *u8 = sys_mmap(32); j2[0]=0xff as u8; j2[1]=0xd8 as u8; g_cat(j2, 2, "NXPAGETWO" as *u8) 229 let j10: *u8 = sys_mmap(32); j10[0]=0xff as u8; j10[1]=0xd8 as u8; g_cat(j10, 2, "NXPAGETEN" as *u8) 230 let txt: *u8 = sys_mmap(32); g_cat(txt, 0, "notanimageatall" as *u8) 231 let jnk: *u8 = sys_mmap(32); g_cat(jnk, 0, "APPLJUNKBYTES" as *u8) 232 let n1: i64 = 11 233 let n2: i64 = 11 234 let n10: i64 = 11 235 let ntxt: i64 = 15 236 let njnk: i64 = 13 237 238 if stage == 1 { 239 g_p("CBX-GATE: fixture-crafted zip/rar4/rar5 vs the REAL built extractor (self-exec chain)\n" as *u8) 240 __syscall(258, 0-100, "/tmp/cbxgate" as *u8, 0x1ed, 0, 0, 0) 241 242 // ---------- write ALL fixtures once (later stages only read them) ---------- 243 // fixture 1: t1.cbz -- zip, archive order 10,1,junk,2,txt 244 let zb: *u8 = sys_mmap(65536) 245 var zo: i64 = 0 246 let l0: i64 = zo; zo = zlfh(zb, zo, "b/page10.jpg" as *u8, j10, n10) 247 let l1: i64 = zo; zo = zlfh(zb, zo, "b/page1.jpg" as *u8, j1, n1) 248 let l2: i64 = zo; zo = zlfh(zb, zo, "__MACOSX/._page1.jpg" as *u8, jnk, njnk) 249 let l3: i64 = zo; zo = zlfh(zb, zo, "b/page2.jpg" as *u8, j2, n2) 250 let l4: i64 = zo; zo = zlfh(zb, zo, "b/pagetxt.jpg" as *u8, txt, ntxt) 251 let cd: i64 = zo 252 zo = zcde(zb, zo, "b/page10.jpg" as *u8, n10, l0) 253 zo = zcde(zb, zo, "b/page1.jpg" as *u8, n1, l1) 254 zo = zcde(zb, zo, "__MACOSX/._page1.jpg" as *u8, njnk, l2) 255 zo = zcde(zb, zo, "b/page2.jpg" as *u8, n2, l3) 256 zo = zcde(zb, zo, "b/pagetxt.jpg" as *u8, ntxt, l4) 257 zo = zeocd(zb, zo, 5, cd, zo - cd) 258 put_file("/tmp/cbxgate/t1.cbz" as *u8, zb, zo) 259 260 // fixture 2: t2.cbr -- rar4 STORE, archive order 10,2 261 let rb: *u8 = sys_mmap(65536) 262 var ro: i64 = 0 263 rb[0]=0x52 as u8; rb[1]=0x61 as u8; rb[2]=0x72 as u8; rb[3]=0x21 as u8; rb[4]=0x1a as u8; rb[5]=0x07 as u8; rb[6]=0x00 as u8 264 ro = 7 265 ro = r4file(rb, ro, "p10.jpg" as *u8, j10, n10) 266 ro = r4file(rb, ro, "p2.jpg" as *u8, j2, n2) 267 put_file("/tmp/cbxgate/t2.cbr" as *u8, rb, ro) 268 269 // fixture 3: t3.cbr -- rar5 STORE, archive order 10,2 270 let qb: *u8 = sys_mmap(65536) 271 var qo: i64 = 0 272 qb[0]=0x52 as u8; qb[1]=0x61 as u8; qb[2]=0x72 as u8; qb[3]=0x21 as u8; qb[4]=0x1a as u8; qb[5]=0x07 as u8; qb[6]=0x01 as u8; qb[7]=0x00 as u8 273 qo = 8 274 qo = r5file(qb, qo, "x10.jpg" as *u8, j10, n10) 275 qo = r5file(qb, qo, "x2.jpg" as *u8, j2, n2) 276 put_file("/tmp/cbxgate/t3.cbr" as *u8, qb, qo) 277 278 // fixture 4: t4.cbr -- a ZIP wearing .cbr (magic sniff must route it) 279 let vb: *u8 = sys_mmap(65536) 280 var vo: i64 = 0 281 let v0: i64 = vo; vo = zlfh(vb, vo, "z1.jpg" as *u8, j1, n1) 282 let vcd: i64 = vo 283 vo = zcde(vb, vo, "z1.jpg" as *u8, n1, v0) 284 vo = zeocd(vb, vo, 1, vcd, vo - vcd) 285 put_file("/tmp/cbxgate/t4.cbr" as *u8, vb, vo) 286 287 // ---------- stage 1 checks: zip ---------- 288 let st1: i64 = run_x("/tmp/cbxgate/t1.cbz" as *u8, "cbxgate_zip" as *u8) 289 var ok1: i64 = 0; if st1 == 0 { ok1 = 1 } 290 chk(cnt, ok1, "zip: extractor produced cbx.json" as *u8) 291 let jz: *u8 = sys_mmap(512) 292 var jzo: i64 = g_cat(jz, 0, "knowledge/staging/media/reader/cbxgate_zip/cbx.json" as *u8); jz[jzo] = 0 as u8 293 let lbz: *i64 = sys_mmap(16) as *i64 294 let dz: *u8 = sys_read_file(jz, lbz) 295 var okn: i64 = 0 296 var okc: i64 = 0 297 if (dz as i64) != 0 { 298 if find_sub(dz, lbz[0], "\"npages\":3" as *u8) >= 0 { okn = 1 } 299 if find_sub(dz, lbz[0], "\"cfix\":2" as *u8) >= 0 { okc = 1 } 300 } 301 chk(cnt, okn, "zip: npages==3 (junk name + nonimage bytes both skipped)" as *u8) 302 chk(cnt, okc, "zip: cbx.json carries cfix:2 cache-heal tag" as *u8) 303 chk(cnt, page_has("cbxgate_zip" as *u8, "page000.jpg" as *u8, "NXPAGEONE" as *u8), "zip: page000 == page1 (natural order)" as *u8) 304 chk(cnt, page_has("cbxgate_zip" as *u8, "page001.jpg" as *u8, "NXPAGETWO" as *u8), "zip: page001 == page2 (natural order)" as *u8) 305 chk(cnt, page_has("cbxgate_zip" as *u8, "page002.jpg" as *u8, "NXPAGETEN" as *u8), "zip: page002 == page10 (10 AFTER 2 -- ascii bug dead)" as *u8) 306 selfexec(self, 2, cnt) 307 } 308 309 if stage == 2 { 310 let st2: i64 = run_x("/tmp/cbxgate/t2.cbr" as *u8, "cbxgate_rar4" as *u8) 311 var ok2: i64 = 0; if st2 == 0 { ok2 = 1 } 312 chk(cnt, ok2, "rar4: produced cbx.json (STORE walker)" as *u8) 313 chk(cnt, page_has("cbxgate_rar4" as *u8, "page000.jpg" as *u8, "NXPAGETWO" as *u8), "rar4: page000 == p2 (natural order)" as *u8) 314 chk(cnt, page_has("cbxgate_rar4" as *u8, "page001.jpg" as *u8, "NXPAGETEN" as *u8), "rar4: page001 == p10" as *u8) 315 selfexec(self, 3, cnt) 316 } 317 318 if stage == 3 { 319 let st3: i64 = run_x("/tmp/cbxgate/t3.cbr" as *u8, "cbxgate_rar5" as *u8) 320 var ok3: i64 = 0; if st3 == 0 { ok3 = 1 } 321 chk(cnt, ok3, "rar5: produced cbx.json (vint STORE walker)" as *u8) 322 chk(cnt, page_has("cbxgate_rar5" as *u8, "page000.jpg" as *u8, "NXPAGETWO" as *u8), "rar5: page000 == x2 (natural order)" as *u8) 323 chk(cnt, page_has("cbxgate_rar5" as *u8, "page001.jpg" as *u8, "NXPAGETEN" as *u8), "rar5: page001 == x10" as *u8) 324 selfexec(self, 4, cnt) 325 } 326 327 // stage 4: renamed-container sniff + verdict 328 let st4: i64 = run_x("/tmp/cbxgate/t4.cbr" as *u8, "cbxgate_ziplie" as *u8) 329 var ok4: i64 = 0; if st4 == 0 { ok4 = 1 } 330 chk(cnt, ok4, "renamed: .cbr that is really zip produced cbx.json (sniff)" as *u8) 331 chk(cnt, page_has("cbxgate_ziplie" as *u8, "page000.jpg" as *u8, "NXPAGEONE" as *u8), "renamed: page000 == z1" as *u8) 332 333 g_p("CBX-GATE: pass=" as *u8); g_pn(cnt[0]); g_p(" fail=" as *u8); g_pn(cnt[1]); g_p("\n" as *u8) 334 if cnt[1] == 0 { g_p("CBX-GATE-GREEN\n" as *u8); sys_exit(0); return 0 } 335 g_p("CBX-GATE-RED\n" as *u8); sys_exit(1); return 1 336}