]> git.itanic.dy.fi Git - rrdd/commitdiff
rrdtool.c: Improve data sanitization
authorTimo Kokkonen <timo.t.kokkonen@iki.fi>
Sun, 24 Jun 2012 08:29:27 +0000 (11:29 +0300)
committerTimo Kokkonen <timo.t.kokkonen@iki.fi>
Sun, 24 Jun 2012 08:29:27 +0000 (11:29 +0300)
The code is doing rather complex string manipulation. Without
sufficient commentation it is hard to understand what it really
does. Better documentation is now included.

Non-numerical data is also now marked as undefined, if there are no
numbers at all in the input data. Completely empty entries are also
marked as undefined.

Finally, santitized string output is NULL terminated even if also the
last entry was undefined.

Signed-off-by: Timo Kokkonen <timo.t.kokkonen@iki.fi>
rrdtool.c

index 3a8d9ab0f0e4581825755a8cd53678d499f1f159..8f6bc4a43f3568a385665760f827d204519950db 100644 (file)
--- a/rrdtool.c
+++ b/rrdtool.c
@@ -119,33 +119,60 @@ static int sanitize_rrd_update_data(char *data)
        src = data;
        cln = clean_data;
 
+       /*
+        * Copy a legit floating point number to clean_data buffer
+        * starting from *src and ending to next ':'. If no legit
+        * number could be found, put a 'U' there instead to make
+        * rrdtool to understand this datapoint is undefined.
+        */
+
        while (src < data + RRD_DATA_MAX_LEN && *src) {
                minus = 0;
+
+               /* skip any non_numbers but not ':' */
+               while (*src && !isdigit(*src) && *src != '-' && *src != ':')
+                       src++;
+
                if (*src == '-') {
                        src++;
                        minus = 1;
                }
 
+               /* Now find the end of the number */
                end = skip_numbers(src);
 
+               /* Floating point numberrs may have a dot with more numbers */
                if (*end == '.') {
                        end++;
                        end = skip_numbers(end);
                }
 
-               if (*end == ':' || !*end) {
+               /*
+                * Now we have gone past the number, there should be a
+                * colon or zero byte. If src == end, there was no
+                * number and the entry is undefined instead.
+                */
+               if ((*end == ':' || !*end) && src != end) {
                        if (minus) {
                                *cln = '-';
                                cln++;
                        }
+
+                       /*
+                        * Copy the legit number and start copying the
+                        * next one
+                        */
                        for (; src <= end; src++, cln++)
                                *cln = *src;
 
                        goto next;
                }
 
+               /* Skip over whatever junk there might be */
                while (*end != ':' && *end)
                        end++;
+
+               /* Mark the entry as undefined */
                *cln = 'U';
                cln++;
                *cln = ':';
@@ -156,6 +183,14 @@ static int sanitize_rrd_update_data(char *data)
                entries++;
        }
 
+       /*
+        * If last entry was undefined, we need to remove the extra
+        * colon at the end
+        */
+       if (*(cln - 1) == ':')
+               cln--;
+       *cln = '\0';
+
        strncpy(data, clean_data, RRD_DATA_MAX_LEN);
        return entries;
 }