fclp / fluent-command-line-parser

A simple, strongly typed .NET C# command line parser library using a fluent easy to use interface
Other
530 stars 85 forks source link

Incorrectly parsed "--" argument #99

Open ruslanfedoseenko opened 6 years ago

ruslanfedoseenko commented 6 years ago

With folowing command line arguments are not parsed correctly app.exe --xx "--" --yy 1 --zz 2 Value mapped for --xx arg is "--yy" All other values are not parsed and got default values

siywilliams commented 6 years ago

Oh crumbs yes I can see that happening.

-- tells the parser to stop searching for switches after that point and instead treat them as values.

It needs fixing so that if the -- is a string value itself such as "--" or '--' then it should be recognised as a string value and not a special token.

oleksabor commented 5 years ago

I've just tried

app.exe -a "-javascript-delay 3000 -q --no-outline --encoding utf-8 --user-style-sheet defaults/default-css.css"

expected result is to get parameter a with -javascript-delay 3000 -q --no-outline --encoding utf-8 --user-style-sheet defaults/default-css.css value

Is it the same case ?

siywilliams commented 5 years ago

Yes looks exactly the same case unfortunately

oleksabor commented 5 years ago

looks strange

I've just added tests as below

class when_args_contains_double_dash_value : ParseTestContext
{
    Establish context = () => SetupArgs("-a \"--\"");

    It should_return_a_single_option = () =>
        result.ParsedOptions.Count().ShouldEqual(1);

    It should_set_the_parsed_option_name = () =>
        result.ParsedOptions.First().Key.ShouldEqual("a");

    It should_set_the_parsed_option_value_to_the_double_dash = () =>
        result.ParsedOptions.First().Value.ShouldEqual("\"--\"");
}

class when_args_contains_double_dash_value_complex : ParseTestContext
{
    Establish context = () => SetupArgs("-a \"--ignored-switch-value 1234\"");

    It should_return_a_single_option = () =>
        result.ParsedOptions.Count().ShouldEqual(1);

    It should_set_the_parsed_option_value_to_the_double_dash = () =>
        result.ParsedOptions.First().Value.ShouldEqual("\"--ignored-switch-value 1234\"");
}
class when_args_contains_single_dash_value : ParseTestContext
{
    Establish context = () => SetupArgs("-a \"-\"");

    It should_return_a_single_option = () =>
        result.ParsedOptions.Count().ShouldEqual(1);

    It should_set_the_parsed_option_name = () =>
        result.ParsedOptions.First().Key.ShouldEqual("a");

    It should_set_the_parsed_option_value_to_the_double_dash = () =>
        result.ParsedOptions.First().Value.ShouldEqual("\"-\"");
}

class when_args_contains_single_dash_value_complex : ParseTestContext
{
    Establish context = () => SetupArgs("-a \"-ignored-switch-value 1234\"");

    It should_return_a_single_option = () =>
        result.ParsedOptions.Count().ShouldEqual(1);

    It should_set_the_parsed_option_value_to_the_double_dash = () =>
        result.ParsedOptions.First().Value.ShouldEqual("\"-ignored-switch-value 1234\"");
}

to the CommandLineParserEnginerMark2Tests class and it works fine on develop branch I've changed ShouldEqual to the wrong value and tests fail (as expected)

Does it mean that the develop branch has no bug?

oleksabor commented 5 years ago

ok, here is my testing result for the case when argument value contains - or --: OS (.net framework whatever) parses command line before it is done in the FCLP so I've wrote the code like

static void Main(string[] args)
{
    foreach (var a in args)
        Log.DebugFormat("input argument:{0}", a);
}

for command line like

app.exe -a "--some value"

output is

Debug input argument:-a Debug input argument:--some value

so second parameter has got value with space inside but " was removed by the OS (and it has no chance to get to the FCLP) .

To override this " has to be escaped like

app.exe -a "\"--some value\""

this produces expected output

Debug (windowsService1.Program) input argument:-a Debug (windowsService1.Program) input argument:"--some value"

as you can see first " from the command line was "taken" by the OS and \" value was unescaped to " in the argument value.

and when FCLP Parse(args) is executed there is "--some value" with double quotes in the args[1] item.

I've checked this for FCLP 1.4.3, 1.5.0.20 and develop branch - it works as expected if there is escaped double quote in the argument value.

Probably it has to be documented but I'm not sure that this is a bug. It is rather a feature ;-)

siywilliams commented 5 years ago

Probably it has to be documented but I'm not sure that this is a bug. It is rather a feature ;-)

@oleksabor ha ha thanks for your extensive investigation, I'm not sure what "feature" to call this !?

I've seen it many times before where .NET has already interpreted the commands args badly before they even get to FCLP. In that situation the library can't really do anything to help, so it is important that this is understood.

Thanks again