mirror of
https://github.com/nlohmann/json.git
synced 2026-11-02 19:05:35 +00:00
JSON_DIAGNOSTIC_POSITIONS: comparing a value-initialized iterator throws instead of crashing
With JSON_DIAGNOSTIC_POSITIONS, comparing a value-initialized iterator (which has no container) with another iterator built the invalid_iterator.212 message from the byte positions of the iterator's value, which is a null pointer: UBSan reports "member call on null pointer" in exception::get_byte_positions(), then the process crashes. Every other configuration throws invalid_iterator.212. get_byte_positions() now returns no positions for a null value, as the JSON_DIAGNOSTICS path already does. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
3 files changed
+15
-2
No files matched your search
@@ -222,7 +222,8 @@ class exception : public std::exception
|
|||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static std::string get_byte_positions(const BasicJsonType* leaf_element)
|
static std::string get_byte_positions(const BasicJsonType* leaf_element)
|
||||||
{
|
{
|
||||||
if ((leaf_element->start_pos() != std::string::npos) && (leaf_element->end_pos() != std::string::npos))
|
// a value-initialized iterator has no value (invalid_iterator.212)
|
||||||
|
if (leaf_element != nullptr && leaf_element->start_pos() != std::string::npos && leaf_element->end_pos() != std::string::npos)
|
||||||
{
|
{
|
||||||
return concat("(bytes ", std::to_string(leaf_element->start_pos()), "-", std::to_string(leaf_element->end_pos()), ") ");
|
return concat("(bytes ", std::to_string(leaf_element->start_pos()), "-", std::to_string(leaf_element->end_pos()), ") ");
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+2
-1
@@ -5719,7 +5719,8 @@ class exception : public std::exception
|
|||||||
template<typename BasicJsonType>
|
template<typename BasicJsonType>
|
||||||
static std::string get_byte_positions(const BasicJsonType* leaf_element)
|
static std::string get_byte_positions(const BasicJsonType* leaf_element)
|
||||||
{
|
{
|
||||||
if ((leaf_element->start_pos() != std::string::npos) && (leaf_element->end_pos() != std::string::npos))
|
// a value-initialized iterator has no value (invalid_iterator.212)
|
||||||
|
if (leaf_element != nullptr && leaf_element->start_pos() != std::string::npos && leaf_element->end_pos() != std::string::npos)
|
||||||
{
|
{
|
||||||
return concat("(bytes ", std::to_string(leaf_element->start_pos()), "-", std::to_string(leaf_element->end_pos()), ") ");
|
return concat("(bytes ", std::to_string(leaf_element->start_pos()), "-", std::to_string(leaf_element->end_pos()), ") ");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,3 +243,14 @@ TEST_CASE("values read from a binary format have no positions")
|
|||||||
check_no_positions(j);
|
check_no_positions(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("comparing a value-initialized iterator throws invalid_iterator.212")
|
||||||
|
{
|
||||||
|
// such an iterator has no value to take the byte positions from; the
|
||||||
|
// comparison used to dereference the null pointer instead of throwing
|
||||||
|
json j = {1, 2};
|
||||||
|
json::iterator it{};
|
||||||
|
CHECK_THROWS_WITH_AS(it == j.begin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers", json::invalid_iterator);
|
||||||
|
CHECK_THROWS_WITH_AS(it < j.begin(), "[json.exception.invalid_iterator.212] cannot compare iterators of different containers", json::invalid_iterator);
|
||||||
|
CHECK_THROWS_WITH_AS(j.begin() == it, "[json.exception.invalid_iterator.212] cannot compare iterators of different containers", json::invalid_iterator);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user