diff --git a/dist/commonjs/index.js b/dist/commonjs/index.js --- a/dist/commonjs/index.js +++ b/dist/commonjs/index.js @@ -453,6 +453,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; @@ -480,7 +482,8 @@ class Minimatch { p === '..' || !p2 || p2 === '.' || - p2 === '..') { + p2 === '..' || + globParts.length >= braceExpandMax) { continue; } didSomething = true; @@ -537,6 +540,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
@@ -444,6 +444,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;
@@ -471,7 +473,8 @@ export class Minimatch {
                         p === '..' ||
                         !p2 ||
                         p2 === '.' ||
-                        p2 === '..') {
+                        p2 === '..' ||
+                        globParts.length >= braceExpandMax) {
                         continue;
                     }
                     didSomething = true;
@@ -528,6 +531,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);