diff options
-rw-r--r-- | src/scripting.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/scripting.c b/src/scripting.c index db1e4d4b5..153b94240 100644 --- a/src/scripting.c +++ b/src/scripting.c @@ -125,6 +125,16 @@ void sha1hex(char *digest, char *script, size_t len) { */ char *redisProtocolToLuaType(lua_State *lua, char* reply) { + + if (!lua_checkstack(lua, 5)) { + /* + * Increase the Lua stack if needed, to make sure there is enough room + * to push 5 elements to the stack. On failure, exit with panic. + * Notice that we need, in the worst case, 5 elements because redisProtocolToLuaType_Aggregate + * might push 5 elements to the Lua stack.*/ + serverPanic("lua stack limit reach when parsing redis.call reply"); + } + char *p = reply; switch(*p) { @@ -275,6 +285,17 @@ void luaSortArray(lua_State *lua) { * ------------------------------------------------------------------------- */ void luaReplyToRedisReply(client *c, lua_State *lua) { + + if (!lua_checkstack(lua, 4)) { + /* Increase the Lua stack if needed to make sure there is enough room + * to push 4 elements to the stack. On failure, return error. + * Notice that we need, in the worst case, 4 elements because returning a map might + * require push 4 elements to the Lua stack.*/ + addReplyErrorFormat(c, "reached lua stack limit"); + lua_pop(lua,1); // pop the element from the stack + return; + } + int t = lua_type(lua,-1); switch(t) { @@ -292,6 +313,9 @@ void luaReplyToRedisReply(client *c, lua_State *lua) { * Error are returned as a single element table with 'err' field. * Status replies are returned as single element table with 'ok' * field. */ + + /* Handle error reply. */ + /* we took care of the stack size on function start */ lua_pushstring(lua,"err"); lua_gettable(lua,-2); t = lua_type(lua,-1); @@ -320,6 +344,7 @@ void luaReplyToRedisReply(client *c, lua_State *lua) { lua_pop(lua,1); /* Discard the 'ok' field value we popped */ while(1) { + /* we took care of the stack size on function start */ lua_pushnumber(lua,j++); lua_gettable(lua,-2); t = lua_type(lua,-1); @@ -2243,6 +2268,17 @@ void ldbEval(lua_State *lua, sds *argv, int argc) { void ldbRedis(lua_State *lua, sds *argv, int argc) { int j, saved_rc = server.lua_replicate_commands; + if (!lua_checkstack(lua, argc + 1)) { + /* Increase the Lua stack if needed to make sure there is enough room + * to push 'argc + 1' elements to the stack. On failure, return error. + * Notice that we need, in worst case, 'argc + 1' elements because we push all the arguments + * given by the user (without the first argument) and we also push the 'redis' global table and + * 'redis.call' function so: + * (1 (redis table)) + (1 (redis.call function)) + (argc - 1 (all arguments without the first)) = argc + 1*/ + ldbLogRedisReply("max lua stack reached"); + return; + } + lua_getglobal(lua,"redis"); lua_pushstring(lua,"call"); lua_gettable(lua,-2); /* Stack: redis, redis.call */ |