diff options
author | David Malcolm <dmalcolm@redhat.com> | 2019-05-23 00:42:03 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2019-05-23 00:42:03 +0000 |
commit | 30d3ba5142311df568e8f62a374d83d0bdab42bf (patch) | |
tree | 94063ddaab8d31b6e0f1b5ab9eb9870683948b21 /gcc/json.cc | |
parent | cf9219c7420320986f9bcd956b04b95a51ebac49 (diff) | |
download | gcc-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.cc | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/gcc/json.cc b/gcc/json.cc index 2e8e21b..512e2e5 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 (); |