From 67750f851ad01d054401ce988fe95f7bfe4cb9bf Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Wed, 4 Jan 2017 18:57:02 -0800 Subject: [PATCH 001/218] Update the README in preparation for php-memcached 3.x release --- README.markdown | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/README.markdown b/README.markdown index ae1b86db..35f4d7a0 100644 --- a/README.markdown +++ b/README.markdown @@ -1,15 +1,15 @@ Build Status ------------ -[![Build Status](https://travis-ci.org/php-memcached-dev/php-memcached.png?branch=php7)](https://travis-ci.org/php-memcached-dev/php-memcached) +[![Build Status](https://travis-ci.org/php-memcached-dev/php-memcached.png)](https://travis-ci.org/php-memcached-dev/php-memcached) Description ----------- -This extension uses libmemcached library to provide API for communicating with -memcached servers. +This is the [PECL memcached](https://pecl.php.net/package/memcached) extension, +using the libmemcached library to connect to memcached servers. -memcached is a high-performance, distributed memory object caching system, -generic in nature, but intended for use in speeding up dynamic web applications -by alleviating database load. +[memcached](https://memcached.org) is a high-performance, distributed memory +object caching system, generic in nature, but intended for use in speeding up +dynamic web applications by alleviating database load. Building -------- @@ -19,8 +19,19 @@ Building $ make $ make test -Resources ---------- - * [libmemcached](http://libmemcached.org/libMemcached.html) - * [memcached](http://memcached.org/) - * [igbinary](https://github.com/igbinary/igbinary) +Dependencies +------------ + +php-memcached 3.x releases support PHP 7.0 - 7.1, and require libmemcached 1.x or higher, and optionally support igbinary 2.0 or higher. + +php-memcached 2.x releases support PHP 5.2 - 5.6, and require libmemcached 0.44 or higher, and optionally support igbinary 1.0 or higher. + +[libmemcached](http://libmemcached.org/libMemcached.html) version 1.0.16 or +higher is recommended for best performance and compatibility with memcached +servers. + +[igbinary](https://github.com/igbinary/igbinary) is a faster and more compact +binary serializer for PHP data structures. When installing php-memcached from +source code, the igbinary module must be installed first so that php-memcached +can access its C header files. Load both modules in your `php.ini` at runtime +to begin using igbinary. From dd0219168659419ff4e936b6f77d75e199b2e2d7 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 5 Jan 2017 11:45:07 -0800 Subject: [PATCH 002/218] Add mention of msgpack to the README --- README.markdown | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/README.markdown b/README.markdown index 35f4d7a0..0cb2c032 100644 --- a/README.markdown +++ b/README.markdown @@ -22,9 +22,17 @@ Building Dependencies ------------ -php-memcached 3.x releases support PHP 7.0 - 7.1, and require libmemcached 1.x or higher, and optionally support igbinary 2.0 or higher. - -php-memcached 2.x releases support PHP 5.2 - 5.6, and require libmemcached 0.44 or higher, and optionally support igbinary 1.0 or higher. +php-memcached 3.x: +* Supports PHP 7.0 - 7.1. +* Requires libmemcached 1.x or higher. +* Optionally supports igbinary 2.0 or higher. +* Optionally supports msgpack 2.0 or higher. + +php-memcached 2.x: +* Supports PHP 5.2 - 5.6. +* Requires libmemcached 0.44 or higher. +* Optionally supports igbinary 1.0 or higher. +* Optionally supports msgpack 0.5 or higher. [libmemcached](http://libmemcached.org/libMemcached.html) version 1.0.16 or higher is recommended for best performance and compatibility with memcached @@ -35,3 +43,9 @@ binary serializer for PHP data structures. When installing php-memcached from source code, the igbinary module must be installed first so that php-memcached can access its C header files. Load both modules in your `php.ini` at runtime to begin using igbinary. + +[msgpack](https://msgpack.org) is a faster and more compact data structure +representation that is interoperable with msgpack implementations for other +languages. When installing php-memcached from source code, the msgpack module +must be installed first so that php-memcached can access its C header files. +Load both modules in your `php.ini` at runtime to begin using msgpack. From 7f6c3330327d5a89f9ced7fabbe63ac7fc7f4196 Mon Sep 17 00:00:00 2001 From: Arjen Date: Fri, 20 Jan 2017 13:20:42 +0100 Subject: [PATCH 003/218] Cannot reset OPT_PREFIX_KEY #293 (#294) - ZSTR_VAL(str) == 0 should be ZSTR_LEN(str) == 0 - add reset_keyprefix.phpt to package.xml --- package.xml | 1 + php_memcached.c | 2 +- tests/reset_keyprefix.phpt | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tests/reset_keyprefix.phpt diff --git a/package.xml b/package.xml index 244acfab..f2b81369 100644 --- a/package.xml +++ b/package.xml @@ -164,6 +164,7 @@ Tests + diff --git a/php_memcached.c b/php_memcached.c index e6b741ef..e1a045b5 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -2867,7 +2867,7 @@ int php_memc_set_option(php_memc_object_t *intern, long option, zval *value) char tmp[MEMCACHED_PREFIX_KEY_MAX_SIZE - 1]; #endif str = zval_get_string(value); - if (ZSTR_VAL(str) == 0) { + if (ZSTR_LEN(str) == 0) { key = NULL; } else { /* diff --git a/tests/reset_keyprefix.phpt b/tests/reset_keyprefix.phpt new file mode 100644 index 00000000..385a21d5 --- /dev/null +++ b/tests/reset_keyprefix.phpt @@ -0,0 +1,38 @@ +--TEST-- +Cannot reset OPT_PREFIX_KEY #293 +--SKIPIF-- + +--FILE-- +set('key1', 'abc'); +var_dump($m->get('key1')); + +$m->setOption(Memcached::OPT_PREFIX_KEY, 'prefix'); +var_dump($m->get('key1')); + +$m->setOption(Memcached::OPT_PREFIX_KEY, false); +var_dump($m->get('key1')); + +$m->setOption(Memcached::OPT_PREFIX_KEY, 'prefix'); +var_dump($m->get('key1')); + +$m->setOption(Memcached::OPT_PREFIX_KEY, ''); +var_dump($m->get('key1')); + +$m->setOption(Memcached::OPT_PREFIX_KEY, 'prefix'); +var_dump($m->get('key1')); + +$m->setOption(Memcached::OPT_PREFIX_KEY, null); +var_dump($m->get('key1')); +--EXPECTF-- +string(3) "abc" +bool(false) +string(3) "abc" +bool(false) +string(3) "abc" +bool(false) +string(3) "abc" \ No newline at end of file From c564fd875ead3110b27dd3e1dfb9e5d4afabd042 Mon Sep 17 00:00:00 2001 From: Arjen Date: Fri, 20 Jan 2017 14:26:57 +0100 Subject: [PATCH 004/218] Cleanup all checks for unsupported libmemcached versions (#295) --- config.m4 | 2 +- package.xml | 2 -- php_libmemcached_compat.c | 37 ------------------------ php_libmemcached_compat.h | 59 --------------------------------------- php_memcached.c | 58 ++++++-------------------------------- php_memcached_private.h | 10 +++++-- php_memcached_session.c | 2 +- 7 files changed, 17 insertions(+), 153 deletions(-) delete mode 100644 php_libmemcached_compat.c delete mode 100644 php_libmemcached_compat.h diff --git a/config.m4 b/config.m4 index e6a2dfd0..ab6142a1 100644 --- a/config.m4 +++ b/config.m4 @@ -318,7 +318,7 @@ if test "$PHP_MEMCACHED" != "no"; then AC_DEFINE(HAVE_MEMCACHED_EXIST, [1], [Whether memcached_exist is defined]) fi - PHP_MEMCACHED_FILES="php_memcached.c php_libmemcached_compat.c g_fmt.c" + PHP_MEMCACHED_FILES="php_memcached.c g_fmt.c" if test "$PHP_SYSTEM_FASTLZ" != "no"; then AC_CHECK_HEADERS([fastlz.h], [ac_cv_have_fastlz="yes"], [ac_cv_have_fastlz="no"]) diff --git a/package.xml b/package.xml index f2b81369..e8d5c743 100644 --- a/package.xml +++ b/package.xml @@ -72,8 +72,6 @@ Tests - - diff --git a/php_libmemcached_compat.c b/php_libmemcached_compat.c deleted file mode 100644 index bd35d8fe..00000000 --- a/php_libmemcached_compat.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) 2009 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andrei Zmievski | - +----------------------------------------------------------------------+ -*/ - -#include "php_memcached.h" -#include "php_memcached_private.h" -#include "php_libmemcached_compat.h" - -memcached_return php_memcached_exist (memcached_st *memc, zend_string *key) -{ -#ifdef HAVE_MEMCACHED_EXIST - return memcached_exist (memc, key->val, key->len); -#else - memcached_return rc = MEMCACHED_SUCCESS; - uint32_t flags = 0; - size_t value_length = 0; - char *value = NULL; - - value = memcached_get (memc, key->val, key->len, &value_length, &flags, &rc); - if (value) { - free (value); - } - return rc; -#endif -} diff --git a/php_libmemcached_compat.h b/php_libmemcached_compat.h deleted file mode 100644 index e740d310..00000000 --- a/php_libmemcached_compat.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Copyright (c) 2009 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.0 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_0.txt. | - | If you did not receive a copy of the PHP license and are unable to | - | obtain it through the world-wide-web, please send a note to | - | license@php.net so we can mail you a copy immediately. | - +----------------------------------------------------------------------+ - | Authors: Andrei Zmievski | - +----------------------------------------------------------------------+ -*/ - -#ifndef PHP_LIBMEMCACHED_COMPAT -#define PHP_LIBMEMCACHED_COMPAT - -/* this is the version(s) we support */ -#include - -memcached_return php_memcached_exist (memcached_st *memc, zend_string *key); - -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x00052000 -# define MEMCACHED_SERVER_TEMPORARILY_DISABLED (1024 << 2) -#endif - -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000002 -# define HAVE_MEMCACHED_TOUCH 1 -#endif - -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000017 -# define HAVE_MEMCACHED_INSTANCE_ST 1 -#endif - -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00049000 -# define HAVE_LIBMEMCACHED_CHECK_CONFIGURATION 1 -#endif - -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000002 -# define HAVE_MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS 1 -#endif - -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00049000 -# define HAVE_LIBMEMCACHED_MEMCACHED 1 -#endif - -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000018 -# define HAVE_MEMCACHED_BEHAVIOR_SERVER_TIMEOUT_LIMIT 1 -#endif - -#ifdef HAVE_MEMCACHED_INSTANCE_ST -typedef const memcached_instance_st * php_memcached_instance_st; -#else -typedef memcached_server_instance_st php_memcached_instance_st; -#endif - -#endif diff --git a/php_memcached.c b/php_memcached.c index e1a045b5..79001319 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -1753,7 +1753,6 @@ PHP_METHOD(Memcached, setByKey) } /* }}} */ -#ifdef HAVE_MEMCACHED_TOUCH /* {{{ Memcached::touch(string key, [, int expiration ]) Sets a new expiration for the given key */ PHP_METHOD(Memcached, touch) @@ -1769,8 +1768,6 @@ PHP_METHOD(Memcached, touchByKey) php_memc_store_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, MEMC_OP_TOUCH, 1); } /* }}} */ -#endif - /* {{{ Memcached::setMulti(array items [, int expiration ]) Sets the keys/values specified in the items array */ @@ -2305,17 +2302,7 @@ PHP_METHOD(Memcached, addServer) MEMC_METHOD_FETCH_OBJECT; s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000002 - if (ZSTR_VAL(host)[0] == '/') { /* unix domain socket */ - status = memcached_server_add_unix_socket_with_weight(intern->memc, ZSTR_VAL(host), weight); - } else if (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_USE_UDP)) { - status = memcached_server_add_udp_with_weight(intern->memc, ZSTR_VAL(host), port, weight); - } else { - status = memcached_server_add_with_weight(intern->memc, ZSTR_VAL(host), port, weight); - } -#else status = memcached_server_add_with_weight(intern->memc, ZSTR_VAL(host), port, weight); -#endif if (s_memc_status_handle_result_code(intern, status) == FAILURE) { RETURN_FALSE; @@ -2511,7 +2498,6 @@ PHP_METHOD(Memcached, flushBuffers) } /* }}} */ -#ifdef HAVE_LIBMEMCACHED_CHECK_CONFIGURATION /* {{{ Memcached::getLastErrorMessage() Returns the last error message that occurred */ PHP_METHOD(Memcached, getLastErrorMessage) @@ -2559,7 +2545,6 @@ PHP_METHOD(Memcached, getLastErrorErrno) RETURN_LONG(memcached_last_error_errno(intern->memc)); } /* }}} */ -#endif /* {{{ Memcached::getLastDisconnectedServer() Returns the last disconnected server @@ -2794,11 +2779,7 @@ static PHP_METHOD(Memcached, getOption) result = memcached_callback_get(intern->memc, MEMCACHED_CALLBACK_PREFIX_KEY, &retval); if (retval == MEMCACHED_SUCCESS && result) { -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX == 0x00049000 - RETURN_STRINGL(result, strlen(result)); -#else RETURN_STRING(result); -#endif } else { RETURN_EMPTY_STRING(); } @@ -2863,23 +2844,11 @@ int php_memc_set_option(php_memc_object_t *intern, long option, zval *value) { zend_string *str; char *key; -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX == 0x00049000 - char tmp[MEMCACHED_PREFIX_KEY_MAX_SIZE - 1]; -#endif str = zval_get_string(value); if (ZSTR_LEN(str) == 0) { key = NULL; } else { - /* - work-around a bug in libmemcached in version 0.49 that truncates the trailing - character of the key prefix, to avoid the issue we pad it with a '0' - */ -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX == 0x00049000 - snprintf(tmp, sizeof(tmp), "%s0", ZSTR_VAL(str)); - key = tmp; -#else key = ZSTR_VAL(str); -#endif } if (memcached_callback_set(intern->memc, MEMCACHED_CALLBACK_PREFIX_KEY, key) == MEMCACHED_BAD_KEY_PROVIDED) { zend_string_release(str); @@ -2908,14 +2877,9 @@ int php_memc_set_option(php_memc_object_t *intern, long option, zval *value) * (non-weighted) case. We have to clean up ourselves. */ if (!lval) { -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX > 0x00037000 - (void)memcached_behavior_set_key_hash(intern->memc, MEMCACHED_HASH_DEFAULT); - (void)memcached_behavior_set_distribution_hash(intern->memc, MEMCACHED_HASH_DEFAULT); - (void)memcached_behavior_set_distribution(intern->memc, MEMCACHED_DISTRIBUTION_MODULA); -#else - intern->memc->hash = 0; - intern->memc->distribution = 0; -#endif + (void)memcached_behavior_set_key_hash(intern->memc, MEMCACHED_HASH_DEFAULT); + (void)memcached_behavior_set_distribution_hash(intern->memc, MEMCACHED_HASH_DEFAULT); + (void)memcached_behavior_set_distribution(intern->memc, MEMCACHED_DISTRIBUTION_MODULA); } break; @@ -3997,10 +3961,10 @@ static zend_function_entry memcached_class_methods[] = { MEMC_ME(set, arginfo_set) MEMC_ME(setByKey, arginfo_setByKey) -#ifdef HAVE_MEMCACHED_TOUCH + MEMC_ME(touch, arginfo_touch) MEMC_ME(touchByKey, arginfo_touchByKey) -#endif + MEMC_ME(setMulti, arginfo_setMulti) MEMC_ME(setMultiByKey, arginfo_setMultiByKey) @@ -4032,11 +3996,10 @@ static zend_function_entry memcached_class_methods[] = { MEMC_ME(quit, arginfo_quit) MEMC_ME(flushBuffers, arginfo_flushBuffers) -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00049000 MEMC_ME(getLastErrorMessage, arginfo_getLastErrorMessage) MEMC_ME(getLastErrorCode, arginfo_getLastErrorCode) MEMC_ME(getLastErrorErrno, arginfo_getLastErrorErrno) -#endif + MEMC_ME(getLastDisconnectedServer, arginfo_getLastDisconnectedServer) MEMC_ME(getStats, arginfo_getStats) @@ -4229,9 +4192,8 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) REGISTER_MEMC_CLASS_CONST_LONG(OPT_DISTRIBUTION, MEMCACHED_BEHAVIOR_DISTRIBUTION); REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_MODULA, MEMCACHED_DISTRIBUTION_MODULA); REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_CONSISTENT, MEMCACHED_DISTRIBUTION_CONSISTENT); -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00049000 REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_VIRTUAL_BUCKET, MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET); -#endif + REGISTER_MEMC_CLASS_CONST_LONG(OPT_LIBKETAMA_COMPATIBLE, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED); REGISTER_MEMC_CLASS_CONST_LONG(OPT_LIBKETAMA_HASH, MEMCACHED_BEHAVIOR_KETAMA_HASH); REGISTER_MEMC_CLASS_CONST_LONG(OPT_TCP_KEEPALIVE, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE); @@ -4257,14 +4219,10 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) REGISTER_MEMC_CLASS_CONST_LONG(OPT_SORT_HOSTS, MEMCACHED_BEHAVIOR_SORT_HOSTS); REGISTER_MEMC_CLASS_CONST_LONG(OPT_VERIFY_KEY, MEMCACHED_BEHAVIOR_VERIFY_KEY); REGISTER_MEMC_CLASS_CONST_LONG(OPT_USE_UDP, MEMCACHED_BEHAVIOR_USE_UDP); -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x00037000 REGISTER_MEMC_CLASS_CONST_LONG(OPT_NUMBER_OF_REPLICAS, MEMCACHED_BEHAVIOR_NUMBER_OF_REPLICAS); REGISTER_MEMC_CLASS_CONST_LONG(OPT_RANDOMIZE_REPLICA_READ, MEMCACHED_BEHAVIOR_RANDOMIZE_REPLICA_READ); -#endif -#ifdef HAVE_MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS REGISTER_MEMC_CLASS_CONST_LONG(OPT_REMOVE_FAILED_SERVERS, MEMCACHED_BEHAVIOR_REMOVE_FAILED_SERVERS); -#endif -#ifdef HAVE_MEMCACHED_BEHAVIOR_SERVER_TIMEOUT_LIMIT +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000018 REGISTER_MEMC_CLASS_CONST_LONG(OPT_SERVER_TIMEOUT_LIMIT, MEMCACHED_BEHAVIOR_SERVER_TIMEOUT_LIMIT); #endif diff --git a/php_memcached_private.h b/php_memcached_private.h index a04e19be..fe6ccc2c 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -25,7 +25,13 @@ # include "config.h" #endif -#include "php_libmemcached_compat.h" +#include + +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000017 +typedef const memcached_instance_st * php_memcached_instance_st; +#else +typedef memcached_server_instance_st php_memcached_instance_st; +#endif #include #include @@ -208,8 +214,6 @@ PHP_MINFO_FUNCTION(memcached); char *php_memc_printable_func (zend_fcall_info *fci, zend_fcall_info_cache *fci_cache); -memcached_return php_memcached_exist (memcached_st *memc, zend_string *key); - zend_bool php_memc_init_sasl_if_needed(); #endif /* PHP_MEMCACHED_PRIVATE_H */ diff --git a/php_memcached_session.c b/php_memcached_session.c index 42659fe5..c7e6d1cd 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -527,7 +527,7 @@ PS_VALIDATE_SID_FUNC(memcached) { memcached_st *memc = PS_GET_MOD_DATA(); - if (php_memcached_exist(memc, key) == MEMCACHED_SUCCESS) { + if (memcached_exist(memc, key->val, key->len) == MEMCACHED_SUCCESS) { return SUCCESS; } else { return FAILURE; From d9dea45e9719abd0761ae51368359975cb26534b Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Fri, 20 Jan 2017 07:21:39 -0500 Subject: [PATCH 005/218] Add release notes about session protocol,get and getMulti changing (#271) And update the memcached-api.php file for the branch. --- memcached-api.php | 8 ++++---- package.xml | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/memcached-api.php b/memcached-api.php index d22d0cf9..e0e8f944 100644 --- a/memcached-api.php +++ b/memcached-api.php @@ -189,13 +189,13 @@ class Memcached { public function __construct( $persistent_id = '', $on_new_object_cb = null ) {} - public function get( $key, $cache_cb = null, &$cas_token = null, &$udf_flags = null ) {} + public function get( $key, callable $cache_cb = null, $flags = 0) {} - public function getByKey( $server_key, $key, $cache_cb = null, &$cas_token = null, &$udf_flags = null ) {} + public function getByKey( $server_key, $key, callable $cache_cb = null, $flags = 0 ) {} - public function getMulti( array $keys, &$cas_tokens = null, $flags = 0, &$udf_flags = null ) {} + public function getMulti( array $keys, $flags = 0) {} - public function getMultiByKey( $server_key, array $keys, &$cas_tokens = null, $flags = 0, &$udf_flags = null ) {} + public function getMultiByKey( $server_key, array $keys, $flags = 0) {} public function getDelayed( array $keys, $with_cas = null, $value_cb = null ) {} diff --git a/package.xml b/package.xml index e8d5c743..0dd61ada 100644 --- a/package.xml +++ b/package.xml @@ -38,8 +38,9 @@ libmemcached. Please note that this is a beta release and reporting any issues w before we move closer to releasing stable version. API - * get commands do not take cas or user flags parameters. - * get and getMulti commands take Memcached::GET_EXTENDED flag to retrieve user flags and cas tokens + * The method signature of get, getByKey, getMulti, and getMultiByKey changed. + * get* and getMulti* commands no longer take cas or user flags parameters. + * get* and getMulti* commands now take the Memcached::GET_EXTENDED flag to retrieve user flags and cas tokens. * Fixes getStats command to return all stats from all servers * Fixes allKeys command behaviour * Fixes error where cache callback for get command was not setting expiration time properly @@ -48,6 +49,7 @@ API * CAS tokens are returned as integers and they overflow to strings as needed Session handler + * The session memcached protocol config name was changed, and the default protocol was changed from text to binary protocol. If your memcached setup does not support the binary protocol(e.g. if using twemproxy), then set memcached.sess_binary_protocol = Off. (Previously called memcached.sess_binary) * Session lock algorithm updated (new ini-values memcached.sess_lock_wait_min, memcached.sess_lock_wait_max and memcached.sess_lock_retries) * Session extension uses PHP allocators (still some work to do on the rest of the extension) * Ini-values take effect during session_start or session_regenerate_id From 172d1ffe694406bf64193070b5498f44c4db093a Mon Sep 17 00:00:00 2001 From: Arjen Date: Fri, 20 Jan 2017 19:14:54 +0100 Subject: [PATCH 006/218] Fix tests for PHP 7.1 (#297) invoke_callback_2 fails because of ArgumentCountException (init_cb_arg gets only 2 args) Check number of passed arguments with func_num_args() insteadof checking $args is null session_lock fails because of second warning in 7.1 Skip session_lock.phpt for php < 7.1 and create new testcase for >= 7.1 which tests both warnings. Update .travis.yml, don't allow failures for 7.1 anymore! --- .travis.yml | 6 +--- package.xml | 1 + tests/invoke_callback_2.phpt | 17 +++++----- tests/session_lock-php71.phpt | 62 +++++++++++++++++++++++++++++++++++ tests/session_lock.phpt | 2 ++ 5 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 tests/session_lock-php71.phpt diff --git a/.travis.yml b/.travis.yml index 4aae7552..02c367a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,8 +8,6 @@ php: matrix: fast_finish: true - allow_failures: - - php: 7.1 env: - LIBMEMCACHED_VERSION=1.0.18 # Debian Jessie / Ubuntu Xenial @@ -31,6 +29,4 @@ script: cache: directories: - - $HOME/cache - - + - $HOME/cache \ No newline at end of file diff --git a/package.xml b/package.xml index 0dd61ada..2091f2e2 100644 --- a/package.xml +++ b/package.xml @@ -165,6 +165,7 @@ Tests + diff --git a/tests/invoke_callback_2.phpt b/tests/invoke_callback_2.phpt index 07e84f94..9749ed18 100644 --- a/tests/invoke_callback_2.phpt +++ b/tests/invoke_callback_2.phpt @@ -18,9 +18,9 @@ function init_cb_fail($m, $id) { echo "configured, should not be called.\n"; } -function init_cb_arg($m, $id, $arg) { +function init_cb_arg($m, $id) { + var_dump(func_num_args()); var_dump($id); - var_dump($arg); } function init_nopersist_cb($m, $id) { @@ -33,15 +33,14 @@ class Foo extends Memcached { parent::__construct($id, array($this, 'init')); } - function init($obj, $id, $options) { + function init($obj, $id) { + var_dump(func_num_args()); var_dump($this->isPristine()); var_dump($this->isPersistent()); var_dump($id); } } -error_reporting(0); - echo "cb call\n"; $m1 = new Memcached('foo1', 'init_cb'); @@ -50,7 +49,6 @@ $m1 = new Memcached('foo1', 'init_cb_fail'); echo "cb arg without arg\n"; $m1 = new Memcached('foo3', 'init_cb_arg'); -echo $php_errormsg, "\n"; echo "cb arg not persistent\n"; $m1 = new Memcached(null, 'init_nopersist_cb'); @@ -63,7 +61,7 @@ $m1 = new Foo('baz'); echo "cb second persistent in object\n"; $m1 = new Foo('baz'); - +?> --EXPECT-- cb call string(9) "Memcached" @@ -71,17 +69,18 @@ bool(true) string(4) "foo1" cb not run cb arg without arg +int(2) string(4) "foo3" -NULL - cb arg not persistent bool(false) NULL cb in object +int(2) bool(true) bool(false) NULL cb persistent in object +int(2) bool(true) bool(true) string(3) "baz" diff --git a/tests/session_lock-php71.phpt b/tests/session_lock-php71.phpt new file mode 100644 index 00000000..207f64cf --- /dev/null +++ b/tests/session_lock-php71.phpt @@ -0,0 +1,62 @@ +--TEST-- +Session lock +--SKIPIF-- + +--INI-- +memcached.sess_locking = true +memcached.sess_lock_wait_min = 500 +memcached.sess_lock_wait_max = 1000 +memcached.sess_lock_retries = 3 +memcached.sess_prefix = "memc.test." + +session.save_handler = memcached + +--FILE-- +addServer(MEMC_SERVER_HOST, MEMC_SERVER_PORT); + +ob_start(); +ini_set ('session.save_path', MEMC_SERVER_HOST . ':' . MEMC_SERVER_PORT); + +session_start(); +$session_id = session_id(); + +$_SESSION["test"] = "hello"; +session_write_close(); + +session_start(); +var_dump ($m->get ('memc.test.' . session_id())); +var_dump ($m->get ('memc.test.lock.' . session_id())); +session_write_close(); +var_dump ($m->get ('memc.test.lock.' . session_id())); + +// Test lock min / max +$m->set ('memc.test.lock.' . $session_id, '1'); + +$time_start = microtime(true); +session_start(); +$time = microtime(true) - $time_start; + +if (round ($time, 1) != 2.5) { + echo "Waited longer than expected: $time" . PHP_EOL; +} +echo "OK"; + +--EXPECTF-- +string(17) "test|s:5:"hello";" +string(1) "1" +bool(false) + +Warning: session_start(): Unable to clear session lock record in %s on line %d + +Warning: session_start(): Failed to read session data: memcached (path: 127.0.0.1:11211) in %s on line %d +OK diff --git a/tests/session_lock.phpt b/tests/session_lock.phpt index 79c32888..570e5a2a 100644 --- a/tests/session_lock.phpt +++ b/tests/session_lock.phpt @@ -4,6 +4,8 @@ Session lock = 70100) print "skip"; ?> --INI-- memcached.sess_locking = true From c3f90bcb59dc434986844cc1c91db0e1cd8b078d Mon Sep 17 00:00:00 2001 From: Frost Wong Date: Sat, 21 Jan 2017 02:19:34 +0800 Subject: [PATCH 007/218] correct a spelling mistake (#207) --- config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.m4 b/config.m4 index ab6142a1..50e2d3bd 100644 --- a/config.m4 +++ b/config.m4 @@ -24,7 +24,7 @@ PHP_ARG_ENABLE(memcached-sasl, whether to enable memcached sasl support, [ --disable-memcached-sasl Disable memcached sasl support], yes, no) PHP_ARG_ENABLE(memcached-protocol, whether to enable memcached protocol support, -[ --enable-memcached-protocol Enable memcached protocoll support], no, no) +[ --enable-memcached-protocol Enable memcached protocol support], no, no) PHP_ARG_WITH(system-fastlz, whether to use system FastLZ bibrary, [ --with-system-fastlz Use system FastLZ bibrary], no, no) From 5fee5fa9099af5094b1ecc65945fff07918dd6f0 Mon Sep 17 00:00:00 2001 From: Steven Hilder Date: Fri, 20 Jan 2017 21:02:47 +0200 Subject: [PATCH 008/218] Use bool data type for HAVE_* class constants (#166) --- php_memcached.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 79001319..b500b887 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -4140,39 +4140,39 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) * Indicate whether igbinary serializer is available */ #ifdef HAVE_MEMCACHED_IGBINARY - REGISTER_MEMC_CLASS_CONST_LONG(HAVE_IGBINARY, 1); + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_IGBINARY, 1); #else - REGISTER_MEMC_CLASS_CONST_LONG(HAVE_IGBINARY, 0); + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_IGBINARY, 0); #endif /* * Indicate whether json serializer is available */ #ifdef HAVE_JSON_API - REGISTER_MEMC_CLASS_CONST_LONG(HAVE_JSON, 1); + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_JSON, 1); #else - REGISTER_MEMC_CLASS_CONST_LONG(HAVE_JSON, 0); + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_JSON, 0); #endif /* * Indicate whether msgpack serializer is available */ #ifdef HAVE_MEMCACHED_MSGPACK - REGISTER_MEMC_CLASS_CONST_LONG(HAVE_MSGPACK, 1); + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_MSGPACK, 1); #else - REGISTER_MEMC_CLASS_CONST_LONG(HAVE_MSGPACK, 0); + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_MSGPACK, 0); #endif #ifdef HAVE_MEMCACHED_SESSION - REGISTER_MEMC_CLASS_CONST_LONG(HAVE_SESSION, 1); + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_SESSION, 1); #else - REGISTER_MEMC_CLASS_CONST_LONG(HAVE_SESSION, 0); + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_SESSION, 0); #endif #ifdef HAVE_MEMCACHED_SASL - REGISTER_MEMC_CLASS_CONST_LONG(HAVE_SASL, 1); + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_SASL, 1); #else - REGISTER_MEMC_CLASS_CONST_LONG(HAVE_SASL, 0); + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_SASL, 0); #endif /* From b15936c0c04b3c24ec5677f1c4a8bc694d455a4a Mon Sep 17 00:00:00 2001 From: Timandes White Date: Sun, 22 Jan 2017 10:34:50 +0800 Subject: [PATCH 009/218] Add optional parameter 'type' for method 'getStats' (#298) --- memcached-api.php | 2 +- php_memcached.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/memcached-api.php b/memcached-api.php index e0e8f944..64b20b26 100644 --- a/memcached-api.php +++ b/memcached-api.php @@ -275,7 +275,7 @@ public function getLastDisconnectedServer( ) {} public function flush( $delay = 0 ) {} - public function getStats( ) {} + public function getStats( $type = null ) {} public function getVersion( ) {} diff --git a/php_memcached.c b/php_memcached.c index b500b887..0a19f204 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -2645,16 +2645,21 @@ memcached_return s_stat_execute_cb (php_memcached_instance_st instance, const ch PHP_METHOD(Memcached, getStats) { memcached_return status; + char *args = NULL; + zend_string *args_string = NULL; MEMC_METHOD_INIT_VARS; - if (zend_parse_parameters_none() == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!", &args_string) == FAILURE) { return; } MEMC_METHOD_FETCH_OBJECT; + if (args_string) + args = ZSTR_VAL(args_string); + array_init(return_value); - status = memcached_stat_execute(intern->memc, NULL, s_stat_execute_cb, return_value); + status = memcached_stat_execute(intern->memc, args, s_stat_execute_cb, return_value); if (s_memc_status_handle_result_code(intern, status) == FAILURE) { zval_ptr_dtor(return_value); RETURN_FALSE; @@ -3927,6 +3932,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_setBucket, 3) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_getStats, 0) + ZEND_ARG_INFO(0, args) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_getVersion, 0) From 493d6911bfc5460039b428b8c7c66b577511a19c Mon Sep 17 00:00:00 2001 From: Aris Buzachis Date: Sun, 22 Jan 2017 23:37:42 +0200 Subject: [PATCH 010/218] fix: 0 max_execution_time ini value (#266) It seems that zend_ini_long doesn't work anymore with ZEND_STRS and that the extesion should use ZEND_STRL, back again. --- php_memcached_session.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached_session.c b/php_memcached_session.c index c7e6d1cd..e8f61cf5 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -113,7 +113,7 @@ time_t s_lock_expiration() return s_adjust_expiration(MEMC_SESS_INI(lock_expiration)); } else { - zend_long max_execution_time = zend_ini_long(ZEND_STRS("max_execution_time"), 0); + zend_long max_execution_time = zend_ini_long(ZEND_STRL("max_execution_time"), 0); if (max_execution_time > 0) { return s_adjust_expiration(max_execution_time); } From 2af9b615907109874988ff57c27b04eecc862ee2 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 23 Jan 2017 07:28:10 +0000 Subject: [PATCH 011/218] Fix port number in getVersion (#300) (390) --- php_memcached.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index 0a19f204..cf26bff6 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -3353,7 +3353,7 @@ memcached_return s_server_cursor_version_cb(const memcached_st *ptr, php_memcach instance->micro_version); #endif - address = strpprintf(0, "%s:%d", memcached_server_name(instance), memcached_server_port(instance) - 1); + address = strpprintf(0, "%s:%d", memcached_server_name(instance), memcached_server_port(instance)); ZVAL_STR(&rv, version); zend_hash_add(Z_ARRVAL_P(return_value), address, &rv); From 9debfacb8c1c3daeb18388796711c87ad56d6c35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samantha=20Qui=C3=B1ones?= Date: Tue, 17 Mar 2015 00:32:06 -0400 Subject: [PATCH 012/218] Extended key checking to match the language of the memcached spec (#167) Updated to php7 branch by Aaron Stone --- php_memcached.c | 43 +++++++++------- tests/keys.phpt | 69 ++++++++++++++++++++++++++ tests/session_badconf_emptyprefix.phpt | 2 +- tests/session_badconf_prefix.phpt | 2 +- 4 files changed, 97 insertions(+), 19 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index cf26bff6..64f135ad 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -202,15 +202,28 @@ static inline php_memc_object_t *php_memc_fetch_object(zend_object *obj) { } \ memc_user_data = (php_memc_user_data_t *) memcached_get_user_data(intern->memc); -#define MEMC_CHECK_KEY(intern, key) \ - if (UNEXPECTED(ZSTR_LEN(key) == 0 || \ - ZSTR_LEN(key) > MEMC_OBJECT_KEY_MAX_LENGTH || \ - (memcached_behavior_get(intern->memc, \ - MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) ? \ - strchr(ZSTR_VAL(key), '\n') : \ - strchr(ZSTR_VAL(key), ' ')))) { \ - intern->rescode = MEMCACHED_BAD_KEY_PROVIDED; \ - RETURN_FALSE; \ +static +zend_bool s_memc_valid_key_binary(const char *key) +{ + return strchr(key, '\n') == NULL; +} + +static +zend_bool s_memc_valid_key_ascii(const char *key) +{ + while (*key && !iscntrl(*key) && !isspace(*key)) ++key; + return *key == '\0'; +} + +#define MEMC_CHECK_KEY(intern, key) \ + if (UNEXPECTED(ZSTR_LEN(key) == 0 || \ + ZSTR_LEN(key) > MEMC_OBJECT_KEY_MAX_LENGTH || \ + (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) \ + ? !s_memc_valid_key_binary(ZSTR_VAL(key)) \ + : !s_memc_valid_key_ascii(ZSTR_VAL(key)) \ + ))) { \ + intern->rescode = MEMCACHED_BAD_KEY_PROVIDED; \ + RETURN_FALSE; \ } #ifdef HAVE_MEMCACHED_PROTOCOL @@ -307,18 +320,14 @@ static PHP_INI_MH(OnUpdateSessionPrefixString) { if (new_value && ZSTR_LEN(new_value) > 0) { - char *ptr = ZSTR_VAL(new_value); - - while (*ptr != '\0') { - if (isspace (*ptr++)) { - php_error_docref(NULL, E_WARNING, "memcached.sess_prefix cannot contain whitespace characters"); - return FAILURE; - } - } if (ZSTR_LEN(new_value) > MEMCACHED_MAX_KEY) { php_error_docref(NULL, E_WARNING, "memcached.sess_prefix too long (max: %d)", MEMCACHED_MAX_KEY - 1); return FAILURE; } + if (!s_memc_valid_key_ascii(ZSTR_VAL(new_value))) { + php_error_docref(NULL, E_WARNING, "memcached.sess_prefix cannot contain whitespace or control characters"); + return FAILURE; + } } return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } diff --git a/tests/keys.phpt b/tests/keys.phpt index 63cce0a3..f320e03f 100644 --- a/tests/keys.phpt +++ b/tests/keys.phpt @@ -28,6 +28,11 @@ var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); var_dump ($ascii->set (''/*empty key*/, 'this is a test')); var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); +for ($i=0;$i<32;$i++) { + var_dump ($ascii->set ('asciikeywithnonprintablechar-' . chr($i) . '-here', 'this is a test')); + var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); +} + var_dump ($ascii->set (str_repeat ('1234567890', 512), 'this is a test')); var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); @@ -46,4 +51,68 @@ bool(false) bool(true) bool(false) bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) OK diff --git a/tests/session_badconf_emptyprefix.phpt b/tests/session_badconf_emptyprefix.phpt index fd19f1df..f49a8417 100644 --- a/tests/session_badconf_emptyprefix.phpt +++ b/tests/session_badconf_emptyprefix.phpt @@ -24,5 +24,5 @@ session_write_close(); echo "OK"; --EXPECTF-- -Warning: ini_set(): memcached.sess_prefix cannot contain whitespace characters in %s on line %d +Warning: ini_set(): memcached.sess_prefix cannot contain whitespace or control characters in %s on line %d OK diff --git a/tests/session_badconf_prefix.phpt b/tests/session_badconf_prefix.phpt index c42e8376..8421edc3 100644 --- a/tests/session_badconf_prefix.phpt +++ b/tests/session_badconf_prefix.phpt @@ -18,7 +18,7 @@ ini_set('memcached.sess_prefix', str_repeat('a', 512)); echo "OK"; --EXPECTF-- -Warning: ini_set(): memcached.sess_prefix cannot contain whitespace characters in %s on line %d +Warning: ini_set(): memcached.sess_prefix cannot contain whitespace or control characters in %s on line %d Warning: ini_set(): memcached.sess_prefix too long (max: %d) in %s on line %d OK \ No newline at end of file From e1932dceb68767995a03345164db8437e00d04e8 Mon Sep 17 00:00:00 2001 From: dyeldandi Date: Tue, 24 Jan 2017 15:37:37 +0400 Subject: [PATCH 013/218] Added error reporting to session code (#301) --- php_memcached_session.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/php_memcached_session.c b/php_memcached_session.c index e8f61cf5..25ca0ae2 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -442,6 +442,7 @@ PS_READ_FUNC(memcached) *val = ZSTR_EMPTY_ALLOC(); return SUCCESS; } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "error getting session from memcached: %s", memcached_last_error_message(memc)); return FAILURE; } } @@ -470,6 +471,8 @@ PS_WRITE_FUNC(memcached) do { if (memcached_set(memc, key->val, key->len, val->val, val->len, expiration, 0) == MEMCACHED_SUCCESS) { return SUCCESS; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "error saving session to memcached: %s", memcached_last_error_message(memc)); } } while (--retries > 0); From 8924e3d72b9c735ec3e411f1958d84ac68b139c7 Mon Sep 17 00:00:00 2001 From: Dick Tang Date: Wed, 25 Jan 2017 02:17:07 +0800 Subject: [PATCH 014/218] fix: compression edge case (#255) * correct the compression_factor calculation * send uncompress value and proper set compressed flags when compression saving is too small --- php_memcached.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 64f135ad..b014ecc6 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -108,10 +108,10 @@ static int php_memc_list_entry(void) { #define MEMC_VAL_COMPRESSION_ZLIB (1<<1) #define MEMC_VAL_COMPRESSION_FASTLZ (1<<2) -#define MEMC_VAL_GET_FLAGS(internal_flags) ((internal_flags & MEMC_MASK_INTERNAL) >> 4) -#define MEMC_VAL_SET_FLAG(internal_flags, internal_flag) ((internal_flags) |= ((internal_flag << 4) & MEMC_MASK_INTERNAL)) -#define MEMC_VAL_HAS_FLAG(internal_flags, internal_flag) ((MEMC_VAL_GET_FLAGS(internal_flags) & internal_flag) == internal_flag) -#define MEMC_VAL_DEL_FLAG(internal_flags, internal_flag) internal_flags &= ~((internal_flag << 4) & MEMC_MASK_INTERNAL) +#define MEMC_VAL_GET_FLAGS(internal_flags) (((internal_flags) & MEMC_MASK_INTERNAL) >> 4) +#define MEMC_VAL_SET_FLAG(internal_flags, internal_flag) ((internal_flags) |= (((internal_flag) << 4) & MEMC_MASK_INTERNAL)) +#define MEMC_VAL_HAS_FLAG(internal_flags, internal_flag) ((MEMC_VAL_GET_FLAGS(internal_flags) & (internal_flag)) == (internal_flag)) +#define MEMC_VAL_DEL_FLAG(internal_flags, internal_flag) (internal_flags &= (~(((internal_flag) << 4) & MEMC_MASK_INTERNAL))) /**************************************** User-defined flags @@ -876,7 +876,8 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str } /* This means the value was too small to be compressed, still a success */ - if (compressed_size > (ZSTR_LEN(payload) * MEMC_G(compression_factor))) { + if (ZSTR_LEN(payload) <= (compressed_size * MEMC_G(compression_factor))) { + MEMC_VAL_DEL_FLAG(*flags, MEMC_VAL_COMPRESSION_FASTLZ | MEMC_VAL_COMPRESSION_ZLIB); efree (buffer); return 1; } From 7283b11d147c7fab4915623c627a75a612534a6b Mon Sep 17 00:00:00 2001 From: Dick Tang Date: Fri, 10 Jun 2016 21:37:55 +0800 Subject: [PATCH 015/218] test: compression edge case verification (#256) test compressed SET/GET under various settings of - compression_factor - compression_threshold - data length --- package.xml | 1 + tests/compression_conditions.phpt | 125 ++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 tests/compression_conditions.phpt diff --git a/package.xml b/package.xml index 2091f2e2..27491332 100644 --- a/package.xml +++ b/package.xml @@ -94,6 +94,7 @@ Tests + diff --git a/tests/compression_conditions.phpt b/tests/compression_conditions.phpt new file mode 100644 index 00000000..ca3c2d77 --- /dev/null +++ b/tests/compression_conditions.phpt @@ -0,0 +1,125 @@ +--TEST-- +Memcached compression test +--SKIPIF-- + +--FILE-- +setOption(Memcached::OPT_COMPRESSION, false); + } else { + $m->setOption(Memcached::OPT_COMPRESSION, true); + $m->setOption(Memcached::OPT_COMPRESSION_TYPE, get_compression($set_compression)); + } + + $m->set($key, $value, 1800); + + $value_back = $m->get($key); + var_dump($value === $value_back); +} + +fetch_with_compression($m, 'hello01', $data, 'zlib', 1.3, 4); +fetch_with_compression($m, 'hello02', $data, 'fastlz', 1.3, 4); +fetch_with_compression($m, 'hello03', $data, '', 1.3, 4); +fetch_with_compression($m, 'hello04', $short_data, 'zlib', 1.3, 4); +fetch_with_compression($m, 'hello05', $short_data, 'fastlz', 1.3, 4); +fetch_with_compression($m, 'hello06', $short_data, '', 1.3, 4); +fetch_with_compression($m, 'hello11', $data, 'zlib', 0.3, 4); +fetch_with_compression($m, 'hello12', $data, 'fastlz', 0.3, 4); +fetch_with_compression($m, 'hello13', $data, '', 0.3, 4); +fetch_with_compression($m, 'hello14', $short_data, 'zlib', 0.3, 4); +fetch_with_compression($m, 'hello15', $short_data, 'fastlz', 0.3, 4); +fetch_with_compression($m, 'hello16', $short_data, '', 0.3, 4); +fetch_with_compression($m, 'hello21', $data, 'zlib', 1.3, 2000); +fetch_with_compression($m, 'hello22', $data, 'fastlz', 1.3, 2000); +fetch_with_compression($m, 'hello23', $data, '', 1.3, 2000); +fetch_with_compression($m, 'hello24', $short_data, 'zlib', 1.3, 2000); +fetch_with_compression($m, 'hello25', $short_data, 'fastlz', 1.3, 2000); +fetch_with_compression($m, 'hello26', $short_data, '', 1.3, 2000); +fetch_with_compression($m, 'hello31', $data, 'zlib', 0.3, 2000); +fetch_with_compression($m, 'hello32', $data, 'fastlz', 0.3, 2000); +fetch_with_compression($m, 'hello33', $data, '', 0.3, 2000); +fetch_with_compression($m, 'hello34', $short_data, 'zlib', 0.3, 2000); +fetch_with_compression($m, 'hello35', $short_data, 'fastlz', 0.3, 2000); +fetch_with_compression($m, 'hello36', $short_data, '', 0.3, 2000); +?> +--EXPECT-- +len=[4877] set=[zlib] factor=[1.3] threshold=[4] +bool(true) +len=[4877] set=[fastlz] factor=[1.3] threshold=[4] +bool(true) +len=[4877] set=[] factor=[1.3] threshold=[4] +bool(true) +len=[7] set=[zlib] factor=[1.3] threshold=[4] +Memcached::set(): could not compress value +bool(true) +len=[7] set=[fastlz] factor=[1.3] threshold=[4] +bool(true) +len=[7] set=[] factor=[1.3] threshold=[4] +bool(true) +len=[4877] set=[zlib] factor=[0.3] threshold=[4] +bool(true) +len=[4877] set=[fastlz] factor=[0.3] threshold=[4] +bool(true) +len=[4877] set=[] factor=[0.3] threshold=[4] +bool(true) +len=[7] set=[zlib] factor=[0.3] threshold=[4] +Memcached::set(): could not compress value +bool(true) +len=[7] set=[fastlz] factor=[0.3] threshold=[4] +bool(true) +len=[7] set=[] factor=[0.3] threshold=[4] +bool(true) +len=[4877] set=[zlib] factor=[1.3] threshold=[2000] +bool(true) +len=[4877] set=[fastlz] factor=[1.3] threshold=[2000] +bool(true) +len=[4877] set=[] factor=[1.3] threshold=[2000] +bool(true) +len=[7] set=[zlib] factor=[1.3] threshold=[2000] +bool(true) +len=[7] set=[fastlz] factor=[1.3] threshold=[2000] +bool(true) +len=[7] set=[] factor=[1.3] threshold=[2000] +bool(true) +len=[4877] set=[zlib] factor=[0.3] threshold=[2000] +bool(true) +len=[4877] set=[fastlz] factor=[0.3] threshold=[2000] +bool(true) +len=[4877] set=[] factor=[0.3] threshold=[2000] +bool(true) +len=[7] set=[zlib] factor=[0.3] threshold=[2000] +bool(true) +len=[7] set=[fastlz] factor=[0.3] threshold=[2000] +bool(true) +len=[7] set=[] factor=[0.3] threshold=[2000] +bool(true) From c85f34c01ba884987fa3ed4daf7846e503a89cdf Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Wed, 25 Jan 2017 00:12:44 -0800 Subject: [PATCH 016/218] Make sure that s_compress_value() will always leave a valid payload, even if it did not get compressed --- php_memcached.c | 53 ++++++++++++++++--------------- tests/compression_conditions.phpt | 2 -- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index b014ecc6..1e73a4f9 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -830,6 +830,7 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str /* status */ zend_bool compress_status = 0; zend_string *payload = *payload_in; + uint32_t compression_type_flag = 0; /* Additional 5% for the data */ size_t buffer_size = (size_t) (((double) ZSTR_LEN(payload) * 1.05) + 1.0); @@ -847,7 +848,7 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str if (compressed_size > 0) { compress_status = 1; - MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSION_FASTLZ); + compression_type_flag = MEMC_VAL_COMPRESSION_FASTLZ; } } break; @@ -859,7 +860,7 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str if (status == Z_OK) { compress_status = 1; - MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSION_ZLIB); + compression_type_flag = MEMC_VAL_COMPRESSION_ZLIB; } } break; @@ -869,31 +870,29 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str break; } - if (!compress_status) { - php_error_docref(NULL, E_WARNING, "could not compress value"); - efree (buffer); - return 0; - } - - /* This means the value was too small to be compressed, still a success */ + /* This means the value was too small to be compressed and ended up larger */ if (ZSTR_LEN(payload) <= (compressed_size * MEMC_G(compression_factor))) { - MEMC_VAL_DEL_FLAG(*flags, MEMC_VAL_COMPRESSION_FASTLZ | MEMC_VAL_COMPRESSION_ZLIB); - efree (buffer); - return 1; + compress_status = 0; } - MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSED); + /* Replace the payload with the compressed copy */ + if (compress_status) { + MEMC_VAL_SET_FLAG(*flags, MEMC_VAL_COMPRESSED | compression_type_flag); + payload = zend_string_realloc(payload, compressed_size + sizeof(uint32_t), 0); - payload = zend_string_realloc(payload, compressed_size + sizeof(uint32_t), 0); + /* Copy the uin32_t at the beginning */ + memcpy(ZSTR_VAL(payload), &original_size, sizeof(uint32_t)); + memcpy(ZSTR_VAL(payload) + sizeof (uint32_t), buffer, compressed_size); + efree(buffer); - /* Copy the uin32_t at the beginning */ - memcpy(ZSTR_VAL(payload), &original_size, sizeof(uint32_t)); - memcpy(ZSTR_VAL(payload) + sizeof (uint32_t), buffer, compressed_size); - efree(buffer); + zend_string_forget_hash_val(payload); + *payload_in = payload; - zend_string_forget_hash_val(payload); - *payload_in = payload; - return 1; + return 1; + } + + /* Original payload was not modified */ + return 0; } static @@ -1043,11 +1042,13 @@ zend_string *s_zval_to_payload(php_memc_object_t *intern, zval *value, uint32_t /* If we have compression flag, compress the value */ if (should_compress) { - /* status */ - if (!s_compress_value (memc_user_data->compression_type, &payload, flags)) { - zend_string_release(payload); - return NULL; - } + /* s_compress_value() will always leave a valid payload, even if that payload + * did not actually get compressed. The flags will be set according to the + * to the compression type or no compression. + * + * No need to check the return value because the payload is always valid. + */ + (void)s_compress_value (memc_user_data->compression_type, &payload, flags); } if (memc_user_data->set_udf_flags >= 0) { diff --git a/tests/compression_conditions.phpt b/tests/compression_conditions.phpt index ca3c2d77..749ebe8a 100644 --- a/tests/compression_conditions.phpt +++ b/tests/compression_conditions.phpt @@ -80,7 +80,6 @@ bool(true) len=[4877] set=[] factor=[1.3] threshold=[4] bool(true) len=[7] set=[zlib] factor=[1.3] threshold=[4] -Memcached::set(): could not compress value bool(true) len=[7] set=[fastlz] factor=[1.3] threshold=[4] bool(true) @@ -93,7 +92,6 @@ bool(true) len=[4877] set=[] factor=[0.3] threshold=[4] bool(true) len=[7] set=[zlib] factor=[0.3] threshold=[4] -Memcached::set(): could not compress value bool(true) len=[7] set=[fastlz] factor=[0.3] threshold=[4] bool(true) From 6085768b48705b1e2a8f4ca516e43e0105850f3d Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 26 Jan 2017 02:06:30 +0000 Subject: [PATCH 017/218] Support for 64-bit offsets for increment and decrement (#306) While the memcached protocol allows for 64-bit increments or decrements, there is a quirk in the libmemcached API that the memcached_increment() and memcached_decrement() functions take only a 32-bit adjustment value. Since the memcached_increment_by_key() and memcached_decrement_by_key() functions do accept 64-bit adjustment values, and the memcached_increment() and memcached_decrement() functions are simply wrappers around those, we'll use them directly and thus support 64-bit adjustments in all cases. --- php_memcached.c | 25 +++++++++++++++---------- tests/incrdecr.phpt | 22 ++++++++++++++++++---- tests/incrdecr_bykey.phpt | 22 ++++++++++++++++++---- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 1e73a4f9..93d8738f 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -2185,7 +2185,7 @@ static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by static void php_memc_incdec_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key, zend_bool incr) { zend_string *key, *server_key = NULL; - long offset = 1; + zend_long offset = 1; uint64_t value = UINT64_MAX, initial = 0; time_t expiry = 0; memcached_return status; @@ -2208,22 +2208,27 @@ static void php_memc_incdec_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key, MEMC_CHECK_KEY(intern, key); if (offset < 0) { - php_error_docref(NULL, E_WARNING, "offset has to be > 0"); + php_error_docref(NULL, E_WARNING, "offset cannot be a negative value"); RETURN_FALSE; } if ((!by_key && n_args < 3) || (by_key && n_args < 4)) { if (by_key) { if (incr) { - status = memcached_increment_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), (unsigned int)offset, &value); + status = memcached_increment_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, &value); } else { - status = memcached_decrement_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), (unsigned int)offset, &value); + status = memcached_decrement_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, &value); } } else { + /* The libmemcached API has a quirk that memcached_increment() takes only a 32-bit + * offset, but memcached_increment_by_key() and all other increment and decrement + * functions take a 64-bit offset. The memcached protocol allows increment/decrement + * greater than UINT_MAX, so we just work around memcached_increment() here. + */ if (incr) { - status = memcached_increment(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), (unsigned int)offset, &value); + status = memcached_increment_by_key(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(key), ZSTR_LEN(key), offset, &value); } else { - status = memcached_decrement(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), (unsigned int)offset, &value); + status = memcached_decrement_by_key(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(key), ZSTR_LEN(key), offset, &value); } } @@ -2237,15 +2242,15 @@ static void php_memc_incdec_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key, } if (by_key) { if (incr) { - status = memcached_increment_with_initial_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), (unsigned int)offset, initial, expiry, &value); + status = memcached_increment_with_initial_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, expiry, &value); } else { - status = memcached_decrement_with_initial_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), (unsigned int)offset, initial, expiry, &value); + status = memcached_decrement_with_initial_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, expiry, &value); } } else { if (incr) { - status = memcached_increment_with_initial(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), (unsigned int)offset, initial, expiry, &value); + status = memcached_increment_with_initial(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, expiry, &value); } else { - status = memcached_decrement_with_initial(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), (unsigned int)offset, initial, expiry, &value); + status = memcached_decrement_with_initial(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, expiry, &value); } } if (s_should_retry_write(intern, status) && retries-- > 0) { diff --git a/tests/incrdecr.phpt b/tests/incrdecr.phpt index fc640985..cb3914a4 100644 --- a/tests/incrdecr.phpt +++ b/tests/incrdecr.phpt @@ -29,14 +29,25 @@ $m->decrement('foo', 2); var_dump($m->get('foo')); error_reporting(0); -echo "Invalid offset\n"; + +echo "Negative offset\n"; +$php_errormsg = ''; $m->increment('foo', -1); echo $php_errormsg, "\n"; var_dump($m->get('foo')); + +$php_errormsg = ''; $m->decrement('foo', -1); echo $php_errormsg, "\n"; var_dump($m->get('foo')); +echo "Enormous offset\n"; +$m->increment('foo', 4294967296); +var_dump($m->get('foo')); + +$m->decrement('foo', 4294967296); +var_dump($m->get('foo')); + --EXPECT-- Not there bool(false) @@ -51,8 +62,11 @@ int(2) int(4) int(3) int(1) -Invalid offset -Memcached::increment(): offset has to be > 0 +Negative offset +Memcached::increment(): offset cannot be a negative value +int(1) +Memcached::decrement(): offset cannot be a negative value int(1) -Memcached::decrement(): offset has to be > 0 +Enormous offset +int(4294967297) int(1) diff --git a/tests/incrdecr_bykey.phpt b/tests/incrdecr_bykey.phpt index 9c2db8dd..809f3b83 100644 --- a/tests/incrdecr_bykey.phpt +++ b/tests/incrdecr_bykey.phpt @@ -26,14 +26,25 @@ $m->decrementByKey('foo', 'foo', 2); var_dump($m->get('foo')); error_reporting(0); -echo "Invalid offset\n"; + +echo "Negative offset\n"; +$php_errormsg = ''; $m->incrementByKey('foo', 'foo', -1); echo $php_errormsg, "\n"; var_dump($m->get('foo')); + +$php_errormsg = ''; $m->decrementByKey('foo', 'foo', -1); echo $php_errormsg, "\n"; var_dump($m->get('foo')); +echo "Enormous offset\n"; +$m->incrementByKey('foo', 'foo', 4294967296); +var_dump($m->get('foo')); + +$m->decrementByKey('foo', 'foo', 4294967296); +var_dump($m->get('foo')); + --EXPECT-- Not there bool(false) @@ -45,8 +56,11 @@ int(2) int(4) int(3) int(1) -Invalid offset -Memcached::incrementByKey(): offset has to be > 0 +Negative offset +Memcached::incrementByKey(): offset cannot be a negative value +int(1) +Memcached::decrementByKey(): offset cannot be a negative value int(1) -Memcached::decrementByKey(): offset has to be > 0 +Enormous offset +int(4294967297) int(1) From 7a3b50992c5f68ed07132b6780128b3c7a1295e8 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 26 Jan 2017 01:43:46 -0800 Subject: [PATCH 018/218] Add ChangeLog notes and tentative release date for 3.0.0 --- ChangeLog | 39 +++++++++++++++++++++++++++++++++++++++ package.xml | 21 +++++++++++++++------ 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05f77181..24cb0a74 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,44 @@ memcached extension changelog +Version 3.0.0 (2017-01-27) +-------------------------- + * Support for PHP 7.0 and PHP 7.1 + * Fix compiling with SASL disabled + * Improved the test suite and Travis CI test runners + * Fix small string compression / decompression + * Fix increment/decrement with adjustments greater than 32-bit integers + * Fix session.gc_maxlifetime to handle both relative and absolute times + * Fix inability to reset OPT_PREFIX_KEY + +Version 3.0.0a1 (2016-02-22) +---------------------------- + Dependencies + * Support for PHP 7.0 + * Requires libmemcached 1.0 or higher + * Optional extension igbinary must 2.0 or higher + * Optional extension msgpack must be 2.0 or higher + + API + * The method signature of get, getByKey, getMulti, and getMultiByKey changed. + * get* and getMulti* commands no longer take cas or user flags parameters. + * get* and getMulti* commands now take the Memcached::GET_EXTENDED flag to retrieve user flags and cas tokens. + * Fixes getStats command to return all stats from all servers + * Fixes allKeys command behaviour + * Fixes error where cache callback for get command was not setting expiration time properly + * Added server type to server list + * Remove use_sasl ini-variable and initialise sasl as needed + * CAS tokens are returned as integers and they overflow to strings as needed + + Session handler + * The session memcached protocol config name was changed, and the default protocol was changed from text to binary protocol. If your memcached setup does not support the binary protocol(e.g. if using twemproxy), then set memcached.sess_binary_protocol = Off. (Previously called memcached.sess_binary) + * Session lock algorithm updated (new ini-values memcached.sess_lock_wait_min, memcached.sess_lock_wait_max and memcached.sess_lock_retries) + * Session extension uses PHP allocators (still some work to do on the rest of the extension) + * Ini-values take effect during session_start or session_regenerate_id + * Fixes crash with session_regenerate_id (work-around for PHP bug) + + Tests + * Fix several problematic tests + Version 2.2.0 (2014-04-01) -------------------------- * Added the OPT_SERVER_TIMEOUT_LIMIT behaviour diff --git a/package.xml b/package.xml index 27491332..357086f8 100644 --- a/package.xml +++ b/package.xml @@ -21,21 +21,20 @@ http://pear.php.net/dtd/package-2.0.xsd"> mkoppanen@php.net yes - 2016-02-22 + 2017-01-27 - 3.0.0a1 + 3.0.0 3.0.0 - alpha - alpha + stable + stable PHP PHP7 release of memcached extension. Note that support for libmemcached 0.x series has been discontinued and the oldest actively tested version is 1.0.2. It is highly recommended to use version 1.0.18 of -libmemcached. Please note that this is a beta release and reporting any issues would be highly appreciated -before we move closer to releasing stable version. +libmemcached. API * The method signature of get, getByKey, getMulti, and getMultiByKey changed. @@ -179,6 +178,16 @@ Tests 1.4.0b1 + + + igbinary + 2.0 + + + msgpack + 2.0 + + memcached From e495a6bb1de9ab7940d431f3deecf6d8e71584d2 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 30 Jan 2017 14:27:55 -0800 Subject: [PATCH 019/218] Bump version to 3.0.0 --- php_memcached.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.h b/php_memcached.h index 9e466cb4..0b1a9264 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -27,7 +27,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.0.0b1" +#define PHP_MEMCACHED_VERSION "3.0.0" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 218b019509453a463b8485afe1869a42051a6414 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 30 Jan 2017 21:58:31 -0800 Subject: [PATCH 020/218] Fix memory leak from recent change to s_compress_value Commit c85f34c01ba884987fa3ed4daf7846e503a89cdf cleaned up the function, but missed an all-important efree(buffer) on the no-compression path. --- php_memcached.c | 1 + 1 file changed, 1 insertion(+) diff --git a/php_memcached.c b/php_memcached.c index 93d8738f..ba3473de 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -892,6 +892,7 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str } /* Original payload was not modified */ + efree(buffer); return 0; } From e4f4878f123b1b7c2ef839e12c022de9629937ec Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 2 Feb 2017 19:53:25 +0000 Subject: [PATCH 021/218] Travis CI purge old versions of memcached and libmemcached (#309) * Purge all things memcached from Travis CI before installing local copies * Add ancient libmemcached 1.0.2 to Travis CI matrix --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 02c367a9..2581b516 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ env: - LIBMEMCACHED_VERSION=1.0.18 # Debian Jessie / Ubuntu Xenial - LIBMEMCACHED_VERSION=1.0.16 # RHEL / CentOS 7 - LIBMEMCACHED_VERSION=1.0.8 # Debian Wheezy / Ubuntu Trusty + - LIBMEMCACHED_VERSION=1.0.2 # Ancient addons: apt: @@ -22,6 +23,7 @@ addons: - libevent-dev before_script: + - sudo apt-get purge -qq '^memcached*' '^libmemcached*' - ./.travis/travis.sh before_script $LIBMEMCACHED_VERSION script: @@ -29,4 +31,4 @@ script: cache: directories: - - $HOME/cache \ No newline at end of file + - $HOME/cache From fa620a48c4e5676c9f79b49694d90e3c3d7e78b6 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 7 Feb 2017 12:34:07 +0000 Subject: [PATCH 022/218] Restore php_libmemcached_compat with workaround for missing memcached_exists (#314) This partially reverts commit c564fd875ead3110b27dd3e1dfb9e5d4afabd042 from #295 --- config.m4 | 2 +- package.xml | 2 ++ php_libmemcached_compat.c | 37 +++++++++++++++++++++++++++++++++++++ php_libmemcached_compat.h | 31 +++++++++++++++++++++++++++++++ php_memcached.c | 2 -- php_memcached_private.h | 10 +++------- php_memcached_session.c | 2 +- 7 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 php_libmemcached_compat.c create mode 100644 php_libmemcached_compat.h diff --git a/config.m4 b/config.m4 index 50e2d3bd..b34c30bf 100644 --- a/config.m4 +++ b/config.m4 @@ -318,7 +318,7 @@ if test "$PHP_MEMCACHED" != "no"; then AC_DEFINE(HAVE_MEMCACHED_EXIST, [1], [Whether memcached_exist is defined]) fi - PHP_MEMCACHED_FILES="php_memcached.c g_fmt.c" + PHP_MEMCACHED_FILES="php_memcached.c php_libmemcached_compat.c g_fmt.c" if test "$PHP_SYSTEM_FASTLZ" != "no"; then AC_CHECK_HEADERS([fastlz.h], [ac_cv_have_fastlz="yes"], [ac_cv_have_fastlz="no"]) diff --git a/package.xml b/package.xml index 357086f8..2f01cf46 100644 --- a/package.xml +++ b/package.xml @@ -73,6 +73,8 @@ Tests + + diff --git a/php_libmemcached_compat.c b/php_libmemcached_compat.c new file mode 100644 index 00000000..bd35d8fe --- /dev/null +++ b/php_libmemcached_compat.c @@ -0,0 +1,37 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Andrei Zmievski | + +----------------------------------------------------------------------+ +*/ + +#include "php_memcached.h" +#include "php_memcached_private.h" +#include "php_libmemcached_compat.h" + +memcached_return php_memcached_exist (memcached_st *memc, zend_string *key) +{ +#ifdef HAVE_MEMCACHED_EXIST + return memcached_exist (memc, key->val, key->len); +#else + memcached_return rc = MEMCACHED_SUCCESS; + uint32_t flags = 0; + size_t value_length = 0; + char *value = NULL; + + value = memcached_get (memc, key->val, key->len, &value_length, &flags, &rc); + if (value) { + free (value); + } + return rc; +#endif +} diff --git a/php_libmemcached_compat.h b/php_libmemcached_compat.h new file mode 100644 index 00000000..9bcbc20f --- /dev/null +++ b/php_libmemcached_compat.h @@ -0,0 +1,31 @@ +/* + +----------------------------------------------------------------------+ + | Copyright (c) 2009 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.0 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_0.txt. | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Andrei Zmievski | + +----------------------------------------------------------------------+ +*/ + +#ifndef PHP_LIBMEMCACHED_COMPAT +#define PHP_LIBMEMCACHED_COMPAT + +/* this is the version(s) we support */ +#include + +memcached_return php_memcached_exist (memcached_st *memc, zend_string *key); + +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000017 +typedef const memcached_instance_st * php_memcached_instance_st; +#else +typedef memcached_server_instance_st php_memcached_instance_st; +#endif + +#endif diff --git a/php_memcached.c b/php_memcached.c index ba3473de..514f4c33 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -4022,7 +4022,6 @@ static zend_function_entry memcached_class_methods[] = { MEMC_ME(getLastErrorMessage, arginfo_getLastErrorMessage) MEMC_ME(getLastErrorCode, arginfo_getLastErrorCode) MEMC_ME(getLastErrorErrno, arginfo_getLastErrorErrno) - MEMC_ME(getLastDisconnectedServer, arginfo_getLastDisconnectedServer) MEMC_ME(getStats, arginfo_getStats) @@ -4216,7 +4215,6 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_MODULA, MEMCACHED_DISTRIBUTION_MODULA); REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_CONSISTENT, MEMCACHED_DISTRIBUTION_CONSISTENT); REGISTER_MEMC_CLASS_CONST_LONG(DISTRIBUTION_VIRTUAL_BUCKET, MEMCACHED_DISTRIBUTION_VIRTUAL_BUCKET); - REGISTER_MEMC_CLASS_CONST_LONG(OPT_LIBKETAMA_COMPATIBLE, MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED); REGISTER_MEMC_CLASS_CONST_LONG(OPT_LIBKETAMA_HASH, MEMCACHED_BEHAVIOR_KETAMA_HASH); REGISTER_MEMC_CLASS_CONST_LONG(OPT_TCP_KEEPALIVE, MEMCACHED_BEHAVIOR_TCP_KEEPALIVE); diff --git a/php_memcached_private.h b/php_memcached_private.h index fe6ccc2c..a04e19be 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -25,13 +25,7 @@ # include "config.h" #endif -#include - -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000017 -typedef const memcached_instance_st * php_memcached_instance_st; -#else -typedef memcached_server_instance_st php_memcached_instance_st; -#endif +#include "php_libmemcached_compat.h" #include #include @@ -214,6 +208,8 @@ PHP_MINFO_FUNCTION(memcached); char *php_memc_printable_func (zend_fcall_info *fci, zend_fcall_info_cache *fci_cache); +memcached_return php_memcached_exist (memcached_st *memc, zend_string *key); + zend_bool php_memc_init_sasl_if_needed(); #endif /* PHP_MEMCACHED_PRIVATE_H */ diff --git a/php_memcached_session.c b/php_memcached_session.c index 25ca0ae2..1695b330 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -530,7 +530,7 @@ PS_VALIDATE_SID_FUNC(memcached) { memcached_st *memc = PS_GET_MOD_DATA(); - if (memcached_exist(memc, key->val, key->len) == MEMCACHED_SUCCESS) { + if (php_memcached_exist(memc, key) == MEMCACHED_SUCCESS) { return SUCCESS; } else { return FAILURE; From a86de05e86c47542f03084b6a6f37b5ba1e733cc Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 7 Feb 2017 12:34:23 +0000 Subject: [PATCH 023/218] Fix compiling with memcached binary protocol enabled (#312) --- php_memcached.c | 22 +++------------------- php_memcached.h | 8 ++++++++ php_memcached_server.c | 33 ++++++++++++++------------------- 3 files changed, 25 insertions(+), 38 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 514f4c33..78528332 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -51,12 +51,6 @@ # include "ext/msgpack/php_msgpack.h" #endif -#ifdef ZTS -#define MEMC_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, memc.v) -#else -#define MEMC_G(v) (php_memcached_globals.memc.v) -#endif - static int le_memc; static int php_memc_list_entry(void) { @@ -238,24 +232,14 @@ static inline php_memc_server_t *php_memc_server_fetch_object(zend_object *obj) } #define Z_MEMC_SERVER_P(zv) php_memc_server_fetch_object(Z_OBJ_P(zv)) -#ifdef ZTS -#define MEMC_SERVER_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, server.v) -#else -#define MEMC_SERVER_G(v) (php_memcached_globals.server.v) -#endif +static zend_object_handlers memcached_server_object_handlers; +static zend_class_entry *memcached_server_ce = NULL; #endif static zend_class_entry *memcached_ce = NULL; - static zend_class_entry *memcached_exception_ce = NULL; - static zend_object_handlers memcached_object_handlers; -#ifdef HAVE_MEMCACHED_PROTOCOL -static zend_object_handlers memcached_server_object_handlers; -static zend_class_entry *memcached_server_ce = NULL; -#endif - #ifdef HAVE_SPL static zend_class_entry *spl_ce_RuntimeException = NULL; #endif @@ -3644,7 +3628,7 @@ PHP_METHOD(MemcachedServer, run) static PHP_METHOD(MemcachedServer, on) { - long event; + zend_long event; zend_fcall_info fci; zend_fcall_info_cache fci_cache; zend_bool rc = 0; diff --git a/php_memcached.h b/php_memcached.h index 0b1a9264..5d1e3a77 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -42,6 +42,14 @@ PHP_MEMCACHED_API zend_class_entry *php_memc_get_exception_base(int root); extern zend_module_entry memcached_module_entry; #define phpext_memcached_ptr &memcached_module_entry +#ifdef ZTS +#define MEMC_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, memc.v) +#define MEMC_SERVER_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, server.v) +#else +#define MEMC_G(v) (php_memcached_globals.memc.v) +#define MEMC_SERVER_G(v) (php_memcached_globals.server.v) +#endif + #endif /* PHP_MEMCACHED_H */ /* diff --git a/php_memcached_server.c b/php_memcached_server.c index 94305101..4c0080e8 100644 --- a/php_memcached_server.c +++ b/php_memcached_server.c @@ -24,7 +24,7 @@ #undef _NDEBUG #include -#define MEMC_GET_CB(cb_type) (MEMC_G(server.callbacks)[cb_type]) +#define MEMC_GET_CB(cb_type) (MEMC_SERVER_G(callbacks)[cb_type]) #define MEMC_HAS_CB(cb_type) (MEMC_GET_CB(cb_type).fci.size > 0) #define MEMC_MAKE_ZVAL_COOKIE(my_zcookie, my_ptr) \ @@ -37,7 +37,7 @@ #define MEMC_MAKE_RESULT_CAS(my_zresult_cas, my_result_cas) \ do { \ my_result_cas = 0; \ - my_result_cas = zval_get_double(my_zresult_cas); \ + my_result_cas = zval_get_double(&my_zresult_cas); \ } while (0) @@ -56,27 +56,22 @@ typedef struct { } php_memc_client_t; static -long s_invoke_php_callback (php_memc_server_cb_t *cb, zval ***params, ssize_t param_count) +long s_invoke_php_callback (php_memc_server_cb_t *cb, zval *params, ssize_t param_count) { - long retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; - zval *retval_ptr = NULL; + zval *retval = NULL; - cb->fci.params = params; + cb->fci.retval = retval; + cb->fci.params = params; cb->fci.param_count = param_count; - - /* Call the cb */ - cb->fci.no_separation = 1; - cb->fci.retval_ptr_ptr = &retval_ptr; + cb->fci.no_separation = 1; if (zend_call_function(&(cb->fci), &(cb->fci_cache)) == FAILURE) { - char *buf = php_memc_printable_func (&(cb->fci), &(cb->fci_cache)); + char *buf = php_memc_printable_func(&(cb->fci), &(cb->fci_cache)); php_error_docref(NULL, E_WARNING, "Failed to invoke callback %s()", buf); efree (buf); } - if (retval_ptr) { - retval = zval_get_long(retval_ptr); - } - return retval; + + return retval == NULL ? PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND : zval_get_long(retval); } // memcached protocol callbacks @@ -217,7 +212,7 @@ protocol_binary_response_status s_incr_decr_handler (php_memc_event_t event, con retval = s_invoke_php_callback (&MEMC_GET_CB(event), params, 7); - *result = (uint64_t)zval_get_long(zresult); + *result = (uint64_t)zval_get_long(&zresult); MEMC_MAKE_RESULT_CAS(zresult_cas, *result_cas); @@ -301,7 +296,7 @@ protocol_binary_response_status s_flush_handler(const void *cookie, uint32_t whe MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); ZVAL_COPY(¶ms[0], &zcookie); - ZVAL_COPY(¶ms[1], &zwhen) + ZVAL_COPY(¶ms[1], &zwhen); retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_FLUSH), params, 2); @@ -561,7 +556,7 @@ protocol_binary_response_status s_version_handler (const void *cookie, convert_to_string(&zversion); } - retval = response_handler (cookie, Z_STRVAL_P(zversion), (uint32_t) Z_STRLEN_P(zversion)); + retval = response_handler (cookie, Z_STRVAL(zversion), (uint32_t) Z_STRLEN(zversion)); } zval_ptr_dtor(¶ms[0]); @@ -592,7 +587,7 @@ void s_handle_memcached_event (evutil_socket_t fd, short what, void *arg) socklen_t addr_in_len = sizeof(addr_in); if (getpeername (fd, (struct sockaddr *) &addr_in, &addr_in_len) == 0) { - ZVAL_STRING(&zremoteip, inet_ntoa (addr_in.sin_addr), 1); + ZVAL_STRING(&zremoteip, inet_ntoa (addr_in.sin_addr)); ZVAL_LONG(&zremoteport, ntohs (addr_in.sin_port)); } else { php_error_docref(NULL, E_WARNING, "getpeername failed: %s", strerror (errno)); From 08b39ed6b142a1a059295c803d50e625741e3f5a Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 7 Feb 2017 12:34:41 +0000 Subject: [PATCH 024/218] Ignore specific errors from memcached_dump for getAllKeys() with newer memcached servers (#315) --- php_memcached.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index 78528332..d6f42575 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -2725,7 +2725,15 @@ PHP_METHOD(Memcached, getAllKeys) array_init(return_value); rc = memcached_dump(intern->memc, callback, return_value, 1); - if (s_memc_status_handle_result_code(intern, rc) == FAILURE) { + + /* Ignore two errors. libmemcached has a hardcoded loop of 200 slab + * classes that matches memcached < 1.4.24, at which version the server + * has only 63 slabs and throws an error when requesting the 64th slab. + * + * In multi-server some non-deterministic number of elements will be dropped. + */ + if (rc != MEMCACHED_CLIENT_ERROR && rc != MEMCACHED_SERVER_ERROR + && s_memc_status_handle_result_code(intern, rc) == FAILURE) { zval_dtor(return_value); RETURN_FALSE; } From 115cc0a2c41f617b639c55beed5513a06898403f Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 7 Feb 2017 12:34:54 +0000 Subject: [PATCH 025/218] Add API entries for flushBuffers() and getAllKeys() (#316) --- memcached-api.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/memcached-api.php b/memcached-api.php index 64b20b26..df725091 100644 --- a/memcached-api.php +++ b/memcached-api.php @@ -275,7 +275,11 @@ public function getLastDisconnectedServer( ) {} public function flush( $delay = 0 ) {} + public function flushBuffers( ) {} + public function getStats( $type = null ) {} + + public function getAllKeys( ) {} public function getVersion( ) {} From d019588648d3e7dd8d642234c95ff6f85cac1d94 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 7 Feb 2017 06:19:13 -0800 Subject: [PATCH 026/218] Notes for version 3.0.1 --- ChangeLog | 9 +++++++ package.xml | 67 +++++++++++++++++++++++++++++++++++------------------ 2 files changed, 54 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 24cb0a74..a21e14b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ memcached extension changelog +Version 3.0.1 (2017-02-07) +------------- + + * Add API entries for flushBuffers() and getAllKeys() (#316) + * Ignore specific errors from memcached_dump for getAllKeys() with newer memcached servers (#315) + * Fix compiling with memcached binary protocol enabled (#312) + * Restore php_libmemcached_compat with workaround for missing memcached_exists (#314) + * Travis CI purge old versions of memcached and libmemcached (#309) + Version 3.0.0 (2017-01-27) -------------------------- * Support for PHP 7.0 and PHP 7.1 diff --git a/package.xml b/package.xml index 2f01cf46..3366baf3 100644 --- a/package.xml +++ b/package.xml @@ -21,9 +21,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> mkoppanen@php.net yes - 2017-01-27 + 2017-02-07 - 3.0.0 + 3.0.1 3.0.0 @@ -36,26 +36,12 @@ PHP7 release of memcached extension. Note that support for libmemcached 0.x seri and the oldest actively tested version is 1.0.2. It is highly recommended to use version 1.0.18 of libmemcached. -API - * The method signature of get, getByKey, getMulti, and getMultiByKey changed. - * get* and getMulti* commands no longer take cas or user flags parameters. - * get* and getMulti* commands now take the Memcached::GET_EXTENDED flag to retrieve user flags and cas tokens. - * Fixes getStats command to return all stats from all servers - * Fixes allKeys command behaviour - * Fixes error where cache callback for get command was not setting expiration time properly - * Added server type to server list - * Remove use_sasl ini-variable and initialise sasl as needed - * CAS tokens are returned as integers and they overflow to strings as needed - -Session handler - * The session memcached protocol config name was changed, and the default protocol was changed from text to binary protocol. If your memcached setup does not support the binary protocol(e.g. if using twemproxy), then set memcached.sess_binary_protocol = Off. (Previously called memcached.sess_binary) - * Session lock algorithm updated (new ini-values memcached.sess_lock_wait_min, memcached.sess_lock_wait_max and memcached.sess_lock_retries) - * Session extension uses PHP allocators (still some work to do on the rest of the extension) - * Ini-values take effect during session_start or session_regenerate_id - * Fixes crash with session_regenerate_id (work-around for PHP bug) - -Tests - * Fix several problematic tests +Fixes + * Add API entries for flushBuffers() and getAllKeys() (#316) + * Ignore specific errors from memcached_dump for getAllKeys() with newer memcached servers (#315) + * Fix compiling with memcached binary protocol enabled (#312) + * Restore php_libmemcached_compat with workaround for missing memcached_exists (#314) + * Travis CI purge old versions of memcached and libmemcached (#309) @@ -196,6 +182,43 @@ Tests + + + stable + stable + + + 3.0.0 + 3.0.0 + + 2016-01-27 + +PHP7 release of memcached extension. Note that support for libmemcached 0.x series has been discontinued +and the oldest actively tested version is 1.0.2. It is highly recommended to use version 1.0.18 of +libmemcached. + +API + * The method signature of get, getByKey, getMulti, and getMultiByKey changed. + * get* and getMulti* commands no longer take cas or user flags parameters. + * get* and getMulti* commands now take the Memcached::GET_EXTENDED flag to retrieve user flags and cas tokens. + * Fixes getStats command to return all stats from all servers + * Fixes allKeys command behaviour + * Fixes error where cache callback for get command was not setting expiration time properly + * Added server type to server list + * Remove use_sasl ini-variable and initialise sasl as needed + * CAS tokens are returned as integers and they overflow to strings as needed + +Session handler + * The session memcached protocol config name was changed, and the default protocol was changed from text to binary protocol. If your memcached setup does not support the binary protocol(e.g. if using tw + * Session lock algorithm updated (new ini-values memcached.sess_lock_wait_min, memcached.sess_lock_wait_max and memcached.sess_lock_retries) + * Session extension uses PHP allocators (still some work to do on the rest of the extension) + * Ini-values take effect during session_start or session_regenerate_id + * Fixes crash with session_regenerate_id (work-around for PHP bug) + +Tests + * Fix several problematic tests + + alpha From 71f20e19253f27d6deaeab200007bd4cf9d8aec4 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 7 Feb 2017 06:20:51 -0800 Subject: [PATCH 027/218] Bump version to 3.0.1 --- php_memcached.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.h b/php_memcached.h index 5d1e3a77..1a9411f9 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -27,7 +27,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.0.0" +#define PHP_MEMCACHED_VERSION "3.0.1" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 8a40f2ca5f08f3b3d9fe1eb7f068737484b0bc03 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Wed, 8 Feb 2017 10:00:47 -0800 Subject: [PATCH 028/218] Add myself to package.xml before uploading to PECL --- package.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/package.xml b/package.xml index 3366baf3..bbec4158 100644 --- a/package.xml +++ b/package.xml @@ -21,6 +21,12 @@ http://pear.php.net/dtd/package-2.0.xsd"> mkoppanen@php.net yes + + Aaron Stone + sodabrew + aaron@serendipity.cx + yes + 2017-02-07 3.0.1 From f8fd6228e34e1b49947890b060a501a6eab6978c Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 9 Feb 2017 07:24:15 +0100 Subject: [PATCH 029/218] ensure tests are ok for 32bits build --- tests/gh_90.phpt | 4 ++-- tests/incrdecr.phpt | 6 +++--- tests/incrdecr_bykey.phpt | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/gh_90.phpt b/tests/gh_90.phpt index 733b7615..2a16f603 100644 --- a/tests/gh_90.phpt +++ b/tests/gh_90.phpt @@ -12,7 +12,7 @@ $memcached = memc_get_instance (array ( // Create a key for use as a lock. If this key already exists, wait till it doesn't exist. { $key = 'LockKey'; - $lockToken = mt_rand(0, pow(2, 32)); //Random value betwen 0 and 2^32 for ownership verification + $lockToken = mt_rand(0, mt_getrandmax()); //Random value for ownership verification while (true) { @@ -88,4 +88,4 @@ array(10) { int(1) ["9_%s"]=> int(1) -} \ No newline at end of file +} diff --git a/tests/incrdecr.phpt b/tests/incrdecr.phpt index cb3914a4..b4e9469b 100644 --- a/tests/incrdecr.phpt +++ b/tests/incrdecr.phpt @@ -42,10 +42,10 @@ echo $php_errormsg, "\n"; var_dump($m->get('foo')); echo "Enormous offset\n"; -$m->increment('foo', 4294967296); +$m->increment('foo', 0x7f000000); var_dump($m->get('foo')); -$m->decrement('foo', 4294967296); +$m->decrement('foo', 0x7f000000); var_dump($m->get('foo')); --EXPECT-- @@ -68,5 +68,5 @@ int(1) Memcached::decrement(): offset cannot be a negative value int(1) Enormous offset -int(4294967297) +int(2130706433) int(1) diff --git a/tests/incrdecr_bykey.phpt b/tests/incrdecr_bykey.phpt index 809f3b83..8b931fa7 100644 --- a/tests/incrdecr_bykey.phpt +++ b/tests/incrdecr_bykey.phpt @@ -39,10 +39,10 @@ echo $php_errormsg, "\n"; var_dump($m->get('foo')); echo "Enormous offset\n"; -$m->incrementByKey('foo', 'foo', 4294967296); +$m->incrementByKey('foo', 'foo', 0x7f000000); var_dump($m->get('foo')); -$m->decrementByKey('foo', 'foo', 4294967296); +$m->decrementByKey('foo', 'foo', 0x7f000000); var_dump($m->get('foo')); --EXPECT-- @@ -62,5 +62,5 @@ int(1) Memcached::decrementByKey(): offset cannot be a negative value int(1) Enormous offset -int(4294967297) +int(2130706433) int(1) From ecd77ab93ff060f27bef32e40c2bd88fba3df199 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 9 Feb 2017 06:40:50 -0800 Subject: [PATCH 030/218] Recommend libmemcached 1.0.18 or higher to match the release notes --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 0cb2c032..f145c2df 100644 --- a/README.markdown +++ b/README.markdown @@ -34,7 +34,7 @@ php-memcached 2.x: * Optionally supports igbinary 1.0 or higher. * Optionally supports msgpack 0.5 or higher. -[libmemcached](http://libmemcached.org/libMemcached.html) version 1.0.16 or +[libmemcached](http://libmemcached.org/libMemcached.html) version 1.0.18 or higher is recommended for best performance and compatibility with memcached servers. From 83d5f308999ffad2c0642b7e450e2e350e464342 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 10 Feb 2017 13:51:14 +0000 Subject: [PATCH 031/218] Separate test for 64-bit increment/decrement/incrementByKey/decrementByKey (#321) --- package.xml | 2 ++ tests/incrdecr_64.phpt | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 tests/incrdecr_64.phpt diff --git a/package.xml b/package.xml index bbec4158..7aadf4db 100644 --- a/package.xml +++ b/package.xml @@ -74,6 +74,7 @@ Fixes + @@ -143,6 +144,7 @@ Fixes + diff --git a/tests/incrdecr_64.phpt b/tests/incrdecr_64.phpt new file mode 100644 index 00000000..dfa32c6a --- /dev/null +++ b/tests/incrdecr_64.phpt @@ -0,0 +1,39 @@ +--TEST-- +64-bit Memcached::increment() decrement() incrementByKey() decrementByKey() +--SKIPIF-- + +--FILE-- +set('foo', 1); +var_dump($m->get('foo')); + +echo "Enormous offset 64-bit\n"; +$m->increment('foo', 0x100000000); +var_dump($m->get('foo')); + +$m->decrement('foo', 0x100000000); +var_dump($m->get('foo')); + +echo "Enormous offset 64-bit by key\n"; +$m->incrementByKey('foo', 'foo', 0x100000000); +var_dump($m->get('foo')); + +$m->decrementByKey('foo', 'foo', 0x100000000); +var_dump($m->get('foo')); + +--EXPECT-- +Normal +int(1) +Enormous offset 64-bit +int(4294967297) +int(1) +Enormous offset 64-bit by key +int(4294967297) +int(1) From f7c92b06997d298f63a13d1791fa7a050c8598b9 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sun, 12 Feb 2017 15:56:22 +0000 Subject: [PATCH 032/218] Update warning for touch command in binary protocol mode with libmemcached < 1.0.18 (#322) --- package.xml | 1 + php_libmemcached_compat.c | 21 +++++++++++++++ php_libmemcached_compat.h | 3 +++ php_memcached.c | 13 ++------- php_memcached_session.c | 2 +- tests/gh_155.phpt | 7 +++-- tests/session_basic.phpt | 1 + tests/session_basic2.phpt | 1 + tests/session_basic3.phpt | 1 + tests/session_lazy_warning.phpt | 47 +++++++++++++++++++++++++++++++++ tests/session_lock-php71.phpt | 4 +++ tests/session_lock.phpt | 4 +++ tests/touch_binary.phpt | 5 +++- 13 files changed, 95 insertions(+), 15 deletions(-) create mode 100644 tests/session_lazy_warning.phpt diff --git a/package.xml b/package.xml index 7aadf4db..a5c7c07b 100644 --- a/package.xml +++ b/package.xml @@ -157,6 +157,7 @@ Fixes + diff --git a/php_libmemcached_compat.c b/php_libmemcached_compat.c index bd35d8fe..7f003b1d 100644 --- a/php_libmemcached_compat.c +++ b/php_libmemcached_compat.c @@ -35,3 +35,24 @@ memcached_return php_memcached_exist (memcached_st *memc, zend_string *key) return rc; #endif } + +memcached_return php_memcached_touch(memcached_st *memc, const char *key, size_t key_len, time_t expiration) +{ +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 + if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { + php_error_docref(NULL, E_WARNING, "using touch command with binary protocol is not recommended with libmemcached versions below 1.0.18, please use ascii protocol or upgrade libmemcached"); + } +#endif + return memcached_touch(memc, key, key_len, expiration); +} + +memcached_return php_memcached_touch_by_key(memcached_st *memc, const char *server_key, size_t server_key_len, const char *key, size_t key_len, time_t expiration) +{ +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 + if (memcached_behavior_get(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { + php_error_docref(NULL, E_WARNING, "using touch command with binary protocol is not recommended with libmemcached versions below 1.0.18, please use ascii protocol or upgrade libmemcached"); + } +#endif + return memcached_touch_by_key(memc, server_key, server_key_len, key, key_len, expiration); +} + diff --git a/php_libmemcached_compat.h b/php_libmemcached_compat.h index 9bcbc20f..42a409dc 100644 --- a/php_libmemcached_compat.h +++ b/php_libmemcached_compat.h @@ -22,6 +22,9 @@ memcached_return php_memcached_exist (memcached_st *memc, zend_string *key); +memcached_return php_memcached_touch(memcached_st *memc, const char *key, size_t key_len, time_t expiration); +memcached_return php_memcached_touch_by_key(memcached_st *memc, const char *server_key, size_t server_key_len, const char *key, size_t key_len, time_t expiration); + #if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX >= 0x01000017 typedef const memcached_instance_st * php_memcached_instance_st; #else diff --git a/php_memcached.c b/php_memcached.c index d6f42575..19673323 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -1081,7 +1081,7 @@ zend_bool s_memc_write_zval (php_memc_object_t *intern, php_memc_write_op op, ze break; case MEMC_OP_TOUCH: - status = memcached_touch_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), expiration); + status = php_memcached_touch_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), expiration); break; case MEMC_OP_ADD: @@ -1113,7 +1113,7 @@ zend_bool s_memc_write_zval (php_memc_object_t *intern, php_memc_write_op op, ze break; case MEMC_OP_TOUCH: - status = memcached_touch(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), expiration); + status = php_memcached_touch(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), expiration); break; case MEMC_OP_ADD: @@ -1959,15 +1959,6 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool } } - - if (op == MEMC_OP_TOUCH) { -#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000016 - if (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL)) { - php_error_docref(NULL, E_WARNING, "using touch command with binary protocol is not recommended with libmemcached versions below 1.0.16"); - } -#endif - } - if (!s_memc_write_zval (intern, op, server_key, key, value, expiration)) { RETURN_FALSE; } diff --git a/php_memcached_session.c b/php_memcached_session.c index 1695b330..b6d93c5f 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -542,7 +542,7 @@ PS_UPDATE_TIMESTAMP_FUNC(memcached) memcached_st *memc = PS_GET_MOD_DATA(); time_t expiration = s_session_expiration(maxlifetime); - if (memcached_touch(memc, key->val, key->len, expiration) == MEMCACHED_FAILURE) { + if (php_memcached_touch(memc, key->val, key->len, expiration) == MEMCACHED_FAILURE) { return FAILURE; } return SUCCESS; diff --git a/tests/gh_155.phpt b/tests/gh_155.phpt index a5b61d00..699e8eca 100644 --- a/tests/gh_155.phpt +++ b/tests/gh_155.phpt @@ -4,7 +4,10 @@ Test for bug 155 --FILE-- setOption(Memcached::OPT_BINARY_PROTOCOL,true); +$m->setOption(Memcached::OPT_BINARY_PROTOCOL, true); $m->addServer(MEMC_SERVER_HOST, MEMC_SERVER_PORT); $key = 'bug_155_' . uniqid(); diff --git a/tests/session_basic.phpt b/tests/session_basic.phpt index 3fdb6bd7..0e8b3469 100644 --- a/tests/session_basic.phpt +++ b/tests/session_basic.phpt @@ -7,6 +7,7 @@ if (!Memcached::HAVE_SESSION) print "skip"; ?> --INI-- session.save_handler = memcached +memcached.sess_binary_protocol = Off --FILE-- --INI-- session.save_handler = memcached +memcached.sess_binary_protocol = Off --FILE-- --INI-- session.save_handler = memcached +memcached.sess_binary_protocol = Off --FILE-- = 0x01000018) die ('skip too old libmemcached'); +?> +--INI-- +session.save_handler = memcached +memcached.sess_binary_protocol = On +--FILE-- +TRUE]); +$_SESSION['foo'] = 1; +session_write_close(); + +$_SESSION = NULL; + +var_dump($_SESSION); +session_start(); +var_dump($_SESSION); +session_write_close(); + +session_start(); +session_destroy(); + +session_start(); +var_dump($_SESSION); +session_write_close(); + + +--EXPECTF-- +NULL +array(1) { + ["foo"]=> + int(1) +} + +Warning: session_write_close(): using touch command with binary protocol is not recommended with libmemcached versions below 1.0.18, please use ascii protocol or upgrade libmemcached in %s on line %d +array(0) { +} diff --git a/tests/session_lock-php71.phpt b/tests/session_lock-php71.phpt index 207f64cf..c0fceb67 100644 --- a/tests/session_lock-php71.phpt +++ b/tests/session_lock-php71.phpt @@ -14,6 +14,10 @@ memcached.sess_lock_wait_max = 1000 memcached.sess_lock_retries = 3 memcached.sess_prefix = "memc.test." +# Turn off binary protocol while the test matrix has older versions of +# libmemcached for which the extension warns of a broken touch command. +memcached.sess_binary_protocol = Off + session.save_handler = memcached --FILE-- diff --git a/tests/session_lock.phpt b/tests/session_lock.phpt index 570e5a2a..cedc83bb 100644 --- a/tests/session_lock.phpt +++ b/tests/session_lock.phpt @@ -14,6 +14,10 @@ memcached.sess_lock_wait_max = 1000 memcached.sess_lock_retries = 3 memcached.sess_prefix = "memc.test." +# Turn off binary protocol while the test matrix has older versions of +# libmemcached for which the extension warns of a broken touch command. +memcached.sess_binary_protocol = Off + session.save_handler = memcached --FILE-- diff --git a/tests/touch_binary.phpt b/tests/touch_binary.phpt index cc35e8fb..382c1778 100644 --- a/tests/touch_binary.phpt +++ b/tests/touch_binary.phpt @@ -4,7 +4,10 @@ Touch in binary mode --FILE-- Date: Sun, 12 Feb 2017 08:05:55 -0800 Subject: [PATCH 033/218] Release notes for 3.0.2 --- ChangeLog | 9 ++++++++- package.xml | 36 +++++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index a21e14b8..914cb4e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,14 @@ memcached extension changelog +Version 3.0.2 (2017-02-12) +-------------------------- + + * Update warning for touch command in binary protocol mode with libmemcached < 1.0.18 (#322) + * Add tests for 64-bit increment/decrement/incrementByKey/decrementByKey (#321) + * Fix tests for 32-bit increment/decrement/incrementByKey/decrementByKey (#319) + Version 3.0.1 (2017-02-07) -------------- +-------------------------- * Add API entries for flushBuffers() and getAllKeys() (#316) * Ignore specific errors from memcached_dump for getAllKeys() with newer memcached servers (#315) diff --git a/package.xml b/package.xml index a5c7c07b..82b6a39e 100644 --- a/package.xml +++ b/package.xml @@ -27,9 +27,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> aaron@serendipity.cx yes - 2017-02-07 + 2017-02-12 - 3.0.1 + 3.0.2 3.0.0 @@ -43,11 +43,10 @@ and the oldest actively tested version is 1.0.2. It is highly recommended to use libmemcached. Fixes - * Add API entries for flushBuffers() and getAllKeys() (#316) - * Ignore specific errors from memcached_dump for getAllKeys() with newer memcached servers (#315) - * Fix compiling with memcached binary protocol enabled (#312) - * Restore php_libmemcached_compat with workaround for missing memcached_exists (#314) - * Travis CI purge old versions of memcached and libmemcached (#309) + * Update warning for touch command in binary protocol mode with libmemcached < 1.0.18 (#322) + * Add tests for 64-bit increment/decrement/incrementByKey/decrementByKey (#321) + * Fix tests for 32-bit increment/decrement/incrementByKey/decrementByKey (#319) + @@ -191,6 +190,29 @@ Fixes + + + stable + stable + + + 3.0.1 + 3.0.0 + + 2016-02-07 + +PHP7 release of memcached extension. Note that support for libmemcached 0.x series has been discontinued +and the oldest actively tested version is 1.0.2. It is highly recommended to use version 1.0.18 of +libmemcached. + +Fixes + * Add API entries for flushBuffers() and getAllKeys() (#316) + * Ignore specific errors from memcached_dump for getAllKeys() with newer memcached servers (#315) + * Fix compiling with memcached binary protocol enabled (#312) + * Restore php_libmemcached_compat with workaround for missing memcached_exists (#314) + * Travis CI purge old versions of memcached and libmemcached (#309) + + stable From de250ed68cce14b6779316b3909b22e777469bf8 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sun, 12 Feb 2017 08:06:04 -0800 Subject: [PATCH 034/218] Bump version to 3.0.2 --- php_memcached.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.h b/php_memcached.h index 1a9411f9..e36b614b 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -27,7 +27,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.0.1" +#define PHP_MEMCACHED_VERSION "3.0.2" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 81bc04f1ac45181b06a788124c04e381d8aa2481 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sun, 12 Feb 2017 16:04:39 -0800 Subject: [PATCH 035/218] Use the word below instead of less-than symbol in package.xml because XML --- package.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.xml b/package.xml index 82b6a39e..bfaf51ae 100644 --- a/package.xml +++ b/package.xml @@ -43,7 +43,7 @@ and the oldest actively tested version is 1.0.2. It is highly recommended to use libmemcached. Fixes - * Update warning for touch command in binary protocol mode with libmemcached < 1.0.18 (#322) + * Update warning for touch command in binary protocol mode with libmemcached below 1.0.18 (#322) * Add tests for 64-bit increment/decrement/incrementByKey/decrementByKey (#321) * Fix tests for 32-bit increment/decrement/incrementByKey/decrementByKey (#319) From 1e7e4eedb62befa7449a92528d6e0adaf8786369 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sun, 19 Feb 2017 18:26:55 +0800 Subject: [PATCH 036/218] Fixed issue #327 --- php_memcached_session.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/php_memcached_session.c b/php_memcached_session.c index b6d93c5f..8678ffff 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -435,8 +435,9 @@ PS_READ_FUNC(memcached) payload = memcached_get(memc, key->val, key->len, &payload_len, &flags, &status); if (status == MEMCACHED_SUCCESS) { + zend_bool *is_persistent = memcached_get_user_data(memc); *val = zend_string_init(payload, payload_len, 0); - efree(payload); + pefree(payload, *is_persistent); return SUCCESS; } else if (status == MEMCACHED_NOTFOUND) { *val = ZSTR_EMPTY_ALLOC(); From bff303547f67f6832a5df48b3e5eb78642871156 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sun, 19 Feb 2017 18:32:16 +0800 Subject: [PATCH 037/218] Fixed memleak (severs) --- package.xml | 1 + php_memcached_session.c | 1 + tests/session_persistent.phpt | 27 +++++++++++++++++++++++++++ 3 files changed, 29 insertions(+) create mode 100644 tests/session_persistent.phpt diff --git a/package.xml b/package.xml index bfaf51ae..554aa428 100644 --- a/package.xml +++ b/package.xml @@ -118,6 +118,7 @@ Fixes + diff --git a/php_memcached_session.c b/php_memcached_session.c index 8678ffff..afa973bb 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -351,6 +351,7 @@ PS_OPEN_FUNC(memcached) else { efree(plist_key); PS_SET_MOD_DATA(memc); + memcached_server_list_free(servers); return SUCCESS; } } diff --git a/tests/session_persistent.phpt b/tests/session_persistent.phpt new file mode 100644 index 00000000..cb29c3e8 --- /dev/null +++ b/tests/session_persistent.phpt @@ -0,0 +1,27 @@ +--TEST-- +Session persistent +--SKIPIF-- + +--INI-- +session.save_handler=memcached +memcached.sess_persistent=1 +--FILE-- + +--EXPECT-- +array(1) { + ["test"]=> + bool(true) +} From a8517cd97b4df25cdc04b3f40b810c0202c7daba Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sun, 19 Feb 2017 18:34:48 +0800 Subject: [PATCH 038/218] dev version --- php_memcached.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.h b/php_memcached.h index e36b614b..1ec55df6 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -27,7 +27,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.0.2" +#define PHP_MEMCACHED_VERSION "3.0.3-dev" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 99cab0e08166ca9b4219016b30cf0d5e2c0f393c Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sun, 19 Feb 2017 17:23:35 -0800 Subject: [PATCH 039/218] Fix session-persistent test failures on older libmemcached versions --- tests/session_persistent.phpt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/session_persistent.phpt b/tests/session_persistent.phpt index cb29c3e8..e096f2b6 100644 --- a/tests/session_persistent.phpt +++ b/tests/session_persistent.phpt @@ -3,7 +3,8 @@ Session persistent --SKIPIF-- --INI-- session.save_handler=memcached From beb58dc69f59fff185baa92cef6a6e739769a5ab Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sun, 19 Feb 2017 19:30:22 -0800 Subject: [PATCH 040/218] Replace traditional free with pefree to match the registered allocators, fixes #328 --- php_libmemcached_compat.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/php_libmemcached_compat.c b/php_libmemcached_compat.c index 7f003b1d..4e294647 100644 --- a/php_libmemcached_compat.c +++ b/php_libmemcached_compat.c @@ -18,19 +18,20 @@ #include "php_memcached_private.h" #include "php_libmemcached_compat.h" -memcached_return php_memcached_exist (memcached_st *memc, zend_string *key) +memcached_return php_memcached_exist(memcached_st *memc, zend_string *key) { #ifdef HAVE_MEMCACHED_EXIST - return memcached_exist (memc, key->val, key->len); + return memcached_exist(memc, key->val, key->len); #else memcached_return rc = MEMCACHED_SUCCESS; uint32_t flags = 0; size_t value_length = 0; char *value = NULL; - value = memcached_get (memc, key->val, key->len, &value_length, &flags, &rc); + value = memcached_get(memc, key->val, key->len, &value_length, &flags, &rc); if (value) { - free (value); + zend_bool *is_persistent = memcached_get_user_data(memc); + pefree(value, *is_persistent); } return rc; #endif From 357efc40df1fee72a5fca918be308ebf97afd87b Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sun, 19 Feb 2017 19:48:33 -0800 Subject: [PATCH 041/218] Release notes for 3.0.3 --- ChangeLog | 6 ++++++ package.xml | 31 +++++++++++++++++++++++++------ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 914cb4e3..1db3dd44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ memcached extension changelog +Version 3.0.3 (2017-02-19) +-------------------------- + + * Fix crash when checking session data with older versions of libmemcached (#328) + * Fix crash due to zend_mm_corrupted when fetching session data (#327) + Version 3.0.2 (2017-02-12) -------------------------- diff --git a/package.xml b/package.xml index 554aa428..2306344d 100644 --- a/package.xml +++ b/package.xml @@ -27,9 +27,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> aaron@serendipity.cx yes - 2017-02-12 + 2017-02-19 - 3.0.2 + 3.0.3 3.0.0 @@ -43,10 +43,8 @@ and the oldest actively tested version is 1.0.2. It is highly recommended to use libmemcached. Fixes - * Update warning for touch command in binary protocol mode with libmemcached below 1.0.18 (#322) - * Add tests for 64-bit increment/decrement/incrementByKey/decrementByKey (#321) - * Fix tests for 32-bit increment/decrement/incrementByKey/decrementByKey (#319) - + * Fix crash when checking session data with older versions of libmemcached (#328) + * Fix crash due to zend_mm_corrupted when fetching session data (#327) @@ -191,6 +189,27 @@ Fixes + + + stable + stable + + + 3.0.2 + 3.0.0 + + 2016-02-12 + +PHP7 release of memcached extension. Note that support for libmemcached 0.x series has been discontinued +and the oldest actively tested version is 1.0.2. It is highly recommended to use version 1.0.18 of +libmemcached. + +Fixes + * Update warning for touch command in binary protocol mode with libmemcached below 1.0.18 (#322) + * Add tests for 64-bit increment/decrement/incrementByKey/decrementByKey (#321) + * Fix tests for 32-bit increment/decrement/incrementByKey/decrementByKey (#319) + + stable From 466485a2ca98b4c1354c7815d23e3bdc64b69db9 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sun, 19 Feb 2017 19:48:43 -0800 Subject: [PATCH 042/218] Bump version to 3.0.3 --- php_memcached.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.h b/php_memcached.h index 1ec55df6..65a0349f 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -27,7 +27,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.0.3-dev" +#define PHP_MEMCACHED_VERSION "3.0.3" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From d81697f7a04646edbbed8ecf34cb524ab1ff8d3c Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Mon, 20 Feb 2017 19:27:39 +0100 Subject: [PATCH 043/218] Refresh memcached.ini provided configuration - remove deprecated options - add missing memcached.sess_server_failure_limit option - comment all options default value (only needed when not default value) see php.ini-production which follow this convention --- memcached.ini | 56 +++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/memcached.ini b/memcached.ini index 59001aaf..fa9a6fd4 100644 --- a/memcached.ini +++ b/memcached.ini @@ -2,45 +2,39 @@ ; Use session locking ; valid values: On, Off ; the default is On -memcached.sess_locking = On - -; !! DEPRECATED AND REMOVED in 3.x !! -; memcached.sess_lock_wait = 150000 - -; !! DEPRECATED AND REMOVED in 3.x !! -; memcached.sess_lock_max_wait = 0; +;memcached.sess_locking = On ; The minimum time, in milliseconds, to wait between session lock attempts. ; This value is double on each lock retry until memcached.sess_lock_wait_max ; is reached, after which any further retries will take sess_lock_wait_max seconds. ; Default is 1000. -memcached.sess_lock_wait_min = 1000; +;memcached.sess_lock_wait_min = 1000; ; The maximum time, in milliseconds, to wait between session lock attempts. ; Default is 2000. -memcached.sess_lock_wait_max = 2000; +;memcached.sess_lock_wait_max = 2000; ; The number of times to retry locking the session lock, not including the first attempt. ; Default is 5. -memcached.sess_lock_retries = 5; +;memcached.sess_lock_retries = 5; ; The time, in seconds, before a lock should release itself. ; Setting to 0 results in the default behaviour, which is to ; use the memcached.sess_lock_max_wait setting. If that is ; also 0, max_execution_time will be used. -memcached.sess_lock_expire = 0; +;memcached.sess_lock_expire = 0; ; memcached session key prefix ; valid values are strings less than 219 bytes long ; the default value is "memc.sess.key." -memcached.sess_prefix = "memc.sess.key." +;memcached.sess_prefix = "memc.sess.key." ; Whether or not to re-use the memcached connections corresponding to the value(s) ; of session.save_path after the execution of the script ends. ; Don't use this if certain settings (e.g. SASL settings, sess_binary_protocol) would ; be overridden between requests. ; Default is Off. -memcached.sess_persistent = Off +;memcached.sess_persistent = Off ; memcached session consistent hash mode ; if set to On, consistent hashing (libketama) is used @@ -48,11 +42,15 @@ memcached.sess_persistent = Off ; When consistent hashing is used, one can add or remove cache ; node(s) without messing up too much with existing keys ; default is On -memcached.sess_consistent_hash = On +;memcached.sess_consistent_hash = On ; Allow failed memcached server to automatically be removed. ; Default is Off. (In previous versions, this setting was called memcached.sess_remove_failed) -memcached.sess_remove_failed_servers = Off +;memcached.sess_remove_failed_servers = Off + +; Set this value to enable the server be removed after +; configured number of continuous times connection failure. +;memcached.sess_server_failure_limit = 0 ; Write data to a number of additional memcached servers ; This is "poor man's HA" as libmemcached calls it. @@ -61,34 +59,34 @@ memcached.sess_remove_failed_servers = Off ; from a replica. However, if the failed memcache server ; becomes available again it will read the session from there ; which could have old data or no data at all -memcached.sess_number_of_replicas = 0 +;memcached.sess_number_of_replicas = 0 ; Use the memcached binary protocol for memcached sessions (Instead of the text protocol) ; libmemcached replicas work only if binary mode is enabled. ; However, certain proxies (such as twemproxy) will work only if the binary protocol is disabled. ; Default is On. In older versions of php-memcached, this setting was Off and was called memcached.sess_binary. -memcached.sess_binary_protocol = On +;memcached.sess_binary_protocol = On ; memcached session replica read randomize -memcached.sess_randomize_replica_read = Off +;memcached.sess_randomize_replica_read = Off ; memcached connect timeout value ; In non-blocking mode this changes the value of the timeout ; during socket connection in milliseconds. Specifying -1 means an infinite timeout. -memcached.sess_connect_timeout = 1000 +;memcached.sess_connect_timeout = 1000 ; Session SASL username ; Both username and password need to be set for SASL to be enabled ; In addition to this memcached.use_sasl needs to be on -memcached.sess_sasl_username = NULL +;memcached.sess_sasl_username = NULL ; Session SASL password -memcached.sess_sasl_password = NULL +;memcached.sess_sasl_password = NULL ; Set the compression type ; valid values are: fastlz, zlib ; the default is fastlz -memcached.compression_type = "fastlz" +;memcached.compression_type = "fastlz" ; Compression factor ; Store compressed value only if the compression @@ -98,13 +96,13 @@ memcached.compression_type = "fastlz" ; plain_len > comp_len * factor ; ; the default value is 1.3 (23% space saving) -memcached.compression_factor = "1.3" +;memcached.compression_factor = "1.3" ; The compression threshold ; ; Do not compress serialized values below this threshold. ; the default is 2000 bytes -memcached.compression_threshold = 2000 +;memcached.compression_threshold = 2000 ; Set the default serializer for new memcached objects. ; valid values are: php, igbinary, json, json_array, msgpack @@ -119,14 +117,14 @@ memcached.compression_threshold = 2000 ; msgpack - a cross-language binary serializer ; ; The default is igbinary if available, then msgpack if available, then php otherwise. -memcached.serializer = "igbinary" +;memcached.serializer = "igbinary" ; The amount of retries for failed store commands. ; This mechanism allows transparent fail-over to secondary servers when ; set/increment/decrement/setMulti operations fail on the desired server in a multi-server ; environment. ; the default is 2 -memcached.store_retry_count = 2 +;memcached.store_retry_count = 2 ; Sets the default for consistent hashing for new connections. ; (To configure consistent hashing for session connections, @@ -137,7 +135,7 @@ memcached.store_retry_count = 2 ; When consistent hashing is used, one can add or remove cache ; node(s) without messing up too much with existing keys ; default is Off -memcached.default_consistent_hash = Off +;memcached.default_consistent_hash = Off ; Sets the default memcached protocol for new connections. ; (To configure the memcached protocol for connections used by sessions, @@ -146,7 +144,7 @@ memcached.default_consistent_hash = Off ; If set to On, the memcached binary protocol is used by default. ; If set to Off, the memcached text protocol is used. ; Default is Off -memcached.default_binary_protocol = Off +;memcached.default_binary_protocol = Off ; Sets the default memcached connection timeout for new connections. ; (To configure the memcached connection timeout for sessions, @@ -155,4 +153,4 @@ memcached.default_binary_protocol = Off ; during socket connection in milliseconds. Specifying -1 means an infinite timeout. ; Specifying 0 means using the memcached library's default connection timeout. ; Default is 0. -memcached.default_connect_timeout = 0 +;memcached.default_connect_timeout = 0 From 0a90491dd13af8dfc9a2e1ee600590fe9245ac50 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Mon, 20 Feb 2017 19:32:37 +0100 Subject: [PATCH 044/218] set sess_binary_protocol off by default with older libmemcached --- memcached.ini | 4 +++- php_memcached.c | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/memcached.ini b/memcached.ini index fa9a6fd4..6d05da3c 100644 --- a/memcached.ini +++ b/memcached.ini @@ -64,7 +64,9 @@ ; Use the memcached binary protocol for memcached sessions (Instead of the text protocol) ; libmemcached replicas work only if binary mode is enabled. ; However, certain proxies (such as twemproxy) will work only if the binary protocol is disabled. -; Default is On. In older versions of php-memcached, this setting was Off and was called memcached.sess_binary. +; In older versions of php-memcached, this setting was Off and was called memcached.sess_binary. +; Default is On with libmemcached 1.0.18 or newer. +; Default is Off with older version. ;memcached.sess_binary_protocol = On ; memcached session replica read randomize diff --git a/php_memcached.c b/php_memcached.c index 19673323..b920970b 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -332,7 +332,11 @@ PHP_INI_BEGIN() MEMC_SESSION_INI_ENTRY("lock_wait_max", "2000", OnUpdateLongGEZero, lock_wait_max) MEMC_SESSION_INI_ENTRY("lock_retries", "5", OnUpdateLong, lock_retries) MEMC_SESSION_INI_ENTRY("lock_expire", "0", OnUpdateLongGEZero, lock_expiration) +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 + MEMC_SESSION_INI_ENTRY("binary_protocol", "0", OnUpdateBool, binary_protocol_enabled) +#else MEMC_SESSION_INI_ENTRY("binary_protocol", "1", OnUpdateBool, binary_protocol_enabled) +#endif MEMC_SESSION_INI_ENTRY("consistent_hash", "1", OnUpdateBool, consistent_hash_enabled) MEMC_SESSION_INI_ENTRY("number_of_replicas", "0", OnUpdateLongGEZero, number_of_replicas) MEMC_SESSION_INI_ENTRY("randomize_replica_read", "0", OnUpdateLongGEZero, randomize_replica_read_enabled) From 3b3e63dac7df9e6085442d7cd4f1e898e1af9114 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 21 Feb 2017 23:47:15 +0100 Subject: [PATCH 045/218] typo in skip message (#331) --- tests/session_lazy_warning.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/session_lazy_warning.phpt b/tests/session_lazy_warning.phpt index 79d7f2f3..6847f5b5 100644 --- a/tests/session_lazy_warning.phpt +++ b/tests/session_lazy_warning.phpt @@ -4,7 +4,7 @@ Session lazy binary warning old libmemcached = 0x01000018) die ('skip too old libmemcached'); +if (Memcached::LIBMEMCACHED_VERSION_HEX >= 0x01000018) die ('skip too recent libmemcached'); ?> --INI-- session.save_handler = memcached From 037ed570bae27a7a3d47fda9f38f6d0355554e9b Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 22 Feb 2017 01:22:11 +0100 Subject: [PATCH 046/218] Fix build warnings (#329) --- php_memcached.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 19673323..55d1bdb8 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -194,7 +194,8 @@ static inline php_memc_object_t *php_memc_fetch_object(zend_object *obj) { php_error_docref(NULL, E_WARNING, "Memcached constructor was not called"); \ return; \ } \ - memc_user_data = (php_memc_user_data_t *) memcached_get_user_data(intern->memc); + memc_user_data = (php_memc_user_data_t *) memcached_get_user_data(intern->memc); \ + (void)memc_user_data; /* avoid unused variable warning */ static zend_bool s_memc_valid_key_binary(const char *key) @@ -898,7 +899,7 @@ zend_bool s_serialize_value (php_memc_serializer_type serializer, zval *value, s php_error_docref(NULL, E_WARNING, "could not serialize value with igbinary"); return 0; } - smart_str_appendl (buf, buffer, buffer_len); + smart_str_appendl (buf, (char *)buffer, buffer_len); efree(buffer); MEMC_VAL_SET_TYPE(*flags, MEMC_VAL_IS_IGBINARY); } @@ -1058,7 +1059,7 @@ zend_bool s_memc_write_zval (php_memc_object_t *intern, php_memc_write_op op, ze { uint32_t flags = 0; zend_string *payload = NULL; - memcached_return status; + memcached_return status = 0; php_memc_user_data_t *memc_user_data = memcached_get_user_data(intern->memc); zend_long retries = memc_user_data->store_retry_count; @@ -3911,10 +3912,12 @@ ZEND_BEGIN_ARG_INFO(arginfo_getOption, 0) ZEND_ARG_INFO(0, option) ZEND_END_ARG_INFO() +#ifdef HAVE_MEMCACHED_SASL ZEND_BEGIN_ARG_INFO(arginfo_setSaslAuthData, 0) ZEND_ARG_INFO(0, username) ZEND_ARG_INFO(0, password) ZEND_END_ARG_INFO() +#endif ZEND_BEGIN_ARG_INFO(arginfo_setOption, 0) ZEND_ARG_INFO(0, option) From 6b660bd554368bae69c2fbf490c6e78712e50708 Mon Sep 17 00:00:00 2001 From: Akihito Nakano Date: Sun, 23 Apr 2017 15:12:36 +0900 Subject: [PATCH 047/218] Fix optional parameter getStats($type) (#337) * Fix 'type' is optional * Change argument name args -> type --- php_memcached.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 55d1bdb8..3f3ac286 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -3876,6 +3876,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_addServer, 0, 0, 2) ZEND_ARG_INFO(0, weight) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_getStats, 0, 0, 0) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO(arginfo_addServers, 0) ZEND_ARG_ARRAY_INFO(0, servers, 0) ZEND_END_ARG_INFO() @@ -3934,10 +3938,6 @@ ZEND_BEGIN_ARG_INFO(arginfo_setBucket, 3) ZEND_ARG_INFO(0, replicas) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_getStats, 0) - ZEND_ARG_INFO(0, args) -ZEND_END_ARG_INFO() - ZEND_BEGIN_ARG_INFO(arginfo_getVersion, 0) ZEND_END_ARG_INFO() From c23ea262f3b481951b0131db358770b352953e14 Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Sun, 30 Apr 2017 08:15:36 -0700 Subject: [PATCH 048/218] Document GET_EXTENDED flag. Add/rename other missing/misnamed constants. (#335) --- memcached-api.php | 108 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 89 insertions(+), 19 deletions(-) diff --git a/memcached-api.php b/memcached-api.php index df725091..f5174e22 100644 --- a/memcached-api.php +++ b/memcached-api.php @@ -10,13 +10,13 @@ class Memcached { */ const OPT_HASH; - - const OPT_HASH_DEFAULT; + + const HASH_DEFAULT; const HASH_MD5; const HASH_CRC; - + const HASH_FNV1_64; const HASH_FNV1A_64; @@ -34,12 +34,16 @@ class Memcached { const DISTRIBUTION_MODULA; const DISTRIBUTION_CONSISTENT; - + const DISTRIBUTION_VIRTUAL_BUCKET; - const LIBKETAMA_COMPATIBLE; + const OPT_LIBKETAMA_COMPATIBLE; - const OPT_BUFFER_REQUESTS; + const OPT_LIBKETAMA_HASH; + + const OPT_TCP_KEEPALIVE; + + const OPT_BUFFER_WRITES; const OPT_BINARY_PROTOCOL; @@ -57,9 +61,9 @@ class Memcached { const OPT_DEAD_TIMEOUT; - const OPT_SND_TIMEOUT; + const OPT_SEND_TIMEOUT; - const OPT_RCV_TIMEOUT; + const OPT_RECV_TIMEOUT; const OPT_POLL_TIMEOUT; @@ -71,22 +75,34 @@ class Memcached { const OPT_AUTO_EJECT_HOSTS; - const OPT_NUMBER_OF_REPLICAS; - const OPT_NOREPLY; const OPT_VERIFY_KEY; - + + const OPT_USE_UDP; + + const OPT_NUMBER_OF_REPLICAS; + const OPT_RANDOMIZE_REPLICA_READS; + const OPT_REMOVE_FAILED_SERVERS; /** - * Class parameters + * Supported serializers */ const HAVE_JSON; const HAVE_IGBINARY; + const HAVE_MSGPACK; + + /** + * Feature support + */ + const HAVE_SESSION; + + const HAVE_SASL; + /** * Class options. */ @@ -107,18 +123,24 @@ class Memcached { const SERIALIZER_JSON_ARRAY; + const SERIALIZER_MSGPACK; + /** * Compression types */ - const COMPRESSION_TYPE_FASTLZ; + const COMPRESSION_FASTLZ; - const COMPRESSION_TYPE_ZLIB; + const COMPRESSION_ZLIB; /** - * Flags + * Flags for get and getMulti operations. */ + // Whether to preserve key order in the result const GET_PRESERVE_ORDER; + // Whether to fetch CAS token as well (use "gets"). + const GET_EXTENDED; + /** * Return values */ @@ -186,9 +208,57 @@ class Memcached { const RES_CONNECTION_SOCKET_CREATE_FAILURE; + const RES_E2BIG; + + const RES_KEY_TOO_BIG; + + const RES_SERVER_TEMPORARILY_DISABLED; + + const RES_SERVER_MEMORY_ALLOCATION_FAILURE; + + const RES_AUTH_PROBLEM; + + const RES_AUTH_FAILURE; + + const RES_AUTH_CONTINUE; + + /** Server callbacks, if compiled with --memcached-protocol */ + const ON_CONNECT; + const ON_ADD; + const ON_APPEND; + const ON_DECREMENT; + const ON_DELETE; + const ON_FLUSH; + const ON_GET; + const ON_INCREMENT; + const ON_NOOP; + const ON_PREPEND; + const ON_QUIT; + const ON_REPLACE; + const ON_SET; + const ON_STAT; + const ON_VERSION; + /** Constants used when compiled with --memcached-protocol */ + const RESPONSE_SUCCESS; + const RESPONSE_KEY_ENOENT; + const RESPONSE_KEY_EEXISTS; + const RESPONSE_E2BIG; + const RESPONSE_EINVAL; + const RESPONSE_NOT_STORED; + const RESPONSE_DELTA_BADVAL; + const RESPONSE_NOT_MY_VBUCKET; + const RESPONSE_AUTH_ERROR; + const RESPONSE_AUTH_CONTINUE; + const RESPONSE_UNKNOWN_COMMAND; + const RESPONSE_ENOMEM; + const RESPONSE_NOT_SUPPORTED; + const RESPONSE_EINTERNAL; + const RESPONSE_EBUSY; + const RESPONSE_ETMPFAIL; + public function __construct( $persistent_id = '', $on_new_object_cb = null ) {} - + public function get( $key, callable $cache_cb = null, $flags = 0) {} public function getByKey( $server_key, $key, callable $cache_cb = null, $flags = 0 ) {} @@ -202,7 +272,7 @@ public function getDelayed( array $keys, $with_cas = null, $value_cb = null ) {} public function getDelayedByKey( $server_key, array $keys, $with_cas = null, $value_cb = null ) {} public function fetch( ) {} - + public function fetchAll( ) {} public function set( $key, $value, $expiration = 0, $udf_flags = 0 ) {} @@ -250,7 +320,7 @@ public function increment( $key, $offset = 1, $initial_value = 0, $expiry = 0) { public function decrement( $key, $offset = 1, $initial_value = 0, $expiry = 0) {} public function getOption( $option ) {} - + public function setOption( $option, $value ) {} public function setOptions( array $options ) {} @@ -280,7 +350,7 @@ public function flushBuffers( ) {} public function getStats( $type = null ) {} public function getAllKeys( ) {} - + public function getVersion( ) {} public function getResultCode( ) {} From 14581c4604b4e4a525e1a30a52a8ac39ac1ac7e4 Mon Sep 17 00:00:00 2001 From: Eric Norris Date: Tue, 2 May 2017 16:24:34 -0400 Subject: [PATCH 049/218] s/encryption/compression/g (#342) --- php_memcached.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index 3f3ac286..7cda4ac3 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -3383,7 +3383,7 @@ zend_string *s_decompress_value (const char *payload, size_t payload_len, uint32 is_zlib = MEMC_VAL_HAS_FLAG(flags, MEMC_VAL_COMPRESSION_ZLIB); if (!is_fastlz && !is_zlib) { - php_error_docref(NULL, E_WARNING, "could not decompress value: unrecognised encryption type"); + php_error_docref(NULL, E_WARNING, "could not decompress value: unrecognised compression type"); return NULL; } From 5f28025c15c87d0895f39def77068c8fd66d442a Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Tue, 23 May 2017 11:43:19 +0800 Subject: [PATCH 050/218] This will lead unexpected behavior if zval is an interned string --- php_memcached.c | 1 - 1 file changed, 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index 7cda4ac3..9eacbbfb 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -1019,7 +1019,6 @@ zend_string *s_zval_to_payload(php_memc_object_t *intern, zval *value, uint32_t } break; } - zend_string_forget_hash_val(payload); /* turn off compression for values below the threshold */ if (ZSTR_LEN(payload) == 0 || ZSTR_LEN(payload) < MEMC_G(compression_threshold)) { From 23cf6c60f398cecb896e4fead37c18c9b56717fa Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Fri, 9 Jun 2017 11:08:33 -0700 Subject: [PATCH 051/218] Fix ReflectionMethod signatures for appendByKey,prepend, etc. (#352) --- php_memcached.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 9eacbbfb..7e020eaa 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -3775,27 +3775,23 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_append, 0, 0, 2) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_appendByKey, 0, 0, 3) ZEND_ARG_INFO(0, server_key) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_prepend, 0, 0, 2) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_prependByKey, 0, 0, 3) ZEND_ARG_INFO(0, server_key) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_cas, 0, 0, 3) From 43bbf0080206b157b0d3f47ab1f07ede4bc80c86 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 7 Jul 2017 18:45:42 -0700 Subject: [PATCH 052/218] In PHP 7.2, php_errormsg is deprecated --- tests/append.phpt | 2 +- tests/bad_construct.phpt | 2 +- tests/experimental/fetch_badunserialize.phpt | 2 +- tests/experimental/fetchall_badunserialize.phpt | 2 +- tests/experimental/getdelayed_badunserialize.phpt | 2 +- tests/experimental/getdelayed_cbthrows.phpt | 2 +- tests/experimental/getmulti_badunserialize.phpt | 2 +- tests/experimental/replace_bykey.phpt | 2 +- .../serializer/serializer_php_bad_serialize.phpt | 2 +- .../serializer/serializer_php_bad_unserialize.phpt | 2 +- tests/experimental/setmulti_badserialize.phpt | 2 +- tests/incrdecr.phpt | 8 ++++---- tests/incrdecr_bykey.phpt | 8 ++++---- 13 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tests/append.phpt b/tests/append.phpt index c463fde8..b958b391 100644 --- a/tests/append.phpt +++ b/tests/append.phpt @@ -11,7 +11,7 @@ error_reporting(0); $m->delete('foo'); $m->setOption(Memcached::OPT_COMPRESSION, true); var_dump($m->append('foo', 'a')); -echo $php_errormsg, "\n"; +echo error_get_last()["message"], "\n"; $m->setOption(Memcached::OPT_COMPRESSION, false); $m->delete('foo'); diff --git a/tests/bad_construct.phpt b/tests/bad_construct.phpt index aa9b18c4..0b740e00 100644 --- a/tests/bad_construct.phpt +++ b/tests/bad_construct.phpt @@ -6,7 +6,7 @@ Memcached construct with bad arguments getDelayed(array('foo'), false)); try { var_dump($m->fetch()); } catch (Exception $e) { - echo $php_errormsg, "\n"; + echo error_get_last()["message"], "\n"; echo $e->getMessage(), "\n"; } diff --git a/tests/experimental/fetchall_badunserialize.phpt b/tests/experimental/fetchall_badunserialize.phpt index e3ad3310..5684763f 100644 --- a/tests/experimental/fetchall_badunserialize.phpt +++ b/tests/experimental/fetchall_badunserialize.phpt @@ -42,7 +42,7 @@ var_dump($m->getDelayed(array('foo'), false)); try { var_dump($m->fetchAll()); } catch (Exception $e) { - echo $php_errormsg, "\n"; + echo error_get_last()["message"], "\n"; echo $e->getMessage(), "\n"; } diff --git a/tests/experimental/getdelayed_badunserialize.phpt b/tests/experimental/getdelayed_badunserialize.phpt index 571e76e0..397135ae 100644 --- a/tests/experimental/getdelayed_badunserialize.phpt +++ b/tests/experimental/getdelayed_badunserialize.phpt @@ -45,7 +45,7 @@ error_reporting(0); try { var_dump($m->getDelayed(array('foo'), false, 'mycb')); } catch (Exception $e) { - echo $php_errormsg, "\n"; + echo error_get_last()["message"], "\n"; echo $e->getMessage(), "\n"; } diff --git a/tests/experimental/getdelayed_cbthrows.phpt b/tests/experimental/getdelayed_cbthrows.phpt index 2b71b4b4..b0427ac9 100644 --- a/tests/experimental/getdelayed_cbthrows.phpt +++ b/tests/experimental/getdelayed_cbthrows.phpt @@ -24,7 +24,7 @@ error_reporting(0); try { $m->getDelayedByKey('kef', array_keys($data), false, 'myfunc'); } catch (Exception $e) { - echo $php_errormsg, "\n"; + echo error_get_last()["message"], "\n"; echo $e->getMessage(), "\n"; } diff --git a/tests/experimental/getmulti_badunserialize.phpt b/tests/experimental/getmulti_badunserialize.phpt index b33d5ccd..963e9730 100644 --- a/tests/experimental/getmulti_badunserialize.phpt +++ b/tests/experimental/getmulti_badunserialize.phpt @@ -32,7 +32,7 @@ error_reporting(0); try { var_dump($m->getMulti(array('bar', 'foo'))); } catch (Exception $e) { - echo $php_errormsg, "\n"; + echo error_get_last()["message"], "\n"; echo $e->getMessage(), "\n"; } diff --git a/tests/experimental/replace_bykey.phpt b/tests/experimental/replace_bykey.phpt index b2f72836..cddf10f0 100644 --- a/tests/experimental/replace_bykey.phpt +++ b/tests/experimental/replace_bykey.phpt @@ -10,7 +10,7 @@ error_reporting(0); $m->delete('foo'); var_dump($m->replaceByKey('kef', 'foo', 'bar', 60)); -echo $php_errormsg, "\n"; +echo error_get_last()["message"], "\n"; echo $m->getResultMessage(), "\n"; var_dump($m->getByKey('kef', 'foo')); diff --git a/tests/experimental/serializer/serializer_php_bad_serialize.phpt b/tests/experimental/serializer/serializer_php_bad_serialize.phpt index 81e88b0c..76d3daca 100644 --- a/tests/experimental/serializer/serializer_php_bad_serialize.phpt +++ b/tests/experimental/serializer/serializer_php_bad_serialize.phpt @@ -44,7 +44,7 @@ error_reporting(0); try { var_dump($m->set('foo', new Foo(), 10)); } catch (Exception $e) { - echo $php_errormsg, "\n"; + echo error_get_last()["message"], "\n"; echo $e->getMessage(), "\n"; } try { diff --git a/tests/experimental/serializer/serializer_php_bad_unserialize.phpt b/tests/experimental/serializer/serializer_php_bad_unserialize.phpt index 39d2cc37..341ddedc 100644 --- a/tests/experimental/serializer/serializer_php_bad_unserialize.phpt +++ b/tests/experimental/serializer/serializer_php_bad_unserialize.phpt @@ -40,7 +40,7 @@ var_dump($m->set('foo', new Foo(), 10)); try { var_dump($m->get('foo')); } catch (Exception $e) { - echo $php_errormsg, "\n"; + echo error_get_last()["message"], "\n"; echo $e->getMessage(), "\n"; } diff --git a/tests/experimental/setmulti_badserialize.phpt b/tests/experimental/setmulti_badserialize.phpt index 3bba314a..eafc7772 100644 --- a/tests/experimental/setmulti_badserialize.phpt +++ b/tests/experimental/setmulti_badserialize.phpt @@ -36,7 +36,7 @@ try { } } - echo $php_errormsg, "\n"; + echo error_get_last()["message"], "\n"; echo $e->getMessage(), "\n"; } var_dump($m->getByKey('kef', 'foo')); diff --git a/tests/incrdecr.phpt b/tests/incrdecr.phpt index b4e9469b..87b410c9 100644 --- a/tests/incrdecr.phpt +++ b/tests/incrdecr.phpt @@ -31,14 +31,14 @@ var_dump($m->get('foo')); error_reporting(0); echo "Negative offset\n"; -$php_errormsg = ''; +error_clear_last(); $m->increment('foo', -1); -echo $php_errormsg, "\n"; +echo error_get_last()["message"], "\n"; var_dump($m->get('foo')); -$php_errormsg = ''; +error_clear_last(); $m->decrement('foo', -1); -echo $php_errormsg, "\n"; +echo error_get_last()["message"], "\n"; var_dump($m->get('foo')); echo "Enormous offset\n"; diff --git a/tests/incrdecr_bykey.phpt b/tests/incrdecr_bykey.phpt index 8b931fa7..ee089938 100644 --- a/tests/incrdecr_bykey.phpt +++ b/tests/incrdecr_bykey.phpt @@ -28,14 +28,14 @@ var_dump($m->get('foo')); error_reporting(0); echo "Negative offset\n"; -$php_errormsg = ''; +error_clear_last(); $m->incrementByKey('foo', 'foo', -1); -echo $php_errormsg, "\n"; +echo error_get_last()["message"], "\n"; var_dump($m->get('foo')); -$php_errormsg = ''; +error_clear_last(); $m->decrementByKey('foo', 'foo', -1); -echo $php_errormsg, "\n"; +echo error_get_last()["message"], "\n"; var_dump($m->get('foo')); echo "Enormous offset\n"; From e91eae7be3d6076f5a66f4ef3b588d61df8ec1a2 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 10 Jul 2017 14:46:20 -0700 Subject: [PATCH 053/218] Split tests for invalid keys ascii and binary Test get command for invalid keys as well as set command --- package.xml | 3 +- tests/keys.phpt | 118 ------------------------- tests/keys_ascii.phpt | 190 +++++++++++++++++++++++++++++++++++++++++ tests/keys_binary.phpt | 190 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 382 insertions(+), 119 deletions(-) delete mode 100644 tests/keys.phpt create mode 100644 tests/keys_ascii.phpt create mode 100644 tests/keys_binary.phpt diff --git a/package.xml b/package.xml index 2306344d..2cc8995b 100644 --- a/package.xml +++ b/package.xml @@ -147,7 +147,8 @@ Fixes - + + diff --git a/tests/keys.phpt b/tests/keys.phpt deleted file mode 100644 index f320e03f..00000000 --- a/tests/keys.phpt +++ /dev/null @@ -1,118 +0,0 @@ ---TEST-- -Test different kind of keys ---SKIPIF-- - ---FILE-- - true, - )); - -$ascii = memc_get_instance (); -$ascii->setOption(Memcached::OPT_VERIFY_KEY, 1); - -var_dump ($binary->set ('binary key with spaces', 'this is a test')); -var_dump ($binary->getResultCode () == Memcached::RES_SUCCESS); - -var_dump ($binary->set ('binarykeywithnewline' . PHP_EOL, 'this is a test')); -var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); - -var_dump ($ascii->set ('ascii key with spaces', 'this is a test')); -var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); - -var_dump ($binary->set ('asciikeywithnewline' . PHP_EOL, 'this is a test')); -var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); - -var_dump ($ascii->set (''/*empty key*/, 'this is a test')); -var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); - -for ($i=0;$i<32;$i++) { - var_dump ($ascii->set ('asciikeywithnonprintablechar-' . chr($i) . '-here', 'this is a test')); - var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); -} - -var_dump ($ascii->set (str_repeat ('1234567890', 512), 'this is a test')); -var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); - -echo "OK" . PHP_EOL; - ---EXPECT-- -bool(true) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -bool(false) -bool(true) -OK diff --git a/tests/keys_ascii.phpt b/tests/keys_ascii.phpt new file mode 100644 index 00000000..f7e98894 --- /dev/null +++ b/tests/keys_ascii.phpt @@ -0,0 +1,190 @@ +--TEST-- +Test valid and invalid keys - ascii +--SKIPIF-- + +--FILE-- + false, + Memcached::OPT_VERIFY_KEY => false + )); +// libmemcached can verify keys, but these are tests are for our own +// function s_memc_valid_key_ascii, so explicitly disable the checks +// that libmemcached can perform. + +echo 'ASCII: SPACES' . PHP_EOL; +var_dump ($ascii->set ('ascii key with spaces', 'this is a test')); +var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'ASCII: NEWLINE' . PHP_EOL; +var_dump ($ascii->set ('asciikeywithnewline' . PHP_EOL, 'this is a test')); +var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'ASCII: EMPTY' . PHP_EOL; +var_dump ($ascii->set (''/*empty key*/, 'this is a test')); +var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'ASCII: TOO LONG' . PHP_EOL; +var_dump ($ascii->set (str_repeat ('1234567890', 512), 'this is a test')); +var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'ASCII: GET' . PHP_EOL; +for ($i=0;$i<32;$i++) { + var_dump ($ascii->get ('asciikeywithnonprintablechar-' . chr($i) . '-here')); + var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); +} + +echo 'ASCII: SET' . PHP_EOL; +for ($i=0;$i<32;$i++) { + var_dump ($ascii->set ('asciikeywithnonprintablechar-' . chr($i) . '-here', 'this is a test')); + var_dump ($ascii->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); +} + +echo 'OK' . PHP_EOL; + +--EXPECT-- +ASCII: SPACES +bool(false) +bool(true) +ASCII: NEWLINE +bool(false) +bool(true) +ASCII: EMPTY +bool(false) +bool(true) +ASCII: TOO LONG +bool(false) +bool(true) +ASCII: GET +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +ASCII: SET +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +OK diff --git a/tests/keys_binary.phpt b/tests/keys_binary.phpt new file mode 100644 index 00000000..f0ae67bd --- /dev/null +++ b/tests/keys_binary.phpt @@ -0,0 +1,190 @@ +--TEST-- +Test valid and invalid keys - binary +--SKIPIF-- + +--FILE-- + true, + )); + +echo 'BINARY: SPACES' . PHP_EOL; +var_dump ($binary->set ('binary key with spaces', 'this is a test')); +var_dump ($binary->getResultCode () == Memcached::RES_SUCCESS); + +echo 'BINARY: NEWLINE' . PHP_EOL; +var_dump ($binary->set ('binarykeywithnewline' . PHP_EOL, 'this is a test')); +var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'BINARY: EMPTY' . PHP_EOL; +var_dump ($binary->set (''/*empty key*/, 'this is a test')); +var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'BINARY: TOO LONG' . PHP_EOL; +var_dump ($binary->set (str_repeat ('1234567890', 512), 'this is a test')); +var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + +echo 'BINARY: GET' . PHP_EOL; +// Only newline fails in binary mode (char 10) +for ($i=0;$i<32;$i++) { + $binary->delete ('binarykeywithnonprintablechar-' . chr($i) . '-here'); + var_dump ($binary->get ('binarykeywithnonprintablechar-' . chr($i) . '-here')); + var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); +} + +echo 'BINARY: SET' . PHP_EOL; +// Only newline fails in binary mode (char 10) +for ($i=0;$i<32;$i++) { + var_dump ($binary->set ('binarykeywithnonprintablechar-' . chr($i) . '-here', 'this is a test')); + var_dump ($binary->getResultCode () == Memcached::RES_BAD_KEY_PROVIDED); + $binary->delete ('binarykeywithnonprintablechar-' . chr($i) . '-here'); +} + +echo 'OK' . PHP_EOL; + +--EXPECT-- +BINARY: SPACES +bool(true) +bool(true) +BINARY: NEWLINE +bool(false) +bool(true) +BINARY: EMPTY +bool(false) +bool(true) +BINARY: TOO LONG +bool(false) +bool(true) +BINARY: GET +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +BINARY: SET +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(true) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +OK From be93a459eedc54fbbf2dfa63babea38b730fc313 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 10 Jul 2017 11:04:59 -0700 Subject: [PATCH 054/218] Fix the key validity tests to handle strings with embedded nulls --- php_memcached.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 4449200b..65d11eb2 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -198,24 +198,30 @@ static inline php_memc_object_t *php_memc_fetch_object(zend_object *obj) { (void)memc_user_data; /* avoid unused variable warning */ static -zend_bool s_memc_valid_key_binary(const char *key) +zend_bool s_memc_valid_key_binary(zend_string *key) { - return strchr(key, '\n') == NULL; + return memchr(ZSTR_VAL(key), '\n', ZSTR_LEN(key)) == NULL; } static -zend_bool s_memc_valid_key_ascii(const char *key) +zend_bool s_memc_valid_key_ascii(zend_string *key) { - while (*key && !iscntrl(*key) && !isspace(*key)) ++key; - return *key == '\0'; + const char *str = ZSTR_VAL(key); + size_t i, len = ZSTR_LEN(key); + + for (i = 0; i < len; i++) { + if (iscntrl(str[i]) || isspace(str[i])) + return 0; + } + return 1; } #define MEMC_CHECK_KEY(intern, key) \ if (UNEXPECTED(ZSTR_LEN(key) == 0 || \ ZSTR_LEN(key) > MEMC_OBJECT_KEY_MAX_LENGTH || \ (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) \ - ? !s_memc_valid_key_binary(ZSTR_VAL(key)) \ - : !s_memc_valid_key_ascii(ZSTR_VAL(key)) \ + ? !s_memc_valid_key_binary(key) \ + : !s_memc_valid_key_ascii(key) \ ))) { \ intern->rescode = MEMCACHED_BAD_KEY_PROVIDED; \ RETURN_FALSE; \ @@ -309,7 +315,7 @@ PHP_INI_MH(OnUpdateSessionPrefixString) php_error_docref(NULL, E_WARNING, "memcached.sess_prefix too long (max: %d)", MEMCACHED_MAX_KEY - 1); return FAILURE; } - if (!s_memc_valid_key_ascii(ZSTR_VAL(new_value))) { + if (!s_memc_valid_key_ascii(new_value)) { php_error_docref(NULL, E_WARNING, "memcached.sess_prefix cannot contain whitespace or control characters"); return FAILURE; } From 39bfab06c0c27dc620486f56a926308df5d4c819 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 11 Jul 2017 15:57:51 -0700 Subject: [PATCH 055/218] In PHP 7.2 the session_start() error messages have changed a bit (#359) See PHP Bug 71038 for details https://bugs.php.net/bug.php?id=71038 Added PHP 7.2.0alpha2 to Travis CI matrix --- .travis.yml | 3 ++- package.xml | 1 + tests/session_badconf_servers-php72.phpt | 30 ++++++++++++++++++++++++ tests/session_badconf_servers.phpt | 7 +++--- 4 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 tests/session_badconf_servers-php72.phpt diff --git a/.travis.yml b/.travis.yml index 2581b516..d12cd3c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,9 @@ dist: trusty language: php php: - - 7.0 + - 7.2.0alpha2 - 7.1 + - 7.0 matrix: fast_finish: true diff --git a/package.xml b/package.xml index 2cc8995b..5e1961f7 100644 --- a/package.xml +++ b/package.xml @@ -113,6 +113,7 @@ Fixes + diff --git a/tests/session_badconf_servers-php72.phpt b/tests/session_badconf_servers-php72.phpt new file mode 100644 index 00000000..92012369 --- /dev/null +++ b/tests/session_badconf_servers-php72.phpt @@ -0,0 +1,30 @@ +--TEST-- +Session bad configurations, invalid save path (server list) +--SKIPIF-- + +--INI-- +session.save_handler = memcached +--FILE-- + 70100) print "skip"; ?> --INI-- session.save_handler = memcached @@ -24,5 +25,5 @@ ini_set('session.save_path', ''); session_start(); session_write_close(); ---EXPECTF-- +--EXPECT-- session_start(): failed to parse session.save_path From 56145402e9d4a624037cdbfb5d9bab3bc7874e21 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 27 Jul 2017 00:03:48 -0700 Subject: [PATCH 056/218] Travis CI now provides the PHP 7.2 alias --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d12cd3c9..d2457f55 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ dist: trusty language: php php: - - 7.2.0alpha2 + - 7.2 - 7.1 - 7.0 From f82e6845af474ff98c5b6dae283f8beb3f4e6d4d Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 20 Nov 2017 23:15:34 -0600 Subject: [PATCH 057/218] Use new fast_zpp parameter parsing API (#311) The one that took a while to figure out was zpp("f!") to Z_PARAM_FUNC_EX(fci, fcc, 1, 0) --- php_memcached.c | 368 +++++++++++++++++++++++++++++++----------------- 1 file changed, 242 insertions(+), 126 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 65d11eb2..891b2a3e 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -1184,9 +1184,13 @@ static PHP_METHOD(Memcached, __construct) zend_bool is_persistent = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!f!S", &persistent_id, &fci, &fci_cache, &conn_str) == FAILURE) { - return; - } + /* "|S!f!S" */ + ZEND_PARSE_PARAMETERS_START(0, 3) + Z_PARAM_OPTIONAL + Z_PARAM_STR_EX(persistent_id, 1, 0) + Z_PARAM_FUNC_EX(fci, fci_cache, 1, 0) + Z_PARAM_STR(conn_str) + ZEND_PARSE_PARAMETERS_END(); intern = Z_MEMC_OBJ_P(getThis()); intern->is_pristine = 1; @@ -1413,13 +1417,22 @@ void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) MEMC_METHOD_INIT_VARS; if (by_key) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|f!l", &server_key, &key, &fci, &fcc, &get_flags) == FAILURE) { - return; - } + /* "SS|f!l" */ + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_FUNC_EX(fci, fcc, 1, 0) + Z_PARAM_LONG(get_flags) + ZEND_PARSE_PARAMETERS_END(); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|f!l", &key, &fci, &fcc, &get_flags) == FAILURE) { - return; - } + /* "S|f!l" */ + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_FUNC_EX(fci, fcc, 1, 0) + Z_PARAM_LONG(get_flags) + ZEND_PARSE_PARAMETERS_END(); } MEMC_METHOD_FETCH_OBJECT; @@ -1505,14 +1518,20 @@ static void php_memc_getMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke zend_bool retval, preserve_order; if (by_key) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sa|l", &server_key, - &keys, &flags) == FAILURE) { - return; - } + /* "Sa|l" */ + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(server_key) + Z_PARAM_ARRAY(keys) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(flags) + ZEND_PARSE_PARAMETERS_END(); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|l", &keys, &flags) == FAILURE) { - return; - } + /* "a|l" */ + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_ARRAY(keys) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(flags) + ZEND_PARSE_PARAMETERS_END(); } MEMC_METHOD_FETCH_OBJECT; @@ -1642,15 +1661,22 @@ static void php_memc_getDelayed_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ if (by_key) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sa/|bf!", &server_key, - &keys, &with_cas, &fci, &fcc) == FAILURE) { - return; - } + /* "Sa/|bf!" */ + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_STR(server_key) + Z_PARAM_ARRAY_EX(keys, 0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(with_cas) + Z_PARAM_FUNC_EX(fci, fcc, 1, 0) + ZEND_PARSE_PARAMETERS_END(); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/|bf!", &keys, &with_cas, - &fci, &fcc) == FAILURE) { - return; - } + /* "a/|bf!" */ + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_ARRAY_EX(keys, 0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_BOOL(with_cas) + Z_PARAM_FUNC_EX(fci, fcc, 1, 0) + ZEND_PARSE_PARAMETERS_END(); } MEMC_METHOD_FETCH_OBJECT; @@ -1796,7 +1822,7 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke { zval *entries; zend_string *server_key = NULL; - time_t expiration = 0; + zend_long expiration = 0, ignored; zval *value; zend_string *skey; zend_ulong num_key; @@ -1804,14 +1830,22 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke MEMC_METHOD_INIT_VARS; if (by_key) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sa|ll", &server_key, - &entries, &expiration) == FAILURE) { - return; - } + /* "Sa|ll" */ + ZEND_PARSE_PARAMETERS_START(2, 4) + Z_PARAM_STR(server_key) + Z_PARAM_ARRAY(entries) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + Z_PARAM_LONG(ignored) + ZEND_PARSE_PARAMETERS_END(); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "a|ll", &entries, &expiration) == FAILURE) { - return; - } + /* "a|ll" */ + ZEND_PARSE_PARAMETERS_START(1, 3) + Z_PARAM_ARRAY(entries) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + Z_PARAM_LONG(ignored) + ZEND_PARSE_PARAMETERS_END(); } MEMC_METHOD_FETCH_OBJECT; @@ -1921,35 +1955,56 @@ static void php_memc_store_impl(INTERNAL_FUNCTION_PARAMETERS, int op, zend_bool if (by_key) { if (op == MEMC_OP_APPEND || op == MEMC_OP_PREPEND) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "SSS", &server_key, &key, &s_value) == FAILURE) { - return; - } + /* "SSS" */ + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_STR(s_value) + ZEND_PARSE_PARAMETERS_END(); value = &s_zvalue; ZVAL_STR(value, s_value); } else if (op == MEMC_OP_TOUCH) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|l", &server_key, &key, &expiration) == FAILURE) { - return; - } + /* "SS|l" */ + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "SSz|l", &server_key, &key, &value, &expiration) == FAILURE) { - return; - } + /* "SSz|l" */ + ZEND_PARSE_PARAMETERS_START(3, 4) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_ZVAL(value) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); } } else { if (op == MEMC_OP_APPEND || op == MEMC_OP_PREPEND) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &key, &s_value) == FAILURE) { - return; - } + /* "SS" */ + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_STR(key) + Z_PARAM_STR(s_value) + ZEND_PARSE_PARAMETERS_END(); value = &s_zvalue; ZVAL_STR(value, s_value); } else if (op == MEMC_OP_TOUCH) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|l", &key, &expiration) == FAILURE) { - return; - } + /* "S|l */ + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sz|l", &key, &value, &expiration) == FAILURE) { - return; - } + /* "Sz|l" */ + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(key) + Z_PARAM_ZVAL(value) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); } } @@ -1984,22 +2039,34 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) zend_string *key; zend_string *server_key = NULL; zval *value; - time_t expiration = 0; + zend_long expiration = 0; + zend_long ignored; zend_string *payload; uint32_t flags = 0; memcached_return status; MEMC_METHOD_INIT_VARS; if (by_key) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zSSz|ll", &zv_cas, &server_key, &key, - &value, &expiration) == FAILURE) { - return; - } + /* "zSSz|ll" */ + ZEND_PARSE_PARAMETERS_START(4, 6) + Z_PARAM_ZVAL(zv_cas) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_ZVAL(value) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + Z_PARAM_LONG(ignored) + ZEND_PARSE_PARAMETERS_END(); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "zSz|ll", &zv_cas, &key, &value, - &expiration) == FAILURE) { - return; - } + /* "zSz|ll" */ + ZEND_PARSE_PARAMETERS_START(3, 5) + Z_PARAM_ZVAL(zv_cas) + Z_PARAM_STR(key) + Z_PARAM_ZVAL(value) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + Z_PARAM_LONG(ignored) + ZEND_PARSE_PARAMETERS_END(); } MEMC_METHOD_FETCH_OBJECT; @@ -2081,18 +2148,25 @@ PHP_METHOD(Memcached, deleteMultiByKey) static void php_memc_delete_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) { zend_string *key, *server_key; - time_t expiration = 0; + zend_long expiration = 0; memcached_return status; MEMC_METHOD_INIT_VARS; if (by_key) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS|l", &server_key, &key, &expiration) == FAILURE) { - return; - } + /* "SS|l" */ + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|l", &key, &expiration) == FAILURE) { - return; - } + /* "S|l" */ + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); server_key = key; } @@ -2120,20 +2194,27 @@ static void php_memc_deleteMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by { zval *entries, *zv, ret; zend_string *server_key = NULL; - time_t expiration = 0; + zend_long expiration = 0; zend_string *entry; memcached_return status; MEMC_METHOD_INIT_VARS; if (by_key) { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sa/|l", &server_key, &entries, &expiration) == FAILURE) { - return; - } + /* "Sa/|l" */ + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(server_key) + Z_PARAM_ARRAY_EX(entries, 0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); } else { - if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/|l", &entries, &expiration) == FAILURE) { - return; - } + /* "a/|l" */ + ZEND_PARSE_PARAMETERS_START(1, 2) + Z_PARAM_ARRAY_EX(entries, 0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(expiration) + ZEND_PARSE_PARAMETERS_END(); } MEMC_METHOD_FETCH_OBJECT; @@ -2172,21 +2253,33 @@ static void php_memc_incdec_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key, { zend_string *key, *server_key = NULL; zend_long offset = 1; - uint64_t value = UINT64_MAX, initial = 0; - time_t expiry = 0; + zend_long expiry = 0; + zend_long initial = 0; + uint64_t value = UINT64_MAX; memcached_return status; int n_args = ZEND_NUM_ARGS(); MEMC_METHOD_INIT_VARS; if (!by_key) { - if (zend_parse_parameters(n_args, "S|lll", &key, &offset, &initial, &expiry) == FAILURE) { - return; - } + /* "S|lll" */ + ZEND_PARSE_PARAMETERS_START(1, 4) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(offset) + Z_PARAM_LONG(initial) + Z_PARAM_LONG(expiry) + ZEND_PARSE_PARAMETERS_END(); } else { - if (zend_parse_parameters(n_args, "SS|lll", &server_key, &key, &offset, &initial, &expiry) == FAILURE) { - return; - } + /* "SS|lll" */ + ZEND_PARSE_PARAMETERS_START(2, 5) + Z_PARAM_STR(server_key) + Z_PARAM_STR(key) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(offset) + Z_PARAM_LONG(initial) + Z_PARAM_LONG(expiry) + ZEND_PARSE_PARAMETERS_END(); } MEMC_METHOD_FETCH_OBJECT; @@ -2228,15 +2321,15 @@ static void php_memc_incdec_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key, } if (by_key) { if (incr) { - status = memcached_increment_with_initial_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, expiry, &value); + status = memcached_increment_with_initial_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, (time_t)expiry, &value); } else { - status = memcached_decrement_with_initial_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, expiry, &value); + status = memcached_decrement_with_initial_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, (time_t)expiry, &value); } } else { if (incr) { - status = memcached_increment_with_initial(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, expiry, &value); + status = memcached_increment_with_initial(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, (time_t)expiry, &value); } else { - status = memcached_decrement_with_initial(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, expiry, &value); + status = memcached_decrement_with_initial(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), offset, initial, (time_t)expiry, &value); } } if (s_should_retry_write(intern, status) && retries-- > 0) { @@ -2293,13 +2386,17 @@ PHP_METHOD(Memcached, incrementByKey) PHP_METHOD(Memcached, addServer) { zend_string *host; - long port, weight = 0; + zend_long port, weight = 0; memcached_return status; MEMC_METHOD_INIT_VARS; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sl|l", &host, &port, &weight) == FAILURE) { - return; - } + /* "Sa/|l" */ + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(host) + Z_PARAM_LONG(port) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(weight) + ZEND_PARSE_PARAMETERS_END(); MEMC_METHOD_FETCH_OBJECT; s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); @@ -2327,9 +2424,10 @@ PHP_METHOD(Memcached, addServers) memcached_return status; MEMC_METHOD_INIT_VARS; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/", &servers) == FAILURE) { - return; - } + /* "a/" */ + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY_EX(servers, 0, 1) + ZEND_PARSE_PARAMETERS_END(); MEMC_METHOD_FETCH_OBJECT; s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); @@ -2431,9 +2529,10 @@ PHP_METHOD(Memcached, getServerByKey) memcached_return error; MEMC_METHOD_INIT_VARS; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &server_key) == FAILURE) { - return; - } + /* "S" */ + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(server_key) + ZEND_PARSE_PARAMETERS_END(); MEMC_METHOD_FETCH_OBJECT; s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); @@ -2651,9 +2750,11 @@ PHP_METHOD(Memcached, getStats) zend_string *args_string = NULL; MEMC_METHOD_INIT_VARS; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S!", &args_string) == FAILURE) { - return; - } + /* "|S!" */ + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_STR_EX(args_string, 1, 0) + ZEND_PARSE_PARAMETERS_END(); MEMC_METHOD_FETCH_OBJECT; @@ -2745,13 +2846,15 @@ PHP_METHOD(Memcached, getAllKeys) Flushes the data on all the servers */ static PHP_METHOD(Memcached, flush) { - time_t delay = 0; + zend_long delay = 0; memcached_return status; MEMC_METHOD_INIT_VARS; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &delay) == FAILURE) { - return; - } + /* "|l" */ + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(delay) + ZEND_PARSE_PARAMETERS_END(); MEMC_METHOD_FETCH_OBJECT; s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); @@ -2769,14 +2872,15 @@ static PHP_METHOD(Memcached, flush) Returns the value for the given option constant */ static PHP_METHOD(Memcached, getOption) { - long option; + zend_long option; uint64_t result; memcached_behavior flag; MEMC_METHOD_INIT_VARS; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &option) == FAILURE) { - return; - } + /* "l" */ + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_LONG(option) + ZEND_PARSE_PARAMETERS_END(); MEMC_METHOD_FETCH_OBJECT; @@ -3018,7 +3122,7 @@ PHP_METHOD(Memcached, setBucket) { zval *zserver_map; zval *zforward_map = NULL; - long replicas = 0; + zend_long replicas = 0; zend_bool retval = 1; uint32_t *server_map = NULL, *forward_map = NULL; @@ -3026,9 +3130,12 @@ PHP_METHOD(Memcached, setBucket) memcached_return rc; MEMC_METHOD_INIT_VARS; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "aa!l", &zserver_map, &zforward_map, &replicas) == FAILURE) { - return; - } + /* "aa!l" */ + ZEND_PARSE_PARAMETERS_START(3, 3) + Z_PARAM_ARRAY(zserver_map) + Z_PARAM_ARRAY_EX(zforward_map, 1, 0) + Z_PARAM_LONG(replicas) + ZEND_PARSE_PARAMETERS_END(); MEMC_METHOD_FETCH_OBJECT; @@ -3089,9 +3196,11 @@ static PHP_METHOD(Memcached, setOptions) MEMC_METHOD_INIT_VARS; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &options) == FAILURE) { - return; - } + /* "a" */ + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_ARRAY(options) + ZEND_PARSE_PARAMETERS_END(); + MEMC_METHOD_FETCH_OBJECT; @@ -3114,13 +3223,15 @@ static PHP_METHOD(Memcached, setOptions) Sets the value for the given option constant */ static PHP_METHOD(Memcached, setOption) { - long option; + zend_long option; zval *value; MEMC_METHOD_INIT_VARS; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "lz/", &option, &value) == FAILURE) { - return; - } + /* "lz/" */ + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_LONG(option) + Z_PARAM_ZVAL_EX(value, 0, 1) + ZEND_PARSE_PARAMETERS_END(); MEMC_METHOD_FETCH_OBJECT; @@ -3137,9 +3248,11 @@ static PHP_METHOD(Memcached, setSaslAuthData) memcached_return status; zend_string *user, *pass; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "SS", &user, &pass) == FAILURE) { - return; - } + /* "SS/" */ + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_STR(user) + Z_PARAM_STR(pass) + ZEND_PARSE_PARAMETERS_END(); if (!php_memc_init_sasl_if_needed()) { RETURN_FALSE; @@ -3621,9 +3734,10 @@ PHP_METHOD(MemcachedServer, run) php_memc_server_t *intern; intern = Z_MEMC_SERVER_P(getThis()); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &address) == FAILURE) { - return; - } + /* "S" */ + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(address) + ZEND_PARSE_PARAMETERS_END(); rc = php_memc_proto_handler_run(intern->handler, address); @@ -3642,9 +3756,11 @@ PHP_METHOD(MemcachedServer, on) zend_fcall_info_cache fci_cache; zend_bool rc = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "lf!", &event, &fci, &fci_cache) == FAILURE) { - return; - } + /* "lf!" */ + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_LONG(event) + Z_PARAM_FUNC_EX(fci, fci_cache, 1, 0) + ZEND_PARSE_PARAMETERS_END(); if (event <= MEMC_SERVER_ON_MIN || event >= MEMC_SERVER_ON_MAX) { RETURN_FALSE; From 3f1362ae8b5d4f4ed9ad01bc826c906608137746 Mon Sep 17 00:00:00 2001 From: Tom Van Looy Date: Tue, 21 Nov 2017 06:18:26 +0100 Subject: [PATCH 058/218] Remove unused defines MEMC_SESS_DEFAULT_LOCK_WAIT and MEMC_SESS_LOCK_EXPIRATION (#354) --- php_memcached_session.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/php_memcached_session.c b/php_memcached_session.c index afa973bb..ab3e7222 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -22,9 +22,6 @@ extern ZEND_DECLARE_MODULE_GLOBALS(php_memcached) -#define MEMC_SESS_DEFAULT_LOCK_WAIT 150000 -#define MEMC_SESS_LOCK_EXPIRATION 30 - #define REALTIME_MAXDELTA 60*60*24*30 ps_module ps_mod_memcached = { From 5edd5bac25016646a4e6f4ad758847ceaaa1d874 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 20 Nov 2017 23:48:40 -0600 Subject: [PATCH 059/218] Restore default value memcached.sess_prefix = "memc.sess.key." Resolves #340 --- php_memcached.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index 891b2a3e..952b582c 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -352,7 +352,7 @@ PHP_INI_BEGIN() MEMC_SESSION_INI_ENTRY("connect_timeout", "0", OnUpdateLongGEZero, connect_timeout) MEMC_SESSION_INI_ENTRY("sasl_username", "", OnUpdateString, sasl_username) MEMC_SESSION_INI_ENTRY("sasl_password", "", OnUpdateString, sasl_password) - MEMC_SESSION_INI_ENTRY("prefix", "memc.sess.", OnUpdateSessionPrefixString, prefix) + MEMC_SESSION_INI_ENTRY("prefix", "memc.sess.key.", OnUpdateSessionPrefixString, prefix) MEMC_SESSION_INI_ENTRY("persistent", "0", OnUpdateBool, persistent_enabled) /* Deprecated */ From f30e7428e5f55f0dc8eec0dc6d30cc3f0f05d73e Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Tue, 5 Dec 2017 18:13:23 +0100 Subject: [PATCH 060/218] Fix typo bibrary to library (#372) --- config.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.m4 b/config.m4 index b34c30bf..705f4957 100644 --- a/config.m4 +++ b/config.m4 @@ -26,8 +26,8 @@ PHP_ARG_ENABLE(memcached-sasl, whether to enable memcached sasl support, PHP_ARG_ENABLE(memcached-protocol, whether to enable memcached protocol support, [ --enable-memcached-protocol Enable memcached protocol support], no, no) -PHP_ARG_WITH(system-fastlz, whether to use system FastLZ bibrary, -[ --with-system-fastlz Use system FastLZ bibrary], no, no) +PHP_ARG_WITH(system-fastlz, whether to use system FastLZ library, +[ --with-system-fastlz Use system FastLZ library], no, no) if test -z "$PHP_ZLIB_DIR"; then PHP_ARG_WITH(zlib-dir, for ZLIB, From 809e4b078a6a4d8fc683b1160f1ae6e6b43bd925 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 20 Nov 2017 22:43:00 -0600 Subject: [PATCH 061/218] Release notes for 3.0.4 --- ChangeLog | 11 +++++++++++ package.xml | 38 ++++++++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1db3dd44..5e406ee2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ memcached extension changelog +Version 3.0.4 (2017-11-20) +-------------------------- + + * Fix corrupted interned strings (#338) + * Fix unit tests for compatibility with PHP 7.2 (#358, #359) + * Fix \x0a in key name locks up connection and triggers a fatal timeout error (#339) + * Fix missing optional parameter getStats($type) (#337) + * Fix typo in skip message (#331) + * Fix build warnings (#329) + * Document GET_EXTENDED flag, add/rename other missing/misnamed constants (#335) + Version 3.0.3 (2017-02-19) -------------------------- diff --git a/package.xml b/package.xml index 5e1961f7..bbdaae81 100644 --- a/package.xml +++ b/package.xml @@ -27,9 +27,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> aaron@serendipity.cx yes - 2017-02-19 + 2017-11-20 - 3.0.3 + 3.0.4 3.0.0 @@ -38,13 +38,19 @@ http://pear.php.net/dtd/package-2.0.xsd"> PHP -PHP7 release of memcached extension. Note that support for libmemcached 0.x series has been discontinued -and the oldest actively tested version is 1.0.2. It is highly recommended to use version 1.0.18 of +PHP 7.0 - 7.1 - 7.2 release of memcached extension. Note that support for +libmemcached 0.x series has been discontinued and the oldest actively tested +version is 1.0.2. It is highly recommended to use version 1.0.18 of libmemcached. Fixes - * Fix crash when checking session data with older versions of libmemcached (#328) - * Fix crash due to zend_mm_corrupted when fetching session data (#327) + * Fix corrupted interned strings (#338) + * Fix unit tests for compatibility with PHP 7.2 (#358, #359) + * Fix \x0a in key name locks up connection and triggers a fatal timeout error (#339) + * Fix missing optional parameter getStats($type) (#337) + * Fix typo in skip message (#331) + * Fix build warnings (#329) + * Document GET_EXTENDED flag, add/rename other missing/misnamed constants (#335) @@ -191,6 +197,26 @@ Fixes + + + stable + stable + + + 3.0.3 + 3.0.0 + + 2017-02-19 + +PHP7 release of memcached extension. Note that support for libmemcached 0.x series has been discontinued +and the oldest actively tested version is 1.0.2. It is highly recommended to use version 1.0.18 of +libmemcached. + +Fixes + * Fix crash when checking session data with older versions of libmemcached (#328) + * Fix crash due to zend_mm_corrupted when fetching session data (#327) + + stable From 04e404631f4a94d825287cb92d55290395d77b73 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sun, 10 Dec 2017 01:21:51 -0800 Subject: [PATCH 062/218] Bump version to 3.1.0-dev --- php_memcached.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.h b/php_memcached.h index 65a0349f..5194c038 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -27,7 +27,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.0.3" +#define PHP_MEMCACHED_VERSION "3.1.0-dev" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 6767a79dc3f74e4a8bb214beaeccf0b2d769746b Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 19 Dec 2017 04:06:52 -0800 Subject: [PATCH 063/218] Supports PHP 7.0 - 7.2 --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index f145c2df..19a8ab18 100644 --- a/README.markdown +++ b/README.markdown @@ -23,7 +23,7 @@ Dependencies ------------ php-memcached 3.x: -* Supports PHP 7.0 - 7.1. +* Supports PHP 7.0 - 7.2. * Requires libmemcached 1.x or higher. * Optionally supports igbinary 2.0 or higher. * Optionally supports msgpack 2.0 or higher. From c65cc1c2661e4bc529761bcc033247446b869f2c Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 18 Jan 2018 12:36:04 -0800 Subject: [PATCH 064/218] Fix session persistence by checking memcached behavior values before setting (#379) --- php_memcached_session.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/php_memcached_session.c b/php_memcached_session.c index ab3e7222..d8e9be62 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -186,12 +186,15 @@ void s_unlock_session(memcached_st *memc) static zend_bool s_configure_from_ini_values(memcached_st *memc, zend_bool silent) { - memcached_return rc; - #define check_set_behavior(behavior, value) \ - if ((rc = memcached_behavior_set(memc, (behavior), (value))) != MEMCACHED_SUCCESS) { \ - if (!silent) { php_error_docref(NULL, E_WARNING, "failed to initialise session memcached configuration: %s", memcached_strerror(memc, rc)); } \ - return 0; \ + if ((value) != memcached_behavior_get(memc, (behavior))) { \ + memcached_return rc; \ + if ((rc = memcached_behavior_set(memc, (behavior), (value))) != MEMCACHED_SUCCESS) { \ + if (!silent) { \ + php_error_docref(NULL, E_WARNING, "failed to initialise session memcached configuration: %s", memcached_strerror(memc, rc)); \ + } \ + return 0; \ + } \ } if (MEMC_SESS_INI(binary_protocol_enabled)) { @@ -243,7 +246,7 @@ zend_bool s_configure_from_ini_values(memcached_st *memc, zend_bool silent) user_data->has_sasl_data = 1; } -#undef safe_set_behavior +#undef check_set_behavior return 1; } From 7ed5b38a3e0fb8ad490c095da9c659b50d7a0ebd Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 18 Jan 2018 19:21:41 -0800 Subject: [PATCH 065/218] Removed ifdef 0 code and trivial block cleanup --- php_memcached.c | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 952b582c..cc6456be 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -228,7 +228,6 @@ zend_bool s_memc_valid_key_ascii(zend_string *key) } #ifdef HAVE_MEMCACHED_PROTOCOL - typedef struct { php_memc_proto_handler_t *handler; zend_object zo; @@ -1235,34 +1234,25 @@ static PHP_METHOD(Memcached, __construct) memcached_set_user_data(intern->memc, memc_user_data); /* Set default behaviors */ - { -#ifdef mikko_0 - fprintf (stderr, "consistent_hash_enabled=%d binary_protocol_enabled=%d connect_timeout=%ld\n", - MEMC_G(default_behavior.consistent_hash_enabled), MEMC_G(default_behavior.binary_protocol_enabled), MEMC_G(default_behavior.connect_timeout)); -#endif - - memcached_return rc; + if (MEMC_G(default_behavior.consistent_hash_enabled)) { - if (MEMC_G(default_behavior.consistent_hash_enabled)) { - - rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT); - if (rc != MEMCACHED_SUCCESS) { - php_error_docref(NULL, E_WARNING, "Failed to turn on consistent hash: %s", memcached_strerror(intern->memc, rc)); - } + memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT); + if (rc != MEMCACHED_SUCCESS) { + php_error_docref(NULL, E_WARNING, "Failed to turn on consistent hash: %s", memcached_strerror(intern->memc, rc)); } + } - if (MEMC_G(default_behavior.binary_protocol_enabled)) { - rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); - if (rc != MEMCACHED_SUCCESS) { - php_error_docref(NULL, E_WARNING, "Failed to turn on binary protocol: %s", memcached_strerror(intern->memc, rc)); - } + if (MEMC_G(default_behavior.binary_protocol_enabled)) { + memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); + if (rc != MEMCACHED_SUCCESS) { + php_error_docref(NULL, E_WARNING, "Failed to turn on binary protocol: %s", memcached_strerror(intern->memc, rc)); } + } - if (MEMC_G(default_behavior.connect_timeout)) { - rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, MEMC_G(default_behavior.connect_timeout)); - if (rc != MEMCACHED_SUCCESS) { - php_error_docref(NULL, E_WARNING, "Failed to set connect timeout: %s", memcached_strerror(intern->memc, rc)); - } + if (MEMC_G(default_behavior.connect_timeout)) { + memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_CONNECT_TIMEOUT, MEMC_G(default_behavior.connect_timeout)); + if (rc != MEMCACHED_SUCCESS) { + php_error_docref(NULL, E_WARNING, "Failed to set connect timeout: %s", memcached_strerror(intern->memc, rc)); } } From e622992e6f6d7c3098eb3c42c1b5f80d9cdf1c6a Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 18 Jan 2018 23:58:19 -0800 Subject: [PATCH 066/218] The configure script warns if libmemcached needs sasl.h if sasl.h cannot be found (#380) --- config.m4 | 65 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/config.m4 b/config.m4 index 705f4957..7a4a6c9f 100644 --- a/config.m4 +++ b/config.m4 @@ -184,7 +184,7 @@ if test "$PHP_MEMCACHED" != "no"; then else AC_MSG_RESULT([$msgpack_inc_path]) fi - fi + fi AC_MSG_CHECKING([for memcached session support]) if test "$PHP_MEMCACHED_SESSION" != "no"; then @@ -255,42 +255,45 @@ if test "$PHP_MEMCACHED" != "no"; then PHP_EVAL_LIBLINE($PHP_LIBMEMCACHED_LIBS, MEMCACHED_SHARED_LIBADD) PHP_EVAL_INCLINE($PHP_LIBMEMCACHED_INCLUDES) - # - # Added -lpthread here because AC_TRY_LINK tests on CentOS 6 seem to fail with undefined reference to pthread_once - # + dnl # Added -lpthread here because AC_TRY_LINK tests on CentOS 6 seem to fail with undefined reference to pthread_once ORIG_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $INCLUDES" + dnl # Always check if libmemcached was built with SASL support, + dnl # because it will require sasl.h even if not used here. + AC_CACHE_CHECK([for libmemcached sasl.h requirement], ac_cv_memc_sasl_support, [ + AC_TRY_COMPILE( + [ #include ], + [ + #if LIBMEMCACHED_WITH_SASL_SUPPORT + /* yes */ + #else + # error "no sasl support" + #endif + ], + [ ac_cv_memc_sasl_support="yes" ], + [ ac_cv_memc_sasl_support="no" ] + ) + ]) + + if test "$ac_cv_memc_sasl_support" = "yes"; then + AC_CHECK_HEADERS([sasl/sasl.h], [ac_cv_have_memc_sasl_h="yes"], [ac_cv_have_memc_sasl_h="no"]) + fi + + dnl # If libmemcached requires sasl.h but we can't find sasl.h, that's a hard error + dnl # regardless of the option --enable-memcached-sasl or --disable-memcached-sasl AC_MSG_CHECKING([whether to enable sasl support]) + if test "$ac_cv_memc_sasl_support" = "yes" && test "$ac_cv_have_memc_sasl_h" = "no"; then + AC_MSG_ERROR([no, libmemcached built with sasl required, but sasl.h not found.]) + fi + if test "$PHP_MEMCACHED_SASL" != "no"; then AC_MSG_RESULT(yes) - AC_CHECK_HEADERS([sasl/sasl.h], [ac_cv_have_memc_sasl_h="yes"], [ac_cv_have_memc_sasl_h="no"]) - - if test "$ac_cv_have_memc_sasl_h" = "yes"; then - - AC_CACHE_CHECK([whether libmemcached supports sasl], ac_cv_memc_sasl_support, [ - AC_TRY_COMPILE( - [ #include ], - [ - #if LIBMEMCACHED_WITH_SASL_SUPPORT - /* yes */ - #else - # error "no sasl support" - #endif - ], - [ ac_cv_memc_sasl_support="yes" ], - [ ac_cv_memc_sasl_support="no" ] - ) - ]) - - if test "$ac_cv_memc_sasl_support" = "yes"; then - PHP_CHECK_LIBRARY(sasl2, sasl_client_init, [PHP_ADD_LIBRARY(sasl2, 1, MEMCACHED_SHARED_LIBADD)]) - AC_DEFINE(HAVE_MEMCACHED_SASL, 1, [Have SASL support]) - else - AC_MSG_ERROR([no, libmemcached sasl support is not enabled. Run configure with --disable-memcached-sasl to disable this check]) - fi + if test "$ac_cv_memc_sasl_support" = "yes" && test "$ac_cv_have_memc_sasl_h" = "yes"; then + PHP_CHECK_LIBRARY(sasl2, sasl_client_init, [PHP_ADD_LIBRARY(sasl2, 1, MEMCACHED_SHARED_LIBADD)]) + AC_DEFINE(HAVE_MEMCACHED_SASL, 1, [Have SASL support]) else - AC_MSG_ERROR([no, sasl.h is not available. Run configure with --disable-memcached-sasl to disable this check]) + AC_MSG_ERROR([no, libmemcached built with sasl disabled. Run configure with --disable-memcached-sasl or update libmemcached with sasl support]) fi else AC_MSG_RESULT([no]) @@ -298,7 +301,7 @@ if test "$PHP_MEMCACHED" != "no"; then ORIG_CFLAGS="$CFLAGS" ORIG_LIBS="$LIBS" - + CFLAGS="$CFLAGS $PHP_LIBMEMCACHED_INCLUDES" LIBS="$LIBS $PHP_LIBMEMCACHED_LIBS" From 5c6de2b0e4096211d56f11131acb5d5bdc794190 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sat, 20 Jan 2018 08:04:40 -0800 Subject: [PATCH 067/218] Add support for libmemcached encryption (#381) This feature is fully supported in libmemcached 1.0.18 and higher, but has a notable bug in the original implementation in libmemcached versions 1.0.6 - 1.0.17 that the encryption key, once set, cannot be changed otherwise all further get/set operations fail. --- config.m4 | 19 ++++++++++++ memcached-api.php | 4 +++ package.xml | 2 ++ php_memcached.c | 56 ++++++++++++++++++++++++++++++++++ tests/set_encoding_key.phpt | 59 ++++++++++++++++++++++++++++++++++++ tests/set_encoding_key2.phpt | 37 ++++++++++++++++++++++ 6 files changed, 177 insertions(+) create mode 100644 tests/set_encoding_key.phpt create mode 100644 tests/set_encoding_key2.phpt diff --git a/config.m4 b/config.m4 index 7a4a6c9f..d38d5dc4 100644 --- a/config.m4 +++ b/config.m4 @@ -317,10 +317,29 @@ if test "$PHP_MEMCACHED" != "no"; then CFLAGS="$ORIG_CFLAGS" LIBS="$ORIG_LIBS" + CFLAGS="$CFLAGS $PHP_LIBMEMCACHED_INCLUDES" + LIBS="$LIBS $PHP_LIBMEMCACHED_LIBS" + if test "$ac_cv_have_memcached_exist" = "yes"; then AC_DEFINE(HAVE_MEMCACHED_EXIST, [1], [Whether memcached_exist is defined]) fi + AC_CACHE_CHECK([whether memcached_set_encoding_key is defined], ac_cv_have_memcached_set_encoding_key, [ + AC_TRY_LINK( + [ #include ], + [ memcached_set_encoding_key (NULL, NULL, 0); ], + [ ac_cv_have_memcached_set_encoding_key="yes" ], + [ ac_cv_have_memcached_set_encoding_key="no" ] + ) + ]) + + CFLAGS="$ORIG_CFLAGS" + LIBS="$ORIG_LIBS" + + if test "$ac_cv_have_memcached_set_encoding_key" = "yes"; then + AC_DEFINE(HAVE_MEMCACHED_SET_ENCODING_KEY, [1], [Whether memcached_set_encoding_key is defined]) + fi + PHP_MEMCACHED_FILES="php_memcached.c php_libmemcached_compat.c g_fmt.c" if test "$PHP_SYSTEM_FASTLZ" != "no"; then diff --git a/memcached-api.php b/memcached-api.php index f5174e22..8ab03d4c 100644 --- a/memcached-api.php +++ b/memcached-api.php @@ -96,6 +96,8 @@ class Memcached { const HAVE_MSGPACK; + const HAVE_ENCODING; + /** * Feature support */ @@ -363,6 +365,8 @@ public function isPristine( ) {} public function setSaslAuthData( $username, $password ) {} + public function setEncodingKey( $key ) {} + } class MemcachedException extends Exception { diff --git a/package.xml b/package.xml index bbdaae81..a8ece289 100644 --- a/package.xml +++ b/package.xml @@ -159,6 +159,8 @@ Fixes + + diff --git a/php_memcached.c b/php_memcached.c index cc6456be..ec76f9bb 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -142,6 +142,7 @@ typedef struct { zend_bool is_persistent; zend_bool compression_enabled; + zend_bool encoding_enabled; zend_long serializer; zend_long compression_type; @@ -1227,6 +1228,7 @@ static PHP_METHOD(Memcached, __construct) memc_user_data->serializer = MEMC_G(serializer_type); memc_user_data->compression_type = MEMC_G(compression_type); memc_user_data->compression_enabled = 1; + memc_user_data->encoding_enabled = 0; memc_user_data->store_retry_count = MEMC_G(store_retry_count); memc_user_data->set_udf_flags = -1; memc_user_data->is_persistent = is_persistent; @@ -3265,6 +3267,42 @@ static PHP_METHOD(Memcached, setSaslAuthData) /* }}} */ #endif /* HAVE_MEMCACHED_SASL */ +#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY +/* {{{ Memcached::setEncodingKey(string key) + Sets AES encryption key (libmemcached 1.0.6 and higher) */ +static PHP_METHOD(Memcached, setEncodingKey) +{ + MEMC_METHOD_INIT_VARS; + memcached_return status; + zend_string *key; + + /* "S" */ + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(key) + ZEND_PARSE_PARAMETERS_END(); + + MEMC_METHOD_FETCH_OBJECT; + + // libmemcached < 1.0.18 cannot handle a change of encoding key. Warn about this and return false. +#if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 + if (memc_user_data->encoding_enabled) { + php_error_docref(NULL, E_WARNING, "libmemcached versions less than 1.0.18 cannot change encoding key"); + RETURN_FALSE; + } +#endif + + status = memcached_set_encoding_key(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key)); + + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { + RETURN_FALSE; + } + + memc_user_data->encoding_enabled = 1; + RETURN_TRUE; +} +/* }}} */ +#endif /* HAVE_MEMCACHED_SET_ENCODING_KEY */ + /* {{{ Memcached::getResultCode() Returns the result code from the last operation */ static PHP_METHOD(Memcached, getResultCode) @@ -4034,6 +4072,12 @@ ZEND_BEGIN_ARG_INFO(arginfo_setSaslAuthData, 0) ZEND_END_ARG_INFO() #endif +#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY +ZEND_BEGIN_ARG_INFO(arginfo_setEncodingKey, 0) + ZEND_ARG_INFO(0, key) +ZEND_END_ARG_INFO() +#endif + ZEND_BEGIN_ARG_INFO(arginfo_setOption, 0) ZEND_ARG_INFO(0, option) ZEND_ARG_INFO(0, value) @@ -4133,6 +4177,9 @@ static zend_function_entry memcached_class_methods[] = { MEMC_ME(setBucket, arginfo_setBucket) #ifdef HAVE_MEMCACHED_SASL MEMC_ME(setSaslAuthData, arginfo_setSaslAuthData) +#endif +#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY + MEMC_ME(setEncodingKey, arginfo_setEncodingKey) #endif MEMC_ME(isPersistent, arginfo_isPersistent) MEMC_ME(isPristine, arginfo_isPristine) @@ -4282,6 +4329,15 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_MSGPACK, 0); #endif + /* + * Indicate whether set_encoding_key is available + */ +#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_ENCODING, 1); +#else + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_ENCODING, 0); +#endif + #ifdef HAVE_MEMCACHED_SESSION REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_SESSION, 1); #else diff --git a/tests/set_encoding_key.phpt b/tests/set_encoding_key.phpt new file mode 100644 index 00000000..72d96daa --- /dev/null +++ b/tests/set_encoding_key.phpt @@ -0,0 +1,59 @@ +--TEST-- +Test libmemcached encryption +--SKIPIF-- + +--FILE-- +setEncodingKey("Hello")); +var_dump ($m->set ($key, 'set using encoding')); +var_dump ($m->get ($key)); + +echo "OK" . PHP_EOL; + +# Change the encryption key. The old value will be inaccessible. +var_dump ($m->setEncodingKey("World")); +var_dump ($m->get ($key)); + +echo "OK" . PHP_EOL; + +# Restore the original key to retrieve old values again. +var_dump ($m->setEncodingKey("Hello")); +var_dump ($m->get ($key)); + +echo "OK" . PHP_EOL; + +# With a new encoding key we can still write new values, +# this works as expected with libmemcached 1.0.18 and higher. +var_dump ($m->setEncodingKey("World")); +var_dump ($m->get ($key)); +var_dump ($m->set ($key, 'set using encoding')); +var_dump ($m->get ($key)); + +echo "OK" . PHP_EOL; + +?> +--EXPECT-- +bool(true) +bool(true) +string(18) "set using encoding" +OK +bool(true) +bool(false) +OK +bool(true) +string(18) "set using encoding" +OK +bool(true) +bool(false) +bool(true) +string(18) "set using encoding" +OK diff --git a/tests/set_encoding_key2.phpt b/tests/set_encoding_key2.phpt new file mode 100644 index 00000000..f8d21a16 --- /dev/null +++ b/tests/set_encoding_key2.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test libmemcached encryption +--SKIPIF-- += 0x01000018) die ("skip test for libmemcached lower than 1.0.18"); +?> +--FILE-- +setEncodingKey("Hello")); +var_dump ($m->set ($key, 'set using encoding')); +var_dump ($m->get ($key)); + +echo "OK" . PHP_EOL; + +# libmemcached < 1.0.18 goes into a bad state when the encoding key is changed, +# so php-memcached warns and returns false when trying to change the key. +var_dump ($m->setEncodingKey("World")); + +echo "OK" . PHP_EOL; + +?> +--EXPECTF-- +bool(true) +bool(true) +string(18) "set using encoding" +OK + +Warning: Memcached::setEncodingKey(): libmemcached versions less than 1.0.18 cannot change encoding key in %s on line %d +bool(false) +OK From 2fc7d3659c127eaabc0458e46e7118bcd721f92c Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sun, 21 Jan 2018 21:46:56 -0800 Subject: [PATCH 068/218] Fix wrong INI parsing method for memcached.sess_randomize_replica_read --- php_memcached.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index ec76f9bb..8a5afa57 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -346,7 +346,7 @@ PHP_INI_BEGIN() #endif MEMC_SESSION_INI_ENTRY("consistent_hash", "1", OnUpdateBool, consistent_hash_enabled) MEMC_SESSION_INI_ENTRY("number_of_replicas", "0", OnUpdateLongGEZero, number_of_replicas) - MEMC_SESSION_INI_ENTRY("randomize_replica_read", "0", OnUpdateLongGEZero, randomize_replica_read_enabled) + MEMC_SESSION_INI_ENTRY("randomize_replica_read", "0", OnUpdateBool, randomize_replica_read_enabled) MEMC_SESSION_INI_ENTRY("remove_failed_servers", "0", OnUpdateBool, remove_failed_servers_enabled) MEMC_SESSION_INI_ENTRY("server_failure_limit", "0", OnUpdateLongGEZero, server_failure_limit) MEMC_SESSION_INI_ENTRY("connect_timeout", "0", OnUpdateLongGEZero, connect_timeout) From deb451ae9e519b326becfe51f4097918684d9003 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sun, 21 Jan 2018 21:47:48 -0800 Subject: [PATCH 069/218] Fix wrong undefs of local macros for registering constants --- php_memcached.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 8a5afa57..6a03b0c3 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -4514,12 +4514,15 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) REGISTER_MEMC_CLASS_CONST_LONG(RESPONSE_ETMPFAIL, PROTOCOL_BINARY_RESPONSE_ETMPFAIL); #endif - #undef REGISTER_MEMC_CLASS_CONST_LONG - /* * Return value from simple get errors */ REGISTER_MEMC_CLASS_CONST_BOOL(GET_ERROR_RETURN_VALUE, 0); + + #undef REGISTER_MEMC_CLASS_CONST_LONG + #undef REGISTER_MEMC_CLASS_CONST_BOOL + #undef REGISTER_MEMC_CLASS_CONST_NULL + } /* }}} */ From f54ed299c0220a0a308b346e53944a35247e4efa Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 23 Jan 2018 03:32:07 -0800 Subject: [PATCH 070/218] Use STD_PHP_INI_BOOLEAN to correctly display php.ini booleans --- php_memcached.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 6a03b0c3..495cfd1e 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -326,34 +326,40 @@ PHP_INI_MH(OnUpdateSessionPrefixString) #define MEMC_INI_ENTRY(key, default_value, update_fn, gkey) \ STD_PHP_INI_ENTRY("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals) +#define MEMC_INI_BOOL(key, default_value, update_fn, gkey) \ + STD_PHP_INI_BOOLEAN("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals) + #define MEMC_SESSION_INI_ENTRY(key, default_value, update_fn, gkey) \ STD_PHP_INI_ENTRY("memcached.sess_"key, default_value, PHP_INI_ALL, update_fn, session.gkey, zend_php_memcached_globals, php_memcached_globals) +#define MEMC_SESSION_INI_BOOL(key, default_value, update_fn, gkey) \ + STD_PHP_INI_BOOLEAN("memcached.sess_"key, default_value, PHP_INI_ALL, update_fn, session.gkey, zend_php_memcached_globals, php_memcached_globals) + /* {{{ INI entries */ PHP_INI_BEGIN() #ifdef HAVE_MEMCACHED_SESSION - MEMC_SESSION_INI_ENTRY("locking", "1", OnUpdateBool, lock_enabled) + MEMC_SESSION_INI_BOOL ("locking", "1", OnUpdateBool, lock_enabled) MEMC_SESSION_INI_ENTRY("lock_wait_min", "1000", OnUpdateLongGEZero, lock_wait_min) MEMC_SESSION_INI_ENTRY("lock_wait_max", "2000", OnUpdateLongGEZero, lock_wait_max) MEMC_SESSION_INI_ENTRY("lock_retries", "5", OnUpdateLong, lock_retries) MEMC_SESSION_INI_ENTRY("lock_expire", "0", OnUpdateLongGEZero, lock_expiration) #if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 - MEMC_SESSION_INI_ENTRY("binary_protocol", "0", OnUpdateBool, binary_protocol_enabled) + MEMC_SESSION_INI_BOOL ("binary_protocol", "0", OnUpdateBool, binary_protocol_enabled) #else - MEMC_SESSION_INI_ENTRY("binary_protocol", "1", OnUpdateBool, binary_protocol_enabled) + MEMC_SESSION_INI_BOOL ("binary_protocol", "1", OnUpdateBool, binary_protocol_enabled) #endif - MEMC_SESSION_INI_ENTRY("consistent_hash", "1", OnUpdateBool, consistent_hash_enabled) + MEMC_SESSION_INI_BOOL ("consistent_hash", "1", OnUpdateBool, consistent_hash_enabled) MEMC_SESSION_INI_ENTRY("number_of_replicas", "0", OnUpdateLongGEZero, number_of_replicas) - MEMC_SESSION_INI_ENTRY("randomize_replica_read", "0", OnUpdateBool, randomize_replica_read_enabled) - MEMC_SESSION_INI_ENTRY("remove_failed_servers", "0", OnUpdateBool, remove_failed_servers_enabled) + MEMC_SESSION_INI_BOOL ("randomize_replica_read", "0", OnUpdateBool, randomize_replica_read_enabled) + MEMC_SESSION_INI_BOOL ("remove_failed_servers", "0", OnUpdateBool, remove_failed_servers_enabled) MEMC_SESSION_INI_ENTRY("server_failure_limit", "0", OnUpdateLongGEZero, server_failure_limit) MEMC_SESSION_INI_ENTRY("connect_timeout", "0", OnUpdateLongGEZero, connect_timeout) MEMC_SESSION_INI_ENTRY("sasl_username", "", OnUpdateString, sasl_username) MEMC_SESSION_INI_ENTRY("sasl_password", "", OnUpdateString, sasl_password) + MEMC_SESSION_INI_BOOL ("persistent", "0", OnUpdateBool, persistent_enabled) MEMC_SESSION_INI_ENTRY("prefix", "memc.sess.key.", OnUpdateSessionPrefixString, prefix) - MEMC_SESSION_INI_ENTRY("persistent", "0", OnUpdateBool, persistent_enabled) /* Deprecated */ STD_PHP_INI_ENTRY("memcached.sess_lock_wait", "not set", PHP_INI_ALL, OnUpdateDeprecatedLockValue, no_effect, zend_php_memcached_globals, php_memcached_globals) @@ -367,14 +373,16 @@ PHP_INI_BEGIN() MEMC_INI_ENTRY("serializer", SERIALIZER_DEFAULT_NAME, OnUpdateSerializer, serializer_name) MEMC_INI_ENTRY("store_retry_count", "2", OnUpdateLong, store_retry_count) - MEMC_INI_ENTRY("default_consistent_hash", "0", OnUpdateBool, default_behavior.consistent_hash_enabled) - MEMC_INI_ENTRY("default_binary_protocol", "0", OnUpdateBool, default_behavior.binary_protocol_enabled) + MEMC_INI_BOOL ("default_consistent_hash", "0", OnUpdateBool, default_behavior.consistent_hash_enabled) + MEMC_INI_BOOL ("default_binary_protocol", "0", OnUpdateBool, default_behavior.binary_protocol_enabled) MEMC_INI_ENTRY("default_connect_timeout", "0", OnUpdateLongGEZero, default_behavior.connect_timeout) PHP_INI_END() /* }}} */ +#undef MEMC_INI_BOOL #undef MEMC_INI_ENTRY +#undef MEMC_SESSION_INI_BOOL #undef MEMC_SESSION_INI_ENTRY /**************************************** From 2c693c7a9b8239ccc73d6c8ae8f95f21ae282b5e Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 23 Jan 2018 03:52:34 -0800 Subject: [PATCH 071/218] Allow connect_timeout value of -1 and show Unlimited in phpinfo() --- php_memcached.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 495cfd1e..1d015ccc 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -329,12 +329,18 @@ PHP_INI_MH(OnUpdateSessionPrefixString) #define MEMC_INI_BOOL(key, default_value, update_fn, gkey) \ STD_PHP_INI_BOOLEAN("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals) +#define MEMC_INI_LINK(key, default_value, update_fn, gkey) \ + STD_PHP_INI_ENTRY_EX("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals, display_link_numbers) + #define MEMC_SESSION_INI_ENTRY(key, default_value, update_fn, gkey) \ STD_PHP_INI_ENTRY("memcached.sess_"key, default_value, PHP_INI_ALL, update_fn, session.gkey, zend_php_memcached_globals, php_memcached_globals) #define MEMC_SESSION_INI_BOOL(key, default_value, update_fn, gkey) \ STD_PHP_INI_BOOLEAN("memcached.sess_"key, default_value, PHP_INI_ALL, update_fn, session.gkey, zend_php_memcached_globals, php_memcached_globals) +#define MEMC_SESSION_INI_LINK(key, default_value, update_fn, gkey) \ + STD_PHP_INI_ENTRY_EX("memcached.sess_"key, default_value, PHP_INI_ALL, update_fn, session.gkey, zend_php_memcached_globals, php_memcached_globals, display_link_numbers) + /* {{{ INI entries */ PHP_INI_BEGIN() @@ -355,7 +361,8 @@ PHP_INI_BEGIN() MEMC_SESSION_INI_BOOL ("randomize_replica_read", "0", OnUpdateBool, randomize_replica_read_enabled) MEMC_SESSION_INI_BOOL ("remove_failed_servers", "0", OnUpdateBool, remove_failed_servers_enabled) MEMC_SESSION_INI_ENTRY("server_failure_limit", "0", OnUpdateLongGEZero, server_failure_limit) - MEMC_SESSION_INI_ENTRY("connect_timeout", "0", OnUpdateLongGEZero, connect_timeout) + MEMC_SESSION_INI_LINK ("connect_timeout", "0", OnUpdateLong, connect_timeout) + MEMC_SESSION_INI_ENTRY("sasl_username", "", OnUpdateString, sasl_username) MEMC_SESSION_INI_ENTRY("sasl_password", "", OnUpdateString, sasl_password) MEMC_SESSION_INI_BOOL ("persistent", "0", OnUpdateBool, persistent_enabled) @@ -375,14 +382,16 @@ PHP_INI_BEGIN() MEMC_INI_BOOL ("default_consistent_hash", "0", OnUpdateBool, default_behavior.consistent_hash_enabled) MEMC_INI_BOOL ("default_binary_protocol", "0", OnUpdateBool, default_behavior.binary_protocol_enabled) - MEMC_INI_ENTRY("default_connect_timeout", "0", OnUpdateLongGEZero, default_behavior.connect_timeout) + MEMC_INI_LINK ("default_connect_timeout", "0", OnUpdateLong, default_behavior.connect_timeout) PHP_INI_END() /* }}} */ #undef MEMC_INI_BOOL +#undef MEMC_INI_LINK #undef MEMC_INI_ENTRY #undef MEMC_SESSION_INI_BOOL +#undef MEMC_SESSION_INI_LINK #undef MEMC_SESSION_INI_ENTRY /**************************************** From dfcbc02693d49fa8708f6282776f7af4a884d904 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 23 Jan 2018 04:13:27 -0800 Subject: [PATCH 072/218] Remove memcached.ini reference to deprecated sess_lock_max_wait setting --- memcached.ini | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/memcached.ini b/memcached.ini index 6d05da3c..e4256c10 100644 --- a/memcached.ini +++ b/memcached.ini @@ -20,8 +20,7 @@ ; The time, in seconds, before a lock should release itself. ; Setting to 0 results in the default behaviour, which is to -; use the memcached.sess_lock_max_wait setting. If that is -; also 0, max_execution_time will be used. +; use PHP's max_execution_time. ;memcached.sess_lock_expire = 0; ; memcached session key prefix From e0ccf87c517bc3ec54067166d34058f21d67b0b3 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 23 Jan 2018 06:21:40 -0800 Subject: [PATCH 073/218] Avoid hanging getStats() when binary protocol and non-blocking are both enabled Fixes #348. --- package.xml | 1 + php_memcached.c | 12 ++++++ tests/stats_hang.phpt | 89 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 tests/stats_hang.phpt diff --git a/package.xml b/package.xml index a8ece289..c0e8e09d 100644 --- a/package.xml +++ b/package.xml @@ -168,6 +168,7 @@ Fixes + diff --git a/php_memcached.c b/php_memcached.c index 1d015ccc..a42ff195 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -2757,6 +2757,7 @@ PHP_METHOD(Memcached, getStats) memcached_return status; char *args = NULL; zend_string *args_string = NULL; + uint64_t orig_no_block, orig_protocol; MEMC_METHOD_INIT_VARS; /* "|S!" */ @@ -2770,8 +2771,19 @@ PHP_METHOD(Memcached, getStats) if (args_string) args = ZSTR_VAL(args_string); + /* stats hangs in nonblocking mode, turn off during the call. Only change the + * value if needed, because libmemcached reconnects for this behavior_set. */ + orig_no_block = memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_NO_BLOCK); + orig_protocol = memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL); + if (orig_no_block && orig_protocol) + memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_NO_BLOCK, 0); + array_init(return_value); status = memcached_stat_execute(intern->memc, args, s_stat_execute_cb, return_value); + + if (orig_no_block && orig_protocol) + memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_NO_BLOCK, orig_no_block); + if (s_memc_status_handle_result_code(intern, status) == FAILURE) { zval_ptr_dtor(return_value); RETURN_FALSE; diff --git a/tests/stats_hang.phpt b/tests/stats_hang.phpt new file mode 100644 index 00000000..181e15e0 --- /dev/null +++ b/tests/stats_hang.phpt @@ -0,0 +1,89 @@ +--TEST-- +Check stats does not hang on non-blocking binary protocol +--SKIPIF-- + +--FILE-- +setOption(Memcached::OPT_NO_BLOCK, true); +$m->setOption(Memcached::OPT_BINARY_PROTOCOL, true); + +$stats = $m->getStats(); +$conns1 = $stats[$key]['total_connections']; + +$stats = $m->getStats(); +$conns2 = $stats[$key]['total_connections']; + +var_dump($conns1 == $conns2); +var_dump($m->getOption(Memcached::OPT_NO_BLOCK)); +var_dump($m->getOption(Memcached::OPT_BINARY_PROTOCOL)); +echo "OK" . PHP_EOL; + +// If either or both options are false no need to reconnect +$m->setOption(Memcached::OPT_NO_BLOCK, false); +$m->setOption(Memcached::OPT_BINARY_PROTOCOL, true); + +$stats = $m->getStats(); +$conns1 = $stats[$key]['total_connections']; + +$stats = $m->getStats(); +$conns2 = $stats[$key]['total_connections']; + +var_dump($conns1 == $conns2); +var_dump($m->getOption(Memcached::OPT_NO_BLOCK)); +var_dump($m->getOption(Memcached::OPT_BINARY_PROTOCOL)); +echo "OK" . PHP_EOL; + +// If either or both options are false no need to reconnect +$m->setOption(Memcached::OPT_NO_BLOCK, true); +$m->setOption(Memcached::OPT_BINARY_PROTOCOL, false); + +$stats = $m->getStats(); +$conns1 = $stats[$key]['total_connections']; + +$stats = $m->getStats(); +$conns2 = $stats[$key]['total_connections']; + +var_dump($conns1 == $conns2); +var_dump($m->getOption(Memcached::OPT_NO_BLOCK)); +var_dump($m->getOption(Memcached::OPT_BINARY_PROTOCOL)); +echo "OK" . PHP_EOL; + +// If either or both options are false no need to reconnect +$m->setOption(Memcached::OPT_NO_BLOCK, false); +$m->setOption(Memcached::OPT_BINARY_PROTOCOL, false); + +$stats = $m->getStats(); +$conns1 = $stats[$key]['total_connections']; + +$stats = $m->getStats(); +$conns2 = $stats[$key]['total_connections']; + +var_dump($conns1 == $conns2); +var_dump($m->getOption(Memcached::OPT_NO_BLOCK)); +var_dump($m->getOption(Memcached::OPT_BINARY_PROTOCOL)); +echo "OK" . PHP_EOL; + +?> +--EXPECT-- +bool(false) +int(1) +int(1) +OK +bool(true) +int(0) +int(1) +OK +bool(true) +int(1) +int(0) +OK +bool(true) +int(0) +int(0) +OK From 8bfdbcc9063dafcb25fdb1d1705e07ee027d7379 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 29 Mar 2018 23:26:46 -0700 Subject: [PATCH 074/218] Update for new PHP 7.3 REFCOUNT macros (#390) --- .travis.yml | 3 +++ php_memcached.c | 4 ++-- php_memcached_private.h | 7 +++++++ php_memcached_session.c | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d2457f55..26973f0a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,12 +3,15 @@ dist: trusty language: php php: + - master - 7.2 - 7.1 - 7.0 matrix: fast_finish: true + allow_failures: + - php: master env: - LIBMEMCACHED_VERSION=1.0.18 # Debian Jessie / Ubuntu Xenial diff --git a/php_memcached.c b/php_memcached.c index a42ff195..bd0f559e 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -1298,7 +1298,7 @@ static PHP_METHOD(Memcached, __construct) le.type = php_memc_list_entry(); le.ptr = intern->memc; - GC_REFCOUNT(&le) = 1; + GC_SET_REFCOUNT(&le, 1); /* plist_key is not a persistent allocated key, thus we use str_update here */ if (zend_hash_str_update_mem(&EG(persistent_list), ZSTR_VAL(plist_key), ZSTR_LEN(plist_key), &le, sizeof(le)) == NULL) { @@ -3831,7 +3831,7 @@ PHP_METHOD(MemcachedServer, on) Z_TRY_ADDREF(fci.function_name); if (fci.object) { - GC_REFCOUNT(fci.object)++; + GC_ADDREF(fci.object); } } RETURN_BOOL(rc); diff --git a/php_memcached_private.h b/php_memcached_private.h index a04e19be..abc0459c 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -72,6 +72,13 @@ typedef unsigned long int uint32_t; # endif #endif +/* Backwards compatibility for GC API change in PHP 7.3 */ +#if PHP_VERSION_ID < 70300 +# define GC_ADDREF(p) ++GC_REFCOUNT(p) +# define GC_DELREF(p) --GC_REFCOUNT(p) +# define GC_SET_REFCOUNT(p, rc) GC_REFCOUNT(p) = rc +#endif + /**************************************** Structures and definitions ****************************************/ diff --git a/php_memcached_session.c b/php_memcached_session.c index d8e9be62..607a02c2 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -376,7 +376,7 @@ PS_OPEN_FUNC(memcached) le.type = s_memc_sess_list_entry(); le.ptr = memc; - GC_REFCOUNT(&le) = 1; + GC_SET_REFCOUNT(&le, 1); /* plist_key is not a persistent allocated key, thus we use str_update here */ if (zend_hash_str_update_mem(&EG(persistent_list), plist_key, plist_key_len, &le, sizeof(le)) == NULL) { From 893d7d53062a0ff0a4112c22ce048db0b2afc67d Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 29 Mar 2018 23:42:08 -0700 Subject: [PATCH 075/218] Expose build configuration via PECL (#383) --- package.xml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/package.xml b/package.xml index c0e8e09d..0edfd3da 100644 --- a/package.xml +++ b/package.xml @@ -197,7 +197,15 @@ Fixes memcached - + + + + + + + + + From f4dafd207e4b3f1f54a7ce52194dda7cf40b0934 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sun, 8 Apr 2018 19:39:38 -0700 Subject: [PATCH 076/218] Add INI setting to choose session consistent hash (ketama or ketama_weighted) (#392) Provides a new INI option to select the same consistent hash behavior as older versions of php-memcached, to aid in migration from PHP 5.x to PHP 7.x. When `memcached_sess_consistent_hash_type` is set to `ketama` or `ketama_weighted`, that sets either MEMCACHED_BEHAVIOR_KETAMA or MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED, respectively. Resolves #344 --- memcached.ini | 7 +++++++ php_memcached.c | 20 +++++++++++++++++++- php_memcached.h | 8 -------- php_memcached_private.h | 15 +++++++++++++++ php_memcached_session.c | 16 +++++----------- 5 files changed, 46 insertions(+), 20 deletions(-) diff --git a/memcached.ini b/memcached.ini index e4256c10..138fd09a 100644 --- a/memcached.ini +++ b/memcached.ini @@ -43,6 +43,13 @@ ; default is On ;memcached.sess_consistent_hash = On +; memcached session consistent hash type +; if set to 'ketama', consistent hashing (libketama) is used +; for session handling (default for php-memcached 3.x) +; if set to 'ketama_weighted', weighted consistent hashing (libketama) is used +; for session handling (default for php-memcached 2.x) +;memcached.sess_consistent_hash_type = "ketama" + ; Allow failed memcached server to automatically be removed. ; Default is Off. (In previous versions, this setting was called memcached.sess_remove_failed) ;memcached.sess_remove_failed_servers = Off diff --git a/php_memcached.c b/php_memcached.c index bd0f559e..c24e58af 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -323,6 +323,22 @@ PHP_INI_MH(OnUpdateSessionPrefixString) return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } +static +PHP_INI_MH(OnUpdateConsistentHash) +{ + if (!new_value) { + MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA; + } else if (!strcmp(ZSTR_VAL(new_value), "ketama")) { + MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA; + } else if (!strcmp(ZSTR_VAL(new_value), "ketama_weighted")) { + MEMC_SESS_INI(consistent_hash_type) = MEMCACHED_BEHAVIOR_KETAMA_WEIGHTED; + } else { + php_error_docref(NULL, E_WARNING, "memcached.sess_consistent_hash_type must be ketama or ketama_weighted"); + return FAILURE; + } + return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); +} + #define MEMC_INI_ENTRY(key, default_value, update_fn, gkey) \ STD_PHP_INI_ENTRY("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals) @@ -357,6 +373,7 @@ PHP_INI_BEGIN() MEMC_SESSION_INI_BOOL ("binary_protocol", "1", OnUpdateBool, binary_protocol_enabled) #endif MEMC_SESSION_INI_BOOL ("consistent_hash", "1", OnUpdateBool, consistent_hash_enabled) + MEMC_SESSION_INI_ENTRY("consistent_hash_type", "ketama", OnUpdateConsistentHash, consistent_hash_name) MEMC_SESSION_INI_ENTRY("number_of_replicas", "0", OnUpdateLongGEZero, number_of_replicas) MEMC_SESSION_INI_BOOL ("randomize_replica_read", "0", OnUpdateBool, randomize_replica_read_enabled) MEMC_SESSION_INI_BOOL ("remove_failed_servers", "0", OnUpdateBool, remove_failed_servers_enabled) @@ -1254,7 +1271,6 @@ static PHP_METHOD(Memcached, __construct) /* Set default behaviors */ if (MEMC_G(default_behavior.consistent_hash_enabled)) { - memcached_return rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_DISTRIBUTION, MEMCACHED_DISTRIBUTION_CONSISTENT); if (rc != MEMCACHED_SUCCESS) { php_error_docref(NULL, E_WARNING, "Failed to turn on consistent hash: %s", memcached_strerror(intern->memc, rc)); @@ -4263,6 +4279,8 @@ PHP_GINIT_FUNCTION(php_memcached) php_memcached_globals->session.lock_expiration = 30; php_memcached_globals->session.binary_protocol_enabled = 1; php_memcached_globals->session.consistent_hash_enabled = 1; + php_memcached_globals->session.consistent_hash_type = MEMCACHED_BEHAVIOR_KETAMA; + php_memcached_globals->session.consistent_hash_name = NULL; php_memcached_globals->session.number_of_replicas = 0; php_memcached_globals->session.server_failure_limit = 1; php_memcached_globals->session.randomize_replica_read_enabled = 1; diff --git a/php_memcached.h b/php_memcached.h index 5194c038..a33f8be6 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -42,14 +42,6 @@ PHP_MEMCACHED_API zend_class_entry *php_memc_get_exception_base(int root); extern zend_module_entry memcached_module_entry; #define phpext_memcached_ptr &memcached_module_entry -#ifdef ZTS -#define MEMC_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, memc.v) -#define MEMC_SERVER_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, server.v) -#else -#define MEMC_G(v) (php_memcached_globals.memc.v) -#define MEMC_SERVER_G(v) (php_memcached_globals.server.v) -#endif - #endif /* PHP_MEMCACHED_H */ /* diff --git a/php_memcached_private.h b/php_memcached_private.h index abc0459c..cf652e39 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -156,6 +156,8 @@ ZEND_BEGIN_MODULE_GLOBALS(php_memcached) zend_bool binary_protocol_enabled; zend_bool consistent_hash_enabled; + char *consistent_hash_name; + int consistent_hash_type; zend_long server_failure_limit; zend_long number_of_replicas; @@ -207,6 +209,19 @@ ZEND_BEGIN_MODULE_GLOBALS(php_memcached) ZEND_END_MODULE_GLOBALS(php_memcached) +/* Globals accessor macros */ +#ifdef ZTS +# define MEMC_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, memc.v) +# define MEMC_SERVER_G(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, server.v) +# define MEMC_SESS_INI(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, session.v) +#else +# define MEMC_G(v) (php_memcached_globals.memc.v) +# define MEMC_SERVER_G(v) (php_memcached_globals.server.v) +# define MEMC_SESS_INI(v) (php_memcached_globals.session.v) +#endif + +#define MEMC_SESS_STR_INI(vv) ((MEMC_SESS_INI(vv) && *MEMC_SESS_INI(vv)) ? MEMC_SESS_INI(vv) : NULL) + PHP_RINIT_FUNCTION(memcached); PHP_RSHUTDOWN_FUNCTION(memcached); PHP_MINIT_FUNCTION(memcached); diff --git a/php_memcached_session.c b/php_memcached_session.c index 607a02c2..7d072af2 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -43,14 +43,6 @@ typedef struct { # define MAX(a,b) (((a)>(b))?(a):(b)) #endif -#ifdef ZTS -#define MEMC_SESS_INI(v) TSRMG(php_memcached_globals_id, zend_php_memcached_globals *, session.v) -#else -#define MEMC_SESS_INI(v) (php_memcached_globals.session.v) -#endif - -#define MEMC_SESS_STR_INI(vv) ((MEMC_SESS_INI(vv) && *MEMC_SESS_INI(vv)) ? MEMC_SESS_INI(vv) : NULL) - static int le_memc_sess; @@ -187,9 +179,11 @@ static zend_bool s_configure_from_ini_values(memcached_st *memc, zend_bool silent) { #define check_set_behavior(behavior, value) \ - if ((value) != memcached_behavior_get(memc, (behavior))) { \ + int b = (behavior); \ + uint64_t v = (value); \ + if (v != memcached_behavior_get(memc, b)) { \ memcached_return rc; \ - if ((rc = memcached_behavior_set(memc, (behavior), (value))) != MEMCACHED_SUCCESS) { \ + if ((rc = memcached_behavior_set(memc, b, v)) != MEMCACHED_SUCCESS) { \ if (!silent) { \ php_error_docref(NULL, E_WARNING, "failed to initialise session memcached configuration: %s", memcached_strerror(memc, rc)); \ } \ @@ -202,7 +196,7 @@ zend_bool s_configure_from_ini_values(memcached_st *memc, zend_bool silent) } if (MEMC_SESS_INI(consistent_hash_enabled)) { - check_set_behavior(MEMCACHED_BEHAVIOR_KETAMA, 1); + check_set_behavior(MEMC_SESS_INI(consistent_hash_type), 1); } if (MEMC_SESS_INI(server_failure_limit)) { From f5f84c592f8950ae150d7123704feb6a1258e3c5 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 30 Jun 2018 19:00:44 +0200 Subject: [PATCH 077/218] Remove unused Git attributes ident (#402) The $Id$ keywords were used in Subversion where they can be substituted with filename, last revision number change, last changed date, and last user who changed it. In Git this functionality is different and can be done with Git attribute ident. These need to be defined manually for each file in the .gitattributes file and are afterwards replaced with 40-character hexadecimal blob object name which is based only on the particular file contents. This patch simplifies handling of $Id$ keywords by removing them since they are not used anymore. --- config.m4 | 2 -- config.w32 | 1 - php_memcached.c | 2 -- php_memcached.h | 2 -- php_memcached_private.h | 2 -- 5 files changed, 9 deletions(-) diff --git a/config.m4 b/config.m4 index d38d5dc4..f086d492 100644 --- a/config.m4 +++ b/config.m4 @@ -1,5 +1,3 @@ -dnl -dnl $ Id: $ dnl vim:se ts=2 sw=2 et: PHP_ARG_ENABLE(memcached, whether to enable memcached support, diff --git a/config.w32 b/config.w32 index 380a9a12..e6e0c425 100644 --- a/config.w32 +++ b/config.w32 @@ -1,4 +1,3 @@ -// $ Id: $ // vim:ft=javascript ARG_WITH('memcached', 'libmemcached extension', 'no'); diff --git a/php_memcached.c b/php_memcached.c index c24e58af..01f98729 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -14,8 +14,6 @@ +----------------------------------------------------------------------+ */ -/* $ Id: $ */ - /* TODO * - set LIBKETAMA_COMPATIBLE as the default? * - fix unserialize(serialize($memc)) diff --git a/php_memcached.h b/php_memcached.h index a33f8be6..59989f5b 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -14,8 +14,6 @@ +----------------------------------------------------------------------+ */ -/* $ Id: $ */ - #ifndef PHP_MEMCACHED_H #define PHP_MEMCACHED_H diff --git a/php_memcached_private.h b/php_memcached_private.h index cf652e39..561812e5 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -14,8 +14,6 @@ +----------------------------------------------------------------------+ */ -/* $ Id: $ */ - #ifndef PHP_MEMCACHED_PRIVATE_H #define PHP_MEMCACHED_PRIVATE_H From c54075a1bf77188af172287395dee4b81bbafd74 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Mon, 2 Jul 2018 19:16:12 +0200 Subject: [PATCH 078/218] Remove .cvsignore unused file (#404) The .cvsignore file was used in CVS. In Git the .gitignore file includes the ignored project files. --- .cvsignore | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) delete mode 100644 .cvsignore diff --git a/.cvsignore b/.cvsignore deleted file mode 100644 index cc617d3d..00000000 --- a/.cvsignore +++ /dev/null @@ -1,46 +0,0 @@ -*.lo -*.la -.deps -.libs -Makefile -Makefile.fragments -Makefile.global -Makefile.objects -acinclude.m4 -aclocal.m4 -autom4te.cache -build -config.cache -config.guess -config.h -config.h.in -config.log -config.nice -config.status -config.sub -configure -configure.in -conftest -conftest.c -include -install-sh -libtool -ltmain.sh -missing -mkinstalldirs -modules -scan_makefile_in.awk -*.dsw -*.plg -*.opt -*.ncb -Release -Release_inline -Debug -Release_TS -Release_TSDbg -Release_TS_inline -Debug_TS -memcached*.tgz -run-tests.php -cscope.out From b70b82ee4a793e3664394a20f92dd711044eea5b Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 21 Jul 2018 00:57:05 +0200 Subject: [PATCH 079/218] Remove forgotten unused comment about -lpthread (#406) The -lpthread option has been added long time ago in commit c10de3699faa3ecb4cb6861d6c92157e0c7e18ce and has been since also refactored and therefore comment is not needed anymore: feed35e22040b874ba6fc8659dc16b498e6e4150 --- config.m4 | 1 - 1 file changed, 1 deletion(-) diff --git a/config.m4 b/config.m4 index f086d492..9694b5e2 100644 --- a/config.m4 +++ b/config.m4 @@ -253,7 +253,6 @@ if test "$PHP_MEMCACHED" != "no"; then PHP_EVAL_LIBLINE($PHP_LIBMEMCACHED_LIBS, MEMCACHED_SHARED_LIBADD) PHP_EVAL_INCLINE($PHP_LIBMEMCACHED_INCLUDES) - dnl # Added -lpthread here because AC_TRY_LINK tests on CentOS 6 seem to fail with undefined reference to pthread_once ORIG_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $INCLUDES" From 549e7c8a3af643ab5ce76002a6748990f04570d2 Mon Sep 17 00:00:00 2001 From: Tom Van Looy Date: Sat, 21 Jul 2018 01:01:55 +0200 Subject: [PATCH 080/218] Change session_lock default ini values (#350) --- memcached.ini | 12 ++++++------ php_memcached.c | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/memcached.ini b/memcached.ini index 138fd09a..c2072324 100644 --- a/memcached.ini +++ b/memcached.ini @@ -7,16 +7,16 @@ ; The minimum time, in milliseconds, to wait between session lock attempts. ; This value is double on each lock retry until memcached.sess_lock_wait_max ; is reached, after which any further retries will take sess_lock_wait_max seconds. -; Default is 1000. -;memcached.sess_lock_wait_min = 1000; +; Default is 150. +;memcached.sess_lock_wait_min = 150; ; The maximum time, in milliseconds, to wait between session lock attempts. -; Default is 2000. -;memcached.sess_lock_wait_max = 2000; +; Default is 150. +;memcached.sess_lock_wait_max = 150; ; The number of times to retry locking the session lock, not including the first attempt. -; Default is 5. -;memcached.sess_lock_retries = 5; +; Default is 200. +;memcached.sess_lock_retries = 200; ; The time, in seconds, before a lock should release itself. ; Setting to 0 results in the default behaviour, which is to diff --git a/php_memcached.c b/php_memcached.c index 01f98729..2e283818 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -361,8 +361,8 @@ PHP_INI_BEGIN() #ifdef HAVE_MEMCACHED_SESSION MEMC_SESSION_INI_BOOL ("locking", "1", OnUpdateBool, lock_enabled) - MEMC_SESSION_INI_ENTRY("lock_wait_min", "1000", OnUpdateLongGEZero, lock_wait_min) - MEMC_SESSION_INI_ENTRY("lock_wait_max", "2000", OnUpdateLongGEZero, lock_wait_max) + MEMC_SESSION_INI_ENTRY("lock_wait_min", "150", OnUpdateLongGEZero, lock_wait_min) + MEMC_SESSION_INI_ENTRY("lock_wait_max", "150", OnUpdateLongGEZero, lock_wait_max) MEMC_SESSION_INI_ENTRY("lock_retries", "5", OnUpdateLong, lock_retries) MEMC_SESSION_INI_ENTRY("lock_expire", "0", OnUpdateLongGEZero, lock_expiration) #if defined(LIBMEMCACHED_VERSION_HEX) && LIBMEMCACHED_VERSION_HEX < 0x01000018 @@ -4271,9 +4271,9 @@ PHP_GINIT_FUNCTION(php_memcached) #ifdef HAVE_MEMCACHED_SESSION php_memcached_globals->session.lock_enabled = 0; - php_memcached_globals->session.lock_wait_max = 2000; - php_memcached_globals->session.lock_wait_min = 1000; - php_memcached_globals->session.lock_retries = 5; + php_memcached_globals->session.lock_wait_max = 150; + php_memcached_globals->session.lock_wait_min = 150; + php_memcached_globals->session.lock_retries = 200; php_memcached_globals->session.lock_expiration = 30; php_memcached_globals->session.binary_protocol_enabled = 1; php_memcached_globals->session.consistent_hash_enabled = 1; From 58b299e5856f6728e9adef4cd8d5b33a4aaf3748 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 1 Sep 2018 18:27:21 +0200 Subject: [PATCH 081/218] Add configure.ac to Git ignored files (#405) Starting with PHP 7.2, the phpize script outputs configure.ac. Earlier verisons of phpize generated configure.in. Since configure.in was already on the gitignore list, this PR adds configure.ac to the gitignore list. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index bc9d558c..0cbefe90 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ config.status config.sub configure configure.in +configure.ac conftest conftest.c include From f773f278c9c43a40f3a66fea792247b4e04df931 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Sat, 1 Sep 2018 18:30:31 +0200 Subject: [PATCH 082/218] Replace obsolete AC_TRY_FOO with AC_FOO_IFELSE (#403) Autoconf made several macros obsolete including the AC_TRY_COMPILE and AC_TRY_LINK in 2000 and since Autoconf 2.50: http://git.savannah.gnu.org/cgit/autoconf.git/tree/ChangeLog.2 These macros should be replaced with the current AC_FOO_IFELSE instead. It is fairly safe to upgrade and take the recommendation advice of autoconf upgrade manual since the upgrade should be compatible at least with PHP versions 5.4 and up, on some systems even with PHP 5.3. PHP versions from 5.4 to 7.1 require Autoconf 2.59+ and PHP 7.2+ require Autoconf 2.64+. This patch was created with the help of autoupdate script. Reference docs: - https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Obsolete-Macros.html - https://www.gnu.org/software/autoconf/manual/autoconf-2.59/autoconf.pdf --- config.m4 | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/config.m4 b/config.m4 index 9694b5e2..1f75d622 100644 --- a/config.m4 +++ b/config.m4 @@ -259,17 +259,15 @@ if test "$PHP_MEMCACHED" != "no"; then dnl # Always check if libmemcached was built with SASL support, dnl # because it will require sasl.h even if not used here. AC_CACHE_CHECK([for libmemcached sasl.h requirement], ac_cv_memc_sasl_support, [ - AC_TRY_COMPILE( - [ #include ], - [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ #if LIBMEMCACHED_WITH_SASL_SUPPORT /* yes */ #else # error "no sasl support" #endif - ], - [ ac_cv_memc_sasl_support="yes" ], - [ ac_cv_memc_sasl_support="no" ] + ]])], + [ac_cv_memc_sasl_support="yes"], + [ac_cv_memc_sasl_support="no"] ) ]) @@ -303,12 +301,11 @@ if test "$PHP_MEMCACHED" != "no"; then LIBS="$LIBS $PHP_LIBMEMCACHED_LIBS" AC_CACHE_CHECK([whether memcached_exist is defined], ac_cv_have_memcached_exist, [ - AC_TRY_LINK( - [ #include ], - [ memcached_exist (NULL, NULL, 0); ], - [ ac_cv_have_memcached_exist="yes" ], - [ ac_cv_have_memcached_exist="no" ] - ) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[#include ]], + [[memcached_exist (NULL, NULL, 0);]])], + [ac_cv_have_memcached_exist="yes"], + [ac_cv_have_memcached_exist="no"]) ]) CFLAGS="$ORIG_CFLAGS" @@ -322,12 +319,11 @@ if test "$PHP_MEMCACHED" != "no"; then fi AC_CACHE_CHECK([whether memcached_set_encoding_key is defined], ac_cv_have_memcached_set_encoding_key, [ - AC_TRY_LINK( - [ #include ], - [ memcached_set_encoding_key (NULL, NULL, 0); ], - [ ac_cv_have_memcached_set_encoding_key="yes" ], - [ ac_cv_have_memcached_set_encoding_key="no" ] - ) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[#include ]], + [[memcached_set_encoding_key (NULL, NULL, 0);]])], + [ac_cv_have_memcached_set_encoding_key="yes"], + [ac_cv_have_memcached_set_encoding_key="no"]) ]) CFLAGS="$ORIG_CFLAGS" @@ -359,13 +355,12 @@ if test "$PHP_MEMCACHED" != "no"; then AC_MSG_RESULT([enabled]) AC_CACHE_CHECK([whether libmemcachedprotocol is usable], ac_cv_have_libmemcachedprotocol, [ - AC_TRY_COMPILE( - [ #include ], - [ memcached_binary_protocol_callback_st s_test_impl; + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[memcached_binary_protocol_callback_st s_test_impl; s_test_impl.interface.v1.delete_object = 0; - ], - [ ac_cv_have_libmemcachedprotocol="yes" ], - [ ac_cv_have_libmemcachedprotocol="no" ] + ]])], + [ac_cv_have_libmemcachedprotocol="yes"], + [ac_cv_have_libmemcachedprotocol="no"] ) ]) From 6220e207b05e7ff8ef0ed3ac79907bcd753c4a65 Mon Sep 17 00:00:00 2001 From: "Michael D. Stemle, Jr" Date: Wed, 14 Nov 2018 19:25:58 -0500 Subject: [PATCH 083/218] In the latest zlib package for homebrew, the install target is /usr/local/opt/zlib, so I'm adding that to the list. (#410) --- config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.m4 b/config.m4 index 1f75d622..6deddfb9 100644 --- a/config.m4 +++ b/config.m4 @@ -60,7 +60,7 @@ if test "$PHP_MEMCACHED" != "no"; then AC_MSG_ERROR([Can't find ZLIB headers under "$PHP_ZLIB_DIR"]) fi else - for i in /usr/local /usr; do + for i in /usr/local /usr/local/opt/zlib /usr; do if test -f "$i/include/zlib/zlib.h"; then PHP_ZLIB_DIR="$i" PHP_ZLIB_INCDIR="$i/include/zlib" From 6d8f5d524f35e72422b9e81319b96f23af02adcc Mon Sep 17 00:00:00 2001 From: Xander Date: Thu, 15 Nov 2018 11:27:53 +1100 Subject: [PATCH 084/218] Windows fixes (#411) --- README.win32.txt | 13 +++++++++++++ config.w32 | 30 ++++++++++++++++++++++++++++-- php_memcached.c | 8 +++++++- php_memcached.h | 5 +++++ php_memcached_private.h | 4 ++++ 5 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 README.win32.txt diff --git a/README.win32.txt b/README.win32.txt new file mode 100644 index 00000000..c717aa8a --- /dev/null +++ b/README.win32.txt @@ -0,0 +1,13 @@ +Build Steps for Windows +------------------------- + +Follow https://wiki.php.net/internals/windows/stepbystepbuild_sdk_2#building_pecl_extensions + +- Add igbinary module to pecl directory if support desired +- Download/Compile libmemcached & add to deps folders (includes & lib). Lib should be named memcache.lib + - Important for 32bit: libmemcached must be built with _USE_32BIT_TIME_T defined (confirmed on PHP 7.2, VC15) + - https://github.com/yshurik/libmemcached-win/tree/1.0.18 is confirmed working + - To use the dll on the releases page you'd likely need to change the header files to use __time64_t instead of time_t +- Enable all options desired: --enable-memcached=shared --enable-memcached-session --enable-memcached-json + - for igbinary, add --enable-memcached-igbinary --enable-igbinary=shared +- Run nmake \ No newline at end of file diff --git a/config.w32 b/config.w32 index e6e0c425..9c84a059 100644 --- a/config.w32 +++ b/config.w32 @@ -1,6 +1,10 @@ // vim:ft=javascript -ARG_WITH('memcached', 'libmemcached extension', 'no'); +ARG_ENABLE('memcached', 'libmemcached extension', 'no'); + +ARG_ENABLE('memcached-session', 'whether to enable memcached session handler support', 'no'); +ARG_ENABLE('memcached-igbinary', 'whether to enable memcached igbinary serializer support', 'no'); +ARG_ENABLE('memcached-json', 'whether to enable memcached json serializer support', 'no'); if (PHP_MEMCACHED == "yes") { @@ -11,7 +15,29 @@ if (PHP_MEMCACHED == "yes") { if (!CHECK_HEADER_ADD_INCLUDE("libmemcached/memcached.h", "CFLAGS_MEMCACHED")) { ERROR("memcached: header 'libmemcached/memcached.h' not found"); } - EXTENSION("memcached", "memcached.c"); + + if (PHP_MEMCACHED_JSON != "no"){ + AC_DEFINE("HAVE_JSON_API",1); + } + + var memcached_extra_src = ""; + + if (PHP_MEMCACHED_SESSION != "no"){ + AC_DEFINE("HAVE_MEMCACHED_SESSION",1); + ADD_EXTENSION_DEP("memcached", "session", true) + memcached_extra_src += " php_memcached_session.c"; + } + + if (PHP_MEMCACHED_IGBINARY != "no"){ + AC_DEFINE("HAVE_MEMCACHED_IGBINARY",1); + ADD_EXTENSION_DEP("memcached", "igbinary", true); + if (!CHECK_HEADER_ADD_INCLUDE("igbinary.h", "CFLAGS_MEMCACHED")) { + ERROR("memcached: header 'igbinary.h' not found"); + } + } + + EXTENSION("memcached", "php_memcached.c php_libmemcached_compat.c g_fmt.c"+memcached_extra_src); + ADD_SOURCES(configure_module_dirname+"\\fastlz", "fastlz.c", "memcached"); AC_DEFINE("HAVE_MEMCACHED", 1, "memcached support"); AC_DEFINE("MEMCACHED_EXPORTS", 1) } diff --git a/php_memcached.c b/php_memcached.c index 2e283818..760c2c45 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -42,8 +42,14 @@ #endif #ifdef HAVE_MEMCACHED_IGBINARY +#ifdef PHP_WIN32 +//Windows extensions are generally built together, +//so it wont be in the installed location +#include "igbinary.h" +#else # include "ext/igbinary/igbinary.h" #endif +#endif #ifdef HAVE_MEMCACHED_MSGPACK # include "ext/msgpack/php_msgpack.h" @@ -1428,7 +1434,7 @@ zend_bool s_get_apply_fn(php_memc_object_t *intern, zend_string *key, zval *valu static void php_memc_get_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) { - php_memc_get_ctx_t context = {}; + php_memc_get_ctx_t context = {0}; php_memc_keys_t keys = {0}; zend_long get_flags = 0; zend_string *key; diff --git a/php_memcached.h b/php_memcached.h index 59989f5b..b391790a 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -19,7 +19,12 @@ #include "php.h" #include "Zend/zend_smart_str.h" + +#ifdef PHP_WIN32 +#include "main/config.w32.h" +#else #include "main/php_config.h" +#endif #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/php_memcached_private.h b/php_memcached_private.h index 561812e5..3e1f3586 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -17,7 +17,11 @@ #ifndef PHP_MEMCACHED_PRIVATE_H #define PHP_MEMCACHED_PRIVATE_H +#ifdef PHP_WIN32 +#include "main/config.w32.h" +#else #include "main/php_config.h" +#endif #ifdef HAVE_CONFIG_H # include "config.h" From 0b79956e6d92268295c67e26bc173d44724bf5a8 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 9 Apr 2018 00:35:56 -0700 Subject: [PATCH 085/218] Error message if old PERSISTENT=n flag is used in session.save_path --- package.xml | 1 + php_memcached_session.c | 7 +++++++ tests/session_badconf_persistent.phpt | 25 +++++++++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 tests/session_badconf_persistent.phpt diff --git a/package.xml b/package.xml index 0edfd3da..2c537c02 100644 --- a/package.xml +++ b/package.xml @@ -117,6 +117,7 @@ Fixes + diff --git a/php_memcached_session.c b/php_memcached_session.c index 7d072af2..6acd9d3e 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -319,6 +319,13 @@ PS_OPEN_FUNC(memcached) memcached_server_list_st servers; + // Fail on incompatible PERSISTENT identifier (removed in php-memcached 3.0) + if (strstr(save_path, "PERSISTENT=")) { + php_error_docref(NULL, E_WARNING, "failed to parse session.save_path: PERSISTENT is replaced by memcached.sess_persistent = On"); + PS_SET_MOD_DATA(NULL); + return FAILURE; + } + // First parse servers servers = memcached_servers_parse(save_path); diff --git a/tests/session_badconf_persistent.phpt b/tests/session_badconf_persistent.phpt new file mode 100644 index 00000000..04b5e44e --- /dev/null +++ b/tests/session_badconf_persistent.phpt @@ -0,0 +1,25 @@ +--TEST-- +Session bad configurations, persistent +--SKIPIF-- + +--INI-- +session.save_handler = "memcached" +session.save_path = "PERSISTENT=1 hello:11211,world:11211" + +--FILE-- + Date: Mon, 9 Apr 2018 02:15:58 -0700 Subject: [PATCH 086/218] Nits --- php_memcached.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 760c2c45..a7c33d31 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -1526,7 +1526,7 @@ zend_bool s_get_multi_apply_fn(php_memc_object_t *intern, zend_string *key, zval add_assoc_zval(&node, "cas", cas); add_assoc_long(&node, "flags", (zend_long) MEMC_VAL_GET_USER_FLAGS(flags)); - zend_symtable_update(Z_ARRVAL_P(context->return_value), key, &node); + zend_symtable_update(Z_ARRVAL_P(context->return_value), key, &node); } else { zend_symtable_update(Z_ARRVAL_P(context->return_value), key, value); @@ -3213,7 +3213,7 @@ PHP_METHOD(Memcached, setBucket) rc = memcached_bucket_set (intern->memc, server_map, forward_map, (uint32_t) server_map_len, replicas); if (s_memc_status_handle_result_code(intern, rc) == FAILURE) { - retval = 0;; + retval = 0; } efree(server_map); From 282eca70cb6f4466093ab9a2f89ee1fbea5f1abd Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 21 Dec 2018 01:29:12 -0800 Subject: [PATCH 087/218] Add PHP 7.3 to Travis CI matrix, drop ancient libmemcached --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 26973f0a..ddc6d379 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ dist: trusty language: php php: - master + - 7.3 - 7.2 - 7.1 - 7.0 @@ -17,7 +18,6 @@ env: - LIBMEMCACHED_VERSION=1.0.18 # Debian Jessie / Ubuntu Xenial - LIBMEMCACHED_VERSION=1.0.16 # RHEL / CentOS 7 - LIBMEMCACHED_VERSION=1.0.8 # Debian Wheezy / Ubuntu Trusty - - LIBMEMCACHED_VERSION=1.0.2 # Ancient addons: apt: From e9381d07ca09367846d974b1ce1d4b02f8ba7c0a Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 21 Dec 2018 01:39:33 -0800 Subject: [PATCH 088/218] Travis CI switch to Xenial, remove deprecated sudo flag --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ddc6d379..5ce37750 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ -sudo: required -dist: trusty +dist: xenial language: php php: From c5618158c56569a1c20a94b4d792a3e182b528d0 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 21 Dec 2018 02:08:04 -0800 Subject: [PATCH 089/218] Handle fatal error in session badconf persistent test --- tests/session_badconf_persistent.phpt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/session_badconf_persistent.phpt b/tests/session_badconf_persistent.phpt index 04b5e44e..7deeb1e1 100644 --- a/tests/session_badconf_persistent.phpt +++ b/tests/session_badconf_persistent.phpt @@ -16,10 +16,10 @@ ob_start(); session_start(); session_write_close(); -echo "OK"; +// In PHP < 7.2 this is a Fatal Error so the OK is not printed +// echo "OK"; --EXPECTF-- Warning: session_start(): failed to parse session.save_path: PERSISTENT is replaced by memcached.sess_persistent = On in %s on line %d -Warning: session_start(): Failed to initialize storage module: memcached (path: PERSISTENT=1 %s) in %s on line %d -OK +%s: session_start(): Failed to initialize storage module: memcached (path: PERSISTENT=1 %s) in %s on line %d From 193590e93b4169fb830791d68b28d748f3951729 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 21 Dec 2018 03:48:49 -0800 Subject: [PATCH 090/218] Release notes for 3.1.0 --- ChangeLog | 28 +++++++++++++++++++++++ package.xml | 64 ++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 81 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5e406ee2..71536d94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,33 @@ memcached extension changelog +Version 3.1.0 (2017-12-21) +-------------------------- + + New + * Support for PHP 7.3 (#385, #390) + * Add INI setting to choose session consistent hash (ketama or ketama_weighted) (#344, #392) + * Add support for libmemcached encryption (#345, #381) + * Add error reporting to session code (#165) + * Expose build configuration via PECL (#383) + + Fixes + * Fix hanging getStats() when binary protocol and non-blocking are both enabled (#348) + * Fix session persistence by checking memcached behavior values before setting (#379) + * Fix memcached.sess_persistent not working with memcached.sess_binary_protocol = On (#375) + * Configure warns if libmemcached needs sasl.h (#341, #380) + * Resolve various INI deviations in 3.0.3 (#351) + * Turn off sess_binary_protocol by default with older libmemcached (#330) + + Changes + * Impove Windows builds (#411) + * Support Homebrew ZLIB path (#410) + * Remove forgotten unused comment about -lpthread (#406) + * Git ignore configure.ac (#405) + * Replace obsolete macros AC_TRY_FOO with AC_FOO_IFELSE (#403) + * Remove unused defines (#354) + * Change session_lock and sess_prefix default ini values (#340, #350) + * Use new fast_zpp parameter parsing API (#302, #311) + Version 3.0.4 (2017-11-20) -------------------------- diff --git a/package.xml b/package.xml index 2c537c02..3015d032 100644 --- a/package.xml +++ b/package.xml @@ -27,9 +27,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> aaron@serendipity.cx yes - 2017-11-20 + 2018-12-21 - 3.0.4 + 3.1.0 3.0.0 @@ -38,19 +38,35 @@ http://pear.php.net/dtd/package-2.0.xsd"> PHP -PHP 7.0 - 7.1 - 7.2 release of memcached extension. Note that support for +PHP 7.0 - 7.1 - 7.2 - 7.3 release of memcached extension. Note that support for libmemcached 0.x series has been discontinued and the oldest actively tested -version is 1.0.2. It is highly recommended to use version 1.0.18 of +version is 1.0.8. It is highly recommended to use version 1.0.18 of libmemcached. +New + * Support for PHP 7.3 (#385, #390) + * Add INI setting to choose session consistent hash (ketama or ketama_weighted) (#344, #392) + * Add support for libmemcached encryption (#345, #381) + * Add error reporting to session code (#165) + * Expose build configuration via PECL (#383) + Fixes - * Fix corrupted interned strings (#338) - * Fix unit tests for compatibility with PHP 7.2 (#358, #359) - * Fix \x0a in key name locks up connection and triggers a fatal timeout error (#339) - * Fix missing optional parameter getStats($type) (#337) - * Fix typo in skip message (#331) - * Fix build warnings (#329) - * Document GET_EXTENDED flag, add/rename other missing/misnamed constants (#335) + * Fix hanging getStats() when binary protocol and non-blocking are both enabled (#348) + * Fix session persistence by checking memcached behavior values before setting (#379) + * Fix memcached.sess_persistent not working with memcached.sess_binary_protocol = On (#375) + * Configure warns if libmemcached needs sasl.h (#341, #380) + * Resolve various INI deviations in 3.0.3 (#351) + * Turn off sess_binary_protocol by default with older libmemcached (#330) + +Changes + * Impove Windows builds (#411) + * Support Homebrew ZLIB path (#410) + * Remove forgotten unused comment about -lpthread (#406) + * Git ignore configure.ac (#405) + * Replace obsolete macros AC_TRY_FOO with AC_FOO_IFELSE (#403) + * Remove unused defines (#354) + * Change session_lock and sess_prefix default ini values (#340, #350) + * Use new fast_zpp parameter parsing API (#302, #311) @@ -209,6 +225,32 @@ Fixes + + + stable + stable + + + 3.0.4 + 3.0.0 + + 2017-11-20 + +PHP 7.0 - 7.1 - 7.2 release of memcached extension. Note that support for +libmemcached 0.x series has been discontinued and the oldest actively tested +version is 1.0.2. It is highly recommended to use version 1.0.18 of +libmemcached. + +Fixes + * Fix corrupted interned strings (#338) + * Fix unit tests for compatibility with PHP 7.2 (#358, #359) + * Fix \x0a in key name locks up connection and triggers a fatal timeout error (#339) + * Fix missing optional parameter getStats($type) (#337) + * Fix typo in skip message (#331) + * Fix build warnings (#329) + * Document GET_EXTENDED flag, add/rename other missing/misnamed constants (#335) + + stable From 699e68953a908e90235cf23671ce245ad35c5ef6 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 21 Dec 2018 03:49:01 -0800 Subject: [PATCH 091/218] Bump version to 3.1.0 --- php_memcached.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.h b/php_memcached.h index b391790a..97c64404 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -30,7 +30,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.1.0-dev" +#define PHP_MEMCACHED_VERSION "3.1.0" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 4a82c59f49fe0a222a6cab6cc612f899ccc199a5 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 21 Dec 2018 04:44:15 -0800 Subject: [PATCH 092/218] Document that --disable-x options are --enable-x --- config.m4 | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/config.m4 b/config.m4 index 6deddfb9..c7a15f11 100644 --- a/config.m4 +++ b/config.m4 @@ -1,40 +1,40 @@ dnl vim:se ts=2 sw=2 et: PHP_ARG_ENABLE(memcached, whether to enable memcached support, -[ --enable-memcached Enable memcached support]) +[ --enable-memcached Enable memcached support]) PHP_ARG_WITH(libmemcached-dir, for libmemcached, -[ --with-libmemcached-dir[=DIR] Set the path to libmemcached install prefix.], yes) +[ --with-libmemcached-dir=DIR Set the path to libmemcached install prefix.], yes) PHP_ARG_ENABLE(memcached-session, whether to enable memcached session handler support, -[ --disable-memcached-session Disable memcached session handler support], yes, no) +[ --enable-memcached-session Enable memcached session handler support], yes, no) PHP_ARG_ENABLE(memcached-igbinary, whether to enable memcached igbinary serializer support, -[ --enable-memcached-igbinary Enable memcached igbinary serializer support], no, no) +[ --enable-memcached-igbinary Enable memcached igbinary serializer support], no, no) PHP_ARG_ENABLE(memcached-json, whether to enable memcached json serializer support, -[ --enable-memcached-json Enable memcached json serializer support], no, no) +[ --enable-memcached-json Enable memcached json serializer support], no, no) PHP_ARG_ENABLE(memcached-msgpack, whether to enable memcached msgpack serializer support, -[ --enable-memcached-msgpack Enable memcached msgpack serializer support], no, no) +[ --enable-memcached-msgpack Enable memcached msgpack serializer support], no, no) PHP_ARG_ENABLE(memcached-sasl, whether to enable memcached sasl support, -[ --disable-memcached-sasl Disable memcached sasl support], yes, no) +[ --enable-memcached-sasl Enable memcached sasl support], yes, no) PHP_ARG_ENABLE(memcached-protocol, whether to enable memcached protocol support, -[ --enable-memcached-protocol Enable memcached protocol support], no, no) +[ --enable-memcached-protocol Enable memcached protocol support], no, no) PHP_ARG_WITH(system-fastlz, whether to use system FastLZ library, -[ --with-system-fastlz Use system FastLZ library], no, no) +[ --with-system-fastlz Use system FastLZ library], no, no) if test -z "$PHP_ZLIB_DIR"; then PHP_ARG_WITH(zlib-dir, for ZLIB, -[ --with-zlib-dir[=DIR] Set the path to ZLIB install prefix.], no) +[ --with-zlib-dir=DIR Set the path to ZLIB install prefix.], no) fi if test -z "$PHP_DEBUG"; then AC_ARG_ENABLE(debug, - [ --enable-debug compile with debugging symbols],[ + [ --enable-debug Compile with debugging symbols],[ PHP_DEBUG=$enableval ],[ PHP_DEBUG=no ]) From b4d105bd41f1b6a54635d1e681f38924b264ec67 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 21 Dec 2018 04:45:44 -0800 Subject: [PATCH 093/218] Set defaults to match --enable-x rather than --disable-x --- package.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.xml b/package.xml index 3015d032..d9270d03 100644 --- a/package.xml +++ b/package.xml @@ -220,9 +220,9 @@ Changes - - - + + + From 9f7d049737f6ebe77013e6a21906959844696ade Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 21 Dec 2018 04:46:06 -0800 Subject: [PATCH 094/218] Fix zend_string warning --- php_memcached.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index a7c33d31..858d0aca 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -493,7 +493,7 @@ char *php_memc_printable_func (zend_fcall_info *fci, zend_fcall_info_cache *fci_ char *buffer = NULL; if (fci->object) { - spprintf (&buffer, 0, "%s::%s", ZSTR_VAL(fci->object->ce->name), fci_cache->function_handler->common.function_name); + spprintf (&buffer, 0, "%s::%s", ZSTR_VAL(fci->object->ce->name), ZSTR_VAL(fci_cache->function_handler->common.function_name)); } else { if (Z_TYPE (fci->function_name) == IS_OBJECT) { spprintf (&buffer, 0, "%s", ZSTR_VAL(Z_OBJCE(fci->function_name)->name)); From e2dbf33fe9a9fcced24dc2728084fd09e1fe8b72 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 21 Dec 2018 04:51:32 -0800 Subject: [PATCH 095/218] Release notes for 3.1.1 --- ChangeLog | 5 ++++ package.xml | 68 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index 71536d94..4a1748b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ memcached extension changelog +Version 3.1.1 (2017-12-21) +-------------------------- + + * Fix --disable-memcached-sasl and --disable-memcached-session replaced by --enable variants (#416) + Version 3.1.0 (2017-12-21) -------------------------- diff --git a/package.xml b/package.xml index d9270d03..9b6faf68 100644 --- a/package.xml +++ b/package.xml @@ -29,7 +29,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> 2018-12-21 - 3.1.0 + 3.1.1 3.0.0 @@ -43,30 +43,8 @@ libmemcached 0.x series has been discontinued and the oldest actively tested version is 1.0.8. It is highly recommended to use version 1.0.18 of libmemcached. -New - * Support for PHP 7.3 (#385, #390) - * Add INI setting to choose session consistent hash (ketama or ketama_weighted) (#344, #392) - * Add support for libmemcached encryption (#345, #381) - * Add error reporting to session code (#165) - * Expose build configuration via PECL (#383) - Fixes - * Fix hanging getStats() when binary protocol and non-blocking are both enabled (#348) - * Fix session persistence by checking memcached behavior values before setting (#379) - * Fix memcached.sess_persistent not working with memcached.sess_binary_protocol = On (#375) - * Configure warns if libmemcached needs sasl.h (#341, #380) - * Resolve various INI deviations in 3.0.3 (#351) - * Turn off sess_binary_protocol by default with older libmemcached (#330) - -Changes - * Impove Windows builds (#411) - * Support Homebrew ZLIB path (#410) - * Remove forgotten unused comment about -lpthread (#406) - * Git ignore configure.ac (#405) - * Replace obsolete macros AC_TRY_FOO with AC_FOO_IFELSE (#403) - * Remove unused defines (#354) - * Change session_lock and sess_prefix default ini values (#340, #350) - * Use new fast_zpp parameter parsing API (#302, #311) + * Fix --disable-memcached-sasl and --disable-memcached-session replaced by --enable variants (#416) @@ -225,6 +203,48 @@ Changes + + + stable + stable + + + 3.1.0 + 3.0.0 + + 2018-12-21 + +PHP 7.0 - 7.1 - 7.2 - 7.3 release of memcached extension. Note that support for +libmemcached 0.x series has been discontinued and the oldest actively tested +version is 1.0.8. It is highly recommended to use version 1.0.18 of +libmemcached. + +New + * Support for PHP 7.3 (#385, #390) + * Add INI setting to choose session consistent hash (ketama or ketama_weighted) (#344, #392) + * Add support for libmemcached encryption (#345, #381) + * Add error reporting to session code (#165) + * Expose build configuration via PECL (#383) + +Fixes + * Fix hanging getStats() when binary protocol and non-blocking are both enabled (#348) + * Fix session persistence by checking memcached behavior values before setting (#379) + * Fix memcached.sess_persistent not working with memcached.sess_binary_protocol = On (#375) + * Configure warns if libmemcached needs sasl.h (#341, #380) + * Resolve various INI deviations in 3.0.3 (#351) + * Turn off sess_binary_protocol by default with older libmemcached (#330) + +Changes + * Impove Windows builds (#411) + * Support Homebrew ZLIB path (#410) + * Remove forgotten unused comment about -lpthread (#406) + * Git ignore configure.ac (#405) + * Replace obsolete macros AC_TRY_FOO with AC_FOO_IFELSE (#403) + * Remove unused defines (#354) + * Change session_lock and sess_prefix default ini values (#340, #350) + * Use new fast_zpp parameter parsing API (#302, #311) + + stable From b4103acd0356db74518534c5da1702c72b38d459 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 21 Dec 2018 04:51:44 -0800 Subject: [PATCH 096/218] Bump version to 3.1.1 --- php_memcached.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.h b/php_memcached.h index 97c64404..3197d058 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -30,7 +30,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.1.0" +#define PHP_MEMCACHED_VERSION "3.1.1" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 5ad7c05614dc2ea7f977193ad6157187d15fc89e Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sat, 22 Dec 2018 05:59:52 -0800 Subject: [PATCH 097/218] Partially revert b4d105b caught one option too many --- package.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.xml b/package.xml index 9b6faf68..7eca1a2c 100644 --- a/package.xml +++ b/package.xml @@ -198,7 +198,7 @@ Fixes - + From 206f12bddaf014eec4a53437c16c99ae9537216c Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sat, 22 Dec 2018 07:54:24 -0800 Subject: [PATCH 098/218] Release notes for 3.1.2 --- package.xml | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/package.xml b/package.xml index 7eca1a2c..8f54da93 100644 --- a/package.xml +++ b/package.xml @@ -27,9 +27,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> aaron@serendipity.cx yes - 2018-12-21 + 2018-12-22 - 3.1.1 + 3.1.2 3.0.0 @@ -44,7 +44,7 @@ version is 1.0.8. It is highly recommended to use version 1.0.18 of libmemcached. Fixes - * Fix --disable-memcached-sasl and --disable-memcached-session replaced by --enable variants (#416) + * Fix --enable-memcached-protocol was set to yes by default, reverted to no (#418) @@ -203,6 +203,26 @@ Fixes + + + stable + stable + + + 3.1.1 + 3.0.0 + + 2018-12-21 + +PHP 7.0 - 7.1 - 7.2 - 7.3 release of memcached extension. Note that support for +libmemcached 0.x series has been discontinued and the oldest actively tested +version is 1.0.8. It is highly recommended to use version 1.0.18 of +libmemcached. + +Fixes + * Fix --disable-memcached-sasl and --disable-memcached-session replaced by --enable variants (#416) + + stable From 02e1e2ffd25fc0cc5e8b0507e83d28612128cc8c Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sat, 22 Dec 2018 07:54:42 -0800 Subject: [PATCH 099/218] Bump version to 3.1.2 --- php_memcached.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.h b/php_memcached.h index 3197d058..810b62ed 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -30,7 +30,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.1.1" +#define PHP_MEMCACHED_VERSION "3.1.2" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 35292435e29795166b65bbb73653a957c9f91cee Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Sat, 22 Dec 2018 17:00:04 +0100 Subject: [PATCH 100/218] fix build warning (#417) --- php_memcached.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index 858d0aca..4deb5de8 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -2752,7 +2752,7 @@ memcached_return s_stat_execute_cb (php_memcached_instance_st instance, const ch server_values = zend_hash_add(Z_ARRVAL_P(return_value), server_key, &zv); } - spprintf (&buffer, 0, "%.*s", value_length, value); + spprintf (&buffer, 0, "%.*s", (int)value_length, value); /* Check type */ if (s_long_value (buffer, &long_val)) { From c85d9029fbe525fb1cd113d22d61aba1eb9876bd Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 24 Dec 2018 13:16:42 -0800 Subject: [PATCH 101/218] Fix --disable-memcached-session by ifdef-ing session INI handler callbacks (#420) Resolves #396 --- php_memcached.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php_memcached.c b/php_memcached.c index 4deb5de8..930e1189 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -302,6 +302,7 @@ static PHP_INI_MH(OnUpdateSerializer) return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } +#ifdef HAVE_MEMCACHED_SESSION static PHP_INI_MH(OnUpdateDeprecatedLockValue) { @@ -342,6 +343,7 @@ PHP_INI_MH(OnUpdateConsistentHash) } return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage); } +#endif // HAVE_MEMCACHED_SESSION #define MEMC_INI_ENTRY(key, default_value, update_fn, gkey) \ STD_PHP_INI_ENTRY("memcached."key, default_value, PHP_INI_ALL, update_fn, memc.gkey, zend_php_memcached_globals, php_memcached_globals) From c76ec9e6ea3e15f239f71532025762a0217afb44 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 24 Dec 2018 13:38:57 -0800 Subject: [PATCH 102/218] Release notes for 3.1.2 and 3.1.3, fix dates for 3.1.x --- ChangeLog | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4a1748b3..e55dd8fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,11 +1,21 @@ memcached extension changelog -Version 3.1.1 (2017-12-21) +Version 3.1.3 (2018-12-24) +-------------------------- + + * Fix --disable-memcached-session by ifdef-ing session INI handler callbacks (#396, #420) + +Version 3.1.2 (2018-12-22) +-------------------------- + + * Fix --enable-memcached-protocol was set to yes by default, reverted to no (#418) + +Version 3.1.1 (2018-12-21) -------------------------- * Fix --disable-memcached-sasl and --disable-memcached-session replaced by --enable variants (#416) -Version 3.1.0 (2017-12-21) +Version 3.1.0 (2018-12-21) -------------------------- New From 9cf95806225d79716db606ae9351b0c4043f6862 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 24 Dec 2018 13:40:29 -0800 Subject: [PATCH 103/218] Release notes for 3.1.3 --- package.xml | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/package.xml b/package.xml index 8f54da93..a801f856 100644 --- a/package.xml +++ b/package.xml @@ -27,9 +27,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> aaron@serendipity.cx yes - 2018-12-22 + 2018-12-24 - 3.1.2 + 3.1.3 3.0.0 @@ -44,7 +44,7 @@ version is 1.0.8. It is highly recommended to use version 1.0.18 of libmemcached. Fixes - * Fix --enable-memcached-protocol was set to yes by default, reverted to no (#418) + * Fix --disable-memcached-session by ifdef-ing session INI handler callbacks (#396, #420) @@ -203,6 +203,26 @@ Fixes + + + stable + stable + + + 3.1.2 + 3.0.0 + + 2018-12-22 + +PHP 7.0 - 7.1 - 7.2 - 7.3 release of memcached extension. Note that support for +libmemcached 0.x series has been discontinued and the oldest actively tested +version is 1.0.8. It is highly recommended to use version 1.0.18 of +libmemcached. + +Fixes + * Fix --enable-memcached-protocol was set to yes by default, reverted to no (#418) + + stable From 3ba380c1290959f67fc0d00755c93918037ead71 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 24 Dec 2018 13:40:44 -0800 Subject: [PATCH 104/218] Bump version to 3.1.3 --- php_memcached.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.h b/php_memcached.h index 810b62ed..be1235e7 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -30,7 +30,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.1.2" +#define PHP_MEMCACHED_VERSION "3.1.3" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 37f2cf98ae8000e54aab3c1be558d2dfc667304b Mon Sep 17 00:00:00 2001 From: Tyson Andre Date: Mon, 11 Mar 2019 17:39:57 -0400 Subject: [PATCH 105/218] Fix segfault for unknown memcache flags Set retval to false so that the resulting uninitialized zval won't be used. --- php_memcached.c | 1 + 1 file changed, 1 insertion(+) diff --git a/php_memcached.c b/php_memcached.c index 930e1189..85c79901 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -3745,6 +3745,7 @@ zend_bool s_memcached_result_to_zval(memcached_st *memc, memcached_result_st *re default: php_error_docref(NULL, E_WARNING, "unknown payload type"); + retval = 0; break; } zend_string_release(data); From 455d7823b9d02c9cad442413de096baf98351ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20M?= Date: Thu, 11 Apr 2019 14:59:20 +0200 Subject: [PATCH 106/218] Supports PHP 7.3 Supported according to #408 --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 19a8ab18..c3ee51a1 100644 --- a/README.markdown +++ b/README.markdown @@ -23,7 +23,7 @@ Dependencies ------------ php-memcached 3.x: -* Supports PHP 7.0 - 7.2. +* Supports PHP 7.0 - 7.3. * Requires libmemcached 1.x or higher. * Optionally supports igbinary 2.0 or higher. * Optionally supports msgpack 2.0 or higher. From cd62e8f463132c166697d5ae5e0026a255be13ac Mon Sep 17 00:00:00 2001 From: Gerry Demaret Date: Tue, 21 May 2019 20:44:17 +0200 Subject: [PATCH 107/218] Update documented default for sess_lock_retries (#432) The documented default was 200, while in reality it seems this is actually set to 5. While 5 is arguably on the low side, at least have the documentation in sync with reality. --- memcached.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/memcached.ini b/memcached.ini index c2072324..5ed79bdb 100644 --- a/memcached.ini +++ b/memcached.ini @@ -15,8 +15,8 @@ ;memcached.sess_lock_wait_max = 150; ; The number of times to retry locking the session lock, not including the first attempt. -; Default is 200. -;memcached.sess_lock_retries = 200; +; Default is 5. +;memcached.sess_lock_retries = 5; ; The time, in seconds, before a lock should release itself. ; Setting to 0 results in the default behaviour, which is to From 7443d16d02fb73cdba2e90ae282446f80969229c Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Mon, 17 Jun 2019 16:04:47 +0100 Subject: [PATCH 108/218] Test on PHP 7.4 as well as 8.0 (#440) --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 5ce37750..22db51da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ dist: xenial language: php php: - master + - 7.4snapshot - 7.3 - 7.2 - 7.1 From 5d154be2864ce9b1572119e2416a874e73c0ccc5 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 3 Oct 2019 16:25:36 -0700 Subject: [PATCH 109/218] Remove stray instances of TSRMLS_CC macro This macro was defined empty in PHP 7.x, and removed in PHP 8.x. --- php_memcached_session.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php_memcached_session.c b/php_memcached_session.c index 6acd9d3e..ce9a46db 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -445,7 +445,7 @@ PS_READ_FUNC(memcached) *val = ZSTR_EMPTY_ALLOC(); return SUCCESS; } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "error getting session from memcached: %s", memcached_last_error_message(memc)); + php_error_docref(NULL, E_WARNING, "error getting session from memcached: %s", memcached_last_error_message(memc)); return FAILURE; } } @@ -475,7 +475,7 @@ PS_WRITE_FUNC(memcached) if (memcached_set(memc, key->val, key->len, val->val, val->len, expiration, 0) == MEMCACHED_SUCCESS) { return SUCCESS; } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "error saving session to memcached: %s", memcached_last_error_message(memc)); + php_error_docref(NULL, E_WARNING, "error saving session to memcached: %s", memcached_last_error_message(memc)); } } while (--retries > 0); From 26e38ccee6110a1491c5e36d297cdb12cb261a99 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 3 Oct 2019 16:46:23 -0700 Subject: [PATCH 110/218] Use temporary fork of igbinary for php-8 support --- .travis/travis.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis/travis.sh b/.travis/travis.sh index 81049355..090e3992 100755 --- a/.travis/travis.sh +++ b/.travis/travis.sh @@ -67,8 +67,9 @@ function install_libmemcached() { } function install_igbinary() { - git clone https://github.com/igbinary/igbinary.git + git clone https://github.com/sodabrew/igbinary.git pushd igbinary + git checkout php-8 phpize ./configure make From 77120444b4f24b51621aa3e9088e08349597c786 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sat, 5 Oct 2019 09:02:48 -0700 Subject: [PATCH 111/218] Revert "Use temporary fork of igbinary for php-8 support" Upstream accepted the patch for PHP master / PHP 8 support. This reverts commit 26e38ccee6110a1491c5e36d297cdb12cb261a99. --- .travis/travis.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis/travis.sh b/.travis/travis.sh index 090e3992..81049355 100755 --- a/.travis/travis.sh +++ b/.travis/travis.sh @@ -67,9 +67,8 @@ function install_libmemcached() { } function install_igbinary() { - git clone https://github.com/sodabrew/igbinary.git + git clone https://github.com/igbinary/igbinary.git pushd igbinary - git checkout php-8 phpize ./configure make From 0ee62bd55d85ae1495ca87c096cde061df8df00a Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sat, 5 Oct 2019 09:32:26 -0700 Subject: [PATCH 112/218] Release notes for 3.1.4 --- ChangeLog | 8 ++++++++ README.markdown | 2 +- package.xml | 31 +++++++++++++++++++++++++++---- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index e55dd8fd..05060cb7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,13 @@ memcached extension changelog +Version 3.1.4 (2019-10-06) +-------------------------- + + * Test on PHP 7.4 as well as 8.0 (#440) + * Fix segfault for unknown memcached flags (#431) + * Update documented defaults for sess_lock_retries( #432) + * Remove stray instances of the TSRMLS_CC macro for PHP 8 compatibility (#444) + Version 3.1.3 (2018-12-24) -------------------------- diff --git a/README.markdown b/README.markdown index c3ee51a1..31f57b16 100644 --- a/README.markdown +++ b/README.markdown @@ -23,7 +23,7 @@ Dependencies ------------ php-memcached 3.x: -* Supports PHP 7.0 - 7.3. +* Supports PHP 7.0 - 7.4. * Requires libmemcached 1.x or higher. * Optionally supports igbinary 2.0 or higher. * Optionally supports msgpack 2.0 or higher. diff --git a/package.xml b/package.xml index a801f856..0cbc9f63 100644 --- a/package.xml +++ b/package.xml @@ -27,9 +27,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> aaron@serendipity.cx yes - 2018-12-24 + 2019-10-06 - 3.1.3 + 3.1.4 3.0.0 @@ -38,13 +38,16 @@ http://pear.php.net/dtd/package-2.0.xsd"> PHP -PHP 7.0 - 7.1 - 7.2 - 7.3 release of memcached extension. Note that support for +PHP 7.0 - 7.1 - 7.2 - 7.3 - 7.4 release of memcached extension. Note that support for libmemcached 0.x series has been discontinued and the oldest actively tested version is 1.0.8. It is highly recommended to use version 1.0.18 of libmemcached. Fixes - * Fix --disable-memcached-session by ifdef-ing session INI handler callbacks (#396, #420) + * Test on PHP 7.4 as well as 8.0 (#440) + * Fix segfault for unknown memcached flags (#431) + * Update documented defaults for sess_lock_retries( #432) + * Remove stray instances of the TSRMLS_CC macro for PHP 8 compatibility (#444) @@ -203,6 +206,26 @@ Fixes + + + stable + stable + + + 3.1.3 + 3.0.0 + + 2018-12-22 + +PHP 7.0 - 7.1 - 7.2 - 7.3 release of memcached extension. Note that support for +libmemcached 0.x series has been discontinued and the oldest actively tested +version is 1.0.8. It is highly recommended to use version 1.0.18 of +libmemcached. + +Fixes + * Fix --disable-memcached-session by ifdef-ing session INI handler callbacks (#396, #420) + + stable From 5fd997fc68674a192db19c32c4c46aa201fff215 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sun, 6 Oct 2019 09:01:37 -0700 Subject: [PATCH 113/218] Bump version to 3.1.4 --- php_memcached.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.h b/php_memcached.h index be1235e7..71e3acef 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -30,7 +30,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.1.3" +#define PHP_MEMCACHED_VERSION "3.1.4" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 03f034f63ea8224cf0072f9bcf3fd9c7b6141290 Mon Sep 17 00:00:00 2001 From: Po-Chuan Hsieh Date: Tue, 19 Nov 2019 02:01:10 +0800 Subject: [PATCH 114/218] Fix build with PHP 7.4 (#445) Build error on FreeBSD with PHP 7.4 RC6: --- php_memcached.lo --- /wrkdirs/usr/ports/databases/pecl-memcached/work-php74/memcached-3.1.4/php_memcached.c:3237:7: error: expected ';' after expression ulong key_index; ^ ; /wrkdirs/usr/ports/databases/pecl-memcached/work-php74/memcached-3.1.4/php_memcached.c:3237:2: error: use of undeclared identifier 'ulong' ulong key_index; ^ /wrkdirs/usr/ports/databases/pecl-memcached/work-php74/memcached-3.1.4/php_memcached.c:3237:8: error: use of undeclared identifier 'key_index' ulong key_index; ^ /wrkdirs/usr/ports/databases/pecl-memcached/work-php74/memcached-3.1.4/php_memcached.c:3250:49: error: use of undeclared identifier 'key_index' ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(options), key_index, key, value) { ^ /wrkdirs/usr/ports/databases/pecl-memcached/work-php74/memcached-3.1.4/php_memcached.c:3255:44: error: use of undeclared identifier 'key_index' if (!php_memc_set_option(intern, (long) key_index, value)) { ^ 5 errors generated. *** [php_memcached.lo] Error code 1 --- php_memcached.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index 85c79901..50636952 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -3234,7 +3234,7 @@ static PHP_METHOD(Memcached, setOptions) zval *options; zend_bool ok = 1; zend_string *key; - ulong key_index; + zend_ulong key_index; zval *value; MEMC_METHOD_INIT_VARS; From 7141624896470d28492a6f39c844f57ea57cbf1f Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Sun, 6 Oct 2019 09:04:40 -0700 Subject: [PATCH 115/218] Fix typo --- package.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.xml b/package.xml index 0cbc9f63..4cf8d3ee 100644 --- a/package.xml +++ b/package.xml @@ -46,7 +46,7 @@ libmemcached. Fixes * Test on PHP 7.4 as well as 8.0 (#440) * Fix segfault for unknown memcached flags (#431) - * Update documented defaults for sess_lock_retries( #432) + * Update documented defaults for sess_lock_retries (#432) * Remove stray instances of the TSRMLS_CC macro for PHP 8 compatibility (#444) From d7daff649406efbd43af3253212b1cb946ff3f85 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 3 Dec 2019 13:56:22 -0800 Subject: [PATCH 116/218] Bump version and release notes for 3.1.5 --- ChangeLog | 5 +++++ package.xml | 32 ++++++++++++++++++++++++++------ php_memcached.h | 2 +- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 05060cb7..31994e3b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ memcached extension changelog +Version 3.1.5 (2019-12-03) +-------------------------- + + * Fix build with PHP 7.4 release due to ulong typedef removal (#445) + Version 3.1.4 (2019-10-06) -------------------------- diff --git a/package.xml b/package.xml index 4cf8d3ee..c5588a3f 100644 --- a/package.xml +++ b/package.xml @@ -27,9 +27,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> aaron@serendipity.cx yes - 2019-10-06 + 2019-12-03 - 3.1.4 + 3.1.5 3.0.0 @@ -44,10 +44,7 @@ version is 1.0.8. It is highly recommended to use version 1.0.18 of libmemcached. Fixes - * Test on PHP 7.4 as well as 8.0 (#440) - * Fix segfault for unknown memcached flags (#431) - * Update documented defaults for sess_lock_retries (#432) - * Remove stray instances of the TSRMLS_CC macro for PHP 8 compatibility (#444) + * Fix build with PHP 7.4 release due to ulong typedef removal (#445) @@ -206,6 +203,29 @@ Fixes + + + stable + stable + + + 3.1.4 + 3.0.0 + + 2019-10-06 + +PHP 7.0 - 7.1 - 7.2 - 7.3 - 7.4 release of memcached extension. Note that support for +libmemcached 0.x series has been discontinued and the oldest actively tested +version is 1.0.8. It is highly recommended to use version 1.0.18 of +libmemcached. + +Fixes + * Test on PHP 7.4 as well as 8.0 (#440) + * Fix segfault for unknown memcached flags (#431) + * Update documented defaults for sess_lock_retries (#432) + * Remove stray instances of the TSRMLS_CC macro for PHP 8 compatibility (#444) + + stable diff --git a/php_memcached.h b/php_memcached.h index 71e3acef..cccb6d47 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -30,7 +30,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.1.4" +#define PHP_MEMCACHED_VERSION "3.1.5" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From ed3f39d07e08517e68acdbf57304da1328d7adac Mon Sep 17 00:00:00 2001 From: Julien Boulen Date: Wed, 11 Mar 2020 12:00:43 +0100 Subject: [PATCH 117/218] Fix memcached.ini comment - use new config name not the old one (#455) --- memcached.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/memcached.ini b/memcached.ini index 5ed79bdb..35548f32 100644 --- a/memcached.ini +++ b/memcached.ini @@ -60,7 +60,7 @@ ; Write data to a number of additional memcached servers ; This is "poor man's HA" as libmemcached calls it. -; If this value is positive and sess_remove_failed is enabled +; If this value is positive and sess_remove_failed_servers is enabled ; when a memcached server fails the session will continue to be available ; from a replica. However, if the failed memcache server ; becomes available again it will read the session from there From 2d43ce8c92c08f4576e57ad88c8521f85e90cd94 Mon Sep 17 00:00:00 2001 From: Jon Desrosiers Date: Tue, 29 Sep 2020 14:16:48 -0400 Subject: [PATCH 118/218] PHP 7.4 is no longer in "snapshot". (#460) --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 22db51da..7d6b57d7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ dist: xenial language: php php: - master - - 7.4snapshot + - 7.4 - 7.3 - 7.2 - 7.1 @@ -34,5 +34,5 @@ script: - ./.travis/travis.sh script $LIBMEMCACHED_VERSION cache: - directories: + directories: - $HOME/cache From c94e014da53cc8a3d0510402f36bc6e5e17bf608 Mon Sep 17 00:00:00 2001 From: Dmitriy Date: Fri, 2 Oct 2020 19:34:31 +0300 Subject: [PATCH 119/218] fix php 8.0 build (#461) fci.no_separation removed on php 8.0. https://github.com/php/php-src/commit/302933daea77663f5759b10accd1d0231393b24c --- php_memcached_server.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/php_memcached_server.c b/php_memcached_server.c index 4c0080e8..870209c1 100644 --- a/php_memcached_server.c +++ b/php_memcached_server.c @@ -63,7 +63,9 @@ long s_invoke_php_callback (php_memc_server_cb_t *cb, zval *params, ssize_t para cb->fci.retval = retval; cb->fci.params = params; cb->fci.param_count = param_count; +#if PHP_VERSION_ID < 80000 cb->fci.no_separation = 1; +#endif if (zend_call_function(&(cb->fci), &(cb->fci_cache)) == FAILURE) { char *buf = php_memc_printable_func(&(cb->fci), &(cb->fci_cache)); From e8f53777d3f578586f2a32f1b3bdcc3f53e74b39 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 8 Oct 2020 11:58:43 +0200 Subject: [PATCH 120/218] generate arginfo from stub for PHP 7 and 8 --- php_memcached.c | 404 +------------------------------- php_memcached.stub.php | 94 ++++++++ php_memcached_arginfo.h | 411 +++++++++++++++++++++++++++++++++ php_memcached_legacy_arginfo.h | 407 ++++++++++++++++++++++++++++++++ tests/bad_construct.phpt | 5 +- tests/bad_construct_8.phpt | 34 +++ tests/expire.phpt | 1 + tests/undefined_set.phpt | 10 +- tests/vbucket.phpt | 20 -- tests/vbucket_error_7.phpt | 40 ++++ tests/vbucket_error_8.phpt | 41 ++++ 11 files changed, 1044 insertions(+), 423 deletions(-) create mode 100644 php_memcached.stub.php create mode 100644 php_memcached_arginfo.h create mode 100644 php_memcached_legacy_arginfo.h create mode 100644 tests/bad_construct_8.phpt create mode 100644 tests/vbucket_error_7.phpt create mode 100644 tests/vbucket_error_8.phpt diff --git a/php_memcached.c b/php_memcached.c index 50636952..147cb4ab 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -1853,7 +1853,7 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke { zval *entries; zend_string *server_key = NULL; - zend_long expiration = 0, ignored; + zend_long expiration = 0; zval *value; zend_string *skey; zend_ulong num_key; @@ -1867,7 +1867,6 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke Z_PARAM_ARRAY(entries) Z_PARAM_OPTIONAL Z_PARAM_LONG(expiration) - Z_PARAM_LONG(ignored) ZEND_PARSE_PARAMETERS_END(); } else { /* "a|ll" */ @@ -1875,7 +1874,6 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke Z_PARAM_ARRAY(entries) Z_PARAM_OPTIONAL Z_PARAM_LONG(expiration) - Z_PARAM_LONG(ignored) ZEND_PARSE_PARAMETERS_END(); } @@ -2071,7 +2069,6 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) zend_string *server_key = NULL; zval *value; zend_long expiration = 0; - zend_long ignored; zend_string *payload; uint32_t flags = 0; memcached_return status; @@ -2086,7 +2083,6 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) Z_PARAM_ZVAL(value) Z_PARAM_OPTIONAL Z_PARAM_LONG(expiration) - Z_PARAM_LONG(ignored) ZEND_PARSE_PARAMETERS_END(); } else { /* "zSz|ll" */ @@ -2096,7 +2092,6 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) Z_PARAM_ZVAL(value) Z_PARAM_OPTIONAL Z_PARAM_LONG(expiration) - Z_PARAM_LONG(ignored) ZEND_PARSE_PARAMETERS_END(); } @@ -3862,395 +3857,10 @@ PHP_METHOD(MemcachedServer, on) #endif -/* {{{ methods arginfo */ -ZEND_BEGIN_ARG_INFO_EX(arginfo___construct, 0, 0, 0) - ZEND_ARG_INFO(0, persistent_id) - ZEND_ARG_INFO(0, callback) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getResultCode, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getResultMessage, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_get, 0, 0, 1) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, cache_cb) - ZEND_ARG_INFO(0, get_flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_getByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, cache_cb) - ZEND_ARG_INFO(0, get_flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_getMulti, 0, 0, 1) - ZEND_ARG_ARRAY_INFO(0, keys, 0) - ZEND_ARG_INFO(0, get_flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_getMultiByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_ARRAY_INFO(0, keys, 0) - ZEND_ARG_INFO(0, get_flags) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_getDelayed, 0, 0, 1) - ZEND_ARG_ARRAY_INFO(0, keys, 0) - ZEND_ARG_INFO(0, with_cas) - ZEND_ARG_INFO(0, value_cb) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_getDelayedByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_ARRAY_INFO(0, keys, 0) - ZEND_ARG_INFO(0, with_cas) - ZEND_ARG_INFO(0, value_cb) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_fetch, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_fetchAll, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_set, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_setByKey, 0, 0, 3) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_touch, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_touchByKey, 0, 0, 3) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_setMulti, 0, 0, 1) - ZEND_ARG_ARRAY_INFO(0, items, 0) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_setMultiByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_ARRAY_INFO(0, items, 0) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_add, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_addByKey, 0, 0, 3) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_replace, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_replaceByKey, 0, 0, 3) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_append, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_appendByKey, 0, 0, 3) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_prepend, 0, 0, 2) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_prependByKey, 0, 0, 3) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_cas, 0, 0, 3) - ZEND_ARG_INFO(0, cas_token) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_casByKey, 0, 0, 4) - ZEND_ARG_INFO(0, cas_token) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, value) - ZEND_ARG_INFO(0, expiration) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_delete, 0, 0, 1) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, time) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_deleteMulti, 0, 0, 1) - ZEND_ARG_INFO(0, keys) - ZEND_ARG_INFO(0, time) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_deleteByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, time) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_deleteMultiByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, keys) - ZEND_ARG_INFO(0, time) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_increment, 0, 0, 1) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, offset) - ZEND_ARG_INFO(0, initial_value) - ZEND_ARG_INFO(0, expiry) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_decrement, 0, 0, 1) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, offset) - ZEND_ARG_INFO(0, initial_value) - ZEND_ARG_INFO(0, expiry) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_incrementByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, offset) - ZEND_ARG_INFO(0, initial_value) - ZEND_ARG_INFO(0, expiry) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_decrementByKey, 0, 0, 2) - ZEND_ARG_INFO(0, server_key) - ZEND_ARG_INFO(0, key) - ZEND_ARG_INFO(0, offset) - ZEND_ARG_INFO(0, initial_value) - ZEND_ARG_INFO(0, expiry) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_flush, 0, 0, 0) - ZEND_ARG_INFO(0, delay) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_addServer, 0, 0, 2) - ZEND_ARG_INFO(0, host) - ZEND_ARG_INFO(0, port) - ZEND_ARG_INFO(0, weight) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_getStats, 0, 0, 0) - ZEND_ARG_INFO(0, type) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_addServers, 0) - ZEND_ARG_ARRAY_INFO(0, servers, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getServerList, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_resetServerList, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_quit, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_flushBuffers, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getServerByKey, 0) - ZEND_ARG_INFO(0, server_key) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorMessage, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorCode, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getLastErrorErrno, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getLastDisconnectedServer, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getOption, 0) - ZEND_ARG_INFO(0, option) -ZEND_END_ARG_INFO() - -#ifdef HAVE_MEMCACHED_SASL -ZEND_BEGIN_ARG_INFO(arginfo_setSaslAuthData, 0) - ZEND_ARG_INFO(0, username) - ZEND_ARG_INFO(0, password) -ZEND_END_ARG_INFO() -#endif - -#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY -ZEND_BEGIN_ARG_INFO(arginfo_setEncodingKey, 0) - ZEND_ARG_INFO(0, key) -ZEND_END_ARG_INFO() -#endif - -ZEND_BEGIN_ARG_INFO(arginfo_setOption, 0) - ZEND_ARG_INFO(0, option) - ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_setOptions, 0) - ZEND_ARG_INFO(0, options) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_setBucket, 3) - ZEND_ARG_INFO(0, host_map) - ZEND_ARG_INFO(0, forward_map) - ZEND_ARG_INFO(0, replicas) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getVersion, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_isPersistent, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_isPristine, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO(arginfo_getAllKeys, 0) -ZEND_END_ARG_INFO() -/* }}} */ - -/* {{{ memcached_class_methods */ -#define MEMC_ME(name, args) PHP_ME(Memcached, name, args, ZEND_ACC_PUBLIC) -static zend_function_entry memcached_class_methods[] = { - MEMC_ME(__construct, arginfo___construct) - - MEMC_ME(getResultCode, arginfo_getResultCode) - MEMC_ME(getResultMessage, arginfo_getResultMessage) - - MEMC_ME(get, arginfo_get) - MEMC_ME(getByKey, arginfo_getByKey) - MEMC_ME(getMulti, arginfo_getMulti) - MEMC_ME(getMultiByKey, arginfo_getMultiByKey) - MEMC_ME(getDelayed, arginfo_getDelayed) - MEMC_ME(getDelayedByKey, arginfo_getDelayedByKey) - MEMC_ME(fetch, arginfo_fetch) - MEMC_ME(fetchAll, arginfo_fetchAll) - - MEMC_ME(set, arginfo_set) - MEMC_ME(setByKey, arginfo_setByKey) - - MEMC_ME(touch, arginfo_touch) - MEMC_ME(touchByKey, arginfo_touchByKey) - - MEMC_ME(setMulti, arginfo_setMulti) - MEMC_ME(setMultiByKey, arginfo_setMultiByKey) - - MEMC_ME(cas, arginfo_cas) - MEMC_ME(casByKey, arginfo_casByKey) - MEMC_ME(add, arginfo_add) - MEMC_ME(addByKey, arginfo_addByKey) - MEMC_ME(append, arginfo_append) - MEMC_ME(appendByKey, arginfo_appendByKey) - MEMC_ME(prepend, arginfo_prepend) - MEMC_ME(prependByKey, arginfo_prependByKey) - MEMC_ME(replace, arginfo_replace) - MEMC_ME(replaceByKey, arginfo_replaceByKey) - MEMC_ME(delete, arginfo_delete) - MEMC_ME(deleteMulti, arginfo_deleteMulti) - MEMC_ME(deleteByKey, arginfo_deleteByKey) - MEMC_ME(deleteMultiByKey, arginfo_deleteMultiByKey) - - MEMC_ME(increment, arginfo_increment) - MEMC_ME(decrement, arginfo_decrement) - MEMC_ME(incrementByKey, arginfo_incrementByKey) - MEMC_ME(decrementByKey, arginfo_decrementByKey) - - MEMC_ME(addServer, arginfo_addServer) - MEMC_ME(addServers, arginfo_addServers) - MEMC_ME(getServerList, arginfo_getServerList) - MEMC_ME(getServerByKey, arginfo_getServerByKey) - MEMC_ME(resetServerList, arginfo_resetServerList) - MEMC_ME(quit, arginfo_quit) - MEMC_ME(flushBuffers, arginfo_flushBuffers) - - MEMC_ME(getLastErrorMessage, arginfo_getLastErrorMessage) - MEMC_ME(getLastErrorCode, arginfo_getLastErrorCode) - MEMC_ME(getLastErrorErrno, arginfo_getLastErrorErrno) - MEMC_ME(getLastDisconnectedServer, arginfo_getLastDisconnectedServer) - - MEMC_ME(getStats, arginfo_getStats) - MEMC_ME(getVersion, arginfo_getVersion) - MEMC_ME(getAllKeys, arginfo_getAllKeys) - - MEMC_ME(flush, arginfo_flush) - - MEMC_ME(getOption, arginfo_getOption) - MEMC_ME(setOption, arginfo_setOption) - MEMC_ME(setOptions, arginfo_setOptions) - MEMC_ME(setBucket, arginfo_setBucket) -#ifdef HAVE_MEMCACHED_SASL - MEMC_ME(setSaslAuthData, arginfo_setSaslAuthData) -#endif -#ifdef HAVE_MEMCACHED_SET_ENCODING_KEY - MEMC_ME(setEncodingKey, arginfo_setEncodingKey) -#endif - MEMC_ME(isPersistent, arginfo_isPersistent) - MEMC_ME(isPristine, arginfo_isPristine) - { NULL, NULL, NULL } -}; -#undef MEMC_ME -/* }}} */ - -#ifdef HAVE_MEMCACHED_PROTOCOL -/* {{{ */ -#define MEMC_SE_ME(name, args) PHP_ME(MemcachedServer, name, args, ZEND_ACC_PUBLIC) -static -zend_function_entry memcached_server_class_methods[] = { - MEMC_SE_ME(run, NULL) - MEMC_SE_ME(on, NULL) - { NULL, NULL, NULL } -}; -#undef MEMC_SE_ME -/* }}} */ +#if PHP_VERSION_ID < 80000 +#include "php_memcached_legacy_arginfo.h" +#else +#include "php_memcached_arginfo.h" #endif /* {{{ memcached_module_entry @@ -4592,7 +4202,7 @@ PHP_MINIT_FUNCTION(memcached) le_memc = zend_register_list_destructors_ex(NULL, php_memc_dtor, "Memcached persistent connection", module_number); - INIT_CLASS_ENTRY(ce, "Memcached", memcached_class_methods); + INIT_CLASS_ENTRY(ce, "Memcached", class_Memcached_methods); memcached_ce = zend_register_internal_class(&ce); memcached_ce->create_object = php_memc_object_new; @@ -4602,7 +4212,7 @@ PHP_MINIT_FUNCTION(memcached) memcached_server_object_handlers.clone_obj = NULL; memcached_server_object_handlers.free_obj = php_memc_server_free_storage; - INIT_CLASS_ENTRY(ce, "MemcachedServer", memcached_server_class_methods); + INIT_CLASS_ENTRY(ce, "MemcachedServer", class_MemcachedServer_methods); memcached_server_ce = zend_register_internal_class(&ce); memcached_server_ce->create_object = php_memc_server_new; #endif diff --git a/php_memcached.stub.php b/php_memcached.stub.php new file mode 100644 index 00000000..4ba6d5b6 --- /dev/null +++ b/php_memcached.stub.php @@ -0,0 +1,94 @@ + += 80000) die("skip PHP 7 only"); +?> --FILE-- +--FILE-- +getMessage() . PHP_EOL; +} + +class extended extends Memcached { + public function __construct () { + } +} + +error_reporting(E_ALL); +$extended = new extended (); +var_dump ($extended->setOption (Memcached::OPT_BINARY_PROTOCOL, true)); + +echo "OK" . PHP_EOL; + +--EXPECTF-- +Memcached::__construct(): Argument #1 ($persistent_id) must be of type ?string, stdClass given + +Warning: Memcached::setOption(): Memcached constructor was not called in %s +NULL +OK + diff --git a/tests/expire.phpt b/tests/expire.phpt index eac02408..4fb49c55 100644 --- a/tests/expire.phpt +++ b/tests/expire.phpt @@ -7,6 +7,7 @@ https://code.google.com/p/memcached/issues/detail?id=275 $min_version = "1.4.8"; include dirname(__FILE__) . "/skipif.inc"; if (!method_exists("memcached", "touch")) die ("skip memcached::touch is not available"); +if (getenv("SKIP_SLOW_TESTS")) die('skip slow test'); ?> --FILE-- set($key, $value, $no_time); var_dump($rv); ?> --EXPECTF-- -Notice: Undefined variable: no_key in %s +%s: Undefined variable%sno_key in %s bool(false) -Notice: Undefined variable: no_value in %s +%s: Undefined variable%sno_value in %s bool(true) -Notice: Undefined variable: no_key in %s +%s: Undefined variable%sno_key in %s -Notice: Undefined variable: no_value in %s +%s: Undefined variable%sno_value in %s bool(false) -Notice: Undefined variable: no_time in %s +%s: Undefined variable%sno_time in %s bool(true) diff --git a/tests/vbucket.phpt b/tests/vbucket.phpt index f17eb94a..a691680d 100644 --- a/tests/vbucket.phpt +++ b/tests/vbucket.phpt @@ -18,14 +18,6 @@ var_dump ($m->setBucket (array (1,2,2), array (1,2,2), 2)); var_dump ($m->setBucket (array ('a', 'b', 'c'), null, 2)); -var_dump ($m->setBucket (array (), null, 2)); - -var_dump ($m->setBucket (array (), array (), -1)); - -var_dump ($m->setBucket (null, array (), -1)); - -var_dump ($m->setBucket (array (-1), array (-1), 1)); - echo "OK\n"; ?> @@ -33,16 +25,4 @@ echo "OK\n"; bool(true) bool(true) bool(true) - -Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d -bool(false) - -Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d -bool(false) - -Warning: Memcached::setBucket() expects parameter 1 to be array, null given in %s on line %d -NULL - -Warning: Memcached::setBucket(): the map must contain positive integers in %s on line %d -bool(false) OK diff --git a/tests/vbucket_error_7.phpt b/tests/vbucket_error_7.phpt new file mode 100644 index 00000000..286534af --- /dev/null +++ b/tests/vbucket_error_7.phpt @@ -0,0 +1,40 @@ +--TEST-- +Memcached virtual buckets +--SKIPIF-- += 80000) die("skip PHP 7 only"); +?> +--FILE-- + Memcached::DISTRIBUTION_VIRTUAL_BUCKET + )); + +var_dump ($m->setBucket (array (), null, 2)); + +var_dump ($m->setBucket (array (), array (), -1)); + +var_dump ($m->setBucket (null, array (), -1)); + +var_dump ($m->setBucket (array (-1), array (-1), 1)); + +echo "OK\n"; + +?> +--EXPECTF-- + +Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d +bool(false) + +Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d +bool(false) + +Warning: Memcached::setBucket() expects parameter 1 to be array, null given in %s on line %d +NULL + +Warning: Memcached::setBucket(): the map must contain positive integers in %s on line %d +bool(false) +OK diff --git a/tests/vbucket_error_8.phpt b/tests/vbucket_error_8.phpt new file mode 100644 index 00000000..c8af2315 --- /dev/null +++ b/tests/vbucket_error_8.phpt @@ -0,0 +1,41 @@ +--TEST-- +Memcached virtual buckets +--SKIPIF-- + +--FILE-- + Memcached::DISTRIBUTION_VIRTUAL_BUCKET + )); + +var_dump ($m->setBucket (array (), null, 2)); + +var_dump ($m->setBucket (array (), array (), -1)); + +try { + var_dump ($m->setBucket (null, array (), -1)); +} catch (TypeError $e) { + echo $e->getMessage() . PHP_EOL; +} + +var_dump ($m->setBucket (array (-1), array (-1), 1)); + +echo "OK\n"; + +?> +--EXPECTF-- +Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d +bool(false) + +Warning: Memcached::setBucket(): server map cannot be empty in %s on line %d +bool(false) +Memcached::setBucket(): Argument #1 ($host_map) must be of type array, null given + +Warning: Memcached::setBucket(): the map must contain positive integers in %s on line %d +bool(false) +OK From 18945f9b5867e3c4c7016ded29801da7337301ec Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 8 Oct 2020 12:37:20 +0200 Subject: [PATCH 121/218] add new file to pecl archive --- package.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/package.xml b/package.xml index c5588a3f..ec44bd1b 100644 --- a/package.xml +++ b/package.xml @@ -59,6 +59,9 @@ Fixes + + + @@ -133,10 +136,13 @@ Fixes + + + From baa6bfda6fbf4c1c75b5a7492db4cc40e6aa81f3 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 8 Oct 2020 13:45:49 +0200 Subject: [PATCH 122/218] cleanup HAVE_SPL, removed in 8 as always there --- php_memcached.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 147cb4ab..8d9040ec 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -55,6 +55,8 @@ # include "ext/msgpack/php_msgpack.h" #endif +# include "ext/spl/spl_exceptions.h" + static int le_memc; static int php_memc_list_entry(void) { @@ -251,10 +253,6 @@ static zend_class_entry *memcached_ce = NULL; static zend_class_entry *memcached_exception_ce = NULL; static zend_object_handlers memcached_object_handlers; -#ifdef HAVE_SPL -static zend_class_entry *spl_ce_RuntimeException = NULL; -#endif - ZEND_DECLARE_MODULE_GLOBALS(php_memcached) #ifdef COMPILE_DL_MEMCACHED @@ -3764,7 +3762,6 @@ zend_class_entry *php_memc_get_exception(void) PHP_MEMCACHED_API zend_class_entry *php_memc_get_exception_base(int root) { -#ifdef HAVE_SPL if (!root) { if (!spl_ce_RuntimeException) { zend_class_entry *pce; @@ -3781,7 +3778,7 @@ zend_class_entry *php_memc_get_exception_base(int root) return spl_ce_RuntimeException; } } -#endif + return zend_exception_get_default(); } @@ -3877,10 +3874,8 @@ static const zend_module_dep memcached_deps[] = { #ifdef HAVE_MEMCACHED_MSGPACK ZEND_MOD_REQUIRED("msgpack") #endif -#ifdef HAVE_SPL ZEND_MOD_REQUIRED("spl") -#endif - {NULL, NULL, NULL} + ZEND_MOD_END }; #endif From 38ad2e0b0923230472118f97b3471529ee2353b2 Mon Sep 17 00:00:00 2001 From: Julien Boulen Date: Fri, 9 Oct 2020 11:52:03 +0200 Subject: [PATCH 123/218] Fix memcached.ini comment - remove reference to old config name (#456) Co-authored-by: julien --- memcached.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/memcached.ini b/memcached.ini index 35548f32..c11db719 100644 --- a/memcached.ini +++ b/memcached.ini @@ -85,7 +85,6 @@ ; Session SASL username ; Both username and password need to be set for SASL to be enabled -; In addition to this memcached.use_sasl needs to be on ;memcached.sess_sasl_username = NULL ; Session SASL password From a452d9a1e59ae0bc58174d7bd8101ee440d4aa1d Mon Sep 17 00:00:00 2001 From: hulk Date: Fri, 9 Oct 2020 02:53:09 -0700 Subject: [PATCH 124/218] MOD: don't re-set the libmemcached option if not modified (#451) libmemcached would close all connections if the option(like MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) was set, even though value wasn't modified. --- php_memcached.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/php_memcached.c b/php_memcached.c index 8d9040ec..4389fd2f 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -3104,6 +3104,11 @@ int php_memc_set_option(php_memc_object_t *intern, long option, zval *value) lval = zval_get_long(value); if (flag < MEMCACHED_BEHAVIOR_MAX) { + // don't reset the option when the option value wasn't modified, + // while the libmemcached may shutdown all connections. + if (memcached_behavior_get(intern->memc, flag) == (uint64_t)lval) { + return 1; + } rc = memcached_behavior_set(intern->memc, flag, (uint64_t)lval); } else { From 7120d80cb9dc69a58c552ce44304c1e2f0eeaee3 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 9 Oct 2020 03:23:41 -0700 Subject: [PATCH 125/218] Set TCP_NODELAY when setting binary protocol (#421) * Set TCP_NODELAY when setting binary protocol * Add braces to the check_set_behavior macro --- php_memcached.c | 5 +++++ php_memcached_session.c | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index 4389fd2f..85799730 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -1286,6 +1286,11 @@ static PHP_METHOD(Memcached, __construct) if (rc != MEMCACHED_SUCCESS) { php_error_docref(NULL, E_WARNING, "Failed to turn on binary protocol: %s", memcached_strerror(intern->memc, rc)); } + /* Also enable TCP_NODELAY when binary protocol is enabled */ + rc = memcached_behavior_set(intern->memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, 1); + if (rc != MEMCACHED_SUCCESS) { + php_error_docref(NULL, E_WARNING, "Failed to set TCP_NODELAY: %s", memcached_strerror(intern->memc, rc)); + } } if (MEMC_G(default_behavior.connect_timeout)) { diff --git a/php_memcached_session.c b/php_memcached_session.c index ce9a46db..e509cb84 100644 --- a/php_memcached_session.c +++ b/php_memcached_session.c @@ -178,7 +178,9 @@ void s_unlock_session(memcached_st *memc) static zend_bool s_configure_from_ini_values(memcached_st *memc, zend_bool silent) { +/* This macro looks like a function but returns errors directly */ #define check_set_behavior(behavior, value) \ +{ \ int b = (behavior); \ uint64_t v = (value); \ if (v != memcached_behavior_get(memc, b)) { \ @@ -189,10 +191,13 @@ zend_bool s_configure_from_ini_values(memcached_st *memc, zend_bool silent) } \ return 0; \ } \ - } + } \ +} if (MEMC_SESS_INI(binary_protocol_enabled)) { check_set_behavior(MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, 1); + /* Also enable TCP_NODELAY when binary protocol is enabled */ + check_set_behavior(MEMCACHED_BEHAVIOR_TCP_NODELAY, 1); } if (MEMC_SESS_INI(consistent_hash_enabled)) { From f97b2e3ad95bbd83c862abba08c34ac3f4acc497 Mon Sep 17 00:00:00 2001 From: SpencerMalone Date: Fri, 9 Oct 2020 04:49:58 -0700 Subject: [PATCH 126/218] Include a fuller list of response constants from libmemcached (#457) --- php_memcached.c | 69 +++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 85799730..d49b7d57 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -4073,34 +4073,47 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) * libmemcached result codes */ - REGISTER_MEMC_CLASS_CONST_LONG(RES_SUCCESS, MEMCACHED_SUCCESS); - REGISTER_MEMC_CLASS_CONST_LONG(RES_FAILURE, MEMCACHED_FAILURE); - REGISTER_MEMC_CLASS_CONST_LONG(RES_HOST_LOOKUP_FAILURE, MEMCACHED_HOST_LOOKUP_FAILURE); - REGISTER_MEMC_CLASS_CONST_LONG(RES_UNKNOWN_READ_FAILURE, MEMCACHED_UNKNOWN_READ_FAILURE); - REGISTER_MEMC_CLASS_CONST_LONG(RES_PROTOCOL_ERROR, MEMCACHED_PROTOCOL_ERROR); - REGISTER_MEMC_CLASS_CONST_LONG(RES_CLIENT_ERROR, MEMCACHED_CLIENT_ERROR); - REGISTER_MEMC_CLASS_CONST_LONG(RES_SERVER_ERROR, MEMCACHED_SERVER_ERROR); - REGISTER_MEMC_CLASS_CONST_LONG(RES_WRITE_FAILURE, MEMCACHED_WRITE_FAILURE); - REGISTER_MEMC_CLASS_CONST_LONG(RES_DATA_EXISTS, MEMCACHED_DATA_EXISTS); - REGISTER_MEMC_CLASS_CONST_LONG(RES_NOTSTORED, MEMCACHED_NOTSTORED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_NOTFOUND, MEMCACHED_NOTFOUND); - REGISTER_MEMC_CLASS_CONST_LONG(RES_PARTIAL_READ, MEMCACHED_PARTIAL_READ); - REGISTER_MEMC_CLASS_CONST_LONG(RES_SOME_ERRORS, MEMCACHED_SOME_ERRORS); - REGISTER_MEMC_CLASS_CONST_LONG(RES_NO_SERVERS, MEMCACHED_NO_SERVERS); - REGISTER_MEMC_CLASS_CONST_LONG(RES_END, MEMCACHED_END); - REGISTER_MEMC_CLASS_CONST_LONG(RES_ERRNO, MEMCACHED_ERRNO); - REGISTER_MEMC_CLASS_CONST_LONG(RES_BUFFERED, MEMCACHED_BUFFERED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_TIMEOUT, MEMCACHED_TIMEOUT); - REGISTER_MEMC_CLASS_CONST_LONG(RES_BAD_KEY_PROVIDED, MEMCACHED_BAD_KEY_PROVIDED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_STORED, MEMCACHED_STORED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_DELETED, MEMCACHED_DELETED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_STAT, MEMCACHED_STAT); - REGISTER_MEMC_CLASS_CONST_LONG(RES_ITEM, MEMCACHED_ITEM); - REGISTER_MEMC_CLASS_CONST_LONG(RES_NOT_SUPPORTED, MEMCACHED_NOT_SUPPORTED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_FETCH_NOTFINISHED, MEMCACHED_FETCH_NOTFINISHED); - REGISTER_MEMC_CLASS_CONST_LONG(RES_SERVER_MARKED_DEAD, MEMCACHED_SERVER_MARKED_DEAD); - REGISTER_MEMC_CLASS_CONST_LONG(RES_UNKNOWN_STAT_KEY, MEMCACHED_UNKNOWN_STAT_KEY); - REGISTER_MEMC_CLASS_CONST_LONG(RES_INVALID_HOST_PROTOCOL, MEMCACHED_INVALID_HOST_PROTOCOL); + REGISTER_MEMC_CLASS_CONST_LONG(RES_SUCCESS, MEMCACHED_SUCCESS); + REGISTER_MEMC_CLASS_CONST_LONG(RES_FAILURE, MEMCACHED_FAILURE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_HOST_LOOKUP_FAILURE, MEMCACHED_HOST_LOOKUP_FAILURE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_CONNECTION_FAILURE, MEMCACHED_CONNECTION_FAILURE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_CONNECTION_BIND_FAILURE, MEMCACHED_CONNECTION_BIND_FAILURE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_WRITE_FAILURE, MEMCACHED_WRITE_FAILURE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_READ_FAILURE, MEMCACHED_READ_FAILURE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_UNKNOWN_READ_FAILURE, MEMCACHED_UNKNOWN_READ_FAILURE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_PROTOCOL_ERROR, MEMCACHED_PROTOCOL_ERROR); + REGISTER_MEMC_CLASS_CONST_LONG(RES_CLIENT_ERROR, MEMCACHED_CLIENT_ERROR); + REGISTER_MEMC_CLASS_CONST_LONG(RES_SERVER_ERROR, MEMCACHED_SERVER_ERROR); + REGISTER_MEMC_CLASS_CONST_LONG(RES_DATA_EXISTS, MEMCACHED_DATA_EXISTS); + REGISTER_MEMC_CLASS_CONST_LONG(RES_DATA_DOES_NOT_EXIST, MEMCACHED_DATA_DOES_NOT_EXIST); + REGISTER_MEMC_CLASS_CONST_LONG(RES_NOTSTORED, MEMCACHED_NOTSTORED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_STORED, MEMCACHED_STORED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_NOTFOUND, MEMCACHED_NOTFOUND); + REGISTER_MEMC_CLASS_CONST_LONG(RES_PARTIAL_READ, MEMCACHED_PARTIAL_READ); + REGISTER_MEMC_CLASS_CONST_LONG(RES_SOME_ERRORS, MEMCACHED_SOME_ERRORS); + REGISTER_MEMC_CLASS_CONST_LONG(RES_NO_SERVERS, MEMCACHED_NO_SERVERS); + REGISTER_MEMC_CLASS_CONST_LONG(RES_END, MEMCACHED_END); + REGISTER_MEMC_CLASS_CONST_LONG(RES_DELETED, MEMCACHED_DELETED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_VALUE, MEMCACHED_VALUE); + REGISTER_MEMC_CLASS_CONST_LONG(RES_STAT, MEMCACHED_STAT); + REGISTER_MEMC_CLASS_CONST_LONG(RES_ITEM, MEMCACHED_ITEM); + REGISTER_MEMC_CLASS_CONST_LONG(RES_ERRNO, MEMCACHED_ERRNO); + REGISTER_MEMC_CLASS_CONST_LONG(RES_FAIL_UNIX_SOCKET, MEMCACHED_FAIL_UNIX_SOCKET); + REGISTER_MEMC_CLASS_CONST_LONG(RES_NOT_SUPPORTED, MEMCACHED_NOT_SUPPORTED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_NO_KEY_PROVIDED, MEMCACHED_NO_KEY_PROVIDED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_FETCH_NOTFINISHED, MEMCACHED_FETCH_NOTFINISHED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_TIMEOUT, MEMCACHED_TIMEOUT); + REGISTER_MEMC_CLASS_CONST_LONG(RES_BUFFERED, MEMCACHED_BUFFERED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_BAD_KEY_PROVIDED, MEMCACHED_BAD_KEY_PROVIDED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_INVALID_HOST_PROTOCOL, MEMCACHED_INVALID_HOST_PROTOCOL); + REGISTER_MEMC_CLASS_CONST_LONG(RES_SERVER_MARKED_DEAD, MEMCACHED_SERVER_MARKED_DEAD); + REGISTER_MEMC_CLASS_CONST_LONG(RES_UNKNOWN_STAT_KEY, MEMCACHED_UNKNOWN_STAT_KEY); + REGISTER_MEMC_CLASS_CONST_LONG(RES_INVALID_ARGUMENTS, MEMCACHED_INVALID_ARGUMENTS); + REGISTER_MEMC_CLASS_CONST_LONG(RES_PARSE_ERROR, MEMCACHED_PARSE_ERROR); + REGISTER_MEMC_CLASS_CONST_LONG(RES_PARSE_USER_ERROR, MEMCACHED_PARSE_USER_ERROR); + REGISTER_MEMC_CLASS_CONST_LONG(RES_DEPRECATED, MEMCACHED_DEPRECATED); + REGISTER_MEMC_CLASS_CONST_LONG(RES_IN_PROGRESS, MEMCACHED_IN_PROGRESS); + REGISTER_MEMC_CLASS_CONST_LONG(RES_MAXIMUM_RETURN, MEMCACHED_MAXIMUM_RETURN); REGISTER_MEMC_CLASS_CONST_LONG(RES_MEMORY_ALLOCATION_FAILURE, MEMCACHED_MEMORY_ALLOCATION_FAILURE); REGISTER_MEMC_CLASS_CONST_LONG(RES_CONNECTION_SOCKET_CREATE_FAILURE, MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE); From 9a429d43f8a4aab9292287502a3393588e2255c1 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 17 Nov 2020 12:04:15 +0100 Subject: [PATCH 127/218] Promote error "Memcached constructor was not called" to exception with PHP 8 (#465) For consistency with other PHP 8 extensions. --- php_memcached.c | 11 +++++++++++ tests/bad_construct_8.phpt | 12 +++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index d49b7d57..1e218a00 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -195,6 +195,7 @@ static inline php_memc_object_t *php_memc_fetch_object(zend_object *obj) { php_memc_object_t* intern = NULL; \ php_memc_user_data_t* memc_user_data = NULL; +#if PHP_VERSION_ID < 80000 #define MEMC_METHOD_FETCH_OBJECT \ intern = Z_MEMC_OBJ_P(object); \ if (!intern->memc) { \ @@ -203,6 +204,16 @@ static inline php_memc_object_t *php_memc_fetch_object(zend_object *obj) { } \ memc_user_data = (php_memc_user_data_t *) memcached_get_user_data(intern->memc); \ (void)memc_user_data; /* avoid unused variable warning */ +#else +#define MEMC_METHOD_FETCH_OBJECT \ + intern = Z_MEMC_OBJ_P(object); \ + if (!intern->memc) { \ + zend_throw_error(NULL, "Memcached constructor was not called"); \ + RETURN_THROWS(); \ + } \ + memc_user_data = (php_memc_user_data_t *) memcached_get_user_data(intern->memc); \ + (void)memc_user_data; /* avoid unused variable warning */ +#endif static zend_bool s_memc_valid_key_binary(zend_string *key) diff --git a/tests/bad_construct_8.phpt b/tests/bad_construct_8.phpt index 81daa5a5..10928cfd 100644 --- a/tests/bad_construct_8.phpt +++ b/tests/bad_construct_8.phpt @@ -20,15 +20,17 @@ class extended extends Memcached { } error_reporting(E_ALL); -$extended = new extended (); -var_dump ($extended->setOption (Memcached::OPT_BINARY_PROTOCOL, true)); +try { + $extended = new extended (); + var_dump ($extended->setOption (Memcached::OPT_BINARY_PROTOCOL, true)); +} catch (Error $e) { + echo $e->getMessage() . PHP_EOL; +} echo "OK" . PHP_EOL; --EXPECTF-- Memcached::__construct(): Argument #1 ($persistent_id) must be of type ?string, stdClass given - -Warning: Memcached::setOption(): Memcached constructor was not called in %s -NULL +Memcached constructor was not called OK From 8f3c5dc0fa773aded5d169e5c5b8eab18c8931c6 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 1 Dec 2020 04:09:57 +0100 Subject: [PATCH 128/218] fix php8 arginfo (#467) --- php_memcached.stub.php | 14 +++++++------- php_memcached_arginfo.h | 28 ++++++++++++++-------------- php_memcached_legacy_arginfo.h | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/php_memcached.stub.php b/php_memcached.stub.php index 4ba6d5b6..e44ff4aa 100644 --- a/php_memcached.stub.php +++ b/php_memcached.stub.php @@ -35,16 +35,16 @@ public function cas(string $cas_token, string $key, mixed $value, int $expiratio public function casByKey(string $cas_token, string $server_key, string $key, mixed $value, int $expiration=0): bool {} public function add(string $key, mixed $value, int $expiration=0): bool {} public function addByKey(string $server_key, string $key, mixed $value, int $expiration=0): bool {} - public function append(string $key, string $value): bool {} - public function appendByKey(string $server_key, string $key, string $value): bool {} - public function prepend(string $key, string $value): bool {} - public function prependByKey(string $server_key, string $key, string $value): bool {} + public function append(string $key, string $value): ?bool {} + public function appendByKey(string $server_key, string $key, string $value): ?bool {} + public function prepend(string $key, string $value): ?bool {} + public function prependByKey(string $server_key, string $key, string $value): ?bool {} public function replace(string $key, mixed $value, int $expiration=0): bool {} public function replaceByKey(string $server_key, string $key, mixed $value, int $expiration=0): bool {} public function delete(string $key, int $time=0): bool {} - public function deleteMulti(array $keys, int $time=0): bool {} + public function deleteMulti(array $keys, int $time=0): array {} public function deleteByKey(string $server_key, string $key, int $time=0): bool {} - public function deleteMultiByKey(string $server_key, array $keys, int $time=0): bool {} + public function deleteMultiByKey(string $server_key, array $keys, int $time=0): array {} public function increment(string $key, int $offset=1, int $initial_value=0, int $expiry=0): false|int {} public function decrement(string $key, int $offset=1, int $initial_value=0, int $expiry=0): false|int {} @@ -73,7 +73,7 @@ public function flush(int $delay=0): bool {} public function getOption(int $option): mixed {} public function setOption(int $option, mixed $value): bool {} public function setOptions(array $options): bool {} - public function setBucket(array $host_map, array $forward_map, int $replicas): bool {} + public function setBucket(array $host_map, ?array $forward_map, int $replicas): bool {} #ifdef HAVE_MEMCACHED_SASL public function setSaslAuthData(string $username, string $password): bool {} #endif diff --git a/php_memcached_arginfo.h b/php_memcached_arginfo.h index 6729dd36..18b17cc7 100644 --- a/php_memcached_arginfo.h +++ b/php_memcached_arginfo.h @@ -1,10 +1,10 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: a33d23c6659922e98d3704879eb4bc820e1819df */ + * Stub hash: 3e5af769d67ce91bd713bb11b325a9ccaabbfb7a */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, persistent_id, IS_STRING, 0, "NULL") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, callback, IS_CALLABLE, 0, "NULL") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, connection_str, IS_STRING, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, persistent_id, IS_STRING, 1, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, callback, IS_CALLABLE, 1, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, connection_str, IS_STRING, 1, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getResultCode, 0, 0, IS_LONG, 0) @@ -15,14 +15,14 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_get, 0, 1, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cache_cb, IS_CALLABLE, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cache_cb, IS_CALLABLE, 1, "NULL") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, get_flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getByKey, 0, 2, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, server_key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cache_cb, IS_CALLABLE, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cache_cb, IS_CALLABLE, 1, "NULL") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, get_flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() @@ -40,14 +40,14 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getDelayed, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, with_cas, _IS_BOOL, 0, "0") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value_cb, IS_CALLABLE, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value_cb, IS_CALLABLE, 1, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getDelayedByKey, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, server_key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, with_cas, _IS_BOOL, 0, "0") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value_cb, IS_CALLABLE, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value_cb, IS_CALLABLE, 1, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_fetch, 0, 0, MAY_BE_FALSE|MAY_BE_ARRAY) @@ -109,12 +109,12 @@ ZEND_END_ARG_INFO() #define arginfo_class_Memcached_addByKey arginfo_class_Memcached_setByKey -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_append, 0, 2, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_append, 0, 2, _IS_BOOL, 1) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_appendByKey, 0, 3, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_appendByKey, 0, 3, _IS_BOOL, 1) ZEND_ARG_TYPE_INFO(0, server_key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, value, IS_STRING, 0) @@ -133,7 +133,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_delete, 0, 1, _I ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, time, IS_LONG, 0, "0") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_deleteMulti, 0, 1, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_deleteMulti, 0, 1, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, time, IS_LONG, 0, "0") ZEND_END_ARG_INFO() @@ -144,7 +144,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_deleteByKey, 0, ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, time, IS_LONG, 0, "0") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_deleteMultiByKey, 0, 2, _IS_BOOL, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_deleteMultiByKey, 0, 2, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO(0, server_key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, time, IS_LONG, 0, "0") @@ -202,7 +202,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_Memcached_getLastDisconnectedServer arginfo_class_Memcached_fetch ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_getStats, 0, 0, MAY_BE_FALSE|MAY_BE_ARRAY) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_STRING, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_STRING, 1, "NULL") ZEND_END_ARG_INFO() #define arginfo_class_Memcached_getVersion arginfo_class_Memcached_fetch @@ -228,7 +228,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_setBucket, 0, 3, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, host_map, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO(0, forward_map, IS_ARRAY, 0) + ZEND_ARG_TYPE_INFO(0, forward_map, IS_ARRAY, 1) ZEND_ARG_TYPE_INFO(0, replicas, IS_LONG, 0) ZEND_END_ARG_INFO() diff --git a/php_memcached_legacy_arginfo.h b/php_memcached_legacy_arginfo.h index 6f21d2a8..2c0b2de3 100644 --- a/php_memcached_legacy_arginfo.h +++ b/php_memcached_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: a33d23c6659922e98d3704879eb4bc820e1819df */ + * Stub hash: 3e5af769d67ce91bd713bb11b325a9ccaabbfb7a */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) ZEND_ARG_INFO(0, persistent_id) From fc33513d32504843fe0864f9855d3a0b37a76ddc Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 3 Dec 2020 09:16:42 -0800 Subject: [PATCH 129/218] Add PHP 8.0 to the Travis CI matrix, use 'nightly' builds (#462) --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7d6b57d7..5478b296 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,8 @@ dist: xenial language: php php: - - master + - nightly + - 8.0 - 7.4 - 7.3 - 7.2 @@ -12,7 +13,7 @@ php: matrix: fast_finish: true allow_failures: - - php: master + - php: nightly env: - LIBMEMCACHED_VERSION=1.0.18 # Debian Jessie / Ubuntu Xenial From b8202146903692e3ae2f2f7ad9915c3c03928ac3 Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Thu, 17 Dec 2020 20:00:42 +0000 Subject: [PATCH 130/218] Fixed ParseError in stub file (#468) Match PHP 7 version of the file which has NULL as the default value of this bool argument. --- php_memcached.stub.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php_memcached.stub.php b/php_memcached.stub.php index e44ff4aa..6b84c5b7 100644 --- a/php_memcached.stub.php +++ b/php_memcached.stub.php @@ -17,8 +17,8 @@ public function get(string $key, callable $cache_cb=NULL, int $get_flags=0): mix public function getByKey(string $server_key, string $key, callable $cache_cb=NULL, int $get_flags=0): mixed {} public function getMulti(array $keys, int $get_flags=0): false|array {} public function getMultiByKey(string $server_key, array $keys, int $get_flags=0): false|array {} - public function getDelayed(array $keys, bool $with_cas=0, callable $value_cb=NULL): bool {} - public function getDelayedByKey(string $server_key, array $keys, bool $with_cas=0, callable $value_cb=NULL): bool {} + public function getDelayed(array $keys, bool $with_cas=NULL, callable $value_cb=NULL): bool {} + public function getDelayedByKey(string $server_key, array $keys, bool $with_cas=NULL, callable $value_cb=NULL): bool {} public function fetch(): false|array {} public function fetchAll(): false|array {} From bfb0a66809d43080219ab5381235f848c91eff7e Mon Sep 17 00:00:00 2001 From: Graham Campbell Date: Fri, 18 Dec 2020 23:40:15 +0000 Subject: [PATCH 131/218] Re-generated .h files after stubs were modified (#469) --- php_memcached_arginfo.h | 22 +++++++++++----------- php_memcached_legacy_arginfo.h | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/php_memcached_arginfo.h b/php_memcached_arginfo.h index 18b17cc7..6b05cf4c 100644 --- a/php_memcached_arginfo.h +++ b/php_memcached_arginfo.h @@ -1,10 +1,10 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3e5af769d67ce91bd713bb11b325a9ccaabbfb7a */ + * Stub hash: 8ce11ff45ccb2b1c765e5f313305f539ca3fa4f6 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, persistent_id, IS_STRING, 1, "NULL") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, callback, IS_CALLABLE, 1, "NULL") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, connection_str, IS_STRING, 1, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, persistent_id, IS_STRING, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, callback, IS_CALLABLE, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, connection_str, IS_STRING, 0, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getResultCode, 0, 0, IS_LONG, 0) @@ -15,14 +15,14 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_get, 0, 1, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cache_cb, IS_CALLABLE, 1, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cache_cb, IS_CALLABLE, 0, "NULL") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, get_flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getByKey, 0, 2, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, server_key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cache_cb, IS_CALLABLE, 1, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cache_cb, IS_CALLABLE, 0, "NULL") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, get_flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() @@ -39,15 +39,15 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getDelayed, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, with_cas, _IS_BOOL, 0, "0") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value_cb, IS_CALLABLE, 1, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, with_cas, _IS_BOOL, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value_cb, IS_CALLABLE, 0, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getDelayedByKey, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, server_key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, with_cas, _IS_BOOL, 0, "0") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value_cb, IS_CALLABLE, 1, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, with_cas, _IS_BOOL, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value_cb, IS_CALLABLE, 0, "NULL") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_fetch, 0, 0, MAY_BE_FALSE|MAY_BE_ARRAY) @@ -202,7 +202,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_Memcached_getLastDisconnectedServer arginfo_class_Memcached_fetch ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_getStats, 0, 0, MAY_BE_FALSE|MAY_BE_ARRAY) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_STRING, 1, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_STRING, 0, "NULL") ZEND_END_ARG_INFO() #define arginfo_class_Memcached_getVersion arginfo_class_Memcached_fetch diff --git a/php_memcached_legacy_arginfo.h b/php_memcached_legacy_arginfo.h index 2c0b2de3..c9426166 100644 --- a/php_memcached_legacy_arginfo.h +++ b/php_memcached_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3e5af769d67ce91bd713bb11b325a9ccaabbfb7a */ + * Stub hash: 8ce11ff45ccb2b1c765e5f313305f539ca3fa4f6 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) ZEND_ARG_INFO(0, persistent_id) From c8f9376a8b1399907e732064890101da7261d8bb Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Mon, 18 Jan 2021 16:34:41 +0100 Subject: [PATCH 132/218] fix php8 arginfo (#472) --- php_memcached.stub.php | 12 ++++++------ php_memcached_arginfo.h | 22 +++++++++++----------- php_memcached_legacy_arginfo.h | 2 +- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/php_memcached.stub.php b/php_memcached.stub.php index 6b84c5b7..5a735b57 100644 --- a/php_memcached.stub.php +++ b/php_memcached.stub.php @@ -8,17 +8,17 @@ class Memcached { - public function __construct(string $persistent_id=NULL, callable $callback=NULL, string $connection_str=NULL) {} + public function __construct(string $persistent_id=null, callable $callback=null, string $connection_str=null) {} public function getResultCode(): int {} public function getResultMessage(): string {} - public function get(string $key, callable $cache_cb=NULL, int $get_flags=0): mixed {} - public function getByKey(string $server_key, string $key, callable $cache_cb=NULL, int $get_flags=0): mixed {} + public function get(string $key, callable $cache_cb=null, int $get_flags=0): mixed {} + public function getByKey(string $server_key, string $key, callable $cache_cb=null, int $get_flags=0): mixed {} public function getMulti(array $keys, int $get_flags=0): false|array {} public function getMultiByKey(string $server_key, array $keys, int $get_flags=0): false|array {} - public function getDelayed(array $keys, bool $with_cas=NULL, callable $value_cb=NULL): bool {} - public function getDelayedByKey(string $server_key, array $keys, bool $with_cas=NULL, callable $value_cb=NULL): bool {} + public function getDelayed(array $keys, bool $with_cas=false, callable $value_cb=null): bool {} + public function getDelayedByKey(string $server_key, array $keys, bool $with_cas=false, callable $value_cb=null): bool {} public function fetch(): false|array {} public function fetchAll(): false|array {} @@ -64,7 +64,7 @@ public function getLastErrorCode(): int {} public function getLastErrorErrno(): int {} public function getLastDisconnectedServer(): false|array {} - public function getStats(string $type=NULL): false|array {} + public function getStats(string $type=null): false|array {} public function getVersion(): false|array {} public function getAllKeys(): false|array {} diff --git a/php_memcached_arginfo.h b/php_memcached_arginfo.h index 6b05cf4c..4c8a6845 100644 --- a/php_memcached_arginfo.h +++ b/php_memcached_arginfo.h @@ -1,10 +1,10 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 8ce11ff45ccb2b1c765e5f313305f539ca3fa4f6 */ + * Stub hash: 573d35c5c6b6c397943e0f8ab9c505e2f4ce9e34 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, persistent_id, IS_STRING, 0, "NULL") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, callback, IS_CALLABLE, 0, "NULL") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, connection_str, IS_STRING, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, persistent_id, IS_STRING, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, callback, IS_CALLABLE, 1, "null") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, connection_str, IS_STRING, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getResultCode, 0, 0, IS_LONG, 0) @@ -15,14 +15,14 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_get, 0, 1, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cache_cb, IS_CALLABLE, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cache_cb, IS_CALLABLE, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, get_flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getByKey, 0, 2, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, server_key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cache_cb, IS_CALLABLE, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, cache_cb, IS_CALLABLE, 1, "null") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, get_flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() @@ -39,15 +39,15 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getDelayed, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, with_cas, _IS_BOOL, 0, "NULL") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value_cb, IS_CALLABLE, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, with_cas, _IS_BOOL, 0, "false") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value_cb, IS_CALLABLE, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getDelayedByKey, 0, 2, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, server_key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, with_cas, _IS_BOOL, 0, "NULL") - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value_cb, IS_CALLABLE, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, with_cas, _IS_BOOL, 0, "false") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value_cb, IS_CALLABLE, 1, "null") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_fetch, 0, 0, MAY_BE_FALSE|MAY_BE_ARRAY) @@ -202,7 +202,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_Memcached_getLastDisconnectedServer arginfo_class_Memcached_fetch ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_getStats, 0, 0, MAY_BE_FALSE|MAY_BE_ARRAY) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_STRING, 0, "NULL") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_STRING, 1, "null") ZEND_END_ARG_INFO() #define arginfo_class_Memcached_getVersion arginfo_class_Memcached_fetch diff --git a/php_memcached_legacy_arginfo.h b/php_memcached_legacy_arginfo.h index c9426166..a615e3a6 100644 --- a/php_memcached_legacy_arginfo.h +++ b/php_memcached_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 8ce11ff45ccb2b1c765e5f313305f539ca3fa4f6 */ + * Stub hash: 573d35c5c6b6c397943e0f8ab9c505e2f4ce9e34 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) ZEND_ARG_INFO(0, persistent_id) From 19a02bb5bfaeb520b857a2d64172f7d2a9615fb3 Mon Sep 17 00:00:00 2001 From: Arjen de Korte Date: Thu, 21 Jan 2021 04:06:53 +0100 Subject: [PATCH 133/218] Don't expect tests/expire to fail (#475) The issue reported in https://code.google.com/archive/p/memcached/issues/275 was fixed more than 8 years ago and the test is no longer expected to fail --- tests/expire.phpt | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/expire.phpt b/tests/expire.phpt index 4fb49c55..d53309e7 100644 --- a/tests/expire.phpt +++ b/tests/expire.phpt @@ -1,7 +1,5 @@ --TEST-- Memcached store, fetch & touch expired key ---XFAIL-- -https://code.google.com/p/memcached/issues/detail?id=275 --SKIPIF-- Date: Wed, 9 Jun 2021 14:53:43 +0200 Subject: [PATCH 134/218] fix incorrect zp, fixes #484 --- php_memcached.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 1e218a00..d2f23434 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -1876,7 +1876,7 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke if (by_key) { /* "Sa|ll" */ - ZEND_PARSE_PARAMETERS_START(2, 4) + ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_STR(server_key) Z_PARAM_ARRAY(entries) Z_PARAM_OPTIONAL @@ -1884,7 +1884,7 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke ZEND_PARSE_PARAMETERS_END(); } else { /* "a|ll" */ - ZEND_PARSE_PARAMETERS_START(1, 3) + ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_ARRAY(entries) Z_PARAM_OPTIONAL Z_PARAM_LONG(expiration) From 51c9baf49f96c5f35be8257549f426ef1860f0ef Mon Sep 17 00:00:00 2001 From: Joe Watkins Date: Wed, 9 Jun 2021 14:58:37 +0200 Subject: [PATCH 135/218] fix zpp in mem_cas_impl --- php_memcached.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index d2f23434..2ea93604 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -2089,8 +2089,8 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) MEMC_METHOD_INIT_VARS; if (by_key) { - /* "zSSz|ll" */ - ZEND_PARSE_PARAMETERS_START(4, 6) + /* "zSSz|l" */ + ZEND_PARSE_PARAMETERS_START(4, 5) Z_PARAM_ZVAL(zv_cas) Z_PARAM_STR(server_key) Z_PARAM_STR(key) @@ -2099,8 +2099,8 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) Z_PARAM_LONG(expiration) ZEND_PARSE_PARAMETERS_END(); } else { - /* "zSz|ll" */ - ZEND_PARSE_PARAMETERS_START(3, 5) + /* "zSz|l" */ + ZEND_PARSE_PARAMETERS_START(3, 4) Z_PARAM_ZVAL(zv_cas) Z_PARAM_STR(key) Z_PARAM_ZVAL(value) From 899e4dc27c672b1617a232e9757809bf0dd5b89a Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 9 Jun 2021 14:30:12 +0200 Subject: [PATCH 136/218] fix test for PHP 8.1 --- tests/undefined_set.phpt | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/tests/undefined_set.phpt b/tests/undefined_set.phpt index caeda19d..581c9406 100644 --- a/tests/undefined_set.phpt +++ b/tests/undefined_set.phpt @@ -10,30 +10,25 @@ $m = memc_get_instance (); $key = 'foobarbazDEADC0DE'; $value = array('foo' => 'bar'); -$rv = $m->set($no_key, $value, 360); +// silent to hide: +// Warning: Undefined variable +// Deprecated: Memcached::set(): Passing null to parameter (PHP 8.1) + +$rv = @$m->set($no_key, $value, 360); var_dump($rv); -$rv = $m->set($key, $no_value, 360); +$rv = @$m->set($key, $no_value, 360); var_dump($rv); -$rv = $m->set($no_key, $no_value, 360); +$rv = @$m->set($no_key, $no_value, 360); var_dump($rv); -$rv = $m->set($key, $value, $no_time); +$rv = @$m->set($key, $value, $no_time); var_dump($rv); ?> --EXPECTF-- -%s: Undefined variable%sno_key in %s bool(false) - -%s: Undefined variable%sno_value in %s bool(true) - -%s: Undefined variable%sno_key in %s - -%s: Undefined variable%sno_value in %s bool(false) - -%s: Undefined variable%sno_time in %s bool(true) From 0c3f411e710a360a41c256c310f3e7440acb5add Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 9 Jun 2021 14:30:12 +0200 Subject: [PATCH 137/218] fix test for PHP 8.1 --- tests/undefined_set.phpt | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/tests/undefined_set.phpt b/tests/undefined_set.phpt index caeda19d..581c9406 100644 --- a/tests/undefined_set.phpt +++ b/tests/undefined_set.phpt @@ -10,30 +10,25 @@ $m = memc_get_instance (); $key = 'foobarbazDEADC0DE'; $value = array('foo' => 'bar'); -$rv = $m->set($no_key, $value, 360); +// silent to hide: +// Warning: Undefined variable +// Deprecated: Memcached::set(): Passing null to parameter (PHP 8.1) + +$rv = @$m->set($no_key, $value, 360); var_dump($rv); -$rv = $m->set($key, $no_value, 360); +$rv = @$m->set($key, $no_value, 360); var_dump($rv); -$rv = $m->set($no_key, $no_value, 360); +$rv = @$m->set($no_key, $no_value, 360); var_dump($rv); -$rv = $m->set($key, $value, $no_time); +$rv = @$m->set($key, $value, $no_time); var_dump($rv); ?> --EXPECTF-- -%s: Undefined variable%sno_key in %s bool(false) - -%s: Undefined variable%sno_value in %s bool(true) - -%s: Undefined variable%sno_key in %s - -%s: Undefined variable%sno_value in %s bool(false) - -%s: Undefined variable%sno_time in %s bool(true) From c2a31946f0be9a12d2ebb54f876da9dce17c40a3 Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Thu, 25 Feb 2021 06:52:02 -0800 Subject: [PATCH 138/218] Fix stubs to make them consistent for PHP 8 --- php_memcached.stub.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/php_memcached.stub.php b/php_memcached.stub.php index 5a735b57..1efc5877 100644 --- a/php_memcached.stub.php +++ b/php_memcached.stub.php @@ -8,17 +8,17 @@ class Memcached { - public function __construct(string $persistent_id=null, callable $callback=null, string $connection_str=null) {} + public function __construct(?string $persistent_id=null, ?callable $callback=null, ?string $connection_str=null) {} public function getResultCode(): int {} public function getResultMessage(): string {} - public function get(string $key, callable $cache_cb=null, int $get_flags=0): mixed {} - public function getByKey(string $server_key, string $key, callable $cache_cb=null, int $get_flags=0): mixed {} + public function get(string $key, ?callable $cache_cb=null, int $get_flags=0): mixed {} + public function getByKey(string $server_key, string $key, ?callable $cache_cb=null, int $get_flags=0): mixed {} public function getMulti(array $keys, int $get_flags=0): false|array {} public function getMultiByKey(string $server_key, array $keys, int $get_flags=0): false|array {} - public function getDelayed(array $keys, bool $with_cas=false, callable $value_cb=null): bool {} - public function getDelayedByKey(string $server_key, array $keys, bool $with_cas=false, callable $value_cb=null): bool {} + public function getDelayed(array $keys, bool $with_cas=false, ?callable $value_cb=null): bool {} + public function getDelayedByKey(string $server_key, array $keys, bool $with_cas=false, ?callable $value_cb=null): bool {} public function fetch(): false|array {} public function fetchAll(): false|array {} @@ -64,7 +64,7 @@ public function getLastErrorCode(): int {} public function getLastErrorErrno(): int {} public function getLastDisconnectedServer(): false|array {} - public function getStats(string $type=null): false|array {} + public function getStats(?string $type=null): false|array {} public function getVersion(): false|array {} public function getAllKeys(): false|array {} From 7bbf4fbad3b25cb2628b96eafce50d19f22e3b47 Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Thu, 25 Feb 2021 07:52:54 -0800 Subject: [PATCH 139/218] Expose internal key check via checkKey() method Make ascii key check consistent with libmemcached's isgraph() check Add test to check that they match --- php_memcached.c | 20 +++++++++++++++++++- php_memcached.stub.php | 1 + php_memcached_arginfo.h | 8 +++++++- php_memcached_legacy_arginfo.h | 8 +++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 2ea93604..d49cbeb4 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -228,7 +228,7 @@ zend_bool s_memc_valid_key_ascii(zend_string *key) size_t i, len = ZSTR_LEN(key); for (i = 0; i < len; i++) { - if (iscntrl(str[i]) || isspace(str[i])) + if (!isgraph(str[i]) || isspace(str[i])) return 0; } return 1; @@ -3450,6 +3450,24 @@ static PHP_METHOD(Memcached, isPristine) } /* }}} */ +/* {{{ bool Memcached::checkKey(string key) + Checks if a key is valid */ +PHP_METHOD(Memcached, checkKey) +{ + zend_string *key; + MEMC_METHOD_INIT_VARS; + + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(key) + ZEND_PARSE_PARAMETERS_END(); + + MEMC_METHOD_FETCH_OBJECT; + s_memc_set_status(intern, MEMCACHED_SUCCESS, 0); + MEMC_CHECK_KEY(intern, key); + RETURN_TRUE; +} +/* }}} */ + /**************************************** Internal support code ****************************************/ diff --git a/php_memcached.stub.php b/php_memcached.stub.php index 1efc5877..819186f4 100644 --- a/php_memcached.stub.php +++ b/php_memcached.stub.php @@ -83,6 +83,7 @@ public function setEncodingKey(string $key): bool {} #endif public function isPersistent(): bool {} public function isPristine(): bool {} + public function checkKey(string $key): bool {} } #ifdef HAVE_MEMCACHED_PROTOCOL diff --git a/php_memcached_arginfo.h b/php_memcached_arginfo.h index 4c8a6845..3373624e 100644 --- a/php_memcached_arginfo.h +++ b/php_memcached_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 573d35c5c6b6c397943e0f8ab9c505e2f4ce9e34 */ + * Stub hash: 3f4694d4e1f3d1647a832acd8539b056b2ab5e7a */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, persistent_id, IS_STRING, 1, "null") @@ -249,6 +249,10 @@ ZEND_END_ARG_INFO() #define arginfo_class_Memcached_isPristine arginfo_class_Memcached_resetServerList +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_checkKey, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) +ZEND_END_ARG_INFO() + #if defined(HAVE_MEMCACHED_PROTOCOL) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_MemcachedServer_run, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, address, IS_STRING, 0) @@ -325,6 +329,7 @@ ZEND_METHOD(Memcached, setEncodingKey); #endif ZEND_METHOD(Memcached, isPersistent); ZEND_METHOD(Memcached, isPristine); +ZEND_METHOD(Memcached, checkKey); #if defined(HAVE_MEMCACHED_PROTOCOL) ZEND_METHOD(MemcachedServer, run); #endif @@ -396,6 +401,7 @@ static const zend_function_entry class_Memcached_methods[] = { #endif ZEND_ME(Memcached, isPersistent, arginfo_class_Memcached_isPersistent, ZEND_ACC_PUBLIC) ZEND_ME(Memcached, isPristine, arginfo_class_Memcached_isPristine, ZEND_ACC_PUBLIC) + ZEND_ME(Memcached, checkKey, arginfo_class_Memcached_checkKey, ZEND_ACC_PUBLIC) ZEND_FE_END }; diff --git a/php_memcached_legacy_arginfo.h b/php_memcached_legacy_arginfo.h index a615e3a6..ad6d6562 100644 --- a/php_memcached_legacy_arginfo.h +++ b/php_memcached_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 573d35c5c6b6c397943e0f8ab9c505e2f4ce9e34 */ + * Stub hash: 3f4694d4e1f3d1647a832acd8539b056b2ab5e7a */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) ZEND_ARG_INFO(0, persistent_id) @@ -245,6 +245,10 @@ ZEND_END_ARG_INFO() #define arginfo_class_Memcached_isPristine arginfo_class_Memcached_getResultCode +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached_checkKey, 0, 0, 1) + ZEND_ARG_INFO(0, key) +ZEND_END_ARG_INFO() + #if defined(HAVE_MEMCACHED_PROTOCOL) ZEND_BEGIN_ARG_INFO_EX(arginfo_class_MemcachedServer_run, 0, 0, 1) ZEND_ARG_INFO(0, address) @@ -321,6 +325,7 @@ ZEND_METHOD(Memcached, setEncodingKey); #endif ZEND_METHOD(Memcached, isPersistent); ZEND_METHOD(Memcached, isPristine); +ZEND_METHOD(Memcached, checkKey); #if defined(HAVE_MEMCACHED_PROTOCOL) ZEND_METHOD(MemcachedServer, run); #endif @@ -392,6 +397,7 @@ static const zend_function_entry class_Memcached_methods[] = { #endif ZEND_ME(Memcached, isPersistent, arginfo_class_Memcached_isPersistent, ZEND_ACC_PUBLIC) ZEND_ME(Memcached, isPristine, arginfo_class_Memcached_isPristine, ZEND_ACC_PUBLIC) + ZEND_ME(Memcached, checkKey, arginfo_class_Memcached_checkKey, ZEND_ACC_PUBLIC) ZEND_FE_END }; From 7be9f007799ccdd9018176a0a3ea3cf7c7d56ab0 Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Thu, 25 Feb 2021 07:55:27 -0800 Subject: [PATCH 140/218] Add test --- package.xml | 1 + tests/check_key.phpt | 132 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 tests/check_key.phpt diff --git a/package.xml b/package.xml index ec44bd1b..519de583 100644 --- a/package.xml +++ b/package.xml @@ -87,6 +87,7 @@ Fixes + diff --git a/tests/check_key.phpt b/tests/check_key.phpt new file mode 100644 index 00000000..74ec6214 --- /dev/null +++ b/tests/check_key.phpt @@ -0,0 +1,132 @@ +--TEST-- +Memcached::checkKey() +--SKIPIF-- + +--FILE-- + false, + Memcached::OPT_VERIFY_KEY => true + )); + +$keys = [ + 'foo', + 'foo bar', + str_repeat('a',65), + str_repeat('b',250), + str_repeat('c',251), + 'Montréal', + 'København', + 'Düsseldorf', + 'Kraków', + 'İstanbul', + 'ﺎﺨﺘﺑﺍﺭ PHP', + '測試', + 'Тестирование', + 'پی ایچ پی کی جانچ ہو رہی ہے', + 'Testataan PHP: tä', + 'Að prófa PHP', + 'د پی ایچ پی ازمول', + 'Pruvà PHP' +]; +foreach($keys as $key) { + echo "Checking \"$key\"" . PHP_EOL; + echo "MEMC_CHECK_KEY: "; + var_dump($m->checkKey($key)); + echo "libmemcached: "; + var_dump($m->set($key, "this is a test")); + var_dump($m->getResultMessage()); + echo "\n"; +} +--EXPECT-- +Checking "foo" +MEMC_CHECK_KEY: bool(true) +libmemcached: bool(true) +string(7) "SUCCESS" + +Checking "foo bar" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +MEMC_CHECK_KEY: bool(true) +libmemcached: bool(true) +string(7) "SUCCESS" + +Checking "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" +MEMC_CHECK_KEY: bool(true) +libmemcached: bool(true) +string(7) "SUCCESS" + +Checking "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Montréal" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "København" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Düsseldorf" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Kraków" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "İstanbul" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "ﺎﺨﺘﺑﺍﺭ PHP" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "測試" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Тестирование" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "پی ایچ پی کی جانچ ہو رہی ہے" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Testataan PHP: tä" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Að prófa PHP" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "د پی ایچ پی ازمول" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + +Checking "Pruvà PHP" +MEMC_CHECK_KEY: bool(false) +libmemcached: bool(false) +string(46) "A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE" + From 8ed8092c7f4c07e170f38465dbf89a3447fe35cd Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 19 Jan 2021 16:16:30 +0100 Subject: [PATCH 141/218] fix MemcachedServer related: #418, m6w6/libmemcached#94 --- php_memcached.c | 3 ++ php_memcached_server.c | 80 +++++++++++++++++++++++------------ server-example/run-server.php | 2 +- 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index d49cbeb4..e7a28e0a 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -3520,6 +3520,8 @@ static void php_memc_server_free_storage(zend_object *object) { php_memc_server_t *intern = php_memc_server_fetch_object(object); + + php_memc_proto_handler_destroy(&intern->handler); zend_object_std_dtor(&intern->zo); } @@ -3533,6 +3535,7 @@ zend_object *php_memc_server_new(zend_class_entry *ce) object_properties_init(&intern->zo, ce); intern->zo.handlers = &memcached_server_object_handlers; + intern->handler = php_memc_proto_handler_new(); return &intern->zo; } diff --git a/php_memcached_server.c b/php_memcached_server.c index 870209c1..e816b90d 100644 --- a/php_memcached_server.c +++ b/php_memcached_server.c @@ -17,13 +17,16 @@ #include "php_memcached.h" #include "php_memcached_private.h" #include "php_memcached_server.h" +#include "php_network.h" #include -#undef NDEBUG -#undef _NDEBUG #include +#if HAVE_ARPA_INET_H +# include +#endif + #define MEMC_GET_CB(cb_type) (MEMC_SERVER_G(callbacks)[cb_type]) #define MEMC_HAS_CB(cb_type) (MEMC_GET_CB(cb_type).fci.size > 0) @@ -58,9 +61,9 @@ typedef struct { static long s_invoke_php_callback (php_memc_server_cb_t *cb, zval *params, ssize_t param_count) { - zval *retval = NULL; + zval retval; - cb->fci.retval = retval; + cb->fci.retval = &retval; cb->fci.params = params; cb->fci.param_count = param_count; #if PHP_VERSION_ID < 80000 @@ -73,7 +76,7 @@ long s_invoke_php_callback (php_memc_server_cb_t *cb, zval *params, ssize_t para efree (buf); } - return retval == NULL ? PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND : zval_get_long(retval); + return Z_ISUNDEF(retval) ? PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND : zval_get_long(&retval); } // memcached protocol callbacks @@ -96,6 +99,7 @@ protocol_binary_response_status s_add_handler(const void *cookie, const void *ke ZVAL_LONG(&zflags, flags); ZVAL_LONG(&zexptime, exptime); ZVAL_NULL(&zresult_cas); + ZVAL_MAKE_REF(&zresult_cas); ZVAL_COPY(¶ms[0], &zcookie); ZVAL_COPY(¶ms[1], &zkey); @@ -142,6 +146,7 @@ protocol_binary_response_status s_append_prepend_handler (php_memc_event_t event ZVAL_STRINGL(&zvalue, data, data_len); ZVAL_DOUBLE(&zcas, cas); ZVAL_NULL(&zresult_cas); + ZVAL_MAKE_REF(&zresult_cas); ZVAL_COPY(¶ms[0], &zcookie); ZVAL_COPY(¶ms[1], &zkey); @@ -198,11 +203,13 @@ protocol_binary_response_status s_incr_decr_handler (php_memc_event_t event, con MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); ZVAL_STRINGL(&zkey, key, key_len); - ZVAL_LONG(&zdelta, (long) delta); - ZVAL_LONG(&zinital, (long) initial); - ZVAL_LONG(&zexpiration, (long) expiration); + ZVAL_LONG(&zdelta, (zend_long) delta); + ZVAL_LONG(&zinital, (zend_long) initial); + ZVAL_LONG(&zexpiration, (zend_long) expiration); ZVAL_LONG(&zresult, 0); + ZVAL_MAKE_REF(&zresult); ZVAL_NULL(&zresult_cas); + ZVAL_MAKE_REF(&zresult_cas); ZVAL_COPY(¶ms[0], &zcookie); ZVAL_COPY(¶ms[1], &zkey); @@ -322,6 +329,13 @@ protocol_binary_response_status s_get_handler (const void *cookie, const void *k } MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); + ZVAL_STRINGL(&zkey, key, key_len); + ZVAL_NULL(&zvalue); + ZVAL_MAKE_REF(&zvalue); + ZVAL_NULL(&zflags); + ZVAL_MAKE_REF(&zflags); + ZVAL_NULL(&zresult_cas); + ZVAL_MAKE_REF(&zresult_cas); ZVAL_COPY(¶ms[0], &zcookie); ZVAL_COPY(¶ms[1], &zkey); @@ -436,11 +450,12 @@ protocol_binary_response_status s_set_replace_handler (php_memc_event_t event, c MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); ZVAL_STRINGL(&zkey, key, key_len); - ZVAL_STRINGL(&zdata, ((char *) data), (int) data_len); - ZVAL_LONG(&zflags, (long) flags); - ZVAL_LONG(&zexpiration, (long) expiration); + ZVAL_STRINGL(&zdata, data, data_len); + ZVAL_LONG(&zflags, (zend_long) flags); + ZVAL_LONG(&zexpiration, (zend_long) expiration); ZVAL_DOUBLE(&zcas, (double) cas); ZVAL_NULL(&zresult_cas); + ZVAL_MAKE_REF(&zresult_cas); ZVAL_COPY(¶ms[0], &zcookie); ZVAL_COPY(¶ms[1], &zkey); @@ -504,6 +519,7 @@ protocol_binary_response_status s_stat_handler (const void *cookie, const void * ZVAL_STRINGL(&zkey, key, key_len); ZVAL_NULL(&zbody); + ZVAL_MAKE_REF(&zbody); ZVAL_COPY(¶ms[0], &zcookie); ZVAL_COPY(¶ms[1], &zkey); @@ -584,17 +600,27 @@ void s_handle_memcached_event (evutil_socket_t fd, short what, void *arg) zval zremoteip, zremoteport; zval params[2]; protocol_binary_response_status retval; - - struct sockaddr_in addr_in; - socklen_t addr_in_len = sizeof(addr_in); - - if (getpeername (fd, (struct sockaddr *) &addr_in, &addr_in_len) == 0) { - ZVAL_STRING(&zremoteip, inet_ntoa (addr_in.sin_addr)); - ZVAL_LONG(&zremoteport, ntohs (addr_in.sin_port)); + struct sockaddr_storage ss; + socklen_t ss_len = sizeof(ss); + + ZVAL_NULL(&zremoteip); + ZVAL_NULL(&zremoteport); + + if (getpeername (fd, (struct sockaddr *) &ss, &ss_len) == 0) { + char addr_buf[0x100]; + + switch (ss.ss_family) { + case AF_INET6: + ZVAL_STRING(&zremoteip, inet_ntop(ss.ss_family, &((struct sockaddr_in6 *) &ss)->sin6_addr, addr_buf, sizeof(addr_buf))); + ZVAL_LONG(&zremoteport, ntohs(((struct sockaddr_in6 *) &ss)->sin6_port)); + break; + case AF_INET: + ZVAL_STRING(&zremoteip, inet_ntop(ss.ss_family, &((struct sockaddr_in *) &ss)->sin_addr, addr_buf, sizeof(addr_buf))); + ZVAL_LONG(&zremoteport, ntohs(((struct sockaddr_in *) &ss)->sin_port)); + break; + } } else { php_error_docref(NULL, E_WARNING, "getpeername failed: %s", strerror (errno)); - ZVAL_NULL(&zremoteip); - ZVAL_NULL(&zremoteport); } ZVAL_COPY(¶ms[0], &zremoteip); @@ -714,22 +740,20 @@ php_memc_proto_handler_t *php_memc_proto_handler_new () } static -evutil_socket_t s_create_listening_socket (const char *spec) +evutil_socket_t s_create_listening_socket (const zend_string *spec) { evutil_socket_t sock; struct sockaddr_storage addr; - int addr_len; - + socklen_t addr_len; int rc; addr_len = sizeof (struct sockaddr); - rc = evutil_parse_sockaddr_port (spec, (struct sockaddr *) &addr, &addr_len); - if (rc != 0) { - php_error_docref(NULL, E_WARNING, "Failed to parse bind address"); + if (SUCCESS != php_network_parse_network_address_with_port(spec->val, spec->len, (struct sockaddr *) &addr, &addr_len)) { + php_error_docref(NULL, E_WARNING, "Failed to parse bind address: %s", spec->val); return -1; } - sock = socket (AF_INET, SOCK_STREAM, 0); + sock = socket (addr.ss_family, SOCK_STREAM, 0); if (sock < 0) { php_error_docref(NULL, E_WARNING, "socket failed: %s", strerror (errno)); return -1; @@ -770,7 +794,7 @@ evutil_socket_t s_create_listening_socket (const char *spec) zend_bool php_memc_proto_handler_run (php_memc_proto_handler_t *handler, zend_string *address) { struct event *accept_event; - evutil_socket_t sock = s_create_listening_socket (address->val); + evutil_socket_t sock = s_create_listening_socket (address); if (sock == -1) { return 0; diff --git a/server-example/run-server.php b/server-example/run-server.php index a02c6a60..a9ba5834 100644 --- a/server-example/run-server.php +++ b/server-example/run-server.php @@ -89,4 +89,4 @@ function ($client_id) { return Memcached::RESPONSE_SUCCESS; }); -$server->run ("127.0.0.1:3434"); \ No newline at end of file +$server->run ("127.0.0.1:3434"); From 46967cc67fb7294893489b8317f5a3cc31b64079 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 19 Jan 2021 16:32:52 +0100 Subject: [PATCH 142/218] use php_network_get_peer_name --- php_memcached_server.c | 38 ++++++++++------------------------- server-example/run-server.php | 4 ++-- 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/php_memcached_server.c b/php_memcached_server.c index e816b90d..fee8d28d 100644 --- a/php_memcached_server.c +++ b/php_memcached_server.c @@ -597,41 +597,25 @@ void s_handle_memcached_event (evutil_socket_t fd, short what, void *arg) if (!client->on_connect_invoked) { if (MEMC_HAS_CB(MEMC_SERVER_ON_CONNECT)) { - zval zremoteip, zremoteport; - zval params[2]; + zend_string *zremoteaddr_str; + zval zremoteaddr; + zval params[1]; protocol_binary_response_status retval; - struct sockaddr_storage ss; - socklen_t ss_len = sizeof(ss); - - ZVAL_NULL(&zremoteip); - ZVAL_NULL(&zremoteport); - - if (getpeername (fd, (struct sockaddr *) &ss, &ss_len) == 0) { - char addr_buf[0x100]; - - switch (ss.ss_family) { - case AF_INET6: - ZVAL_STRING(&zremoteip, inet_ntop(ss.ss_family, &((struct sockaddr_in6 *) &ss)->sin6_addr, addr_buf, sizeof(addr_buf))); - ZVAL_LONG(&zremoteport, ntohs(((struct sockaddr_in6 *) &ss)->sin6_port)); - break; - case AF_INET: - ZVAL_STRING(&zremoteip, inet_ntop(ss.ss_family, &((struct sockaddr_in *) &ss)->sin_addr, addr_buf, sizeof(addr_buf))); - ZVAL_LONG(&zremoteport, ntohs(((struct sockaddr_in *) &ss)->sin_port)); - break; - } + + ZVAL_NULL(&zremoteaddr); + + if (SUCCESS == php_network_get_peer_name (fd, &zremoteaddr_str, NULL, NULL)) { + ZVAL_STR(&zremoteaddr, zremoteaddr_str); } else { php_error_docref(NULL, E_WARNING, "getpeername failed: %s", strerror (errno)); } - ZVAL_COPY(¶ms[0], &zremoteip); - ZVAL_COPY(¶ms[1], &zremoteport); + ZVAL_COPY(¶ms[0], &zremoteaddr); - retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_CONNECT), params, 2); + retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_CONNECT), params, 1); zval_ptr_dtor(¶ms[0]); - zval_ptr_dtor(¶ms[1]); - zval_ptr_dtor(&zremoteip); - zval_ptr_dtor(&zremoteport); + zval_ptr_dtor(&zremoteaddr); if (retval != PROTOCOL_BINARY_RESPONSE_SUCCESS) { memcached_protocol_client_destroy (client->protocol_client); diff --git a/server-example/run-server.php b/server-example/run-server.php index a9ba5834..b7612c80 100644 --- a/server-example/run-server.php +++ b/server-example/run-server.php @@ -3,8 +3,8 @@ $server = new MemcachedServer(); $server->on (Memcached::ON_CONNECT, - function ($remote_ip, $remote_port) { - echo "Incoming connection from {$remote_ip}:{$remote_port}" . PHP_EOL; + function ($remote_addr) { + echo "Incoming connection from {$remote_addr}" . PHP_EOL; return Memcached::RESPONSE_SUCCESS; }); From f4f724caf74f506b6121e87b95239a8a11795284 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 19 Jan 2021 16:34:08 +0100 Subject: [PATCH 143/218] remove unused include again --- php_memcached_server.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/php_memcached_server.c b/php_memcached_server.c index fee8d28d..ce93a2bf 100644 --- a/php_memcached_server.c +++ b/php_memcached_server.c @@ -23,10 +23,6 @@ #include -#if HAVE_ARPA_INET_H -# include -#endif - #define MEMC_GET_CB(cb_type) (MEMC_SERVER_G(callbacks)[cb_type]) #define MEMC_HAS_CB(cb_type) (MEMC_GET_CB(cb_type).fci.size > 0) From 7381ce71b891d8500cecce91da00555366625b5c Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Tue, 19 Jan 2021 16:57:39 +0100 Subject: [PATCH 144/218] as per https://github.com/php-memcached-dev/php-memcached/pull/474#issuecomment-762934191 --- php_memcached_server.c | 1 + 1 file changed, 1 insertion(+) diff --git a/php_memcached_server.c b/php_memcached_server.c index ce93a2bf..1f28d936 100644 --- a/php_memcached_server.c +++ b/php_memcached_server.c @@ -299,6 +299,7 @@ protocol_binary_response_status s_flush_handler(const void *cookie, uint32_t whe } MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); + ZVAL_LONG(&zwhen, when); ZVAL_COPY(¶ms[0], &zcookie); ZVAL_COPY(¶ms[1], &zwhen); From 57f2999ea5113b2b31523c659cfb223a8fd6a5ce Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 20 Jan 2021 10:54:13 +0100 Subject: [PATCH 145/218] add 1 test for MemcachedServer --- tests/memcachedserver.phpt | 58 +++++++++++++++++++++++ tests/server.inc | 78 +++++++++++++++++++++++++++++++ tests/server.php | 94 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 tests/memcachedserver.phpt create mode 100644 tests/server.inc create mode 100644 tests/server.php diff --git a/tests/memcachedserver.phpt b/tests/memcachedserver.phpt new file mode 100644 index 00000000..54b7fe45 --- /dev/null +++ b/tests/memcachedserver.phpt @@ -0,0 +1,58 @@ +--TEST-- +Memcached::get() with cache callback +--SKIPIF-- + +--FILE-- +setOption(Memcached::OPT_BINARY_PROTOCOL, true); +$cache->setOption(Memcached::OPT_COMPRESSION, false); +$cache->addServer('127.0.0.1', 3434); + +$cache->add("add_key", "hello", 500); +$cache->append("append_key", "world"); +$cache->prepend("prepend_key", "world"); + +$cache->increment("incr", 2, 1, 500); +$cache->decrement("decr", 2, 1, 500); + +$cache->delete("delete_k"); +$cache->flush(1); + +var_dump($cache->get('get_this')); + +$cache->set ('set_key', 'value 1', 100); +$cache->replace ('replace_key', 'value 2', 200); + +var_dump($cache->getStats()); + +$cache->quit(); + +memcached_server_stop($server); +?> +Done +--EXPECTF-- +Listening on 127.0.0.1:3434 +Incoming connection from 127.0.0.1:%s +Incoming connection from 127.0.0.1:%s +client_id=[%s]: Add key=[add_key], value=[hello], flags=[0], expiration=[500] +client_id=[%s]: Append key=[append_key], value=[world], cas=[0] +client_id=[%s]: Prepend key=[prepend_key], value=[world], cas=[0] +client_id=[%s]: Incrementing key=[incr], delta=[2], initial=[1], expiration=[500] +client_id=[%s]: Decrementing key=[decr], delta=[2], initial=[1], expiration=[500] +client_id=[%s]: Delete key=[delete_k], cas=[0] +client_id=[%s]: Flush when=[1] +client_id=[%s]: Get key=[get_this] +client_id=[%s]: Noop +string(20) "Hello to you client!" +client_id=[%s]: Set key=[set_key], value=[value 1], flags=[0], expiration=[100], cas=[0] +client_id=[%s]: Replace key=[replace_key], value=[value 2], flags=[0], expiration=[200], cas=[0] +bool(false) +Done diff --git a/tests/server.inc b/tests/server.inc new file mode 100644 index 00000000..96cc942f --- /dev/null +++ b/tests/server.inc @@ -0,0 +1,78 @@ + STDIN, + 1 => STDOUT, + 2 => STDERR, + ); + + $cmd = "{$php_executable} {$php_args} {$code} {$host}:{$port} "; + if (substr(PHP_OS, 0, 3) == 'WIN') { + $cmd = "{$php_executable} {$php_args} {$code} {$host}:{$port} "; + + $handle = proc_open(addslashes($cmd), $descriptorspec, $pipes, __DIR__, NULL, array("bypass_shell" => true, "suppress_errors" => true)); + } else { + $cmd = "exec {$cmd} 2>/dev/null"; + + $handle = proc_open($cmd, $descriptorspec, $pipes, __DIR__); + } + + // note: even when server prints 'Listening on localhost:8964...Press Ctrl-C to quit.' + // it might not be listening yet...need to wait until fsockopen() call returns + $error = "Unable to connect to server\n"; + for ($i=0; $i < 60; $i++) { + usleep(50000); // 50ms per try + $status = proc_get_status($handle); + $fp = @fsockopen($host, $port); + // Failure, the server is no longer running + if (!($status && $status['running'])) { + $error = "Server is not running\n"; + break; + } + // Success, Connected to servers + if ($fp) { + $error = ''; + break; + } + } + + if ($fp) { + fclose($fp); + } + + if ($error) { + echo $error; + proc_terminate($handle); + exit(1); + } + + register_shutdown_function( + function($handle) { + proc_terminate($handle); + }, + $handle + ); + + return $handle; +} + +function memcached_server_stop($handle) { + $success = FALSE; + if ($handle) { + proc_terminate($handle); + /* Wait for server to shutdown */ + for ($i = 0; $i < 60; $i++) { + $status = proc_get_status($handle); + if (!($status && $status['running'])) { + $success = TRUE; + break; + } + usleep(50000); + } + } + return $success; +} + diff --git a/tests/server.php b/tests/server.php new file mode 100644 index 00000000..674f91ac --- /dev/null +++ b/tests/server.php @@ -0,0 +1,94 @@ +on (Memcached::ON_CONNECT, + function ($remote_addr) { + echo "Incoming connection from {$remote_addr}" . PHP_EOL; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_ADD, + function ($client_id, $key, $value, $flags, $expiration, &$cas) { + echo "client_id=[$client_id]: Add key=[$key], value=[$value], flags=[$flags], expiration=[$expiration]" . PHP_EOL; + $cas = 15; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_APPEND, + function ($client_id, $key, $value, $cas, &$result_cas) { + echo "client_id=[$client_id]: Append key=[$key], value=[$value], cas=[$cas]" . PHP_EOL; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_PREPEND, + function ($client_id, $key, $value, $cas, &$result_cas) { + echo "client_id=[$client_id]: Prepend key=[$key], value=[$value], cas=[$cas]" . PHP_EOL; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_INCREMENT, + function ($client_id, $key, $delta, $initial, $expiration, &$result, &$result_cas) { + echo "client_id=[$client_id]: Incrementing key=[$key], delta=[$delta], initial=[$initial], expiration=[$expiration]" . PHP_EOL; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_DECREMENT, + function ($client_id, $key, $delta, $initial, $expiration, &$result, &$result_cas) { + echo "client_id=[$client_id]: Decrementing key=[$key], delta=[$delta], initial=[$initial], expiration=[$expiration]" . PHP_EOL; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_DELETE, + function ($client_id, $key, $cas) { + echo "client_id=[$client_id]: Delete key=[$key], cas=[$cas]" . PHP_EOL; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_FLUSH, + function ($client_id, $when) { + echo "client_id=[$client_id]: Flush when=[$when]" . PHP_EOL; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_GET, + function ($client_id, $key, &$value, &$flags, &$cas) { + echo "client_id=[$client_id]: Get key=[$key]" . PHP_EOL; + $value = "Hello to you client!"; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_NOOP, + function ($client_id) { + echo "client_id=[$client_id]: Noop" . PHP_EOL; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_REPLACE, + function ($client_id, $key, $value, $flags, $expiration, $cas, &$result_cas) { + echo "client_id=[$client_id]: Replace key=[$key], value=[$value], flags=[$flags], expiration=[$expiration], cas=[$cas]" . PHP_EOL; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_SET, + function ($client_id, $key, $value, $flags, $expiration, $cas, &$result_cas) { + echo "client_id=[$client_id]: Set key=[$key], value=[$value], flags=[$flags], expiration=[$expiration], cas=[$cas]" . PHP_EOL; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_STAT, + function ($client_id, $key, &$value) { + echo "client_id=[$client_id]: Stat key=[$key]" . PHP_EOL; + $value = "Stat reply"; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_QUIT, + function ($client_id) { + echo "client_id=[$client_id]: Client quit" . PHP_EOL; + return Memcached::RESPONSE_SUCCESS; + }); + +$addr = ($_SERVER['argv'][1] ?? "127.0.0.1:3434"); +echo "Listening on $addr" . PHP_EOL; +$server->run($addr); From d21814e647f15b654e6fa6009ef49d148e54dffc Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 20 Jan 2021 12:08:53 +0100 Subject: [PATCH 146/218] minor fix for version handler --- php_memcached_server.c | 1 + tests/memcachedserver.phpt | 5 +++-- tests/server.php | 7 +++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/php_memcached_server.c b/php_memcached_server.c index 1f28d936..57cb749b 100644 --- a/php_memcached_server.c +++ b/php_memcached_server.c @@ -560,6 +560,7 @@ protocol_binary_response_status s_version_handler (const void *cookie, MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); ZVAL_NULL(&zversion); + ZVAL_MAKE_REF(&zversion); ZVAL_COPY(¶ms[0], &zcookie); ZVAL_COPY(¶ms[1], &zversion); diff --git a/tests/memcachedserver.phpt b/tests/memcachedserver.phpt index 54b7fe45..6d4abb9d 100644 --- a/tests/memcachedserver.phpt +++ b/tests/memcachedserver.phpt @@ -31,7 +31,8 @@ var_dump($cache->get('get_this')); $cache->set ('set_key', 'value 1', 100); $cache->replace ('replace_key', 'value 2', 200); -var_dump($cache->getStats()); +// TODO var_dump($cache->getVersion()); +// TODO var_dump($cache->getStats()); $cache->quit(); @@ -54,5 +55,5 @@ client_id=[%s]: Noop string(20) "Hello to you client!" client_id=[%s]: Set key=[set_key], value=[value 1], flags=[0], expiration=[100], cas=[0] client_id=[%s]: Replace key=[replace_key], value=[value 2], flags=[0], expiration=[200], cas=[0] -bool(false) +client_id=[%s]: Client quit Done diff --git a/tests/server.php b/tests/server.php index 674f91ac..c39b04e8 100644 --- a/tests/server.php +++ b/tests/server.php @@ -79,6 +79,13 @@ function ($client_id, $key, $value, $flags, $expiration, $cas, &$result_cas) { $server->on (Memcached::ON_STAT, function ($client_id, $key, &$value) { echo "client_id=[$client_id]: Stat key=[$key]" . PHP_EOL; + $value = "Stat reply for $key"; + return Memcached::RESPONSE_SUCCESS; + }); + +$server->on (Memcached::ON_VERSION, + function ($client_id, &$value) { + echo "client_id=[$client_id]: Version" . PHP_EOL; $value = "Stat reply"; return Memcached::RESPONSE_SUCCESS; }); From 0262e5c8031194736c6985f91a9ba7f2c7eea9db Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 20 Jan 2021 16:43:57 +0100 Subject: [PATCH 147/218] handle empty STATS key --- php_memcached_server.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/php_memcached_server.c b/php_memcached_server.c index 57cb749b..d1e903a1 100644 --- a/php_memcached_server.c +++ b/php_memcached_server.c @@ -514,7 +514,11 @@ protocol_binary_response_status s_stat_handler (const void *cookie, const void * MEMC_MAKE_ZVAL_COOKIE(zcookie, cookie); - ZVAL_STRINGL(&zkey, key, key_len); + if (key && key_len) { + ZVAL_STRINGL(&zkey, key, key_len); + } else { + ZVAL_NULL(&zkey); + } ZVAL_NULL(&zbody); ZVAL_MAKE_REF(&zbody); @@ -566,7 +570,6 @@ protocol_binary_response_status s_version_handler (const void *cookie, ZVAL_COPY(¶ms[1], &zversion); retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_VERSION), params, 2); - if (retval == PROTOCOL_BINARY_RESPONSE_SUCCESS) { if (Z_TYPE(zversion) != IS_STRING) { convert_to_string(&zversion); From f064f6c817b899a7c0e8ea089c81163c66a9be05 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 20 Jan 2021 16:51:34 +0100 Subject: [PATCH 148/218] fix running the server from command line --- tests/server.inc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/server.inc b/tests/server.inc index 96cc942f..5700a9d2 100644 --- a/tests/server.inc +++ b/tests/server.inc @@ -1,7 +1,7 @@ STDIN, @@ -29,7 +29,7 @@ function memcached_server_start($code = 'server.php', $host = "127.0.0.1", $port $fp = @fsockopen($host, $port); // Failure, the server is no longer running if (!($status && $status['running'])) { - $error = "Server is not running\n"; + $error = "Server is not running {$status['command']}\n"; break; } // Success, Connected to servers @@ -75,4 +75,3 @@ function memcached_server_stop($handle) { } return $success; } - From 941ae835441e38e61e5349969f58b120c4ec7506 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 20 Jan 2021 16:52:31 +0100 Subject: [PATCH 149/218] add stats/version tests --- tests/memcachedserver.phpt | 31 ++++++++++++++++++++++++++++--- tests/server.php | 2 +- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/tests/memcachedserver.phpt b/tests/memcachedserver.phpt index 6d4abb9d..82601e12 100644 --- a/tests/memcachedserver.phpt +++ b/tests/memcachedserver.phpt @@ -1,10 +1,13 @@ --TEST-- -Memcached::get() with cache callback +MemcachedServer --SKIPIF-- --FILE-- get('get_this')); $cache->set ('set_key', 'value 1', 100); $cache->replace ('replace_key', 'value 2', 200); -// TODO var_dump($cache->getVersion()); -// TODO var_dump($cache->getStats()); +var_dump($cache->getVersion()); +var_dump($cache->getStats()); +var_dump($cache->getStats("foobar")); $cache->quit(); @@ -55,5 +59,26 @@ client_id=[%s]: Noop string(20) "Hello to you client!" client_id=[%s]: Set key=[set_key], value=[value 1], flags=[0], expiration=[100], cas=[0] client_id=[%s]: Replace key=[replace_key], value=[value 2], flags=[0], expiration=[200], cas=[0] +client_id=[%s]: Version +array(1) { + ["127.0.0.1:3434"]=> + string(5) "1.1.1" +} +client_id=[%s]: Stat key=[] +array(1) { + ["127.0.0.1:3434"]=> + array(1) { + [""]=> + string(15) "Stat reply for " + } +} +client_id=[%s]: Stat key=[foobar] +array(1) { + ["127.0.0.1:3434"]=> + array(1) { + ["foobar"]=> + string(21) "Stat reply for foobar" + } +} client_id=[%s]: Client quit Done diff --git a/tests/server.php b/tests/server.php index c39b04e8..b6ab1cf6 100644 --- a/tests/server.php +++ b/tests/server.php @@ -86,7 +86,7 @@ function ($client_id, $key, &$value) { $server->on (Memcached::ON_VERSION, function ($client_id, &$value) { echo "client_id=[$client_id]: Version" . PHP_EOL; - $value = "Stat reply"; + $value = "1.1.1"; return Memcached::RESPONSE_SUCCESS; }); From bee6b53d57e18a13e21aa4d5c887b5303228a339 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 20 Jan 2021 17:42:58 +0100 Subject: [PATCH 150/218] expect an array as STATS value and reply foreach key/value --- php_memcached_server.c | 36 +++++++++++++++++++++++++----------- tests/memcachedserver.phpt | 16 ++++++++++------ tests/server.php | 7 +++++-- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/php_memcached_server.c b/php_memcached_server.c index d1e903a1..a166051e 100644 --- a/php_memcached_server.c +++ b/php_memcached_server.c @@ -506,7 +506,7 @@ protocol_binary_response_status s_stat_handler (const void *cookie, const void * { zval params[3]; protocol_binary_response_status retval = PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND; - zval zcookie, zkey, zbody; + zval zcookie, zkey, zstats; if (!MEMC_HAS_CB(MEMC_SERVER_ON_STAT)) { return retval; @@ -519,24 +519,38 @@ protocol_binary_response_status s_stat_handler (const void *cookie, const void * } else { ZVAL_NULL(&zkey); } - ZVAL_NULL(&zbody); - ZVAL_MAKE_REF(&zbody); + ZVAL_NULL(&zstats); + ZVAL_MAKE_REF(&zstats); ZVAL_COPY(¶ms[0], &zcookie); ZVAL_COPY(¶ms[1], &zkey); - ZVAL_COPY(¶ms[2], &zbody); + ZVAL_COPY(¶ms[2], &zstats); retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_STAT), params, 3); if (retval == PROTOCOL_BINARY_RESPONSE_SUCCESS) { - if (Z_TYPE(zbody) == IS_NULL) { + if (Z_ISNULL(zstats)) { retval = response_handler(cookie, NULL, 0, NULL, 0); - } - else { - if (Z_TYPE(zbody) != IS_STRING) { - convert_to_string(&zbody); + } else { + zval *zarray = &zstats; + zend_string *key; + zval *val; + + ZVAL_DEREF(zarray); + if (Z_TYPE_P(zarray) != IS_ARRAY) { + convert_to_array(zarray); + } + + ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zarray), key, val) + { + zend_string *val_str = zval_get_string(val); + retval = response_handler(cookie, key->val, key->len, val_str->val, val_str->len); + if (retval != PROTOCOL_BINARY_RESPONSE_SUCCESS) { + break; + } + zend_string_release(val_str); } - retval = response_handler(cookie, key, key_len, Z_STRVAL(zbody), (uint32_t) Z_STRLEN(zbody)); + ZEND_HASH_FOREACH_END(); } } @@ -545,7 +559,7 @@ protocol_binary_response_status s_stat_handler (const void *cookie, const void * zval_ptr_dtor(¶ms[2]); zval_ptr_dtor (&zcookie); zval_ptr_dtor (&zkey); - zval_ptr_dtor (&zbody); + zval_ptr_dtor (&zstats); return retval; } diff --git a/tests/memcachedserver.phpt b/tests/memcachedserver.phpt index 82601e12..d47dd73b 100644 --- a/tests/memcachedserver.phpt +++ b/tests/memcachedserver.phpt @@ -67,17 +67,21 @@ array(1) { client_id=[%s]: Stat key=[] array(1) { ["127.0.0.1:3434"]=> - array(1) { - [""]=> - string(15) "Stat reply for " + array(2) { + ["key"]=> + string(0) "" + ["foo"]=> + string(3) "bar" } } client_id=[%s]: Stat key=[foobar] array(1) { ["127.0.0.1:3434"]=> - array(1) { - ["foobar"]=> - string(21) "Stat reply for foobar" + array(2) { + ["key"]=> + string(6) "foobar" + ["foo"]=> + string(3) "bar" } } client_id=[%s]: Client quit diff --git a/tests/server.php b/tests/server.php index b6ab1cf6..f5ff2f6a 100644 --- a/tests/server.php +++ b/tests/server.php @@ -77,9 +77,12 @@ function ($client_id, $key, $value, $flags, $expiration, $cas, &$result_cas) { }); $server->on (Memcached::ON_STAT, - function ($client_id, $key, &$value) { + function ($client_id, $key, array &$values = null) { echo "client_id=[$client_id]: Stat key=[$key]" . PHP_EOL; - $value = "Stat reply for $key"; + $values = [ + "key" => $key, + "foo" => "bar", + ]; return Memcached::RESPONSE_SUCCESS; }); From 984086633264d30fad442c4a2394145f9e014d1a Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 20 Jan 2021 18:00:52 +0100 Subject: [PATCH 151/218] valgrind --- php_memcached.c | 5 ++++- tests/server.inc | 9 +++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index e7a28e0a..19af8fda 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -3925,7 +3925,6 @@ static PHP_GINIT_FUNCTION(php_memcached) { #ifdef HAVE_MEMCACHED_SESSION - php_memcached_globals->session.lock_enabled = 0; php_memcached_globals->session.lock_wait_max = 150; php_memcached_globals->session.lock_wait_min = 150; @@ -3944,8 +3943,12 @@ PHP_GINIT_FUNCTION(php_memcached) php_memcached_globals->session.persistent_enabled = 0; php_memcached_globals->session.sasl_username = NULL; php_memcached_globals->session.sasl_password = NULL; +#endif +#ifdef HAVE_MEMCACHED_PROTOCOL + memset(&php_memcached_globals->server, 0, sizeof(php_memcached_globals->server)); #endif + php_memcached_globals->memc.serializer_name = NULL; php_memcached_globals->memc.serializer_type = SERIALIZER_DEFAULT; php_memcached_globals->memc.compression_name = NULL; diff --git a/tests/server.inc b/tests/server.inc index 5700a9d2..9678f043 100644 --- a/tests/server.inc +++ b/tests/server.inc @@ -23,7 +23,7 @@ function memcached_server_start($code = 'server.php', $host = "127.0.0.1", $port // note: even when server prints 'Listening on localhost:8964...Press Ctrl-C to quit.' // it might not be listening yet...need to wait until fsockopen() call returns $error = "Unable to connect to server\n"; - for ($i=0; $i < 60; $i++) { + for ($i=0; $i < getenv("VALGRIND") ? 1000 : 60; $i++) { usleep(50000); // 50ms per try $status = proc_get_status($handle); $fp = @fsockopen($host, $port); @@ -46,12 +46,16 @@ function memcached_server_start($code = 'server.php', $host = "127.0.0.1", $port if ($error) { echo $error; proc_terminate($handle); + proc_close($handle); exit(1); } register_shutdown_function( function($handle) { - proc_terminate($handle); + if (is_resource($handle)) { + proc_terminate($handle); + proc_close($handle); + } }, $handle ); @@ -72,6 +76,7 @@ function memcached_server_stop($handle) { } usleep(50000); } + proc_close($handle); } return $success; } From 6dc086e721d2d843f240f69ed181575588a9c140 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 21 Jan 2021 17:28:07 +0100 Subject: [PATCH 152/218] add test files to package.xml --- package.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.xml b/package.xml index 519de583..8241d221 100644 --- a/package.xml +++ b/package.xml @@ -173,7 +173,10 @@ Fixes - + + + + From 4b6c45dd23be82abc2fdbf1655700ddd55c09538 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Mon, 25 Jan 2021 14:45:03 +0100 Subject: [PATCH 153/218] implement stats callback suggestions by Remi --- php_memcached_server.c | 45 +++++++++++++++++++++----------------- tests/memcachedserver.phpt | 22 +++++++++++++++++++ tests/server.php | 19 ++++++++++------ 3 files changed, 59 insertions(+), 27 deletions(-) diff --git a/php_memcached_server.c b/php_memcached_server.c index a166051e..24c328f8 100644 --- a/php_memcached_server.c +++ b/php_memcached_server.c @@ -519,7 +519,7 @@ protocol_binary_response_status s_stat_handler (const void *cookie, const void * } else { ZVAL_NULL(&zkey); } - ZVAL_NULL(&zstats); + array_init(&zstats); ZVAL_MAKE_REF(&zstats); ZVAL_COPY(¶ms[0], &zcookie); @@ -529,29 +529,34 @@ protocol_binary_response_status s_stat_handler (const void *cookie, const void * retval = s_invoke_php_callback (&MEMC_GET_CB(MEMC_SERVER_ON_STAT), params, 3); if (retval == PROTOCOL_BINARY_RESPONSE_SUCCESS) { - if (Z_ISNULL(zstats)) { - retval = response_handler(cookie, NULL, 0, NULL, 0); - } else { - zval *zarray = &zstats; - zend_string *key; - zval *val; - - ZVAL_DEREF(zarray); - if (Z_TYPE_P(zarray) != IS_ARRAY) { - convert_to_array(zarray); - } + zval *zarray = &zstats; + zend_string *key; + zend_long idx; + zval *val; + + ZVAL_DEREF(zarray); + if (Z_TYPE_P(zarray) != IS_ARRAY) { + convert_to_array(zarray); + } - ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(zarray), key, val) - { - zend_string *val_str = zval_get_string(val); + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(zarray), idx, key, val) + { + zend_string *val_str = zval_get_string(val); + + if (key) { retval = response_handler(cookie, key->val, key->len, val_str->val, val_str->len); - if (retval != PROTOCOL_BINARY_RESPONSE_SUCCESS) { - break; - } - zend_string_release(val_str); + } else { + char buf[0x20], *ptr, *end = &buf[sizeof(buf) - 1]; + ptr = zend_print_long_to_buf(end, idx); + retval = response_handler(cookie, ptr, end - ptr, val_str->val, val_str->len); + } + zend_string_release(val_str); + + if (retval != PROTOCOL_BINARY_RESPONSE_SUCCESS) { + break; } - ZEND_HASH_FOREACH_END(); } + ZEND_HASH_FOREACH_END(); } zval_ptr_dtor(¶ms[0]); diff --git a/tests/memcachedserver.phpt b/tests/memcachedserver.phpt index d47dd73b..8d6bf222 100644 --- a/tests/memcachedserver.phpt +++ b/tests/memcachedserver.phpt @@ -37,6 +37,8 @@ $cache->replace ('replace_key', 'value 2', 200); var_dump($cache->getVersion()); var_dump($cache->getStats()); var_dump($cache->getStats("foobar")); +var_dump($cache->getStats("scalar")); +var_dump($cache->getStats("numeric array")); $cache->quit(); @@ -84,5 +86,25 @@ array(1) { string(3) "bar" } } +client_id=[%s]: Stat key=[scalar] +array(1) { + ["127.0.0.1:3434"]=> + array(1) { + [0]=> + string(%d) "you want it, you get it" + } +} +client_id=[%s]: Stat key=[numeric array] +array(1) { + ["127.0.0.1:3434"]=> + array(3) { + [-1]=> + string(3) "one" + [0]=> + string(3) "two" + [1]=> + string(5) "three" + } +} client_id=[%s]: Client quit Done diff --git a/tests/server.php b/tests/server.php index f5ff2f6a..bce4c0bf 100644 --- a/tests/server.php +++ b/tests/server.php @@ -77,13 +77,18 @@ function ($client_id, $key, $value, $flags, $expiration, $cas, &$result_cas) { }); $server->on (Memcached::ON_STAT, - function ($client_id, $key, array &$values = null) { - echo "client_id=[$client_id]: Stat key=[$key]" . PHP_EOL; - $values = [ - "key" => $key, - "foo" => "bar", - ]; - return Memcached::RESPONSE_SUCCESS; + function ($client_id, $key, array &$values) { + echo "client_id=[$client_id]: Stat key=[$key]" . PHP_EOL; + + if ($key === "scalar") { + $values = "you want it, you get it"; + } elseif ($key === "numeric array") { + $values = [-1 => "one", "two", "three"]; + } else { + $values["key"] = $key; + $values["foo"] = "bar"; + } + return Memcached::RESPONSE_SUCCESS; }); $server->on (Memcached::ON_VERSION, From 4e7f20cdb062537d5c4fc7ef0cf5d4e3b912fd13 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Mon, 25 Jan 2021 14:54:24 +0100 Subject: [PATCH 154/218] skip test with libmemcached < 1.1.0 --- tests/memcachedserver.phpt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/memcachedserver.phpt b/tests/memcachedserver.phpt index 8d6bf222..145acfba 100644 --- a/tests/memcachedserver.phpt +++ b/tests/memcachedserver.phpt @@ -8,6 +8,10 @@ if (!extension_loaded("memcached")) { if (!class_exists("MemcachedServer")) { die("skip memcached not built with libmemcachedprotocol support\n"); } + +if (Memcached::LIBMEMCACHED_VERSION_HEX < 0x1001000) { + die("skip needs at least libmemcached 1.1.0\n"); +} ?> --FILE-- Date: Tue, 26 Jan 2021 11:38:12 +0100 Subject: [PATCH 155/218] add IPv6 test --- tests/memcachedserver.phpt | 4 ++ tests/memcachedserver6.phpt | 114 ++++++++++++++++++++++++++++++++++++ tests/server.php | 2 + 3 files changed, 120 insertions(+) create mode 100644 tests/memcachedserver6.phpt diff --git a/tests/memcachedserver.phpt b/tests/memcachedserver.phpt index 145acfba..21ce8d64 100644 --- a/tests/memcachedserver.phpt +++ b/tests/memcachedserver.phpt @@ -40,6 +40,7 @@ $cache->replace ('replace_key', 'value 2', 200); var_dump($cache->getVersion()); var_dump($cache->getStats()); +var_dump($cache->getStats("empty")); var_dump($cache->getStats("foobar")); var_dump($cache->getStats("scalar")); var_dump($cache->getStats("numeric array")); @@ -80,6 +81,9 @@ array(1) { string(3) "bar" } } +client_id=[%s]: Stat key=[empty] +array(0) { +} client_id=[%s]: Stat key=[foobar] array(1) { ["127.0.0.1:3434"]=> diff --git a/tests/memcachedserver6.phpt b/tests/memcachedserver6.phpt new file mode 100644 index 00000000..8ae0b362 --- /dev/null +++ b/tests/memcachedserver6.phpt @@ -0,0 +1,114 @@ +--TEST-- +MemcachedServer +--SKIPIF-- + +--FILE-- +setOption(Memcached::OPT_BINARY_PROTOCOL, true); +$cache->setOption(Memcached::OPT_COMPRESSION, false); +$cache->addServer('[::1]', 3434); + +$cache->add("add_key", "hello", 500); +$cache->append("append_key", "world"); +$cache->prepend("prepend_key", "world"); + +$cache->increment("incr", 2, 1, 500); +$cache->decrement("decr", 2, 1, 500); + +$cache->delete("delete_k"); +$cache->flush(1); + +var_dump($cache->get('get_this')); + +$cache->set ('set_key', 'value 1', 100); +$cache->replace ('replace_key', 'value 2', 200); + +var_dump($cache->getVersion()); +var_dump($cache->getStats()); +var_dump($cache->getStats("empty")); +var_dump($cache->getStats("foobar")); +var_dump($cache->getStats("scalar")); +var_dump($cache->getStats("numeric array")); + +$cache->quit(); + +memcached_server_stop($server); +?> +Done +--EXPECTF-- +Listening on [::1]:3434 +Incoming connection from [::1]:%s +Incoming connection from [::1]:%s +client_id=[%s]: Add key=[add_key], value=[hello], flags=[0], expiration=[500] +client_id=[%s]: Append key=[append_key], value=[world], cas=[0] +client_id=[%s]: Prepend key=[prepend_key], value=[world], cas=[0] +client_id=[%s]: Incrementing key=[incr], delta=[2], initial=[1], expiration=[500] +client_id=[%s]: Decrementing key=[decr], delta=[2], initial=[1], expiration=[500] +client_id=[%s]: Delete key=[delete_k], cas=[0] +client_id=[%s]: Flush when=[1] +client_id=[%s]: Get key=[get_this] +client_id=[%s]: Noop +string(20) "Hello to you client!" +client_id=[%s]: Set key=[set_key], value=[value 1], flags=[0], expiration=[100], cas=[0] +client_id=[%s]: Replace key=[replace_key], value=[value 2], flags=[0], expiration=[200], cas=[0] +client_id=[%s]: Version +array(1) { + ["[::1]:3434"]=> + string(5) "1.1.1" +} +client_id=[%s]: Stat key=[] +array(1) { + ["[::1]:3434"]=> + array(2) { + ["key"]=> + string(0) "" + ["foo"]=> + string(3) "bar" + } +} +client_id=[%s]: Stat key=[empty] +array(0) { +} +client_id=[%s]: Stat key=[foobar] +array(1) { + ["[::1]:3434"]=> + array(2) { + ["key"]=> + string(6) "foobar" + ["foo"]=> + string(3) "bar" + } +} +client_id=[%s]: Stat key=[scalar] +array(1) { + ["[::1]:3434"]=> + array(1) { + [0]=> + string(%d) "you want it, you get it" + } +} +client_id=[%s]: Stat key=[numeric array] +array(1) { + ["[::1]:3434"]=> + array(3) { + [-1]=> + string(3) "one" + [0]=> + string(3) "two" + [1]=> + string(5) "three" + } +} +client_id=[%s]: Client quit +Done diff --git a/tests/server.php b/tests/server.php index bce4c0bf..9a50eb06 100644 --- a/tests/server.php +++ b/tests/server.php @@ -84,6 +84,8 @@ function ($client_id, $key, array &$values) { $values = "you want it, you get it"; } elseif ($key === "numeric array") { $values = [-1 => "one", "two", "three"]; + } elseif ($key === "empty") { + $values = []; } else { $values["key"] = $key; $values["foo"] = "bar"; From 10f449752bb42459f7b29aeaf4583854ccc24678 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 26 Jan 2021 11:42:37 +0100 Subject: [PATCH 156/218] small sleep to avoid loosing message from subprocess --- tests/memcachedserver.phpt | 1 + tests/memcachedserver6.phpt | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/memcachedserver.phpt b/tests/memcachedserver.phpt index 21ce8d64..7b058d70 100644 --- a/tests/memcachedserver.phpt +++ b/tests/memcachedserver.phpt @@ -46,6 +46,7 @@ var_dump($cache->getStats("scalar")); var_dump($cache->getStats("numeric array")); $cache->quit(); +usleep(50000); memcached_server_stop($server); ?> diff --git a/tests/memcachedserver6.phpt b/tests/memcachedserver6.phpt index 8ae0b362..a2277b4a 100644 --- a/tests/memcachedserver6.phpt +++ b/tests/memcachedserver6.phpt @@ -42,6 +42,7 @@ var_dump($cache->getStats("scalar")); var_dump($cache->getStats("numeric array")); $cache->quit(); +usleep(50000); memcached_server_stop($server); ?> From 13ba74317d7a94f87b9d30e6297fb39142c04d36 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 27 Jul 2021 08:35:08 +0200 Subject: [PATCH 157/218] Improve phpinfo information - display libmemcached-awesome when used (since 1.1.1) - display both builtime and runtime versions when different --- php_memcached.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index d49cbeb4..0f42a97f 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -4300,7 +4300,22 @@ PHP_MINFO_FUNCTION(memcached) php_info_print_table_start(); php_info_print_table_header(2, "memcached support", "enabled"); php_info_print_table_row(2, "Version", PHP_MEMCACHED_VERSION); - php_info_print_table_row(2, "libmemcached version", memcached_lib_version()); + +#ifdef LIBMEMCACHED_AWESOME + if (strcmp(LIBMEMCACHED_VERSION_STRING, memcached_lib_version())) { + php_info_print_table_row(2, "libmemcached-awesome headers version", LIBMEMCACHED_VERSION_STRING); + php_info_print_table_row(2, "libmemcached-awesome library version", memcached_lib_version()); + } else { + php_info_print_table_row(2, "libmemcached-awesome version", memcached_lib_version()); + } +#else + if (strcmp(LIBMEMCACHED_VERSION_STRING, memcached_lib_version())) { + php_info_print_table_row(2, "libmemcached headers version", LIBMEMCACHED_VERSION_STRING); + php_info_print_table_row(2, "libmemcached library version", memcached_lib_version()); + } else { + php_info_print_table_row(2, "libmemcached version", memcached_lib_version()); + } +#endif #ifdef HAVE_MEMCACHED_SASL php_info_print_table_row(2, "SASL support", "yes"); From 605a8a63a7461983512ce12601e995dad18f5a9b Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 29 Jul 2021 04:55:08 +0200 Subject: [PATCH 158/218] fix zend_dtoa API change in 8.1.0beta1 (#487) --- g_fmt.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/g_fmt.c b/g_fmt.c index 73f82fd0..f456790c 100644 --- a/g_fmt.c +++ b/g_fmt.c @@ -27,12 +27,17 @@ * // Teddy Grenman , 2010-05-18. */ -#include +#include char *php_memcached_g_fmt(register char *b, double x) { register int i, k; register char *s; - int decpt, j, sign; + int decpt, j; +#if PHP_VERSION_ID < 80100 + int sign; +#else + bool sign; +#endif char *b0, *s0, *se; b0 = b; From 6d457155fbdf2c8c4615c04a4beb1a7462d55097 Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Mon, 23 Aug 2021 05:56:19 +0100 Subject: [PATCH 159/218] Remove "failed to set key" warning from setMulti (#490) This was introduced in https://github.com/php-memcached-dev/php-memcached/commit/6837d89494, pull https://github.com/php-memcached-dev/php-memcached/pull/214. I suspect it may have been a left-over from debugging something. The test was later changed in 6837d89494 to expect the warning in question, although other similar tests don't encounter such warning currently. It appears no other Memcached methods emit a PHP Warning when they encounter a write read or failure. Instead, they typically turn their return value into boolean false, and provide details via getResultMessage(). The introduction of this warning since php-memcached 3.0 has led to a number of confused consumers (locally #260, #409, #450, and more reports within downstream issue trackers). Closes https://github.com/php-memcached-dev/php-memcached/issues/409. --- php_memcached.c | 5 ++--- tests/experimental/setmulti_badserialize.phpt | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index d49cbeb4..069aa60d 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -1907,9 +1907,8 @@ static void php_memc_setMulti_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_ke str_key = zend_string_init(tmp_key, tmp_len, 0); } - if (!s_memc_write_zval (intern, MEMC_OP_SET, server_key, str_key, value, expiration)) { - php_error_docref(NULL, E_WARNING, "failed to set key %s", ZSTR_VAL(str_key)); - } + /* If this failed to write a value, intern stores the error for the return value */ + s_memc_write_zval (intern, MEMC_OP_SET, server_key, str_key, value, expiration); if (!skey) { zend_string_release (str_key); diff --git a/tests/experimental/setmulti_badserialize.phpt b/tests/experimental/setmulti_badserialize.phpt index eafc7772..2d8dde53 100644 --- a/tests/experimental/setmulti_badserialize.phpt +++ b/tests/experimental/setmulti_badserialize.phpt @@ -42,6 +42,5 @@ try { var_dump($m->getByKey('kef', 'foo')); --EXPECT-- -Memcached::setMultiByKey(): failed to set key foo 1234 int(10) From e6df8ab3f6620cf0b2d4e683753aae846a68b4e5 Mon Sep 17 00:00:00 2001 From: hulk Date: Mon, 23 Aug 2021 12:57:11 +0800 Subject: [PATCH 160/218] FIX: store_retry_count shouldn't be set implicitly (#452) It's wired that store commands would be auto-retry implicitly while the default value of store_retry_count was 2, as well as the timeout, would be 3 times in those store commands which may confuse users. IMHO, the retry should be set explicitly instead of implicitly. --- memcached.ini | 4 ++-- php_memcached.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/memcached.ini b/memcached.ini index c11db719..c54e1fd4 100644 --- a/memcached.ini +++ b/memcached.ini @@ -130,8 +130,8 @@ ; This mechanism allows transparent fail-over to secondary servers when ; set/increment/decrement/setMulti operations fail on the desired server in a multi-server ; environment. -; the default is 2 -;memcached.store_retry_count = 2 +; the default is 0 +;memcached.store_retry_count = 0 ; Sets the default for consistent hashing for new connections. ; (To configure consistent hashing for session connections, diff --git a/php_memcached.c b/php_memcached.c index 069aa60d..0f02878c 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -410,7 +410,7 @@ PHP_INI_BEGIN() MEMC_INI_ENTRY("compression_factor", "1.3", OnUpdateReal, compression_factor) MEMC_INI_ENTRY("compression_threshold", "2000", OnUpdateLong, compression_threshold) MEMC_INI_ENTRY("serializer", SERIALIZER_DEFAULT_NAME, OnUpdateSerializer, serializer_name) - MEMC_INI_ENTRY("store_retry_count", "2", OnUpdateLong, store_retry_count) + MEMC_INI_ENTRY("store_retry_count", "0", OnUpdateLong, store_retry_count) MEMC_INI_BOOL ("default_consistent_hash", "0", OnUpdateBool, default_behavior.consistent_hash_enabled) MEMC_INI_BOOL ("default_binary_protocol", "0", OnUpdateBool, default_behavior.binary_protocol_enabled) From 60a8f9f8810aab2b4cff16b05667c6d4af85ef09 Mon Sep 17 00:00:00 2001 From: mszabo-wikia Date: Mon, 8 Nov 2021 18:18:14 +0100 Subject: [PATCH 161/218] Add GitHub Actions build (#492) travis-ci.org builds have ceased, so this patch adds a GitHub Actions workflow to build and test the extension, as well as a Dependabot configuration file to keep the referenced actions up to date. I've opted to slightly simplify the workflow compared to the Travis build script. For one, I have not included libmemcached protocol support, as most distros do not supply a libmemcached compiled with server protocol support, and previous discussion suggests its usefulness in the context of this extension may be limited.[1] I've also opted to remove multiversion libmemcached testing in favor of using the system libmemcached, as the referenced other versions seem to be old enough for this to hopefully not be a problem. These could conceivably be reintroduced if needed. --- [1] https://github.com/php-memcached-dev/php-memcached/issues/418#issuecomment-449587972 --- .github/dependabot.yml | 6 + .github/workflows/build-and-test.yml | 84 +++++++++ .travis.yml | 39 ---- .travis/travis.sh | 270 --------------------------- 4 files changed, 90 insertions(+), 309 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/build-and-test.yml delete mode 100644 .travis.yml delete mode 100755 .travis/travis.sh diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..12301490 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml new file mode 100644 index 00000000..eb19d01e --- /dev/null +++ b/.github/workflows/build-and-test.yml @@ -0,0 +1,84 @@ +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + continue-on-error: ${{ matrix.experimental }} + strategy: + fail-fast: false + matrix: + php: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0'] + experimental: [false] + include: + - php: '8.1' + experimental: true + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + submodules: true + - name: Install PHP ${{ matrix.php }} + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: none, json, igbinary, msgpack + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install libmemcached-dev memcached libsasl2-dev sasl2-bin zlib1g-dev + - name: Start memcached daemons + run: | + export SASL_CONF_PATH="/tmp/sasl2" + mkdir "${SASL_CONF_PATH}" + export MEMCACHED_SASL_PWDB="${SASL_CONF_PATH}/sasldb2" + + # Create configuration + cat< "${SASL_CONF_PATH}/memcached.conf" + mech_list: PLAIN + plainlog_level: 5 + sasldb_path: ${MEMCACHED_SASL_PWDB} + EOF + + echo "test" | /usr/sbin/saslpasswd2 -c memcached -a memcached -f "${MEMCACHED_SASL_PWDB}" + + # Run normal memcached + memcached -d -p 11211 + + # Run memcached on port 11212 with SASL support + memcached -S -d -p 11212 + - name: Build extension + run: | + phpize + ./configure \ + --enable-memcached-protocol=no \ + --enable-memcached-sasl \ + --enable-memcached-json \ + --enable-memcached-msgpack \ + --enable-memcached-igbinary + make + sudo make install + - name: Create test configuration + run: | + cat< tests/config.inc.local + /dev/null - if [ $? != 0 ]; then - echo "Missing $file from package.xml" - retval=1; - fi - done - return $retval -} - -function install_libmemcached() { - - if test -d "${LIBMEMCACHED_PREFIX}" - then - echo "Using cached libmemcached: ${LIBMEMCACHED_PREFIX}" - return - fi - - wget "https://launchpad.net/libmemcached/1.0/${LIBMEMCACHED_VERSION}/+download/libmemcached-${LIBMEMCACHED_VERSION}.tar.gz" -O libmemcached-${LIBMEMCACHED_VERSION}.tar.gz - - tar xvfz libmemcached-${LIBMEMCACHED_VERSION}.tar.gz - pushd "libmemcached-${LIBMEMCACHED_VERSION}" - - local protocol_flag="" - if test "x$ENABLE_PROTOOCOL" = "xyes"; then - protocol_flag="--enable-libmemcachedprotocol" - fi - - ./configure --prefix="$LIBMEMCACHED_PREFIX" $protocol_flag LDFLAGS="-lpthread" - make - make install - popd -} - -function install_igbinary() { - git clone https://github.com/igbinary/igbinary.git - pushd igbinary - phpize - ./configure - make - make install - popd -} - -function install_msgpack() { - git clone https://github.com/msgpack/msgpack-php.git - pushd msgpack-php - phpize - ./configure - make - make install - popd -} - -function install_memcached() { - local prefix="${HOME}/cache/memcached-sasl-${MEMCACHED_VERSION}" - - if test -d "$prefix" - then - echo "Using cached memcached: ${prefix}" - return - fi - - wget http://www.memcached.org/files/memcached-${MEMCACHED_VERSION}.tar.gz -O memcached-${MEMCACHED_VERSION}.tar.gz - tar xfz memcached-${MEMCACHED_VERSION}.tar.gz - - pushd memcached-${MEMCACHED_VERSION} - ./configure --enable-sasl --enable-sasl-pwdb --prefix="${prefix}" - make - make install - popd -} - -function run_memcached() { - local prefix="${HOME}/cache/memcached-sasl-${MEMCACHED_VERSION}" - - export SASL_CONF_PATH="/tmp/sasl2" - - if test -d "${SASL_CONF_PATH}" - then - rm -rf "${SASL_CONF_PATH}" - fi - - mkdir "${SASL_CONF_PATH}" - export MEMCACHED_SASL_PWDB="${SASL_CONF_PATH}/sasldb2" - - # Create configuration - cat< "${SASL_CONF_PATH}/memcached.conf" -mech_list: PLAIN -plainlog_level: 5 -sasldb_path: ${MEMCACHED_SASL_PWDB} -EOF - - echo "test" | /usr/sbin/saslpasswd2 -c memcached -a memcached -f "${MEMCACHED_SASL_PWDB}" - - # Run normal memcached - "${prefix}/bin/memcached" -d -p 11211 - - # Run memcached on port 11212 with SASL support - "${prefix}/bin/memcached" -S -d -p 11212 -} - -function build_php_memcached() { - pear package - mkdir "$PHP_MEMCACHED_BUILD_DIR" - tar xfz "memcached-${PHP_MEMCACHED_VERSION}.tgz" -C "$PHP_MEMCACHED_BUILD_DIR" - pushd "${PHP_MEMCACHED_BUILD_DIR}/memcached-${PHP_MEMCACHED_VERSION}" - phpize - - local protocol_flag="" - if test "x$ENABLE_PROTOCOL" = "xyes"; then - protocol_flag="--enable-memcached-protocol" - fi - - local sasl_flag="--disable-memcached-sasl" - if test "x$ENABLE_SASL" = "xyes"; then - sasl_flag="--enable-memcached-sasl" - fi - - # ./configure --with-libmemcached-dir="$LIBMEMCACHED_PREFIX" $protocol_flag $sasl_flag - ./configure --with-libmemcached-dir="$LIBMEMCACHED_PREFIX" $protocol_flag $sasl_flag --enable-memcached-json --enable-memcached-msgpack --enable-memcached-igbinary - make - make install - popd -} - -function create_memcached_test_configuration() { -cat< "${PHP_MEMCACHED_BUILD_DIR}/memcached-${PHP_MEMCACHED_VERSION}/tests/config.inc.local" - " - exit 1 -fi - -if test "x$LIBMEMCACHED_VERSION" = "x"; then - echo "Usage: $0 " - exit 1 -fi - -if test "x$3" != "x"; then - MEMCACHED_VERSION=$3 -fi - -# the extension version -PHP_MEMCACHED_VERSION=$(php -r '$sxe = simplexml_load_file ("package.xml"); echo (string) $sxe->version->release;') - -# Libmemcached install dir -LIBMEMCACHED_PREFIX="${HOME}/cache/libmemcached-${LIBMEMCACHED_VERSION}" - -# Where to do the build -PHP_MEMCACHED_BUILD_DIR="/tmp/php-memcached-build" - -# Check whether to enable building with protoocol and sasl support -check_protocol_support -check_sasl_support - -echo "Enable protocol: $ENABLE_PROTOOCOL" -echo "Enable sasl: $ENABLE_SASL" - -set -e - -case $ACTION in - before_script) - # validate the package.xml - validate_package_xml || exit 1 - - # Install libmemcached version - install_libmemcached - - # Install igbinary extension - install_igbinary - - # Install msgpack extension - install_msgpack - - install_memcached - run_memcached - ;; - - script) - # Build the extension - build_php_memcached - - # Create configuration - if test "x$ENABLE_SASL" = "xyes"; then - create_memcached_test_configuration - fi - - # Run tests - set +e - run_memcached_tests || exit 1 - ;; - - *) - echo "Unknown action. Valid actions are: before_script and script" - exit 1 - ;; -esac - - - - - From d3b8ce13f13cee3017aa8a00a0cfb2e7709154d8 Mon Sep 17 00:00:00 2001 From: Ruud Kamphuis Date: Mon, 29 Nov 2021 19:58:58 +0100 Subject: [PATCH 162/218] Remove experimental for PHP 8.1 and add PHP 8.2 experimental (#494) --- .github/workflows/build-and-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index eb19d01e..aa1b22c7 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -7,10 +7,10 @@ jobs: strategy: fail-fast: false matrix: - php: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0'] + php: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] experimental: [false] include: - - php: '8.1' + - php: '8.2' experimental: true steps: - name: Checkout From 7a0623098261c4f9d20a9eb325e33474862a5524 Mon Sep 17 00:00:00 2001 From: lfeng Date: Wed, 29 Dec 2021 16:24:57 +0800 Subject: [PATCH 163/218] fix windows php8 php_stdint.h path --- php_memcached_private.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/php_memcached_private.h b/php_memcached_private.h index 3e1f3586..127ff28c 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -48,7 +48,11 @@ #include #ifdef PHP_WIN32 +#if PHP_VERSION_ID >= 80000 +#include "php_stdint.h" +#else # include "win32/php_stdint.h" +#endif #else /* Used to store the size of the block */ # if defined(HAVE_INTTYPES_H) From 5a8db865c16c95af56769c7e292fc6fe6c70635d Mon Sep 17 00:00:00 2001 From: lfeng Date: Thu, 30 Dec 2021 10:08:48 +0800 Subject: [PATCH 164/218] format code --- php_memcached_private.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php_memcached_private.h b/php_memcached_private.h index 127ff28c..2891d80b 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -48,8 +48,8 @@ #include #ifdef PHP_WIN32 -#if PHP_VERSION_ID >= 80000 -#include "php_stdint.h" +# if PHP_VERSION_ID >= 80000 +# include "php_stdint.h" #else # include "win32/php_stdint.h" #endif From 082615656f80e8654c22de97ed3017233dd18278 Mon Sep 17 00:00:00 2001 From: lfeng Date: Thu, 30 Dec 2021 14:04:09 +0800 Subject: [PATCH 165/218] format code --- php_memcached_private.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php_memcached_private.h b/php_memcached_private.h index 2891d80b..b4b1115b 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -48,8 +48,8 @@ #include #ifdef PHP_WIN32 -# if PHP_VERSION_ID >= 80000 -# include "php_stdint.h" + # if PHP_VERSION_ID >= 80000 + # include "php_stdint.h" #else # include "win32/php_stdint.h" #endif From 8a5ef9ef348f1cb6d3438072acc777b66eeb2ea2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 2 Mar 2022 13:57:02 -0800 Subject: [PATCH 166/218] Bump actions/checkout from 2 to 3 (#505) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-and-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index aa1b22c7..79b22569 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -14,7 +14,7 @@ jobs: experimental: true steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: true - name: Install PHP ${{ matrix.php }} From 5bb007e62503cf2730514db742a3d47b2d28f9be Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Mon, 7 Mar 2022 14:47:06 +0100 Subject: [PATCH 167/218] Prepare 3.2.0RC1 --- package.xml | 49 +++++++++++++++++++++++++++++++++++++------------ php_memcached.h | 2 +- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/package.xml b/package.xml index 8241d221..99a1b204 100644 --- a/package.xml +++ b/package.xml @@ -27,24 +27,27 @@ http://pear.php.net/dtd/package-2.0.xsd"> aaron@serendipity.cx yes - 2019-12-03 + + Remi Collet + remi + remi@php.net + yes + + 2022-03-07 - 3.1.5 - 3.0.0 + 3.2.0RC1 + 3.2.0 - stable - stable + beta + beta PHP -PHP 7.0 - 7.1 - 7.2 - 7.3 - 7.4 release of memcached extension. Note that support for -libmemcached 0.x series has been discontinued and the oldest actively tested -version is 1.0.8. It is highly recommended to use version 1.0.18 of -libmemcached. - -Fixes - * Fix build with PHP 7.4 release due to ulong typedef removal (#445) +- PHP 8.0 and 8.1 support +- store_retry_count is no more set explicitly (#452) +- fix MemcachedServer (libmemcached-awesome is recommended) +- code cleanup @@ -177,6 +180,7 @@ Fixes + @@ -213,6 +217,27 @@ Fixes + + 2019-12-03 + + 3.1.5 + 3.0.0 + + + stable + stable + + PHP + +PHP 7.0 - 7.1 - 7.2 - 7.3 - 7.4 release of memcached extension. Note that support for +libmemcached 0.x series has been discontinued and the oldest actively tested +version is 1.0.8. It is highly recommended to use version 1.0.18 of +libmemcached. + +Fixes + * Fix build with PHP 7.4 release due to ulong typedef removal (#445) + + stable diff --git a/php_memcached.h b/php_memcached.h index cccb6d47..f53f4a5c 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -30,7 +30,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.1.5" +#define PHP_MEMCACHED_VERSION "3.2.0RC1" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From e45fef86348b3fb58779f3cb601d7a0d8b425c5e Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Fri, 18 Feb 2022 00:03:42 +0200 Subject: [PATCH 168/218] Create gh_500.phpt --- package.xml | 1 + tests/gh_500.phpt | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/gh_500.phpt diff --git a/package.xml b/package.xml index 99a1b204..90844f21 100644 --- a/package.xml +++ b/package.xml @@ -107,6 +107,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> + diff --git a/tests/gh_500.phpt b/tests/gh_500.phpt new file mode 100644 index 00000000..366138db --- /dev/null +++ b/tests/gh_500.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test for Github issue 500 +--SKIPIF-- + +--FILE-- +addServers($newServers); + +$m->set('floatpoint', 100.2); +$n = $m->get('floatpoint'); +var_dump($n); + +$m->set('floatpoint_neg', -300.4); +$n = $m->get('floatpoint_neg'); +var_dump($n); +?> +--EXPECT-- +float(100.2) +float(-300.4) From 857b8afab80592f56349ace1f6d02f9002a1189d Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 9 Mar 2022 11:17:17 +0100 Subject: [PATCH 169/218] 8.x is supported + libmemcached-awesome --- README.markdown | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.markdown b/README.markdown index 31f57b16..8819caf9 100644 --- a/README.markdown +++ b/README.markdown @@ -23,7 +23,7 @@ Dependencies ------------ php-memcached 3.x: -* Supports PHP 7.0 - 7.4. +* Supports PHP 7.0 - 8.1. * Requires libmemcached 1.x or higher. * Optionally supports igbinary 2.0 or higher. * Optionally supports msgpack 2.0 or higher. @@ -34,9 +34,10 @@ php-memcached 2.x: * Optionally supports igbinary 1.0 or higher. * Optionally supports msgpack 0.5 or higher. -[libmemcached](http://libmemcached.org/libMemcached.html) version 1.0.18 or -higher is recommended for best performance and compatibility with memcached -servers. +[libmemcached](http://libmemcached.org/libMemcached.html) or the new +[libmemcached-awesome](https://github.com/awesomized/libmemcached) version +1.0.18 or higher is recommended for best performance and compatibility with +memcached servers. [igbinary](https://github.com/igbinary/igbinary) is a faster and more compact binary serializer for PHP data structures. When installing php-memcached from From c7433c9a53e6b8cafd28ca8a0aee6474763fc02d Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 9 Mar 2022 14:22:40 +0100 Subject: [PATCH 170/218] Fix MSVC builds wrt. ssize_t The Windows SDK does not define `ssize_t`, so libmemcached does not define `HAVE_SSIZE_T`. However, PHP's config.w32.h has `#define ssize_t SSIZE_T`, so building memcached fails. We fix this by defining `HAVE_SSIZE_T` via the extension's `CFLAGS`. --- config.w32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.w32 b/config.w32 index 9c84a059..7ca3a498 100644 --- a/config.w32 +++ b/config.w32 @@ -36,7 +36,7 @@ if (PHP_MEMCACHED == "yes") { } } - EXTENSION("memcached", "php_memcached.c php_libmemcached_compat.c g_fmt.c"+memcached_extra_src); + EXTENSION("memcached", "php_memcached.c php_libmemcached_compat.c g_fmt.c"+memcached_extra_src, null, " /DHAVE_SSIZE_T"); ADD_SOURCES(configure_module_dirname+"\\fastlz", "fastlz.c", "memcached"); AC_DEFINE("HAVE_MEMCACHED", 1, "memcached support"); AC_DEFINE("MEMCACHED_EXPORTS", 1) From 1f4b029003896f8f891041070dc7f90ead45dff3 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 9 Mar 2022 14:30:51 +0100 Subject: [PATCH 171/218] [ci skip] fix windows build in changelog --- package.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/package.xml b/package.xml index 90844f21..cf13e03b 100644 --- a/package.xml +++ b/package.xml @@ -48,6 +48,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> - store_retry_count is no more set explicitly (#452) - fix MemcachedServer (libmemcached-awesome is recommended) - code cleanup +- fix windows build From ca0d9392cb1f32754df99b2035fc3b3f0ddf493d Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 9 Mar 2022 14:34:33 +0100 Subject: [PATCH 172/218] Prepare 3.2.0RC2 --- package.xml | 4 ++-- php_memcached.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.xml b/package.xml index cf13e03b..18926a80 100644 --- a/package.xml +++ b/package.xml @@ -33,9 +33,9 @@ http://pear.php.net/dtd/package-2.0.xsd"> remi@php.net yes - 2022-03-07 + 2022-03-09 - 3.2.0RC1 + 3.2.0RC2 3.2.0 diff --git a/php_memcached.h b/php_memcached.h index f53f4a5c..5fb082f3 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -30,7 +30,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.2.0RC1" +#define PHP_MEMCACHED_VERSION "3.2.0RC2" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 4694a665d23a39854cbb978a9bdbb566a2a90585 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 9 Mar 2022 14:49:44 +0100 Subject: [PATCH 173/218] Adhere to standard naming convention of Windows libs for PHP The memcached library is usually named libmemcached.lib, so we should check for this name, too. --- config.w32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.w32 b/config.w32 index 7ca3a498..51aa3bd0 100644 --- a/config.w32 +++ b/config.w32 @@ -8,7 +8,7 @@ ARG_ENABLE('memcached-json', 'whether to enable memcached json serializer suppor if (PHP_MEMCACHED == "yes") { - if (!CHECK_LIB("memcached.lib", "memcached", PHP_MEMCACHED)) { + if (!CHECK_LIB("memcached.lib;libmemcached.lib", "memcached", PHP_MEMCACHED)) { ERROR("memcached: library 'memcached' not found"); } From d1cb3ae87be5382444322118f87324f4044d13b0 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 24 Mar 2022 13:57:18 +0100 Subject: [PATCH 174/218] Prepare 3.2.0 --- package.xml | 8 ++++---- php_memcached.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.xml b/package.xml index 18926a80..761c9584 100644 --- a/package.xml +++ b/package.xml @@ -33,14 +33,14 @@ http://pear.php.net/dtd/package-2.0.xsd"> remi@php.net yes - 2022-03-09 + 2022-03-24 - 3.2.0RC2 + 3.2.0 3.2.0 - beta - beta + stable + stable PHP diff --git a/php_memcached.h b/php_memcached.h index 5fb082f3..dfb3444d 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -30,7 +30,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.2.0RC2" +#define PHP_MEMCACHED_VERSION "3.2.0" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 09e094d3909ceb97bd98ccb658b5a7b6637650a4 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 24 Mar 2022 14:02:06 +0100 Subject: [PATCH 175/218] back to dev --- package.xml | 27 +++++++++++++++++++++------ php_memcached.h | 2 +- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/package.xml b/package.xml index 761c9584..9dc283be 100644 --- a/package.xml +++ b/package.xml @@ -35,7 +35,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> 2022-03-24 - 3.2.0 + 3.2.1dev 3.2.0 @@ -44,11 +44,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> PHP -- PHP 8.0 and 8.1 support -- store_retry_count is no more set explicitly (#452) -- fix MemcachedServer (libmemcached-awesome is recommended) -- code cleanup -- fix windows build +- @@ -219,6 +215,25 @@ http://pear.php.net/dtd/package-2.0.xsd"> + + 2022-03-24 + + 3.2.0 + 3.2.0 + + + stable + stable + + PHP + +- PHP 8.0 and 8.1 support +- store_retry_count is no more set explicitly (#452) +- fix MemcachedServer (libmemcached-awesome is recommended) +- code cleanup +- fix windows build + + 2019-12-03 diff --git a/php_memcached.h b/php_memcached.h index dfb3444d..e966d19d 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -30,7 +30,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.2.0" +#define PHP_MEMCACHED_VERSION "3.2.1-dev" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 1f22de74379208d9758ba99a9bd7373eefeb48f2 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Mon, 28 Mar 2022 08:09:29 +0200 Subject: [PATCH 176/218] fix #513 skip test with old and dead libmemcached --- tests/memcachedserver.phpt | 1 - tests/memcachedserver6.phpt | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/memcachedserver.phpt b/tests/memcachedserver.phpt index 7b058d70..407fcf97 100644 --- a/tests/memcachedserver.phpt +++ b/tests/memcachedserver.phpt @@ -8,7 +8,6 @@ if (!extension_loaded("memcached")) { if (!class_exists("MemcachedServer")) { die("skip memcached not built with libmemcachedprotocol support\n"); } - if (Memcached::LIBMEMCACHED_VERSION_HEX < 0x1001000) { die("skip needs at least libmemcached 1.1.0\n"); } diff --git a/tests/memcachedserver6.phpt b/tests/memcachedserver6.phpt index a2277b4a..3d02b244 100644 --- a/tests/memcachedserver6.phpt +++ b/tests/memcachedserver6.phpt @@ -8,6 +8,9 @@ if (!extension_loaded("memcached")) { if (!class_exists("MemcachedServer")) { die("skip memcached not built with libmemcachedprotocol support\n"); } +if (Memcached::LIBMEMCACHED_VERSION_HEX < 0x1001000) { + die("skip needs at least libmemcached 1.1.0\n"); +} ?> --FILE-- Date: Fri, 3 Jun 2022 16:56:00 +0200 Subject: [PATCH 177/218] fix ${var} deprecation --- tests/touch_binary.phpt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/touch_binary.phpt b/tests/touch_binary.phpt index 382c1778..059ec74c 100644 --- a/tests/touch_binary.phpt +++ b/tests/touch_binary.phpt @@ -28,12 +28,12 @@ function status_print ($op, $mem, $expected) $code = $mem->getResultcode(); if ($code == $expected) - echo "${op} status code as expected" . PHP_EOL; + echo "{$op} status code as expected" . PHP_EOL; else { $expected = resolve_to_constant ($expected); $code = resolve_to_constant ($code); - echo "${op} status code mismatch, expected ${expected} but got ${code}" . PHP_EOL; + echo "{$op} status code mismatch, expected {$expected} but got {$code}" . PHP_EOL; } } From ce2dfa5e649e01e4b4df925ebaef95ca75a3f353 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 28 Jul 2022 09:28:33 +0200 Subject: [PATCH 178/218] mark password as a sensitive param for 8.2 (#516) * mark password as a sensitive param for 8.2 --- php_memcached.c | 7 +++---- php_memcached.stub.php | 6 +++--- php_memcached_arginfo.h | 37 +++++++++++++++++++++++++++++----- php_memcached_legacy_arginfo.h | 30 ++++++++++++++++++++++----- 4 files changed, 63 insertions(+), 17 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 73deaf64..7ccc9b58 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -3898,6 +3898,7 @@ PHP_METHOD(MemcachedServer, on) #if PHP_VERSION_ID < 80000 #include "php_memcached_legacy_arginfo.h" #else +#include "zend_attributes.h" #include "php_memcached_arginfo.h" #endif @@ -4254,8 +4255,7 @@ PHP_MINIT_FUNCTION(memcached) le_memc = zend_register_list_destructors_ex(NULL, php_memc_dtor, "Memcached persistent connection", module_number); - INIT_CLASS_ENTRY(ce, "Memcached", class_Memcached_methods); - memcached_ce = zend_register_internal_class(&ce); + memcached_ce = register_class_Memcached(); memcached_ce->create_object = php_memc_object_new; #ifdef HAVE_MEMCACHED_PROTOCOL @@ -4264,8 +4264,7 @@ PHP_MINIT_FUNCTION(memcached) memcached_server_object_handlers.clone_obj = NULL; memcached_server_object_handlers.free_obj = php_memc_server_free_storage; - INIT_CLASS_ENTRY(ce, "MemcachedServer", class_MemcachedServer_methods); - memcached_server_ce = zend_register_internal_class(&ce); + memcached_server_ce = register_class_MemcachedServer(); memcached_server_ce->create_object = php_memc_server_new; #endif diff --git a/php_memcached.stub.php b/php_memcached.stub.php index 819186f4..a44b1801 100644 --- a/php_memcached.stub.php +++ b/php_memcached.stub.php @@ -3,9 +3,9 @@ /** * @generate-function-entries * @generate-legacy-arginfo + * @generate-class-entries */ - class Memcached { public function __construct(?string $persistent_id=null, ?callable $callback=null, ?string $connection_str=null) {} @@ -75,7 +75,7 @@ public function setOption(int $option, mixed $value): bool {} public function setOptions(array $options): bool {} public function setBucket(array $host_map, ?array $forward_map, int $replicas): bool {} #ifdef HAVE_MEMCACHED_SASL - public function setSaslAuthData(string $username, string $password): bool {} + public function setSaslAuthData(string $username, #[\SensitiveParameter] string $password): bool {} #endif #ifdef HAVE_MEMCACHED_SET_ENCODING_KEY @@ -86,7 +86,7 @@ public function isPristine(): bool {} public function checkKey(string $key): bool {} } -#ifdef HAVE_MEMCACHED_PROTOCOL +#if defined(HAVE_MEMCACHED_PROTOCOL) class MemcachedServer { public function run(string $address): bool {} diff --git a/php_memcached_arginfo.h b/php_memcached_arginfo.h index 3373624e..3108e39f 100644 --- a/php_memcached_arginfo.h +++ b/php_memcached_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3f4694d4e1f3d1647a832acd8539b056b2ab5e7a */ + * Stub hash: 0964c9bfee903e59b63e5a16bd8b6611d827b151 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, persistent_id, IS_STRING, 1, "null") @@ -406,12 +406,39 @@ static const zend_function_entry class_Memcached_methods[] = { }; -static const zend_function_entry class_MemcachedServer_methods[] = { #if defined(HAVE_MEMCACHED_PROTOCOL) +static const zend_function_entry class_MemcachedServer_methods[] = { ZEND_ME(MemcachedServer, run, arginfo_class_MemcachedServer_run, ZEND_ACC_PUBLIC) -#endif -#if defined(HAVE_MEMCACHED_PROTOCOL) ZEND_ME(MemcachedServer, on, arginfo_class_MemcachedServer_on, ZEND_ACC_PUBLIC) -#endif ZEND_FE_END }; +#endif + +static zend_class_entry *register_class_Memcached(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "Memcached", class_Memcached_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); +#if (PHP_VERSION_ID >= 80200) + +#if defined(HAVE_MEMCACHED_SASL) + + zend_add_parameter_attribute(zend_hash_str_find_ptr(&class_entry->function_table, "setsaslauthdata", sizeof("setsaslauthdata") - 1), 1, ZSTR_KNOWN(ZEND_STR_SENSITIVEPARAMETER), 0); +#endif +#endif + + return class_entry; +} + +#if defined(HAVE_MEMCACHED_PROTOCOL) +static zend_class_entry *register_class_MemcachedServer(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "MemcachedServer", class_MemcachedServer_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + + return class_entry; +} +#endif diff --git a/php_memcached_legacy_arginfo.h b/php_memcached_legacy_arginfo.h index ad6d6562..6bb8e2d6 100644 --- a/php_memcached_legacy_arginfo.h +++ b/php_memcached_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3f4694d4e1f3d1647a832acd8539b056b2ab5e7a */ + * Stub hash: 0964c9bfee903e59b63e5a16bd8b6611d827b151 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) ZEND_ARG_INFO(0, persistent_id) @@ -402,12 +402,32 @@ static const zend_function_entry class_Memcached_methods[] = { }; -static const zend_function_entry class_MemcachedServer_methods[] = { #if defined(HAVE_MEMCACHED_PROTOCOL) +static const zend_function_entry class_MemcachedServer_methods[] = { ZEND_ME(MemcachedServer, run, arginfo_class_MemcachedServer_run, ZEND_ACC_PUBLIC) -#endif -#if defined(HAVE_MEMCACHED_PROTOCOL) ZEND_ME(MemcachedServer, on, arginfo_class_MemcachedServer_on, ZEND_ACC_PUBLIC) -#endif ZEND_FE_END }; +#endif + +static zend_class_entry *register_class_Memcached(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "Memcached", class_Memcached_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + + return class_entry; +} + +#if defined(HAVE_MEMCACHED_PROTOCOL) +static zend_class_entry *register_class_MemcachedServer(void) +{ + zend_class_entry ce, *class_entry; + + INIT_CLASS_ENTRY(ce, "MemcachedServer", class_MemcachedServer_methods); + class_entry = zend_register_internal_class_ex(&ce, NULL); + + return class_entry; +} +#endif From 3ff7436dd9ff6b7951f5e9e93cc35242b41a26a8 Mon Sep 17 00:00:00 2001 From: LeoLee Date: Wed, 31 Aug 2022 03:41:08 +0800 Subject: [PATCH 179/218] Windows msgpack support (#518) Co-authored-by: lfeng --- config.w32 | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/config.w32 b/config.w32 index 51aa3bd0..76d4ee3c 100644 --- a/config.w32 +++ b/config.w32 @@ -5,6 +5,7 @@ ARG_ENABLE('memcached', 'libmemcached extension', 'no'); ARG_ENABLE('memcached-session', 'whether to enable memcached session handler support', 'no'); ARG_ENABLE('memcached-igbinary', 'whether to enable memcached igbinary serializer support', 'no'); ARG_ENABLE('memcached-json', 'whether to enable memcached json serializer support', 'no'); +ARG_ENABLE('memcached-msgpack', 'whether to enable memcached msgpack serializer support', 'no'); if (PHP_MEMCACHED == "yes") { @@ -35,7 +36,13 @@ if (PHP_MEMCACHED == "yes") { ERROR("memcached: header 'igbinary.h' not found"); } } - + if (PHP_MEMCACHED_MSGPACK != "no"){ + AC_DEFINE("HAVE_MEMCACHED_MSGPACK",1); + ADD_EXTENSION_DEP("memcached", "msgpack", true); + if (!CHECK_HEADER_ADD_INCLUDE("php_msgpack.h", "CFLAGS_MEMCACHED")) { + ERROR("memcached: header 'php_msgpack.h' not found"); + } + } EXTENSION("memcached", "php_memcached.c php_libmemcached_compat.c g_fmt.c"+memcached_extra_src, null, " /DHAVE_SSIZE_T"); ADD_SOURCES(configure_module_dirname+"\\fastlz", "fastlz.c", "memcached"); AC_DEFINE("HAVE_MEMCACHED", 1, "memcached support"); From aa4868d0f1e91ad08f59fa93c60756587a26f8e5 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Tue, 27 Sep 2022 16:35:41 +0100 Subject: [PATCH 180/218] Put false in union types at the end --- php_memcached.stub.php | 26 +++++++++++++------------- php_memcached_arginfo.h | 16 ++++++++-------- php_memcached_legacy_arginfo.h | 2 +- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/php_memcached.stub.php b/php_memcached.stub.php index a44b1801..80cd44ca 100644 --- a/php_memcached.stub.php +++ b/php_memcached.stub.php @@ -15,12 +15,12 @@ public function getResultMessage(): string {} public function get(string $key, ?callable $cache_cb=null, int $get_flags=0): mixed {} public function getByKey(string $server_key, string $key, ?callable $cache_cb=null, int $get_flags=0): mixed {} - public function getMulti(array $keys, int $get_flags=0): false|array {} - public function getMultiByKey(string $server_key, array $keys, int $get_flags=0): false|array {} + public function getMulti(array $keys, int $get_flags=0): array|false {} + public function getMultiByKey(string $server_key, array $keys, int $get_flags=0): array|false {} public function getDelayed(array $keys, bool $with_cas=false, ?callable $value_cb=null): bool {} public function getDelayedByKey(string $server_key, array $keys, bool $with_cas=false, ?callable $value_cb=null): bool {} - public function fetch(): false|array {} - public function fetchAll(): false|array {} + public function fetch(): array|false {} + public function fetchAll(): array|false {} public function set(string $key, mixed $value, int $expiration=0): bool {} public function setByKey(string $server_key, string $key, mixed $value, int $expiration=0): bool {} @@ -46,15 +46,15 @@ public function deleteMulti(array $keys, int $time=0): array {} public function deleteByKey(string $server_key, string $key, int $time=0): bool {} public function deleteMultiByKey(string $server_key, array $keys, int $time=0): array {} - public function increment(string $key, int $offset=1, int $initial_value=0, int $expiry=0): false|int {} - public function decrement(string $key, int $offset=1, int $initial_value=0, int $expiry=0): false|int {} - public function incrementByKey(string $server_key, string $key, int $offset=1, int $initial_value=0, int $expiry=0): false|int {} - public function decrementByKey(string $server_key, string $key, int $offset=1, int $initial_value=0, int $expiry=0): false|int {} + public function increment(string $key, int $offset=1, int $initial_value=0, int $expiry=0): int|false {} + public function decrement(string $key, int $offset=1, int $initial_value=0, int $expiry=0): int|false {} + public function incrementByKey(string $server_key, string $key, int $offset=1, int $initial_value=0, int $expiry=0): int|false {} + public function decrementByKey(string $server_key, string $key, int $offset=1, int $initial_value=0, int $expiry=0): int|false {} public function addServer(string $host, int $port, int $weight=0): bool {} public function addServers(array $servers): bool {} public function getServerList(): array {} - public function getServerByKey(string $server_key): false|array {} + public function getServerByKey(string $server_key): array|false {} public function resetServerList(): bool {} public function quit(): bool {} public function flushBuffers(): bool {} @@ -62,11 +62,11 @@ public function flushBuffers(): bool {} public function getLastErrorMessage(): string {} public function getLastErrorCode(): int {} public function getLastErrorErrno(): int {} - public function getLastDisconnectedServer(): false|array {} + public function getLastDisconnectedServer(): array|false {} - public function getStats(?string $type=null): false|array {} - public function getVersion(): false|array {} - public function getAllKeys(): false|array {} + public function getStats(?string $type=null): array|false {} + public function getVersion(): array|false {} + public function getAllKeys(): array|false {} public function flush(int $delay=0): bool {} diff --git a/php_memcached_arginfo.h b/php_memcached_arginfo.h index 3108e39f..2b6ef282 100644 --- a/php_memcached_arginfo.h +++ b/php_memcached_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 0964c9bfee903e59b63e5a16bd8b6611d827b151 */ + * Stub hash: 8cb8a18e8e09c6bfc62a51fc31d60171038500ef */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, persistent_id, IS_STRING, 1, "null") @@ -26,12 +26,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getByKey, 0, 2, ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, get_flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_getMulti, 0, 1, MAY_BE_FALSE|MAY_BE_ARRAY) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_getMulti, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, get_flags, IS_LONG, 0, "0") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_getMultiByKey, 0, 2, MAY_BE_FALSE|MAY_BE_ARRAY) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_getMultiByKey, 0, 2, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, server_key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, keys, IS_ARRAY, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, get_flags, IS_LONG, 0, "0") @@ -50,7 +50,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getDelayedByKey, ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value_cb, IS_CALLABLE, 1, "null") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_fetch, 0, 0, MAY_BE_FALSE|MAY_BE_ARRAY) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_fetch, 0, 0, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_END_ARG_INFO() #define arginfo_class_Memcached_fetchAll arginfo_class_Memcached_fetch @@ -150,7 +150,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_deleteMultiByKey ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, time, IS_LONG, 0, "0") ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_increment, 0, 1, MAY_BE_FALSE|MAY_BE_LONG) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_increment, 0, 1, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, offset, IS_LONG, 0, "1") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, initial_value, IS_LONG, 0, "0") @@ -159,7 +159,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_Memcached_decrement arginfo_class_Memcached_increment -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_incrementByKey, 0, 2, MAY_BE_FALSE|MAY_BE_LONG) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_incrementByKey, 0, 2, MAY_BE_LONG|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, server_key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, offset, IS_LONG, 0, "1") @@ -182,7 +182,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_getServerList, 0, 0, IS_ARRAY, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_getServerByKey, 0, 1, MAY_BE_FALSE|MAY_BE_ARRAY) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_getServerByKey, 0, 1, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO(0, server_key, IS_STRING, 0) ZEND_END_ARG_INFO() @@ -201,7 +201,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_Memcached_getLastDisconnectedServer arginfo_class_Memcached_fetch -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_getStats, 0, 0, MAY_BE_FALSE|MAY_BE_ARRAY) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_class_Memcached_getStats, 0, 0, MAY_BE_ARRAY|MAY_BE_FALSE) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, type, IS_STRING, 1, "null") ZEND_END_ARG_INFO() diff --git a/php_memcached_legacy_arginfo.h b/php_memcached_legacy_arginfo.h index 6bb8e2d6..81edffa0 100644 --- a/php_memcached_legacy_arginfo.h +++ b/php_memcached_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 0964c9bfee903e59b63e5a16bd8b6611d827b151 */ + * Stub hash: 8cb8a18e8e09c6bfc62a51fc31d60171038500ef */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) ZEND_ARG_INFO(0, persistent_id) From 121473118ab13b4993c6623f4a63a7e91ce61261 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Mon, 14 Nov 2022 08:43:03 +0100 Subject: [PATCH 181/218] Fix #523 Incorrect PHP reflection type for Memcached::cas $cas_token --- php_memcached.stub.php | 4 ++-- php_memcached_arginfo.h | 6 +++--- php_memcached_legacy_arginfo.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/php_memcached.stub.php b/php_memcached.stub.php index 80cd44ca..7e85ef32 100644 --- a/php_memcached.stub.php +++ b/php_memcached.stub.php @@ -31,8 +31,8 @@ public function touchByKey(string $server_key, string $key, int $expiration=0): public function setMulti(array $items, int $expiration=0): bool {} public function setMultiByKey(string $server_key, array $items, int $expiration=0): bool {} - public function cas(string $cas_token, string $key, mixed $value, int $expiration=0): bool {} - public function casByKey(string $cas_token, string $server_key, string $key, mixed $value, int $expiration=0): bool {} + public function cas(string|int|float $cas_token, string $key, mixed $value, int $expiration=0): bool {} + public function casByKey(string|int|float $cas_token, string $server_key, string $key, mixed $value, int $expiration=0): bool {} public function add(string $key, mixed $value, int $expiration=0): bool {} public function addByKey(string $server_key, string $key, mixed $value, int $expiration=0): bool {} public function append(string $key, string $value): ?bool {} diff --git a/php_memcached_arginfo.h b/php_memcached_arginfo.h index 2b6ef282..e8b999de 100644 --- a/php_memcached_arginfo.h +++ b/php_memcached_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 8cb8a18e8e09c6bfc62a51fc31d60171038500ef */ + * Stub hash: 75604abd7f58655a9ebda6f0ea579840311c1f08 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, persistent_id, IS_STRING, 1, "null") @@ -91,14 +91,14 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_setMultiByKey, 0 ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_cas, 0, 3, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, cas_token, IS_STRING, 0) + ZEND_ARG_TYPE_MASK(0, cas_token, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE, NULL) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, expiration, IS_LONG, 0, "0") ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Memcached_casByKey, 0, 4, _IS_BOOL, 0) - ZEND_ARG_TYPE_INFO(0, cas_token, IS_STRING, 0) + ZEND_ARG_TYPE_MASK(0, cas_token, MAY_BE_STRING|MAY_BE_LONG|MAY_BE_DOUBLE, NULL) ZEND_ARG_TYPE_INFO(0, server_key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0) diff --git a/php_memcached_legacy_arginfo.h b/php_memcached_legacy_arginfo.h index 81edffa0..66d5bb91 100644 --- a/php_memcached_legacy_arginfo.h +++ b/php_memcached_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 8cb8a18e8e09c6bfc62a51fc31d60171038500ef */ + * Stub hash: 75604abd7f58655a9ebda6f0ea579840311c1f08 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Memcached___construct, 0, 0, 0) ZEND_ARG_INFO(0, persistent_id) From 38c38d7b47074b3007a67c2d2b435011872469e8 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 16 Nov 2022 07:56:04 +0100 Subject: [PATCH 182/218] changelog --- package.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.xml b/package.xml index 9dc283be..6a14b96c 100644 --- a/package.xml +++ b/package.xml @@ -44,7 +44,8 @@ http://pear.php.net/dtd/package-2.0.xsd"> PHP -- +- mark password as a sensitive param for PHP 8.2 +- Fix #523 Incorrect PHP reflection type for Memcached::cas $cas_token From 3b0070aab2e5984e9ad322df51449b570f85bbc9 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Fri, 6 Jan 2023 14:32:41 -0800 Subject: [PATCH 183/218] CI: Add PHP 8.2 to the required matrix, add PHP 8.3 to experimental (#529) --- .github/workflows/build-and-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 79b22569..a5995e3a 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -7,10 +7,10 @@ jobs: strategy: fail-fast: false matrix: - php: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] + php: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] experimental: [false] include: - - php: '8.2' + - php: '8.3' experimental: true steps: - name: Checkout From 04a0f72eaafc0ac4ba646b57761b8d7331cdc82a Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Mon, 9 Jan 2023 11:07:54 -0800 Subject: [PATCH 184/218] CI: Add libmemcached-awesome to matrix (#530) --- .github/workflows/build-and-test.yml | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index a5995e3a..7384dd88 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -10,6 +10,9 @@ jobs: php: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] experimental: [false] include: + - php: '8.2' + awesome: true + experimental: true - php: '8.3' experimental: true steps: @@ -25,7 +28,21 @@ jobs: - name: Install dependencies run: | sudo apt-get update - sudo apt-get install libmemcached-dev memcached libsasl2-dev sasl2-bin zlib1g-dev + sudo apt-get install cmake memcached libsasl2-dev sasl2-bin zlib1g-dev + - if: ${{ ! matrix.awesome }} + name: Install libmemcached-dev (from distro) + run: sudo apt-get install libmemcached-dev + - if: ${{ matrix.awesome }} + name: Install libmemcached-awesome (from source) + run: | + curl -sL -o libmemcached.tgz https://github.com/awesomized/libmemcached/archive/refs/tags/1.1.3.tar.gz + mkdir libmemcached + tar --strip-components=1 -xf libmemcached.tgz -C libmemcached + mkdir build-libmemcached + cd build-libmemcached + cmake -D ENABLE_HASH_HSIEH=ON -D ENABLE_SASL=ON ../libmemcached + make + sudo make install - name: Start memcached daemons run: | export SASL_CONF_PATH="/tmp/sasl2" From 6a58af6abc3edbe3d4848f80e54e1fb5cb821ba4 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 18 Jan 2023 18:50:05 +0100 Subject: [PATCH 185/218] Add minimal Windows CI (#532) For now, only building the extension is supported. --- .github/workflows/build-windows.yml | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/build-windows.yml diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml new file mode 100644 index 00000000..36cf7cba --- /dev/null +++ b/.github/workflows/build-windows.yml @@ -0,0 +1,37 @@ +name: Build on Windows +on: [push, pull_request] +jobs: + windows: + defaults: + run: + shell: cmd + strategy: + matrix: + version: ['7.4', '8.0', '8.1'] + arch: [x64, x86] + ts: [nts, zts] + runs-on: windows-latest + steps: + - name: Checkout memcached + uses: actions/checkout@v2 + - name: Setup PHP + id: setup-php + uses: cmb69/setup-php-sdk@v0.7 + with: + version: ${{matrix.version}} + arch: ${{matrix.arch}} + ts: ${{matrix.ts}} + deps: zlib + - name: Fetch libmemcached + run: curl -OLs https://windows.php.net/downloads/pecl/deps/libmemcached-1.1.1-${{steps.setup-php.outputs.vs}}-${{matrix.arch}}.zip && 7z x libmemcached-1.1.1-${{steps.setup-php.outputs.vs}}-${{matrix.arch}}.zip -o..\deps + - name: Enable Developer Command Prompt + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: ${{matrix.arch}} + toolset: ${{steps.setup-php.outputs.toolset}} + - name: phpize + run: phpize + - name: configure + run: configure --enable-memcached --enable-memcached-session --enable-memcached-json --with-prefix=${{steps.setup-php.outputs.prefix}} + - name: make + run: nmake From 1eac9f8b8e8998f2feefc47d3aa80cfe93da22af Mon Sep 17 00:00:00 2001 From: LeoLee Date: Wed, 1 Feb 2023 06:45:26 +0800 Subject: [PATCH 186/218] PHP 8 compatibility Windows (#528) Use PHP_VERSION_ID instead of _MSC_VER to select the right headers. win32/php_stdint.h was removed in PHP 8.0.0 and php_stdint.h file was removed in PHP 8.2.0 entirely: https://github.com/php/php-src/blob/PHP-8.2/UPGRADING.INTERNALS#L26 --- php_memcached_private.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/php_memcached_private.h b/php_memcached_private.h index b4b1115b..48f1dfab 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -48,11 +48,11 @@ #include #ifdef PHP_WIN32 - # if PHP_VERSION_ID >= 80000 - # include "php_stdint.h" -#else -# include "win32/php_stdint.h" -#endif + # if PHP_VERSION_ID >= 80000 + # include + #else + # include "win32/php_stdint.h" + #endif #else /* Used to store the size of the block */ # if defined(HAVE_INTTYPES_H) From 811c8a142239242f928419d349eea092536c24aa Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Thu, 2 Feb 2023 20:42:07 +0100 Subject: [PATCH 187/218] Fix #522 Signed integer overflow (#526) --- php_memcached.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index 7ccc9b58..ece54408 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -86,7 +86,7 @@ static int php_memc_list_entry(void) { /**************************************** Payload value flags ****************************************/ -#define MEMC_CREATE_MASK(start, n_bits) (((1 << n_bits) - 1) << start) +#define MEMC_CREATE_MASK(start, n_bits) (((1U << n_bits) - 1) << start) #define MEMC_MASK_TYPE MEMC_CREATE_MASK(0, 4) #define MEMC_MASK_INTERNAL MEMC_CREATE_MASK(4, 12) From 6926c53ac32a579b38a0dcc3c8aec662f8cd9dd5 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Tue, 11 Apr 2023 11:15:46 -0700 Subject: [PATCH 188/218] README.markdown: PHP 8.2 is supported --- README.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 8819caf9..b17b7e55 100644 --- a/README.markdown +++ b/README.markdown @@ -23,7 +23,7 @@ Dependencies ------------ php-memcached 3.x: -* Supports PHP 7.0 - 8.1. +* Supports PHP 7.0 - 8.2 or higher. * Requires libmemcached 1.x or higher. * Optionally supports igbinary 2.0 or higher. * Optionally supports msgpack 2.0 or higher. From 58335902966f37f82548210556095a11759bcc60 Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Thu, 27 Apr 2023 11:32:10 -0400 Subject: [PATCH 189/218] zstd support (#539) This adds zstd compression support. The current two options, zlib and fastlz is basically a choice between performance and compression ratio. You would choose zlib if you are memory-bound and fastlz if you are cpu-bound. With zstd, you get the performance of fastlz with the compression of zlib. And often it wins on both. See this benchmark I ran on json files of varying sizes: https://gist.github.com/rlerdorf/788f3d0144f9c5514d8fee9477cbe787 Taking just a 40k json blob, we see that zstd at compression level 3 reduces it to 8862 bytes. Our current zlib 1 gets worse compression at 10091 bytes and takes longer both to compress and decompress. C Size ratio% C MB/s D MB/s SCORE Name File 8037 19.9 0.58 2130.89 0.08 zstd 22 file-39.54k-json 8204 20.3 31.85 2381.59 0.01 zstd 10 file-39.54k-json 8371 20.7 47.52 547.12 0.01 zlib 9 file-39.54k-json 8477 20.9 74.84 539.83 0.01 zlib 6 file-39.54k-json 8862 21.9 449.86 2130.89 0.01 zstd 3 file-39.54k-json 9171 22.7 554.62 2381.59 0.01 zstd 1 file-39.54k-json 10091 24.9 153.94 481.99 0.01 zlib 1 file-39.54k-json 10646 26.3 43.39 8097.40 0.01 lz4 16 file-39.54k-json 10658 26.3 72.30 8097.40 0.01 lz4 10 file-39.54k-json 13004 32.1 1396.10 6747.83 0.01 lz4 1 file-39.54k-json 13321 32.9 440.08 1306.03 0.01 fastlz 2 file-39.54k-json 14807 36.6 444.91 1156.77 0.01 fastlz 1 file-39.54k-json 15517 38.3 1190.79 4048.70 0.02 zstd -10 file-39.54k-json The fact that decompression a dramatically faster with zstd is a win for most common memcache uses since they tend to be read-heavy. The PR also adds a `memcache.compression_level` INI switch which currently only applies to zstd compression. It could probably be made to also apply to zlib and fastlz. --- config.m4 | 10 ++++ php_memcached.c | 78 ++++++++++++++++++++++++++++++- php_memcached_private.h | 4 +- tests/compression_conditions.phpt | 2 + tests/compression_types.phpt | 34 ++++++++++++++ 5 files changed, 125 insertions(+), 3 deletions(-) diff --git a/config.m4 b/config.m4 index c7a15f11..0e4ef8cf 100644 --- a/config.m4 +++ b/config.m4 @@ -27,6 +27,9 @@ PHP_ARG_ENABLE(memcached-protocol, whether to enable memcached protocol support, PHP_ARG_WITH(system-fastlz, whether to use system FastLZ library, [ --with-system-fastlz Use system FastLZ library], no, no) +PHP_ARG_WITH(zstd, whether to use system zstd library, +[ --with-zstd Use system zstd library], no, no) + if test -z "$PHP_ZLIB_DIR"; then PHP_ARG_WITH(zlib-dir, for ZLIB, [ --with-zlib-dir=DIR Set the path to ZLIB install prefix.], no) @@ -345,6 +348,13 @@ if test "$PHP_MEMCACHED" != "no"; then PHP_MEMCACHED_FILES="${PHP_MEMCACHED_FILES} fastlz/fastlz.c" fi + if test "$PHP_ZSTD" != "no"; then + AC_CHECK_HEADERS([zstd.h], [ac_cv_have_zstd="yes"], [ac_cv_have_zstd="no"]) + PHP_CHECK_LIBRARY(zstd, ZSTD_compress, + [PHP_ADD_LIBRARY(zstd, 1, MEMCACHED_SHARED_LIBADD)], + [AC_MSG_ERROR(zstd library not found)]) + fi + if test "$PHP_MEMCACHED_SESSION" != "no"; then PHP_MEMCACHED_FILES="${PHP_MEMCACHED_FILES} php_memcached_session.c" fi diff --git a/php_memcached.c b/php_memcached.c index ece54408..e7d5736c 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -37,6 +37,10 @@ #endif #include +#ifdef HAVE_ZSTD_H +#include +#endif + #ifdef HAVE_JSON_API # include "ext/json/php_json.h" #endif @@ -77,6 +81,7 @@ static int php_memc_list_entry(void) { #define MEMC_OPT_COMPRESSION_TYPE -1004 #define MEMC_OPT_STORE_RETRY_COUNT -1005 #define MEMC_OPT_USER_FLAGS -1006 +#define MEMC_OPT_COMPRESSION_LEVEL -1007 /**************************************** Custom result codes @@ -107,6 +112,7 @@ static int php_memc_list_entry(void) { #define MEMC_VAL_COMPRESSED (1<<0) #define MEMC_VAL_COMPRESSION_ZLIB (1<<1) #define MEMC_VAL_COMPRESSION_FASTLZ (1<<2) +#define MEMC_VAL_COMPRESSION_ZSTD (1<<3) #define MEMC_VAL_GET_FLAGS(internal_flags) (((internal_flags) & MEMC_MASK_INTERNAL) >> 4) #define MEMC_VAL_SET_FLAG(internal_flags, internal_flag) ((internal_flags) |= (((internal_flag) << 4) & MEMC_MASK_INTERNAL)) @@ -152,6 +158,7 @@ typedef struct { zend_long serializer; zend_long compression_type; + zend_long compression_level; zend_long store_retry_count; zend_long set_udf_flags; @@ -278,6 +285,10 @@ static PHP_INI_MH(OnUpdateCompressionType) MEMC_G(compression_type) = COMPRESSION_TYPE_FASTLZ; } else if (!strcmp(ZSTR_VAL(new_value), "zlib")) { MEMC_G(compression_type) = COMPRESSION_TYPE_ZLIB; +#ifdef HAVE_ZSTD_H + } else if (!strcmp(ZSTR_VAL(new_value), "zstd")) { + MEMC_G(compression_type) = COMPRESSION_TYPE_ZSTD; +#endif } else { return FAILURE; } @@ -408,6 +419,7 @@ PHP_INI_BEGIN() MEMC_INI_ENTRY("compression_type", "fastlz", OnUpdateCompressionType, compression_name) MEMC_INI_ENTRY("compression_factor", "1.3", OnUpdateReal, compression_factor) + MEMC_INI_ENTRY("compression_level", "3", OnUpdateLong, compression_level) MEMC_INI_ENTRY("compression_threshold", "2000", OnUpdateLong, compression_threshold) MEMC_INI_ENTRY("serializer", SERIALIZER_DEFAULT_NAME, OnUpdateSerializer, serializer_name) MEMC_INI_ENTRY("store_retry_count", "0", OnUpdateLong, store_retry_count) @@ -897,6 +909,19 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str } break; +#ifdef HAVE_ZSTD_H + case COMPRESSION_TYPE_ZSTD: + { + compressed_size = ZSTD_compress((void *)buffer, buffer_size, ZSTR_VAL(payload), ZSTR_LEN(payload), MEMC_G(compression_level)); + + if (!ZSTD_isError(compressed_size)) { + compress_status = 1; + compression_type_flag = MEMC_VAL_COMPRESSION_ZSTD; + } + } + break; +#endif + case COMPRESSION_TYPE_ZLIB: { compressed_size = buffer_size; @@ -2939,6 +2964,9 @@ static PHP_METHOD(Memcached, getOption) case MEMC_OPT_COMPRESSION_TYPE: RETURN_LONG(memc_user_data->compression_type); + case MEMC_OPT_COMPRESSION_LEVEL: + RETURN_LONG(memc_user_data->compression_level); + case MEMC_OPT_COMPRESSION: RETURN_BOOL(memc_user_data->compression_enabled); @@ -3001,6 +3029,9 @@ int php_memc_set_option(php_memc_object_t *intern, long option, zval *value) case MEMC_OPT_COMPRESSION_TYPE: lval = zval_get_long(value); if (lval == COMPRESSION_TYPE_FASTLZ || +#ifdef HAVE_ZSTD_H + lval == COMPRESSION_TYPE_ZSTD || +#endif lval == COMPRESSION_TYPE_ZLIB) { memc_user_data->compression_type = lval; } else { @@ -3608,16 +3639,24 @@ zend_string *s_decompress_value (const char *payload, size_t payload_len, uint32 uint32_t stored_length; unsigned long length; zend_bool decompress_status = 0; - zend_bool is_fastlz = 0, is_zlib = 0; + zend_bool is_fastlz = 0, is_zlib = 0, is_zstd = 0; if (payload_len < sizeof (uint32_t)) { return NULL; } is_fastlz = MEMC_VAL_HAS_FLAG(flags, MEMC_VAL_COMPRESSION_FASTLZ); + is_zstd = MEMC_VAL_HAS_FLAG(flags, MEMC_VAL_COMPRESSION_ZSTD); is_zlib = MEMC_VAL_HAS_FLAG(flags, MEMC_VAL_COMPRESSION_ZLIB); - if (!is_fastlz && !is_zlib) { +#ifndef HAVE_ZSTD_H + if (is_zstd) { + php_error_docref(NULL, E_WARNING, "could not decompress value: value was compressed with zstd but zstd support has not been compiled in"); + return NULL; + } +#endif + + if (!is_fastlz && !is_zlib && !is_zstd) { php_error_docref(NULL, E_WARNING, "could not decompress value: unrecognised compression type"); return NULL; } @@ -3629,6 +3668,23 @@ zend_string *s_decompress_value (const char *payload, size_t payload_len, uint32 buffer = zend_string_alloc (stored_length, 0); +#ifdef HAVE_ZSTD_H + if (is_zstd) { + length = ZSTD_getFrameContentSize(payload, payload_len); + if (length == ZSTD_CONTENTSIZE_ERROR) { + php_error_docref(NULL, E_WARNING, "value was not compressed by zstd"); + zend_string_release (buffer); + return NULL; + } else if (length == ZSTD_CONTENTSIZE_UNKNOWN) { + php_error_docref(NULL, E_WARNING, "zstd streaming decompression not supported"); + zend_string_release (buffer); + return NULL; + } + decompress_status = !ZSTD_isError(ZSTD_decompress(&buffer->val, buffer->len, payload, payload_len)); + + } + else +#endif if (is_fastlz) { decompress_status = ((length = fastlz_decompress(payload, payload_len, &buffer->val, buffer->len)) > 0); } @@ -3955,6 +4011,7 @@ PHP_GINIT_FUNCTION(php_memcached) php_memcached_globals->memc.compression_threshold = 2000; php_memcached_globals->memc.compression_type = COMPRESSION_TYPE_FASTLZ; php_memcached_globals->memc.compression_factor = 1.30; + php_memcached_globals->memc.compression_level = 3; php_memcached_globals->memc.store_retry_count = 2; php_memcached_globals->memc.sasl_initialised = 0; @@ -4000,6 +4057,7 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) REGISTER_MEMC_CLASS_CONST_LONG(OPT_COMPRESSION, MEMC_OPT_COMPRESSION); REGISTER_MEMC_CLASS_CONST_LONG(OPT_COMPRESSION_TYPE, MEMC_OPT_COMPRESSION_TYPE); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_COMPRESSION_LEVEL, MEMC_OPT_COMPRESSION_LEVEL); REGISTER_MEMC_CLASS_CONST_LONG(OPT_PREFIX_KEY, MEMC_OPT_PREFIX_KEY); REGISTER_MEMC_CLASS_CONST_LONG(OPT_SERIALIZER, MEMC_OPT_SERIALIZER); @@ -4015,6 +4073,15 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_IGBINARY, 0); #endif + /* + * Indicate whether zstd compression is available + */ +#ifdef HAVE_ZSTD_H + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_ZSTD, 1); +#else + REGISTER_MEMC_CLASS_CONST_BOOL(HAVE_ZSTD, 0); +#endif + /* * Indicate whether json serializer is available */ @@ -4186,6 +4253,7 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) */ REGISTER_MEMC_CLASS_CONST_LONG(COMPRESSION_FASTLZ, COMPRESSION_TYPE_FASTLZ); REGISTER_MEMC_CLASS_CONST_LONG(COMPRESSION_ZLIB, COMPRESSION_TYPE_ZLIB); + REGISTER_MEMC_CLASS_CONST_LONG(COMPRESSION_ZSTD, COMPRESSION_TYPE_ZSTD); /* * Flags. @@ -4351,6 +4419,12 @@ PHP_MINFO_FUNCTION(memcached) php_info_print_table_row(2, "msgpack support", "no"); #endif +#ifdef HAVE_ZSTD_H + php_info_print_table_row(2, "zstd support", "yes"); +#else + php_info_print_table_row(2, "zstd support", "no"); +#endif + php_info_print_table_end(); DISPLAY_INI_ENTRIES(); diff --git a/php_memcached_private.h b/php_memcached_private.h index 48f1dfab..aefaf4fb 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -98,7 +98,8 @@ typedef enum { typedef enum { COMPRESSION_TYPE_ZLIB = 1, - COMPRESSION_TYPE_FASTLZ = 2 + COMPRESSION_TYPE_FASTLZ = 2, + COMPRESSION_TYPE_ZSTD = 3 } php_memc_compression_type; typedef struct { @@ -186,6 +187,7 @@ ZEND_BEGIN_MODULE_GLOBALS(php_memcached) zend_long compression_threshold; double compression_factor; zend_long store_retry_count; + zend_long compression_level; /* Converted values*/ php_memc_serializer_type serializer_type; diff --git a/tests/compression_conditions.phpt b/tests/compression_conditions.phpt index 749ebe8a..960058b6 100644 --- a/tests/compression_conditions.phpt +++ b/tests/compression_conditions.phpt @@ -21,6 +21,8 @@ function get_compression($name) { return Memcached::COMPRESSION_ZLIB; case 'fastlz': return Memcached::COMPRESSION_FASTLZ; + case 'zstd': + return Memcached::COMPRESSION_ZSTD; default: echo "Strange compression type: $name\n"; return 0; diff --git a/tests/compression_types.phpt b/tests/compression_types.phpt index ce07aed5..81d7867c 100644 --- a/tests/compression_types.phpt +++ b/tests/compression_types.phpt @@ -15,6 +15,10 @@ function get_compression($name) { return Memcached::COMPRESSION_ZLIB; case 'fastlz': return Memcached::COMPRESSION_FASTLZ; + case 'zstd': + if (Memcached::HAVE_ZSTD) { + return Memcached::COMPRESSION_ZSTD; + } else return 0; default: echo "Strange compression type: $name\n"; return 0; @@ -54,6 +58,26 @@ fetch_with_compression($m, 'hello6', $data, '', 'fastlz'); fetch_with_compression($m, 'hello7', $data, 'zlib', ''); fetch_with_compression($m, 'hello8', $data, 'fastlz', ''); fetch_with_compression($m, 'hello9', $data, '', ''); +if (Memcached::HAVE_ZSTD) { +fetch_with_compression($m, 'hello10', $data, 'zstd', 'zstd'); +fetch_with_compression($m, 'hello11', $data, 'zstd', 'fastlz'); +fetch_with_compression($m, 'hello12', $data, 'fastlz', 'zstd'); +fetch_with_compression($m, 'hello13', $data, '', 'zstd'); +fetch_with_compression($m, 'hello14', $data, 'zstd', ''); +} else { + echo << --EXPECT-- set=[zlib] get=[zlib] @@ -74,3 +98,13 @@ set=[fastlz] get=[] bool(true) set=[] get=[] bool(true) +set=[zstd] get=[zstd] +bool(true) +set=[zstd] get=[fastlz] +bool(true) +set=[fastlz] get=[zstd] +bool(true) +set=[] get=[zstd] +bool(true) +set=[zstd] get=[] +bool(true) From 7348cc11f729432116b652ccddb87011d553ca42 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Thu, 27 Apr 2023 18:35:07 +0300 Subject: [PATCH 190/218] Move working tests up a folder (#503) Tests in the experimental/ folder were not executed on CI. The ones that work move up, the few that remain in experimental/ need further investigation to get working or remove. --- tests/{experimental => }/add_bykey.phpt | 6 +- .../addserver_unixdomain.phpt | 2 +- tests/{experimental => }/append_bykey.phpt | 4 +- tests/{experimental => }/cas_bykey.phpt | 4 +- tests/{experimental => }/cas_invalid_key.phpt | 6 +- tests/{experimental => }/delete_bykey.phpt | 6 +- .../deletemulti_nonstringkeys.phpt | 4 +- tests/experimental/get_bykey_cas.phpt | 70 ------------------- tests/{experimental => }/fetch.phpt | 4 +- .../fetch_badunserialize.phpt | 15 +++- .../fetchall_badunserialize.phpt | 15 +++- tests/{experimental => }/get.phpt | 6 +- tests/{experimental => }/get_bykey.phpt | 6 +- tests/get_bykey_cas.phpt | 61 ++++++++++++++++ .../getdelayed_badserver.phpt | 2 +- .../getdelayed_badunserialize.phpt | 15 +++- .../{experimental => }/getdelayed_bykey.phpt | 4 +- .../getdelayed_bykey_cas.phpt | 34 +++++---- .../getdelayed_nonstring_keys.phpt | 4 +- .../getmulti_badserver.phpt | 8 +-- .../getmulti_badunserialize.phpt | 12 +++- tests/{experimental => }/getmulti_bykey.phpt | 4 +- tests/{experimental => }/getmulti_empty.phpt | 4 +- .../getmulti_partial_error.phpt | 4 +- tests/{experimental => }/getversion.phpt | 4 +- tests/{experimental => }/locale_float.phpt | 4 +- tests/{experimental => }/moduleinfo.phpt | 2 +- tests/{experimental => }/prepend_bykey.phpt | 4 +- tests/{experimental => }/replace_bykey.phpt | 4 +- tests/{experimental => }/set_bykey.phpt | 6 +- .../set_comp_below_factor.phpt | 4 +- .../set_default_serializer.phpt | 2 +- .../set_invalid_serializer.phpt | 2 +- .../setget_zero_factor.phpt | 4 +- tests/{experimental => }/setmulti_bykey.phpt | 4 +- 35 files changed, 190 insertions(+), 150 deletions(-) rename tests/{experimental => }/add_bykey.phpt (84%) rename tests/{experimental => }/addserver_unixdomain.phpt (87%) rename tests/{experimental => }/append_bykey.phpt (78%) rename tests/{experimental => }/cas_bykey.phpt (84%) rename tests/{experimental => }/cas_invalid_key.phpt (65%) rename tests/{experimental => }/delete_bykey.phpt (82%) rename tests/{experimental => }/deletemulti_nonstringkeys.phpt (87%) delete mode 100644 tests/experimental/get_bykey_cas.phpt rename tests/{experimental => }/fetch.phpt (93%) rename tests/{experimental => }/fetch_badunserialize.phpt (76%) rename tests/{experimental => }/fetchall_badunserialize.phpt (76%) rename tests/{experimental => }/get.phpt (78%) rename tests/{experimental => }/get_bykey.phpt (75%) create mode 100644 tests/get_bykey_cas.phpt rename tests/{experimental => }/getdelayed_badserver.phpt (87%) rename tests/{experimental => }/getdelayed_badunserialize.phpt (77%) rename tests/{experimental => }/getdelayed_bykey.phpt (89%) rename tests/{experimental => }/getdelayed_bykey_cas.phpt (76%) rename tests/{experimental => }/getdelayed_nonstring_keys.phpt (90%) rename tests/{experimental => }/getmulti_badserver.phpt (85%) rename tests/{experimental => }/getmulti_badunserialize.phpt (77%) rename tests/{experimental => }/getmulti_bykey.phpt (82%) rename tests/{experimental => }/getmulti_empty.phpt (60%) rename tests/{experimental => }/getmulti_partial_error.phpt (84%) rename tests/{experimental => }/getversion.phpt (69%) rename tests/{experimental => }/locale_float.phpt (80%) rename tests/{experimental => }/moduleinfo.phpt (86%) rename tests/{experimental => }/prepend_bykey.phpt (78%) rename tests/{experimental => }/replace_bykey.phpt (82%) rename tests/{experimental => }/set_bykey.phpt (83%) rename tests/{experimental => }/set_comp_below_factor.phpt (74%) rename tests/{experimental => }/set_default_serializer.phpt (95%) rename tests/{experimental => }/set_invalid_serializer.phpt (92%) rename tests/{experimental => }/setget_zero_factor.phpt (70%) rename tests/{experimental => }/setmulti_bykey.phpt (87%) diff --git a/tests/experimental/add_bykey.phpt b/tests/add_bykey.phpt similarity index 84% rename from tests/experimental/add_bykey.phpt rename to tests/add_bykey.phpt index 195fe96d..1c1521d2 100644 --- a/tests/experimental/add_bykey.phpt +++ b/tests/add_bykey.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached::addByKey() --SKIPIF-- - + --FILE-- delete('foo'); @@ -15,7 +15,7 @@ echo $m->getResultMessage(), "\n"; var_dump($m->addByKey('foo', '', 1, 10)); echo $m->getResultMessage(), "\n"; // This is OK for the binary protocol -$rv = $m->addByKey('foo', ' asd ���', 1, 1); +$rv = $m->addByKey('foo', ' asd åäö', 1, 1); if ($m->getOption(Memcached::OPT_BINARY_PROTOCOL)) { if ($rv !== true and $m->getResultCode() !== Memcached::RES_SUCCESS) { var_dump($rv); diff --git a/tests/experimental/addserver_unixdomain.phpt b/tests/addserver_unixdomain.phpt similarity index 87% rename from tests/experimental/addserver_unixdomain.phpt rename to tests/addserver_unixdomain.phpt index 4848015d..7e16834c 100644 --- a/tests/experimental/addserver_unixdomain.phpt +++ b/tests/addserver_unixdomain.phpt @@ -1,7 +1,7 @@ --TEST-- Memcached::addServer() unix doamin socket --SKIPIF-- - + --CLEAN-- + --FILE-- setOption(Memcached::OPT_COMPRESSION, false); diff --git a/tests/experimental/cas_bykey.phpt b/tests/cas_bykey.phpt similarity index 84% rename from tests/experimental/cas_bykey.phpt rename to tests/cas_bykey.phpt index 0a9da94e..32808813 100644 --- a/tests/experimental/cas_bykey.phpt +++ b/tests/cas_bykey.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached::casByKey() --SKIPIF-- - + --FILE-- delete('cas_test'); diff --git a/tests/experimental/cas_invalid_key.phpt b/tests/cas_invalid_key.phpt similarity index 65% rename from tests/experimental/cas_invalid_key.phpt rename to tests/cas_invalid_key.phpt index 6011c4b8..b8a815dc 100644 --- a/tests/experimental/cas_invalid_key.phpt +++ b/tests/cas_invalid_key.phpt @@ -1,17 +1,17 @@ --TEST-- Memcached::cas() with strange key --SKIPIF-- - + --FILE-- cas(0, '', true, 10)); echo $m->getResultMessage(), "\n"; -var_dump($m->cas(0, ' �� jas kjjhask d ', true, 10)); # no spaces allowed +var_dump($m->cas(0, ' äö jas kjjhask d ', true, 10)); # no spaces allowed echo $m->getResultMessage(), "\n"; --EXPECTF-- diff --git a/tests/experimental/delete_bykey.phpt b/tests/delete_bykey.phpt similarity index 82% rename from tests/experimental/delete_bykey.phpt rename to tests/delete_bykey.phpt index 807af8ca..929ffbc1 100644 --- a/tests/experimental/delete_bykey.phpt +++ b/tests/delete_bykey.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached::deleteByKey() --SKIPIF-- - + --FILE-- setByKey('keffe', 'eisaleeoo', "foo"); @@ -21,7 +21,7 @@ var_dump($m->deleteByKey('keffe', '')); echo $m->getResultMessage(), "\n"; var_dump($m->deleteByKey('', 'keffe')); echo $m->getResultMessage(), "\n"; -var_dump($m->deleteByKey('keffe', '���as�� �a�sd�f asdf')); # no spaces allowed +var_dump($m->deleteByKey('keffe', 'äöåasäö åaösdäf asdf')); # no spaces allowed echo $m->getResultMessage(), "\n"; --EXPECTF-- string(3) "foo" diff --git a/tests/experimental/deletemulti_nonstringkeys.phpt b/tests/deletemulti_nonstringkeys.phpt similarity index 87% rename from tests/experimental/deletemulti_nonstringkeys.phpt rename to tests/deletemulti_nonstringkeys.phpt index 2dac8920..8e275e9c 100644 --- a/tests/experimental/deletemulti_nonstringkeys.phpt +++ b/tests/deletemulti_nonstringkeys.phpt @@ -1,10 +1,10 @@ --TEST-- Delete multi with integer keys --SKIPIF-- - + --FILE-- ---FILE-- -set('foo', 1, 10); - -$cas = null; -var_dump($m->getByKey('foo', 'foo', null, $cas)); -var_dump($cas); -echo $m->getResultMessage(), "\n"; - -$cas = null; -var_dump($m->getByKey('', 'foo', null, $cas)); -var_dump($cas); -echo $m->getResultMessage(), "\n"; - -$m->set('bar', "asdf", 10); - -$cas = null; -var_dump($m->getByKey('foo', 'bar', null, $cas)); -var_dump($cas); -echo $m->getResultMessage(), "\n"; - -$m->delete('foo'); -$cas = null; -var_dump($m->getByKey(' � foo jkh a s ���', 'foo', null, $cas)); -var_dump($cas); -echo $m->getResultMessage(), "\n"; - -$cas = null; -var_dump($m->getByKey(' � foo jkh a s ���', '', null, $cas)); -var_dump($cas); -echo $m->getResultMessage(), "\n"; - -$m->delete('foo'); -$cas = null; -var_dump($m->getByKey('foo', 'foo', 'the_callback', $cas)); -var_dump($cas); -var_dump($m->getByKey('foo', 'foo')); ---EXPECTF-- -int(1) -float(%d) -SUCCESS -int(1) -float(%d) -SUCCESS -string(4) "asdf" -float(%d) -SUCCESS -bool(false) -float(0) -NOT FOUND -bool(false) -NULL -A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE -called -string(4) "1234" -float(0) -string(4) "1234" diff --git a/tests/experimental/fetch.phpt b/tests/fetch.phpt similarity index 93% rename from tests/experimental/fetch.phpt rename to tests/fetch.phpt index 13136c5b..68977466 100644 --- a/tests/experimental/fetch.phpt +++ b/tests/fetch.phpt @@ -1,7 +1,7 @@ --TEST-- Memcached getDelayed() and fetch() with and without cas --SKIPIF-- - + --FILE-- + --FILE-- serialize_throws) { + throw new Exception("1234"); + } + return ["1234"]; + } + + public function __unserialize($str) { + throw new Exception("123456"); + } } $data = new Foo(); diff --git a/tests/experimental/fetchall_badunserialize.phpt b/tests/fetchall_badunserialize.phpt similarity index 76% rename from tests/experimental/fetchall_badunserialize.phpt rename to tests/fetchall_badunserialize.phpt index 5684763f..815c9e21 100644 --- a/tests/experimental/fetchall_badunserialize.phpt +++ b/tests/fetchall_badunserialize.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached::fetch() with bad unserialize --SKIPIF-- - + --FILE-- serialize_throws) { + throw new Exception("1234"); + } + return ["1234"]; + } + + public function __unserialize($str) { + throw new Exception("123456"); + } } $data = new Foo(); diff --git a/tests/experimental/get.phpt b/tests/get.phpt similarity index 78% rename from tests/experimental/get.phpt rename to tests/get.phpt index 308bda98..71889064 100644 --- a/tests/experimental/get.phpt +++ b/tests/get.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached::get() --SKIPIF-- - + --FILE-- delete('foo'); @@ -20,7 +20,7 @@ var_dump($m->get('foo')); echo $m->getResultMessage(), "\n"; $m->delete('foo'); -var_dump($m->get(' � foo jkh a s ���')); +var_dump($m->get(' ä foo jkh a s åäö')); echo $m->getResultMessage(), "\n"; --EXPECT-- bool(false) diff --git a/tests/experimental/get_bykey.phpt b/tests/get_bykey.phpt similarity index 75% rename from tests/experimental/get_bykey.phpt rename to tests/get_bykey.phpt index a392aaeb..704e8f04 100644 --- a/tests/experimental/get_bykey.phpt +++ b/tests/get_bykey.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached::getByKey() --SKIPIF-- - + --FILE-- set('foo', 1, 10); @@ -20,7 +20,7 @@ var_dump($m->getByKey('foo', 'bar')); echo $m->getResultMessage(), "\n"; $m->delete('foo'); -var_dump($m->getByKey(' � foo jkh a s ���', 'foo')); +var_dump($m->getByKey(' ä foo jkh a s åäö', 'foo')); echo $m->getResultMessage(), "\n"; --EXPECTF-- diff --git a/tests/get_bykey_cas.phpt b/tests/get_bykey_cas.phpt new file mode 100644 index 00000000..90b566c4 --- /dev/null +++ b/tests/get_bykey_cas.phpt @@ -0,0 +1,61 @@ +--TEST-- +Memcached::getByKey() with CAS +--SKIPIF-- + +--FILE-- +set('foo', 1, 10); + +$v = $m->getByKey('foo', 'foo', null, Memcached::GET_EXTENDED); +var_dump($v['value']); +var_dump($v['cas']); +echo $m->getResultMessage(), "\n"; + +$v = $m->getByKey('', 'foo', null, Memcached::GET_EXTENDED); +var_dump($v['value']); +var_dump($v['cas']); +echo $m->getResultMessage(), "\n"; + +$m->set('bar', "asdf", 10); + +$v = $m->getByKey('foo', 'bar', null, Memcached::GET_EXTENDED); +var_dump($v['value']); +var_dump($v['cas']); +echo $m->getResultMessage(), "\n"; + +$m->delete('foo'); +var_dump($m->getByKey(' ä foo jkh a s åäö', 'foo', null, Memcached::GET_EXTENDED)); +echo $m->getResultMessage(), "\n"; + +var_dump($m->getByKey(' ä foo jkh a s åäö', '', null, Memcached::GET_EXTENDED)); +echo $m->getResultMessage(), "\n"; + +$m->delete('foo'); +var_dump($m->getByKey('foo', 'foo', 'the_callback', Memcached::GET_EXTENDED)); +var_dump($m->getByKey('foo', 'foo')); +--EXPECTF-- +int(1) +int(%d) +SUCCESS +int(1) +int(%d) +SUCCESS +string(4) "asdf" +int(%d) +SUCCESS +bool(false) +NOT FOUND +bool(false) +A BAD KEY WAS PROVIDED/CHARACTERS OUT OF RANGE +called +bool(false) +bool(false) \ No newline at end of file diff --git a/tests/experimental/getdelayed_badserver.phpt b/tests/getdelayed_badserver.phpt similarity index 87% rename from tests/experimental/getdelayed_badserver.phpt rename to tests/getdelayed_badserver.phpt index c4902174..5d274efb 100644 --- a/tests/experimental/getdelayed_badserver.phpt +++ b/tests/getdelayed_badserver.phpt @@ -1,7 +1,7 @@ --TEST-- Memcached::getDelayedByKey() with bad server --SKIPIF-- - + --FILE-- + --FILE-- serialize_throws) { + throw new Exception("1234"); + } + return ["1234"]; + } + + public function __unserialize($str) { + throw new Exception("123456"); + } } function mycb($memc, $key, $value) { diff --git a/tests/experimental/getdelayed_bykey.phpt b/tests/getdelayed_bykey.phpt similarity index 89% rename from tests/experimental/getdelayed_bykey.phpt rename to tests/getdelayed_bykey.phpt index a29f646b..442320a2 100644 --- a/tests/experimental/getdelayed_bykey.phpt +++ b/tests/getdelayed_bykey.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached::getDelayedByKey() --SKIPIF-- - + --FILE-- + --FILE-- getDelayedByKey('kef', array_keys($data), true, 'myfunc'); ?> --EXPECTF-- -array(3) { +array(4) { ["key"]=> string(3) "foo" ["value"]=> string(8) "foo-data" ["cas"]=> - float(%d) + int(%d) + ["flags"]=> + int(0) } -array(3) { +array(4) { ["key"]=> string(3) "bar" ["value"]=> string(8) "bar-data" ["cas"]=> - float(%d) + int(%d) + ["flags"]=> + int(0) } -array(3) { +array(4) { ["key"]=> string(3) "baz" ["value"]=> string(8) "baz-data" ["cas"]=> - float(%d) + int(%d) + ["flags"]=> + int(0) } -array(3) { +array(4) { ["key"]=> string(3) "lol" ["value"]=> string(8) "lol-data" ["cas"]=> - float(%d) + int(%d) + ["flags"]=> + int(0) } -array(3) { +array(4) { ["key"]=> string(3) "kek" ["value"]=> string(8) "kek-data" ["cas"]=> - float(%d) + int(%d) + ["flags"]=> + int(0) } diff --git a/tests/experimental/getdelayed_nonstring_keys.phpt b/tests/getdelayed_nonstring_keys.phpt similarity index 90% rename from tests/experimental/getdelayed_nonstring_keys.phpt rename to tests/getdelayed_nonstring_keys.phpt index 81363f3b..005d0579 100644 --- a/tests/experimental/getdelayed_nonstring_keys.phpt +++ b/tests/getdelayed_nonstring_keys.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached getDelayed non string keys --SKIPIF-- - + --FILE-- + --FILE-- getResultCode()) { } --EXPECTF-- -array(0) { -} +bool(false) NO SERVERS DEFINED -array(0) { -} +bool(false) %d: %s diff --git a/tests/experimental/getmulti_badunserialize.phpt b/tests/getmulti_badunserialize.phpt similarity index 77% rename from tests/experimental/getmulti_badunserialize.phpt rename to tests/getmulti_badunserialize.phpt index 963e9730..280feed3 100644 --- a/tests/experimental/getmulti_badunserialize.phpt +++ b/tests/getmulti_badunserialize.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached::getMulti() with bad unserialize --SKIPIF-- - + --FILE-- set('bar', "12", 10)); diff --git a/tests/experimental/getmulti_bykey.phpt b/tests/getmulti_bykey.phpt similarity index 82% rename from tests/experimental/getmulti_bykey.phpt rename to tests/getmulti_bykey.phpt index 3f7a6f78..b615dc66 100644 --- a/tests/experimental/getmulti_bykey.phpt +++ b/tests/getmulti_bykey.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached::getMultiByKey() --SKIPIF-- - + --FILE-- set('foo', 1, 10); diff --git a/tests/experimental/getmulti_empty.phpt b/tests/getmulti_empty.phpt similarity index 60% rename from tests/experimental/getmulti_empty.phpt rename to tests/getmulti_empty.phpt index 6279104d..3550e814 100644 --- a/tests/experimental/getmulti_empty.phpt +++ b/tests/getmulti_empty.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached::getMulti() with empty array --SKIPIF-- - + --FILE-- getMulti(array()); diff --git a/tests/experimental/getmulti_partial_error.phpt b/tests/getmulti_partial_error.phpt similarity index 84% rename from tests/experimental/getmulti_partial_error.phpt rename to tests/getmulti_partial_error.phpt index fa392e9e..928f49f4 100644 --- a/tests/experimental/getmulti_partial_error.phpt +++ b/tests/getmulti_partial_error.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached::getMulti() partial error --SKIPIF-- - + --FILE-- + --FILE-- getVersion()); -include dirname(dirname(__FILE__)) . "/config.inc"; +include dirname(__FILE__) . "/config.inc"; $m = memc_get_instance (); $stats = $m->getVersion(); diff --git a/tests/experimental/locale_float.phpt b/tests/locale_float.phpt similarity index 80% rename from tests/experimental/locale_float.phpt rename to tests/locale_float.phpt index c071d974..2f25ea73 100644 --- a/tests/experimental/locale_float.phpt +++ b/tests/locale_float.phpt @@ -2,14 +2,14 @@ Float should not consider locale --SKIPIF-- --FILE-- diff --git a/tests/experimental/prepend_bykey.phpt b/tests/prepend_bykey.phpt similarity index 78% rename from tests/experimental/prepend_bykey.phpt rename to tests/prepend_bykey.phpt index 87d3fd38..482899de 100644 --- a/tests/experimental/prepend_bykey.phpt +++ b/tests/prepend_bykey.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached::appendByKey() --SKIPIF-- - + --FILE-- setOption(Memcached::OPT_COMPRESSION, false); diff --git a/tests/experimental/replace_bykey.phpt b/tests/replace_bykey.phpt similarity index 82% rename from tests/experimental/replace_bykey.phpt rename to tests/replace_bykey.phpt index cddf10f0..b844824c 100644 --- a/tests/experimental/replace_bykey.phpt +++ b/tests/replace_bykey.phpt @@ -1,10 +1,10 @@ --TEST-- Memcached::replaceByKey() --SKIPIF-- - + --FILE-- + --FILE-- setByKey('foo', 'foo', 1, 10)); @@ -14,7 +14,7 @@ echo $m->getResultMessage(), "\n"; var_dump($m->setByKey('foo', '', 1, 10)); echo $m->getResultMessage(), "\n"; // This is OK for the binary protocol -$rv = $m->setByKey('foo', ' asd ���', 1, 1); +$rv = $m->setByKey('foo', ' asd åäö', 1, 1); if ($m->getOption(Memcached::OPT_BINARY_PROTOCOL)) { if ($rv !== true and $m->getResultCode() !== Memcached::RES_SUCCESS) { var_dump($rv); diff --git a/tests/experimental/set_comp_below_factor.phpt b/tests/set_comp_below_factor.phpt similarity index 74% rename from tests/experimental/set_comp_below_factor.phpt rename to tests/set_comp_below_factor.phpt index 12e6d6a4..80d28006 100644 --- a/tests/experimental/set_comp_below_factor.phpt +++ b/tests/set_comp_below_factor.phpt @@ -1,10 +1,10 @@ --TEST-- Compress below factor and fail to plain. --SKIPIF-- - + --FILE-- + --FILE-- + --FILE-- + --FILE-- + --FILE-- Date: Thu, 27 Apr 2023 10:48:49 -0500 Subject: [PATCH 191/218] Add option to locally enforce payload size limit (#515) Add a configuration option to enforce an item size limit on the client side. This avoids sending large items over the wire and getting rejected by the server which can cause delays. The default is 0 for no limit. The same error code RES_E2BIG is used for the client side limit as for the server side limit. --- memcached.ini | 6 +++++ php_memcached.c | 45 ++++++++++++++++++++++++++++++++++++++ php_memcached_private.h | 5 +++-- tests/cas_e2big.phpt | 32 +++++++++++++++++++++++++++ tests/options.phpt | 32 +++++++++++++++++++++++++++ tests/set_large.phpt | 4 +++- tests/set_large_e2big.phpt | 27 +++++++++++++++++++++++ tests/setoptions.phpt | 3 +++ 8 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 tests/cas_e2big.phpt create mode 100644 tests/set_large_e2big.phpt diff --git a/memcached.ini b/memcached.ini index c54e1fd4..5decf399 100644 --- a/memcached.ini +++ b/memcached.ini @@ -133,6 +133,12 @@ ; the default is 0 ;memcached.store_retry_count = 0 +; The maximum payload size in bytes that can be written. +; Writing a payload larger than the limit will result in RES_E2BIG error. +; Specifying 0 means no limit is enforced, though the server may still reject with RES_E2BIG. +; Default is 0. +;memcached.item_size_limit = 1000000 + ; Sets the default for consistent hashing for new connections. ; (To configure consistent hashing for session connections, ; use memcached.sess_consistent_hash instead) diff --git a/php_memcached.c b/php_memcached.c index e7d5736c..9c5ba8aa 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -82,6 +82,7 @@ static int php_memc_list_entry(void) { #define MEMC_OPT_STORE_RETRY_COUNT -1005 #define MEMC_OPT_USER_FLAGS -1006 #define MEMC_OPT_COMPRESSION_LEVEL -1007 +#define MEMC_OPT_ITEM_SIZE_LIMIT -1008 /**************************************** Custom result codes @@ -162,6 +163,7 @@ typedef struct { zend_long store_retry_count; zend_long set_udf_flags; + zend_long item_size_limit; #ifdef HAVE_MEMCACHED_SASL zend_bool has_sasl_data; @@ -423,6 +425,7 @@ PHP_INI_BEGIN() MEMC_INI_ENTRY("compression_threshold", "2000", OnUpdateLong, compression_threshold) MEMC_INI_ENTRY("serializer", SERIALIZER_DEFAULT_NAME, OnUpdateSerializer, serializer_name) MEMC_INI_ENTRY("store_retry_count", "0", OnUpdateLong, store_retry_count) + MEMC_INI_ENTRY("item_size_limit", "0", OnUpdateLongGEZero, item_size_limit) MEMC_INI_BOOL ("default_consistent_hash", "0", OnUpdateBool, default_behavior.consistent_hash_enabled) MEMC_INI_BOOL ("default_binary_protocol", "0", OnUpdateBool, default_behavior.binary_protocol_enabled) @@ -1127,6 +1130,21 @@ zend_string *s_zval_to_payload(php_memc_object_t *intern, zval *value, uint32_t return payload; } +static +zend_bool s_is_payload_too_big(php_memc_object_t *intern, zend_string *payload) +{ + php_memc_user_data_t *memc_user_data = memcached_get_user_data(intern->memc); + + /* An item size limit of 0 implies no limit enforced */ + if (memc_user_data->item_size_limit == 0) { + return 0; + } + if (ZSTR_LEN(payload) > memc_user_data->item_size_limit) { + return 1; + } + return 0; +} + static zend_bool s_should_retry_write (php_memc_object_t *intern, memcached_return status) { @@ -1153,6 +1171,12 @@ zend_bool s_memc_write_zval (php_memc_object_t *intern, php_memc_write_op op, ze s_memc_set_status(intern, MEMC_RES_PAYLOAD_FAILURE, 0); return 0; } + + if (s_is_payload_too_big(intern, payload)) { + s_memc_set_status(intern, MEMCACHED_E2BIG, 0); + zend_string_release(payload); + return 0; + } } #define memc_write_using_fn(fn_name) payload ? fn_name(intern->memc, ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(payload), ZSTR_LEN(payload), expiration, flags) : MEMC_RES_PAYLOAD_FAILURE; @@ -1305,6 +1329,7 @@ static PHP_METHOD(Memcached, __construct) memc_user_data->encoding_enabled = 0; memc_user_data->store_retry_count = MEMC_G(store_retry_count); memc_user_data->set_udf_flags = -1; + memc_user_data->item_size_limit = MEMC_G(item_size_limit); memc_user_data->is_persistent = is_persistent; memcached_set_user_data(intern->memc, memc_user_data); @@ -2145,6 +2170,12 @@ static void php_memc_cas_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool by_key) RETURN_FALSE; } + if (s_is_payload_too_big(intern, payload)) { + intern->rescode = MEMCACHED_E2BIG; + zend_string_release(payload); + RETURN_FALSE; + } + if (by_key) { status = memcached_cas_by_key(intern->memc, ZSTR_VAL(server_key), ZSTR_LEN(server_key), ZSTR_VAL(key), ZSTR_LEN(key), ZSTR_VAL(payload), ZSTR_LEN(payload), expiration, flags, cas); } else { @@ -2970,6 +3001,9 @@ static PHP_METHOD(Memcached, getOption) case MEMC_OPT_COMPRESSION: RETURN_BOOL(memc_user_data->compression_enabled); + case MEMC_OPT_ITEM_SIZE_LIMIT: + RETURN_LONG(memc_user_data->item_size_limit); + case MEMC_OPT_PREFIX_KEY: { memcached_return retval; @@ -3041,6 +3075,15 @@ int php_memc_set_option(php_memc_object_t *intern, long option, zval *value) } break; + case MEMC_OPT_ITEM_SIZE_LIMIT: + lval = zval_get_long(value); + if (lval < 0) { + php_error_docref(NULL, E_WARNING, "ITEM_SIZE_LIMIT must be >= 0"); + return 0; + } + memc_user_data->item_size_limit = lval; + break; + case MEMC_OPT_PREFIX_KEY: { zend_string *str; @@ -4013,6 +4056,7 @@ PHP_GINIT_FUNCTION(php_memcached) php_memcached_globals->memc.compression_factor = 1.30; php_memcached_globals->memc.compression_level = 3; php_memcached_globals->memc.store_retry_count = 2; + php_memcached_globals->memc.item_size_limit = 0; php_memcached_globals->memc.sasl_initialised = 0; php_memcached_globals->no_effect = 0; @@ -4063,6 +4107,7 @@ static void php_memc_register_constants(INIT_FUNC_ARGS) REGISTER_MEMC_CLASS_CONST_LONG(OPT_USER_FLAGS, MEMC_OPT_USER_FLAGS); REGISTER_MEMC_CLASS_CONST_LONG(OPT_STORE_RETRY_COUNT, MEMC_OPT_STORE_RETRY_COUNT); + REGISTER_MEMC_CLASS_CONST_LONG(OPT_ITEM_SIZE_LIMIT, MEMC_OPT_ITEM_SIZE_LIMIT); /* * Indicate whether igbinary serializer is available diff --git a/php_memcached_private.h b/php_memcached_private.h index aefaf4fb..93c20570 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -186,8 +186,9 @@ ZEND_BEGIN_MODULE_GLOBALS(php_memcached) char *compression_name; zend_long compression_threshold; double compression_factor; - zend_long store_retry_count; - zend_long compression_level; + zend_long store_retry_count; + zend_long compression_level; + zend_long item_size_limit; /* Converted values*/ php_memc_serializer_type serializer_type; diff --git a/tests/cas_e2big.phpt b/tests/cas_e2big.phpt new file mode 100644 index 00000000..99c3562b --- /dev/null +++ b/tests/cas_e2big.phpt @@ -0,0 +1,32 @@ +--TEST-- +set data exceeding size limit +--SKIPIF-- + +--FILE-- + 100, +)); + +$m->delete('cas_e2big_test'); + +$m->set('cas_e2big_test', 'hello'); +$result = $m->get('cas_e2big_test', null, Memcached::GET_EXTENDED); +var_dump(is_array($result) && isset($result['cas']) && isset($result['value']) && $result['value'] == 'hello'); + +$value = str_repeat('a large payload', 1024 * 1024); + +var_dump($m->cas($result['cas'], 'cas_e2big_test', $value, 360)); +var_dump($m->getResultCode() == Memcached::RES_E2BIG); +var_dump($m->getResultMessage() == 'ITEM TOO BIG'); +var_dump($m->get('cas_e2big_test') == 'hello'); +var_dump($m->getResultCode() == Memcached::RES_SUCCESS); +?> +--EXPECT-- +bool(true) +bool(false) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/tests/options.phpt b/tests/options.phpt index ce895385..a096c8f1 100644 --- a/tests/options.phpt +++ b/tests/options.phpt @@ -26,6 +26,26 @@ var_dump($m->getOption(Memcached::OPT_COMPRESSION_TYPE) == Memcached::COMPRESSIO var_dump($m->setOption(Memcached::OPT_COMPRESSION_TYPE, 0)); var_dump($m->getOption(Memcached::OPT_COMPRESSION_TYPE) == Memcached::COMPRESSION_FASTLZ); + +echo "item_size_limit setOption\n"; +var_dump($m->setOption(Memcached::OPT_ITEM_SIZE_LIMIT, 0)); +var_dump($m->getOption(Memcached::OPT_ITEM_SIZE_LIMIT) === 0); +var_dump($m->setOption(Memcached::OPT_ITEM_SIZE_LIMIT, -1)); +var_dump($m->setOption(Memcached::OPT_ITEM_SIZE_LIMIT, 1000000)); +var_dump($m->getOption(Memcached::OPT_ITEM_SIZE_LIMIT) == 1000000); + +echo "item_size_limit ini\n"; +ini_set('memcached.item_size_limit', '0'); +$m = new Memcached(); +var_dump($m->getOption(Memcached::OPT_ITEM_SIZE_LIMIT) === 0); + +ini_set('memcached.item_size_limit', '1000000'); +$m = new Memcached(); +var_dump($m->getOption(Memcached::OPT_ITEM_SIZE_LIMIT) == 1000000); + +ini_set('memcached.item_size_limit', null); +$m = new Memcached(); +var_dump($m->getOption(Memcached::OPT_ITEM_SIZE_LIMIT) === 0); ?> --EXPECTF-- bool(true) @@ -41,3 +61,15 @@ bool(true) bool(true) bool(false) bool(true) +item_size_limit setOption +bool(true) +bool(true) + +Warning: Memcached::setOption(): ITEM_SIZE_LIMIT must be >= 0 in %s on line %d +bool(false) +bool(true) +bool(true) +item_size_limit ini +bool(true) +bool(true) +bool(true) diff --git a/tests/set_large.phpt b/tests/set_large.phpt index f3cb4cc3..ba9fbca1 100644 --- a/tests/set_large.phpt +++ b/tests/set_large.phpt @@ -5,7 +5,9 @@ set large data --FILE-- 0, +)); $key = 'foobarbazDEADC0DE'; $value = str_repeat("foo bar", 1024 * 1024); diff --git a/tests/set_large_e2big.phpt b/tests/set_large_e2big.phpt new file mode 100644 index 00000000..498231e4 --- /dev/null +++ b/tests/set_large_e2big.phpt @@ -0,0 +1,27 @@ +--TEST-- +set data exceeding size limit +--SKIPIF-- + +--FILE-- + 100, +)); + +$m->delete('set_large_e2big_test'); + +$value = str_repeat('a large payload', 1024 * 1024); + +var_dump($m->set('set_large_e2big_test', $value)); +var_dump($m->getResultCode() == Memcached::RES_E2BIG); +var_dump($m->getResultMessage() == 'ITEM TOO BIG'); +var_dump($m->get('set_large_e2big_test') === false); +var_dump($m->getResultCode() == Memcached::RES_NOTFOUND); +?> +--EXPECT-- +bool(false) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/tests/setoptions.phpt b/tests/setoptions.phpt index 4bf39d14..9cefd138 100644 --- a/tests/setoptions.phpt +++ b/tests/setoptions.phpt @@ -13,12 +13,14 @@ var_dump($m->setOptions(array( Memcached::OPT_COMPRESSION => 0, Memcached::OPT_LIBKETAMA_COMPATIBLE => 1, Memcached::OPT_CONNECT_TIMEOUT => 5000, + Memcached::OPT_ITEM_SIZE_LIMIT => 1000000, ))); var_dump($m->getOption(Memcached::OPT_PREFIX_KEY) == 'a_prefix'); var_dump($m->getOption(Memcached::OPT_SERIALIZER) == Memcached::SERIALIZER_PHP); var_dump($m->getOption(Memcached::OPT_COMPRESSION) == 0); var_dump($m->getOption(Memcached::OPT_LIBKETAMA_COMPATIBLE) == 1); +var_dump($m->getOption(Memcached::OPT_ITEM_SIZE_LIMIT) == 1000000); echo "test invalid options\n"; @@ -36,6 +38,7 @@ bool(true) bool(true) bool(true) bool(true) +bool(true) test invalid options Warning: Memcached::setOptions(): invalid configuration option in %s on line %d From 7fefcb792423906bba2bac66a49194f98bf11aa6 Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Wed, 3 May 2023 19:10:38 -0400 Subject: [PATCH 192/218] Make the compression_level at settable option and expand it to zlib (#540) Make it possible to use setOption to set Memcached::OPT_COMPRESSION_LEVEL which was missed in the original zstd PR #539 zlib compression was using the default zlib compression level of 6. With this PR it is now possible to choose other levels for zlib as well. The default remains at 6 so nothing will change for people upgrading unless they explicitly set a different level. Here is some more benchmarking data using php serialized data https://gist.github.com/rlerdorf/b9bae385446d5a30b65e6e241e34d0a8 fastlz is not really useful at any value size anymore. Anybody looking for lightning quick compression and decompression should use zstd at level 1. compression_level is not applied to fastlz because it only has 2 levels and php-memcached already switches from level 1 to 2 automatically for values larger than 65535 bytes. Forcing it to one or the other doesn't seem useful. --- php_memcached.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 9c5ba8aa..00d5e3d4 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -884,7 +884,7 @@ zend_bool s_invoke_cache_callback(zval *zobject, zend_fcall_info *fci, zend_fcal ****************************************/ static -zend_bool s_compress_value (php_memc_compression_type compression_type, zend_string **payload_in, uint32_t *flags) +zend_bool s_compress_value (php_memc_compression_type compression_type, zend_long compression_level, zend_string **payload_in, uint32_t *flags) { /* status */ zend_bool compress_status = 0; @@ -915,7 +915,13 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str #ifdef HAVE_ZSTD_H case COMPRESSION_TYPE_ZSTD: { - compressed_size = ZSTD_compress((void *)buffer, buffer_size, ZSTR_VAL(payload), ZSTR_LEN(payload), MEMC_G(compression_level)); + compressed_size = ZSTD_compress((void *)buffer, buffer_size, ZSTR_VAL(payload), ZSTR_LEN(payload), compression_level); + + if (compression_level < -22) { + compression_level = -22; + } else if (compression_level > 22) { + compression_level = 22; + } if (!ZSTD_isError(compressed_size)) { compress_status = 1; @@ -928,7 +934,14 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_str case COMPRESSION_TYPE_ZLIB: { compressed_size = buffer_size; - int status = compress((Bytef *) buffer, &compressed_size, (Bytef *) ZSTR_VAL(payload), ZSTR_LEN(payload)); + + if (compression_level < 0) { + compression_level = 0; + } else if (compression_level > 9) { + compression_level = 9; + } + + int status = compress2((Bytef *) buffer, &compressed_size, (Bytef *) ZSTR_VAL(payload), ZSTR_LEN(payload), compression_level); if (status == Z_OK) { compress_status = 1; @@ -1120,7 +1133,7 @@ zend_string *s_zval_to_payload(php_memc_object_t *intern, zval *value, uint32_t * * No need to check the return value because the payload is always valid. */ - (void)s_compress_value (memc_user_data->compression_type, &payload, flags); + (void)s_compress_value (memc_user_data->compression_type, memc_user_data->compression_level, &payload, flags); } if (memc_user_data->set_udf_flags >= 0) { @@ -1325,6 +1338,7 @@ static PHP_METHOD(Memcached, __construct) memc_user_data = pecalloc (1, sizeof(*memc_user_data), is_persistent); memc_user_data->serializer = MEMC_G(serializer_type); memc_user_data->compression_type = MEMC_G(compression_type); + memc_user_data->compression_level = MEMC_G(compression_level); memc_user_data->compression_enabled = 1; memc_user_data->encoding_enabled = 0; memc_user_data->store_retry_count = MEMC_G(store_retry_count); @@ -3075,6 +3089,11 @@ int php_memc_set_option(php_memc_object_t *intern, long option, zval *value) } break; + case MEMC_OPT_COMPRESSION_LEVEL: + lval = zval_get_long(value); + memc_user_data->compression_level = lval; + break; + case MEMC_OPT_ITEM_SIZE_LIMIT: lval = zval_get_long(value); if (lval < 0) { @@ -4054,7 +4073,7 @@ PHP_GINIT_FUNCTION(php_memcached) php_memcached_globals->memc.compression_threshold = 2000; php_memcached_globals->memc.compression_type = COMPRESSION_TYPE_FASTLZ; php_memcached_globals->memc.compression_factor = 1.30; - php_memcached_globals->memc.compression_level = 3; + php_memcached_globals->memc.compression_level = 6; php_memcached_globals->memc.store_retry_count = 2; php_memcached_globals->memc.item_size_limit = 0; From d2b1172dffbee713857a960bd10b550f7921a1eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 07:57:32 -0700 Subject: [PATCH 193/218] Bump actions/checkout from 2 to 3 (#534) Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 36cf7cba..de13c538 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -13,7 +13,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout memcached - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP id: setup-php uses: cmb69/setup-php-sdk@v0.7 From eb39e469d02576033e75848ca757a32e3502a3a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 24 Oct 2023 10:33:10 -0700 Subject: [PATCH 194/218] Bump actions/checkout from 3 to 4 (#548) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-and-test.yml | 2 +- .github/workflows/build-windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 7384dd88..2dcb6673 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -17,7 +17,7 @@ jobs: experimental: true steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: submodules: true - name: Install PHP ${{ matrix.php }} diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index de13c538..a7aa8577 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -13,7 +13,7 @@ jobs: runs-on: windows-latest steps: - name: Checkout memcached - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup PHP id: setup-php uses: cmb69/setup-php-sdk@v0.7 From dfd038f13c4347fc15835cd9077a960218e01d98 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 27 Dec 2023 19:55:59 -0500 Subject: [PATCH 195/218] Correct whitespace formatting (#553) --- php_memcached_private.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php_memcached_private.h b/php_memcached_private.h index 93c20570..2c22ecba 100644 --- a/php_memcached_private.h +++ b/php_memcached_private.h @@ -186,8 +186,8 @@ ZEND_BEGIN_MODULE_GLOBALS(php_memcached) char *compression_name; zend_long compression_threshold; double compression_factor; - zend_long store_retry_count; - zend_long compression_level; + zend_long store_retry_count; + zend_long compression_level; zend_long item_size_limit; /* Converted values*/ From 7f31d8651b9ec98b2eb46705d1d17983b9999c13 Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Thu, 7 Mar 2024 10:36:43 -0500 Subject: [PATCH 196/218] The key length check was not taking the prefix into account --- php_memcached.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/php_memcached.c b/php_memcached.c index 00d5e3d4..1e686f17 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -230,6 +230,19 @@ zend_bool s_memc_valid_key_binary(zend_string *key) return memchr(ZSTR_VAL(key), '\n', ZSTR_LEN(key)) == NULL; } +static +uint32_t s_memc_object_key_max_length(php_memc_object_t *intern) { + memcached_return retval; + char *result; + + result = memcached_callback_get(intern->memc, MEMCACHED_CALLBACK_PREFIX_KEY, &retval); + if (retval == MEMCACHED_SUCCESS && result) { + return MEMC_OBJECT_KEY_MAX_LENGTH - strlen(result); + } else { + return MEMC_OBJECT_KEY_MAX_LENGTH; + } +} + static zend_bool s_memc_valid_key_ascii(zend_string *key) { @@ -245,7 +258,7 @@ zend_bool s_memc_valid_key_ascii(zend_string *key) #define MEMC_CHECK_KEY(intern, key) \ if (UNEXPECTED(ZSTR_LEN(key) == 0 || \ - ZSTR_LEN(key) > MEMC_OBJECT_KEY_MAX_LENGTH || \ + ZSTR_LEN(key) > s_memc_object_key_max_length(intern) || \ (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) \ ? !s_memc_valid_key_binary(key) \ : !s_memc_valid_key_ascii(key) \ From abd372b454986afbea0a53ee1eb8393ff1145216 Mon Sep 17 00:00:00 2001 From: William Van Hevelingen Date: Wed, 15 May 2024 18:31:36 -0700 Subject: [PATCH 197/218] CI: Add PHP 8.3 to the required matrix, add PHP 8.4 to experimental (#557) --- .github/workflows/build-and-test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 2dcb6673..14733ec1 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -7,13 +7,13 @@ jobs: strategy: fail-fast: false matrix: - php: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2'] + php: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] experimental: [false] include: - php: '8.2' awesome: true experimental: true - - php: '8.3' + - php: '8.4' experimental: true steps: - name: Checkout @@ -35,7 +35,7 @@ jobs: - if: ${{ matrix.awesome }} name: Install libmemcached-awesome (from source) run: | - curl -sL -o libmemcached.tgz https://github.com/awesomized/libmemcached/archive/refs/tags/1.1.3.tar.gz + curl -sL -o libmemcached.tgz https://github.com/awesomized/libmemcached/archive/refs/tags/1.1.4.tar.gz mkdir libmemcached tar --strip-components=1 -xf libmemcached.tgz -C libmemcached mkdir build-libmemcached @@ -83,7 +83,7 @@ jobs: define ("MEMC_SASL_SERVER_HOST", "127.0.0.1"); define ("MEMC_SASL_SERVER_PORT", 11212); - + define ('MEMC_SASL_USER', 'memcached'); define ('MEMC_SASL_PASS', 'test'); EOF From d8d99f07846d201836fe2308263dd0fac087c7be Mon Sep 17 00:00:00 2001 From: William Van Hevelingen Date: Wed, 15 May 2024 22:39:48 -0700 Subject: [PATCH 198/218] docs: fix build status on README.md (#558) --- README.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index b17b7e55..38dbd5bc 100644 --- a/README.markdown +++ b/README.markdown @@ -1,6 +1,6 @@ Build Status ------------ -[![Build Status](https://travis-ci.org/php-memcached-dev/php-memcached.png)](https://travis-ci.org/php-memcached-dev/php-memcached) +![Build Status](https://github.com/php-memcached-dev/php-memcached/actions/workflows/build-and-test.yml/badge.svg?branch=master) Description ----------- @@ -23,7 +23,7 @@ Dependencies ------------ php-memcached 3.x: -* Supports PHP 7.0 - 8.2 or higher. +* Supports PHP 7.0 - 8.3 or higher. * Requires libmemcached 1.x or higher. * Optionally supports igbinary 2.0 or higher. * Optionally supports msgpack 2.0 or higher. From 93c1bc449ff32e2a26b5f922fdd6dfa43edaeeb9 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 25 Sep 2024 23:54:00 +0200 Subject: [PATCH 199/218] ci: attempt to fix windows build --- .github/workflows/build-windows.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index a7aa8577..fefd7deb 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -7,7 +7,7 @@ jobs: shell: cmd strategy: matrix: - version: ['7.4', '8.0', '8.1'] + version: ['8.3'] arch: [x64, x86] ts: [nts, zts] runs-on: windows-latest @@ -16,7 +16,7 @@ jobs: uses: actions/checkout@v4 - name: Setup PHP id: setup-php - uses: cmb69/setup-php-sdk@v0.7 + uses: php/setup-php-sdk@v0.9 with: version: ${{matrix.version}} arch: ${{matrix.arch}} From 8a6b0c78014dfb0d133595f06fc4c5bb29ba9a83 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Wed, 25 Sep 2024 23:54:27 +0200 Subject: [PATCH 200/218] ci: ubuntu already ships with awesomized/libmemcached --- .github/workflows/build-and-test.yml | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 14733ec1..a142e10b 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -10,9 +10,6 @@ jobs: php: ['7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] experimental: [false] include: - - php: '8.2' - awesome: true - experimental: true - php: '8.4' experimental: true steps: @@ -29,20 +26,8 @@ jobs: run: | sudo apt-get update sudo apt-get install cmake memcached libsasl2-dev sasl2-bin zlib1g-dev - - if: ${{ ! matrix.awesome }} - name: Install libmemcached-dev (from distro) + - name: Install libmemcached-dev run: sudo apt-get install libmemcached-dev - - if: ${{ matrix.awesome }} - name: Install libmemcached-awesome (from source) - run: | - curl -sL -o libmemcached.tgz https://github.com/awesomized/libmemcached/archive/refs/tags/1.1.4.tar.gz - mkdir libmemcached - tar --strip-components=1 -xf libmemcached.tgz -C libmemcached - mkdir build-libmemcached - cd build-libmemcached - cmake -D ENABLE_HASH_HSIEH=ON -D ENABLE_SASL=ON ../libmemcached - make - sudo make install - name: Start memcached daemons run: | export SASL_CONF_PATH="/tmp/sasl2" From 899f0d52425b3efe2f67ed73eca115a0b5dc6c34 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Tue, 30 Jan 2024 09:44:48 +0100 Subject: [PATCH 201/218] Fix incompatible pointer types --- php_memcached.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 00d5e3d4..c3ef16e8 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -933,7 +933,7 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_lon case COMPRESSION_TYPE_ZLIB: { - compressed_size = buffer_size; + unsigned long cs = compressed_size = buffer_size; if (compression_level < 0) { compression_level = 0; @@ -941,9 +941,10 @@ zend_bool s_compress_value (php_memc_compression_type compression_type, zend_lon compression_level = 9; } - int status = compress2((Bytef *) buffer, &compressed_size, (Bytef *) ZSTR_VAL(payload), ZSTR_LEN(payload), compression_level); + int status = compress2((Bytef *) buffer, &cs, (Bytef *) ZSTR_VAL(payload), ZSTR_LEN(payload), compression_level); if (status == Z_OK) { + compressed_size = cs; compress_status = 1; compression_type_flag = MEMC_VAL_COMPRESSION_ZLIB; } @@ -3751,7 +3752,10 @@ zend_string *s_decompress_value (const char *payload, size_t payload_len, uint32 decompress_status = ((length = fastlz_decompress(payload, payload_len, &buffer->val, buffer->len)) > 0); } else if (is_zlib) { - decompress_status = (uncompress((Bytef *) buffer->val, &buffer->len, (Bytef *)payload, payload_len) == Z_OK); + unsigned long ds = buffer->len; + + decompress_status = (uncompress((Bytef *) buffer->val, &ds, (Bytef *)payload, payload_len) == Z_OK); + buffer->len = ds; } ZSTR_VAL(buffer)[stored_length] = '\0'; From 7227982467bb16786817b6c1aec85f99ce1e3a2e Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Thu, 19 Sep 2024 07:52:19 +0100 Subject: [PATCH 202/218] Added a composer.json to enable support for PIE --- composer.json | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 composer.json diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..3356c89d --- /dev/null +++ b/composer.json @@ -0,0 +1,68 @@ +{ + "name": "php-memcached/php-memcached", + "type": "php-ext", + "license": "PHP-3.01", + "description": "memcached extension based on libmemcached library ", + "require": { + "php": ">= 7.0.0" + }, + "suggest": { + "ext-igbinary": "igbinary is a faster and more compact binary serializer for PHP data structures.", + "ext-msgpack": "msgpack is a faster and more compact data structure representation that is interoperable with msgpack implementations for other languages." + }, + "php-ext": { + "extension-name": "memcached", + "configure-options": [ + { + "name": "enable-memcached", + "description": "Enable memcached support" + }, + { + "name": "with-libmemcached-dir", + "description": "Set the path to libmemcached install prefix.", + "needs-value": true + }, + { + "name": "enable-memcached-session", + "description": "Enable memcached session handler support" + }, + { + "name": "enable-memcached-igbinary", + "description": "Enable memcached igbinary serializer support" + }, + { + "name": "enable-memcached-json", + "description": "Enable memcached json serializer support" + }, + { + "name": "enable-memcached-msgpack", + "description": "Enable memcached msgpack serializer support" + }, + { + "name": "enable-memcached-sasl", + "description": "Enable memcached sasl support" + }, + { + "name": "enable-memcached-protocol", + "description": "Enable memcached protocol support" + }, + { + "name": "with-system-fastlz", + "description": "Use system FastLZ library" + }, + { + "name": "with-zstd", + "description": "Use system zstd library" + }, + { + "name": "with-zlib-dir", + "description": "Set the path to ZLIB install prefix.", + "needs-value": true + }, + { + "name": "enable-debug", + "description": "Compile with debugging symbols" + } + ] + } +} From 0987380a558c4dadb9e0fa909132c5adea1f44ad Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Thu, 19 Oct 2023 18:07:48 -0700 Subject: [PATCH 203/218] If client-side verify_key is not enabled, don't check it automatically --- php_memcached.c | 1 + 1 file changed, 1 insertion(+) diff --git a/php_memcached.c b/php_memcached.c index c3ef16e8..71725bb9 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -246,6 +246,7 @@ zend_bool s_memc_valid_key_ascii(zend_string *key) #define MEMC_CHECK_KEY(intern, key) \ if (UNEXPECTED(ZSTR_LEN(key) == 0 || \ ZSTR_LEN(key) > MEMC_OBJECT_KEY_MAX_LENGTH || \ + memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_VERIFY_KEY) && \ (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) \ ? !s_memc_valid_key_binary(key) \ : !s_memc_valid_key_ascii(key) \ From 198e9b3681bb0a401385271e5a25b0d863b89d8f Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Thu, 19 Oct 2023 19:06:12 -0700 Subject: [PATCH 204/218] fix tests --- tests/cas_invalid_key.phpt | 5 ++++- tests/delete_bykey.phpt | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/cas_invalid_key.phpt b/tests/cas_invalid_key.phpt index b8a815dc..9cb7293c 100644 --- a/tests/cas_invalid_key.phpt +++ b/tests/cas_invalid_key.phpt @@ -5,7 +5,10 @@ Memcached::cas() with strange key --FILE-- false, + Memcached::OPT_VERIFY_KEY => true +)); error_reporting(0); var_dump($m->cas(0, '', true, 10)); diff --git a/tests/delete_bykey.phpt b/tests/delete_bykey.phpt index 929ffbc1..6aa589c5 100644 --- a/tests/delete_bykey.phpt +++ b/tests/delete_bykey.phpt @@ -5,7 +5,10 @@ Memcached::deleteByKey() --FILE-- false, + Memcached::OPT_VERIFY_KEY => true +)); $m->setByKey('keffe', 'eisaleeoo', "foo"); var_dump($m->getByKey('keffe', 'eisaleeoo')); From da71ae036237130b9e879f02326690e8ca73358a Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Thu, 19 Oct 2023 21:42:43 -0700 Subject: [PATCH 205/218] Fix more tests with a slight refactor --- php_memcached.c | 3 +-- tests/get.phpt | 5 ++++- tests/keys_ascii.phpt | 5 +---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 71725bb9..55c20089 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -246,10 +246,9 @@ zend_bool s_memc_valid_key_ascii(zend_string *key) #define MEMC_CHECK_KEY(intern, key) \ if (UNEXPECTED(ZSTR_LEN(key) == 0 || \ ZSTR_LEN(key) > MEMC_OBJECT_KEY_MAX_LENGTH || \ - memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_VERIFY_KEY) && \ (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) \ ? !s_memc_valid_key_binary(key) \ - : !s_memc_valid_key_ascii(key) \ + : (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_VERIFY_KEY) && !s_memc_valid_key_ascii(key)) \ ))) { \ intern->rescode = MEMCACHED_BAD_KEY_PROVIDED; \ RETURN_FALSE; \ diff --git a/tests/get.phpt b/tests/get.phpt index 71889064..722308f0 100644 --- a/tests/get.phpt +++ b/tests/get.phpt @@ -5,7 +5,10 @@ Memcached::get() --FILE-- false, + Memcached::OPT_VERIFY_KEY => true +)); $m->delete('foo'); diff --git a/tests/keys_ascii.phpt b/tests/keys_ascii.phpt index f7e98894..e7846e99 100644 --- a/tests/keys_ascii.phpt +++ b/tests/keys_ascii.phpt @@ -8,11 +8,8 @@ Test valid and invalid keys - ascii include dirname (__FILE__) . '/config.inc'; $ascii = memc_get_instance (array ( Memcached::OPT_BINARY_PROTOCOL => false, - Memcached::OPT_VERIFY_KEY => false + Memcached::OPT_VERIFY_KEY => true )); -// libmemcached can verify keys, but these are tests are for our own -// function s_memc_valid_key_ascii, so explicitly disable the checks -// that libmemcached can perform. echo 'ASCII: SPACES' . PHP_EOL; var_dump ($ascii->set ('ascii key with spaces', 'this is a test')); From d15c2e2fdf3791a0fc7b711a8b02cfce1e78b76f Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Fri, 20 Oct 2023 08:00:37 -0700 Subject: [PATCH 206/218] Check for spaces in keys when using the non-binary protocol even if key verification is disabled to avoid injection issues --- php_memcached.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/php_memcached.c b/php_memcached.c index 55c20089..e77e99b0 100644 --- a/php_memcached.c +++ b/php_memcached.c @@ -231,14 +231,21 @@ zend_bool s_memc_valid_key_binary(zend_string *key) } static -zend_bool s_memc_valid_key_ascii(zend_string *key) +zend_bool s_memc_valid_key_ascii(zend_string *key, uint64_t verify_key) { const char *str = ZSTR_VAL(key); size_t i, len = ZSTR_LEN(key); - for (i = 0; i < len; i++) { - if (!isgraph(str[i]) || isspace(str[i])) - return 0; + if (verify_key) { + for (i = 0; i < len; i++) { + if (!isgraph(str[i]) || isspace(str[i])) + return 0; + } + } else { /* if key verification is disabled, only check for spaces to avoid injection issues */ + for (i = 0; i < len; i++) { + if (isspace(str[i])) + return 0; + } } return 1; } @@ -248,7 +255,7 @@ zend_bool s_memc_valid_key_ascii(zend_string *key) ZSTR_LEN(key) > MEMC_OBJECT_KEY_MAX_LENGTH || \ (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL) \ ? !s_memc_valid_key_binary(key) \ - : (memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_VERIFY_KEY) && !s_memc_valid_key_ascii(key)) \ + : !s_memc_valid_key_ascii(key, memcached_behavior_get(intern->memc, MEMCACHED_BEHAVIOR_VERIFY_KEY)) \ ))) { \ intern->rescode = MEMCACHED_BAD_KEY_PROVIDED; \ RETURN_FALSE; \ @@ -342,7 +349,7 @@ PHP_INI_MH(OnUpdateSessionPrefixString) php_error_docref(NULL, E_WARNING, "memcached.sess_prefix too long (max: %d)", MEMCACHED_MAX_KEY - 1); return FAILURE; } - if (!s_memc_valid_key_ascii(new_value)) { + if (!s_memc_valid_key_ascii(new_value, 1)) { php_error_docref(NULL, E_WARNING, "memcached.sess_prefix cannot contain whitespace or control characters"); return FAILURE; } From 3ca10ec762c3844088f49d2f82a64ee188582d83 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 26 Sep 2024 13:28:51 +0200 Subject: [PATCH 207/218] ci: supply a name for the ubuntu workflow --- .github/workflows/build-and-test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index a142e10b..2e10b05b 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -1,3 +1,5 @@ + +name: Test on Ubuntu on: [push, pull_request] jobs: From 2719e1ec2d0050d9ad82f32528b866c6cacfa586 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 26 Sep 2024 13:29:34 +0200 Subject: [PATCH 208/218] prepare v3.3.0RC1 - Add #515 option to locally enforce payload size limit - Add #539 zstd support - Add #540 compression_level option - Mark password as a sensitive param for PHP 8.2 - Fix Windows PHP 8 compatibility - Fix #518 Windows msgpack support - Fix #522 signed integer overflow - Fix #523 incorrect PHP reflection type for Memcached::cas $cas_token - Fix #546 don't check key automatically, unless client-side verify_key is enabled - Fix #555 incompatible pointer types (32-bit) --- package.xml | 20 ++++++++++++++------ php_memcached.h | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/package.xml b/package.xml index 6a14b96c..bee0600e 100644 --- a/package.xml +++ b/package.xml @@ -33,19 +33,27 @@ http://pear.php.net/dtd/package-2.0.xsd"> remi@php.net yes - 2022-03-24 + 2024-09-26 - 3.2.1dev - 3.2.0 + 3.3.0RC1 + 3.3.0 - stable + beta stable PHP -- mark password as a sensitive param for PHP 8.2 -- Fix #523 Incorrect PHP reflection type for Memcached::cas $cas_token +- Add #515 option to locally enforce payload size limit +- Add #539 zstd support +- Add #540 compression_level option +- Mark password as a sensitive param for PHP 8.2 +- Fix Windows PHP 8 compatibility +- Fix #518 Windows msgpack support +- Fix #522 signed integer overflow +- Fix #523 incorrect PHP reflection type for Memcached::cas $cas_token +- Fix #546 don't check key automatically, unless client-side verify_key is enabled +- Fix #555 incompatible pointer types (32-bit) diff --git a/php_memcached.h b/php_memcached.h index e966d19d..56664235 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -30,7 +30,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.2.1-dev" +#define PHP_MEMCACHED_VERSION "3.3.0RC1" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From 25a192cde20e43e1a1200f6aee74aebeb3bfb435 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Fri, 4 Oct 2024 16:45:19 +0200 Subject: [PATCH 209/218] release v3.3.0RC1 - Add #515 option to locally enforce payload size limit - Add #539 zstd support - Add #540 compression_level option - Mark password as a sensitive param for PHP 8.2 - Fix Windows PHP 8 compatibility - Fix #518 Windows msgpack support - Fix #522 signed integer overflow - Fix #523 incorrect PHP reflection type for Memcached::cas $cas_token - Fix #546 don't check key automatically, unless client-side verify_key is enabled --- package.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/package.xml b/package.xml index bee0600e..e1d6f060 100644 --- a/package.xml +++ b/package.xml @@ -33,7 +33,13 @@ http://pear.php.net/dtd/package-2.0.xsd"> remi@php.net yes - 2024-09-26 + + Michael Wallner + mike + mike@php.net + yes + + 2024-10-04 3.3.0RC1 3.3.0 From 6189c32892d4bc553a3707160656469a089b5d43 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 30 Sep 2024 13:00:37 +0200 Subject: [PATCH 210/218] Use setup-php-sdk caching While a new release is pending, it seems worthwhile to make use of the caching as soon as possible to speed up Windows CI. --- .github/workflows/build-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index fefd7deb..b4231090 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -16,7 +16,7 @@ jobs: uses: actions/checkout@v4 - name: Setup PHP id: setup-php - uses: php/setup-php-sdk@v0.9 + uses: php/setup-php-sdk@d07cd9875fcb041bbfa63c2c592c4e68a137e1ca with: version: ${{matrix.version}} arch: ${{matrix.arch}} From 61957273e30537c3b14ec0413bc6863156d1b538 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 30 Sep 2024 13:07:18 +0200 Subject: [PATCH 211/218] Actually enable caching --- .github/workflows/build-windows.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index b4231090..c30c9dfe 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -22,6 +22,7 @@ jobs: arch: ${{matrix.arch}} ts: ${{matrix.ts}} deps: zlib + cache: true - name: Fetch libmemcached run: curl -OLs https://windows.php.net/downloads/pecl/deps/libmemcached-1.1.1-${{steps.setup-php.outputs.vs}}-${{matrix.arch}}.zip && 7z x libmemcached-1.1.1-${{steps.setup-php.outputs.vs}}-${{matrix.arch}}.zip -o..\deps - name: Enable Developer Command Prompt From cf30549f250690607d8c7363051a6a7bd3f637b6 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 30 Sep 2024 13:20:10 +0200 Subject: [PATCH 212/218] Test PHP 8.4 on Windows, too While caching speeds up the Windows builds, allocating an available runner takes some time (especially for many pushes in a short time). Thus we only build PHP 8.4 x64,zts, which should already suffice to detect most issues. --- .github/workflows/build-windows.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index c30c9dfe..3356c265 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -7,9 +7,13 @@ jobs: shell: cmd strategy: matrix: - version: ['8.3'] + version: ['8.3', '8.4'] arch: [x64, x86] ts: [nts, zts] + exclude: + - { version: '8.4', arch: x64, ts: zts } + - { version: '8.4', arch: x86, ts: nts } + - { version: '8.4', arch: x86, ts: zts } runs-on: windows-latest steps: - name: Checkout memcached From 8877b9ac8ab6dfc29384a549e06de0c03f8081eb Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 30 Sep 2024 13:25:46 +0200 Subject: [PATCH 213/218] Use new download server windows.php.net is in the process of being replaced by downloads.php.net, so we switch right away. --- .github/workflows/build-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 3356c265..d4d6133b 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -28,7 +28,7 @@ jobs: deps: zlib cache: true - name: Fetch libmemcached - run: curl -OLs https://windows.php.net/downloads/pecl/deps/libmemcached-1.1.1-${{steps.setup-php.outputs.vs}}-${{matrix.arch}}.zip && 7z x libmemcached-1.1.1-${{steps.setup-php.outputs.vs}}-${{matrix.arch}}.zip -o..\deps + run: curl -OLs https://downloads.php.net/~windows/pecl/deps/libmemcached-1.1.1-${{steps.setup-php.outputs.vs}}-${{matrix.arch}}.zip && 7z x libmemcached-1.1.1-${{steps.setup-php.outputs.vs}}-${{matrix.arch}}.zip -o..\deps - name: Enable Developer Command Prompt uses: ilammy/msvc-dev-cmd@v1 with: From c6f7d8d2beb4e9172ef517e7f99046db803f23ac Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 30 Sep 2024 13:31:04 +0200 Subject: [PATCH 214/218] Cater to yet missing libmemcached-vs17 Using libmemcached-vs16 instead should be fine. --- .github/workflows/build-windows.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index d4d6133b..c5b04ce6 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -28,7 +28,9 @@ jobs: deps: zlib cache: true - name: Fetch libmemcached - run: curl -OLs https://downloads.php.net/~windows/pecl/deps/libmemcached-1.1.1-${{steps.setup-php.outputs.vs}}-${{matrix.arch}}.zip && 7z x libmemcached-1.1.1-${{steps.setup-php.outputs.vs}}-${{matrix.arch}}.zip -o..\deps + run: | + set MEMCACHED_FILENAME=libmemcached-1.1.1-${{steps.setup-php.outputs.vs == 'vs17' && 'vs16' || steps.setup-php.outputs.vs}}-${{matrix.arch}}.zip + curl -OLs https://downloads.php.net/~windows/pecl/deps/%MEMCACHED_FILENAME% && 7z x %MEMCACHED_FILENAME% -o..\deps - name: Enable Developer Command Prompt uses: ilammy/msvc-dev-cmd@v1 with: From 089a367fe211ca4eebe5b7ae8fb1370ac00add94 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 30 Sep 2024 15:07:48 +0200 Subject: [PATCH 215/218] Update setup-php-sdk to v0.10 --- .github/workflows/build-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index c5b04ce6..4c2640e4 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -20,7 +20,7 @@ jobs: uses: actions/checkout@v4 - name: Setup PHP id: setup-php - uses: php/setup-php-sdk@d07cd9875fcb041bbfa63c2c592c4e68a137e1ca + uses: php/setup-php-sdk@v0.10 with: version: ${{matrix.version}} arch: ${{matrix.arch}} From 9243f1ff40a771de11093726a7862cc085b19da2 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 15 Oct 2024 15:02:35 +0200 Subject: [PATCH 216/218] Update libmemcached to 1.1.4 for Windows CI --- .github/workflows/build-windows.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 4c2640e4..15dba3f2 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -29,7 +29,7 @@ jobs: cache: true - name: Fetch libmemcached run: | - set MEMCACHED_FILENAME=libmemcached-1.1.1-${{steps.setup-php.outputs.vs == 'vs17' && 'vs16' || steps.setup-php.outputs.vs}}-${{matrix.arch}}.zip + set MEMCACHED_FILENAME=libmemcached-1.1.4-${{steps.setup-php.outputs.vs == 'vs17' && 'vs16' || steps.setup-php.outputs.vs}}-${{matrix.arch}}.zip curl -OLs https://downloads.php.net/~windows/pecl/deps/%MEMCACHED_FILENAME% && 7z x %MEMCACHED_FILENAME% -o..\deps - name: Enable Developer Command Prompt uses: ilammy/msvc-dev-cmd@v1 From b0b82692d789a2a5fd95b3910e87f73615c0f918 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 17 Oct 2024 19:33:43 +0200 Subject: [PATCH 217/218] release v3.3.0 --- package.xml | 7 ++++--- php_memcached.h | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package.xml b/package.xml index e1d6f060..1acb7c73 100644 --- a/package.xml +++ b/package.xml @@ -39,13 +39,13 @@ http://pear.php.net/dtd/package-2.0.xsd"> mike@php.net yes - 2024-10-04 + 2024-10-17 - 3.3.0RC1 + 3.3.0 3.3.0 - beta + stable stable PHP @@ -54,6 +54,7 @@ http://pear.php.net/dtd/package-2.0.xsd"> - Add #539 zstd support - Add #540 compression_level option - Mark password as a sensitive param for PHP 8.2 +- Upgrade Windows libmemcached to v1.1.4 - Fix Windows PHP 8 compatibility - Fix #518 Windows msgpack support - Fix #522 signed integer overflow diff --git a/php_memcached.h b/php_memcached.h index 56664235..905f941d 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -30,7 +30,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.3.0RC1" +#define PHP_MEMCACHED_VERSION "3.3.0" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport) From bfcd9e7bbac40693cc055adc5f8722ef13909e38 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 17 Oct 2024 19:50:29 +0200 Subject: [PATCH 218/218] back to dev --- package.xml | 41 ++++++++++++++++++++++++++++------------- php_memcached.h | 2 +- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/package.xml b/package.xml index 1acb7c73..5565863e 100644 --- a/package.xml +++ b/package.xml @@ -41,26 +41,16 @@ http://pear.php.net/dtd/package-2.0.xsd"> 2024-10-17 - 3.3.0 + 3.3.1dev 3.3.0 - stable + beta stable PHP -- Add #515 option to locally enforce payload size limit -- Add #539 zstd support -- Add #540 compression_level option -- Mark password as a sensitive param for PHP 8.2 -- Upgrade Windows libmemcached to v1.1.4 -- Fix Windows PHP 8 compatibility -- Fix #518 Windows msgpack support -- Fix #522 signed integer overflow -- Fix #523 incorrect PHP reflection type for Memcached::cas $cas_token -- Fix #546 don't check key automatically, unless client-side verify_key is enabled -- Fix #555 incompatible pointer types (32-bit) +- @@ -231,6 +221,31 @@ http://pear.php.net/dtd/package-2.0.xsd"> + + 2024-10-17 + + 3.3.0 + 3.3.0 + + + stable + stable + + PHP + +- Add #515 option to locally enforce payload size limit +- Add #539 zstd support +- Add #540 compression_level option +- Mark password as a sensitive param for PHP 8.2 +- Upgrade Windows libmemcached to v1.1.4 +- Fix Windows PHP 8 compatibility +- Fix #518 Windows msgpack support +- Fix #522 signed integer overflow +- Fix #523 incorrect PHP reflection type for Memcached::cas $cas_token +- Fix #546 don't check key automatically, unless client-side verify_key is enabled +- Fix #555 incompatible pointer types (32-bit) + + 2022-03-24 diff --git a/php_memcached.h b/php_memcached.h index 905f941d..dfd19185 100644 --- a/php_memcached.h +++ b/php_memcached.h @@ -30,7 +30,7 @@ # include "config.h" #endif -#define PHP_MEMCACHED_VERSION "3.3.0" +#define PHP_MEMCACHED_VERSION "3.3.1dev" #if defined(PHP_WIN32) && defined(MEMCACHED_EXPORTS) #define PHP_MEMCACHED_API __declspec(dllexport)