code wiki / (root) / nx_wpt_ingest_gate.nx

nx_wpt_ingest_gate.nx source

↩ module page · 489 lines · 24343 B

1// nx_wpt_ingest_gate.nx -- IN-PROCESS gate for BR21 (nx_wpt_acquire_lib, carried by nx_wpt_ingest). 2// 3// THE ANTI-VACUITY TOOTH IS THE WHOLE POINT AND IT IS NAMED. The defect BR21 closes is that the hand 4// acquisition path re-emitted every body through a TEXT TOOL ARGUMENT -- a NUL-terminated C string -- 5// and html/syntax/parsing-html-fragments is the ENCODING-DETECTION suite, whose fixtures are UTF-16LE 6// with a BOM and therefore carry a NUL as their FOURTH BYTE. An ASCII fixture round-trips perfectly 7// through the broken path, so an ASCII fixture is a test the defect cannot fail. Every byte-exactness 8// tooth below runs on a UTF-16LE-with-BOM body built at RUNTIME, and the fixture is first asserted to 9// actually contain the NUL before any outcome is read: assert the fixture reached the condition 10// BEFORE asserting the outcome. 11// 12// THE HASH ANCHOR COMES FROM OUTSIDE THE ESTATE. wa_verify_blob compares against the git blob object 13// name GitHub declares. One tooth pins that arithmetic to f2ba8f84ab5c1bce84a7b441cb1959cfc7093b7f, 14// which is git hash-object of the three bytes abc under git 2.49.0 -- a value this estate did not 15// choose and cannot influence. Without it, computing a digest with swhid and then checking it with 16// swhid would prove plumbing and call it correctness. 17// 18// SCOPE, STATED: this gate is OFFLINE by construction. It proves the manifest parser, the dual 19// verification, the raw write, the read-back compare, the pin rule, the name allowlist, the 20// completeness conjunction and the manifest/marker emit. It does NOT prove the transport -- that is 21// nx_https_fetch_follow's subject, and the end-to-end proof is the live re-ingest reproducing 22// corpus_sha16 54e90b086e0c6530 and 1819a1dcd3030f03, recorded on browser.plan, not here. 23// 24// license_tier: ORIGINAL 25 26import "nx_syscalls.nx" 27import "nx_gate_verdict.nx" 28import "nx_wpt_acquire_lib.nx" 29 30const GT_DIR: *u8 = "/tmp/wsp_gate" 31const GT_FIX_CAP: i64 = 65536 32const GT_JSON_CAP: i64 = 65536 33const GT_BOM0: i64 = 255 34const GT_BOM1: i64 = 254 35const GT_FIX_LEN: i64 = 72 // DERIVED: 2 BOM bytes + 2 bytes per char of a 35-char title 36const GT_FIX_CSTR: i64 = 3 // DERIVED: BOM, BOM, first char -- then the NUL a C string stops at 37const GT_NUMBUF: i64 = 64 // DERIVED: a 64-bit decimal is at most 20 digits, plus a sign and a NUL 38const GT_SIZE_A: i64 = 1204 // the size GitHub declares for DOMTokenList-Iterable.html at the pin 39const GT_SIZE_B: i64 = 1205 // GT_SIZE_A + 1: the nearest neighbour, so the renderer cannot be a constant 40const GT_DIGITS_A: i64 = 5 // DERIVED: one char for the zero, plus the four digits of GT_SIZE_A 41const GT_DIGITS_B: i64 = 4 // DERIVED: the digit count of GT_SIZE_B 42 43// ---- RUNTIME FIXTURE BUILDERS (a detector that scans source finds its own fixtures) ------------- 44 45func gt_utf16le(d: *u8) -> i64 { 46 d[0] = GT_BOM0 as u8 47 d[1] = GT_BOM1 as u8 48 let s: *u8 = "<title>WPT encoding fixture</title>" as *u8 49 var i: i64 = 0 50 var o: i64 = 2 51 while s[i] != (0 as u8) { 52 d[o] = s[i] 53 o = o + 1 54 d[o] = 0 as u8 55 o = o + 1 56 i = i + 1 57 } 58 return o 59} 60 61func gt_q(d: *u8, o: i64) -> i64 { d[o] = 34 as u8; return o + 1 } 62func gt_ch(d: *u8, o: i64, c: i64) -> i64 { d[o] = c as u8; return o + 1 } 63func gt_kv(d: *u8, o: i64, k: *u8, v: *u8) -> i64 { 64 var p: i64 = gt_q(d, o) 65 p = wsp_scat(d, p, k) 66 p = gt_q(d, p) 67 p = gt_ch(d, p, 58) 68 p = gt_ch(d, p, 32) 69 p = gt_q(d, p) 70 p = wsp_scat(d, p, v) 71 p = gt_q(d, p) 72 p = gt_ch(d, p, 44) 73 p = gt_ch(d, p, 10) 74 return p 75} 76func gt_kn(d: *u8, o: i64, k: *u8, v: i64) -> i64 { 77 var p: i64 = gt_q(d, o) 78 p = wsp_scat(d, p, k) 79 p = gt_q(d, p) 80 p = gt_ch(d, p, 58) 81 p = gt_ch(d, p, 32) 82 p = wa_mf_num(d, p, v) 83 p = gt_ch(d, p, 44) 84 p = gt_ch(d, p, 10) 85 return p 86} 87// one contents-API record in GitHub's real field order, including the path and download_url values 88// that carry the file name -- so a parser matching a key without its quotes would be caught here. 89func gt_rec(d: *u8, o: i64, name: *u8, sha: *u8, size: i64, typ: *u8, with_sha: i64) -> i64 { 90 var p: i64 = gt_ch(d, o, 123) 91 p = gt_ch(d, p, 10) 92 p = gt_kv(d, p, "name" as *u8, name) 93 let pathbuf: *u8 = sys_mmap(1024) 94 var q: i64 = wsp_scat(pathbuf, 0, "dom/lists/" as *u8) 95 q = wsp_scat(pathbuf, q, name) 96 pathbuf[q] = 0 as u8 97 p = gt_kv(d, p, "path" as *u8, pathbuf) 98 if with_sha == 1 { p = gt_kv(d, p, "sha" as *u8, sha) } 99 p = gt_kn(d, p, "size" as *u8, size) 100 let dl: *u8 = sys_mmap(1024) 101 var r: i64 = wsp_scat(dl, 0, "https://raw.githubusercontent.com/web-platform-tests/wpt/dead/dom/lists/" as *u8) 102 r = wsp_scat(dl, r, name) 103 dl[r] = 0 as u8 104 p = gt_kv(d, p, "download_url" as *u8, dl) 105 p = gt_kv(d, p, "type" as *u8, typ) 106 p = gt_ch(d, p, 125) 107 p = gt_ch(d, p, 44) 108 p = gt_ch(d, p, 10) 109 return p 110} 111 112func gt_path(out: *u8, leaf: *u8) -> i64 { 113 var p: i64 = wsp_scat(out, 0, GT_DIR) 114 p = wsp_scat(out, p, "/" as *u8) 115 p = wsp_scat(out, p, leaf) 116 out[p] = 0 as u8 117 return p 118} 119func gt_exists(path: *u8) -> i64 { 120 let fd: i64 = sys_openat_rd(path) 121 if fd < 0 { return 0 } 122 sys_close(fd) 123 return 1 124} 125func gt_zero(rep: *i64) -> i64 { var i: i64 = 0; while i < WA_R_SLOTS { rep[i] = 0; i = i + 1 } return 0 } 126 127func gt_blobsha(data: *u8, n: i64, out: *u8) -> i64 { 128 let id: *u8 = sys_mmap(WA_ID_CAP) 129 let r: i64 = swhid_cnt(data, n, id) 130 if r < 0 { return 0 } 131 var i: i64 = 0 132 while i < WA_SHA_HEX { out[i] = id[WA_SWHID_PREFIX + i]; i = i + 1 } 133 out[WA_SHA_HEX] = 0 as u8 134 return 1 135} 136func gt_hexeq(a: *u8, b: *u8) -> i64 { 137 var i: i64 = 0 138 while i < WA_SHA_HEX { if a[i] != b[i] { return 0 } i = i + 1 } 139 return 1 140} 141 142func main() -> i64 { 143 gv_head("nx_wpt_ingest_gate -- BR21 byte-preserving WPT corpus ingest" as *u8) 144 let ctr: *i64 = gv_ctr() 145 146 // ---- SETUP. Idempotent by construction: every fixture is unlinked first, so a run reports on 147 // itself and never on the leavings of the previous one. Gate scratch lives under /tmp, never 148 // beside a production tree. 149 sys_mkdir(GT_DIR, MODE_0755) 150 let p_ok: *u8 = sys_mmap(WA_PATH_CAP) 151 let p_tr: *u8 = sys_mmap(WA_PATH_CAP) 152 let p_bad: *u8 = sys_mmap(WA_PATH_CAP) 153 let p_mf: *u8 = sys_mmap(WA_PATH_CAP) 154 let p_mk: *u8 = sys_mmap(WA_PATH_CAP) 155 gt_path(p_ok, "utf16le-bom.html" as *u8) 156 gt_path(p_tr, "nul-truncated.html" as *u8) 157 gt_path(p_bad, "never-written.html" as *u8) 158 gt_path(p_mf, "MANIFEST.tsv" as *u8) 159 wa_marker_path(GT_DIR, p_mk) 160 sys_unlinkat(p_ok) 161 sys_unlinkat(p_tr) 162 sys_unlinkat(p_bad) 163 sys_unlinkat(p_mf) 164 sys_unlinkat(p_mk) 165 gv_need("setup-scratch-dir-is-writable" as *u8, gt_exists(GT_DIR), ctr) 166 var clean: i64 = 0 167 if gt_exists(p_ok) == 0 { clean = 1 } 168 gv_need("setup-left-no-fixture-behind" as *u8, clean, ctr) 169 170 // ---- THE FIXTURE, AND THE PROOF IT CAN FAIL ------------------------------------------------ 171 let f: *u8 = sys_mmap(GT_FIX_CAP) 172 let n: i64 = gt_utf16le(f) 173 let cstr: i64 = wa_strlen(f) 174 gv_puts(" fixture: bytes=" as *u8); gv_num(n) 175 gv_puts(" b0=" as *u8); gv_num(f[0] as i64) 176 gv_puts(" b1=" as *u8); gv_num(f[1] as i64) 177 gv_puts(" b3=" as *u8); gv_num(f[3] as i64) 178 gv_puts(" c_string_length=" as *u8); gv_num(cstr); gv_puts("\n" as *u8) 179 var t_bom: i64 = 0 180 if (f[0] as i64) == GT_BOM0 { if (f[1] as i64) == GT_BOM1 { t_bom = 1 } } 181 gv_check("fixture-is-utf16le-with-a-bom" as *u8, t_bom, ctr) 182 var t_nul: i64 = 0 183 if n > GT_FIX_CSTR { if (f[3] as i64) == 0 { t_nul = 1 } } 184 gv_check("fixture-carries-an-embedded-nul-at-byte-3-so-the-defect-can-fire" as *u8, t_nul, ctr) 185 var t_arith: i64 = 0 186 if cstr == GT_FIX_CSTR { if n == GT_FIX_LEN { t_arith = 1 } } 187 gv_check("fixture-a-c-string-carrier-sees-3-bytes-where-the-file-has-72" as *u8, t_arith, ctr) 188 189 // ---- THE EXTERNAL HASH ANCHOR --------------------------------------------------------------- 190 let kat: *u8 = sys_mmap(64) 191 gt_blobsha("abc" as *u8, 3, kat) 192 gv_puts(" blob sha of abc = " as *u8); gv_puts(kat); gv_puts("\n" as *u8) 193 let kat_hit: i64 = gt_hexeq(kat, "f2ba8f84ab5c1bce84a7b441cb1959cfc7093b7f" as *u8) 194 let kat_miss: i64 = gt_hexeq(kat, "f2ba8f84ab5c1bce84a7b441cb1959cfc7093b7e" as *u8) 195 gv_bite("blob-sha-hits-the-git-2-49-0-vector-for-abc-and-misses-a-one-nibble-neighbour" as *u8, kat_hit, kat_miss, ctr) 196 197 // ---- VERIFICATION --------------------------------------------------------------------------- 198 let sha: *u8 = sys_mmap(64) 199 gt_blobsha(f, n, sha) 200 var t_v0: i64 = 0 201 if wa_verify_blob(f, n, n, sha) == 0 { t_v0 = 1 } 202 gv_check("verify-accepts-a-body-matching-both-declared-numbers" as *u8, t_v0, ctr) 203 var t_v1: i64 = 0 204 if wa_verify_blob(f, n, n + 1, sha) == 1 { t_v1 = 1 } 205 gv_check("neg-control-verify-refuses-a-declared-size-one-too-large" as *u8, t_v1, ctr) 206 var t_v2: i64 = 0 207 if wa_verify_blob(f, GT_FIX_CSTR, n, sha) == 1 { t_v2 = 1 } 208 gv_check("neg-control-verify-refuses-a-nul-truncated-body" as *u8, t_v2, ctr) 209 210 // A BYTE SWAP PRESERVES LENGTH, so this is the tooth proving the sha leg is load-bearing rather 211 // than decoration beside the size check. 212 let g: *u8 = sys_mmap(GT_FIX_CAP) 213 var c: i64 = 0 214 while c < n { g[c] = f[c]; c = c + 1 } 215 let swap: i64 = g[4] as i64 216 g[4] = g[6] 217 g[6] = swap as u8 218 let vg: i64 = wa_verify_blob(g, n, n, sha) 219 gv_puts(" byte-swapped copy: same length=" as *u8); gv_num(n) 220 gv_puts(" verify_code=" as *u8); gv_num(vg); gv_puts(" (1 size, 2 sha)\n" as *u8) 221 var t_swapfix: i64 = 0 222 if (g[4] as i64) != (f[4] as i64) { t_swapfix = 1 } 223 gv_check("fixture-the-swap-really-changed-a-byte" as *u8, t_swapfix, ctr) 224 var t_v3: i64 = 0 225 if vg == 2 { t_v3 = 1 } 226 gv_check("neg-control-verify-catches-a-byte-swap-on-the-sha-which-the-size-check-cannot-see" as *u8, t_v3, ctr) 227 228 // ---- RAW WRITE AND READ-BACK ---------------------------------------------------------------- 229 var t_w: i64 = 0 230 if wa_write_raw(p_ok, f, n) == 0 { t_w = 1 } 231 gv_check("write-raw-reports-success-on-the-utf16le-body" as *u8, t_w, ctr) 232 var t_rb: i64 = 0 233 if wa_readback_eq(p_ok, f, n) == 1 { t_rb = 1 } 234 gv_check("readback-is-byte-identical-to-the-utf16le-body" as *u8, t_rb, ctr) 235 236 let lp: *i64 = sys_mmap(16) as *i64 237 lp[0] = 0 238 let back: *u8 = sys_read_file(p_ok, lp) 239 var len_ok: i64 = 0 240 var bom_ok: i64 = 0 241 if (back as i64) != 0 { 242 if lp[0] == n { if n == GT_FIX_LEN { len_ok = 1 } } 243 if (back[0] as i64) == GT_BOM0 { if (back[1] as i64) == GT_BOM1 { bom_ok = 1 } } 244 } 245 gv_puts(" read back: bytes=" as *u8); gv_num(lp[0]); gv_puts("\n" as *u8) 246 gv_check("readback-length-on-disk-is-72-not-3" as *u8, len_ok, ctr) 247 gv_check("readback-preserves-both-bom-bytes" as *u8, bom_ok, ctr) 248 249 // THE DEFECT ITSELF, PLANTED: write only up to the first NUL, which is exactly what a text 250 // argument carrier does, and prove the read-back compare refuses it. 251 var t_plant: i64 = 0 252 if wa_write_raw(p_tr, f, cstr) == 0 { if wa_readback_eq(p_tr, f, n) == 0 { t_plant = 1 } } 253 gv_check("neg-control-a-nul-truncated-write-is-caught-by-the-readback-compare" as *u8, t_plant, ctr) 254 255 // ---- LAND ONE ------------------------------------------------------------------------------- 256 let rep: *i64 = sys_mmap(WA_R_SLOTS * 8) as *i64 257 gt_zero(rep) 258 sys_unlinkat(p_ok) 259 let nm_ok: *u8 = "utf16le-bom.html" as *u8 260 let rc1: i64 = wa_land_one(GT_DIR, nm_ok, wa_strlen(nm_ok), f, n, n, sha, rep) 261 var t_l1: i64 = 0 262 if rc1 == 0 { if rep[WA_R_LANDED] == 1 { t_l1 = 1 } } 263 gv_check("land-one-lands-a-verified-body-and-counts-it" as *u8, t_l1, ctr) 264 let rc2: i64 = wa_land_one(GT_DIR, nm_ok, wa_strlen(nm_ok), f, n, n, sha, rep) 265 var t_l2: i64 = 0 266 if rc2 == 0 { if rep[WA_R_LANDED] == 2 { if wa_readback_eq(p_ok, f, n) == 1 { t_l2 = 1 } } } 267 gv_check("land-one-is-idempotent-and-the-second-landing-is-byte-identical" as *u8, t_l2, ctr) 268 var t_ag: i64 = 0 269 if wa_already_good(GT_DIR, nm_ok, wa_strlen(nm_ok), n, sha) == 1 { t_ag = 1 } 270 gv_check("already-good-sees-a-file-satisfying-both-declared-numbers" as *u8, t_ag, ctr) 271 var t_ag2: i64 = 0 272 if wa_already_good(GT_DIR, nm_ok, wa_strlen(nm_ok), n + 1, sha) == 0 { t_ag2 = 1 } 273 gv_check("neg-control-already-good-refuses-when-the-declared-size-differs" as *u8, t_ag2, ctr) 274 275 // A BODY THAT FAILS VERIFICATION MUST NEVER REACH THE DISK: a corrupt file is indistinguishable 276 // from a good one to every later reader, and the runner would fold it into a corpus_sha. 277 gt_zero(rep) 278 let nm_bad: *u8 = "never-written.html" as *u8 279 let rc3: i64 = wa_land_one(GT_DIR, nm_bad, wa_strlen(nm_bad), f, n, n, kat, rep) 280 var t_l3: i64 = 0 281 if rc3 == 2 { if rep[WA_R_FAIL_SHA] == 1 { t_l3 = 1 } } 282 gv_check("neg-control-land-one-refuses-a-body-whose-blob-sha-differs" as *u8, t_l3, ctr) 283 var t_l4: i64 = 0 284 if gt_exists(p_bad) == 0 { t_l4 = 1 } 285 gv_check("neg-control-a-refused-body-left-no-file-on-disk" as *u8, t_l4, ctr) 286 287 gt_zero(rep) 288 let nm_esc: *u8 = "../escaped.html" as *u8 289 let rc4: i64 = wa_land_one(GT_DIR, nm_esc, wa_strlen(nm_esc), f, n, n, sha, rep) 290 var t_l5: i64 = 0 291 if rc4 == 5 { if rep[WA_R_REFUSED_NAME] == 1 { t_l5 = 1 } } 292 gv_check("neg-control-land-one-refuses-a-parent-traversal-name" as *u8, t_l5, ctr) 293 294 // ---- THE SHARED DECIMAL RENDERER ------------------------------------------------------------ 295 // wa_mf_num is the ONE decimal renderer in the lib -- wa_putn composes it rather than carrying a 296 // second copy, and every size written into MANIFEST.tsv goes through it. Zero is the case a 297 // hand-rolled renderer gets wrong, so it is the case tested first. 298 let nb: *u8 = sys_mmap(GT_NUMBUF) 299 var no: i64 = wa_mf_num(nb, 0, 0) 300 no = wa_mf_num(nb, no, GT_SIZE_A) 301 nb[no] = 0 as u8 302 gv_puts(" wa_mf_num zero then GT_SIZE_A = " as *u8); gv_puts(nb) 303 gv_puts(" offset=" as *u8); gv_num(no); gv_puts("\n" as *u8) 304 var t_d0: i64 = 0 305 if no == GT_DIGITS_A { if wa_find(nb, GT_DIGITS_A, 0, "01204" as *u8) == 0 { t_d0 = 1 } } 306 gv_check("decimal-renderer-writes-zero-then-1204-and-returns-the-right-offset" as *u8, t_d0, ctr) 307 let nb2: *u8 = sys_mmap(GT_NUMBUF) 308 let no2: i64 = wa_mf_num(nb2, 0, GT_SIZE_B) 309 var t_d1: i64 = 0 310 if no2 == GT_DIGITS_B { if wa_find(nb2, GT_DIGITS_B, 0, "1205" as *u8) == 0 { t_d1 = 1 } } 311 gv_check("neg-control-decimal-renderer-renders-1205-differently-from-1204" as *u8, t_d1, ctr) 312 313 // ---- THE PIN -------------------------------------------------------------------------------- 314 let pin_good: i64 = wa_is_pin("a7b5671e50ee3610ec3ad2e1278a33b2cb11339c" as *u8) 315 let pin_branch: i64 = wa_is_pin("main" as *u8) 316 gv_bite("pin-accepts-a-40-hex-commit-and-refuses-a-branch-name" as *u8, pin_good, pin_branch, ctr) 317 var t_p2: i64 = 0 318 if wa_is_pin("A7B5671E50EE3610EC3AD2E1278A33B2CB11339C" as *u8) == 0 { t_p2 = 1 } 319 gv_check("neg-control-pin-refuses-uppercase-hex" as *u8, t_p2, ctr) 320 var t_p3: i64 = 0 321 if wa_is_pin("a7b5671e50ee3610ec3ad2e1278a33b2cb11339" as *u8) == 0 { t_p3 = 1 } 322 gv_check("neg-control-pin-refuses-39-hex" as *u8, t_p3, ctr) 323 324 // ---- THE NAME ALLOWLIST --------------------------------------------------------------------- 325 let nm_real: *u8 = "namednodemap-supported-property-names.html" as *u8 326 var t_n0: i64 = 0 327 if wa_is_safe_name(nm_real, wa_strlen(nm_real)) == 1 { t_n0 = 1 } 328 gv_check("safe-name-accepts-a-real-wpt-filename" as *u8, t_n0, ctr) 329 var t_n1: i64 = 0 330 if wa_is_safe_name(nm_esc, wa_strlen(nm_esc)) == 0 { t_n1 = 1 } 331 gv_check("neg-control-safe-name-refuses-parent-traversal" as *u8, t_n1, ctr) 332 let nm_sl: *u8 = "a/b.html" as *u8 333 var t_n2: i64 = 0 334 if wa_is_safe_name(nm_sl, wa_strlen(nm_sl)) == 0 { t_n2 = 1 } 335 gv_check("neg-control-safe-name-refuses-a-slash" as *u8, t_n2, ctr) 336 let nm_dot: *u8 = ".hidden.html" as *u8 337 var t_n3: i64 = 0 338 if wa_is_safe_name(nm_dot, wa_strlen(nm_dot)) == 0 { t_n3 = 1 } 339 gv_check("neg-control-safe-name-refuses-a-leading-dot" as *u8, t_n3, ctr) 340 341 // ---- THE MANIFEST PARSER -------------------------------------------------------------------- 342 // Four records in GitHub's real field order: two .html files, one .md file, one directory whose 343 // name ends .html. The declared population is 2 -- the other two are skipped for two DIFFERENT 344 // reasons and each reason has its own counter. 345 let js: *u8 = sys_mmap(GT_JSON_CAP) 346 var jo: i64 = gt_ch(js, 0, 91) 347 jo = gt_ch(js, jo, 10) 348 jo = gt_rec(js, jo, "DOMTokenList-Iterable.html" as *u8, "4cf84b12a22d15cbc8fb76d174ee0cbb7693b63b" as *u8, 1204, "file" as *u8, 1) 349 jo = gt_rec(js, jo, nm_real, "0000000000000000000000000000000000000000" as *u8, 1114, "file" as *u8, 1) 350 jo = gt_rec(js, jo, "README.md" as *u8, "59c821a7daa465a852a1e9cba209af40de132d12" as *u8, 67, "file" as *u8, 1) 351 jo = gt_rec(js, jo, "subdir.html" as *u8, "1111111111111111111111111111111111111111" as *u8, 0, "dir" as *u8, 1) 352 jo = gt_ch(js, jo, 93) 353 354 let namebuf: *u8 = sys_mmap(65536) 355 let offs: *i64 = sys_mmap(1024) as *i64 356 let sizes: *i64 = sys_mmap(1024) as *i64 357 let shas: *u8 = sys_mmap(4096) 358 gt_zero(rep) 359 let cnt: i64 = wa_parse_manifest(js, jo, namebuf, 65536, offs, sizes, shas, 64, rep) 360 gv_puts(" parse: entries=" as *u8); gv_num(rep[WA_R_ENTRIES]) 361 gv_puts(" declared=" as *u8); gv_num(cnt) 362 gv_puts(" skipped_nothtml=" as *u8); gv_num(rep[WA_R_SKIPPED_NOTHTML]) 363 gv_puts(" skipped_notfile=" as *u8); gv_num(rep[WA_R_SKIPPED_NOTFILE]); gv_puts("\n" as *u8) 364 var t_m0: i64 = 0 365 if rep[WA_R_ENTRIES] == 4 { t_m0 = 1 } 366 gv_check("manifest-parse-saw-all-four-entries" as *u8, t_m0, ctr) 367 var t_m1: i64 = 0 368 if cnt == 2 { if rep[WA_R_DECLARED] == 2 { t_m1 = 1 } } 369 gv_check("manifest-parse-declares-2-html-files-of-4-entries" as *u8, t_m1, ctr) 370 var t_m2: i64 = 0 371 if rep[WA_R_SKIPPED_NOTHTML] == 1 { if rep[WA_R_SKIPPED_NOTFILE] == 1 { t_m2 = 1 } } 372 gv_check("manifest-parse-counts-the-two-skip-reasons-separately" as *u8, t_m2, ctr) 373 var t_m3: i64 = 0 374 if (rep[WA_R_DECLARED] + rep[WA_R_SKIPPED_NOTHTML] + rep[WA_R_SKIPPED_NOTFILE]) == rep[WA_R_ENTRIES] { t_m3 = 1 } 375 gv_check("manifest-parse-partition-sums-to-the-entry-count" as *u8, t_m3, ctr) 376 377 var t_m4: i64 = 0 378 if cnt == 2 { 379 let n0: *u8 = ((namebuf as i64) + offs[0]) as *u8 380 let n1: *u8 = ((namebuf as i64) + offs[1]) as *u8 381 if wa_find(n0, wa_strlen(n0), 0, "DOMTokenList-Iterable.html" as *u8) == 0 { 382 if wa_find(n1, wa_strlen(n1), 0, nm_real) == 0 { t_m4 = 1 } 383 } 384 } 385 // the filename in record 2 contains the letters n-a-m-e twice; a key needle without its quotes 386 // would split the record there and lose it. 387 gv_check("manifest-parse-not-confused-by-a-filename-containing-the-key" as *u8, t_m4, ctr) 388 var t_m5: i64 = 0 389 if cnt == 2 { if sizes[0] == 1204 { if sizes[1] == 1114 { t_m5 = 1 } } } 390 gv_check("manifest-parse-reads-the-declared-sizes" as *u8, t_m5, ctr) 391 var t_m6: i64 = 0 392 if cnt == 2 { if gt_hexeq(shas, "4cf84b12a22d15cbc8fb76d174ee0cbb7693b63b" as *u8) == 1 { t_m6 = 1 } } 393 gv_check("manifest-parse-reads-the-declared-blob-sha" as *u8, t_m6, ctr) 394 395 // A record missing one required field REFUSES the whole parse. A silently skipped row would be a 396 // smaller population, which reads as better news. 397 let js2: *u8 = sys_mmap(GT_JSON_CAP) 398 var j2: i64 = gt_ch(js2, 0, 91) 399 j2 = gt_rec(js2, j2, "ok.html" as *u8, "4cf84b12a22d15cbc8fb76d174ee0cbb7693b63b" as *u8, 10, "file" as *u8, 1) 400 j2 = gt_rec(js2, j2, "nosha.html" as *u8, "unused" as *u8, 10, "file" as *u8, 0) 401 j2 = gt_ch(js2, j2, 93) 402 gt_zero(rep) 403 var t_m7: i64 = 0 404 if wa_parse_manifest(js2, j2, namebuf, 65536, offs, sizes, shas, 64, rep) == WA_PARSE_MALFORMED { t_m7 = 1 } 405 gv_check("neg-control-a-record-missing-its-sha-refuses-the-whole-parse" as *u8, t_m7, ctr) 406 gt_zero(rep) 407 var t_m8: i64 = 0 408 if wa_parse_manifest(js, jo, namebuf, 65536, offs, sizes, shas, 1, rep) == WA_PARSE_OVERFLOW { t_m8 = 1 } 409 gv_check("neg-control-more-records-than-the-table-is-refused-not-capped" as *u8, t_m8, ctr) 410 gt_zero(rep) 411 var t_m9: i64 = 0 412 if wa_parse_manifest(js, jo, namebuf, 8, offs, sizes, shas, 64, rep) == WA_PARSE_NAMEBUF { t_m9 = 1 } 413 gv_check("neg-control-exhausted-name-storage-is-refused-not-capped" as *u8, t_m9, ctr) 414 415 // ---- THE COMPLETENESS CONJUNCTION ----------------------------------------------------------- 416 gt_zero(rep) 417 var t_c0: i64 = 0 418 if wa_coverage_complete(rep) == 0 { t_c0 = 1 } 419 gv_check("neg-control-coverage-complete-is-false-on-the-empty-set" as *u8, t_c0, ctr) 420 rep[WA_R_DECLARED] = 5 421 rep[WA_R_LANDED] = 3 422 rep[WA_R_REUSED] = 2 423 var t_c1: i64 = 0 424 if wa_coverage_complete(rep) == 1 { t_c1 = 1 } 425 gv_check("coverage-complete-true-when-every-declared-file-is-present" as *u8, t_c1, ctr) 426 var t_c2: i64 = 0 427 if wa_report_sums(rep) == 1 { t_c2 = 1 } 428 gv_check("partition-sums-when-the-report-is-consistent" as *u8, t_c2, ctr) 429 rep[WA_R_REUSED] = 1 430 rep[WA_R_FAIL_SHA] = 1 431 var t_c3: i64 = 0 432 if wa_coverage_complete(rep) == 0 { t_c3 = 1 } 433 gv_check("neg-control-coverage-complete-false-when-one-file-failed" as *u8, t_c3, ctr) 434 rep[WA_R_FAIL_SHA] = 0 435 var t_c4: i64 = 0 436 if wa_report_sums(rep) == 0 { t_c4 = 1 } 437 gv_check("neg-control-partition-leaks-when-the-report-does-not-reconcile" as *u8, t_c4, ctr) 438 439 // ---- MANIFEST EMIT AND THE MARKER ----------------------------------------------------------- 440 gt_zero(rep) 441 let cnt2: i64 = wa_parse_manifest(js, jo, namebuf, 65536, offs, sizes, shas, 64, rep) 442 rep[WA_R_LANDED] = cnt2 443 rep[WA_R_COVERAGE_COMPLETE] = 1 444 wa_manifest_write(GT_DIR, "dom/lists" as *u8, "a7b5671e50ee3610ec3ad2e1278a33b2cb11339c" as *u8, 445 namebuf, offs, sizes, shas, cnt2, rep) 446 lp[0] = 0 447 let mb: *u8 = sys_read_file(p_mf, lp) 448 var has_pin: i64 = 0 449 var last_is_verdict: i64 = 0 450 var mlen: i64 = 0 451 if (mb as i64) != 0 { 452 mlen = lp[0] 453 if wa_find(mb, mlen, 0, "a7b5671e50ee3610ec3ad2e1278a33b2cb11339c" as *u8) >= 0 { has_pin = 1 } 454 // the LAST line, taken by POSITION: step over the trailing newline, then back to the one before 455 var e: i64 = mlen - 1 456 if e >= 0 { if (mb[e] as i64) == 10 { e = e - 1 } } 457 var s2: i64 = e 458 var seeking: i64 = 1 459 while seeking == 1 { 460 if s2 <= 0 { seeking = 0 } else { 461 if (mb[s2-1] as i64) == 10 { seeking = 0 } else { s2 = s2 - 1 } 462 } 463 } 464 if wa_find(mb, mlen, s2, "verdict" as *u8) == s2 { last_is_verdict = 1 } 465 } 466 gv_puts(" manifest: bytes=" as *u8); gv_num(mlen) 467 gv_puts(" rows=" as *u8); gv_num(cnt2); gv_puts("\n" as *u8) 468 var t_e0: i64 = 0 469 if mlen > 0 { t_e0 = 1 } 470 gv_check("manifest-emit-produced-a-readable-file" as *u8, t_e0, ctr) 471 gv_check("manifest-emit-carries-the-commit-pin" as *u8, has_pin, ctr) 472 gv_check("manifest-emit-last-line-is-the-canonical-verdict" as *u8, last_is_verdict, ctr) 473 474 wa_marker_set(GT_DIR, 0, 5, 3) 475 let mk_written: i64 = gt_exists(p_mk) 476 wa_marker_set(GT_DIR, 1, 5, 5) 477 var mk_still: i64 = gt_exists(p_mk) 478 gv_bite("marker-is-written-when-incomplete-and-removed-when-complete" as *u8, mk_written, mk_still, ctr) 479 480 // ---- TEARDOWN (the next run must measure itself, not this one) ------------------------------ 481 sys_unlinkat(p_ok) 482 sys_unlinkat(p_tr) 483 sys_unlinkat(p_bad) 484 sys_unlinkat(p_mf) 485 sys_unlinkat(p_mk) 486 487 return gv_verdict("nx_wpt_ingest_gate" as *u8, ctr, 488 "offline proof of the ingest core: manifest parse, dual verification against the declared size and the declared git blob sha, raw write, read-back compare, pin rule, name allowlist, completeness conjunction, manifest and marker emit. The transport is nx_https_fetch_follow's subject and is NOT proven here." as *u8) 489}