diff options
| -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;  } | 
