X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fdaemon%2Fcommon.c;h=d53f1ec0aa968f63a8130362047cf2b83458f05a;hb=afb38f31abd27d5b4ce08023f8bbbaeeb353c55f;hp=d1d8bf15dcfcd85124849b7653b3fcee9be560a3;hpb=f7d1db6cc1bed058ca03747f5c6bdd07ce12be27;p=collectd.git diff --git a/src/daemon/common.c b/src/daemon/common.c index d1d8bf15..d53f1ec0 100644 --- a/src/daemon/common.c +++ b/src/daemon/common.c @@ -334,52 +334,60 @@ int strsplit (char *string, char **fields, size_t size) return ((int) i); } -int strjoin (char *buffer, size_t buffer_size, - char **fields, size_t fields_num, - const char *sep) -{ - size_t avail; - char *ptr; - size_t sep_len; +int strjoin(char *buffer, size_t buffer_size, char **fields, size_t fields_num, + const char *sep) { + size_t avail = 0; + char *ptr = buffer; + size_t sep_len = 0; - if ((buffer_size < 1) || (fields_num == 0)) - return (-1); + size_t buffer_req = 0; - memset (buffer, 0, buffer_size); - ptr = buffer; - avail = buffer_size - 1; + if (((fields_num != 0) && (fields == NULL)) || + ((buffer_size != 0) && (buffer == NULL))) + return (-EINVAL); - sep_len = 0; - if (sep != NULL) - sep_len = strlen (sep); + if (buffer != NULL) + buffer[0] = 0; - for (size_t i = 0; i < fields_num; i++) - { - size_t field_len; + if (buffer_size != 0) + avail = buffer_size - 1; - if ((i > 0) && (sep_len > 0)) - { - if (avail < sep_len) - return (-1); + if (sep != NULL) + sep_len = strlen(sep); - memcpy (ptr, sep, sep_len); - ptr += sep_len; - avail -= sep_len; - } - if (avail == 0) - return (-1); + for (size_t i = 0; i < fields_num; i++) { + size_t field_len = strlen(fields[i]); - field_len = strlen (fields[i]); - if (avail < field_len) - field_len = avail; + if (i != 0) + buffer_req += sep_len; + buffer_req += field_len; - memcpy (ptr, fields[i], field_len); - ptr += field_len; - avail -= field_len; - } + if ((i != 0) && (sep_len > 0)) { + if (sep_len >= avail) { + /* prevent subsequent iterations from writing to the + * buffer. */ + avail = 0; + continue; + } + + memcpy(ptr, sep, sep_len); + + ptr += sep_len; + avail -= sep_len; + } + + if (field_len > avail) + field_len = avail; + + memcpy(ptr, fields[i], field_len); + ptr += field_len; + + avail -= field_len; + if (ptr != NULL) + *ptr = 0; + } - assert (buffer[buffer_size - 1] == 0); - return ((int) ((buffer_size - 1) - avail)); + return (int)buffer_req; } int escape_string (char *buffer, size_t buffer_size)