From 35bac3c9741af54d121a8ef4e04ff20755943444 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Wed, 29 Oct 2025 22:35:41 -0400 Subject: bugfix: fix truncation of decoded numbers outside lua_Integer's range (#116) json_next_number_token stores the `long long` return value from `stroll` in a `lua_Integer` (which is typically a typedef for `ptrdiff_t`). On 32-bit platforms, this ends up storing an 8-byte number into a 4-byte variable, truncating the value. Instead, store the converted value in a temporary `long long` variable so we can detect the scenario and decode into a `lua_Number`. Signed-off-by: James McCoy --- lua_cjson.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'lua_cjson.c') diff --git a/lua_cjson.c b/lua_cjson.c index bbd8eff..93b81e6 100644 --- a/lua_cjson.c +++ b/lua_cjson.c @@ -1190,7 +1190,7 @@ static int json_is_invalid_number(json_parse_t *json) static void json_next_number_token(json_parse_t *json, json_token_t *token) { char *endptr; - token->value.integer = strtoll(json->ptr, &endptr, 10); + long long tmpval = strtoll(json->ptr, &endptr, 10); if (json->ptr == endptr || *endptr == '.' || *endptr == 'e' || *endptr == 'E' || *endptr == 'x') { token->type = T_NUMBER; @@ -1199,8 +1199,16 @@ static void json_next_number_token(json_parse_t *json, json_token_t *token) json_set_token_error(token, json, "invalid number"); return; } + } else if (tmpval > PTRDIFF_MAX || tmpval < PTRDIFF_MIN) { + /* Typical Lua builds typedef ptrdiff_t to lua_Integer. If tmpval is + * outside the range of that type, we need to use T_NUMBER to avoid + * truncation. + */ + token->type = T_NUMBER; + token->value.number = tmpval; } else { token->type = T_INTEGER; + token->value.integer = tmpval; } json->ptr = endptr; /* Skip the processed number */ -- cgit v1.2.3-55-g6feb