mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-7.4'
* PHP-7.4: Introduce extra counter to avoid RTD key collisions
This commit is contained in:
commit
a40a69fdd0
4 changed files with 37 additions and 33 deletions
|
@ -524,6 +524,8 @@ static void zend_set_default_compile_time_values(void) /* {{{ */
|
||||||
/* default compile-time values */
|
/* default compile-time values */
|
||||||
CG(short_tags) = short_tags_default;
|
CG(short_tags) = short_tags_default;
|
||||||
CG(compiler_options) = compiler_options_default;
|
CG(compiler_options) = compiler_options_default;
|
||||||
|
|
||||||
|
CG(rtd_key_counter) = 0;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
|
@ -132,16 +132,11 @@ static void zend_destroy_property_info_internal(zval *zv) /* {{{ */
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static zend_string *zend_build_runtime_definition_key(zend_string *name, unsigned char *lex_pos) /* {{{ */
|
static zend_string *zend_build_runtime_definition_key(zend_string *name, uint32_t start_lineno) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_string *result;
|
|
||||||
char char_pos_buf[32];
|
|
||||||
size_t char_pos_len = sprintf(char_pos_buf, "%p", lex_pos);
|
|
||||||
zend_string *filename = CG(active_op_array)->filename;
|
zend_string *filename = CG(active_op_array)->filename;
|
||||||
|
zend_string *result = zend_strpprintf(0, "%c%s%s:%" PRIu32 "$%" PRIx32,
|
||||||
/* NULL, name length, filename length, last accepting char position length */
|
'\0', ZSTR_VAL(name), ZSTR_VAL(filename), start_lineno, CG(rtd_key_counter)++);
|
||||||
result = zend_string_alloc(1 + ZSTR_LEN(name) + ZSTR_LEN(filename) + char_pos_len, 0);
|
|
||||||
sprintf(ZSTR_VAL(result), "%c%s%s%s", '\0', ZSTR_VAL(name), ZSTR_VAL(filename), char_pos_buf);
|
|
||||||
return zend_new_interned_string(result);
|
return zend_new_interned_string(result);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
@ -6124,8 +6119,11 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
key = zend_build_runtime_definition_key(lcname, decl->lex_pos);
|
key = zend_build_runtime_definition_key(lcname, decl->start_lineno);
|
||||||
zend_hash_update_ptr(CG(function_table), key, op_array);
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
if (op_array->fn_flags & ZEND_ACC_CLOSURE) {
|
if (op_array->fn_flags & ZEND_ACC_CLOSURE) {
|
||||||
opline = zend_emit_op_tmp(result, ZEND_DECLARE_LAMBDA_FUNCTION, NULL, NULL);
|
opline = zend_emit_op_tmp(result, ZEND_DECLARE_LAMBDA_FUNCTION, NULL, NULL);
|
||||||
|
@ -6529,16 +6527,11 @@ void zend_compile_implements(zend_ast *ast) /* {{{ */
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
static zend_string *zend_generate_anon_class_name(unsigned char *lex_pos) /* {{{ */
|
static zend_string *zend_generate_anon_class_name(uint32_t start_lineno) /* {{{ */
|
||||||
{
|
{
|
||||||
zend_string *result;
|
|
||||||
char char_pos_buf[32];
|
|
||||||
size_t char_pos_len = sprintf(char_pos_buf, "%p", lex_pos);
|
|
||||||
zend_string *filename = CG(active_op_array)->filename;
|
zend_string *filename = CG(active_op_array)->filename;
|
||||||
|
zend_string *result = zend_strpprintf(0, "class@anonymous%c%s:%" PRIu32 "$%" PRIx32,
|
||||||
/* NULL, name length, filename length, last accepting char position length */
|
'\0', ZSTR_VAL(filename), start_lineno, CG(rtd_key_counter)++);
|
||||||
result = zend_string_alloc(sizeof("class@anonymous") + ZSTR_LEN(filename) + char_pos_len, 0);
|
|
||||||
sprintf(ZSTR_VAL(result), "class@anonymous%c%s%s", '\0', ZSTR_VAL(filename), char_pos_buf);
|
|
||||||
return zend_new_interned_string(result);
|
return zend_new_interned_string(result);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
@ -6578,7 +6571,7 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
|
||||||
|
|
||||||
zend_register_seen_symbol(lcname, ZEND_SYMBOL_CLASS);
|
zend_register_seen_symbol(lcname, ZEND_SYMBOL_CLASS);
|
||||||
} else {
|
} else {
|
||||||
name = zend_generate_anon_class_name(decl->lex_pos);
|
name = zend_generate_anon_class_name(decl->start_lineno);
|
||||||
lcname = zend_string_tolower(name);
|
lcname = zend_string_tolower(name);
|
||||||
}
|
}
|
||||||
lcname = zend_new_interned_string(lcname);
|
lcname = zend_new_interned_string(lcname);
|
||||||
|
@ -6728,20 +6721,19 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
|
||||||
opline->extended_value = zend_alloc_cache_slot();
|
opline->extended_value = zend_alloc_cache_slot();
|
||||||
opline->result_type = IS_VAR;
|
opline->result_type = IS_VAR;
|
||||||
opline->result.var = get_temporary_variable();
|
opline->result.var = get_temporary_variable();
|
||||||
|
|
||||||
if (!zend_hash_add_ptr(CG(class_table), lcname, ce)) {
|
if (!zend_hash_add_ptr(CG(class_table), lcname, ce)) {
|
||||||
/* this anonymous class has been included */
|
zend_error_noreturn(E_ERROR,
|
||||||
zval zv;
|
"Runtime definition key collision for %s. This is a bug", ZSTR_VAL(name));
|
||||||
ZVAL_PTR(&zv, ce);
|
|
||||||
destroy_zend_class(&zv);
|
|
||||||
return opline;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
zend_string *key = zend_build_runtime_definition_key(lcname, decl->lex_pos);
|
zend_string *key = zend_build_runtime_definition_key(lcname, decl->start_lineno);
|
||||||
|
|
||||||
/* RTD key is placed after lcname literal in op1 */
|
/* RTD key is placed after lcname literal in op1 */
|
||||||
zend_add_literal_string(&key);
|
zend_add_literal_string(&key);
|
||||||
zend_hash_update_ptr(CG(class_table), key, ce);
|
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;
|
opline->opcode = ZEND_DECLARE_CLASS;
|
||||||
if (extends_ast && toplevel
|
if (extends_ast && toplevel
|
||||||
|
|
|
@ -127,6 +127,8 @@ struct _zend_compiler_globals {
|
||||||
|
|
||||||
HashTable *delayed_variance_obligations;
|
HashTable *delayed_variance_obligations;
|
||||||
HashTable *delayed_autoloads;
|
HashTable *delayed_autoloads;
|
||||||
|
|
||||||
|
uint32_t rtd_key_counter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -439,8 +439,16 @@ static void zend_accel_function_hash_copy(HashTable *target, HashTable *source)
|
||||||
t = zend_hash_find_ex(target, p->key, 1);
|
t = zend_hash_find_ex(target, p->key, 1);
|
||||||
if (UNEXPECTED(t != NULL)) {
|
if (UNEXPECTED(t != NULL)) {
|
||||||
if (EXPECTED(ZSTR_LEN(p->key) > 0) && EXPECTED(ZSTR_VAL(p->key)[0] == 0)) {
|
if (EXPECTED(ZSTR_LEN(p->key) > 0) && EXPECTED(ZSTR_VAL(p->key)[0] == 0)) {
|
||||||
/* Mangled key */
|
/* Runtime definition key. There are two circumstances under which the key can
|
||||||
t = zend_hash_update(target, p->key, &p->val);
|
* already be defined:
|
||||||
|
* 1. The file has been re-included without being changed in the meantime. In
|
||||||
|
* this case we can keep the old value, because we know that the definition
|
||||||
|
* hasn't changed.
|
||||||
|
* 2. The file has been changed in the meantime, but the RTD key ends up colliding.
|
||||||
|
* This would be a bug.
|
||||||
|
* As we can't distinguish these cases, we assume that it is 1. and keep the old
|
||||||
|
* value. */
|
||||||
|
continue;
|
||||||
} else {
|
} else {
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
@ -483,8 +491,8 @@ static void zend_accel_function_hash_copy_from_shm(HashTable *target, HashTable
|
||||||
t = zend_hash_find_ex(target, p->key, 1);
|
t = zend_hash_find_ex(target, p->key, 1);
|
||||||
if (UNEXPECTED(t != NULL)) {
|
if (UNEXPECTED(t != NULL)) {
|
||||||
if (EXPECTED(ZSTR_LEN(p->key) > 0) && EXPECTED(ZSTR_VAL(p->key)[0] == 0)) {
|
if (EXPECTED(ZSTR_LEN(p->key) > 0) && EXPECTED(ZSTR_VAL(p->key)[0] == 0)) {
|
||||||
/* Mangled key */
|
/* See comment in zend_accel_function_hash_copy(). */
|
||||||
zend_hash_update_ptr(target, p->key, Z_PTR(p->val));
|
continue;
|
||||||
} else {
|
} else {
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
|
@ -526,7 +534,7 @@ static void zend_accel_class_hash_copy(HashTable *target, HashTable *source)
|
||||||
t = zend_hash_find_ex(target, p->key, 1);
|
t = zend_hash_find_ex(target, p->key, 1);
|
||||||
if (UNEXPECTED(t != NULL)) {
|
if (UNEXPECTED(t != NULL)) {
|
||||||
if (EXPECTED(ZSTR_LEN(p->key) > 0) && EXPECTED(ZSTR_VAL(p->key)[0] == 0)) {
|
if (EXPECTED(ZSTR_LEN(p->key) > 0) && EXPECTED(ZSTR_VAL(p->key)[0] == 0)) {
|
||||||
/* Mangled key - ignore and wait for runtime */
|
/* See comment in zend_accel_function_hash_copy(). */
|
||||||
continue;
|
continue;
|
||||||
} else if (UNEXPECTED(!ZCG(accel_directives).ignore_dups)) {
|
} else if (UNEXPECTED(!ZCG(accel_directives).ignore_dups)) {
|
||||||
zend_class_entry *ce1 = Z_PTR(p->val);
|
zend_class_entry *ce1 = Z_PTR(p->val);
|
||||||
|
@ -563,7 +571,7 @@ static void zend_accel_class_hash_copy_from_shm(HashTable *target, HashTable *so
|
||||||
t = zend_hash_find_ex(target, p->key, 1);
|
t = zend_hash_find_ex(target, p->key, 1);
|
||||||
if (UNEXPECTED(t != NULL)) {
|
if (UNEXPECTED(t != NULL)) {
|
||||||
if (EXPECTED(ZSTR_LEN(p->key) > 0) && EXPECTED(ZSTR_VAL(p->key)[0] == 0)) {
|
if (EXPECTED(ZSTR_LEN(p->key) > 0) && EXPECTED(ZSTR_VAL(p->key)[0] == 0)) {
|
||||||
/* Mangled key - ignore and wait for runtime */
|
/* See comment in zend_accel_function_hash_copy(). */
|
||||||
continue;
|
continue;
|
||||||
} else if (UNEXPECTED(!ZCG(accel_directives).ignore_dups)) {
|
} else if (UNEXPECTED(!ZCG(accel_directives).ignore_dups)) {
|
||||||
zend_class_entry *ce1 = Z_PTR(p->val);
|
zend_class_entry *ce1 = Z_PTR(p->val);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue