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
}