Skip to content

Let glob * and ? match across / and \ [patch] - #119

Merged
matt-edmondson merged 2 commits into
mainfrom
fix/glob-wildcards-cross-separators
Sep 28, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
fix/glob-wildcards-cross-separators

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #114

What changed

ResolveGlob compiles tokens with DotNet.Glob. DotNet.Glob matches file paths, so * and ? stop at / and \. As a result, no wildcard could match any item that contained a slash or backslash. For example, *readme* dropped docs/readme.md.

This PR takes the issue's second suggested fix. Both separators are replaced with a private-use character (U+E000) in the filter token before Glob.Parse, and in each text token before IsMatch. To DotNet.Glob they are then ordinary characters. The replacement happens in the same place for the pattern and the text, so a literal / in a pattern still matches only a / (or \) in the text. The glob cache, the case-insensitive options and the half-typed-range handling are unchanged.

I chose this over replacing DotNet.Glob with a hand-written glob-to-regex translation because it is much smaller. It changes only the three IsMatch call sites and ResolveGlob. It also leaves the lines touched by #116 and #117 alone, so the three PRs can merge in any order. If you want the regex translation later, it can replace this one.

Tests

The five repro tests from the issue are added. There are three more:

  • a case-insensitive match across a slash
  • an excluded token matching across a slash
  • a guard that a literal / in a pattern still requires a separator in the text

With the change reverted, 7 of the new tests fail; the literal-slash guard passes either way. With the change, the full suite passes: 114 tests, 0 failed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VKxYoUXQqgRKJR6ynbvnms


Generated by Claude Code

DotNet.Glob is a file-path glob, so its wildcards stopped at path
separators and any item containing a slash or backslash could not be
matched: "*readme*" dropped "docs/readme.md". Both separators are now
swapped for a private-use character in the pattern and the text before
DotNet.Glob sees them, so they are ordinary characters.

Fixes #114

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VKxYoUXQqgRKJR6ynbvnms
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013xQ2dceFuWS8VLEn2xLuZE
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 79453d3 into main Sep 28, 2026
12 checks passed
@matt-edmondson
matt-edmondson deleted the fix/glob-wildcards-cross-separators branch September 28, 2026 01:33
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.

Glob * and ? never match across / or \, so any item containing a slash is filtered out

2 participants