From 2b60e54fb1fb825a65f0668d83d912d7af873295 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 12 May 2025 16:01:27 +0200 Subject: [PATCH] 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. --- src/tools.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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) { -- 2.39.5