summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2016-05-04 18:42:16 +0200
committerNikita Popov <nikic@php.net>2016-05-04 18:43:11 +0200
commit9af0c96af4ded5ac0935e6cc1a2fa253ce77dfac (patch)
tree739b3d05f0298996893fb7f024baaa27dc1ce4c1
parent44372d69532a9951cd87695d48c6e7a2a01f7acc (diff)
downloadphp-git-9af0c96af4ded5ac0935e6cc1a2fa253ce77dfac.tar.gz
Fix bug #72159
-rw-r--r--NEWS1
-rw-r--r--Zend/tests/name_collision_07.phpt15
-rw-r--r--Zend/tests/name_collision_08.phpt15
-rw-r--r--Zend/tests/name_collision_09.phpt15
-rw-r--r--Zend/zend_compile.c59
5 files changed, 73 insertions, 32 deletions
diff --git a/NEWS b/NEWS
index 2fd0bcede7..8da85888e2 100644
--- 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
index 0000000000..bc596a3549
--- /dev/null
+++ b/Zend/tests/name_collision_07.phpt
@@ -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
index 0000000000..d897419102
--- /dev/null
+++ b/Zend/tests/name_collision_08.phpt
@@ -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
index 0000000000..b46459eef6
--- /dev/null
+++ b/Zend/tests/name_collision_09.phpt
@@ -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
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 6b78bd8bd5..593c19e015 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -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));
}