diff options
author | Nikita Popov <nikic@php.net> | 2016-10-08 16:56:17 +0200 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2016-10-08 17:00:27 +0200 |
commit | 2a75f5026a47099f585e29c5a9d8a2989dab42af (patch) | |
tree | bc19f0670ba87ca271f27cba1be2fb6d1a9d477a | |
parent | 159de7723edb9cfb597e743494aeb83b6584b5d4 (diff) | |
download | php-git-2a75f5026a47099f585e29c5a9d8a2989dab42af.tar.gz |
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.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | Zend/tests/use_function/no_conflict_with_classes.phpt | 15 | ||||
-rw-r--r-- | Zend/tests/use_no_file_conflict.phpt | 12 | ||||
-rw-r--r-- | Zend/tests/use_no_file_conflict_1.inc | 4 | ||||
-rw-r--r-- | Zend/tests/use_no_file_conflict_2.inc | 4 | ||||
-rw-r--r-- | Zend/zend_compile.c | 71 |
6 files changed, 75 insertions, 34 deletions
@@ -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 0000000000..bde94afb03 --- /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 0000000000..9423995af3 --- /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 0000000000..c2739ff64d --- /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 0000000000..badcc85bea --- /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 53cafcb56d..eb373906eb 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); |