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