fixed an out-of-bounds memory access for datatable annotations
Costa Tsaousis (ktsaou) committed
Nov 30, 2015 at 23:06 UTC
1a0a471828400e20c0ec8eb58b20a0a90f303bd7
1 file changed
+33
-15
src/rrd2json.c
+33
-15
@@ -274,6 +274,7 @@ typedef struct rrdresult {
274
275
int d; // the number of dimensions
276
int n; // the number of values in the arrays
277
+ int rows; // the number of rows used
278
279
uint8_t *od; // the options for the dimensions
280
@@ -286,7 +287,7 @@ typedef struct rrdresult {
287
int has_st_lock; // if st is read locked by us
288
} RRDR;
289
289
-#define rrdr_rows(r) ((r)->c + 1)
290
+#define rrdr_rows(r) ((r)->rows)
291
292
/*
293
static void rrdr_dump(RRDR *r)
@@ -307,15 +308,15 @@ static void rrdr_dump(RRDR *r)
308
);
309
}
310
310
- if(r->c < 0) {
311
+ if(r->rows <= 0) {
312
fprintf(stderr, "RRDR does not have any values in it.\n");
313
return;
314
}
315
315
- fprintf(stderr, "RRDR includes %d values in it:\n", r->c + 1);
316
+ fprintf(stderr, "RRDR includes %d values in it:\n", r->rows);
317
318
// for each line in the array
318
- for(i = 0; i <= r->c ;i++) {
319
+ for(i = 0; i < r->rows ;i++) {
320
calculated_number *cn = &r->v[ i * r->d ];
321
uint8_t *co = &r->o[ i * r->d ];
322
@@ -374,7 +375,7 @@ void rrdr_disable_not_selected_dimensions(RRDR *r, const char *dims)
375
376
static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
377
{
377
- int annotations = 0, dates = JSON_DATES_JS, dates_with_new = 0;
378
+ int row_annotations = 0, dates = JSON_DATES_JS, dates_with_new = 0;
379
char kq[2] = "", // key quote
380
sq[2] = "", // string quote
381
pre_label[101] = "", // before each label
@@ -399,7 +400,7 @@ static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
400
kq[0] = '"';
401
sq[0] = '"';
402
}
402
- annotations = 1;
403
+ row_annotations = 1;
404
snprintf(pre_date, 100, " {%sc%s:[{%sv%s:%s", kq, kq, kq, kq, sq);
405
snprintf(post_date, 100, "%s}", sq);
406
snprintf(pre_label, 100, ",\n {%sid%s:%s%s,%slabel%s:%s", kq, kq, sq, sq, kq, kq, sq);
@@ -458,7 +459,7 @@ static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
459
long c, i;
460
RRDDIM *rd;
461
461
- // print the csv header
462
+ // print the header lines
463
for(c = 0, i = 0, rd = r->st->dimensions; rd ;c++, rd = rd->next) {
464
if(unlikely(r->od[c] & RRDR_HIDDEN)) continue;
465
if(unlikely((options & RRDR_OPTION_NONZERO) && !(r->od[c] & RRDR_NONZERO))) continue;
@@ -519,10 +520,17 @@ static void rrdr2json(RRDR *r, BUFFER *wb, uint32_t options, int datatable)
520
521
buffer_strcat(wb, post_date);
522
522
- if(annotations) {
523
- if(co[c] & RRDR_RESET)
524
- buffer_strcat(wb, overflow_annotation);
525
- else
523
+ if(row_annotations) {
524
+ // google supports one annotation per row
525
+ int annotation_found = 0;
526
+ for(c = 0, rd = r->st->dimensions; rd ;c++, rd = rd->next) {
527
+ if(co[c] & RRDR_RESET) {
528
+ buffer_strcat(wb, overflow_annotation);
529
+ annotation_found = 1;
530
+ break;
531
+ }
532
+ }
533
+ if(!annotation_found)
534
buffer_strcat(wb, normal_annotation);
535
}
536
}
@@ -733,9 +741,10 @@ inline static uint8_t *rrdr_line_options(RRDR *r)
741
inline static int rrdr_line_init(RRDR *r, time_t t)
742
{
743
r->c++;
744
+
745
if(unlikely(r->c >= r->n)) {
746
+ error("requested to step above RRDR size for chart %s", r->st->name);
747
r->c = r->n - 1;
738
- return 0;
748
}
749
750
// save the time
@@ -781,6 +790,12 @@ inline static void rrdr_free(RRDR *r)
790
free(r);
791
}
792
793
+inline void rrdr_done(RRDR *r)
794
+{
795
+ r->rows = r->c + 1;
796
+ r->c = 0;
797
+}
798
+
799
static RRDR *rrdr_create(RRDSET *st, int n)
800
{
801
if(unlikely(!st)) {
@@ -799,19 +814,21 @@ static RRDR *rrdr_create(RRDSET *st, int n)
814
for(rd = st->dimensions ; rd ; rd = rd->next) r->d++;
815
816
r->n = n;
802
- r->t = malloc(n * sizeof(time_t));
817
+
818
+ r->t = calloc(n, sizeof(time_t));
819
if(unlikely(!r->t)) goto cleanup;
820
805
- r->v = malloc(n * r->d * sizeof(calculated_number));
821
+ r->v = calloc(n * r->d, sizeof(calculated_number));
822
if(unlikely(!r->v)) goto cleanup;
823
808
- r->o = malloc(n * r->d * sizeof(uint8_t));
824
+ r->o = calloc(n * r->d, sizeof(uint8_t));
825
if(unlikely(!r->o)) goto cleanup;
826
827
r->od = calloc(r->d, sizeof(uint8_t));
828
if(unlikely(!r->od)) goto cleanup;
829
830
r->c = -1;
831
+ r->rows = 0;
832
833
return r;
834
@@ -1063,6 +1080,7 @@ RRDR *rrd2rrdr(RRDSET *st, long points, long long after, long long before, int g
1080
}
1081
}
1082
1083
+ rrdr_done(r);
1084
return r;
1085
}
1086