diff options
author | Rob Landley <rob@landley.net> | 2014-12-04 21:41:12 -0600 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2014-12-04 21:41:12 -0600 |
commit | 2fb85a3588bf2271e0506c5ab3bcb6a84bf77255 (patch) | |
tree | 8a82f407f321ed1ea18779430af81272989c6fa7 | |
parent | 0a7915624ea4d3a629879e6a6fd79f432ffde016 (diff) | |
download | toybox-2fb85a3588bf2271e0506c5ab3bcb6a84bf77255.tar.gz |
Implement xstrncat() and fix xstrndup().
-rw-r--r-- | lib/lib.h | 1 | ||||
-rw-r--r-- | lib/xwrap.c | 21 |
2 files changed, 18 insertions, 4 deletions
@@ -81,6 +81,7 @@ void show_help(void); // xwrap.c void xstrncpy(char *dest, char *src, size_t size); +void xstrncat(char *dest, char *src, size_t size); void xexit(void) noreturn; void *xmalloc(size_t size); void *xzalloc(size_t size); diff --git a/lib/xwrap.c b/lib/xwrap.c index a2dd1c69..96db3522 100644 --- a/lib/xwrap.c +++ b/lib/xwrap.c @@ -9,13 +9,25 @@ #include "toys.h" -// Strcpy with size checking: exit if there's not enough space for the string. +// strcpy and strncat with size checking. Size is the total space in "dest", +// including null terminator. Exit if there's not enough space for the string +// (including space for the null terminator), because silently truncating is +// still broken behavior. (And leaving the string unterminated is INSANE.) void xstrncpy(char *dest, char *src, size_t size) { if (strlen(src)+1 > size) error_exit("'%s' > %ld bytes", src, (long)size); strcpy(dest, src); } +void xstrncat(char *dest, char *src, size_t size) +{ + long len = strlen(src); + + if (len+strlen(dest)+1 > size) + error_exit("'%s%s' > %ld bytes", src, (long)size); + strcpy(dest+len, src); +} + void xexit(void) { if (toys.rebound) longjmp(*toys.rebound, 1); @@ -52,9 +64,10 @@ void *xrealloc(void *ptr, size_t size) // Die unless we can allocate a copy of this many bytes of string. char *xstrndup(char *s, size_t n) { - char *ret = xmalloc(++n); - strncpy(ret, s, n); - ret[--n]=0; + char *ret = strndup(s, ++n); + + if (!ret) error_exit("xstrndup"); + ret[--n] = 0; return ret; } |