diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-08-12 16:58:52 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-08-12 17:12:28 +0200 |
commit | f3fdf570b3cd3df14af3d698950d341623a97088 (patch) | |
tree | e119dd0998f13fdaa6e8adca2928416cda3cf8b4 | |
parent | 9b43e29d9b55eafb4e063a0b2d817356f5b908b5 (diff) | |
download | php-git-f3fdf570b3cd3df14af3d698950d341623a97088.tar.gz |
Intern alias old_name early
This is likely going to end up interned lateron at some point
when the new_name is referenced somewhere. However, it may be
that there are some uses that do not get interned before that.
In this case we will intern a string that already have zval
users, without updating the refcounted flag on those zvals.
In particular this can happen with something like [Foo::class],
where Foo is an imported symbol. The string it resolves to won't
get interned right away, but may be interned later.
use Foo as Bar;
$x = [Bar::class];
var_dump(Bar::X);
debug_zval_dump($x); // Will show negative refcount
class Foo {
const X = 1;
}
However, this doesn't really fix the root cause, there are probably
other situations where something similar can occur.
-rw-r--r-- | Zend/zend_compile.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index a91dfeeecf..f25ce2f55d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6619,6 +6619,7 @@ void zend_compile_use(zend_ast *ast) /* {{{ */ } zend_string_addref(old_name); + old_name = zend_new_interned_string(old_name); if (!zend_hash_add_ptr(current_import, lookup_name, old_name)) { zend_error_noreturn(E_COMPILE_ERROR, "Cannot use%s %s as %s because the name " "is already in use", zend_get_use_type_str(type), ZSTR_VAL(old_name), ZSTR_VAL(new_name)); |