nx_http_dechunk_test.nx source
↩ module page · 61 lines · 3289 B
1// nx_http_dechunk_test.nx -- KATs + negative controls for the sovereign chunked decoder.
2// expect_exit: 0
3// license_tier: ORIGINAL
4import "nx_http_dechunk.nx"
5import "nx_syscalls.nx"
6
7func t_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
8func t_putn(v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64 = v; if m < 0 { m = 0 - m; sys_write(1, "-" 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(1, bb, k); return 0 }
9func t_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
10
11func t_eq(a: *u8, an: i64, b: *u8, bn: i64) -> i64 {
12 if an != bn { return 0 }
13 var i: i64 = 0
14 while i < an { if a[i] != b[i] { return 0 } i = i + 1 }
15 return 1
16}
17
18func main() -> i64 {
19 let out: *u8 = sys_mmap(65536)
20 var pass: i64 = 0
21 var total: i64 = 0
22
23 // KAT1: classic two-chunk "4 Wiki / 5 pedia / 0" -> "Wikipedia"
24 let in1: *u8 = "4\x0D\x0AWiki\x0D\x0A5\x0D\x0Apedia\x0D\x0A0\x0D\x0A\x0D\x0A\x00"
25 let exp1: *u8 = "Wikipedia\x00"
26 let d1: i64 = nx_http_dechunk(in1, t_slen(in1), out, 65536)
27 total = total + 1
28 t_puts("KAT1 two-chunk: len=" as *u8); t_putn(d1); t_puts(" want=9 -> " as *u8)
29 if t_eq(out, d1, exp1, t_slen(exp1)) == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
30
31 // KAT2: TWO-hex-digit size 0x10=16 -> "0123456789ABCDEF"
32 let in2: *u8 = "10\x0D\x0A0123456789ABCDEF\x0D\x0A0\x0D\x0A\x0D\x0A\x00"
33 let exp2: *u8 = "0123456789ABCDEF\x00"
34 let d2: i64 = nx_http_dechunk(in2, t_slen(in2), out, 65536)
35 total = total + 1
36 t_puts("KAT2 hex-0x10: len=" as *u8); t_putn(d2); t_puts(" want=16 -> " as *u8)
37 if t_eq(out, d2, exp2, t_slen(exp2)) == 1 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
38
39 // NEG-A: un-chunked plaintext must ERROR, not pass through
40 let in3: *u8 = "hello world\x00"
41 let d3: i64 = nx_http_dechunk(in3, t_slen(in3), out, 65536)
42 total = total + 1
43 t_puts("NEG-A plaintext: ret=" as *u8); t_putn(d3); t_puts(" want<0 -> " as *u8)
44 if d3 < 0 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
45
46 // NEG-B: overflow guard must fire when out_cap is too small (no OOB write)
47 let d4: i64 = nx_http_dechunk(in1, t_slen(in1), out, 3)
48 total = total + 1
49 t_puts("NEG-B overflow cap=3: ret=" as *u8); t_putn(d4); t_puts(" want<0 -> " as *u8)
50 if d4 < 0 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
51
52 // NEG-C: the transform actually transformed (raw chunked bytes != decoded body)
53 let d5: i64 = nx_http_dechunk(in1, t_slen(in1), out, 65536)
54 total = total + 1
55 t_puts("NEG-C raw!=decoded -> " as *u8)
56 if t_eq(in1, t_slen(in1), out, d5) == 0 { pass = pass + 1; t_puts("PASS\n" as *u8) } else { t_puts("FAIL\n" as *u8) }
57
58 t_puts("DECHUNK-GATE passed " as *u8); t_putn(pass); t_puts("/" as *u8); t_putn(total)
59 if pass == total { t_puts(" verdict=GREEN\n" as *u8); sys_exit(0); return 0 }
60 t_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1
61}