From: Willy Tarreau Date: Tue, 21 Jul 2020 13:44:38 +0000 (+0200) Subject: BUG/MEDIUM: arg: empty args list must be dropped X-Git-Tag: v2.3-dev2~43 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=75fd2ff83a081d0be1f512a13f4c2a44808227f9;p=thirdparty%2Fhaproxy.git BUG/MEDIUM: arg: empty args list must be dropped Before commit 80b53ffb1 ("MEDIUM: arg: make make_arg_list() stop after its own arguments"), consumers of arguments would measure the length of the string between the first opening and closing parenthesis before calling make_arg_list(), and this latter one would detect an empty string early by len==0 and would not allocate an argument list. Since that commit, this has a changed a bit because the argument parser is now the one in charge for delimiting the argument string, so the early test cannot be used anymore. But the argument list is still allocated, and despite the number of arguments being returned, consumers do not necessarily rely on it but instead they rely on the non-null arg_p pointer that used to be allocated only if at least one argument was present. But as it's now always allocated, the first argument always carries the first argument's type with an empty value, which confuses all functions that take a unique optional argument (such as uuid()). The proper long term solution would be to always use the returned argument count, but at least we can make sure the function always returns an empty argument list when fed with an empty set of parenthesis, as it always used to do. This is what this patch does. This fix must be backported to 2.2 and fixes github issue #763. Thanks to Luke Seelenbinder for reporting the problem. --- diff --git a/src/arg.c b/src/arg.c index ec7626d008..df5929877d 100644 --- a/src/arg.c +++ b/src/arg.c @@ -395,6 +395,14 @@ int make_arg_list(const char *in, int len, uint64_t mask, struct arg **argp, return -1; empty_err: + /* If we've only got an empty set of parenthesis with nothing + * in between, there is no arg at all. + */ + if (!pos) { + free(*argp); + *argp = NULL; + } + if (pos >= min_arg) goto end_parse;