From b2a0c545d8ce2d35ba3f4a77fe710861b1b74628 Mon Sep 17 00:00:00 2001 From: David Korczynski Date: Sat, 6 Dec 2025 20:07:36 +0000 Subject: [PATCH] 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 --- src/json.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/json.c b/src/json.c index 2a919009..00a367f1 100644 --- a/src/json.c +++ b/src/json.c @@ -47,6 +47,7 @@ const struct _json_value json_value_none; #include #include #include +#include typedef unsigned int json_uchar; @@ -758,14 +759,31 @@ json_value * json_parse_ex (json_settings * settings, else { flags |= flag_num_e_got_sign; + /* Overflow check for exponent */ + if (num_e > (LONG_MAX / 10) || (num_e == (LONG_MAX / 10) && (b - '0') > (LONG_MAX % 10))) { + sprintf(error, "%d:%d: Exponent too large (overflow)", line_and_col); + goto e_failed; + } num_e = (num_e * 10) + (b - '0'); continue; } + /* Overflow check for integer */ + long prev = top->u.integer; + if ((prev > 0 && (prev > (LONG_MAX / 10) || (prev == (LONG_MAX / 10) && (b - '0') > (LONG_MAX % 10)))) || + (prev < 0 && (prev < (LONG_MIN / 10) || (prev == (LONG_MIN / 10) && -(b - '0') < (LONG_MIN % 10))))) { + sprintf(error, "%d:%d: Integer too large (overflow)", line_and_col); + goto e_failed; + } top->u.integer = (top->u.integer * 10) + (b - '0'); continue; } + /* Overflow check for fraction */ + if (num_fraction > (LONG_MAX / 10) || (num_fraction == (LONG_MAX / 10) && (b - '0') > (LONG_MAX % 10))) { + sprintf(error, "%d:%d: Fraction too large (overflow)", line_and_col); + goto e_failed; + } num_fraction = (num_fraction * 10) + (b - '0'); continue; }