mirror of
https://github.com/nlohmann/json.git
synced 2026-09-30 03:30:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f0a93bbf6f |
@@ -70,6 +70,9 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
||||
1. The function can throw the following exceptions:
|
||||
- Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an array
|
||||
or null; in that case, using the `[]` operator with an index makes no sense.
|
||||
- Throws `#!cpp std::length_error` if `idx` equals the maximum value of `size_type`; the array is left unchanged.
|
||||
(This is the one index for which growing the array to hold it cannot be expressed as a `size_type` size, the same
|
||||
way an oversized [`resize`](https://en.cppreference.com/w/cpp/container/vector/resize) throws.)
|
||||
2. The function can throw the following exceptions:
|
||||
- Throws [`type_error.305`](../../home/exceptions.md#jsonexceptiontype_error305) if the JSON value is not an object
|
||||
or null; in that case, using the `[]` operator with a key makes no sense.
|
||||
@@ -257,7 +260,8 @@ Strong exception safety: if an exception occurs, the original value stays intact
|
||||
|
||||
## Version history
|
||||
|
||||
1. Added in version 1.0.0.
|
||||
1. Added in version 1.0.0. Fixed in version 3.13.0 to throw `#!cpp std::length_error` instead of emptying the array and
|
||||
accessing it out of bounds when `idx` equals the maximum value of `size_type`.
|
||||
2. Added in version 1.0.0. Added overloads for `T* key` in version 1.1.0. Removed overloads for `T* key` (replaced by 3)
|
||||
in version 3.11.0.
|
||||
3. Added in version 3.11.0. Fixed in version 3.13.0 to consistently accept `std::string_view`-convertible keys, as
|
||||
|
||||
@@ -36,7 +36,9 @@
|
||||
#include <iosfwd> // istream, ostream
|
||||
#endif // JSON_NO_IO
|
||||
#include <iterator> // make_move_iterator, random_access_iterator_tag
|
||||
#include <limits> // numeric_limits
|
||||
#include <memory> // unique_ptr
|
||||
#include <stdexcept> // length_error
|
||||
#include <string> // string, stoi, to_string
|
||||
#include <utility> // declval, forward, move, pair, swap
|
||||
#include <vector> // vector
|
||||
@@ -2830,6 +2832,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// fill up the array with null values if given idx is outside the range
|
||||
if (idx >= m_data.m_value.array->size())
|
||||
{
|
||||
// idx + 1 would overflow size_type and wrap to 0, which would empty
|
||||
// the array instead of growing it; reject such an idx the same way
|
||||
// resize() rejects other indices that are too large to represent
|
||||
if (JSON_HEDLEY_UNLIKELY(idx == (std::numeric_limits<size_type>::max)()))
|
||||
{
|
||||
JSON_THROW(std::length_error(detail::concat("array index ", std::to_string(idx), " exceeds size_type")));
|
||||
}
|
||||
#if JSON_DIAGNOSTICS
|
||||
// remember array size & capacity before resizing
|
||||
const auto old_size = m_data.m_value.array->size();
|
||||
|
||||
@@ -36,7 +36,9 @@
|
||||
#include <iosfwd> // istream, ostream
|
||||
#endif // JSON_NO_IO
|
||||
#include <iterator> // make_move_iterator, random_access_iterator_tag
|
||||
#include <limits> // numeric_limits
|
||||
#include <memory> // unique_ptr
|
||||
#include <stdexcept> // length_error
|
||||
#include <string> // string, stoi, to_string
|
||||
#include <utility> // declval, forward, move, pair, swap
|
||||
#include <vector> // vector
|
||||
@@ -28911,6 +28913,13 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
// fill up the array with null values if given idx is outside the range
|
||||
if (idx >= m_data.m_value.array->size())
|
||||
{
|
||||
// idx + 1 would overflow size_type and wrap to 0, which would empty
|
||||
// the array instead of growing it; reject such an idx the same way
|
||||
// resize() rejects other indices that are too large to represent
|
||||
if (JSON_HEDLEY_UNLIKELY(idx == (std::numeric_limits<size_type>::max)()))
|
||||
{
|
||||
JSON_THROW(std::length_error(detail::concat("array index ", std::to_string(idx), " exceeds size_type")));
|
||||
}
|
||||
#if JSON_DIAGNOSTICS
|
||||
// remember array size & capacity before resizing
|
||||
const auto old_size = m_data.m_value.array->size();
|
||||
|
||||
@@ -147,6 +147,24 @@ TEST_CASE("element access 1")
|
||||
CHECK(j_const[7] == json({1, 2, 3}));
|
||||
}
|
||||
|
||||
SECTION("SIZE_MAX index (#5647)")
|
||||
{
|
||||
// idx + 1 must not be computed for idx == SIZE_MAX: it wraps to 0,
|
||||
// which would empty the array and then write out of bounds instead
|
||||
// of growing it; reject it like an oversized resize() would and
|
||||
// leave the array unchanged
|
||||
const auto max_idx = (std::numeric_limits<json::size_type>::max)();
|
||||
const std::string expected = "array index " + std::to_string(max_idx) + " exceeds size_type";
|
||||
const json j_before = j; // NOLINT(performance-unnecessary-copy-initialization)
|
||||
|
||||
CHECK_THROWS_WITH_AS(j[max_idx] = 1, expected.c_str(), std::length_error&);
|
||||
CHECK(j == j_before);
|
||||
|
||||
json j_empty = json::array();
|
||||
CHECK_THROWS_WITH_AS(j_empty[max_idx] = 1, expected.c_str(), std::length_error&);
|
||||
CHECK(j_empty == json::array());
|
||||
}
|
||||
|
||||
SECTION("access on non-array type")
|
||||
{
|
||||
SECTION("null")
|
||||
|
||||
Reference in New Issue
Block a user