]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: config: warn about the consequences of empty arguments on a config line
authorWilly Tarreau <w@1wt.eu>
Fri, 2 May 2025 13:47:41 +0000 (15:47 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 5 May 2025 14:17:24 +0000 (16:17 +0200)
For historical reasons, the config parser relies on the trailing '\0'
to detect the end of the line being parsed. When the lines started to be
tokenized into arguments, this principle has been preserved, and now all
the parsers rely on *args[arg]='\0' to detect the end of a line. But as
reported in issue #2944, while most of the time it breaks the parsing
like below:

     http-request deny if { path_dir '' }

it can also cause some elements to be silently ignored like below:

     acl bad_path path_sub '%2E' '' '%2F'

This may also subtly happen with environment variables that don't exist
or which are empty:

     acl bad_path path_sub '%2E' "$BAD_PATTERN" '%2F'

Fortunately, parse_line() returns the number of arguments found, so it's
easy from the callers to verify if any was empty. The goal of this commit
is not to perform sensitive changes, it's only to mention when parsing a
line that an empty argument was found and alert about its consequences
using a warning. Most of the time when this happens, the config does not
parse. But for examples as the ACLs above, there could be consequences
that are better detected early.

This patch depends on this previous fix:
   BUG/MINOR: tools: do not create an empty arg from trailing spaces

Co-authored-by: Valentine Krasnobaeva <vkrasnobaeva@haproxy.com>
src/cfgparse.c

index 7716b6cd50631e18926f89cfe065f35ecf20aed4..2123dd4c5d3328a9d31d6cfb14f121c38ba105ff 100644 (file)
@@ -1982,6 +1982,7 @@ next_line:
                while (1) {
                        uint32_t err;
                        const char *errptr;
+                       int check_arg;
 
                        arg = sizeof(args) / sizeof(*args);
                        outlen = outlinesize;
@@ -2064,6 +2065,14 @@ next_line:
                                goto next_line;
                        }
 
+                       for (check_arg = 0; check_arg < arg; check_arg++) {
+                               if (*args[check_arg])
+                                       continue;
+                               ha_warning("parsing [%s:%d]: argument number %d is empty and marks the end of the argument list; all subsequent arguments will be ignored.\n",
+                                          file, linenum, check_arg + 1);
+                               break;
+                       }
+
                        /* everything's OK */
                        break;
                }