libmicrohttpd2

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

commit 53a0516488ed94ae6516432943c0851a35716f84
parent e986c2bdfcc5b2d9b9af6dc8d8cf98b26bf8bf95
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date:   Sat, 29 Aug 2026 17:05:38 +0200

Fixed NULL pointer initialisations on exotic platforms

Diffstat:
Mdoc/examples/sessions.c | 3+++
Msrc/examples2/demo.c | 1+
Msrc/include/options-generator.c | 23++++++++++++++++++++++-
Msrc/mhd2/auth_digest.c | 12++++++++++++
Msrc/mhd2/daemon_add_conn.c | 29++++-------------------------
Msrc/mhd2/daemon_create.c | 8++++----
Msrc/mhd2/h2/h2_conn_streams.c | 1+
Msrc/mhd2/mhd_read_file.c | 3+++
Msrc/mhd2/response_from.c | 3+++
Msrc/mhd2/stream_funcs.c | 60++++++++++++++++++++++++++++++++++++------------------------
Msrc/mhd2/stream_funcs.h | 12++++++++++++
Msrc/mhd2/tls_gnu_funcs.c | 16++++++++++++++++
Msrc/mhd2/tls_multi_funcs.c | 13+++++++++++++
Msrc/mhd2/tls_open_funcs.c | 13+++++++++----
14 files changed, 139 insertions(+), 58 deletions(-)

diff --git a/doc/examples/sessions.c b/doc/examples/sessions.c @@ -614,6 +614,9 @@ create_response (void *cls, fprintf (stderr, "calloc error: %s\n", strerror (errno)); return MHD_NO; } + request->session = NULL; + request->pp = NULL; + request->post_url = NULL; *req_cls = request; if (0 == strcmp (method, MHD_HTTP_METHOD_POST)) { diff --git a/src/examples2/demo.c b/src/examples2/demo.c @@ -1192,6 +1192,7 @@ generate_page (void *cls, memset (uc, 0, sizeof (struct UploadContext)); + uc->filename = NULL; strcpy (uc->tmpname, "mhd-demo-XXXXXX"); uc->fd = -1; diff --git a/src/include/options-generator.c b/src/include/options-generator.c @@ -68,6 +68,27 @@ struct Option char *conditional; }; + +static void +option_init_blank (struct Option *o) +{ + unsigned int i; + + memset (o, 0, sizeof (*o)); + o->next = NULL; + o->name = NULL; + o->type = NULL; + o->comment = NULL; + o->custom_setter = NULL; + for (i = 0; i < MAX_ARGS; ++i) + { + o->arguments[i] = NULL; + o->descriptions[i] = NULL; + } + o->conditional = NULL; +} + + static FILE *f; static char *category; @@ -837,7 +858,7 @@ TOP: { struct Option *o = (struct Option *)malloc (sizeof (struct Option)); - memset (o, 0, sizeof (*o)); + option_init_blank (o); if (NULL == head) head = o; else diff --git a/src/mhd2/auth_digest.c b/src/mhd2/auth_digest.c @@ -868,6 +868,18 @@ get_rq_auth_digest_params (struct MHD_Request *restrict req) return MHD_SC_CONNECTION_POOL_NO_MEM_AUTH_DATA; memset (dauth, 0, sizeof(struct mhd_AuthDigesReqParams)); +#ifndef HAVE_NULL_PTR_ALL_ZEROS + dauth->nonce.value.cstr = NULL; + dauth->opaque.value.cstr = NULL; + dauth->response.value.cstr = NULL; + dauth->username.value.cstr = NULL; + dauth->username_ext.value.cstr = NULL; + dauth->realm.value.cstr = NULL; + dauth->uri.value.cstr = NULL; + dauth->qop_raw.value.cstr = NULL; + dauth->cnonce.value.cstr = NULL; + dauth->nc.value.cstr = NULL; +#endif /* ! HAVE_NULL_PTR_ALL_ZEROS */ if (!parse_dauth_params (&h_auth_value, dauth)) return MHD_SC_REQ_AUTH_DATA_BROKEN; diff --git a/src/mhd2/daemon_add_conn.c b/src/mhd2/daemon_add_conn.c @@ -94,6 +94,7 @@ #include "events_process.h" #include "daemon_funcs.h" +#include "stream_funcs.h" #include "response_from.h" #include "response_destroy.h" #include "conn_timeout.h" @@ -143,29 +144,7 @@ connection_set_initial_state (struct MHD_Connection *restrict c) c->conn_reuse = mhd_CONN_KEEPALIVE_POSSIBLE; c->event_loop_info = MHD_EVENT_LOOP_INFO_RECV; - // TODO: move request reset to special function - memset (&(c->rq), 0, sizeof(c->rq)); - // TODO: move reply reset to special function - memset (&(c->rp), 0, sizeof(c->rp)); - -#ifndef HAVE_NULL_PTR_ALL_ZEROS - // TODO: move request reset to special function - mhd_DLINKEDL_INIT_LIST (&(c->rq), fields); -# ifdef MHD_SUPPORT_POST_PARSER - mhd_DLINKEDL_INIT_LIST (&(c->rq), post_fields); -# endif /* MHD_SUPPORT_POST_PARSER */ - c->rq.version = NULL; - c->rq.url = NULL; - c->rq.field_lines.start = NULL; - c->rq.app_context = NULL; - c->rq.hdrs.rq_line.rq_tgt = NULL; - c->rq.hdrs.rq_line.rq_tgt_qmark = NULL; - - // TODO: move reply reset to special function - c->rp.app_act_ctx.connection = NULL; - c->rp.response = NULL; - c->rp.resp_iov.iov = NULL; -#endif /* ! HAVE_NULL_PTR_ALL_ZEROS */ + mhd_stream_init_req_reply (c); c->write_buffer = NULL; c->write_buffer_size = 0; @@ -259,9 +238,9 @@ new_connection_prepare_ (struct MHD_Daemon *restrict daemon, { #ifndef HAVE_NULL_PTR_ALL_ZEROS mhd_DLINKEDL_INIT_LINKS (c, all_conn); - c->extr_event.app_cntx = NULL; + c->events.extrn.app_cntx = NULL; mhd_DLINKEDL_INIT_LINKS (c, proc_ready); - mhd_DLINKEDL_INIT_LINKS (c, by_timeout); + mhd_DLINKEDL_INIT_LINKS (&(c->timeout), tmout_list); # ifdef MHD_SUPPORT_UPGRADE c->upgr.c = NULL; mhd_DLINKEDL_INIT_LINKS (c, upgr_cleanup); diff --git a/src/mhd2/daemon_create.c b/src/mhd2/daemon_create.c @@ -91,13 +91,15 @@ MHD_daemon_create (MHD_RequestCallback req_cb, if (NULL != s) { /* calloc() does not guarantee that floating point values and pointers - are initialised to zero and NULL (respectfully). */ + are initialised to zero and NULL (respectively). */ /* Any floating point and pointer members must be initialised manually here */ #ifndef HAVE_NULL_PTR_ALL_ZEROS s->bind_sa.v_sa = NULL; s->tls_cert_key.v_mem_key = NULL; s->tls_cert_key.v_mem_cert = NULL; s->tls_cert_key.v_mem_pass = NULL; + s->tls_app_name.v_app_name = NULL; + s->tls_openssl_def_file.v_pathname = NULL; s->tls_client_ca = NULL; s->tls_psk_callback.v_psk_cb = NULL; s->tls_psk_callback.v_psk_cb_cls = NULL; @@ -112,11 +114,9 @@ MHD_daemon_create (MHD_RequestCallback req_cb, s->notify_stream.v_nsc = NULL; s->notify_stream.v_cls = NULL; s->random_entropy.v_buf = NULL; - s->tls_cert_key.v_mem_cert = NULL; - s->tls_cert_key.v_mem_key = NULL; - s->tls_cert_key.v_mem_pass = NULL; /* d->log_params.v_log_cb = NULL; */ /* used directly */ + /* d->log_params.v_log_cb_cls = NULL;*/ /* used directly */ #endif /* !HAVE_NULL_PTR_ALL_ZEROS */ s->large_pool_size = SIZE_MAX; /* The impossible value */ diff --git a/src/mhd2/h2/h2_conn_streams.c b/src/mhd2/h2/h2_conn_streams.c @@ -101,6 +101,7 @@ conn_add_new_stream (struct MHD_Connection *restrict c, mhd_DLINKEDL_INIT_LINKS (s, streams); mhd_DLINKEDL_INIT_LINKS (s, send_q); s->req.app_context = NULL; + s->rpl.response = NULL; #endif /* ! HAVE_NULL_PTR_ALL_ZEROS */ s->c = c; diff --git a/src/mhd2/mhd_read_file.c b/src/mhd2/mhd_read_file.c @@ -169,6 +169,9 @@ mhd_read_file (int file_fd, return mhd_FILE_READ_ERROR; memset (&ovrlp, 0, sizeof(ovrlp)); +# ifndef HAVE_NULL_PTR_ALL_ZEROS + ovrlp.hEvent = NULL; +# endif /* ! HAVE_NULL_PTR_ALL_ZEROS */ reqReadSize = (DWORD)buf_size; if (reqReadSize != buf_size) reqReadSize = (DWORD)(~((DWORD)0)); diff --git a/src/mhd2/response_from.c b/src/mhd2/response_from.c @@ -475,6 +475,9 @@ mhd_response_special_for_error (unsigned int sc, #ifndef HAVE_NULL_PTR_ALL_ZEROS mhd_DLINKEDL_INIT_LIST (res, headers); +# ifdef MHD_SUPPORT_AUTH_DIGEST + mhd_DLINKEDL_INIT_LIST (res, auth_d_hdrs); +# endif /* MHD_SUPPORT_AUTH_DIGEST */ res->free.cb = NULL; res->free.cls = NULL; res->special_resp.spec_hdr = NULL; diff --git a/src/mhd2/stream_funcs.c b/src/mhd2/stream_funcs.c @@ -87,6 +87,41 @@ #include "mhd_public_api.h" +MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void +mhd_stream_init_req_reply (struct MHD_Connection *restrict c) +{ + memset (&(c->rq), 0, sizeof(c->rq)); + memset (&(c->rp), 0, sizeof(c->rp)); + +#ifndef HAVE_NULL_PTR_ALL_ZEROS + mhd_DLINKEDL_INIT_LIST (&(c->rq), fields); +# ifdef MHD_SUPPORT_POST_PARSER + mhd_DLINKEDL_INIT_LIST (&(c->rq), post_fields); +# endif /* MHD_SUPPORT_POST_PARSER */ + c->rq.cntn.lbuf.data = NULL; +# ifdef MHD_SUPPORT_AUTH_BASIC + c->rq.auth.basic.intr.username.cstr = NULL; + c->rq.auth.basic.intr.password.cstr = NULL; +# endif /* MHD_SUPPORT_AUTH_BASIC */ +# ifdef MHD_SUPPORT_AUTH_DIGEST + c->rq.auth.digest.rqp = NULL; + c->rq.auth.digest.info = NULL; +# endif /* MHD_SUPPORT_AUTH_DIGEST */ + c->rq.version = NULL; + c->rq.method.cstr = NULL; + c->rq.url = NULL; + c->rq.field_lines.start = NULL; + c->rq.app_context = NULL; + c->rq.hdrs.rq_line.rq_tgt = NULL; + c->rq.hdrs.rq_line.rq_tgt_qmark = NULL; + + c->rp.app_act_ctx.connection = NULL; + c->rp.response = NULL; + c->rp.resp_iov.iov = NULL; +#endif /* ! HAVE_NULL_PTR_ALL_ZEROS */ +} + + MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void * mhd_stream_alloc_memory (struct MHD_Connection *restrict c, size_t size) @@ -594,31 +629,8 @@ mhd_stream_finish_req_serving (struct MHD_Connection *restrict c, c->stage = mhd_HTTP_STAGE_INIT; c->event_loop_info = MHD_EVENT_LOOP_INFO_RECV; /* Dummy state, real state set later */ - // TODO: move request reset to special function - memset (&c->rq, 0, sizeof(c->rq)); - - // TODO: move reply reset to special function /* iov (if any) will be deallocated by mhd_pool_reset */ - memset (&c->rp, 0, sizeof(c->rp)); - -#ifndef HAVE_NULL_PTR_ALL_ZEROS - // TODO: move request reset to special function - mhd_DLINKEDL_INIT_LIST (&(c->rq), fields); -# ifdef MHD_SUPPORT_POST_PARSER - mhd_DLINKEDL_INIT_LIST (&(c->rq), post_fields); -# endif /* MHD_SUPPORT_POST_PARSER */ - c->rq.version = NULL; - c->rq.url = NULL; - c->rq.field_lines.start = NULL; - c->rq.app_context = NULL; - c->rq.hdrs.rq_line.rq_tgt = NULL; - c->rq.hdrs.rq_line.rq_tgt_qmark = NULL; - - // TODO: move reply reset to special function - c->rp.app_act_ctx.connection = NULL; - c->rp.response = NULL; - c->rp.resp_iov.iov = NULL; -#endif /* ! HAVE_NULL_PTR_ALL_ZEROS */ + mhd_stream_init_req_reply (c); c->write_buffer = NULL; c->write_buffer_size = 0; diff --git a/src/mhd2/stream_funcs.h b/src/mhd2/stream_funcs.h @@ -54,6 +54,18 @@ struct MHD_Connection; /* forward declaration */ /** + * Initialise request- and reply-specific stream data. + * + * Any resources referenced by the old values must be released before calling + * this function. + * @param c the connection whose request and reply data are initialised + */ +MHD_INTERNAL void +mhd_stream_init_req_reply (struct MHD_Connection *restrict c) +MHD_FN_PAR_NONNULL_ALL_; + + +/** * The stage of input data processing. * Used for out-of-memory (in the pool) handling. */ diff --git a/src/mhd2/tls_gnu_funcs.c b/src/mhd2/tls_gnu_funcs.c @@ -773,6 +773,22 @@ mhd_tls_gnu_daemon_init3 (struct MHD_Daemon *restrict d, if (NULL == d_tls) return MHD_SC_DAEMON_MEM_ALLOC_FAILURE; +#ifndef HAVE_NULL_PTR_ALL_ZEROS +# ifdef mhd_TLS_GNU_DH_PARAMS_NEEDS_PKCS3 + d_tls->dh_params = NULL; +# endif /* mhd_TLS_GNU_DH_PARAMS_NEEDS_PKCS3 */ +# ifdef mhd_HAVE_GNUTLS_ACME + d_tls->acme_certs = NULL; +# endif /* mhd_HAVE_GNUTLS_ACME */ + d_tls->cred.gnu_cred = NULL; + d_tls->pri_cache = NULL; +# ifdef mhd_TLS_GNU_HAS_ALPN + d_tls->alpn_prots[0].data = NULL; + d_tls->alpn_prots[1].data = NULL; + d_tls->alpn_prots[2].data = NULL; +# endif /* mhd_TLS_GNU_HAS_ALPN */ +#endif /* ! HAVE_NULL_PTR_ALL_ZEROS */ + #ifdef mhd_HAVE_GNUTLS_ACME d_tls->acme_certs = mhd_daemon_get_acme_certs (d); #endif /* mhd_HAVE_GNUTLS_ACME */ diff --git a/src/mhd2/tls_multi_funcs.c b/src/mhd2/tls_multi_funcs.c @@ -374,6 +374,19 @@ mhd_tls_multi_daemon_init (struct MHD_Daemon *restrict d, if (NULL == d_tls) return MHD_SC_DAEMON_MEM_ALLOC_FAILURE; + d_tls->choice = mhd_TLS_MULTI_ROUTE_NONE; +#ifndef HAVE_NULL_PTR_ALL_ZEROS +# ifdef MHD_SUPPORT_GNUTLS + d_tls->data.gnutls = NULL; +# endif /* MHD_SUPPORT_GNUTLS */ +# ifdef MHD_SUPPORT_OPENSSL + d_tls->data.openssl = NULL; +# endif /* MHD_SUPPORT_OPENSSL */ +# ifdef MHD_SUPPORT_MBEDTLS + d_tls->data.mbedtls = NULL; +# endif /* MHD_SUPPORT_MBEDTLS */ +#endif /* ! HAVE_NULL_PTR_ALL_ZEROS */ + res = MHD_SC_INTERNAL_ERROR; /* Mute compiler warning, the value should not be used */ switch (s->tls) { diff --git a/src/mhd2/tls_open_funcs.c b/src/mhd2/tls_open_funcs.c @@ -766,10 +766,6 @@ daemon_init_lib_ctx (struct MHD_Daemon *restrict d, { enum MHD_StatusCode ret; -#ifndef HAVE_NULL_PTR_ALL_ZEROS - d_tls->libctx = NULL; -#endif /* HAVE_NULL_PTR_ALL_ZEROS */ - if (!create_lib_ctx (d, d_tls)) return MHD_SC_TLS_DAEMON_INIT_FAILED; @@ -1827,6 +1823,15 @@ mhd_tls_open_daemon_init (struct MHD_Daemon *restrict d, if (NULL == d_tls) return MHD_SC_DAEMON_MEM_ALLOC_FAILURE; +#ifndef HAVE_NULL_PTR_ALL_ZEROS + d_tls->libctx = NULL; + d_tls->ctx = NULL; + d_tls->alpn_prots = NULL; +# ifdef mhd_HAVE_OPENSSL_ACME + d_tls->acme_certs = NULL; +# endif /* mhd_HAVE_OPENSSL_ACME */ +#endif /* ! HAVE_NULL_PTR_ALL_ZEROS */ + #ifdef mhd_HAVE_OPENSSL_ACME d_tls->acme_certs = mhd_daemon_get_acme_certs (d); #endif /* mhd_HAVE_OPENSSL_ACME */