diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-05-20 11:24:37 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-05-20 11:24:37 +0200 |
commit | c2068e95b4be9a503070b5466b714f4836787ca3 (patch) | |
tree | ea5155389126a99446c46f59d9caedbd0b18d838 | |
parent | 0a74da385dd1cf25cf7870fdc82cbe1c7256fab3 (diff) | |
parent | 4f47ba99f002d50e11c111b8625d81f79b2bf52f (diff) | |
download | php-git-c2068e95b4be9a503070b5466b714f4836787ca3.tar.gz |
Merge branch 'PHP-7.4'
* PHP-7.4:
Fix bug #79603, by retrying on RTD key collision
-rw-r--r-- | Zend/zend_compile.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 58c74e1da0..9c6546ac41 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6212,11 +6212,12 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as return; } - key = zend_build_runtime_definition_key(lcname, decl->start_lineno); - if (!zend_hash_add_ptr(CG(function_table), key, op_array)) { - zend_error_noreturn(E_ERROR, - "Runtime definition key collision for function %s. This is a bug", ZSTR_VAL(name)); - } + /* Generate RTD keys until we find one that isn't in use yet. */ + key = NULL; + do { + zend_tmp_string_release(key); + key = zend_build_runtime_definition_key(lcname, decl->start_lineno); + } while (!zend_hash_add_ptr(CG(function_table), key, op_array)); if (op_array->fn_flags & ZEND_ACC_CLOSURE) { opline = zend_emit_op_tmp(result, ZEND_DECLARE_LAMBDA_FUNCTION, NULL, NULL); @@ -6662,8 +6663,15 @@ void zend_compile_class_decl(znode *result, zend_ast *ast, zend_bool toplevel) / zend_register_seen_symbol(lcname, ZEND_SYMBOL_CLASS); } else { - name = zend_generate_anon_class_name(decl); - lcname = zend_string_tolower(name); + /* Find an anon class name that is not in use yet. */ + name = NULL; + lcname = NULL; + do { + zend_tmp_string_release(name); + zend_tmp_string_release(lcname); + name = zend_generate_anon_class_name(decl); + lcname = zend_string_tolower(name); + } while (zend_hash_exists(CG(class_table), lcname)); } lcname = zend_new_interned_string(lcname); @@ -6795,18 +6803,20 @@ void zend_compile_class_decl(znode *result, zend_ast *ast, zend_bool toplevel) / opline->extended_value = zend_alloc_cache_slot(); zend_make_var_result(result, opline); if (!zend_hash_add_ptr(CG(class_table), lcname, ce)) { + /* We checked above that the class name is not used. This really shouldn't happen. */ zend_error_noreturn(E_ERROR, "Runtime definition key collision for %s. This is a bug", ZSTR_VAL(name)); } } else { - zend_string *key = zend_build_runtime_definition_key(lcname, decl->start_lineno); + /* Generate RTD keys until we find one that isn't in use yet. */ + zend_string *key = NULL; + do { + zend_tmp_string_release(key); + key = zend_build_runtime_definition_key(lcname, decl->start_lineno); + } while (!zend_hash_add_ptr(CG(class_table), key, ce)); /* RTD key is placed after lcname literal in op1 */ zend_add_literal_string(&key); - if (!zend_hash_add_ptr(CG(class_table), key, ce)) { - zend_error_noreturn(E_ERROR, - "Runtime definition key collision for class %s. This is a bug", ZSTR_VAL(name)); - } opline->opcode = ZEND_DECLARE_CLASS; if (extends_ast && toplevel |