1 diff a/doc/rrdcreate.pod b/doc/rrdcreate.pod
2 --- a/doc/rrdcreate.pod
3 +++ b/doc/rrdcreate.pod
4 @@ -184,6 +184,7 @@ I<steps> defines how many of these I<primary data points> are used to build
5 a I<consolidated data point> which then goes into the archive.
7 I<rows> defines how many generations of data values are kept in an B<RRA>.
8 +Obviously, this has to be greater than zero.
10 =back
12 diff a/src/rrd_create.c b/src/rrd_create.c
13 --- a/src/rrd_create.c
14 +++ b/src/rrd_create.c
15 @@ -207,6 +207,7 @@ rrd_create_r(const char *filename,
16 char *argvcopy;
17 char *tokptr;
18 size_t old_size = sizeof(rra_def_t)*(rrd.stat_head->rra_cnt);
19 + int row_cnt;
20 if((rrd.rra_def = rrd_realloc(rrd.rra_def,
21 old_size+sizeof(rra_def_t)))==NULL)
22 {
23 @@ -269,7 +270,10 @@ rrd_create_r(const char *filename,
24 case CF_SEASONAL:
25 case CF_DEVPREDICT:
26 case CF_FAILURES:
27 - rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt = atoi(token);
28 + row_cnt = atoi(token);
29 + if (row_cnt <= 0)
30 + rrd_set_error("Invalid row count: %i", row_cnt);
31 + rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt = row_cnt;
32 break;
33 default:
34 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_cdp_xff_val].u_val = atof(token);
35 @@ -350,7 +354,10 @@ rrd_create_r(const char *filename,
36 rrd_set_error("Unexpected extra argument for consolidation function DEVPREDICT");
37 break;
38 default:
39 - rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt = atoi(token);
40 + row_cnt = atoi(token);
41 + if (row_cnt <= 0)
42 + rrd_set_error("Invalid row count: %i", row_cnt);
43 + rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt = row_cnt;
44 break;
45 }
46 break;