mirror of
https://github.com/nlohmann/json.git
synced 2026-09-06 08:17:59 +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);
|
const auto idx = array_index<BasicJsonType>(reference_token);
|
||||||
if (idx >= ptr->size())
|
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);
|
const auto idx = array_index<BasicJsonType>(reference_token);
|
||||||
if (idx >= ptr->size())
|
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);
|
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")
|
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[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_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
|
// 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[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_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
|
DOCTEST_MSVC_SUPPRESS_WARNING_POP
|
||||||
|
|||||||
@@ -30,10 +30,6 @@ using nlohmann::json;
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include "make_test_data_available.hpp"
|
#include "make_test_data_available.hpp"
|
||||||
|
|
||||||
#ifdef JSON_HAS_CPP_17
|
|
||||||
#include <variant>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "fifo_map.hpp"
|
#include "fifo_map.hpp"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
Reference in New Issue
Block a user