1From 1c5023002bad3a5b0bbc181fdb324160beace733 Mon Sep 17 00:00:00 2001 2From: Joshua Watt <JPEWhacker@gmail.com> 3Date: Tue, 19 Nov 2019 12:47:30 -0600 4Subject: [PATCH] stdlib: Add strlcat 5 6Adds strlcat which can be used to safely concatenate strings 7 8Upstream-Status: Submitted [https://bugzilla.nasm.us/show_bug.cgi?id=3392635] 9Signed-off-by: Joshua Watt <JPEWhacker@gmail.com> 10 11--- 12 Makefile.in | 2 +- 13 configure.ac | 2 ++ 14 include/compiler.h | 4 ++++ 15 stdlib/strlcat.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 16 4 files changed, 50 insertions(+), 1 deletion(-) 17 create mode 100644 stdlib/strlcat.c 18 19diff --git a/Makefile.in b/Makefile.in 20index bfae1f8..156dc4c 100644 21--- a/Makefile.in 22+++ b/Makefile.in 23@@ -101,7 +101,7 @@ NASM = asm/nasm.$(O) 24 NDISASM = disasm/ndisasm.$(O) 25 26 LIBOBJ = stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \ 27- stdlib/strnlen.$(O) stdlib/strrchrnul.$(O) \ 28+ stdlib/strnlen.$(O) stdlib/strrchrnul.$(O) stdlib/strlcat.$(O) \ 29 \ 30 nasmlib/ver.$(O) \ 31 nasmlib/alloc.$(O) nasmlib/asprintf.$(O) nasmlib/errfile.$(O) \ 32diff --git a/configure.ac b/configure.ac 33index 7b72769..14fd033 100644 34--- a/configure.ac 35+++ b/configure.ac 36@@ -234,6 +234,7 @@ PA_FUNC_SNPRINTF 37 PA_FUNC_VSNPRINTF 38 AC_CHECK_FUNCS([strlcpy]) 39 AC_CHECK_FUNCS([strrchrnul]) 40+AC_CHECK_FUNCS([strlcat]) 41 42 dnl These types are POSIX-specific, and Windows does it differently... 43 AC_CHECK_TYPES([struct _stati64]) 44@@ -253,6 +254,7 @@ AC_CHECK_DECLS(strsep) 45 AC_CHECK_DECLS(strlcpy) 46 AC_CHECK_DECLS(strnlen) 47 AC_CHECK_DECLS(strrchrnul) 48+AC_CHECK_DECLS(strlcat) 49 50 dnl Check for missing types 51 AC_TYPE_UINTPTR_T 52diff --git a/include/compiler.h b/include/compiler.h 53index b4fd3a8..7fb4821 100644 54--- a/include/compiler.h 55+++ b/include/compiler.h 56@@ -169,6 +169,10 @@ size_t strlcpy(char *, const char *, size_t); 57 char *strrchrnul(const char *, int); 58 #endif 59 60+#if !defined(HAVE_STRLCAT) || !HAVE_DECL_STRLCAT 61+size_t strlcat(char *, const char *, size_t); 62+#endif 63+ 64 #ifndef __cplusplus /* C++ has false, true, bool as keywords */ 65 # ifdef HAVE_STDBOOL_H 66 # include <stdbool.h> 67diff --git a/stdlib/strlcat.c b/stdlib/strlcat.c 68new file mode 100644 69index 0000000..7084d46 70--- /dev/null 71+++ b/stdlib/strlcat.c 72@@ -0,0 +1,43 @@ 73+/* 74+ * Copyright (c) 2019 Garmin Ltd. or its subsidiaries 75+ * 76+ * Permission to use, copy, modify, and distribute this software for any 77+ * purpose with or without fee is hereby granted, provided that the above 78+ * copyright notice and this permission notice appear in all copies. 79+ * 80+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 81+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 82+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 83+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 84+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 85+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 86+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 87+ */ 88+ 89+#include "compiler.h" 90+ 91+/* 92+ * Concatenate src string to dest of size size. The destination buffer will 93+ * have no more than size-1 character when the operation finishes. Always NUL 94+ * terminates, unless size == 0 or dest has no NUL terminator. Returns 95+ * strlen(initial dest) + strlen(src); if retval >= size, truncation occurred. 96+ */ 97+#ifndef HAVE_STRLCAT 98+ 99+size_t strlcat(char *dest, const char *src, size_t size) 100+{ 101+ size_t n; 102+ 103+ /* find the NULL terminator in dest */ 104+ for (n = 0; i < size && dest[n] != '\0'; n++) 105+ ; 106+ 107+ /* destination was not NULL terminated. Return the initial size */ 108+ if (n == size) 109+ return size; 110+ 111+ return strlcpy(&dest[n], src, size - n) + n; 112+} 113+ 114+#endif 115+ 116