Skip to content

Combining-character (NFD) text never matches its precomposed (NFC) equivalent #70

Description

@matt-edmondson

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions