From fca78f8111557b5e00e1814b44c89ba01cc5aeb7 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Tue, 17 Sep 2024 07:25:44 +0200 Subject: [PATCH] Bugfix: mbstring polyfills must not raise value errors in PHP 7 --- src/Mbstring/Mbstring.php | 60 +++++++++++++++++++++++---------- src/Mbstring/bootstrap.php | 12 +++---- src/Php83/Php83.php | 25 +++++++++----- src/Php83/bootstrap.php | 16 ++++----- src/Php83/bootstrap80.php | 19 +++++++++++ src/Php84/Php84.php | 41 ++++++++++++++++------ src/Php84/bootstrap.php | 14 +++++--- src/Php84/bootstrap80.php | 34 +++++++++++++++++++ tests/Mbstring/MbstringTest.php | 49 ++++++++++++++++++++++++++- tests/Php83/Php83Test.php | 25 +++++++++++++- tests/Php84/Php84Test.php | 24 +++++++++++++ 11 files changed, 262 insertions(+), 57 deletions(-) create mode 100644 src/Php83/bootstrap80.php create mode 100644 src/Php84/bootstrap80.php diff --git a/src/Mbstring/Mbstring.php b/src/Mbstring/Mbstring.php index 3d45c9d9a..c5c143c7b 100644 --- a/src/Mbstring/Mbstring.php +++ b/src/Mbstring/Mbstring.php @@ -834,19 +834,32 @@ public static function mb_ord($s, $encoding = null) return $code; } - public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null): string + /** @return string|false */ + public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null) { if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { + if (\PHP_VERSION_ID < 80000) { + trigger_error('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH', \E_USER_WARNING); + + return false; + } + throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); } if (null === $encoding) { $encoding = self::mb_internal_encoding(); - } else { - self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given'); + } elseif (!self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given')) { + return false; } if (self::mb_strlen($pad_string, $encoding) <= 0) { + if (\PHP_VERSION_ID < 80000) { + trigger_error('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string', \E_USER_WARNING); + + return false; + } + throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string'); } @@ -869,12 +882,13 @@ public static function mb_str_pad(string $string, int $length, string $pad_strin } } - public static function mb_ucfirst(string $string, ?string $encoding = null): string + /** @return string|false */ + public static function mb_ucfirst(string $string, ?string $encoding = null) { if (null === $encoding) { $encoding = self::mb_internal_encoding(); - } else { - self::assertEncoding($encoding, 'mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given'); + } elseif (!self::assertEncoding($encoding, 'mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given')) { + return false; } $firstChar = mb_substr($string, 0, 1, $encoding); @@ -883,12 +897,13 @@ public static function mb_ucfirst(string $string, ?string $encoding = null): str return $firstChar.mb_substr($string, 1, null, $encoding); } - public static function mb_lcfirst(string $string, ?string $encoding = null): string + /** @return string|false */ + public static function mb_lcfirst(string $string, ?string $encoding = null) { if (null === $encoding) { $encoding = self::mb_internal_encoding(); - } else { - self::assertEncoding($encoding, 'mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given'); + } elseif (!self::assertEncoding($encoding, 'mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given')) { + return false; } $firstChar = mb_substr($string, 0, 1, $encoding); @@ -971,27 +986,31 @@ private static function getEncoding($encoding) return $encoding; } - public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string + /** @return string|false */ + public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null) { return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__); } - public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string + /** @return string|false */ + public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null) { return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__); } - public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string + /** @return string|false */ + public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null) { return self::mb_internal_trim('{[%s]+$}D', $string, $characters, $encoding, __FUNCTION__); } - private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function): string + /** @return string|false */ + private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function) { if (null === $encoding) { $encoding = self::mb_internal_encoding(); - } else { - self::assertEncoding($encoding, $function.'(): Argument #3 ($encoding) must be a valid encoding, "%s" given'); + } elseif (!self::assertEncoding($encoding, $function.'(): Argument #3 ($encoding) must be a valid encoding, "%s" given')) { + return false; } if ('' === $characters) { @@ -1029,7 +1048,7 @@ private static function mb_internal_trim(string $regex, string $string, ?string return iconv('UTF-8', $encoding.'//IGNORE', $string); } - private static function assertEncoding(string $encoding, string $errorFormat): void + private static function assertEncoding(string $encoding, string $errorFormat): bool { try { $validEncoding = @self::mb_check_encoding('', $encoding); @@ -1037,9 +1056,14 @@ private static function assertEncoding(string $encoding, string $errorFormat): v throw new \ValueError(sprintf($errorFormat, $encoding)); } - // BC for PHP 7.3 and lower if (!$validEncoding) { - throw new \ValueError(sprintf($errorFormat, $encoding)); + if (\PHP_VERSION_ID >= 80000) { + throw new \ValueError(sprintf($errorFormat, $encoding)); + } + + trigger_error(sprintf($errorFormat, $encoding), E_USER_WARNING); } + + return $validEncoding; } } diff --git a/src/Mbstring/bootstrap.php b/src/Mbstring/bootstrap.php index ff51ae079..08146134c 100644 --- a/src/Mbstring/bootstrap.php +++ b/src/Mbstring/bootstrap.php @@ -133,27 +133,27 @@ function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstrin } if (!function_exists('mb_str_pad')) { - function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } + function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null) { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } } if (!function_exists('mb_ucfirst')) { - function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); } + function mb_ucfirst(string $string, ?string $encoding = null) { return p\Mbstring::mb_ucfirst($string, $encoding); } } if (!function_exists('mb_lcfirst')) { - function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); } + function mb_lcfirst(string $string, ?string $encoding = null) { return p\Mbstring::mb_lcfirst($string, $encoding); } } if (!function_exists('mb_trim')) { - function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); } + function mb_trim(string $string, ?string $characters = null, ?string $encoding = null) { return p\Mbstring::mb_trim($string, $characters, $encoding); } } if (!function_exists('mb_ltrim')) { - function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } + function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null) { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } } if (!function_exists('mb_rtrim')) { - function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); } + function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null) { return p\Mbstring::mb_rtrim($string, $characters, $encoding); } } diff --git a/src/Php83/Php83.php b/src/Php83/Php83.php index 3d94b6c32..26f6db14a 100644 --- a/src/Php83/Php83.php +++ b/src/Php83/Php83.php @@ -40,7 +40,8 @@ public static function json_validate(string $json, int $depth = 512, int $flags return \JSON_ERROR_NONE === json_last_error(); } - public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null): string + /** @return string|false */ + public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null) { if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); @@ -50,19 +51,27 @@ public static function mb_str_pad(string $string, int $length, string $pad_strin $encoding = mb_internal_encoding(); } + $errorToTrigger = null; try { - $validEncoding = @mb_check_encoding('', $encoding); + if (!@mb_check_encoding('', $encoding)) { + $errorToTrigger = sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding); + } } catch (\ValueError $e) { - throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); + $errorToTrigger = sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding); } - // BC for PHP 7.3 and lower - if (!$validEncoding) { - throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); + if (mb_strlen($pad_string, $encoding) <= 0) { + $errorToTrigger = 'mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string'; } - if (mb_strlen($pad_string, $encoding) <= 0) { - throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string'); + if (null !== $errorToTrigger) { + if (PHP_VERSION_ID < 80000) { + trigger_error($errorToTrigger, E_USER_WARNING); + + return false; + } + + throw new \ValueError($errorToTrigger); } $paddingRequired = $length - mb_strlen($string, $encoding); diff --git a/src/Php83/bootstrap.php b/src/Php83/bootstrap.php index a92799cb3..8d721a29c 100644 --- a/src/Php83/bootstrap.php +++ b/src/Php83/bootstrap.php @@ -19,12 +19,6 @@ function json_validate(string $json, int $depth = 512, int $flags = 0): bool { return p\Php83::json_validate($json, $depth, $flags); } } -if (extension_loaded('mbstring')) { - if (!function_exists('mb_str_pad')) { - function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Php83::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } - } -} - if (!function_exists('stream_context_set_options')) { function stream_context_set_options($context, array $options): bool { return stream_context_set_option($context, $options); } } @@ -37,8 +31,14 @@ function str_increment(string $string): string { return p\Php83::str_increment($ function str_decrement(string $string): string { return p\Php83::str_decrement($string); } } -if (\PHP_VERSION_ID >= 80100) { - return require __DIR__.'/bootstrap81.php'; +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (extension_loaded('mbstring')) { + if (!function_exists('mb_str_pad')) { + function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null) { return p\Php83::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } + } } if (!function_exists('ldap_exop_sync') && function_exists('ldap_exop')) { diff --git a/src/Php83/bootstrap80.php b/src/Php83/bootstrap80.php new file mode 100644 index 000000000..b1cf0942e --- /dev/null +++ b/src/Php83/bootstrap80.php @@ -0,0 +1,19 @@ += 80100) { + return require __DIR__.'/bootstrap81.php'; +} + +if (!function_exists('ldap_exop_sync') && function_exists('ldap_exop')) { + function ldap_exop_sync($ldap, string $request_oid, ?string $request_data = null, ?array $controls = null, &$response_data = null, &$response_oid = null): bool { return ldap_exop($ldap, $request_oid, $request_data, $controls, $response_data, $response_oid); } +} + +if (!function_exists('ldap_connect_wallet') && function_exists('ldap_connect')) { + function ldap_connect_wallet(?string $uri, string $wallet, string $password, int $auth_mode = \GSLC_SSL_NO_AUTH) { return ldap_connect($uri, $wallet, $password, $auth_mode); } +} diff --git a/src/Php84/Php84.php b/src/Php84/Php84.php index 1bca70b56..0384f0855 100644 --- a/src/Php84/Php84.php +++ b/src/Php84/Php84.php @@ -19,7 +19,8 @@ */ final class Php84 { - public static function mb_ucfirst(string $string, ?string $encoding = null): string + /** @return string|false */ + public static function mb_ucfirst(string $string, ?string $encoding = null) { if (null === $encoding) { $encoding = mb_internal_encoding(); @@ -31,8 +32,13 @@ public static function mb_ucfirst(string $string, ?string $encoding = null): str throw new \ValueError(sprintf('mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given', $encoding)); } - // BC for PHP 7.3 and lower if (!$validEncoding) { + if (PHP_VERSION_ID < 80000) { + trigger_error(sprintf('mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given', $encoding), \E_USER_WARNING); + + return false; + } + throw new \ValueError(sprintf('mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given', $encoding)); } @@ -42,7 +48,8 @@ public static function mb_ucfirst(string $string, ?string $encoding = null): str return $firstChar.mb_substr($string, 1, null, $encoding); } - public static function mb_lcfirst(string $string, ?string $encoding = null): string + /** @return string|false */ + public static function mb_lcfirst(string $string, ?string $encoding = null) { if (null === $encoding) { $encoding = mb_internal_encoding(); @@ -54,8 +61,13 @@ public static function mb_lcfirst(string $string, ?string $encoding = null): str throw new \ValueError(sprintf('mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given', $encoding)); } - // BC for PHP 7.3 and lower if (!$validEncoding) { + if (PHP_VERSION_ID < 80000) { + trigger_error(sprintf('mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given', $encoding), \E_USER_WARNING); + + return false; + } + throw new \ValueError(sprintf('mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given', $encoding)); } @@ -109,22 +121,26 @@ public static function array_all(array $array, callable $callback): bool return true; } - public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string + /** @return string|false */ + public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null) { return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__); } - public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string + /** @return string|false */ + public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null) { return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__); } - public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string + /** @return string|false */ + public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null) { - return self::mb_internal_trim('{[%s]+$}Du', $string, $characters, $encoding, __FUNCTION__); + return self::mb_internal_trim('{[%s]+$}D', $string, $characters, $encoding, __FUNCTION__); } - private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function): string + /** @return string|false */ + private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function) { if (null === $encoding) { $encoding = mb_internal_encoding(); @@ -136,8 +152,13 @@ private static function mb_internal_trim(string $regex, string $string, ?string throw new \ValueError(sprintf('%s(): Argument #3 ($encoding) must be a valid encoding, "%s" given', $function, $encoding)); } - // BC for PHP 7.3 and lower if (!$validEncoding) { + if (PHP_VERSION_ID < 80000) { + trigger_error(sprintf('%s(): Argument #3 ($encoding) must be a valid encoding, "%s" given', $function, $encoding), \E_USER_WARNING); + + return false; + } + throw new \ValueError(sprintf('%s(): Argument #3 ($encoding) must be a valid encoding, "%s" given', $function, $encoding)); } diff --git a/src/Php84/bootstrap.php b/src/Php84/bootstrap.php index 342158c63..4aacc21c8 100644 --- a/src/Php84/bootstrap.php +++ b/src/Php84/bootstrap.php @@ -39,24 +39,28 @@ function array_any(array $array, callable $callback): bool { return p\Php84::arr function array_all(array $array, callable $callback): bool { return p\Php84::array_all($array, $callback); } } +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__ . '/bootstrap80.php'; +} + if (extension_loaded('mbstring')) { if (!function_exists('mb_ucfirst')) { - function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Php84::mb_ucfirst($string, $encoding); } + function mb_ucfirst(string $string, ?string $encoding = null) { return p\Php84::mb_ucfirst($string, $encoding); } } if (!function_exists('mb_lcfirst')) { - function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Php84::mb_lcfirst($string, $encoding); } + function mb_lcfirst(string $string, ?string $encoding = null) { return p\Php84::mb_lcfirst($string, $encoding); } } if (!function_exists('mb_trim')) { - function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_trim($string, $characters, $encoding); } + function mb_trim(string $string, ?string $characters = null, ?string $encoding = null) { return p\Php84::mb_trim($string, $characters, $encoding); } } if (!function_exists('mb_ltrim')) { - function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_ltrim($string, $characters, $encoding); } + function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null) { return p\Php84::mb_ltrim($string, $characters, $encoding); } } if (!function_exists('mb_rtrim')) { - function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_rtrim($string, $characters, $encoding); } + function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null) { return p\Php84::mb_rtrim($string, $characters, $encoding); } } } diff --git a/src/Php84/bootstrap80.php b/src/Php84/bootstrap80.php new file mode 100644 index 000000000..88b31ac71 --- /dev/null +++ b/src/Php84/bootstrap80.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Php84 as p; + +if (extension_loaded('mbstring')) { + if (!function_exists('mb_ucfirst')) { + function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Php84::mb_ucfirst($string, $encoding); } + } + + if (!function_exists('mb_lcfirst')) { + function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Php84::mb_lcfirst($string, $encoding); } + } + + if (!function_exists('mb_trim')) { + function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_trim($string, $characters, $encoding); } + } + + if (!function_exists('mb_ltrim')) { + function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_ltrim($string, $characters, $encoding); } + } + + if (!function_exists('mb_rtrim')) { + function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Php84::mb_rtrim($string, $characters, $encoding); } + } +} diff --git a/tests/Mbstring/MbstringTest.php b/tests/Mbstring/MbstringTest.php index 2020f4566..15b78fdd8 100644 --- a/tests/Mbstring/MbstringTest.php +++ b/tests/Mbstring/MbstringTest.php @@ -648,15 +648,38 @@ public function testMbStrPad(string $expectedResult, string $string, int $length * @covers \Symfony\Polyfill\Mbstring\Mbstring::mb_str_pad * * @dataProvider mbStrPadInvalidArgumentsProvider + * @requires PHP 8 */ public function testMbStrPadInvalidArguments(string $expectedError, string $string, int $length, string $padString, int $padType, ?string $encoding = null) { $this->expectException(\ValueError::class); - $this->expectErrorMessage($expectedError); + $this->expectExceptionMessage($expectedError); mb_str_pad($string, $length, $padString, $padType, $encoding); } + /** + * @covers \Symfony\Polyfill\Mbstring\Mbstring::mb_str_pad + * + * @dataProvider mbStrPadInvalidArgumentsProvider + * @requires PHP < 8 + */ + public function testMbStrPadInvalidArgumentsOnPhp7(string $expectedError, string $string, int $length, string $padString, int $padType, ?string $encoding = null) + { + $this->expectException(\ErrorException::class); + $this->expectExceptionMessage($expectedError); + + set_error_handler(static function ($errno, $errstr, $errfile, $errline) { + throw new \ErrorException($errstr, $errno, $errfile, $errline); + }); + + try { + mb_str_pad($string, $length, $padString, $padType, $encoding); + } finally { + restore_error_handler(); + } + } + /** * @dataProvider ucFirstDataProvider */ @@ -815,12 +838,36 @@ public function testMbRTrim(string $expected, string $string, ?string $character $this->assertSame($expected, mb_rtrim($string, $characters, $encoding)); } + /** + * @requires PHP 8 + */ public function testMbTrimException() { $this->expectException(\ValueError::class); + $this->expectExceptionMessage('mb_trim(): Argument #3 ($encoding) must be a valid encoding, "NULL" given'); + mb_trim("\u{180F}", '', 'NULL'); } + /** + * @requires PHP < 8 + */ + public function testMbTrimExceptionOnPhp7() + { + $this->expectException(\ErrorException::class); + $this->expectExceptionMessage('mb_trim(): Argument #3 ($encoding) must be a valid encoding, "NULL" given'); + + set_error_handler(static function ($errno, $errstr, $errfile, $errline) { + throw new \ErrorException($errstr, $errno, $errfile, $errline); + }); + + try { + mb_trim("\u{180F}", '', 'NULL'); + } finally { + restore_error_handler(); + } + } + public function testMbTrimEncoding() { $this->assertSame('あ', mb_convert_encoding(mb_trim("\x81\x40\x82\xa0\x81\x40", "\x81\x40", 'SJIS'), 'UTF-8', 'SJIS')); diff --git a/tests/Php83/Php83Test.php b/tests/Php83/Php83Test.php index 545a8fdc1..ab5e7860e 100644 --- a/tests/Php83/Php83Test.php +++ b/tests/Php83/Php83Test.php @@ -42,15 +42,38 @@ public function testMbStrPad(string $expectedResult, string $string, int $length * @covers \Symfony\Polyfill\Php83\Php83::mb_str_pad * * @dataProvider mbStrPadInvalidArgumentsProvider + * @requires PHP 8 */ public function testMbStrPadInvalidArguments(string $expectedError, string $string, int $length, string $padString, int $padType, ?string $encoding = null) { $this->expectException(\ValueError::class); - $this->expectErrorMessage($expectedError); + $this->expectExceptionMessage($expectedError); mb_str_pad($string, $length, $padString, $padType, $encoding); } + /** + * @covers \Symfony\Polyfill\Php83\Php83::mb_str_pad + * + * @dataProvider mbStrPadInvalidArgumentsProvider + * @requires PHP < 8 + */ + public function testMbStrPadInvalidArgumentsOnPhp7(string $expectedError, string $string, int $length, string $padString, int $padType, ?string $encoding = null) + { + $this->expectException(\ErrorException::class); + $this->expectExceptionMessage($expectedError); + + set_error_handler(static function ($errno, $errstr, $errfile, $errline) { + throw new \ErrorException($errstr, $errno, $errfile, $errline); + }); + + try { + mb_str_pad($string, $length, $padString, $padType, $encoding); + } finally { + restore_error_handler(); + } + } + public static function paddingStringProvider(): iterable { // Simple ASCII strings diff --git a/tests/Php84/Php84Test.php b/tests/Php84/Php84Test.php index 9d573a186..f4b45a256 100644 --- a/tests/Php84/Php84Test.php +++ b/tests/Php84/Php84Test.php @@ -227,12 +227,36 @@ public function testMbRTrim(string $expected, string $string, ?string $character $this->assertSame($expected, mb_rtrim($string, $characters, $encoding)); } + /** + * @requires PHP 8 + */ public function testMbTrimException() { $this->expectException(\ValueError::class); + $this->expectExceptionMessage('mb_trim(): Argument #3 ($encoding) must be a valid encoding, "NULL" given'); + mb_trim("\u{180F}", '', 'NULL'); } + /** + * @requires PHP < 8 + */ + public function testMbTrimExceptionOnPhp7() + { + $this->expectException(\ErrorException::class); + $this->expectExceptionMessage('mb_trim(): Argument #3 ($encoding) must be a valid encoding, "NULL" given'); + + set_error_handler(static function ($errno, $errstr, $errfile, $errline) { + throw new \ErrorException($errstr, $errno, $errfile, $errline); + }); + + try { + mb_trim("\u{180F}", '', 'NULL'); + } finally { + restore_error_handler(); + } + } + public function testMbTrimEncoding() { $this->assertSame('あ', mb_convert_encoding(mb_trim("\x81\x40\x82\xa0\x81\x40", "\x81\x40", 'SJIS'), 'UTF-8', 'SJIS'));