From dff336960f8b0466ebcdd21abbeddb451d29e1f9 Mon Sep 17 00:00:00 2001 From: Florian Forster Date: Wed, 17 Jun 2015 16:19:25 +0200 Subject: [PATCH] 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. --- src/common.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) 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) -- 2.30.2