From 848189f10a98768b372186de8b9fe013ad49d4e5 Mon Sep 17 00:00:00 2001 From: Omar Polo Date: Thu, 6 Jun 2024 13:43:12 +0000 Subject: [PATCH] attempt to deal with the portability fiasco of strnvis(3) --- configure | 9 +++++++++ ge.c | 2 +- gmid.c | 2 +- gmid.h | 1 + have/broken-strnvis.c | 15 +++++++++++++++ utils.c | 17 +++++++++++++++++ 6 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 have/broken-strnvis.c diff --git a/configure b/configure index d44a5f6..f58b605 100755 --- a/configure +++ b/configure @@ -275,6 +275,7 @@ fi HAVE_ENDIAN_H=0 HAVE_SYS_ENDIAN_H=0 HAVE_MACHINE_ENDIAN=0 +HAVE_BROKEN_STRNVIS=0 runtest endian_h ENDIAN_H || \ runtest sys_endian_h SYS_ENDIAN_H || \ @@ -317,6 +318,12 @@ runtest tree_h TREE_H || true runtest vasprintf VASPRINTF -D_GNU_SOURCE || true runtest vis VIS -DLIBBSD_OPENBSD_VIS || true +if [ ${HAVE_VIS} -eq 1 ]; then + if singletest broken-strnvis BROKEN_STRNVIS "-Wall -Werror"; then + HAVE_BROKEN_STRNVIS=1 + fi +fi + if [ ${HAVE_ARC4RANDOM} -eq 1 -a ${HAVE_ARC4RANDOM_BUF} -eq 0 ]; then COMPATS="compat/arc4random.c ${COMPATS}" fi @@ -648,6 +655,8 @@ cat <<__HEREDOC__ # define HOST_NAME_MAX 255 # endif #endif + +#define HAVE_BROKEN_STRNVIS ${HAVE_BROKEN_STRNVIS} __HEREDOC__ echo "file config.h: written" 1>&2 diff --git a/ge.c b/ge.c index 2bd3991..0296dba 100644 --- a/ge.c +++ b/ge.c @@ -83,7 +83,7 @@ log_request(struct client *c, int code, const char *meta) strlcpy(cntmp, subj + 4, sizeof(cntmp)); if ((n = strchr(cntmp, '/')) != NULL) *n = '\0'; - strnvis(cn, cntmp, sizeof(cn), VIS_WHITE|VIS_DQ); + gmid_strnvis(cn, cntmp, sizeof(cn), VIS_WHITE|VIS_DQ); } } diff --git a/gmid.c b/gmid.c index 408b184..f050193 100644 --- a/gmid.c +++ b/gmid.c @@ -140,7 +140,7 @@ log_request(struct client *c, int code, const char *meta) strlcpy(cntmp, subj + 4, sizeof(cntmp)); if ((n = strchr(cntmp, '/')) != NULL) *n = '\0'; - strnvis(cn, cntmp, sizeof(cn), VIS_WHITE|VIS_DQ); + gmid_strnvis(cn, cntmp, sizeof(cn), VIS_WHITE|VIS_DQ); } } diff --git a/gmid.h b/gmid.h index 21d793c..4546e3a 100644 --- a/gmid.h +++ b/gmid.h @@ -469,5 +469,6 @@ EVP_PKEY *ssl_load_pkey(const uint8_t *, size_t); struct vhost *new_vhost(void); struct location *new_location(void); struct proxy *new_proxy(void); +int gmid_strnvis(char *, const char *, size_t, int); #endif diff --git a/have/broken-strnvis.c b/have/broken-strnvis.c new file mode 100644 index 0000000..f2a9a59 --- /dev/null +++ b/have/broken-strnvis.c @@ -0,0 +1,15 @@ +/* + * public domain + */ + +#include +#include +#include + +int +main(void) +{ + char buf[128]; + + return strnvis(buf, sizeof(buf), "Hello, world!\n", 0); +} diff --git a/utils.c b/utils.c index 7ceea2e..bbb6b11 100644 --- a/utils.c +++ b/utils.c @@ -22,6 +22,7 @@ #include #include +#include /* for gmid_strnvis() */ #include #include @@ -496,3 +497,19 @@ new_proxy(void) p->protocols = TLS_PROTOCOLS_DEFAULT; return p; } + +/* + * I can't rant enough about this situation. As far as I've understood, + * OpenBSD introduced strnvis(3) with a signature, then NetBSD did it but + * with a incompatible signature. FreeBSD followed NetBSD. libbsd followed + * OpenBSD but now is thinking to switch. WTF? + */ +int +gmid_strnvis(char *dst, const char *src, size_t destsize, int flag) +{ +#if HAVE_BROKEN_STRNVIS + return strnvis(dst, destsize, src, flag); +#else + return strnvis(dst, src, destsize, flag); +#endif +}