Skip to content

Commit 6c14860

Browse files
committed
Do not crash on nested negative extglobs
This is still doing the wrong thing wrt Bash 4.3 on *(!(*.js)) not matching foo.js, though. Same with +(!(*.js)). +(!(*.js)) is like !(*.js) or !(*.js)!(*.js) or ... Thanks to koala_man in IRC #bash channel on Freenode for helping understand this. Nevertheless, this fixes #68, albeit imperfectly.
1 parent 5adde89 commit 6c14860

2 files changed

Lines changed: 35 additions & 1 deletion

File tree

minimatch.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,11 +570,24 @@ function parse (pattern, isSub) {
570570
var nlFirst = re.slice(nl.reStart, nl.reEnd - 8)
571571
var nlLast = re.slice(nl.reEnd - 8, nl.reEnd)
572572
var nlAfter = re.slice(nl.reEnd)
573+
574+
nlLast += nlAfter
575+
576+
// Handle nested stuff like *(*.js|!(*.json)), where open parens
577+
// mean that we should *not* include the ) in the bit that is considered
578+
// "after" the negated section.
579+
var openParensBefore = nlBefore.split('(').length - 1
580+
var cleanAfter = nlAfter
581+
for (i = 0; i < openParensBefore; i++) {
582+
cleanAfter = cleanAfter.replace(/\)[+*?]?/, '')
583+
}
584+
nlAfter = cleanAfter
585+
573586
var dollar = ''
574587
if (nlAfter === '' && isSub !== SUBPARSE) {
575588
dollar = '$'
576589
}
577-
var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast + nlAfter
590+
var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast
578591
re = newRe
579592
}
580593

test/tricky-negations.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,27 @@ var cases = {
7272

7373
'foo.js.js': {
7474
'*.!(js)': true
75+
},
76+
77+
'testjson.json': {
78+
'*(*.json|!(*.js))': true,
79+
'+(*.json|!(*.js))': true,
80+
'@(*.json|!(*.js))': true,
81+
'?(*.json|!(*.js))': true
82+
},
83+
84+
'foojs.js': {
85+
'*(*.json|!(*.js))': false, // XXX bash 4.3 disagrees!
86+
'+(*.json|!(*.js))': false, // XXX bash 4.3 disagrees!
87+
'@(*.json|!(*.js))': false,
88+
'?(*.json|!(*.js))': false
89+
},
90+
91+
'other.bar': {
92+
'*(*.json|!(*.js))': true,
93+
'+(*.json|!(*.js))': true,
94+
'@(*.json|!(*.js))': true,
95+
'?(*.json|!(*.js))': true
7596
}
7697

7798
}

0 commit comments

Comments
 (0)