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

fix: correctly double escape when script runs a known .cmd file #80

Merged
merged 2 commits into from
Jun 22, 2022

Conversation

nlf
Copy link
Contributor

@nlf nlf commented Jun 21, 2022

as called out by @rhendric, i neglected to do the necessary checks to see if we need to double escape additional arguments being passed to a .cmd file

this change makes it so that we attempt to look up the full path that the command will resolve to, and if we can and that thing is a .cmd file, then we double escape the arguments we pass to it. if not, we single escape.

as noted in his comment this does not mean that all scripts will work perfectly, as there are many complex use cases that we will fail to support here. however this gets us significantly further along than we were and i believe addresses the vast majority of scripts in the wild.

@nlf nlf requested a review from a team as a code owner June 21, 2022 23:31
@nlf nlf force-pushed the nlf/double-escape-batch-args branch from bbc3947 to b39f99b Compare June 21, 2022 23:33
@nlf nlf force-pushed the nlf/double-escape-batch-args branch from b39f99b to 9f187df Compare June 21, 2022 23:58
Comment on lines 68 to 70
if (doubleEscape) {
result = escape.cmd(result)
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to double up your backslash escapes too, which I believe you don't want. There are two escape mechanisms at work here: a low-level one that is part of the Windows command line conventions, and a higher-level one specific to cmd.exe. Only the latter should be applied twice in case of a batch file. (That means doubling up your carets, and possibly in your implementation doubling up your percents as well. When I implemented this in Puka, I escaped percents with carets just like any other character special to cmd.exe, so I don't have tests covering what happens when you try to escape percents by doubling them.)

(You could just import that escaping function as quoteForCmd from Puka's public exports, BTW, instead of rolling your own. No modifications necessary. If batch file, provide 1 as the third argument (this parameter admittedly is currently undocumented but it probably makes sense for me to make it public API). I'm not trying to pressure you into using my library out of pride, but my automated tests throw hundreds of randomly-generated strings that focus on all the edge cases I know about at that implementation and actually run the results through cmd.exe to make sure that the escaping is correct. I'm very confident in it. If I'm reviewing an implementation that does something different and doesn't have a similarly robust test suite behind it, I'm going to be a lot less confident I've caught all the problems in it.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is going to double up your backslash escapes too, which I believe you don't want. There are two escape mechanisms at work here: a low-level one that is part of the Windows command line conventions, and a higher-level one specific to cmd.exe. Only the latter should be applied twice in case of a batch file.

ahhhhh! i understand. i did some hands on testing on my windows machine and adapted the code to not double up the backslashes, as you mentioned. i also refactored the tests and added a whole bunch more cases.

When I implemented this in Puka, I escaped percents with carets just like any other character special to cmd.exe

the % encoding to %% behavior is specific to batch files, which we're now using, so that's why we have differences there

my automated tests throw hundreds of randomly-generated strings that focus on all the edge cases I know about at that implementation and actually run the results through cmd.exe to make sure that the escaping is correct

I really liked this idea, so for now I at least made it so each of the expectations in the tests will spawn an actual process and ensures that the output matches the input. this will at least make it really easy to add regression tests

@nlf nlf force-pushed the nlf/double-escape-batch-args branch 3 times, most recently from 296d395 to 7052862 Compare June 22, 2022 19:28
@nlf nlf force-pushed the nlf/double-escape-batch-args branch from 7052862 to 8c62010 Compare June 22, 2022 19:34
pathToInitial = initialCmd.toLowerCase()
}

const doubleEscape = pathToInitial.endsWith('.cmd') || pathToInitial.endsWith('.bat')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How certain are we this list is comprehensive?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the default value of %PATHEXT% at least on my machine is .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC

of these, .BAT and .CMD are the only two that run through cmd.exe so i feel pretty ok about it

Copy link
Member

@wraithgar wraithgar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved w/ one double check question.

@nlf nlf merged commit 0f613cd into main Jun 22, 2022
@nlf nlf deleted the nlf/double-escape-batch-args branch June 22, 2022 21:12
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

Successfully merging this pull request may close these issues.

3 participants