com php-src: Fixed bug #73423 (Reproducible crash with GDB backtrace): NEWS ext/spl/spl_iterators.c ext/spl/tests/bug73423 .phpt
| From: | Xinchen Hui | Date: | Wed, 02 Nov 2016 04:11:30 +0000 |
| Subject: | com php-src: Fixed bug #73423 (Reproducible crash with GDB backtrace): NEWS ext/spl/spl_iterators.c ext/spl/tests/bug73423 .phpt | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-95383@lists.php.net to get a copy of this message | ||
Commit: 1efb9fd32d2618bd603e3bc4dc9adb45d509cada
Author: Xinchen Hui <laruence@gmail.com> Wed, 2 Nov 2016 12:11:30 +0800
Parents: 8957ff36b38a560cfa9a2a3f2a1271cfb2fcbeb9
Branches: PHP-7.0 PHP-7.1 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=1efb9fd32d2618bd603e3bc4dc9adb45d509cada
Log:
Fixed bug #73423 (Reproducible crash with GDB backtrace)
Bugs:
https://bugs.php.net/73423
Changed paths:
M NEWS
M ext/spl/spl_iterators.c
A ext/spl/tests/bug73423.phpt
Diff:
diff --git a/NEWS b/NEWS
index a0c5152..ac4d958 100644
--- a/NEWS
+++ b/NEWS
@@ -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 6708689..cc784df 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 0000000..58e1acb
--- /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