Repository navigation
[Finder] Fix Glob::toRegex() producing an invalid regex for bracket expressions containing a slash - #67785
Merged
Conversation
…xpressions containing a slash
nicolas-grekas
force-pushed
the
fix/glob-bracket-slash
branch
from
November 2, 2026 06:50
ebdb277 to
c412284
Compare
Member
|
Thanks for the fix. I pushed a small rework: Treating the |
Member
|
Thank you @0xABCD01. |
This was referenced Nov 4, 2026
Merged
Merged
Merged
This was referenced Nov 6, 2026
nicolas-grekas
added a commit
that referenced
this pull request
Nov 6, 2026
…s wrong (KalimeroMK) This PR was merged into the 6.4 branch. Discussion ---------- [Finder] Fix three bracket expressions Glob::toRegex() gets wrong | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | - | License | MIT #67785 stopped `Glob::toRegex()` returning an invalid regex for a bracket expression holding a `/`. Three shapes still get it wrong. I compared every result below against PHP's own `glob()` on a directory holding the matching names. **`[:alpha:]` compiles to nothing.** PCRE reads the whole class as a POSIX one and refuses it: ```php preg_match(Glob::toRegex('[:alpha:]'), 'a'); // Warning: preg_match(): Compilation failed // bool(false) ``` A POSIX class needs the outer brackets, so `[:alpha:]` is the set of the characters `:alpha`, and `glob('[:alpha:]')` matches `:` and `a`. The `:` is escaped now, and `[[:alpha:]]` is untouched. **`[[-?]` compiles to nothing.** Its range runs backwards, which POSIX leaves undefined and PCRE rejects. `glob('[[-?]')` matches nothing, not even a file of that name, so the bracket expression becomes `(?!)` when PCRE will not take it. **`[[:alpha:]` matched the wrong thing.** `$scanEnd` records that no `]` closed the `[`, and the next `[` before that point reuses the answer. That is wrong for a `[` the scan swallowed as part of a `[:...:]`, which can still open a bracket expression of its own: `glob('[[:alpha:]')` matches `[:` and `[a`, not the literal pattern, and `glob('[[:alpha:]/]')` matches `[a/]`. The assertion in `testGlobToRegexBracketsAfterAnUnclosedOne` changes for that reason. Comparing `Glob::toRegex()` with `fnmatch()` over 12906 pattern/subject pairs leaves no pattern that fails to compile. Commits ------- 4b6d3b0 [Finder] Fix three bracket expressions Glob::toRegex() gets wrong
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Glob::bracketExpressionToRegex()returnsnullwhen a/comes before the closing], by design: the[is then meant to be a literal character, like an unclosed[. The caller did not honor that. Onnullthe[fell through to the plain-character branch and was copied into the regex unescaped; the following/marked a new segment start, so a(?=[^.])lookahead was injected into the middle of the class:As a result, every glob whose bracket expression contains a slash (
[/],[a/b],x[y/z]w, ...) madepreg_match()fail with a compilation warning and matched nothing, including throughFinder::name().This PR appends
\[' when the bracket scan returnsnull, mirroring the unclosed-bracket case one branch over. The rest of the pattern keeps being processed as ordinary glob text: a valid bracket expression later in the pattern still parses, and a*after the invalidated[` stays a wildcard. A differential run over ~146k pattern/text pairs against the previous implementation shows behavior changes only for patterns with a slash inside a bracket expression.