From: Willy Tarreau Date: Wed, 30 Sep 2026 06:50:07 +0000 (+0200) Subject: BUG/MINOR: http: do not consume the delimiter of a truncated q-factor X-Git-Tag: v3.5-dev8~87 X-Git-Url: https://git.kaiwu.me/%7B@url%7D?a=commitdiff_plain;h=f9dd42a9c1c337a846683910a9f9c8f6184c3479;p=haproxy.git BUG/MINOR: http: do not consume the delimiter of a truncated q-factor http_parse_qvalue() increments its cursor before checking that the character it just read is the '.' which must follow the integer part: if (*qvalue++ != '.') goto out; so when the q-factor has no decimal part, as in "q=0", the cursor reported through points one byte past the character which terminated it, that is past the ',' separating it from the next value. sample_conv_q_preferred(), which implements the "language" converter, resumes its scan at that position and then looks for the next ',' from there, so it silently skips everything up to the following separator. With "accept-language: fr;q=0, en;q=0.1" the "en" value is never examined and the converter reports no match at all, while "q=0.0" works as expected. The other caller, the accept-encoding parsing of the compression filter, passes NULL as and is unaffected. Note that this bug has been there since the introduction of the function in 1.5-dev23 via commit 0e9b1b4d1f ("MEDIUM: compression: consider the "q=" attribute in Accept-Encoding"). This should be backported to all branches. --- diff --git a/src/http.c b/src/http.c index c29f77572..9cc202475 100644 --- a/src/http.c +++ b/src/http.c @@ -1266,8 +1266,9 @@ int http_parse_qvalue(const char *qvalue, const char **end) goto out; q = (*qvalue++ - '0') * 1000; - if (*qvalue++ != '.') + if (*qvalue != '.') goto out; + qvalue++; if (!isdigit((unsigned char)*qvalue)) goto out;