fix(state-line-guard): Edit path used String.replace, not a function
current.replace(oldStr, newStr) with newStr as a STRING lets JS treat $-sequences inside it ($&, $`, $', $$, $n) as special replacement patterns, even though oldStr (the search side) is a plain string. A new_string documenting old backtick-substitution style ($`cmd`) - the kind of prose a STATE.md shell-conventions section writes routinely - triggers it. Measured against the real bug (.claude/STATE.md, 2026-08-15): a 5-line addition on a 112-line file projected to 219 lines and was wrongly denied. Fix: current.replace(oldStr, () => newStr) - a function replacement is never pattern-substituted, covering every $-sequence at once. The replace_all branch (split/join) was never affected. Direction was always fail-closed (over-blocks, never under-blocks a real oversize), but it made exactly the STATE.md files that document shell conventions hard to edit via Edit. state-line-guard-selftest.sh: 23/23 (+2, section 9: $` as the repro, $& as a second sequence proving the fix is general). Also updates CLAUDE.md's pinned selftest counts (197/178/69/21 were already stale before this session's own additions; now 206/183/69/23).
This commit is contained in:
parent
bd24b8f0e7
commit
b5c860eb03
3 changed files with 104 additions and 6 deletions
|
|
@ -114,7 +114,10 @@ if (toolName === 'Write') {
|
|||
}
|
||||
projected = toolInput.replace_all
|
||||
? current.split(oldStr).join(newStr)
|
||||
: current.replace(oldStr, newStr);
|
||||
// A string replacement here would let JS interpret $-sequences inside
|
||||
// newStr ($&, $`, $', $$, $n) as special patterns instead of literal
|
||||
// text - a function replacement is never pattern-substituted.
|
||||
: current.replace(oldStr, () => newStr);
|
||||
currentLines = countLines(current);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue