diff --git a/src/yajl_parser.c b/src/yajl_parser.c index 1a528a64..0e448aeb 100644 --- a/src/yajl_parser.c +++ b/src/yajl_parser.c @@ -29,7 +29,7 @@ #include #include -#define MAX_VALUE_TO_MULTIPLY ((LLONG_MAX / 10) + (LLONG_MAX % 10)) +#define MAX_VALUE_TO_MULTIPLY (LLONG_MIN / 10) /* same semantics as strtol */ long long @@ -42,12 +42,12 @@ yajl_parse_integer(const unsigned char *number, unsigned int length) if (*pos == '+') { pos++; } while (pos < number + length) { - if ( ret > MAX_VALUE_TO_MULTIPLY ) { + if ( ret < MAX_VALUE_TO_MULTIPLY ) { errno = ERANGE; return sign == 1 ? LLONG_MAX : LLONG_MIN; } ret *= 10; - if (LLONG_MAX - ret < (*pos - '0')) { + if ((sign == 1 ? -LLONG_MAX : LLONG_MIN) - ret > -(*pos - '0')) { errno = ERANGE; return sign == 1 ? LLONG_MAX : LLONG_MIN; } @@ -55,10 +55,10 @@ yajl_parse_integer(const unsigned char *number, unsigned int length) errno = ERANGE; return sign == 1 ? LLONG_MAX : LLONG_MIN; } - ret += (*pos++ - '0'); + ret -= (*pos++ - '0'); } - return sign * ret; + return -sign * ret; } unsigned char * diff --git a/test/parsing/cases/bignums.json b/test/parsing/cases/bignums.json index 75aca9ac..482e0bdd 100644 --- a/test/parsing/cases/bignums.json +++ b/test/parsing/cases/bignums.json @@ -1 +1 @@ -[ 9223372036854775807, -9223372036854775807 ] +[ 9223372036854775807, -9223372036854775808 ] diff --git a/test/parsing/cases/bignums.json.gold b/test/parsing/cases/bignums.json.gold index 8bb3b1ee..0db68f92 100644 --- a/test/parsing/cases/bignums.json.gold +++ b/test/parsing/cases/bignums.json.gold @@ -1,5 +1,5 @@ array open '[' integer: 9223372036854775807 -integer: -9223372036854775807 +integer: -9223372036854775808 array close ']' memory leaks: 0 diff --git a/test/parsing/cases/low_overflow.json b/test/parsing/cases/low_overflow.json index 9af921bf..ec15935b 100644 --- a/test/parsing/cases/low_overflow.json +++ b/test/parsing/cases/low_overflow.json @@ -1 +1 @@ --9223372036854775808 \ No newline at end of file +-9223372036854775809 diff --git a/test/parsing/cases/low_overflow_regression.json b/test/parsing/cases/low_overflow_regression.json new file mode 100644 index 00000000..ddf4fc63 --- /dev/null +++ b/test/parsing/cases/low_overflow_regression.json @@ -0,0 +1 @@ +-92233720368547758080 diff --git a/test/parsing/cases/low_overflow_regression.json.gold b/test/parsing/cases/low_overflow_regression.json.gold new file mode 100644 index 00000000..19c4b77d --- /dev/null +++ b/test/parsing/cases/low_overflow_regression.json.gold @@ -0,0 +1,2 @@ +parse error: integer overflow +memory leaks: 0