]> granicus.if.org Git - php/commitdiff
Fix bug #72159
authorNikita Popov <nikic@php.net>
Wed, 4 May 2016 16:42:16 +0000 (18:42 +0200)
committerNikita Popov <nikic@php.net>
Wed, 4 May 2016 16:43:11 +0000 (18:43 +0200)
NEWS
Zend/tests/name_collision_07.phpt [new file with mode: 0644]
Zend/tests/name_collision_08.phpt [new file with mode: 0644]
Zend/tests/name_collision_09.phpt [new file with mode: 0644]
Zend/zend_compile.c

diff --git a/NEWS b/NEWS
index 2fd0bcede7a268c4a9180017723540cab2c135df..8da85888e29ae138d4388cb15a064f93cb318468 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ PHP                                                                        NEWS
   . Fixed bug #71737 (Memory leak in closure with parameter named $this).
     (Nikita)
   . Fixed bug #72059 (?? is not allowed on constant expressions). (Bob, Marcio)
+  . Fixed bug #72159 (Imported Class Overrides Local Class Name). (Nikita)
 
 - Curl:
   . Fixed bug #68658 (Define CURLE_SSL_CACERT_BADFILE). (Pierrick)
diff --git a/Zend/tests/name_collision_07.phpt b/Zend/tests/name_collision_07.phpt
new file mode 100644 (file)
index 0000000..bc596a3
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+Class declaration colliding with import (in namespace)
+--FILE--
+<?php
+
+namespace Foo {
+    class Bar {}
+}
+
+namespace Bazzle {
+    use Foo\Bar;
+    class Bar {}
+}
+--EXPECTF--
+Fatal error: Cannot declare class Bazzle\Bar because the name is already in use in %s on line %d
diff --git a/Zend/tests/name_collision_08.phpt b/Zend/tests/name_collision_08.phpt
new file mode 100644 (file)
index 0000000..d897419
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+Function declaration colliding with import (in namespace)
+--FILE--
+<?php
+
+namespace Foo {
+    function bar() {}
+}
+
+namespace Bazzle {
+    use function Foo\bar;
+    function bar() {}
+}
+--EXPECTF--
+Fatal error: Cannot declare function Bazzle\bar because the name is already in use in %s on line %d
diff --git a/Zend/tests/name_collision_09.phpt b/Zend/tests/name_collision_09.phpt
new file mode 100644 (file)
index 0000000..b46459e
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+Class declaration colliding with import (in namespace)
+--FILE--
+<?php
+
+namespace Foo {
+    const BAR = 42;
+}
+
+namespace Bazzle {
+    use const Foo\BAR;
+    const BAR = 24;
+}
+--EXPECTF--
+Fatal error: Cannot declare const Bazzle\BAR because the name is already in use in %s on line %d
index 6b78bd8bd5b3b3c95ff098e68b79014df2aa4bb2..593c19e01519d12f611d1fccd7b250e306f4568e 100644 (file)
@@ -4819,15 +4819,16 @@ void zend_begin_method_decl(zend_op_array *op_array, zend_string *name, zend_boo
 static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_ast_decl *decl) /* {{{ */
 {
        zend_ast *params_ast = decl->child[0];
-       zend_string *name = decl->name, *lcname;
+       zend_string *unqualified_name, *name, *lcname;
        zend_op *opline;
 
-       op_array->function_name = name = zend_prefix_with_ns(name);
-
+       unqualified_name = decl->name;
+       op_array->function_name = name = zend_prefix_with_ns(unqualified_name);
        lcname = zend_string_tolower(name);
 
        if (FC(imports_function)) {
-               zend_string *import_name = zend_hash_find_ptr(FC(imports_function), lcname);
+               zend_string *import_name = zend_hash_find_ptr_lc(
+                       FC(imports_function), ZSTR_VAL(unqualified_name), ZSTR_LEN(unqualified_name));
                if (import_name && !zend_string_equals_ci(lcname, import_name)) {
                        zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare function %s "
                                "because the name is already in use", ZSTR_VAL(name));
@@ -5210,7 +5211,7 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
        zend_ast *extends_ast = decl->child[0];
        zend_ast *implements_ast = decl->child[1];
        zend_ast *stmt_ast = decl->child[2];
-       zend_string *name, *lcname, *import_name = NULL;
+       zend_string *name, *lcname;
        zend_class_entry *ce = zend_arena_alloc(&CG(arena), sizeof(zend_class_entry));
        zend_op *opline;
        znode declare_node, extends_node;
@@ -5219,31 +5220,25 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */
        znode original_implementing_class = FC(implementing_class);
 
        if (EXPECTED((decl->flags & ZEND_ACC_ANON_CLASS) == 0)) {
+               zend_string *unqualified_name = decl->name;
+
                if (CG(active_class_entry)) {
                        zend_error_noreturn(E_COMPILE_ERROR, "Class declarations may not be nested");
                }
-               name = decl->name;
-               zend_assert_valid_class_name(name);
-               lcname = zend_string_tolower(name);
-               if (FC(current_namespace)) {
-                       name = zend_prefix_with_ns(name);
 
-                       zend_string_release(lcname);
-                       lcname = zend_string_tolower(name);
-               } else {
-                       zend_string_addref(name);
-               }
+               zend_assert_valid_class_name(unqualified_name);
+               name = zend_prefix_with_ns(unqualified_name);
+               name = zend_new_interned_string(name);
+               lcname = zend_string_tolower(name);
 
                if (FC(imports)) {
-                       import_name = zend_hash_find_ptr(FC(imports), lcname);
-               }
-
-               if (import_name && !zend_string_equals_ci(lcname, import_name)) {
-                       zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s "
-                                       "because the name is already in use", ZSTR_VAL(name));
+                       zend_string *import_name = zend_hash_find_ptr_lc(
+                               FC(imports), ZSTR_VAL(unqualified_name), ZSTR_LEN(unqualified_name));
+                       if (import_name && !zend_string_equals_ci(lcname, import_name)) {
+                               zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare class %s "
+                                               "because the name is already in use", ZSTR_VAL(name));
+                       }
                }
-
-               name = zend_new_interned_string(name);
        } else {
                name = zend_generate_anon_class_name(decl->lex_pos);
                lcname = zend_string_tolower(name);
@@ -5594,26 +5589,26 @@ void zend_compile_const_decl(zend_ast *ast) /* {{{ */
                zend_ast *const_ast = list->child[i];
                zend_ast *name_ast = const_ast->child[0];
                zend_ast *value_ast = const_ast->child[1];
-               zend_string *name = zend_ast_get_str(name_ast);
+               zend_string *unqualified_name = zend_ast_get_str(name_ast);
 
-               zend_string *import_name;
+               zend_string *name;
                znode name_node, value_node;
                zval *value_zv = &value_node.u.constant;
 
                value_node.op_type = IS_CONST;
                zend_const_expr_to_zval(value_zv, value_ast);
 
-               if (zend_lookup_reserved_const(ZSTR_VAL(name), ZSTR_LEN(name))) {
-                       zend_error_noreturn(E_COMPILE_ERROR, "Cannot redeclare constant '%s'", ZSTR_VAL(name));
+               if (zend_lookup_reserved_const(ZSTR_VAL(unqualified_name), ZSTR_LEN(unqualified_name))) {
+                       zend_error_noreturn(E_COMPILE_ERROR,
+                               "Cannot redeclare constant '%s'", ZSTR_VAL(unqualified_name));
                }
 
-               name = zend_prefix_with_ns(name);
+               name = zend_prefix_with_ns(unqualified_name);
                name = zend_new_interned_string(name);
 
-               if (FC(imports_const)
-                       && (import_name = zend_hash_find_ptr(FC(imports_const), name))
-               ) {
-                       if (!zend_string_equals(import_name, name)) {
+               if (FC(imports_const)) {
+                       zend_string *import_name = zend_hash_find_ptr(FC(imports_const), unqualified_name);
+                       if (import_name && !zend_string_equals(import_name, name)) {
                                zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare const %s because "
                                        "the name is already in use", ZSTR_VAL(name));
                        }