Skip to content

Commit b2a0c54

Browse files
DavidKorczynskimadeye
authored andcommitted
json: fix signed integer overflows
Signed integer overflows can happen in three distinct places. This fixes it so an error happens when an overflow is observed. Signed-off-by: David Korczynski <[email protected]>
1 parent 9afa3ca commit b2a0c54

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

src/json.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ const struct _json_value json_value_none;
4747
#include <string.h>
4848
#include <ctype.h>
4949
#include <math.h>
50+
#include <limits.h>
5051

5152
typedef unsigned int json_uchar;
5253

@@ -758,14 +759,31 @@ json_value * json_parse_ex (json_settings * settings,
758759
else
759760
{
760761
flags |= flag_num_e_got_sign;
762+
/* Overflow check for exponent */
763+
if (num_e > (LONG_MAX / 10) || (num_e == (LONG_MAX / 10) && (b - '0') > (LONG_MAX % 10))) {
764+
sprintf(error, "%d:%d: Exponent too large (overflow)", line_and_col);
765+
goto e_failed;
766+
}
761767
num_e = (num_e * 10) + (b - '0');
762768
continue;
763769
}
764770

771+
/* Overflow check for integer */
772+
long prev = top->u.integer;
773+
if ((prev > 0 && (prev > (LONG_MAX / 10) || (prev == (LONG_MAX / 10) && (b - '0') > (LONG_MAX % 10)))) ||
774+
(prev < 0 && (prev < (LONG_MIN / 10) || (prev == (LONG_MIN / 10) && -(b - '0') < (LONG_MIN % 10))))) {
775+
sprintf(error, "%d:%d: Integer too large (overflow)", line_and_col);
776+
goto e_failed;
777+
}
765778
top->u.integer = (top->u.integer * 10) + (b - '0');
766779
continue;
767780
}
768781

782+
/* Overflow check for fraction */
783+
if (num_fraction > (LONG_MAX / 10) || (num_fraction == (LONG_MAX / 10) && (b - '0') > (LONG_MAX % 10))) {
784+
sprintf(error, "%d:%d: Fraction too large (overflow)", line_and_col);
785+
goto e_failed;
786+
}
769787
num_fraction = (num_fraction * 10) + (b - '0');
770788
continue;
771789
}

0 commit comments

Comments
 (0)