From: Josef 'Jeff' Sipek Date: Thu, 4 Mar 2021 21:21:07 +0000 (-0500) Subject: lib-lua: Implement a Lua 5.1 & 5.2 compatibility wrapper for lua_isinteger X-Git-Tag: 2.3.15~294 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=32e963965c6ba68a141ec5bd68f6cd3c14f0736a;p=thirdparty%2Fdovecot%2Fcore.git lib-lua: Implement a Lua 5.1 & 5.2 compatibility wrapper for lua_isinteger --- diff --git a/src/lib-lua/dlua-compat.c b/src/lib-lua/dlua-compat.c index f057b09c31..d50d2d53f9 100644 --- a/src/lib-lua/dlua-compat.c +++ b/src/lib-lua/dlua-compat.c @@ -25,6 +25,27 @@ void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { } #endif +#ifndef HAVE_LUA_ISINTEGER +# if LUA_VERSION_NUM >= 503 +# error "Lua 5.3+ should have lua_isinteger()" +# endif +/* + * Lua 5.3 added lua_isinteger() which tells us whether or not the input is + * an integer. In Lua 5.1 and 5.2, we have to emulate it. + */ +int lua_isinteger(lua_State *L, int idx) +{ + int isnum; + + if (lua_type(L, idx) != LUA_TNUMBER) + return 0; + + (void) lua_tointegerx(L, idx, &isnum); + + return isnum; +} +#endif + #ifndef HAVE_LUA_TOINTEGERX # if LUA_VERSION_NUM >= 502 # error "Lua 5.2+ should have lua_tointegerx()" diff --git a/src/lib-lua/dlua-compat.h b/src/lib-lua/dlua-compat.h index d35f474597..f1e564d5d0 100644 --- a/src/lib-lua/dlua-compat.h +++ b/src/lib-lua/dlua-compat.h @@ -5,6 +5,18 @@ * In general, make whatever Lua version we have behave more like Lua 5.3. */ +#ifndef HAVE_LUA_ISINTEGER +/* + * Lua 5.3 can actually keep track of intergers vs. numbers. As a + * consequence, lua_isinteger() tells us if the internal representation of + * the number is an integer (vs. a number). In previous versions, there was + * no way to check for this and our compatibility wrapper is not quite + * capable of matching the 5.3 behavior exactly. Therefore, it returns 1 + * when the number is representable as an integer instead. + */ +int lua_isinteger(lua_State *L, int idx); +#endif + #ifndef HAVE_LUA_TOINTEGERX /* * Lua 5.2 and 5.3 both have lua_tointegerx(), but their behavior is subtly diff --git a/src/lib-lua/test-lua.c b/src/lib-lua/test-lua.c index 607f275d93..5e7e8e5346 100644 --- a/src/lib-lua/test-lua.c +++ b/src/lib-lua/test-lua.c @@ -66,6 +66,7 @@ static void test_lua(void) /* check lua_tointegerx against top-of-stack item */ static void check_tointegerx_compat(lua_State *L, int expected_isnum, + int expected_isint, lua_Integer expected_value) { lua_Integer value; @@ -77,10 +78,12 @@ static void check_tointegerx_compat(lua_State *L, int expected_isnum, if (isnum == 1) test_assert(value == expected_value); + test_assert(lua_isinteger(L, -1) == expected_isint); + lua_pop(L, 1); } -static void test_compat_tointegerx(void) +static void test_compat_tointegerx_and_isinteger(void) { static const struct { const char *input; @@ -155,25 +158,35 @@ static void test_compat_tointegerx(void) const char *error; size_t i; - test_begin("lua compat tostringx"); + test_begin("lua compat tostringx/isinteger"); test_assert(dlua_script_create_string("", &script, NULL, &error) == 0); for (i = 0; i < N_ELEMENTS(str_tests); i++) { lua_pushstring(script->L, str_tests[i].input); - check_tointegerx_compat(script->L, str_tests[i].isnum, + check_tointegerx_compat(script->L, str_tests[i].isnum, 0, str_tests[i].output); } for (i = 0; i < N_ELEMENTS(num_tests); i++) { + int isint; + + /* See lua_isinteger() comment in dlua-compat.h */ +#if LUA_VERSION_NUM == 503 + isint = 0; +#else + isint = num_tests[i].isnum; +#endif + lua_pushnumber(script->L, num_tests[i].input); check_tointegerx_compat(script->L, num_tests[i].isnum, + isint, num_tests[i].output); } for (i = 0; i < N_ELEMENTS(int_tests); i++) { lua_pushinteger(script->L, int_tests[i].input); - check_tointegerx_compat(script->L, 1, + check_tointegerx_compat(script->L, 1, 1, int_tests[i].output); } @@ -185,7 +198,7 @@ static void test_compat_tointegerx(void) int main(void) { void (*tests[])(void) = { test_lua, - test_compat_tointegerx, + test_compat_tointegerx_and_isinteger, NULL };