From f51ea1ce13c436cff495f8b1cfa3b32c47d34879 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 10 Sep 2026 18:46:04 +0200 Subject: [PATCH] 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 --- include/nlohmann/detail/input/binary_reader.hpp | 8 +++++--- single_include/nlohmann/json.hpp | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index b65a2bd47..efa93070d 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -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; } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 9649aa1f6..e5ee9b785 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -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; }