Index: tools/gn/value.cc |
diff --git a/tools/gn/value.cc b/tools/gn/value.cc |
index 1a4215ce29e19569b344a5adf1507a603f8416b6..6dfe23417a4a4d6ee3183e613561bc7f434b1c18 100644 |
--- a/tools/gn/value.cc |
+++ b/tools/gn/value.cc |
@@ -124,27 +124,15 @@ |
return base::Int64ToString(int_value_); |
case STRING: |
if (quote_string) { |
- 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; |
+ 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 + "\""; |
} |
return string_value_; |
case LIST: { |