Skip to content

Commit 2912a6f

Browse files
committed
Allow spaces when tokenizing option-value
Previous behavior split the incoming token long-name value using the equal sign as the separator. This would cause an option's value containing spaces to get truncated. New behavior does regex. match to make sure format is correct and gets the full value.
1 parent 78848d0 commit 2912a6f

File tree

2 files changed

+49
-3
lines changed

2 files changed

+49
-3
lines changed

src/CommandLine/Core/Tokenizer.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using CommandLine.Infrastructure;
77
using CSharpx;
88
using RailwaySharp.ErrorHandling;
9+
using System.Text.RegularExpressions;
910

1011
namespace CommandLine.Core
1112
{
@@ -188,9 +189,19 @@ private static IEnumerable<Token> TokenizeLongName(
188189
onError(new BadFormatTokenError(value));
189190
yield break;
190191
}
191-
var parts = text.Split('=');
192-
yield return Token.Name(parts[0]);
193-
yield return Token.Value(parts[1], true);
192+
193+
var tokenMatch = Regex.Match(text, "^([^=]+)=([^ ].*)$");
194+
195+
if (tokenMatch.Success)
196+
{
197+
yield return Token.Name(tokenMatch.Groups[1].Value);
198+
yield return Token.Value(tokenMatch.Groups[2].Value, true);
199+
}
200+
else
201+
{
202+
onError(new BadFormatTokenError(value));
203+
yield break;
204+
}
194205
}
195206
}
196207
}

tests/CommandLine.Tests/Unit/Core/TokenizerTests.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,41 @@ public void Normalize_should_remove_all_value_with_explicit_assignment_of_existi
9292

9393
// Teardown
9494
}
95+
96+
[Fact]
97+
public void Should_properly_parse_option_with_equals_in_value()
98+
{
99+
/**
100+
* This is how the arg. would look in `static void Main(string[] args)`
101+
* if passed from the command-line and the option-value wrapped in quotes.
102+
* Ex.) ./app --connectionString="Server=localhost;Data Source..."
103+
*/
104+
var args = new[] { "--connectionString=Server=localhost;Data Source=(LocalDB)\v12.0;Initial Catalog=temp;" };
105+
106+
var result = Tokenizer.Tokenize(args, name => NameLookupResult.OtherOptionFound, token => token);
107+
108+
var tokens = result.SucceededWith();
109+
110+
Assert.NotNull(tokens);
111+
Assert.Equal(2, tokens.Count());
112+
Assert.Equal("connectionString", tokens.First().Text);
113+
Assert.Equal("Server=localhost;Data Source=(LocalDB)\v12.0;Initial Catalog=temp;", tokens.Last().Text);
114+
}
115+
116+
[Fact]
117+
public void Should_return_error_if_option_format_with_equals_is_not_correct()
118+
{
119+
var args = new[] { "--option1 = fail", "--option2= fail" };
120+
121+
var result = Tokenizer.Tokenize(args, name => NameLookupResult.OtherOptionFound, token => token);
122+
123+
var tokens = result.SuccessfulMessages();
124+
125+
Assert.NotNull(tokens);
126+
Assert.Equal(2, tokens.Count());
127+
Assert.Equal(ErrorType.BadFormatTokenError, tokens.First().Tag);
128+
Assert.Equal(ErrorType.BadFormatTokenError, tokens.Last().Tag);
129+
}
95130
}
96131

97132
}

0 commit comments

Comments
 (0)