libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

commit 41bcb750d7ee0c01459be210886dad00a50e54d6
parent c4ffd734e441eab72fea517c6b8a5744c9e4b069
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date:   Mon, 17 Aug 2026 10:31:26 +0200

HTTP/2: fixed use of too large output size when limited by pool size

Diffstat:
Msrc/mhd2/h2/h2_reply_funcs.c | 28+++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/src/mhd2/h2/h2_reply_funcs.c b/src/mhd2/h2/h2_reply_funcs.c @@ -445,6 +445,7 @@ stream_content_send (struct mhd_H2Stream *s) size_t payload_used; int_least32_t wndw_limit; uint_least32_t full_payload_limit; + uint_least32_t payload_size_limit; mhd_assert (mhd_H2_RPL_STAGE_HEADERS_COMPLETE == s->rpl.stage); mhd_assert (s->rpl.send_content); @@ -469,10 +470,6 @@ stream_content_send (struct mhd_H2Stream *s) else cntnt_left = MHD_SIZE_UNKNOWN; - if ((min_size_for_data > full_payload_limit) - && (cntnt_left != full_payload_limit)) - return false; - dat = mhd_h2_frame_init_data (&h2frame, s->stream_id, false); /* could be updated below */ @@ -488,13 +485,30 @@ stream_content_send (struct mhd_H2Stream *s) pld_buff_size = buff.size - payload_offset; mhd_assert (mhd_H2_FR_HDR_BASE_SIZE < pld_buff_size); + /* The acquired buffer could be smaller than the requested limit. + The payload of this frame is limited by the acquired buffer. */ + payload_size_limit = full_payload_limit; + if (pld_buff_size < payload_size_limit) + payload_size_limit = (uint_least32_t)pld_buff_size; + + if ((min_size_for_data > payload_size_limit) + && (cntnt_left != payload_size_limit) + && (mhd_RESPONSE_CONTENT_DATA_CALLBACK != r->cntn_dtype)) + { /* The acquired space is too small to be used efficiently. + The callback content is not limited: the application may provide + the data in small portions. */ + mhd_h2_out_buff_unlock (s->c, + 0u); + return false; + } + mhd_assert (r->cntn_size > s->rpl.cntn_read_pos); payload_used = 0u; switch (r->cntn_dtype) { case mhd_RESPONSE_CONTENT_DATA_BUFFER: - payload_used = (size_t)full_payload_limit; + payload_used = (size_t)payload_size_limit; memcpy (pld_buff, r->cntn.buf + s->rpl.cntn_read_pos, payload_used); @@ -502,7 +516,7 @@ stream_content_send (struct mhd_H2Stream *s) case mhd_RESPONSE_CONTENT_DATA_IOVEC: if (!content_read_iovec (r, s->rpl.cntn_read_pos, - pld_buff_size, + (size_t)payload_size_limit, pld_buff, &payload_used)) payload_used = 0u; @@ -510,7 +524,7 @@ stream_content_send (struct mhd_H2Stream *s) case mhd_RESPONSE_CONTENT_DATA_FILE: if (!content_read_file (r, s->rpl.cntn_read_pos, - pld_buff_size, + (size_t)payload_size_limit, pld_buff, &payload_used)) payload_used = 0u;