json: Handle error cases while parsing numbers

Signed-off-by: Arun Raghavan <arun@arunraghavan.net>
This commit is contained in:
Arun Raghavan 2016-06-01 17:18:35 +05:30
parent 777a5091f6
commit 5b1bd84902
2 changed files with 30 additions and 1 deletions

View file

@ -194,7 +194,7 @@ error:
} }
static const char* parse_number(const char *str, pa_json_object *obj) { static const char* parse_number(const char *str, pa_json_object *obj) {
bool negative = false, has_fraction = false, has_exponent = false; bool negative = false, has_fraction = false, has_exponent = false, valid = false;
unsigned int integer = 0; unsigned int integer = 0;
unsigned int fraction = 0; unsigned int fraction = 0;
unsigned int fraction_digits = 0; unsigned int fraction_digits = 0;
@ -206,11 +206,14 @@ static const char* parse_number(const char *str, pa_json_object *obj) {
} }
if (*str == '0') { if (*str == '0') {
valid = true;
str++; str++;
goto fraction; goto fraction;
} }
while (is_digit(*str)) { while (is_digit(*str)) {
valid = true;
if (integer > ((negative ? INT_MAX : UINT_MAX) / 10)) { if (integer > ((negative ? INT_MAX : UINT_MAX) / 10)) {
pa_log("Integer overflow while parsing number"); pa_log("Integer overflow while parsing number");
goto error; goto error;
@ -221,11 +224,20 @@ static const char* parse_number(const char *str, pa_json_object *obj) {
} }
fraction: fraction:
if (!valid) {
pa_log("Missing digits while parsing number");
goto error;
}
if (*str == '.') { if (*str == '.') {
has_fraction = true; has_fraction = true;
str++; str++;
valid = false;
while (is_digit(*str)) { while (is_digit(*str)) {
valid = true;
if (fraction > (UINT_MAX / 10)) { if (fraction > (UINT_MAX / 10)) {
pa_log("Integer overflow while parsing fractional part of number"); pa_log("Integer overflow while parsing fractional part of number");
goto error; goto error;
@ -235,6 +247,11 @@ fraction:
fraction_digits++; fraction_digits++;
str++; str++;
} }
if (!valid) {
pa_log("No digit after '.' while parsing fraction");
goto error;
}
} }
if (*str == 'e' || *str == 'E') { if (*str == 'e' || *str == 'E') {
@ -242,6 +259,7 @@ fraction:
has_exponent = true; has_exponent = true;
str++; str++;
valid = false;
if (*str == '-') { if (*str == '-') {
exponent_negative = true; exponent_negative = true;
@ -250,6 +268,8 @@ fraction:
str++; str++;
while (is_digit(*str)) { while (is_digit(*str)) {
valid = true;
if (exponent > (INT_MAX / 10)) { if (exponent > (INT_MAX / 10)) {
pa_log("Integer overflow while parsing exponent part of number"); pa_log("Integer overflow while parsing exponent part of number");
goto error; goto error;
@ -259,6 +279,11 @@ fraction:
str++; str++;
} }
if (!valid) {
pa_log("No digit in exponent while parsing fraction");
goto error;
}
if (exponent_negative) if (exponent_negative)
exponent *= -1; exponent *= -1;
} }

View file

@ -223,6 +223,10 @@ START_TEST(bad_test) {
"123456789012345678901234567890" /* Overflow */, "123456789012345678901234567890" /* Overflow */,
"0.123456789012345678901234567890" /* Overflow */, "0.123456789012345678901234567890" /* Overflow */,
"1e123456789012345678901234567890" /* Overflow */, "1e123456789012345678901234567890" /* Overflow */,
"1e" /* Bad number string */,
"1." /* Bad number string */,
"1.e3" /* Bad number string */,
"-" /* Bad number string */,
}; };
for (i = 0; i < PA_ELEMENTSOF(bad_parse); i++) { for (i = 0; i < PA_ELEMENTSOF(bad_parse); i++) {