Assert on missing array indices in const operator[] and document the JSON pointer case

The const operator[] overloads are unchecked by design, and a missing key
or index is undefined behavior. The key overload guards this with a
runtime assertion, but the index overload did not, although the element
access documentation says an assertion fires in both cases. The const
JSON pointer overload inherits both through json_pointer::get_unchecked(),
so a pointer to a missing array index read out of bounds even in debug
builds, and its documentation promised out_of_range.404 for any pointer
that cannot be resolved.

Add JSON_ASSERT(idx < size()) to const operator[](size_type), which also
covers the index leg of the const JSON pointer overload. Document the
undefined behavior for the const JSON pointer overload in operator[].md
and in the runtime assertions page. Release builds are unchanged.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann
2026-09-27 23:17:42 +02:00
parent 373005f7ac
commit 93fe62fc0b
5 changed files with 60 additions and 14 deletions
+8 -2
View File
@@ -535,6 +535,10 @@ class json_pointer
@return const reference to the JSON value pointed to by the JSON
pointer
@pre Every object key and array index the pointer refers to exists.
Like the const operator[] for keys and indices, a missing one is
undefined behavior, guarded by a runtime assertion.
@throw parse_error.106 if an array index begins with '0'
@throw parse_error.109 if an array index was not a number
@throw out_of_range.402 if the array index '-' is used
@@ -549,7 +553,8 @@ class json_pointer
{
case detail::value_t::object:
{
// use unchecked object access
// use unchecked object access; the const operator[]
// asserts that the key exists
ptr = &ptr->operator[](reference_token);
break;
}
@@ -562,7 +567,8 @@ class json_pointer
JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
}
// use unchecked array access
// use unchecked array access; the const operator[]
// asserts that the index exists
ptr = &ptr->operator[](array_index<BasicJsonType>(reference_token));
break;
}
+1
View File
@@ -2866,6 +2866,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
// const operator[] only works for arrays
if (JSON_HEDLEY_LIKELY(is_array()))
{
JSON_ASSERT(idx < m_data.m_value.array->size());
return m_data.m_value.array->operator[](idx);
}