Skip to content

Commit eaf52bd

Browse files
authored
Reject array insert(pos, first, last) iterators not pointing into an array
The array-range insert() overload checked that pos fits the current value and that first/last share the same owning value, but never verified that value is itself an array. Passing iterators from an object, a primitive, or null handed value-initialized (singular) std::vector iterators straight to array_t::insert(), which is undefined behavior. Add the missing is_array() check, mirroring the equivalent check already present in the object-range insert() overload. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
1 parent 8e3cdd0 commit eaf52bd

4 files changed

Lines changed: 28 additions & 0 deletions

File tree

docs/mkdocs/docs/api/basic_json/insert.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ Strong exception safety: if an exception occurs, the original value stays intact
8888
do not belong to the same JSON value; example: `"iterators do not fit"`
8989
- Throws [`invalid_iterator.211`](../../home/exceptions.md#jsonexceptioninvalid_iterator211) if `first` or `last`
9090
are iterators into container for which insert is called; example: `"passed iterators may not belong to container"`
91+
- Throws [`invalid_iterator.202`](../../home/exceptions.md#jsonexceptioninvalid_iterator202) if `first` or `last`
92+
do not point to an array; example: `"iterators first and last must point to arrays"`
9193
4. The function can throw the following exceptions:
9294
- Throws [`type_error.309`](../../home/exceptions.md#jsonexceptiontype_error309) if called on JSON values other than
9395
arrays; example: `"cannot use insert() with string"`

include/nlohmann/json.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3425,6 +3425,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
34253425
JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
34263426
}
34273427

3428+
// passed iterators must belong to arrays
3429+
if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_array()))
3430+
{
3431+
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to arrays", this));
3432+
}
3433+
34283434
// insert to array and return iterator
34293435
return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
34303436
}

single_include/nlohmann/json.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24932,6 +24932,12 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
2493224932
JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
2493324933
}
2493424934

24935+
// passed iterators must belong to arrays
24936+
if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_array()))
24937+
{
24938+
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to arrays", this));
24939+
}
24940+
2493524941
// insert to array and return iterator
2493624942
return insert_iterator(pos, first.m_it.array_iterator, last.m_it.array_iterator);
2493724943
}

tests/src/unit-modifiers.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,20 @@ TEST_CASE("modifiers")
641641
CHECK_THROWS_WITH_AS(j_array.insert(j_array.end(), j_other_array.begin(), j_other_array2.end()), "[json.exception.invalid_iterator.210] iterators do not fit",
642642
json::invalid_iterator&);
643643
}
644+
645+
SECTION("iterators not pointing into an array")
646+
{
647+
json j_object2 = {{"k", 1}, {"l", 2}};
648+
json j_primitive = 5;
649+
json j_null;
650+
651+
CHECK_THROWS_WITH_AS(j_array.insert(j_array.begin(), j_object2.begin(), j_object2.end()), "[json.exception.invalid_iterator.202] iterators first and last must point to arrays",
652+
json::invalid_iterator&);
653+
CHECK_THROWS_WITH_AS(j_array.insert(j_array.begin(), j_primitive.begin(), j_primitive.end()), "[json.exception.invalid_iterator.202] iterators first and last must point to arrays",
654+
json::invalid_iterator&);
655+
CHECK_THROWS_WITH_AS(j_array.insert(j_array.begin(), j_null.begin(), j_null.end()), "[json.exception.invalid_iterator.202] iterators first and last must point to arrays",
656+
json::invalid_iterator&);
657+
}
644658
}
645659

646660
SECTION("range for object")

0 commit comments

Comments
 (0)