code wiki / (root) / nx_site_publish_gate.nx

nx_site_publish_gate.nx source

↩ module page · 90 lines · 4431 B

1// nx_site_publish_gate.nx -- gates artifact-publish placement semantics on a THROWAWAY CWD (the docroot 2// is CWD-relative sites/): fresh publish lands byte-identical; republish preserves .prev AND lands v2; 3// traversal ('..', absolute) DENIED with NOTHING written; secret-needle relpath DENIED via the IO layer; 4// absent source honest ABSENT. Runner: mkdir a scratch dir, cd into it, run. Exit 0 only on all-PASS. 5// license_tier: ORIGINAL expect_exit: 0 6import "nx_site_publish_lib.nx" 7import "nx_seg_store.nx" // ss_writefile -- fixture author 8 9const SG_CHECKS: i64 = 7 10const SG_AV: i64 = 64 // synthetic argv cells 11const SG_RB: i64 = 4096 // read-back buffer 12 13func sg_check(name: *u8, ok: i64, pass: *i64) -> i64 { 14 fsx_puts("T " as *u8); fsx_puts(name); fsx_puts(" -> " as *u8) 15 if ok == 1 { fsx_puts("PASS\n" as *u8); pass[0] = pass[0] + 1 } else { fsx_puts("FAIL\n" as *u8) } 16 return 0 17} 18func sg_run(src: *u8, site: *u8, rel: *u8) -> i64 { 19 let av: *i64 = sys_mmap(SG_AV) as *i64 20 av[0] = "nx_site_publish" as *u8 as i64 21 av[PB_ARG_VERB] = "publish" as *u8 as i64 22 av[PB_ARG_SRC] = src as i64 23 av[PB_ARG_SITE] = site as i64 24 av[PB_ARG_REL] = rel as i64 25 return sp_main(PB_ARGC, av) 26} 27func sg_eq(path: *u8, expect: *u8) -> i64 { 28 let b: *u8 = sys_mmap(SG_RB) 29 let n: i64 = vw_read(path, b, SG_RB - 1) 30 if n < 0 { return 0 } 31 b[n] = 0 as u8 32 return fsx_seq(b, expect) 33} 34func sg_absent(path: *u8) -> i64 { 35 let b: *u8 = sys_mmap(SG_RB) 36 if vw_read(path, b, SG_RB - 1) < 0 { return 1 } 37 return 0 38} 39 40func main() -> i64 { 41 let pass: *i64 = sys_mmap(16) as *i64 42 pass[0] = 0 43 sys_mkdir("sites" as *u8, 0x1ed) 44 sys_mkdir("sites/gatesite" as *u8, 0x1ed) 45 ss_writefile("v1.html" as *u8, "<h1>one</h1>" as *u8, vw_slen("<h1>one</h1>" as *u8)) 46 ss_writefile("v2.html" as *u8, "<h1>two</h1>" as *u8, vw_slen("<h1>two</h1>" as *u8)) 47 // T1 fresh publish lands byte-identical, no .prev 48 var ok1: i64 = 0 49 if sg_run("v1.html" as *u8, "gatesite" as *u8, "page.html" as *u8) == 0 { 50 if sg_eq("sites/gatesite/page.html" as *u8, "<h1>one</h1>" as *u8) == 1 { 51 ok1 = sg_absent("sites/gatesite/page.html.prev" as *u8) 52 } 53 } 54 sg_check("fresh-publish-lands" as *u8, ok1, pass) 55 // T2 republish: .prev holds v1, target holds v2 56 var ok2: i64 = 0 57 if sg_run("v2.html" as *u8, "gatesite" as *u8, "page.html" as *u8) == 0 { 58 if sg_eq("sites/gatesite/page.html" as *u8, "<h1>two</h1>" as *u8) == 1 { 59 ok2 = sg_eq("sites/gatesite/page.html.prev" as *u8, "<h1>one</h1>" as *u8) 60 } 61 } 62 sg_check("republish-preserves-prev" as *u8, ok2, pass) 63 // T3 traversal in relpath DENIED, nothing written outside 64 var ok3: i64 = 0 65 if sg_run("v1.html" as *u8, "gatesite" as *u8, "../escape.html" as *u8) == FSX_RC_DENIED { 66 ok3 = sg_absent("sites/escape.html" as *u8) 67 } 68 sg_check("relpath-traversal-denied" as *u8, ok3, pass) 69 // T4 absolute site DENIED 70 sg_check("absolute-site-denied" as *u8, (sg_run("v1.html" as *u8, "/etc" as *u8, "x.html" as *u8) == FSX_RC_DENIED) as i64, pass) 71 // T5 secret-needle relpath DENIED by the IO layer's write deny 72 sg_check("secret-relpath-denied" as *u8, (sg_run("v1.html" as *u8, "gatesite" as *u8, "apikey.html" as *u8) == FSX_RC_DENIED) as i64, pass) 73 // T6 absent source -> honest ABSENT 74 sg_check("absent-source-honest" as *u8, (sg_run("nope.html" as *u8, "gatesite" as *u8, "y.html" as *u8) == FSX_RC_ABSENT) as i64, pass) 75 // T7 REGRESSION (debt seq910): a relpath whose PARENT DIRECTORY does not exist must fail 76 // LOUD with FSX_RC_IO and write nothing. This is the case T1-T6 never covered -- the gate 77 // was 6/6 GREEN while the only silent exit in sp_main went untested, and a real publish to 78 // "research/rt004.html" returned empty output and read as success. 79 var ok7: i64 = 0 80 if sg_run("v1.html" as *u8, "gatesite" as *u8, "nodir/page.html" as *u8) == FSX_RC_IO { 81 ok7 = sg_absent("sites/gatesite/nodir/page.html" as *u8) 82 } 83 sg_check("missing-parent-dir-fails-loud" as *u8, ok7, pass) 84 85 fsx_puts("SITE-PUBLISH-GATE pass=" as *u8); fsx_putn(pass[0]); fsx_puts("/" as *u8); fsx_putn(SG_CHECKS); fsx_puts(" verdict=" as *u8) 86 if pass[0] == SG_CHECKS { fsx_puts("GREEN\n" as *u8); sys_exit(0); return 0 } 87 fsx_puts("RED\n" as *u8) 88 sys_exit(1) 89 return 1 90}