diff --git a/Zend/Optimizer/pass1.c b/Zend/Optimizer/pass1.c index 818829fcdf6ba..4c8a03b4a4085 100644 --- a/Zend/Optimizer/pass1.c +++ b/Zend/Optimizer/pass1.c @@ -164,7 +164,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) if (ce) { zend_class_constant *cc = zend_hash_find_ptr( &ce->constants_table, Z_STR(ZEND_OP2_LITERAL(opline))); - if (cc && (ZEND_CLASS_CONST_FLAGS(cc) & ZEND_ACC_PPP_MASK) == ZEND_ACC_PUBLIC && !(ce->ce_flags & ZEND_ACC_TRAIT)) { + if (cc && !(ZEND_CLASS_CONST_FLAGS(cc) & ZEND_ACC_DEPRECATED) && (ZEND_CLASS_CONST_FLAGS(cc) & ZEND_ACC_PPP_MASK) == ZEND_ACC_PUBLIC && !(ce->ce_flags & ZEND_ACC_TRAIT)) { zval *c = &cc->value; if (Z_TYPE_P(c) == IS_CONSTANT_AST) { zend_ast *ast = Z_ASTVAL_P(c); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 68cd9403f1efb..fca6493544d7e 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1728,7 +1728,9 @@ static bool zend_try_compile_const_expr_resolve_class_name(zval *zv, zend_ast *c /* We don't use zend_verify_const_access because we need to deal with unlinked classes. */ static bool zend_verify_ct_const_access(zend_class_constant *c, zend_class_entry *scope) { - if (c->ce->ce_flags & ZEND_ACC_TRAIT) { + if (ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED) { + return 0; + } else if (c->ce->ce_flags & ZEND_ACC_TRAIT) { /* This condition is only met on directly accessing trait constants, * because the ce is replaced to the class entry of the composing class * on binding. */ diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index edc9fc0b82d44..7c10a5395403a 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -347,6 +347,14 @@ ZEND_API zval *zend_get_class_constant_ex(zend_string *class_name, zend_string * goto failure; } + if (UNEXPECTED(ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED)) { + if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) { + zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(class_name), ZSTR_VAL(constant_name)); + if (EG(exception)) { + goto failure; + } + } + } ret_constant = &c->value; } } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index b7d98e55a001a..121e150295923 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -5983,6 +5983,17 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO HANDLE_EXCEPTION(); } + bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; + if (UNEXPECTED(is_constant_deprecated)) { + zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP2(); + HANDLE_EXCEPTION(); + } + } + value = &c->value; // Enums require loading of all class constants to build the backed enum table if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { @@ -5999,7 +6010,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO HANDLE_EXCEPTION(); } } - if (OP2_TYPE == IS_CONST) { + if (OP2_TYPE == IS_CONST && !is_constant_deprecated) { CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); } } else { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 56fdc55ea7404..8d4f51e987516 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -7261,6 +7261,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS HANDLE_EXCEPTION(); } + bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; + if (UNEXPECTED(is_constant_deprecated)) { + zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + HANDLE_EXCEPTION(); + } + } + value = &c->value; // Enums require loading of all class constants to build the backed enum table if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { @@ -7277,7 +7288,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS HANDLE_EXCEPTION(); } } - if (IS_CONST == IS_CONST) { + if (IS_CONST == IS_CONST && !is_constant_deprecated) { CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); } } else { @@ -8414,6 +8425,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS HANDLE_EXCEPTION(); } + bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; + if (UNEXPECTED(is_constant_deprecated)) { + zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + } + value = &c->value; // Enums require loading of all class constants to build the backed enum table if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { @@ -8430,7 +8452,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS HANDLE_EXCEPTION(); } } - if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && !is_constant_deprecated) { CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); } } else { @@ -25082,6 +25104,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ HANDLE_EXCEPTION(); } + bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; + if (UNEXPECTED(is_constant_deprecated)) { + zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + HANDLE_EXCEPTION(); + } + } + value = &c->value; // Enums require loading of all class constants to build the backed enum table if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { @@ -25098,7 +25131,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ HANDLE_EXCEPTION(); } } - if (IS_CONST == IS_CONST) { + if (IS_CONST == IS_CONST && !is_constant_deprecated) { CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); } } else { @@ -25644,6 +25677,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ HANDLE_EXCEPTION(); } + bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; + if (UNEXPECTED(is_constant_deprecated)) { + zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + } + value = &c->value; // Enums require loading of all class constants to build the backed enum table if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { @@ -25660,7 +25704,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ HANDLE_EXCEPTION(); } } - if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && !is_constant_deprecated) { CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); } } else { @@ -34228,6 +34272,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS HANDLE_EXCEPTION(); } + bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; + if (UNEXPECTED(is_constant_deprecated)) { + zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + HANDLE_EXCEPTION(); + } + } + value = &c->value; // Enums require loading of all class constants to build the backed enum table if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { @@ -34244,7 +34299,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS HANDLE_EXCEPTION(); } } - if (IS_CONST == IS_CONST) { + if (IS_CONST == IS_CONST && !is_constant_deprecated) { CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); } } else { @@ -34580,6 +34635,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS HANDLE_EXCEPTION(); } + bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; + if (UNEXPECTED(is_constant_deprecated)) { + zend_error(E_DEPRECATED, "Constant %s::%s is deprecated", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + } + value = &c->value; // Enums require loading of all class constants to build the backed enum table if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { @@ -34596,7 +34662,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS HANDLE_EXCEPTION(); } } - if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && !is_constant_deprecated) { CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); } } else { diff --git a/ext/intl/formatter/formatter.stub.php b/ext/intl/formatter/formatter.stub.php index da6a6e3c5a6c2..84ae31b518380 100644 --- a/ext/intl/formatter/formatter.stub.php +++ b/ext/intl/formatter/formatter.stub.php @@ -392,6 +392,7 @@ class NumberFormatter public const TYPE_DOUBLE = UNKNOWN; /** * @var int + * @deprecated * @cvalue FORMAT_TYPE_CURRENCY */ public const TYPE_CURRENCY = UNKNOWN; diff --git a/ext/intl/formatter/formatter_arginfo.h b/ext/intl/formatter/formatter_arginfo.h index 3488b025c725c..27851b180514f 100644 --- a/ext/intl/formatter/formatter_arginfo.h +++ b/ext/intl/formatter/formatter_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: de64db0e66d2113dd10c556cd61324a7a7952973 */ + * Stub hash: 3b050eaf6f2f54e3726b04a17d40b06ad610a724 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_NumberFormatter___construct, 0, 0, 2) ZEND_ARG_TYPE_INFO(0, locale, IS_STRING, 0) @@ -571,7 +571,7 @@ static zend_class_entry *register_class_NumberFormatter(void) zval const_TYPE_CURRENCY_value; ZVAL_LONG(&const_TYPE_CURRENCY_value, FORMAT_TYPE_CURRENCY); zend_string *const_TYPE_CURRENCY_name = zend_string_init_interned("TYPE_CURRENCY", sizeof("TYPE_CURRENCY") - 1, 1); - zend_declare_class_constant_ex(class_entry, const_TYPE_CURRENCY_name, &const_TYPE_CURRENCY_value, ZEND_ACC_PUBLIC, NULL); + zend_declare_class_constant_ex(class_entry, const_TYPE_CURRENCY_name, &const_TYPE_CURRENCY_value, ZEND_ACC_PUBLIC|ZEND_ACC_DEPRECATED, NULL); zend_string_release(const_TYPE_CURRENCY_name); return class_entry; diff --git a/ext/intl/tests/deprecated_number_formater_type_currency.phpt b/ext/intl/tests/deprecated_number_formater_type_currency.phpt new file mode 100644 index 0000000000000..bbc53cc291012 --- /dev/null +++ b/ext/intl/tests/deprecated_number_formater_type_currency.phpt @@ -0,0 +1,15 @@ +--TEST-- +NumberFormatter::TYPE_CURRENCY is deprecated +--EXTENSIONS-- +intl +--FILE-- + +--EXPECTF-- +Deprecated: Constant NumberFormatter::TYPE_CURRENCY is deprecated in %s on line %d +int(4) + +Deprecated: Constant NumberFormatter::TYPE_CURRENCY is deprecated in %s on line %d +int(4) diff --git a/ext/intl/tests/formatter_format_and_parse_errors.phpt b/ext/intl/tests/formatter_format_and_parse_errors.phpt index 5d46cafa36b81..e58455c5e4e98 100644 --- a/ext/intl/tests/formatter_format_and_parse_errors.phpt +++ b/ext/intl/tests/formatter_format_and_parse_errors.phpt @@ -54,12 +54,20 @@ try { } ?> ---EXPECT-- +--EXPECTF-- numfmt_format(): Argument #3 ($type) must be a NumberFormatter::TYPE_* constant NumberFormatter::format(): Argument #2 ($type) must be a NumberFormatter::TYPE_* constant numfmt_parse(): Argument #3 ($type) must be a NumberFormatter::TYPE_* constant NumberFormatter::parse(): Argument #2 ($type) must be a NumberFormatter::TYPE_* constant + +Deprecated: Constant NumberFormatter::TYPE_CURRENCY is deprecated in %s on line %d numfmt_format(): Argument #3 ($type) cannot be NumberFormatter::TYPE_CURRENCY constant, use numfmt_format_currency() function instead + +Deprecated: Constant NumberFormatter::TYPE_CURRENCY is deprecated in %s on line %d NumberFormatter::format(): Argument #2 ($type) cannot be NumberFormatter::TYPE_CURRENCY constant, use NumberFormatter::formatCurrency() method instead + +Deprecated: Constant NumberFormatter::TYPE_CURRENCY is deprecated in %s on line %d numfmt_parse(): Argument #3 ($type) cannot be NumberFormatter::TYPE_CURRENCY constant, use numfmt_parse_currency() function instead + +Deprecated: Constant NumberFormatter::TYPE_CURRENCY is deprecated in %s on line %d NumberFormatter::parse(): Argument #2 ($type) cannot be NumberFormatter::TYPE_CURRENCY constant, use NumberFormatter::parseCurrency() method instead diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index c49bdada4e308..13ad7952b9864 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2649,6 +2649,8 @@ PHP_FUNCTION(mb_strimwidth) } if (width < 0) { + php_error_docref(NULL, E_DEPRECATED, + "passing a negative integer to argument #3 ($width) is deprecated"); width += mb_get_strwidth(str, enc); if (from > 0) { diff --git a/ext/mbstring/tests/mb_strimwidth.phpt b/ext/mbstring/tests/mb_strimwidth.phpt index 6662c3c19261b..90c073b326252 100644 --- a/ext/mbstring/tests/mb_strimwidth.phpt +++ b/ext/mbstring/tests/mb_strimwidth.phpt @@ -71,7 +71,8 @@ testStrimwidth($utf16le, -3, 5, 'UTF-16LE'); // We'll count back 4 characters, then allow a width of ((4 * 2) - 2) = 6 // Since the output will not reach the END of the string, the trim marker // will have to be added, and will consume a width of 3 -testStrimwidth($utf16le, -4, -2, 'UTF-16LE'); +// We also suppress the deprecation for negative width as of PHP 8.3 +@testStrimwidth($utf16le, -4, -2, 'UTF-16LE'); echo "\n== EUC-JP ==\n"; @@ -103,11 +104,13 @@ testStrimwidth($euc_jp, 9, 5, 'EUC-JP'); // Skip 15 characters, which leaves a total width of 42. Then trim string down // to 5 less than that, which is a width of 37. -testStrimwidth($euc_jp, 15, -5, 'EUC-JP'); +// We also suppress the deprecation for negative width as of PHP 8.3 +@testStrimwidth($euc_jp, 15, -5, 'EUC-JP'); // Take the last 30 characters, which have a width of 54. Trim string down to // 25 less than that, which is 29. -testStrimwidth($euc_jp, -30, -25, 'EUC-JP'); +// We also suppress the deprecation for negative width as of PHP 8.3 +@testStrimwidth($euc_jp, -30, -25, 'EUC-JP'); // Skip over 39 characters... but since string is only 39 characters long, // it takes us to the end of the string, and output is empty @@ -115,10 +118,12 @@ testStrimwidth($euc_jp, 39, 10, 'EUC-JP'); // Take the last 10 characters, which have a width of 20. Trim string down to // 12 less than that, which is a width of 8. -testStrimwidth($euc_jp, -10, -12, 'EUC-JP'); +// We also suppress the deprecation for negative width as of PHP 8.3 +@testStrimwidth($euc_jp, -10, -12, 'EUC-JP'); try { - var_dump(mb_strimwidth($euc_jp, 0, -100,'...','EUC-JP')); + // We also suppress the deprecation for negative width as of PHP 8.3 + var_dump(@mb_strimwidth($euc_jp, 0, -100,'...','EUC-JP')); } catch (\ValueError $e) { echo $e->getMessage() . \PHP_EOL; } @@ -133,7 +138,8 @@ try { echo $e->getMessage() . \PHP_EOL; } try { - var_dump(mb_strimwidth($euc_jp, -10, -21,'...','EUC-JP')); + // We also suppress the deprecation for negative width as of PHP 8.3 + var_dump(@mb_strimwidth($euc_jp, -10, -21,'...','EUC-JP')); } catch (\ValueError $e) { echo $e->getMessage() . \PHP_EOL; } @@ -147,7 +153,8 @@ for ($from = -5; $from <= 5; $from++) { // This case is illegal and will throw an exception $pass = false; try { - mb_strimwidth($str, $from, $width, '...', 'ASCII'); + /* Shut up deprecation notice for now */ + @mb_strimwidth($str, $from, $width, '...', 'ASCII'); } catch (\ValueError $e) { $pass = true; } @@ -156,7 +163,8 @@ for ($from = -5; $from <= 5; $from++) { continue; } - $result = mb_strimwidth($str, $from, $width, '...', 'ASCII'); + /* Shut up deprecation notice for now */ + $result = @mb_strimwidth($str, $from, $width, '...', 'ASCII'); if ($from < 0 && $width < 0 && ($width - $from) <= 3) { if ($result !== '...') @@ -211,7 +219,8 @@ testStrimwidth("日本語abc", -3, 10, 'UTF-8'); // Regression test; old implementation did not handle positive 'from' argument // combined with negative 'width' argument correctly when portion being skipped // over included fullwidth characters -testStrimwidth("日本語abcdef", 3, -1, 'UTF-8'); +// We also suppress the deprecation for negative width as of PHP 8.3 +@testStrimwidth("日本語abcdef", 3, -1, 'UTF-8'); ?> --EXPECT-- diff --git a/ext/mbstring/tests/mb_strimwidth_deprecated.phpt b/ext/mbstring/tests/mb_strimwidth_deprecated.phpt new file mode 100644 index 0000000000000..3c952b7bf42e6 --- /dev/null +++ b/ext/mbstring/tests/mb_strimwidth_deprecated.phpt @@ -0,0 +1,11 @@ +--TEST-- +mb_strimwidth() is deprecated with negative width +--EXTENSIONS-- +mbstring +--FILE-- + +--EXPECTF-- +Deprecated: mb_strimwidth(): passing a negative integer to argument #3 ($width) is deprecated in %s on line %d +string(8) "ome s..."