Skip to content

Commit 4f47ba9

Browse files
committed
Fix bug #79603, by retrying on RTD key collision
This is a non-intrusive fix for 7.4, still trying to find a good solution for master. Closes GH-5597.
1 parent db0cdcb commit 4f47ba9

File tree

2 files changed

+23
-12
lines changed

2 files changed

+23
-12
lines changed

NEWS

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ PHP NEWS
1616
. Fixed bug #79588 (Boolean opcache settings ignore on/off values). (cmb)
1717
. Fixed bug #79548 (Preloading segfault with inherited method using static
1818
variable). (Nikita)
19+
. Fixed bug #79603 (RTD collision with opcache). (Nikita)
1920

2021
- SimpleXML:
2122
. Fixed bug #79528 (Different object of the same xml between 7.4.5 and

Zend/zend_compile.c

+22-12
Original file line numberDiff line numberDiff line change
@@ -5934,11 +5934,12 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as
59345934
return;
59355935
}
59365936

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

59435944
if (op_array->fn_flags & ZEND_ACC_CLOSURE) {
59445945
opline = zend_emit_op_tmp(result, ZEND_DECLARE_LAMBDA_FUNCTION, NULL, NULL);
@@ -6404,8 +6405,15 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
64046405

64056406
zend_register_seen_symbol(lcname, ZEND_SYMBOL_CLASS);
64066407
} else {
6407-
name = zend_generate_anon_class_name(decl->start_lineno);
6408-
lcname = zend_string_tolower(name);
6408+
/* Find an anon class name that is not in use yet. */
6409+
name = NULL;
6410+
lcname = NULL;
6411+
do {
6412+
zend_tmp_string_release(name);
6413+
zend_tmp_string_release(lcname);
6414+
name = zend_generate_anon_class_name(decl->start_lineno);
6415+
lcname = zend_string_tolower(name);
6416+
} while (zend_hash_exists(CG(class_table), lcname));
64096417
}
64106418
lcname = zend_new_interned_string(lcname);
64116419

@@ -6562,18 +6570,20 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
65626570
opline->result_type = IS_VAR;
65636571
opline->result.var = get_temporary_variable();
65646572
if (!zend_hash_add_ptr(CG(class_table), lcname, ce)) {
6573+
/* We checked above that the class name is not used. This really shouldn't happen. */
65656574
zend_error_noreturn(E_ERROR,
65666575
"Runtime definition key collision for %s. This is a bug", ZSTR_VAL(name));
65676576
}
65686577
} else {
6569-
zend_string *key = zend_build_runtime_definition_key(lcname, decl->start_lineno);
6578+
/* Generate RTD keys until we find one that isn't in use yet. */
6579+
zend_string *key = NULL;
6580+
do {
6581+
zend_tmp_string_release(key);
6582+
key = zend_build_runtime_definition_key(lcname, decl->start_lineno);
6583+
} while (!zend_hash_add_ptr(CG(class_table), key, ce));
65706584

65716585
/* RTD key is placed after lcname literal in op1 */
65726586
zend_add_literal_string(&key);
6573-
if (!zend_hash_add_ptr(CG(class_table), key, ce)) {
6574-
zend_error_noreturn(E_ERROR,
6575-
"Runtime definition key collision for class %s. This is a bug", ZSTR_VAL(name));
6576-
}
65776587

65786588
opline->opcode = ZEND_DECLARE_CLASS;
65796589
if (extends_ast && toplevel

0 commit comments

Comments
 (0)