summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rwxr-xr-xZend/tests/bug35634.phpt36
-rw-r--r--Zend/zend.c19
3 files changed, 56 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 5c37fde9cc..3d493125ca 100644
--- a/NEWS
+++ b/NEWS
@@ -33,6 +33,8 @@ PHP NEWS
not found"). (Ilia)
- Fixed bug #36214 (__get method works properly only when conditional operator
is used). (Dmitry)
+- Fixed bug #35634 (Erroneous "Class declarations may not be nested" error
+ raised). (Carl P. Corliss, Dmitry)
- Fixed bug #35106 (nested foreach fails when array variable has a reference).
(Dmitry)
diff --git a/Zend/tests/bug35634.phpt b/Zend/tests/bug35634.phpt
new file mode 100755
index 0000000000..9681b6ad40
--- /dev/null
+++ b/Zend/tests/bug35634.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Bug #35634 (Erroneous "Class declarations may not be nested" error raised)
+--INI--
+error_reporting=0
+--FILE--
+<?php
+if (defined("pass3")) {
+
+ class ErrorClass {
+ }
+
+} else if (defined("pass2")) {
+
+ class TestClass {
+ function __construct() {
+ }
+ function TestClass() {
+ $this->__construct();
+ }
+ }
+
+} else {
+
+ function errorHandler($errorNumber, $errorMessage, $fileName, $lineNumber) {
+ define("pass3", 1);
+ include(__FILE__);
+ die("Error: $errorMessage ($fileName:$lineNumber)\n");
+ }
+
+ set_error_handler('errorHandler');
+ define("pass2", 1);
+ include(__FILE__);
+}
+?>
+--EXPECTF--
+Error: Redefining already defined constructor for class TestClass (%sbug35634.php:12)
diff --git a/Zend/zend.c b/Zend/zend.c
index 988779f5e0..7f75803544 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -900,6 +900,8 @@ ZEND_API void zend_error(int type, const char *format, ...)
char *error_filename;
uint error_lineno;
zval *orig_user_error_handler;
+ zend_bool in_compilation;
+ zend_class_entry *saved_class_entry;
TSRMLS_FETCH();
/* Obtain relevant filename and lineno */
@@ -1007,7 +1009,18 @@ ZEND_API void zend_error(int type, const char *format, ...)
orig_user_error_handler = EG(user_error_handler);
EG(user_error_handler) = NULL;
-
+
+ /* User error handler may include() additinal PHP files.
+ * If an error was generated during comilation PHP will compile
+ * such scripts recursivly, but some CG() variables may be
+ * inconsistent. */
+
+ in_compilation = zend_is_compiling(TSRMLS_C);
+ if (in_compilation) {
+ saved_class_entry = CG(active_class_entry);
+ CG(active_class_entry) = NULL;
+ }
+
if (call_user_function_ex(CG(function_table), NULL, orig_user_error_handler, &retval, 5, params, 1, NULL TSRMLS_CC)==SUCCESS) {
if (retval) {
if (Z_TYPE_P(retval) == IS_BOOL && Z_LVAL_P(retval) == 0) {
@@ -1020,6 +1033,10 @@ ZEND_API void zend_error(int type, const char *format, ...)
zend_error_cb(type, error_filename, error_lineno, format, args);
}
+ if (in_compilation) {
+ CG(active_class_entry) = saved_class_entry;
+ }
+
if (!EG(user_error_handler)) {
EG(user_error_handler) = orig_user_error_handler;
}