nx_wasm_pair_extension_gate.nx source
↩ module page · 154 lines · 9145 B
1import "nx_game_page_artifact_lib.nx"
2import "nx_gate_verdict.nx"
3import "nx_wasm_data.nx"
4// Mutate only private read buffers so negative controls cannot change staged artifacts.
5func wpe_interface_mutation(plain: *u8,pn: i64,twin: *u8,tn: i64,section: i64,label: *u8,checks: *i64) -> i64 {
6 let c: *GpaWasmCursor=sys_mmap(__size_of(GpaWasmCursor)) as *GpaWasmCursor
7 if gpa_section(twin,tn,section,c)!=1 || c.size<=0 {
8 gv_check("interface section fixture located",0,checks)
9 sys_munmap(c as *u8,__size_of(GpaWasmCursor))
10 return 0
11 }
12 let last: i64=c.size-1
13 let saved: u8=c.data[last]
14 c.data[last]=saved^(1 as u8)
15 gv_check_eq(label,gpa_interface_extension(plain,pn,twin,tn),0,checks)
16 c.data[last]=saved
17 gv_check_eq("restored interface accepted",gpa_interface_extension(plain,pn,twin,tn),1,checks)
18 sys_munmap(c as *u8,__size_of(GpaWasmCursor))
19 return 1
20}
21// Fixture extents exercise the real compiler allocator without allocating payload memory.
22func wpe_layout_checks(checks: *i64) -> i64 {
23 let m: *Module=sys_mmap(__size_of(Module)) as *Module
24 let slots: i64=3
25 m.globals=sys_mmap(slots*NX_MODULE_GLOBAL_STRIDE) as *Global
26 m.n_globals=slots;m.globals_cap=slots
27 let first: *Global=m.globals
28 let zero: *Global=(m.globals as i64+NX_MODULE_GLOBAL_STRIDE) as *Global
29 let last: *Global=(m.globals as i64+2*NX_MODULE_GLOBAL_STRIDE) as *Global
30 first.len=13;first.is_string=1
31 zero.len=3*WD_PAGE+5;zero.zero_init=1
32 last.len=WD_CELL
33 let plain_pages: i64=wd_prepare(m,1,0)
34 let first_address: i64=wd_address(0)
35 let zero_address: i64=wd_address(1)
36 let last_address: i64=wd_address(2)
37 let shared_pages: i64=wd_prepare(m,1,1)
38 gv_check_eq("mixed layout first address preserved",wd_address(0),first_address,checks)
39 gv_check_eq("mixed layout zero global address preserved",wd_address(1),zero_address,checks)
40 gv_check_eq("mixed layout last address preserved",wd_address(2),last_address,checks)
41 gv_check_eq("string terminator and alignment reserved",zero_address,WD_PAGE+2*WD_CELL,checks)
42 gv_check_eq("zero storage extent and alignment reserved",last_address,4*WD_PAGE+3*WD_CELL,checks)
43 gv_check_eq("state follows all global storage",wd_init_address,4*WD_PAGE+4*WD_CELL,checks)
44 gv_check_eq("mixed layout shared pages",shared_pages,5,checks)
45 gv_check_eq("mixed layout plain pages",plain_pages,5,checks)
46 gv_check("state fits declared initial memory",(wd_init_address+WD_CELL<=shared_pages*WD_PAGE) as i64,checks)
47 gv_kv("mixed_state_address_bytes",wd_init_address)
48 m.n_globals=1
49 first.is_string=0;first.zero_init=1;first.len=WD_PAGE
50 let boundary_plain: i64=wd_prepare(m,1,0)
51 let boundary_shared: i64=wd_prepare(m,1,1)
52 gv_check_eq("page filled by zero storage plain pages",boundary_plain,2,checks)
53 gv_check_eq("page filled by zero storage state address",wd_init_address,2*WD_PAGE,checks)
54 gv_check_eq("state requires next page when full",boundary_shared,3,checks)
55 first.len=WD_PAGE-WD_CELL
56 gv_check_eq("state fits final aligned cell without extra page",wd_prepare(m,1,1),2,checks)
57 gv_check_eq("final cell reservation",wd_init_address,2*WD_PAGE-WD_CELL,checks)
58 gv_kv("boundary_state_address_bytes",wd_init_address)
59 // Repeated compilation must not retain a flag belonging to the previous module.
60 wd_prepare(m,1,0)
61 gv_check_eq("plain layout clears prior initialization reservation",wd_init_address,0,checks)
62 m.n_globals=0
63 gv_check_eq("empty shared layout preserves requested pages",wd_prepare(m,1,1),1,checks)
64 gv_check_eq("empty layout has no initialization reservation",wd_init_address,0,checks)
65 sys_munmap(m.globals as *u8,slots*NX_MODULE_GLOBAL_STRIDE)
66 sys_munmap(m as *u8,__size_of(Module))
67 return 0
68}
69func wpe_envelope_checks(plain: *u8,pn: i64,twin: *u8,tn: i64,checks: *i64) -> i64 {
70 gv_check_eq("actual module envelope preserved",gpa_extension_envelope(plain,pn,twin,tn),1,checks)
71 gv_check_eq("truncated envelope refused",gpa_extension_envelope(plain,pn,twin,tn-1),0,checks)
72 var c: GpaWasmCursor
73 if gpa_section(twin,tn,12,&c)==1 && c.size>0 {
74 let saved: u8=c.data[0]
75 c.data[0]=saved^(1 as u8)
76 gv_check_eq("changed data count refused",gpa_extension_envelope(plain,pn,twin,tn),0,checks)
77 c.data[0]=saved
78 } else { gv_check("data count fixture present",0,checks) }
79 if gpa_section(twin,tn,2,&c)==1 {
80 let imports: i64=gpa_u32(&c)
81 let name_size: i64=gpa_u32(&c)
82 if imports==1 && name_size>0 && name_size<=c.size-c.pos {
83 let saved: u8=c.data[c.pos]
84 c.data[c.pos]=saved^(1 as u8)
85 gv_check_eq("changed import namespace refused",gpa_extension_envelope(plain,pn,twin,tn),0,checks)
86 c.data[c.pos]=saved
87 } else { gv_check("memory import fixture located",0,checks) }
88 } else { gv_check("memory import present",0,checks) }
89 // Append bounded binary sections to a private copy, never the on-disk artifacts.
90 let copy: *u8=sys_mmap(tn+3)
91 var i: i64=0
92 while i<tn { copy[i]=twin[i];i=i+1 }
93 copy[tn]=13 as u8;copy[tn+1]=0 as u8
94 gv_check_eq("unsupported section refused",gpa_extension_envelope(plain,pn,copy,tn+2),0,checks)
95 copy[tn]=1 as u8;copy[tn+1]=1 as u8;copy[tn+2]=0 as u8
96 gv_check_eq("duplicate and out-of-order type section refused",gpa_extension_envelope(plain,pn,copy,tn+3),0,checks)
97 copy[tn]=0 as u8;copy[tn+1]=1 as u8;copy[tn+2]=0 as u8
98 gv_check_eq("unpaired custom section refused",gpa_extension_envelope(plain,pn,copy,tn+3),0,checks)
99 gv_check_eq("restored module envelope accepted",gpa_extension_envelope(plain,pn,twin,tn),1,checks)
100 sys_munmap(copy,tn+3)
101 return 0
102}
103func main(argc: i64,argv: *i64) -> i64 {
104 let checks: *i64=gv_ctr()
105 if argc!=3 { gv_check("plain and shared artifacts required",0,checks);return gv_verdict("WASM-PAIR-EXTENSION",checks,"artifact arguments absent") }
106 wpe_layout_checks(checks)
107 let sizes: *i64=sys_mmap(__size_of(i64)*2) as *i64
108 let plain: *u8=sys_read_file(argv[1] as *u8,sizes)
109 let pn: i64=sizes[0]
110 let twin: *u8=sys_read_file(argv[2] as *u8,sizes)
111 let tn: i64=sizes[0]
112 if plain==(0 as *u8) || twin==(0 as *u8) || pn<=0 || tn<=0 {
113 gv_check("both real artifacts readable",0,checks)
114 return gv_verdict("WASM-PAIR-EXTENSION",checks,"artifact read failed")
115 }
116 wpe_envelope_checks(plain,pn,twin,tn,checks)
117 gv_check_eq("all application bodies preserved",gpa_application_code(plain,pn,twin,tn),1,checks)
118 gv_check_eq("all payloads and exact initializer preserved",gpa_data_initialization(plain,pn,twin,tn),1,checks)
119 gv_check_eq("actual application types and exports preserved",gpa_interface_extension(plain,pn,twin,tn),1,checks)
120 wpe_interface_mutation(plain,pn,twin,tn,1,"changed type refused",checks)
121 wpe_interface_mutation(plain,pn,twin,tn,3,"changed initializer type reference refused",checks)
122 wpe_interface_mutation(plain,pn,twin,tn,7,"changed initializer export index refused",checks)
123 gv_check_eq("truncated module interface refused",gpa_interface_extension(plain,pn,twin,tn-1),0,checks)
124 let a: *GpaWasmCursor=sys_mmap(__size_of(GpaWasmCursor)) as *GpaWasmCursor
125 let b: *GpaWasmCursor=sys_mmap(__size_of(GpaWasmCursor)) as *GpaWasmCursor
126 let extra: *GpaWasmCursor=sys_mmap(__size_of(GpaWasmCursor)) as *GpaWasmCursor
127 let data_found: i64=gpa_section(twin,tn,11,b)
128 gv_check_eq("real passive data present",data_found,1,checks)
129 if data_found==1 {
130 let count: i64=gpa_u32(b)
131 let kind: i64=gpa_u32(b)
132 let bytes: i64=gpa_u32(b)
133 if count>0 && kind==1 && bytes>0 && bytes<=b.size-b.pos {
134 let saved: u8=b.data[b.pos]
135 b.data[b.pos]=saved^(1 as u8)
136 gv_check_eq("changed payload refused",gpa_data_initialization(plain,pn,twin,tn),0,checks)
137 b.data[b.pos]=saved
138 } else { gv_check("fixture has mutable passive payload",0,checks) }
139 }
140 if gpa_section(plain,pn,10,a)==1 && gpa_section(twin,tn,10,b)==1 {
141 if gpa_code_prefix(a,b,extra)==1 {
142 let saved: u8=extra.data[extra.size-1]
143 extra.data[extra.size-1]=0 as u8
144 gv_check_eq("altered initializer refused",gpa_data_initialization(plain,pn,twin,tn),0,checks)
145 extra.data[extra.size-1]=saved
146 } else { gv_check("initializer fixture located",0,checks) }
147 } else { gv_check("code sections located",0,checks) }
148 gv_check_eq("truncated shared artifact refused",gpa_data_initialization(plain,pn,twin,tn-1),0,checks)
149 gv_check_eq("restored artifacts pass",gpa_data_initialization(plain,pn,twin,tn),1,checks)
150 sys_munmap(a as *u8,__size_of(GpaWasmCursor));sys_munmap(b as *u8,__size_of(GpaWasmCursor))
151 sys_munmap(extra as *u8,__size_of(GpaWasmCursor))
152 sys_munmap(plain,pn);sys_munmap(twin,tn);sys_munmap(sizes as *u8,__size_of(i64)*2)
153 return gv_verdict("WASM-PAIR-EXTENSION",checks,"real compiled modules; code, data, initializer and interface mutation evidence; full pair acceptance remains separate")
154}