diff options
| author | James McCoy <jamessan@jamessan.com> | 2025-10-29 22:35:41 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-30 10:35:41 +0800 |
| commit | 35bac3c9741af54d121a8ef4e04ff20755943444 (patch) | |
| tree | 4322865a6ba0c944c77a568157cd962dc1aa7b6c | |
| parent | cd944c13a94713a984c4593fc3639e49ae59b91d (diff) | |
| download | lua-cjson-master.tar.gz lua-cjson-master.tar.bz2 lua-cjson-master.zip | |
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.c | 10 |
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) | |||
| 1190 | static void json_next_number_token(json_parse_t *json, json_token_t *token) | 1190 | static 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 | ||
