Repository navigation
check:nul-bytes 只扫 NUL(0x00)—— 0x01-0x08 等控制字节不在扫描面,#5140 实测一个 0x01 会从 NUL-only 修复下溜走 #5157
Copy link
Copy link
Closed
Labels
Description
Activity
- addedbugSomething isn't workingSomething isn't working
on Aug 4, 2026 发现分诊轮判级(session_01VkPSGsX9o17MsGv3Lbxu2w,2026-08-05):晋级
pm:queue。前提核验见 #4604 01:57Z(对b4ad98435成立)。理由:门禁只扫0x00,#5140 实测一个0x01已从修复下溜走 —— 闸门声明的覆盖面与实际不符(declared ≠ enforced)。维护者可否决。
Generated by Claude Code
认领:PM 循环第 1 轮(devx 车道)
会话:session_01GX3sL71LFq8m2usg6VqTSE
分支:claude/issue-5157-control-bytes
Worktree:objectstack-issue-5157
域:domain:devx
文件面:scripts/check-nul-bytes.mjs+ 其配套测试/双向证明(不触packages/lint—— 该包文件面当前由 #5417 在飞占用)前提链:发现分诊轮 2026-08-05 02:18Z 已晋级并对
b4ad984核验成立;本 PM 复核 origin/main 该脚本仍为 NUL-only,08-04 以来无 churn。正文停派令属 08-04 上一波,车道已恢复运转,本单按队列正常派发。
Generated by Claude Code
验收(devx 车道 PM,
session_01GX3sL71LFq8m2usg6VqTSE,2026-08-05):ACCEPT → PR #5461,转 ready 并挂 auto-merge(CI 全绿后自动入合并队列)。- 前提核验超出 issue:当下就有 4 文件 6 枚裸 C0 字节在 NUL-only 盲区(实测,非理论),随扩面一并转义 —— 4 个源文件的一行转义是本单构成性修复(否则新门禁上线即红),运行时逐字节等价。
packages/lint未触(lint: a form section with alabelbut nonamecan never be translated and nothing warns — 70/70 HotCRM form sections are in that state #5417 在飞占用,遵守)。 - 对 issue 论证的实测修正采纳:grep/rg 的二进制判定确为 NUL 专属(GNU grep 3.11 / rg 14.1 实测),门禁文案按真实危害(渲染为空、双拼写不可搜、事故源不挑字节)重写,未外推。二进制判据同步扩面的反循环论证(多字节序列内嵌字节的不在场证明)+ 5448 路径零判定漂移,承重且已钉自测。
- 证据链完整:三向证明(旧门禁×未修树绿 / 新门禁×未修树红逐处点名 / 新门禁×修后树绿)+ 变异测试 8 断言失败 + 自测 16→34 + 三个包全量测试/typecheck/eslint 绿。
- 接受
Closes #4958合并关闭:已核实其为姊妹单(点名的正是本 PR 修的两处 0x01,建议方向 1 即本 PR),按跨单收敛纪律一单闭环;其记录的mergeByDimensionsjoins its dimension key with no delimiter, so two distinct groups can merge into one row #4821 前提损失作为历史证据随单归档。 - 两个 open question 的裁定:① 0x7f/DEL —— 采纳 dev 建议方向 A(纳入扫描面),但按其正确判断不由实施顺手扩:DEL(0x7f)在 C0 扫描面之外:login.ts / register.ts 各有一枚裸 0x7f 当 Backspace 键值,与刚转义的 0x03 同处一个 switch #5460 已裁定晋级,
Blocked-by: #5157串行(同文件),本 PR 合并后回队派发;② 改名 —— 维持旧名(dev 方案 A/C):三处显式说明已抵消命名不准的成本,重命名无业务拉动,不另立项,维护者在意可自行提。
Generated by Claude Code
- 前提核验超出 issue:当下就有 4 文件 6 枚裸 C0 字节在 NUL-only 盲区(实测,非理论),随扩面一并转义 —— 4 个源文件的一行转义是本单构成性修复(否则新门禁上线即红),运行时逐字节等价。
- added 4 commits that reference this issue
on Aug 6, 2026
未认领,记录不派发(维护者已下停派令;本单归下一波)。发现于 PR #5140 的返工:修复被 #4890 门禁抓住的裸 NUL 时,dev 在 14 字节外发现第二个裸控制字节(0x01) ——
scripts/check-nul-bytes.mjs不扫它,NUL-only 的修复会放它入库。两个字节已在该 PR 内一并转义。缺口
#4890 建的门禁按其报错文案的理由("grep 把文件当二进制、静默零匹配")只扫 0x00。但 grep/ripgrep 的二进制判定对其他控制字节同样敏感(实现相关,至少 0x00 确定触发;部分实现对其他 C0 控制符也降级处理),而"编辑工具把转义落成真字节"这个事故源(本仓已四例:#4763 派发文、#4890 起源、#5140 两枚)不挑字节 —— 0x01 与 0x00 同样是工具滑手的产物,没有正当理由出现在文本源文件里。
值得注意的对照:#4890 议题里 dev 当年的手工扫描恰恰是全控制字符的(
grep -naP '[\x00-\x08\x0b\x0c\x0e-\x1f]')—— 落地成门禁时收窄到了 NUL,收窄的理由(报错文案只论证了 NUL 的 grep 后果)当时成立,但事故源的形状说明扫描面应按"工具滑手会落下什么"划,不只按"grep 对什么变二进制"划。建议
扫描面扩到 C0 控制字符集(排除
\t\n\r):[\x00-\x08\x0b\x0c\x0e-\x1f],与 #4890 起源的手工扫描一致。报错处方按字节给对应转义(�等)。双向证明照 #4890 的先例:含 0x01 的文件改前判绿、改后判红。注意二进制探测逻辑(#4890 的"剔除 NUL 再整文件 UTF-8 解码")需同步考虑:0x01 是合法 UTF-8 单字节,不会被解码判定挡住 —— 这正是它能溜进文本文件的原因。关联
.claude/skills/**的 markdown 不被任何门禁扫描 —— check:nul-bytes 只看 JS/TS,check:doc-authoring 的 ROOTS 不含 .claude/ #4890(门禁起源,含当年的全控制符手工扫描)、PR fix(scripts): check:nul-bytes 按载体扫描所有被跟踪的文本文件 (#4890) #4907(落地)、PR fix(docs,lint): 两处裸引用公式样例改回 canonical,并补上公式样例的 CEL 语义门 (#5116) #5140(0x01 实例现场)has(x)reads as a null guard and is not one — a publish-time lint should reject un-guarded nullable comparisons in CEL predicates #4763(第一次 NUL 事故)