mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-26 21:36:06 -04:00
05f6293067
FOUND BY ACCIDENT, WHICH IS THE POINT. `grep -rn func_8013C08C src/` returned NOTHING for a function that is defined right there. The file held a RAW NUL byte inside a character literal — the source read `== '<NUL>'` where it should read `== '\0'`. It COMPILES (the fleet was byte-identical), so no byte-gate ever objected. But file(1) classifies such a file as `data`, and **grep treats a file containing NUL as BINARY and reports nothing, silently**. The whole file therefore vanished from every grep-based audit and every hand search. I burned real time chasing a phantom missing function before `file` gave it away. SCOPE, measured: 137 files — every `_o0c`/`_o0e` region created in THIS session. The templated bodies carried the NUL fleet-wide, so I propagated the defect today. All fixed (`'<NUL>'` -> `'\0'`); R22 CLEAN-FLEET 140 passed, 0 failed of 140 => byte-neutral. NEW ORACLE: tools/audit_text_sources.py + `make audit-text-sources`, wired into tools-health, coverage-asserting over all 3,887 tracked .c/.h files (R32). This is the SAME silent-skip family as SS124 (a scanner that cannot see something reports it is not there) and SS126a (a bare except swallowing a coverage assertion) — but one layer LOWER, in the tool everyone reaches for first. The byte-gate is structurally blind to it (R34): the bytes are correct, so it has nothing to say. It needs its own oracle. MY OWN ERROR, RECORDED: proving the new guard fires, I injected a NUL into the REAL tracked file and restored it through nested shell escaping. The restore left `'\\0'` — an escaped backslash, i.e. a multi-character constant, NOT a NUL — a genuine semantic change. R22 caught it (139/140) in one cycle, before any commit; repaired to `'\0'` (10465 -> 10466 bytes) and re-verified 140/140. The lesson is not "be careful": a negative control must corrupt a SCRATCH COPY under .run/, never the tracked file it is testing. Testing a guard must not risk introducing the defect the guard exists to catch.
68 lines
3.0 KiB
Python
68 lines
3.0 KiB
Python
#!/usr/bin/env python3
|
|
"""audit_text_sources.py — every tracked C source must be TEXT, or grep silently skips it.
|
|
|
|
WHY THIS EXISTS (P30 SESSION-28, found the hard way). `src/ov_SC01_077/ov_SC01_077_o0.c` carried a
|
|
RAW NUL byte inside a character literal — the source read `== '<NUL>'` where it should have read
|
|
`== '\\0'`. It compiled fine (the fleet was byte-identical), so no byte-gate ever objected. But
|
|
`file(1)` classified it as `data`, and **grep treats a file containing NUL as BINARY and reports
|
|
nothing** — silently. So:
|
|
|
|
* `grep -rn func_8013C08C src/` found NOTHING, for a function that is defined right there;
|
|
* every grep-based audit or hand-search over `src/` skipped the whole file, invisibly;
|
|
* an investigation into "why does this family not propagate" burned real time chasing a
|
|
phantom missing function before `file` gave it away.
|
|
|
|
That is the SAME silent-skip class as §124 (a scanner that cannot see something reports it is not
|
|
there) — one level lower, in the tooling everyone reaches for first. The byte-gate is structurally
|
|
blind to it (R34): the bytes are correct, so it has nothing to say. It needs its own oracle.
|
|
|
|
R32: this asserts COVERAGE (every candidate file was classified) and fails on the gap, rather than
|
|
scanning until it happens to find something.
|
|
"""
|
|
import os
|
|
import sys
|
|
|
|
REPO = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
ROOTS = ("src", "include")
|
|
EXTS = (".c", ".h")
|
|
|
|
|
|
def offenders():
|
|
"""[(path, reason)] for every tracked-source file grep would treat as binary."""
|
|
bad, seen = [], 0
|
|
for root in ROOTS:
|
|
for dirpath, _dirs, files in os.walk(os.path.join(REPO, root)):
|
|
for f in files:
|
|
if not f.endswith(EXTS):
|
|
continue
|
|
seen += 1
|
|
p = os.path.join(dirpath, f)
|
|
data = open(p, "rb").read()
|
|
n = data.count(b"\x00")
|
|
if n:
|
|
rel = os.path.relpath(p, REPO)
|
|
i = data.find(b"\x00")
|
|
line = data[:i].count(b"\n") + 1
|
|
bad.append((rel, f"{n} NUL byte(s), first at line {line}"))
|
|
return bad, seen
|
|
|
|
|
|
def main():
|
|
bad, seen = offenders()
|
|
print(f"audit-text-sources: scanned {seen} tracked {'/'.join(EXTS)} file(s) under {'/'.join(ROOTS)}")
|
|
if not bad:
|
|
print("audit-text-sources: OK — every source is TEXT (grep can see all of them).")
|
|
return 0
|
|
print(f"audit-text-sources: {len(bad)} FILE(S) GREP WOULD SILENTLY SKIP:")
|
|
for rel, why in bad:
|
|
print(f" {rel}: {why}")
|
|
print("\nA NUL in C source is almost always a raw control character written into a char "
|
|
"literal (`'<NUL>'` instead of `'\\0'`). It COMPILES, so no byte-gate objects — but the "
|
|
"file becomes invisible to grep and to every grep-based audit. Fix the literal, then "
|
|
"re-gate the affected binary to prove the change is byte-neutral.")
|
|
return 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|