]> git.kaiwu.me - haproxy.git/commitdiff
BUG/MINOR: h3: reset HTX message after trailers parsing error
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Tue, 27 Oct 2026 14:42:04 +0000 (15:42 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 28 Oct 2026 10:06:00 +0000 (11:06 +0100)
HTTP/3 trailers parsing was adapted by the following patch to rely on
the common function http_trailers_to_htx().

  25a11d345425be08cb01fec0eae5dfe8b423ee57
  MEDIUM: h3: rely on the generic trailers parser

Along this change, h3_trailers_to_htx() error path has been updated to
regroup failure with or without glitch via two labels. However, it
bypasses HTX message reset, leaving the stream buffer appearing as full
and possibly containing a partial trailers conversion.

Fix this by restoring the single unified function end. Return value and
glitch are directly adjusted in the switch statement from
http_trailers_to_htx() result.

No need to backport.

src/h3.c

index 7510a0a04ca0ffac7aaf3972b3d039d48da323b2..d8cf0c28190d384e2ba2ce07d947ef319a9f2151 100644 (file)
--- a/src/h3.c
+++ b/src/h3.c
@@ -1609,15 +1609,24 @@ static ssize_t h3_trailers_to_htx(struct qcs *qcs, const struct buffer *buf,
                 * Pseudo-header fields MUST NOT appear in trailer sections.
                 */
                TRACE_ERROR("pseudo-header field in trailers", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
-               goto fail_with_glitch;
+               h3s->err = H3_ERR_MESSAGE_ERROR;
+               qcc_report_glitch(h3c->qcc, 1);
+               len = -1;
+               goto out;
 
        case HTTP_PRS_INV_HNAME:
                TRACE_ERROR("invalid characters in field name", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
-               goto fail_with_glitch;
+               h3s->err = H3_ERR_MESSAGE_ERROR;
+               qcc_report_glitch(h3c->qcc, 1);
+               len = -1;
+               goto out;
 
        case HTTP_PRS_FORB_TRL:
                TRACE_ERROR("forbidden HTTP/3 headers", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
-               goto fail_with_glitch;
+               h3s->err = H3_ERR_MESSAGE_ERROR;
+               qcc_report_glitch(h3c->qcc, 1);
+               len = -1;
+               goto out;
 
        case HTTP_PRS_INV_HVAL:
                /* RFC 9114 10.3 Intermediary-Encapsulation Attacks
@@ -1630,7 +1639,10 @@ static ssize_t h3_trailers_to_htx(struct qcs *qcs, const struct buffer *buf,
                 * value MUST be treated as malformed
                 */
                TRACE_ERROR("control character present in trailer value", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
-               goto fail_with_glitch;
+               h3s->err = H3_ERR_MESSAGE_ERROR;
+               qcc_report_glitch(h3c->qcc, 1);
+               len = -1;
+               goto out;
 
        default:
                /* Not a protocol error, only the trailers block could not
@@ -1638,7 +1650,8 @@ static ssize_t h3_trailers_to_htx(struct qcs *qcs, const struct buffer *buf,
                 * caused by too large trailers).
                 */
                TRACE_ERROR("cannot add trailer", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
-               goto fail;
+               len = -1;
+               goto out;
        }
 
        if (fin)
@@ -1661,13 +1674,6 @@ static ssize_t h3_trailers_to_htx(struct qcs *qcs, const struct buffer *buf,
 
        TRACE_LEAVE(H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
        return len;
-
- fail_with_glitch:
-       qcc_report_glitch(h3c->qcc, 1);
-       h3s->err = H3_ERR_MESSAGE_ERROR;
- fail:
-       TRACE_DEVEL("leaving on error", H3_EV_RX_FRAME|H3_EV_RX_HDR, qcs->qcc->conn, qcs);
-       return -1;
 }
 
 /* Copy from buffer <buf> a H3 DATA frame of length <len> in QUIC stream <qcs>