char *opname = c->argv[1]->ptr;
robj *o, *targetkey = c->argv[2];
long op, j, numkeys;
+ robj **objects; /* Array of soruce objects. */
unsigned char **src; /* Array of source strings pointers. */
long *len, maxlen = 0; /* Array of length of src strings, and max len. */
unsigned char *res = NULL; /* Resulting string. */
numkeys = c->argc - 3;
src = zmalloc(sizeof(unsigned char*) * numkeys);
len = zmalloc(sizeof(long) * numkeys);
+ objects = zmalloc(sizeof(robj*) * numkeys);
for (j = 0; j < numkeys; j++) {
o = lookupKeyRead(c->db,c->argv[j+3]);
/* Handle non-existing keys as empty strings. */
if (o == NULL) {
+ objects[j] = NULL;
src[j] = NULL;
len[j] = 0;
continue;
}
/* Return an error if one of the keys is not a string. */
if (checkType(c,o,REDIS_STRING)) {
+ for (j = j-1; j >= 0; j--) {
+ if (objects[j])
+ decrRefCount(objects[j]);
+ }
zfree(src);
zfree(len);
+ zfree(objects);
return;
}
- src[j] = o->ptr;
- len[j] = sdslen(o->ptr);
+ objects[j] = getDecodedObject(o);
+ src[j] = objects[j]->ptr;
+ len[j] = sdslen(objects[j]->ptr);
if (len[j] > maxlen) maxlen = len[j];
}
res[j] = output;
}
}
+ for (j = 0; j < numkeys; j++) {
+ if (objects[j])
+ decrRefCount(objects[j]);
+ }
zfree(src);
zfree(len);
+ zfree(objects);
/* Store the computed value into the target key */
if (maxlen) {
} 0
catch {unset num}
- foreach vec [list "" "\xaa" "\x00\x00\xff" "foobar"] {
+ foreach vec [list "" "\xaa" "\x00\x00\xff" "foobar" "123"] {
incr num
test "BITCOUNT against test vector #$num" {
r set str $vec
foreach op {and or xor} {
test "BITOP $op fuzzing" {
for {set i 0} {$i < 10} {incr i} {
+ r flushall
set vec {}
set veckeys {}
set numvec [expr {[randomInt 10]+1}]
}
}
}
+
+ test {BITOP with integer encoded source objects} {
+ r set a 1
+ r set b 2
+ r bitop xor dest a b a
+ r get dest
+ } {2}
+
+ test {BITOP with non string source key} {
+ r del c
+ r set a 1
+ r set b 2
+ r lpush c foo
+ catch {r bitop xor dest a b c d} e
+ set e
+ } {*ERR*}
}