Fix: abnormal termination

This commit is contained in:
chenguoping 2020-06-11 15:29:50 +08:00
parent 14881cf901
commit 0027908a21
4 changed files with 46 additions and 4 deletions

View File

@ -3531,6 +3531,11 @@ class basic_json
// const operator[] only works for arrays // const operator[] only works for arrays
if (JSON_HEDLEY_LIKELY(is_array())) 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); return m_value.array->operator[](idx);
} }
@ -3618,7 +3623,11 @@ class basic_json
// const operator[] only works for objects // const operator[] only works for objects
if (JSON_HEDLEY_LIKELY(is_object())) 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; return m_value.object->find(key)->second;
} }
@ -3710,7 +3719,11 @@ class basic_json
// at only works for objects // at only works for objects
if (JSON_HEDLEY_LIKELY(is_object())) 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; return m_value.object->find(key)->second;
} }

View File

@ -19312,6 +19312,11 @@ class basic_json
// const operator[] only works for arrays // const operator[] only works for arrays
if (JSON_HEDLEY_LIKELY(is_array())) 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); return m_value.array->operator[](idx);
} }
@ -19399,7 +19404,11 @@ class basic_json
// const operator[] only works for objects // const operator[] only works for objects
if (JSON_HEDLEY_LIKELY(is_object())) 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; return m_value.object->find(key)->second;
} }
@ -19491,7 +19500,11 @@ class basic_json
// at only works for objects // at only works for objects
if (JSON_HEDLEY_LIKELY(is_object())) 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; return m_value.object->find(key)->second;
} }

View File

@ -185,6 +185,13 @@ TEST_CASE("element access 1")
CHECK(j_const[7] == json({1, 2, 3})); 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("access on non-array type")
{ {
SECTION("null") SECTION("null")

View File

@ -202,6 +202,10 @@ TEST_CASE("JSON pointers")
CHECK(j[json::json_pointer("/foo/1")] == j["foo"][1]); CHECK(j[json::json_pointer("/foo/1")] == j["foo"][1]);
CHECK(j["/foo/1"_json_pointer] == 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 // checked array access
CHECK(j.at(json::json_pointer("/foo/0")) == j["foo"][0]); CHECK(j.at(json::json_pointer("/foo/0")) == j["foo"][0]);
CHECK(j.at(json::json_pointer("/foo/1")) == j["foo"][1]); 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("/i\\j")] == j["i\\j"]);
CHECK(j[json::json_pointer("/k\"l")] == j["k\"l"]); 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 // checked access
CHECK(j.at(json::json_pointer("/ ")) == j[" "]); CHECK(j.at(json::json_pointer("/ ")) == j[" "]);
CHECK(j.at(json::json_pointer("/c%d")) == j["c%d"]); CHECK(j.at(json::json_pointer("/c%d")) == j["c%d"]);