From f404ecb8335767b32a214ba611629c8ec2f1d27f Mon Sep 17 00:00:00 2001 From: michael-grunder Date: Mon, 25 Sep 2023 14:03:48 -0700 Subject: [PATCH 1/5] Find our callback by pattern with PSUBSCRIBE * Use the pattern Redis provides us not the channel, if this is a wildcard based `PSUBSCRIBE` payload. * Don't test whether our slots match in `SSUBSCRIBE` when not in cluster mode. Fixes #2395 --- library.c | 27 ++++++++++++++++----------- redis_commands.c | 2 +- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/library.c b/library.c index 6405eee1f0..5749e96254 100644 --- a/library.c +++ b/library.c @@ -545,8 +545,9 @@ PHP_REDIS_API int redis_subscribe_response(INTERNAL_FUNCTION_PARAMETERS, /* Multibulk response, {[pattern], type, channel, payload } */ while (redis_sock->subs[i]) { zval z_ret, z_args[4], *z_type, *z_chan, *z_pat = NULL, *z_data; - HashTable *ht_tab; int tab_idx = 1, is_pmsg = 0; + HashTable *ht_tab; + zend_string *zs; ZVAL_NULL(&z_resp); if (!redis_sock_read_multibulk_reply_zval(redis_sock, &z_resp)) { @@ -573,22 +574,26 @@ PHP_REDIS_API int redis_subscribe_response(INTERNAL_FUNCTION_PARAMETERS, } // Extract pattern if it's a pmessage - if(is_pmsg) { - if ((z_pat = zend_hash_index_find(ht_tab, tab_idx++)) == NULL) { + if (is_pmsg) { + z_pat = zend_hash_index_find(ht_tab, tab_idx++); + if (z_pat == NULL || Z_TYPE_P(z_pat) != IS_STRING) goto failure; - } } - // Extract channel and data - if ((z_chan = zend_hash_index_find(ht_tab, tab_idx++)) == NULL || - (z_data = zend_hash_index_find(ht_tab, tab_idx++)) == NULL - ) { + /* Extract channel */ + z_chan = zend_hash_index_find(ht_tab, tab_idx++); + if (z_chan == NULL || Z_TYPE_P(z_chan) != IS_STRING) goto failure; - } - if ((cb = zend_hash_str_find_ptr(redis_sock->subs[i], Z_STRVAL_P(z_chan), Z_STRLEN_P(z_chan))) == NULL) { + /* Finally, extract data */ + z_data = zend_hash_index_find(ht_tab, tab_idx++); + if (z_data == NULL) + goto failure; + + /* Find our callback, either by channel or pattern string */ + zs = z_pat != NULL ? Z_STR_P(z_pat) : Z_STR_P(z_chan); + if ((cb = zend_hash_find_ptr(redis_sock->subs[i], zs)) == NULL) goto failure; - } // Different args for SUBSCRIBE and PSUBSCRIBE z_args[0] = *getThis(); diff --git a/redis_commands.c b/redis_commands.c index 637f084a83..dd075801a3 100644 --- a/redis_commands.c +++ b/redis_commands.c @@ -1580,7 +1580,7 @@ int redis_subscribe_cmd(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, ZEND_HASH_FOREACH_VAL(ht_chan, z_chan) { redis_cmd_append_sstr_key_zval(&cmdstr, z_chan, redis_sock, slot ? &s2 : NULL); - if (shardslot != REDIS_CLUSTER_SLOTS && s2 != shardslot) { + if (slot && (shardslot != REDIS_CLUSTER_SLOTS && s2 != shardslot)) { php_error_docref(NULL, E_WARNING, "All shard channels needs to belong to a single slot"); smart_string_free(&cmdstr); efree(sctx); From 3ec80ff09f8f8dc65c0f3347c79da32333a771f1 Mon Sep 17 00:00:00 2001 From: michael-grunder Date: Tue, 10 Oct 2023 09:27:12 -0700 Subject: [PATCH 2/5] Fix flaky test and OBJECT in a pipeline. * We weren't properly passing `z_tab` through to the underlying OBJECT handler, which was causing PhpRedis to crash if you tried to execute the OBJECT command in a pipeline. * Rework the `testTouch` unit test to try and avoid erroneous failures due to CI instance CPU scheduling. --- library.c | 4 ++-- tests/RedisTest.php | 15 ++++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/library.c b/library.c index 5749e96254..c5f9820752 100644 --- a/library.c +++ b/library.c @@ -1519,9 +1519,9 @@ redis_object_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval ZEND_ASSERT(ctx == PHPREDIS_CTX_PTR || ctx == PHPREDIS_CTX_PTR + 1); if (ctx == PHPREDIS_CTX_PTR) { - return redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL); + return redis_long_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL); } else { - return redis_string_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL); + return redis_string_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, z_tab, NULL); } } diff --git a/tests/RedisTest.php b/tests/RedisTest.php index 20aabf8bcc..7f4ea91632 100644 --- a/tests/RedisTest.php +++ b/tests/RedisTest.php @@ -941,13 +941,18 @@ public function testTouch() { $this->redis->del('notakey'); $this->assertTrue($this->redis->mset(['{idle}1' => 'beep', '{idle}2' => 'boop'])); - usleep(1100000); - $this->assertTrue($this->redis->object('idletime', '{idle}1') >= 1); - $this->assertTrue($this->redis->object('idletime', '{idle}2') >= 1); + usleep(2100000); + $this->assertTrue($this->redis->object('idletime', '{idle}1') >= 2); + $this->assertTrue($this->redis->object('idletime', '{idle}2') >= 2); $this->assertEquals(2, $this->redis->touch('{idle}1', '{idle}2', '{idle}notakey')); - $this->assertTrue($this->redis->object('idletime', '{idle}1') == 0); - $this->assertTrue($this->redis->object('idletime', '{idle}2') == 0); + $idle1 = $this->redis->object('idletime', '{idle}1'); + $idle2 = $this->redis->object('idletime', '{idle}2'); + + /* We're not testing if idle is 0 because CPU scheduling on GitHub CI + * potatoes can cause that to erroneously fail. */ + $this->assertTrue($idle1 < 2); + $this->assertTrue($idle2 < 2); } public function testKeys() From abb3708c3dd9ac9bdc61ee72129335e552c979a5 Mon Sep 17 00:00:00 2001 From: Pavlo Yatsukhnenko Date: Fri, 13 Oct 2023 17:50:37 +0300 Subject: [PATCH 3/5] Fix deprecation error when passing null to match_type parameter --- redis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redis.c b/redis.c index 1e001f2097..1d36d76319 100644 --- a/redis.c +++ b/redis.c @@ -2765,7 +2765,7 @@ generic_scan_cmd(INTERNAL_FUNCTION_PARAMETERS, REDIS_SCAN_TYPE type) { } else { // Doesn't require a key if(zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), - "Oz/|s!lS", &object, redis_ce, &z_iter, + "Oz/|s!lS!", &object, redis_ce, &z_iter, &pattern, &pattern_len, &count, &match_type) == FAILURE) { From c9e92365e08faf27be9334a0d9485c1e5e78264e Mon Sep 17 00:00:00 2001 From: Pavlo Yatsukhnenko Date: Sun, 22 Oct 2023 19:02:13 +0300 Subject: [PATCH 4/5] Update CHANGELOG.md --- CHANGELOG.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6494bbd504..aa1793b853 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,30 @@ and PhpRedis adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +### Sponsors :sparkling_heart: + +- [Audiomack](https://audiomack.com) +- [Open LMS](https://openlms.net/) +- [BlueHost](https://bluehost.com) +- [Object Cache Pro for WordPress](https://objectcache.pro/) +- [Avtandil Kikabidze](https://github.com/akalongman) +- [Zaher Ghaibeh](https://github.com/zaherg) +- [BatchLabs](https://batch.com) +- [Stackhero](https://github.com/stackhero-io) +- [Florian Levis](https://github.com/Gounlaf) +- [Luis Zárate](https://github.com/jlzaratec) + +### Fixed +- Fix deprecation error when passing null to match_type parameter. + [b835aaa3](https://github.com/phpredis/phpredis/commit/b835aaa3) + ([Pavlo Yatsukhnenko](https://github.com/yatsukhnenko)) +- Fix flaky test and OBJECT in a pipeline. + [a7f51f70](https://github.com/phpredis/phpredis/commit/a7f51f70) + ([Michael Grunder](https://github.com/michael-grunder)) +- Find our callback by pattern with PSUBSCRIBE + [2f276dcd](https://github.com/phpredis/phpredis/commit/2f276dcd) + ([Michael Grunder](https://github.com/michael-grunder)) + ## [6.0.1] - 2023-09-23 ([GitHub](https://github.com/phpredis/phpredis/releases/6.0.1), [PECL](https://pecl.php.net/package/redis/6.0.1)) ### Sponsors :sparkling_heart: From 62cf943fecc5182c6329b332df43cf28012cef55 Mon Sep 17 00:00:00 2001 From: Pavlo Yatsukhnenko Date: Sun, 22 Oct 2023 19:16:41 +0300 Subject: [PATCH 5/5] 6.0.2 --- CHANGELOG.md | 2 ++ package.xml | 51 +++++++++++++++++++++++++++++++++++++++------------ php_redis.h | 2 +- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa1793b853..ddeba96937 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and PhpRedis adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm ## [Unreleased] +## [6.0.2] - 2023-10-22 ([GitHub](https://github.com/phpredis/phpredis/releases/6.0.2), [PECL](https://pecl.php.net/package/redis/6.0.2)) + ### Sponsors :sparkling_heart: - [Audiomack](https://audiomack.com) diff --git a/package.xml b/package.xml index 66a738a146..332dab572d 100644 --- a/package.xml +++ b/package.xml @@ -27,9 +27,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> n.favrefelix@gmail.com no - 2023-09-23 + 2023-10-22 - 6.0.1 + 6.0.2 6.0.0 @@ -53,19 +53,15 @@ http://pear.php.net/dtd/package-2.0.xsd"> --- - phpredis 6.0.1 - - This release contains fix for unknown expiration modifier issue - as well as memory leak and segfault in exec function - and small documentation improvements. + phpredis 6.0.2 + This release contains fixes for OBJECT, PSUBSCRIBE and SCAN commands. You can find a detailed list of changes in CHANGELOG.md and package.xml or by inspecting the git commit logs. - * Fix memory leak and segfault in Redis::exec [362e1141] (Pavlo Yatsukhnenko), (Markus Podar) - * Fix unknown expiration modifier [264c0c7e, 95bd184b] (Pavlo Yatsukhnenko) - * Update documentation [3674d663, 849bedb6, 1ad95b63] (Till Kruss), (Joost OrangeJuiced) - + * Fix deprecation error when passing null to match_type parameter.[b835aaa3] (Pavlo Yatsukhnenko) + * Fix flaky test and OBJECT in a pipeline. [a7f51f70] (Michael Grunder) + * Find our callback by pattern with PSUBSCRIBE [2f276dcd] (Michael Grunder) @@ -159,7 +155,38 @@ http://pear.php.net/dtd/package-2.0.xsd"> stablestable - 6.0.16.0.1 + 6.0.26.0.0 + 2023-10-22 + + --- Sponsors --- + + Audiomack - https://audiomack.com + Open LMS - https://openlms.net + BlueHost - https://bluehost.com + Object Cache Pro for WordPress - https://objectcache.pro + Avtandil Kikabidze - https://github.com/akalongman + Zaher Ghaibeh - https://github.com/zaherg + BatchLabs - https://batch.com + Stackhero - https://github.com/stackhero-io + Florian Levis - https://github.com/Gounlaf + Luis Zarate - https://github.com/jlzaratec + + --- + + phpredis 6.0.2 + + This release contains fixes for OBJECT, PSUBSCRIBE and SCAN commands. + You can find a detailed list of changes in CHANGELOG.md and package.xml + or by inspecting the git commit logs. + + * Fix deprecation error when passing null to match_type parameter.[b835aaa3] (Pavlo Yatsukhnenko) + * Fix flaky test and OBJECT in a pipeline. [a7f51f70] (Michael Grunder) + * Find our callback by pattern with PSUBSCRIBE [2f276dcd] (Michael Grunder) + + + + stablestable + 6.0.16.0.0 2023-09-23 --- Sponsors --- diff --git a/php_redis.h b/php_redis.h index 3f03883d88..d9f4dda509 100644 --- a/php_redis.h +++ b/php_redis.h @@ -23,7 +23,7 @@ #define PHP_REDIS_H /* phpredis version */ -#define PHP_REDIS_VERSION "6.0.1" +#define PHP_REDIS_VERSION "6.0.2" /* For convenience we store the salt as a printable hex string which requires 2 * characters per byte + 1 for the NULL terminator */