]> granicus.if.org Git - php/commitdiff
Fixed Bug #61052 (Missing error check in trait 'insteadof' clause)
authorStefan Marr <gron@php.net>
Sun, 4 Mar 2012 19:34:19 +0000 (19:34 +0000)
committerStefan Marr <gron@php.net>
Sun, 4 Mar 2012 19:34:19 +0000 (19:34 +0000)
Zend/tests/traits/bug61052.phpt [new file with mode: 0644]
Zend/zend_compile.c

diff --git a/Zend/tests/traits/bug61052.phpt b/Zend/tests/traits/bug61052.phpt
new file mode 100644 (file)
index 0000000..421e907
--- /dev/null
@@ -0,0 +1,18 @@
+--TEST--
+Bug #61052 (missing error check in trait 'insteadof' clause)
+--FILE--
+<?php
+trait T1 {
+  function foo(){ echo "T1\n"; }
+}
+trait T2 {
+  function foo(){ echo "T2\n"; }
+}
+class C {
+  use T1, T2 {
+    T1::foo insteadof T1;
+  }
+}
+C::foo();
+--EXPECTF--
+Fatal error: Inconsistent insteadof definition. The method foo is to be used from T1, but T1 is also on the exclude list in %s on line %d
index 88c5020a29f866b4aaa036af91f7c622e73a4858..c3c35eb5fc6a0e9d0e5943d0e38708d4ad5f8fe6 100644 (file)
@@ -3984,13 +3984,28 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /*
                        
                                /** With the other traits, we are more permissive.
                                        We do not give errors for those. This allows to be more
-                                       defensive in such definitions. */
+                                       defensive in such definitions.
+                                       However, we want to make sure that the insteadof declartion
+                                       is consistent in itself.
+                                */
                                j = 0;
                                while (cur_precedence->exclude_from_classes[j]) {
                                        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);
+                                       
+                                       /* make sure that the trait method is not from a class mentioned in
+                                        exclude_from_classes, for consistency */
+                                       if (cur_precedence->trait_method->ce == cur_precedence->exclude_from_classes[i]) {
+                                               zend_error(E_COMPILE_ERROR,
+                                                                  "Inconsistent insteadof definition. " 
+                                                                  "The method %s is to be used from %s, but %s is also on the exclude list",
+                                                                  cur_method_ref->method_name,
+                                                                  cur_precedence->trait_method->ce->name,
+                                                                  cur_precedence->trait_method->ce->name);
+                                       }
+                                       
                                        efree(class_name);
                                        j++;
                                }