Node: Quoted command-line argument with space treats trailing backslash as escaping quote

Created on 17 Jul 2018  Â·  13Comments  Â·  Source: nodejs/node

  • Version: v8.11.3
  • Platform: Windows 10 Pro 64-bit
  • Subsystem:

console.log(process.argv);

The above will show the issue in a console application run from PowerShell.

If:

  • a command-line argument is passed
  • the argument is quoted
  • the argument is a path
  • the path contains a space
  • the path ends in a backslash

then the backslash will escape the final quote, which will be included in the argument value.

Example:
node foo "C:\Program Files\"

[ 'C:\\Program Files\\nodejs\\node.exe',
  'C:\\SourceCode\\foo\\foo.js',
  'C:\\Program Files"' ]

Note that the final argument ends with a double-quote instead of a backslash.

cli windows wrong repo

Most helpful comment

I have confirmed that @seishun is correct - this is a bug in PowerShell.

foo.c:

#include<stdio.h>

int main(int argc, char *argv[])
{
    if (argc >= 2)
        printf("%s", argv[1]);

    return 0;
}

Compiled with Microsoft C/C++ compiler v19.14.26433 for x86 to foo.exe

./foo "C:\Program Files\"

C:\Program Files"

I apologize for the erroneous bug report.

All 13 comments

FWIW, shell commands and batch files process such arguments properly:

> echo "C:\Program Files\"
"C:\Program Files\"

test.bat:

echo %1
> test.bat "C:\Program Files\"

> echo "C:\Program Files\"
"C:\Program Files\"

/cc @nodejs/platform-windows

@vsemozhetbyt can you confirm that this happens on master?

Cannot reproduce on MacOS.

➜ out/Release/node ~/Code/temp/node/cli.js "/dev/null"
[ '/Users/ryzokuken/Code/nodejs/node/out/Release/node',
  '/Users/ryzokuken/Code/temp/node/cli.js',
  '/dev/null' ]

Yes, this happens with 6.14.3, 8.11.3, 10.6.0 and 11.0.0-nightly20180717ab10bfe376.
Tested in Windows 7 x64 on cmd.exe.

Not a Node.js issue. This is how PowerShell and cmd parse arguments. Same behavior in Python.

The logic of actually setting the value is fairly trivial and fool-proof:

  // process.argv
  Local<Array> arguments = Array::New(env->isolate(), argc);
  for (int i = 0; i < argc; ++i) {
    arguments->Set(i, String::NewFromUtf8(env->isolate(), argv[i]));
  }
  process->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "argv"), arguments);

Perhaps there's something wrong with the argv value supplied itself?

@seishun thanks for the clarification.

Refs: https://ss64.com/nt/syntax-esc.html

Some commands (e.g. REG and FINDSTR) use the standard escape character of \ (as used by C, Python, SQL, bash and many other languages.)
The \ escape can cause problems with quoted directory paths that contain a trailing backslash because the closing quote " at the end of the line will be escaped \".

To save a directory path with a trailing backslash (\) requires adding a second backslash to 'escape the escape'
so for example instead of "C:\My Docs\" use "C:\My Docs\\"

@seishun If this is a PowerShell bug, why does this work correctly?

Get-ChildItem "C:\Program Files\"

    Directory: C:\Program Files


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         5/4/2018  11:12 PM                7-Zip
...

Get-ChildItem is a PowerShell intrinsic. Try it with any executable.

The similar issue with FINDSTR:

> cat test.txt

"C:\Program Files\"

> FINDSTR "C:\Program Files\\" test.txt
"C:\Program Files\"

> FINDSTR "C:\Program Files\" test.txt

The last commannd just waits for inputs (processing all the parameters as a one string?)

I have confirmed that @seishun is correct - this is a bug in PowerShell.

foo.c:

#include<stdio.h>

int main(int argc, char *argv[])
{
    if (argc >= 2)
        printf("%s", argv[1]);

    return 0;
}

Compiled with Microsoft C/C++ compiler v19.14.26433 for x86 to foo.exe

./foo "C:\Program Files\"

C:\Program Files"

I apologize for the erroneous bug report.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

addaleax picture addaleax  Â·  3Comments

Brekmister picture Brekmister  Â·  3Comments

seishun picture seishun  Â·  3Comments

filipesilvaa picture filipesilvaa  Â·  3Comments

cong88 picture cong88  Â·  3Comments