dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.07k stars 1.56k forks source link

Dart parses quotation marks in arguments incorrectly on Windows #46079

Open nex3 opened 3 years ago

nex3 commented 3 years ago

When passing an argument that contains an escaped quotation mark to a Dart application on Windows, that argument will include the entire rest of the command line as well. For example (Note that "" is an escaped quotation mark, per MSDN):

// test.dart
import 'package:convert';

void main(List<String> args) => print(json.encode(args));
> dart test.dart "foo""bar" baz
["foo\"bar baz","baz"]

In addition, if there's a space after the escaped quotation mark, that's parsed as a separate argument entirely:

> dart test.dart "foo "" bar" baz
["foo \"","bar baz"]

I'm using Dart 2.12.4. This also occurs for the dart, dart2native, dart compile exe, and dart2js executables when passed -D variables that contain quotes.

lrhn commented 3 years ago

Definitely something iffy going on with double-quotes. Using: main(args) => args.forEach((x) => print("<$x>"));, I get:

dart args.dart "a""b" c
<a"b c>
<c>

Spaces seem fine, the double-quotes break something in the argument parser.

The parameter handling should be done by compiler-inserted code, so it's weird that it doesn't work. We are not using the Visual C++ compiler any more, so maybe the clang compile does something wrong compared to the Visual C++ behavior. But, when I compile the following with clang-cl.exe, it works just like it should:

#include <stdio.h>
int main(int argc, const char* argv[]) {
  for (int i = 1; i < argc; i++) {
     printf("<%s>", argv[i]);
  }
}

So it looks like it's something we do wrong, on top of what the compiler already does correctly.

Or maybe we are double-parsing the parameters, if we pass them to another tool as a command-line without escaping them again. (It doesn't match the symptoms, though, not even if we are trying to escape naively).