gron                                     Fri, 18 Nov 2011 13:49:07 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=319483

Log:
Fixes Bug #54441 (Handling of changing modifiers on a trait alias)
# this now results also in a compilation error, since it would open the door 
for inconsistencies, and violates the DRY principle.

Bug: https://bugs.php.net/54441 (Assigned) Traits - Visibility on alias names
      
Changed paths:
    A   php/php-src/branches/PHP_5_4/Zend/tests/traits/bug54441.phpt
    U   php/php-src/branches/PHP_5_4/Zend/zend_compile.c
    A   php/php-src/trunk/Zend/tests/traits/bug54441.phpt
    U   php/php-src/trunk/Zend/zend_compile.c

Added: php/php-src/branches/PHP_5_4/Zend/tests/traits/bug54441.phpt
===================================================================
--- php/php-src/branches/PHP_5_4/Zend/tests/traits/bug54441.phpt                
                (rev 0)
+++ php/php-src/branches/PHP_5_4/Zend/tests/traits/bug54441.phpt        
2011-11-18 13:49:07 UTC (rev 319483)
@@ -0,0 +1,19 @@
+--TEST--
+Bug #54441 (Changing trait static method visibility)
+--FILE--
+<?php
+
+trait Foo {
+  public function bar() {}
+}
+
+class Boo {
+  use Foo {
+    bar as dontKnow;
+    dontKnow as protected;
+  }
+}
+
+?>
+--EXPECTF--
+Fatal error: The modifiers for the trait alias dontKnow() need to be changed 
in the same statment in which the alias is defined. Error in %s on line %d

Modified: php/php-src/branches/PHP_5_4/Zend/zend_compile.c
===================================================================
--- php/php-src/branches/PHP_5_4/Zend/zend_compile.c    2011-11-18 13:46:39 UTC 
(rev 319482)
+++ php/php-src/branches/PHP_5_4/Zend/zend_compile.c    2011-11-18 13:49:07 UTC 
(rev 319483)
@@ -4320,16 +4320,49 @@
 static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry 
*ce TSRMLS_DC) /* {{{ */
 {
        int i = 0;
+       zend_trait_alias* cur_alias;
+       char* lc_method_name;

        if (ce->trait_aliases) {
                while (ce->trait_aliases[i]) {
+                       cur_alias = ce->trait_aliases[i];
                        /** The trait for this alias has not been resolved, 
this means, this
                                alias was not applied. Abort with an error. */
-                       if (!ce->trait_aliases[i]->trait_method->ce) {
-                               zend_error(E_COMPILE_ERROR,
-                                                  "An alias (%s) was defined 
for method %s(), but this method does not exist",
-                                                  ce->trait_aliases[i]->alias,
-                                                  
ce->trait_aliases[i]->trait_method->method_name);
+                       if (!cur_alias->trait_method->ce) {
+                               if (cur_alias->alias) {
+                                       /** Plain old inconsistency/typo/bug */
+                                       zend_error(E_COMPILE_ERROR,
+                                                          "An alias (%s) was 
defined for method %s(), but this method does not exist",
+                                                          cur_alias->alias,
+                                                          
cur_alias->trait_method->method_name);
+                               }
+                               else {
+                                       /** Here are two possible cases:
+                                               1) this is an attempt to 
modifiy the visibility
+                                                  of a method introduce as 
part of another alias.
+                                                  Since that seems to violate 
the DRY principle,
+                                                  we check against it and 
abort.
+                                               2) it is just a plain old 
inconsitency/typo/bug
+                                                  as in the case where alias 
is set. */
+
+                                       lc_method_name = 
zend_str_tolower_dup(cur_alias->trait_method->method_name,
+                                                                               
                                  cur_alias->trait_method->mname_len);
+                                       if 
(zend_hash_exists(&ce->function_table,
+                                                                               
 lc_method_name,
+                                                                               
 cur_alias->trait_method->mname_len+1)) {
+                                               efree(lc_method_name);
+                                               zend_error(E_COMPILE_ERROR,
+                                                                  "The 
modifiers for the trait alias %s() need to be changed in the same statment in 
which the alias is defined. Error",
+                                                                  
cur_alias->trait_method->method_name);
+                                       }
+                                       else {
+                                               efree(lc_method_name);
+                                               zend_error(E_COMPILE_ERROR,
+                                                                  "The 
modifiers of the trait method %s() are changed, but this method does not exist. 
Error",
+                                                                  
cur_alias->trait_method->method_name);
+
+                                       }
+                               }
                        }
                        i++;
                }

Added: php/php-src/trunk/Zend/tests/traits/bug54441.phpt
===================================================================
--- php/php-src/trunk/Zend/tests/traits/bug54441.phpt                           
(rev 0)
+++ php/php-src/trunk/Zend/tests/traits/bug54441.phpt   2011-11-18 13:49:07 UTC 
(rev 319483)
@@ -0,0 +1,19 @@
+--TEST--
+Bug #54441 (Changing trait static method visibility)
+--FILE--
+<?php
+
+trait Foo {
+  public function bar() {}
+}
+
+class Boo {
+  use Foo {
+    bar as dontKnow;
+    dontKnow as protected;
+  }
+}
+
+?>
+--EXPECTF--
+Fatal error: The modifiers for the trait alias dontKnow() need to be changed 
in the same statment in which the alias is defined. Error in %s on line %d

Modified: php/php-src/trunk/Zend/zend_compile.c
===================================================================
--- php/php-src/trunk/Zend/zend_compile.c       2011-11-18 13:46:39 UTC (rev 
319482)
+++ php/php-src/trunk/Zend/zend_compile.c       2011-11-18 13:49:07 UTC (rev 
319483)
@@ -4320,16 +4320,49 @@
 static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry 
*ce TSRMLS_DC) /* {{{ */
 {
        int i = 0;
+       zend_trait_alias* cur_alias;
+       char* lc_method_name;

        if (ce->trait_aliases) {
                while (ce->trait_aliases[i]) {
+                       cur_alias = ce->trait_aliases[i];
                        /** The trait for this alias has not been resolved, 
this means, this
                                alias was not applied. Abort with an error. */
-                       if (!ce->trait_aliases[i]->trait_method->ce) {
-                               zend_error(E_COMPILE_ERROR,
-                                                  "An alias (%s) was defined 
for method %s(), but this method does not exist",
-                                                  ce->trait_aliases[i]->alias,
-                                                  
ce->trait_aliases[i]->trait_method->method_name);
+                       if (!cur_alias->trait_method->ce) {
+                               if (cur_alias->alias) {
+                                       /** Plain old inconsistency/typo/bug */
+                                       zend_error(E_COMPILE_ERROR,
+                                                          "An alias (%s) was 
defined for method %s(), but this method does not exist",
+                                                          cur_alias->alias,
+                                                          
cur_alias->trait_method->method_name);
+                               }
+                               else {
+                                       /** Here are two possible cases:
+                                               1) this is an attempt to 
modifiy the visibility
+                                                  of a method introduce as 
part of another alias.
+                                                  Since that seems to violate 
the DRY principle,
+                                                  we check against it and 
abort.
+                                               2) it is just a plain old 
inconsitency/typo/bug
+                                                  as in the case where alias 
is set. */
+
+                                       lc_method_name = 
zend_str_tolower_dup(cur_alias->trait_method->method_name,
+                                                                               
                                  cur_alias->trait_method->mname_len);
+                                       if 
(zend_hash_exists(&ce->function_table,
+                                                                               
 lc_method_name,
+                                                                               
 cur_alias->trait_method->mname_len+1)) {
+                                               efree(lc_method_name);
+                                               zend_error(E_COMPILE_ERROR,
+                                                                  "The 
modifiers for the trait alias %s() need to be changed in the same statment in 
which the alias is defined. Error",
+                                                                  
cur_alias->trait_method->method_name);
+                                       }
+                                       else {
+                                               efree(lc_method_name);
+                                               zend_error(E_COMPILE_ERROR,
+                                                                  "The 
modifiers of the trait method %s() are changed, but this method does not exist. 
Error",
+                                                                  
cur_alias->trait_method->method_name);
+
+                                       }
+                               }
                        }
                        i++;
                }

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to