@@ -147,26 +147,29 @@ private static function processTokens(array $tokens): array
147147 $ nextType = $ tokens [$ offset + 1 ][0 ] ?? null ;
148148
149149 if ($ type === self ::T_BACKSLASH && false === $ escaped ) {
150+ // skip the backslash and set flag to escape next token
150151 $ escaped = true ;
151152
152153 continue ;
153154 }
154155
155156 if ($ escaped === true ) {
157+ // escaped flag is set, so make this a literal char and unset
158+ // the escaped flag
156159 $ resolved [] = [self ::T_CHAR , $ char ];
157160 $ escaped = false ;
158161
159162 continue ;
160163 }
161164
162- // normal globstar
165+ // globstar must be preceded by and succeeded by a directory separator
163166 if (
164167 $ type === self ::T_SLASH &&
165- ( $ tokens [ $ offset + 1 ][ 0 ] ?? null ) === self ::T_ASTERIX && ($ tokens [$ offset + 2 ][0 ] ?? null ) === self ::T_ASTERIX && ($ tokens [$ offset + 3 ][0 ] ?? null ) === self ::T_SLASH
168+ $ nextType === self ::T_ASTERIX && ($ tokens [$ offset + 2 ][0 ] ?? null ) === self ::T_ASTERIX && ($ tokens [$ offset + 3 ][0 ] ?? null ) === self ::T_SLASH
166169 ) {
167170 $ resolved [] = [self ::T_GLOBSTAR , '** ' ];
168171
169- // we eat the two `*` in addition to the slash
172+ // we eat the two `*` and the trailing slash
170173 $ offset += 3 ;
171174
172175 continue ;
@@ -208,6 +211,10 @@ private static function processTokens(array $tokens): array
208211 continue ;
209212 }
210213
214+ // https://man7.org/linux/man-pages/man7/glob.7.html
215+ // > The string enclosed by the brackets cannot be empty; therefore
216+ // > ']' can be allowed between the brackets, provided that it is
217+ // > the first character.
211218 if ($ type === self ::T_BRACKET_OPEN && $ nextType === self ::T_BRACKET_CLOSE ) {
212219 $ bracketOpen = true ;
213220 $ resolved [] = [self ::T_BRACKET_OPEN , '[ ' ];
@@ -218,6 +225,8 @@ private static function processTokens(array $tokens): array
218225 continue ;
219226 }
220227
228+ // if we're already in a bracket and the next two chars are [: then
229+ // start parsing a character class...
221230 if ($ bracketOpen && $ type === self ::T_BRACKET_OPEN && $ nextType === self ::T_COLON ) {
222231 // this looks like a named [:character:] class
223232 $ class = '' ;
@@ -240,14 +249,17 @@ private static function processTokens(array $tokens): array
240249 $ resolved [] = [self ::T_CHAR , ': ' . $ class ];
241250 }
242251
252+
253+ // if bracket is already open and we have another open bracket
254+ // interpret it as a literal
243255 if ($ bracketOpen === true && $ type === self ::T_BRACKET_OPEN ) {
244- // if bracket is already open, interpret everything as a
245- // literal char
246256 $ resolved [] = [self ::T_CHAR , $ char ];
247257
248258 continue ;
249259 }
250260
261+ // if we are NOT in an open bracket and we have an open bracket
262+ // then pop the bracket on the stack and enter bracket-mode.
251263 if ($ bracketOpen === false && $ type === self ::T_BRACKET_OPEN ) {
252264 $ bracketOpen = true ;
253265 $ resolved [] = [$ type , $ char ];
@@ -256,7 +268,15 @@ private static function processTokens(array $tokens): array
256268 continue ;
257269 }
258270
259- if ($ type === self ::T_BRACKET_CLOSE ) {
271+ // if are in a bracket and we get to bracket close then
272+ // pop the last open bracket off the stack and continue
273+ //
274+ // TODO: $bracketOpen === true below is not tested
275+ if ($ bracketOpen === true && $ type === self ::T_BRACKET_CLOSE ) {
276+
277+ // TODO: this is not tested
278+ $ bracketOpen = false ;
279+
260280 array_pop ($ brackets );
261281 $ resolved [] = [$ type , $ char ];
262282
0 commit comments