1 |
From 0ea2ef125b88fc996e2405221ea98112e3abdcd5 Mon Sep 17 00:00:00 2001 |
2 |
From: Dmitry Stogov <dmitry@php.net> |
3 |
Date: Tue, 2 Aug 2011 07:38:23 +0000 |
4 |
Subject: [PATCH] Fixed bug #55339 (Segfault with |
5 |
allow_call_time_pass_reference = Off) |
6 |
|
7 |
--- |
8 |
NEWS | 2 ++ |
9 |
Zend/tests/bug55339.phpt | 31 +++++++++++++++++++++++++++++++ |
10 |
Zend/zend.c | 41 +++++++++++++++++++++++++++++++++++++++++ |
11 |
3 files changed, 74 insertions(+) |
12 |
create mode 100644 Zend/tests/bug55339.phpt |
13 |
|
14 |
diff --git a/Zend/tests/bug55339.phpt b/Zend/tests/bug55339.phpt |
15 |
new file mode 100644 |
16 |
index 0000000..7d5ab4a |
17 |
--- /dev/null |
18 |
+++ b/Zend/tests/bug55339.phpt |
19 |
@@ -0,0 +1,31 @@ |
20 |
+--TEST-- |
21 |
+Bug #55339 (Segfault with allow_call_time_pass_reference = Off) |
22 |
+--INI-- |
23 |
+allow_call_time_pass_reference=off |
24 |
+--FILE-- |
25 |
+<?php |
26 |
+function error_handler($errno, $errstr, $errfile, $errline) { |
27 |
+ eval(';'); |
28 |
+} |
29 |
+ |
30 |
+set_error_handler('error_handler'); |
31 |
+ |
32 |
+eval(<<<'EOF' |
33 |
+function foo() |
34 |
+{ |
35 |
+ $array = array(); |
36 |
+ foreach ($array as $key => $value) { |
37 |
+ bar($key, &$value); |
38 |
+ } |
39 |
+} |
40 |
+ |
41 |
+function bar() |
42 |
+{ |
43 |
+ |
44 |
+} |
45 |
+EOF |
46 |
+); |
47 |
+ |
48 |
+echo "OK\n"; |
49 |
+--EXPECT-- |
50 |
+OK |
51 |
diff --git a/Zend/zend.c b/Zend/zend.c |
52 |
index 6861f61..bcfedeb 100644 |
53 |
--- a/Zend/zend.c |
54 |
+++ b/Zend/zend.c |
55 |
@@ -958,6 +958,23 @@ ZEND_API int zend_get_configuration_directive(const char *name, uint name_length |
56 |
} |
57 |
/* }}} */ |
58 |
|
59 |
+#define SAVE_STACK(stack) do { \ |
60 |
+ if (CG(stack).top) { \ |
61 |
+ memcpy(&stack, &CG(stack), sizeof(zend_stack)); \ |
62 |
+ CG(stack).top = CG(stack).max = 0; \ |
63 |
+ CG(stack).elements = NULL; \ |
64 |
+ } else { \ |
65 |
+ stack.top = 0; \ |
66 |
+ } \ |
67 |
+ } while (0) |
68 |
+ |
69 |
+#define RESTORE_STACK(stack) do { \ |
70 |
+ if (stack.top) { \ |
71 |
+ zend_stack_destroy(&CG(stack)); \ |
72 |
+ memcpy(&CG(stack), &stack, sizeof(zend_stack)); \ |
73 |
+ } \ |
74 |
+ } while (0) |
75 |
+ |
76 |
ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */ |
77 |
{ |
78 |
va_list args; |
79 |
@@ -970,6 +987,14 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */ |
80 |
zval *orig_user_error_handler; |
81 |
zend_bool in_compilation; |
82 |
zend_class_entry *saved_class_entry; |
83 |
+ zend_stack bp_stack; |
84 |
+ zend_stack function_call_stack; |
85 |
+ zend_stack switch_cond_stack; |
86 |
+ zend_stack foreach_copy_stack; |
87 |
+ zend_stack object_stack; |
88 |
+ zend_stack declare_stack; |
89 |
+ zend_stack list_stack; |
90 |
+ zend_stack labels_stack; |
91 |
TSRMLS_FETCH(); |
92 |
|
93 |
/* Obtain relevant filename and lineno */ |
94 |
@@ -1097,6 +1122,14 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */ |
95 |
if (in_compilation) { |
96 |
saved_class_entry = CG(active_class_entry); |
97 |
CG(active_class_entry) = NULL; |
98 |
+ SAVE_STACK(bp_stack); |
99 |
+ SAVE_STACK(function_call_stack); |
100 |
+ SAVE_STACK(switch_cond_stack); |
101 |
+ SAVE_STACK(foreach_copy_stack); |
102 |
+ SAVE_STACK(object_stack); |
103 |
+ SAVE_STACK(declare_stack); |
104 |
+ SAVE_STACK(list_stack); |
105 |
+ SAVE_STACK(labels_stack); |
106 |
} |
107 |
|
108 |
if (call_user_function_ex(CG(function_table), NULL, orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC) == SUCCESS) { |
109 |
@@ -1113,6 +1146,14 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */ |
110 |
|
111 |
if (in_compilation) { |
112 |
CG(active_class_entry) = saved_class_entry; |
113 |
+ RESTORE_STACK(bp_stack); |
114 |
+ RESTORE_STACK(function_call_stack); |
115 |
+ RESTORE_STACK(switch_cond_stack); |
116 |
+ RESTORE_STACK(foreach_copy_stack); |
117 |
+ RESTORE_STACK(object_stack); |
118 |
+ RESTORE_STACK(declare_stack); |
119 |
+ RESTORE_STACK(list_stack); |
120 |
+ RESTORE_STACK(labels_stack); |
121 |
} |
122 |
|
123 |
if (!EG(user_error_handler)) { |
124 |
-- |
125 |
1.7.11.5 |
126 |
|