Skip to content

Commit bbc5a99

Browse files
committed
Merge branch 'hotfix/2.1.1'
2 parents 3b862a0 + b124666 commit bbc5a99

File tree

3 files changed

+45
-29
lines changed

3 files changed

+45
-29
lines changed

src/DotNet.Glob.Tests/GlobTests.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ public void Does_Not_Match(string pattern, params string[] testStrings)
4848
[InlineData("p?th/*a[bcd]b[e-g]a[1-4][!wxyz][!a-c][!1-3].*", "pGth/yGKNY6acbea3rm8.")]
4949
[InlineData("/**/file.*", "/folder/file.csv")]
5050
[InlineData("/**/file.*", "/file.txt")]
51-
[InlineData("/**/file.*", "/file.txt")]
5251
[InlineData("**/file.*", "/file.txt")]
5352
[InlineData("/*file.txt", "/file.txt")]
5453
[InlineData("C:\\THIS_IS_A_DIR\\*", "C:\\THIS_IS_A_DIR\\somefile")] // Regression Test for https://github.com/dazinator/DotNet.Glob/issues/20
@@ -78,14 +77,18 @@ public void Does_Not_Match(string pattern, params string[] testStrings)
7877
[InlineData(@"C:\myergen[*][]]ator", @"C:\myergen*]ator")]
7978
[InlineData(@"C:\myergen[*]]ator", @"C:\myergen*ator", @"C:\myergen]ator")]
8079
[InlineData(@"C:\myergen[?]ator", @"C:\myergen?ator")]
81-
[InlineData(@"/path[\]hatstand", @"/path\hatstand")]
80+
[InlineData(@"/path[\]hatstand", @"/path\hatstand")]
81+
[InlineData(@"**\[#!]*\**", @"#test3", @"#test3\", @"\#test3\foo", @"\#test3")]
82+
[InlineData(@"**\[#!]*", @"#test3", "#this is a comment", @"\#test3")]
83+
[InlineData(@"[#!]*\**","#this is a comment")]
84+
[InlineData(@"[#!]*", @"#test3", "#this is a comment")]
8285
public void IsMatch(string pattern, params string[] testStrings)
8386
{
8487
var glob = Globbing.Glob.Parse(pattern);
8588
foreach (var testString in testStrings)
8689
{
8790
var match = glob.IsMatch(testString);
88-
Assert.True(match);
91+
Assert.True(match, $"glob {pattern} failed to match test string: {testString}");
8992
}
9093
}
9194

src/DotNet.Glob/Evaluation/WildcardDirectoryTokenEvaluator.cs

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using System;
2-
using System.Text;
3-
using DotNet.Globbing.Token;
1+
using DotNet.Globbing.Token;
42

53
namespace DotNet.Globbing.Evaluation
64
{
@@ -31,35 +29,49 @@ public bool IsMatch(string allChars, int currentPosition, out int newPosition)
3129
newPosition = currentPosition;
3230

3331
// 1. Are we already at the end of the test string?
34-
if (currentPosition >= allChars.Length)
32+
if (currentPosition >= allChars.Length - 1)
3533
{
3634
return true;
3735
}
3836

3937
// A) If leading seperator then current character needs to be that seperator.
40-
var currentChar = allChars[currentPosition];
41-
if (this._token.LeadingPathSeperator != null)
38+
char currentChar = allChars[currentPosition];
39+
if (_token.LeadingPathSeperator != null)
4240
{
4341
if (!GlobStringReader.IsPathSeperator(currentChar))
4442
{
4543
// expected seperator.
4644
return false;
4745
}
48-
46+
//else
47+
//{
4948
// advance current position to match the leading seperator.
5049
currentPosition = currentPosition + 1;
50+
//}
51+
}
52+
else
53+
{
54+
// no leading seperator, means ** used at start of pattern not /** used within pattern.
55+
// If **/ is used for start of pattern then input string doesn't need to start with a / or \ and it will be matched.
56+
// i.e **/foo/bar will match foo/bar or /foo/bar.
57+
// where as /**/foo/bar will not match foo/bar it will only match /foo/bar.
58+
if (GlobStringReader.IsPathSeperator(currentChar))
59+
{
60+
// advance current position to match the leading seperator.
61+
currentPosition = currentPosition + 1;
62+
}
5163
}
5264

5365
// 2. if no more tokens require matching (i.e ** is the last token) - we match.
54-
if (this._subEvaluator.EvaluatorCount == 0)
66+
if (_subEvaluator.EvaluatorCount == 0)
5567
{
5668
newPosition = allChars.Length;
5769
return true;
5870
}
5971

6072
// 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).
6173
// 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.
62-
var maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength);
74+
int maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength);
6375

6476
// 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.
6577
// Otherwise we have to test at multiple character positions until we find a match (less efficient)
@@ -69,12 +81,12 @@ public bool IsMatch(string allChars, int currentPosition, out int newPosition)
6981
// As we can only match full segments, make sure character before chacracter at max pos is a seperator,
7082
if (maxPos > 0)
7183
{
72-
var mustMatchUntilChar = allChars[maxPos - 1];
84+
char mustMatchUntilChar = allChars[maxPos - 1];
7385
if (!GlobStringReader.IsPathSeperator(mustMatchUntilChar))
7486
{
7587
// can only match full segments.
7688
return false;
77-
}
89+
}
7890
}
7991

8092
// Advance position to max pos.
@@ -90,6 +102,7 @@ public bool IsMatch(string allChars, int currentPosition, out int newPosition)
90102
currentChar = allChars[currentPosition];
91103

92104
// If the ** token was parsed with a trailing slash - i.e "**/" then we need to match past it before we test remainijng tokens.
105+
// special exception if **/ is at start of pattern, as then the input string need not have any path seperators.
93106
if (_token.TrailingPathSeperator != null)
94107
{
95108
if (GlobStringReader.IsPathSeperator(currentChar))
@@ -125,7 +138,7 @@ public bool IsMatch(string allChars, int currentPosition, out int newPosition)
125138
// match the seperator.
126139
currentPosition = currentPosition + 1;
127140
break;
128-
}
141+
}
129142
}
130143
}
131144
}
@@ -134,15 +147,9 @@ public bool IsMatch(string allChars, int currentPosition, out int newPosition)
134147

135148
}
136149

137-
public virtual int ConsumesMinLength
138-
{
139-
get { return _subEvaluator.ConsumesMinLength; }
140-
}
150+
public virtual int ConsumesMinLength => _subEvaluator.ConsumesMinLength;
141151

142-
public bool ConsumesVariableLength
143-
{
144-
get { return true; }
145-
}
152+
public bool ConsumesVariableLength => true;
146153

147154
#endregion
148155

src/DotNet.Glob/Evaluation/WildcardTokenEvaluator.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ public class WildcardTokenEvaluator : IGlobTokenEvaluator
99
private readonly WildcardToken _token;
1010
private readonly CompositeTokenEvaluator _subEvaluator;
1111
private readonly bool _requiresSubEvaluation;
12+
1213

1314
public WildcardTokenEvaluator(WildcardToken token, CompositeTokenEvaluator subEvaluator)
1415
{
1516
_token = token;
1617
_subEvaluator = subEvaluator;
17-
_requiresSubEvaluation = _subEvaluator.EvaluatorCount > 0;
18+
_requiresSubEvaluation = _subEvaluator.EvaluatorCount > 0;
1819
}
1920

2021
#region IGlobTokenEvaluator
@@ -72,27 +73,32 @@ public bool IsMatch(string allChars, int currentPosition, out int newPosition)
7273
}
7374
var isMatch = _subEvaluator.IsMatch(allChars, requiredMatchPosition, out newPosition);
7475
return isMatch;
75-
}
76+
}
7677

7778
// We can match a variable amount of characters but,
7879
// We can't match more characters than the amount that will take us past the min required length required by the sub evaluator tokens,
7980
// and as we are not a directory wildcard, we can't match past a path seperator.
80-
var maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength);
81-
for (int i = currentPosition; i <= maxPos; i++)
81+
var maxPos = allChars.Length - 1;
82+
if (_subEvaluator.ConsumesMinLength > 0)
8283
{
83-
var currentChar = allChars[i];
84+
maxPos = maxPos - _subEvaluator.ConsumesMinLength + 1;
85+
}
86+
// var maxPos = (allChars.Length - _subEvaluator.ConsumesMinLength);
87+
for (int i = currentPosition; i <= maxPos; i++)
88+
{
8489

8590
var isMatch = _subEvaluator.IsMatch(allChars, i, out newPosition);
8691
if (isMatch)
8792
{
8893
return true;
8994
}
9095

96+
var currentChar = allChars[i];
9197
if (currentChar == '/' || currentChar == '\\')
9298
{
9399
return false;
94100
}
95-
}
101+
}
96102

97103
return false;
98104

0 commit comments

Comments
 (0)