Skip to content

Commit

Permalink
Fix memory leak in compile_string()
Browse files Browse the repository at this point in the history
When a provided variable/function/struct lookup function returns the same value
for different names, the returned object leaks.
  • Loading branch information
amotzkau committed Oct 2, 2023
1 parent cff0fa7 commit 7808384
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
6 changes: 3 additions & 3 deletions src/prolang.y
Original file line number Diff line number Diff line change
Expand Up @@ -6680,7 +6680,7 @@ find_struct ( ident_t * ident, efun_override_t override )
lt->t_struct.def_idx = LAMBDA_STRUCTS_COUNT;

assign_svalue_no_free(&ref_str, str); /* Add a reference. */
idx = store_lambda_value(str);
idx = store_lambda_value(&ref_str);

name->u.global.struct_id = LAMBDA_STRUCTS_COUNT;
ADD_LAMBDA_STRUCT((lambda_struct_ident_t){
Expand Down Expand Up @@ -8659,7 +8659,7 @@ lookup_function (ident_t *ident, char* super, efun_override_t override)
int idx;

assign_svalue_no_free(&ref_fun, fun); /* Add a reference. */
idx = store_lambda_value(fun);
idx = store_lambda_value(&ref_fun);

ident->u.global.function = LAMBDA_FUNCTIONS_COUNT;
ADD_LAMBDA_FUNCTION((lambda_ident_t){.kind = LAMBDA_IDENT_VALUE, .value_index = idx});
Expand Down Expand Up @@ -8770,7 +8770,7 @@ lookup_global_variable (ident_t *ident)
int idx;

assign_svalue_no_free(&ref_var, var); /* Add a reference. */
idx = store_lambda_value(var);
idx = store_lambda_value(&ref_var);

ident->u.global.variable = LAMBDA_VARIABLES_COUNT;
ADD_LAMBDA_VARIABLE((lambda_ident_t){.kind = LAMBDA_IDENT_VALUE, .value_index = idx});
Expand Down
28 changes: 28 additions & 0 deletions test/t-efuns.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,15 @@ mixed *tests =
}))) == "ABCZ";
:)
}),
({ "compile_string (same function multiple times from function)", 0,
(:
return funcall(compile_string(0, "fun1() + fun2() + fun3()", (<cs_opts>
functions: function closure(symbol name) : closure cl = function int() { return 10; }
{
return cl;
}))) == 30;
:)
}),
({ "compile_string (missing function from function)", TF_ERROR,
(:
compile_string(0, "fun1() + fun2(\"z\")", (<cs_opts>
Expand Down Expand Up @@ -541,6 +550,15 @@ mixed *tests =
}))) == "ABCX" && v2 == "X";
:)
}),
({ "compile_string (same value multiple times from function)", 0,
(:
return funcall(compile_string(0, "a+b+c", (<cs_opts>
variables: function mixed(symbol name) : int value = 10
{
return &value;
}))) == 30;
:)
}),
({ "compile_string (variable, missing in function)", TF_ERROR,
(:
string v1 = "ABC";
Expand Down Expand Up @@ -628,6 +646,16 @@ mixed *tests =
}));
:)
}),
({ "compile_string (same struct multiple times from function)", 0,
(:
return deep_eq(funcall(compile_string(0,
"({ (<my_struct1> ({10})), (<my_struct2> ({20})), (<my_struct3> ({30})) })", (<cs_opts>
structs: function struct mixed(symbol name) : struct test_struct s = (<test_struct>)
{
return s;
}))), ({ (<test_struct> ({10})), (<test_struct> ({20})), (<test_struct> ({30})) }));
:)
}),
({ "compile_string (struct from object)", 0,
(:
return deep_eq(funcall(compile_string(0, "(<test_struct> ({10}))", (<cs_opts> use_object_structs: 1))),
Expand Down

0 comments on commit 7808384

Please sign in to comment.