From d558365fd390c3c0df0bf22f26e58b1c4cbc4326 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Sun, 10 Aug 2025 00:24:33 +0100 Subject: [PATCH] ext/standard: Deprecate passing string which are not one byte long to ord() RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_passing_string_which_are_not_one_byte_long_to_ord --- Zend/tests/constants/class_constants_005.phpt | 2 +- Zend/tests/nullsafe_operator/013.phpt | 2 ++ Zend/zend_compile.c | 16 ++++++++++------ ext/standard/string.c | 9 +++++++++ .../get_html_translation_table_basic6.phpt | 2 +- ext/standard/tests/strings/ord_basic.phpt | 2 -- ext/standard/tests/strings/ord_not_1_byte.phpt | 15 +++++++++++++++ 7 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 ext/standard/tests/strings/ord_not_1_byte.phpt diff --git a/Zend/tests/constants/class_constants_005.phpt b/Zend/tests/constants/class_constants_005.phpt index de53c2c0caa54..7accce13f208b 100644 --- a/Zend/tests/constants/class_constants_005.phpt +++ b/Zend/tests/constants/class_constants_005.phpt @@ -4,7 +4,7 @@ String interning during constants substitution opcache.enable_cli=0 --FILE-- diff --git a/Zend/tests/nullsafe_operator/013.phpt b/Zend/tests/nullsafe_operator/013.phpt index 883f6ac24aa8d..abc850a15a055 100644 --- a/Zend/tests/nullsafe_operator/013.phpt +++ b/Zend/tests/nullsafe_operator/013.phpt @@ -53,6 +53,8 @@ Deprecated: chr(): Passing null to parameter #1 ($codepoint) of type int is depr string(1) "%s" Deprecated: ord(): Passing null to parameter #1 ($character) of type string is deprecated in %s on line %d + +Deprecated: ord(): Providing an empty string is deprecated in %s on line %d int(0) string(98) "call_user_func_array(): Argument #1 ($callback) must be a valid callback, no array or string given" string(77) "call_user_func_array(): Argument #2 ($args) must be of type array, null given" diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 205023fa69b64..44fdaf63d8f81 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4167,14 +4167,18 @@ static zend_result zend_compile_func_chr(znode *result, const zend_ast_list *arg } /* }}} */ -static zend_result zend_compile_func_ord(znode *result, zend_ast_list *args) /* {{{ */ +static zend_result zend_compile_func_ord(znode *result, const zend_ast_list *args) /* {{{ */ { - if (args->children == 1 && - args->child[0]->kind == ZEND_AST_ZVAL && - Z_TYPE_P(zend_ast_get_zval(args->child[0])) == IS_STRING) { - + zval *str; + if ( + args->children == 1 + && args->child[0]->kind == ZEND_AST_ZVAL + && (str = zend_ast_get_zval(args->child[0])) + && Z_TYPE_P(str) == IS_STRING + && Z_STRLEN_P(str) == 1 + ) { result->op_type = IS_CONST; - ZVAL_LONG(&result->u.constant, (unsigned char)Z_STRVAL_P(zend_ast_get_zval(args->child[0]))[0]); + ZVAL_LONG(&result->u.constant, (unsigned char)Z_STRVAL_P(str)[0]); return SUCCESS; } else { return FAILURE; diff --git a/ext/standard/string.c b/ext/standard/string.c index a5acb28ddb3bc..0c163ce445e97 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -2651,6 +2651,15 @@ PHP_FUNCTION(ord) Z_PARAM_STR(str) ZEND_PARSE_PARAMETERS_END(); + if (UNEXPECTED(ZSTR_LEN(str) != 1)) { + if (ZSTR_LEN(str) == 0) { + php_error_docref(NULL, E_DEPRECATED, + "Providing an empty string is deprecated"); + } else { + php_error_docref(NULL, E_DEPRECATED, + "Providing a string which is not one byte long is deprecated, use ord($str[0]) instead"); + } + } RETURN_LONG((unsigned char) ZSTR_VAL(str)[0]); } /* }}} */ diff --git a/ext/standard/tests/strings/get_html_translation_table_basic6.phpt b/ext/standard/tests/strings/get_html_translation_table_basic6.phpt index 1715b0852bfac..f4fadf7134c30 100644 --- a/ext/standard/tests/strings/get_html_translation_table_basic6.phpt +++ b/ext/standard/tests/strings/get_html_translation_table_basic6.phpt @@ -3,7 +3,7 @@ Test get_html_translation_table() function : basic functionality - HTML 5/Window --FILE-- +--EXPECTF-- +Deprecated: ord(): Providing an empty string is deprecated in %s on line 3 +int(0) + +Deprecated: ord(): Providing a string which is not one byte long is deprecated, use ord($str[0]) instead in %s on line 4 +int(72)