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/aedbcfd5 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/aedbcfd5 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/aedbcfd5 Branch: refs/heads/1.5.x Commit: aedbcfd5dc5b4352bf34088fa91d6ceeabcc641f Parents: c3a9358 Author: Alexander Rukletsov <[email protected]> Authored: Tue Mar 13 13:37:49 2018 +0100 Committer: Alexander Rukletsov <[email protected]> Committed: Sun Apr 22 22:25:38 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/aedbcfd5/3rdparty/stout/include/stout/json.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/stout/include/stout/json.hpp b/3rdparty/stout/include/stout/json.hpp index 4f9ea1b..fca97c5 100644 --- a/3rdparty/stout/include/stout/json.hpp +++ b/3rdparty/stout/include/stout/json.hpp @@ -892,13 +892,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/aedbcfd5/3rdparty/stout/tests/json_tests.cpp ---------------------------------------------------------------------- diff --git a/3rdparty/stout/tests/json_tests.cpp b/3rdparty/stout/tests/json_tests.cpp index adaa343..62d5719 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)); }
