minimatch 3.1.2 → 3.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/minimatch.js +160 -102
- package/package.json +2 -2
package/minimatch.js
CHANGED
|
@@ -142,6 +142,8 @@ function Minimatch (pattern, options) {
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
this.options = options
|
|
145
|
+
this.maxGlobstarRecursion = options.maxGlobstarRecursion !== undefined
|
|
146
|
+
? options.maxGlobstarRecursion : 200
|
|
145
147
|
this.set = []
|
|
146
148
|
this.pattern = pattern
|
|
147
149
|
this.regexp = null
|
|
@@ -390,6 +392,9 @@ function parse (pattern, isSub) {
|
|
|
390
392
|
continue
|
|
391
393
|
}
|
|
392
394
|
|
|
395
|
+
// coalesce consecutive non-globstar * characters
|
|
396
|
+
if (c === '*' && stateChar === '*') continue
|
|
397
|
+
|
|
393
398
|
// if we already have a stateChar, then it means
|
|
394
399
|
// that there was something like ** or +? in there.
|
|
395
400
|
// Handle the stateChar, then proceed with this one.
|
|
@@ -784,109 +789,173 @@ Minimatch.prototype.match = function match (f, partial) {
|
|
|
784
789
|
// out of pattern, then that's fine, as long as all
|
|
785
790
|
// the parts match.
|
|
786
791
|
Minimatch.prototype.matchOne = function (file, pattern, partial) {
|
|
787
|
-
|
|
792
|
+
if (pattern.indexOf(GLOBSTAR) !== -1) {
|
|
793
|
+
return this._matchGlobstar(file, pattern, partial, 0, 0)
|
|
794
|
+
}
|
|
795
|
+
return this._matchOne(file, pattern, partial, 0, 0)
|
|
796
|
+
}
|
|
788
797
|
|
|
789
|
-
|
|
790
|
-
|
|
798
|
+
Minimatch.prototype._matchGlobstar = function (file, pattern, partial, fileIndex, patternIndex) {
|
|
799
|
+
var i
|
|
791
800
|
|
|
792
|
-
|
|
801
|
+
// find first globstar from patternIndex
|
|
802
|
+
var firstgs = -1
|
|
803
|
+
for (i = patternIndex; i < pattern.length; i++) {
|
|
804
|
+
if (pattern[i] === GLOBSTAR) { firstgs = i; break }
|
|
805
|
+
}
|
|
793
806
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
; fi++, pi++) {
|
|
800
|
-
this.debug('matchOne loop')
|
|
801
|
-
var p = pattern[pi]
|
|
802
|
-
var f = file[fi]
|
|
807
|
+
// find last globstar
|
|
808
|
+
var lastgs = -1
|
|
809
|
+
for (i = pattern.length - 1; i >= 0; i--) {
|
|
810
|
+
if (pattern[i] === GLOBSTAR) { lastgs = i; break }
|
|
811
|
+
}
|
|
803
812
|
|
|
804
|
-
|
|
813
|
+
var head = pattern.slice(patternIndex, firstgs)
|
|
814
|
+
var body = pattern.slice(firstgs + 1, lastgs)
|
|
815
|
+
var tail = pattern.slice(lastgs + 1)
|
|
805
816
|
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
if (
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
//
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
// - matchOne(x/y/z/c, c) -> no
|
|
833
|
-
// - matchOne(y/z/c, c) -> no
|
|
834
|
-
// - matchOne(z/c, c) -> no
|
|
835
|
-
// - matchOne(c, c) yes, hit
|
|
836
|
-
var fr = fi
|
|
837
|
-
var pr = pi + 1
|
|
838
|
-
if (pr === pl) {
|
|
839
|
-
this.debug('** at the end')
|
|
840
|
-
// a ** at the end will just swallow the rest.
|
|
841
|
-
// We have found a match.
|
|
842
|
-
// however, it will not swallow /.x, unless
|
|
843
|
-
// options.dot is set.
|
|
844
|
-
// . and .. are *never* matched by **, for explosively
|
|
845
|
-
// exponential reasons.
|
|
846
|
-
for (; fi < fl; fi++) {
|
|
847
|
-
if (file[fi] === '.' || file[fi] === '..' ||
|
|
848
|
-
(!options.dot && file[fi].charAt(0) === '.')) return false
|
|
849
|
-
}
|
|
850
|
-
return true
|
|
817
|
+
// check the head
|
|
818
|
+
if (head.length) {
|
|
819
|
+
var fileHead = file.slice(fileIndex, fileIndex + head.length)
|
|
820
|
+
if (!this._matchOne(fileHead, head, partial, 0, 0)) {
|
|
821
|
+
return false
|
|
822
|
+
}
|
|
823
|
+
fileIndex += head.length
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
// check the tail
|
|
827
|
+
var fileTailMatch = 0
|
|
828
|
+
if (tail.length) {
|
|
829
|
+
if (tail.length + fileIndex > file.length) return false
|
|
830
|
+
|
|
831
|
+
var tailStart = file.length - tail.length
|
|
832
|
+
if (this._matchOne(file, tail, partial, tailStart, 0)) {
|
|
833
|
+
fileTailMatch = tail.length
|
|
834
|
+
} else {
|
|
835
|
+
// affordance for stuff like a/**/* matching a/b/
|
|
836
|
+
if (file[file.length - 1] !== '' ||
|
|
837
|
+
fileIndex + tail.length === file.length) {
|
|
838
|
+
return false
|
|
839
|
+
}
|
|
840
|
+
tailStart--
|
|
841
|
+
if (!this._matchOne(file, tail, partial, tailStart, 0)) {
|
|
842
|
+
return false
|
|
851
843
|
}
|
|
844
|
+
fileTailMatch = tail.length + 1
|
|
845
|
+
}
|
|
846
|
+
}
|
|
852
847
|
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
// found a match.
|
|
863
|
-
return true
|
|
864
|
-
} else {
|
|
865
|
-
// can't swallow "." or ".." ever.
|
|
866
|
-
// can only swallow ".foo" when explicitly asked.
|
|
867
|
-
if (swallowee === '.' || swallowee === '..' ||
|
|
868
|
-
(!options.dot && swallowee.charAt(0) === '.')) {
|
|
869
|
-
this.debug('dot detected!', file, fr, pattern, pr)
|
|
870
|
-
break
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
// ** swallows a segment, and continue.
|
|
874
|
-
this.debug('globstar swallow a segment, and continue')
|
|
875
|
-
fr++
|
|
876
|
-
}
|
|
848
|
+
// if body is empty (single ** between head and tail)
|
|
849
|
+
if (!body.length) {
|
|
850
|
+
var sawSome = !!fileTailMatch
|
|
851
|
+
for (i = fileIndex; i < file.length - fileTailMatch; i++) {
|
|
852
|
+
var f = String(file[i])
|
|
853
|
+
sawSome = true
|
|
854
|
+
if (f === '.' || f === '..' ||
|
|
855
|
+
(!this.options.dot && f.charAt(0) === '.')) {
|
|
856
|
+
return false
|
|
877
857
|
}
|
|
858
|
+
}
|
|
859
|
+
return sawSome
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
// split body into segments at each GLOBSTAR
|
|
863
|
+
var bodySegments = [[[], 0]]
|
|
864
|
+
var currentBody = bodySegments[0]
|
|
865
|
+
var nonGsParts = 0
|
|
866
|
+
var nonGsPartsSums = [0]
|
|
867
|
+
for (var bi = 0; bi < body.length; bi++) {
|
|
868
|
+
var b = body[bi]
|
|
869
|
+
if (b === GLOBSTAR) {
|
|
870
|
+
nonGsPartsSums.push(nonGsParts)
|
|
871
|
+
currentBody = [[], 0]
|
|
872
|
+
bodySegments.push(currentBody)
|
|
873
|
+
} else {
|
|
874
|
+
currentBody[0].push(b)
|
|
875
|
+
nonGsParts++
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
var idx = bodySegments.length - 1
|
|
880
|
+
var fileLength = file.length - fileTailMatch
|
|
881
|
+
for (var si = 0; si < bodySegments.length; si++) {
|
|
882
|
+
bodySegments[si][1] = fileLength -
|
|
883
|
+
(nonGsPartsSums[idx--] + bodySegments[si][0].length)
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
return !!this._matchGlobStarBodySections(
|
|
887
|
+
file, bodySegments, fileIndex, 0, partial, 0, !!fileTailMatch
|
|
888
|
+
)
|
|
889
|
+
}
|
|
878
890
|
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
891
|
+
// return false for "nope, not matching"
|
|
892
|
+
// return null for "not matching, cannot keep trying"
|
|
893
|
+
Minimatch.prototype._matchGlobStarBodySections = function (
|
|
894
|
+
file, bodySegments, fileIndex, bodyIndex, partial, globStarDepth, sawTail
|
|
895
|
+
) {
|
|
896
|
+
var bs = bodySegments[bodyIndex]
|
|
897
|
+
if (!bs) {
|
|
898
|
+
// just make sure there are no bad dots
|
|
899
|
+
for (var i = fileIndex; i < file.length; i++) {
|
|
900
|
+
sawTail = true
|
|
901
|
+
var f = file[i]
|
|
902
|
+
if (f === '.' || f === '..' ||
|
|
903
|
+
(!this.options.dot && f.charAt(0) === '.')) {
|
|
904
|
+
return false
|
|
887
905
|
}
|
|
906
|
+
}
|
|
907
|
+
return sawTail
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
var body = bs[0]
|
|
911
|
+
var after = bs[1]
|
|
912
|
+
while (fileIndex <= after) {
|
|
913
|
+
var m = this._matchOne(
|
|
914
|
+
file.slice(0, fileIndex + body.length),
|
|
915
|
+
body,
|
|
916
|
+
partial,
|
|
917
|
+
fileIndex,
|
|
918
|
+
0
|
|
919
|
+
)
|
|
920
|
+
// if limit exceeded, no match. intentional false negative,
|
|
921
|
+
// acceptable break in correctness for security.
|
|
922
|
+
if (m && globStarDepth < this.maxGlobstarRecursion) {
|
|
923
|
+
var sub = this._matchGlobStarBodySections(
|
|
924
|
+
file, bodySegments,
|
|
925
|
+
fileIndex + body.length, bodyIndex + 1,
|
|
926
|
+
partial, globStarDepth + 1, sawTail
|
|
927
|
+
)
|
|
928
|
+
if (sub !== false) {
|
|
929
|
+
return sub
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
var f = file[fileIndex]
|
|
933
|
+
if (f === '.' || f === '..' ||
|
|
934
|
+
(!this.options.dot && f.charAt(0) === '.')) {
|
|
888
935
|
return false
|
|
889
936
|
}
|
|
937
|
+
fileIndex++
|
|
938
|
+
}
|
|
939
|
+
return null
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
Minimatch.prototype._matchOne = function (file, pattern, partial, fileIndex, patternIndex) {
|
|
943
|
+
var fi, pi, fl, pl
|
|
944
|
+
for (
|
|
945
|
+
fi = fileIndex, pi = patternIndex, fl = file.length, pl = pattern.length
|
|
946
|
+
; (fi < fl) && (pi < pl)
|
|
947
|
+
; fi++, pi++
|
|
948
|
+
) {
|
|
949
|
+
this.debug('matchOne loop')
|
|
950
|
+
var p = pattern[pi]
|
|
951
|
+
var f = file[fi]
|
|
952
|
+
|
|
953
|
+
this.debug(pattern, p, f)
|
|
954
|
+
|
|
955
|
+
// should be impossible.
|
|
956
|
+
// some invalid regexp stuff in the set.
|
|
957
|
+
/* istanbul ignore if */
|
|
958
|
+
if (p === false || p === GLOBSTAR) return false
|
|
890
959
|
|
|
891
960
|
// something other than **
|
|
892
961
|
// non-magic patterns just have to match exactly
|
|
@@ -903,17 +972,6 @@ Minimatch.prototype.matchOne = function (file, pattern, partial) {
|
|
|
903
972
|
if (!hit) return false
|
|
904
973
|
}
|
|
905
974
|
|
|
906
|
-
// Note: ending in / means that we'll get a final ""
|
|
907
|
-
// at the end of the pattern. This can only match a
|
|
908
|
-
// corresponding "" at the end of the file.
|
|
909
|
-
// If the file ends in /, then it can only match a
|
|
910
|
-
// a pattern that ends in /, unless the pattern just
|
|
911
|
-
// doesn't have any more for it. But, a/b/ should *not*
|
|
912
|
-
// match "a/b/*", even though "" matches against the
|
|
913
|
-
// [^/]*? pattern, except in partial mode, where it might
|
|
914
|
-
// simply not be reached yet.
|
|
915
|
-
// However, a/b/ should still satisfy a/*
|
|
916
|
-
|
|
917
975
|
// now either we fell off the end of the pattern, or we're done.
|
|
918
976
|
if (fi === fl && pi === pl) {
|
|
919
977
|
// ran out of pattern and filename at the same time.
|
package/package.json
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me)",
|
|
3
3
|
"name": "minimatch",
|
|
4
4
|
"description": "a glob matcher in javascript",
|
|
5
|
-
"version": "3.1.
|
|
5
|
+
"version": "3.1.4",
|
|
6
6
|
"publishConfig": {
|
|
7
|
-
"tag": "v3
|
|
7
|
+
"tag": "legacy-v3"
|
|
8
8
|
},
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|