fix(kb): check_okf.py flags control bytes (NUL etc.) outside \t\n\r

The validator only ever parsed frontmatter fields — it never scanned body
content, so a file with literal NUL bytes pasted in from a psql SELECT
(kb/audits/wiki-kompilat-recon-2026-08-26.md) passed silently. Adds a
whole-file scan for control bytes other than tab/newline/CR, one error per
offending line. Covered by scripts/kb/tests/test_check_okf.py.
This commit is contained in:
oskar 2026-08-27 15:51:39 +02:00
parent a0a86140c1
commit 8af8c2eeab
2 changed files with 76 additions and 0 deletions

View file

@ -18,6 +18,8 @@ reguły tego repo:
10. Wpisy `contradicts` wyglądające jak ścieżka .md też muszą istnieć;
pozostałe wpisy to wolny tekst.
11. `stub` o ile obecne musi być boolem.
12. Brak bajtów kontrolnych poza \t \n \r w całym pliku (łapie wklejki NUL/inne
binarne śmieci wklejone z zewnętrznych źródeł, np. wyników SELECT-ów).
Zakres domyślny: kb/ oraz docs/sessions/, z wyłączeniem README-wskaźników
(POINTER_GLOBS) te nawigacją do kb-doca, nie dokumentami KB, i celowo nie
@ -71,6 +73,7 @@ POINTER_GLOBS = (
EXCLUDE_DIRS = ("build",)
DATE_RE = re.compile(r"^\d{4}-\d{2}-\d{2}$")
CONTROL_CHAR_RE = re.compile(r"[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]")
def is_pointer(rel: str) -> bool:
@ -232,6 +235,17 @@ def check_file(path: Path, root: Path) -> list[str]:
f"{rel}: `contradicts` wskazuje na nieistniejący plik: {item}"
)
seen_lines: set[int] = set()
for m in CONTROL_CHAR_RE.finditer(text):
line_no = text.count("\n", 0, m.start()) + 1
if line_no in seen_lines:
continue
seen_lines.add(line_no)
errors.append(
f"{rel}: bajt kontrolny {ord(m.group()):#04x} w linii {line_no} "
"(dozwolone tylko \\t \\n \\r)"
)
return errors

View file

@ -0,0 +1,62 @@
"""Tests for check_okf.py — the OKF v0.1 frontmatter validator.
Covers the control-character check added 2026-08-27: a file that otherwise has
valid frontmatter must still fail if its body contains a NUL byte or other
control byte outside \\t \\n \\r (the class of bug found in
kb/audits/wiki-kompilat-recon-2026-08-26.md raw bytes pasted in from a psql
SELECT over the mail corpus).
"""
from __future__ import annotations
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
import check_okf # noqa: E402
VALID_FRONTMATTER = """---
okf: "0.1"
type: decision
visibility: private
status: active
updated: 2026-08-27
links: []
---
"""
def _write(tmp_path: Path, body: str) -> Path:
p = tmp_path / "doc.md"
p.write_text(VALID_FRONTMATTER + body, encoding="utf-8")
return p
def test_clean_file_has_no_control_char_errors(tmp_path):
path = _write(tmp_path, "# Title\n\nZwykła treść z \t tabulatorem i \r\n końcem linii.\n")
errors = check_okf.check_file(path, tmp_path)
assert errors == []
def test_nul_byte_in_body_is_flagged(tmp_path):
path = _write(tmp_path, "# Title\n\nZawiera bajt NUL: \x00 w tym miejscu.\n")
errors = check_okf.check_file(path, tmp_path)
assert any("bajt kontrolny" in e and "0x0" in e for e in errors)
def test_control_char_error_reports_correct_line(tmp_path):
body = "linia 1\nlinia 2\nzepsuta \x00 linia 3\nlinia 4\n"
path = _write(tmp_path, body)
errors = check_okf.check_file(path, tmp_path)
control_errors = [e for e in errors if "bajt kontrolny" in e]
assert len(control_errors) == 1
# Frontmatter occupies 7 lines before the body starts.
frontmatter_lines = VALID_FRONTMATTER.count("\n")
expected_line = frontmatter_lines + 3
assert f"w linii {expected_line}" in control_errors[0]
def test_multiple_control_chars_same_line_reported_once(tmp_path):
path = _write(tmp_path, "para \x00 z dwoma \x00 bajtami na tej samej linii\n")
errors = check_okf.check_file(path, tmp_path)
control_errors = [e for e in errors if "bajt kontrolny" in e]
assert len(control_errors) == 1