mirror of
https://github.com/linux-msm/qmic.git
synced 2024-11-27 03:44:11 +08:00
parser: be more restrictive when parsing numbers
When a number is parsed, the leading one or two characters are used to indicate whether the number should be interpreted as hexadecimal, octal or decimal. But because the parser accepts any digits regardless of the base, it allows things like 039 to be treated as an octal number, despite '9' not being a valid digit. The previous commit makes matters even worse, allowing [a-fA-F] to be accepted for octal or decimal values. Such errors are caught (but ignored) later when converting the accepted string into a number in strtoull(). We are already looking at the first character or two to determine the base, *after* scanning the number. Instead, determine the base when the first one or two characters are first input, and restrict which characters are accepted in the number based on that. As a consequence, strtoul() will examine all of the characters comprising the number (whereas previously it would stop if it encountered invalid character for the base). Finally, accept either "0x" or "0X" to indicate hexadecimal. This doesn't actually change behavior much, but as long as we're checking every character in a number for validity we might as well be restrictive. Signed-off-by: Alex Elder <elder@linaro.org> Message-Id: <20211001232338.769309-25-elder@linaro.org> Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This commit is contained in:
parent
84f213e584
commit
61f6fe9d1c
34
parser.c
34
parser.c
@ -165,11 +165,18 @@ static bool skip(char ch)
|
|||||||
return in_comment;
|
return in_comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Used for parsing octal numbers */
|
||||||
|
static int isodigit(int c)
|
||||||
|
{
|
||||||
|
return isdigit(c) && c < '9';
|
||||||
|
}
|
||||||
|
|
||||||
static struct token yylex()
|
static struct token yylex()
|
||||||
{
|
{
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
struct token token = {};
|
struct token token = {};
|
||||||
unsigned long long num;
|
unsigned long long num;
|
||||||
|
int (*isvalid)(int);
|
||||||
char buf[128];
|
char buf[128];
|
||||||
char *p = buf;
|
char *p = buf;
|
||||||
int base;
|
int base;
|
||||||
@ -214,20 +221,31 @@ static struct token yylex()
|
|||||||
|
|
||||||
return token;
|
return token;
|
||||||
} else if (isdigit(ch)) {
|
} else if (isdigit(ch)) {
|
||||||
|
/* Determine base and valid character set */
|
||||||
|
if (ch == '0') {
|
||||||
|
*p++ = ch;
|
||||||
|
ch = input();
|
||||||
|
if (ch == 'x' || ch == 'X') {
|
||||||
|
*p++ = ch;
|
||||||
|
ch = input();
|
||||||
|
isvalid = isxdigit;
|
||||||
|
base = 16;
|
||||||
|
} else {
|
||||||
|
isvalid = isodigit;
|
||||||
|
base = 8;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
isvalid = isdigit;
|
||||||
|
base = 10;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
*p++ = ch;
|
*p++ = ch;
|
||||||
ch = input();
|
ch = input();
|
||||||
} while (isxdigit(ch) || (p - buf == 1 && ch == 'x'));
|
} while (isvalid(ch));
|
||||||
unput(ch);
|
unput(ch);
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
if (buf[0] == '0' && buf[1] == 'x')
|
|
||||||
base = 16;
|
|
||||||
else if (buf[0] == '0')
|
|
||||||
base = 8;
|
|
||||||
else
|
|
||||||
base = 10;
|
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
num = strtoull(buf, NULL, base);
|
num = strtoull(buf, NULL, base);
|
||||||
if (errno)
|
if (errno)
|
||||||
|
19
tests/bad_X.qmi
Normal file
19
tests/bad_X.qmi
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
struct qmi_result {
|
||||||
|
u16 result;
|
||||||
|
u16 error;
|
||||||
|
};
|
||||||
|
|
||||||
|
request test_request {
|
||||||
|
# Previously "0X" was not allowed to indicate a hexadecimal value
|
||||||
|
required u8 test_number = 0X12;
|
||||||
|
} = 0x23;
|
||||||
|
|
||||||
|
response test_response {
|
||||||
|
required qmi_result r = 2;
|
||||||
|
} = 043;
|
||||||
|
|
||||||
|
indication test_indication {
|
||||||
|
optional u64 value = 0x99;
|
||||||
|
} = 0x7;
|
19
tests/bad_decimal.qmi
Normal file
19
tests/bad_decimal.qmi
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
struct qmi_result {
|
||||||
|
u16 result;
|
||||||
|
u16 error;
|
||||||
|
};
|
||||||
|
|
||||||
|
request test_request {
|
||||||
|
required u8 test_number = 0x12;
|
||||||
|
} = 0x23;
|
||||||
|
|
||||||
|
response test_response {
|
||||||
|
# Note that 'a' is not a valid decimal digit
|
||||||
|
required qmi_result r = 2a;
|
||||||
|
} = 043;
|
||||||
|
|
||||||
|
indication test_indication {
|
||||||
|
optional u64 value = 0x99;
|
||||||
|
} = 0x7;
|
19
tests/bad_hex.qmi
Normal file
19
tests/bad_hex.qmi
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
struct qmi_result {
|
||||||
|
u16 result;
|
||||||
|
u16 error;
|
||||||
|
};
|
||||||
|
|
||||||
|
request test_request {
|
||||||
|
# Note that 'g' is not a valid hexadecimal digit
|
||||||
|
required u8 test_number = 0x1g;
|
||||||
|
} = 0x23;
|
||||||
|
|
||||||
|
response test_response {
|
||||||
|
required qmi_result r = 2;
|
||||||
|
} = 043;
|
||||||
|
|
||||||
|
indication test_indication {
|
||||||
|
optional u64 value = 0x99;
|
||||||
|
} = 0x7;
|
19
tests/bad_octal.qmi
Normal file
19
tests/bad_octal.qmi
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package test;
|
||||||
|
|
||||||
|
struct qmi_result {
|
||||||
|
u16 result;
|
||||||
|
u16 error;
|
||||||
|
};
|
||||||
|
|
||||||
|
request test_request {
|
||||||
|
# Note that '8' is not a valid octal digit
|
||||||
|
optional test_struct foo = 028;
|
||||||
|
} = 0x23;
|
||||||
|
|
||||||
|
response test_response {
|
||||||
|
required qmi_result r = 2;
|
||||||
|
} = 043;
|
||||||
|
|
||||||
|
indication test_indication {
|
||||||
|
optional u64 value = 0x99;
|
||||||
|
} = 0x7;
|
Loading…
Reference in New Issue
Block a user