Make parse_bson_internal's end-of-document top a copy, not a reference

Same issue as the CBOR and UBJSON/BJData readers: top aliased
container_stack.back() and was read (top.is_object) right after
container_stack.pop_back() ended its lifetime. A copy stays valid
regardless of what happens to the stack; nothing here mutates the live
entry, so no field needs to go through container_stack.back() directly.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann
2026-09-10 18:46:04 +02:00
parent cee54087c8
commit f51ea1ce13
2 changed files with 10 additions and 6 deletions
@@ -337,8 +337,10 @@ class binary_reader
if (element_type == 0) // end of the innermost document
{
const container_frame& top = container_stack.back();
const bool is_object = top.is_object;
// a copy, not a reference: it must stay valid across the
// pop_back() below, which destroys the container_stack
// element it would otherwise alias
const container_frame top = container_stack.back();
if (JSON_HEDLEY_UNLIKELY(!check_bson_document_size(top.start_position, top.declared_size)))
{
@@ -346,7 +348,7 @@ class binary_reader
}
container_stack.pop_back();
if (JSON_HEDLEY_UNLIKELY(is_object ? !sax->end_object() : !sax->end_array()))
if (JSON_HEDLEY_UNLIKELY(top.is_object ? !sax->end_object() : !sax->end_array()))
{
return false;
}
+5 -3
View File
@@ -11161,8 +11161,10 @@ class binary_reader
if (element_type == 0) // end of the innermost document
{
const container_frame& top = container_stack.back();
const bool is_object = top.is_object;
// a copy, not a reference: it must stay valid across the
// pop_back() below, which destroys the container_stack
// element it would otherwise alias
const container_frame top = container_stack.back();
if (JSON_HEDLEY_UNLIKELY(!check_bson_document_size(top.start_position, top.declared_size)))
{
@@ -11170,7 +11172,7 @@ class binary_reader
}
container_stack.pop_back();
if (JSON_HEDLEY_UNLIKELY(is_object ? !sax->end_object() : !sax->end_array()))
if (JSON_HEDLEY_UNLIKELY(top.is_object ? !sax->end_object() : !sax->end_array()))
{
return false;
}