From: Amaury Denoyelle Date: Wed, 7 Oct 2026 13:31:40 +0000 (+0200) Subject: BUG/MEDIUM: h3: fix end-of-input report on DATA wrapping X-Git-Tag: v3.5-dev9~172 X-Git-Url: https://git.kaiwu.me/$%7BGITURL%7D$%7Bcid%7D?a=commitdiff_plain;h=bcdbc399d34f82a21c49162f203f2ff16b0aed79;p=haproxy.git BUG/MEDIUM: h3: fix end-of-input report on DATA wrapping A received H3 DATA frame may wrap in the buffer. Function h3_data_to_htx() will parse it in two pass in this case, calling htx_add_data() twice. A double bug was present in case of such parsing as second call of htx_add_data() return value was immediately added in . This could cause first check to activate QC_SF_DEM_FULL to be ignored. This is a minor issue, as MUX would immediately reinvoke h3_rcv_buf(), with the flag set this time. The second bug is more important : comparison for HTX EOM reporting was invalid in case of a two pass parsing. Most of the time, this result in EOM not reported, causing the stream layer to report a stream interruption with state CL--. Fix this by using an intermediary return value for the second htx_add_data() invokation. This value is only added to once necessary checks are performed. It is important to keep h3_data_to_htx() to still return the total value of HTX added data to avoid parser desync issue. This must be backported up to 2.6, after a period of observation. --- diff --git a/src/h3.c b/src/h3.c index fb6d9556b..a52538cf8 100644 --- a/src/h3.c +++ b/src/h3.c @@ -1669,7 +1669,7 @@ static ssize_t h3_data_to_htx(struct qcs *qcs, const struct buffer *buf, { struct buffer *appbuf = NULL; struct htx *htx = NULL; - size_t htx_sent = 0; + size_t htx_sent = 0, ret; int htx_space; char *head; @@ -1734,14 +1734,15 @@ static ssize_t h3_data_to_htx(struct qcs *qcs, const struct buffer *buf, goto retry; } - htx_sent += htx_add_data(htx, ist2(head, len)); - if (htx_sent < len) { + ret = htx_add_data(htx, ist2(head, len)); + if (ret < len) { qcs->flags |= QC_SF_DEM_FULL; goto out; } - if (fin && len == htx_sent) + if (fin && len == ret) htx_set_eom(htx); + htx_sent += ret; out: if (appbuf)