What happens
Fuzzy.Contains/CalculateScore (FuzzySearch/Fuzzy.cs, lines 46-69 and 99-200) compare subject and pattern purely per UTF-16 char, with no Unicode normalization. A precomposed character (e.g. é, U+00E9) and its canonically-equivalent decomposed form (e + combining acute accent, U+0301) are visually and semantically identical text, but are different code-unit sequences, so they're treated as a non-match.
Reproduction
Fuzzy.Contains("café", "café"); // → true (precomposed vs precomposed)
Fuzzy.Contains("café", "café"); // → false (decomposed vs precomposed — same visible text!)
Why it matters
Decomposed (NFD) text is common in real input — e.g. filenames read from HFS+/APFS-backed filesystems, or text pasted from certain sources, are frequently NFD-normalized. Any consumer using FuzzySearch to match against such filenames or text will silently miss matches for accented/composed characters despite the visible text being identical to the search term.
Suggested fix
Normalize both spans to a common form (e.g. string.Normalize(NormalizationForm.FormC)) before comparing, or explicitly document this as a known limitation if avoiding the extra allocation on the hot path is a priority.
Acceptance criteria
Fuzzy.Contains (and the scoring overload) treat canonically-equivalent NFC/NFD forms of the same text as matching.
- Add a test covering an NFD-decomposed subject or pattern against its NFC-precomposed counterpart.
What happens
Fuzzy.Contains/CalculateScore(FuzzySearch/Fuzzy.cs, lines 46-69 and 99-200) compare subject and pattern purely per UTF-16char, with no Unicode normalization. A precomposed character (e.g.é, U+00E9) and its canonically-equivalent decomposed form (e+ combining acute accent, U+0301) are visually and semantically identical text, but are different code-unit sequences, so they're treated as a non-match.Reproduction
Why it matters
Decomposed (NFD) text is common in real input — e.g. filenames read from HFS+/APFS-backed filesystems, or text pasted from certain sources, are frequently NFD-normalized. Any consumer using
FuzzySearchto match against such filenames or text will silently miss matches for accented/composed characters despite the visible text being identical to the search term.Suggested fix
Normalize both spans to a common form (e.g.
string.Normalize(NormalizationForm.FormC)) before comparing, or explicitly document this as a known limitation if avoiding the extra allocation on the hot path is a priority.Acceptance criteria
Fuzzy.Contains(and the scoring overload) treat canonically-equivalent NFC/NFD forms of the same text as matching.