From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: B Horn Date: Sat, 15 Jun 2024 02:33:08 +0100 Subject: [PATCH] misc: Implement grub_strlcpy() grub_strlcpy() acts the same way as strlcpy() does on most *NIX, returning the length of src and ensuring dest is always NUL terminated except when size is 0. Signed-off-by: B Horn Reviewed-by: Daniel Kiper --- include/grub/misc.h | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/include/grub/misc.h b/include/grub/misc.h index 981526644..0592aa68f 100644 --- a/include/grub/misc.h +++ b/include/grub/misc.h @@ -72,6 +72,45 @@ grub_stpcpy (char *dest, const char *src) return d - 1; } +static inline grub_size_t +grub_strlcpy (char *dest, const char *src, grub_size_t size) +{ + char *d = dest; + grub_size_t res = 0; + /* + * We do not subtract one from size here to avoid dealing with underflowing + * the value, which is why to_copy is always checked to be greater than one + * throughout this function. + */ + grub_size_t to_copy = size; + + /* Copy size - 1 bytes to dest. */ + if (to_copy > 1) + while ((*d++ = *src++) != '\0' && ++res && --to_copy > 1) + ; + + /* + * NUL terminate if size != 0. The previous step may have copied a NUL byte + * if it reached the end of the string, but we know dest[size - 1] must always + * be a NUL byte. + */ + if (size != 0) + dest[size - 1] = '\0'; + + /* If there is still space in dest, but are here, we reached the end of src. */ + if (to_copy > 1) + return res; + + /* + * If we haven't reached the end of the string, iterate through to determine + * the strings total length. + */ + while (*src++ != '\0' && ++res) + ; + + return res; +} + /* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ static inline void * grub_memcpy (void *dest, const void *src, grub_size_t n)