aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames McCoy <jamessan@jamessan.com>2025-10-29 22:35:41 -0400
committerGitHub <noreply@github.com>2025-10-30 10:35:41 +0800
commit35bac3c9741af54d121a8ef4e04ff20755943444 (patch)
tree4322865a6ba0c944c77a568157cd962dc1aa7b6c
parentcd944c13a94713a984c4593fc3639e49ae59b91d (diff)
downloadlua-cjson-master.tar.gz
lua-cjson-master.tar.bz2
lua-cjson-master.zip
bugfix: fix truncation of decoded numbers outside lua_Integer's range (#116)HEADmaster
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 <jamessan@jamessan.com>
-rw-r--r--lua_cjson.c10
1 files changed, 9 insertions, 1 deletions
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)
1190static void json_next_number_token(json_parse_t *json, json_token_t *token) 1190static void json_next_number_token(json_parse_t *json, json_token_t *token)
1191{ 1191{
1192 char *endptr; 1192 char *endptr;
1193 token->value.integer = strtoll(json->ptr, &endptr, 10); 1193 long long tmpval = strtoll(json->ptr, &endptr, 10);
1194 if (json->ptr == endptr || *endptr == '.' || *endptr == 'e' || 1194 if (json->ptr == endptr || *endptr == '.' || *endptr == 'e' ||
1195 *endptr == 'E' || *endptr == 'x') { 1195 *endptr == 'E' || *endptr == 'x') {
1196 token->type = T_NUMBER; 1196 token->type = T_NUMBER;
@@ -1199,8 +1199,16 @@ static void json_next_number_token(json_parse_t *json, json_token_t *token)
1199 json_set_token_error(token, json, "invalid number"); 1199 json_set_token_error(token, json, "invalid number");
1200 return; 1200 return;
1201 } 1201 }
1202 } else if (tmpval > PTRDIFF_MAX || tmpval < PTRDIFF_MIN) {
1203 /* Typical Lua builds typedef ptrdiff_t to lua_Integer. If tmpval is
1204 * outside the range of that type, we need to use T_NUMBER to avoid
1205 * truncation.
1206 */
1207 token->type = T_NUMBER;
1208 token->value.number = tmpval;
1202 } else { 1209 } else {
1203 token->type = T_INTEGER; 1210 token->type = T_INTEGER;
1211 token->value.integer = tmpval;
1204 } 1212 }
1205 json->ptr = endptr; /* Skip the processed number */ 1213 json->ptr = endptr; /* Skip the processed number */
1206 1214