brymen-dmm: improve text to number conversion robustness, signed OL
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.
This commit is contained in:
parent
11addc897a
commit
56213aa027
|
@ -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.");
|
||||
/*
|
||||
* 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';
|
||||
|
||||
/* Check for overflow, or get the number value. */
|
||||
if (strstr(buf, "+OL")) {
|
||||
*floatval = +INFINITY;
|
||||
return SR_OK;
|
||||
}
|
||||
if (strstr(buf, "-OL")) {
|
||||
*floatval = -INFINITY;
|
||||
return SR_OK;
|
||||
}
|
||||
if (strstr(buf, "OL")) {
|
||||
*floatval = INFINITY;
|
||||
return SR_OK;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
if (sr_atof_ascii(str, floatval) != SR_OK)
|
||||
return SR_ERR;
|
||||
ret = sr_atof_ascii(buf, floatval);
|
||||
if (ret != SR_OK)
|
||||
return ret;
|
||||
|
||||
return SR_OK;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue