From 9f4bd3040d2809f209d73f696b21302f311665b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Mon, 3 Jul 2023 15:16:10 +0200 Subject: [PATCH] Revert "Remove name field from the zend_constant struct (#10954)" This reverts commit f42992f580343931434dff2e4b2042ff945b48a1. Fix GH-11423 --- UPGRADING.INTERNALS | 4 --- Zend/zend_builtin_functions.c | 22 +++++++++----- Zend/zend_constants.c | 44 +++++++++++++++------------ Zend/zend_constants.h | 4 +-- Zend/zend_execute.c | 2 +- Zend/zend_execute_API.c | 3 ++ Zend/zend_vm_def.h | 3 +- Zend/zend_vm_execute.h | 3 +- ext/com_dotnet/com_typeinfo.c | 9 +++--- ext/opcache/ZendAccelerator.c | 3 ++ ext/opcache/jit/zend_jit_vm_helpers.c | 2 +- ext/reflection/php_reflection.c | 11 +++---- sapi/cli/php_cli.c | 9 ++++-- sapi/phpdbg/phpdbg.c | 21 ++++++------- sapi/phpdbg/phpdbg_info.c | 9 +++--- 15 files changed, 81 insertions(+), 68 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 84ef7ac8bc7..c2212f0dc1a 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -42,10 +42,6 @@ PHP 8.3 INTERNALS UPGRADE NOTES * The order of members of zend_op_array, zend_ssa_var, zend_ssa_var_info, zend_executor_globals and php_core_globals have changed to improve struct packing which reduces their size. -* The name field have been removed from the zend_constant struct. Now, - constant names are only stored as keys of the global constants table. - That's why the `zend_register_constant()` function now expects the - constant name as its first parameter. * Many calls to zend_assign_to_variable have been replaced with zend_assign_to_variable_ex which allows delaying the releasing of the old variable value. This avoids side-effects through destructors between the diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index acf69536d45..d388768035f 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -511,7 +511,8 @@ ZEND_FUNCTION(define) register_constant: /* non persistent */ ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); - if (zend_register_constant(name, &c) == SUCCESS) { + c.name = zend_string_copy(name); + if (zend_register_constant(&c) == SUCCESS) { RETURN_TRUE; } else { RETURN_FALSE; @@ -1479,7 +1480,6 @@ ZEND_FUNCTION(get_defined_constants) zend_constant *val; int module_number; zval *modules, const_val; - zend_string *const_name; char **module_names; zend_module_entry *module; int i = 1; @@ -1494,7 +1494,12 @@ ZEND_FUNCTION(get_defined_constants) } ZEND_HASH_FOREACH_END(); module_names[i] = "user"; - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(zend_constants), const_name, val) { + ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), val) { + if (!val->name) { + /* skip special constants */ + continue; + } + if (ZEND_CONSTANT_MODULE_NUMBER(val) == PHP_USER_CONSTANT) { module_number = i; } else if (ZEND_CONSTANT_MODULE_NUMBER(val) > i) { @@ -1510,19 +1515,22 @@ ZEND_FUNCTION(get_defined_constants) } ZVAL_COPY_OR_DUP(&const_val, &val->value); - zend_hash_add_new(Z_ARRVAL(modules[module_number]), const_name, &const_val); + zend_hash_add_new(Z_ARRVAL(modules[module_number]), val->name, &const_val); } ZEND_HASH_FOREACH_END(); efree(module_names); efree(modules); } else { zend_constant *constant; - zend_string *const_name; zval const_val; - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(zend_constants), const_name, constant) { + ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), constant) { + if (!constant->name) { + /* skip special constants */ + continue; + } ZVAL_COPY_OR_DUP(&const_val, &constant->value); - zend_hash_add_new(Z_ARRVAL_P(return_value), const_name, &const_val); + zend_hash_add_new(Z_ARRVAL_P(return_value), constant->name, &const_val); } ZEND_HASH_FOREACH_END(); } } diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index edc9fc0b82d..20220bb68b8 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -43,9 +43,15 @@ void free_zend_constant(zval *zv) if (!(ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT)) { zval_ptr_dtor_nogc(&c->value); + if (c->name) { + zend_string_release_ex(c->name, 0); + } efree(c); } else { zval_internal_ptr_dtor(&c->value); + if (c->name) { + zend_string_release_ex(c->name, 1); + } free(c); } } @@ -61,6 +67,7 @@ static void copy_zend_constant(zval *zv) memcpy(Z_PTR_P(zv), c, sizeof(zend_constant)); c = Z_PTR_P(zv); + c->name = zend_string_copy(c->name); if (Z_TYPE(c->value) == IS_STRING) { Z_STR(c->value) = zend_string_dup(Z_STR(c->value), 1); } @@ -122,7 +129,8 @@ ZEND_API void zend_register_null_constant(const char *name, size_t name_len, int ZVAL_NULL(&c.value); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); - zend_register_internal_constant(name, name_len, &c); + c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); + zend_register_constant(&c); } ZEND_API void zend_register_bool_constant(const char *name, size_t name_len, bool bval, int flags, int module_number) @@ -131,7 +139,8 @@ ZEND_API void zend_register_bool_constant(const char *name, size_t name_len, boo ZVAL_BOOL(&c.value, bval); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); - zend_register_internal_constant(name, name_len, &c); + c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); + zend_register_constant(&c); } ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zend_long lval, int flags, int module_number) @@ -140,7 +149,8 @@ ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zen ZVAL_LONG(&c.value, lval); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); - zend_register_internal_constant(name, name_len, &c); + c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); + zend_register_constant(&c); } @@ -150,7 +160,8 @@ ZEND_API void zend_register_double_constant(const char *name, size_t name_len, d ZVAL_DOUBLE(&c.value, dval); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); - zend_register_internal_constant(name, name_len, &c); + c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); + zend_register_constant(&c); } @@ -160,7 +171,8 @@ ZEND_API void zend_register_stringl_constant(const char *name, size_t name_len, ZVAL_STR(&c.value, zend_string_init_interned(strval, strlen, flags & CONST_PERSISTENT)); ZEND_CONSTANT_SET_FLAGS(&c, flags, module_number); - zend_register_internal_constant(name, name_len, &c); + c.name = zend_string_init_interned(name, name_len, flags & CONST_PERSISTENT); + zend_register_constant(&c); } @@ -533,9 +545,10 @@ static void* zend_hash_add_constant(HashTable *ht, zend_string *key, zend_consta return ret; } -ZEND_API zend_result zend_register_constant(zend_string *name, zend_constant *c) +ZEND_API zend_result zend_register_constant(zend_constant *c) { zend_string *lowercase_name = NULL; + zend_string *name; zend_result ret = SUCCESS; bool persistent = (ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT) != 0; @@ -543,12 +556,14 @@ ZEND_API zend_result zend_register_constant(zend_string *name, zend_constant *c) printf("Registering constant for module %d\n", c->module_number); #endif - const char *slash = strrchr(ZSTR_VAL(name), '\\'); + const char *slash = strrchr(ZSTR_VAL(c->name), '\\'); if (slash) { - lowercase_name = zend_string_init(ZSTR_VAL(name), ZSTR_LEN(name), persistent); - zend_str_tolower(ZSTR_VAL(lowercase_name), slash - ZSTR_VAL(name)); + lowercase_name = zend_string_init(ZSTR_VAL(c->name), ZSTR_LEN(c->name), persistent); + zend_str_tolower(ZSTR_VAL(lowercase_name), slash - ZSTR_VAL(c->name)); lowercase_name = zend_new_interned_string(lowercase_name); name = lowercase_name; + } else { + name = c->name; } /* Check if the user is trying to define any special constant */ @@ -557,6 +572,7 @@ ZEND_API zend_result zend_register_constant(zend_string *name, zend_constant *c) || zend_hash_add_constant(EG(zend_constants), name, c) == NULL ) { zend_error(E_WARNING, "Constant %s already defined", ZSTR_VAL(name)); + zend_string_release(c->name); if (!persistent) { zval_ptr_dtor_nogc(&c->value); } @@ -567,13 +583,3 @@ ZEND_API zend_result zend_register_constant(zend_string *name, zend_constant *c) } return ret; } - -ZEND_API zend_result zend_register_internal_constant(const char *name, size_t name_len, zend_constant *c) { - zend_string *name_str = zend_string_init_interned(name, name_len, ZEND_CONSTANT_FLAGS(c) & CONST_PERSISTENT); - - zend_result result = zend_register_constant(name_str, c); - - zend_string_release(name_str); - - return result; -} diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index d0ad242143f..736dbb00910 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -32,6 +32,7 @@ typedef struct _zend_constant { zval value; + zend_string *name; } zend_constant; #define ZEND_CONSTANT_FLAGS(c) \ @@ -83,8 +84,7 @@ ZEND_API void zend_register_long_constant(const char *name, size_t name_len, zen ZEND_API void zend_register_double_constant(const char *name, size_t name_len, double dval, int flags, int module_number); ZEND_API void zend_register_string_constant(const char *name, size_t name_len, const char *strval, int flags, int module_number); ZEND_API void zend_register_stringl_constant(const char *name, size_t name_len, const char *strval, size_t strlen, int flags, int module_number); -ZEND_API zend_result zend_register_internal_constant(const char *name, size_t name_len, zend_constant *c); -ZEND_API zend_result zend_register_constant(zend_string *name, zend_constant *c); +ZEND_API zend_result zend_register_constant(zend_constant *c); #ifdef ZTS void zend_copy_constants(HashTable *target, HashTable *source); #endif diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 29631504d5f..b017a3c7941 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -5008,7 +5008,7 @@ static zend_always_inline zend_result _zend_quick_get_constant( if (!check_defined_only) { ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); if (ZEND_CONSTANT_FLAGS(c) & CONST_DEPRECATED) { - zend_error(E_DEPRECATED, "Constant %s is deprecated", ZSTR_VAL(Z_STR_P(key))); + zend_error(E_DEPRECATED, "Constant %s is deprecated", ZSTR_VAL(c->name)); return SUCCESS; } } diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index dfb13005f64..eba8ab3df81 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -294,6 +294,9 @@ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown) break; } zval_ptr_dtor_nogc(&c->value); + if (c->name) { + zend_string_release_ex(c->name, 0); + } efree(c); zend_string_release_ex(key, 0); } ZEND_HASH_MAP_FOREACH_END_DEL(); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index b7d98e55a00..778f15435f7 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -8127,8 +8127,9 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST) } /* non persistent, case sensitive */ ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); + c.name = zend_string_copy(Z_STR_P(name)); - if (zend_register_constant(Z_STR_P(name), &c) == FAILURE) { + if (zend_register_constant(&c) == FAILURE) { } FREE_OP1(); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 56fdc55ea74..5b0aec530a7 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -7615,8 +7615,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST } /* non persistent, case sensitive */ ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); + c.name = zend_string_copy(Z_STR_P(name)); - if (zend_register_constant(Z_STR_P(name), &c) == FAILURE) { + if (zend_register_constant(&c) == FAILURE) { } diff --git a/ext/com_dotnet/com_typeinfo.c b/ext/com_dotnet/com_typeinfo.c index bebbe2e2ad0..ccdcc3ff7e8 100644 --- a/ext/com_dotnet/com_typeinfo.c +++ b/ext/com_dotnet/com_typeinfo.c @@ -197,7 +197,7 @@ PHP_COM_DOTNET_API zend_result php_com_import_typelib(ITypeLib *TL, int mode, in if (pTKind == TKIND_ENUM) { ITypeLib_GetTypeInfo(TL, i, &TypeInfo); for (j = 0; ; j++) { - zend_string *const_name, *name; + zend_string *const_name; if (FAILED(ITypeInfo_GetVarDesc(TypeInfo, j, &pVarDesc))) { break; @@ -228,13 +228,12 @@ PHP_COM_DOTNET_API zend_result php_com_import_typelib(ITypeLib *TL, int mode, in ZVAL_LONG(&c.value, Z_LVAL(value)); if (mode & CONST_PERSISTENT) { /* duplicate string in a persistent manner */ - name = zend_string_dup(const_name, /* persistent */ true); + c.name = zend_string_dup(const_name, /* persistent */ true); zend_string_release_ex(const_name, /* persistent */ false); } else { - name = const_name; + c.name = const_name; } - zend_register_constant(name, &c); - zend_string_release(name); + zend_register_constant(&c); } ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc); } diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index a4113f954ef..51bdc0d9d88 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -735,6 +735,9 @@ static void accel_copy_permanent_strings(zend_new_interned_string_func_t new_int p->key = new_interned_string(p->key); } c = (zend_constant*)Z_PTR(p->val); + if (c->name) { + c->name = new_interned_string(c->name); + } if (Z_TYPE(c->value) == IS_STRING) { ZVAL_STR(&c->value, new_interned_string(Z_STR(c->value))); } diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index d78cde95e96..3bed3c36f96 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -282,7 +282,7 @@ static zend_always_inline zend_constant* _zend_quick_get_constant( if (!check_defined_only) { if (ZEND_CONSTANT_FLAGS(c) & CONST_DEPRECATED) { - zend_error(E_DEPRECATED, "Constant %s is deprecated", ZSTR_VAL(Z_STR_P(key))); + zend_error(E_DEPRECATED, "Constant %s is deprecated", ZSTR_VAL(c->name)); if (EG(exception)) { return NULL; } diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 7d24f5b4b22..ff7d50f01a8 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1045,13 +1045,11 @@ static void _extension_string(smart_str *str, zend_module_entry *module, char *i { smart_str str_constants = {0}; zend_constant *constant; - zend_string *name; int num_constants = 0; - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(zend_constants), name, constant) { - + ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), constant) { if (ZEND_CONSTANT_MODULE_NUMBER(constant) == module->module_number) { - _const_string(&str_constants, ZSTR_VAL(name), &constant->value, indent); + _const_string(&str_constants, ZSTR_VAL(constant->name), &constant->value, indent); num_constants++; } } ZEND_HASH_FOREACH_END(); @@ -6037,7 +6035,6 @@ ZEND_METHOD(ReflectionExtension, getConstants) reflection_object *intern; zend_module_entry *module; zend_constant *constant; - zend_string *name; if (zend_parse_parameters_none() == FAILURE) { RETURN_THROWS(); @@ -6045,11 +6042,11 @@ ZEND_METHOD(ReflectionExtension, getConstants) GET_REFLECTION_OBJECT_PTR(module); array_init(return_value); - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(zend_constants), name, constant) { + ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), constant) { if (module->module_number == ZEND_CONSTANT_MODULE_NUMBER(constant)) { zval const_val; ZVAL_COPY_OR_DUP(&const_val, &constant->value); - zend_hash_update(Z_ARRVAL_P(return_value), name, &const_val); + zend_hash_update(Z_ARRVAL_P(return_value), constant->name, &const_val); } } ZEND_HASH_FOREACH_END(); } diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index c3598003058..be10b43a7f3 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -558,13 +558,16 @@ static void cli_register_file_handles(void) php_stream_to_zval(s_err, &ec.value); Z_CONSTANT_FLAGS(ic.value) = 0; - zend_register_internal_constant("STDIN", sizeof("STDIN")-1, &ic); + ic.name = zend_string_init_interned("STDIN", sizeof("STDIN")-1, 0); + zend_register_constant(&ic); Z_CONSTANT_FLAGS(oc.value) = 0; - zend_register_internal_constant("STDOUT", sizeof("STDOUT")-1, &oc); + oc.name = zend_string_init_interned("STDOUT", sizeof("STDOUT")-1, 0); + zend_register_constant(&oc); Z_CONSTANT_FLAGS(ec.value) = 0; - zend_register_internal_constant("STDERR", sizeof("STDERR")-1, &ec); + ec.name = zend_string_init_interned("STDERR", sizeof("STDERR")-1, 0); + zend_register_constant(&ec); } static const char *param_mode_conflict = "Either execute direct code, process stdin or use a file.\n"; diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 17b7513789e..a69ac171cfa 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -912,24 +912,21 @@ void phpdbg_register_file_handles(void) /* {{{ */ ic.value = zin; Z_CONSTANT_FLAGS(ic.value) = 0; - zend_string *stdin_name = zend_string_init(ZEND_STRL("STDIN"), 0); - zend_hash_del(EG(zend_constants), stdin_name); - zend_register_constant(stdin_name, &ic); - zend_string_release(stdin_name); + ic.name = zend_string_init(ZEND_STRL("STDIN"), 0); + zend_hash_del(EG(zend_constants), ic.name); + zend_register_constant(&ic); oc.value = zout; Z_CONSTANT_FLAGS(oc.value) = 0; - zend_string *stdout_name = zend_string_init(ZEND_STRL("STDOUT"), 0); - zend_hash_del(EG(zend_constants), stdout_name); - zend_register_constant(stdout_name, &oc); - zend_string_release(stdout_name); + oc.name = zend_string_init(ZEND_STRL("STDOUT"), 0); + zend_hash_del(EG(zend_constants), oc.name); + zend_register_constant(&oc); ec.value = zerr; Z_CONSTANT_FLAGS(ec.value) = 0; - zend_string *stderr_name = zend_string_init(ZEND_STRL("STDERR"), 0); - zend_hash_del(EG(zend_constants), stderr_name); - zend_register_constant(stderr_name, &ec); - zend_string_release(stderr_name); + ec.name = zend_string_init(ZEND_STRL("STDERR"), 0); + zend_hash_del(EG(zend_constants), ec.name); + zend_register_constant(&ec); } /* }}} */ diff --git a/sapi/phpdbg/phpdbg_info.c b/sapi/phpdbg/phpdbg_info.c index d6457ef805c..0a1e7570a49 100644 --- a/sapi/phpdbg/phpdbg_info.c +++ b/sapi/phpdbg/phpdbg_info.c @@ -100,15 +100,14 @@ PHPDBG_INFO(constants) /* {{{ */ { HashTable consts; zend_constant *data; - zend_string *name; zend_hash_init(&consts, 8, NULL, NULL, 0); if (EG(zend_constants)) { phpdbg_try_access { - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(EG(zend_constants), name, data) { + ZEND_HASH_MAP_FOREACH_PTR(EG(zend_constants), data) { if (ZEND_CONSTANT_MODULE_NUMBER(data) == PHP_USER_CONSTANT) { - zend_hash_update_ptr(&consts, name, data); + zend_hash_update_ptr(&consts, data->name, data); } } ZEND_HASH_FOREACH_END(); } phpdbg_catch_access { @@ -120,14 +119,14 @@ PHPDBG_INFO(constants) /* {{{ */ if (zend_hash_num_elements(&consts)) { phpdbg_out("Address Refs Type Constant\n"); - ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(&consts, name, data) { + ZEND_HASH_MAP_FOREACH_PTR(&consts, data) { #define VARIABLEINFO(msg, ...) \ phpdbg_writeln( \ "%-18p %-7d %-9s %.*s" msg, &data->value, \ Z_REFCOUNTED(data->value) ? Z_REFCOUNT(data->value) : 1, \ zend_get_type_by_const(Z_TYPE(data->value)), \ - (int) ZSTR_LEN(name), ZSTR_VAL(name), ##__VA_ARGS__) + (int) ZSTR_LEN(data->name), ZSTR_VAL(data->name), ##__VA_ARGS__) switch (Z_TYPE(data->value)) { case IS_STRING: