diff options
author | Xinchen Hui <laruence@gmail.com> | 2016-11-02 12:11:30 +0800 |
---|---|---|
committer | Xinchen Hui <laruence@gmail.com> | 2016-11-02 12:11:30 +0800 |
commit | 1efb9fd32d2618bd603e3bc4dc9adb45d509cada (patch) | |
tree | dc6389c7ee6b7f4d4a6ab96998ba3ccc10a927b1 | |
parent | 8957ff36b38a560cfa9a2a3f2a1271cfb2fcbeb9 (diff) | |
download | php-git-1efb9fd32d2618bd603e3bc4dc9adb45d509cada.tar.gz |
Fixed bug #73423 (Reproducible crash with GDB backtrace)
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | ext/spl/spl_iterators.c | 14 | ||||
-rw-r--r-- | ext/spl/tests/bug73423.phpt | 71 |
3 files changed, 84 insertions, 4 deletions
@@ -10,6 +10,9 @@ PHP NEWS . Fixed bug #73392 (A use-after-free in zend allocator management). (Laruence) +- SPL: + . Fixed bug #73423 (Reproducible crash with GDB backtrace). (Laruence) + 10 Nov 2016 PHP 7.0.13 - Core: diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 6708689d05..cc784df937 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -175,9 +175,12 @@ static void spl_recursive_it_dtor(zend_object_iterator *_iter) zend_object_iterator *sub_iter; while (object->level > 0) { - sub_iter = object->iterators[object->level].iterator; - zend_iterator_dtor(sub_iter); - zval_ptr_dtor(&object->iterators[object->level--].zobject); + if (!Z_ISUNDEF(object->iterators[object->level].zobject)) { + sub_iter = object->iterators[object->level].iterator; + zend_iterator_dtor(sub_iter); + zval_ptr_dtor(&object->iterators[object->level].zobject); + } + object->level--; } object->iterators = erealloc(object->iterators, sizeof(spl_sub_iterator)); object->level = 0; @@ -391,8 +394,11 @@ next_step: } } if (object->level > 0) { + zval garbage; + ZVAL_COPY_VALUE(&garbage, &object->iterators[object->level].zobject); + ZVAL_UNDEF(&object->iterators[object->level].zobject); + zval_ptr_dtor(&garbage); zend_iterator_dtor(iterator); - zval_ptr_dtor(&object->iterators[object->level].zobject); object->level--; } } else { diff --git a/ext/spl/tests/bug73423.phpt b/ext/spl/tests/bug73423.phpt new file mode 100644 index 0000000000..58e1acb822 --- /dev/null +++ b/ext/spl/tests/bug73423.phpt @@ -0,0 +1,71 @@ +--TEST-- +Bug #73423 (Reproducible crash with GDB backtrace) +--FILE-- +<?php + +class foo implements \RecursiveIterator + { + public $foo = []; + + public Function current () + { + return current ($this->foo); + } + + public Function key () + { + return key ($this->foo); + } + + public Function next () + { + next ($this->foo); + } + + public Function rewind () + { + reset ($this->foo); + } + + public Function valid () + { + return current ($this->foo) !== false; + } + + public Function getChildren () + { + return current ($this->foo); + } + + public Function hasChildren () + { + return (bool) count ($this->foo); + } + } + + +class fooIterator extends \RecursiveFilterIterator + { + public Function __destruct () + { + eval("class A extends NotExists {}"); + + /* CRASH */ + } + + public Function accept () + { + return true; + } + } + + +$foo = new foo (); + +$foo->foo[] = new foo (); + +foreach (new \RecursiveIteratorIterator (new fooIterator ($foo)) as $bar) ; + +?> +--EXPECTF-- +Fatal error: Class 'NotExists' not found in %sbug73423.php(%d) : eval()'d code on line 1 |