diff options
author | michael-grunder <michael.grunder@gmail.com> | 2022-10-27 08:06:02 +0300 |
---|---|---|
committer | Michael Grunder <michael.grunder@gmail.com> | 2022-10-27 17:45:08 +0300 |
commit | af13f951aacda7e8fc0597827812ad4eb194e318 (patch) | |
tree | c39d65234eee7ae66c9d4f5bd375612bfbcd774d | |
parent | 71344612bcce04aba777bbe9b6947837a08600d5 (diff) |
Fix BITOP cross-slot bug
Fixes #2210
-rw-r--r-- | redis_commands.c | 6 | ||||
-rw-r--r-- | tests/RedisTest.php | 18 |
2 files changed, 21 insertions, 3 deletions
diff --git a/redis_commands.c b/redis_commands.c index 56446cab..31c37aa4 100644 --- a/redis_commands.c +++ b/redis_commands.c @@ -2825,12 +2825,12 @@ int redis_bitop_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, // Verify slot if this is a Cluster request if (slot) { kslot = cluster_hash_key(key, key_len); - if (*slot == -1 || kslot != *slot) { - php_error_docref(NULL, E_WARNING, - "Warning, not all keys hash to the same slot!"); + if (*slot != -1 && kslot != *slot) { + php_error_docref(NULL, E_WARNING, "Warning, not all keys hash to the same slot!"); zend_string_release(zstr); if (key_free) efree(key); efree(z_args); + efree(cmdstr.c); return FAILURE; } *slot = kslot; diff --git a/tests/RedisTest.php b/tests/RedisTest.php index 466a83a6..336cf23e 100644 --- a/tests/RedisTest.php +++ b/tests/RedisTest.php @@ -230,6 +230,24 @@ class Redis_Test extends TestSuite $this->assertEquals(5, $this->redis->bitcount('bitcountkey', 0, 9, true)); } + public function testBitop() { + if (!$this->minVersionCheck('2.6.0')) + $this->markTestSkipped(); + + $this->redis->set("{key}1", "foobar"); + $this->redis->set("{key}2", "abcdef"); + + // Regression test for GitHub issue #2210 + $this->assertEquals(6, $this->redis->bitop('AND', '{key}1', '{key}2')); + + // Make sure RedisCluster doesn't even send the command. We don't care + // about what Redis returns + @$this->redis->bitop('AND', 'key1', 'key2', 'key3'); + $this->assertEquals(NULL, $this->redis->getLastError()); + + $this->redis->del('{key}1', '{key}2'); + } + public function testBitsets() { $this->redis->del('key'); |