blob: 0ede8a8328d6caa3851a1abdb73470610adbda6b [file] [log] [blame]
Andrew Geissler635e0e42020-08-21 15:58:33 -05001From 1c5023002bad3a5b0bbc181fdb324160beace733 Mon Sep 17 00:00:00 2001
Andrew Geissler82c905d2020-04-13 13:39:40 -05002From: Joshua Watt <JPEWhacker@gmail.com>
3Date: Tue, 19 Nov 2019 12:47:30 -0600
Andrew Geissler635e0e42020-08-21 15:58:33 -05004Subject: [PATCH] stdlib: Add strlcat
Andrew Geissler82c905d2020-04-13 13:39:40 -05005
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>
Andrew Geissler635e0e42020-08-21 15:58:33 -050010
Andrew Geissler82c905d2020-04-13 13:39:40 -050011---
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
Andrew Geissler635e0e42020-08-21 15:58:33 -050020index bfae1f8..156dc4c 100644
Andrew Geissler82c905d2020-04-13 13:39:40 -050021--- a/Makefile.in
22+++ b/Makefile.in
Andrew Geissler635e0e42020-08-21 15:58:33 -050023@@ -101,7 +101,7 @@ NASM = asm/nasm.$(O)
Andrew Geissler82c905d2020-04-13 13:39:40 -050024 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) \
Andrew Geissler635e0e42020-08-21 15:58:33 -050031 nasmlib/alloc.$(O) nasmlib/asprintf.$(O) nasmlib/errfile.$(O) \
Andrew Geissler82c905d2020-04-13 13:39:40 -050032diff --git a/configure.ac b/configure.ac
Andrew Geissler635e0e42020-08-21 15:58:33 -050033index 7b72769..14fd033 100644
Andrew Geissler82c905d2020-04-13 13:39:40 -050034--- a/configure.ac
35+++ b/configure.ac
Andrew Geissler635e0e42020-08-21 15:58:33 -050036@@ -234,6 +234,7 @@ PA_FUNC_SNPRINTF
37 PA_FUNC_VSNPRINTF
Andrew Geissler82c905d2020-04-13 13:39:40 -050038 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])
Andrew Geissler635e0e42020-08-21 15:58:33 -050044@@ -253,6 +254,7 @@ AC_CHECK_DECLS(strsep)
Andrew Geissler82c905d2020-04-13 13:39:40 -050045 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
Andrew Geissler635e0e42020-08-21 15:58:33 -050053index b4fd3a8..7fb4821 100644
Andrew Geissler82c905d2020-04-13 13:39:40 -050054--- a/include/compiler.h
55+++ b/include/compiler.h
Andrew Geissler635e0e42020-08-21 15:58:33 -050056@@ -169,6 +169,10 @@ size_t strlcpy(char *, const char *, size_t);
Andrew Geissler82c905d2020-04-13 13:39:40 -050057 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
Andrew Geissler635e0e42020-08-21 15:58:33 -050069index 0000000..7084d46
Andrew Geissler82c905d2020-04-13 13:39:40 -050070--- /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+