Commit 58a4c7b0 authored by brettw@chromium.org's avatar brettw@chromium.org

Escape more characters for GN shell writing.

BUG=358764
TBR=scottmg

Review URL: https://codereview.chromium.org/305653008

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@273857 0039d316-1c4b-4281-b951-d872f2087c98
parent e9382023
...@@ -8,6 +8,24 @@ ...@@ -8,6 +8,24 @@
namespace { namespace {
// A "1" in this lookup table means that char is valid in the shell.
const char kShellValid[0x80] = {
// 00-1f: all are invalid
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// ' ' ! " # $ % & ' ( ) * + , - . /
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0,
// @ A B C D E F G H I J K L M N O
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
// P Q R S T U V W X Y Z [ \ ] ^ _
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1,
// ` a b c d e f g h i j k l m n o
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
// p q r s t u v w x y z { | } ~
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0 };
template<typename DestString> template<typename DestString>
void EscapeStringToString(const base::StringPiece& str, void EscapeStringToString(const base::StringPiece& str,
const EscapeOptions& options, const EscapeOptions& options,
...@@ -17,14 +35,12 @@ void EscapeStringToString(const base::StringPiece& str, ...@@ -17,14 +35,12 @@ void EscapeStringToString(const base::StringPiece& str,
for (size_t i = 0; i < str.size(); i++) { for (size_t i = 0; i < str.size(); i++) {
if (str[i] == '$' && (options.mode & ESCAPE_NINJA)) { if (str[i] == '$' && (options.mode & ESCAPE_NINJA)) {
// Escape dollars signs since ninja treats these specially. // Escape dollars signs since ninja treats these specially. If we're also
// escaping for the shell, we need to backslash-escape that again.
if (options.mode & ESCAPE_SHELL)
dest->push_back('\\');
dest->push_back('$'); dest->push_back('$');
dest->push_back('$'); dest->push_back('$');
} else if (str[i] == '"' && (options.mode & ESCAPE_SHELL)) {
// Escape quotes with backslashes for the command-line (Ninja doesn't
// care).
dest->push_back('\\');
dest->push_back('"');
} else if (str[i] == ' ') { } else if (str[i] == ' ') {
if (options.mode & ESCAPE_NINJA) { if (options.mode & ESCAPE_NINJA) {
// For Ninja just escape spaces with $. // For Ninja just escape spaces with $.
...@@ -61,6 +77,12 @@ void EscapeStringToString(const base::StringPiece& str, ...@@ -61,6 +77,12 @@ void EscapeStringToString(const base::StringPiece& str,
} else if (str[i] == ':' && (options.mode & ESCAPE_NINJA)) { } else if (str[i] == ':' && (options.mode & ESCAPE_NINJA)) {
dest->push_back('$'); dest->push_back('$');
dest->push_back(':'); dest->push_back(':');
} else if ((options.mode & ESCAPE_SHELL) &&
(static_cast<unsigned>(str[i]) >= 0x80 ||
!kShellValid[static_cast<int>(str[i])])) {
// All other invalid shell chars get backslash-escaped.
dest->push_back('\\');
dest->push_back(str[i]);
} else { } else {
dest->push_back(str[i]); dest->push_back(str[i]);
} }
......
...@@ -19,10 +19,24 @@ TEST(Escape, Shell) { ...@@ -19,10 +19,24 @@ TEST(Escape, Shell) {
#if defined(OS_WIN) #if defined(OS_WIN)
// Windows shell doesn't escape backslashes, but it does backslash-escape // Windows shell doesn't escape backslashes, but it does backslash-escape
// quotes. // quotes.
EXPECT_EQ("\"asdf: \\\"$\\bar\"", result); EXPECT_EQ("\"asdf: \\\"\\$\\bar\"", result);
#else #else
EXPECT_EQ("\"asdf: \\\"$\\\\bar\"", result); EXPECT_EQ("\"asdf: \\\"\\$\\\\bar\"", result);
#endif #endif
// Some more generic shell chars.
result = EscapeString("a_;<*b", opts, NULL);
EXPECT_EQ("a_\\;\\<\\*b", result);
}
TEST(Escape, NinjaShell) {
EscapeOptions opts;
opts.mode = ESCAPE_NINJA_SHELL;
// When escaping for Ninja and the shell, we would escape a $, then escape
// the backslash again.
std::string result = EscapeString("a$b", opts, NULL);
EXPECT_EQ("a\\$$b", result);
} }
TEST(Escape, UsedQuotes) { TEST(Escape, UsedQuotes) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment