Skip to content

Escape regex metacharacters in over-long search patterns - #33

Merged
comigor merged 2 commits into
comigor:masterfrom
skagedal:fix-special-char-escaping
Sep 7, 2026
Merged

Escape regex metacharacters in over-long search patterns#33
comigor merged 2 commits into
comigor:masterfrom
skagedal:fix-special-char-escaping

Conversation

@skagedal

@skagedal skagedal commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

This issue was found by Claude as I was evaluating this library. I agree with the findings of the agent, and it closes an existing open issue (#23).

Claude report

SPECIAL_CHARS_REGEX escaped its own leading bracket, so the character class never opened and matched nothing. The replacement string was a JS-ism too: Dart's replaceAll does not expand $&, so even with a correct class every metacharacter would have been replaced by the literal text \$& rather than escaped.

The net effect was that no escaping happened at all. Patterns longer than maxPatternLength go down the regex path and were compiled raw, so an unbalanced (, an unterminated [ or a trailing \ threw a FormatException, and other metacharacters were quietly treated as regex syntax rather than matched literally.

Fix the character class and switch to replaceAllMapped so the match can actually be referenced. Three of the five new tests fail without this change with the FormatExceptions above; the other two pin down the literal-matching behaviour, which the old code happened to get right.

Both defects date back to the original Fuse.js port in 01e0f6a.

skagedal and others added 2 commits September 7, 2026 13:12
`SPECIAL_CHARS_REGEX` escaped its own leading bracket, so the character
class never opened and matched nothing. The replacement string was a
JS-ism too: Dart's `replaceAll` does not expand `$&`, so even with a
correct class every metacharacter would have been replaced by the
literal text `\$&` rather than escaped.

The net effect was that no escaping happened at all. Patterns longer
than `maxPatternLength` go down the regex path and were compiled raw, so
an unbalanced `(`, an unterminated `[` or a trailing `\` threw a
FormatException, and other metacharacters were quietly treated as regex
syntax rather than matched literally.

Fix the character class and switch to `replaceAllMapped` so the match
can actually be referenced. Three of the five new tests fail without
this change with the FormatExceptions above; the other two pin down the
literal-matching behaviour, which the old code happened to get right.

Both defects date back to the original Fuse.js port in 01e0f6a.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@comigor
comigor merged commit 211d3e7 into comigor:master Sep 7, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants