Skip to content

Trailing back-slash in String argument value leads to incorrect parsing #270

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ghost opened this issue Dec 9, 2015 · 7 comments
Closed

Comments

@ghost
Copy link

ghost commented Dec 9, 2015

Hi,
as subject.

Given a -p String parameter:
ReadText.Demo.exe head -p "c:\trailing - back - slash"

It gets parsed as:
c:\trailing - back - slash"

The trailing back-slash causes the value of the parameter to hold the double-quote value, while the back-slash is lost.
This seems to happen only when the traling back-slash is immediately followed by the double-quote.

Thanks

@nemec
Copy link
Collaborator

nemec commented Dec 9, 2015

That's the magic of .Net.

If a double quotation mark follows an odd number of backslashes, including just one, each preceding pair is replaced with one backslash and the remaining backslash is removed; however, in this case the double quotation mark is not removed

The quick fix: put a double-slash at the end of your path instead of a single one. Since .Net does some pre-processing of arguments to get your string[] args parameter to Main(), CommandLine can't do anything about it unless it performs the parsing on the full string.

That has some trade-offs since System.Environment.CommandLine isn't as obvious as passing in an argument array (which most C# programmers are familiar with)

@ghost
Copy link
Author

ghost commented Dec 9, 2015

It could be worth considering parsing System.Environment.CommandLine then, which preserves the correct arguments.

@ghost ghost closed this as completed Dec 9, 2015
@ericnewton76
Copy link

I feel like some documentation regarding this would be beneficial... basically that the recommended approach is to utilize the System.Environment.CommandLine instead of string[] args from Main.

@nemec
Copy link
Collaborator

nemec commented Dec 9, 2015

@ericnewton76 Env.CommandLine is not a drop-in replacement for args, since it is just a single string (similar to ProcessStartInfo.Arguments). Splitting the line on spaces would work except when there is quoted text, in which case we'd have to implement the parsing logic within the parser itself (I don't believe there is an equivalent to Python's shlex.split in .Net).

This would probably take the form of a new overload for ParseArguments that accepts a single string.

@ghost
Copy link
Author

ghost commented Dec 9, 2015

It goes down to the Windows API, CommandLineToArgvW. There's a lot of material about this weird behavior, like https://blogs.msdn.microsoft.com/oldnewthing/20100917-00/?p=12833/

Funny thing, it seems that DOS bat files behave differently. Wondering if they use a different API or if cmd reimplemented command line parsing.
i.e.
@echo %1
@echo %2

sample.cmd "this works\fine" "hello"
"this works\fine"
"hello"

@nemec
Copy link
Collaborator

nemec commented Dec 9, 2015

Yep, one argument against it is that the current behavior is standard, if quirky. Those familiar with Windows command line who know about escaping slashes may expect your tool to behave the same way.

@ghost
Copy link
Author

ghost commented Dec 9, 2015

Right, that's a valid point. I tried other command line libraries and they all rely on the same behavior. Probably we can live with it :)

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants