[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