@cryptotaxi247 / netdata-1 / commits / ad8d481d3

fixed corruption in charts JSON, when each chunk of data is above 1024 bytes; fixes #2498

Costa Tsaousis (ktsaou) committed Jul 23, 2017 at 00:32 UTC ad8d481d361347fbc224ce62a58c2af0fcd0cec1
4 files changed +43 -17
src/main.c
+1
@@ -635,6 +635,7 @@ int main(int argc, char **argv) {
635 char* debug_flags_string = "debug_flags=";
636
637 if(strcmp(optarg, "unittest") == 0) {
638 + if(unit_test_buffer()) exit(1);
639 if(unit_test_str2ld()) exit(1);
640 //default_rrd_update_every = 1;
641 //default_rrd_memory_mode = RRD_MEMORY_MODE_RAM;
src/unit_test.c
+28
@@ -269,6 +269,34 @@ int unit_test_str2ld() {
269 return 0;
270 }
271
272 +int unit_test_buffer() {
273 + BUFFER *wb = buffer_create(1);
274 + char string[2048 + 1];
275 + char final[9000 + 1];
276 + int i;
277 +
278 + for(i = 0; i < 2048; i++)
279 + string[i] = (char)((i % 24) + 'a');
280 + string[2048] = '\0';
281 +
282 + const char *fmt = "string1: %s\nstring2: %s\nstring3: %s\nstring4: %s";
283 + buffer_sprintf(wb, fmt, string, string, string, string);
284 + snprintfz(final, 9000, fmt, string, string, string, string);
285 +
286 + const char *s = buffer_tostring(wb);
287 +
288 + if(buffer_strlen(wb) != strlen(final) || strcmp(s, final) != 0) {
289 + fprintf(stderr, "\nbuffer_sprintf() is faulty.\n");
290 + fprintf(stderr, "\nstring : %s (length %zu)\n", string, strlen(string));
291 + fprintf(stderr, "\nbuffer : %s (length %zu)\n", s, buffer_strlen(wb));
292 + fprintf(stderr, "\nexpected: %s (length %zu)\n", final, strlen(final));
293 + return -1;
294 + }
295 +
296 + fprintf(stderr, "buffer_sprintf() works as expected.\n");
297 + return 0;
298 +}
299 +
300 // --------------------------------------------------------------------------------------------------------------------
301
302 struct feed_values {
src/unit_test.h
+1
@@ -5,5 +5,6 @@ extern int unit_test_storage(void);
5 extern int unit_test(long delay, long shift);
6 extern int run_all_mockup_tests(void);
7 extern int unit_test_str2ld(void);
8 +extern int unit_test_buffer(void);
9
10 #endif /* NETDATA_UNIT_TEST_H */
src/web_buffer.c
+13 -17
@@ -201,29 +201,25 @@ void buffer_sprintf(BUFFER *wb, const char *fmt, ...)
201 {
202 if(unlikely(!fmt || !*fmt)) return;
203
204 - buffer_need_bytes(wb, 2);
205 -
206 - size_t len = wb->size - wb->len - 1;
207 - size_t wrote;
208 -
204 va_list args;
210 - va_start(args, fmt);
211 - wrote = (size_t) vsnprintfz(&wb->buffer[wb->len], len, fmt, args);
212 - va_end(args);
205 + size_t wrote = 0, need = 2, multiplier = 0, len;
206
214 - if(unlikely(wrote >= len)) {
215 - // truncated
216 - buffer_overflow_check(wb);
207 + do {
208 + need += wrote + multiplier * WEB_DATA_LENGTH_INCREASE_STEP;
209 + multiplier++;
210
218 - debug(D_WEB_BUFFER, "web_buffer_sprintf(): increasing web_buffer at position %zu, size = %zu\n", wb->len, wb->size);
219 - buffer_need_bytes(wb, len + WEB_DATA_LENGTH_INCREASE_STEP);
211 + debug(D_WEB_BUFFER, "web_buffer_sprintf(): increasing web_buffer at position %zu, size = %zu, by %zu bytes (wrote = %zu)\n", wb->len, wb->size, need, wrote);
212 + buffer_need_bytes(wb, need);
213 +
214 + len = wb->size - wb->len - 1;
215
216 va_start(args, fmt);
222 - buffer_vsprintf(wb, fmt, args);
217 + wrote = (size_t) vsnprintfz(&wb->buffer[wb->len], len, fmt, args);
218 va_end(args);
224 - }
225 - else
226 - wb->len += wrote;
219 +
220 + } while(wrote >= len);
221 +
222 + wb->len += wrote;
223
224 // the buffer is \0 terminated by vsnprintf
225 }