[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd2] branch master updated (cdd4c1f -> a71f9db)
From: |
Admin |
Subject: |
[libmicrohttpd2] branch master updated (cdd4c1f -> a71f9db) |
Date: |
Fri, 13 Jun 2025 23:38:08 +0200 |
This is an automated email from the git hooks/post-receive script.
karlson2k pushed a change to branch master
in repository libmicrohttpd2.
from cdd4c1f get_all_net_updates_by_epoll(): reduced the size of the data
passed to the kernel
new 1d78def conn_data_send.c: fixed large sending, added some asserts
new cd707e8 bootstrap: make sure that pre-commit hook really used
new 3acd1a8 bootstrap: English fixes
new 514dca2 xdigittovalue(): optimised.
new ee27dba mhd_str.c: minor readability improvements
new d9c6ed2 Fixed compiler warnings
new 7de8674 daemon_start: cosmetics, fixed code style
new 93cc9c9 mhd_str: added functions attributes, fixed doxy, removed
extra checks in functions
new ca74fb1 mhd_str: added 8 bit -> 2 xdigits one-pass encoding
new 5295c08 configure: added release build linker flags
new ae5c45e mhd_str: optimised caseless comparisons and case
transformations
new c4f4136 mhd_locks: added W32 implementation based on SRW locks (and
minor improvements)
new 33c0677 parse_http_std_method(): optimised
new c36e910 POST parser: optimised large upload processing
new c5a7c98 POST parser: improved parsing performance by storing complete
delimiter instead of boundary
new 41677cb configure: minor check improvement
new 72ab415 POST parser: accelerate by using memmem() for delimiters
new 02e26a6 Renamed test_postprocessor -> test_postparser to match API
naming
new 331b046 conn_data_send.c: fixed formatting
new 6d53267 perf_replies: fixed formatting
new a71f9db perf_replies: added response sizes 8 MiB and 101 MiB
The 21 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
bootstrap | 48 +-
configure.ac | 17 +-
contrib/precommit_hook.sh | 0
src/mhd2/conn_data_send.c | 21 +-
src/mhd2/daemon_start.c | 89 +-
src/mhd2/events_process.c | 13 +-
src/mhd2/mhd_locks.h | 96 +-
src/mhd2/mhd_post_parser.h | 6 +-
src/mhd2/mhd_str.c | 1095 ++++++++++++--------
src/mhd2/mhd_str.h | 120 ++-
src/mhd2/post_parser_funcs.c | 376 +++++--
src/mhd2/stream_process_request.c | 120 ++-
src/tests/client_server/Makefile.am | 2 +-
.../{test_postprocessor.c => test_postparser.c} | 0
src/tools/perf_replies.c | 270 ++++-
15 files changed, 1539 insertions(+), 734 deletions(-)
mode change 100644 => 100755 contrib/precommit_hook.sh
rename src/tests/client_server/{test_postprocessor.c => test_postparser.c}
(100%)
diff --git a/bootstrap b/bootstrap
index 93df79c..26ac06b 100755
--- a/bootstrap
+++ b/bootstrap
@@ -17,17 +17,17 @@ have_cmd()
}
fi
-# Extract dotted digits version from stdin and print it to stdout
+# Extract the dotted version string from stdin and write it to stdout
ver_filter()
{
${SED-sed} -n
's/^\(.*[^0-9.]\)\{0,1\}\([0-9][0-9]*\(\.[0-9][0-9]*\)\{0,4\}\).*$/\2/p'
}
# Compare two version strings
-# Return:
+# Return codes:
# * 11 if the first version is greater than the second version
# * 10 if versions are equal
-# * 9 if the first version is less than the second version
+# * 9 if the first version is less than the second version
__helper_ver_cmp()
{
_verA=$1
@@ -60,6 +60,7 @@ ver_cmp()
[ $? $2 10 ]
}
+# Locate the bootstrap source directory
bs_srcdir='' || exit 1
if have_cmd 'dirname' && test X"`dirname / 2>/dev/null`" = X"/"; then
bs_srcdir=`dirname $0` || exit 2
@@ -70,14 +71,14 @@ else
esac
fi
-test -n "$bs_srcdir" && cd "$bs_srcdir" || echo "Warning: cannot detect
sources directory" 1>&2
+test -n "$bs_srcdir" && cd "$bs_srcdir" || echo "Warning: cannot detect the
source directory" 1>&2
if test ! -f './configure.ac'; then
- echo "Error: no 'configure.ac' found. Wrong sources directory?" 1>&2
+ echo "Error: 'configure.ac' not found. Wrong source directory?" 1>&2
exit 2
fi
if test ! -f './src/include/microhttpd2.h'; then
- echo "Error: file 'src/include/microhttpd2.h' not found. Wrong sources
directory?" 1>&2
+ echo "Error: 'src/include/microhttpd2.h' not found. Wrong source directory?"
1>&2
exit 2
fi
@@ -88,19 +89,19 @@ if have_cmd ${UNCRUSTIFY}; then
UNCRUSTIFY_VER_NEEDED="0.78.0"
if ver_cmp "$UNCRUSTIFY_VER" -ge "$UNCRUSTIFY_VER_NEEDED"; then
if test -f uncrustify.cfg; then
- echo "Uncrustify configuration already exists, skipping installation
from the upstream file."
+ echo "Uncrustify configuration already exists; skipping installation of
the configuration from the upstream file."
else
- echo "Installing libmicrohttpd uncrustify configuration"
+ echo "Installing the libmicrohttpd Uncrustify configuration"
rm -f ./uncrustify.cfg
ln -s contrib/uncrustify.cfg uncrustify.cfg || \
cp contrib/uncrustify.cfg uncrustify.cfg || \
- echo "Failed to install uncrustify configuration file" 1>&2
+ echo "Failed to install Uncrustify configuration file" 1>&2
fi
else
- echo "Uncrustify version $UNCRUSTIFY_VER detected, hook not installed.
Please install uncrustify $UNCRUSTIFY_VER_NEEDED or newer if you plan to
contribute to development."
+ echo "Uncrustify version $UNCRUSTIFY_VER detected -- hook not installed.
Please install Uncrustify $UNCRUSTIFY_VER_NEEDED or newer if you plan to
contribute to development."
fi
else
- echo "Uncrustify not detected, hook not installed. Please install uncrustify
$UNCRUSTIFY_VER_NEEDED or newer if you plan to contribute to development."
+ echo "Uncrustify not detected -- hook not installed. Please install
Uncrustify $UNCRUSTIFY_VER_NEEDED or newer if you plan to contribute to
development."
fi
test -n "$GIT" || GIT="$GIT_CMD"
@@ -111,7 +112,7 @@ if test -d "${GIT_DIR-.git}"; then
if have_cmd "$GIT"; then
ver_GIT=`"$GIT" --version 2>/dev/null | ver_filter`
if ver_cmp "$ver_GIT" -lt "1.7"; then
- echo "git version $ver_GIT detected. If you plan to contribute to
development, consider installing a modern Git version."
+ echo "Git version $ver_GIT detected. If you plan to contribute to
development, consider installing a modern Git version."
else
if test -f "${GIT_DIR-.git}/mhd2_special_config"; then :; else
git_settings_modified='no'
@@ -133,16 +134,16 @@ if test -d "${GIT_DIR-.git}"; then
fi
fi
if test "$git_settings_modified" != "no"; then
- echo "Some git repository settings has been modified."
- echo "Use next command to prevent such modifications in the future:"
+ echo "Some Git repository settings have been modified."
+ echo "Use the following command to prevent such modifications in the
future:"
echo " touch '${GIT_DIR-.git}/mhd2_special_config'"
fi
fi
if test -f uncrustify.cfg && have_cmd ${UNCRUSTIFY}; then
if test -f "${GIT_DIR-.git}/hooks/pre-commit"; then
- echo "Pre-commit git hook already exists, skipping installation from
the upstream file."
+ echo "Pre-commit Git hook already exists; skipping installation of
the upstream file."
else
- echo "Installing uncrustify pre-commit git hook"
+ echo "Installing Uncrustify pre-commit Git hook"
rm -f "${GIT_DIR-.git}/hooks/pre-commit"
if test ${GIT_DIR+y}; then
ln -s "`pwd`/contrib/precommit_hook.sh"
"${GIT_DIR}/hooks/pre-commit"
@@ -150,11 +151,14 @@ if test -d "${GIT_DIR-.git}"; then
ln -s ../../contrib/precommit_hook.sh .git/hooks/pre-commit
fi
test $? -eq 0 || cp contrib/precommit_hook.sh
"${GIT_DIR-.git}/hooks/pre-commit" || \
- echo "Failed to install pre-commit git hook" 1>&2
+ echo "Failed to install pre-commit Git hook" 1>&2
if test -f "${GIT_DIR-.git}/hooks/pre-commit"; then
+ if chmod +x "${GIT_DIR-.git}/hooks/pre-commit"; then :; else
+ echo "Failed to mark the pre-commit Git hook as executable" 1>&2
+ fi
if dir_GIT_HOOKS=`"$GIT" config --get core.hooksPath 2>/dev/null`
&& test "X$dir_GIT_HOOKS" != "X${GIT_DIR-.git}/hooks"; then
- echo "Installed hook will not be used due to git configuration."
- echo "Consider updating git configuration by running the
following command:"
+ echo "The installed hook will not be used due to the current Git
configuration."
+ echo "Consider updating the Git configuration by running the
following command:"
echo " '$GIT' config --local core.hooksPath
'${GIT_DIR-.git}/hooks'"
fi
fi
@@ -162,10 +166,10 @@ if test -d "${GIT_DIR-.git}"; then
fi
fi
else
- echo "No 'git' command detected, skipping installation of pre-commit git
hook and git configuration."
+ echo "No 'git' command detected; skipping installation of the pre-commit
Git hook and Git configuration."
fi
else
- echo "No '${GIT_DIR-.git}' directory found, skipping installation of
pre-commit git hook and git configuration."
+ echo "No '${GIT_DIR-.git}' directory found; skipping installation of the
pre-commit Git hook and Git configuration."
fi
WANT_AUTOCONF=latest
@@ -174,4 +178,4 @@ export WANT_AUTOCONF
export WANT_AUTOMAKE
autoreconf -vi ${1+"$@"} || \
- echo "*** Failed to build autoconf output files ***" >&2
+ echo "*** Failed to build Autoconf output files ***" >&2
diff --git a/configure.ac b/configure.ac
index ec449f0..4718c5c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -551,6 +551,10 @@ AS_CASE([${enable_build_type}],[release|release-*],
[
MHD_CHECK_ADD_CC_CFLAGS([-Wformat-security -Wstack-protector],
[CFLAGS_ac])
MHD_CHECK_ADD_CC_CFLAGS([-Wuninitialized -Winit-self -Walloc-zero
-Wbidi-chars=any], [CFLAGS_ac])
+ ],
+ [
+ MHD_FIND_ADD_CC_CFLAG([CFLAGS_ac], [-fno-plt], [-mno-plt], [-Gy])
+ MHD_CHECK_ADD_CC_CFLAGS([-fno-semantic-interposition], [CFLAGS_ac])
]
)
AS_VAR_IF([enable_build_type],["release"],
@@ -559,8 +563,13 @@ AS_CASE([${enable_build_type}],[release|release-*],
]
)
CFLAGS="${CFLAGS_ac} ${user_CFLAGS}"
- # W32-specific
LDFLAGS="${user_LDFLAGS}"
+ MHD_CHECK_ADD_CC_LDFLAGS([-Wl,-O1], [LDFLAGS_ac])
+ AS_VAR_IF([enable_build_type],["release-hardened"],
+ [:],
+ [MHD_CHECK_ADD_CC_LDFLAGS([-Wl,--gc-sections -Wl,--icf=all],
[LDFLAGS_ac])]
+ )
+ # W32-specific
MHD_CHECK_ADD_CC_LDFLAG([-Wl,--disable-long-section-names], [LDFLAGS_ac])
LDFLAGS="${LDFLAGS_ac} ${user_LDFLAGS}"
]
@@ -3920,10 +3929,10 @@ MHD_CHECK_FUNC([memmem],
#include <string.h>
]],
[[
- const char *haystack = "abc";
+ const char *haystack = "abcd";
size_t hslen = 3;
- const char *needle = "b";
- size_t needlelen = 1;
+ const char *needle = "bc";
+ size_t needlelen = 2;
i][f ((haystack + 1) != memmem(haystack, hslen, needle, needlelen))
return 3;
diff --git a/contrib/precommit_hook.sh b/contrib/precommit_hook.sh
old mode 100644
new mode 100755
diff --git a/src/mhd2/conn_data_send.c b/src/mhd2/conn_data_send.c
index 065120b..5a84136 100644
--- a/src/mhd2/conn_data_send.c
+++ b/src/mhd2/conn_data_send.c
@@ -199,15 +199,20 @@ mhd_conn_data_send (struct MHD_Connection *restrict c)
if (mhd_REPLY_CNTN_LOC_RESP_BUF == c->rp.cntn_loc)
{
bool complete_response = true;
- size_t send_size =
- (size_t) (c->rp.rsp_cntn_read_pos - resp->cntn_size);
+ const uint_fast64_t send_left =
+ resp->cntn_size - c->rp.rsp_cntn_read_pos;
+ size_t send_size = (size_t) send_left;
+
+ mhd_assert (MHD_SIZE_UNKNOWN != resp->cntn_size);
+ mhd_assert (mhd_HTTP_STAGE_UNCHUNKED_BODY_READY == c->stage);
mhd_assert (mhd_RESPONSE_CONTENT_DATA_BUFFER == resp->cntn_dtype);
mhd_assert (c->rp.rsp_cntn_read_pos < resp->cntn_size);
- if ((c->rp.rsp_cntn_read_pos - resp->cntn_size) != send_size)
+ if (send_left != send_size)
{
send_size = (size_t) ~((size_t) 0);
complete_response = false;
+ mhd_assert (send_left >= send_size);
}
res = mhd_send_data (c,
@@ -216,6 +221,8 @@ mhd_conn_data_send (struct MHD_Connection *restrict c)
+ c->rp.rsp_cntn_read_pos,
complete_response,
&sent);
+ mhd_assert ((mhd_SOCKET_ERR_NO_ERROR != res) ||
+ sent <= send_size);
}
else if (mhd_REPLY_CNTN_LOC_CONN_BUF == c->rp.cntn_loc)
{
@@ -228,6 +235,9 @@ mhd_conn_data_send (struct MHD_Connection *restrict c)
c->write_buffer + c->write_buffer_send_offset,
true,
&sent);
+ mhd_assert ((mhd_SOCKET_ERR_NO_ERROR != res) || \
+ sent <= (c->write_buffer_append_offset \
+ - c->write_buffer_send_offset));
}
else if (mhd_REPLY_CNTN_LOC_IOV == c->rp.cntn_loc)
{
@@ -238,7 +248,7 @@ mhd_conn_data_send (struct MHD_Connection *restrict c)
true,
&sent);
}
- #if defined(mhd_USE_SENDFILE)
+#if defined(mhd_USE_SENDFILE)
else if (mhd_REPLY_CNTN_LOC_FILE == c->rp.cntn_loc)
{
mhd_assert (mhd_RESPONSE_CONTENT_DATA_FILE == resp->cntn_dtype);
@@ -254,7 +264,7 @@ mhd_conn_data_send (struct MHD_Connection *restrict c)
}
}
}
- #endif /* mhd_USE_SENDFILE */
+#endif /* mhd_USE_SENDFILE */
else
{
mhd_assert (0 && "Should be unreachable");
@@ -285,6 +295,7 @@ mhd_conn_data_send (struct MHD_Connection *restrict c)
else
{
c->rp.rsp_cntn_read_pos += sent;
+ mhd_assert (resp->cntn_size >= c->rp.rsp_cntn_read_pos);
if (c->rp.rsp_cntn_read_pos == resp->cntn_size)
c->stage = mhd_HTTP_STAGE_FULL_REPLY_SENT;
}
diff --git a/src/mhd2/daemon_start.c b/src/mhd2/daemon_start.c
index 180ce0e..1950835 100644
--- a/src/mhd2/daemon_start.c
+++ b/src/mhd2/daemon_start.c
@@ -342,10 +342,10 @@ enum mhd_CreateSktType
*/
static enum MHD_StatusCode
create_bind_listen_stream_socket_inner (struct MHD_Daemon *restrict d,
- struct DaemonOptions *restrict s,
- bool v6_tried,
- bool force_v6_any_dual,
- enum MHD_StatusCode prev_bnd_lstn_err)
+ struct DaemonOptions *restrict s,
+ bool v6_tried,
+ bool force_v6_any_dual,
+ enum MHD_StatusCode prev_bnd_lstn_err)
{
MHD_Socket sk;
enum mhd_CreateSktType sk_type;
@@ -702,16 +702,16 @@ create_bind_listen_stream_socket_inner (struct MHD_Daemon
*restrict d,
#ifdef HAVE_INET6
if (mhd_SKT_IP_V4_WITH_FALLBACK == sk_type)
return create_bind_listen_stream_socket_inner (d,
- s,
- v6_tried,
- true,
- prev_bnd_lstn_err);
+ s,
+ v6_tried,
+ true,
+ prev_bnd_lstn_err);
if (mhd_SKT_IP_V4_WITH_V6_OPT == sk_type)
return create_bind_listen_stream_socket_inner (d,
- s,
- true,
- false,
- prev_bnd_lstn_err);
+ s,
+ true,
+ false,
+ prev_bnd_lstn_err);
#endif /* HAVE_INET6 */
if (MHD_SC_OK != prev_bnd_lstn_err)
@@ -725,7 +725,7 @@ create_bind_listen_stream_socket_inner (struct MHD_Daemon
*restrict d,
return MHD_SC_AF_NOT_AVAILABLE;
}
mhd_LOG_MSG (d, MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET, \
- "Failed to open listen socket");
+ "Failed to open listen socket");
return MHD_SC_FAILED_TO_OPEN_LISTEN_SOCKET;
}
@@ -811,10 +811,10 @@ create_bind_listen_stream_socket_inner (struct MHD_Daemon
*restrict d,
{
(void) mhd_socket_close (sk);
return create_bind_listen_stream_socket_inner (d,
- s,
- true,
- false,
- prev_bnd_lstn_err);
+ s,
+ true,
+ false,
+
prev_bnd_lstn_err);
}
if (! state_unknown)
{
@@ -826,8 +826,8 @@ create_bind_listen_stream_socket_inner (struct MHD_Daemon
*restrict d,
"Failed to disable IP dual-stack configuration " \
"for the listen socket");
ret = (MHD_SC_OK == prev_bnd_lstn_err) ?
- MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_REJECTED :
- prev_bnd_lstn_err;
+ MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_REJECTED :
+ prev_bnd_lstn_err;
break;
}
else if (mhd_SKT_UNKNOWN != sk_type)
@@ -839,8 +839,8 @@ create_bind_listen_stream_socket_inner (struct MHD_Daemon
*restrict d,
if (mhd_SKT_IP_DUAL_REQUIRED == sk_type)
{
ret = (MHD_SC_OK == prev_bnd_lstn_err) ?
- MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_REJECTED :
- prev_bnd_lstn_err;
+ MHD_SC_LISTEN_DUAL_STACK_CONFIGURATION_REJECTED :
+ prev_bnd_lstn_err;
break;
}
}
@@ -978,25 +978,25 @@ create_bind_listen_stream_socket_inner (struct MHD_Daemon
*restrict d,
if (0 != bind (sk, p_use_sa, use_sa_size))
{
ret = (MHD_SC_OK == prev_bnd_lstn_err) ?
- MHD_SC_LISTEN_SOCKET_BIND_FAILED : prev_bnd_lstn_err;
+ MHD_SC_LISTEN_SOCKET_BIND_FAILED : prev_bnd_lstn_err;
#ifdef HAVE_INET6
if (mhd_SKT_IP_V4_WITH_FALLBACK == sk_type)
{
(void) mhd_socket_close (sk);
return create_bind_listen_stream_socket_inner (d,
- s,
- v6_tried,
- true,
- ret);
+ s,
+ v6_tried,
+ true,
+ ret);
}
if (mhd_SKT_IP_V4_WITH_V6_OPT == sk_type)
{
(void) mhd_socket_close (sk);
return create_bind_listen_stream_socket_inner (d,
- s,
- true,
- false,
- ret);
+ s,
+ true,
+ false,
+ ret);
}
#endif /* HAVE_INET6 */
break;
@@ -1024,19 +1024,19 @@ create_bind_listen_stream_socket_inner (struct
MHD_Daemon *restrict d,
{
(void) mhd_socket_close (sk);
return create_bind_listen_stream_socket_inner (d,
- s,
- v6_tried,
- true,
- ret);
+ s,
+ v6_tried,
+ true,
+ ret);
}
if (mhd_SKT_IP_V4_WITH_V6_OPT == sk_type)
{
(void) mhd_socket_close (sk);
return create_bind_listen_stream_socket_inner (d,
- s,
- true,
- false,
- ret);
+ s,
+ true,
+ false,
+ ret);
}
#endif /* HAVE_INET6 */
break;
@@ -1114,10 +1114,10 @@ create_bind_listen_stream_socket (struct MHD_Daemon
*restrict d,
enum MHD_StatusCode ret;
ret = create_bind_listen_stream_socket_inner (d,
- s,
- false,
- false,
- MHD_SC_OK);
+ s,
+ false,
+ false,
+ MHD_SC_OK);
#ifdef MHD_SUPPORT_LOG_FUNCTIONALITY
if (MHD_SC_LISTEN_SOCKET_BIND_FAILED == ret)
mhd_LOG_MSG (d, MHD_SC_LISTEN_SOCKET_BIND_FAILED, \
@@ -1980,7 +1980,10 @@ allocate_events (struct MHD_Daemon *restrict d)
if ((num_elements > d->conns.cfg.count_limit) /* Check for value overflow
*/
|| (mhd_D_HAS_THR_PER_CONN (d)))
{
- const unsigned int upper_limit = (sizeof(void*) >= 8) ? 4096 : 1024;
+ const unsigned int upper_limit = (sizeof(void*) >= 8) ? 4096u : 1024u;
+
+ mhd_assert (0 < (int) upper_limit);
+ mhd_assert (upper_limit == (unsigned int) (size_t) upper_limit);
/* Trade neglectable performance penalty for memory saving */
/* Very large amount of new events processed in batches */
diff --git a/src/mhd2/events_process.c b/src/mhd2/events_process.c
index 1f67a00..9411a27 100644
--- a/src/mhd2/events_process.c
+++ b/src/mhd2/events_process.c
@@ -1593,7 +1593,7 @@ get_all_net_updates_by_epoll (struct MHD_Daemon *restrict
d)
// TODO: add listen socket enable/disable
/* Minimise amount of data passed from userspace to kernel and back */
- max_events = d->conns.cfg.count_limit;
+ max_events = (int) d->conns.cfg.count_limit;
#ifdef MHD_SUPPORT_THREADS
++max_events;
#endif /* MHD_SUPPORT_THREADS */
@@ -1602,9 +1602,8 @@ get_all_net_updates_by_epoll (struct MHD_Daemon *restrict
d)
/* Make sure that one extra slot used to clearly detect that all events
* were gotten. */
++max_events;
- if (0 > max_events)
- max_events = (int) (((unsigned int)~((unsigned int) 0)) >> 1);
- if (max_events > (int) d->events.data.epoll.num_elements)
+ if ((0 > max_events) ||
+ (max_events > (int) d->events.data.epoll.num_elements))
max_events = (int) d->events.data.epoll.num_elements;
events_processed = 0;
@@ -1648,12 +1647,14 @@ get_all_net_updates_by_epoll (struct MHD_Daemon
*restrict d)
return true; /* All events have been read */
/* Use all buffer for the next getting events round(s) */
- max_events = d->events.data.epoll.num_elements;
+ max_events = (int) d->events.data.epoll.num_elements;
+ mhd_assert (0 < max_events);
+ mhd_assert (d->events.data.epoll.num_elements == (size_t) max_events);
max_wait = 0; /* Do not block on the next getting events rounds */
events_processed += (unsigned int) num_events; /* Avoid reading too many
events */
} while ((events_processed < d->conns.cfg.count_limit)
- || (events_processed < d->conns.cfg.count_limit + 2));
+ || (events_processed < d->conns.cfg.count_limit + 2));
return true;
}
diff --git a/src/mhd2/mhd_locks.h b/src/mhd2/mhd_locks.h
index fcc77a4..4dd0017 100644
--- a/src/mhd2/mhd_locks.h
+++ b/src/mhd2/mhd_locks.h
@@ -41,23 +41,34 @@
#ifdef MHD_SUPPORT_THREADS
-#if defined(mhd_THREADS_KIND_W32)
-# define mhd_MUTEX_KIND_W32_CS 1
+#if defined(HAVE_PTHREAD_H) && defined(mhd_THREADS_KIND_POSIX)
+/**
+ * The mutex is POSIX Threads' mutex
+ */
+# define mhd_MUTEX_KIND_PTHREAD 1
+# include <pthread.h>
+# include "sys_null_macro.h"
+#elif defined(mhd_THREADS_KIND_W32)
+# include "sys_w32_ver.h"
+# if _WIN32_WINNT >= 0x0600 /* Vista or later */ && \
+ ! defined (MHD_NO_W32_SRWLOCKS)
+/**
+ * The mutex is W32 SRW lock
+ */
+# define mhd_MUTEX_KIND_W32_SRW 1
+# else
+/**
+ * The mutex is W32 Critical Section
+ */
+# define mhd_MUTEX_KIND_W32_CS 1
+# endif
# if 0 /* _WIN32_WINNT >= 0x0602 */ /* Win8 or later */
- /* This include does not work as _ARM_ or _AMD64_ macros
- are missing */
+/* This include does not work as _ARM_ or _AMD64_ macros
+ are missing */
# include <synchapi.h>
# else
# include <windows.h>
# endif
-#elif defined(HAVE_PTHREAD_H) && defined(mhd_THREADS_KIND_POSIX)
-# define mhd_MUTEX_KIND_PTHREAD 1
-# include <pthread.h>
-# ifdef HAVE_STDDEF_H
-# include <stddef.h> /* for NULL */
-# else
-# include "sys_base_types.h"
-# endif
#else
#error No base mutex API is available.
#endif
@@ -66,6 +77,8 @@
#if defined(mhd_MUTEX_KIND_PTHREAD)
typedef pthread_mutex_t mhd_mutex;
+#elif defined(mhd_MUTEX_KIND_W32_SRW)
+typedef SRWLOCK mhd_mutex;
#elif defined(mhd_MUTEX_KIND_W32_CS)
typedef CRITICAL_SECTION mhd_mutex;
#endif
@@ -76,7 +89,14 @@ typedef CRITICAL_SECTION mhd_mutex;
* @param pmutex the pointer to the mutex
* @return nonzero on success, zero otherwise
*/
-# define mhd_mutex_init(pmutex) (! (pthread_mutex_init ((pmutex), NULL)))
+# define mhd_mutex_init(pmutex) (0 == pthread_mutex_init ((pmutex), NULL))
+#elif defined(mhd_MUTEX_KIND_W32_SRW)
+/**
+ * Initialise a new mutex.
+ * @param pmutex the pointer to the mutex
+ * @return always nonzero (success)
+ */
+# define mhd_mutex_init(pmutex) (InitializeSRWLock ((pmutex)), ! 0)
#elif defined(mhd_MUTEX_KIND_W32_CS)
# if _WIN32_WINNT < 0x0600
/* Before Vista */
@@ -142,6 +162,13 @@ typedef CRITICAL_SECTION mhd_mutex;
*/
# define mhd_MUTEX_INITIALISER_STAT PTHREAD_MUTEX_INITIALIZER
# endif /* PTHREAD_MUTEX_INITIALIZER */
+#elif defined(mhd_MUTEX_KIND_W32_SRW)
+# if defined(SRWLOCK_INIT)
+/**
+ * The value to statically initialise mutex
+ */
+# define mhd_MUTEX_INITIALISER_STAT SRWLOCK_INIT
+# endif
#endif
#ifdef mhd_MUTEX_INITIALISER_STAT
@@ -158,12 +185,19 @@ typedef CRITICAL_SECTION mhd_mutex;
* @param pmutex the pointer to the mutex
* @return nonzero on success, zero otherwise
*/
-# define mhd_mutex_destroy(pmutex) (! (pthread_mutex_destroy ((pmutex))))
+# define mhd_mutex_destroy(pmutex) (0 == pthread_mutex_destroy ((pmutex)))
+#elif defined(mhd_MUTEX_KIND_W32_SRW)
+/**
+ * Destroy (no-op) previously initialised mutex.
+ * @param pmutex the pointer to the mutex
+ * @return always nonzero (success)
+ */
+# define mhd_mutex_destroy(pmutex) ((void) (pmutex))
#elif defined(mhd_MUTEX_KIND_W32_CS)
/**
* Destroy previously initialised mutex.
* @param pmutex the pointer to the mutex
- * @return Always nonzero
+ * @return always nonzero (success)
*/
# define mhd_mutex_destroy(pmutex) (DeleteCriticalSection ((pmutex)), ! 0)
#endif
@@ -177,14 +211,23 @@ typedef CRITICAL_SECTION mhd_mutex;
* @param pmutex the pointer to the mutex
* @return nonzero on success, zero otherwise
*/
-# define mhd_mutex_lock(pmutex) (! (pthread_mutex_lock ((pmutex))))
+# define mhd_mutex_lock(pmutex) (0 == pthread_mutex_lock ((pmutex)))
+#elif defined(mhd_MUTEX_KIND_W32_SRW)
+/**
+ * Acquire a lock on previously initialised mutex.
+ * If the mutex was already locked by other thread, function blocks until
+ * the mutex becomes available.
+ * @param pmutex the pointer to the mutex
+ * @return always nonzero (success)
+ */
+# define mhd_mutex_lock(pmutex) (AcquireSRWLockExclusive ((pmutex)), ! 0)
#elif defined(mhd_MUTEX_KIND_W32_CS)
/**
* Acquire a lock on previously initialised mutex.
* If the mutex was already locked by other thread, function blocks until
* the mutex becomes available.
* @param pmutex the pointer to the mutex
- * @return nonzero on success, zero otherwise
+ * @return always nonzero (success)
*/
# define mhd_mutex_lock(pmutex) (EnterCriticalSection ((pmutex)), ! 0)
#endif
@@ -195,12 +238,21 @@ typedef CRITICAL_SECTION mhd_mutex;
* @param pmutex the pointer to the mutex
* @return nonzero on success, zero otherwise
*/
-# define mhd_mutex_unlock(pmutex) (! (pthread_mutex_unlock ((pmutex))))
+# define mhd_mutex_unlock(pmutex) (0 == pthread_mutex_unlock ((pmutex)))
+#elif defined(mhd_MUTEX_KIND_W32_SRW)
+/**
+ * Acquire a lock on previously initialised mutex.
+ * If the mutex was already locked by other thread, function blocks until
+ * the mutex becomes available.
+ * @param pmutex the pointer to the mutex
+ * @return always nonzero (success)
+ */
+# define mhd_mutex_lock(pmutex) (ReleaseSRWLockExclusive ((pmutex)), ! 0)
#elif defined(mhd_MUTEX_KIND_W32_CS)
/**
* Unlock previously initialised and locked mutex.
* @param pmutex pointer to mutex
- * @return Always nonzero
+ * @return always nonzero (success)
*/
# define mhd_mutex_unlock(pmutex) (LeaveCriticalSection ((pmutex)), ! 0)
#endif
@@ -243,11 +295,11 @@ typedef CRITICAL_SECTION mhd_mutex;
# define mhd_MUTEX_INITIALISER_STAT /* empty */
# define mhd_MUTEX_STATIC_DEFN_INIT(ignored) /* nothing */
# define mhd_mutex_destroy(ignored) (! 0)
-# define mhd_mutex_destroy_chk(ignored) (void) 0
+# define mhd_mutex_destroy_chk(ignored) ((void) 0)
# define mhd_mutex_lock(ignored) (! 0)
-# define mhd_mutex_lock_chk(ignored) (void) 0
+# define mhd_mutex_lock_chk(ignored) ((void) 0)
# define mhd_mutex_unlock(ignored) (! 0)
-# define mhd_mutex_unlock_chk(ignored) (void) 0
+# define mhd_mutex_unlock_chk(ignored) ((void) 0)
#endif /* ! MHD_SUPPORT_THREADS */
diff --git a/src/mhd2/mhd_post_parser.h b/src/mhd2/mhd_post_parser.h
index 3e70cd3..378464c 100644
--- a/src/mhd2/mhd_post_parser.h
+++ b/src/mhd2/mhd_post_parser.h
@@ -410,10 +410,10 @@ struct mhd_PostParserMPartFormData
size_t delim_check_start;
/**
- * The boundary marker.
- * Allocated in the stream's memory pool
+ * Multi-part delimited.
+ * Consists of CRLF + "--" + boundary marker.
*/
- struct mhd_BufferConst bound;
+ struct mhd_BufferConst delim;
};
diff --git a/src/mhd2/mhd_str.c b/src/mhd2/mhd_str.c
index dd3b5c0..1136cb8 100644
--- a/src/mhd2/mhd_str.c
+++ b/src/mhd2/mhd_str.c
@@ -59,7 +59,7 @@
* @param c character to check
* @return non-zero if character is lower case letter, zero otherwise
*/
-MHD_static_inline_ bool
+MHD_static_inline_ MHD_FN_CONST_ bool
isasciilower (char c)
{
return (c >= 'a') && (c <= 'z');
@@ -75,7 +75,7 @@ isasciilower (char c)
* @param c character to check
* @return non-zero if character is upper case letter, zero otherwise
*/
-MHD_static_inline_ bool
+MHD_static_inline_ MHD_FN_CONST_ bool
isasciiupper (char c)
{
return (c <= 'Z') && (c >= 'A');
@@ -89,7 +89,7 @@ isasciiupper (char c)
* @param c character to check
* @return non-zero if character is letter in US-ASCII, zero otherwise
*/
-MHD_static_inline_ bool
+MHD_static_inline_ MHD_FN_CONST_ bool
isasciialpha (char c)
{
return isasciilower (c) || isasciiupper (c);
@@ -105,7 +105,7 @@ isasciialpha (char c)
* @param c character to check
* @return non-zero if character is decimal digit, zero otherwise
*/
-MHD_static_inline_ bool
+MHD_static_inline_ MHD_FN_CONST_ bool
isasciidigit (char c)
{
return (c <= '9') && (c >= '0');
@@ -119,7 +119,7 @@ isasciidigit (char c)
* @param c character to check
* @return non-zero if character is decimal digit, zero otherwise
*/
-MHD_static_inline_ bool
+MHD_static_inline_ MHD_FN_CONST_ bool
isasciixdigit (char c)
{
return isasciidigit (c) ||
@@ -134,7 +134,7 @@ isasciixdigit (char c)
* @param c character to check
* @return non-zero if character is decimal digit or letter, zero otherwise
*/
-MHD_static_inline_ bool
+MHD_static_inline_ MHD_FN_CONST_ bool
isasciialnum (char c)
{
return isasciialpha (c) || isasciidigit (c);
@@ -154,10 +154,10 @@ isasciialnum (char c)
* @param c character to convert
* @return converted to lower case character
*/
-MHD_static_inline_ char
+MHD_static_inline_ MHD_FN_CONST_ char
toasciilower (char c)
{
- return isasciiupper (c) ? (c - 'A' + 'a') : c;
+ return isasciiupper (c) ? (char) (0x20u | (unsigned char) c) : c;
}
@@ -170,10 +170,10 @@ toasciilower (char c)
* @param c character to convert
* @return converted to upper case character
*/
-MHD_static_inline_ char
+MHD_static_inline_ MHD_FN_CONST_ char
toasciiupper (char c)
{
- return isasciilower (c) ? (c - 'a' + 'A') : c;
+ return isasciilower (c) ? (char) ((~0x20u) & (unsigned char) c) : c;
}
@@ -187,7 +187,7 @@ toasciiupper (char c)
* @param c character to convert
* @return value of decimal digit or -1 if @ c is not decimal digit
*/
-MHD_static_inline_ int
+MHD_static_inline_ MHD_FN_CONST_ int
todigitvalue (char c)
{
if (isasciidigit (c))
@@ -206,326 +206,279 @@ todigitvalue (char c)
* @param c character to convert
* @return value of hexadecimal digit or -1 if @ c is not hexadecimal digit
*/
-MHD_static_inline_ int
+MHD_static_inline_ MHD_FN_CONST_ int
xdigittovalue (char c)
{
+ const unsigned char uc = (unsigned char) c; /* Force unsigned value */
#if ! defined(MHD_FAVOR_SMALL_CODE)
- switch ((unsigned char) c)
- {
-#if 0 /* Disabled to give the compiler a hint about low probability */
- case 0x00U: /* NUL */
- case 0x01U: /* SOH */
- case 0x02U: /* STX */
- case 0x03U: /* ETX */
- case 0x04U: /* EOT */
- case 0x05U: /* ENQ */
- case 0x06U: /* ACK */
- case 0x07U: /* BEL */
- case 0x08U: /* BS */
- case 0x09U: /* HT */
- case 0x0AU: /* LF */
- case 0x0BU: /* VT */
- case 0x0CU: /* FF */
- case 0x0DU: /* CR */
- case 0x0EU: /* SO */
- case 0x0FU: /* SI */
- case 0x10U: /* DLE */
- case 0x11U: /* DC1 */
- case 0x12U: /* DC2 */
- case 0x13U: /* DC3 */
- case 0x14U: /* DC4 */
- case 0x15U: /* NAK */
- case 0x16U: /* SYN */
- case 0x17U: /* ETB */
- case 0x18U: /* CAN */
- case 0x19U: /* EM */
- case 0x1AU: /* SUB */
- case 0x1BU: /* ESC */
- case 0x1CU: /* FS */
- case 0x1DU: /* GS */
- case 0x1EU: /* RS */
- case 0x1FU: /* US */
- case 0x20U: /* ' ' */
- case 0x21U: /* '!' */
- case 0x22U: /* '"' */
- case 0x23U: /* '#' */
- case 0x24U: /* '$' */
- case 0x25U: /* '%' */
- case 0x26U: /* '&' */
- case 0x27U: /* '\'' */
- case 0x28U: /* '(' */
- case 0x29U: /* ')' */
- case 0x2AU: /* '*' */
- case 0x2BU: /* '+' */
- case 0x2CU: /* ',' */
- case 0x2DU: /* '-' */
- case 0x2EU: /* '.' */
- case 0x2FU: /* '/' */
- return -1;
-#endif
- case 0x30U: /* '0' */
- return 0;
- case 0x31U: /* '1' */
- return 1;
- case 0x32U: /* '2' */
- return 2;
- case 0x33U: /* '3' */
- return 3;
- case 0x34U: /* '4' */
- return 4;
- case 0x35U: /* '5' */
- return 5;
- case 0x36U: /* '6' */
- return 6;
- case 0x37U: /* '7' */
- return 7;
- case 0x38U: /* '8' */
- return 8;
- case 0x39U: /* '9' */
- return 9;
-#if 0 /* Disabled to give the compiler a hint about low probability */
- case 0x3AU: /* ':' */
- case 0x3BU: /* ';' */
- case 0x3CU: /* '<' */
- case 0x3DU: /* '=' */
- case 0x3EU: /* '>' */
- case 0x3FU: /* '?' */
- case 0x40U: /* '@' */
- return -1;
-#endif
- case 0x41U: /* 'A' */
- return 0xAU;
- case 0x42U: /* 'B' */
- return 0xBU;
- case 0x43U: /* 'C' */
- return 0xCU;
- case 0x44U: /* 'D' */
- return 0xDU;
- case 0x45U: /* 'E' */
- return 0xEU;
- case 0x46U: /* 'F' */
- return 0xFU;
-#if 0 /* Disabled to give the compiler a hint about low probability */
- case 0x47U: /* 'G' */
- case 0x48U: /* 'H' */
- case 0x49U: /* 'I' */
- case 0x4AU: /* 'J' */
- case 0x4BU: /* 'K' */
- case 0x4CU: /* 'L' */
- case 0x4DU: /* 'M' */
- case 0x4EU: /* 'N' */
- case 0x4FU: /* 'O' */
- case 0x50U: /* 'P' */
- case 0x51U: /* 'Q' */
- case 0x52U: /* 'R' */
- case 0x53U: /* 'S' */
- case 0x54U: /* 'T' */
- case 0x55U: /* 'U' */
- case 0x56U: /* 'V' */
- case 0x57U: /* 'W' */
- case 0x58U: /* 'X' */
- case 0x59U: /* 'Y' */
- case 0x5AU: /* 'Z' */
- case 0x5BU: /* '[' */
- case 0x5CU: /* '\' */
- case 0x5DU: /* ']' */
- case 0x5EU: /* '^' */
- case 0x5FU: /* '_' */
- case 0x60U: /* '`' */
- return -1;
-#endif
- case 0x61U: /* 'a' */
- return 0xAU;
- case 0x62U: /* 'b' */
- return 0xBU;
- case 0x63U: /* 'c' */
- return 0xCU;
- case 0x64U: /* 'd' */
- return 0xDU;
- case 0x65U: /* 'e' */
- return 0xEU;
- case 0x66U: /* 'f' */
- return 0xFU;
-#if 0 /* Disabled to give the compiler a hint about low probability */
- case 0x67U: /* 'g' */
- case 0x68U: /* 'h' */
- case 0x69U: /* 'i' */
- case 0x6AU: /* 'j' */
- case 0x6BU: /* 'k' */
- case 0x6CU: /* 'l' */
- case 0x6DU: /* 'm' */
- case 0x6EU: /* 'n' */
- case 0x6FU: /* 'o' */
- case 0x70U: /* 'p' */
- case 0x71U: /* 'q' */
- case 0x72U: /* 'r' */
- case 0x73U: /* 's' */
- case 0x74U: /* 't' */
- case 0x75U: /* 'u' */
- case 0x76U: /* 'v' */
- case 0x77U: /* 'w' */
- case 0x78U: /* 'x' */
- case 0x79U: /* 'y' */
- case 0x7AU: /* 'z' */
- case 0x7BU: /* '{' */
- case 0x7CU: /* '|' */
- case 0x7DU: /* '}' */
- case 0x7EU: /* '~' */
- case 0x7FU: /* DEL */
- case 0x80U: /* EXT */
- case 0x81U: /* EXT */
- case 0x82U: /* EXT */
- case 0x83U: /* EXT */
- case 0x84U: /* EXT */
- case 0x85U: /* EXT */
- case 0x86U: /* EXT */
- case 0x87U: /* EXT */
- case 0x88U: /* EXT */
- case 0x89U: /* EXT */
- case 0x8AU: /* EXT */
- case 0x8BU: /* EXT */
- case 0x8CU: /* EXT */
- case 0x8DU: /* EXT */
- case 0x8EU: /* EXT */
- case 0x8FU: /* EXT */
- case 0x90U: /* EXT */
- case 0x91U: /* EXT */
- case 0x92U: /* EXT */
- case 0x93U: /* EXT */
- case 0x94U: /* EXT */
- case 0x95U: /* EXT */
- case 0x96U: /* EXT */
- case 0x97U: /* EXT */
- case 0x98U: /* EXT */
- case 0x99U: /* EXT */
- case 0x9AU: /* EXT */
- case 0x9BU: /* EXT */
- case 0x9CU: /* EXT */
- case 0x9DU: /* EXT */
- case 0x9EU: /* EXT */
- case 0x9FU: /* EXT */
- case 0xA0U: /* EXT */
- case 0xA1U: /* EXT */
- case 0xA2U: /* EXT */
- case 0xA3U: /* EXT */
- case 0xA4U: /* EXT */
- case 0xA5U: /* EXT */
- case 0xA6U: /* EXT */
- case 0xA7U: /* EXT */
- case 0xA8U: /* EXT */
- case 0xA9U: /* EXT */
- case 0xAAU: /* EXT */
- case 0xABU: /* EXT */
- case 0xACU: /* EXT */
- case 0xADU: /* EXT */
- case 0xAEU: /* EXT */
- case 0xAFU: /* EXT */
- case 0xB0U: /* EXT */
- case 0xB1U: /* EXT */
- case 0xB2U: /* EXT */
- case 0xB3U: /* EXT */
- case 0xB4U: /* EXT */
- case 0xB5U: /* EXT */
- case 0xB6U: /* EXT */
- case 0xB7U: /* EXT */
- case 0xB8U: /* EXT */
- case 0xB9U: /* EXT */
- case 0xBAU: /* EXT */
- case 0xBBU: /* EXT */
- case 0xBCU: /* EXT */
- case 0xBDU: /* EXT */
- case 0xBEU: /* EXT */
- case 0xBFU: /* EXT */
- case 0xC0U: /* EXT */
- case 0xC1U: /* EXT */
- case 0xC2U: /* EXT */
- case 0xC3U: /* EXT */
- case 0xC4U: /* EXT */
- case 0xC5U: /* EXT */
- case 0xC6U: /* EXT */
- case 0xC7U: /* EXT */
- case 0xC8U: /* EXT */
- case 0xC9U: /* EXT */
- case 0xCAU: /* EXT */
- case 0xCBU: /* EXT */
- case 0xCCU: /* EXT */
- case 0xCDU: /* EXT */
- case 0xCEU: /* EXT */
- case 0xCFU: /* EXT */
- case 0xD0U: /* EXT */
- case 0xD1U: /* EXT */
- case 0xD2U: /* EXT */
- case 0xD3U: /* EXT */
- case 0xD4U: /* EXT */
- case 0xD5U: /* EXT */
- case 0xD6U: /* EXT */
- case 0xD7U: /* EXT */
- case 0xD8U: /* EXT */
- case 0xD9U: /* EXT */
- case 0xDAU: /* EXT */
- case 0xDBU: /* EXT */
- case 0xDCU: /* EXT */
- case 0xDDU: /* EXT */
- case 0xDEU: /* EXT */
- case 0xDFU: /* EXT */
- case 0xE0U: /* EXT */
- case 0xE1U: /* EXT */
- case 0xE2U: /* EXT */
- case 0xE3U: /* EXT */
- case 0xE4U: /* EXT */
- case 0xE5U: /* EXT */
- case 0xE6U: /* EXT */
- case 0xE7U: /* EXT */
- case 0xE8U: /* EXT */
- case 0xE9U: /* EXT */
- case 0xEAU: /* EXT */
- case 0xEBU: /* EXT */
- case 0xECU: /* EXT */
- case 0xEDU: /* EXT */
- case 0xEEU: /* EXT */
- case 0xEFU: /* EXT */
- case 0xF0U: /* EXT */
- case 0xF1U: /* EXT */
- case 0xF2U: /* EXT */
- case 0xF3U: /* EXT */
- case 0xF4U: /* EXT */
- case 0xF5U: /* EXT */
- case 0xF6U: /* EXT */
- case 0xF7U: /* EXT */
- case 0xF8U: /* EXT */
- case 0xF9U: /* EXT */
- case 0xFAU: /* EXT */
- case 0xFBU: /* EXT */
- case 0xFCU: /* EXT */
- case 0xFDU: /* EXT */
- case 0xFEU: /* EXT */
- case 0xFFU: /* EXT */
- return -1;
- default:
- mhd_assert (0);
- break; /* Should be unreachable */
-#else
- default:
- break;
-#endif
- }
- return -1;
+ static const signed char map_xdigit_to_value[256] = {
+ -1 /* 0x00 (NUL) */,
+ -1 /* 0x01 (SOH) */,
+ -1 /* 0x02 (STX) */,
+ -1 /* 0x03 (ETX) */,
+ -1 /* 0x04 (EOT) */,
+ -1 /* 0x05 (ENQ) */,
+ -1 /* 0x06 (ACK) */,
+ -1 /* 0x07 (BEL) */,
+ -1 /* 0x08 (BS) */,
+ -1 /* 0x09 (HT) */,
+ -1 /* 0x0A (LF) */,
+ -1 /* 0x0B (VT) */,
+ -1 /* 0x0C (FF) */,
+ -1 /* 0x0D (CR) */,
+ -1 /* 0x0E (SO) */,
+ -1 /* 0x0F (SI) */,
+ -1 /* 0x10 (DLE) */,
+ -1 /* 0x11 (DC1) */,
+ -1 /* 0x12 (DC2) */,
+ -1 /* 0x13 (DC3) */,
+ -1 /* 0x14 (DC4) */,
+ -1 /* 0x15 (NAK) */,
+ -1 /* 0x16 (SYN) */,
+ -1 /* 0x17 (ETB) */,
+ -1 /* 0x18 (CAN) */,
+ -1 /* 0x19 (EM) */,
+ -1 /* 0x1A (SUB) */,
+ -1 /* 0x1B (ESC) */,
+ -1 /* 0x1C (FS) */,
+ -1 /* 0x1D (GS) */,
+ -1 /* 0x1E (RS) */,
+ -1 /* 0x1F (US) */,
+ -1 /* 0x20 (' ') */,
+ -1 /* 0x21 ('!') */,
+ -1 /* 0x22 ('"') */,
+ -1 /* 0x23 ('#') */,
+ -1 /* 0x24 ('$') */,
+ -1 /* 0x25 ('%') */,
+ -1 /* 0x26 ('&') */,
+ -1 /* 0x27 ('\'') */,
+ -1 /* 0x28 ('(') */,
+ -1 /* 0x29 (')') */,
+ -1 /* 0x2A ('*') */,
+ -1 /* 0x2B ('+') */,
+ -1 /* 0x2C (',') */,
+ -1 /* 0x2D ('-') */,
+ -1 /* 0x2E ('.') */,
+ -1 /* 0x2F ('/') */,
+ 0 /* 0x30 ('0') */,
+ 1 /* 0x31 ('1') */,
+ 2 /* 0x32 ('2') */,
+ 3 /* 0x33 ('3') */,
+ 4 /* 0x34 ('4') */,
+ 5 /* 0x35 ('5') */,
+ 6 /* 0x36 ('6') */,
+ 7 /* 0x37 ('7') */,
+ 8 /* 0x38 ('8') */,
+ 9 /* 0x39 ('9') */,
+ -1 /* 0x3A (':') */,
+ -1 /* 0x3B (';') */,
+ -1 /* 0x3C ('<') */,
+ -1 /* 0x3D ('=') */,
+ -1 /* 0x3E ('>') */,
+ -1 /* 0x3F ('?') */,
+ -1 /* 0x40 ('@') */,
+ 10 /* 0x41 ('A') */,
+ 11 /* 0x42 ('B') */,
+ 12 /* 0x43 ('C') */,
+ 13 /* 0x44 ('D') */,
+ 14 /* 0x45 ('E') */,
+ 15 /* 0x46 ('F') */,
+ -1 /* 0x47 ('G') */,
+ -1 /* 0x48 ('H') */,
+ -1 /* 0x49 ('I') */,
+ -1 /* 0x4A ('J') */,
+ -1 /* 0x4B ('K') */,
+ -1 /* 0x4C ('L') */,
+ -1 /* 0x4D ('M') */,
+ -1 /* 0x4E ('N') */,
+ -1 /* 0x4F ('O') */,
+ -1 /* 0x50 ('P') */,
+ -1 /* 0x51 ('Q') */,
+ -1 /* 0x52 ('R') */,
+ -1 /* 0x53 ('S') */,
+ -1 /* 0x54 ('T') */,
+ -1 /* 0x55 ('U') */,
+ -1 /* 0x56 ('V') */,
+ -1 /* 0x57 ('W') */,
+ -1 /* 0x58 ('X') */,
+ -1 /* 0x59 ('Y') */,
+ -1 /* 0x5A ('Z') */,
+ -1 /* 0x5B ('[') */,
+ -1 /* 0x5C ('\') */,
+ -1 /* 0x5D (']') */,
+ -1 /* 0x5E ('^') */,
+ -1 /* 0x5F ('_') */,
+ -1 /* 0x60 ('`') */,
+ 10 /* 0x61 ('a') */,
+ 11 /* 0x62 ('b') */,
+ 12 /* 0x63 ('c') */,
+ 13 /* 0x64 ('d') */,
+ 14 /* 0x65 ('e') */,
+ 15 /* 0x66 ('f') */,
+ -1 /* 0x67 ('g') */,
+ -1 /* 0x68 ('h') */,
+ -1 /* 0x69 ('i') */,
+ -1 /* 0x6A ('j') */,
+ -1 /* 0x6B ('k') */,
+ -1 /* 0x6C ('l') */,
+ -1 /* 0x6D ('m') */,
+ -1 /* 0x6E ('n') */,
+ -1 /* 0x6F ('o') */,
+ -1 /* 0x70 ('p') */,
+ -1 /* 0x71 ('q') */,
+ -1 /* 0x72 ('r') */,
+ -1 /* 0x73 ('s') */,
+ -1 /* 0x74 ('t') */,
+ -1 /* 0x75 ('u') */,
+ -1 /* 0x76 ('v') */,
+ -1 /* 0x77 ('w') */,
+ -1 /* 0x78 ('x') */,
+ -1 /* 0x79 ('y') */,
+ -1 /* 0x7A ('z') */,
+ -1 /* 0x7B ('{') */,
+ -1 /* 0x7C ('|') */,
+ -1 /* 0x7D ('}') */,
+ -1 /* 0x7E ('~') */,
+ -1 /* 0x7F (DEL) */,
+ -1 /* 0x80 (EXT) */,
+ -1 /* 0x81 (EXT) */,
+ -1 /* 0x82 (EXT) */,
+ -1 /* 0x83 (EXT) */,
+ -1 /* 0x84 (EXT) */,
+ -1 /* 0x85 (EXT) */,
+ -1 /* 0x86 (EXT) */,
+ -1 /* 0x87 (EXT) */,
+ -1 /* 0x88 (EXT) */,
+ -1 /* 0x89 (EXT) */,
+ -1 /* 0x8A (EXT) */,
+ -1 /* 0x8B (EXT) */,
+ -1 /* 0x8C (EXT) */,
+ -1 /* 0x8D (EXT) */,
+ -1 /* 0x8E (EXT) */,
+ -1 /* 0x8F (EXT) */,
+ -1 /* 0x90 (EXT) */,
+ -1 /* 0x91 (EXT) */,
+ -1 /* 0x92 (EXT) */,
+ -1 /* 0x93 (EXT) */,
+ -1 /* 0x94 (EXT) */,
+ -1 /* 0x95 (EXT) */,
+ -1 /* 0x96 (EXT) */,
+ -1 /* 0x97 (EXT) */,
+ -1 /* 0x98 (EXT) */,
+ -1 /* 0x99 (EXT) */,
+ -1 /* 0x9A (EXT) */,
+ -1 /* 0x9B (EXT) */,
+ -1 /* 0x9C (EXT) */,
+ -1 /* 0x9D (EXT) */,
+ -1 /* 0x9E (EXT) */,
+ -1 /* 0x9F (EXT) */,
+ -1 /* 0xA0 (EXT) */,
+ -1 /* 0xA1 (EXT) */,
+ -1 /* 0xA2 (EXT) */,
+ -1 /* 0xA3 (EXT) */,
+ -1 /* 0xA4 (EXT) */,
+ -1 /* 0xA5 (EXT) */,
+ -1 /* 0xA6 (EXT) */,
+ -1 /* 0xA7 (EXT) */,
+ -1 /* 0xA8 (EXT) */,
+ -1 /* 0xA9 (EXT) */,
+ -1 /* 0xAA (EXT) */,
+ -1 /* 0xAB (EXT) */,
+ -1 /* 0xAC (EXT) */,
+ -1 /* 0xAD (EXT) */,
+ -1 /* 0xAE (EXT) */,
+ -1 /* 0xAF (EXT) */,
+ -1 /* 0xB0 (EXT) */,
+ -1 /* 0xB1 (EXT) */,
+ -1 /* 0xB2 (EXT) */,
+ -1 /* 0xB3 (EXT) */,
+ -1 /* 0xB4 (EXT) */,
+ -1 /* 0xB5 (EXT) */,
+ -1 /* 0xB6 (EXT) */,
+ -1 /* 0xB7 (EXT) */,
+ -1 /* 0xB8 (EXT) */,
+ -1 /* 0xB9 (EXT) */,
+ -1 /* 0xBA (EXT) */,
+ -1 /* 0xBB (EXT) */,
+ -1 /* 0xBC (EXT) */,
+ -1 /* 0xBD (EXT) */,
+ -1 /* 0xBE (EXT) */,
+ -1 /* 0xBF (EXT) */,
+ -1 /* 0xC0 (EXT) */,
+ -1 /* 0xC1 (EXT) */,
+ -1 /* 0xC2 (EXT) */,
+ -1 /* 0xC3 (EXT) */,
+ -1 /* 0xC4 (EXT) */,
+ -1 /* 0xC5 (EXT) */,
+ -1 /* 0xC6 (EXT) */,
+ -1 /* 0xC7 (EXT) */,
+ -1 /* 0xC8 (EXT) */,
+ -1 /* 0xC9 (EXT) */,
+ -1 /* 0xCA (EXT) */,
+ -1 /* 0xCB (EXT) */,
+ -1 /* 0xCC (EXT) */,
+ -1 /* 0xCD (EXT) */,
+ -1 /* 0xCE (EXT) */,
+ -1 /* 0xCF (EXT) */,
+ -1 /* 0xD0 (EXT) */,
+ -1 /* 0xD1 (EXT) */,
+ -1 /* 0xD2 (EXT) */,
+ -1 /* 0xD3 (EXT) */,
+ -1 /* 0xD4 (EXT) */,
+ -1 /* 0xD5 (EXT) */,
+ -1 /* 0xD6 (EXT) */,
+ -1 /* 0xD7 (EXT) */,
+ -1 /* 0xD8 (EXT) */,
+ -1 /* 0xD9 (EXT) */,
+ -1 /* 0xDA (EXT) */,
+ -1 /* 0xDB (EXT) */,
+ -1 /* 0xDC (EXT) */,
+ -1 /* 0xDD (EXT) */,
+ -1 /* 0xDE (EXT) */,
+ -1 /* 0xDF (EXT) */,
+ -1 /* 0xE0 (EXT) */,
+ -1 /* 0xE1 (EXT) */,
+ -1 /* 0xE2 (EXT) */,
+ -1 /* 0xE3 (EXT) */,
+ -1 /* 0xE4 (EXT) */,
+ -1 /* 0xE5 (EXT) */,
+ -1 /* 0xE6 (EXT) */,
+ -1 /* 0xE7 (EXT) */,
+ -1 /* 0xE8 (EXT) */,
+ -1 /* 0xE9 (EXT) */,
+ -1 /* 0xEA (EXT) */,
+ -1 /* 0xEB (EXT) */,
+ -1 /* 0xEC (EXT) */,
+ -1 /* 0xED (EXT) */,
+ -1 /* 0xEE (EXT) */,
+ -1 /* 0xEF (EXT) */,
+ -1 /* 0xF0 (EXT) */,
+ -1 /* 0xF1 (EXT) */,
+ -1 /* 0xF2 (EXT) */,
+ -1 /* 0xF3 (EXT) */,
+ -1 /* 0xF4 (EXT) */,
+ -1 /* 0xF5 (EXT) */,
+ -1 /* 0xF6 (EXT) */,
+ -1 /* 0xF7 (EXT) */,
+ -1 /* 0xF8 (EXT) */,
+ -1 /* 0xF9 (EXT) */,
+ -1 /* 0xFA (EXT) */,
+ -1 /* 0xFB (EXT) */,
+ -1 /* 0xFC (EXT) */,
+ -1 /* 0xFD (EXT) */,
+ -1 /* 0xFE (EXT) */,
+ -1 /* 0xFF (EXT) */
+ };
+ return map_xdigit_to_value[uc];
#else /* MHD_FAVOR_SMALL_CODE */
- if (c <= 9)
- {
- if (c >= 0)
- return (unsigned char) (c - '0');
- }
- else if (c <= 'F')
- {
- if (c >= 'A')
- return (unsigned char) (c - 'A' + 10);
- }
- else if (c >= 'a')
- {
- if (c <= 'f')
- return (unsigned char) (c - 'a' + 10);
- }
+ unsigned int try_val;
+
+ try_val = uc - (unsigned char) '0';
+ if (9 >= try_val)
+ return (int) (unsigned int) try_val;
+ try_val = (uc | 0x20u /* fold case */) - (unsigned char) 'a';
+ if (5 >= try_val)
+ return (int) (unsigned int) (try_val + 10u);
return -1;
#endif /* MHD_FAVOR_SMALL_CODE */
@@ -538,7 +491,7 @@ xdigittovalue (char c)
* @param v the value to convert, must be less then 16
* @return hexadecimal digit
*/
-MHD_static_inline_ char
+MHD_static_inline_ MHD_FN_CONST_ char
valuetoxdigit (unsigned int v)
{
#if ! defined(MHD_FAVOR_SMALL_CODE)
@@ -560,6 +513,294 @@ valuetoxdigit (unsigned int v)
}
+#if ! defined(MHD_FAVOR_SMALL_CODE)
+/**
+ * Convert 8 bit value to two US-ASCII hexadecimal digits.
+ *
+ * @param v the value to convert
+ * @return pointer to char[2] with two hexadecimal digits
+ */
+MHD_static_inline_ MHD_FN_CONST_ MHD_FN_RETURNS_NONNULL_ const char*
+uint8totwoxdigits (uint8_t v)
+{
+ static const char map_uint8_to_two_xdigits[][2] =
+ { { '0', '0' },
+ { '0', '1' },
+ { '0', '2' },
+ { '0', '3' },
+ { '0', '4' },
+ { '0', '5' },
+ { '0', '6' },
+ { '0', '7' },
+ { '0', '8' },
+ { '0', '9' },
+ { '0', 'a' },
+ { '0', 'b' },
+ { '0', 'c' },
+ { '0', 'd' },
+ { '0', 'e' },
+ { '0', 'f' },
+ { '1', '0' },
+ { '1', '1' },
+ { '1', '2' },
+ { '1', '3' },
+ { '1', '4' },
+ { '1', '5' },
+ { '1', '6' },
+ { '1', '7' },
+ { '1', '8' },
+ { '1', '9' },
+ { '1', 'a' },
+ { '1', 'b' },
+ { '1', 'c' },
+ { '1', 'd' },
+ { '1', 'e' },
+ { '1', 'f' },
+ { '2', '0' },
+ { '2', '1' },
+ { '2', '2' },
+ { '2', '3' },
+ { '2', '4' },
+ { '2', '5' },
+ { '2', '6' },
+ { '2', '7' },
+ { '2', '8' },
+ { '2', '9' },
+ { '2', 'a' },
+ { '2', 'b' },
+ { '2', 'c' },
+ { '2', 'd' },
+ { '2', 'e' },
+ { '2', 'f' },
+ { '3', '0' },
+ { '3', '1' },
+ { '3', '2' },
+ { '3', '3' },
+ { '3', '4' },
+ { '3', '5' },
+ { '3', '6' },
+ { '3', '7' },
+ { '3', '8' },
+ { '3', '9' },
+ { '3', 'a' },
+ { '3', 'b' },
+ { '3', 'c' },
+ { '3', 'd' },
+ { '3', 'e' },
+ { '3', 'f' },
+ { '4', '0' },
+ { '4', '1' },
+ { '4', '2' },
+ { '4', '3' },
+ { '4', '4' },
+ { '4', '5' },
+ { '4', '6' },
+ { '4', '7' },
+ { '4', '8' },
+ { '4', '9' },
+ { '4', 'a' },
+ { '4', 'b' },
+ { '4', 'c' },
+ { '4', 'd' },
+ { '4', 'e' },
+ { '4', 'f' },
+ { '5', '0' },
+ { '5', '1' },
+ { '5', '2' },
+ { '5', '3' },
+ { '5', '4' },
+ { '5', '5' },
+ { '5', '6' },
+ { '5', '7' },
+ { '5', '8' },
+ { '5', '9' },
+ { '5', 'a' },
+ { '5', 'b' },
+ { '5', 'c' },
+ { '5', 'd' },
+ { '5', 'e' },
+ { '5', 'f' },
+ { '6', '0' },
+ { '6', '1' },
+ { '6', '2' },
+ { '6', '3' },
+ { '6', '4' },
+ { '6', '5' },
+ { '6', '6' },
+ { '6', '7' },
+ { '6', '8' },
+ { '6', '9' },
+ { '6', 'a' },
+ { '6', 'b' },
+ { '6', 'c' },
+ { '6', 'd' },
+ { '6', 'e' },
+ { '6', 'f' },
+ { '7', '0' },
+ { '7', '1' },
+ { '7', '2' },
+ { '7', '3' },
+ { '7', '4' },
+ { '7', '5' },
+ { '7', '6' },
+ { '7', '7' },
+ { '7', '8' },
+ { '7', '9' },
+ { '7', 'a' },
+ { '7', 'b' },
+ { '7', 'c' },
+ { '7', 'd' },
+ { '7', 'e' },
+ { '7', 'f' },
+ { '8', '0' },
+ { '8', '1' },
+ { '8', '2' },
+ { '8', '3' },
+ { '8', '4' },
+ { '8', '5' },
+ { '8', '6' },
+ { '8', '7' },
+ { '8', '8' },
+ { '8', '9' },
+ { '8', 'a' },
+ { '8', 'b' },
+ { '8', 'c' },
+ { '8', 'd' },
+ { '8', 'e' },
+ { '8', 'f' },
+ { '9', '0' },
+ { '9', '1' },
+ { '9', '2' },
+ { '9', '3' },
+ { '9', '4' },
+ { '9', '5' },
+ { '9', '6' },
+ { '9', '7' },
+ { '9', '8' },
+ { '9', '9' },
+ { '9', 'a' },
+ { '9', 'b' },
+ { '9', 'c' },
+ { '9', 'd' },
+ { '9', 'e' },
+ { '9', 'f' },
+ { 'a', '0' },
+ { 'a', '1' },
+ { 'a', '2' },
+ { 'a', '3' },
+ { 'a', '4' },
+ { 'a', '5' },
+ { 'a', '6' },
+ { 'a', '7' },
+ { 'a', '8' },
+ { 'a', '9' },
+ { 'a', 'a' },
+ { 'a', 'b' },
+ { 'a', 'c' },
+ { 'a', 'd' },
+ { 'a', 'e' },
+ { 'a', 'f' },
+ { 'b', '0' },
+ { 'b', '1' },
+ { 'b', '2' },
+ { 'b', '3' },
+ { 'b', '4' },
+ { 'b', '5' },
+ { 'b', '6' },
+ { 'b', '7' },
+ { 'b', '8' },
+ { 'b', '9' },
+ { 'b', 'a' },
+ { 'b', 'b' },
+ { 'b', 'c' },
+ { 'b', 'd' },
+ { 'b', 'e' },
+ { 'b', 'f' },
+ { 'c', '0' },
+ { 'c', '1' },
+ { 'c', '2' },
+ { 'c', '3' },
+ { 'c', '4' },
+ { 'c', '5' },
+ { 'c', '6' },
+ { 'c', '7' },
+ { 'c', '8' },
+ { 'c', '9' },
+ { 'c', 'a' },
+ { 'c', 'b' },
+ { 'c', 'c' },
+ { 'c', 'd' },
+ { 'c', 'e' },
+ { 'c', 'f' },
+ { 'd', '0' },
+ { 'd', '1' },
+ { 'd', '2' },
+ { 'd', '3' },
+ { 'd', '4' },
+ { 'd', '5' },
+ { 'd', '6' },
+ { 'd', '7' },
+ { 'd', '8' },
+ { 'd', '9' },
+ { 'd', 'a' },
+ { 'd', 'b' },
+ { 'd', 'c' },
+ { 'd', 'd' },
+ { 'd', 'e' },
+ { 'd', 'f' },
+ { 'e', '0' },
+ { 'e', '1' },
+ { 'e', '2' },
+ { 'e', '3' },
+ { 'e', '4' },
+ { 'e', '5' },
+ { 'e', '6' },
+ { 'e', '7' },
+ { 'e', '8' },
+ { 'e', '9' },
+ { 'e', 'a' },
+ { 'e', 'b' },
+ { 'e', 'c' },
+ { 'e', 'd' },
+ { 'e', 'e' },
+ { 'e', 'f' },
+ { 'f', '0' },
+ { 'f', '1' },
+ { 'f', '2' },
+ { 'f', '3' },
+ { 'f', '4' },
+ { 'f', '5' },
+ { 'f', '6' },
+ { 'f', '7' },
+ { 'f', '8' },
+ { 'f', '9' },
+ { 'f', 'a' },
+ { 'f', 'b' },
+ { 'f', 'c' },
+ { 'f', 'd' },
+ { 'f', 'e' },
+ { 'f', 'f' }
+#ifndef NDEBUG
+ ,
+ { 0, 0 }
+#endif /* ! NDEBUG */
+ };
+
+ mhd_assert (257u == \
+ (sizeof(map_uint8_to_two_xdigits) \
+ / sizeof(map_uint8_to_two_xdigits[0])));
+
+ return map_uint8_to_two_xdigits[v];
+ /**
+ * Indicates that function uint8totwoxdigits() is available
+ */
+#define mhd_HAVE_UINT8TOTWOXDIGITS 1
+}
+
+
+#endif /* ! MHD_FAVOR_SMALL_CODE */
+
+
/**
* Caseless compare two characters.
*
@@ -567,13 +808,15 @@ valuetoxdigit (unsigned int v)
* @param c2 the second char to compare
* @return boolean 'true' if chars are caseless equal, false otherwise
*/
-MHD_static_inline_ bool
-charsequalcaseless (const char c1, const char c2)
+MHD_static_inline_ MHD_FN_CONST_ bool
+charsequalcaseless (char c1, char c2)
{
- return ( (c1 == c2) ||
- (((c1 - 'A' + 'a') == c2) ?
- isasciiupper (c1) :
- ((c1 == (c2 - 'A' + 'a')) && isasciiupper (c2))) );
+ if (c1 == c2)
+ return true;
+ /* Fold case on both sides */
+ c1 = ((char) (~0x20u & (unsigned char) c1));
+ c2 = ((char) (~0x20u & (unsigned char) c2));
+ return (c1 == c2) && isasciiupper (c1);
}
@@ -721,17 +964,17 @@ static const char map_value_to_xdigit[16] =
* @param c2 the second char to compare
* @return boolean 'true' if chars are caseless equal, false otherwise
*/
-# define charsequalcaseless(c1, c2) \
+#define charsequalcaseless(c1, c2) \
( ((c1) == (c2)) || \
- ((((c1) - 'A' + 'a') == (c2)) ? \
- isasciiupper (c1) : \
- (((c1) == ((c2) - 'A' + 'a')) && isasciiupper (c2))) )
+ (((0x20u | (unsigned char) c1) == (0x20u | (unsigned char) c2)) && \
+ toasciilower (((char) (0x20u | (unsigned char) c2)))) )
#endif /* !HAVE_INLINE_FUNCS */
#ifndef MHD_FAVOR_SMALL_CODE
-MHD_INTERNAL bool
+MHD_INTERNAL MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_CSTR_ (1) MHD_FN_PAR_CSTR_ (2) bool
mhd_str_equal_caseless (const char *str1,
const char *str2)
{
@@ -754,7 +997,8 @@ mhd_str_equal_caseless (const char *str1,
#endif /* ! MHD_FAVOR_SMALL_CODE */
-MHD_INTERNAL bool
+MHD_INTERNAL MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_ (1) MHD_FN_PAR_IN_ (2) bool
mhd_str_equal_caseless_n (const char *const str1,
const char *const str2,
size_t maxlen)
@@ -776,7 +1020,8 @@ mhd_str_equal_caseless_n (const char *const str1,
}
-MHD_INTERNAL bool
+MHD_INTERNAL MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_ (1) MHD_FN_PAR_IN_ (2) bool
mhd_str_equal_caseless_bin_n (const char *const str1,
const char *const str2,
size_t len)
@@ -796,7 +1041,9 @@ mhd_str_equal_caseless_bin_n (const char *const str1,
}
-MHD_INTERNAL bool
+MHD_INTERNAL MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_CSTR_ (1)
+MHD_FN_PAR_IN_ (1) MHD_FN_PAR_IN_ (2) bool
mhd_str_has_token_caseless (const char *restrict str,
const char *const restrict token,
size_t token_len)
@@ -843,7 +1090,9 @@ mhd_str_has_token_caseless (const char *restrict str,
}
-MHD_INTERNAL bool
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_IN_SIZE_ (3,4)
+MHD_FN_PAR_OUT_ (5) MHD_FN_PAR_INOUT_ (6) bool
mhd_str_remove_token_caseless (const char *restrict str,
size_t str_len,
const char *const restrict token,
@@ -996,7 +1245,9 @@ mhd_str_remove_token_caseless (const char *restrict str,
}
-MHD_INTERNAL bool
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_INOUT_ (1) MHD_FN_PAR_INOUT_ (2)
+MHD_FN_PAR_IN_SIZE_ (3,4) bool
mhd_str_remove_tokens_caseless (char *restrict str,
size_t *restrict str_len,
const char *const restrict tkns,
@@ -1148,14 +1399,16 @@ mhd_str_remove_tokens_caseless (char *restrict str,
#ifndef MHD_FAVOR_SMALL_CODE
/* Use individual function for each case */
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_CSTR_ (1) MHD_FN_PAR_IN_ (1)
+MHD_FN_PAR_OUT_ (2) size_t
mhd_str_to_uint64 (const char *restrict str,
uint_fast64_t *restrict out_val)
{
const char *const start = str;
uint_fast64_t res;
- if (! str || ! out_val || ! isasciidigit (str[0]))
+ if (! isasciidigit (str[0]))
return 0;
res = 0;
@@ -1179,7 +1432,9 @@ mhd_str_to_uint64 (const char *restrict str,
}
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_SIZE_ (1,2)
+MHD_FN_PAR_OUT_ (3) size_t
mhd_str_to_uint64_n (const char *restrict str,
size_t maxlen,
uint_fast64_t *restrict out_val)
@@ -1187,7 +1442,7 @@ mhd_str_to_uint64_n (const char *restrict str,
uint_fast64_t res;
size_t i;
- if (! str || ! maxlen || ! out_val || ! isasciidigit (str[0]))
+ if (! maxlen || ! isasciidigit (str[0]))
return 0;
res = 0;
@@ -1212,7 +1467,9 @@ mhd_str_to_uint64_n (const char *restrict str,
}
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_CSTR_ (1)
+MHD_FN_PAR_IN_ (1) MHD_FN_PAR_OUT_ (2) size_t
mhd_strx_to_uint32 (const char *restrict str,
uint_fast32_t *restrict out_val)
{
@@ -1220,9 +1477,6 @@ mhd_strx_to_uint32 (const char *restrict str,
uint_fast32_t res;
int digit;
- if (! str || ! out_val)
- return 0;
-
res = 0;
digit = xdigittovalue (*str);
while (digit >= 0)
@@ -1246,7 +1500,9 @@ mhd_strx_to_uint32 (const char *restrict str,
}
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_SIZE_ (1,2)
+MHD_FN_PAR_OUT_ (3) size_t
mhd_strx_to_uint32_n (const char *restrict str,
size_t maxlen,
uint_fast32_t *restrict out_val)
@@ -1254,8 +1510,6 @@ mhd_strx_to_uint32_n (const char *restrict str,
size_t i;
uint_fast32_t res;
int digit;
- if (! str || ! out_val)
- return 0;
res = 0;
i = 0;
@@ -1281,25 +1535,15 @@ mhd_strx_to_uint32_n (const char *restrict str,
}
-/**
- * Convert hexadecimal US-ASCII digits in string to number in uint_fast64_t.
- * Conversion stopped at first non-digit character.
- *
- * @param str string to convert
- * @param[out] out_val pointer to uint_fast64_t to store result of conversion
- * @return non-zero number of characters processed on succeed,
- * zero if no digit is found, resulting value is larger
- * then possible to store in uint_fast64_t or @a out_val is NULL
- */
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_CSTR_ (1)
+MHD_FN_PAR_IN_ (1) MHD_FN_PAR_OUT_ (2) size_t
mhd_strx_to_uint64 (const char *restrict str,
uint_fast64_t *restrict out_val)
{
const char *const start = str;
uint_fast64_t res;
int digit;
- if (! str || ! out_val)
- return 0;
res = 0;
digit = xdigittovalue (*str);
@@ -1324,20 +1568,9 @@ mhd_strx_to_uint64 (const char *restrict str,
}
-/**
- * Convert not more then @a maxlen hexadecimal US-ASCII digits in string
- * to number in uint_fast64_t.
- * Conversion stopped at first non-digit character or after @a maxlen
- * digits.
- *
- * @param str string to convert
- * @param maxlen maximum number of characters to process
- * @param[out] out_val pointer to uint_fast64_t to store result of conversion
- * @return non-zero number of characters processed on succeed,
- * zero if no digit is found, resulting value is larger
- * then possible to store in uint_fast64_t or @a out_val is NULL
- */
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_SIZE_ (1,2)
+MHD_FN_PAR_OUT_ (3) size_t
mhd_strx_to_uint64_n (const char *restrict str,
size_t maxlen,
uint_fast64_t *restrict out_val)
@@ -1345,8 +1578,6 @@ mhd_strx_to_uint64_n (const char *restrict str,
size_t i;
uint_fast64_t res;
int digit;
- if (! str || ! out_val)
- return 0;
res = 0;
i = 0;
@@ -1371,24 +1602,8 @@ mhd_strx_to_uint64_n (const char *restrict str,
#else /* MHD_FAVOR_SMALL_CODE */
-/**
- * Generic function for converting not more then @a maxlen
- * hexadecimal or decimal US-ASCII digits in string to number.
- * Conversion stopped at first non-digit character or after @a maxlen
- * digits.
- * To be used only within macro.
- *
- * @param str the string to convert
- * @param maxlen the maximum number of characters to process
- * @param out_val the pointer to variable to store result of conversion
- * @param val_size the size of variable pointed by @a out_val, in bytes, 4 or 8
- * @param max_val the maximum decoded number
- * @param base the numeric base, 10 or 16
- * @return non-zero number of characters processed on succeed,
- * zero if no digit is found, resulting value is larger
- * then @a max_val, @a val_size is not 4/8 or @a out_val is NULL
- */
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_SIZE_ (3,4) size_t
mhd_str_to_uvalue_n (const char *restrict str,
size_t maxlen,
void *restrict out_val,
@@ -1401,8 +1616,7 @@ mhd_str_to_uvalue_n (const char *restrict str,
const uint_fast64_t max_v_div_b = max_val / base;
const uint_fast64_t max_v_mod_b = max_val % base;
- if (! str || ! out_val ||
- ((base != 16) && (base != 10)) )
+ if ((base != 16) && (base != 10))
return 0;
res = 0;
@@ -1440,7 +1654,8 @@ mhd_str_to_uvalue_n (const char *restrict str,
#endif /* MHD_FAVOR_SMALL_CODE */
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_OUT_SIZE_ (2,3) size_t
mhd_uint32_to_strx (uint_fast32_t val,
char *buf,
size_t buf_size)
@@ -1474,7 +1689,8 @@ mhd_uint32_to_strx (uint_fast32_t val,
#ifndef MHD_FAVOR_SMALL_CODE
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_OUT_SIZE_ (2,3) size_t
mhd_uint16_to_str (uint_least16_t val,
char *buf,
size_t buf_size)
@@ -1516,7 +1732,8 @@ mhd_uint16_to_str (uint_least16_t val,
#endif /* !MHD_FAVOR_SMALL_CODE */
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_OUT_SIZE_ (2,3) size_t
mhd_uint64_to_str (uint_fast64_t val,
char *buf,
size_t buf_size)
@@ -1555,7 +1772,8 @@ mhd_uint64_to_str (uint_fast64_t val,
}
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_OUT_SIZE_ (3,4) size_t
mhd_uint8_to_str_pad (uint8_t val,
uint8_t min_digits,
char *buf,
@@ -1564,8 +1782,6 @@ mhd_uint8_to_str_pad (uint8_t val,
size_t pos; /**< the position of the current printed digit */
int digit;
mhd_assert (3 >= min_digits);
- if (0 == buf_size)
- return 0;
pos = 0;
digit = val / 100;
@@ -1613,8 +1829,14 @@ mhd_bin_to_hex (const void *restrict bin,
for (i = 0; i < size; ++i)
{
const uint8_t b = ((const uint8_t *) bin)[i];
+#ifdef mhd_HAVE_UINT8TOTWOXDIGITS
+ const char *two_xdigits = uint8totwoxdigits (b);
+ hex[i * 2] = two_xdigits[0];
+ hex[i * 2 + 1] = two_xdigits[1];
+#else /* ! mhd_HAVE_UINT8TOTWOXDIGITS */
hex[i * 2] = valuetoxdigit (b >> 4);
hex[i * 2 + 1] = valuetoxdigit (b & 0x0Fu);
+#endif /* ! mhd_HAVE_UINT8TOTWOXDIGITS */
}
return i * 2;
}
@@ -1635,7 +1857,8 @@ mhd_bin_to_hex_z (const void *restrict bin,
}
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_ (3) size_t
mhd_hex_to_bin (const char *restrict hex,
size_t len,
void *restrict bin)
@@ -1643,8 +1866,6 @@ mhd_hex_to_bin (const char *restrict hex,
size_t r;
size_t w;
- if (0 == len)
- return 0;
r = 0;
w = 0;
if (0 != len % 2)
@@ -1674,7 +1895,8 @@ mhd_hex_to_bin (const char *restrict hex,
}
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_SIZE_ (3,4) size_t
mhd_str_pct_decode_strict_n (const char *pct_encoded,
size_t pct_encoded_len,
char *decoded,
@@ -1761,7 +1983,9 @@ mhd_str_pct_decode_strict_n (const char *pct_encoded,
}
-MHD_INTERNAL size_t
+MHD_INTERNAL
+MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (3)
+MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_SIZE_ (3,4) size_t
mhd_str_pct_decode_lenient_n (const char *pct_encoded,
size_t pct_encoded_len,
char *decoded,
@@ -1866,7 +2090,8 @@ mhd_str_pct_decode_lenient_n (const char *pct_encoded,
}
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_CSTR_ (1) size_t
mhd_str_pct_decode_in_place_strict (char *str)
{
#ifdef MHD_FAVOR_SMALL_CODE
@@ -1923,7 +2148,8 @@ mhd_str_pct_decode_in_place_strict (char *str)
}
-MHD_INTERNAL size_t
+MHD_INTERNAL
+MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_CSTR_ (1) size_t
mhd_str_pct_decode_in_place_lenient (char *restrict str,
bool *restrict broken_encoding)
{
@@ -2001,7 +2227,9 @@ mhd_str_pct_decode_in_place_lenient (char *restrict str,
#ifdef MHD_SUPPORT_AUTH_DIGEST
-MHD_INTERNAL bool
+
+MHD_INTERNAL MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_IN_SIZE_ (3,4) bool
mhd_str_equal_quoted_bin_n (const char *quoted,
size_t quoted_len,
const char *unquoted,
@@ -2031,7 +2259,8 @@ mhd_str_equal_quoted_bin_n (const char *quoted,
}
-MHD_INTERNAL bool
+MHD_INTERNAL MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_IN_SIZE_ (3,4) bool
mhd_str_equal_caseless_quoted_bin_n (const char *quoted,
size_t quoted_len,
const char *unquoted,
@@ -2065,7 +2294,8 @@ mhd_str_equal_caseless_quoted_bin_n (const char *quoted,
#if defined(MHD_SUPPORT_AUTH_DIGEST) || defined(MHD_SUPPORT_POST_PARSER)
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_SIZE_ (3,2) size_t
mhd_str_unquote (const char *quoted,
size_t quoted_len,
char *result)
@@ -2189,21 +2419,23 @@ base64_char_to_value_ (uint8_t c)
{
if ('A' <= c)
return (mhd_base64_map_type) ((c - 'A') + 0);
- if ('0' <= c)
+ else if ('0' <= c)
{
if ('9' >= c)
return (mhd_base64_map_type) ((c - '0') + 52);
- if ('=' == c)
+ else if ('=' == c)
return -2;
- return -1;
+ else
+ return -1;
}
- if ('+' == c)
+ else if ('+' == c)
return 62;
- if ('/' == c)
+ else if ('/' == c)
return 63;
- return -1;
+ else
+ return -1;
}
- if (('z' >= c) && ('a' <= c))
+ else if (('z' >= c) && ('a' <= c))
return (mhd_base64_map_type) ((c - 'a') + 26);
return -1;
}
@@ -2215,7 +2447,8 @@ base64_char_to_value_ (uint8_t c)
mhd_DATA_TRUNCATION_RUNTIME_CHECK_DISABLE
-MHD_INTERNAL size_t
+MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_SIZE_ (3,4) size_t
mhd_base64_to_bin_n (const char *base64,
size_t base64_len,
void *bin,
@@ -2392,7 +2625,7 @@ mhd_DATA_TRUNCATION_RUNTIME_CHECK_RESTORE
#endif /* MHD_SUPPORT_AUTH_BASIC */
-MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ bool
+MHD_INTERNAL MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_ bool
mhd_str_starts_with_token_opt_param (const struct MHD_String *restrict str,
const struct MHD_String *restrict token)
{
@@ -2426,8 +2659,8 @@ mhd_str_starts_with_token_opt_param (const struct
MHD_String *restrict str,
MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_
-MHD_FN_PAR_OUT_ (4)
-MHD_FN_PAR_OUT_ (5) enum mhd_StingStartsWithTokenResult
+MHD_FN_PAR_IN_ (1) MHD_FN_PAR_IN_ (2) MHD_FN_PAR_IN_ (3)
+MHD_FN_PAR_OUT_ (4) MHD_FN_PAR_OUT_ (5) enum mhd_StingStartsWithTokenResult
mhd_str_starts_with_token_req_param (
const struct MHD_String *restrict str,
const struct MHD_String *restrict token,
diff --git a/src/mhd2/mhd_str.h b/src/mhd2/mhd_str.h
index 312913c..e412935 100644
--- a/src/mhd2/mhd_str.h
+++ b/src/mhd2/mhd_str.h
@@ -55,7 +55,8 @@
*/
MHD_INTERNAL bool
mhd_str_equal_caseless (const char *str1,
- const char *str2);
+ const char *str2)
+MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_CSTR_ (1) MHD_FN_PAR_CSTR_ (2);
#else /* MHD_FAVOR_SMALL_CODE */
/* Reuse mhd_str_equal_caseless_n() to reduce size */
@@ -77,7 +78,8 @@ mhd_str_equal_caseless (const char *str1,
MHD_INTERNAL bool
mhd_str_equal_caseless_n (const char *const str1,
const char *const str2,
- size_t maxlen);
+ size_t maxlen)
+MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_ (1) MHD_FN_PAR_IN_ (2);
/**
@@ -93,7 +95,8 @@ mhd_str_equal_caseless_n (const char *const str1,
MHD_INTERNAL bool
mhd_str_equal_caseless_bin_n (const char *const str1,
const char *const str2,
- size_t len);
+ size_t len)
+MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_ (1) MHD_FN_PAR_IN_ (2);
/**
@@ -130,7 +133,9 @@ mhd_str_equal_caseless_bin_n (const char *const str1,
MHD_INTERNAL bool
mhd_str_has_token_caseless (const char *restrict str,
const char *const restrict token,
- size_t token_len);
+ size_t token_len)
+MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_CSTR_ (1)
+MHD_FN_PAR_IN_ (1) MHD_FN_PAR_IN_ (2);
/**
* Check whether @a str has case-insensitive static @a tkn.
@@ -180,7 +185,9 @@ mhd_str_remove_token_caseless (const char *restrict str,
const char *const restrict token,
const size_t token_len,
char *restrict buf,
- ssize_t *restrict buf_size);
+ ssize_t *restrict buf_size)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_IN_SIZE_ (3,4)
+MHD_FN_PAR_OUT_ (5) MHD_FN_PAR_INOUT_ (6);
/**
@@ -210,7 +217,9 @@ MHD_INTERNAL bool
mhd_str_remove_tokens_caseless (char *restrict str,
size_t *restrict str_len,
const char *const restrict tkns,
- const size_t tkns_len);
+ const size_t tkns_len)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1) MHD_FN_PAR_INOUT_ (2)
+MHD_FN_PAR_IN_SIZE_ (3,4);
#ifndef MHD_FAVOR_SMALL_CODE
@@ -223,12 +232,14 @@ mhd_str_remove_tokens_caseless (char *restrict str,
* @param str string to convert
* @param[out] out_val pointer to uint_fast64_t to store result of conversion
* @return non-zero number of characters processed on succeed,
- * zero if no digit is found, resulting value is larger
- * then possible to store in uint_fast64_t or @a out_val is NULL
+ * zero if no digit is found or resulting value is larger
+ * then possible to store in uint_fast64_t
*/
MHD_INTERNAL size_t
mhd_str_to_uint64 (const char *restrict str,
- uint_fast64_t *restrict out_val);
+ uint_fast64_t *restrict out_val)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_CSTR_ (1) MHD_FN_PAR_IN_ (1)
+MHD_FN_PAR_OUT_ (2);
/**
* Convert not more then @a maxlen decimal US-ASCII digits in string to
@@ -240,13 +251,14 @@ mhd_str_to_uint64 (const char *restrict str,
* @param maxlen maximum number of characters to process
* @param[out] out_val pointer to uint_fast64_t to store result of conversion
* @return non-zero number of characters processed on succeed,
- * zero if no digit is found, resulting value is larger
- * then possible to store in uint_fast64_t or @a out_val is NULL
+ * zero if no digit is found or resulting value is larger
+ * then possible to store in uint_fast64_t
*/
MHD_INTERNAL size_t
mhd_str_to_uint64_n (const char *restrict str,
size_t maxlen,
- uint_fast64_t *restrict out_val);
+ uint_fast64_t *restrict out_val)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_ (3);
/**
@@ -256,12 +268,14 @@ mhd_str_to_uint64_n (const char *restrict str,
* @param str string to convert
* @param[out] out_val pointer to uint_fast32_t to store result of conversion
* @return non-zero number of characters processed on succeed,
- * zero if no digit is found, resulting value is larger
- * then possible to store in uint_fast32_t or @a out_val is NULL
+ * zero if no digit is found or resulting value is larger
+ * then possible to store in uint_fast32_t
*/
MHD_INTERNAL size_t
mhd_strx_to_uint32 (const char *restrict str,
- uint_fast32_t *restrict out_val);
+ uint_fast32_t *restrict out_val)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_CSTR_ (1)
+MHD_FN_PAR_IN_ (1) MHD_FN_PAR_OUT_ (2);
/**
@@ -274,13 +288,14 @@ mhd_strx_to_uint32 (const char *restrict str,
* @param maxlen maximum number of characters to process
* @param[out] out_val pointer to uint_fast32_t to store result of conversion
* @return non-zero number of characters processed on succeed,
- * zero if no digit is found, resulting value is larger
- * then possible to store in uint_fast32_t or @a out_val is NULL
+ * zero if no digit is found or resulting value is larger
+ * then possible to store in uint_fast32_t
*/
MHD_INTERNAL size_t
mhd_strx_to_uint32_n (const char *restrict str,
size_t maxlen,
- uint_fast32_t *restrict out_val);
+ uint_fast32_t *restrict out_val)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_ (3);
/**
@@ -290,12 +305,14 @@ mhd_strx_to_uint32_n (const char *restrict str,
* @param str string to convert
* @param[out] out_val pointer to uint_fast64_t to store result of conversion
* @return non-zero number of characters processed on succeed,
- * zero if no digit is found, resulting value is larger
- * then possible to store in uint_fast64_t or @a out_val is NULL
+ * zero if no digit is found or resulting value is larger
+ * then possible to store in uint_fast64_t
*/
MHD_INTERNAL size_t
mhd_strx_to_uint64 (const char *restrict str,
- uint_fast64_t *restrict out_val);
+ uint_fast64_t *restrict out_val)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_CSTR_ (1)
+MHD_FN_PAR_IN_ (1) MHD_FN_PAR_OUT_ (2);
/**
@@ -308,13 +325,14 @@ mhd_strx_to_uint64 (const char *restrict str,
* @param maxlen maximum number of characters to process
* @param[out] out_val pointer to uint_fast64_t to store result of conversion
* @return non-zero number of characters processed on succeed,
- * zero if no digit is found, resulting value is larger
- * then possible to store in uint_fast64_t or @a out_val is NULL
+ * zero if no digit is found or resulting value is larger
+ * then possible to store in uint_fast64_t
*/
MHD_INTERNAL size_t
mhd_strx_to_uint64_n (const char *restrict str,
size_t maxlen,
- uint_fast64_t *restrict out_val);
+ uint_fast64_t *restrict out_val)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_ (3);
#else /* MHD_FAVOR_SMALL_CODE */
/* Use one universal function and macros to reduce size */
@@ -334,7 +352,8 @@ mhd_strx_to_uint64_n (const char *restrict str,
* @param base the numeric base, 10 or 16
* @return non-zero number of characters processed on succeed,
* zero if no digit is found, resulting value is larger
- * then @a max_val, @a val_size is not 4/8 or @a out_val is NULL
+ * then @a max_val, @a val_size is not 4 or 8
+ * or @a base is not 10 or 16
*/
MHD_INTERNAL size_t
mhd_str_to_uvalue_n (const char *restrict str,
@@ -342,7 +361,8 @@ mhd_str_to_uvalue_n (const char *restrict str,
void *restrict out_val,
size_t val_size,
uint_fast64_t max_val,
- unsigned int base);
+ unsigned int base)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_SIZE_ (3,4);
#define mhd_str_to_uint64(s,ov) \
mhd_str_to_uvalue_n ((s),SIZE_MAX,(ov), \
@@ -399,7 +419,8 @@ mhd_str_to_uvalue_n (const char *restrict str,
MHD_INTERNAL size_t
mhd_uint32_to_strx (uint_fast32_t val,
char *buf,
- size_t buf_size);
+ size_t buf_size)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_SIZE_ (2,3);
#ifndef MHD_FAVOR_SMALL_CODE
@@ -415,7 +436,8 @@ mhd_uint32_to_strx (uint_fast32_t val,
MHD_INTERNAL size_t
mhd_uint16_to_str (uint_least16_t val,
char *buf,
- size_t buf_size);
+ size_t buf_size)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_SIZE_ (2,3);
#else /* MHD_FAVOR_SMALL_CODE */
#define mhd_uint16_to_str(v,b,s) mhd_uint64_to_str (v,b,s)
@@ -434,7 +456,8 @@ mhd_uint16_to_str (uint_least16_t val,
MHD_INTERNAL size_t
mhd_uint64_to_str (uint_fast64_t val,
char *buf,
- size_t buf_size);
+ size_t buf_size)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_SIZE_ (2,3);
/**
@@ -456,7 +479,8 @@ MHD_INTERNAL size_t
mhd_uint8_to_str_pad (uint8_t val,
uint8_t min_digits,
char *buf,
- size_t buf_size);
+ size_t buf_size)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_SIZE_ (3,4);
/**
@@ -505,7 +529,8 @@ MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_SIZE_ (1, 2)
MHD_FN_PAR_OUT_ (3);
MHD_INTERNAL size_t
mhd_hex_to_bin (const char *restrict hex,
size_t len,
- void *restrict bin);
+ void *restrict bin)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_ (3);
/**
* Decode string with percent-encoded characters as defined by
@@ -529,7 +554,8 @@ MHD_INTERNAL size_t
mhd_str_pct_decode_strict_n (const char *pct_encoded,
size_t pct_encoded_len,
char *decoded,
- size_t buf_size);
+ size_t buf_size)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_SIZE_ (3,4);
/**
* Decode string with percent-encoded characters as defined by
@@ -558,7 +584,9 @@ mhd_str_pct_decode_lenient_n (const char *pct_encoded,
size_t pct_encoded_len,
char *decoded,
size_t buf_size,
- bool *restrict broken_encoding);
+ bool *restrict broken_encoding)
+MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_NONNULL_ (3)
+MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_SIZE_ (3,4);
/**
@@ -575,7 +603,8 @@ mhd_str_pct_decode_lenient_n (const char *pct_encoded,
* @return the number of character in decoded string
*/
MHD_INTERNAL size_t
-mhd_str_pct_decode_in_place_strict (char *str);
+mhd_str_pct_decode_in_place_strict (char *str)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_CSTR_ (1);
/**
@@ -598,7 +627,8 @@ mhd_str_pct_decode_in_place_strict (char *str);
*/
MHD_INTERNAL size_t
mhd_str_pct_decode_in_place_lenient (char *restrict str,
- bool *restrict broken_encoding);
+ bool *restrict broken_encoding)
+MHD_FN_PAR_NONNULL_ (1) MHD_FN_PAR_CSTR_ (1);
#ifdef MHD_SUPPORT_AUTH_DIGEST
/**
@@ -624,7 +654,9 @@ MHD_INTERNAL bool
mhd_str_equal_quoted_bin_n (const char *quoted,
size_t quoted_len,
const char *unquoted,
- size_t unquoted_len);
+ size_t unquoted_len)
+MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_
+ MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_IN_SIZE_ (3,4);
/**
* Check whether the string after "unquoting" equals static string.
@@ -669,7 +701,9 @@ MHD_INTERNAL bool
mhd_str_equal_caseless_quoted_bin_n (const char *quoted,
size_t quoted_len,
const char *unquoted,
- size_t unquoted_len);
+ size_t unquoted_len)
+MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_
+ MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_IN_SIZE_ (3,4);
/**
* Check whether the string after "unquoting" equals static string, ignoring
@@ -713,7 +747,8 @@ mhd_str_equal_caseless_quoted_bin_n (const char *quoted,
MHD_INTERNAL size_t
mhd_str_unquote (const char *quoted,
size_t quoted_len,
- char *result);
+ char *result)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_SIZE_ (3,2);
#endif /* MHD_SUPPORT_AUTH_DIGEST || MHD_SUPPORT_POST_PARSER */
@@ -776,7 +811,8 @@ MHD_INTERNAL size_t
mhd_base64_to_bin_n (const char *base64,
size_t base64_len,
void *bin,
- size_t bin_size);
+ size_t bin_size)
+MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_IN_SIZE_ (1,2) MHD_FN_PAR_OUT_SIZE_ (3,4);
#endif /* MHD_SUPPORT_AUTH_BASIC */
@@ -797,7 +833,7 @@ mhd_base64_to_bin_n (const char *base64,
MHD_INTERNAL bool
mhd_str_starts_with_token_opt_param (const struct MHD_String *restrict str,
const struct MHD_String *restrict token)
-MHD_FN_PAR_NONNULL_ALL_;
+MHD_FN_PURE_ MHD_FN_PAR_NONNULL_ALL_;
/**
@@ -852,6 +888,8 @@ mhd_str_starts_with_token_req_param (
const struct MHD_String *restrict par,
struct mhd_BufferConst *restrict par_value,
bool *restrict par_value_needs_unquote)
-MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_(4) MHD_FN_PAR_OUT_ (5);
+MHD_FN_PAR_NONNULL_ALL_
+MHD_FN_PAR_IN_(1) MHD_FN_PAR_IN_(2) MHD_FN_PAR_IN_(3)
+MHD_FN_PAR_OUT_(4) MHD_FN_PAR_OUT_ (5);
#endif /* MHD_STR_H */
diff --git a/src/mhd2/post_parser_funcs.c b/src/mhd2/post_parser_funcs.c
index 1095829..a525c90 100644
--- a/src/mhd2/post_parser_funcs.c
+++ b/src/mhd2/post_parser_funcs.c
@@ -96,6 +96,7 @@ process_mpart_header (struct MHD_Connection *restrict c,
struct mhd_BufferConst mpart_bound;
bool mpart_bound_quoted;
enum mhd_StingStartsWithTokenResult res;
+ char *buf;
mhd_assert (NULL != h_cnt_tp->cstr);
@@ -140,39 +141,49 @@ process_mpart_header (struct MHD_Connection *restrict c,
mhd_assert (NULL != mpart_bound.data);
+ buf = (char *)
+ mhd_stream_alloc_memory (c,
+ mpart_bound.size + 4);
+ if (NULL == buf)
+ {
+ /* It is very low probability that pool would not have memory just
+ * to held the small boundary string. While it could be possible
+ * to allocate memory from "large buffer", it would over-complicate
+ * code here and at freeing part. */
+ mhd_LOG_MSG (c->daemon, MHD_SC_REQ_POST_PARSE_FAILED_NO_POOL_MEM, \
+ "The request POST data cannot be parsed because " \
+ "there is not enough pool memory.");
+ c->rq.u_proc.post.parse_result = MHD_POST_PARSE_RES_FAILED_NO_POOL_MEM;
+ return mhd_MPART_DET_ERROR_SET;
+ }
+
+ c->rq.u_proc.post.enc = MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA;
+
+ buf[0] = '\r';
+ buf[1] = '\n';
+ buf[2] = '-';
+ buf[3] = '-';
+
if (! mpart_bound_quoted)
{
- c->rq.u_proc.post.enc = MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA;
- c->rq.u_proc.post.e_d.m_form.bound = mpart_bound;
+ memcpy (buf + 4,
+ mpart_bound.data,
+ mpart_bound.size);
+ c->rq.u_proc.post.e_d.m_form.delim.data = buf;
+ c->rq.u_proc.post.e_d.m_form.delim.size = mpart_bound.size + 4;
}
else
{
- char *buf;
-
+ size_t unq_size;
mhd_assert (2 <= mpart_bound.size); /* At least one char and at least one
'\' */
- buf = (char *)
- mhd_stream_alloc_memory (c,
- mpart_bound.size);
- if (NULL == buf)
- {
- /* It is very low probability that pool would not have memory just
- * to held the small boundary string. While it could be possible
- * to allocate memory from "large buffer", it would over-complicate
- * code here and at freeing part. */
- mhd_LOG_MSG (c->daemon, MHD_SC_REQ_POST_PARSE_FAILED_NO_POOL_MEM, \
- "The request POST data cannot be parsed because " \
- "there is not enough pool memory.");
- c->rq.u_proc.post.parse_result = MHD_POST_PARSE_RES_FAILED_NO_POOL_MEM;
- return mhd_MPART_DET_ERROR_SET;
- }
- c->rq.u_proc.post.enc = MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA;
- c->rq.u_proc.post.e_d.m_form.bound.size =
- mhd_str_unquote (mpart_bound.data,
- mpart_bound.size,
- buf);
- mhd_assert (0 != c->rq.u_proc.post.e_d.m_form.bound.size);
+ unq_size = mhd_str_unquote (mpart_bound.data,
+ mpart_bound.size,
+ buf + 4);
+ c->rq.u_proc.post.e_d.m_form.delim.data = buf;
+ c->rq.u_proc.post.e_d.m_form.delim.size = unq_size + 4;
}
+ mhd_assert (4 < c->rq.u_proc.post.e_d.m_form.delim.size);
return mhd_MPART_DET_OK;
}
@@ -333,12 +344,13 @@ reset_parse_field_data_mpart_init (struct
mhd_PostParserData *pdata)
pdata->e_d.m_form.st = mhd_POST_MPART_ST_NOT_STARTED;
pdata->e_d.m_form.line_start = mhd_POST_INVALID_POS;
pdata->e_d.m_form.delim_check_start = mhd_POST_INVALID_POS;
- mhd_assert (NULL != pdata->e_d.m_form.bound.data);
- mhd_assert (0 != pdata->e_d.m_form.bound.size);
- mhd_assert (NULL == memchr (pdata->e_d.m_form.bound.data, '\r', \
- pdata->e_d.m_form.bound.size));
- mhd_assert (NULL == memchr (pdata->e_d.m_form.bound.data, '\n', \
- pdata->e_d.m_form.bound.size));
+ mhd_assert (NULL != pdata->e_d.m_form.delim.data);
+ mhd_assert (4 < pdata->e_d.m_form.delim.size);
+ mhd_assert (0 == memcmp (pdata->e_d.m_form.delim.data, "\r\n--", 4));
+ mhd_assert (NULL == memchr (pdata->e_d.m_form.delim.data + 4, '\r', \
+ pdata->e_d.m_form.delim.size - 4));
+ mhd_assert (NULL == memchr (pdata->e_d.m_form.delim.data + 4, '\n', \
+ pdata->e_d.m_form.delim.size - 4));
pdata->field_start = 0;
}
@@ -445,7 +457,7 @@ mhd_stream_prepare_for_post_parse (struct MHD_Connection
*restrict c)
c->rq.u_proc.post.enc);
mhd_assert ((MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA != \
c->rq.u_proc.post.enc) || \
- (0 != c->rq.u_proc.post.e_d.m_form.bound.size));
+ (4 < c->rq.u_proc.post.e_d.m_form.delim.size));
init_post_parse_data (c);
@@ -1430,9 +1442,11 @@ parse_post_mpart (struct MHD_Connection *restrict c,
struct mhd_PostParserMPartFormData *const mf = &(p_data->e_d.m_form); /**<
the current "form-data" parsing details */
size_t i;
- mhd_assert (NULL != mf->bound.data);
- mhd_assert (NULL == memchr (mf->bound.data, '\r', mf->bound.size));
- mhd_assert (NULL == memchr (mf->bound.data, '\n', mf->bound.size));
+ mhd_assert (NULL != mf->delim.data);
+ mhd_assert (4 < mf->delim.size);
+ mhd_assert (0 == memcmp (mf->delim.data, "\r\n--", 4));
+ mhd_assert (NULL == memchr (mf->delim.data + 4, '\r', mf->delim.size - 4));
+ mhd_assert (NULL == memchr (mf->delim.data + 4, '\n', mf->delim.size - 4));
mhd_assert (MHD_HTTP_POST_ENCODING_MULTIPART_FORMDATA == \
c->rq.u_proc.post.enc);
mhd_assert (MHD_POST_PARSE_RES_OK == p_data->parse_result);
@@ -1455,8 +1469,81 @@ parse_post_mpart (struct MHD_Connection *restrict c,
mhd_assert (0 == p_data->value_off);
mhd_assert (mhd_POST_INVALID_POS == mf->delim_check_start);
mhd_assert (mhd_POST_INVALID_POS == mf->line_start);
+#ifdef HAVE_MEMMEM
+ if (mf->delim.size <= *pdata_size - i)
+ {
+ const char *delim_ptr;
+ if (! bare_lf_as_crlf)
+ delim_ptr = (const char *) memmem (buf + i,
+ *pdata_size - i,
+ mf->delim.data,
+ mf->delim.size);
+ else
+ delim_ptr = (const char *) memmem (buf + i,
+ *pdata_size - i,
+ mf->delim.data + 1,
+ mf->delim.size - 1);
+ if (NULL != delim_ptr)
+ {
+ size_t delim_pos;
+
+ mhd_assert (delim_ptr >= buf + i);
+ mhd_assert (delim_ptr + mf->delim.size - 1 <= buf + *pdata_size);
+
+ delim_pos = (size_t) (delim_ptr - buf);
+
+ mhd_assert (i <= delim_pos);
+
+ if (! bare_lf_as_crlf)
+ {
+ mf->line_start = delim_pos + 2u; /* '2' for CRLF */
+ i = delim_pos + mf->delim.size;
+ }
+ else
+ {
+ mf->line_start = delim_pos + 1u; /* '1' for LF */
+ i = delim_pos + mf->delim.size - 1;
+ }
+ mf->st = mhd_POST_MPART_ST_FIRST_DELIM_FOUND;
+ continue;
+ }
+ i = *pdata_size - mf->delim.size + 1u; /* '+ 1u' to move to then next
position */
+ if (! bare_lf_as_crlf)
+ i += 1u;
+ }
+#endif /* HAVE_MEMMEM */
do /* Fast local loop */
{
+#ifndef MHD_FAVOR_SMALL_CODE
+ const char *lf_ptr;
+ size_t lf_pos;
+
+ lf_ptr = (const char *) memchr (buf + i, '\n', *pdata_size - i);
+ if (NULL == lf_ptr)
+ {
+ if ('\r' == buf[*pdata_size - 1])
+ mf->st = mhd_POST_MPART_ST_PREAMBL_CR_FOUND;
+ i = *pdata_size;
+ break;
+ }
+ lf_pos = (size_t) (lf_ptr - buf);
+ mhd_assert (i <= lf_pos);
+ mhd_assert (*pdata_size > i);
+ if (bare_lf_as_crlf)
+ {
+ i = lf_pos + 1;
+ mf->st = mhd_POST_MPART_ST_PREAMBL_LINE_START;
+ break;
+ }
+ else if ((i < lf_pos) &&
+ ('\r' == buf[lf_pos - 1]))
+ {
+ i = lf_pos + 1;
+ mf->st = mhd_POST_MPART_ST_PREAMBL_LINE_START;
+ break;
+ }
+ i = lf_pos;
+#else /* MHD_FAVOR_SMALL_CODE */
if ('\r' == buf[i])
{
mf->st = mhd_POST_MPART_ST_PREAMBL_CR_FOUND;
@@ -1469,6 +1556,7 @@ parse_post_mpart (struct MHD_Connection *restrict c,
++i; /* Go to the next char */
break;
}
+#endif /* MHD_FAVOR_SMALL_CODE */
} while (*pdata_size > ++i);
mhd_assert ((*pdata_size == i) || \
(mhd_POST_MPART_ST_PREAMBL_CR_FOUND == mf->st) || \
@@ -1496,38 +1584,50 @@ parse_post_mpart (struct MHD_Connection *restrict c,
mhd_assert (mhd_POST_INVALID_POS == mf->delim_check_start);
mhd_assert (mhd_POST_INVALID_POS == mf->line_start);
mf->line_start = i;
+#ifndef MHD_FAVOR_SMALL_CODE
+ if (*pdata_size - i >= mf->delim.size - 2) /* Exclude CRLF prefix for
the first delimiter */
+ { /* Exclude CRLF prefix for the first delimiter */
+ if (0 == memcmp (buf + i, mf->delim.data + 2, mf->delim.size - 2))
+ {
+ mf->st = mhd_POST_MPART_ST_FIRST_DELIM_FOUND;
+ i += mf->delim.size - 2;
+ }
+ else
+ mf->st = mhd_POST_MPART_ST_BACK_TO_PREAMBL;
+ continue;
+ }
+#endif /* ! MHD_FAVOR_SMALL_CODE */
mf->st = mhd_POST_MPART_ST_PREAMBL_CHECKING_FOR_DELIM;
mhd_FALLTHROUGH;
/* Intentional fallthrough */
case mhd_POST_MPART_ST_PREAMBL_CHECKING_FOR_DELIM:
mhd_assert (mhd_POST_INVALID_POS == mf->delim_check_start); /* Ignored
for first delimiter */
mhd_assert (i >= mf->line_start);
- do /* Fast local loop */
+ mhd_assert (*pdata_size >= mf->line_start);
+ mhd_assert (i < mf->line_start + (mf->delim.size - 2));
+ if (*pdata_size - mf->line_start >= (mf->delim.size - 2))
{
- mhd_assert (i - mf->line_start < mf->bound.size + 2);
- if (i < mf->line_start + 2)
+ /* Enough data for the delimiter */
+ if (0 == memcmp (buf + mf->line_start,
+ mf->delim.data + 2,
+ mf->delim.size - 2))
{
- if ('-' != buf[i])
- {
- mf->st = mhd_POST_MPART_ST_BACK_TO_PREAMBL;
- break;
- }
- }
- else if (i <= mf->line_start + mf->bound.size + 1)
- {
- if (mf->bound.data[i - (mf->line_start + 2)] != buf[i])
- {
- mf->st = mhd_POST_MPART_ST_BACK_TO_PREAMBL;
- break;
- }
- else if (i == mf->line_start + mf->bound.size + 1)
- {
- mf->st = mhd_POST_MPART_ST_FIRST_DELIM_FOUND;
- ++i;
- break;
- }
+ mf->st = mhd_POST_MPART_ST_FIRST_DELIM_FOUND;
+ i = mf->line_start + (mf->delim.size - 2);
}
- } while (*pdata_size > ++i);
+ else
+ mf->st = mhd_POST_MPART_ST_BACK_TO_PREAMBL;
+ }
+ else
+ {
+ /* Not enough data for the delimiter */
+ if (0 == memcmp (buf + mf->line_start,
+ mf->delim.data + 2,
+ *pdata_size - mf->line_start))
+ i = *pdata_size;
+ else
+ mf->st = mhd_POST_MPART_ST_BACK_TO_PREAMBL;
+ }
mhd_assert ((*pdata_size == i) || \
(mhd_POST_MPART_ST_FIRST_DELIM_FOUND == mf->st) || \
(mhd_POST_MPART_ST_BACK_TO_PREAMBL == mf->st));
@@ -1535,7 +1635,7 @@ parse_post_mpart (struct MHD_Connection *restrict c,
case mhd_POST_MPART_ST_FIRST_DELIM_FOUND:
mhd_assert (mhd_POST_INVALID_POS == mf->delim_check_start); /* Ignored
for first delimiter */
mhd_assert (mhd_POST_INVALID_POS != mf->line_start);
- mhd_assert (i >= mf->line_start + mf->bound.size + 2);
+ mhd_assert (i >= mf->line_start + mf->delim.size - 2);
do /* Fast local loop */
{
if ('\n' == buf[i])
@@ -1556,7 +1656,7 @@ parse_post_mpart (struct MHD_Connection *restrict c,
mf->st = mhd_POST_MPART_ST_FORMAT_ERROR;
break;
}
- else if ((i == mf->line_start + mf->bound.size + 3) &&
+ else if ((i == mf->line_start + (mf->delim.size - 2) + 1) &&
('-' == buf [i - 1]) &&
('-' == buf [i]))
{
@@ -1620,13 +1720,11 @@ parse_post_mpart (struct MHD_Connection *restrict c,
mf->st = mhd_POST_MPART_ST_FORMAT_ERROR;
break;
}
- else if (mf->line_start + mf->bound.size + 1 == i)
+ else if (mf->line_start + (mf->delim.size - 2) == i + 1)
{
- if (('-' == buf[mf->line_start]) &&
- ('-' == buf[mf->line_start + 1]) &&
- (0 == memcmp (buf + mf->line_start + 2,
- mf->bound.data,
- mf->bound.size)))
+ if (0 == memcmp (buf + mf->line_start,
+ mf->delim.data + 2,
+ mf->delim.size - 2))
{
/* The delimiter before the end of the header */
if (2 > mf->line_start)
@@ -1875,8 +1973,87 @@ parse_post_mpart (struct MHD_Connection *restrict c,
mhd_assert (mhd_POST_INVALID_POS == mf->delim_check_start);
mhd_assert (mhd_POST_INVALID_POS == mf->line_start);
mhd_assert (mhd_POST_INVALID_POS != p_data->field_start);
+#ifdef HAVE_MEMMEM
+ if (mf->delim.size <= *pdata_size - i)
+ {
+ const char *delim_ptr;
+ if (! bare_lf_as_crlf)
+ delim_ptr = (const char *) memmem (buf + i,
+ *pdata_size - i,
+ mf->delim.data,
+ mf->delim.size);
+ else
+ delim_ptr = (const char *) memmem (buf + i,
+ *pdata_size - i,
+ mf->delim.data + 1,
+ mf->delim.size - 1);
+ if (NULL != delim_ptr)
+ {
+ size_t delim_pos;
+
+ mhd_assert (delim_ptr >= buf + i);
+ mhd_assert (delim_ptr + mf->delim.size - 1 <= buf + *pdata_size);
+
+ delim_pos = (size_t) (delim_ptr - buf);
+
+ mhd_assert (i <= delim_pos);
+
+ if (! bare_lf_as_crlf)
+ {
+ mf->line_start = delim_pos + 2;
+ i = delim_pos + mf->delim.size;
+ }
+ else
+ {
+ mf->line_start = delim_pos + 1;
+ i = delim_pos + mf->delim.size - 1;
+ if ((delim_pos > i) &&
+ ('\r' == buf[delim_pos - 1]))
+ --delim_pos;
+ }
+ mf->delim_check_start = delim_pos;
+ mf->st = mhd_POST_MPART_ST_DELIM_FOUND;
+ continue;
+ }
+ i = *pdata_size - mf->delim.size + 1u; /* '+ 1u' to move to then next
position */
+ if (! bare_lf_as_crlf)
+ i += 1u;
+ }
+#endif /* HAVE_MEMMEM */
do /* Fast local loop */
{
+#ifndef MHD_FAVOR_SMALL_CODE
+ const char *lf_ptr;
+ size_t lf_pos;
+
+ lf_ptr = (const char *) memchr (buf + i, '\n', *pdata_size - i);
+ if (NULL == lf_ptr)
+ {
+ if ('\r' == buf[*pdata_size - 1])
+ mf->st = mhd_POST_MPART_ST_VALUE_CR_FOUND;
+ i = *pdata_size;
+ break;
+ }
+ lf_pos = (size_t) (lf_ptr - buf);
+ mhd_assert (i <= lf_pos);
+ mhd_assert (*pdata_size > i);
+ if ((i < lf_pos) &&
+ ('\r' == buf[lf_pos - 1]))
+ {
+ mf->delim_check_start = lf_pos - 1;
+ mf->st = mhd_POST_MPART_ST_VALUE_LINE_START;
+ i = lf_pos + 1;
+ break;
+ }
+ else if (bare_lf_as_crlf)
+ {
+ mf->delim_check_start = lf_pos;
+ mf->st = mhd_POST_MPART_ST_VALUE_LINE_START;
+ i = lf_pos + 1;
+ break;
+ }
+ i = lf_pos;
+#else /* MHD_FAVOR_SMALL_CODE */
if ('\r' == buf[i])
{
mf->delim_check_start = i;
@@ -1891,6 +2068,7 @@ parse_post_mpart (struct MHD_Connection *restrict c,
++i;
break;
}
+#endif /* MHD_FAVOR_SMALL_CODE */
} while (*pdata_size > ++i);
mhd_assert ((*pdata_size == i) || \
(mhd_POST_MPART_ST_VALUE_CR_FOUND == mf->st) || \
@@ -1909,47 +2087,59 @@ parse_post_mpart (struct MHD_Connection *restrict c,
mhd_assert (mhd_POST_INVALID_POS != mf->delim_check_start);
mhd_assert (mhd_POST_INVALID_POS != p_data->field_start);
mf->line_start = i;
+#ifndef MHD_FAVOR_SMALL_CODE
+ if (*pdata_size - i >= mf->delim.size - 2)
+ {
+ if (0 == memcmp (buf + i, mf->delim.data + 2, mf->delim.size - 2))
+ {
+ mf->st = mhd_POST_MPART_ST_DELIM_FOUND;
+ i += mf->delim.size - 2;
+ }
+ else
+ mf->st = mhd_POST_MPART_ST_BACK_TO_VALUE;
+ continue;
+ }
+#endif /* ! MHD_FAVOR_SMALL_CODE */
mf->st = mhd_POST_MPART_ST_VALUE_CHECKING_FOR_DELIM;
mhd_FALLTHROUGH;
/* Intentional fallthrough */
case mhd_POST_MPART_ST_VALUE_CHECKING_FOR_DELIM:
mhd_assert (mhd_POST_INVALID_POS != p_data->field_start);
mhd_assert (i >= mf->line_start);
- do /* Fast local loop */
+ mhd_assert (*pdata_size >= mf->line_start);
+ mhd_assert (i < mf->line_start + (mf->delim.size - 2));
+ if (*pdata_size - mf->line_start >= (mf->delim.size - 2))
{
- mhd_assert (i - mf->line_start < mf->bound.size + 2);
- if (i < mf->line_start + 2)
+ /* Enough data for the delimiter */
+ if (0 == memcmp (buf + mf->line_start,
+ mf->delim.data + 2,
+ mf->delim.size - 2))
{
- if ('-' != buf[i])
- {
- mf->st = mhd_POST_MPART_ST_BACK_TO_VALUE;
- break;
- }
+ mf->st = mhd_POST_MPART_ST_DELIM_FOUND;
+ i = mf->line_start + (mf->delim.size - 2);
}
- else if (i <= mf->line_start + mf->bound.size + 1)
- {
- if (mf->bound.data[i - (mf->line_start + 2)] != buf[i])
- {
- mf->st = mhd_POST_MPART_ST_BACK_TO_VALUE;
- break;
- }
- if (i == mf->line_start + mf->bound.size + 1)
- {
- mf->st = mhd_POST_MPART_ST_DELIM_FOUND;
- ++i;
- break;
- }
- }
- } while (*pdata_size > ++i);
+ else
+ mf->st = mhd_POST_MPART_ST_BACK_TO_VALUE;
+ }
+ else
+ {
+ /* Not enough data for the delimiter */
+ if (0 == memcmp (buf + mf->line_start,
+ mf->delim.data + 2,
+ *pdata_size - mf->line_start))
+ i = *pdata_size;
+ else
+ mf->st = mhd_POST_MPART_ST_BACK_TO_VALUE;
+ }
mhd_assert ((*pdata_size == i) || \
- (mhd_POST_MPART_ST_BACK_TO_VALUE == mf->st) || \
- (mhd_POST_MPART_ST_DELIM_FOUND == mf->st));
+ (mhd_POST_MPART_ST_DELIM_FOUND == mf->st) || \
+ (mhd_POST_MPART_ST_BACK_TO_VALUE == mf->st));
continue;
case mhd_POST_MPART_ST_DELIM_FOUND:
mhd_assert (mhd_POST_INVALID_POS != mf->delim_check_start);
mhd_assert (mhd_POST_INVALID_POS != mf->line_start);
mhd_assert (mhd_POST_INVALID_POS != p_data->field_start);
- mhd_assert (i >= mf->line_start + mf->bound.size + 2);
+ mhd_assert (i >= mf->line_start + mf->delim.size - 2);
do /* Fast local loop */
{
if ('\n' == buf[i])
@@ -1967,7 +2157,7 @@ parse_post_mpart (struct MHD_Connection *restrict c,
mf->st = mhd_POST_MPART_ST_FORMAT_ERROR;
break;
}
- else if ((i == mf->line_start + mf->bound.size + 3) &&
+ else if ((i == mf->line_start + (mf->delim.size - 2) + 1) &&
('-' == buf [i - 1]) &&
('-' == buf [i]))
{
diff --git a/src/mhd2/stream_process_request.c
b/src/mhd2/stream_process_request.c
index 5bdf8d3..baf5afa 100644
--- a/src/mhd2/stream_process_request.c
+++ b/src/mhd2/stream_process_request.c
@@ -461,35 +461,97 @@ parse_http_std_method (struct MHD_Connection *restrict
connection)
mhd_assert (NULL != m);
mhd_assert (0 != len);
- if ((mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_GET) == len) &&
- (0 == memcmp (m, MHD_HTTP_METHOD_STR_GET, len)))
- connection->rq.http_mthd = mhd_HTTP_METHOD_GET;
- else if ((mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_HEAD) == len) &&
- (0 == memcmp (m, MHD_HTTP_METHOD_STR_HEAD, len)))
- connection->rq.http_mthd = mhd_HTTP_METHOD_HEAD;
- else if ((mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_POST) == len) &&
- (0 == memcmp (m, MHD_HTTP_METHOD_STR_POST, len)))
- connection->rq.http_mthd = mhd_HTTP_METHOD_POST;
- else if ((mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_PUT) == len) &&
- (0 == memcmp (m, MHD_HTTP_METHOD_STR_PUT, len)))
- connection->rq.http_mthd = mhd_HTTP_METHOD_PUT;
- else if ((mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_DELETE) == len) &&
- (0 == memcmp (m, MHD_HTTP_METHOD_STR_DELETE, len)))
- connection->rq.http_mthd = mhd_HTTP_METHOD_DELETE;
- else if ((mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_CONNECT) == len) &&
- (0 == memcmp (m, MHD_HTTP_METHOD_STR_CONNECT, len)))
- connection->rq.http_mthd = mhd_HTTP_METHOD_CONNECT;
- else if ((mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_OPTIONS) == len) &&
- (0 == memcmp (m, MHD_HTTP_METHOD_STR_OPTIONS, len)))
- connection->rq.http_mthd = mhd_HTTP_METHOD_OPTIONS;
- else if ((mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_TRACE) == len) &&
- (0 == memcmp (m, MHD_HTTP_METHOD_STR_TRACE, len)))
- connection->rq.http_mthd = mhd_HTTP_METHOD_TRACE;
- else if ((mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_ASTERISK) == len) &&
- (0 == memcmp (m, MHD_HTTP_METHOD_STR_ASTERISK, len)))
- connection->rq.http_mthd = mhd_HTTP_METHOD_ASTERISK;
- else
- connection->rq.http_mthd = mhd_HTTP_METHOD_OTHER;
+ switch (len)
+ {
+ case 3: /* mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_GET) */
+ /* mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_PUT) */
+ mhd_assert (len == mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_GET));
+ mhd_assert (len == mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_PUT));
+ if (0 == memcmp (m,
+ MHD_HTTP_METHOD_STR_GET,
+ mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_GET)))
+ {
+ connection->rq.http_mthd = mhd_HTTP_METHOD_GET;
+ return;
+ }
+ else if (0 == memcmp (m,
+ MHD_HTTP_METHOD_STR_PUT,
+ mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_PUT)))
+ {
+ connection->rq.http_mthd = mhd_HTTP_METHOD_PUT;
+ return;
+ }
+ break;
+ case 4: /* mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_HEAD) */
+ /* mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_POST) */
+ mhd_assert (len == mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_HEAD));
+ mhd_assert (len == mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_POST));
+ if (0 == memcmp (m,
+ MHD_HTTP_METHOD_STR_HEAD,
+ mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_HEAD)))
+ {
+ connection->rq.http_mthd = mhd_HTTP_METHOD_HEAD;
+ return;
+ }
+ else if (0 == memcmp (m,
+ MHD_HTTP_METHOD_STR_POST,
+ mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_POST)))
+ {
+ connection->rq.http_mthd = mhd_HTTP_METHOD_POST;
+ return;
+ }
+ break;
+ case 6: /* mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_DELETE) */
+ mhd_assert (len == mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_DELETE));
+ if (0 == memcmp (m,
+ MHD_HTTP_METHOD_STR_DELETE,
+ mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_DELETE)))
+ {
+ connection->rq.http_mthd = mhd_HTTP_METHOD_DELETE;
+ return;
+ }
+ break;
+ case 7: /* mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_CONNECT) */
+ /* mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_OPTIONS) */
+ mhd_assert (len == mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_CONNECT));
+ mhd_assert (len == mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_OPTIONS));
+ if (0 == memcmp (m,
+ MHD_HTTP_METHOD_STR_CONNECT,
+ mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_CONNECT)))
+ {
+ connection->rq.http_mthd = mhd_HTTP_METHOD_CONNECT;
+ return;
+ }
+ else if (0 == memcmp (m,
+ MHD_HTTP_METHOD_STR_OPTIONS,
+ mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_OPTIONS)))
+ {
+ connection->rq.http_mthd = mhd_HTTP_METHOD_OPTIONS;
+ return;
+ }
+ break;
+ case 5: /* mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_TRACE) */
+ mhd_assert (len == mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_TRACE));
+ if (0 == memcmp (m,
+ MHD_HTTP_METHOD_STR_TRACE,
+ mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_TRACE)))
+ {
+ connection->rq.http_mthd = mhd_HTTP_METHOD_TRACE;
+ return;
+ }
+ break;
+ case 1: /* mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_ASTERISK) */
+ mhd_assert (len == mhd_SSTR_LEN (MHD_HTTP_METHOD_STR_ASTERISK));
+ if ('*' == m[0])
+ {
+ connection->rq.http_mthd = mhd_HTTP_METHOD_ASTERISK;
+ return;
+ }
+ break;
+ default:
+ break; /* Handled after the "switch()" body */
+ }
+ connection->rq.http_mthd = mhd_HTTP_METHOD_OTHER;
}
diff --git a/src/tests/client_server/Makefile.am
b/src/tests/client_server/Makefile.am
index a050839..0559a97 100644
--- a/src/tests/client_server/Makefile.am
+++ b/src/tests/client_server/Makefile.am
@@ -29,7 +29,7 @@ $(top_builddir)/src/mhd2/libmicrohttpd2.la:
$(top_builddir)/src/mhd2/Makefile
check_PROGRAMS = \
test_client_server \
test_authentication \
- test_postprocessor
+ test_postparser
if MHD_SUPPORT_HTTPS
check_PROGRAMS += \
diff --git a/src/tests/client_server/test_postprocessor.c
b/src/tests/client_server/test_postparser.c
similarity index 100%
rename from src/tests/client_server/test_postprocessor.c
rename to src/tests/client_server/test_postparser.c
diff --git a/src/tools/perf_replies.c b/src/tools/perf_replies.c
index 6c713b3..2d1a7bd 100644
--- a/src/tools/perf_replies.c
+++ b/src/tools/perf_replies.c
@@ -341,8 +341,10 @@ show_help (void)
printf ("Response body size options (mutually exclusive):\n");
printf (" -E, --empty empty response, 0 bytes\n");
printf (" -T, --tiny tiny response, 3 bytes (default)\n");
- printf (" -M, --medium medium response, 8 KB\n");
- printf (" -L, --large large response, 1 MB\n");
+ printf (" -M, --medium medium response, 8 KiB\n");
+ printf (" -L, --large large response, 1 MiB\n");
+ printf (" -X, --xlarge extra large response, 8 MiB\n");
+ printf (" -J, --jumbo jumbo response, 101 MiB\n");
printf ("\n");
printf ("Response use options (mutually exclusive):\n");
printf (" -S, --shared pool of pre-generated shared response\n"
@@ -384,6 +386,8 @@ struct PerfRepl_parameters
int tiny;
int medium;
int large;
+ int xlarge;
+ int jumbo;
int shared;
int single;
int unique;
@@ -413,6 +417,8 @@ static struct PerfRepl_parameters tool_params = {
0,
0,
0,
+ 0,
+ 0,
0
};
@@ -502,6 +508,8 @@ process_param__thread_per_conn (const char *param_name)
return '-' == param_name[1] ?
PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
}
+
+
#endif /* disabled code */
@@ -589,6 +597,18 @@ process_param__empty (const char *param_name)
"with '-L' or '--large'.\n", param_name);
return PERF_RPL_PARAM_ERROR;
}
+ if (tool_params.xlarge)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-X' or '--xlarge'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ if (tool_params.jumbo)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-J' or '--jumbo'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
tool_params.empty = ! 0;
return '-' == param_name[1] ?
PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
@@ -616,6 +636,18 @@ process_param__tiny (const char *param_name)
"with '-L' or '--large'.\n", param_name);
return PERF_RPL_PARAM_ERROR;
}
+ if (tool_params.xlarge)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-X' or '--xlarge'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ if (tool_params.jumbo)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-J' or '--jumbo'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
tool_params.tiny = ! 0;
return '-' == param_name[1] ?
PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
@@ -643,6 +675,18 @@ process_param__medium (const char *param_name)
"with '-L' or '--large'.\n", param_name);
return PERF_RPL_PARAM_ERROR;
}
+ if (tool_params.xlarge)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-X' or '--xlarge'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ if (tool_params.jumbo)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-J' or '--jumbo'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
tool_params.medium = ! 0;
return '-' == param_name[1] ?
PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
@@ -670,12 +714,102 @@ process_param__large (const char *param_name)
"with '-M' or '--medium'.\n", param_name);
return PERF_RPL_PARAM_ERROR;
}
+ if (tool_params.xlarge)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-X' or '--xlarge'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ if (tool_params.jumbo)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-J' or '--jumbo'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
tool_params.large = ! 0;
return '-' == param_name[1] ?
PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
}
+static enum PerfRepl_param_result
+process_param__xlarge (const char *param_name)
+{
+ if (tool_params.empty)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-E' or '--empty'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ if (tool_params.tiny)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-T' or '--tiny'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ if (tool_params.medium)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-M' or '--medium'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ if (tool_params.large)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-L' or '--large'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ if (tool_params.jumbo)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-J' or '--jumbo'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ tool_params.xlarge = ! 0;
+ return '-' == param_name[1] ?
+ PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
+}
+
+
+static enum PerfRepl_param_result
+process_param__jumbo (const char *param_name)
+{
+ if (tool_params.empty)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-E' or '--empty'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ if (tool_params.tiny)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-T' or '--tiny'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ if (tool_params.medium)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-M' or '--medium'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ if (tool_params.large)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-L' or '--large'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ if (tool_params.xlarge)
+ {
+ fprintf (stderr, "Parameter '%s' cannot be used together "
+ "with '-X' or '--xlarge'.\n", param_name);
+ return PERF_RPL_PARAM_ERROR;
+ }
+ tool_params.jumbo = ! 0;
+ return '-' == param_name[1] ?
+ PERF_RPL_PARAM_FULL_STR :PERF_RPL_PARAM_ONE_CHAR;
+}
+
+
static enum PerfRepl_param_result
process_param__shared (const char *param_name)
{
@@ -862,6 +996,10 @@ process_short_param (const char *param, const char
*next_param)
return process_param__medium ("-M");
else if ('L' == param_chr)
return process_param__large ("-L");
+ else if ('X' == param_chr)
+ return process_param__xlarge ("-X");
+ else if ('J' == param_chr)
+ return process_param__jumbo ("-J");
else if ('S' == param_chr)
return process_param__shared ("-S");
else if ('I' == param_chr)
@@ -954,6 +1092,12 @@ process_long_param (const char *param, const char
*next_param)
else if ((mhd_SSTR_LEN ("large") == param_len) &&
(0 == memcmp (param, "large", mhd_SSTR_LEN ("large"))))
return process_param__large ("--large");
+ else if ((mhd_SSTR_LEN ("xlarge") == param_len) &&
+ (0 == memcmp (param, "xlarge", mhd_SSTR_LEN ("xlarge"))))
+ return process_param__xlarge ("--xlarge");
+ else if ((mhd_SSTR_LEN ("jumbo") == param_len) &&
+ (0 == memcmp (param, "jumbo", mhd_SSTR_LEN ("jumbo"))))
+ return process_param__jumbo ("--jumbo");
else if ((mhd_SSTR_LEN ("shared") == param_len) &&
(0 == memcmp (param, "shared", mhd_SSTR_LEN ("shared"))))
return process_param__shared ("--shared");
@@ -1129,6 +1273,7 @@ check_apply_param__threads (void)
}
}
+
#if 0 /* disabled code */
/**
@@ -1151,6 +1296,8 @@ check_apply_param__thread_per_conn (void)
return ! 0;
}
+
+
#endif /* disabled code */
@@ -1212,10 +1359,10 @@ check_param__select (void)
static void
-check_param__empty_tiny_medium_large (void)
+check_param__empty_tiny_medium_large_xlarge_jumbo (void)
{
if (0 == (tool_params.empty | tool_params.tiny | tool_params.medium
- | tool_params.large))
+ | tool_params.large | tool_params.xlarge | tool_params.jumbo))
tool_params.tiny = ! 0;
}
@@ -1278,7 +1425,7 @@ check_apply_params (void)
return PERF_RPL_ERR_CODE_BAD_PARAM;
if (! check_param__select ())
return PERF_RPL_ERR_CODE_BAD_PARAM;
- check_param__empty_tiny_medium_large ();
+ check_param__empty_tiny_medium_large_xlarge_jumbo ();
check_param__shared_single_unique ();
if (! check_param__connections ())
return PERF_RPL_ERR_CODE_BAD_PARAM;
@@ -1286,6 +1433,29 @@ check_apply_params (void)
}
+static uint_fast64_t
+mini_rnd (void)
+{
+ /* Simple xoshiro256+ implementation */
+ static uint_fast64_t s[4] = {
+ 0x76e15d3efefdcbbfuLL, 0xc5004e441c522fb3uLL,
+ 0x77710069854ee241uLL, 0x39109bb02acbe635uLL
+ }; /* Good enough for static initialisation */
+
+ const uint_fast64_t ret = (s[0] + s[3]) & 0xFFFFFFFFFFFFFFFFuLL;
+ const uint_fast64_t t = (s[1] << 17) & 0xFFFFFFFFFFFFFFFFuLL;
+
+ s[2] ^= s[0];
+ s[3] ^= s[1];
+ s[1] ^= s[2];
+ s[0] ^= s[3];
+ s[2] ^= t;
+ s[3] = ((s[3] << 45u) | (s[3] << (64u - 45u))) & 0xFFFFFFFFFFFFFFFFuLL;
+
+ return ret;
+}
+
+
/* The pool of shared responses */
static struct MHD_Response **resps = NULL;
static unsigned int num_resps = 0;
@@ -1310,7 +1480,7 @@ init_response_body_data (void)
fprintf (stderr, "Failed to allocate memory.\n");
return 0;
}
- if (tool_params.medium)
+ if (16u * 1024u >= body_dyn_size)
{
/* Fill the body with HTML-like content */
size_t pos;
@@ -1338,13 +1508,38 @@ init_response_body_data (void)
pos += filler_pos;
memcpy (body_dyn + pos, body_footer, mhd_SSTR_LEN (body_footer));
}
- else
+ else if (2u * 1024u * 1024u >= body_dyn_size)
{
/* Fill the body with binary-like content */
size_t pos;
for (pos = 0; pos < body_dyn_size; ++pos)
body_dyn[pos] = (char) (unsigned char) (255U - pos % 256U);
}
+ else
+ {
+ /* Fill the body with pseudo-random binary-like content */
+ size_t pos;
+ uint_fast64_t rnd_data;
+ for (pos = 0; pos < body_dyn_size - body_dyn_size % 8;
+ pos += 8)
+ {
+ rnd_data = mini_rnd ();
+ body_dyn[pos + 0] = (char) (unsigned char) (rnd_data >> 0);
+ body_dyn[pos + 1] = (char) (unsigned char) (rnd_data >> 8);
+ body_dyn[pos + 2] = (char) (unsigned char) (rnd_data >> 16);
+ body_dyn[pos + 3] = (char) (unsigned char) (rnd_data >> 24);
+ body_dyn[pos + 4] = (char) (unsigned char) (rnd_data >> 32);
+ body_dyn[pos + 5] = (char) (unsigned char) (rnd_data >> 40);
+ body_dyn[pos + 6] = (char) (unsigned char) (rnd_data >> 48);
+ body_dyn[pos + 7] = (char) (unsigned char) (rnd_data >> 54);
+ }
+ rnd_data = mini_rnd ();
+ for ((void) pos; pos < body_dyn_size; ++pos)
+ {
+ body_dyn[pos] = (char) (unsigned char) (rnd_data);
+ rnd_data >>= 8u;
+ }
+ }
}
return ! 0;
}
@@ -1356,19 +1551,19 @@ create_reusable_response_object (void)
struct MHD_Response *r;
if (NULL != body_dyn)
r = MHD_response_from_buffer_static (MHD_HTTP_STATUS_OK,
- body_dyn_size,
- body_dyn);
+ body_dyn_size,
+ body_dyn);
else if (tool_params.empty)
r = MHD_response_from_empty (MHD_HTTP_STATUS_OK);
else
- r = MHD_response_from_buffer_static (MHD_HTTP_STATUS_OK,
- mhd_SSTR_LEN (tiny_body),
- tiny_body);
+ r = MHD_response_from_buffer_static (MHD_HTTP_STATUS_OK,
+ mhd_SSTR_LEN (tiny_body),
+ tiny_body);
if (NULL != r)
{
if (MHD_SC_OK !=
- MHD_RESPONSE_SET_OPTIONS(r,
- MHD_R_OPTION_REUSABLE (MHD_YES)))
+ MHD_RESPONSE_SET_OPTIONS (r,
+ MHD_R_OPTION_REUSABLE (MHD_YES)))
{
MHD_response_destroy (r);
r = NULL;
@@ -1387,6 +1582,10 @@ init_data (void)
body_dyn_size = 8U * 1024U;
else if (tool_params.large)
body_dyn_size = 1024U * 1024U;
+ else if (tool_params.xlarge)
+ body_dyn_size = 8U * 1024U * 1024U;
+ else if (tool_params.jumbo)
+ body_dyn_size = 101U * 1024U * 1024U;
else
body_dyn_size = 0;
@@ -1475,10 +1674,10 @@ deinit_data (void)
MHD_FN_PAR_NONNULL_ (2) MHD_FN_PAR_NONNULL_ (3)
static const struct MHD_Action *
answer_shared_response (void *cls,
- struct MHD_Request *MHD_RESTRICT request,
- const struct MHD_String *MHD_RESTRICT path,
- enum MHD_HTTP_Method method,
- uint_fast64_t upload_size)
+ struct MHD_Request *MHD_RESTRICT request,
+ const struct MHD_String *MHD_RESTRICT path,
+ enum MHD_HTTP_Method method,
+ uint_fast64_t upload_size)
{
unsigned int resp_index;
static volatile unsigned int last_index = 0;
@@ -1560,10 +1759,10 @@ answer_unique_tiny_response (void *cls,
return
MHD_action_from_response (
- request,
- MHD_response_from_buffer_static (MHD_HTTP_STATUS_OK,
- mhd_SSTR_LEN (tiny_body),
- tiny_body));
+ request,
+ MHD_response_from_buffer_static (MHD_HTTP_STATUS_OK,
+ mhd_SSTR_LEN (tiny_body),
+ tiny_body));
}
@@ -1585,10 +1784,10 @@ answer_unique_dyn_response (void *cls,
return
MHD_action_from_response (
- request,
- MHD_response_from_buffer_static (MHD_HTTP_STATUS_OK,
- body_dyn_size,
- body_dyn));
+ request,
+ MHD_response_from_buffer_static (MHD_HTTP_STATUS_OK,
+ body_dyn_size,
+ body_dyn));
}
@@ -1596,7 +1795,7 @@ static void
print_perf_warnings (void)
{
int newline_needed = 0;
-#if !defined(NDEBUG) || defined(_DEBUG)
+#if ! defined(NDEBUG) || defined(_DEBUG)
fprintf (stderr, "WARNING: Running with debug asserts enabled, "
"the performance is suboptimal.\n");
newline_needed |= ! 0;
@@ -1628,7 +1827,6 @@ print_perf_warnings (void)
}
-
static const char *
get_mhd_poll_func_name (struct MHD_Daemon *d)
{
@@ -1732,9 +1930,13 @@ get_mhd_response_size (void)
else if (tool_params.tiny)
return "3 bytes (tiny)";
else if (tool_params.medium)
- return "8 KB (medium)";
+ return "8 KiB (medium)";
else if (tool_params.large)
- return "1 MB (large)";
+ return "1 MiB (large)";
+ else if (tool_params.xlarge)
+ return "8 MiB (xlarge)";
+ else if (tool_params.jumbo)
+ return "101 MiB (jumbo)";
return "!!internal error!!";
}
@@ -1804,7 +2006,7 @@ run_mhd (void)
opt_arr[opt_count++] = MHD_D_OPTION_WM_WORKER_THREADS (num_requsted_threads);
if (! tool_params.date_header)
- opt_arr[opt_count++] = MHD_D_OPTION_SUPPRESS_DATE_HEADER(MHD_YES);
+ opt_arr[opt_count++] = MHD_D_OPTION_SUPPRESS_DATE_HEADER (MHD_YES);
if (0 != tool_params.connections)
opt_arr[opt_count++] =
@@ -1824,8 +2026,8 @@ run_mhd (void)
}
if (MHD_SC_OK != MHD_daemon_set_options (d,
- opt_arr,
- opt_count))
+ opt_arr,
+ opt_count))
{
fprintf (stderr, "Error setting daemon options.\n");
MHD_daemon_destroy (d);
@@ -1866,7 +2068,7 @@ run_mhd (void)
0 == def_timeout ? " (no timeout)" : "");
}
printf (" 'Date:' header: %s\n",
- (! get_mhd_suppr_date(d)) ? "Yes" : "No");
+ (! get_mhd_suppr_date (d)) ? "Yes" : "No");
if (0 != port)
{
printf ("To test with remote client use\n"
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [libmicrohttpd2] branch master updated (cdd4c1f -> a71f9db),
Admin <=
- [libmicrohttpd2] 09/21: mhd_str: added 8 bit -> 2 xdigits one-pass encoding, Admin, 2025/06/13
- [libmicrohttpd2] 11/21: mhd_str: optimised caseless comparisons and case transformations, Admin, 2025/06/13
- [libmicrohttpd2] 13/21: parse_http_std_method(): optimised, Admin, 2025/06/13
- [libmicrohttpd2] 21/21: perf_replies: added response sizes 8 MiB and 101 MiB, Admin, 2025/06/13
- [libmicrohttpd2] 02/21: bootstrap: make sure that pre-commit hook really used, Admin, 2025/06/13
- [libmicrohttpd2] 01/21: conn_data_send.c: fixed large sending, added some asserts, Admin, 2025/06/13
- [libmicrohttpd2] 04/21: xdigittovalue(): optimised., Admin, 2025/06/13
- [libmicrohttpd2] 18/21: Renamed test_postprocessor -> test_postparser to match API naming, Admin, 2025/06/13
- [libmicrohttpd2] 16/21: configure: minor check improvement, Admin, 2025/06/13
- [libmicrohttpd2] 12/21: mhd_locks: added W32 implementation based on SRW locks (and minor improvements), Admin, 2025/06/13