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

Merged
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args
Jun 22, 2022
Merged

fix: correctly double escape when script runs a known .cmd file#80
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args

Conversation

@nlf

@nlfnlf commented Jun 21, 2022

Copy link
Copy Markdown
Contributor

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 ownerJune 21, 2022 23:31
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from bbc3947 to b39f99bCompareJune 21, 2022 23:33
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from b39f99b to 9f187dfCompareJune 21, 2022 23:58
Comment threadlib/make-spawn-args.js Outdated
Comment on lines +68 to +70
if (doubleEscape) {
result = escape.cmd(result)
}

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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
nlfforce-pushed the nlf/double-escape-batch-args branch 3 times, most recently from 296d395 to 7052862CompareJune 22, 2022 19:28
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from 7052862 to 8c62010CompareJune 22, 2022 19:34
pathToInitial = initialCmd.toLowerCase()
}

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

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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

@wraithgarwraithgar left a comment

Copy link
Copy Markdown
Contributor

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 mainJun 22, 2022
@nlf
nlf deleted the nlf/double-escape-batch-args branch June 22, 2022 21:12
@github-actionsgithub-actionsBot mentioned this pull request Jun 22, 2022
Sign up for freeto 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

@nlf@wraithgar@rhendric
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

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

Merged
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args
Jun 22, 2022
Merged

fix: correctly double escape when script runs a known .cmd file#80
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args

Conversation

@nlf

@nlfnlf commented Jun 21, 2022

Copy link
Copy Markdown
Contributor

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 ownerJune 21, 2022 23:31
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from bbc3947 to b39f99bCompareJune 21, 2022 23:33
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from b39f99b to 9f187dfCompareJune 21, 2022 23:58
Comment threadlib/make-spawn-args.js Outdated
Comment on lines +68 to +70
if (doubleEscape) {
result = escape.cmd(result)
}

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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
nlfforce-pushed the nlf/double-escape-batch-args branch 3 times, most recently from 296d395 to 7052862CompareJune 22, 2022 19:28
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from 7052862 to 8c62010CompareJune 22, 2022 19:34
pathToInitial = initialCmd.toLowerCase()
}

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

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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

@wraithgarwraithgar left a comment

Copy link
Copy Markdown
Contributor

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 mainJun 22, 2022
@nlf
nlf deleted the nlf/double-escape-batch-args branch June 22, 2022 21:12
@github-actionsgithub-actionsBot mentioned this pull request Jun 22, 2022
Sign up for freeto 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

@nlf@wraithgar@rhendric
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

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

Merged
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args
Jun 22, 2022
Merged

fix: correctly double escape when script runs a known .cmd file#80
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args

Conversation

@nlf

@nlfnlf commented Jun 21, 2022

Copy link
Copy Markdown
Contributor

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 ownerJune 21, 2022 23:31
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from bbc3947 to b39f99bCompareJune 21, 2022 23:33
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from b39f99b to 9f187dfCompareJune 21, 2022 23:58
Comment threadlib/make-spawn-args.js Outdated
Comment on lines +68 to +70
if (doubleEscape) {
result = escape.cmd(result)
}

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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
nlfforce-pushed the nlf/double-escape-batch-args branch 3 times, most recently from 296d395 to 7052862CompareJune 22, 2022 19:28
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from 7052862 to 8c62010CompareJune 22, 2022 19:34
pathToInitial = initialCmd.toLowerCase()
}

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

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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

@wraithgarwraithgar left a comment

Copy link
Copy Markdown
Contributor

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 mainJun 22, 2022
@nlf
nlf deleted the nlf/double-escape-batch-args branch June 22, 2022 21:12
@github-actionsgithub-actionsBot mentioned this pull request Jun 22, 2022
Sign up for freeto 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

@nlf@wraithgar@rhendric
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

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

Merged
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args
Jun 22, 2022
Merged

fix: correctly double escape when script runs a known .cmd file#80
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args

Conversation

@nlf

@nlfnlf commented Jun 21, 2022

Copy link
Copy Markdown
Contributor

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 ownerJune 21, 2022 23:31
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from bbc3947 to b39f99bCompareJune 21, 2022 23:33
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from b39f99b to 9f187dfCompareJune 21, 2022 23:58
Comment threadlib/make-spawn-args.js Outdated
Comment on lines +68 to +70
if (doubleEscape) {
result = escape.cmd(result)
}

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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
nlfforce-pushed the nlf/double-escape-batch-args branch 3 times, most recently from 296d395 to 7052862CompareJune 22, 2022 19:28
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from 7052862 to 8c62010CompareJune 22, 2022 19:34
pathToInitial = initialCmd.toLowerCase()
}

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

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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

@wraithgarwraithgar left a comment

Copy link
Copy Markdown
Contributor

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 mainJun 22, 2022
@nlf
nlf deleted the nlf/double-escape-batch-args branch June 22, 2022 21:12
@github-actionsgithub-actionsBot mentioned this pull request Jun 22, 2022
Sign up for freeto 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

@nlf@wraithgar@rhendric
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

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

Merged
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args
Jun 22, 2022
Merged

fix: correctly double escape when script runs a known .cmd file#80
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args

Conversation

@nlf

@nlfnlf commented Jun 21, 2022

Copy link
Copy Markdown
Contributor

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 ownerJune 21, 2022 23:31
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from bbc3947 to b39f99bCompareJune 21, 2022 23:33
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from b39f99b to 9f187dfCompareJune 21, 2022 23:58
Comment threadlib/make-spawn-args.js Outdated
Comment on lines +68 to +70
if (doubleEscape) {
result = escape.cmd(result)
}

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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
nlfforce-pushed the nlf/double-escape-batch-args branch 3 times, most recently from 296d395 to 7052862CompareJune 22, 2022 19:28
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from 7052862 to 8c62010CompareJune 22, 2022 19:34
pathToInitial = initialCmd.toLowerCase()
}

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

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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

@wraithgarwraithgar left a comment

Copy link
Copy Markdown
Contributor

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 mainJun 22, 2022
@nlf
nlf deleted the nlf/double-escape-batch-args branch June 22, 2022 21:12
@github-actionsgithub-actionsBot mentioned this pull request Jun 22, 2022
Sign up for freeto 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

@nlf@wraithgar@rhendric
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

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

Merged
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args
Jun 22, 2022
Merged

fix: correctly double escape when script runs a known .cmd file#80
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args

Conversation

@nlf

@nlfnlf commented Jun 21, 2022

Copy link
Copy Markdown
Contributor

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 ownerJune 21, 2022 23:31
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from bbc3947 to b39f99bCompareJune 21, 2022 23:33
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from b39f99b to 9f187dfCompareJune 21, 2022 23:58
Comment threadlib/make-spawn-args.js Outdated
Comment on lines +68 to +70
if (doubleEscape) {
result = escape.cmd(result)
}

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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
nlfforce-pushed the nlf/double-escape-batch-args branch 3 times, most recently from 296d395 to 7052862CompareJune 22, 2022 19:28
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from 7052862 to 8c62010CompareJune 22, 2022 19:34
pathToInitial = initialCmd.toLowerCase()
}

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

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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

@wraithgarwraithgar left a comment

Copy link
Copy Markdown
Contributor

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 mainJun 22, 2022
@nlf
nlf deleted the nlf/double-escape-batch-args branch June 22, 2022 21:12
@github-actionsgithub-actionsBot mentioned this pull request Jun 22, 2022
Sign up for freeto 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

@nlf@wraithgar@rhendric
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

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

Merged
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args
Jun 22, 2022
Merged

fix: correctly double escape when script runs a known .cmd file#80
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args

Conversation

@nlf

@nlfnlf commented Jun 21, 2022

Copy link
Copy Markdown
Contributor

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 ownerJune 21, 2022 23:31
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from bbc3947 to b39f99bCompareJune 21, 2022 23:33
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from b39f99b to 9f187dfCompareJune 21, 2022 23:58
Comment threadlib/make-spawn-args.js Outdated
Comment on lines +68 to +70
if (doubleEscape) {
result = escape.cmd(result)
}

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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
nlfforce-pushed the nlf/double-escape-batch-args branch 3 times, most recently from 296d395 to 7052862CompareJune 22, 2022 19:28
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from 7052862 to 8c62010CompareJune 22, 2022 19:34
pathToInitial = initialCmd.toLowerCase()
}

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

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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

@wraithgarwraithgar left a comment

Copy link
Copy Markdown
Contributor

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 mainJun 22, 2022
@nlf
nlf deleted the nlf/double-escape-batch-args branch June 22, 2022 21:12
@github-actionsgithub-actionsBot mentioned this pull request Jun 22, 2022
Sign up for freeto 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

@nlf@wraithgar@rhendric
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

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

Merged
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args
Jun 22, 2022
Merged

fix: correctly double escape when script runs a known .cmd file#80
nlf merged 2 commits into
mainfrom
nlf/double-escape-batch-args

Conversation

@nlf

@nlfnlf commented Jun 21, 2022

Copy link
Copy Markdown
Contributor

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 ownerJune 21, 2022 23:31
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from bbc3947 to b39f99bCompareJune 21, 2022 23:33
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from b39f99b to 9f187dfCompareJune 21, 2022 23:58
Comment threadlib/make-spawn-args.js Outdated
Comment on lines +68 to +70
if (doubleEscape) {
result = escape.cmd(result)
}

Copy link
Copy Markdown

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
Copy Markdown
ContributorAuthor

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
nlfforce-pushed the nlf/double-escape-batch-args branch 3 times, most recently from 296d395 to 7052862CompareJune 22, 2022 19:28
@nlf
nlfforce-pushed the nlf/double-escape-batch-args branch from 7052862 to 8c62010CompareJune 22, 2022 19:34
pathToInitial = initialCmd.toLowerCase()
}

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

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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

@wraithgarwraithgar left a comment

Copy link
Copy Markdown
Contributor

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 mainJun 22, 2022
@nlf
nlf deleted the nlf/double-escape-batch-args branch June 22, 2022 21:12
@github-actionsgithub-actionsBot mentioned this pull request Jun 22, 2022
Sign up for freeto 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

@nlf@wraithgar@rhendric