diff --git a/NEWS b/NEWS index 4e1196fb09466..b3995df9cbb2d 100644 --- a/NEWS +++ b/NEWS @@ -120,6 +120,8 @@ PHP NEWS - Standard: . Fixed bug GH-19926 (reset internal pointer earlier while splicing array while COW violation flag is still set). (alexandre-daubois) + . Added form feed (\f) in the default trimmed characters of trim(), rtrim() + and ltrim(). (Weilin Du) . Invalid mode values now throw in array_filter() instead of being silently defaulted to 0. (Jorg Sowa) . Fixed bug GH-21058 (error_log() crashes with message_type 3 and diff --git a/UPGRADING b/UPGRADING index 454a7b900f352..ef6c520c80050 100644 --- a/UPGRADING +++ b/UPGRADING @@ -47,6 +47,8 @@ PHP 8.6 UPGRADE NOTES - Standard: . Invalid mode values now throw in array_filter() instead of being silently defaulted to 0. + . Form feed (\f) is now added in the default trimmed characters of trim(), + rtrim() and ltrim(). RFC: https://wiki.php.net/rfc/trim_form_feed ======================================== 2. New Features diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 6fa0d47c7bd7f..6d0c565fc2d41 100644 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -2318,16 +2318,16 @@ function strcoll(string $string1, string $string2): int {} * @frameless-function {"arity": 1} * @frameless-function {"arity": 2} */ -function trim(string $string, string $characters = " \n\r\t\v\0"): string {} +function trim(string $string, string $characters = " \f\n\r\t\v\0"): string {} /** @compile-time-eval */ -function rtrim(string $string, string $characters = " \n\r\t\v\0"): string {} +function rtrim(string $string, string $characters = " \f\n\r\t\v\0"): string {} /** @alias rtrim */ -function chop(string $string, string $characters = " \n\r\t\v\0"): string {} +function chop(string $string, string $characters = " \f\n\r\t\v\0"): string {} /** @compile-time-eval */ -function ltrim(string $string, string $characters = " \n\r\t\v\0"): string {} +function ltrim(string $string, string $characters = " \f\n\r\t\v\0"): string {} /** * @compile-time-eval diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index e467710f72f91..d0109fa27c960 100644 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit basic_functions.stub.php instead. - * Stub hash: 8d1c2a735f412f8571675c6b025c3a418b68fb65 + * Stub hash: f5583557f058e4862750d1262296d7f59cb0eed0 * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) @@ -839,7 +839,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_trim, 0, 1, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, string, IS_STRING, 0) - ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, characters, IS_STRING, 0, "\" \\n\\r\\t\\v\\x00\"") + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, characters, IS_STRING, 0, "\" \\f\\n\\r\\t\\v\\x00\"") ZEND_END_ARG_INFO() #define arginfo_rtrim arginfo_trim diff --git a/ext/standard/basic_functions_decl.h b/ext/standard/basic_functions_decl.h index 9e6fb0def4472..139b47f2444d4 100644 --- a/ext/standard/basic_functions_decl.h +++ b/ext/standard/basic_functions_decl.h @@ -1,8 +1,8 @@ /* This is a generated file, edit basic_functions.stub.php instead. - * Stub hash: 8d1c2a735f412f8571675c6b025c3a418b68fb65 */ + * Stub hash: f5583557f058e4862750d1262296d7f59cb0eed0 */ -#ifndef ZEND_BASIC_FUNCTIONS_DECL_8d1c2a735f412f8571675c6b025c3a418b68fb65_H -#define ZEND_BASIC_FUNCTIONS_DECL_8d1c2a735f412f8571675c6b025c3a418b68fb65_H +#ifndef ZEND_BASIC_FUNCTIONS_DECL_f5583557f058e4862750d1262296d7f59cb0eed0_H +#define ZEND_BASIC_FUNCTIONS_DECL_f5583557f058e4862750d1262296d7f59cb0eed0_H typedef enum zend_enum_RoundingMode { ZEND_ENUM_RoundingMode_HalfAwayFromZero = 1, @@ -15,4 +15,4 @@ typedef enum zend_enum_RoundingMode { ZEND_ENUM_RoundingMode_PositiveInfinity = 8, } zend_enum_RoundingMode; -#endif /* ZEND_BASIC_FUNCTIONS_DECL_8d1c2a735f412f8571675c6b025c3a418b68fb65_H */ +#endif /* ZEND_BASIC_FUNCTIONS_DECL_f5583557f058e4862750d1262296d7f59cb0eed0_H */ diff --git a/ext/standard/string.c b/ext/standard/string.c index d146b4534e275..7d609a032dd17 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -515,11 +515,16 @@ static inline zend_result php_charmask(const unsigned char *input, size_t len, c } /* }}} */ +static zend_always_inline bool php_is_whitespace(unsigned char c) +{ + return c <= ' ' && (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == '\0'); +} + /* {{{ php_trim_int() * mode 1 : trim left * mode 2 : trim right * mode 3 : trim left and right - * what indicates which chars are to be trimmed. NULL->default (' \t\n\r\v\0') + * what indicates which chars are to be trimmed. NULL->default (' \f\t\n\r\v\0') */ static zend_always_inline zend_string *php_trim_int(zend_string *str, const char *what, size_t what_len, int mode) { @@ -573,10 +578,7 @@ static zend_always_inline zend_string *php_trim_int(zend_string *str, const char } else { if (mode & 1) { while (start != end) { - unsigned char c = (unsigned char)*start; - - if (c <= ' ' && - (c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == '\0')) { + if (php_is_whitespace((unsigned char)*start)) { start++; } else { break; @@ -585,10 +587,7 @@ static zend_always_inline zend_string *php_trim_int(zend_string *str, const char } if (mode & 2) { while (start != end) { - unsigned char c = (unsigned char)*(end-1); - - if (c <= ' ' && - (c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == '\v' || c == '\0')) { + if (php_is_whitespace((unsigned char)*(end-1))) { end--; } else { break; @@ -611,7 +610,7 @@ static zend_always_inline zend_string *php_trim_int(zend_string *str, const char * mode 1 : trim left * mode 2 : trim right * mode 3 : trim left and right - * what indicates which chars are to be trimmed. NULL->default (' \t\n\r\v\0') + * what indicates which chars are to be trimmed. NULL->default (' \f\t\n\r\v\0') */ PHPAPI zend_string *php_trim(zend_string *str, const char *what, size_t what_len, int mode) { diff --git a/ext/standard/tests/strings/trim.phpt b/ext/standard/tests/strings/trim.phpt index fd0c26d7794aa..9ce5e1dfff02b 100644 --- a/ext/standard/tests/strings/trim.phpt +++ b/ext/standard/tests/strings/trim.phpt @@ -18,6 +18,9 @@ var_dump("ABC" === trim("ABC\x50\xC1\x60\x90","\x50..\xC1")); var_dump("ABC\x50\xC1" === trim("ABC\x50\xC1\x60\x90","\x51..\xC0")); var_dump("ABC\x50" === trim("ABC\x50\xC1\x60\x90","\x51..\xC1")); var_dump("ABC" === trim("ABC\x50\xC1\x60\x90","\x50..\xC1")); +var_dump("ABC" === trim("\fABC\f")); +var_dump("ABC" === ltrim("\fABC")); +var_dump("ABC" === rtrim("ABC\f")); ?> --EXPECT-- @@ -36,3 +39,6 @@ bool(true) bool(true) bool(true) bool(true) +bool(true) +bool(true) +bool(true)