From 42b6b927c9b899b9cb82f7b576776b34c1a1bb03 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 15 Oct 2022 17:24:22 +0200 Subject: [PATCH] libc: Implement strlcpy(), and make strncpy() standard-compliant --- libs/libc/include/string.h | 17 ++++++++++------- libs/libc/src/string.cpp | 27 ++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/libs/libc/include/string.h b/libs/libc/include/string.h index 64d0eaf2..6dddf2f3 100644 --- a/libs/libc/include/string.h +++ b/libs/libc/include/string.h @@ -33,9 +33,8 @@ extern "C" /* Returns the length of the string str, while examining at most max bytes of str. */ size_t strnlen(const char* str, size_t max); - /* Copies the string src into dest. This function is unsafe, use strncpy instead. */ - __lc_deprecated("strcpy is unsafe and should not be used; use strncpy instead") char* strcpy(char* dest, - const char* src); + /* Copies at most size-1 bytes from the string src into dest, null-terminating the result. */ + size_t strlcpy(char* dst, const char* src, size_t size); /* Copies at most max bytes from the string src into dest. */ char* strncpy(char* dest, const char* src, size_t max); @@ -46,10 +45,6 @@ extern "C" /* Returns a pointer to the last occurrence of the character c in str, or NULL if it is not found. */ char* strrchr(const char* str, int c); - /* Concatenates the string src into dest. This function is unsafe, use strncat instead. */ - __lc_deprecated("strcat is unsafe and should not be used; use strncat instead") char* strcat(char* dest, - const char* src); - /* Concatenates at most max bytes of the string src into dest. */ char* strncat(char* dest, const char* src, size_t max); @@ -68,6 +63,14 @@ extern "C" /* Clears n bytes of buf. */ void* bzero(void* buf, size_t n); + /* Copies the string src into dest. This function is unsafe, use strlcpy instead. */ + __lc_deprecated("strcpy is unsafe and should not be used; use strlcpy instead") char* strcpy(char* dest, + const char* src); + + /* Concatenates the string src into dest. This function is unsafe, use strncat instead. */ + __lc_deprecated("strcat is unsafe and should not be used; use strncat instead") char* strcat(char* dest, + const char* src); + #ifdef __cplusplus } #endif diff --git a/libs/libc/src/string.cpp b/libs/libc/src/string.cpp index 958182d7..683168ff 100644 --- a/libs/libc/src/string.cpp +++ b/libs/libc/src/string.cpp @@ -70,15 +70,32 @@ extern "C" char* strcpy(char* dest, const char* src) { - memcpy(dest, src, strlen(src) + 1); + return (char*)memcpy(dest, src, strlen(src) + 1); + } + + char* strncpy(char* dest, const char* src, size_t max) + { + size_t i; + for (i = 0; i < max && src[i] != 0; i++) dest[i] = src[i]; + for (; i < max; i++) dest[i] = 0; return dest; } - char* strncpy(char* dest, const char* src, size_t max) // FIXME: Implement strncpy according to the specification. + size_t strlcpy(char* dest, const char* src, size_t size) { - size_t src_len = strlen(src) + 1; // NULL byte - memcpy(dest, src, src_len > max ? max : src_len); - return dest; + size_t len = strlen(src); + if (size == 0) return len; + if (len < (size - 1)) + { + memcpy(dest, src, len); + dest[len] = 0; + } + else + { + memcpy(dest, src, size - 1); + dest[size - 1] = 0; + } + return len; } int strcmp(const char* a, const char* b)