Skip to content

Commit

Permalink
CFE-4244: Add the function name to the result cache key
Browse files Browse the repository at this point in the history
The function cache only used the args values, which in some cases
could lead to mixing results from different functions with the same arguments.
  • Loading branch information
amousset committed Sep 11, 2023
1 parent 57745c7 commit 4fbabae
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
18 changes: 16 additions & 2 deletions libpromises/eval_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -2837,7 +2837,14 @@ bool EvalContextFunctionCacheGet(const EvalContext *ctx,
return false;
}

Rval *rval = FuncCacheMapGet(ctx->function_cache, args);
// The cache key is made of the function name and all args values
Rlist *args_copy = RlistCopy(args);
assert(fp != NULL);
assert(fp->name != NULL);
assert(ctx != NULL);
Rlist *key = RlistPrepend(&args_copy, fp->name, RVAL_TYPE_SCALAR);
Rval *rval = FuncCacheMapGet(ctx->function_cache, key);
RlistDestroy(key);
if (rval)
{
if (rval_out)
Expand All @@ -2863,7 +2870,14 @@ void EvalContextFunctionCachePut(EvalContext *ctx,

Rval *rval_copy = xmalloc(sizeof(Rval));
*rval_copy = RvalCopy(*rval);
FuncCacheMapInsert(ctx->function_cache, RlistCopy(args), rval_copy);

Rlist *args_copy = RlistCopy(args);
assert(fp != NULL);
assert(fp->name != NULL);
assert(ctx != NULL);
Rlist *key = RlistPrepend(&args_copy, fp->name, RVAL_TYPE_SCALAR);

FuncCacheMapInsert(ctx->function_cache, key, rval_copy);
}

/* cfPS and associated machinery */
Expand Down
38 changes: 38 additions & 0 deletions tests/acceptance/01_vars/02_functions/cache_name.cf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#######################################################
#
# Test that the function result cache checks function name
#
#######################################################

body common control
{
inputs => { "../../default.cf.sub" };
bundlesequence => { default("$(this.promise_filename)") };
version => "1.0";
}

#######################################################


bundle agent init
{
}

#######################################################

bundle agent test
{
vars:
"res1" string => host2ip("cfengine.com");
# must not reuse result from previous line
"res2" string => ip2host("cfengine.com");
}


#######################################################

bundle agent check
{
methods:
"any" usebundle => dcs_check_strcmp("${test.res1}", "${test.res2}", "$(this.promise_filename)", "yes");
}

0 comments on commit 4fbabae

Please sign in to comment.