luci-lib-jsonc: improve handling of integral numeric values

Properly deal with integral numeric values exceeding the int32_t range
by replacing the cast logic with more fine grained checks:

 - Lua numbers which are integers in the first place are directly converted
   to JSON integers

 - Finite double Lua numbers which are integral are converted to JSON
   integer values

 - All other numeric values are converted to JSON doubles

This should bring the handling of large integral value in line with the
documented behavior of turning non-fractional Lua numbers into JSON
integers.

Fixes: #6647
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
Jo-Philipp Wich 2023-10-25 22:35:08 +02:00
parent 425bcfcb52
commit efcd487978

View file

@ -294,7 +294,7 @@ static bool visited(struct seen **sp, const void *ptr) {
static struct json_object * _lua_to_json_rec(lua_State *L, int index, static struct json_object * _lua_to_json_rec(lua_State *L, int index,
struct seen **seen) struct seen **seen)
{ {
lua_Number nd, ni; lua_Number nd;
struct json_object *obj; struct json_object *obj;
const char *key; const char *key;
int i, max; int i, max;
@ -364,10 +364,12 @@ static struct json_object * _lua_to_json_rec(lua_State *L, int index,
return json_object_new_boolean(lua_toboolean(L, index)); return json_object_new_boolean(lua_toboolean(L, index));
case LUA_TNUMBER: case LUA_TNUMBER:
nd = lua_tonumber(L, index); if (lua_isinteger(L, index))
ni = lua_tointeger(L, index); return json_object_new_int64(lua_tointeger(L, index));
if (nd == ni) nd = lua_tonumber(L, index);
if (isfinite(nd) && trunc(nd) == nd)
return json_object_new_int64(nd); return json_object_new_int64(nd);
return json_object_new_double(nd); return json_object_new_double(nd);