Fix extra heap_unref for ref arguments in delegate calls

When a delegate finishes calling all registered functions,
variable_fini() was called on the original stack arguments. For ref
types, this results in an unbalanced heap_unref() because the caller
pushes raw ref-values without incrementing the reference count. Non-ref
string/struct/array arguments are not affected because their push
instructions allocate new heap slots with ownership.

This fixes use-after-free in T_Loop@checkSelect in Rance 9.
This commit is contained in:
kichikuou
2026-03-28 08:18:41 +09:00
parent ecc04bc9bb
commit 197b89620c
+9 -1
View File
@@ -421,7 +421,15 @@ static void delegate_call(int dg_no, int return_address)
stack_pop(); // dg_index
stack_pop(); // dg_page
for (int i = ain->delegates[dg_no].nr_variables - 1; i >= 0; i--) {
variable_fini(stack_pop(), ain->delegates[dg_no].variables[i].type.data, true);
union vm_value v = stack_pop();
enum ain_data_type type = ain->delegates[dg_no].variables[i].type.data;
switch (type) {
case AIN_REF_TYPE:
break;
default:
variable_fini(v, type, true);
break;
}
}
if (return_values) {
stack_push(r);