Use JSON escaping for JSON string output The previous code used Value::ToString to convert GN strings into quoted JSON strings, but this caused incorrect escaping behavior. For example, the string "$" needs to be escaped in Ninja to prevent accidental variable expansion but not in JSON. Change-Id: I91c8e9b2486a67af5a3ba41efdb731aa31cc6df3 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/18900 Commit-Queue: Takuto Ikuta <tikuta@google.com> Reviewed-by: Takuto Ikuta <tikuta@google.com>
diff --git a/src/gn/output_conversion.cc b/src/gn/output_conversion.cc index 971e740..3bfbb10 100644 --- a/src/gn/output_conversion.cc +++ b/src/gn/output_conversion.cc
@@ -4,6 +4,7 @@ #include "gn/output_conversion.h" +#include "gn/escape.h" #include "gn/settings.h" #include "gn/value.h" @@ -37,8 +38,10 @@ RenderScopeToJSON(value, out, indent + 1); else if (value.type() == Value::LIST) RenderListToJSON(value, out, indent + 1); + else if (value.type() == Value::STRING) + EscapeJSONStringToStream(out, value.ToString(false), EscapeOptions()); else - out << value.ToString(true); + out << value.ToString(false); first = false; } out << "\n"; @@ -61,8 +64,11 @@ RenderScopeToJSON(pair.second, out, indent + 1); else if (pair.second.type() == Value::LIST) RenderListToJSON(pair.second, out, indent + 1); + else if (pair.second.type() == Value::STRING) + EscapeJSONStringToStream(out, pair.second.ToString(false), + EscapeOptions()); else - out << pair.second.ToString(true); + out << pair.second.ToString(false); first = false; } out << "\n";
diff --git a/src/gn/output_conversion_unittest.cc b/src/gn/output_conversion_unittest.cc index 43fdad5..1eaf2ab 100644 --- a/src/gn/output_conversion_unittest.cc +++ b/src/gn/output_conversion_unittest.cc
@@ -186,8 +186,11 @@ auto c_scope = std::make_unique<Scope>(settings()); Value e_value(nullptr, Value::LIST); e_value.list_value().push_back(Value(nullptr, "bar")); + e_value.list_value().push_back(Value(nullptr, "$")); auto e_value_scope = std::make_unique<Scope>(settings()); + Value d_value(nullptr, "$"); + e_value_scope->SetValue("d", d_value, nullptr); Value f_value(nullptr, "baz"); e_value_scope->SetValue("f", f_value, nullptr); e_value.list_value().push_back(Value(nullptr, std::move(e_value_scope))); @@ -202,7 +205,9 @@ "c": { "e": [ "bar", + "$", { + "d": "$", "f": "baz" } ]