]> git.kaiwu.me - haproxy.git/commit
BUG/MINOR: h3: don't use a block pointer to roll back a partial HTX conversion
authorWilly Tarreau <w@1wt.eu>
Mon, 27 Jul 2026 08:58:43 +0000 (10:58 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 27 Jul 2026 13:29:55 +0000 (15:29 +0200)
commit909785d67db3d5ab3cdf4c971de85220eda8cc90
treebc5fe1200ac5b7c8de6fe84fc46eafa2ec9fbd34
parent865351d4ed7cb883349fe8b61ee1aacade8f467e
BUG/MINOR: h3: don't use a block pointer to roll back a partial HTX conversion

h3_resp_headers_to_htx() and h3_trailers_to_htx() save a pointer on the tail
HTX block of the destination message and use it to remove whatever they added
when the conversion fails:

tailblk = htx_get_tail_blk(htx);
...
 out:
if (appbuf) {
if ((ssize_t)len < 0)
htx_truncate_blk(htx, tailblk);

An HTX block pointer encodes a block *position* (the table is indexed backwards
from the end of the storage area), so it stops designating the same block as
soon as the table is compacted. htx_add_trailer() may reach
htx_reserve_nxblk(), which calls htx_defrag_blks() when the block table has
grown down to the payload while htx->head > 0, i.e. for a nearly full buffer
whose head was already consumed. All blocks then move down by the old value of
htx->head while the saved pointer does not follow, and htx_truncate_blk()
truncates at the wrong place, leaving partially converted trailers in the
message or removing valid blocks.

Only the trailers are really concerned: h3_resp_headers_to_htx() refuses to
work on a non-empty message, so no defragmentation can happen there, but it is
fixed the same way for consistency.

Let's save the amount of data present before the conversion and use
htx_truncate(), which works on a byte offset and is thus insensitive to any
block move, as htx_append_msg() already does.

This should be backported to all versions where the H3 trailers are supported,
so 2.8 and above.
src/h3.c