Skip to content

fix: negate [!...] bracket expressions like [^...]#180

Open
spokodev wants to merge 1 commit into
micromatch:masterfrom
spokodev:fix-bracket-negation
Open

fix: negate [!...] bracket expressions like [^...]#180
spokodev wants to merge 1 commit into
micromatch:masterfrom
spokodev:fix-bracket-negation

Conversation

@spokodev

Copy link
Copy Markdown

A leading ! inside a bracket expression is a negation operator, equivalent to ^ (POSIX 2.13.1, Bash 4.3). picomatch honors [^...] but leaves [!...] un-negated, treating ! as a literal class member:

picomatch.isMatch("a", "[!a]")    // true,  expected false
picomatch.isMatch("b", "[!a]")    // false, expected true
picomatch.isMatch("d", "[!a-c]")  // false, expected true

Bash and minimatch both negate here. The !^ conversion in lib/parse.js was gated behind opts.posix === true, but single-! negation is core glob syntax (the posix option is documented for named classes like [:alpha:]), and [^...] already works without the flag.

Removing the gate makes [!a] compile to the same negated class as [^a]. The prev.value === "[" guard keeps a non-leading ! literal ([a!] is unchanged). Full suite stays at 1975 passing with no regressions; added bracket-negation tests.

A leading `!` inside a bracket expression is a negation operator,
equivalent to `^` (POSIX 2.13.1, Bash). picomatch honored `[^...]` but
left `[!...]` un-negated, treating `!` as a literal class member:

    picomatch.isMatch('a', '[!a]')   // true,  expected false
    picomatch.isMatch('b', '[!a]')   // false, expected true

The `!`→`^` conversion was gated behind `opts.posix`, but basic
single-`!` negation is core glob syntax and `[^...]` already works
without the flag. Removing the gate makes `[!a]` compile to the same
negated class as `[^a]`. A `!` that is not the first bracket character
stays literal (`[a!]`).
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.

1 participant