From: Florian Forster Date: Wed, 17 Jun 2015 14:19:25 +0000 (+0200) Subject: src/daemon/common.c: Implement strjoin() with memcpy(). X-Git-Tag: collectd-5.5.1~105^2~1 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=dff336960f8b0466ebcdd21abbeddb451d29e1f9;p=collectd.git src/daemon/common.c: Implement strjoin() with memcpy(). The previous implementation used strncat() which has the unfortunate and unintuitive behavior of copying n+1 bytes to the buffer. --- diff --git a/src/common.c b/src/common.c index efd63c08..f41e9506 100644 --- a/src/common.c +++ b/src/common.c @@ -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)