Otherwise `arg++` will be executed for every argument after the maximum, returning a bogus value.
Consider a configuration like this: listen foo 1 2 3 [...] 64 65 Then running a configuration check within valgrind reports the following: ==18265== Conditional jump or move depends on uninitialised value(s) ==18265== at 0x56E8B83: vfprintf (vfprintf.c:1631) ==18265== by 0x57B1895: __vsnprintf_chk (vsnprintf_chk.c:63) ==18265== by 0x4A8642: vsnprintf (stdio2.h:77) ==18265== by 0x4A8642: memvprintf (tools.c:3647) ==18265== by 0x4CB8A4: print_message (log.c:1085) ==18265== by 0x4CE0AC: ha_alert (log.c:1128) ==18265== by 0x459E41: readcfgfile (cfgparse.c:1978) ==18265== by 0x507CB5: init (haproxy.c:2029) ==18265== by 0x4182A2: main (haproxy.c:3137) ==18265== ==18265== Use of uninitialised value of size 8 ==18265== at 0x56E576B: _itoa_word (_itoa.c:179) ==18265== by 0x56E912C: vfprintf (vfprintf.c:1631) ==18265== by 0x57B1895: __vsnprintf_chk (vsnprintf_chk.c:63) ==18265== by 0x4A8642: vsnprintf (stdio2.h:77) ==18265== by 0x4A8642: memvprintf (tools.c:3647) ==18265== by 0x4CB8A4: print_message (log.c:1085) ==18265== by 0x4CE0AC: ha_alert (log.c:1128) ==18265== by 0x459E41: readcfgfile (cfgparse.c:1978) ==18265== by 0x507CB5: init (haproxy.c:2029) ==18265== by 0x4182A2: main (haproxy.c:3137) ==18265== ==18265== Conditional jump or move depends on uninitialised value(s) ==18265== at 0x56E5775: _itoa_word (_itoa.c:179) ==18265== by 0x56E912C: vfprintf (vfprintf.c:1631) ==18265== by 0x57B1895: __vsnprintf_chk (vsnprintf_chk.c:63) ==18265== by 0x4A8642: vsnprintf (stdio2.h:77) ==18265== by 0x4A8642: memvprintf (tools.c:3647) ==18265== by 0x4CB8A4: print_message (log.c:1085) ==18265== by 0x4CE0AC: ha_alert (log.c:1128) ==18265== by 0x459E41: readcfgfile (cfgparse.c:1978) ==18265== by 0x507CB5: init (haproxy.c:2029) ==18265== by 0x4182A2: main (haproxy.c:3137) ==18265== ==18265== Conditional jump or move depends on uninitialised value(s) ==18265== at 0x56E91AF: vfprintf (vfprintf.c:1631) ==18265== by 0x57B1895: __vsnprintf_chk (vsnprintf_chk.c:63) ==18265== by 0x4A8642: vsnprintf (stdio2.h:77) ==18265== by 0x4A8642: memvprintf (tools.c:3647) ==18265== by 0x4CB8A4: print_message (log.c:1085) ==18265== by 0x4CE0AC: ha_alert (log.c:1128) ==18265== by 0x459E41: readcfgfile (cfgparse.c:1978) ==18265== by 0x507CB5: init (haproxy.c:2029) ==18265== by 0x4182A2: main (haproxy.c:3137) ==18265== ==18265== Conditional jump or move depends on uninitialised value(s) ==18265== at 0x56E8C59: vfprintf (vfprintf.c:1631) ==18265== by 0x57B1895: __vsnprintf_chk (vsnprintf_chk.c:63) ==18265== by 0x4A8642: vsnprintf (stdio2.h:77) ==18265== by 0x4A8642: memvprintf (tools.c:3647) ==18265== by 0x4CB8A4: print_message (log.c:1085) ==18265== by 0x4CE0AC: ha_alert (log.c:1128) ==18265== by 0x459E41: readcfgfile (cfgparse.c:1978) ==18265== by 0x507CB5: init (haproxy.c:2029) ==18265== by 0x4182A2: main (haproxy.c:3137) ==18265== ==18265== Conditional jump or move depends on uninitialised value(s) ==18265== at 0x56E941A: vfprintf (vfprintf.c:1631) ==18265== by 0x57B1895: __vsnprintf_chk (vsnprintf_chk.c:63) ==18265== by 0x4A8642: vsnprintf (stdio2.h:77) ==18265== by 0x4A8642: memvprintf (tools.c:3647) ==18265== by 0x4CB8A4: print_message (log.c:1085) ==18265== by 0x4CE0AC: ha_alert (log.c:1128) ==18265== by 0x459E41: readcfgfile (cfgparse.c:1978) ==18265== by 0x507CB5: init (haproxy.c:2029) ==18265== by 0x4182A2: main (haproxy.c:3137) ==18265== ==18265== Conditional jump or move depends on uninitialised value(s) ==18265== at 0x56E8CAB: vfprintf (vfprintf.c:1631) ==18265== by 0x57B1895: __vsnprintf_chk (vsnprintf_chk.c:63) ==18265== by 0x4A8642: vsnprintf (stdio2.h:77) ==18265== by 0x4A8642: memvprintf (tools.c:3647) ==18265== by 0x4CB8A4: print_message (log.c:1085) ==18265== by 0x4CE0AC: ha_alert (log.c:1128) ==18265== by 0x459E41: readcfgfile (cfgparse.c:1978) ==18265== by 0x507CB5: init (haproxy.c:2029) ==18265== by 0x4182A2: main (haproxy.c:3137) ==18265== ==18265== Conditional jump or move depends on uninitialised value(s) ==18265== at 0x56E8CE2: vfprintf (vfprintf.c:1631) ==18265== by 0x57B1895: __vsnprintf_chk (vsnprintf_chk.c:63) ==18265== by 0x4A8642: vsnprintf (stdio2.h:77) ==18265== by 0x4A8642: memvprintf (tools.c:3647) ==18265== by 0x4CB8A4: print_message (log.c:1085) ==18265== by 0x4CE0AC: ha_alert (log.c:1128) ==18265== by 0x459E41: readcfgfile (cfgparse.c:1978) ==18265== by 0x507CB5: init (haproxy.c:2029) ==18265== by 0x4182A2: main (haproxy.c:3137) ==18265== ==18265== Conditional jump or move depends on uninitialised value(s) ==18265== at 0x56EA2DB: vfprintf (vfprintf.c:1632) ==18265== by 0x57B1895: __vsnprintf_chk (vsnprintf_chk.c:63) ==18265== by 0x4A8642: vsnprintf (stdio2.h:77) ==18265== by 0x4A8642: memvprintf (tools.c:3647) ==18265== by 0x4CB8A4: print_message (log.c:1085) ==18265== by 0x4CE0AC: ha_alert (log.c:1128) ==18265== by 0x459E41: readcfgfile (cfgparse.c:1978) ==18265== by 0x507CB5: init (haproxy.c:2029) ==18265== by 0x4182A2: main (haproxy.c:3137) ==18265== [ALERT] 174/165720 (18265) : parsing [./config.cfg:2]: too many words, truncating at word 65, position -95900735: <(null)>. [ALERT] 174/165720 (18265) : Error(s) found in configuration file : ./config.cfg [ALERT] 174/165720 (18265) : Fatal errors found in configuration. Valgrind reports conditional jumps relying on an undefined value and the error message clearly is incorrect. After this patch is applied the relying on undefined values is gone and the <(null)> will actually show the argument. However the position still is incorrect. This will be fixed in a follow up patch. This patch fixes up commit c8d167bcfb4ae6ae19368a66d5be3e92613e0df0 which is 2.2 only. No backport needed. --- src/tools.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tools.c b/src/tools.c index 10c973761..c4eabce2f 100644 --- a/src/tools.c +++ b/src/tools.c @@ -4901,8 +4901,10 @@ uint32_t parse_line(char *in, char *out, size_t *outlen, char **args, int *nbarg arg++; if (arg < argsmax) args[arg] = out + outpos; - else + else { err |= PARSE_ERR_TOOMANY; + goto leave; + } } else if (*in == '$' && (opts & PARSE_OPT_ENV) && (dquote || !(opts & PARSE_OPT_DQUOTE))) { /* environment variables are evaluated anywhere, or only -- 2.27.0