Stout: Ensured exceptions are caught for `picojson::parse()`. `picojson::parse()` might throw in some cases, including when a parsed number is out of bounds. This patch captures possible exceptions at the call site and converts them to `Error`s.
Review: https://reviews.apache.org/r/66091 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/2d7b7ef6 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/2d7b7ef6 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/2d7b7ef6 Branch: refs/heads/master Commit: 2d7b7ef6d17e81395214741a613a68a6fb86483f Parents: d6552b0 Author: Alexander Rukletsov <[email protected]> Authored: Tue Mar 13 13:37:49 2018 +0100 Committer: Alexander Rukletsov <[email protected]> Committed: Sun Apr 22 22:20:23 2018 +0200 ---------------------------------------------------------------------- 3rdparty/stout/include/stout/json.hpp | 21 +++++++++++++++++---- 3rdparty/stout/tests/json_tests.cpp | 14 ++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/2d7b7ef6/3rdparty/stout/include/stout/json.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/stout/include/stout/json.hpp b/3rdparty/stout/include/stout/json.hpp index 102cd99..5e738cf 100644 --- a/3rdparty/stout/include/stout/json.hpp +++ b/3rdparty/stout/include/stout/json.hpp @@ -890,13 +890,26 @@ inline Try<Value> parse(const std::string& s) // Because PicoJson supports repeated parsing of multiple objects/arrays in a // stream, it will quietly ignore trailing non-whitespace characters. We would // rather throw an error, however, so use `last_char` to check for this. + // + // TODO(alexr): Address cases when `s` is empty or consists only of whitespace + // characters. const char* lastVisibleChar = parseBegin + s.find_last_not_of(strings::WHITESPACE); - // Parse the string, returning a pointer to the character - // immediately following the last one parsed. - const char* parseEnd = - picojson::parse(value, parseBegin, parseBegin + s.size(), &error); + // Parse the string, returning a pointer to the character immediately + // following the last one parsed. Convert exceptions to `Error`s. + // + // TODO(alexr): Remove `try-catch` wrapper once picojson stops throwing + // on parsing, see https://github.com/kazuho/picojson/issues/94 + const char* parseEnd; + try { + parseEnd = + picojson::parse(value, parseBegin, parseBegin + s.size(), &error); + } catch (const std::overflow_error&) { + return Error("Value out of range"); + } catch (...) { + return Error("Unknown JSON parse error"); + } if (!error.empty()) { return Error(error); http://git-wip-us.apache.org/repos/asf/mesos/blob/2d7b7ef6/3rdparty/stout/tests/json_tests.cpp ---------------------------------------------------------------------- diff --git a/3rdparty/stout/tests/json_tests.cpp b/3rdparty/stout/tests/json_tests.cpp index af00e42..508d843 100644 --- a/3rdparty/stout/tests/json_tests.cpp +++ b/3rdparty/stout/tests/json_tests.cpp @@ -270,6 +270,20 @@ TEST(JsonTest, ParseError) " "; EXPECT_ERROR(JSON::parse<JSON::Object>(jsonString)); + + jsonString = R"~( + { + "double1": 123123123121231231231231321312312312123123122E112312387129381723\x0d\x0a\x0d\x0a\x0d\x0a\x0d + })~"; + + EXPECT_ERROR(JSON::parse<JSON::Object>(jsonString)); + + jsonString = R"~( + { + "double2": -332861120361594135E400 + })~"; + + EXPECT_ERROR(JSON::parse<JSON::Object>(jsonString)); }
