From de4cc74dc25c6bee428e05fe8b33754dc7841379 Mon Sep 17 00:00:00 2001 From: Miguel Portilla Date: Fri, 12 Jan 2018 15:13:08 -0500 Subject: [PATCH] Add json nest unit test --- src/ripple/json/impl/json_reader.cpp | 4 +-- src/ripple/json/json_reader.h | 2 ++ src/test/json/json_value_test.cpp | 49 ++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/ripple/json/impl/json_reader.cpp b/src/ripple/json/impl/json_reader.cpp index 65aa2681dad..13b9c5580d3 100644 --- a/src/ripple/json/impl/json_reader.cpp +++ b/src/ripple/json/impl/json_reader.cpp @@ -29,8 +29,6 @@ namespace Json // Implementation of class Reader // //////////////////////////////// -constexpr unsigned nest_limit = 1000; - static std::string codePointToUTF8 (unsigned int cp) @@ -143,7 +141,7 @@ Reader::readValue(unsigned depth) { Token token; skipCommentTokens ( token ); - if (depth >= nest_limit) + if (depth > nest_limit) return addError("Syntax error: maximum nesting depth exceeded", token); bool successful = true; diff --git a/src/ripple/json/json_reader.h b/src/ripple/json/json_reader.h index 5a29f136321..6e08e82b3bd 100644 --- a/src/ripple/json/json_reader.h +++ b/src/ripple/json/json_reader.h @@ -81,6 +81,8 @@ class Reader */ std::string getFormatedErrorMessages () const; + static constexpr unsigned nest_limit {1000}; + private: enum TokenType { diff --git a/src/test/json/json_value_test.cpp b/src/test/json/json_value_test.cpp index cbe43b67ac1..c5e70f15a7e 100644 --- a/src/test/json/json_value_test.cpp +++ b/src/test/json/json_value_test.cpp @@ -24,6 +24,8 @@ #include #include +#include + namespace ripple { struct json_value_test : beast::unit_test::suite @@ -249,6 +251,52 @@ struct json_value_test : beast::unit_test::suite } } + void test_nest_limits () + { + Json::Reader r; + { + auto nest = [](std::uint32_t depth)->std::string { + std::string s = "{"; + for (std::uint32_t i{1}; i <= depth; ++i) + s += "\"obj\":{"; + for (std::uint32_t i{1}; i <= depth; ++i) + s += "}"; + s += "}"; + return s; + }; + + { + // Within object nest limit + auto json{nest(std::min(10u, Json::Reader::nest_limit))}; + Json::Value j; + BEAST_EXPECT(r.parse(json, j)); + } + + { + // Exceed object nest limit + auto json{nest(Json::Reader::nest_limit + 1)}; + Json::Value j; + BEAST_EXPECT(!r.parse(json, j)); + } + } + + auto nest = [](std::uint32_t depth)->std::string { + std::string s = "{"; + for (std::uint32_t i{1}; i <= depth; ++i) + s += "\"array\":[{"; + for (std::uint32_t i{1}; i <= depth; ++i) + s += "]}"; + s += "}"; + return s; + }; + { + // Exceed array nest limit + auto json{nest(Json::Reader::nest_limit + 1)}; + Json::Value j; + BEAST_EXPECT(!r.parse(json, j)); + } + } + void run () { test_bool (); @@ -258,6 +306,7 @@ struct json_value_test : beast::unit_test::suite test_move (); test_comparisons (); test_compact (); + test_nest_limits (); } };