[pushed] json: fix escaping of object keys
David Malcolm
dmalcolm@redhat.com
Sat Dec 16 21:23:41 GMT 2023
Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Successful run of analyzer integration tests on x86_64-pc-linux-gnu.
Pushed to trunk as r14-6634-g30d9a3a69841b1.
gcc/ChangeLog:
* json.cc (print_escaped_json_string): New, taken from
string::print.
(object::print): Use it for printing keys.
(string::print): Move implementation to
print_escaped_json_string.
(selftest::test_writing_objects): Add a key containing
quote, backslash, and control characters.
Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
gcc/json.cc | 94 ++++++++++++++++++++++++++++++-----------------------
1 file changed, 54 insertions(+), 40 deletions(-)
diff --git a/gcc/json.cc b/gcc/json.cc
index 90ddd7ab3b15..350917af5df1 100644
--- a/gcc/json.cc
+++ b/gcc/json.cc
@@ -28,6 +28,52 @@ along with GCC; see the file COPYING3. If not see
using namespace json;
+/* Print a JSON string to PP, escaping '"', control characters,
+ and embedded null bytes.
+ The string is required to be UTF-8 encoded. */
+
+static void
+print_escaped_json_string (pretty_printer *pp,
+ const char *utf8_str,
+ size_t len)
+{
+ pp_character (pp, '"');
+ for (size_t i = 0; i != len; ++i)
+ {
+ char ch = utf8_str[i];
+ switch (ch)
+ {
+ case '"':
+ pp_string (pp, "\\\"");
+ break;
+ case '\\':
+ pp_string (pp, "\\\\");
+ break;
+ case '\b':
+ pp_string (pp, "\\b");
+ break;
+ case '\f':
+ pp_string (pp, "\\f");
+ break;
+ case '\n':
+ pp_string (pp, "\\n");
+ break;
+ case '\r':
+ pp_string (pp, "\\r");
+ break;
+ case '\t':
+ pp_string (pp, "\\t");
+ break;
+ case '\0':
+ pp_string (pp, "\\0");
+ break;
+ default:
+ pp_character (pp, ch);
+ }
+ }
+ pp_character (pp, '"');
+}
+
/* class json::value. */
/* Dump this json::value tree to OUTF.
@@ -85,9 +131,7 @@ object::print (pretty_printer *pp, bool formatted) const
}
map_t &mut_map = const_cast<map_t &> (m_map);
value *value = *mut_map.get (key);
- pp_doublequote (pp);
- pp_string (pp, key); // FIXME: escaping?
- pp_doublequote (pp);
+ print_escaped_json_string (pp, key, strlen (key));
pp_string (pp, ": ");
const int indent = strlen (key) + 4;
if (formatted)
@@ -284,41 +328,7 @@ void
string::print (pretty_printer *pp,
bool formatted ATTRIBUTE_UNUSED) const
{
- pp_character (pp, '"');
- for (size_t i = 0; i != m_len; ++i)
- {
- char ch = m_utf8[i];
- switch (ch)
- {
- case '"':
- pp_string (pp, "\\\"");
- break;
- case '\\':
- pp_string (pp, "\\\\");
- break;
- case '\b':
- pp_string (pp, "\\b");
- break;
- case '\f':
- pp_string (pp, "\\f");
- break;
- case '\n':
- pp_string (pp, "\\n");
- break;
- case '\r':
- pp_string (pp, "\\r");
- break;
- case '\t':
- pp_string (pp, "\\t");
- break;
- case '\0':
- pp_string (pp, "\\0");
- break;
- default:
- pp_character (pp, ch);
- }
- }
- pp_character (pp, '"');
+ print_escaped_json_string (pp, m_utf8, m_len);
}
/* class json::literal, a subclass of json::value. */
@@ -388,13 +398,17 @@ test_writing_objects ()
object obj;
obj.set_string ("foo", "bar");
obj.set_string ("baz", "quux");
+ obj.set_string ("\"\\\b\f\n\r\t", "value for awkward key");
+
/* This test relies on json::object writing out key/value pairs
in key-insertion order. */
ASSERT_PRINT_EQ (obj, true,
"{\"foo\": \"bar\",\n"
- " \"baz\": \"quux\"}");
+ " \"baz\": \"quux\",\n"
+ " \"\\\"\\\\\\b\\f\\n\\r\\t\": \"value for awkward key\"}");
ASSERT_PRINT_EQ (obj, false,
- "{\"foo\": \"bar\", \"baz\": \"quux\"}");
+ "{\"foo\": \"bar\", \"baz\": \"quux\""
+ ", \"\\\"\\\\\\b\\f\\n\\r\\t\": \"value for awkward key\"}");
}
/* Verify that JSON arrays are written correctly. */
--
2.26.3
More information about the Gcc-patches
mailing list