fix(tools): stop _strategy_exact emitting overlapping matches (#56211)

_strategy_exact advanced its scan cursor by pos+1 instead of
pos+len(pattern), so self-overlapping patterns (e.g. "aa" in "aaaa")
matched at overlapping offsets. _apply_replacements works in reverse
order, so the second replacement operated on already-modified content
using stale offsets — corrupting the file and reporting the wrong count
under replace_all=True. Advancing by len(pattern) matches str.replace()
semantics.
This commit is contained in:
Teknium 2026-07-01 02:13:13 -07:00 committed by GitHub
parent ea533e7f41
commit d57a4c197c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 1 deletions

View file

@ -349,7 +349,12 @@ def _strategy_exact(content: str, pattern: str) -> List[Tuple[int, int]]:
if pos == -1:
break
matches.append((pos, pos + len(pattern)))
start = pos + 1
# Advance past the whole match, not just one char, so self-overlapping
# patterns (e.g. "aa" in "aaaa") produce non-overlapping spans matching
# str.replace() semantics. Advancing by 1 yielded overlapping matches
# that corrupt the file under replace_all=True (reverse-order apply on
# stale offsets).
start = pos + len(pattern)
return matches