[LTP] [PATCH 06/15] ujson: reader: Check for signed integer overflow
Andrea Cervesato
andrea.cervesato@suse.de
Mon Oct 5 15:25:34 CEST 2026
From: Andrea Cervesato <andrea.cervesato@suse.com>
In get_int(), integers longer than LONG_MAX overflow long during
multiplication and addition, resulting in undefined behavior.
Accumulate the value in unsigned long, check against LONG_MAX or
LONG_MIN limits on each digit, and report an error on overflow.
Fixes: c50a0e0751c8 ("libs: Vendor ujson library")
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
libs/ujson/ujson_reader.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/libs/ujson/ujson_reader.c b/libs/ujson/ujson_reader.c
index 0975ca1a1..272df4d55 100644
--- a/libs/ujson/ujson_reader.c
+++ b/libs/ujson/ujson_reader.c
@@ -11,6 +11,7 @@
#include <string.h>
#include <stdarg.h>
#include <stdint.h>
+#include <limits.h>
#include "ujson_utf.h"
#include "ujson_reader.h"
@@ -309,7 +310,7 @@ static int is_digit(char b)
static int get_int(ujson_reader *buf, struct ujson_val *res)
{
- long val = 0;
+ unsigned long val = 0;
int sign = 1;
if (eatb(buf, '-')) {
@@ -325,17 +326,25 @@ static int get_int(ujson_reader *buf, struct ujson_val *res)
return 1;
}
+ unsigned long max = (sign < 0) ? (unsigned long)LONG_MAX + 1UL : (unsigned long)LONG_MAX;
+
while (is_digit(peekb(buf))) {
- val *= 10;
- val += getb(buf) - '0';
- //TODO: overflow?
+ unsigned int d = getb(buf) - '0';
+
+ if (val > (max - d) / 10) {
+ ujson_err(buf, "Integer overflow");
+ return 1;
+ }
+
+ val = val * 10 + d;
}
if (sign < 0)
- val = -val;
+ res->val_int = (long)(0UL - val);
+ else
+ res->val_int = (long)val;
- res->val_int = val;
- res->val_float = val;
+ res->val_float = res->val_int;
return 0;
}
--
2.51.0
More information about the ltp
mailing list