@@ -25,13 +25,13 @@ public bool IsMatch(string allChars, int currentPosition, out int newPosition)
2525#endif
2626{
2727// We shortcut to success for a ** in some special cases:-
28- // 1. The remaining tokens don't need to consume a minimum number of chracters in order to match.
28+ // 1. The remaining tokens don't need to consume a minimum number of chracters in order to match.
2929
3030// We shortcut to failure for a ** in some special cases:-
3131// A) The token was parsed with a leading path separator (i.e '/**' and the current charater we are matching from isn't a path separator.
3232
3333newPosition = currentPosition ;
34- // bool matchedLeadingSeperator = false;
34+ // bool matchedLeadingSeperator = false;
3535
3636// A) If leading seperator then current character needs to be that seperator.
3737if ( allChars . Length <= currentPosition || currentPosition < 0 )
@@ -40,7 +40,7 @@ public bool IsMatch(string allChars, int currentPosition, out int newPosition)
4040}
4141char currentChar = allChars [ currentPosition ] ;
4242if ( _token . LeadingPathSeparator != null )
43- {
43+ {
4444if ( ! GlobStringReader . IsPathSeparator ( currentChar ) )
4545{
4646// expected separator.
@@ -49,25 +49,26 @@ public bool IsMatch(string allChars, int currentPosition, out int newPosition)
4949//else
5050//{
5151// advance current position to match the leading separator.
52- // matchedLeadingSeperator = true;
52+ // matchedLeadingSeperator = true;
5353currentPosition = currentPosition + 1 ;
5454//}
5555}
5656else
5757{
58- // no leading seperator,
59- // means ** or possibly **/ used, not /**
58+ // no leading seperator, in which case match an optional leading seperator in string.
59+
60+ // means ** or possibly **/ used as pattern, not /**
6061// Input string doesn't need to start with a / or \ but if it does, it will be matched.
6162// i.e **/foo/bar will match foo/bar or /foo/bar.
6263// where as /**/foo/bar will not match foo/bar it will only match /foo/bar.
63- // currentChar = allChars[currentPosition];
64+ // currentChar = allChars[currentPosition];
6465if ( GlobStringReader . IsPathSeparator ( currentChar ) )
6566{
6667// advance current position to match the leading separator.
67- // matchedLeadingSeperator = true;
68- currentPosition = currentPosition + 1 ;
68+ // matchedLeadingSeperator = true;
69+ currentPosition = currentPosition + 1 ;
6970}
70- }
71+ }
7172
7273// 1. if no more tokens require matching we match.
7374if ( _subEvaluator . ConsumesMinLength == 0 )
@@ -79,6 +80,12 @@ public bool IsMatch(string allChars, int currentPosition, out int newPosition)
7980// Because we know we have more tokens in the pattern (subevaluators) - those will require a minimum amount of characters to match (could be 0 too).
8081// We can therefore calculate a "max" character position that we can match to, as if we exceed that position the remaining tokens cant possibly match.
8182int maxPos = ( allChars . Length - _subEvaluator . ConsumesMinLength ) ;
83+
84+ // Is there enough remaining characters to provide a match, if not exit early.
85+ if ( currentPosition > maxPos )
86+ {
87+ return false ;
88+ }
8289
8390// If all of the remaining tokens have a precise length, we can calculate the exact character that we need to macth to in the string.
8491// Otherwise we have to test at multiple character positions until we find a match (less efficient)
@@ -131,7 +138,7 @@ public bool IsMatch(string allChars, int currentPosition, out int newPosition)
131138if ( ! matchedSeperator )
132139{
133140return false ;
134- }
141+ }
135142}
136143
137144isMatch = _subEvaluator . IsMatch ( allChars , currentPosition , out newPosition ) ;
@@ -148,7 +155,7 @@ public bool IsMatch(string allChars, int currentPosition, out int newPosition)
148155// Iterate until we hit the next separator or maxPos.
149156matchedSeperator = false ;
150157while ( currentPosition < maxPos )
151- {
158+ {
152159currentPosition = currentPosition + 1 ;
153160currentChar = allChars [ currentPosition ] ;
154161