From 0027908a218415bda5d75a32619f9d0d001a5f8b Mon Sep 17 00:00:00 2001 From: chenguoping Date: Thu, 11 Jun 2020 15:29:50 +0800 Subject: [PATCH] Fix: abnormal termination --- include/nlohmann/json.hpp | 17 +++++++++++++++-- single_include/nlohmann/json.hpp | 17 +++++++++++++++-- test/src/unit-element_access1.cpp | 7 +++++++ test/src/unit-json_pointer.cpp | 9 +++++++++ 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index d1dc41192..e2b594e49 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -3531,6 +3531,11 @@ class basic_json // const operator[] only works for arrays if (JSON_HEDLEY_LIKELY(is_array())) { + if (JSON_HEDLEY_LIKELY(idx >= m_value.array->size())) + { + JSON_THROW(out_of_range::create(401, "array index (" + std::to_string(idx) + + ") is out of range")); + } return m_value.array->operator[](idx); } @@ -3618,7 +3623,11 @@ class basic_json // const operator[] only works for objects if (JSON_HEDLEY_LIKELY(is_object())) { - assert(m_value.object->find(key) != m_value.object->end()); + if (JSON_HEDLEY_LIKELY(m_value.object->find(key) == m_value.object->end())) + { + // create better exception explanation + JSON_THROW(out_of_range::create(403, "key '" + key + "' not found")); + } return m_value.object->find(key)->second; } @@ -3710,7 +3719,11 @@ class basic_json // at only works for objects if (JSON_HEDLEY_LIKELY(is_object())) { - assert(m_value.object->find(key) != m_value.object->end()); + if (JSON_HEDLEY_LIKELY(m_value.object->find(key) == m_value.object->end())) + { + // create better exception explanation + JSON_THROW(out_of_range::create(403, "key '" + std::string(key) + "' not found")); + } return m_value.object->find(key)->second; } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index e45a756f3..5ff1c347e 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -19312,6 +19312,11 @@ class basic_json // const operator[] only works for arrays if (JSON_HEDLEY_LIKELY(is_array())) { + if (JSON_HEDLEY_LIKELY(idx >= m_value.array->size())) + { + JSON_THROW(out_of_range::create(401, "array index (" + std::to_string(idx) + + ") is out of range")); + } return m_value.array->operator[](idx); } @@ -19399,7 +19404,11 @@ class basic_json // const operator[] only works for objects if (JSON_HEDLEY_LIKELY(is_object())) { - assert(m_value.object->find(key) != m_value.object->end()); + if (JSON_HEDLEY_LIKELY(m_value.object->find(key) == m_value.object->end())) + { + // create better exception explanation + JSON_THROW(out_of_range::create(403, "key '" + key + "' not found")); + } return m_value.object->find(key)->second; } @@ -19491,7 +19500,11 @@ class basic_json // at only works for objects if (JSON_HEDLEY_LIKELY(is_object())) { - assert(m_value.object->find(key) != m_value.object->end()); + if (JSON_HEDLEY_LIKELY(m_value.object->find(key) == m_value.object->end())) + { + // create better exception explanation + JSON_THROW(out_of_range::create(403, "key '" + std::string(key) + "' not found")); + } return m_value.object->find(key)->second; } diff --git a/test/src/unit-element_access1.cpp b/test/src/unit-element_access1.cpp index a0a18fecb..9f35f0a18 100644 --- a/test/src/unit-element_access1.cpp +++ b/test/src/unit-element_access1.cpp @@ -185,6 +185,13 @@ TEST_CASE("element access 1") CHECK(j_const[7] == json({1, 2, 3})); } + SECTION("access outside bounds") + { + CHECK_THROWS_AS(j_const[8], json::out_of_range&); + CHECK_THROWS_WITH(j_const[8], + "[json.exception.out_of_range.401] array index (8) is out of range"); + } + SECTION("access on non-array type") { SECTION("null") diff --git a/test/src/unit-json_pointer.cpp b/test/src/unit-json_pointer.cpp index 1e68bc83e..18c431eaa 100644 --- a/test/src/unit-json_pointer.cpp +++ b/test/src/unit-json_pointer.cpp @@ -202,6 +202,10 @@ TEST_CASE("JSON pointers") CHECK(j[json::json_pointer("/foo/1")] == j["foo"][1]); CHECK(j["/foo/1"_json_pointer] == j["foo"][1]); + CHECK_THROWS_AS(j[json::json_pointer("/foo/2")], json::out_of_range&); + CHECK_THROWS_WITH(j[json::json_pointer("/foo/2")], + "[json.exception.out_of_range.401] array index (2) is out of range"); + // checked array access CHECK(j.at(json::json_pointer("/foo/0")) == j["foo"][0]); CHECK(j.at(json::json_pointer("/foo/1")) == j["foo"][1]); @@ -217,6 +221,11 @@ TEST_CASE("JSON pointers") CHECK(j[json::json_pointer("/i\\j")] == j["i\\j"]); CHECK(j[json::json_pointer("/k\"l")] == j["k\"l"]); + // not existing access + CHECK_THROWS_AS(j[json::json_pointer("/not-existing")], json::out_of_range&); + CHECK_THROWS_WITH(j[json::json_pointer("/not-existing")], + "[json.exception.out_of_range.403] key 'not-existing' not found"); + // checked access CHECK(j.at(json::json_pointer("/ ")) == j[" "]); CHECK(j.at(json::json_pointer("/c%d")) == j["c%d"]);