| Index: tools/gn/value.cc
|
| diff --git a/tools/gn/value.cc b/tools/gn/value.cc
|
| index 6dfe23417a4a4d6ee3183e613561bc7f434b1c18..1a4215ce29e19569b344a5adf1507a603f8416b6 100644
|
| --- a/tools/gn/value.cc
|
| +++ b/tools/gn/value.cc
|
| @@ -124,15 +124,27 @@
|
| return base::Int64ToString(int_value_);
|
| case STRING:
|
| if (quote_string) {
|
| - std::string escaped = string_value_;
|
| - // First escape all special uses of a backslash.
|
| - ReplaceSubstringsAfterOffset(&escaped, 0, "\\$", "\\\\$");
|
| - ReplaceSubstringsAfterOffset(&escaped, 0, "\\\"", "\\\\\"");
|
| -
|
| - // Now escape special chars.
|
| - ReplaceSubstringsAfterOffset(&escaped, 0, "$", "\\$");
|
| - ReplaceSubstringsAfterOffset(&escaped, 0, "\"", "\\\"");
|
| - return "\"" + escaped + "\"";
|
| + std::string result = "\"";
|
| + bool hanging_backslash = false;
|
| + for (char ch : string_value_) {
|
| + // If the last character was a literal backslash and the next
|
| + // character could form a valid escape sequence, we need to insert
|
| + // an extra backslash to prevent that.
|
| + if (hanging_backslash && (ch == '$' || ch == '"' || ch == '\\'))
|
| + result += '\\';
|
| + // If the next character is a dollar sign or double quote, it needs
|
| + // to be escaped; otherwise it can be printed as is.
|
| + if (ch == '$' || ch == '"')
|
| + result += '\\';
|
| + result += ch;
|
| + hanging_backslash = (ch == '\\');
|
| + }
|
| + // Again, we need to prevent the closing double quotes from becoming
|
| + // an escape sequence.
|
| + if (hanging_backslash)
|
| + result += '\\';
|
| + result += '"';
|
| + return result;
|
| }
|
| return string_value_;
|
| case LIST: {
|
|
|