From 872a773fac1e2880428d82e9f589ff16a5fde727 Mon Sep 17 00:00:00 2001
From: Guilherme Janczak <guilherme.janczak@yandex.com>
Date: Fri, 6 May 2022 18:42:52 +0000
Subject: [PATCH] remove libbsd

libbsd is only used once and as part of a larger, incorrect function.
I rewrote the code that used it without the need for it.
---
 CMakeLists.txt               | 41 ++++++-----------------------
 Makefile.am                  | 12 ++++-----
 builds/cmake/platform.hpp.in |  2 --
 configure.ac                 | 39 +--------------------------
 packaging/debian/control     |  2 --
 packaging/debian/zeromq.dsc  |  2 +-
 packaging/redhat/zeromq.spec |  2 +-
 src/compat.hpp               | 51 +++++++++++++++++++++++-------------
 8 files changed, 50 insertions(+), 101 deletions(-)

--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -240,19 +240,6 @@ if(NOT ZMQ_USE_GNUTLS)
   endif()
 endif()
 
-if(NOT MSVC)
-  option(WITH_LIBBSD "Use libbsd instead of builtin strlcpy" ON)
-  if(WITH_LIBBSD)
-    pkg_check_modules(LIBBSD "libbsd")
-    if(LIBBSD_FOUND)
-      message(STATUS "Using libbsd")
-      set(pkg_config_names_private "${pkg_config_names_private} libbsd")
-      set(ZMQ_HAVE_LIBBSD 1)
-    endif()
-  endif()
-  check_cxx_symbol_exists(strlcpy string.h ZMQ_HAVE_STRLCPY)
-endif()
-
 # Select curve encryption library, defaults to tweetnacl To use libsodium instead, use --with-libsodium(must be
 # installed) To disable curve, use --disable-curve
 
@@ -1437,10 +1424,6 @@ if(BUILD_SHARED)
     target_link_libraries(libzmq ${NSS3_LIBRARIES})
   endif()
 
-  if(LIBBSD_FOUND)
-    target_link_libraries(libzmq ${LIBBSD_LIBRARIES})
-  endif()
-
   if(SODIUM_FOUND)
     target_link_libraries(libzmq ${SODIUM_LIBRARIES})
     # On Solaris, libsodium depends on libssp
@@ -1482,10 +1465,6 @@ if(BUILD_STATIC)
     target_link_libraries(libzmq-static ${GNUTLS_LIBRARIES})
   endif()
 
-  if(LIBBSD_FOUND)
-    target_link_libraries(libzmq-static ${LIBBSD_LIBRARIES})
-  endif()
-
   if(NSS3_FOUND)
     target_link_libraries(libzmq-static ${NSS3_LIBRARIES})
   endif()
@@ -1550,10 +1529,6 @@ if(BUILD_SHARED)
         target_link_libraries(${perf-tool} ${GNUTLS_LIBRARIES})
       endif()
 
-      if(LIBBSD_FOUND)
-        target_link_libraries(${perf-tool} ${LIBBSD_LIBRARIES})
-      endif()
-
       if(NSS3_FOUND)
         target_link_libraries(${perf-tool} ${NSS3_LIBRARIES})
       endif()
--- a/Makefile.am
+++ b/Makefile.am
@@ -351,11 +351,11 @@ if HAVE_VSCRIPT_COMPLEX
 src_libzmq_la_LDFLAGS += $(VSCRIPT_LDFLAGS),$(srcdir)/src/libzmq.vers
 endif
 
-src_libzmq_la_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) $(LIBUNWIND_CFLAGS) $(LIBBSD_CFLAGS)
-src_libzmq_la_CFLAGS = $(CODE_COVERAGE_CFLAGS) $(LIBUNWIND_CFLAGS) $(LIBBSD_CFLAGS)
+src_libzmq_la_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) $(LIBUNWIND_CFLAGS)
+src_libzmq_la_CFLAGS = $(CODE_COVERAGE_CFLAGS) $(LIBUNWIND_CFLAGS)
 src_libzmq_la_CXXFLAGS = @LIBZMQ_EXTRA_CXXFLAGS@ $(CODE_COVERAGE_CXXFLAGS) \
-	$(LIBUNWIND_CFLAGS) $(LIBBSD_CFLAGS)
-src_libzmq_la_LIBADD = $(CODE_COVERAGE_LDFLAGS) $(LIBUNWIND_LIBS) $(LIBBSD_LIBS)
+	$(LIBUNWIND_CFLAGS)
+src_libzmq_la_LIBADD = $(CODE_COVERAGE_LDFLAGS) $(LIBUNWIND_LIBS)
 
 if USE_NSS
 src_libzmq_la_CPPFLAGS += ${NSS3_CFLAGS}
@@ -849,10 +849,10 @@ tests_test_security_curve_SOURCES += \
 endif
 
 tests_test_security_curve_LDADD = \
-        ${TESTUTIL_LIBS} src/libzmq.la $(LIBUNWIND_LIBS) $(LIBBSD_LIBS)
+        ${TESTUTIL_LIBS} src/libzmq.la $(LIBUNWIND_LIBS)
 tests_test_security_curve_CPPFLAGS = \
         ${TESTUTIL_CPPFLAGS} \
-	${LIBUNWIND_CFLAGS}  ${LIBBSD_CFLAGS}
+	${LIBUNWIND_CFLAGS}
 
 if USE_LIBSODIUM
 tests_test_security_curve_CPPFLAGS += \
--- a/builds/cmake/platform.hpp.in
+++ b/builds/cmake/platform.hpp.in
@@ -52,8 +52,6 @@
 #cmakedefine ZMQ_HAVE_PTHREAD_SET_AFFINITY
 #cmakedefine HAVE_ACCEPT4
 #cmakedefine HAVE_STRNLEN
-#cmakedefine ZMQ_HAVE_STRLCPY
-#cmakedefine ZMQ_HAVE_LIBBSD
 
 #cmakedefine ZMQ_HAVE_IPC
 
--- a/configure.ac
+++ b/configure.ac
@@ -12,7 +12,7 @@ AC_CONFIG_AUX_DIR(config)
 AC_CONFIG_MACRO_DIR(config)
 AC_CONFIG_HEADERS([src/platform.hpp])
 AM_INIT_AUTOMAKE(foreign subdir-objects tar-ustar dist-zip)
-# Allow "configure --disable-maintainer-mode" to disable timestamp checking 
+# Allow "configure --disable-maintainer-mode" to disable timestamp checking
 AM_MAINTAINER_MODE([enable])
 
 m4_pattern_allow([AC_PROG_CC_C99])
@@ -806,43 +806,6 @@ AC_COMPILE_IFELSE(
     ],[
         AC_MSG_RESULT([no])
 ])
-
-AC_ARG_ENABLE([libbsd],
-    [AS_HELP_STRING([--enable-libbsd],
-        [enable libbsd [default=auto]])],
-    [enable_libbsd=$enableval],
-    [enable_libbsd="auto"])
-
-if test "x$enable_libbsd" != "xno"; then
-    PKG_CHECK_MODULES(LIBBSD, [libbsd],
-        [
-            AC_DEFINE(ZMQ_HAVE_LIBBSD, 1, [The libbsd library is to be used])
-            AC_SUBST([LIBBSD_CFLAGS])
-            AC_SUBST([LIBBSD_LIBS])
-            PKGCFG_NAMES_PRIVATE="$PKGCFG_NAMES_PRIVATE libbsd"
-            found_libbsd="yes"
-        ],
-        [
-            found_libbsd="no"
-            if test "x$enable_libbsd" = "xyes"; then
-                AC_MSG_ERROR([Cannot find libbsd])
-            else
-                AC_MSG_WARN([Cannot find libbsd])
-            fi
-        ])
-fi
-AC_MSG_CHECKING([whether strlcpy is available])
-AC_COMPILE_IFELSE(
-    [AC_LANG_PROGRAM(
-        [[#include <string.h>]],
-        [[char buf [100]; size_t bar = strlcpy (buf, "foo", 100); (void)bar; return 0;]])
-    ],[
-        AC_MSG_RESULT([yes])
-        AC_DEFINE(ZMQ_HAVE_STRLCPY, [1],
-            [strlcpy is available])
-    ],[
-        AC_MSG_RESULT([no])
-])
 
 # pthread_setname is non-posix, and there are at least 4 different implementations
 AC_MSG_CHECKING([whether signature of pthread_setname_np() has 1 argument])
--- a/src/compat.hpp
+++ b/src/compat.hpp
@@ -37,26 +37,41 @@
 #define strcasecmp _stricmp
 #define strtok_r strtok_s
 #else
-#ifndef ZMQ_HAVE_STRLCPY
-#ifdef ZMQ_HAVE_LIBBSD
-#include <bsd/string.h>
-#else
-static inline size_t
-strlcpy (char *dest_, const char *src_, const size_t dest_size_)
-{
-    size_t remain = dest_size_;
-    for (; remain && *src_; --remain, ++src_, ++dest_) {
-        *dest_ = *src_;
-    }
-    return dest_size_ - remain;
-}
-#endif
-#endif
+/*
+ * https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strcpy-s-wcscpy-s-mbscpy-s?view=msvc-170
+ */
 template <size_t size>
-static inline int strcpy_s (char (&dest_)[size], const char *const src_)
+static inline int strcpy_s (char (&dst)[size], const char *const src)
 {
-    const size_t res = strlcpy (dest_, src_, size);
-    return res >= size ? ERANGE : 0;
+    size_t i;
+
+    if (src == NULL) {
+        /*
+         * XXX:
+         * Microsoft's documentation is ambiguous.
+         *
+         * How does Microsoft handle size == 0 when src is NULL?
+         * Do they return ERANGE?
+         *
+         * How does Microsoft handle size == 0 when src is non-NULL?
+         * Do they write a '\0' to *dst anyway?
+         */
+        if (size > 0)
+            *dst = '\0';
+        return (errno = EINVAL);
+    }
+
+    for (i = 0;; i++) {
+        if (i >= size) {
+            if (size > 0)
+                *dst = '\0';
+            return (errno = ERANGE);
+        }
+        dst[i] = src[i];
+        if (src[i] == '\0')
+            return 0;
+    }
+    /* NOTREACHED */
 }
 #endif
 
