From 63751f8a9f94dc6d3370084ad0d60826c58b955d Mon Sep 17 00:00:00 2001 From: itchyny Date: Sun, 26 Apr 2026 22:59:17 +0900 Subject: [PATCH] Fix signed-int overflow in `tokenadd` to prevent buffer overflow --- src/jv_parse.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/jv_parse.c b/src/jv_parse.c index 56847b5e..0fb4247b 100644 --- a/src/jv_parse.c +++ b/src/jv_parse.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "jv.h" #include "jv_dtoa.h" @@ -419,14 +420,17 @@ static pfunc stream_token(struct jv_parser* p, char ch) { return 0; } -static void tokenadd(struct jv_parser* p, char c) { +static pfunc tokenadd(struct jv_parser* p, char c) { assert(p->tokenpos <= p->tokenlen); if (p->tokenpos >= (p->tokenlen - 1)) { - p->tokenlen = p->tokenlen*2 + 256; + if (p->tokenlen > INT_MAX / 2) + return "Token too long"; + p->tokenlen *= 2; p->tokenbuf = jv_mem_realloc(p->tokenbuf, p->tokenlen); } assert(p->tokenpos < p->tokenlen); p->tokenbuf[p->tokenpos++] = c; + return 0; } static int unhex4(char* hex) { @@ -677,7 +681,7 @@ static pfunc scan(struct jv_parser* p, char ch, jv* out) { } switch (cls) { case LITERAL: - tokenadd(p, ch); + TRY(tokenadd(p, ch)); break; case WHITESPACE: break; @@ -697,7 +701,7 @@ static pfunc scan(struct jv_parser* p, char ch, jv* out) { p->st = JV_PARSER_NORMAL; if (check_done(p, out)) answer = OK; } else { - tokenadd(p, ch); + TRY(tokenadd(p, ch)); if (ch == '\\' && p->st == JV_PARSER_STRING) { p->st = JV_PARSER_STRING_ESCAPE; } else {