From: Willy Tarreau Date: Mon, 12 May 2025 14:01:27 +0000 (+0200) Subject: BUG/MINOR: tools: improve parse_line()'s robustness against empty args X-Git-Tag: v3.2-dev16~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b60e54fb1;p=thirdparty%2Fhaproxy.git BUG/MINOR: tools: improve parse_line()'s robustness against empty args The fix in 10e6d0bd57 ("BUG/MINOR: tools: only fill first empty arg when not out of range") was not that good. It focused on protecting against becoming out of range to detect we haven't emitted anything, but it's not the right way to detect this. We're always maintaining arg_start as a copy of outpos, and that later one is incremented when emitting a char, so instead of testing args[arg] against out+arg_start, we should instead check outpos against arg_start, thereby eliminating the offset and the need to access args[]. This way we now always know if we've emitted an empty arg without dereferencing args[]. There's no need to backport this unless the fix above is also backported. --- diff --git a/src/tools.c b/src/tools.c index 97b8d65b4..723ea6602 100644 --- a/src/tools.c +++ b/src/tools.c @@ -6439,7 +6439,7 @@ uint32_t parse_line(char *in, char *out, size_t *outlen, char **args, int *nbarg err |= PARSE_ERR_TOOMANY; } if (prev_in_arg && !in_arg) { - if (!empty_arg_ptr && arg < argsmax && args[arg] == out + arg_start) + if (!empty_arg_ptr && outpos == arg_start) empty_arg_ptr = begin_new_arg; EMIT_CHAR(0); arg++; @@ -6481,19 +6481,21 @@ uint32_t parse_line(char *in, char *out, size_t *outlen, char **args, int *nbarg } if (prev_in_arg && !in_arg) { - if (!empty_arg_ptr && arg < argsmax && args[arg] == out + arg_start) + if (!empty_arg_ptr && outpos == arg_start) empty_arg_ptr = begin_new_arg; EMIT_CHAR(0); arg++; + arg_start = outpos; } } /* end of output string */ if (in_arg) { - if (!empty_arg_ptr && arg < argsmax && args[arg] == out + arg_start) + if (!empty_arg_ptr && outpos == arg_start) empty_arg_ptr = begin_new_arg; EMIT_CHAR(0); arg++; + arg_start = outpos; } if (quote) {