Code

fix use of setlocale all over the place ...
[rrdtool-all.git] / program / src / rrd_update.c
index 79583507e6dc2645cb0dea76172ce52f8b0ddb2f..6e15b080af8895f494c2e3d8e249ec31b3885dcf 100644 (file)
@@ -1,6 +1,6 @@
 
 /*****************************************************************************
- * RRDtool 1.3.8  Copyright by Tobi Oetiker, 1997-2009
+ * RRDtool 1.3.9  Copyright by Tobi Oetiker, 1997-2009
  *****************************************************************************
  * rrd_update.c  RRD Update Function
  *****************************************************************************
@@ -884,12 +884,16 @@ static int parse_ds(
             if (i < tmpl_cnt) {
                 updvals[tmpl_idx[i++]] = p + 1;
             }
+            else {
+                rrd_set_error("found extra data on update argument: %s",p+1);
+                return -1;
+            }                
         }
     }
 
     if (i != tmpl_cnt) {
         rrd_set_error("expected %lu data source readings (got %lu) from %s",
-                      tmpl_cnt - 1, i, input);
+                      tmpl_cnt - 1, i - 1, input);
         return -1;
     }
 
@@ -942,7 +946,8 @@ static int get_time_from_reading(
         *current_time = tmp_time.tv_sec;
         *current_time_usec = tmp_time.tv_usec;
     } else {
-        old_locale = setlocale(LC_NUMERIC, "C");
+        old_locale = setlocale(LC_NUMERIC, NULL);
+        setlocale(LC_NUMERIC, "C");
         errno = 0;
         tmp = strtod(updvals[0], 0);
         if (errno > 0) {
@@ -1018,15 +1023,22 @@ static int update_pdp_prep(
             switch (dst_idx) {
             case DST_COUNTER:
             case DST_DERIVE:
-                for (ii = 0; updvals[ds_idx + 1][ii] != '\0'; ii++) {
-                    if ((updvals[ds_idx + 1][ii] < '0'
-                         || updvals[ds_idx + 1][ii] > '9')
-                        && (ii != 0 && updvals[ds_idx + 1][ii] != '-')) {
-                        rrd_set_error("not a simple integer: '%s'",
-                                      updvals[ds_idx + 1]);
+                /* Check if this is a valid integer. `U' is already handled in
+                 * another branch. */
+                for (ii = 0; updvals[ds_idx + 1][ii] != 0; ii++) {
+                    if ((ii == 0) && (dst_idx == DST_DERIVE)
+                            && (updvals[ds_idx + 1][ii] == '-'))
+                        continue;
+
+                    if ((updvals[ds_idx + 1][ii] < '0')
+                            || (updvals[ds_idx + 1][ii] > '9')) {
+                        rrd_set_error("not a simple %s integer: '%s'",
+                                (dst_idx == DST_DERIVE) ? "signed" : "unsigned",
+                                updvals[ds_idx + 1]);
                         return -1;
                     }
-                }
+                } /* for (ii = 0; updvals[ds_idx + 1][ii] != 0; ii++) */
+
                 if (rrd->pdp_prep[ds_idx].last_ds[0] != 'U') {
                     pdp_new[ds_idx] =
                         rrd_diff(updvals[ds_idx + 1],
@@ -1047,7 +1059,8 @@ static int update_pdp_prep(
                 }
                 break;
             case DST_ABSOLUTE:
-                old_locale = setlocale(LC_NUMERIC, "C");
+                old_locale = setlocale(LC_NUMERIC, NULL);
+                setlocale(LC_NUMERIC, "C");
                 errno = 0;
                 pdp_new[ds_idx] = strtod(updvals[ds_idx + 1], &endptr);
                 if (errno > 0) {
@@ -1065,7 +1078,8 @@ static int update_pdp_prep(
                 rate = pdp_new[ds_idx] / interval;
                 break;
             case DST_GAUGE:
-                old_locale = setlocale(LC_NUMERIC, "C");
+                old_locale = setlocale(LC_NUMERIC, NULL);
+                setlocale(LC_NUMERIC, "C");
                 errno = 0;
                 pdp_new[ds_idx] =
                     strtod(updvals[ds_idx + 1], &endptr) * interval;
@@ -1322,6 +1336,10 @@ static int process_pdp_st(
 
         rpnp =
             rpn_expand((rpn_cdefds_t *) &(rrd->ds_def[ds_idx].par[DS_cdef]));
+        if(rpnp == NULL) {
+          rpnstack_free(&rpnstack);
+          return -1;
+        }
         /* substitute data values for OP_VARIABLE nodes */
         for (i = 0; rpnp[i].op != OP_END; i++) {
             if (rpnp[i].op == OP_VARIABLE) {
@@ -1335,6 +1353,7 @@ static int process_pdp_st(
             rpnstack_free(&rpnstack);
             return -1;
         }
+        free(rpnp);
     }
 
     /* make pdp_prep ready for the next run */