diff --git a/dist/commonjs/index.js b/dist/commonjs/index.js --- a/dist/commonjs/index.js +++ b/dist/commonjs/index.js @@ -446,6 +446,8 @@ class Minimatch { // **/*/ -> */**/ <== not valid because ** doesn't follow // this WOULD be allowed if ** did follow symlinks, or * didn't firstPhasePreProcess(globParts) { + // each **/.. split doubles the patterns, so stop at the brace max + const { braceExpandMax = 100_000 } = this.options; let didSomething = false; do { didSomething = false; @@ -473,7 +475,8 @@ class Minimatch { p === '..' || !p2 || p2 === '.' || - p2 === '..') { + p2 === '..' || + globParts.length >= braceExpandMax) { continue; } didSomething = true; @@ -530,6 +533,10 @@ class Minimatch { // {
/**/,
/**/

/} ->

/**/
     // ^-- not valid because ** doens't follow symlinks
     secondPhasePreProcess(globParts) {
+        // each pattern is compared to each other one, so skip this for
+        // large sets. The patterns match the same paths either way.
+        if (globParts.length > 1000)
+            return globParts;
         for (let i = 0; i < globParts.length - 1; i++) {
             for (let j = i + 1; j < globParts.length; j++) {
                 const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes);
diff --git a/dist/esm/index.js b/dist/esm/index.js
--- a/dist/esm/index.js
+++ b/dist/esm/index.js
@@ -434,6 +434,8 @@ export class Minimatch {
     // **/*/ -> */**/ <== not valid because ** doesn't follow
     // this WOULD be allowed if ** did follow symlinks, or * didn't
     firstPhasePreProcess(globParts) {
+        // each **/.. split doubles the patterns, so stop at the brace max
+        const { braceExpandMax = 100_000 } = this.options;
         let didSomething = false;
         do {
             didSomething = false;
@@ -461,7 +463,8 @@ export class Minimatch {
                         p === '..' ||
                         !p2 ||
                         p2 === '.' ||
-                        p2 === '..') {
+                        p2 === '..' ||
+                        globParts.length >= braceExpandMax) {
                         continue;
                     }
                     didSomething = true;
@@ -518,6 +521,10 @@ export class Minimatch {
     // {
/**/,
/**/

/} ->

/**/
     // ^-- not valid because ** doens't follow symlinks
     secondPhasePreProcess(globParts) {
+        // each pattern is compared to each other one, so skip this for
+        // large sets. The patterns match the same paths either way.
+        if (globParts.length > 1000)
+            return globParts;
         for (let i = 0; i < globParts.length - 1; i++) {
             for (let j = i + 1; j < globParts.length; j++) {
                 const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes);