libmicrohttpd2

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

commit 336517d01ce8414d81c71f00a0fa16b54bb26ca8
parent f0fecd1b5e816bbed5f45778dc1abd3148e4d698
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date:   Thu, 29 Oct 2026 22:04:38 +0100

Replaced variable-length array parameters with pointers

Some function parameters were declared as variable-length arrays even
though the corresponding size can be zero. A VLA bound must be greater
than zero, so valid zero-size calls triggered undefined behaviour before
the function body was entered.

Replaced the array declarations with plain pointers and retained their
size annotations using MHD_FN_PAR_IN_SIZE_(). This also permits NULL
pointers when the corresponding size is zero.

Patch provided by Sami Jawhar on the mailing list.

Diffstat:
Mdoc/manual/responses.inc | 4++--
Msrc/include/microhttpd2.h | 10++++++----
Msrc/include/microhttpd2_main.h.in | 7++++---
Msrc/include/microhttpd2_preamble.h.in | 3++-
Msrc/mhd2/response_from.c | 11++++++-----
5 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/doc/manual/responses.inc b/doc/manual/responses.inc @@ -218,7 +218,7 @@ Return @code{NULL} on error (i.e. invalid arguments, out of memory). @end deftypefun @anchor{MHD_response_from_buffer_copy} -@deftypefun {struct MHD_Response *} MHD_response_from_buffer_copy (enum MHD_HTTP_StatusCode sc, size_t buffer_size, const char buffer[buffer_size]) +@deftypefun {struct MHD_Response *} MHD_response_from_buffer_copy (enum MHD_HTTP_StatusCode sc, size_t buffer_size, const char *buffer) Create a response object from an ephemeral @var{buffer}. The data in the @var{buffer} will be copied into internal storage of MHD. @@ -268,7 +268,7 @@ use to implement this.} @cindex scatter write @cindex writev @anchor{MHD_response_from_iovec} -@deftypefun {struct MHD_Response *} MHD_response_from_iovec (enum MHD_HTTP_StatusCode sc, unsigned int iov_count, const struct MHD_IoVec iov[iov_count], MHD_FreeCallback free_cb, void *free_cb_cls) +@deftypefun {struct MHD_Response *} MHD_response_from_iovec (enum MHD_HTTP_StatusCode sc, unsigned int iov_count, const struct MHD_IoVec *iov, MHD_FreeCallback free_cb, void *free_cb_cls) Create a response object from an array of memory buffers. @table @var diff --git a/src/include/microhttpd2.h b/src/include/microhttpd2.h @@ -3912,7 +3912,8 @@ MHD_EXTERN_ enum MHD_StatusCode MHD_connection_set_psk ( struct MHD_ServerCredentialsContext *mscc, size_t psk_size, - const /*void? */ char psk[MHD_FN_PAR_DYN_ARR_SIZE_ (psk_size)]); + const /*void? */ char *psk) +MHD_FN_PAR_IN_SIZE_ (3, 2); #define MHD_connection_set_psk_unavailable(mscc) \ MHD_connection_set_psk (mscc, 0, NULL) @@ -6648,7 +6649,7 @@ MHD_EXTERN_ struct MHD_Response * MHD_response_from_buffer_copy ( enum MHD_HTTP_StatusCode sc, size_t buffer_size, - const char buffer[MHD_FN_PAR_DYN_ARR_SIZE_ (buffer_size)]) + const char *buffer) MHD_FN_PAR_IN_SIZE_ (3, 2); @@ -6696,9 +6697,10 @@ MHD_EXTERN_ struct MHD_Response * MHD_response_from_iovec ( enum MHD_HTTP_StatusCode sc, unsigned int iov_count, - const struct MHD_IoVec iov[MHD_FN_PAR_DYN_ARR_SIZE_ (iov_count)], + const struct MHD_IoVec *iov, MHD_FreeCallback free_cb, - void *free_cb_cls); + void *free_cb_cls) +MHD_FN_PAR_IN_SIZE_ (3, 2); /** diff --git a/src/include/microhttpd2_main.h.in b/src/include/microhttpd2_main.h.in @@ -1589,7 +1589,7 @@ MHD_EXTERN_ struct MHD_Response * MHD_response_from_buffer_copy ( enum MHD_HTTP_StatusCode sc, size_t buffer_size, - const char buffer[MHD_FN_PAR_DYN_ARR_SIZE_ (buffer_size)]) + const char *buffer) MHD_FN_PAR_IN_SIZE_ (3, 2); @@ -1637,9 +1637,10 @@ MHD_EXTERN_ struct MHD_Response * MHD_response_from_iovec ( enum MHD_HTTP_StatusCode sc, unsigned int iov_count, - const struct MHD_IoVec iov[MHD_FN_PAR_DYN_ARR_SIZE_ (iov_count)], + const struct MHD_IoVec *iov, MHD_FreeCallback free_cb, - void *free_cb_cls); + void *free_cb_cls) +MHD_FN_PAR_IN_SIZE_ (3, 2); /** diff --git a/src/include/microhttpd2_preamble.h.in b/src/include/microhttpd2_preamble.h.in @@ -3912,7 +3912,8 @@ MHD_EXTERN_ enum MHD_StatusCode MHD_connection_set_psk ( struct MHD_ServerCredentialsContext *mscc, size_t psk_size, - const /*void? */ char psk[MHD_FN_PAR_DYN_ARR_SIZE_ (psk_size)]); + const /*void? */ char *psk) +MHD_FN_PAR_IN_SIZE_ (3, 2); #define MHD_connection_set_psk_unavailable(mscc) \ MHD_connection_set_psk (mscc, 0, NULL) diff --git a/src/mhd2/response_from.c b/src/mhd2/response_from.c @@ -200,7 +200,7 @@ MHD_FN_PAR_IN_SIZE_ (3, 2) struct MHD_Response * MHD_response_from_buffer_copy ( enum MHD_HTTP_StatusCode sc, size_t buffer_size, - const char buffer[MHD_FN_PAR_DYN_ARR_SIZE_ (buffer_size)]) + const char *buffer) { struct MHD_Response *restrict res; const unsigned char *buf_copy; @@ -242,11 +242,11 @@ MHD_response_from_buffer_copy ( } -static struct MHD_Response * +static MHD_FN_PAR_IN_SIZE_ (3, 2) struct MHD_Response * response_from_iovec_inner ( enum MHD_HTTP_StatusCode sc, unsigned int iov_count, - const struct MHD_IoVec iov[MHD_FN_PAR_DYN_ARR_SIZE_ (iov_count)], + const struct MHD_IoVec *iov, MHD_FreeCallback free_cb, void *free_cb_cls) { @@ -352,11 +352,12 @@ response_from_iovec_inner ( } -MHD_EXTERN_ struct MHD_Response * +MHD_EXTERN_ +MHD_FN_PAR_IN_SIZE_ (3, 2) struct MHD_Response * MHD_response_from_iovec ( enum MHD_HTTP_StatusCode sc, unsigned int iov_count, - const struct MHD_IoVec iov[MHD_FN_PAR_DYN_ARR_SIZE_ (iov_count)], + const struct MHD_IoVec *iov, MHD_FreeCallback free_cb, void *free_cb_cls) {