platform/netlink: cleanup nla_strlcpy()

- let nla_strlcpy() return how many bytes we would like to have
  copied. That way, the caller could detect string truncation.
  In practice, no caller cared about that.

- the code before would also fill the entire buffer with zeros first,
  like strncpy(). We still do that. However, only copy the bytes up
  to the first NUL byte. The previous version would have copied
  "a\0b\0" (with srclen 4) as "a\0b". Strip all bytes after the
  first NUL character from src. That seems more correct here.

- accept nla argument as %NULL.
This commit is contained in:
Thomas Haller 2019-02-17 19:06:39 +01:00
parent 6c24846929
commit b080146cc6

View file

@ -377,22 +377,47 @@ nla_get_u64 (const struct nlattr *nla)
}
size_t
nla_strlcpy (char *dst, const struct nlattr *nla, size_t dstsize)
nla_strlcpy (char *dst,
const struct nlattr *nla,
size_t dstsize)
{
size_t srclen = nla_len (nla);
const char *src = nla_data (nla);
const char *src;
size_t srclen;
size_t len;
if (srclen > 0 && src[srclen - 1] == '\0')
srclen--;
/* - Always writes @dstsize bytes to @dst
* - Copies the first non-NUL characters to @dst.
* Any characters after the first NUL bytes in @nla are ignored.
* - If the string @nla is longer than @dstsize, the string
* gets truncated. @dst will always be NUL terminated. */
if (dstsize > 0) {
size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
memset (dst, 0, dstsize);
memcpy (dst, src, len);
if (G_UNLIKELY (dstsize <= 1)) {
if (dstsize == 1)
dst[0] = '\0';
if ( nla
&& (srclen = nla_len (nla)) > 0)
return strnlen (nla_data (nla), srclen);
return 0;
}
return srclen;
nm_assert (dst);
if (nla) {
srclen = nla_len (nla);
if (srclen > 0) {
src = nla_data (nla);
srclen = strnlen (src, srclen);
if (srclen > 0) {
len = NM_MIN (dstsize - 1, srclen);
memcpy (dst, src, len);
memset (&dst[len], 0, dstsize - len);
return srclen;
}
}
}
memset (dst, 0, dstsize);
return 0;
}
int