Skip to content

Commit c2068e9

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: Fix bug #79603, by retrying on RTD key collision
2 parents 0a74da3 + 4f47ba9 commit c2068e9

File tree

1 file changed

+22
-12
lines changed

1 file changed

+22
-12
lines changed

Zend/zend_compile.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6212,11 +6212,12 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as
62126212
return;
62136213
}
62146214

6215-
key = zend_build_runtime_definition_key(lcname, decl->start_lineno);
6216-
if (!zend_hash_add_ptr(CG(function_table), key, op_array)) {
6217-
zend_error_noreturn(E_ERROR,
6218-
"Runtime definition key collision for function %s. This is a bug", ZSTR_VAL(name));
6219-
}
6215+
/* Generate RTD keys until we find one that isn't in use yet. */
6216+
key = NULL;
6217+
do {
6218+
zend_tmp_string_release(key);
6219+
key = zend_build_runtime_definition_key(lcname, decl->start_lineno);
6220+
} while (!zend_hash_add_ptr(CG(function_table), key, op_array));
62206221

62216222
if (op_array->fn_flags & ZEND_ACC_CLOSURE) {
62226223
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) /
66626663

66636664
zend_register_seen_symbol(lcname, ZEND_SYMBOL_CLASS);
66646665
} else {
6665-
name = zend_generate_anon_class_name(decl);
6666-
lcname = zend_string_tolower(name);
6666+
/* Find an anon class name that is not in use yet. */
6667+
name = NULL;
6668+
lcname = NULL;
6669+
do {
6670+
zend_tmp_string_release(name);
6671+
zend_tmp_string_release(lcname);
6672+
name = zend_generate_anon_class_name(decl);
6673+
lcname = zend_string_tolower(name);
6674+
} while (zend_hash_exists(CG(class_table), lcname));
66676675
}
66686676
lcname = zend_new_interned_string(lcname);
66696677

@@ -6795,18 +6803,20 @@ void zend_compile_class_decl(znode *result, zend_ast *ast, zend_bool toplevel) /
67956803
opline->extended_value = zend_alloc_cache_slot();
67966804
zend_make_var_result(result, opline);
67976805
if (!zend_hash_add_ptr(CG(class_table), lcname, ce)) {
6806+
/* We checked above that the class name is not used. This really shouldn't happen. */
67986807
zend_error_noreturn(E_ERROR,
67996808
"Runtime definition key collision for %s. This is a bug", ZSTR_VAL(name));
68006809
}
68016810
} else {
6802-
zend_string *key = zend_build_runtime_definition_key(lcname, decl->start_lineno);
6811+
/* Generate RTD keys until we find one that isn't in use yet. */
6812+
zend_string *key = NULL;
6813+
do {
6814+
zend_tmp_string_release(key);
6815+
key = zend_build_runtime_definition_key(lcname, decl->start_lineno);
6816+
} while (!zend_hash_add_ptr(CG(class_table), key, ce));
68036817

68046818
/* RTD key is placed after lcname literal in op1 */
68056819
zend_add_literal_string(&key);
6806-
if (!zend_hash_add_ptr(CG(class_table), key, ce)) {
6807-
zend_error_noreturn(E_ERROR,
6808-
"Runtime definition key collision for class %s. This is a bug", ZSTR_VAL(name));
6809-
}
68106820

68116821
opline->opcode = ZEND_DECLARE_CLASS;
68126822
if (extends_ast && toplevel

0 commit comments

Comments
 (0)