Commit:    114245c1b9cf153583c918e130faccc1f61d3ba5
Author:    Nikita Popov <ni...@php.net>         Fri, 1 Feb 2013 19:48:05 +0100
Parents:   2117b8edd1efd9940da8e5c4549e0ce13e92894c
Branches:  PHP-5.5 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=114245c1b9cf153583c918e130faccc1f61d3ba5

Log:
Fix bug #63830: Segfault on undefined function call in nested generator

This also reverses the destruction order of the pushed arguments to
align with how it is done everywhere else.

I'm not exactly sure whether this is the right way to fix it, but it
seems to work fine.

Bugs:
https://bugs.php.net/63830

Changed paths:
  M  NEWS
  A  Zend/tests/generators/nested_calls_with_die.phpt
  M  Zend/zend_generators.c


Diff:
diff --git a/NEWS b/NEWS
index 14c77d0..e79cffe 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,8 @@ PHP                                                             
           NEWS
   . Fixed bug #60833 (self, parent, static behave inconsistently 
     case-sensitive). (Stas, mario at include-once dot org)
   . Implemented FR #60524 (specify temp dir by php.ini). (ALeX Kazik).
+  . Fixed bug #63830 (Segfault on undefined function call in nested generator).
+    (Nikita Popov)
 
 - CLI server:
   . Fixed bug #64128 (buit-in web server is broken on ppc64). (Remi)
diff --git a/Zend/tests/generators/nested_calls_with_die.phpt 
b/Zend/tests/generators/nested_calls_with_die.phpt
new file mode 100644
index 0000000..f43d89b
--- /dev/null
+++ b/Zend/tests/generators/nested_calls_with_die.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test nested calls with die() in a generator
+--FILE--
+<?php
+
+function gen() {
+    die('Test');
+    yield; // force generator
+}
+
+function function_with_3_args() {
+    $gen = gen();
+    $gen->rewind();
+}
+
+function function_with_4_args() {
+    function_with_3_args(4, 5, 6);
+}
+
+function outerGen() {
+    function_with_4_args(0, 1, 2, 3);
+    yield; // force generator
+}
+
+$outerGen = outerGen();
+$outerGen->rewind();
+
+?>
+--EXPECT--
+Test
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 6213206..c1dbee1 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -94,10 +94,16 @@ ZEND_API void zend_generator_close(zend_generator 
*generator, zend_bool finished
 
                /* Clear any backed up stack arguments */
                if (generator->stack != EG(argument_stack)) {
-                       void **stack_frame = 
zend_vm_stack_frame_base(execute_data);
-                       while (generator->stack->top != stack_frame) {
-                               zval_ptr_dtor((zval**)stack_frame);
-                               stack_frame++;
+                       void **ptr = generator->stack->top - 1;
+                       void **end = zend_vm_stack_frame_base(execute_data);
+
+                       /* If the top stack element is the argument count, skip 
it */
+                       if (execute_data->function_state.arguments) {
+                               ptr--;
+                       }
+
+                       for (; ptr >= end; --ptr) {
+                               zval_ptr_dtor((zval**) ptr);
                        }
                }


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to