]> granicus.if.org Git - php/commitdiff
Fixed bug #55339 (Segfault with allow_call_time_pass_reference = Off)
authorDmitry Stogov <dmitry@php.net>
Tue, 2 Aug 2011 07:38:23 +0000 (07:38 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 2 Aug 2011 07:38:23 +0000 (07:38 +0000)
Zend/zend.c

index 8fe185660fe5f07c77473dc70414a3cad184f3f4..738c1d179bc55ec0c0525fe8b88f7e8b37cd825a 100644 (file)
@@ -975,6 +975,23 @@ ZEND_API int zend_get_configuration_directive(const char *name, uint name_length
 }
 /* }}} */
 
+#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 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
        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 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
                        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 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
 
                        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)) {