dmitry                                   Tue, 02 Aug 2011 07:38:23 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=314086

Log:
Fixed bug #55339 (Segfault with allow_call_time_pass_reference = Off)

Bug: https://bugs.php.net/55339 (Feedback) Segfault with 
allow_call_time_pass_reference = Off
      
Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    A   php/php-src/branches/PHP_5_3/Zend/tests/bug55339.phpt
    U   php/php-src/branches/PHP_5_3/Zend/zend.c
    U   php/php-src/branches/PHP_5_4/Zend/zend.c
    U   php/php-src/trunk/Zend/zend.c

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS   2011-08-02 06:21:40 UTC (rev 314085)
+++ php/php-src/branches/PHP_5_3/NEWS   2011-08-02 07:38:23 UTC (rev 314086)
@@ -13,6 +13,8 @@
     (Scott)

 - Core
+  . Fixed bug #55339 (Segfault with allow_call_time_pass_reference = Off).
+    (Dmitry)
   . Fix bug #55295 [NEW]: popen_ex on windows, fixed possible heap overflow
     (Pierre)
   . Fixed bug #50816 (Using class constants in array definition fails).

Added: php/php-src/branches/PHP_5_3/Zend/tests/bug55339.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/tests/bug55339.phpt                       
        (rev 0)
+++ php/php-src/branches/PHP_5_3/Zend/tests/bug55339.phpt       2011-08-02 
07:38:23 UTC (rev 314086)
@@ -0,0 +1,31 @@
+--TEST--
+Bug #55339 (Segfault with allow_call_time_pass_reference = Off)
+--INI--
+allow_call_time_pass_reference=off
+--FILE--
+<?php
+function error_handler($errno, $errstr, $errfile, $errline) {
+       eval(';');
+}
+
+set_error_handler('error_handler');
+
+eval(<<<'EOF'
+function foo()
+{
+    $array = array();
+    foreach ($array as $key => $value) {
+        bar($key, &$value);
+    }
+}
+
+function bar()
+{
+
+}
+EOF
+);
+
+echo "OK\n";
+--EXPECT--
+OK

Modified: php/php-src/branches/PHP_5_3/Zend/zend.c
===================================================================
--- php/php-src/branches/PHP_5_3/Zend/zend.c    2011-08-02 06:21:40 UTC (rev 
314085)
+++ php/php-src/branches/PHP_5_3/Zend/zend.c    2011-08-02 07:38:23 UTC (rev 
314086)
@@ -958,6 +958,23 @@
 }
 /* }}} */

+#define SAVE_STACK(stack) do { \
+               if (CG(stack).top) { \
+                       memcpy(&stack, &CG(stack), sizeof(zend_stack)); \
+                       CG(stack).top = CG(stack).max = 0; \
+                       CG(stack).elements = NULL; \
+               } else { \
+                       stack.top = 0; \
+               } \
+       } while (0)
+
+#define RESTORE_STACK(stack) do { \
+               if (stack.top) { \
+                       zend_stack_destroy(&CG(stack)); \
+                       memcpy(&CG(stack), &stack, sizeof(zend_stack)); \
+               } \
+       } while (0)
+
 ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
 {
        va_list args;
@@ -970,6 +987,14 @@
        zval *orig_user_error_handler;
        zend_bool in_compilation;
        zend_class_entry *saved_class_entry;
+       zend_stack bp_stack;
+       zend_stack function_call_stack;
+       zend_stack switch_cond_stack;
+       zend_stack foreach_copy_stack;
+       zend_stack object_stack;
+       zend_stack declare_stack;
+       zend_stack list_stack;
+       zend_stack labels_stack;
        TSRMLS_FETCH();

        /* Obtain relevant filename and lineno */
@@ -1097,6 +1122,14 @@
                        if (in_compilation) {
                                saved_class_entry = CG(active_class_entry);
                                CG(active_class_entry) = NULL;
+                               SAVE_STACK(bp_stack);
+                               SAVE_STACK(function_call_stack);
+                               SAVE_STACK(switch_cond_stack);
+                               SAVE_STACK(foreach_copy_stack);
+                               SAVE_STACK(object_stack);
+                               SAVE_STACK(declare_stack);
+                               SAVE_STACK(list_stack);
+                               SAVE_STACK(labels_stack);
                        }

                        if (call_user_function_ex(CG(function_table), NULL, 
orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC) == SUCCESS) {
@@ -1113,6 +1146,14 @@

                        if (in_compilation) {
                                CG(active_class_entry) = saved_class_entry;
+                               RESTORE_STACK(bp_stack);
+                               RESTORE_STACK(function_call_stack);
+                               RESTORE_STACK(switch_cond_stack);
+                               RESTORE_STACK(foreach_copy_stack);
+                               RESTORE_STACK(object_stack);
+                               RESTORE_STACK(declare_stack);
+                               RESTORE_STACK(list_stack);
+                               RESTORE_STACK(labels_stack);
                        }

                        if (!EG(user_error_handler)) {

Modified: php/php-src/branches/PHP_5_4/Zend/zend.c
===================================================================
--- php/php-src/branches/PHP_5_4/Zend/zend.c    2011-08-02 06:21:40 UTC (rev 
314085)
+++ php/php-src/branches/PHP_5_4/Zend/zend.c    2011-08-02 07:38:23 UTC (rev 
314086)
@@ -975,6 +975,23 @@
 }
 /* }}} */

+#define SAVE_STACK(stack) do { \
+               if (CG(stack).top) { \
+                       memcpy(&stack, &CG(stack), sizeof(zend_stack)); \
+                       CG(stack).top = CG(stack).max = 0; \
+                       CG(stack).elements = NULL; \
+               } else { \
+                       stack.top = 0; \
+               } \
+       } while (0)
+
+#define RESTORE_STACK(stack) do { \
+               if (stack.top) { \
+                       zend_stack_destroy(&CG(stack)); \
+                       memcpy(&CG(stack), &stack, sizeof(zend_stack)); \
+               } \
+       } while (0)
+
 ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
 {
        va_list args;
@@ -987,6 +1004,14 @@
        zval *orig_user_error_handler;
        zend_bool in_compilation;
        zend_class_entry *saved_class_entry;
+       zend_stack bp_stack;
+       zend_stack function_call_stack;
+       zend_stack switch_cond_stack;
+       zend_stack foreach_copy_stack;
+       zend_stack object_stack;
+       zend_stack declare_stack;
+       zend_stack list_stack;
+       zend_stack context_stack;
        TSRMLS_FETCH();

        /* Obtain relevant filename and lineno */
@@ -1123,6 +1148,14 @@
                        if (in_compilation) {
                                saved_class_entry = CG(active_class_entry);
                                CG(active_class_entry) = NULL;
+                               SAVE_STACK(bp_stack);
+                               SAVE_STACK(function_call_stack);
+                               SAVE_STACK(switch_cond_stack);
+                               SAVE_STACK(foreach_copy_stack);
+                               SAVE_STACK(object_stack);
+                               SAVE_STACK(declare_stack);
+                               SAVE_STACK(list_stack);
+                               SAVE_STACK(context_stack);
                        }

                        if (call_user_function_ex(CG(function_table), NULL, 
orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC) == SUCCESS) {
@@ -1139,6 +1172,14 @@

                        if (in_compilation) {
                                CG(active_class_entry) = saved_class_entry;
+                               RESTORE_STACK(bp_stack);
+                               RESTORE_STACK(function_call_stack);
+                               RESTORE_STACK(switch_cond_stack);
+                               RESTORE_STACK(foreach_copy_stack);
+                               RESTORE_STACK(object_stack);
+                               RESTORE_STACK(declare_stack);
+                               RESTORE_STACK(list_stack);
+                               RESTORE_STACK(context_stack);
                        }

                        if (!EG(user_error_handler)) {

Modified: php/php-src/trunk/Zend/zend.c
===================================================================
--- php/php-src/trunk/Zend/zend.c       2011-08-02 06:21:40 UTC (rev 314085)
+++ php/php-src/trunk/Zend/zend.c       2011-08-02 07:38:23 UTC (rev 314086)
@@ -975,6 +975,23 @@
 }
 /* }}} */

+#define SAVE_STACK(stack) do { \
+               if (CG(stack).top) { \
+                       memcpy(&stack, &CG(stack), sizeof(zend_stack)); \
+                       CG(stack).top = CG(stack).max = 0; \
+                       CG(stack).elements = NULL; \
+               } else { \
+                       stack.top = 0; \
+               } \
+       } while (0)
+
+#define RESTORE_STACK(stack) do { \
+               if (stack.top) { \
+                       zend_stack_destroy(&CG(stack)); \
+                       memcpy(&CG(stack), &stack, sizeof(zend_stack)); \
+               } \
+       } while (0)
+
 ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
 {
        va_list args;
@@ -987,6 +1004,14 @@
        zval *orig_user_error_handler;
        zend_bool in_compilation;
        zend_class_entry *saved_class_entry;
+       zend_stack bp_stack;
+       zend_stack function_call_stack;
+       zend_stack switch_cond_stack;
+       zend_stack foreach_copy_stack;
+       zend_stack object_stack;
+       zend_stack declare_stack;
+       zend_stack list_stack;
+       zend_stack context_stack;
        TSRMLS_FETCH();

        /* Obtain relevant filename and lineno */
@@ -1123,6 +1148,14 @@
                        if (in_compilation) {
                                saved_class_entry = CG(active_class_entry);
                                CG(active_class_entry) = NULL;
+                               SAVE_STACK(bp_stack);
+                               SAVE_STACK(function_call_stack);
+                               SAVE_STACK(switch_cond_stack);
+                               SAVE_STACK(foreach_copy_stack);
+                               SAVE_STACK(object_stack);
+                               SAVE_STACK(declare_stack);
+                               SAVE_STACK(list_stack);
+                               SAVE_STACK(context_stack);
                        }

                        if (call_user_function_ex(CG(function_table), NULL, 
orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC) == SUCCESS) {
@@ -1139,6 +1172,14 @@

                        if (in_compilation) {
                                CG(active_class_entry) = saved_class_entry;
+                               RESTORE_STACK(bp_stack);
+                               RESTORE_STACK(function_call_stack);
+                               RESTORE_STACK(switch_cond_stack);
+                               RESTORE_STACK(foreach_copy_stack);
+                               RESTORE_STACK(object_stack);
+                               RESTORE_STACK(declare_stack);
+                               RESTORE_STACK(list_stack);
+                               RESTORE_STACK(context_stack);
                        }

                        if (!EG(user_error_handler)) {

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

Reply via email to