Permalink
Browse files

Move strlcat, strlcpy, and strnlen

Move strlcat() and strlcpy() from .c source files in to the libspl
string.h header.  By changing these compatibily functions to static
inlines they can included as needed without requiring linking with
the libspl.so library.

Remove strnlen() which is barely used in the source, and has been
provided by glibc since v2.10.

Finally, convert four instances of strnlen() to strlcpy() in
libzfs_input_check.c which were causing build warning when compiling
with gcc 8.2.1.  For example:

  libzfs_input_check.c: In function ‘zfs_destroy’:
  libzfs_input_check.c:651:9: error: ‘strncpy’ specified bound \
      4096 equals destination size [-Werror=stringop-truncation]
    (void) strncpy(zc.zc_name, dataset, sizeof (zc.zc_name));
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
  • Loading branch information...
behlendorf committed Nov 9, 2018
1 parent ad796b8 commit fc70fadb9d8aec8a642da41d1f422bd3a6407b9b
@@ -22,9 +22,6 @@ USER_C = \
list.c \
mkdirp.c \
page.c \
strlcat.c \
strlcpy.c \
strnlen.c \
timestamp.c \
zone.c \
include/sys/list.h \
@@ -28,9 +28,56 @@
#define _LIBSPL_STRING_H
#include_next <string.h>
#include <sys/types.h>
extern size_t strlcat(char *dst, const char *src, size_t dstsize);
extern size_t strlcpy(char *dst, const char *src, size_t len);
extern size_t strnlen(const char *str, size_t maxlen);
/*
* Appends src to the dstsize buffer at dst. The append will never
* overflow the destination buffer and the buffer will always be null
* terminated. Never reference beyond &dst[dstsize-1] when computing
* the length of the pre-existing string.
*/
static inline size_t
strlcat(char *dst, const char *src, size_t dstsize)
{
char *df = dst;
size_t left = dstsize;
size_t l1;
size_t l2 = strlen(src);
size_t copied;
while (left-- != 0 && *df != '\0')
df++;
l1 = df - dst;
if (dstsize == l1)
return (l1 + l2);
copied = l1 + l2 >= dstsize ? dstsize - l1 - 1 : l2;
(void) memcpy(dst + l1, src, copied);
dst[l1+copied] = '\0';
return (l1 + l2);
}
/*
* Copies src to the dstsize buffer at dst. The copy will never
* overflow the destination buffer and the buffer will always be null
* terminated.
*/
static inline size_t
strlcpy(char *dst, const char *src, size_t len)
{
size_t slen = strlen(src);
if (len == 0)
return (slen);
size_t copied = (slen >= len) ? len - 1 : slen;
(void) memcpy(dst, src, copied);
dst[copied] = '\0';
return (slen);
}
#endif

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.
@@ -147,7 +147,7 @@ lzc_ioctl_run(zfs_ioc_t ioc, const char *name, nvlist_t *innvl, int expected)
}
packed = fnvlist_pack(innvl, &size);
(void) strncpy(zc.zc_name, name, sizeof (zc.zc_name));
(void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
zc.zc_name[sizeof (zc.zc_name) - 1] = '\0';
zc.zc_nvlist_src = (uint64_t)(uintptr_t)packed;
zc.zc_nvlist_src_size = size;
@@ -234,7 +234,7 @@ lzc_ioctl_test(zfs_ioc_t ioc, const char *name, nvlist_t *required,
char pname[MAXNAMELEN];
data_type_t ptype;
strncpy(pname, nvpair_name(pair), sizeof (pname));
strlcpy(pname, nvpair_name(pair), sizeof (pname));
pname[sizeof (pname) - 1] = '\0';
ptype = nvpair_type(pair);
fnvlist_remove_nvpair(input, pair);
@@ -648,7 +648,7 @@ zfs_destroy(const char *dataset)
zfs_cmd_t zc = {"\0"};
int err;
(void) strncpy(zc.zc_name, dataset, sizeof (zc.zc_name));
(void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
zc.zc_name[sizeof (zc.zc_name) - 1] = '\0';
zc.zc_objset_type = DMU_OST_ZFS;
err = ioctl(zfs_fd, ZFS_IOC_DESTROY, &zc);
@@ -760,7 +760,7 @@ zfs_ioc_input_tests(const char *pool)
ioc_tested[ioc_skip[i] - ZFS_IOC_FIRST] = B_TRUE;
}
(void) strncpy(zc.zc_name, pool, sizeof (zc.zc_name));
(void) strlcpy(zc.zc_name, pool, sizeof (zc.zc_name));
zc.zc_name[sizeof (zc.zc_name) - 1] = '\0';
for (unsigned ioc = ZFS_IOC_FIRST; ioc < ZFS_IOC_LAST; ioc++) {

0 comments on commit fc70fad

Please sign in to comment.