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

Escaped quote at the end of quoted argument #106

Open WouterTinus opened 5 years ago

WouterTinus commented 5 years ago

I ran into a little bug with the latest Nuget package (1.4.3).

--param "something something" is parsed as something something --param "something \"{4}\" something" is parsed as something \"4\" something

However:

--param "something \"{4}\"" is expected to be something \"4\" but instead gives me something \"4, dropping the final quote.

Thanks for a nice library!

oleksabor commented 4 years ago

The problem is in the UsefulExtension.Remove method:

public static string RemoveAnyWrappingDoubleQuotes(this string str)
{
    return str.IsNullOrWhiteSpace()
               ? str
               : str.TrimStart('"').TrimEnd('"');
}

WrapInDoubleQuotes is executed if there is space in the option value. And there is space. So value like something "4" is wrapped to the "something "4"" when CommandLineParserEngineMark2 does its job. But then StringCommandLineOptionParser.Parse removes the double quote and removes the all double quotes at the end :(

Here is test case

[TestFixture]
public class when_there_is_qoute_in_the_end 
{
    [Test]
    public void parser()
    {
        var args = new[] { "--param", "something \"4\"" };

        var sut = new Fclp.FluentCommandLineParser<Config>();
        sut.Setup(_ => _.Param).As('p', "param");
        var res = sut.Parse(args);

        Assert.AreEqual("something \"4\"", sut.Object.Param);
    }
    [Test]
    public void RemoveAnyWrappingDoubleQuotes()
    {
        var str = "something \"4\"";
        str = str.WrapInDoubleQuotes();
        str = str.RemoveAnyWrappingDoubleQuotes();
        Assert.AreEqual("something \"4\"", str);
    }
}

I've adjusted the RemoveAnyWrappingDoubleQuotes method like below

public static string RemoveAnyWrappingDoubleQuotes(this string str)
{

    if (!str.IsNullOrWhiteSpace())
        if (str.StartsWith("\"") && str.EndsWith("\""))
            return str.Substring(1, str.Length - 2);
    return str;
}

and it works