summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJo-Philipp Wich <jo@mein.io>2022-02-02 23:34:29 +0100
committerJo-Philipp Wich <jo@mein.io>2022-02-03 16:26:44 +0100
commit3600ded530cf099a922cbff73df37d7bcf3c3008 (patch)
tree3f8766c97fba02b451fc51675df19d4161170fa3
parent30592950f08c6ee521a939c9ea90fcf9b65b88b0 (diff)
vm: fix leaking function value on call exception
The internal uc_vm_call_function() helper may fail in different ways before the stack frame has been set up, e.g. if the provided function value was not actually a callable function. In such cases an exception is raised but the actual function value is leaked since there's not yet a stackframe referring to it. Solve the issue by freeing the function value explicitly in these exit cases. Signed-off-by: Jo-Philipp Wich <jo@mein.io>
-rw-r--r--vm.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/vm.c b/vm.c
index 6e3713a..93ac704 100644
--- a/vm.c
+++ b/vm.c
@@ -459,6 +459,7 @@ uc_vm_call_function(uc_vm_t *vm, uc_value_t *ctx, uc_value_t *fno, bool mcall, s
/* XXX: make dependent on stack size */
if (vm->callframes.count >= 1000) {
uc_vm_raise_exception(vm, EXCEPTION_RUNTIME, "Too much recursion");
+ ucv_put(fno);
return false;
}
@@ -495,6 +496,7 @@ uc_vm_call_function(uc_vm_t *vm, uc_value_t *ctx, uc_value_t *fno, bool mcall, s
s = ucv_to_string(vm, arg);
uc_vm_raise_exception(vm, EXCEPTION_TYPE, "(%s) is not iterable", s);
free(s);
+ ucv_put(fno);
return false;
}
@@ -526,6 +528,7 @@ uc_vm_call_function(uc_vm_t *vm, uc_value_t *ctx, uc_value_t *fno, bool mcall, s
if (ucv_type(fno) != UC_CLOSURE) {
uc_vm_raise_exception(vm, EXCEPTION_TYPE, "left-hand side is not a function");
+ ucv_put(fno);
return false;
}