May 24, 2014

Node_redis对数组支持的BUG

做微信公众平台的时候发现Node_redis(https://github.com/mranney/node_redis)一个严重BUG
执行redis.lpush('mylist',['a','b','c'],callback)的时候,预计返回

mylist
a
b
c

实际返回

mylist
a,b,c

Github已经有人提出过这个问题

https://github.com/mranney/node_redis/issues/369#issuecomment-13050944

产生原因

所有的client.COMMAND会调用client.send_command()

RedisClient.prototype[command] = function (args, callback) {
    if (Array.isArray(args) && typeof callback === "function") {
        return this.send_command(command, args, callback);
    } else {
        return this.send_command(command, to_array(arguments));
    }
};

调用client.COMMAND的时候

client.COMMAND(key, ["arg1", "arg2", "arg3"], callback);

会被解析成

client.send_command(COMMAND, [key, ["arg1", "arg2", "arg3"]], callback);

send_command()有如下段落

    for (i = 0, il = args.length, arg; i < il; i += 1) {
        arg = args[i];
        if (typeof arg !== "string") {
            arg = String(arg);
        }
        command_str += "$" + Buffer.byteLength(arg) + "\r\n" + arg + "\r\n";
    }

示例中循环到第二次 arg = ["arg1", "arg2", "arg3"] ,会被String()强制转换为"arg, arg2, arg3",产生BUG。

解决方法

直接调用

client.send_command(COMMAND, [key, "arg1", "arg2", "arg3"], callback);

或者将key包含到数组里面

client.COMMAND([key, "arg1", "arg2", "arg3"], callback);

吐个槽

既然都知道原因了,2013年2月的issue为什么到现在都还没解决!!