Skip to content
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

The quotation in cmd of Deno.run #8852

Closed
septbr opened this issue Dec 22, 2020 · 12 comments · Fixed by #16319
Closed

The quotation in cmd of Deno.run #8852

septbr opened this issue Dec 22, 2020 · 12 comments · Fixed by #16319
Labels
bug Something isn't working correctly runtime Relates to code in the runtime crate windows Related to Windows platform

Comments

@septbr
Copy link

septbr commented Dec 22, 2020


    await Deno.run({ cmd: ['TortoiseProc', '/command:commit', '/path:"D:\\xx\\yy"', '/logmsg:"update yy"']).status();

Expect

    TortoiseProc /command:commit /path:"D:\\xx\\yy" /logmsg:"update yy"

Result

    TortoiseProc /command:commit /path:\"D:\\xx\\yy\" /logmsg:\"update yy\"

    await Deno.run({ cmd: ['cmd', '/c', 'echo', '"x\\y"'], stdout: 'inherit', stderr: 'inherit'}).status();

Expect

    echo "x\y"

Result

    echo \"x\y\"

    await Deno.run({ cmd: ['cmd', '/c', 'echo', '""x\"'], stdout: 'inherit', stderr: 'inherit'}).status();

Expect

    echo ""x"

Result

    echo \"\"x\"\"

" in the result has been replaced by \"
"" or \" in the result has been replaced by \"\"

@stale
Copy link

stale bot commented Feb 21, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Feb 21, 2021
@stale stale bot closed this as completed Feb 28, 2021
@rivy
Copy link
Contributor

rivy commented Mar 8, 2021

Not stale.
This is still a problem for windows applications.

@nayeemrmn
Copy link
Collaborator

This seems expected, and rather a limitation of the CLIs of the applications being run. Does Node have different behaviour?

@rivy
Copy link
Contributor

rivy commented Mar 8, 2021

It's not a CLI limitation.
It's an ongoing problem with Rust's process::Command. Rust has the escape hatch of using the Win32 CreateProcess but Deno doesn't (and likely won't). The windows CreateProcess can take an arbitrary string, but Deno isn't set up to directly call the Win32 CreateProcess function.

And, yes, it's up to the target executable to interpret it, but any arbitrary command line string should be generable by the runtime.

This is definitely a problem when spawning child processes with arbitrary command lines on Windows. It is subtle and occurs as random command lines which panic with weird quoting errors (as the examples noted above). It's very problematic when trying to work around the windows cmd shell quoting quirks (which is needed for task runners; denox, devo, drake).

It's, unfortunately, a complicated issue. (Here's an issue that references some 'light' reading on the subject.)

Given the architecture and goals of Deno, I'm not sure of the best course forward. But I do think that some way to execute arbitrary command lines in Windows should be part of the Deno runtime, even if it's more complicated.

@rivy
Copy link
Contributor

rivy commented Mar 9, 2021

@nayeemrmn , here's a simple, specific example of why this is a problem...

...

Currently, it's impossible to execute certain valid Windows command lines in Deno. For example, cmd /d/c "deno eval -T "console.log('a string')"" is a valid executable command line ...

C:>cmd /d/c "deno eval -T "console.log('a string')""
Check file:///C:/Users/Roy/OneDrive/Projects/deno/$deno$eval.ts
a string

when implemented via Deno.run(...) ...

await Deno.run({cmd: ['cmd', '/d/c', '"deno eval -T "console.log(\'a string\')""']}).status();
// => `The system cannot find the path specified.`

or ...

await Deno.run({cmd: ['cmd', '/d/c', 'deno eval -T "console.log(\'a string\')"']}).status();
// => `error: Unterminated string constant at file:///C:/Users/Roy/OneDrive/Projects/deno/$deno$eval.ts:1:0`

It's not possible to construct this command line because the inner double quotes are escaped, which, in turn, breaks the interpretation by cmd.

...

Notably, node can execute this command line using exec('cmd /d/c "deno eval -T "console.log(\'a string\')""', ...).

@rivy
Copy link
Contributor

rivy commented Mar 23, 2021

@nayeemrmn , can you re-open this?

@nayeemrmn
Copy link
Collaborator

I'm not a maintainer (cc @lucacasonato).

The issue seems valid, if exec('cmd /d/c "deno eval -T "console.log(\'a string\')""', ...) in Node doesn't have a working equivalent in Deno.

@lucacasonato lucacasonato reopened this Mar 23, 2021
@lucacasonato
Copy link
Member

cc @piscisaureus

@max-pub
Copy link

max-pub commented Apr 12, 2022

any progress on this?

@piscisaureus
Copy link
Member

piscisaureus commented Apr 12, 2022

Rust actually has raw_arg. We could use that.

@FKPSC
Copy link

FKPSC commented May 13, 2022

I am running into many issues with Deno.run as well. Running commands like start "app\\Cool app.exe" seems to be literally impossible. If there is a way to do it, please let me know and document it somewhere.

This command is also seemingly impossible to run:
reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -v ReleaseID

A viable workaround would be to echo the command into a .cmd file and then run it.

@kt3k
Copy link
Member

kt3k commented Oct 16, 2022

In Node.js, child_process.spawn has windowsVerbatimArguments option for controlling arg escaping enabled/disabled. https://nodejs.org/api/child_process.html#child_processspawncommand-args-options

And that option is used by cross-spawn npm module. ref: https://github.com/moxystudio/node-cross-spawn/blob/5d843849e1ed434b7030e0aa49281c2bf4ad2e71/lib/parse.js#L59

This issue causes the usage of cross-spawn (via compat feat) always failing on windows.

kt3k added a commit that referenced this issue Oct 17, 2022
This change adds `windowsRawArguments` to `SpawnOptions`. The option enables
skipping the default quoting and escaping while creating the command on
windows.

The option works in a similar way as `windowsVerbatimArguments` in
child_process.spawn options in Node.js, and is necessary for simulating
it in `std/node`.

closes #8852
bartlomieju pushed a commit that referenced this issue Oct 17, 2022
This change adds `windowsRawArguments` to `SpawnOptions`. The option enables
skipping the default quoting and escaping while creating the command on
windows.

The option works in a similar way as `windowsVerbatimArguments` in
child_process.spawn options in Node.js, and is necessary for simulating
it in `std/node`.

closes #8852
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working correctly runtime Relates to code in the runtime crate windows Related to Windows platform
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants