From 179fba3f3801d5528cfc5e82be09cf8ef512b0ba Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Thu, 29 Oct 2015 14:33:58 +0800 Subject: [PATCH] Fixed bug #70808 (array_merge_recursive corrupts memory of unset items) I knew, this fix seems ugly --- NEWS | 4 ++++ ext/standard/array.c | 4 ++++ ext/standard/tests/array/bug70808.phpt | 23 +++++++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 ext/standard/tests/array/bug70808.phpt diff --git a/NEWS b/NEWS index 0cebbd121c..f4e6c8d6f5 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 2015, PHP 7.0.1 +- Standard: + . Fixed bug #70808 (array_merge_recursive corrupts memory of unset items). + (laruence) + - XSL: . Fixed bug #70678 (PHP7 returns true when false is expected). (Felipe) diff --git a/ext/standard/array.c b/ext/standard/array.c index 4678e14488..88818fe78f 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2967,6 +2967,10 @@ PHPAPI int php_array_merge_recursive(HashTable *dest, HashTable *src) /* {{{ */ if (Z_TYPE_P(dest_zval) == IS_NULL) { convert_to_array_ex(dest_zval); add_next_index_null(dest_zval); + } else if (Z_TYPE_P(dest_zval) == IS_ARRAY) { + if (UNEXPECTED(Z_ARRVAL_P(dest_zval)->nNextFreeElement > Z_ARRVAL_P(dest_zval)->nNumUsed)) { + Z_ARRVAL_P(dest_zval)->nNextFreeElement = Z_ARRVAL_P(dest_zval)->nNumUsed; + } } else { convert_to_array_ex(dest_zval); } diff --git a/ext/standard/tests/array/bug70808.phpt b/ext/standard/tests/array/bug70808.phpt new file mode 100644 index 0000000000..8a625386d3 --- /dev/null +++ b/ext/standard/tests/array/bug70808.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #70808 (array_merge_recursive corrupts memory of unset items) +--FILE-- + array(0, 1)); +$arr2 = array("key" => array(2)); + +unset($arr1["key"][1]); + +$result = array_merge_recursive($arr1, $arr2); +print_r($result); +?> +--EXPECT-- +Array +( + [key] => Array + ( + [0] => 0 + [1] => 2 + ) + +) -- 2.49.0