summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2023-01-29 16:18:01 +0100
committerJörg Frings-Fürst <debian@jff-webhosting.net>2023-01-29 16:18:01 +0100
commite829867cc2d6879a0aeb50c08ae40ebc56b4e6b1 (patch)
tree7465150c86969e66a90e4b960bb3537485205842
parent6c88f3bab0b743487b367712fa1ec27d1f87389e (diff)
parentcd47bd564d7fc6177ba2e231d76bf352978409b8 (diff)
Merge branch 'feature/upstream' into develop
-rw-r--r--LICENSE.MIT20
-rw-r--r--LICENSE.WTFPL14
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure26
-rw-r--r--configure.ac4
-rw-r--r--doc/api.rst2
-rw-r--r--doc/changelog.rst24
-rw-r--r--doc/misc_functions.rst16
-rw-r--r--doc/socket_functions.rst18
-rw-r--r--doc/string_formatter.rst9
-rw-r--r--include/libHX/defs.h8
-rw-r--r--include/libHX/io.h5
-rw-r--r--include/libHX/misc.h3
-rw-r--r--include/libHX/option.h12
-rw-r--r--include/libHX/socket.h3
-rw-r--r--src/.gitignore1
-rw-r--r--src/Makefile.am7
-rw-r--r--src/Makefile.in53
-rw-r--r--src/format.c73
-rw-r--r--src/internal.h2
-rw-r--r--src/io.c51
-rw-r--r--src/libHX.map9
-rw-r--r--src/map.c5
-rw-r--r--src/mc.c29
-rw-r--r--src/opt.c46
-rw-r--r--src/socket.c183
-rw-r--r--src/string.c73
-rw-r--r--src/tc-cast.c9
-rw-r--r--src/tc-dir.c8
-rw-r--r--src/tc-format.c24
-rw-r--r--src/tc-io.c1
-rw-r--r--src/tc-list.c8
-rw-r--r--src/tc-list2.c8
-rw-r--r--src/tc-map.c9
-rw-r--r--src/tc-memmem.c6
-rw-r--r--src/tc-misc.c11
-rw-r--r--src/tc-netio.c8
-rw-r--r--src/tc-option.c7
-rw-r--r--src/tc-proc.c8
-rw-r--r--src/tc-rand.c8
-rw-r--r--src/tc-realpath.c6
-rw-r--r--src/tc-shconfig.c6
-rw-r--r--src/tc-socket.c31
-rw-r--r--src/tc-strchr2.c6
-rw-r--r--src/tc-string.c40
-rw-r--r--src/tc-strquote.c6
-rw-r--r--src/tc-switchuser.c15
-rw-r--r--src/tc-time.c10
-rw-r--r--src/tc-xml.c8
49 files changed, 636 insertions, 306 deletions
diff --git a/LICENSE.MIT b/LICENSE.MIT
new file mode 100644
index 0000000..26f131d
--- /dev/null
+++ b/LICENSE.MIT
@@ -0,0 +1,20 @@
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice (including the
+next paragraph) shall be included in all copies or substantial
+portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/LICENSE.WTFPL b/LICENSE.WTFPL
deleted file mode 100644
index 5a8e332..0000000
--- a/LICENSE.WTFPL
+++ /dev/null
@@ -1,14 +0,0 @@
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- Version 2, December 2004
-
- Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
-
- Everyone is permitted to copy and distribute verbatim or modified
- copies of this license document, and changing it is allowed as long
- as the name is changed.
-
- DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. You just DO WHAT THE FUCK YOU WANT TO.
-
diff --git a/config.h.in b/config.h.in
index f930a3c..112ecb4 100644
--- a/config.h.in
+++ b/config.h.in
@@ -93,6 +93,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
diff --git a/configure b/configure
index d40d681..7efd534 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for libHX 4.8.
+# Generated by GNU Autoconf 2.71 for libHX 4.10.
#
#
# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
@@ -618,8 +618,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='libHX'
PACKAGE_TARNAME='libhx'
-PACKAGE_VERSION='4.8'
-PACKAGE_STRING='libHX 4.8'
+PACKAGE_VERSION='4.10'
+PACKAGE_STRING='libHX 4.10'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1375,7 +1375,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures libHX 4.8 to adapt to many kinds of systems.
+\`configure' configures libHX 4.10 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1446,7 +1446,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of libHX 4.8:";;
+ short | recursive ) echo "Configuration of libHX 4.10:";;
esac
cat <<\_ACEOF
@@ -1561,7 +1561,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-libHX configure 4.8
+libHX configure 4.10
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2195,7 +2195,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by libHX $as_me 4.8, which was
+It was created by libHX $as_me 4.10, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -3684,7 +3684,7 @@ fi
# Define the identity of the package.
PACKAGE='libhx'
- VERSION='4.8'
+ VERSION='4.10'
printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -17595,6 +17595,12 @@ then :
printf "%s\n" "#define HAVE_SYS_RESOURCE_H 1" >>confdefs.h
fi
+ac_fn_c_check_header_compile "$LINENO" "sys/un.h" "ac_cv_header_sys_un_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_un_h" = xyes
+then :
+ printf "%s\n" "#define HAVE_SYS_UN_H 1" >>confdefs.h
+
+fi
if test "$ac_cv_header_dlfcn_h" = "yes"; then
HAVE_DLFCN_H_TRUE=
@@ -18765,7 +18771,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by libHX $as_me 4.8, which was
+This file was extended by libHX $as_me 4.10, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -18833,7 +18839,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
-libHX config.status 4.8
+libHX config.status 4.10
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 6e709e9..10c01b7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([libHX], [4.8])
+AC_INIT([libHX], [4.10])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
@@ -65,7 +65,7 @@ CHECK_GCC_FVISIBILITY
AM_CONDITIONAL([WITH_GNU_LD], [test "$with_gnu_ld" = yes])
LIBS_system="$LIBS"
-AC_CHECK_HEADERS([dlfcn.h sys/resource.h])
+AC_CHECK_HEADERS([dlfcn.h sys/resource.h sys/un.h])
AM_CONDITIONAL([HAVE_DLFCN_H], [test "$ac_cv_header_dlfcn_h" = "yes"])
AC_SEARCH_LIBS([dlopen], [dl], [libdl_LIBS="$LIBS"; LIBS="$LIBS_system"])
AC_SUBST([libdl_LIBS])
diff --git a/doc/api.rst b/doc/api.rst
index deb815f..5f009cc 100644
--- a/doc/api.rst
+++ b/doc/api.rst
@@ -9,6 +9,8 @@ Function reference
====== ====== ====== ========================================
RMV MinVer FirstA Name
====== ====== ====== ========================================
+4.9 4.9 4.9 HX_sockaddr_is_local
+4.9 4.9 4.9 HX_ipaddr_is_local
4.7 4.7 4.7 HXQUOTE_BASE64IMAP
4.7 4.7 4.7 HXQUOTE_BASE64URL
4.3 4.3 4.3 HX_unit_seconds
diff --git a/doc/changelog.rst b/doc/changelog.rst
index 1894bf5..9a1590c 100644
--- a/doc/changelog.rst
+++ b/doc/changelog.rst
@@ -1,3 +1,27 @@
+v4.10 (2023-01-29)
+==================
+
+Fixes:
+
+* format: plug a memory leak relating to func_entry_clone
+* Resolve mingw build failure
+
+
+v4.9 (2023-01-23)
+=================
+
+Enhancements:
+
+* socket: add sockaddr_is_local, ipaddr_is_local functions
+
+Fixes:
+
+* format: avoid return value truncation from HXformat_aprintf, HXformat_sprintf
+* format: avoid calling HXmc_length on a non-hxmc object
+* format: add new variations of printf functions returning ssize_t
+* Resolve Coverity-SCAN reports
+
+
v4.8 (2022-12-03)
=================
diff --git a/doc/misc_functions.rst b/doc/misc_functions.rst
index 0f1bdaf..43dacfe 100644
--- a/doc/misc_functions.rst
+++ b/doc/misc_functions.rst
@@ -8,7 +8,6 @@ Miscellaneous functions
int HX_ffs(unsigned long z);
int HX_fls(unsigned long z);
- void HX_hexdump(FILE *fp, const void *ptr, unsigned int len);
void HX_zvecfree(char **);
unsigned int HX_zveclen(const char *const *);
@@ -21,11 +20,6 @@ Miscellaneous functions
Finds the last (most-significant) bit in a value and returns its
position, or ``-1`` to indicate failure.
-``HX_hexdump``
- Outputs a nice pretty-printed hex and ASCII dump to the filedescriptor
- ``fp``. ``ptr`` is the memory area, of which ``len`` bytes will be
- dumped.
-
``HX_zvecfree``
Frees the supplied Z-vector array. (Frees all array elements from the
first element to (excluding) the first ``NULL`` element.)
@@ -33,3 +27,13 @@ Miscellaneous functions
``HX_zveclen``
Counts the number of array elements until the first ``NULL`` array
element is seen, and returns this number.
+
+.. code-block:: c
+
+ #include <libHX/io.h>
+ void HX_hexdump(FILE *fp, const void *ptr, unsigned int len);
+
+``HX_hexdump``
+ Outputs a nice pretty-printed hex and ASCII dump to the filedescriptor
+ ``fp``. ``ptr`` is the memory area, of which ``len`` bytes will be
+ dumped.
diff --git a/doc/socket_functions.rst b/doc/socket_functions.rst
index fe2b69d..ead0f08 100644
--- a/doc/socket_functions.rst
+++ b/doc/socket_functions.rst
@@ -7,6 +7,8 @@ Socket functions
#include <libHX/socket.h>
int HX_socket_from_env(const struct addrinfo *ai, const char *intf);
+ int HX_sockaddr_is_local(const struct sockaddr *, socklen_t, unsigned int flags);
+ int HX_ipaddr_is_local(const char *, unsigned int flags);
``HX_socket_from_env``
The function looks up the current process's file descriptors for a
@@ -14,3 +16,19 @@ Socket functions
(optionally) intf if the latter is not NULL``. Upon success, the fd
number is returned, or -1 if no file descriptor matched. No errors are
signalled.
+
+``HX_sockaddr_is_local``
+ Attempts to determine if the given socket address refers to a local
+ address. This function may be helpful in determining whether a process
+ should spend any time (or not) on compressing data before sending to a
+ peer. The definition of "local" is generally dependent upon the network
+ APIs. The ``flags`` parameter can contain ``AI_V4MAPPED`` if
+ IPv4-mapped IPv6 addresses should be recognized. The function returns
+ >0 if the address is considered local, 0 if not, and any other
+ negative value for a system error that makes the result
+ indeterminate.
+
+``HX_ipaddr_is_local``
+ Takes a text representation of an IPv6/IPv4 address and, after
+ transformation, calls ``HX_sockaddr_is_local``. ``flags`` and
+ return value behave the same as that.
diff --git a/doc/string_formatter.rst b/doc/string_formatter.rst
index fdb9c19..77badf8 100644
--- a/doc/string_formatter.rst
+++ b/doc/string_formatter.rst
@@ -116,10 +116,11 @@ Invoking the formatter
Does substituion and directly outputs the expansion to the given stdio
stream.
-On success, the length of the expanded string is returned, excluding the
-trailing ``\0``. While ``HXformat_sprintf`` will not write more than ``size``
-bytes (including the ``\0``), the length it would have taken is returned,
-similar to what sprintf does. On error, ``-errno`` is returned.
+On success, the length of the expanded string is returned (only up to a maximum
+of SSIZE_MAX), excluding the trailing ``\0``. While ``HXformat_sprintf`` will
+not write more than ``size`` bytes (including the ``\0``), the length it would
+have taken is returned, similar to what sprintf does. On error, ``-errno`` is
+returned.
The HXformat function family recognizes make-style like functions and recursive
expansion, described below.
diff --git a/include/libHX/defs.h b/include/libHX/defs.h
index 49ca7d1..9d17019 100644
--- a/include/libHX/defs.h
+++ b/include/libHX/defs.h
@@ -213,15 +213,15 @@ static __inline__ new_type signed_cast(unsigned char *expr)
# define container_of(v, s, m) containerof((v), s, m)
#endif
-#ifdef _WIN32
+#if !defined(_WIN32) || (defined(__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO + 0 > 0)
/*
* Sufficiently old versions of the VC runtime do not even support %ll.
*/
-# define HX_LONGLONG_FMT "I64"
-# define HX_SIZET_FMT "I"
-#else
# define HX_LONGLONG_FMT "ll"
# define HX_SIZET_FMT "z"
+#else
+# define HX_LONGLONG_FMT "I64"
+# define HX_SIZET_FMT "I"
#endif
#endif /* _LIBHX_DEFS_H */
diff --git a/include/libHX/io.h b/include/libHX/io.h
index 9d35cdc..7e0c7d3 100644
--- a/include/libHX/io.h
+++ b/include/libHX/io.h
@@ -1,6 +1,7 @@
#ifndef _LIBHX_IO_H
#define _LIBHX_IO_H 1
+#include <stdio.h>
#include <sys/types.h>
#ifdef __cplusplus
@@ -41,6 +42,10 @@ extern char *HX_slurp_file(const char *file, size_t *outsize);
extern ssize_t HXio_fullread(int, void *, size_t);
extern ssize_t HXio_fullwrite(int, const void *, size_t);
+#ifndef HX_HEXDUMP_DECLARATION
+#define HX_HEXDUMP_DECLARATION 1
+extern void HX_hexdump(FILE *, const void *, unsigned int);
+#endif
#ifdef __cplusplus
} /* extern "C" */
diff --git a/include/libHX/misc.h b/include/libHX/misc.h
index 211bc96..23607d2 100644
--- a/include/libHX/misc.h
+++ b/include/libHX/misc.h
@@ -59,7 +59,10 @@ extern const char *HX_dlerror(void);
*/
extern int HX_ffs(unsigned long);
extern int HX_fls(unsigned long);
+#ifndef HX_HEXDUMP_DECLARATION
+#define HX_HEXDUMP_DECLARATION 1
extern void HX_hexdump(FILE *, const void *, unsigned int);
+#endif
extern bool HX_timespec_isneg(const struct timespec *);
extern struct timespec *HX_timespec_neg(struct timespec *,
const struct timespec *);
diff --git a/include/libHX/option.h b/include/libHX/option.h
index 5b4bf6f..40cc6e7 100644
--- a/include/libHX/option.h
+++ b/include/libHX/option.h
@@ -27,12 +27,12 @@ extern struct HXformat_map *HXformat_init(void);
extern void HXformat_free(struct HXformat_map *);
extern int HXformat_add(struct HXformat_map *, const char *, const void *,
unsigned int);
-extern int HXformat_aprintf(const struct HXformat_map *,
- hxmc_t **, const char *);
-extern int HXformat_sprintf(const struct HXformat_map *,
- char *, size_t, const char *);
-extern int HXformat_fprintf(const struct HXformat_map *,
- FILE *, const char *);
+#define HXformat_aprintf(a, b, c) HXformat3_aprintf((a), (b), (c))
+#define HXformat_fprintf(a, b, c) HXformat3_fprintf((a), (b), (c))
+#define HXformat_sprintf(a, b, c, d) HXformat3_sprintf((a), (b), (c), (d))
+extern ssize_t HXformat3_aprintf(const struct HXformat_map *, hxmc_t **, const char *);
+extern ssize_t HXformat3_fprintf(const struct HXformat_map *, FILE *, const char *);
+extern ssize_t HXformat3_sprintf(const struct HXformat_map *, char *, size_t, const char *);
/*
* OPT.C
diff --git a/include/libHX/socket.h b/include/libHX/socket.h
index b151682..e9db77f 100644
--- a/include/libHX/socket.h
+++ b/include/libHX/socket.h
@@ -5,6 +5,7 @@
# include <ws2tcpip.h>
#else
# include <netdb.h>
+# include <sys/socket.h>
#endif
#ifdef __cplusplus
@@ -12,6 +13,8 @@ extern "C" {
#endif
extern int HX_socket_from_env(const struct addrinfo *, const char *intf);
+extern int HX_sockaddr_is_local(const struct sockaddr *, socklen_t, unsigned int flags);
+extern int HX_ipaddr_is_local(const char *, unsigned int flags);
#ifdef __cplusplus
} /* extern "C" */
diff --git a/src/.gitignore b/src/.gitignore
index 035dc34..89edb97 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -19,6 +19,7 @@
/t?-rand
/t?-realpath
/t?-shconfig
+/t?-socket
/t?-strchr2
/t?-string
/t?-strquote
diff --git a/src/Makefile.am b/src/Makefile.am
index c30b56c..921e6b7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,7 +13,7 @@ libHX_la_SOURCES = deque.c dl.c format.c io.c map.c \
mc.c misc.c opt.c proc.c \
rand.c socket.c string.c time.c
libHX_la_LIBADD = ${libdl_LIBS} -lm ${libpthread_LIBS} ${librt_LIBS}
-libHX_la_LDFLAGS = -no-undefined -version-info 35:0:3
+libHX_la_LDFLAGS = -no-undefined -version-info 36:0:4
if WITH_GNU_LD
libHX_la_LDFLAGS += -Wl,--version-script=${srcdir}/libHX.map
endif
@@ -36,9 +36,9 @@ EXTRA_DIST = internal.h map_int.h libHX.map
check_PROGRAMS = tc-compile tc-cast tc-deque tc-dir tc-format tc-io \
tc-list tc-list2 tc-map tc-memmem tc-misc tc-netio \
tc-option tc-proc tc-rand tc-realpath \
- tc-shconfig tc-strchr2 tc-string tc-strquote \
+ tc-shconfig tc-socket tc-strchr2 tc-string tc-strquote \
tc-switchuser tc-time
-TESTS = tc-strchr2 tc-strquote
+TESTS = tc-format tc-strchr2 tc-strquote
tc_cast_CFLAGS = ${AM_CFLAGS} -std=gnu99
tc_cast_LDADD = libHX.la -lm
tc_compile_LDADD = libHX.la
@@ -57,6 +57,7 @@ tc_proc_LDADD = libHX.la
tc_rand_LDADD = libHX.la
tc_realpath_LDADD = libHX.la
tc_shconfig_LDADD = libHX.la
+tc_socket_LDADD = libHX.la
tc_strchr2_LDADD = libHX.la
tc_string_LDADD = libHX.la
tc_strquote_LDADD = libHX.la
diff --git a/src/Makefile.in b/src/Makefile.in
index 356dcfe..8257e20 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -101,9 +101,11 @@ check_PROGRAMS = tc-compile$(EXEEXT) tc-cast$(EXEEXT) \
tc-map$(EXEEXT) tc-memmem$(EXEEXT) tc-misc$(EXEEXT) \
tc-netio$(EXEEXT) tc-option$(EXEEXT) tc-proc$(EXEEXT) \
tc-rand$(EXEEXT) tc-realpath$(EXEEXT) tc-shconfig$(EXEEXT) \
- tc-strchr2$(EXEEXT) tc-string$(EXEEXT) tc-strquote$(EXEEXT) \
- tc-switchuser$(EXEEXT) tc-time$(EXEEXT) $(am__EXEEXT_1)
-TESTS = tc-strchr2$(EXEEXT) tc-strquote$(EXEEXT) $(am__EXEEXT_2)
+ tc-socket$(EXEEXT) tc-strchr2$(EXEEXT) tc-string$(EXEEXT) \
+ tc-strquote$(EXEEXT) tc-switchuser$(EXEEXT) tc-time$(EXEEXT) \
+ $(am__EXEEXT_1)
+TESTS = tc-format$(EXEEXT) tc-strchr2$(EXEEXT) tc-strquote$(EXEEXT) \
+ $(am__EXEEXT_2)
@HAVE_CXX_TRUE@am__append_6 = tx-compile tx-cast tx-deque tx-dir \
@HAVE_CXX_TRUE@ tx-intdiff tx-list tx-list2 \
@HAVE_CXX_TRUE@ tx-misc tx-netio \
@@ -244,6 +246,9 @@ tc_realpath_DEPENDENCIES = libHX.la
tc_shconfig_SOURCES = tc-shconfig.c
tc_shconfig_OBJECTS = tc-shconfig.$(OBJEXT)
tc_shconfig_DEPENDENCIES = libHX.la
+tc_socket_SOURCES = tc-socket.c
+tc_socket_OBJECTS = tc-socket.$(OBJEXT)
+tc_socket_DEPENDENCIES = libHX.la
tc_strchr2_SOURCES = tc-strchr2.c
tc_strchr2_OBJECTS = tc-strchr2.$(OBJEXT)
tc_strchr2_DEPENDENCIES = libHX.la
@@ -354,9 +359,10 @@ am__depfiles_remade = ./$(DEPDIR)/deque.Plo ./$(DEPDIR)/dl.Plo \
./$(DEPDIR)/tc-netio.Po ./$(DEPDIR)/tc-option.Po \
./$(DEPDIR)/tc-proc.Po ./$(DEPDIR)/tc-rand.Po \
./$(DEPDIR)/tc-realpath.Po ./$(DEPDIR)/tc-shconfig.Po \
- ./$(DEPDIR)/tc-strchr2.Po ./$(DEPDIR)/tc-string.Po \
- ./$(DEPDIR)/tc-strquote.Po ./$(DEPDIR)/tc-switchuser.Po \
- ./$(DEPDIR)/tc-time.Po ./$(DEPDIR)/tc_cast-tc-cast.Po \
+ ./$(DEPDIR)/tc-socket.Po ./$(DEPDIR)/tc-strchr2.Po \
+ ./$(DEPDIR)/tc-string.Po ./$(DEPDIR)/tc-strquote.Po \
+ ./$(DEPDIR)/tc-switchuser.Po ./$(DEPDIR)/tc-time.Po \
+ ./$(DEPDIR)/tc_cast-tc-cast.Po \
./$(DEPDIR)/tc_list2-tc-list2.Po ./$(DEPDIR)/time.Plo \
./$(DEPDIR)/tx-cast.Po ./$(DEPDIR)/tx-compile.Po \
./$(DEPDIR)/tx-deque.Po ./$(DEPDIR)/tx-dir.Po \
@@ -408,19 +414,19 @@ SOURCES = $(libHX_la_SOURCES) $(libHX_rtcheck_la_SOURCES) tc-cast.c \
tc-compile.c tc-deque.c tc-dir.c tc-format.c tc-io.c tc-list.c \
tc-list2.c tc-map.c tc-memmem.c tc-misc.c tc-netio.c \
tc-option.c tc-proc.c tc-rand.c tc-realpath.c tc-shconfig.c \
- tc-strchr2.c tc-string.c tc-strquote.c tc-switchuser.c \
- tc-time.c $(tx_cast_SOURCES) $(tx_compile_SOURCES) \
- $(tx_deque_SOURCES) $(tx_dir_SOURCES) $(tx_intdiff_SOURCES) \
- $(tx_list_SOURCES) $(tx_list2_SOURCES) $(tx_misc_SOURCES) \
- $(tx_netio_SOURCES) $(tx_option_SOURCES) $(tx_proc_SOURCES) \
- $(tx_rand_SOURCES) $(tx_strchr2_SOURCES) $(tx_string_SOURCES) \
- $(tx_strquote_SOURCES) $(tx_time_SOURCES)
+ tc-socket.c tc-strchr2.c tc-string.c tc-strquote.c \
+ tc-switchuser.c tc-time.c $(tx_cast_SOURCES) \
+ $(tx_compile_SOURCES) $(tx_deque_SOURCES) $(tx_dir_SOURCES) \
+ $(tx_intdiff_SOURCES) $(tx_list_SOURCES) $(tx_list2_SOURCES) \
+ $(tx_misc_SOURCES) $(tx_netio_SOURCES) $(tx_option_SOURCES) \
+ $(tx_proc_SOURCES) $(tx_rand_SOURCES) $(tx_strchr2_SOURCES) \
+ $(tx_string_SOURCES) $(tx_strquote_SOURCES) $(tx_time_SOURCES)
DIST_SOURCES = $(am__libHX_la_SOURCES_DIST) \
$(libHX_rtcheck_la_SOURCES) tc-cast.c tc-compile.c tc-deque.c \
tc-dir.c tc-format.c tc-io.c tc-list.c tc-list2.c tc-map.c \
tc-memmem.c tc-misc.c tc-netio.c tc-option.c tc-proc.c \
- tc-rand.c tc-realpath.c tc-shconfig.c tc-strchr2.c tc-string.c \
- tc-strquote.c tc-switchuser.c tc-time.c \
+ tc-rand.c tc-realpath.c tc-shconfig.c tc-socket.c tc-strchr2.c \
+ tc-string.c tc-strquote.c tc-switchuser.c tc-time.c \
$(am__tx_cast_SOURCES_DIST) $(am__tx_compile_SOURCES_DIST) \
$(am__tx_deque_SOURCES_DIST) $(am__tx_dir_SOURCES_DIST) \
$(am__tx_intdiff_SOURCES_DIST) $(am__tx_list_SOURCES_DIST) \
@@ -774,7 +780,7 @@ libHX_la_SOURCES = deque.c dl.c format.c io.c map.c mc.c misc.c opt.c \
proc.c rand.c socket.c string.c time.c $(am__append_3)
libHX_la_LIBADD = ${libdl_LIBS} -lm ${libpthread_LIBS} ${librt_LIBS} \
$(am__append_4)
-libHX_la_LDFLAGS = -no-undefined -version-info 35:0:3 $(am__append_2)
+libHX_la_LDFLAGS = -no-undefined -version-info 36:0:4 $(am__append_2)
EXTRA_libHX_la_DEPENDENCIES = libHX.map
libHX_rtcheck_la_SOURCES = rtcheck.c
libHX_rtcheck_la_LIBADD = ${libdl_LIBS}
@@ -799,6 +805,7 @@ tc_proc_LDADD = libHX.la
tc_rand_LDADD = libHX.la
tc_realpath_LDADD = libHX.la
tc_shconfig_LDADD = libHX.la
+tc_socket_LDADD = libHX.la
tc_strchr2_LDADD = libHX.la
tc_string_LDADD = libHX.la
tc_strquote_LDADD = libHX.la
@@ -987,6 +994,10 @@ tc-shconfig$(EXEEXT): $(tc_shconfig_OBJECTS) $(tc_shconfig_DEPENDENCIES) $(EXTRA
@rm -f tc-shconfig$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tc_shconfig_OBJECTS) $(tc_shconfig_LDADD) $(LIBS)
+tc-socket$(EXEEXT): $(tc_socket_OBJECTS) $(tc_socket_DEPENDENCIES) $(EXTRA_tc_socket_DEPENDENCIES)
+ @rm -f tc-socket$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(tc_socket_OBJECTS) $(tc_socket_LDADD) $(LIBS)
+
tc-strchr2$(EXEEXT): $(tc_strchr2_OBJECTS) $(tc_strchr2_DEPENDENCIES) $(EXTRA_tc_strchr2_DEPENDENCIES)
@rm -f tc-strchr2$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(tc_strchr2_OBJECTS) $(tc_strchr2_LDADD) $(LIBS)
@@ -1105,6 +1116,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-rand.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-realpath.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-shconfig.Po@am__quote@ # am--include-marker
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-socket.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-strchr2.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-string.Po@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-strquote.Po@am__quote@ # am--include-marker
@@ -1427,6 +1439,13 @@ recheck: all $(check_PROGRAMS)
am__force_recheck=am--force-recheck \
TEST_LOGS="$$log_list"; \
exit $$?
+tc-format.log: tc-format$(EXEEXT)
+ @p='tc-format$(EXEEXT)'; \
+ b='tc-format'; \
+ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+ --log-file $$b.log --trs-file $$b.trs \
+ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+ "$$tst" $(AM_TESTS_FD_REDIRECT)
tc-strchr2.log: tc-strchr2$(EXEEXT)
@p='tc-strchr2$(EXEEXT)'; \
b='tc-strchr2'; \
@@ -1580,6 +1599,7 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/tc-rand.Po
-rm -f ./$(DEPDIR)/tc-realpath.Po
-rm -f ./$(DEPDIR)/tc-shconfig.Po
+ -rm -f ./$(DEPDIR)/tc-socket.Po
-rm -f ./$(DEPDIR)/tc-strchr2.Po
-rm -f ./$(DEPDIR)/tc-string.Po
-rm -f ./$(DEPDIR)/tc-strquote.Po
@@ -1679,6 +1699,7 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/tc-rand.Po
-rm -f ./$(DEPDIR)/tc-realpath.Po
-rm -f ./$(DEPDIR)/tc-shconfig.Po
+ -rm -f ./$(DEPDIR)/tc-socket.Po
-rm -f ./$(DEPDIR)/tc-strchr2.Po
-rm -f ./$(DEPDIR)/tc-string.Po
-rm -f ./$(DEPDIR)/tc-strquote.Po
diff --git a/src/format.c b/src/format.c
index b691dc7..25c09d6 100644
--- a/src/format.c
+++ b/src/format.c
@@ -16,6 +16,12 @@
#include <unistd.h>
#include <libHX.h>
#include "internal.h"
+#undef HXformat_aprintf
+#undef HXformat_fprintf
+#undef HXformat_sprintf
+extern int HXformat_aprintf(const struct HXformat_map *, hxmc_t **, const char *);
+extern int HXformat_sprintf(const struct HXformat_map *, char *, size_t, const char *);
+extern int HXformat_fprintf(const struct HXformat_map *, FILE *, const char *);
/* To make it easier on the highlighter */
#define C_OPEN '('
@@ -97,6 +103,7 @@ static void *func_entry_clone(const void *data, size_t size)
static const struct HXmap_ops func_entry_ops = {
.d_clone = func_entry_clone,
+ .d_free = free,
};
EXPORT_SYMBOL void HXformat_free(struct HXformat_map *blk)
@@ -297,7 +304,6 @@ static hxmc_t *HXformat2_snl(int argc, const hxmc_t *const *argv,
static hxmc_t *HXformat2_substr(int argc, const hxmc_t *const *argv,
const struct HXformat_map *blk)
{
- ssize_t offset, length, z;
hxmc_t *ret;
char *end;
@@ -306,44 +312,27 @@ static hxmc_t *HXformat2_substr(int argc, const hxmc_t *const *argv,
return &HXformat2_nexp;
}
- offset = strtoll(argv[1], &end, 0);
+ long w = LONG_MAX, v = strtol(argv[1], &end, 0);
if (*end != '\0') {
fprintf(stderr, "HXformat2-substr: found garbage in "
"offset specification\n");
return &HXformat2_nexp;
}
-
- z = strlen(argv[0]);
- if (offset < 0)
- offset = z + offset;
- if (offset >= z)
- return &HXformat2_nexp;
-
- if (argc == 2) {
- if (offset < 0)
- offset = 0;
- length = z - offset;
- } else {
- length = strtoll(argv[2], &end, 0);
+ if (argc >= 3) {
+ w = strtol(argv[2], &end, 0);
if (*end != '\0') {
fprintf(stderr, "HXformat2-substr; found garbage in "
"length specification\n");
return &HXformat2_nexp;
}
- if (length < 0)
- length/*end*/ = z + length;
- else
- length/*end*/ = offset + length;
- if (offset < 0)
- offset = 0;
}
- if (length <= 0)
+ size_t start = 0, tocopy = HX_substr_helper(strlen(argv[0]), v, w, &start);
+ if (tocopy == 0)
return &HXformat2_nexp;
-
- ret = HXmc_meminit(NULL, length);
+ ret = HXmc_meminit(NULL, tocopy);
if (ret == NULL)
return &HXformat2_nexp;
- if (HXmc_memcpy(&ret, &argv[0][offset], length) == NULL) {
+ if (HXmc_memcpy(&ret, &argv[0][start], tocopy) == NULL) {
HXmc_free(ret);
return &HXformat2_nexp;
}
@@ -643,6 +632,13 @@ EXPORT_SYMBOL struct HXformat_map *HXformat_init(void)
EXPORT_SYMBOL int HXformat_aprintf(const struct HXformat_map *blk,
hxmc_t **resultp, const char *fmt)
{
+ ssize_t ret = HXformat3_aprintf(blk, resultp, fmt);
+ return ret > INT_MAX ? INT_MAX : ret;
+}
+
+EXPORT_SYMBOL ssize_t HXformat3_aprintf(const struct HXformat_map *blk,
+ hxmc_t **resultp, const char *fmt)
+{
hxmc_t *ex, *ts, *out;
const char *current;
int ret = 0;
@@ -679,7 +675,8 @@ EXPORT_SYMBOL int HXformat_aprintf(const struct HXformat_map *blk,
}
*resultp = out;
- return HXmc_length(out);
+ size_t xl = HXmc_length(out);
+ return xl > SSIZE_MAX ? SSIZE_MAX : xl;
out:
ret = -errno;
@@ -690,10 +687,17 @@ EXPORT_SYMBOL int HXformat_aprintf(const struct HXformat_map *blk,
EXPORT_SYMBOL int HXformat_fprintf(const struct HXformat_map *ftable,
FILE *filp, const char *fmt)
{
+ ssize_t ret = HXformat3_fprintf(ftable, filp, fmt);
+ return ret > INT_MAX ? INT_MAX : ret;
+}
+
+EXPORT_SYMBOL ssize_t HXformat3_fprintf(const struct HXformat_map *ftable,
+ FILE *filp, const char *fmt)
+{
hxmc_t *str;
- int ret;
+ ssize_t ret;
- if ((ret = HXformat_aprintf(ftable, &str, fmt)) <= 0)
+ if ((ret = HXformat3_aprintf(ftable, &str, fmt)) <= 0)
return ret;
errno = 0;
if (fputs(str, filp) < 0)
@@ -705,8 +709,15 @@ EXPORT_SYMBOL int HXformat_fprintf(const struct HXformat_map *ftable,
EXPORT_SYMBOL int HXformat_sprintf(const struct HXformat_map *ftable,
char *dest, size_t size, const char *fmt)
{
+ ssize_t ret = HXformat3_sprintf(ftable, dest, size, fmt);
+ return ret > INT_MAX ? INT_MAX : ret;
+}
+
+EXPORT_SYMBOL ssize_t HXformat3_sprintf(const struct HXformat_map *ftable,
+ char *dest, size_t size, const char *fmt)
+{
hxmc_t *str;
- int ret;
+ ssize_t ret;
if ((ret = HXformat_aprintf(ftable, &str, fmt)) < 0)
return ret;
@@ -715,7 +726,7 @@ EXPORT_SYMBOL int HXformat_sprintf(const struct HXformat_map *ftable,
return 0;
}
strncpy(dest, str, size);
- ret = HXmc_length(dest);
+ size_t xl = strlen(dest);
HXmc_free(str);
- return ret;
+ return xl > SSIZE_MAX ? SSIZE_MAX : xl;
}
diff --git a/src/internal.h b/src/internal.h
index ec60817..0465d81 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -10,6 +10,7 @@
#define LIBHX_INTERNAL_H 1
#include "config.h"
+#include <stdint.h>
#include <libHX/defs.h>
#include <libHX/string.h>
@@ -56,5 +57,6 @@ struct timespec;
struct timeval;
extern hxmc_t *HXparse_dequote_fmt(const char *, const char *, const char **);
+extern size_t HX_substr_helper(size_t, long, long, size_t *);
#endif /* LIBHX_INTERNAL_H */
diff --git a/src/io.c b/src/io.c
index c797193..720a9c5 100644
--- a/src/io.c
+++ b/src/io.c
@@ -57,22 +57,23 @@ struct HXdir {
static int mkdir_gen(const char *d, unsigned int mode)
{
struct stat sb;
- if (lstat(d, &sb) < 0) {
#if defined(_WIN32)
- if (mkdir(d) < 0)
+ if (mkdir(d) == 0)
#else
- if (mkdir(d, mode) < 0) /* use umask() for permissions */
+ if (mkdir(d, mode) == 0) /* use umask() for permissions */
#endif
- return -errno;
- } else {
+ return 1;
+ if (errno != EEXIST)
+ return -errno;
+ if (lstat(d, &sb) == 0) {
#if defined(_WIN32)
- if ((sb.st_mode & S_IFDIR) != S_IFDIR)
+ if (sb.st_mode & S_IFDIR)
#else
- if (!S_ISDIR(sb.st_mode))
+ if (S_ISDIR(sb.st_mode))
#endif
- return -errno;
+ return 0;
}
- return 1;
+ return -EEXIST;
}
EXPORT_SYMBOL struct HXdir *HXdir_open(const char *s)
@@ -204,6 +205,8 @@ EXPORT_SYMBOL int HX_copy_file(const char *src, const char *dest,
unlink(dest);
close(dstfd);
close(srcfd);
+ free(buf);
+ va_end(argp);
return -(errno = saved_errno);
}
uid = sb.st_uid;
@@ -216,6 +219,8 @@ EXPORT_SYMBOL int HX_copy_file(const char *src, const char *dest,
unlink(dest);
close(dstfd);
close(srcfd);
+ free(buf);
+ va_end(argp);
return -(errno = saved_errno);
}
va_end(argp);
@@ -229,6 +234,7 @@ EXPORT_SYMBOL int HX_copy_file(const char *src, const char *dest,
int saved_errno = errno;
close(srcfd);
close(dstfd);
+ free(buf);
return -(errno = saved_errno);
}
}
@@ -264,8 +270,8 @@ EXPORT_SYMBOL int HX_copy_dir(const char *src, const char *dest,
continue;
snprintf(fsrc, MAXFNLEN, "%s/%s", src, fn);
snprintf(fdest, MAXFNLEN, "%s/%s", dest, fn);
-
- lstat(fsrc, &sb);
+ if (lstat(fsrc, &sb) < 0)
+ continue;
sb.st_mode &= 0777; /* clear SUID/GUID/Sticky bits */
if (S_ISREG(sb.st_mode)) {
@@ -278,17 +284,20 @@ EXPORT_SYMBOL int HX_copy_dir(const char *src, const char *dest,
memset(pt, '\0', MAXFNLEN);
if (readlink(fsrc, pt, MAXFNLEN - 1) < MAXFNLEN - 1)
if (symlink(pt, fdest) < 0)
- {};
+ /* ignore */;
} else if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
- mknod(fdest, sb.st_mode, sb.st_dev);
+ if (mknod(fdest, sb.st_mode, sb.st_dev) < 0)
+ /* ignore */;
} else if (S_ISFIFO(sb.st_mode)) {
- mkfifo(fdest, sb.st_mode);
+ if (mkfifo(fdest, sb.st_mode) < 0)
+ /* ignore */;
}
if (lchown(fdest, uid, gid) < 0)
- {};
+ /* ignore */;
if (!S_ISLNK(sb.st_mode))
- chmod(fdest, sb.st_mode);
+ if (chmod(fdest, sb.st_mode) < 0)
+ /* ignore */;
}
HXdir_close(dt);
@@ -321,12 +330,12 @@ EXPORT_SYMBOL int HX_mkdir(const char *idir, unsigned int mode)
if (dir[i] == '/') {
strncpy(buf, dir, i);
buf[i] = '\0';
- if ((v = mkdir_gen(buf, mode)) <= 0)
+ if ((v = mkdir_gen(buf, mode)) < 0)
return v;
} else if (i == len - 1) {
strncpy(buf, dir, len);
buf[len] = '\0';
- if ((v = mkdir_gen(buf, mode)) <= 0)
+ if ((v = mkdir_gen(buf, mode)) < 0)
return v;
}
}
@@ -358,7 +367,8 @@ EXPORT_SYMBOL int HX_readlink(hxmc_t **target, const char *path)
return -(errno = saved_errno);
}
if (static_cast(size_t, ret) < linkbuf_size) {
- HXmc_setlen(target, ret);
+ (*target)[ret] = '\0'; // please cov-scan
+ HXmc_setlen(target, ret); // \0 set here anyway
return ret;
}
linkbuf_size *= 2;
@@ -500,7 +510,7 @@ EXPORT_SYMBOL int HX_realpath(hxmc_t **dest_pptr, const char *path,
ret = HX_realpath_symres(&state, path);
if (ret == -EINVAL)
continue;
- else if (ret < 0)
+ else if (ret <= 0)
goto out;
path = state.path;
}
@@ -668,6 +678,7 @@ static ssize_t HX_sendfile_rw(int dst, int src, size_t count)
xferd += ret;
count -= ret;
}
+ free(buf);
if (xferd > 0)
return xferd;
if (ret < 0)
diff --git a/src/libHX.map b/src/libHX.map
index 085b74f..c4cef55 100644
--- a/src/libHX.map
+++ b/src/libHX.map
@@ -150,3 +150,12 @@ global:
HX_unit_seconds;
HX_strtoull_sec;
} LIBHX_4.2;
+
+LIBHX_4.9 {
+global:
+ HXformat3_aprintf;
+ HXformat3_fprintf;
+ HXformat3_sprintf;
+ HX_ipaddr_is_local;
+ HX_sockaddr_is_local;
+} LIBHX_4.3;
diff --git a/src/map.c b/src/map.c
index a90a731..40f376c 100644
--- a/src/map.c
+++ b/src/map.c
@@ -1304,11 +1304,12 @@ static struct HXrbnode *HXrbtrav_rewalk(struct HXrbtrav *trav)
trav->current = trav->path[--trav->depth];
if (trav->current == NULL)
fprintf(stderr, "btrav_rewalk: problem: current==NULL\n");
- HXrbtrav_checkpoint(trav, trav->current);
+ else
+ HXrbtrav_checkpoint(trav, trav->current);
}
trav->tid = btree->tid;
- if (go_next)
+ if (trav->current != nullptr && go_next)
return HXrbtrav_next(trav);
else
return trav->current;
diff --git a/src/mc.c b/src/mc.c
index d16dcbb..8bf1d95 100644
--- a/src/mc.c
+++ b/src/mc.c
@@ -8,6 +8,7 @@
* either version 2.1 or (at your option) any later version.
*/
#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -20,10 +21,12 @@ static __inline__ size_t __HXmc_request(size_t len)
return sizeof(struct memcont) + len + 1;
}
-static __inline__ void HXmc_check(const struct memcont *c)
+static __inline__ int HXmc_check(const struct memcont *c)
{
- if (c->id != HXMC_IDENT)
+ int err = c->id != HXMC_IDENT;
+ if (err != 0)
fprintf(stderr, "libHX-mc error: not a hxmc object!\n");
+ return err;
}
static __inline__ struct memcont *HXmc_base(const hxmc_t *p)
@@ -61,7 +64,8 @@ EXPORT_SYMBOL hxmc_t *HXmc_memcpy(hxmc_t **vp, const void *ptr, size_t len)
struct memcont *ctx;
if (*vp != NULL) {
ctx = HXmc_base(*vp);
- HXmc_check(ctx);
+ if (HXmc_check(ctx) != 0)
+ return nullptr;
if (ctx->alloc < len) {
ctx = realloc(ctx, __HXmc_request(len));
if (ctx == NULL)
@@ -96,7 +100,8 @@ EXPORT_SYMBOL size_t HXmc_length(const hxmc_t *vp)
if (vp == NULL)
return 0;
ctx = HXmc_base(vp);
- HXmc_check(ctx);
+ if (HXmc_check(ctx) != 0)
+ return SIZE_MAX;
return ctx->length;
}
@@ -115,7 +120,8 @@ EXPORT_SYMBOL hxmc_t *HXmc_trunc(hxmc_t **vp, size_t len)
{
struct memcont *ctx = HXmc_base(*vp);
- HXmc_check(ctx);
+ if (HXmc_check(ctx) != 0)
+ return nullptr;
if (len > ctx->alloc) {
ctx = realloc(ctx, __HXmc_request(len));
if (ctx == NULL)
@@ -141,7 +147,8 @@ EXPORT_SYMBOL hxmc_t *HXmc_memcat(hxmc_t **vp, const void *ptr, size_t len)
struct memcont *ctx = HXmc_base(*vp);
size_t nl = ctx->length + len;
- HXmc_check(ctx);
+ if (HXmc_check(ctx) != 0)
+ return nullptr;
if (nl > ctx->alloc) {
ctx = realloc(ctx, __HXmc_request(nl));
if (ctx == NULL)
@@ -191,7 +198,8 @@ EXPORT_SYMBOL hxmc_t *HXmc_memins(hxmc_t **vp, size_t pos, const void *ptr,
struct memcont *ctx = HXmc_base(*vp);
size_t nl = ctx->length + len;
- HXmc_check(ctx);
+ if (HXmc_check(ctx) != 0)
+ return nullptr;
if (ctx->alloc < nl) {
ctx = realloc(ctx, __HXmc_request(nl));
if (ctx == NULL)
@@ -212,8 +220,8 @@ EXPORT_SYMBOL hxmc_t *HXmc_memins(hxmc_t **vp, size_t pos, const void *ptr,
EXPORT_SYMBOL hxmc_t *HXmc_memdel(hxmc_t *vp, size_t pos, size_t len)
{
struct memcont *ctx = HXmc_base(vp);
- HXmc_check(ctx);
-
+ if (HXmc_check(ctx) != 0)
+ return nullptr;
if (pos + len > ctx->length)
len = ctx->length - pos;
@@ -230,7 +238,8 @@ EXPORT_SYMBOL void HXmc_free(hxmc_t *vp)
if (vp == NULL)
return;
ctx = HXmc_base(vp);
- HXmc_check(ctx);
+ if (HXmc_check(ctx) != 0)
+ return;
free(ctx);
}
diff --git a/src/opt.c b/src/opt.c
index fe2bff3..f91785d 100644
--- a/src/opt.c
+++ b/src/opt.c
@@ -547,8 +547,12 @@ static int HX_getopt_long(const char *cur, struct HX_getopt_vars *par)
key = HX_strdup(cur);
if (key == NULL)
return -errno;
-
value = strchr(key, '=');
+ if (value == nullptr) {
+ /* Cannot happen because state is always !S_TWOLONG */
+ free(key);
+ return -EINVAL;
+ }
*value++ = '\0';
par->cbi.current = lookup_long_pfx(par->cbi.table, key + 2);
if (par->cbi.current == &HXopt_ambig_prefix) {
@@ -699,14 +703,16 @@ EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
struct HX_getopt_vars ps;
const char **opt = *argv;
int state = HXOPT_S_NORMAL;
- int ret = HXOPT_ERR_SUCCESS;
+ int ret = -ENOMEM;
unsigned int argk;
const char *cur;
memset(&ps, 0, sizeof(ps));
ps.remaining = HXdeque_init();
- if (ps.remaining == NULL)
+ if (ps.remaining == NULL) {
+ ret = -errno;
goto out;
+ }
ps.flags = flags;
ps.arg0 = **argv;
ps.cbi.table = table;
@@ -714,17 +720,19 @@ EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
if (*opt != NULL) {
/* put argv[0] back */
char *arg = HX_strdup(*opt++);
- if (arg == NULL)
- goto out_errno;
+ if (arg == NULL) {
+ ret = -errno;
+ goto out;
+ }
if (HXdeque_push(ps.remaining, arg) == NULL) {
free(arg);
- goto out_errno;
+ ret = -errno;
+ goto out;
}
}
if (posix_me_harder())
ps.flags |= HXOPT_RQ_ORDER;
-
for (cur = *opt; cur != NULL; ) {
if (state == HXOPT_S_TWOLONG)
state = HX_getopt_twolong(opt, &ps);
@@ -739,11 +747,11 @@ EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
if (state < 0) {
ret = state;
- break;
+ goto out;
}
if (state & HXOPT_I_ERROR) {
ret = state & ~HXOPT_I_ERROR;
- break;
+ goto out;
}
if (state & HXOPT_I_ASSIGN)
do_assign(&ps.cbi, ps.arg0);
@@ -756,13 +764,13 @@ EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
state &= ~HXOPT_I_MASK;
}
- out:
- if (ret == HXOPT_ERR_SUCCESS) {
- if (!(ps.flags & HXOPT_KEEP_ARGV)) {
+ if (!(ps.flags & HXOPT_KEEP_ARGV)) {
const char **nvec = reinterpret_cast(const char **,
HXdeque_to_vec(ps.remaining, &argk));
- if (nvec == NULL)
- goto out_errno;
+ if (nvec == NULL) {
+ ret = -errno;
+ goto out;
+ }
if (ps.flags & HXOPT_DESTROY_OLD)
/*
* Only the "true, original" argv is stored on the
@@ -780,7 +788,11 @@ EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
/* pointers are owned by nvec/argv now */
HXdeque_free(ps.remaining);
ps.remaining = nullptr;
- }
+ }
+ ret = HXOPT_ERR_SUCCESS;
+
+ out:
+ if (ret == HXOPT_ERR_SUCCESS) {
} else if (ret < 0) {
if (!(ps.flags & HXOPT_QUIET))
fprintf(stderr, "%s: %s\n", __func__, strerror(errno));
@@ -794,10 +806,6 @@ EXPORT_SYMBOL int HX_getopt(const struct HXoption *table, int *argc,
if (ps.remaining != nullptr)
HXdeque_genocide2(ps.remaining, free);
return ret;
-
- out_errno:
- ret = -errno;
- goto out;
}
EXPORT_SYMBOL void HX_getopt_help(const struct HXoptcb *cbi, FILE *nfp)
diff --git a/src/socket.c b/src/socket.c
index 45f4053..ced884a 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -17,8 +17,19 @@
#ifdef _WIN32
# include <ws2tcpip.h>
#else
-# include <sys/socket.h>
# include <netdb.h>
+# include <unistd.h>
+# include <netinet/in.h>
+# include <sys/socket.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif
+#ifdef __linux__
+# include <linux/rtnetlink.h>
+#endif
+#ifdef __OpenBSD__
+# include <net/route.h>
#endif
#include <libHX/proc.h>
#include <libHX/socket.h>
@@ -31,6 +42,9 @@
#if defined(__sunos__) && !defined(SO_PROTOCOL)
# define SO_PROTOCOL SO_PROTOTYPE
#endif
+#ifndef AI_V4MAPPED
+# define AI_V4MAPPED 0
+#endif
static int try_sk_from_env(int fd, const struct addrinfo *ai, const char *intf)
{
@@ -122,3 +136,170 @@ EXPORT_SYMBOL int HX_socket_from_env(const struct addrinfo *ai, const char *intf
errno = ENOENT;
return -1;
}
+
+#ifdef __linux__
+static int linux_sockaddr_local3(int sk, const void *buf, size_t bufsize)
+{
+ if (send(sk, buf, bufsize, 0) < 0)
+ return -errno;
+ char rsp[4096];
+ ssize_t ret = recv(sk, rsp, sizeof(rsp), 0);
+ if (ret < 0)
+ return -errno;
+ else if (static_cast(size_t, ret) < sizeof(struct nlmsghdr))
+ return -EIO;
+ struct nlmsghdr nlh;
+ memcpy(&nlh, rsp, sizeof(nlh));
+ if (!NLMSG_OK(&nlh, ret))
+ return -EIO;
+ const struct rtmsg *rtm = static_cast(void *, rsp + NLMSG_HDRLEN);
+ return rtm->rtm_type == RTN_LOCAL;
+}
+
+static int linux_sockaddr_local2(const struct sockaddr *sa, socklen_t sl)
+{
+ int sk = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
+ if (sk < 0)
+ return -errno;
+ struct {
+ struct nlmsghdr nh;
+ struct rtmsg rth;
+ char attrbuf[4096];
+ } req;
+ memset(&req, 0, sizeof(req));
+ req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.rth));
+ req.nh.nlmsg_flags = NLM_F_REQUEST;
+ req.nh.nlmsg_type = RTM_GETROUTE;
+ req.rth.rtm_family = sa->sa_family;
+ req.rth.rtm_protocol = RTPROT_UNSPEC;
+ req.rth.rtm_type = RTN_UNSPEC;
+ req.rth.rtm_scope = RT_SCOPE_UNIVERSE;
+ req.rth.rtm_table = RT_TABLE_UNSPEC;
+ struct rtattr *rta = reinterpret_cast(struct rtattr *,
+ reinterpret_cast(char *, &req) + NLMSG_ALIGN(req.nh.nlmsg_len));
+ rta->rta_type = RTA_DST;
+
+ int ret = -ENODATA;
+ if (sa->sa_family == AF_INET6) {
+ const struct in6_addr *ad = &reinterpret_cast(const struct sockaddr_in6 *, sa)->sin6_addr;
+ req.rth.rtm_dst_len = 16;
+ rta->rta_len = RTA_LENGTH(16);
+ req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + rta->rta_len;
+ memcpy(RTA_DATA(rta), ad, 16);
+ } else if (sa->sa_family == AF_INET) {
+ struct in_addr ad = reinterpret_cast(const struct sockaddr_in *, sa)->sin_addr;
+ req.rth.rtm_dst_len = 4;
+ rta->rta_len = RTA_LENGTH(4);
+ req.nh.nlmsg_len = NLMSG_ALIGN(req.nh.nlmsg_len) + rta->rta_len;
+ memcpy(RTA_DATA(rta), &ad, 4);
+ }
+ ret = linux_sockaddr_local3(sk, &req, req.nh.nlmsg_len);
+ close(sk);
+ return ret;
+}
+#endif
+
+#ifdef __OpenBSD__
+static int openbsd_sockaddr_local3(int rsk, const void *buf, size_t bufsize)
+{
+ ssize_t ret = send(rsk, buf, bufsize, 0);
+ if (ret < 0)
+ return -errno;
+ else if (ret != bufsize)
+ return -EIO;
+ struct rt_msghdr rsp;
+ do {
+ ret = recv(rsk, &rsp, sizeof(rsp), 0);
+ } while (ret > 0 && (rsp.rtm_version != RTM_VERSION ||
+ rsp.rtm_seq != 1 || rsp.rtm_pid != getpid()));
+ return rsp.rtm_flags & RTF_LOCAL;
+}
+
+static int openbsd_sockaddr_local2(const struct sockaddr *sa, socklen_t sl)
+{
+ int sk = socket(AF_ROUTE, SOCK_RAW, AF_UNSPEC);
+ if (sk < 0)
+ return -errno;
+ struct {
+ struct rt_msghdr rtm;
+ char ab[512];
+ } req;
+ memset(&req, 0, sizeof(req));
+ req.rtm.rtm_type = RTM_GET;
+ req.rtm.rtm_version = RTM_VERSION;
+ req.rtm.rtm_flags = RTF_STATIC | RTF_UP | RTF_HOST | RTF_GATEWAY;
+ req.rtm.rtm_seq = 1;
+ req.rtm.rtm_addrs = /*RTA_IFP |*/ RTA_DST;
+ req.rtm.rtm_tableid = getrtable();
+ req.rtm.rtm_hdrlen = sizeof(req.rtm);
+ memcpy(req.ab, sa, sl);
+ req.rtm.rtm_msglen = sizeof(req.rtm) + sl;
+ int ret = openbsd_sockaddr_local3(sk, &req, req.rtm.rtm_msglen);
+ close(sk);
+ return ret;
+}
+#endif
+
+EXPORT_SYMBOL int HX_sockaddr_is_local(const struct sockaddr *sa, socklen_t sl,
+ unsigned int flags)
+{
+ struct sockaddr_in xl = {};
+
+ if (sa->sa_family == AF_INET6) {
+ if (sl < sizeof(struct sockaddr_in6))
+ return -EINVAL;
+ } else if (sa->sa_family == AF_INET) {
+ if (sl < sizeof(struct sockaddr_in))
+ return -EINVAL;
+ }
+#ifdef HAVE_SYS_UN_H
+ else if (sa->sa_family == AF_UNIX) {
+ if (sl < sizeof(struct sockaddr_un))
+ return 1;
+ }
+#endif
+ else {
+ return -EPROTONOSUPPORT;
+ }
+ if (flags & AI_V4MAPPED && sa->sa_family == AF_INET6) {
+ /*
+ * Preprocess mapped addresses, becuase kernel interfaces do
+ * not support them.
+ */
+ const struct in6_addr *ad = &reinterpret_cast(const struct sockaddr_in6 *, sa)->sin6_addr;
+ static const uint8_t mappedv4[] = {0,0,0,0, 0,0,0,0, 0,0,0xff,0xff};
+ if (memcmp(ad, mappedv4, 12) == 0) {
+ xl.sin_family = AF_INET;
+ memcpy(&xl.sin_addr, &ad->s6_addr[12], 4);
+ sa = reinterpret_cast(struct sockaddr *, &xl);
+ sl = sizeof(xl);
+ }
+ }
+#if defined(__linux__)
+ return linux_sockaddr_local2(sa, sl);
+#elif defined(__OpenBSD__)
+ return openbsd_sockaddr_local2(sa, sl);
+#else
+ if (sa->sa_family == AF_INET) {
+ struct in_addr a = reinterpret_cast(const struct sockaddr_in *, sa)->sin_addr;
+ return ntohl(a.s_addr) >> 24 == 127;
+ } else if (sa->sa_family == AF_INET6) {
+ return IN6_IS_ADDR_LOOPBACK(&reinterpret_cast(const struct sockaddr_in6 *, sa)->sin6_addr);
+ }
+#endif
+ return -EPROTONOSUPPORT;
+}
+
+EXPORT_SYMBOL int HX_ipaddr_is_local(const char *addr, unsigned int flags)
+{
+ struct addrinfo hints = {.ai_flags = flags & AI_V4MAPPED};
+ struct addrinfo *r = nullptr;
+ int err = getaddrinfo(addr, nullptr, &hints, &r);
+ if (err != 0) {
+ freeaddrinfo(r);
+ return 0;
+ }
+ int lcl = HX_sockaddr_is_local(r->ai_addr, r->ai_addrlen, hints.ai_flags);
+ freeaddrinfo(r);
+ return lcl;
+}
diff --git a/src/string.c b/src/string.c
index c14f1b5..ae19271 100644
--- a/src/string.c
+++ b/src/string.c
@@ -27,6 +27,7 @@
* all others pass through
*/
enum HX_quote_selector {
+ HXQUOTE_ALWAYS,
HXQUOTE_ACCEPT,
HXQUOTE_REJECT,
};
@@ -211,6 +212,8 @@ EXPORT_SYMBOL char **HX_split(const char *str, const char *delim,
*cp = max;
ret = malloc(sizeof(char *) * (*cp + 1));
+ if (ret == nullptr)
+ return nullptr;
ret[*cp] = NULL;
{
@@ -378,20 +381,48 @@ EXPORT_SYMBOL char *HX_stpltrim(const char *p)
return const_cast1(char *, p);
}
+/**
+ * Helper for substr() function for dealing with negative off/len values
+ * @z: total length of string
+ * @offset: n>=0 specifies offset from the start,
+ * n<0 specifies offset from the end
+ * @len: "length"; n>=0 specifies length to copy (from @offset),
+ * n<0 specifies the byte relative to the end at which to stop
+ *
+ * @abstart: (result) absolute start
+ * @retval: (result) absolute length to copy (from *@abstart)
+ */
+size_t HX_substr_helper(size_t z, long offset, long len, size_t *start)
+{
+ if (offset >= 0)
+ *start = offset;
+ else if (offset == LONG_MIN)
+ *start = z + -static_cast(size_t, LONG_MIN);
+ else
+ *start = z >= static_cast(unsigned long, -offset) ? z + offset : z;
+
+ size_t end;
+ if (len >= 0)
+ end = *start < SIZE_MAX - len ? *start + len : SIZE_MAX;
+ else if (len == LONG_MIN)
+ end = z + -static_cast(unsigned long, LONG_MIN);
+ else
+ end = z >= static_cast(unsigned long, -len) ? z + len : 0;
+ if (end > z)
+ end = z;
+ return end > *start ? end - *start : 0;
+}
+
/* supports negative offsets like scripting languages */
EXPORT_SYMBOL char *HX_strmid(const char *expr, long offset, long length)
{
- char *buffer;
-
- if (offset < 0)
- offset = strlen(expr) + offset;
- if (length < 0)
- length = strlen(expr) - offset + length;
- if ((buffer = malloc(length + 1)) == NULL)
+ size_t start = 0, tocopy = HX_substr_helper(strlen(expr), offset, length, &start);
+ char *buffer = malloc(tocopy + 1);
+ if (buffer == nullptr)
return NULL;
-
- expr += offset;
- return HX_strlcpy(buffer, expr, length + 1);
+ memcpy(buffer, &expr[start], tocopy);
+ buffer[tocopy] = '\0';
+ return buffer;
}
EXPORT_SYMBOL char *HX_strndup(const char *src, size_t size)
@@ -773,7 +804,7 @@ static size_t HX_quoted_size(const char *s, unsigned int type)
EXPORT_SYMBOL char *HX_strquote(const char *src, unsigned int type,
char **free_me)
{
- const struct HX_quote_rule *rule;
+ const struct HX_quote_rule *rule = nullptr;
bool do_quote;
char *tmp;
@@ -782,15 +813,19 @@ EXPORT_SYMBOL char *HX_strquote(const char *src, unsigned int type,
return NULL;
}
/* If quote_chars is NULL, it is clear all chars are to be encoded. */
- rule = &HX_quote_rules[type];
- if (type >= ARRAY_SIZE(HX_quote_rules) || rule->chars == NULL)
+ if (type >= ARRAY_SIZE(HX_quote_rules)) {
do_quote = true;
- else if (rule->selector == HXQUOTE_REJECT)
- do_quote = strpbrk(src, rule->chars) != NULL;
- else if (rule->selector == HXQUOTE_ACCEPT)
- do_quote = HX_strchr2(src, rule->chars) != NULL;
- else
- do_quote = false;
+ } else {
+ rule = &HX_quote_rules[type];
+ if (rule->selector == HXQUOTE_ALWAYS)
+ do_quote = true;
+ else if (rule->selector == HXQUOTE_REJECT)
+ do_quote = strpbrk(src, rule->chars) != NULL;
+ else if (rule->selector == HXQUOTE_ACCEPT)
+ do_quote = HX_strchr2(src, rule->chars) != NULL;
+ else
+ do_quote = false;
+ }
/*
* free_me == NULL implies that we always allocate, even if
* there is nothing to quote.
diff --git a/src/tc-cast.c b/src/tc-cast.c
index 422054c..2c58805 100644
--- a/src/tc-cast.c
+++ b/src/tc-cast.c
@@ -1,11 +1,4 @@
-/*
- * Testing for compile error in the cast helpers
- * written by Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#include <math.h>
#include <stdint.h>
#include <stdio.h>
diff --git a/src/tc-dir.c b/src/tc-dir.c
index d2e3885..12cbacd 100644
--- a/src/tc-dir.c
+++ b/src/tc-dir.c
@@ -1,10 +1,4 @@
-/*
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#ifndef __cplusplus
# include <stdio.h>
# include <stdlib.h>
diff --git a/src/tc-format.c b/src/tc-format.c
index ad067ee..ed8e6d4 100644
--- a/src/tc-format.c
+++ b/src/tc-format.c
@@ -1,11 +1,4 @@
-/*
- * formatter test program
- * Copyright by Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -55,7 +48,7 @@ static const char *const fmt2_strings[] = {
NULL,
};
-static void t_format(int argc)
+static int t_format(int argc)
{
struct HXformat_map *fmt = HXformat_init();
const char *const *s;
@@ -70,9 +63,14 @@ static void t_format(int argc)
HXformat_add(fmt, "TWOARG", "a, b", HXTYPE_STRING | HXFORMAT_IMMED);
++argc;
printf("# HXformat2\n");
- for (s = fmt2_strings; *s != NULL; ++s)
- HXformat_fprintf(fmt, stdout, *s);
+ for (s = fmt2_strings; *s != NULL; ++s) {
+ char buf[80];
+ if (HXformat_sprintf(fmt, buf, ARRAY_SIZE(buf), *s) < 0 ||
+ HXformat_fprintf(fmt, stdout, *s) < 0)
+ return EXIT_FAILURE;
+ }
HXformat_free(fmt);
+ return EXIT_SUCCESS;
}
int main(int argc, const char **argv)
@@ -84,7 +82,7 @@ int main(int argc, const char **argv)
fprintf(stderr, "HX_init: %s\n", strerror(-ret));
return EXIT_FAILURE;
}
- t_format(argc);
+ ret = t_format(argc);
HX_exit();
- return EXIT_SUCCESS;
+ return ret;
}
diff --git a/src/tc-io.c b/src/tc-io.c
index 1e95e65..639ebcc 100644
--- a/src/tc-io.c
+++ b/src/tc-io.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
diff --git a/src/tc-list.c b/src/tc-list.c
index 751f462..e0087e3 100644
--- a/src/tc-list.c
+++ b/src/tc-list.c
@@ -1,10 +1,4 @@
-/*
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#ifdef __cplusplus
# include <cstdio>
# include <cstdlib>
diff --git a/src/tc-list2.c b/src/tc-list2.c
index f41861b..d70ada2 100644
--- a/src/tc-list2.c
+++ b/src/tc-list2.c
@@ -1,10 +1,4 @@
-/*
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#include <stdio.h>
#include <stdlib.h>
#include <libHX/list.h>
diff --git a/src/tc-map.c b/src/tc-map.c
index ce55688..0037c83 100644
--- a/src/tc-map.c
+++ b/src/tc-map.c
@@ -1,11 +1,4 @@
-/*
- * Test for libHX's maps
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#include "config.h"
#include <errno.h>
#include <math.h>
diff --git a/src/tc-memmem.c b/src/tc-memmem.c
index 3b62ef1..a4f272e 100644
--- a/src/tc-memmem.c
+++ b/src/tc-memmem.c
@@ -1,10 +1,6 @@
+// SPDX-License-Identifier: MIT
/*
* speed test HX_memmem
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
*/
#include <stdio.h>
#include <stdlib.h>
diff --git a/src/tc-misc.c b/src/tc-misc.c
index cb985a3..5b043d4 100644
--- a/src/tc-misc.c
+++ b/src/tc-misc.c
@@ -1,10 +1,4 @@
-/*
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#ifndef __cplusplus
# include <stdlib.h>
#else
@@ -38,7 +32,8 @@ int main(int argc, const char **argv)
if (stat(argv[1], &sa) < 0 ||
stat(argv[2], &sb) < 0)
perror("stat");
- printf("Difference: %ld\n", HX_time_compare(&sa, &sb, 'm'));
+ else
+ printf("Difference: %ld\n", HX_time_compare(&sa, &sb, 'm'));
}
HX_exit();
diff --git a/src/tc-netio.c b/src/tc-netio.c
index 45a6efc..5d3c22e 100644
--- a/src/tc-netio.c
+++ b/src/tc-netio.c
@@ -1,10 +1,4 @@
-/*
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#define WIN32_LEAN_AND_MEAN 1
#ifdef __cplusplus
# include <cstdlib>
diff --git a/src/tc-option.c b/src/tc-option.c
index aa6f12c..db3d3f4 100644
--- a/src/tc-option.c
+++ b/src/tc-option.c
@@ -1,10 +1,7 @@
+// SPDX-License-Identifier: MIT
+// SPDX-FileCopyrightText: 2022 Jan Engelhardt
/*
* option parser test program
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
*/
#include <errno.h>
#include <stdio.h>
diff --git a/src/tc-proc.c b/src/tc-proc.c
index 904c450..19c8b18 100644
--- a/src/tc-proc.c
+++ b/src/tc-proc.c
@@ -1,10 +1,4 @@
-/*
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#ifdef __cplusplus
# include <cerrno>
# include <cstdio>
diff --git a/src/tc-rand.c b/src/tc-rand.c
index 3af45d0..149f18e 100644
--- a/src/tc-rand.c
+++ b/src/tc-rand.c
@@ -1,10 +1,4 @@
-/*
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
diff --git a/src/tc-realpath.c b/src/tc-realpath.c
index c2ef15a..23609ca 100644
--- a/src/tc-realpath.c
+++ b/src/tc-realpath.c
@@ -1,10 +1,6 @@
+// SPDX-License-Identifier: MIT
/*
* Test utility for libHX's realpath
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
*/
#include <stdbool.h>
#include <stdio.h>
diff --git a/src/tc-shconfig.c b/src/tc-shconfig.c
index 8a31c45..556f90f 100644
--- a/src/tc-shconfig.c
+++ b/src/tc-shconfig.c
@@ -1,13 +1,9 @@
/*
A=b;C="d" ; E="F;" ; F= G=Z
*/
+// SPDX-License-Identifier: MIT
/*
* shconfig test program
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
*/
#include <errno.h>
#include <stdio.h>
diff --git a/src/tc-socket.c b/src/tc-socket.c
new file mode 100644
index 0000000..9c73d24
--- /dev/null
+++ b/src/tc-socket.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: MIT
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libHX/defs.h>
+#include <libHX/socket.h>
+#ifndef _WIN32
+# include <netdb.h>
+#endif
+#ifndef AI_V4MAPPED
+# define AI_V4MAPPED 0
+#endif
+
+int main(void)
+{
+ static const char *addrs[] = {
+ "::1", "::2", "::ffff:127.0.0.1", "::",
+ "127.0.0.1", "127.0.0.2", "1.1.1.1", "255.255.255.255",
+ };
+ for (size_t i = 0; i < ARRAY_SIZE(addrs); ++i) {
+ printf("%-16s\t", addrs[i]);
+ int lcl = HX_ipaddr_is_local(addrs[i], AI_V4MAPPED);
+ if (lcl < 0) {
+ printf("%s\n", strerror(-lcl));
+ return EXIT_FAILURE;
+ }
+ printf("%d\n", lcl);
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/src/tc-strchr2.c b/src/tc-strchr2.c
index 6e0eaad..ad37f37 100644
--- a/src/tc-strchr2.c
+++ b/src/tc-strchr2.c
@@ -1,10 +1,6 @@
+// SPDX-License-Identifier: MIT
/*
* Behavior Correctness Test for HX_strchr2
- * Copyright Jan Engelhardt, 2013
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
*/
#include <libHX/string.h>
diff --git a/src/tc-string.c b/src/tc-string.c
index db242a3..77235c2 100644
--- a/src/tc-string.c
+++ b/src/tc-string.c
@@ -1,11 +1,5 @@
/* long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing long line for testing */
-/*
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#ifndef __cplusplus
# include <assert.h>
# include <errno.h>
@@ -480,6 +474,35 @@ static void t_time_strto(void)
}
}
+static int t_strmid(void)
+{
+#define T(spar,opar,lpar,xpar) do { \
+ char *s = HX_strmid((spar), (opar), (lpar)); \
+ if (s == nullptr) \
+ return EXIT_FAILURE; \
+ int ret = strcmp(s, (xpar)); \
+ if (ret != 0) { \
+ fprintf(stderr, "Faillure: substr %s,%d,%d = %s\n", \
+ (spar), static_cast(int, (opar)), static_cast(int, (lpar)), s); \
+ free(s); \
+ return ret; \
+ } \
+ free(s); \
+ } while (false)
+
+ T("Hello World", -12, 5, "");
+ T("bark", -3, -1, "ar");
+ T("cake", -3, -3, "");
+ T("cake", -3, -4, "");
+ T("fun", 0, 0, "");
+ T("bark", 0, 1, "b");
+ T("bark", 0, 5, "bark");
+ T("bark", -4, 1, "b");
+ T("bark", -4, 5, "bark");
+ return EXIT_SUCCESS;
+#undef T
+}
+
int main(int argc, const char **argv)
{
hxmc_t *tx = NULL;
@@ -488,6 +511,9 @@ int main(int argc, const char **argv)
if (HX_init() <= 0)
abort();
+ int ret = t_strmid();
+ if (ret != EXIT_SUCCESS)
+ return EXIT_FAILURE;
fp = fopen(file, "r");
if (fp == NULL) {
diff --git a/src/tc-strquote.c b/src/tc-strquote.c
index fab305e..ef357d1 100644
--- a/src/tc-strquote.c
+++ b/src/tc-strquote.c
@@ -1,10 +1,6 @@
+// SPDX-License-Identifier: MIT
/*
* Behavior Correctness Test for HX_strquote
- * Copyright Jan Engelhardt, 2013
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
*/
#include <stdbool.h>
#include <stdio.h>
diff --git a/src/tc-switchuser.c b/src/tc-switchuser.c
index 3bb3fe9..1763527 100644
--- a/src/tc-switchuser.c
+++ b/src/tc-switchuser.c
@@ -1,14 +1,7 @@
-/*
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-#if defined(HAVE_INITGROUPS)
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -17,6 +10,7 @@
#include <libHX/defs.h>
#include <libHX/option.h>
#include <libHX/proc.h>
+#if defined(HAVE_INITGROUPS)
static char *user_name, *group_name;
static const struct HXoption options_table[] = {
@@ -70,4 +64,9 @@ int main(int argc, const char **argv)
}
return EXIT_SUCCESS;
}
+#else
+int main(void)
+{
+ return EXIT_SUCCESS;
+}
#endif
diff --git a/src/tc-time.c b/src/tc-time.c
index e86ed67..5097cde 100644
--- a/src/tc-time.c
+++ b/src/tc-time.c
@@ -1,10 +1,4 @@
-/*
- * Copyright Jan Engelhardt, 2012
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#include <assert.h>
#include <math.h>
#include <stdio.h>
@@ -27,7 +21,7 @@ static const int NANOSECOND = 1000000000;
static const long long NANOSECOND_LL = 1000000000;
static const unsigned int clock_id = CLOCK_THREAD_CPUTIME_ID;
static const unsigned int step = 1000;
-static const unsigned int step_mul = 10000000;
+static const long step_mul = 10000000;
static const struct timespec pairs[] = {
{-1, 700000000}, {-1, 400000000}, {-1, 0},
diff --git a/src/tc-xml.c b/src/tc-xml.c
index 07cf3b3..49b24ad 100644
--- a/src/tc-xml.c
+++ b/src/tc-xml.c
@@ -1,10 +1,4 @@
-/*
- * Copyright Jan Engelhardt
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the WTF Public License version 2 or
- * (at your option) any later version.
- */
+// SPDX-License-Identifier: MIT
#include <stdbool.h>
#include <stdio.h>
#include <libxml/parser.h>