From 6cd499d6bb59628332989e92506a9cbb374460b9 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 29 Mar 2018 09:40:59 -0700 Subject: [PATCH 1/9] In PHP 7.3 zend_fcall_info_cache.initialized is removed. Per the upgrade notes, zend_fcall_info_cache is considered initialized if zend_fcall_info_cache.function_handler is set. --- msgpack_convert.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/msgpack_convert.c b/msgpack_convert.c index 117727e..b1d4334 100644 --- a/msgpack_convert.c +++ b/msgpack_convert.c @@ -300,7 +300,9 @@ int msgpack_convert_object(zval *return_value, zval *tpl, zval *value) /* {{{ */ fci.params = ¶ms; fci.no_separation = 1; +#if PHP_VERSION_ID < 70300 fcc.initialized = 1; +#endif fcc.function_handler = ce->constructor; #if PHP_VERSION_ID < 70100 From d47169de9c31e8689387982dfbe31e4da7419858 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 29 Mar 2018 09:42:17 -0700 Subject: [PATCH 2/9] Add PHP 7.2 and 7.3 (master) to the Travis CI matrix --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d5608d2..7cd7c90 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,11 +3,11 @@ language: php php: - 7.0 - 7.1 + - 7.2 + - master matrix: fast_finish: true - allow_failures: - - php: 7.1 notifications: email: false From 00f5383020e5c9be9e9503fc9f7f954dc73437e1 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 29 Mar 2018 11:13:55 -0700 Subject: [PATCH 3/9] PHP 7.3 refactored recursive data structures protections --- msgpack_pack.c | 22 +++++++++++----------- php_msgpack.h | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/msgpack_pack.c b/msgpack_pack.c index 646453a..6100b01 100644 --- a/msgpack_pack.c +++ b/msgpack_pack.c @@ -280,15 +280,15 @@ static inline void msgpack_serialize_array(smart_str *buf, zval *val, HashTable value_noref = value; } - if ((Z_TYPE_P(value_noref) == IS_ARRAY && ZEND_HASH_GET_APPLY_COUNT(Z_ARRVAL_P(value_noref)) > 1)) { + if (Z_TYPE_P(value_noref) == IS_ARRAY && Z_IS_RECURSIVE(Z_ARRVAL_P(value_noref))) { msgpack_pack_nil(buf); } else { - if (Z_TYPE_P(value_noref) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(value_noref))) { - ZEND_HASH_INC_APPLY_COUNT(Z_ARRVAL_P(value_noref)); + if (Z_TYPE_P(value_noref) == IS_ARRAY && Z_REFCOUNTED_P(value_noref)) { + Z_PROTECT_RECURSION(Z_ARRVAL_P(value_noref)); } msgpack_serialize_zval(buf, value, var_hash); - if (Z_TYPE_P(value_noref) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(value_noref))) { - ZEND_HASH_DEC_APPLY_COUNT(Z_ARRVAL_P(value_noref)); + if (Z_TYPE_P(value_noref) == IS_ARRAY && Z_REFCOUNTED_P(value_noref)) { + Z_UNPROTECT_RECURSION(Z_ARRVAL_P(value_noref)); } } } ZEND_HASH_FOREACH_END(); @@ -298,10 +298,10 @@ static inline void msgpack_serialize_array(smart_str *buf, zval *val, HashTable for (i = 0; i < n; i++) { if ((data = zend_hash_index_find(ht, i)) == NULL || &data == &val || - (Z_TYPE_P(data) == IS_ARRAY && ZEND_HASH_GET_APPLY_COUNT(Z_ARRVAL_P(data)) > 1)) { + (Z_TYPE_P(data) == IS_ARRAY && Z_IS_RECURSIVE(Z_ARRVAL_P(data)))) { msgpack_pack_nil(buf); } else if (Z_TYPE_P(data) == IS_REFERENCE && Z_TYPE_P(Z_REFVAL_P(data)) == IS_ARRAY && - ZEND_HASH_GET_APPLY_COUNT(Z_ARRVAL_P(Z_REFVAL_P(data))) > 1) { + Z_IS_RECURSIVE(Z_ARRVAL_P(Z_REFVAL_P(data)))) { msgpack_pack_nil(buf); } else { if (Z_TYPE_P(data) == IS_REFERENCE) { @@ -310,14 +310,14 @@ static inline void msgpack_serialize_array(smart_str *buf, zval *val, HashTable data_noref = data; } - if (Z_TYPE_P(data_noref) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data_noref))) { - ZEND_HASH_INC_APPLY_COUNT(Z_ARRVAL_P(data_noref)); + if (Z_TYPE_P(data_noref) == IS_ARRAY && Z_REFCOUNTED_P(data_noref)) { + Z_PROTECT_RECURSION(Z_ARRVAL_P(data_noref)); } msgpack_serialize_zval(buf, data, var_hash); - if (Z_TYPE_P(data_noref) == IS_ARRAY && ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(data_noref))) { - ZEND_HASH_DEC_APPLY_COUNT(Z_ARRVAL_P(data_noref)); + if (Z_TYPE_P(data_noref) == IS_ARRAY && Z_REFCOUNTED_P(data_noref)) { + Z_UNPROTECT_RECURSION(Z_ARRVAL_P(data_noref)); } } } diff --git a/php_msgpack.h b/php_msgpack.h index bbc2ad2..9c152be 100644 --- a/php_msgpack.h +++ b/php_msgpack.h @@ -44,4 +44,21 @@ PHP_MSGPACK_API void php_msgpack_serialize( PHP_MSGPACK_API int php_msgpack_unserialize( zval *return_value, char *str, size_t str_len); +/** Backport macro from PHP 7.3*/ +#ifndef Z_IS_RECURSIVE +#define Z_IS_RECURSIVE(obj) (ZEND_HASH_GET_APPLY_COUNT(obj) > 1) +#endif + +#ifndef Z_REFCOUNTED +#define Z_REFCOUNTED ZEND_HASH_APPLY_PROTECTION(obj) +#endif + +#ifndef Z_PROTECT_RECURSION +#define Z_PROTECT_RECURSION(obj) ZEND_HASH_INC_APPLY_COUNT(obj) +#endif + +#ifndef Z_UNPROTECT_RECURSION +#define Z_UNPROTECT_RECURSION(obj) ZEND_HASH_DEC_APPLY_COUNT(obj) +#endif + #endif /* PHP_MSGPACK_H */ From 035281a93f2ee59a1f52fc65b7edc75124a72c42 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 29 Mar 2018 14:23:09 -0700 Subject: [PATCH 4/9] Make sure that every test loads the msgpack module --- tests/035.phpt | 4 ++++ tests/041.phpt | 4 ++++ tests/bug011.phpt | 19 +++++++++++-------- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/tests/035.phpt b/tests/035.phpt index 89c120d..ac2dc82 100644 --- a/tests/035.phpt +++ b/tests/035.phpt @@ -3,6 +3,10 @@ Profiling perf test. --SKIPIF-- --FILE-- array( ) - ); - } - var_dump( count( msgpack_unpack( msgpack_pack( $items ) ) ) ); +if(!extension_loaded('msgpack')) { + dl('msgpack.' . PHP_SHLIB_SUFFIX); +} + +$items = array( ); +foreach( range( 0, 1024 ) as $r ) { + $items[] = array( + 'foo' => array( ) + ); +} +var_dump( count( msgpack_unpack( msgpack_pack( $items ) ) ) ); ?> --EXPECT-- From 786aee9f73aa6507184e8540ebf06400045fe873 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 29 Mar 2018 15:00:24 -0700 Subject: [PATCH 5/9] Update bug 002 test --- tests/bug002.phpt | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/tests/bug002.phpt b/tests/bug002.phpt index bfd0ad8..2100779 100644 --- a/tests/bug002.phpt +++ b/tests/bug002.phpt @@ -1,28 +1,27 @@ --TEST-- -Bug #2 (Deserializing a large array of nested objects gives "zend_mm_heap corrupted") ---XFAIL-- -Bug is not fixed yet +Bug #2 (Deserializing a large array of nested objects used to give "zend_mm_heap corrupted", now gives parse error) --SKIPIF-- +--FILE-- --EXPECTF-- -bool(true) +int(1024) + +Warning: [msgpack] (php_msgpack_unserialize) Parse error in %s on line %d +bool(false) From fe92d448fb6978e12a033988f8653a6103185e17 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 29 Mar 2018 15:13:21 -0700 Subject: [PATCH 6/9] The random data tests are known to parse as data in PHP 7.1+ --- tests/040.phpt | 4 ++++ tests/040b.phpt | 4 ++++ tests/040c.phpt | 4 ++++ tests/040d.phpt | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/tests/040.phpt b/tests/040.phpt index 5b397d3..ca1f923 100644 --- a/tests/040.phpt +++ b/tests/040.phpt @@ -1,6 +1,10 @@ --TEST-- broken random data test --SKIPIF-- + Date: Thu, 29 Mar 2018 16:00:19 -0700 Subject: [PATCH 7/9] Assume the test runner will load the msgpack module --- tests/001.phpt | 1 - tests/002.phpt | 3 --- tests/003.phpt | 3 --- tests/004.phpt | 3 --- tests/005.phpt | 3 --- tests/006.phpt | 3 --- tests/007.phpt | 3 --- tests/008.phpt | 3 --- tests/009.phpt | 3 --- tests/010.phpt | 3 --- tests/012.phpt | 3 --- tests/013.phpt | 3 --- tests/014.phpt | 3 --- tests/015.phpt | 3 --- tests/015b.phpt | 3 --- tests/015e.phpt | 3 --- tests/016.phpt | 3 --- tests/017.phpt | 3 --- tests/018.phpt | 3 --- tests/019.phpt | 3 --- tests/020.phpt | 3 --- tests/021.phpt | 3 --- tests/022.phpt | 3 --- tests/023.phpt | 3 --- tests/024.phpt | 3 --- tests/025.phpt | 3 --- tests/026.phpt | 3 --- tests/027.phpt | 3 --- tests/028.phpt | 3 --- tests/029.phpt | 1 - tests/031.phpt | 3 --- tests/032.phpt | 3 --- tests/033.phpt | 3 --- tests/034.phpt | 3 --- tests/035.phpt | 3 --- tests/040.phpt | 3 --- tests/040b.phpt | 3 --- tests/040c.phpt | 3 --- tests/040d.phpt | 3 --- tests/041.phpt | 3 --- tests/042.phpt | 3 --- tests/050.phpt | 3 --- tests/060.phpt | 3 --- tests/061.phpt | 3 --- tests/062.phpt | 3 --- tests/063.phpt | 3 --- tests/064.phpt | 3 --- tests/065.phpt | 3 --- tests/066.phpt | 3 --- tests/067.phpt | 3 --- tests/070.phpt | 3 --- tests/071.phpt | 3 --- tests/072.phpt | 3 --- tests/073.phpt | 3 --- tests/080.phpt | 3 --- tests/081.phpt | 3 --- tests/082.phpt | 3 --- tests/083.phpt | 3 --- tests/084.phpt | 3 --- tests/085.phpt | 3 --- tests/086.phpt | 3 --- tests/087.phpt | 3 --- tests/088.phpt | 3 --- tests/089.phpt | 3 --- tests/090.phpt | 4 ---- tests/091.phpt | 4 ---- tests/092.phpt | 4 ---- tests/093.phpt | 4 ---- tests/094.phpt | 4 ---- tests/095.phpt | 4 ---- tests/096.phpt | 4 ---- tests/097.phpt | 4 ---- tests/098.phpt | 4 ---- tests/099.phpt | 4 ---- tests/100.phpt | 4 ---- tests/101.phpt | 4 ---- tests/102.phpt | 4 ---- tests/103.phpt | 4 ---- tests/104.phpt | 4 ---- tests/105.phpt | 4 ---- tests/106.phpt | 4 ---- tests/107.phpt | 4 ---- tests/108.phpt | 4 ---- tests/109.phpt | 4 ---- tests/110.phpt | 4 ---- tests/111.phpt | 4 ---- tests/112.phpt | 4 ---- tests/113.phpt | 4 ---- tests/114.phpt | 4 ---- tests/115.phpt | 4 ---- tests/116.phpt | 4 ---- tests/117.phpt | 4 ---- tests/118.phpt | 4 ---- tests/119.phpt | 4 ---- tests/120.phpt | 4 ---- tests/121.phpt | 4 ---- tests/122.phpt | 4 ---- tests/123.phpt | 4 ---- tests/124.phpt | 4 ---- tests/125.phpt | 4 ---- tests/126.phpt | 4 ---- tests/127.phpt | 4 ---- tests/128.phpt | 4 ---- tests/129.phpt | 4 ---- tests/130.phpt | 4 ---- tests/131.phpt | 4 ---- tests/132.phpt | 4 ---- tests/133.phpt | 4 ---- tests/134.phpt | 4 ---- tests/135.phpt | 4 ---- tests/136.phpt | 4 ---- tests/137.phpt | 31 ++++++++++++++----------------- tests/138.phpt | 34 +++++++++++++++------------------- tests/139.phpt | 4 ---- tests/bug002.phpt | 3 --- tests/bug006.phpt | 3 --- tests/bug011.phpt | 3 --- tests/bug012.phpt | 3 --- tests/bug013.phpt | 4 ---- tests/issue023.phpt | 4 ---- tests/issue080.phpt | 4 ---- tests/issue094.phpt | 4 ---- 122 files changed, 29 insertions(+), 444 deletions(-) diff --git a/tests/001.phpt b/tests/001.phpt index 840ae46..4f4f23d 100644 --- a/tests/001.phpt +++ b/tests/001.phpt @@ -1,7 +1,6 @@ --TEST-- Check for msgpack presence --SKIPIF-- - --FILE-- --EXPECTF-- diff --git a/tests/138.phpt b/tests/138.phpt index f519c08..961b4ff 100644 --- a/tests/138.phpt +++ b/tests/138.phpt @@ -2,30 +2,26 @@ unpack bin format family --SKIPIF-- --EXPECTF-- string(9) "bin8 test" diff --git a/tests/139.phpt b/tests/139.phpt index 5c0abb3..da46bd2 100644 --- a/tests/139.phpt +++ b/tests/139.phpt @@ -7,10 +7,6 @@ if (version_compare(PHP_VERSION, '5.2.0') < 0) { } --FILE-- 2, 1 => 3); diff --git a/tests/bug011.phpt b/tests/bug011.phpt index 0f926a3..32112db 100644 --- a/tests/bug011.phpt +++ b/tests/bug011.phpt @@ -2,9 +2,6 @@ Bug #011 (Check for segfault with empty array structures) --FILE-- Date: Thu, 29 Mar 2018 16:06:56 -0700 Subject: [PATCH 8/9] Z_IS_RECURSIVE_P --- msgpack_pack.c | 6 +++--- php_msgpack.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/msgpack_pack.c b/msgpack_pack.c index 6100b01..c7051e6 100644 --- a/msgpack_pack.c +++ b/msgpack_pack.c @@ -280,7 +280,7 @@ static inline void msgpack_serialize_array(smart_str *buf, zval *val, HashTable value_noref = value; } - if (Z_TYPE_P(value_noref) == IS_ARRAY && Z_IS_RECURSIVE(Z_ARRVAL_P(value_noref))) { + if (Z_TYPE_P(value_noref) == IS_ARRAY && Z_IS_RECURSIVE_P(value_noref)) { msgpack_pack_nil(buf); } else { if (Z_TYPE_P(value_noref) == IS_ARRAY && Z_REFCOUNTED_P(value_noref)) { @@ -298,10 +298,10 @@ static inline void msgpack_serialize_array(smart_str *buf, zval *val, HashTable for (i = 0; i < n; i++) { if ((data = zend_hash_index_find(ht, i)) == NULL || &data == &val || - (Z_TYPE_P(data) == IS_ARRAY && Z_IS_RECURSIVE(Z_ARRVAL_P(data)))) { + (Z_TYPE_P(data) == IS_ARRAY && Z_IS_RECURSIVE_P(data))) { msgpack_pack_nil(buf); } else if (Z_TYPE_P(data) == IS_REFERENCE && Z_TYPE_P(Z_REFVAL_P(data)) == IS_ARRAY && - Z_IS_RECURSIVE(Z_ARRVAL_P(Z_REFVAL_P(data)))) { + Z_IS_RECURSIVE_P(Z_REFVAL_P(data))) { msgpack_pack_nil(buf); } else { if (Z_TYPE_P(data) == IS_REFERENCE) { diff --git a/php_msgpack.h b/php_msgpack.h index 9c152be..65195a3 100644 --- a/php_msgpack.h +++ b/php_msgpack.h @@ -45,8 +45,8 @@ PHP_MSGPACK_API int php_msgpack_unserialize( zval *return_value, char *str, size_t str_len); /** Backport macro from PHP 7.3*/ -#ifndef Z_IS_RECURSIVE -#define Z_IS_RECURSIVE(obj) (ZEND_HASH_GET_APPLY_COUNT(obj) > 1) +#ifndef Z_IS_RECURSIVE_P +#define Z_IS_RECURSIVE_P(obj) (ZEND_HASH_GET_APPLY_COUNT(Z_ARRVAL_P(obj)) > 1) #endif #ifndef Z_REFCOUNTED From 066c2499c33c3b0a6d430de194560b408d118085 Mon Sep 17 00:00:00 2001 From: Aaron Stone Date: Thu, 29 Mar 2018 18:12:05 -0700 Subject: [PATCH 9/9] Z_PROTECT_RECURSION_P --- msgpack_pack.c | 8 ++++---- php_msgpack.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/msgpack_pack.c b/msgpack_pack.c index c7051e6..b9785a8 100644 --- a/msgpack_pack.c +++ b/msgpack_pack.c @@ -284,11 +284,11 @@ static inline void msgpack_serialize_array(smart_str *buf, zval *val, HashTable msgpack_pack_nil(buf); } else { if (Z_TYPE_P(value_noref) == IS_ARRAY && Z_REFCOUNTED_P(value_noref)) { - Z_PROTECT_RECURSION(Z_ARRVAL_P(value_noref)); + Z_PROTECT_RECURSION_P(value_noref); } msgpack_serialize_zval(buf, value, var_hash); if (Z_TYPE_P(value_noref) == IS_ARRAY && Z_REFCOUNTED_P(value_noref)) { - Z_UNPROTECT_RECURSION(Z_ARRVAL_P(value_noref)); + Z_UNPROTECT_RECURSION_P(value_noref); } } } ZEND_HASH_FOREACH_END(); @@ -311,13 +311,13 @@ static inline void msgpack_serialize_array(smart_str *buf, zval *val, HashTable } if (Z_TYPE_P(data_noref) == IS_ARRAY && Z_REFCOUNTED_P(data_noref)) { - Z_PROTECT_RECURSION(Z_ARRVAL_P(data_noref)); + Z_PROTECT_RECURSION_P(data_noref); } msgpack_serialize_zval(buf, data, var_hash); if (Z_TYPE_P(data_noref) == IS_ARRAY && Z_REFCOUNTED_P(data_noref)) { - Z_UNPROTECT_RECURSION(Z_ARRVAL_P(data_noref)); + Z_UNPROTECT_RECURSION_P(data_noref); } } } diff --git a/php_msgpack.h b/php_msgpack.h index 65195a3..6707bef 100644 --- a/php_msgpack.h +++ b/php_msgpack.h @@ -53,12 +53,12 @@ PHP_MSGPACK_API int php_msgpack_unserialize( #define Z_REFCOUNTED ZEND_HASH_APPLY_PROTECTION(obj) #endif -#ifndef Z_PROTECT_RECURSION -#define Z_PROTECT_RECURSION(obj) ZEND_HASH_INC_APPLY_COUNT(obj) +#ifndef Z_PROTECT_RECURSION_P +#define Z_PROTECT_RECURSION_P(obj) ZEND_HASH_INC_APPLY_COUNT(Z_ARRVAL_P(obj)) #endif -#ifndef Z_UNPROTECT_RECURSION -#define Z_UNPROTECT_RECURSION(obj) ZEND_HASH_DEC_APPLY_COUNT(obj) +#ifndef Z_UNPROTECT_RECURSION_P +#define Z_UNPROTECT_RECURSION_P(obj) ZEND_HASH_DEC_APPLY_COUNT(Z_ARRVAL_P(obj)) #endif #endif /* PHP_MSGPACK_H */