redis.call() redis.pcall()*/
| 314 | |
| 315 | /* redis.call() redis.pcall()*/ |
| 316 | int LuaState::luaRedisGenericCommand(lua_State* lua, int raise_error) { |
| 317 | LuaState* ls = getLuaStateFromLua(lua); |
| 318 | int j, argc = lua_gettop(lua); |
| 319 | |
| 320 | ls->updateFakeClient(); |
| 321 | |
| 322 | // TODO(takenliu): fix MULTI loggical. |
| 323 | if (ls->_sess->getCtx()->isInMulti()) { |
| 324 | ls->_fakeSess->getSession()->getCtx()->setMulti(); |
| 325 | } else { |
| 326 | ls->_fakeSess->getSession()->getCtx()->resetMulti(); |
| 327 | } |
| 328 | |
| 329 | /* By using Lua debug hooks it is possible to trigger a recursive call |
| 330 | * to luaRedisGenericCommand(), which normally should never happen. |
| 331 | * To make this function reentrant is futile and makes it slower, but |
| 332 | * we should at least detect such a misuse, and abort. */ |
| 333 | if (ls->inuse) { |
| 334 | const char* recursion_warning = |
| 335 | "luaRedisGenericCommand() recursive call detected. " |
| 336 | "Are you doing funny stuff with Lua debug hooks?"; |
| 337 | LOG(WARNING) << recursion_warning; |
| 338 | luaPushError(lua, recursion_warning); |
| 339 | return 1; |
| 340 | } |
| 341 | ls->inuse++; |
| 342 | |
| 343 | /* Require at least one argument */ |
| 344 | if (argc == 0) { |
| 345 | luaPushError(lua, "Please specify at least one argument for redis.call()"); |
| 346 | ls->inuse--; |
| 347 | DLOG(INFO) << "Please specify at least one argument for redis.call()"; |
| 348 | return raise_error ? luaRaiseError(lua) : 1; |
| 349 | } |
| 350 | std::vector<std::string> args; |
| 351 | |
| 352 | for (j = 0; j < argc; j++) { |
| 353 | char* obj_s; |
| 354 | size_t obj_len; |
| 355 | char dbuf[64]; |
| 356 | |
| 357 | if (lua_type(lua, j + 1) == LUA_TNUMBER) { |
| 358 | /* We can't use lua_tolstring() for number -> string conversion |
| 359 | * since Lua uses a format specifier that loses precision. */ |
| 360 | lua_Number num = lua_tonumber(lua, j + 1); |
| 361 | |
| 362 | obj_len = snprintf(dbuf, sizeof(dbuf), "%.17g", static_cast<double>(num)); |
| 363 | obj_s = dbuf; |
| 364 | } else { |
| 365 | obj_s = const_cast<char*>(lua_tolstring(lua, j + 1, &obj_len)); |
| 366 | if (obj_s == nullptr) |
| 367 | break; /* Not a string. */ |
| 368 | } |
| 369 | |
| 370 | args.emplace_back(obj_s, obj_len); |
| 371 | } |
| 372 | |
| 373 | /* Check if one of the arguments passed by the Lua script |
nothing calls this directly
no test coverage detected