From 46dfd78cbf2591ab9cd2d8e30046e811f4179f7b Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 17 Dec 2019 10:25:29 +0100 Subject: [PATCH] BUG/MINOR: sample: always check converters' arguments In 1.5-dev20, sample-fetch arguments parsing was addresse by commit 689a1df0a1 ("BUG/MEDIUM: sample: simplify and fix the argument parsing"). The issue was that argument checks were not run for sample-fetches if parenthesis were not present. Surprisingly, the fix was mde only for sample-fetches and not for converters which suffer from the exact same problem. There are even a few comments in the code mentioning that some argument validation functions are not called when arguments are missing. This fix applies the exact same method as the one above. The impact of this bug is limited because over the years the code has learned to work around this issue instead of fixing it. This may be backported to all maintained versions. --- src/sample.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/sample.c b/src/sample.c index b3d28cab55..b124c4b861 100644 --- a/src/sample.c +++ b/src/sample.c @@ -921,6 +921,8 @@ struct sample_expr *sample_parse_expr(char **str, int *idx, const char *file, in while (1) { struct sample_conv_expr *conv_expr; + int err_arg; + int argcnt; if (*endt == ')') /* skip last closing parenthesis */ endt++; @@ -963,6 +965,7 @@ struct sample_expr *sample_parse_expr(char **str, int *idx, const char *file, in endt = endw; if (*endt == '(') { /* look for the end of this term */ + endt = ++endw; while (*endt && *endt != ')') endt++; if (*endt != ')') { @@ -990,31 +993,24 @@ struct sample_expr *sample_parse_expr(char **str, int *idx, const char *file, in LIST_ADDQ(&(expr->conv_exprs), &(conv_expr->list)); conv_expr->conv = conv; - if (endt != endw) { - int err_arg; - - if (!conv->arg_mask) { - memprintf(err_msg, "converter '%s' does not support any args", ckw); - goto out_error; - } + al->kw = expr->fetch->kw; + al->conv = conv_expr->conv->kw; + argcnt = make_arg_list(endw, endt - endw, conv->arg_mask, &conv_expr->arg_p, err_msg, NULL, &err_arg, al); + if (argcnt < 0) { + memprintf(err_msg, "invalid arg %d in converter '%s' : %s", err_arg+1, ckw, *err_msg); + goto out_error; + } - al->kw = expr->fetch->kw; - al->conv = conv_expr->conv->kw; - if (make_arg_list(endw + 1, endt - endw - 1, conv->arg_mask, &conv_expr->arg_p, err_msg, NULL, &err_arg, al) < 0) { - memprintf(err_msg, "invalid arg %d in converter '%s' : %s", err_arg+1, ckw, *err_msg); - goto out_error; - } + if (argcnt && !conv->arg_mask) { + memprintf(err_msg, "converter '%s' does not support any args", ckw); + goto out_error; + } - if (!conv_expr->arg_p) - conv_expr->arg_p = empty_arg_list; + if (!conv_expr->arg_p) + conv_expr->arg_p = empty_arg_list; - if (conv->val_args && !conv->val_args(conv_expr->arg_p, conv, file, line, err_msg)) { - memprintf(err_msg, "invalid args in converter '%s' : %s", ckw, *err_msg); - goto out_error; - } - } - else if (ARGM(conv->arg_mask)) { - memprintf(err_msg, "missing args for converter '%s'", ckw); + if (conv->val_args && !conv->val_args(conv_expr->arg_p, conv, file, line, err_msg)) { + memprintf(err_msg, "invalid args in converter '%s' : %s", ckw, *err_msg); goto out_error; } } -- 2.39.5