From 33abc8bcd96fcc77684ba31e7eaf3d6cac09c293 Mon Sep 17 00:00:00 2001 From: Alejandro Colomar Date: Sat, 29 Jul 2023 17:21:24 +0200 Subject: [PATCH] strlcpy.h: Add STRLCPY() macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It wraps strlcpy(3bsd) so that it performs some steps that one might forget, or might be prone to accidents: - It calculates the size of the destination buffer, and makes sure it's an array (otherwise, using sizeof(dst) would be very bad). - It calculates if there's truncation, returning an easy-to-use value. BTW, this macro doesn't have any issues of double evaluation, because sizeof() doesn't evaluate its argument (unless it's a VLA, but then the static_assert(3) within SIZEOF_ARRAY() makes sure VLAs are not allowed). Cc: Christian Göttsche Cc: Serge Hallyn Cc: Iker Pedrosa Signed-off-by: Alejandro Colomar --- lib/Makefile.am | 1 + lib/strlcpy.h | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 lib/strlcpy.h diff --git a/lib/Makefile.am b/lib/Makefile.am index 79e00085..083b2277 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -140,6 +140,7 @@ libshadow_la_SOURCES = \ stpecpy.h \ stpeprintf.c \ stpeprintf.h \ + strlcpy.h \ strtoday.c \ sub.c \ subordinateio.h \ diff --git a/lib/strlcpy.h b/lib/strlcpy.h new file mode 100644 index 00000000..5ef9b8a7 --- /dev/null +++ b/lib/strlcpy.h @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2023, Alejandro Colomar + * SPDX-License-Identifier: BSD-3-Clause + */ + + +#ifndef SHADOW_INCLUDE_LIB_STRLCPY_H_ +#define SHADOW_INCLUDE_LIB_STRLCPY_H_ + + +#include + +#include +#include + +#include "sizeof.h" + + +/* + * SYNOPSIS + * int STRLCPY(char dst[restrict], const char *restrict src); + * + * ARGUMENTS + * dst Destination buffer where to copy a string. + * src Source string to be copied into dst. + * + * DESCRIPTION + * This macro copies the string pointed to by src, into a string + * at the buffer pointed to by dst. If the destination buffer, + * isn't large enough to hold the copy, the resulting string is + * truncated. The size of the buffer is calculated internally via + * SIZEOF_ARRAY(). + * + * RETURN VALUE + * -1 If this call truncated the resulting string. + * + * strlen(dst) + * On success. + * + * ERRORS + * This function doesn't set errno. + */ + + +#define STRLCPY(dst, src) \ +({ \ + size_t sz_, len_; \ + \ + sz_ = SIZEOF_ARRAY(dst); \ + len_ = strlcpy(dst, src, sz_); \ + \ + (len_ >= sz_) ? -1 : len_; \ +}) + + +#endif // include guard