@@ -8,6 +8,9 @@ var escOpen = '\0OPEN'+Math.random()+'\0';
88var escClose = '\0CLOSE' + Math . random ( ) + '\0' ;
99var escComma = '\0COMMA' + Math . random ( ) + '\0' ;
1010var escPeriod = '\0PERIOD' + Math . random ( ) + '\0' ;
11+ var EXPANSION_MAX = 100000 ;
12+
13+ module . exports . EXPANSION_MAX = EXPANSION_MAX ;
1114
1215function numeric ( str ) {
1316 return parseInt ( str , 10 ) == str
@@ -62,10 +65,13 @@ function parseCommaParts(str) {
6265 return parts ;
6366}
6467
65- function expandTop ( str ) {
68+ function expandTop ( str , options ) {
6669 if ( ! str )
6770 return [ ] ;
6871
72+ options = options || { } ;
73+ var max = options . max == null ? EXPANSION_MAX : options . max ;
74+
6975 // I don't know why Bash 4.3 does this, but it does.
7076 // Anything starting with {} will have the first two bytes preserved
7177 // but *only* at the top level, so {},a }b will not expand to anything,
@@ -76,7 +82,7 @@ function expandTop(str) {
7682 str = '\\{\\}' + str . substr ( 2 ) ;
7783 }
7884
79- return expand ( escapeBraces ( str ) , true ) . map ( unescapeBraces ) ;
85+ return expand ( escapeBraces ( str ) , max , true ) . map ( unescapeBraces ) ;
8086}
8187
8288function identity ( e ) {
@@ -97,7 +103,7 @@ function gte(i, y) {
97103 return i >= y ;
98104}
99105
100- function expand ( str , isTop ) {
106+ function expand ( str , max , isTop ) {
101107 var expansions = [ ] ;
102108
103109 var m = balanced ( '{' , '}' , str ) ;
@@ -111,7 +117,7 @@ function expand(str, isTop) {
111117 // {a},b }
112118 if ( m . post . match ( / , (? ! , ) .* \} / ) ) {
113119 str = m . pre + '{' + m . body + escClose + m . post ;
114- return expand ( str ) ;
120+ return expand ( str , max , true ) ;
115121 }
116122 return [ str ] ;
117123 }
@@ -123,10 +129,10 @@ function expand(str, isTop) {
123129 n = parseCommaParts ( m . body ) ;
124130 if ( n . length === 1 ) {
125131 // x{{a,b}}y ==> x{a}y x{b}y
126- n = expand ( n [ 0 ] , false ) . map ( embrace ) ;
132+ n = expand ( n [ 0 ] , max , false ) . map ( embrace ) ;
127133 if ( n . length === 1 ) {
128134 var post = m . post . length
129- ? expand ( m . post , false )
135+ ? expand ( m . post , max , false )
130136 : [ '' ] ;
131137 return post . map ( function ( p ) {
132138 return m . pre + n [ 0 ] + p ;
@@ -141,7 +147,7 @@ function expand(str, isTop) {
141147 // no need to expand pre, since it is guaranteed to be free of brace-sets
142148 var pre = m . pre ;
143149 var post = m . post . length
144- ? expand ( m . post , false )
150+ ? expand ( m . post , max , false )
145151 : [ '' ] ;
146152
147153 var N ;
@@ -185,11 +191,11 @@ function expand(str, isTop) {
185191 N . push ( c ) ;
186192 }
187193 } else {
188- N = concatMap ( n , function ( el ) { return expand ( el , false ) } ) ;
194+ N = concatMap ( n , function ( el ) { return expand ( el , max , false ) } ) ;
189195 }
190196
191197 for ( var j = 0 ; j < N . length ; j ++ ) {
192- for ( var k = 0 ; k < post . length ; k ++ ) {
198+ for ( var k = 0 ; k < post . length && expansions . length < max ; k ++ ) {
193199 var expansion = pre + N [ j ] + post [ k ] ;
194200 if ( ! isTop || isSequence || expansion )
195201 expansions . push ( expansion ) ;
0 commit comments