diff --git a/include/types/arg.h b/include/types/arg.h index 236972148..2762674ee 100644 --- a/include/types/arg.h +++ b/include/types/arg.h @@ -63,8 +63,9 @@ union arg_data { }; struct arg { - int type; /* argument type */ - union arg_data data; /* argument data */ + unsigned char type; /* argument type, ARGT_* */ + unsigned char unresolved; /* argument contains a string in that must be resolved and freed */ + union arg_data data; /* argument data */ }; diff --git a/src/acl.c b/src/acl.c index 8ec046ff0..e51dafc9d 100644 --- a/src/acl.c +++ b/src/acl.c @@ -1227,11 +1227,10 @@ static struct acl_expr *prune_acl_expr(struct acl_expr *expr) for (arg = expr->args; arg; arg++) { if (arg->type == ARGT_STOP) break; - if (arg->type == ARGT_FE || arg->type == ARGT_BE || - arg->type == ARGT_TAB || arg->type == ARGT_SRV || - arg->type == ARGT_USR || arg->type == ARGT_STR) { + if (arg->type == ARGT_STR || arg->unresolved) { free(arg->data.str.str); arg->data.str.str = NULL; + arg->unresolved = 0; } arg++; } @@ -2065,6 +2064,8 @@ acl_find_targets(struct proxy *p) for (arg = expr->args; arg; arg++) { if (arg->type == ARGT_STOP) break; + else if (!arg->unresolved) + continue; else if (arg->type == ARGT_SRV) { struct proxy *px; struct server *srv; @@ -2107,6 +2108,8 @@ acl_find_targets(struct proxy *p) } free(expr->args->data.str.str); + expr->args->data.str.str = NULL; + arg->unresolved = 0; expr->args->data.srv = srv; } else if (arg->type == ARGT_FE) { @@ -2133,6 +2136,8 @@ acl_find_targets(struct proxy *p) } free(expr->args->data.str.str); + expr->args->data.str.str = NULL; + arg->unresolved = 0; expr->args->data.prx = prx; } else if (arg->type == ARGT_BE) { @@ -2159,6 +2164,8 @@ acl_find_targets(struct proxy *p) } free(expr->args->data.str.str); + expr->args->data.str.str = NULL; + arg->unresolved = 0; expr->args->data.prx = prx; } else if (arg->type == ARGT_TAB) { @@ -2186,6 +2193,8 @@ acl_find_targets(struct proxy *p) } free(expr->args->data.str.str); + expr->args->data.str.str = NULL; + arg->unresolved = 0; expr->args->data.prx = prx; } else if (arg->type == ARGT_USR) { @@ -2210,6 +2219,8 @@ acl_find_targets(struct proxy *p) } free(expr->args->data.str.str); + expr->args->data.str.str = NULL; + arg->unresolved = 0; expr->args->data.usr = ul; } } /* end of args processing */ diff --git a/src/arg.c b/src/arg.c index 457c5b38d..9d5fceec2 100644 --- a/src/arg.c +++ b/src/arg.c @@ -127,6 +127,11 @@ int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp, case ARGT_TAB: case ARGT_SRV: case ARGT_USR: + /* These argument types need to be stored as strings during + * parsing then resolved later. + */ + arg->unresolved = 1; + /* fall through */ case ARGT_STR: /* all types that must be resolved are stored as strings * during the parsing. The caller must at one point resolve diff --git a/src/haproxy.c b/src/haproxy.c index ff962c274..48c343344 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -772,11 +772,10 @@ static void deinit_sample_arg(struct arg *p) return; while (p->type != ARGT_STOP) { - if (p->type == ARGT_FE || p->type == ARGT_BE || - p->type == ARGT_TAB || p->type == ARGT_SRV || - p->type == ARGT_USR || p->type == ARGT_STR) { + if (p->type == ARGT_STR || p->unresolved) { free(p->data.str.str); p->data.str.str = NULL; + p->unresolved = 0; } p++; }