diff --git a/src/basic/strxcpyx.c b/src/basic/strxcpyx.c index aaf11d21f6b..c6fbe79647c 100644 --- a/src/basic/strxcpyx.c +++ b/src/basic/strxcpyx.c @@ -19,8 +19,13 @@ /* * Concatenates/copies strings. In any case, terminates in all cases - * with '\0' * and moves the @dest pointer forward to the added '\0'. - * Returns the * remaining size, and 0 if the string was truncated. + * with '\0' and moves the @dest pointer forward to the added '\0'. + * Returns the remaining size, and 0 if the string was truncated. + * + * Due to the intended usage, these helpers silently noop invocations + * having zero size. This is technically an exception to the above + * statement "terminates in all cases". It's unexpected for such calls to + * occur outside of a loop where this is the preferred behavior. */ #include @@ -32,6 +37,12 @@ size_t strpcpy(char **dest, size_t size, const char *src) { size_t len; + assert(dest); + assert(src); + + if (size == 0) + return 0; + len = strlen(src); if (len >= size) { if (size > 1) @@ -51,23 +62,30 @@ size_t strpcpyf(char **dest, size_t size, const char *src, ...) { va_list va; int i; + assert(dest); + assert(src); + + if (size == 0) + return 0; + va_start(va, src); i = vsnprintf(*dest, size, src, va); if (i < (int)size) { *dest += i; size -= i; } else { - *dest += size; size = 0; } va_end(va); - *dest[0] = '\0'; return size; } size_t strpcpyl(char **dest, size_t size, const char *src, ...) { va_list va; + assert(dest); + assert(src); + va_start(va, src); do { size = strpcpy(dest, size, src); @@ -80,6 +98,9 @@ size_t strpcpyl(char **dest, size_t size, const char *src, ...) { size_t strscpy(char *dest, size_t size, const char *src) { char *s; + assert(dest); + assert(src); + s = dest; return strpcpy(&s, size, src); } @@ -88,6 +109,9 @@ size_t strscpyl(char *dest, size_t size, const char *src, ...) { va_list va; char *s; + assert(dest); + assert(src); + va_start(va, src); s = dest; do { diff --git a/src/test/test-strxcpyx.c b/src/test/test-strxcpyx.c index 9bea7701314..d95945f6b01 100644 --- a/src/test/test-strxcpyx.c +++ b/src/test/test-strxcpyx.c @@ -51,6 +51,13 @@ static void test_strpcpyf(void) { assert_se(streq(target, "space left: 25. foobar")); assert_se(space_left == 3); + + /* test overflow */ + s = target; + space_left = strpcpyf(&s, 12, "00 left: %i. ", 999); + assert_se(streq(target, "00 left: 99")); + assert_se(space_left == 0); + assert_se(target[12] == '2'); } static void test_strpcpyl(void) {