From ac722796c373e22a3098bb6f66ef15c1b476625e Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 22 Nov 2017 13:34:41 +0100 Subject: add upstream patch for PHP 7.2 --- 5492f345a2dbe2f2e0610e088a57283c25270e3b.patch | 95 ++++++++++++++++++++++++++ php-pecl-timecop.spec | 8 ++- 2 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 5492f345a2dbe2f2e0610e088a57283c25270e3b.patch diff --git a/5492f345a2dbe2f2e0610e088a57283c25270e3b.patch b/5492f345a2dbe2f2e0610e088a57283c25270e3b.patch new file mode 100644 index 0000000..007a3d4 --- /dev/null +++ b/5492f345a2dbe2f2e0610e088a57283c25270e3b.patch @@ -0,0 +1,95 @@ +From a7584f4a86a84c4a440a28e76041058e4e072106 Mon Sep 17 00:00:00 2001 +From: Yoshio HANAWA +Date: Sun, 19 Nov 2017 20:30:50 +0900 +Subject: [PATCH] Fix "double free" bug against override function caused by + function destructor on PHP 7.2.0+ + +--- + php_timecop.h | 18 ++++++++++++++++++ + timecop_php7.c | 14 +++++++++++--- + 2 files changed, 29 insertions(+), 3 deletions(-) + +diff --git a/php_timecop.h b/php_timecop.h +index 6606ed0..14e8d43 100644 +--- a/php_timecop.h ++++ b/php_timecop.h +@@ -148,6 +148,24 @@ ZEND_END_MODULE_GLOBALS(timecop) + #define TIMECOP_OCE(cname, mname) \ + {cname, mname, OVRD_CLASS_PREFIX cname, SAVE_FUNC_PREFIX mname} + ++/* ++ * Trick for guarding the multi-referenced internal function from function destructor on PHP 7.2.0+ ++ * See: https://github.com/hnw/php-timecop/issues/29#issuecomment-332171527 ++ */ ++#define GUARD_FUNCTION_ARG_INFO_BEGIN(zend_func) { \ ++ zend_arg_info *orig_arg_info; \ ++ zend_function *zf = zend_func; \ ++ if (zf->type == ZEND_INTERNAL_FUNCTION) { \ ++ orig_arg_info = zf->common.arg_info; \ ++ zf->common.arg_info = NULL; \ ++ } ++ ++#define GUARD_FUNCTION_ARG_INFO_END() \ ++ if (zf->type == ZEND_INTERNAL_FUNCTION) { \ ++ zf->common.arg_info = orig_arg_info; \ ++ } \ ++} ++ + struct timecop_override_func_entry { + char *orig_func; + char *ovrd_func; +diff --git a/timecop_php7.c b/timecop_php7.c +index b4d01e7..4acbc57 100644 +--- a/timecop_php7.c ++++ b/timecop_php7.c +@@ -189,7 +189,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_timecop_date_create_from_format, 0, 0, 2) + ZEND_ARG_INFO(0, format) + ZEND_ARG_INFO(0, time) + #if PHP_VERSION_ID >= 70200 +- ZEND_ARG_OBJ_INFO(0, object, DateTimeZone, 1) ++ ZEND_ARG_OBJ_INFO(0, object, DateTimeZone, 1) + #else + ZEND_ARG_INFO(0, object) + #endif +@@ -527,8 +527,10 @@ static int timecop_func_override() + zf_orig, sizeof(zend_internal_function)); + function_add_ref(zf_orig); + ++ GUARD_FUNCTION_ARG_INFO_BEGIN(zf_orig); + zend_hash_str_update_mem(EG(function_table), p->orig_func, strlen(p->orig_func), + zf_ovrd, sizeof(zend_internal_function)); ++ GUARD_FUNCTION_ARG_INFO_END(); + function_add_ref(zf_ovrd); + + p++; +@@ -620,22 +622,28 @@ static int timecop_class_override() + static int timecop_func_override_clear() + { + const struct timecop_override_func_entry *p; +- zend_function *zf_orig; ++ zend_function *zf_orig, *zf_ovld; + + p = &(timecop_override_func_table[0]); + while (p->orig_func != NULL) { + zf_orig = zend_hash_str_find_ptr(EG(function_table), + p->save_func, strlen(p->save_func)); +- if (zf_orig == NULL) { ++ zf_ovld = zend_hash_str_find_ptr(EG(function_table), ++ p->orig_func, strlen(p->orig_func)); ++ if (zf_orig == NULL || zf_ovld == NULL) { + p++; + continue; + } + ++ GUARD_FUNCTION_ARG_INFO_BEGIN(zf_ovld); + zend_hash_str_update_mem(EG(function_table), p->orig_func, strlen(p->orig_func), + zf_orig, sizeof(zend_internal_function)); ++ GUARD_FUNCTION_ARG_INFO_END(); + function_add_ref(zf_orig); + ++ GUARD_FUNCTION_ARG_INFO_BEGIN(zf_orig); + zend_hash_str_del(EG(function_table), p->save_func, strlen(p->save_func)); ++ GUARD_FUNCTION_ARG_INFO_END(); + + p++; + } diff --git a/php-pecl-timecop.spec b/php-pecl-timecop.spec index 46877f7..e616c2f 100644 --- a/php-pecl-timecop.spec +++ b/php-pecl-timecop.spec @@ -23,12 +23,14 @@ Summary: Time travel and freezing extension Name: %{?sub_prefix}php-pecl-timecop Version: 1.2.8 -Release: 2%{?dist}%{!?scl:%{!?nophptag:%(%{__php} -r 'echo ".".PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')}} +Release: 3%{?dist}%{!?scl:%{!?nophptag:%(%{__php} -r 'echo ".".PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')}} License: MIT Group: Development/Languages URL: http://pecl.php.net/package/%{pecl_name} Source0: http://pecl.php.net/get/%{pecl_name}-%{version}.tgz +Patch0: https://github.com/hnw/php-timecop/commit/5492f345a2dbe2f2e0610e088a57283c25270e3b.patch + BuildRequires: %{?scl_prefix}php-devel BuildRequires: %{?scl_prefix}php-pear @@ -90,6 +92,7 @@ sed -e 's/role="test"/role="src"/' \ -i package.xml cd NTS +%patch0 -p1 -b .upstream # Sanity check, really often broken extver=$(sed -n '/#define PHP_TIMECOP_VERSION/{s/.* "//;s/".*$//;p}' php_timecop.h) @@ -232,6 +235,9 @@ fi %changelog +* Wed Nov 22 2017 Remi Collet - 1.2.8-3 +- add upstream patch for PHP 7.2 + * Tue Jul 18 2017 Remi Collet - 1.2.8-2 - rebuild for PHP 7.2.0beta1 new API -- cgit