]> sigrok.org Git - libsigrok.git/commitdiff
brymen-dmm: improve text to number conversion robustness, signed OL
authorGerhard Sittig <redacted>
Mon, 21 Sep 2020 17:57:32 +0000 (19:57 +0200)
committerGerhard Sittig <redacted>
Mon, 21 Sep 2020 17:57:32 +0000 (19:57 +0200)
The BM850(a/s) response packets are a mix of binary and text content.
The text part of it is _not_ a regular ASCIIZ string. Enforce the NUL
termination before running standard C library string routines on it.
Rephrase the conversion routine to become more C idiomatic.

Also check the optional sign for overflow conditions, return either
positive or negative infinity as a result.

src/hardware/brymen-dmm/parser.c

index 7fcb3456ad2200e57adebc9191493e3656baf748..baab57d9dcf8f03598b0576ce2b3bf9ab741bb03 100644 (file)
@@ -148,25 +148,49 @@ SR_PRIV gboolean brymen_packet_is_valid(const uint8_t *buf)
        return TRUE;
 }
 
-static int parse_value(const char *strbuf, int len, float *floatval)
+static int parse_value(const char *txt, size_t len, float *floatval)
 {
-       int s, d;
-       char str[32];
+       const char *txt_end;
+       char c, buf[32], *dst;
+       int ret;
 
-       if (strstr(strbuf, "OL")) {
-               sr_dbg("Overlimit.");
-               *floatval = INFINITY;
-               return SR_OK;
+       /*
+        * The input text is not NUL terminated, the checksum follows
+        * the value text field. Spaces may interfere with the text to
+        * number conversion, especially with exponent parsing. Copy the
+        * input data to a terminated text buffer and strip spaces in the
+        * process, before running ASCIIZ string operations.
+        */
+       if (len >= sizeof(buf)) {
+               sr_err("Insufficient text conversion buffer size.");
+               return SR_ERR_BUG;
+       }
+       txt_end = txt + len;
+       dst = &buf[0];
+       while (txt < txt_end && *txt) {
+               c = *txt++;
+               if (c == ' ')
+                       continue;
+               *dst++ = c;
        }
+       *dst = '\0';
 
-       memset(str, 0, sizeof(str));
-       /* Spaces may interfere with parsing the exponent. Strip them. */
-       for (s = 0, d = 0; s < len; s++) {
-               if (strbuf[s] != ' ')
-                       str[d++] = strbuf[s];
+       /* Check for overflow, or get the number value. */
+       if (strstr(buf, "+OL")) {
+               *floatval = +INFINITY;
+               return SR_OK;
        }
-       if (sr_atof_ascii(str, floatval) != SR_OK)
-               return SR_ERR;
+       if (strstr(buf, "-OL")) {
+               *floatval = -INFINITY;
+               return SR_OK;
+       }
+       if (strstr(buf, "OL")) {
+               *floatval = INFINITY;
+               return SR_OK;
+       }
+       ret = sr_atof_ascii(buf, floatval);
+       if (ret != SR_OK)
+               return ret;
 
        return SR_OK;
 }