aboutsummaryrefslogtreecommitdiff
path: root/gcc/json.cc
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2019-05-23 00:42:03 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2019-05-23 00:42:03 +0000
commit30d3ba5142311df568e8f62a374d83d0bdab42bf (patch)
tree94063ddaab8d31b6e0f1b5ab9eb9870683948b21 /gcc/json.cc
parentcf9219c7420320986f9bcd956b04b95a51ebac49 (diff)
downloadgcc-30d3ba5142311df568e8f62a374d83d0bdab42bf.zip
gcc-30d3ba5142311df568e8f62a374d83d0bdab42bf.tar.gz
gcc-30d3ba5142311df568e8f62a374d83d0bdab42bf.tar.bz2
Bulletproof -fdiagnostics-format=json against bad locations (PR c++/90462)
PR c++/90462 reports an ICE with -fdiagnostics-format=json when attempting to serialize a malformed location to JSON. The compound location_t in question has meaningful "caret" and "start" locations, but has UNKNOWN_LOCATION for its "finish" location, leading to a NULL pointer dereference when attempting to build a JSON string for the filename. This patch bulletproofs the JSON output so that attempts to write a JSON object for a location with a NULL file will lead to an object with no "file" key, and attempts to write a compound location with UNKNOWN_LOCATION for its start or finish will lead to the corresponding JSON child object being omitted. This patch also adds a json::object::get member function, for self-testing the above. gcc/ChangeLog: PR c++/90462 * diagnostic-format-json.cc: Include "selftest.h". (json_from_expanded_location): Only add "file" key for non-NULL file strings. (json_from_location_range): Don't add "start" and "finish" children if they are UNKNOWN_LOCATION. (selftest::test_unknown_location): New selftest. (selftest::test_bad_endpoints): New selftest. (selftest::diagnostic_format_json_cc_tests): New function. * json.cc (json::object::get): New function. (selftest::test_object_get): New selftest. (selftest::json_cc_tests): Call it. * json.h (json::object::get): New decl. * selftest-run-tests.c (selftest::run_tests): Call selftest::diagnostic_format_json_cc_tests. * selftest.h (selftest::diagnostic_format_json_cc_tests): New decl. gcc/testsuite/ChangeLog: PR c++/90462 * g++.dg/pr90462.C: New test. From-SVN: r271535
Diffstat (limited to 'gcc/json.cc')
-rw-r--r--gcc/json.cc29
1 files changed, 29 insertions, 0 deletions
diff --git a/gcc/json.cc b/gcc/json.cc
index 2e8e21b..512e2e51 100644
--- a/gcc/json.cc
+++ b/gcc/json.cc
@@ -99,6 +99,22 @@ object::set (const char *key, value *v)
m_map.put (xstrdup (key), v);
}
+/* Get the json::value * for KEY.
+
+ The object retains ownership of the value. */
+
+value *
+object::get (const char *key) const
+{
+ gcc_assert (key);
+
+ value **ptr = const_cast <map_t &> (m_map).get (key);
+ if (ptr)
+ return *ptr;
+ else
+ return NULL;
+}
+
/* class json::array, a subclass of json::value, representing
an ordered collection of values. */
@@ -240,6 +256,18 @@ assert_print_eq (const json::value &jv, const char *expected_json)
ASSERT_STREQ (expected_json, pp_formatted_text (&pp));
}
+/* Verify that object::get works as expected. */
+
+static void
+test_object_get ()
+{
+ object obj;
+ value *val = new json::string ("value");
+ obj.set ("foo", val);
+ ASSERT_EQ (obj.get ("foo"), val);
+ ASSERT_EQ (obj.get ("not-present"), NULL);
+}
+
/* Verify that JSON objects are written correctly. We can't test more than
one key/value pair, as we don't impose a guaranteed ordering. */
@@ -306,6 +334,7 @@ test_writing_literals ()
void
json_cc_tests ()
{
+ test_object_get ();
test_writing_objects ();
test_writing_arrays ();
test_writing_numbers ();