From: Willy Tarreau Date: Wed, 8 Sep 2021 09:07:32 +0000 (+0200) Subject: MEDIUM: vars: pre-create parsed SCOPE_PROC variables as permanent ones X-Git-Tag: v2.5-dev7~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=df8eeb1619580a39dc4c3605cef472b10bb3386c;p=thirdparty%2Fhaproxy.git MEDIUM: vars: pre-create parsed SCOPE_PROC variables as permanent ones All variables whose names are parsed by the config parser, the command-line parser or the SPOE's register-var-names parser are now preset as permanent. This will guarantee that these variables will exist through out all the process' life, and that it will be possible to implement the "ifexist" feature by looking them up. This was marked medium because pre-setting a variable with an empty value may always have side effects, even though none was spotted at this stage. --- diff --git a/src/vars.c b/src/vars.c index 6fc58dd33b..30bcf3df96 100644 --- a/src/vars.c +++ b/src/vars.c @@ -529,6 +529,7 @@ int vars_check_arg(struct arg *arg, char **err) { char *name; enum vars_scope scope; + struct sample empty_smp = { }; /* Check arg type. */ if (arg->type != ARGT_STR) { @@ -543,6 +544,9 @@ int vars_check_arg(struct arg *arg, char **err) if (!name) return 0; + if (scope == SCOPE_PROC && !var_set(name, scope, &empty_smp, VF_CREATEONLY|VF_PERMANENT)) + return 0; + /* properly destroy the chunk */ chunk_destroy(&arg->data.str); @@ -823,6 +827,7 @@ static enum act_parse_ret parse_store(const char **args, int *arg, struct proxy int var_len; const char *kw_name; int flags, set_var = 0; /* 0=unset-var, 1=set-var, 2=set-var-fmt */ + struct sample empty_smp = { }; if (strncmp(var_name, "set-var-fmt", 11) == 0) { var_name += 11; @@ -856,6 +861,10 @@ static enum act_parse_ret parse_store(const char **args, int *arg, struct proxy if (!rule->arg.vars.name) return ACT_RET_PRS_ERR; + if (rule->arg.vars.scope == SCOPE_PROC && + !var_set(rule->arg.vars.name, rule->arg.vars.scope, &empty_smp, VF_CREATEONLY|VF_PERMANENT)) + return 0; + /* There is no fetch method when variable is unset. Just set the right * action and return. */ if (!set_var) {