xref: /redis-3.2.3/src/scripting.c (revision 9bb91d19)
1 /*
2  * Copyright (c) 2009-2012, Salvatore Sanfilippo <antirez at gmail dot com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *   * Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *   * Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  *   * Neither the name of Redis nor the names of its contributors may be used
14  *     to endorse or promote products derived from this software without
15  *     specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "redis.h"
31 #include "sha1.h"
32 #include "rand.h"
33 
34 #include <lua.h>
35 #include <lauxlib.h>
36 #include <lualib.h>
37 #include <ctype.h>
38 #include <math.h>
39 
40 char *redisProtocolToLuaType_Int(lua_State *lua, char *reply);
41 char *redisProtocolToLuaType_Bulk(lua_State *lua, char *reply);
42 char *redisProtocolToLuaType_Status(lua_State *lua, char *reply);
43 char *redisProtocolToLuaType_Error(lua_State *lua, char *reply);
44 char *redisProtocolToLuaType_MultiBulk(lua_State *lua, char *reply);
45 int redis_math_random (lua_State *L);
46 int redis_math_randomseed (lua_State *L);
47 void sha1hex(char *digest, char *script, size_t len);
48 
49 /* Take a Redis reply in the Redis protocol format and convert it into a
50  * Lua type. Thanks to this function, and the introduction of not connected
51  * clients, it is trivial to implement the redis() lua function.
52  *
53  * Basically we take the arguments, execute the Redis command in the context
54  * of a non connected client, then take the generated reply and convert it
55  * into a suitable Lua type. With this trick the scripting feature does not
56  * need the introduction of a full Redis internals API. Basically the script
57  * is like a normal client that bypasses all the slow I/O paths.
58  *
59  * Note: in this function we do not do any sanity check as the reply is
60  * generated by Redis directly. This allows us to go faster.
61  * The reply string can be altered during the parsing as it is discarded
62  * after the conversion is completed.
63  *
64  * Errors are returned as a table with a single 'err' field set to the
65  * error string.
66  */
67 
68 char *redisProtocolToLuaType(lua_State *lua, char* reply) {
69     char *p = reply;
70 
71     switch(*p) {
72     case ':':
73         p = redisProtocolToLuaType_Int(lua,reply);
74         break;
75     case '$':
76         p = redisProtocolToLuaType_Bulk(lua,reply);
77         break;
78     case '+':
79         p = redisProtocolToLuaType_Status(lua,reply);
80         break;
81     case '-':
82         p = redisProtocolToLuaType_Error(lua,reply);
83         break;
84     case '*':
85         p = redisProtocolToLuaType_MultiBulk(lua,reply);
86         break;
87     }
88     return p;
89 }
90 
91 char *redisProtocolToLuaType_Int(lua_State *lua, char *reply) {
92     char *p = strchr(reply+1,'\r');
93     long long value;
94 
95     string2ll(reply+1,p-reply-1,&value);
96     lua_pushnumber(lua,(lua_Number)value);
97     return p+2;
98 }
99 
100 char *redisProtocolToLuaType_Bulk(lua_State *lua, char *reply) {
101     char *p = strchr(reply+1,'\r');
102     long long bulklen;
103 
104     string2ll(reply+1,p-reply-1,&bulklen);
105     if (bulklen == -1) {
106         lua_pushboolean(lua,0);
107         return p+2;
108     } else {
109         lua_pushlstring(lua,p+2,bulklen);
110         return p+2+bulklen+2;
111     }
112 }
113 
114 char *redisProtocolToLuaType_Status(lua_State *lua, char *reply) {
115     char *p = strchr(reply+1,'\r');
116 
117     lua_newtable(lua);
118     lua_pushstring(lua,"ok");
119     lua_pushlstring(lua,reply+1,p-reply-1);
120     lua_settable(lua,-3);
121     return p+2;
122 }
123 
124 char *redisProtocolToLuaType_Error(lua_State *lua, char *reply) {
125     char *p = strchr(reply+1,'\r');
126 
127     lua_newtable(lua);
128     lua_pushstring(lua,"err");
129     lua_pushlstring(lua,reply+1,p-reply-1);
130     lua_settable(lua,-3);
131     return p+2;
132 }
133 
134 char *redisProtocolToLuaType_MultiBulk(lua_State *lua, char *reply) {
135     char *p = strchr(reply+1,'\r');
136     long long mbulklen;
137     int j = 0;
138 
139     string2ll(reply+1,p-reply-1,&mbulklen);
140     p += 2;
141     if (mbulklen == -1) {
142         lua_pushboolean(lua,0);
143         return p;
144     }
145     lua_newtable(lua);
146     for (j = 0; j < mbulklen; j++) {
147         lua_pushnumber(lua,j+1);
148         p = redisProtocolToLuaType(lua,p);
149         lua_settable(lua,-3);
150     }
151     return p;
152 }
153 
154 void luaPushError(lua_State *lua, char *error) {
155     lua_Debug dbg;
156 
157     lua_newtable(lua);
158     lua_pushstring(lua,"err");
159 
160     /* Attempt to figure out where this function was called, if possible */
161     if(lua_getstack(lua, 1, &dbg) && lua_getinfo(lua, "nSl", &dbg)) {
162         sds msg = sdscatprintf(sdsempty(), "%s: %d: %s",
163             dbg.source, dbg.currentline, error);
164         lua_pushstring(lua, msg);
165         sdsfree(msg);
166     } else {
167         lua_pushstring(lua, error);
168     }
169     lua_settable(lua,-3);
170 }
171 
172 /* Sort the array currently in the stack. We do this to make the output
173  * of commands like KEYS or SMEMBERS something deterministic when called
174  * from Lua (to play well with AOf/replication).
175  *
176  * The array is sorted using table.sort itself, and assuming all the
177  * list elements are strings. */
178 void luaSortArray(lua_State *lua) {
179     /* Initial Stack: array */
180     lua_getglobal(lua,"table");
181     lua_pushstring(lua,"sort");
182     lua_gettable(lua,-2);       /* Stack: array, table, table.sort */
183     lua_pushvalue(lua,-3);      /* Stack: array, table, table.sort, array */
184     if (lua_pcall(lua,1,0,0)) {
185         /* Stack: array, table, error */
186 
187         /* We are not interested in the error, we assume that the problem is
188          * that there are 'false' elements inside the array, so we try
189          * again with a slower function but able to handle this case, that
190          * is: table.sort(table, __redis__compare_helper) */
191         lua_pop(lua,1);             /* Stack: array, table */
192         lua_pushstring(lua,"sort"); /* Stack: array, table, sort */
193         lua_gettable(lua,-2);       /* Stack: array, table, table.sort */
194         lua_pushvalue(lua,-3);      /* Stack: array, table, table.sort, array */
195         lua_getglobal(lua,"__redis__compare_helper");
196         /* Stack: array, table, table.sort, array, __redis__compare_helper */
197         lua_call(lua,2,0);
198     }
199     /* Stack: array (sorted), table */
200     lua_pop(lua,1);             /* Stack: array (sorted) */
201 }
202 
203 int luaRedisGenericCommand(lua_State *lua, int raise_error) {
204     int j, argc = lua_gettop(lua);
205     struct redisCommand *cmd;
206     robj **argv;
207     redisClient *c = server.lua_client;
208     sds reply;
209 
210     /* Require at least one argument */
211     if (argc == 0) {
212         luaPushError(lua,
213             "Please specify at least one argument for redis.call()");
214         return 1;
215     }
216 
217     /* Build the arguments vector */
218     argv = zmalloc(sizeof(robj*)*argc);
219     for (j = 0; j < argc; j++) {
220         if (!lua_isstring(lua,j+1)) break;
221         argv[j] = createStringObject((char*)lua_tostring(lua,j+1),
222                                      lua_strlen(lua,j+1));
223     }
224 
225     /* Check if one of the arguments passed by the Lua script
226      * is not a string or an integer (lua_isstring() return true for
227      * integers as well). */
228     if (j != argc) {
229         j--;
230         while (j >= 0) {
231             decrRefCount(argv[j]);
232             j--;
233         }
234         zfree(argv);
235         luaPushError(lua,
236             "Lua redis() command arguments must be strings or integers");
237         return 1;
238     }
239 
240     /* Setup our fake client for command execution */
241     c->argv = argv;
242     c->argc = argc;
243 
244     /* Command lookup */
245     cmd = lookupCommand(argv[0]->ptr);
246     if (!cmd || ((cmd->arity > 0 && cmd->arity != argc) ||
247                    (argc < -cmd->arity)))
248     {
249         if (cmd)
250             luaPushError(lua,
251                 "Wrong number of args calling Redis command From Lua script");
252         else
253             luaPushError(lua,"Unknown Redis command called from Lua script");
254         goto cleanup;
255     }
256 
257     /* There are commands that are not allowed inside scripts. */
258     if (cmd->flags & REDIS_CMD_NOSCRIPT) {
259         luaPushError(lua, "This Redis command is not allowed from scripts");
260         goto cleanup;
261     }
262 
263     /* Write commands are forbidden against read-only slaves, or if a
264      * command marked as non-deterministic was already called in the context
265      * of this script. */
266     if (cmd->flags & REDIS_CMD_WRITE) {
267         if (server.lua_random_dirty) {
268             luaPushError(lua,
269                 "Write commands not allowed after non deterministic commands");
270             goto cleanup;
271         } else if (server.masterhost && server.repl_slave_ro &&
272                    !server.loading &&
273                    !(server.lua_caller->flags & REDIS_MASTER))
274         {
275             luaPushError(lua, shared.roslaveerr->ptr);
276             goto cleanup;
277         } else if (server.stop_writes_on_bgsave_err &&
278                    server.saveparamslen > 0 &&
279                    server.lastbgsave_status == REDIS_ERR)
280         {
281             luaPushError(lua, shared.bgsaveerr->ptr);
282             goto cleanup;
283         }
284     }
285 
286     /* If we reached the memory limit configured via maxmemory, commands that
287      * could enlarge the memory usage are not allowed, but only if this is the
288      * first write in the context of this script, otherwise we can't stop
289      * in the middle. */
290     if (server.maxmemory && server.lua_write_dirty == 0 &&
291         (cmd->flags & REDIS_CMD_DENYOOM))
292     {
293         if (freeMemoryIfNeeded() == REDIS_ERR) {
294             luaPushError(lua, shared.oomerr->ptr);
295             goto cleanup;
296         }
297     }
298 
299     if (cmd->flags & REDIS_CMD_RANDOM) server.lua_random_dirty = 1;
300     if (cmd->flags & REDIS_CMD_WRITE) server.lua_write_dirty = 1;
301 
302     /* Run the command */
303     c->cmd = cmd;
304     call(c,REDIS_CALL_SLOWLOG | REDIS_CALL_STATS);
305 
306     /* Convert the result of the Redis command into a suitable Lua type.
307      * The first thing we need is to create a single string from the client
308      * output buffers. */
309     reply = sdsempty();
310     if (c->bufpos) {
311         reply = sdscatlen(reply,c->buf,c->bufpos);
312         c->bufpos = 0;
313     }
314     while(listLength(c->reply)) {
315         robj *o = listNodeValue(listFirst(c->reply));
316 
317         reply = sdscatlen(reply,o->ptr,sdslen(o->ptr));
318         listDelNode(c->reply,listFirst(c->reply));
319     }
320     if (raise_error && reply[0] != '-') raise_error = 0;
321     redisProtocolToLuaType(lua,reply);
322     /* Sort the output array if needed, assuming it is a non-null multi bulk
323      * reply as expected. */
324     if ((cmd->flags & REDIS_CMD_SORT_FOR_SCRIPT) &&
325         (reply[0] == '*' && reply[1] != '-')) {
326             luaSortArray(lua);
327     }
328     sdsfree(reply);
329     c->reply_bytes = 0;
330 
331 cleanup:
332     /* Clean up. Command code may have changed argv/argc so we use the
333      * argv/argc of the client instead of the local variables. */
334     for (j = 0; j < c->argc; j++)
335         decrRefCount(c->argv[j]);
336     zfree(c->argv);
337 
338     if (raise_error) {
339         /* If we are here we should have an error in the stack, in the
340          * form of a table with an "err" field. Extract the string to
341          * return the plain error. */
342         lua_pushstring(lua,"err");
343         lua_gettable(lua,-2);
344         return lua_error(lua);
345     }
346     return 1;
347 }
348 
349 int luaRedisCallCommand(lua_State *lua) {
350     return luaRedisGenericCommand(lua,1);
351 }
352 
353 int luaRedisPCallCommand(lua_State *lua) {
354     return luaRedisGenericCommand(lua,0);
355 }
356 
357 /* This adds redis.sha1hex(string) to Lua scripts using the same hashing
358  * function used for sha1ing lua scripts. */
359 int luaRedisSha1hexCommand(lua_State *lua) {
360     int argc = lua_gettop(lua);
361     char digest[41];
362     size_t len;
363     char *s;
364 
365     if (argc != 1) {
366         luaPushError(lua, "wrong number of arguments");
367         return 1;
368     }
369 
370     s = (char*)lua_tolstring(lua,1,&len);
371     sha1hex(digest,s,len);
372     lua_pushstring(lua,digest);
373     return 1;
374 }
375 
376 /* Returns a table with a single field 'field' set to the string value
377  * passed as argument. This helper function is handy when returning
378  * a Redis Protocol error or status reply from Lua:
379  *
380  * return redis.error_reply("ERR Some Error")
381  * return redis.status_reply("ERR Some Error")
382  */
383 int luaRedisReturnSingleFieldTable(lua_State *lua, char *field) {
384     if (lua_gettop(lua) != 1 || lua_type(lua,-1) != LUA_TSTRING) {
385         luaPushError(lua, "wrong number or type of arguments");
386         return 1;
387     }
388 
389     lua_newtable(lua);
390     lua_pushstring(lua, field);
391     lua_pushvalue(lua, -3);
392     lua_settable(lua, -3);
393     return 1;
394 }
395 
396 int luaRedisErrorReplyCommand(lua_State *lua) {
397     return luaRedisReturnSingleFieldTable(lua,"err");
398 }
399 
400 int luaRedisStatusReplyCommand(lua_State *lua) {
401     return luaRedisReturnSingleFieldTable(lua,"ok");
402 }
403 
404 int luaLogCommand(lua_State *lua) {
405     int j, argc = lua_gettop(lua);
406     int level;
407     sds log;
408 
409     if (argc < 2) {
410         luaPushError(lua, "redis.log() requires two arguments or more.");
411         return 1;
412     } else if (!lua_isnumber(lua,-argc)) {
413         luaPushError(lua, "First argument must be a number (log level).");
414         return 1;
415     }
416     level = lua_tonumber(lua,-argc);
417     if (level < REDIS_DEBUG || level > REDIS_WARNING) {
418         luaPushError(lua, "Invalid debug level.");
419         return 1;
420     }
421 
422     /* Glue together all the arguments */
423     log = sdsempty();
424     for (j = 1; j < argc; j++) {
425         size_t len;
426         char *s;
427 
428         s = (char*)lua_tolstring(lua,(-argc)+j,&len);
429         if (s) {
430             if (j != 1) log = sdscatlen(log," ",1);
431             log = sdscatlen(log,s,len);
432         }
433     }
434     redisLogRaw(level,log);
435     sdsfree(log);
436     return 0;
437 }
438 
439 void luaMaskCountHook(lua_State *lua, lua_Debug *ar) {
440     long long elapsed;
441     REDIS_NOTUSED(ar);
442     REDIS_NOTUSED(lua);
443 
444     elapsed = (ustime()/1000) - server.lua_time_start;
445     if (elapsed >= server.lua_time_limit && server.lua_timedout == 0) {
446         redisLog(REDIS_WARNING,"Lua slow script detected: still in execution after %lld milliseconds. You can try killing the script using the SCRIPT KILL command.",elapsed);
447         server.lua_timedout = 1;
448         /* Once the script timeouts we reenter the event loop to permit others
449          * to call SCRIPT KILL or SHUTDOWN NOSAVE if needed. For this reason
450          * we need to mask the client executing the script from the event loop.
451          * If we don't do that the client may disconnect and could no longer be
452          * here when the EVAL command will return. */
453          aeDeleteFileEvent(server.el, server.lua_caller->fd, AE_READABLE);
454     }
455     if (server.lua_timedout)
456         aeProcessEvents(server.el, AE_FILE_EVENTS|AE_DONT_WAIT);
457     if (server.lua_kill) {
458         redisLog(REDIS_WARNING,"Lua script killed by user with SCRIPT KILL.");
459         lua_pushstring(lua,"Script killed by user with SCRIPT KILL...");
460         lua_error(lua);
461     }
462 }
463 
464 void luaLoadLib(lua_State *lua, const char *libname, lua_CFunction luafunc) {
465   lua_pushcfunction(lua, luafunc);
466   lua_pushstring(lua, libname);
467   lua_call(lua, 1, 0);
468 }
469 
470 LUALIB_API int (luaopen_cjson) (lua_State *L);
471 LUALIB_API int (luaopen_struct) (lua_State *L);
472 LUALIB_API int (luaopen_cmsgpack) (lua_State *L);
473 
474 void luaLoadLibraries(lua_State *lua) {
475     luaLoadLib(lua, "", luaopen_base);
476     luaLoadLib(lua, LUA_TABLIBNAME, luaopen_table);
477     luaLoadLib(lua, LUA_STRLIBNAME, luaopen_string);
478     luaLoadLib(lua, LUA_MATHLIBNAME, luaopen_math);
479     luaLoadLib(lua, LUA_DBLIBNAME, luaopen_debug);
480     luaLoadLib(lua, "cjson", luaopen_cjson);
481     luaLoadLib(lua, "struct", luaopen_struct);
482     luaLoadLib(lua, "cmsgpack", luaopen_cmsgpack);
483 
484 #if 0 /* Stuff that we don't load currently, for sandboxing concerns. */
485     luaLoadLib(lua, LUA_LOADLIBNAME, luaopen_package);
486     luaLoadLib(lua, LUA_OSLIBNAME, luaopen_os);
487 #endif
488 }
489 
490 /* Remove a functions that we don't want to expose to the Redis scripting
491  * environment. */
492 void luaRemoveUnsupportedFunctions(lua_State *lua) {
493     lua_pushnil(lua);
494     lua_setglobal(lua,"loadfile");
495 }
496 
497 /* This function installs metamethods in the global table _G that prevent
498  * the creation of globals accidentally.
499  *
500  * It should be the last to be called in the scripting engine initialization
501  * sequence, because it may interact with creation of globals. */
502 void scriptingEnableGlobalsProtection(lua_State *lua) {
503     char *s[32];
504     sds code = sdsempty();
505     int j = 0;
506 
507     /* strict.lua from: http://metalua.luaforge.net/src/lib/strict.lua.html.
508      * Modified to be adapted to Redis. */
509     s[j++]="local mt = {}\n";
510     s[j++]="setmetatable(_G, mt)\n";
511     s[j++]="mt.__newindex = function (t, n, v)\n";
512     s[j++]="  if debug.getinfo(2) then\n";
513     s[j++]="    local w = debug.getinfo(2, \"S\").what\n";
514     s[j++]="    if w ~= \"main\" and w ~= \"C\" then\n";
515     s[j++]="      error(\"Script attempted to create global variable '\"..tostring(n)..\"'\", 2)\n";
516     s[j++]="    end\n";
517     s[j++]="  end\n";
518     s[j++]="  rawset(t, n, v)\n";
519     s[j++]="end\n";
520     s[j++]="mt.__index = function (t, n)\n";
521     s[j++]="  if debug.getinfo(2) and debug.getinfo(2, \"S\").what ~= \"C\" then\n";
522     s[j++]="    error(\"Script attempted to access unexisting global variable '\"..tostring(n)..\"'\", 2)\n";
523     s[j++]="  end\n";
524     s[j++]="  return rawget(t, n)\n";
525     s[j++]="end\n";
526     s[j++]=NULL;
527 
528     for (j = 0; s[j] != NULL; j++) code = sdscatlen(code,s[j],strlen(s[j]));
529     luaL_loadbuffer(lua,code,sdslen(code),"@enable_strict_lua");
530     lua_pcall(lua,0,0,0);
531     sdsfree(code);
532 }
533 
534 /* Initialize the scripting environment.
535  * It is possible to call this function to reset the scripting environment
536  * assuming that we call scriptingRelease() before.
537  * See scriptingReset() for more information. */
538 void scriptingInit(void) {
539     lua_State *lua = lua_open();
540 
541     luaLoadLibraries(lua);
542     luaRemoveUnsupportedFunctions(lua);
543 
544     /* Initialize a dictionary we use to map SHAs to scripts.
545      * This is useful for replication, as we need to replicate EVALSHA
546      * as EVAL, so we need to remember the associated script. */
547     server.lua_scripts = dictCreate(&shaScriptObjectDictType,NULL);
548 
549     /* Register the redis commands table and fields */
550     lua_newtable(lua);
551 
552     /* redis.call */
553     lua_pushstring(lua,"call");
554     lua_pushcfunction(lua,luaRedisCallCommand);
555     lua_settable(lua,-3);
556 
557     /* redis.pcall */
558     lua_pushstring(lua,"pcall");
559     lua_pushcfunction(lua,luaRedisPCallCommand);
560     lua_settable(lua,-3);
561 
562     /* redis.log and log levels. */
563     lua_pushstring(lua,"log");
564     lua_pushcfunction(lua,luaLogCommand);
565     lua_settable(lua,-3);
566 
567     lua_pushstring(lua,"LOG_DEBUG");
568     lua_pushnumber(lua,REDIS_DEBUG);
569     lua_settable(lua,-3);
570 
571     lua_pushstring(lua,"LOG_VERBOSE");
572     lua_pushnumber(lua,REDIS_VERBOSE);
573     lua_settable(lua,-3);
574 
575     lua_pushstring(lua,"LOG_NOTICE");
576     lua_pushnumber(lua,REDIS_NOTICE);
577     lua_settable(lua,-3);
578 
579     lua_pushstring(lua,"LOG_WARNING");
580     lua_pushnumber(lua,REDIS_WARNING);
581     lua_settable(lua,-3);
582 
583     /* redis.sha1hex */
584     lua_pushstring(lua, "sha1hex");
585     lua_pushcfunction(lua, luaRedisSha1hexCommand);
586     lua_settable(lua, -3);
587 
588     /* redis.error_reply and redis.status_reply */
589     lua_pushstring(lua, "error_reply");
590     lua_pushcfunction(lua, luaRedisErrorReplyCommand);
591     lua_settable(lua, -3);
592     lua_pushstring(lua, "status_reply");
593     lua_pushcfunction(lua, luaRedisStatusReplyCommand);
594     lua_settable(lua, -3);
595 
596     /* Finally set the table as 'redis' global var. */
597     lua_setglobal(lua,"redis");
598 
599     /* Replace math.random and math.randomseed with our implementations. */
600     lua_getglobal(lua,"math");
601 
602     lua_pushstring(lua,"random");
603     lua_pushcfunction(lua,redis_math_random);
604     lua_settable(lua,-3);
605 
606     lua_pushstring(lua,"randomseed");
607     lua_pushcfunction(lua,redis_math_randomseed);
608     lua_settable(lua,-3);
609 
610     lua_setglobal(lua,"math");
611 
612     /* Add a helper function that we use to sort the multi bulk output of non
613      * deterministic commands, when containing 'false' elements. */
614     {
615         char *compare_func =    "function __redis__compare_helper(a,b)\n"
616                                 "  if a == false then a = '' end\n"
617                                 "  if b == false then b = '' end\n"
618                                 "  return a<b\n"
619                                 "end\n";
620         luaL_loadbuffer(lua,compare_func,strlen(compare_func),"@cmp_func_def");
621         lua_pcall(lua,0,0,0);
622     }
623 
624     /* Add a helper function we use for pcall error reporting.
625      * Note that when the error is in the C function we want to report the
626      * information about the caller, that's what makes sense from the point
627      * of view of the user debugging a script. */
628     {
629         char *errh_func =       "function __redis__err__handler(err)\n"
630                                 "  local i = debug.getinfo(2,'nSl')\n"
631                                 "  if i and i.what == 'C' then\n"
632                                 "    i = debug.getinfo(3,'nSl')\n"
633                                 "  end\n"
634                                 "  if i then\n"
635                                 "    return i.source .. ':' .. i.currentline .. ': ' .. err\n"
636                                 "  else\n"
637                                 "    return err\n"
638                                 "  end\n"
639                                 "end\n";
640         luaL_loadbuffer(lua,errh_func,strlen(errh_func),"@err_handler_def");
641         lua_pcall(lua,0,0,0);
642     }
643 
644     /* Create the (non connected) client that we use to execute Redis commands
645      * inside the Lua interpreter.
646      * Note: there is no need to create it again when this function is called
647      * by scriptingReset(). */
648     if (server.lua_client == NULL) {
649         server.lua_client = createClient(-1);
650         server.lua_client->flags |= REDIS_LUA_CLIENT;
651     }
652 
653     /* Lua beginners ofter don't use "local", this is likely to introduce
654      * subtle bugs in their code. To prevent problems we protect accesses
655      * to global variables. */
656     scriptingEnableGlobalsProtection(lua);
657 
658     server.lua = lua;
659 }
660 
661 /* Release resources related to Lua scripting.
662  * This function is used in order to reset the scripting environment. */
663 void scriptingRelease(void) {
664     dictRelease(server.lua_scripts);
665     lua_close(server.lua);
666 }
667 
668 void scriptingReset(void) {
669     scriptingRelease();
670     scriptingInit();
671 }
672 
673 /* Perform the SHA1 of the input string. We use this both for hashing script
674  * bodies in order to obtain the Lua function name, and in the implementation
675  * of redis.sha1().
676  *
677  * 'digest' should point to a 41 bytes buffer: 40 for SHA1 converted into an
678  * hexadecimal number, plus 1 byte for null term. */
679 void sha1hex(char *digest, char *script, size_t len) {
680     SHA1_CTX ctx;
681     unsigned char hash[20];
682     char *cset = "0123456789abcdef";
683     int j;
684 
685     SHA1Init(&ctx);
686     SHA1Update(&ctx,(unsigned char*)script,len);
687     SHA1Final(hash,&ctx);
688 
689     for (j = 0; j < 20; j++) {
690         digest[j*2] = cset[((hash[j]&0xF0)>>4)];
691         digest[j*2+1] = cset[(hash[j]&0xF)];
692     }
693     digest[40] = '\0';
694 }
695 
696 void luaReplyToRedisReply(redisClient *c, lua_State *lua) {
697     int t = lua_type(lua,-1);
698 
699     switch(t) {
700     case LUA_TSTRING:
701         addReplyBulkCBuffer(c,(char*)lua_tostring(lua,-1),lua_strlen(lua,-1));
702         break;
703     case LUA_TBOOLEAN:
704         addReply(c,lua_toboolean(lua,-1) ? shared.cone : shared.nullbulk);
705         break;
706     case LUA_TNUMBER:
707         addReplyLongLong(c,(long long)lua_tonumber(lua,-1));
708         break;
709     case LUA_TTABLE:
710         /* We need to check if it is an array, an error, or a status reply.
711          * Error are returned as a single element table with 'err' field.
712          * Status replies are returned as single element table with 'ok' field */
713         lua_pushstring(lua,"err");
714         lua_gettable(lua,-2);
715         t = lua_type(lua,-1);
716         if (t == LUA_TSTRING) {
717             sds err = sdsnew(lua_tostring(lua,-1));
718             sdsmapchars(err,"\r\n","  ",2);
719             addReplySds(c,sdscatprintf(sdsempty(),"-%s\r\n",err));
720             sdsfree(err);
721             lua_pop(lua,2);
722             return;
723         }
724 
725         lua_pop(lua,1);
726         lua_pushstring(lua,"ok");
727         lua_gettable(lua,-2);
728         t = lua_type(lua,-1);
729         if (t == LUA_TSTRING) {
730             sds ok = sdsnew(lua_tostring(lua,-1));
731             sdsmapchars(ok,"\r\n","  ",2);
732             addReplySds(c,sdscatprintf(sdsempty(),"+%s\r\n",ok));
733             sdsfree(ok);
734             lua_pop(lua,1);
735         } else {
736             void *replylen = addDeferredMultiBulkLength(c);
737             int j = 1, mbulklen = 0;
738 
739             lua_pop(lua,1); /* Discard the 'ok' field value we popped */
740             while(1) {
741                 lua_pushnumber(lua,j++);
742                 lua_gettable(lua,-2);
743                 t = lua_type(lua,-1);
744                 if (t == LUA_TNIL) {
745                     lua_pop(lua,1);
746                     break;
747                 }
748                 luaReplyToRedisReply(c, lua);
749                 mbulklen++;
750             }
751             setDeferredMultiBulkLength(c,replylen,mbulklen);
752         }
753         break;
754     default:
755         addReply(c,shared.nullbulk);
756     }
757     lua_pop(lua,1);
758 }
759 
760 /* Set an array of Redis String Objects as a Lua array (table) stored into a
761  * global variable. */
762 void luaSetGlobalArray(lua_State *lua, char *var, robj **elev, int elec) {
763     int j;
764 
765     lua_newtable(lua);
766     for (j = 0; j < elec; j++) {
767         lua_pushlstring(lua,(char*)elev[j]->ptr,sdslen(elev[j]->ptr));
768         lua_rawseti(lua,-2,j+1);
769     }
770     lua_setglobal(lua,var);
771 }
772 
773 /* Define a lua function with the specified function name and body.
774  * The function name musts be a 2 characters long string, since all the
775  * functions we defined in the Lua context are in the form:
776  *
777  *   f_<hex sha1 sum>
778  *
779  * On success REDIS_OK is returned, and nothing is left on the Lua stack.
780  * On error REDIS_ERR is returned and an appropriate error is set in the
781  * client context. */
782 int luaCreateFunction(redisClient *c, lua_State *lua, char *funcname, robj *body) {
783     sds funcdef = sdsempty();
784 
785     funcdef = sdscat(funcdef,"function ");
786     funcdef = sdscatlen(funcdef,funcname,42);
787     funcdef = sdscatlen(funcdef,"() ",3);
788     funcdef = sdscatlen(funcdef,body->ptr,sdslen(body->ptr));
789     funcdef = sdscatlen(funcdef," end",4);
790 
791     if (luaL_loadbuffer(lua,funcdef,sdslen(funcdef),"@user_script")) {
792         addReplyErrorFormat(c,"Error compiling script (new function): %s\n",
793             lua_tostring(lua,-1));
794         lua_pop(lua,1);
795         sdsfree(funcdef);
796         return REDIS_ERR;
797     }
798     sdsfree(funcdef);
799     if (lua_pcall(lua,0,0,0)) {
800         addReplyErrorFormat(c,"Error running script (new function): %s\n",
801             lua_tostring(lua,-1));
802         lua_pop(lua,1);
803         return REDIS_ERR;
804     }
805 
806     /* We also save a SHA1 -> Original script map in a dictionary
807      * so that we can replicate / write in the AOF all the
808      * EVALSHA commands as EVAL using the original script. */
809     {
810         int retval = dictAdd(server.lua_scripts,
811                              sdsnewlen(funcname+2,40),body);
812         redisAssertWithInfo(c,NULL,retval == DICT_OK);
813         incrRefCount(body);
814     }
815     return REDIS_OK;
816 }
817 
818 void evalGenericCommand(redisClient *c, int evalsha) {
819     lua_State *lua = server.lua;
820     char funcname[43];
821     long long numkeys;
822     int delhook = 0, err;
823 
824     /* We want the same PRNG sequence at every call so that our PRNG is
825      * not affected by external state. */
826     redisSrand48(0);
827 
828     /* We set this flag to zero to remember that so far no random command
829      * was called. This way we can allow the user to call commands like
830      * SRANDMEMBER or RANDOMKEY from Lua scripts as far as no write command
831      * is called (otherwise the replication and AOF would end with non
832      * deterministic sequences).
833      *
834      * Thanks to this flag we'll raise an error every time a write command
835      * is called after a random command was used. */
836     server.lua_random_dirty = 0;
837     server.lua_write_dirty = 0;
838 
839     /* Get the number of arguments that are keys */
840     if (getLongLongFromObjectOrReply(c,c->argv[2],&numkeys,NULL) != REDIS_OK)
841         return;
842     if (numkeys > (c->argc - 3)) {
843         addReplyError(c,"Number of keys can't be greater than number of args");
844         return;
845     }
846 
847     /* We obtain the script SHA1, then check if this function is already
848      * defined into the Lua state */
849     funcname[0] = 'f';
850     funcname[1] = '_';
851     if (!evalsha) {
852         /* Hash the code if this is an EVAL call */
853         sha1hex(funcname+2,c->argv[1]->ptr,sdslen(c->argv[1]->ptr));
854     } else {
855         /* We already have the SHA if it is a EVALSHA */
856         int j;
857         char *sha = c->argv[1]->ptr;
858 
859         for (j = 0; j < 40; j++)
860             funcname[j+2] = tolower(sha[j]);
861         funcname[42] = '\0';
862     }
863 
864     /* Push the pcall error handler function on the stack. */
865     lua_getglobal(lua, "__redis__err__handler");
866 
867     /* Try to lookup the Lua function */
868     lua_getglobal(lua, funcname);
869     if (lua_isnil(lua,-1)) {
870         lua_pop(lua,1); /* remove the nil from the stack */
871         /* Function not defined... let's define it if we have the
872          * body of the function. If this is an EVALSHA call we can just
873          * return an error. */
874         if (evalsha) {
875             lua_pop(lua,1); /* remove the error handler from the stack. */
876             addReply(c, shared.noscripterr);
877             return;
878         }
879         if (luaCreateFunction(c,lua,funcname,c->argv[1]) == REDIS_ERR) return;
880         /* Now the following is guaranteed to return non nil */
881         lua_getglobal(lua, funcname);
882         redisAssert(!lua_isnil(lua,-1));
883     }
884 
885     /* Populate the argv and keys table accordingly to the arguments that
886      * EVAL received. */
887     luaSetGlobalArray(lua,"KEYS",c->argv+3,numkeys);
888     luaSetGlobalArray(lua,"ARGV",c->argv+3+numkeys,c->argc-3-numkeys);
889 
890     /* Select the right DB in the context of the Lua client */
891     selectDb(server.lua_client,c->db->id);
892 
893     /* Set an hook in order to be able to stop the script execution if it
894      * is running for too much time.
895      * We set the hook only if the time limit is enabled as the hook will
896      * make the Lua script execution slower. */
897     server.lua_caller = c;
898     server.lua_time_start = ustime()/1000;
899     server.lua_kill = 0;
900     if (server.lua_time_limit > 0 && server.masterhost == NULL) {
901         lua_sethook(lua,luaMaskCountHook,LUA_MASKCOUNT,100000);
902         delhook = 1;
903     }
904 
905     /* At this point whether this script was never seen before or if it was
906      * already defined, we can call it. We have zero arguments and expect
907      * a single return value. */
908 
909     err = lua_pcall(lua,0,1,-2);
910 
911     /* Perform some cleanup that we need to do both on error and success. */
912     if (delhook) lua_sethook(lua,luaMaskCountHook,0,0); /* Disable hook */
913     if (server.lua_timedout) {
914         server.lua_timedout = 0;
915         /* Restore the readable handler that was unregistered when the
916          * script timeout was detected. */
917         aeCreateFileEvent(server.el,c->fd,AE_READABLE,
918                           readQueryFromClient,c);
919     }
920     server.lua_caller = NULL;
921     selectDb(c,server.lua_client->db->id); /* set DB ID from Lua client */
922     lua_gc(lua,LUA_GCSTEP,1);
923 
924     if (err) {
925         addReplyErrorFormat(c,"Error running script (call to %s): %s\n",
926             funcname, lua_tostring(lua,-1));
927         lua_pop(lua,1); /* Consume the Lua reply. */
928     } else {
929         /* On success convert the Lua return value into Redis protocol, and
930          * send it to * the client. */
931         luaReplyToRedisReply(c,lua);
932     }
933 
934     /* EVALSHA should be propagated to Slave and AOF file as full EVAL, unless
935      * we are sure that the script was already in the context of all the
936      * attached slaves *and* the current AOF file if enabled.
937      *
938      * To do so we use a cache of SHA1s of scripts that we already propagated
939      * as full EVAL, that's called the Replication Script Cache.
940      *
941      * For repliation, everytime a new slave attaches to the master, we need to
942      * flush our cache of scripts that can be replicated as EVALSHA, while
943      * for AOF we need to do so every time we rewrite the AOF file. */
944     if (evalsha) {
945         if (!replicationScriptCacheExists(c->argv[1]->ptr)) {
946             /* This script is not in our script cache, replicate it as
947              * EVAL, then add it into the script cache, as from now on
948              * slaves and AOF know about it. */
949             robj *script = dictFetchValue(server.lua_scripts,c->argv[1]->ptr);
950 
951             replicationScriptCacheAdd(c->argv[1]->ptr);
952             redisAssertWithInfo(c,NULL,script != NULL);
953             rewriteClientCommandArgument(c,0,
954                 resetRefCount(createStringObject("EVAL",4)));
955             rewriteClientCommandArgument(c,1,script);
956         }
957     }
958 }
959 
960 void evalCommand(redisClient *c) {
961     evalGenericCommand(c,0);
962 }
963 
964 void evalShaCommand(redisClient *c) {
965     if (sdslen(c->argv[1]->ptr) != 40) {
966         /* We know that a match is not possible if the provided SHA is
967          * not the right length. So we return an error ASAP, this way
968          * evalGenericCommand() can be implemented without string length
969          * sanity check */
970         addReply(c, shared.noscripterr);
971         return;
972     }
973     evalGenericCommand(c,1);
974 }
975 
976 /* We replace math.random() with our implementation that is not affected
977  * by specific libc random() implementations and will output the same sequence
978  * (for the same seed) in every arch. */
979 
980 /* The following implementation is the one shipped with Lua itself but with
981  * rand() replaced by redisLrand48(). */
982 int redis_math_random (lua_State *L) {
983   /* the `%' avoids the (rare) case of r==1, and is needed also because on
984      some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
985   lua_Number r = (lua_Number)(redisLrand48()%REDIS_LRAND48_MAX) /
986                                 (lua_Number)REDIS_LRAND48_MAX;
987   switch (lua_gettop(L)) {  /* check number of arguments */
988     case 0: {  /* no arguments */
989       lua_pushnumber(L, r);  /* Number between 0 and 1 */
990       break;
991     }
992     case 1: {  /* only upper limit */
993       int u = luaL_checkint(L, 1);
994       luaL_argcheck(L, 1<=u, 1, "interval is empty");
995       lua_pushnumber(L, floor(r*u)+1);  /* int between 1 and `u' */
996       break;
997     }
998     case 2: {  /* lower and upper limits */
999       int l = luaL_checkint(L, 1);
1000       int u = luaL_checkint(L, 2);
1001       luaL_argcheck(L, l<=u, 2, "interval is empty");
1002       lua_pushnumber(L, floor(r*(u-l+1))+l);  /* int between `l' and `u' */
1003       break;
1004     }
1005     default: return luaL_error(L, "wrong number of arguments");
1006   }
1007   return 1;
1008 }
1009 
1010 int redis_math_randomseed (lua_State *L) {
1011   redisSrand48(luaL_checkint(L, 1));
1012   return 0;
1013 }
1014 
1015 /* ---------------------------------------------------------------------------
1016  * SCRIPT command for script environment introspection and control
1017  * ------------------------------------------------------------------------- */
1018 
1019 void scriptCommand(redisClient *c) {
1020     if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"flush")) {
1021         scriptingReset();
1022         addReply(c,shared.ok);
1023         replicationScriptCacheFlush();
1024         server.dirty++; /* Propagating this command is a good idea. */
1025     } else if (c->argc >= 2 && !strcasecmp(c->argv[1]->ptr,"exists")) {
1026         int j;
1027 
1028         addReplyMultiBulkLen(c, c->argc-2);
1029         for (j = 2; j < c->argc; j++) {
1030             if (dictFind(server.lua_scripts,c->argv[j]->ptr))
1031                 addReply(c,shared.cone);
1032             else
1033                 addReply(c,shared.czero);
1034         }
1035     } else if (c->argc == 3 && !strcasecmp(c->argv[1]->ptr,"load")) {
1036         char funcname[43];
1037         sds sha;
1038 
1039         funcname[0] = 'f';
1040         funcname[1] = '_';
1041         sha1hex(funcname+2,c->argv[2]->ptr,sdslen(c->argv[2]->ptr));
1042         sha = sdsnewlen(funcname+2,40);
1043         if (dictFind(server.lua_scripts,sha) == NULL) {
1044             if (luaCreateFunction(c,server.lua,funcname,c->argv[2])
1045                     == REDIS_ERR) {
1046                 sdsfree(sha);
1047                 return;
1048             }
1049         }
1050         addReplyBulkCBuffer(c,funcname+2,40);
1051         sdsfree(sha);
1052         forceCommandPropagation(c,REDIS_PROPAGATE_REPL|REDIS_PROPAGATE_AOF);
1053     } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"kill")) {
1054         if (server.lua_caller == NULL) {
1055             addReplySds(c,sdsnew("-NOTBUSY No scripts in execution right now.\r\n"));
1056         } else if (server.lua_write_dirty) {
1057             addReplySds(c,sdsnew("-UNKILLABLE Sorry the script already executed write commands against the dataset. You can either wait the script termination or kill the server in an hard way using the SHUTDOWN NOSAVE command.\r\n"));
1058         } else {
1059             server.lua_kill = 1;
1060             addReply(c,shared.ok);
1061         }
1062     } else {
1063         addReplyError(c, "Unknown SCRIPT subcommand or wrong # of args.");
1064     }
1065 }
1066