nx_fix_putn.nx source
↩ module page · 116 lines · 6798 B
1// nx_fix_putn.nx -- AUTO-FIXER for the propagating leaky-putn anti-pattern (per-character sys_mmap(1) inside a
2// digit-print loop = a mmap-in-loop leak-by-construction, copied into ~40 fetch/census/gate organs). Replaces
3// the exact leaky block with the hoisted write-once form -- BYTE-EXACT match, so a variant that doesn't match
4// is left untouched (safe: never a fuzzy edit). Modes:
5// nx_fix_putn <file> -- fix one file (report FIXED / no-match)
6// nx_fix_putn sweep <dir> -- walk dir, fix every matching .nx, report count
7// After fixing, the caller re-gates/rebuilds (the fix is proven verdict-equal to the 3 hand-fixes). This is the
8// "build the tool so eating the debt is one step" move. Sovereign (getdents64 + file IO, no shell). expect_exit: 0
9import "nx_syscalls.nx"
10import "nx_dir.nx"
11const FX_MAGIC_4096: i64 = 4096
12
13const FX_BUF: i64 = 1048576
14const FX_CAP: i64 = 16384
15
16// the EXACT leaky 2-line block (4-space indent) as it was copied everywhere:
17// var i: i64 = k - 1
18// while i >= 0 { let o: *u8 = sys_mmap(1); o[0] = d[i]; sys_write(1, o, 1); i = i - 1 }
19const FX_NEEDLE: *u8 = " var i: i64 = k - 1\x0a while i >= 0 { let o: *u8 = sys_mmap(1); o[0] = d[i]; sys_write(1, o, 1); i = i - 1 }\x00"
20// the hoisted write-once replacement (buffer allocated ONCE, single sys_write):
21const FX_REPL: *u8 = " let o: *u8 = sys_mmap(24); var i: i64 = 0\x0a while i < k { o[i] = d[k - 1 - i]; i = i + 1 }\x0a sys_write(1, o, k)\x00"
22
23func fx_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
24func fx_putn(v: i64) -> i64 {
25 if v == 0 { sys_write(1, "0" as *u8, 1); return 0 }
26 var m: i64 = v; let d: *u8 = sys_mmap(24); var k: i64 = 0
27 while m > 0 { d[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
28 let o: *u8 = sys_mmap(24); var i: i64 = 0
29 while i < k { o[i] = d[k - 1 - i]; i = i + 1 } sys_write(1, o, k); return 0
30}
31func fx_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
32func fx_read(path: *u8, buf: *u8) -> i64 {
33 let fd: i64 = sys_openat_rd(path); if fd < 0 { return 0 - 1 }
34 var t: i64 = 0; var go: i64 = 1
35 while go == 1 { let r: i64 = sys_read(fd, ((buf as i64) + t) as *u8, FX_BUF - t); if r <= 0 { go = 0 } else { t = t + r; if t >= FX_BUF { go = 0 } } }
36 sys_close(fd); return t
37}
38// find NUL-terminated needle in buf[0..n); return start index or -1
39func fx_find(buf: *u8, n: i64, needle: *u8) -> i64 {
40 let pl: i64 = fx_slen(needle); if pl == 0 { return 0 - 1 }
41 var i: i64 = 0
42 while i + pl <= n {
43 var m: i64 = 0; var hit: i64 = 1
44 while m < pl { if buf[i + m] != needle[m] { hit = 0; m = pl } else { m = m + 1 } }
45 if hit == 1 { return i }
46 i = i + 1
47 }
48 return 0 - 1
49}
50// fix one file in place (byte-exact). returns 1 if changed, 0 if no match, -1 if unreadable.
51func fx_fix_file(path: *u8, buf: *u8, out: *u8) -> i64 {
52 let n: i64 = fx_read(path, buf); if n < 0 { return 0 - 1 }
53 let pos: i64 = fx_find(buf, n, FX_NEEDLE); if pos < 0 { return 0 }
54 let nl: i64 = fx_slen(FX_NEEDLE); let rl: i64 = fx_slen(FX_REPL)
55 // out = buf[0..pos] + REPL + buf[pos+nl..n]
56 var o: i64 = 0; var i: i64 = 0
57 while i < pos { out[o] = buf[i]; o = o + 1; i = i + 1 }
58 // LM-030 FIX (2026-07-30): this loop indexed the const *u8 DIRECTLY, which compiles clean and yields
59 // GARGABE BYTES at runtime -- in THIS organ that meant writing corrupted replacement text straight into
60 // source files it edits in place. Bind to a local first; passing a const to a func is safe, only the
61 // direct index is broken. Proven by nx_constidx_probe vs nx_constidx_ctrl.
62 let repl: *u8 = FX_REPL
63 i = 0; while i < rl { out[o] = repl[i]; o = o + 1; i = i + 1 }
64 i = pos + nl; while i < n { out[o] = buf[i]; o = o + 1; i = i + 1 }
65 let fd: i64 = sys_openat_wr(path, 0x1a4); if fd < 0 { return 0 - 1 }
66 sys_write(fd, out, o); sys_close(fd)
67 return 1
68}
69
70func main(argc: i64, argv: *i64) -> i64 {
71 if argc < 2 { fx_puts("usage: nx_fix_putn <file> | nx_fix_putn sweep <dir>\n" as *u8); sys_exit(2); return 2 }
72 let buf: *u8 = sys_mmap(FX_BUF)
73 let out: *u8 = sys_mmap(FX_BUF + FX_MAGIC_4096)
74
75 // sweep mode? (compare argv[1] to "sweep" char-by-char; ptr-eq on literals is unreliable)
76 let a1: *u8 = argv[1] as *u8
77 var sweep: i64 = 0
78 if a1[0] == (115 as u8) { if a1[1] == (119 as u8) { if a1[2] == (101 as u8) { if a1[3] == (101 as u8) { if a1[4] == (112 as u8) { sweep = 1 } } } } }
79
80 if sweep == 1 {
81 if argc < 3 { fx_puts("usage: nx_fix_putn sweep <dir>\n" as *u8); sys_exit(2); return 2 }
82 let dir: *u8 = argv[2] as *u8
83 let rows: *NxDirRow = (sys_mmap(NX_DIR_ROW_BYTES * FX_CAP)) as *NxDirRow
84 let arena: *u8 = sys_mmap(FX_CAP * 128)
85 let res: *NxDirResult = (sys_mmap(64)) as *NxDirResult
86 nx_dir_list(dir, rows, FX_CAP, arena, FX_CAP * 128, 0, res)
87 let path: *u8 = sys_mmap(512)
88 var fixed: i64 = 0; var scanned: i64 = 0
89 var idx: i64 = 0
90 while idx < res.n_filled {
91 let row: *NxDirRow = ((rows as i64) + idx * NX_DIR_ROW_BYTES) as *NxDirRow
92 idx = idx + 1
93 if row.dtype != NX_DT_REG { continue }
94 let nm: *u8 = row.name_ptr; let nl: i64 = row.name_len
95 if nl < 4 { continue }
96 if nm[nl-3] != (46 as u8) { continue }
97 if nm[nl-2] != (110 as u8) { continue }
98 if nm[nl-1] != (120 as u8) { continue }
99 var o: i64 = 0; var k: i64 = 0
100 while dir[k] != (0 as u8) { path[o] = dir[k]; o = o + 1; k = k + 1 }
101 path[o] = 47 as u8; o = o + 1; k = 0
102 while nm[k] != (0 as u8) { path[o] = nm[k]; o = o + 1; k = k + 1 } path[o] = 0 as u8
103 scanned = scanned + 1
104 let r: i64 = fx_fix_file(path, buf, out)
105 if r == 1 { fixed = fixed + 1; fx_puts(" FIXED " as *u8); fx_puts(path); fx_puts("\n" as *u8) }
106 }
107 fx_puts(" sweep " as *u8); fx_puts(dir); fx_puts(": scanned " as *u8); fx_putn(scanned); fx_puts(" .nx, FIXED " as *u8); fx_putn(fixed); fx_puts(" leaky-putn organs\n" as *u8)
108 fx_puts("NX-FIX-PUTN GREEN: re-gate/rebuild the fixed organs to verify (byte-exact, verdict-equal to the hand-fixes)\n" as *u8)
109 sys_exit(0); return 0
110 }
111
112 let r: i64 = fx_fix_file(a1, buf, out)
113 if r == 1 { fx_puts("FIXED " as *u8); fx_puts(a1); fx_puts(" (leaky-putn -> hoisted write-once)\n" as *u8); sys_exit(0); return 0 }
114 if r == 0 { fx_puts("no-match " as *u8); fx_puts(a1); fx_puts(" (no exact leaky-putn block; left untouched)\n" as *u8); sys_exit(0); return 0 }
115 fx_puts("ERROR unreadable " as *u8); fx_puts(a1); fx_puts("\n" as *u8); sys_exit(1); return 1
116}