mirror of
https://github.com/nlohmann/json.git
synced 2026-09-06 00:08:00 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd0ca40ea6 |
@@ -748,20 +748,6 @@ class json_pointer
|
||||
}
|
||||
}
|
||||
|
||||
// the reference token consists only of digits at this point (cf. checks
|
||||
// above); however, its numeric value might not be representable, in which
|
||||
// case array_index() would throw out_of_range.404/410 -- contains() must
|
||||
// not throw (see #5395), so such a reference token is treated as "not found"
|
||||
errno = 0; // strtoull() does not reset errno on success
|
||||
char* p_end = nullptr; // NOLINT(misc-const-correctness)
|
||||
const unsigned long long magnitude = std::strtoull(reference_token.c_str(), &p_end, 10); // NOLINT(runtime/int)
|
||||
if (JSON_HEDLEY_UNLIKELY(errno == ERANGE // the value exceeds ULLONG_MAX
|
||||
|| magnitude >= static_cast<unsigned long long>((std::numeric_limits<typename BasicJsonType::size_type>::max)()))) // NOLINT(runtime/int)
|
||||
{
|
||||
// the array index cannot be represented as size_type
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto idx = array_index<BasicJsonType>(reference_token);
|
||||
if (idx >= ptr->size())
|
||||
{
|
||||
|
||||
@@ -16394,20 +16394,6 @@ class json_pointer
|
||||
}
|
||||
}
|
||||
|
||||
// the reference token consists only of digits at this point (cf. checks
|
||||
// above); however, its numeric value might not be representable, in which
|
||||
// case array_index() would throw out_of_range.404/410 -- contains() must
|
||||
// not throw (see #5395), so such a reference token is treated as "not found"
|
||||
errno = 0; // strtoull() does not reset errno on success
|
||||
char* p_end = nullptr; // NOLINT(misc-const-correctness)
|
||||
const unsigned long long magnitude = std::strtoull(reference_token.c_str(), &p_end, 10); // NOLINT(runtime/int)
|
||||
if (JSON_HEDLEY_UNLIKELY(errno == ERANGE // the value exceeds ULLONG_MAX
|
||||
|| magnitude >= static_cast<unsigned long long>((std::numeric_limits<typename BasicJsonType::size_type>::max)()))) // NOLINT(runtime/int)
|
||||
{
|
||||
// the array index cannot be represented as size_type
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto idx = array_index<BasicJsonType>(reference_token);
|
||||
if (idx >= ptr->size())
|
||||
{
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// __ _____ _____ _____
|
||||
// __| | __| | | | JSON for Modern C++ (supporting code)
|
||||
// | | |__ | | | | | | version 3.12.0
|
||||
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
||||
//
|
||||
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// This file contains the C++17-only part of unit-items.cpp (structured
|
||||
// bindings support for json::items()). It is kept in a separate
|
||||
// translation unit so the (much larger) unit-items.cpp does not need to
|
||||
// be compiled a second time just for this one SECTION.
|
||||
|
||||
#include "doctest_compatibility.h"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
using nlohmann::json;
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
TEST_CASE("items()")
|
||||
{
|
||||
SECTION("object")
|
||||
{
|
||||
SECTION("structured bindings")
|
||||
{
|
||||
json j = { {"A", 1}, {"B", 2} };
|
||||
|
||||
std::map<std::string, int> m;
|
||||
|
||||
for (auto const&[key, value] : j.items())
|
||||
{
|
||||
m.emplace(key, value);
|
||||
}
|
||||
|
||||
CHECK(j.get<decltype(m)>() == m);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -862,22 +862,6 @@ TEST_CASE("items()")
|
||||
|
||||
CHECK(counter == 3);
|
||||
}
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
SECTION("structured bindings")
|
||||
{
|
||||
json j = { {"A", 1}, {"B", 2} };
|
||||
|
||||
std::map<std::string, int> m;
|
||||
|
||||
for (auto const&[key, value] : j.items())
|
||||
{
|
||||
m.emplace(key, value);
|
||||
}
|
||||
|
||||
CHECK(j.get<decltype(m)>() == m);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SECTION("const object")
|
||||
|
||||
@@ -319,44 +319,6 @@ TEST_CASE("JSON pointers")
|
||||
|
||||
CHECK_THROWS_WITH_AS(j[jp] = 1, throw_msg.c_str(), json::out_of_range&);
|
||||
CHECK_THROWS_WITH_AS(j_const[jp] == 1, throw_msg.c_str(), json::out_of_range&);
|
||||
|
||||
// #5395: contains() must not throw for a reference token that is a
|
||||
// syntactically valid array index but numerically exceeds ULLONG_MAX
|
||||
// (causing strtoull() to set errno to ERANGE) -- it should just report
|
||||
// that the pointer does not resolve to an element
|
||||
CHECK(!j.contains(jp));
|
||||
CHECK(!j_const.contains(jp));
|
||||
}
|
||||
|
||||
{
|
||||
// #5395: same as above, but using the exact reproduction from the issue
|
||||
json::json_pointer const jp("/99999999999999999999");
|
||||
std::string const throw_msg = "[json.exception.out_of_range.404] unresolved reference token '99999999999999999999'";
|
||||
|
||||
CHECK_THROWS_WITH_AS(j[jp] = 1, throw_msg.c_str(), json::out_of_range&);
|
||||
CHECK_THROWS_WITH_AS(j_const[jp] == 1, throw_msg.c_str(), json::out_of_range&);
|
||||
CHECK_THROWS_WITH_AS(j.at(jp) = 1, throw_msg.c_str(), json::out_of_range&);
|
||||
CHECK_THROWS_WITH_AS(j_const.at(jp) == 1, throw_msg.c_str(), json::out_of_range&);
|
||||
|
||||
CHECK(!j.contains(jp));
|
||||
CHECK(!j_const.contains(jp));
|
||||
}
|
||||
|
||||
{
|
||||
// #5395: a reference token that is numerically representable in
|
||||
// unsigned long long but exceeds size_type's max (e.g. ULLONG_MAX
|
||||
// itself on typical 64-bit platforms, where size_type's max equals
|
||||
// ULLONG_MAX) must not make contains() throw either
|
||||
json::json_pointer const jp("/18446744073709551615");
|
||||
std::string const throw_msg = "[json.exception.out_of_range.410] array index 18446744073709551615 exceeds size_type";
|
||||
|
||||
CHECK_THROWS_WITH_AS(j[jp] = 1, throw_msg.c_str(), json::out_of_range&);
|
||||
CHECK_THROWS_WITH_AS(j_const[jp] == 1, throw_msg.c_str(), json::out_of_range&);
|
||||
CHECK_THROWS_WITH_AS(j.at(jp) = 1, throw_msg.c_str(), json::out_of_range&);
|
||||
CHECK_THROWS_WITH_AS(j_const.at(jp) == 1, throw_msg.c_str(), json::out_of_range&);
|
||||
|
||||
CHECK(!j.contains(jp));
|
||||
CHECK(!j_const.contains(jp));
|
||||
}
|
||||
|
||||
// on some machines, the check below is not constant
|
||||
@@ -372,10 +334,6 @@ TEST_CASE("JSON pointers")
|
||||
|
||||
CHECK_THROWS_WITH_AS(j[jp] = 1, throw_msg.c_str(), json::out_of_range&);
|
||||
CHECK_THROWS_WITH_AS(j_const[jp] == 1, throw_msg.c_str(), json::out_of_range&);
|
||||
|
||||
// #5395: contains() must not throw for a reference token exceeding size_type's max
|
||||
CHECK(!j.contains(jp));
|
||||
CHECK(!j_const.contains(jp));
|
||||
}
|
||||
|
||||
DOCTEST_MSVC_SUPPRESS_WARNING_POP
|
||||
|
||||
@@ -30,10 +30,6 @@ using nlohmann::json;
|
||||
#include <cstdio>
|
||||
#include "make_test_data_available.hpp"
|
||||
|
||||
#ifdef JSON_HAS_CPP_17
|
||||
#include <variant>
|
||||
#endif
|
||||
|
||||
#include "fifo_map.hpp"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user