| 501 | #define LUA_CMD_OBJCACHE_SIZE 32 |
| 502 | #define LUA_CMD_OBJCACHE_MAX_LEN 64 |
| 503 | int luaRedisGenericCommand(lua_State *lua, int raise_error) { |
| 504 | int j, argc = lua_gettop(lua); |
| 505 | struct redisCommand *cmd; |
| 506 | client *c = server.lua_client; |
| 507 | sds reply; |
| 508 | |
| 509 | /* Cached across calls. */ |
| 510 | static robj **argv = NULL; |
| 511 | static int argv_size = 0; |
| 512 | static robj *cached_objects[LUA_CMD_OBJCACHE_SIZE]; |
| 513 | static size_t cached_objects_len[LUA_CMD_OBJCACHE_SIZE]; |
| 514 | static int inuse = 0; /* Recursive calls detection. */ |
| 515 | |
| 516 | /* By using Lua debug hooks it is possible to trigger a recursive call |
| 517 | * to luaRedisGenericCommand(), which normally should never happen. |
| 518 | * To make this function reentrant is futile and makes it slower, but |
| 519 | * we should at least detect such a misuse, and abort. */ |
| 520 | if (inuse) { |
| 521 | char *recursion_warning = |
| 522 | "luaRedisGenericCommand() recursive call detected. " |
| 523 | "Are you doing funny stuff with Lua debug hooks?"; |
| 524 | serverLog(LL_WARNING,"%s",recursion_warning); |
| 525 | luaPushError(lua,recursion_warning); |
| 526 | return 1; |
| 527 | } |
| 528 | inuse++; |
| 529 | |
| 530 | /* Require at least one argument */ |
| 531 | if (argc == 0) { |
| 532 | luaPushError(lua, |
| 533 | "Please specify at least one argument for redis.call()"); |
| 534 | inuse--; |
| 535 | return raise_error ? luaRaiseError(lua) : 1; |
| 536 | } |
| 537 | |
| 538 | /* Build the arguments vector */ |
| 539 | if (argv_size < argc) { |
| 540 | argv = zrealloc(argv,sizeof(robj*)*argc); |
| 541 | argv_size = argc; |
| 542 | } |
| 543 | |
| 544 | for (j = 0; j < argc; j++) { |
| 545 | char *obj_s; |
| 546 | size_t obj_len; |
| 547 | char dbuf[64]; |
| 548 | |
| 549 | if (lua_type(lua,j+1) == LUA_TNUMBER) { |
| 550 | /* We can't use lua_tolstring() for number -> string conversion |
| 551 | * since Lua uses a format specifier that loses precision. */ |
| 552 | lua_Number num = lua_tonumber(lua,j+1); |
| 553 | |
| 554 | obj_len = snprintf(dbuf,sizeof(dbuf),"%.17g",(double)num); |
| 555 | obj_s = dbuf; |
| 556 | } else { |
| 557 | obj_s = (char*)lua_tolstring(lua,j+1,&obj_len); |
| 558 | if (obj_s == NULL) break; /* Not a string. */ |
| 559 | } |
| 560 |
no test coverage detected