libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 24725d33d9074b880b7f993165dd408153004862
parent 45dabc9d2503645cbf7a4154ff1f428adfb2b8f4
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Mon,  7 Nov 2016 19:35:02 +0300

Used calloc() where possible with fallback to malloc()+memset().

Diffstat:
Mconfigure.ac | 14++++++++++++++
Msrc/microhttpd/daemon.c | 15+++------------
Msrc/microhttpd/mhd_compat.c | 34++++++++++++++++++++++++++++++++++
Msrc/microhttpd/mhd_compat.h | 12++++++++++++
Msrc/microhttpd/postprocessor.c | 6++----
Msrc/microhttpd/response.c | 19+++++--------------
6 files changed, 70 insertions(+), 30 deletions(-)

diff --git a/configure.ac b/configure.ac @@ -1173,6 +1173,20 @@ AS_VAR_IF([[enable_httpupgrade]],[["yes"]], AM_CONDITIONAL([ENABLE_UPGRADE], [[test "x$enable_httpupgrade" = "xyes"]]) AC_MSG_RESULT([[$enable_httpupgrade]]) +AC_CACHE_CHECK([[for calloc()]], [[mhd_cv_have_func_calloc]], + [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include <stdlib.h> + ]],[[void * ptr = calloc(1, 2)]]) + ], + [[mhd_cv_have_func_calloc='yes']], + [[mhd_cv_have_func_calloc='no']] + ) + ] +) +AS_VAR_IF([[mhd_cv_have_func_calloc]], [["yes"]], + [AC_DEFINE([[HAVE_CALLOC]], [[1]], [Define to 1 if you have the usable `calloc' function.])]) + # Check for fork() and waitpid(). They are used for tests. AC_MSG_CHECKING([[for fork()]]) AC_LINK_IFELSE( diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c @@ -2062,7 +2062,7 @@ internal_add_connection (struct MHD_Daemon *daemon, return MHD_NO; } - if (NULL == (connection = malloc (sizeof (struct MHD_Connection)))) + if (NULL == (connection = MHD_calloc_ (1, sizeof (struct MHD_Connection)))) { eno = errno; #ifdef HAVE_MESSAGES @@ -2077,9 +2077,6 @@ internal_add_connection (struct MHD_Daemon *daemon, errno = eno; return MHD_NO; } - memset (connection, - 0, - sizeof (struct MHD_Connection)); connection->pool = MHD_pool_create (daemon->pool_size); if (NULL == connection->pool) { @@ -3248,7 +3245,7 @@ MHD_poll_all (struct MHD_Daemon *daemon, int poll_itc_idx; struct pollfd *p; - p = malloc (sizeof (struct pollfd) * (2 + num_connections)); + p = MHD_calloc_ ((2 + num_connections), sizeof (struct pollfd)); if (NULL == p) { #ifdef HAVE_MESSAGES @@ -3258,9 +3255,6 @@ MHD_poll_all (struct MHD_Daemon *daemon, #endif return MHD_NO; } - memset (p, - 0, - sizeof (struct pollfd) * (2 + num_connections)); poll_server = 0; poll_listen = -1; if ( (MHD_INVALID_SOCKET != daemon->socket_fd) && @@ -4746,11 +4740,8 @@ MHD_start_daemon_va (unsigned int flags, } if (NULL == dh) return NULL; - if (NULL == (daemon = malloc (sizeof (struct MHD_Daemon)))) + if (NULL == (daemon = MHD_calloc_ (1, sizeof (struct MHD_Daemon)))) return NULL; - memset (daemon, - 0, - sizeof (struct MHD_Daemon)); #ifdef EPOLL_SUPPORT daemon->epoll_fd = -1; #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT) diff --git a/src/microhttpd/mhd_compat.c b/src/microhttpd/mhd_compat.c @@ -34,6 +34,9 @@ #endif /* HAVE_SNPRINTF */ #endif /* _WIN32 && !__CYGWIN__ */ +#ifndef HAVE_CALLOC +#include <string.h> /* for memset() */ +#endif /* ! HAVE_CALLOC */ #if defined(_WIN32) && !defined(__CYGWIN__) @@ -78,3 +81,34 @@ W32_snprintf (char *__restrict s, #endif /* HAVE_SNPRINTF */ #endif /* _WIN32 && !__CYGWIN__ */ + +#ifndef HAVE_CALLOC + +#ifdef __has_builtin +# if __has_builtin(__builtin_mul_overflow) +# define MHD_HAVE_NUL_OVERFLOW 1 +# endif +#elif __GNUC__+0 >= 5 +# define MHD_HAVE_NUL_OVERFLOW 1 +#endif /* __GNUC__ >= 5 */ + + +void *MHD_calloc_(size_t nelem, size_t elsize) +{ + size_t alloc_size; + void *ptr; +#ifdef MHD_HAVE_NUL_OVERFLOW + if (__builtin_mul_overflow(nelem, elsize, &alloc_size) || 0 == alloc_size) + return NULL; +#else /* ! MHD_HAVE_NUL_OVERFLOW */ + alloc_size = nelem * elsize; + if (0 == alloc_size || elsize != alloc_size / nelem) + return NULL; +#endif /* ! MHD_HAVE_NUL_OVERFLOW */ + ptr = malloc (alloc_size); + if (NULL == ptr) + return NULL; + memset(ptr, 0, alloc_size); + return ptr; +} +#endif /* ! HAVE_CALLOC */ diff --git a/src/microhttpd/mhd_compat.h b/src/microhttpd/mhd_compat.h @@ -72,4 +72,16 @@ int W32_snprintf(char *__restrict s, size_t n, const char *__restrict format, .. #endif /* HAVE_RAND */ #endif /* HAVE_RANDOM */ +#ifdef HAVE_CALLOC +/** + * MHD_calloc_ is platform-independent calloc() + */ +#define MHD_calloc_(n,s) calloc((n),(s)) +#else /* ! HAVE_CALLOC */ +/** + * MHD_calloc_ is platform-independent calloc() + */ +void *MHD_calloc_(size_t nelem, size_t elsize); +#endif /* ! HAVE_CALLOC */ + #endif /* MHD_COMPAT_H */ diff --git a/src/microhttpd/postprocessor.c b/src/microhttpd/postprocessor.c @@ -25,6 +25,7 @@ #include "internal.h" #include "mhd_str.h" +#include "mhd_compat.h" /** * Size of on-stack buffer that we use for un-escaping of the value. @@ -325,11 +326,8 @@ MHD_create_post_processor (struct MHD_Connection *connection, buffer_size += 4; /* round up to get nice block sizes despite boundary search */ /* add +1 to ensure we ALWAYS have a zero-termination at the end */ - if (NULL == (ret = malloc (sizeof (struct MHD_PostProcessor) + buffer_size + 1))) + if (NULL == (ret = MHD_calloc_ (1, sizeof (struct MHD_PostProcessor) + buffer_size + 1))) return NULL; - memset (ret, - 0, - sizeof (struct MHD_PostProcessor) + buffer_size + 1); ret->connection = connection; ret->ikvi = iter; ret->cls = iter_cls; diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c @@ -38,6 +38,7 @@ #include "mhd_itc.h" #include "connection.h" #include "memorypool.h" +#include "mhd_compat.h" #if defined(_WIN32) && defined(MHD_W32_MUTEX_) @@ -270,11 +271,8 @@ MHD_create_response_from_callback (uint64_t size, if ((NULL == crc) || (0 == block_size)) return NULL; - if (NULL == (response = malloc (sizeof (struct MHD_Response) + block_size))) + if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response) + block_size))) return NULL; - memset (response, - 0, - sizeof (struct MHD_Response)); response->fd = -1; response->data = (void *) &response[1]; response->data_buffer_size = block_size; @@ -554,11 +552,8 @@ MHD_create_response_from_data (size_t size, if ((NULL == data) && (size > 0)) return NULL; - if (NULL == (response = malloc (sizeof (struct MHD_Response)))) + if (NULL == (response = MHD_calloc_ (1, sizeof (struct MHD_Response)))) return NULL; - memset (response, - 0, - sizeof (struct MHD_Response)); response->fd = -1; if (! MHD_mutex_init_ (&response->mutex)) { @@ -706,12 +701,9 @@ MHD_response_execute_upgrade_ (struct MHD_Response *response, return MHD_NO; } - urh = malloc (sizeof (struct MHD_UpgradeResponseHandle)); + urh = MHD_calloc_ (1, sizeof (struct MHD_UpgradeResponseHandle)); if (NULL == urh) return MHD_NO; - memset (urh, - 0, - sizeof (struct MHD_UpgradeResponseHandle)); urh->connection = connection; rbo = connection->read_buffer_offset; connection->read_buffer_offset = 0; @@ -960,10 +952,9 @@ MHD_create_response_for_upgrade (MHD_UpgradeHandler upgrade_handler, if (NULL == upgrade_handler) return NULL; /* invalid request */ - response = malloc (sizeof (struct MHD_Response)); + response = MHD_calloc_ (1, sizeof (struct MHD_Response)); if (NULL == response) return NULL; - memset (response, 0, sizeof (struct MHD_Response)); if (! MHD_mutex_init_ (&response->mutex)) { free (response);