]> git.kaiwu.me - haproxy.git/commitdiff
CLEANUP: tools: make inetaddr_host_lim*() usable on untrusted inputs
authorWilly Tarreau <w@1wt.eu>
Tue, 3 Nov 2026 07:49:52 +0000 (08:49 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 3 Nov 2026 07:57:32 +0000 (08:57 +0100)
inetaddr_host_lim() and inetaddr_host_lim_ret() were introduced in 1.4.4
by commit d54bbdce87 ("[MINOR] add very fast IP parsing functions") as
fast parsers for some specific use cases. They expect a delimiter after
the IP address (cr/lf/nul/whatever, in fact, anything not a digit), and
this is how they're currently used. As noted by Md. Raisul Islam Mobin,
they could also be misused by external code not aware of this limitation
which by then saved a few CPU cycles per address at an era where they
were still precious, so let's test the end pointer before reading the
digit to make it more future-proof. If this speed still matters, these
ones could probably be rewritten to benefit from automatic vectorization
on SIMD-capable machines.

src/tools.c

index 11ad0f03a96a8fd787189d07519ae40bd9e7af05..f257cee0a2e195d29e613b4f9ffeb9b549e4bfa9 100644 (file)
@@ -3527,10 +3527,8 @@ unsigned int inetaddr_host_lim(const char *text, const char *stop)
 
        p = text;
        while (1) {
-               if (((unsigned)(*p - '0')) <= 9 && p < stop) {
+               while (p < stop && ((unsigned)(*p - '0')) <= 9)
                        p++;
-                       continue;
-               }
 
                /* here, we have a complete byte between <text> and <p> (exclusive) */
                if (p == text)
@@ -3578,10 +3576,8 @@ unsigned int inetaddr_host_lim_ret(char *text, char *stop, char **ret)
 
        p = text;
        while (1) {
-               if (((unsigned)(*p - '0')) <= 9 && p < stop) {
+               while (p < stop && ((unsigned)(*p - '0')) <= 9)
                        p++;
-                       continue;
-               }
 
                /* here, we have a complete byte between <text> and <p> (exclusive) */
                if (p == text)