diff options
author | Jo-Philipp Wich <jo@mein.io> | 2022-02-02 23:34:29 +0100 |
---|---|---|
committer | Jo-Philipp Wich <jo@mein.io> | 2022-02-03 16:26:44 +0100 |
commit | 3600ded530cf099a922cbff73df37d7bcf3c3008 (patch) | |
tree | 3f8766c97fba02b451fc51675df19d4161170fa3 | |
parent | 30592950f08c6ee521a939c9ea90fcf9b65b88b0 (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.c | 3 |
1 files changed, 3 insertions, 0 deletions
@@ -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; } |