1
0
mirror of https://github.com/roytam1/UXP.git synced 2026-05-26 13:58:49 +00:00

[devtools] Further improve special character escaping in "copy as curl".

Follow-up to 15335ce39d1ea2ef4585a36a4d562a3894459a15

Trying to cross-platform sanitize causes issues escaping too much and
as a result mangling the curl commands that get spit out.
This reverts previously added Windows-specific escaping on POSIX and
vice versa.
Since we do not offer cross-platform copying as a curl command in devtools
anyway, it makes little sense to sanitize for the O.S. we're not running on
as we would not be using the command processor in such environments that
could trip over characters for the other O.S. This was previously added
as a defense-in-depth in case we would start offering this, but I see no
real reason to do so, anyway.

Also decided to in-line comments for readability instead of a bulleted
list in the function head.

Mozilla has taken similar steps because of fall-out, but they do offer
cross-platform "copy as curl" for corner cases, so they will have to
find solutions for a problem we won't have.
This commit is contained in:
Moonchild
2025-07-04 22:41:03 +02:00
committed by roytam1
parent e6b48fcc95
commit 2d9cb22a28
+27 -38
View File
@@ -395,9 +395,6 @@ const CurlUtils = {
return "\\u" + ("0000" + code).substr(code.length, 4);
}
// Escape & and |, which are special characters on Windows.
const winSpecialCharsRegEx = /([&\|])/g;
if (/[^\x20-\x7E]|\'/.test(str)) {
// Use ANSI-C quoting syntax.
return "$\'" + str.replace(/\\/g, "\\\\")
@@ -405,58 +402,50 @@ const CurlUtils = {
.replace(/\n/g, "\\n")
.replace(/\r/g, "\\r")
.replace(/!/g, "\\041")
.replace(winSpecialCharsRegEx, "^$1")
.replace(/[^\x20-\x7E]/g, escapeCharacter) + "'";
}
// Use single quote syntax.
return "'" + str.replace(winSpecialCharsRegEx, "^$1") + "'";
return "'" + str + "'";
},
/**
* Escape util function for Windows systems.
*/
escapeStringWin: function (str) {
/*
Because the cmd.exe parser and the MS Crt arguments parsers use some
of the same escape characters, they can interact with each other in
terrible ways, meaning the order of operations is critical here.
1. Replace \ with \\ first, because it is an escape character for
certain conditions in both parsers.
2. Escape double quotes with double backslashes.
3. Escape ` and $ so commands do not get executed, e.g $(calc.exe) or
`\$(calc.exe)
4. Escape all characters we are not sure about with ^, to ensure it
gets to the MS Crt arguments parser safely.
5. The % character is special because the MS Crt arguments parser will
try and look for environment variables and fill them in, in-place. We
cannot escape them with % and cannot escape them with ^ (because it's
cmd.exe's escape, not the MS Crt arguments parser). So, we can get the
cmd.exe parser to escape the character after it, if it is followed by
a valid starting character of an environment variable.
This ensures we do not try and double-escape another ^ if it was placed
by the previous replace.
6. Lastly, we replace new lines with ^ and TWO new lines, because the
first new line is there to enact the escape command, and the second is
the character to escape (in this case new line).
*/
const encapsChars = '^"';
const encapsChars = '"';
return (
encapsChars +
str
// Replace \ with \\ first because it is an escape character for certain
// conditions in both parsers.
.replace(/\\/g, "\\\\")
.replace(/"/g, '\\"')
// Replace double quote chars with two double quotes (not by escaping with \")
// because it is recognized by both cmd.exe and MS CRT arguments parser.
.replace(/"/g, '""')
// Escape ` and $ so commands do not get executed e.g $(calc.exe) or `\$(calc.exe)
.replace(/[`$]/g, "\\$&")
// Then escape all characters we are not sure about with ^ to ensure it
// gets to the MS CRT parser safely.
.replace(/[^a-zA-Z0-9\s_\-:=+~\/.',?;()*\$&\\{}\"`]/g, "^$&")
// The % character is special because MS CRT parser will try and look for
// ENV variables and fill them in its place. We cannot escape them with %
// and cannot escape them with ^ (because it's cmd.exe's escape not MS CRT
// parser); So we can get cmd.exe parser to escape the character after it,
// if it is followed by a valid beginning character of an ENV variable.
// This ensures we do not try and double escape another ^ if it was placed
// by the previous replace.
.replace(/%(?=[a-zA-Z0-9_])/g, "%^")
.replace(/\r?\n/g, "^\n\n")
+ encapsChars);
// We replace \r and \r\n with \n, this allows to consistently escape all new
// lines in the next replace
.replace(/\r\n?/g, "\n")
// Lastly we replace new lines with ^ and TWO new lines because the first
// new line is there to enact the escape command the second is the character
// to escape (in this case new line).
// The extra " enables escaping new lines with ^ within quotes in cmd.exe.
.replace(/\n/g, '"^\r\n\r\n"')
+ encapsChars
);
}
};