★★ 收 pi 两处**实测打出的我自己的缺陷**: ① 探针标记与判据自身源码**碰撞** ⇒ 假红(改用**运行时 nonce**)② 调用者谓词**过宽**(子串出现 ≠ 指向本库)⇒ 假红(谓词收紧 + 尾锚)
★★ (A) pi `551d7d85`: 固定标记 `__AM_P_TAIL__` 与**判据文件自身内容**碰撞 ⇒ 假红
根因: 该字面量**就在本判据源码里**(:374 探针串、:379 grep 那行),
所以当**本判据自己被当数据读**(域偏宽/自指)时,`grep -F … | head -1`
匹配到的是**源码里那行**,而不是文件末尾之后的真尾探针
我复现(自指场景): head=1、tail=375、内容行数=536、应为 538 ⇒ 差 163
(pi 报 162 @ 它的 HEAD,逐位吻合同一机制)
⇒ 修法: **运行时 nonce**(`_am_nonce="AM${RANDOM}${RANDOM}${$}Z"`)——
该记号**不可能**预先出现在任何静态文件里 ⇒ 碰撞**不可表示**
★ 比"再加几个下划线""改成 tail -1"更根本: 前两者只是让碰撞**更难**,nonce 让它**不可能**
★ 实测: 自指场景不再报"探针失败",改为正确报出**真违规**(:293/:401 那两处探针字面量本身)
★ (B) pi `ae164e2e`: 谓词 `.*env-defaults\.sh` 只要求**子串出现** ⇒
`. /tmp/not-our-lib/env-defaults.sh.other` ⇒ rc=**1** 并报其裸赋值,而它**没 source 本库** ⇒ **假红**
⇒ 修法(pi 的诊断对: **域的宽度该用谓词精度管,不该用阈值管** ——
空集/下界守卫都只兜"域偏小"这一方向,加上界阈值只是把**精确性**问题换成**调参**问题):
谓词改成"source 的**参数末尾**必须是 `…/lib/env-defaults.sh`":
`[^[:alnum:]_.-]lib/env-defaults\.sh["']?[[:space:]]*$`
★ 前半排除 `not-our-lib/…`(`-lib` 前是 `-`);**尾锚**排除 `env-defaults.sh.other`(更长的名字)
★ 实测: 本仓 3 个真实调用者全认出;pi 的假红例与 5 个别式反例全拒
⚠️ 射程: 行内文本判法,不解析变量取值 ⇒ `. "$SOMEDIR/lib/env-defaults.sh"` 而 $SOMEDIR
指向别处时仍算调用者(**偏宽**、方向安全: 多查一个文件而非漏查)
★★ (C) 反向对照里**补上 pi 的假红样本**(`/tmp/not-our-lib/env-defaults.sh.other`)——
它正是 (B) 那条回归的守卫;实测把谓词回退成过宽版 ⇒ 反向对照**打红**(rc=1)
★ 回归: 基线 rc=0;pi① rc=1 / pi② rc=0 / pi 假红例 rc=0 / 真调用者 rc=1;
12 向变异矩阵全 rc=1;criteria-hygiene 10/10;--git-hooks 负对照(PATH 无 git / pre-push 不可执行) rc=1 未破
This commit is contained in:
@ -150,12 +150,30 @@ _strip_comments_lex() {
|
||||
_is_caller_text() {
|
||||
local t
|
||||
t="$(printf '%s\n' "$1" | _strip_comments_lex /dev/stdin)"
|
||||
case "$t" in
|
||||
*env-defaults.sh*)
|
||||
grep -qE '^[[:space:]]*(\.|source)[[:space:]].*env-defaults\.sh' <<< "$t"
|
||||
;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
# ★★★ 谓词从"**行内出现子串**"收紧为"**指向本库**"(pi `ae164e2e` 实测打出的**假红**,我复现):
|
||||
# 旧谓词 `.*env-defaults\.sh` 只要求**子串出现** ⇒
|
||||
# `. /tmp/not-our-lib/env-defaults.sh.other` ⇒ rc=**1** 并报该文件裸赋值
|
||||
# 而该文件**没有 source 本库** ⇒ **假红**(域偏宽)。
|
||||
# ★ pi 的诊断对: **域的宽度该用谓词精度管,不该用阈值管** ——
|
||||
# 空集守卫 / 下界守卫**都只兜"域偏小/空"**这个方向,加"上界阈值"只会把
|
||||
# 一个**精确性**问题换成一个**调参**问题(阈值调多少都是猜)。
|
||||
# ⇒ 收紧后的谓词: source 的**参数末尾**必须是 `…/lib/env-defaults.sh`(可带引号/空白),
|
||||
# 即"**这一行指向的就是本库那个文件**",而不是"这一行里出现过这个字符串"。
|
||||
# ① `[^[:alnum:]_.-]lib/env-defaults\.sh` ⇒ 前面必须是**路径分隔符或词边界**,
|
||||
# 排除 `not-our-lib/env-defaults.sh`(`-lib` 前面是 `-`)这类同后缀异文件
|
||||
# ② `["']?[[:space:]]*$` ⇒ **尾锚** ⇒ 排除 `env-defaults.sh.other` 这类**更长**的名字
|
||||
# ★ 实测(本仓 3 个真实调用者 + 6 个反例):
|
||||
# `. "$REPO/deploy/lib/env-defaults.sh"` ⇒ 调用者 ✓
|
||||
# `. "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib/…"` ⇒ 调用者 ✓(两处真实形态)
|
||||
# `. "${REPO#/home}/deploy/lib/env-defaults.sh"` ⇒ 调用者 ✓
|
||||
# `. "$A #B/deploy/lib/env-defaults.sh"` ⇒ 调用者 ✓
|
||||
# `. /tmp/not-our-lib/env-defaults.sh.other` ⇒ 不算 ✓(pi 的假红例)
|
||||
# `. /tmp/not-our-lib/env-defaults.sh` ⇒ 不算 ✓
|
||||
# `. /tmp/x/lib/env-defaults.sh.other` ⇒ 不算 ✓
|
||||
# ⚠️ 射程: 这是**行内文本**的判法,不解析变量实际取值 ——
|
||||
# 若有人写 `. "$SOMEDIR/lib/env-defaults.sh"` 而 `$SOMEDIR` 指向别处,
|
||||
# 本判据仍算它"调用者"(**偏宽**、方向安全,会多查一个文件而不是漏查)。
|
||||
grep -qE '^[[:space:]]*(\.|source)[[:space:]].*[^[:alnum:]_.-]lib/env-defaults\.sh["'"'"']?[[:space:]]*$' <<< "$t"
|
||||
}
|
||||
|
||||
# ① 找"调用者":非注释行里以 `. ` 或 `source ` 起头、且提到 env-defaults.sh 的文件。
|
||||
@ -301,6 +319,8 @@ AGENTMAIL_REQUIRE="git go"' || true)"
|
||||
_pc_bad=""
|
||||
_is_caller_text '. /dev/null;# 提到 env-defaults.sh' && _pc_bad="分号后的注释(该截没截)"
|
||||
_is_caller_text '# . env-defaults.sh' && _pc_bad="${_pc_bad}整行注释"
|
||||
# ★ pi `ae164e2e` 打出的**假红**(谓词过宽: 子串出现 ≠ 指向本库)—— 这条必须在反向对照里:
|
||||
_is_caller_text '. /tmp/not-our-lib/env-defaults.sh.other' && _pc_bad="${_pc_bad}同名后缀的**别的**文件"
|
||||
if [ -n "$_pc_bad" ]; then
|
||||
printf ' [FAIL] 判据自检失败(调用者判定,反向):**非调用者样本**被判成了调用者(%s)——\n' "$_pc_bad" >&2
|
||||
printf ' ⇒ 域会**偏大**,与该库无关的文件被拖进来报红(假红)。按红计。\n' >&2
|
||||
@ -369,14 +389,23 @@ agentmail_require git go' || true)"
|
||||
# `sed 135d` ⇒ `t=801` ≠ 802 ⇒ 抓到;`head/tail -N` ⇒ 缺探针 ⇒ 抓到;
|
||||
# `tac` ⇒ `h=802 t=1`(顺序反)⇒ 抓到;`grep -v '^$'` / `sort -u` ⇒ `t` 偏离 ⇒ 抓到。
|
||||
# ★ 三个条件合起来 = "**这个过滤器是逐行原位的**"(保行数、保顺序、保两端)。
|
||||
_probe_in="AGENTMAIL_REQUIRE=\"__AM_P_HEAD__\"
|
||||
# ★★★ 但**固定标记**本身有个洞(pi `551d7d85` 实测打出的**假红**,我复现):
|
||||
# 标记 `__AM_P_TAIL__` 是**字面量**,而它**出现在本判据自己的源码里**(:374/:379 两处)。
|
||||
# 于是当**本判据文件自己被当成数据读**(域偏宽 / 自指)时,`grep -F … | head -1`
|
||||
# 匹配到的是**源码里那行**,不是文件末尾之后的真尾探针 ⇒ 行号算术失败 ⇒ **假红**。
|
||||
# ★ 这不是"域偏宽"的问题被误报 —— 是**探针的记号与数据不可分辨**。
|
||||
# ⇒ 修法: 用**运行时 nonce**(`$RANDOM` + pid)代替固定字面量 ⇒
|
||||
# 该记号**不可能**预先出现在任何静态文件里 ⇒ 碰撞**不可表示**(比"再多加几个下划线"根本)。
|
||||
# ⚠️ 射程: 这消掉"记号与数据碰撞"这一类;**不**改变"域偏宽"本身是否该红(那是谓词的事,见 `_is_caller_text`)。
|
||||
_am_nonce="AM${RANDOM}${RANDOM}${$}Z"
|
||||
_probe_in="AGENTMAIL_REQUIRE=\"${_am_nonce}HEAD\"
|
||||
$(cat "$f")
|
||||
AGENTMAIL_REQUIRE=\"__AM_P_TAIL__\""
|
||||
AGENTMAIL_REQUIRE=\"${_am_nonce}TAIL\""
|
||||
# 内容行数与探针**同一条读取路径**(都经 `printf '%s\n'` 补回被命令替换吃掉的尾换行)
|
||||
_probe_n="$(printf '%s\n' "$(cat "$f")" | awk 'END{print NR}')"
|
||||
_probe_out="$(_scan_stripped "$(strip_text "$_probe_in")" || true)"
|
||||
_ph="$(grep -F '__AM_P_HEAD__' <<< "$_probe_out" | head -1 | cut -d: -f1)"
|
||||
_pt="$(grep -F '__AM_P_TAIL__' <<< "$_probe_out" | head -1 | cut -d: -f1)"
|
||||
_ph="$(grep -F "${_am_nonce}HEAD" <<< "$_probe_out" | head -1 | cut -d: -f1)"
|
||||
_pt="$(grep -F "${_am_nonce}TAIL" <<< "$_probe_out" | head -1 | cut -d: -f1)"
|
||||
_pexp=$(( ${_ph:-0} + _probe_n + 1 ))
|
||||
if [ -z "$_ph" ] || [ -z "$_pt" ] || [ "$_ph" -ge "$_pt" ] || [ "$_pt" -ne "$_pexp" ]; then
|
||||
printf ' [FAIL] %s 逐文件探针失败:读入这一环**不是逐行原位**的 —— 它在丢弃或重排内容。\n' "$f" >&2
|
||||
@ -389,7 +418,7 @@ AGENTMAIL_REQUIRE=\"__AM_P_TAIL__\""
|
||||
printf ' ⇒ 按红计(绝不能因为两条通道都不说话就当成"没问题")。\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
unset _probe_in _probe_out _probe_n _ph _pt _pexp
|
||||
unset _probe_in _probe_out _probe_n _ph _pt _pexp _am_nonce
|
||||
# ★★★ 逐行局部不变量(2026-09-25 **pi 提的非循环补法**,我实测后采纳):
|
||||
# 上一节的首尾探针只锁"**行数 / 顺序 / 两端**"(**形状**),锁不住"**某一行内容被抹**"。
|
||||
# pi 的补法: 对**每一行**要求
|
||||
|
||||
Reference in New Issue
Block a user