Example #1
0
/* This gets called when the function "client)" gets called in Lua */
int luaCall_client(lua_State *L) {
    LuaFlag            = PIPE_NONE_FLAG;
    int           argc = lua_gettop(L);
    const char   *arg1 = lua_tostring(L, 1);
    if (!arg1) {
        return redisLuaArityErr(L, NULL);
    }
    redisCommand *cmd  = lookupCommand((char *)arg1);

    if (!cmd) {
        char buf[64];
        snprintf(buf, 63, "-ERR Unknown command '%s'\r\n", arg1);
        buf[63] = '\0';
        lua_pushstring(L, buf);
        LuaFlag = PIPE_ONE_LINER_FLAG;
        return 1;
    } else if ((cmd->arity > 0 && cmd->arity != argc) || (argc < -cmd->arity)) {
        return redisLuaArityErr(L, cmd->name);
    }

    if (server.maxmemory && (cmd->flags & REDIS_CMD_DENYOOM) &&
        (zmalloc_used_memory() > server.maxmemory)) {
        LuaFlag = PIPE_ONE_LINER_FLAG;
        lua_pushstring(L,
                 "-ERR command not allowed when used memory > 'maxmemory'\r\n");
        return 1;
    }

    if (server.vm_enabled && server.vm_max_threads > 0 &&
        blockClientOnSwappedKeys(LuaClient, cmd)) return 1;

    long          ok    = 0; /* must come before first GOTO */
    redisClient  *rfc   = rsql_createFakeClient();
    robj        **rargv = zmalloc(sizeof(robj *) * argc);
    for (int i = 0; i < argc; i++) {
        char *arg = (char *)lua_tostring(L, i + 1);
        if (!arg) {
            char *lbuf = "args must be strings";
            luaL_argerror (L, i, lbuf);
            LuaFlag    = PIPE_ONE_LINER_FLAG;
            ok         = 1;
            goto redis_lua_end;
        }
        rargv[i] = _createStringObject(arg);
    }
    rfc->argv = rargv;
    rfc->argc = argc;

    ok = fakeClientPipe(LuaClient, rfc, L, 0, &LuaFlag, luaLine, emptyNoop);

redis_lua_end:
    for (int i = 0; i < argc; i++) decrRefCount(rargv[i]);
    zfree(rargv);
    rsql_freeFakeClient(rfc);
    return (ok > 0) ? 1 : 0;
}
Example #2
0
static void runCmdInFakeClient(sds s) {
    //RL4 "runCmdInFakeClient: %s", s);
    int           argc;
    sds          *argv = sdssplitlen(s, sdslen(s), " ", 1, &argc); // FREEME 017
    if (!argv)    return;
    if (argc < 1) goto run_cmd_end;
    redisCommand *cmd  = lookupCommand(argv[0]);
    if (!cmd)     goto run_cmd_end;
    if ((cmd->arity > 0 && cmd->arity > argc) || (argc < -cmd->arity))
                  goto run_cmd_end;
    int    arity;
    robj **rargv;
    if (cmd->arity > 0 || cmd->proc == insertCommand    ||
                          cmd->proc == sqlSelectCommand ||
                          cmd->proc == tscanCommand)       {
        arity = abs(cmd->arity);
        rargv = zmalloc(sizeof(robj *) * arity);         /* ZFREE ME 018 */
        for (int j = 0; j < arity - 1; j++) {
            rargv[j] = createStringObject(argv[j], sdslen(argv[j])); // FREE 019
        }
        sds lastarg = sdsempty();
        for (int j = arity - 1; j < argc; j++) {
            if (j != (arity - 1)) lastarg = sdscatlen(lastarg, " ", 1);
            lastarg = sdscatlen(lastarg, argv[j], sdslen(argv[j]));
        }
        rargv[arity - 1] = createObject(REDIS_STRING, lastarg); // FREE 019
    } else {
        arity = argc;
        rargv = zmalloc(sizeof(robj *) * arity);         /* ZFREE ME 018 */
        for (int j = 0; j < arity; j++) {
            rargv[j] = createStringObject(argv[j], sdslen(argv[j])); // FREE 019
        }
    }
    redisClient *c  = CurrClient;
    redisClient *fc = rsql_createFakeClient();           /* DESTROY ME 020 */
    fc->argv        = rargv;
    fc->argc        = arity;
    fakeClientPipe(c, fc, NULL, 0, &NriFlag,
                   nonRelIndRespHandler, emptyNonRelIndRespHandler);
    rsql_freeFakeClient(fc);                             /* DESTROYED 020 */
    for (int j = 0; j < arity; j++) decrRefCount(rargv[j]); /* FREED 019 */
    zfree(rargv);                                        /* ZFREED 018 */

run_cmd_end:
    for (int j = 0; j < argc; j++) sdsfree(argv[j]);     /* FREED 017 */
    zfree(argv);                                         /* FREED 017 */
}
Example #3
0
/* TODO the protocol-parsing does not exactly follow the line protocol,
        it follow what the code does ... the code could change */
void createTableAsObjectOperation(redisClient *c, bool is_ins) {
    robj               *wargv[3];
    struct redisClient *wfc    = rsql_createFakeClient(); /* client to write */
    wfc->argc                  = 3;
    wfc->argv                  = wargv;
    wfc->argv[1]               = c->argv[2]; /* table name */

    robj               **rargv = malloc(sizeof(robj *) * c->argc);
    struct redisClient *rfc    = rsql_createFakeClient(); /* client to read */
    rfc->argv                  = rargv;
    for (int i = 4; i < c->argc; i++) {
        rfc->argv[i - 4] = c->argv[i];
    }
    rfc->argc                  = c->argc - 4;
    rfc->db                    = c->db;

    fakeClientPipe(c, rfc, wfc, is_ins, addSingle);

    rsql_freeFakeClient(rfc);
    rsql_freeFakeClient(wfc);
    free(rargv);
    addReply(c, shared.ok);
    return;
}