com php-src: Fix bug #66773, #66862: NEWS Zend/tests/use_func tion/no_conflict_with_classes.phpt Zend/tests/use_n o_file_conflict.phpt
Zend/tests/use_no_file_confl ict_1.inc Zend/tests/use_no_file_conflict_2 .inc Zend/zend_compile.c
| From: | Nikita Popov | Date: | Sat, 08 Oct 2016 15:00:27 +0000 |
| Subject: | com php-src: Fix bug #66773, #66862: NEWS Zend/tests/use_func tion/no_conflict_with_classes.phpt Zend/tests/use_n o_file_conflict.phpt Zend/tests/use_no_file_confl ict_1.inc Zend/tests/use_no_file_conflict_2 .inc Zend/zend_compile.c |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-94869@lists.php.net to get a copy of this message | ||
Commit: 2a75f5026a47099f585e29c5a9d8a2989dab42af
Author: Nikita Popov <nikic@php.net> Sat, 8 Oct 2016 16:56:17 +0200
Parents: 159de7723edb9cfb597e743494aeb83b6584b5d4
Branches: PHP-7.0 PHP-7.1 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=2a75f5026a47099f585e29c5a9d8a2989dab42af
Log:
Fix bug #66773, #66862
This a partial backport of 8754b19. It
a) fixes the class/function/constant import table confusion in the
namespaced case, and
b) restricts conflict checks to a single file based on a filename
pointer comparison.
It does not fix the issues with filename reuse (e.g. due to eval)
and late-bound classes. This part of the change requires globals
changes.
Bugs:
https://bugs.php.net/66773
https://bugs.php.net/66862
Changed paths:
M NEWS
A Zend/tests/use_function/no_conflict_with_classes.phpt
A Zend/tests/use_no_file_conflict.phpt
A Zend/tests/use_no_file_conflict_1.inc
A Zend/tests/use_no_file_conflict_2.inc
M Zend/zend_compile.c
Diff:
diff --git a/NEWS b/NEWS
index 0b4cae7..8117d60 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,9 @@ PHP NEWS
- Core:
. Fixed bug #73181 (parse_str() without a second argument leads to crash).
(Nikita)
+ . Fixed bug #66773 (Autoload with Opcache allows importing conflicting class
+ name to namespace). (Nikita)
+ . Fixed bug #66862 ((Sub-)Namespaces unexpected behaviour). (Nikita)
- GD:
. Fixed bug #73213 (Integer overflow in imageline() with antialiasing). (cmb)
diff --git a/Zend/tests/use_function/no_conflict_with_classes.phpt
b/Zend/tests/use_function/no_conflict_with_classes.phpt
new file mode 100644
index 0000000..bde94af
--- /dev/null
+++ b/Zend/tests/use_function/no_conflict_with_classes.phpt
@@ -0,0 +1,15 @@
+--TEST--
+"use function" should not conflict with class names
+--FILE--
+<?php
+
+namespace Foo;
+
+class Bar {}
+
+use function bar;
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/Zend/tests/use_no_file_conflict.phpt b/Zend/tests/use_no_file_conflict.phpt
new file mode 100644
index 0000000..9423995
--- /dev/null
+++ b/Zend/tests/use_no_file_conflict.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Use conflicts should not occur across files
+--FILE--
+<?php
+
+require __DIR__ . '/use_no_file_conflict_1.inc';
+require __DIR__ . '/use_no_file_conflict_2.inc';
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/Zend/tests/use_no_file_conflict_1.inc b/Zend/tests/use_no_file_conflict_1.inc
new file mode 100644
index 0000000..c2739ff
--- /dev/null
+++ b/Zend/tests/use_no_file_conflict_1.inc
@@ -0,0 +1,4 @@
+<?php
+
+namespace Foo;
+class A {}
diff --git a/Zend/tests/use_no_file_conflict_2.inc b/Zend/tests/use_no_file_conflict_2.inc
new file mode 100644
index 0000000..badcc85
--- /dev/null
+++ b/Zend/tests/use_no_file_conflict_2.inc
@@ -0,0 +1,4 @@
+<?php
+
+namespace Foo;
+use A;
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 53cafcb..eb37390 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -5499,6 +5499,41 @@ static void zend_check_already_in_use(uint32_t type, zend_string *old_name,
zend
}
/* }}} */
+static void zend_check_use_conflict(
+ uint32_t type, zend_string *old_name, zend_string *new_name, zend_string *lookup_name) {
+ switch (type) {
+ case T_CLASS:
+ {
+ zend_class_entry *ce = zend_hash_find_ptr(CG(class_table), lookup_name);
+ if (ce && ce->type == ZEND_USER_CLASS
+ && ce->info.user.filename == CG(compiled_filename)
+ ) {
+ zend_check_already_in_use(type, old_name, new_name, lookup_name);
+ }
+ break;
+ }
+ case T_FUNCTION:
+ {
+ zend_function *fn = zend_hash_find_ptr(CG(function_table), lookup_name);
+ if (fn && fn->type == ZEND_USER_FUNCTION
+ && fn->op_array.filename == CG(compiled_filename)
+ ) {
+ zend_check_already_in_use(type, old_name, new_name, lookup_name);
+ }
+ break;
+ }
+ case T_CONST:
+ {
+ zend_string *filename = zend_hash_find_ptr(&CG(const_filenames), lookup_name);
+ if (filename && filename == CG(compiled_filename)) {
+ zend_check_already_in_use(type, old_name, new_name, lookup_name);
+ }
+ break;
+ }
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+}
+
void zend_compile_use(zend_ast *ast) /* {{{ */
{
zend_ast_list *list = zend_ast_get_list(ast);
@@ -5555,43 +5590,11 @@ void zend_compile_use(zend_ast *ast) /* {{{ */
ZSTR_VAL(ns_name)[ZSTR_LEN(current_ns)] = '\\';
memcpy(ZSTR_VAL(ns_name) + ZSTR_LEN(current_ns) + 1, ZSTR_VAL(lookup_name),
ZSTR_LEN(lookup_name));
- if (zend_hash_exists(CG(class_table), ns_name)) {
- zend_check_already_in_use(type, old_name, new_name, ns_name);
- }
+ zend_check_use_conflict(type, old_name, new_name, ns_name);
zend_string_free(ns_name);
} else {
- switch (type) {
- case T_CLASS:
- {
- zend_class_entry *ce = zend_hash_find_ptr(CG(class_table), lookup_name);
- if (ce && ce->type == ZEND_USER_CLASS
- && ce->info.user.filename == CG(compiled_filename)
- ) {
- zend_check_already_in_use(type, old_name, new_name, lookup_name);
- }
- break;
- }
- case T_FUNCTION:
- {
- zend_function *fn = zend_hash_find_ptr(CG(function_table), lookup_name);
- if (fn && fn->type == ZEND_USER_FUNCTION
- && fn->op_array.filename == CG(compiled_filename)
- ) {
- zend_check_already_in_use(type, old_name, new_name, lookup_name);
- }
- break;
- }
- case T_CONST:
- {
- zend_string *filename = zend_hash_find_ptr(&CG(const_filenames), lookup_name);
- if (filename && filename == CG(compiled_filename)) {
- zend_check_already_in_use(type, old_name, new_name, lookup_name);
- }
- break;
- }
- EMPTY_SWITCH_DEFAULT_CASE()
- }
+ zend_check_use_conflict(type, old_name, new_name, lookup_name);
}
zend_string_addref(old_name);