]> granicus.if.org Git - php/commitdiff
Fixed bug #63219 (Segfault when aliasing trait method when autoloader throws excpetion)
authorXinchen Hui <laruence@php.net>
Mon, 8 Oct 2012 14:59:52 +0000 (22:59 +0800)
committerXinchen Hui <laruence@php.net>
Mon, 8 Oct 2012 14:59:52 +0000 (22:59 +0800)
NEWS
Zend/tests/bug63219.phpt [new file with mode: 0644]
Zend/zend_compile.c

diff --git a/NEWS b/NEWS
index 1924864f5becc0a2a33bd4e3c908ca57a4d3b68f..fcd3bdd529b16bb1b97606565c4bbddfe979845b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ PHP                                                                        NEWS
     (Lars)
 
 - Core:
+  . Fixed bug #63219 (Segfault when aliasing trait method when autoloader
+    throws excpetion). (Laruence)
   . Added optional second argument for assert() to specify custom message. Patch
     by Lonny Kapelushnik (lonny@lonnylot.com). (Lars)
   . Support building PHP with the native client toolchain. (Stuart Langley)
diff --git a/Zend/tests/bug63219.phpt b/Zend/tests/bug63219.phpt
new file mode 100644 (file)
index 0000000..999be4a
--- /dev/null
@@ -0,0 +1,18 @@
+--TEST--
+Bug #63219 (Segfault when aliasing trait method when autoloader throws excpetion)
+--FILE--
+<?php
+trait TFoo {
+    public function fooMethod(){}
+}
+
+class C {
+    use TFoo {
+        Typo::fooMethod as tf;
+    }
+}
+
+echo "okey";
+?>
+--EXPECTF--
+Fatal error: Could not find trait Typo in %sbug63219.php on line %d
index c39d8eaa1e3502cdff474f5440a37c395e9ae406..303eedb6bc10f04b69b5e2180c5a38750313aa34 100644 (file)
@@ -3975,8 +3975,10 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /*
                        /** Resolve classes for all precedence operations. */
                        if (cur_precedence->exclude_from_classes) {
                                cur_method_ref = cur_precedence->trait_method;
-                               cur_precedence->trait_method->ce = zend_fetch_class(cur_method_ref->class_name,
-                                                                                                                                       cur_method_ref->cname_len, ZEND_FETCH_CLASS_TRAIT TSRMLS_CC);
+                               if (!(cur_precedence->trait_method->ce = zend_fetch_class(cur_method_ref->class_name, cur_method_ref->cname_len,
+                                                               ZEND_FETCH_CLASS_TRAIT|ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) {
+                                       zend_error(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name);
+                               }
 
                                /** Ensure that the prefered method is actually available. */
                                lcname = zend_str_tolower_dup(cur_method_ref->method_name,
@@ -4003,7 +4005,9 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /*
                                        char* class_name = (char*)cur_precedence->exclude_from_classes[j];
                                        zend_uint name_length = strlen(class_name);
 
-                                       cur_precedence->exclude_from_classes[j] = zend_fetch_class(class_name, name_length, ZEND_FETCH_CLASS_TRAIT TSRMLS_CC);
+                                       if (!(cur_precedence->exclude_from_classes[j] = zend_fetch_class(class_name, name_length, ZEND_FETCH_CLASS_TRAIT |ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) {
+                                               zend_error(E_COMPILE_ERROR, "Could not find trait %s", class_name);
+                                       }
                                        
                                        /* make sure that the trait method is not from a class mentioned in
                                         exclude_from_classes, for consistency */
@@ -4030,7 +4034,9 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /*
                        /** For all aliases with an explicit class name, resolve the class now. */
                        if (ce->trait_aliases[i]->trait_method->class_name) {
                                cur_method_ref = ce->trait_aliases[i]->trait_method;
-                               cur_method_ref->ce = zend_fetch_class(cur_method_ref->class_name, cur_method_ref->cname_len, ZEND_FETCH_CLASS_TRAIT TSRMLS_CC);
+                               if (!(cur_method_ref->ce = zend_fetch_class(cur_method_ref->class_name, cur_method_ref->cname_len, ZEND_FETCH_CLASS_TRAIT|ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) {
+                                       zend_error(E_COMPILE_ERROR, "Could not find trait %s", cur_method_ref->class_name);
+                               }
 
                                /** And, ensure that the referenced method is resolvable, too. */
                                lcname = zend_str_tolower_dup(cur_method_ref->method_name,