json_view: copy the frame in value_path instead of holding a reference

The reference into the frame stack was only used before pop_back() and
push_back(), but a later change could read it after them. Copy the frame and
advance it through stack.back(), as the other stack walks do.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-11-01 08:38:15 +01:00
1 parent fb6a315746
commit 48fa92ffa9
2 files changed
+8 -8

No files matched your search

+4 -4
View File
@@ -115,8 +115,8 @@ bool value_path(const document_data& d, const node* target, std::vector<std::str
// (tokens[i] leads from stack[i] to stack[i + 1], or to the target) // (tokens[i] leads from stack[i] to stack[i + 1], or to the target)
for (;;) for (;;)
{ {
// (f is not used after the stack changes: pop_back() below, push_back() at the end) // a copy: pop_back() and push_back() below change the stack
frame& f = stack.back(); const frame f = stack.back();
if (f.pos == f.end) if (f.pos == f.end)
{ {
stack.pop_back(); stack.pop_back();
@@ -150,8 +150,8 @@ bool value_path(const document_data& d, const node* target, std::vector<std::str
tokens.push_back(token); tokens.push_back(token);
return true; return true;
} }
f.pos = document_data::after(entry); stack.back().pos = document_data::after(entry);
++f.index; ++stack.back().index;
if (is_container(*child) && (nav::editable() || (target > child && target < child + child->next))) if (is_container(*child) && (nav::editable() || (target > child && target < child + child->next)))
{ {
tokens.push_back(token); tokens.push_back(token);
+4 -4
View File
@@ -4621,8 +4621,8 @@ bool value_path(const document_data& d, const node* target, std::vector<std::str
// (tokens[i] leads from stack[i] to stack[i + 1], or to the target) // (tokens[i] leads from stack[i] to stack[i + 1], or to the target)
for (;;) for (;;)
{ {
// (f is not used after the stack changes: pop_back() below, push_back() at the end) // a copy: pop_back() and push_back() below change the stack
frame& f = stack.back(); const frame f = stack.back();
if (f.pos == f.end) if (f.pos == f.end)
{ {
stack.pop_back(); stack.pop_back();
@@ -4656,8 +4656,8 @@ bool value_path(const document_data& d, const node* target, std::vector<std::str
tokens.push_back(token); tokens.push_back(token);
return true; return true;
} }
f.pos = document_data::after(entry); stack.back().pos = document_data::after(entry);
++f.index; ++stack.back().index;
if (is_container(*child) && (nav::editable() || (target > child && target < child + child->next))) if (is_container(*child) && (nav::editable() || (target > child && target < child + child->next)))
{ {
tokens.push_back(token); tokens.push_back(token);