Code

src/daemon/common.c: Implement strjoin() with memcpy().
authorFlorian Forster <octo@collectd.org>
Wed, 17 Jun 2015 14:19:25 +0000 (16:19 +0200)
committerFlorian Forster <octo@collectd.org>
Wed, 17 Jun 2015 14:21:19 +0000 (16:21 +0200)
The previous implementation used strncat() which has the unfortunate and
unintuitive behavior of copying n+1 bytes to the buffer.

src/common.c

index efd63c085452f7ba238247e1caade93d4bb35ac0..f41e9506b447db19075d0d843c25dc5a176e016c 100644 (file)
@@ -307,44 +307,51 @@ int strsplit (char *string, char **fields, size_t size)
        return ((int) i);
 }
 
-int strjoin (char *dst, size_t dst_len,
+int strjoin (char *buffer, size_t buffer_size,
                char **fields, size_t fields_num,
                const char *sep)
 {
-       size_t field_len;
+       size_t avail;
+       char *ptr;
        size_t sep_len;
-       int i;
-
-       memset (dst, '\0', dst_len);
+       size_t i;
 
-       if (fields_num <= 0)
+       if ((buffer_size < 1) || (fields_num <= 0))
                return (-1);
 
+       memset (buffer, 0, buffer_size);
+       ptr = buffer;
+       avail = buffer_size - 1;
+
        sep_len = 0;
        if (sep != NULL)
                sep_len = strlen (sep);
 
-       for (i = 0; i < (int)fields_num; i++)
+       for (i = 0; i < fields_num; i++)
        {
+               size_t field_len;
+
                if ((i > 0) && (sep_len > 0))
                {
-                       if (dst_len <= sep_len)
+                       if (avail < sep_len)
                                return (-1);
 
-                       strncat (dst, sep, dst_len);
-                       dst_len -= sep_len;
+                       memcpy (ptr, sep, sep_len);
+                       ptr += sep_len;
+                       avail -= sep_len;
                }
 
                field_len = strlen (fields[i]);
-
-               if (dst_len <= field_len)
+               if (avail < field_len)
                        return (-1);
 
-               strncat (dst, fields[i], dst_len);
-               dst_len -= field_len;
+               memcpy (ptr, fields[i], field_len);
+               ptr += field_len;
+               avail -= field_len;
        }
 
-       return (strlen (dst));
+       assert (buffer[buffer_size - 1] == 0);
+       return (strlen (buffer));
 }
 
 int strsubstitute (char *str, char c_from, char c_to)