Commit Diff


commit - b2a6b6137186dd3fce21640150926a133a35c2c8
commit + 5c342d059f884b73823e5a466902a3826b17e6c7
blob - /dev/null
blob + 674b8e229e34a3c2dc2320b9faaccefebdf5c12b (mode 644)
--- /dev/null
+++ compat/explicit_bzero.c
@@ -0,0 +1,12 @@
+/*
+ * Public domain.
+ * Written by Matthew Dempsky.
+ */
+
+#include <string.h>
+
+void
+explicit_bzero(void *buf, size_t len)
+{
+	memset(buf, 0, len);
+}
blob - /dev/null
blob + 1baffbbaa4387388b3f32b5f07513299d95046f7 (mode 644)
--- /dev/null
+++ compat/recallocarray.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
+ * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
+ */
+#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
+
+/*
+ * Even though specified in POSIX, the PAGESIZE and PAGE_SIZE
+ * macros have very poor portability.  Since we only use this
+ * to avoid free() overhead for small shrinking, simply pick
+ * an arbitrary number.
+ */
+#define getpagesize()	(1UL << 12)
+
+/* cheat: provide a prototype for explicit_bzero: if libc doesn't
+ * provide it, we will link to compat/explicit_bzero.c anyway. */
+void explicit_bzero(void*, size_t);
+
+void *
+recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size)
+{
+	size_t oldsize, newsize;
+	void *newptr;
+
+	if (ptr == NULL)
+		return calloc(newnmemb, size);
+
+	if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+	    newnmemb > 0 && SIZE_MAX / newnmemb < size) {
+		errno = ENOMEM;
+		return NULL;
+	}
+	newsize = newnmemb * size;
+
+	if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
+	    oldnmemb > 0 && SIZE_MAX / oldnmemb < size) {
+		errno = EINVAL;
+		return NULL;
+	}
+	oldsize = oldnmemb * size;
+
+	/*
+	 * Don't bother too much if we're shrinking just a bit,
+	 * we do not shrink for series of small steps, oh well.
+	 */
+	if (newsize <= oldsize) {
+		size_t d = oldsize - newsize;
+
+		if (d < oldsize / 2 && d < getpagesize()) {
+			memset((char *)ptr + newsize, 0, d);
+			return ptr;
+		}
+	}
+
+	newptr = malloc(newsize);
+	if (newptr == NULL)
+		return NULL;
+
+	if (newsize > oldsize) {
+		memcpy(newptr, ptr, oldsize);
+		memset((char *)newptr + oldsize, 0, newsize - oldsize);
+	} else
+		memcpy(newptr, ptr, newsize);
+
+	explicit_bzero(ptr, oldsize);
+	free(ptr);
+
+	return newptr;
+}
blob - /dev/null
blob + 6e6cb76d5950925c04b80333361c04697644d7c4 (mode 644)
--- /dev/null
+++ compat/strtonum.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2004 Ted Unangst and Todd Miller
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include "config.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#define	INVALID		1
+#define	TOOSMALL	2
+#define	TOOLARGE	3
+
+long long
+strtonum(const char *numstr, long long minval, long long maxval,
+    const char **errstrp)
+{
+	long long ll = 0;
+	int error = 0;
+	char *ep;
+	struct errval {
+		const char *errstr;
+		int err;
+	} ev[4] = {
+		{ NULL,		0 },
+		{ "invalid",	EINVAL },
+		{ "too small",	ERANGE },
+		{ "too large",	ERANGE },
+	};
+
+	ev[0].err = errno;
+	errno = 0;
+	if (minval > maxval) {
+		error = INVALID;
+	} else {
+		ll = strtoll(numstr, &ep, 10);
+		if (numstr == ep || *ep != '\0')
+			error = INVALID;
+		else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
+			error = TOOSMALL;
+		else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
+			error = TOOLARGE;
+	}
+	if (errstrp != NULL)
+		*errstrp = ev[error].errstr;
+	errno = ev[error].err;
+	if (error)
+		ll = 0;
+
+	return (ll);
+}
blob - 194acf6d01a791df14f9e096b9f819ad30bdca9b
blob + 7bacd2a758673b8b9beb2c5fb3aedbf7efa5711a
--- configure
+++ configure
@@ -41,10 +41,13 @@ LEX=lex
 STATIC=
 
 HAVE_ERR=
+HAVE_EXPLICIT_BZERO=
 HAVE_GETPROGNAME=
 HAVE_LIBTLS=
+HAVE_RECALLOCARRAY=
 HAVE_STRLCAT=
 HAVE_STRLCPY=
+HAVE_STRTONUM=
 HAVE_VASPRINTF=
 
 NEED_GNU_SOURCE=0
@@ -223,9 +226,12 @@ fi
 # tests for config.h
 
 runtest err		ERR		|| true
+runtest explicit_bzero	EXPLICIT_BZERO	|| true
 runtest libtls		LIBTLS		|| true
+runtest recallocarray	RECALLOCARRAY	|| true
 runtest strlcat		STRLCAT		|| true
 runtest strlcpy		STRLCPY		|| true
+runtest strtonum	STRTONUM	|| true
 runtest vasprintf	VASPRINTF	"" -D_GNU_SOURCE || true
 
 if [ ${HAVE_LIBTLS} -eq 0 ]; then
@@ -243,7 +249,6 @@ cat <<__HEREDOC__
 #ifdef __cplusplus
 #error "Do not use C++."
 #endif
-
 __HEREDOC__
 
 [ ${NEED_GNU_SOURCE} -eq 0 ] || echo "#define _GNU_SOURCE"
@@ -256,9 +261,12 @@ __HEREDOC__
 cat <<__HEREDOC__
 
 #define HAVE_ERR		${HAVE_ERR}
+#define HAVE_EXPLICIT_BZERO	${HAVE_EXPLICIT_BZERO}
 #define HAVE_GETPROGNAME	${HAVE_GETPROGNAME}
+#define HAVE_RECALLOCARRAY	${HAVE_RECALLOCARRAY}
 #define HAVE_STRLCAT		${HAVE_STRLCAT}
 #define HAVE_STRLCPY		${HAVE_STRLCPY}
+#define HAVE_STRTONUM		${HAVE_STRTONUM}
 #define HAVE_VASPRINTF		${HAVE_VASPRINTF}
 
 __HEREDOC__
@@ -270,7 +278,14 @@ if [ ${HAVE_ERR} -eq 0 ]; then
 	echo "extern	void	 warnx(const char*, ...);"
 	COMPAT="${COMPAT} compat/err.o"
 fi
-
+if [ ${HAVE_EXPLICIT_BZERO} -eq 0 ]; then
+	echo "extern	void	 explicit_bzero(void*, size_t);"
+	COMPAT="${COMPAT} compat/explicit_bzero.o"
+fi
+if [ ${HAVE_RECALLOCARRAY} -eq 0 ]; then
+	echo "extern	void*	 recallocarray(void*, size_t, size_t, size_t);"
+	COMPAT="${COMPAT} compat/recallocarray.o"
+fi
 if [ ${HAVE_STRLCAT} -eq 0 ]; then
 	echo "extern	size_t	 strlcat(char*, const char*, size_t);"
 	COMPAT="${COMPAT} compat/strlcat.o"
@@ -279,6 +294,10 @@ if [ ${HAVE_STRLCPY} -eq 0 ]; then
 	echo "extern	size_t	 strlcpy(char*, const char*, size_t);"
 	COMPAT="${COMPAT} compat/strlcpy.o"
 fi
+if [ ${HAVE_STRTONUM} -eq 0 ]; then
+	echo "extern	long long strtonum(const char*, long long, long long, const char**)"
+	COMPAT="${COMPAT} compat/strtonum.o"
+fi
 if [ ${HAVE_VASPRINTF} -eq 0 ]; then
 	echo "extern	int	 vasprintf(char**, const char*, va_list);"
 	COMPAT="${COMPAT} compat/vasprintf.o"
blob - /dev/null
blob + 9e8bd7015002dd2294245fc3dfc3c2628b45c2c8 (mode 644)
--- /dev/null
+++ have/explicit_bzero.c
@@ -0,0 +1,10 @@
+#include <string.h>
+
+int
+main(void)
+{
+	char buf[] = "hello world";
+
+	explicit_bzero(buf, sizeof(buf));
+	return strcmp(buf, "");
+}
blob - /dev/null
blob + e0c60d7118f8b94719e18fa5efadb3daf9b36833 (mode 644)
--- /dev/null
+++ have/recallocarray.c
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+
+int
+main(void)
+{
+	void	*p;
+
+	if ((p = calloc(2, 2)) == NULL)
+		return 1;
+	return !recallocarray(p, 2, 3, 2);
+}
blob - /dev/null
blob + 6e2aad2efbc46b09473e200b9a648019bdde8554 (mode 644)
--- /dev/null
+++ have/strtonum.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdlib.h>
+
+int
+main(void)
+{
+	const char *str = "42", *errstr;
+	int res;
+
+	res = strtonum(str, 1, 64, &errstr);
+	return res != 42 || errstr != NULL;
+}