From d0869f705a81d653d73acfb3640df01236d906f1 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Wed, 11 Sep 2024 09:34:10 +0200 Subject: [PATCH] Various fixes and removed deprecations --- src/Iconv/Iconv.php | 32 +++++++++++++++++++++++++++++++- src/Intl/Idn/bootstrap80.php | 4 ++-- src/Util/TestListenerTrait.php | 1 - tests/Iconv/IconvTest.php | 2 +- tests/Mbstring/MbstringTest.php | 16 ++++++++++++---- tests/Php81/Php81Test.php | 1 + 6 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/Iconv/Iconv.php b/src/Iconv/Iconv.php index c17a70dc2..b26a1163d 100644 --- a/src/Iconv/Iconv.php +++ b/src/Iconv/Iconv.php @@ -451,7 +451,7 @@ public static function strlen1($s, $encoding = null) return false; } - return \strlen(utf8_decode($s)); + return \strlen(self::utf8Decode($s)); } public static function strlen2($s, $encoding = null) @@ -741,4 +741,34 @@ private static function getData($file) return false; } + + private static function utf8Decode($s) + { + $s = (string) $s; + $len = \strlen($s); + + for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) { + switch ($s[$i] & "\xF0") { + case "\xC0": + case "\xD0": + $c = (\ord($s[$i] & "\x1F") << 6) | \ord($s[++$i] & "\x3F"); + $s[$j] = $c < 256 ? \chr($c) : '?'; + break; + + case "\xF0": + ++$i; + // no break + + case "\xE0": + $s[$j] = '?'; + $i += 2; + break; + + default: + $s[$j] = $s[$i]; + } + } + + return substr($s, 0, $j); + } } diff --git a/src/Intl/Idn/bootstrap80.php b/src/Intl/Idn/bootstrap80.php index a62c2d69b..33a3fb65f 100644 --- a/src/Intl/Idn/bootstrap80.php +++ b/src/Intl/Idn/bootstrap80.php @@ -118,8 +118,8 @@ } if (!function_exists('idn_to_ascii')) { - function idn_to_ascii(?string $domain, ?int $flags = IDNA_DEFAULT, ?int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_ascii((string) $domain, (int) $flags, (int) $variant, $idna_info); } + function idn_to_ascii(string $domain, int $flags = IDNA_DEFAULT, int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_ascii($domain, $flags, $variant, $idna_info); } } if (!function_exists('idn_to_utf8')) { - function idn_to_utf8(?string $domain, ?int $flags = IDNA_DEFAULT, ?int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_utf8((string) $domain, (int) $flags, (int) $variant, $idna_info); } + function idn_to_utf8(string $domain, int $flags = IDNA_DEFAULT, int $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = null): string|false { return p\Idn::idn_to_utf8($domain, $flags, $variant, $idna_info); } } diff --git a/src/Util/TestListenerTrait.php b/src/Util/TestListenerTrait.php index 58024695c..9527b52bb 100644 --- a/src/Util/TestListenerTrait.php +++ b/src/Util/TestListenerTrait.php @@ -131,7 +131,6 @@ function {$f['name']}{$f['signature']} $map = [ '?' => '', - 'IDNA_DEFAULT' => \PHP_VERSION_ID >= 80100 ? 'IDNA_DEFAULT' : '0', 'array|string|null $string' => 'array|string $string', 'array|string|null $from_encoding = null' => 'array|string|null $from_encoding = null', 'array|string|null $from_encoding' => 'array|string $from_encoding', diff --git a/tests/Iconv/IconvTest.php b/tests/Iconv/IconvTest.php index 214ea36ef..a627e72ca 100644 --- a/tests/Iconv/IconvTest.php +++ b/tests/Iconv/IconvTest.php @@ -29,7 +29,7 @@ public function testIconv() $this->assertFalse(@iconv('UTF-8', 'ISO-8859-1', 'nœud')); $this->assertSame('nud', iconv('UTF-8', 'ISO-8859-1//IGNORE', 'nœud')); - $this->assertSame(utf8_decode('déjà'), iconv('CP1252', 'ISO-8859-1', utf8_decode('déjà'))); + $this->assertSame(mb_convert_encoding('déjà', 'ISO-8859-1', 'UTF-8'), iconv('CP1252', 'ISO-8859-1', mb_convert_encoding('déjà', 'ISO-8859-1', 'UTF-8'))); $this->assertSame('deja noeud', p::iconv('UTF-8//ignore//IGNORE', 'US-ASCII//TRANSLIT//IGNORE//translit', 'déjà nœud')); $this->assertSame('4', iconv('UTF-8', 'UTF-8', 4)); diff --git a/tests/Mbstring/MbstringTest.php b/tests/Mbstring/MbstringTest.php index bacaf3dbe..7e5ab180a 100644 --- a/tests/Mbstring/MbstringTest.php +++ b/tests/Mbstring/MbstringTest.php @@ -68,13 +68,21 @@ public function testInternalEncodingWithInvalidEncoding() */ public function testConvertEncoding() { - $this->assertSame(utf8_decode('déjà'), mb_convert_encoding('déjà', 'Windows-1252')); + $this->assertSame(mb_convert_encoding('déjà', 'ISO-8859-1', 'UTF-8'), mb_convert_encoding('déjà', 'Windows-1252')); + $this->assertSame('déjà', mb_convert_encoding(mb_convert_encoding('déjà', 'ISO-8859-1', 'UTF-8'), 'Utf-8', 'ASCII,ISO-2022-JP,UTF-8,ISO-8859-1')); + $this->assertSame('déjà', mb_convert_encoding(mb_convert_encoding('déjà', 'ISO-8859-1', 'UTF-8'), 'Utf-8', ['ASCII', 'ISO-2022-JP', 'UTF-8', 'ISO-8859-1'])); + } + + /** + * @group legacy + */ + public function testConvertLegacyEncoding() + { + // handling base64 and html entities with mb_convert_encoding is deprecated in PHP 8.2 $this->assertSame(base64_encode('déjà'), mb_convert_encoding('déjà', 'Base64')); $this->assertSame('実<&>déjà', mb_convert_encoding('実<&>déjà', 'Html-entities')); $this->assertSame('déjà', mb_convert_encoding(base64_encode('déjà'), 'Utf-8', 'Base64')); $this->assertSame('déjà', mb_convert_encoding('déjà', 'Utf-8', 'Html-entities')); - $this->assertSame('déjà', mb_convert_encoding(utf8_decode('déjà'), 'Utf-8', 'ASCII,ISO-2022-JP,UTF-8,ISO-8859-1')); - $this->assertSame('déjà', mb_convert_encoding(utf8_decode('déjà'), 'Utf-8', ['ASCII', 'ISO-2022-JP', 'UTF-8', 'ISO-8859-1'])); } /** @@ -567,7 +575,7 @@ public function testStrwidth() { $this->assertSame(3, mb_strwidth("\000実", 'UTF-8')); $this->assertSame(4, mb_strwidth('déjà', 'UTF-8')); - $this->assertSame(4, mb_strwidth(utf8_decode('déjà'), 'CP1252')); + $this->assertSame(4, mb_strwidth(mb_convert_encoding('déjà', 'ISO-8859-1', 'UTF-8'), 'CP1252')); } /** diff --git a/tests/Php81/Php81Test.php b/tests/Php81/Php81Test.php index f3764ef92..7a01758f9 100644 --- a/tests/Php81/Php81Test.php +++ b/tests/Php81/Php81Test.php @@ -34,6 +34,7 @@ public function testArrayIsList() /** * @requires extension mysqli + * @requires PHP < 8.4 */ public function testMysqliRefreshReplicaDefined() {