summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemi Collet <fedora@famillecollet.com>2014-03-20 15:44:05 +0100
committerRemi Collet <fedora@famillecollet.com>2014-03-20 15:44:05 +0100
commit64acc136736ffae3c2d841078cb220b8510b42f0 (patch)
treef7c169e6405db3c425ba9d57b40e971192991547
parentf390374a9d3043e063a9949a3adb91763b75595b (diff)
php-pecl-redis: fix memory corruption with PHP 5.6
-rw-r--r--php-pecl-redis.spec15
-rw-r--r--redis-php56.patch363
2 files changed, 376 insertions, 2 deletions
diff --git a/php-pecl-redis.spec b/php-pecl-redis.spec
index e1be964..02ab2b3 100644
--- a/php-pecl-redis.spec
+++ b/php-pecl-redis.spec
@@ -18,7 +18,7 @@
Summary: Extension for communicating with the Redis key-value store
Name: %{?scl_prefix}php-pecl-redis
Version: 2.2.5
-Release: 1%{?dist}%{!?nophptag:%(%{__php} -r 'echo ".".PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')}
+Release: 2%{?dist}%{!?nophptag:%(%{__php} -r 'echo ".".PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')}
License: PHP
Group: Development/Languages
URL: http://pecl.php.net/package/redis
@@ -26,6 +26,9 @@ Source0: http://pecl.php.net/get/%{pecl_name}-%{version}.tgz
# https://github.com/nicolasff/phpredis/issues/332 - missing tests
Source1: https://github.com/nicolasff/phpredis/archive/%{version}.tar.gz
+# https://github.com/nicolasff/phpredis/pull/447
+Patch0: %{pecl_name}-php56.patch
+
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
BuildRequires: %{?scl_prefix}php-devel
BuildRequires: %{?scl_prefix}php-pecl-igbinary-devel
@@ -81,12 +84,16 @@ mv %{pecl_name}-%{version} nts
# tests folder from github archive
mv phpredis-%{version}/tests nts/tests
+cd nts
+%patch0 -p1 -b .php56
+
# Sanity check, really often broken
-extver=$(sed -n '/#define PHP_REDIS_VERSION/{s/.* "//;s/".*$//;p}' nts/php_redis.h)
+extver=$(sed -n '/#define PHP_REDIS_VERSION/{s/.* "//;s/".*$//;p}' php_redis.h)
if test "x${extver}" != "x%{version}"; then
: Error: Upstream extension version is ${extver}, expecting %{version}.
exit 1
fi
+cd ..
%if %{with_zts}
# duplicate for ZTS build
@@ -241,6 +248,10 @@ rm -rf %{buildroot}
%changelog
+* Thu Mar 20 2014 Remi Collet <rcollet@redhat.com> - 2.2.5-2
+- fix memory corruption with PHP 5.6
+ https://github.com/nicolasff/phpredis/pull/447
+
* Wed Mar 19 2014 Remi Collet <remi@fedoraproject.org> - 2.2.5-1
- Update to 2.2.5
diff --git a/redis-php56.patch b/redis-php56.patch
new file mode 100644
index 0000000..f97af12
--- /dev/null
+++ b/redis-php56.patch
@@ -0,0 +1,363 @@
+From 5520be1042d1b97728a3f8e04ed3c5a6fd0da9f8 Mon Sep 17 00:00:00 2001
+From: Remi Collet <fedora@famillecollet.com>
+Date: Thu, 20 Mar 2014 13:48:04 +0100
+Subject: [PATCH 2/7] Fix memory corruption observed with PHP 5.6.0-dev
+
+---
+ library.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/library.c b/library.c
+index e4ad72b..6525ade 100644
+--- a/library.c
++++ b/library.c
+@@ -1560,6 +1560,11 @@ PHPAPI void redis_free_socket(RedisSock *redis_sock)
+ ZVAL_STRINGL(z_copy, "Array", 5, 1);
+ break;
+
++ case IS_NULL:
++ MAKE_STD_ZVAL(z_copy);
++ ZVAL_STRINGL(z_copy, "", 0, 1);
++ break;
++
+ default: /* copy */
+ MAKE_STD_ZVAL(z_copy);
+ *z_copy = *z;
+--
+1.8.5.5
+
+
+From 8805b133b9b1d0bf18a59ef97d95ca8c3a1ab9a7 Mon Sep 17 00:00:00 2001
+From: Remi Collet <fedora@famillecollet.com>
+Date: Thu, 20 Mar 2014 13:49:26 +0100
+Subject: [PATCH 3/7] redis.c:7022:13: warning: 'keyword' may be used
+ uninitialized in this function (mostly to make gcc happy)
+
+---
+ redis.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/redis.c b/redis.c
+index 4788480..c17bab1 100644
+--- a/redis.c
++++ b/redis.c
+@@ -7014,6 +7014,7 @@ PHPAPI void generic_unsubscribe_cmd(INTERNAL_FUNCTION_PARAMETERS, char *unsub_cm
+ keyword = "HSCAN";
+ break;
+ case TYPE_ZSCAN:
++ default:
+ keyword = "ZSCAN";
+ break;
+ }
+--
+1.8.5.5
+
+
+From 7634db4283409d1fc113596d00a12e531d05c13f Mon Sep 17 00:00:00 2001
+From: Remi Collet <fedora@famillecollet.com>
+Date: Thu, 20 Mar 2014 13:54:53 +0100
+Subject: [PATCH 4/7] Fix: library.c:743:78: warning: unused variable 'p2'
+ (PLEASE CHECK)
+
+---
+ library.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/library.c b/library.c
+index 6525ade..680debd 100644
+--- a/library.c
++++ b/library.c
+@@ -774,8 +774,8 @@ PHPAPI void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *red
+
+ // Treat numbers as numbers, strings as strings
+ is_numeric = 1;
+- for(p2 = value; *p; ++p) {
+- if(*p < '0' || *p > '9') {
++ for(p2 = value; *p2; ++p2) {
++ if(*p2 < '0' || *p2 > '9') {
+ is_numeric = 0;
+ break;
+ }
+--
+1.8.5.5
+
+
+From 47ddcf75fd3582d50937bf90750b67531db5d5c8 Mon Sep 17 00:00:00 2001
+From: Remi Collet <fedora@famillecollet.com>
+Date: Thu, 20 Mar 2014 13:56:11 +0100
+Subject: [PATCH 5/7] Fix ibrary.c:1541:9: warning: unused variable 'sz' +
+ 'val8'
+
+---
+ library.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/library.c b/library.c
+index 680debd..f02f559 100644
+--- a/library.c
++++ b/library.c
+@@ -1538,8 +1538,10 @@ PHPAPI void redis_free_socket(RedisSock *redis_sock)
+ #endif
+ smart_str sstr = {0};
+ zval *z_copy;
++#ifdef HAVE_REDIS_IGBINARY
+ size_t sz;
+ uint8_t *val8;
++#endif
+
+ switch(redis_sock->serializer) {
+ case REDIS_SERIALIZER_NONE:
+--
+1.8.5.5
+
+
+From d74b0d27f347d6fc77c8310259f8462890d38f9b Mon Sep 17 00:00:00 2001
+From: Remi Collet <fedora@famillecollet.com>
+Date: Thu, 20 Mar 2014 13:56:49 +0100
+Subject: [PATCH 6/7] Fix warning: 'klen' may be used uninitialized in this
+ function
+
+---
+ library.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/library.c b/library.c
+index f02f559..57d413e 100644
+--- a/library.c
++++ b/library.c
+@@ -743,7 +743,7 @@ PHPAPI void redis_client_list_reply(INTERNAL_FUNCTION_PARAMETERS, RedisSock *red
+ char *p = resp, *lpos = resp, *kpos = NULL, *vpos = NULL, *p2, *key, *value;
+
+ // Key length, done flag
+- int klen, done = 0, is_numeric;
++ int klen = 0, done = 0, is_numeric;
+
+ // While we've got more to parse
+ while(!done) {
+--
+1.8.5.5
+
+
+From b9a16b5ad5d8c80eac53f530f37e89761ec2c720 Mon Sep 17 00:00:00 2001
+From: Remi Collet <fedora@famillecollet.com>
+Date: Thu, 20 Mar 2014 15:06:40 +0100
+Subject: [PATCH 7/7] revert previous, and better fix for memory corruption
+ (STR_FREE available since 5.0)
+
+---
+ library.c | 5 -----
+ redis.c | 47 ++++++++++++++++++++++++-----------------------
+ 2 files changed, 24 insertions(+), 28 deletions(-)
+
+diff --git a/library.c b/library.c
+index 57d413e..b0f15db 100644
+--- a/library.c
++++ b/library.c
+@@ -1562,11 +1562,6 @@ PHPAPI void redis_free_socket(RedisSock *redis_sock)
+ ZVAL_STRINGL(z_copy, "Array", 5, 1);
+ break;
+
+- case IS_NULL:
+- MAKE_STD_ZVAL(z_copy);
+- ZVAL_STRINGL(z_copy, "", 0, 1);
+- break;
+-
+ default: /* copy */
+ MAKE_STD_ZVAL(z_copy);
+ *z_copy = *z;
+diff --git a/redis.c b/redis.c
+index c17bab1..8c12657 100644
+--- a/redis.c
++++ b/redis.c
+@@ -990,7 +990,7 @@ PHPAPI int redis_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) {
+
+ /* Free our key or value if we prefixed/serialized */
+ if(key_free) efree(key);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+
+ /* Kick off the command */
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+@@ -1023,7 +1023,7 @@ PHPAPI void redis_generic_setex(INTERNAL_FUNCTION_PARAMETERS, char *keyword) {
+ val_free = redis_serialize(redis_sock, z_value, &val, &val_len TSRMLS_CC);
+ key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
+ cmd_len = redis_cmd_format_static(&cmd, keyword, "sls", key, key_len, expire, val, val_len);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(key_free) efree(key);
+
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+@@ -1072,7 +1072,7 @@ PHPAPI void redis_generic_setex(INTERNAL_FUNCTION_PARAMETERS, char *keyword) {
+ val_free = redis_serialize(redis_sock, z_value, &val, &val_len TSRMLS_CC);
+ key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
+ cmd_len = redis_cmd_format_static(&cmd, "SETNX", "ss", key, key_len, val, val_len);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(key_free) efree(key);
+
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+@@ -1110,7 +1110,7 @@ PHPAPI void redis_generic_setex(INTERNAL_FUNCTION_PARAMETERS, char *keyword) {
+ val_free = redis_serialize(redis_sock, z_value, &val, &val_len TSRMLS_CC);
+ key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
+ cmd_len = redis_cmd_format_static(&cmd, "GETSET", "ss", key, key_len, val, val_len);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(key_free) efree(key);
+
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+@@ -1928,7 +1928,7 @@ PHPAPI void redis_unwatch_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redi
+ val_free = redis_serialize(redis_sock, z_value, &val, &val_len TSRMLS_CC);
+ key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
+ cmd_len = redis_cmd_format_static(&cmd, keyword, "ss", key, key_len, val, val_len);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(key_free) efree(key);
+
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+@@ -2004,9 +2004,9 @@ PHPAPI void redis_unwatch_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redi
+ val_free = redis_serialize(redis_sock, z_value, &val, &val_len TSRMLS_CC);
+ pivot_free = redis_serialize(redis_sock, z_pivot, &pivot, &pivot_len TSRMLS_CC);
+ cmd_len = redis_cmd_format_static(&cmd, "LINSERT", "ssss", key, key_len, position, position_len, pivot, pivot_len, val, val_len);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(key_free) efree(key);
+- if(pivot_free) efree(pivot);
++ if(pivot_free) STR_FREE(pivot);
+
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+ IF_ATOMIC() {
+@@ -2178,7 +2178,7 @@ PHPAPI void redis_unwatch_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redi
+ val_free = redis_serialize(redis_sock, z_value, &val, &val_len TSRMLS_CC);
+ key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
+ cmd_len = redis_cmd_format_static(&cmd, "LREM", "sds", key, key_len, count, val, val_len);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(key_free) efree(key);
+
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+@@ -2382,7 +2382,7 @@ PHPAPI void redis_unwatch_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redi
+ src_free = redis_key_prefix(redis_sock, &src, &src_len TSRMLS_CC);
+ dst_free = redis_key_prefix(redis_sock, &dst, &dst_len TSRMLS_CC);
+ cmd_len = redis_cmd_format_static(&cmd, "SMOVE", "sss", src, src_len, dst, dst_len, val, val_len);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(src_free) efree(src);
+ if(dst_free) efree(dst);
+
+@@ -2488,7 +2488,7 @@ PHPAPI void redis_unwatch_response(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redi
+ val_free = redis_serialize(redis_sock, z_value, &val, &val_len TSRMLS_CC);
+ key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
+ cmd_len = redis_cmd_format_static(&cmd, "SISMEMBER", "ss", key, key_len, val, val_len);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(key_free) efree(key);
+
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+@@ -2716,7 +2716,7 @@ PHPAPI int generic_multiple_args_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword
+ /* cleanup prefixed keys. */
+ for(i = 0; i < real_argc + (has_timeout?-1:0); ++i) {
+ if(keys_to_free[i])
+- efree(keys[i]);
++ STR_FREE(keys[i]);
+ }
+ if(single_array && has_timeout) { /* cleanup string created to contain timeout value */
+ efree(keys[real_argc-1]);
+@@ -3362,7 +3362,7 @@ PHPAPI void generic_expire_cmd(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int
+ val_free = redis_serialize(redis_sock, z_value, &val, &val_len TSRMLS_CC);
+ key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
+ cmd_len = redis_cmd_format_static(&cmd, "LSET", "sds", key, key_len, index, val, val_len);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(key_free) efree(key);
+
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+@@ -3782,7 +3782,7 @@ PHPAPI void generic_ttl(INTERNAL_FUNCTION_PARAMETERS, char *keyword) {
+ memcpy(p, _NL, 2); p += 2;
+ }
+
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(key_free) efree(key);
+ }
+ }
+@@ -3964,7 +3964,7 @@ PHPAPI void common_rpoplpush(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock
+ smart_str_appendl(&buf, val, val_len);
+ smart_str_appendl(&buf, _NL, sizeof(_NL) - 1);
+
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ }
+
+ /* end string */
+@@ -4361,7 +4361,7 @@ PHPAPI void common_rpoplpush(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock
+ val_free = redis_serialize(redis_sock, z_value, &val, &val_len TSRMLS_CC);
+ key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
+ cmd_len = redis_cmd_format_static(&cmd, "ZSCORE", "ss", key, key_len, val, val_len);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(key_free) efree(key);
+
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+@@ -4394,7 +4394,7 @@ PHPAPI void generic_rank_method(INTERNAL_FUNCTION_PARAMETERS, char *keyword, int
+ val_free = redis_serialize(redis_sock, z_value, &val, &val_len TSRMLS_CC);
+ key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
+ cmd_len = redis_cmd_format_static(&cmd, keyword, "ss", key, key_len, val, val_len);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(key_free) efree(key);
+
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+@@ -4444,7 +4444,7 @@ PHPAPI void generic_incrby_method(INTERNAL_FUNCTION_PARAMETERS, char *keyword, i
+ val_free = redis_serialize(redis_sock, z_value, &val, &val_len TSRMLS_CC);
+ key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
+ cmd_len = redis_cmd_format_static(&cmd, keyword, "sfs", key, key_len, add, val, val_len);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(key_free) efree(key);
+
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+@@ -4659,7 +4659,7 @@ PHPAPI void generic_z_command(INTERNAL_FUNCTION_PARAMETERS, char *command, int c
+ val_free = redis_serialize(redis_sock, z_value, &val, &val_len TSRMLS_CC);
+ key_free = redis_key_prefix(redis_sock, &key, &key_len TSRMLS_CC);
+ cmd_len = redis_cmd_format_static(&cmd, kw, "sss", key, key_len, member, member_len, val, val_len);
+- if(val_free) efree(val);
++ if(val_free) STR_FREE(val);
+ if(key_free) efree(key);
+
+ REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
+@@ -5179,7 +5179,7 @@ PHPAPI void array_zip_values_and_scores(RedisSock *redis_sock, zval *z_tab, int
+ redis_cmd_append_sstr(&set_cmds, hkey, hkey_len - 1);
+ redis_cmd_append_sstr(&set_cmds, hval, hval_len);
+
+- if(hval_free) efree(hval);
++ if(hval_free) STR_FREE(hval);
+ }
+
+ // Now construct the entire command
+@@ -6685,7 +6685,7 @@ PHPAPI void generic_unsubscribe_cmd(INTERNAL_FUNCTION_PARAMETERS, char *unsub_cm
+ RedisSock *redis_sock;
+ zval *z_val;
+ char *val;
+- int val_free, val_len;
++ int val_len;
+
+ // Parse arguments
+ if(zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz",
+@@ -6700,10 +6700,11 @@ PHPAPI void generic_unsubscribe_cmd(INTERNAL_FUNCTION_PARAMETERS, char *unsub_cm
+ }
+
+ // Serialize, which will return a value even if no serializer is set
+- val_free = redis_serialize(redis_sock, z_val, &val, &val_len TSRMLS_CC);
++ redis_serialize(redis_sock, z_val, &val, &val_len TSRMLS_CC);
+
+- // Return serialized value. Tell PHP to make a copy if redis_serialize didn't.
+- RETURN_STRINGL(val, val_len, !val_free);
++ // Return serialized value. Tell PHP to make a copy as some can be interned.
++ RETVAL_STRINGL(val, val_len, 1);
++ STR_FREE(val);
+ }
+
+ /*
+--
+1.8.5.5
+