From 90ef664e1423602ffdef4f0355679b5b1ed2ca58 Mon Sep 17 00:00:00 2001 From: Roman Tsisyk <roman@tarantool.org> Date: Wed, 21 Jun 2017 21:19:54 +0300 Subject: [PATCH] lua: fix lua_tointeger() usage on 32-bit platforms lua_tointeger() is equivalent to (ptrdiff_t)lua_tonumber(L), which causes precision loss on 32-bit systems when you expect to get a proper uint32_t value. LuaJIT stores numbers as doubles, so lua_tointeger() makes absolutely no sense. Replace lua_tointeger() with lua_tonumber() everywhere except cases when result is converted to int or lua_Integer. Fixes box/indices_any_type.test.lua on i386 and armhf Closes #2459 --- src/box/lua/error.cc | 4 ++-- src/box/lua/index.c | 48 +++++++++++++++++++++---------------------- src/box/lua/misc.cc | 10 ++++----- src/box/lua/net_box.c | 24 +++++++++++----------- src/box/lua/session.c | 2 +- src/box/lua/space.cc | 2 +- src/box/lua/tuple.c | 8 ++++---- src/lua/fiber.c | 4 ++-- src/lua/httpc.c | 8 ++++---- src/lua/utils.c | 2 +- 10 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/box/lua/error.cc b/src/box/lua/error.cc index 1f7f49a224..5b052b63a2 100644 --- a/src/box/lua/error.cc +++ b/src/box/lua/error.cc @@ -58,7 +58,7 @@ luaT_error_raise(lua_State *L) luaT_error(L); return 0; } else if (top >= 2 && lua_type(L, 2) == LUA_TNUMBER) { - code = lua_tointeger(L, 2); + code = lua_tonumber(L, 2); reason = tnt_errcode_desc(code); if (top > 2) { /* Call string.format(reason, ...) to format message */ @@ -80,7 +80,7 @@ luaT_error_raise(lua_State *L) } else if (top == 2 && lua_istable(L, 2)) { /* A special case that rethrows raw error (used by net.box) */ lua_getfield(L, 2, "code"); - code = lua_tointeger(L, -1); + code = lua_tonumber(L, -1); lua_pop(L, 1); lua_getfield(L, 2, "reason"); reason = lua_tostring(L, -1); diff --git a/src/box/lua/index.c b/src/box/lua/index.c index 5015cb2d2f..6dfa64855c 100644 --- a/src/box/lua/index.c +++ b/src/box/lua/index.c @@ -48,7 +48,7 @@ lbox_insert(lua_State *L) if (lua_gettop(L) != 2 || !lua_isnumber(L, 1)) return luaL_error(L, "Usage space:insert(tuple)"); - uint32_t space_id = lua_tointeger(L, 1); + uint32_t space_id = lua_tonumber(L, 1); size_t tuple_len; const char *tuple = lbox_encode_tuple_on_gc(L, 2, &tuple_len); @@ -64,7 +64,7 @@ lbox_replace(lua_State *L) if (lua_gettop(L) != 2 || !lua_isnumber(L, 1)) return luaL_error(L, "Usage space:replace(tuple)"); - uint32_t space_id = lua_tointeger(L, 1); + uint32_t space_id = lua_tonumber(L, 1); size_t tuple_len; const char *tuple = lbox_encode_tuple_on_gc(L, 2, &tuple_len); @@ -82,8 +82,8 @@ lbox_index_update(lua_State *L) (lua_type(L, 4) != LUA_TTABLE && luaT_istuple(L, 4) == NULL)) return luaL_error(L, "Usage index:update(key, ops)"); - uint32_t space_id = lua_tointeger(L, 1); - uint32_t index_id = lua_tointeger(L, 2); + uint32_t space_id = lua_tonumber(L, 1); + uint32_t index_id = lua_tonumber(L, 2); size_t key_len; const char *key = lbox_encode_tuple_on_gc(L, 3, &key_len); size_t ops_len; @@ -104,7 +104,7 @@ lbox_upsert(lua_State *L) (lua_type(L, 3) != LUA_TTABLE && luaT_istuple(L, 3) == NULL)) return luaL_error(L, "Usage space:upsert(tuple_key, ops)"); - uint32_t space_id = lua_tointeger(L, 1); + uint32_t space_id = lua_tonumber(L, 1); size_t tuple_len; const char *tuple = lbox_encode_tuple_on_gc(L, 2, &tuple_len); size_t ops_len; @@ -124,8 +124,8 @@ lbox_index_delete(lua_State *L) (lua_type(L, 3) != LUA_TTABLE && luaT_istuple(L, 3) == NULL)) return luaL_error(L, "Usage space:delete(key)"); - uint32_t space_id = lua_tointeger(L, 1); - uint32_t index_id = lua_tointeger(L, 2); + uint32_t space_id = lua_tonumber(L, 1); + uint32_t index_id = lua_tonumber(L, 2); size_t key_len; const char *key = lbox_encode_tuple_on_gc(L, 3, &key_len); @@ -142,9 +142,9 @@ lbox_index_random(lua_State *L) !lua_isnumber(L, 3)) return luaL_error(L, "Usage index.random(space_id, index_id, rnd)"); - uint32_t space_id = lua_tointeger(L, 1); - uint32_t index_id = lua_tointeger(L, 2); - uint32_t rnd = lua_tointeger(L, 3); + uint32_t space_id = lua_tonumber(L, 1); + uint32_t index_id = lua_tonumber(L, 2); + uint32_t rnd = lua_tonumber(L, 3); struct tuple *tuple; if (box_index_random(space_id, index_id, rnd, &tuple) != 0) @@ -158,8 +158,8 @@ lbox_index_get(lua_State *L) if (lua_gettop(L) != 3 || !lua_isnumber(L, 1) || !lua_isnumber(L, 2)) return luaL_error(L, "Usage index.get(space_id, index_id, key)"); - uint32_t space_id = lua_tointeger(L, 1); - uint32_t index_id = lua_tointeger(L, 2); + uint32_t space_id = lua_tonumber(L, 1); + uint32_t index_id = lua_tonumber(L, 2); size_t key_len; const char *key = lbox_encode_tuple_on_gc(L, 3, &key_len); @@ -175,8 +175,8 @@ lbox_index_min(lua_State *L) if (lua_gettop(L) != 3 || !lua_isnumber(L, 1) || !lua_isnumber(L, 2)) return luaL_error(L, "usage index.min(space_id, index_id, key)"); - uint32_t space_id = lua_tointeger(L, 1); - uint32_t index_id = lua_tointeger(L, 2); + uint32_t space_id = lua_tonumber(L, 1); + uint32_t index_id = lua_tonumber(L, 2); size_t key_len; const char *key = lbox_encode_tuple_on_gc(L, 3, &key_len); @@ -192,8 +192,8 @@ lbox_index_max(lua_State *L) if (lua_gettop(L) != 3 || !lua_isnumber(L, 1) || !lua_isnumber(L, 2)) return luaL_error(L, "usage index.max(space_id, index_id, key)"); - uint32_t space_id = lua_tointeger(L, 1); - uint32_t index_id = lua_tointeger(L, 2); + uint32_t space_id = lua_tonumber(L, 1); + uint32_t index_id = lua_tonumber(L, 2); size_t key_len; const char *key = lbox_encode_tuple_on_gc(L, 3, &key_len); @@ -212,9 +212,9 @@ lbox_index_count(lua_State *L) "iterator, key)"); } - uint32_t space_id = lua_tointeger(L, 1); - uint32_t index_id = lua_tointeger(L, 2); - uint32_t iterator = lua_tointeger(L, 3); + uint32_t space_id = lua_tonumber(L, 1); + uint32_t index_id = lua_tonumber(L, 2); + uint32_t iterator = lua_tonumber(L, 3); size_t key_len; const char *key = lbox_encode_tuple_on_gc(L, 4, &key_len); @@ -246,9 +246,9 @@ lbox_index_iterator(lua_State *L) !lua_isnumber(L, 3)) return luaL_error(L, "usage index.iterator(space_id, index_id, type, key)"); - uint32_t space_id = lua_tointeger(L, 1); - uint32_t index_id = lua_tointeger(L, 2); - uint32_t iterator = lua_tointeger(L, 3); + uint32_t space_id = lua_tonumber(L, 1); + uint32_t index_id = lua_tonumber(L, 2); + uint32_t iterator = lua_tonumber(L, 3); size_t mpkey_len; const char *mpkey = lua_tolstring(L, 4, &mpkey_len); /* Key encoded by Lua */ /* const char *key = lbox_encode_tuple_on_gc(L, 4, key_len); */ @@ -304,8 +304,8 @@ lbox_index_info(lua_State *L) if (lua_gettop(L) != 2 || !lua_isnumber(L, 1) || !lua_isnumber(L, 2)) return luaL_error(L, "usage index.info(space_id, index_id)"); - uint32_t space_id = lua_tointeger(L, 1); - uint32_t index_id = lua_tointeger(L, 2); + uint32_t space_id = lua_tonumber(L, 1); + uint32_t index_id = lua_tonumber(L, 2); struct info_handler info; luaT_info_handler_create(&info, L); diff --git a/src/box/lua/misc.cc b/src/box/lua/misc.cc index ad2c1f4448..c049d95bd0 100644 --- a/src/box/lua/misc.cc +++ b/src/box/lua/misc.cc @@ -80,11 +80,11 @@ lbox_select(lua_State *L) "limit, key)"); } - uint32_t space_id = lua_tointeger(L, 1); - uint32_t index_id = lua_tointeger(L, 2); - int iterator = lua_tointeger(L, 3); - uint32_t offset = lua_tointeger(L, 4); - uint32_t limit = lua_tointeger(L, 5); + uint32_t space_id = lua_tonumber(L, 1); + uint32_t index_id = lua_tonumber(L, 2); + int iterator = lua_tonumber(L, 3); + uint32_t offset = lua_tonumber(L, 4); + uint32_t limit = lua_tonumber(L, 5); size_t key_len; const char *key = lbox_encode_tuple_on_gc(L, 6, &key_len); diff --git a/src/box/lua/net_box.c b/src/box/lua/net_box.c index 266021843d..c112e8ab47 100644 --- a/src/box/lua/net_box.c +++ b/src/box/lua/net_box.c @@ -234,11 +234,11 @@ netbox_encode_select(lua_State *L) luamp_encode_map(cfg, &stream, 6); - uint32_t space_id = lua_tointeger(L, 4); - uint32_t index_id = lua_tointeger(L, 5); + uint32_t space_id = lua_tonumber(L, 4); + uint32_t index_id = lua_tonumber(L, 5); int iterator = lua_tointeger(L, 6); - uint32_t offset = lua_tointeger(L, 7); - uint32_t limit = lua_tointeger(L, 8); + uint32_t offset = lua_tonumber(L, 7); + uint32_t limit = lua_tonumber(L, 8); /* encode space_id */ luamp_encode_uint(cfg, &stream, IPROTO_SPACE_ID); @@ -282,7 +282,7 @@ netbox_encode_insert_or_replace(lua_State *L, uint32_t reqtype) luamp_encode_map(cfg, &stream, 2); /* encode space_id */ - uint32_t space_id = lua_tointeger(L, 4); + uint32_t space_id = lua_tonumber(L, 4); luamp_encode_uint(cfg, &stream, IPROTO_SPACE_ID); luamp_encode_uint(cfg, &stream, space_id); @@ -319,12 +319,12 @@ netbox_encode_delete(lua_State *L) luamp_encode_map(cfg, &stream, 3); /* encode space_id */ - uint32_t space_id = lua_tointeger(L, 4); + uint32_t space_id = lua_tonumber(L, 4); luamp_encode_uint(cfg, &stream, IPROTO_SPACE_ID); luamp_encode_uint(cfg, &stream, space_id); /* encode space_id */ - uint32_t index_id = lua_tointeger(L, 5); + uint32_t index_id = lua_tonumber(L, 5); luamp_encode_uint(cfg, &stream, IPROTO_INDEX_ID); luamp_encode_uint(cfg, &stream, index_id); @@ -349,12 +349,12 @@ netbox_encode_update(lua_State *L) luamp_encode_map(cfg, &stream, 5); /* encode space_id */ - uint32_t space_id = lua_tointeger(L, 4); + uint32_t space_id = lua_tonumber(L, 4); luamp_encode_uint(cfg, &stream, IPROTO_SPACE_ID); luamp_encode_uint(cfg, &stream, space_id); /* encode index_id */ - uint32_t index_id = lua_tointeger(L, 5); + uint32_t index_id = lua_tonumber(L, 5); luamp_encode_uint(cfg, &stream, IPROTO_INDEX_ID); luamp_encode_uint(cfg, &stream, index_id); @@ -389,7 +389,7 @@ netbox_encode_upsert(lua_State *L) luamp_encode_map(cfg, &stream, 4); /* encode space_id */ - uint32_t space_id = lua_tointeger(L, 4); + uint32_t space_id = lua_tonumber(L, 4); luamp_encode_uint(cfg, &stream, IPROTO_SPACE_ID); luamp_encode_uint(cfg, &stream, space_id); @@ -462,7 +462,7 @@ netbox_decode_greeting(lua_State *L) static int netbox_communicate(lua_State *L) { - uint32_t fd = lua_tointeger(L, 1); + uint32_t fd = lua_tonumber(L, 1); const int NETBOX_READAHEAD = 16320; struct ibuf *send_buf = (struct ibuf *) lua_topointer(L, 2); struct ibuf *recv_buf = (struct ibuf *) lua_topointer(L, 3); @@ -475,7 +475,7 @@ netbox_communicate(lua_State *L) if (lua_type(L, 4) == LUA_TSTRING) boundary = lua_tolstring(L, 4, &boundary_len); else - limit = lua_tointeger(L, 4); + limit = lua_tonumber(L, 4); /* timeout */ ev_tstamp timeout = TIMEOUT_INFINITY; diff --git a/src/box/lua/session.c b/src/box/lua/session.c index 7c366868e2..14b41b096c 100644 --- a/src/box/lua/session.c +++ b/src/box/lua/session.c @@ -137,7 +137,7 @@ lbox_session_su(struct lua_State *L) const char *name = lua_tolstring(L, 1, &len); user = user_find_by_name(name, len); } else { - user = user_find(lua_tointeger(L, 1)); + user = user_find(lua_tonumber(L, 1)); } if (user == NULL) luaT_error(L); diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc index 3c35e88984..604cee10c5 100644 --- a/src/box/lua/space.cc +++ b/src/box/lua/space.cc @@ -82,7 +82,7 @@ lbox_space_on_replace(struct lua_State *L) "usage: space:on_replace(function | nil, [function | nil])"); } lua_getfield(L, 1, "id"); /* Get space id. */ - uint32_t id = lua_tointeger(L, lua_gettop(L)); + uint32_t id = lua_tonumber(L, lua_gettop(L)); struct space *space = space_cache_find(id); lua_pop(L, 1); diff --git a/src/box/lua/tuple.c b/src/box/lua/tuple.c index a8669b8c61..ef2cbbb2f7 100644 --- a/src/box/lua/tuple.c +++ b/src/box/lua/tuple.c @@ -140,8 +140,8 @@ lbox_tuple_slice_wrapper(struct lua_State *L) { box_tuple_iterator_t *it = (box_tuple_iterator_t *) lua_topointer(L, 1); - uint32_t start = lua_tointeger(L, 2); - uint32_t end = lua_tointeger(L, 3); + uint32_t start = lua_tonumber(L, 2); + uint32_t end = lua_tonumber(L, 3); assert(end >= start); const char *field; @@ -173,7 +173,7 @@ lbox_tuple_slice(struct lua_State *L) luaL_error(L, "tuple.slice(): bad arguments"); int32_t field_count = box_tuple_field_count(tuple); - offset = lua_tointeger(L, 2); + offset = lua_tonumber(L, 2); if (offset >= 0 && offset < field_count) { start = offset; } else if (offset < 0 && -offset <= field_count) { @@ -183,7 +183,7 @@ lbox_tuple_slice(struct lua_State *L) } if (argc == 2) { - offset = lua_tointeger(L, 3); + offset = lua_tonumber(L, 3); if (offset > 0 && offset <= field_count) { end = offset; } else if (offset < 0 && -offset < field_count) { diff --git a/src/lua/fiber.c b/src/lua/fiber.c index 0c8c305037..4f038ce7a0 100644 --- a/src/lua/fiber.c +++ b/src/lua/fiber.c @@ -156,7 +156,7 @@ lbox_checkfiber(struct lua_State *L, int index) { uint32_t fid; if (lua_type(L, index) == LUA_TNUMBER) { - fid = lua_tointeger(L, index); + fid = lua_tonumber(L, index); } else { fid = *(uint32_t *) luaL_checkudata(L, index, fiberlib_name); } @@ -433,7 +433,7 @@ lbox_fiber_find(struct lua_State *L) { if (lua_gettop(L) != 1) luaL_error(L, "fiber.find(id): bad arguments"); - int fid = lua_tointeger(L, -1); + int fid = lua_tonumber(L, -1); struct fiber *f = fiber_find(fid); if (f) lbox_pushfiber(L, f->fid); diff --git a/src/lua/httpc.c b/src/lua/httpc.c index 17e348fba6..65303e6051 100644 --- a/src/lua/httpc.c +++ b/src/lua/httpc.c @@ -127,12 +127,12 @@ luaT_httpc_request(lua_State *L) lua_getfield(L, 5, "keepalive_idle"); if (!lua_isnil(L, -1)) - keepalive_idle = (long) lua_tointeger(L, -1); + keepalive_idle = (long) lua_tonumber(L, -1); lua_pop(L, 1); lua_getfield(L, 5, "keepalive_interval"); if (!lua_isnil(L, -1)) - keepalive_interval = (long) lua_tointeger(L, -1); + keepalive_interval = (long) lua_tonumber(L, -1); lua_pop(L, 1); if (httpc_set_keepalive(req, keepalive_idle, @@ -144,13 +144,13 @@ luaT_httpc_request(lua_State *L) lua_getfield(L, 5, "low_speed_limit"); if (!lua_isnil(L, -1)) httpc_set_low_speed_limit(req, - (long) lua_tointeger(L, -1)); + (long) lua_tonumber(L, -1)); lua_pop(L, 1); lua_getfield(L, 5, "low_speed_time"); if (!lua_isnil(L, -1)) httpc_set_low_speed_time(req, - (long) lua_tointeger(L, -1)); + (long) lua_tonumber(L, -1)); lua_pop(L, 1); lua_getfield(L, 5, "timeout"); diff --git a/src/lua/utils.c b/src/lua/utils.c index cc66b2c6ed..b40abf54f5 100644 --- a/src/lua/utils.c +++ b/src/lua/utils.c @@ -752,7 +752,7 @@ luaL_convertint64(lua_State *L, int idx, bool unsignd, int64_t *result) */ switch (lua_type(L, idx)) { case LUA_TNUMBER: - *result = lua_tointeger(L, idx); + *result = lua_tonumber(L, idx); return 0; case LUA_TCDATA: cdata = luaL_checkcdata(L, 1, &ctypeid); -- GitLab