summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2020-10-19 13:36:09 +0200
committerJo-Philipp Wich <jo@mein.io>2020-10-19 13:40:41 +0200
commit036ba87c5d18385c5da13c331658363ea0ba6afe (patch)
treeac89ce98fde5e88fac1833236513ac09a2b48c1a
parent898a28de86600b62ddd5f971b910eaadc222bbb7 (diff)
eval: avoid ut_op deref after ut_execute_op() in ut_execute_local()
Since we're invoking ut_execute_op() to obtain the assignment value, the operand pool might have been reallocated at a different memory address, invalidating the label opcode pointer. Obtain a reference to the underlying json label value and re-obtain the assignment opcode pointer with each iteration to avoid dereferencing stale pointers. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--eval.c19
1 files changed, 10 insertions, 9 deletions
diff --git a/eval.c b/eval.c
index 3d76774..c0ad2c3 100644
--- a/eval.c
+++ b/eval.c
@@ -411,23 +411,24 @@ ut_execute_assign(struct ut_state *state, uint32_t off)
static struct json_object *
ut_execute_local(struct ut_state *state, uint32_t off)
{
- struct ut_op *as = ut_get_child(state, off, 0);
- struct json_object *val, *rv = NULL;
- struct ut_op *label;
+ struct ut_op *op = ut_get_op(state, off), *asop, *alop;
+ uint32_t as = op ? op->tree.operand[0] : 0;
+ struct json_object *label, *val, *rv = NULL;
while (as) {
- label = ut_get_op(state, as->tree.operand[0]);
+ asop = ut_get_op(state, as);
+ alop = asop ? ut_get_child(state, as, 0) : NULL;
+ as = asop ? asop->tree.next : 0;
- if (label) {
- val = as->tree.operand[1] ? ut_execute_op(state, as->tree.operand[1]) : NULL;
+ if (alop) {
+ label = alop->val;
+ val = asop->tree.operand[1] ? ut_execute_op(state, asop->tree.operand[1]) : NULL;
if (ut_is_type(val, T_EXCEPTION))
return val;
- rv = ut_setval(state->scope->scope, label->val, val);
+ rv = ut_setval(state->scope->scope, label, val);
}
-
- as = ut_get_op(state, as->tree.next);
}
return rv;