code wiki / _hdl_build / nx_cms_visual_builder_gate.nx
nx_cms_visual_builder_gate.nx source
↩ module page · 107 lines · 6216 B
1// nx_cms_visual_builder_gate.nx -- referee for R-CANVAS v1 (nx_cms_visual_builder): the visual no-JS site
2// editor lib. Proves: the form prefills from a real blueprint (attribute-escaped), the server-side rebuild
3// reconstructs a valid blueprint from posted urlencoded fields (decoded, blank cards omitted), and the
4// format cannot be injected ('|' in a value neutralized; missing title -> a blueprint the daemon's validator
5// refuses). GREEN iff 7/7. license_tier: ORIGINAL expect_exit: 0
6import "nx_gate.nx"
7import "nx_cms_visual_builder.nx"
8import "nx_gate_verdict.nx"
9
10func vg_has(hay: *u8, hn: i64, needle: *u8) -> i64 {
11 if (hay as i64)==0 { return 0 }
12 var nl: i64=0; while needle[nl]!=(0 as u8){nl=nl+1}
13 if nl==0 { return 1 }
14 var i: i64=0
15 while i+nl<=hn { var j: i64=0; var ok: i64=1; while j<nl { if (hay[i+j] as i64)!=(needle[j] as i64) { ok=0; j=nl } else { j=j+1 } } if ok==1 { return 1 } i=i+1 }
16 return 0
17}
18func vg_count(hay: *u8, hn: i64, needle: *u8) -> i64 {
19 if (hay as i64)==0 { return 0 }
20 var nl: i64=0; while needle[nl]!=(0 as u8){nl=nl+1}
21 if nl==0 { return 0 }
22 var c: i64=0
23 var i: i64=0
24 while i+nl<=hn { var j: i64=0; var ok: i64=1; while j<nl { if (hay[i+j] as i64)!=(needle[j] as i64) { ok=0; j=nl } else { j=j+1 } } if ok==1 { c=c+1; i=i+nl } else { i=i+1 } }
25 return c
26}
27func vg_row(name: *u8, ok: i64) -> i64 { gw(" " as *u8); gw(name); if ok==1 { gw(" PASS\n" as *u8) } else { gw(" FAIL\n" as *u8) } return 0 }
28
29func main() -> i64 {
30 // fixture blueprint (a quote in a card body exercises attribute escaping)
31 let cfg: *u8 = "title|Old Title\nheader|Brand|Call now|/\nhero|Big H|Sub S\nsearch|/search|Find\ncard|Card One|We say \"hello\" here\ncard|Card Two|Second body\nstep|Step A\nsig|Trusted\nfooter|F text\n" as *u8
32 var cn: i64 = 0
33 while cfg[cn] != (0 as u8) { cn = cn + 1 }
34 let body: *u8 = sys_mmap(300000)
35 let bl: i64 = vb_form_page(cfg, cn, "TOK" as *u8, 3, body, 0)
36 // T1: prefilled fields (hero, card 1 name, footer) land as input values
37 var t1: i64=0
38 if vg_has(body, bl, "value=\"Big H\"" as *u8)==1 { if vg_has(body, bl, "value=\"Card One\"" as *u8)==1 { if vg_has(body, bl, "value=\"F text\"" as *u8)==1 { t1=1 } } }
39 // T2: attribute escaping -- the quoted card body renders "
40 var t2: i64=0
41 if vg_has(body, bl, "We say "hello" here" as *u8)==1 { t2=1 }
42 // T3: rebuild reconstructs a full blueprint from a posted form
43 let fb: *u8 = "title=New+T&brand=B2&hcta=Go&hhref=%2F&heroh=H2&herosub=S2&searcha=%2Fsearch&searchp=Find&card1t=C1&card1b=D1&step1=S1&sig1=G1&footer=F2" as *u8
44 var fn2: i64 = 0
45 while fb[fn2] != (0 as u8) { fn2 = fn2 + 1 }
46 let out: *u8 = sys_mmap(300000)
47 let ol: i64 = vb_rebuild(fb, fn2, out)
48 var t3: i64=0
49 if vg_has(out, ol, "title|New T\n" as *u8)==1 { if vg_has(out, ol, "hero|H2|S2\n" as *u8)==1 { if vg_has(out, ol, "card|C1|D1\n" as *u8)==1 { if vg_has(out, ol, "footer|F2\n" as *u8)==1 { t3=1 } } } }
50 // T4: urldecoding (+ -> space above; %26 -> &)
51 let fb4: *u8 = "title=A%26B+C&heroh=H&card1t=X&footer=F" as *u8
52 var f4n: i64 = 0
53 while fb4[f4n] != (0 as u8) { f4n = f4n + 1 }
54 let o4l: i64 = vb_rebuild(fb4, f4n, out)
55 var t4: i64=0
56 if vg_has(out, o4l, "title|A&B C\n" as *u8)==1 { t4=1 }
57 // T5: blank cards omitted -- exactly ONE card| line when only card1 is filled
58 if vg_count(out, o4l, "card|" as *u8)==1 { t4=t4 } // (count checked in t5 below on the same rebuild)
59 var t5: i64=0
60 if vg_count(out, o4l, "card|" as *u8)==1 { t5=1 }
61 // T6 (NEG): no title field -> the rebuilt blueprint LACKS title| (the daemon's validator refuses it)
62 let fb6: *u8 = "heroh=H&card1t=X&footer=F" as *u8
63 var f6n: i64 = 0
64 while fb6[f6n] != (0 as u8) { f6n = f6n + 1 }
65 let o6l: i64 = vb_rebuild(fb6, f6n, out)
66 var t6: i64=0
67 if vg_has(out, o6l, "title|" as *u8)==0 { if vg_has(out, o6l, "hero|H" as *u8)==1 { t6=1 } }
68 // T7 (NEG): format injection blocked -- a %7C ('|') inside a value becomes a space, never a field split
69 let fb7: *u8 = "title=T&heroh=H&card1t=A%7CB&card1b=D&footer=F" as *u8
70 var f7n: i64 = 0
71 while fb7[f7n] != (0 as u8) { f7n = f7n + 1 }
72 let o7l: i64 = vb_rebuild(fb7, f7n, out)
73 var t7: i64=0
74 if vg_has(out, o7l, "card|A B|D\n" as *u8)==1 { if vg_has(out, o7l, "card|A|B|" as *u8)==0 { t7=1 } }
75
76 var passes: i64=0
77 if t1==1 { passes=passes+1 } if t2==1 { passes=passes+1 } if t3==1 { passes=passes+1 }
78 if t4==1 { passes=passes+1 } if t5==1 { passes=passes+1 } if t6==1 { passes=passes+1 } if t7==1 { passes=passes+1 }
79 var green: i64=0; if passes==7 { green=1 }
80
81 gw("=== nx_cms_visual_builder_gate -- R-CANVAS v1 visual no-JS editor ===\n" as *u8)
82 vg_row("T1-form-prefills-from-blueprint" as *u8, t1)
83 vg_row("T2-attribute-escaping " as *u8, t2)
84 vg_row("T3-rebuild-full-blueprint " as *u8, t3)
85 vg_row("T4-urldecode-plus-and-pct " as *u8, t4)
86 vg_row("T5-blank-cards-omitted " as *u8, t5)
87 vg_row("T6-missing-title-refusable(neg)" as *u8, t6)
88 vg_row("T7-pipe-injection-blocked(neg) " as *u8, t7)
89 gw("verdict=" as *u8); if green==1 { gw("GREEN" as *u8) } else { gw("RED" as *u8) }
90 gw(" passes=" as *u8); gn(passes); gw("/7\n" as *u8)
91
92 let lg: i64 = sys_openat_append("knowledge/status/cms_visual_builder.log" as *u8, 0x1a4)
93 if lg >= 0 {
94 if green==1 { let m: *u8 = "CMS-VISUAL rows=7 pass=7 verdict=GREEN\n" as *u8; sys_write(lg, m, 39) }
95 else { let m2: *u8 = "CMS-VISUAL verdict=RED\n" as *u8; sys_write(lg, m2, 23) }
96 sys_close(lg)
97 }
98 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
99 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
100 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
101 let ctr__dry: *i64 = gv_ctr()
102 ctr__dry[0] = green
103 ctr__dry[1] = 1
104 let rc__dry: i64 = gv_verdict("CMS-VISUAL-BUILDER-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
105 sys_exit(rc__dry)
106 return rc__dry
107}