From 1b5d24eb2b8f5ef26c6067c895fcb5ebb89a991b Mon Sep 17 00:00:00 2001 From: antirez Date: Mon, 9 Nov 2015 11:43:18 +0100 Subject: [PATCH] Scripting: fix redis.call() error reporting. Arguments arity and arguments type error of redis.call() were not reported correctly to Lua, so the command acted in this regard like redis.pcall(), but just for two commands. Redis.call() should always raise errors instead. --- src/scripting.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/scripting.c b/src/scripting.c index 339f6eef1..54f0172d1 100644 --- a/src/scripting.c +++ b/src/scripting.c @@ -182,6 +182,11 @@ char *redisProtocolToLuaType_MultiBulk(lua_State *lua, char *reply) { return p; } +/* This function is used in order to push an error on the Lua stack in the + * format used by redis.pcall to return errors, which is a lua table + * with a single "err" field set to the error string. Note that this + * table is never a valid reply by proper commands, since the returned + * tables are otherwise always indexed by integers, never by strings. */ void luaPushError(lua_State *lua, char *error) { lua_Debug dbg; @@ -200,6 +205,16 @@ void luaPushError(lua_State *lua, char *error) { lua_settable(lua,-3); } +/* In case the error set into the Lua stack by luaPushError() was generated + * by the non-error-trapping version of redis.pcall(), which is redis.call(), + * this function will raise the Lua error so that the execution of the + * script will be halted. */ +int luaRaiseError(lua_State *lua) { + lua_pushstring(lua,"err"); + lua_gettable(lua,-2); + return lua_error(lua); +} + /* Sort the array currently in the stack. We do this to make the output * of commands like KEYS or SMEMBERS something deterministic when called * from Lua (to play well with AOf/replication). @@ -338,7 +353,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { luaPushError(lua, "Please specify at least one argument for redis.call()"); inuse--; - return 1; + return raise_error ? luaRaiseError(lua) : 1; } /* Build the arguments vector */ @@ -390,7 +405,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { luaPushError(lua, "Lua redis() command arguments must be strings or integers"); inuse--; - return 1; + return raise_error ? luaRaiseError(lua) : 1; } /* Setup our fake client for command execution */ @@ -562,10 +577,8 @@ cleanup: /* If we are here we should have an error in the stack, in the * form of a table with an "err" field. Extract the string to * return the plain error. */ - lua_pushstring(lua,"err"); - lua_gettable(lua,-2); inuse--; - return lua_error(lua); + return luaRaiseError(lua); } inuse--; return 1; -- GitLab