You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Regex with inline (?i) folds case by the current culture, and the first caller's culture is cached for everyone: "(?i)img" stops matching "IMG_1234.JPG" after a tr-TR caller #120
Commit 65c8554 ("Fold case invariantly in regex matching") added RegexOptions.CultureInvariant, but only when the caller passes TextFilterCaseSensitivity.CaseInsensitive (TextFilter/TextFilter.cs, ~line 462):
Users can also turn ignore-case on inside the pattern with (?i), which is ordinary regex syntax. On that path the regex is compiled with RegexOptions.Compiled alone, so it folds case using the thread's CurrentCulture at construction time. The compiled regex is then cached under a key made only of pattern and case sensitivity (for example "s:(?i)img"). This is the cache-poisoning problem the comment above that line describes, which the fix left open on this path.
== tr-TR first
tr-TR: False
en-US: False <- poisoned by the cache
== en-US first
en-US: True
tr-TR: True
The same query with pattern img and the explicit CaseInsensitive option returns True under tr-TR.
The result is that the same filter, in the same app, gives different answers depending on which thread's culture compiled it first. That is a nondeterministic filter bug which is hard to diagnose.
Suggested fix
Always include CultureInvariant. It only has an effect when ignore-case is on, whether set by the option or inline, so case-sensitive matching is unchanged:
Priority: Medium. It needs a non-invariant culture that folds i differently (tr-TR or az) and an inline (?i). When those line up, the process-wide cache makes the result depend on which thread compiled the pattern first, which is hard to diagnose.
Area / suggested assignee: the regex options and cache in TextFilter/TextFilter.cs (~line 462). This is a gap left by 65c8554. Owner: @matt-edmondson
Next step: always include RegexOptions.CultureInvariant, since it is a no-op when case-sensitive. Add the tr-TR-first test modelled on ARegexCompiledUnderOneCultureAnswersTheSameUnderAnother.
Activity
matt-edmondson commentedon Sep 27, 2026
Triage
idifferently (tr-TR or az) and an inline(?i). When those line up, the process-wide cache makes the result depend on which thread compiled the pattern first, which is hard to diagnose.TextFilter/TextFilter.cs(~line 462). This is a gap left by 65c8554. Owner: @matt-edmondsonRegexOptions.CultureInvariant, since it is a no-op when case-sensitive. Add the tr-TR-first test modelled onARegexCompiledUnderOneCultureAnswersTheSameUnderAnother.Generated by Claude Code
Fold an inline (?i) culture-invariantly too [patch]