From d31ac74c03ca9a538853f96396781002f04ac815 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Wed, 21 Oct 2020 15:57:03 +0200 Subject: [PATCH] [String] fix slicing in UnicodeString --- .../String/Tests/AbstractAsciiTestCase.php | 31 +++++++++++++++++++ .../Component/String/UnicodeString.php | 12 ++++--- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php b/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php index 44f14c18af3a2..d752ea41eb608 100644 --- a/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php +++ b/src/Symfony/Component/String/Tests/AbstractAsciiTestCase.php @@ -597,6 +597,37 @@ public static function provideSlice() ['awesome', 'Symfony is awesome', 11, 7], ['awesome', 'Symfony is awesome', -7, null], ['awe', 'Symfony is awesome', -7, -4], + ['S', 'Symfony is awesome', -42, 1], + ['', 'Symfony is awesome', 42, 1], + ['', 'Symfony is awesome', 0, -42], + ]; + } + + /** + * @dataProvider provideSplice + */ + public function testSplice(string $expected, int $start, int $length = null) + { + $this->assertEquals( + static::createFromString($expected), + static::createFromString('Symfony is awesome')->splice('X', $start, $length) + ); + } + + public static function provideSplice() + { + return [ + ['X is awesome', 0, 7], + ['SymfonyXis awesome', 7, 1], + ['Symfony X awesome', 8, 2], + ['Symfony X', 8, null], + ['Symfony isXawesome', 10, 1], + ['Symfony is X', 11, 7], + ['Symfony is X', -7, null], + ['Symfony is Xsome', -7, -4], + ['Xymfony is awesome', -42, 1], + ['Symfony is awesomeX', 42, 1], + ['XSymfony is awesome', 0, -42], ]; } diff --git a/src/Symfony/Component/String/UnicodeString.php b/src/Symfony/Component/String/UnicodeString.php index 16945b70a4407..2db507d7bbf0e 100644 --- a/src/Symfony/Component/String/UnicodeString.php +++ b/src/Symfony/Component/String/UnicodeString.php @@ -267,11 +267,11 @@ public function replaceMatches(string $fromRegexp, $to): AbstractString public function slice(int $start = 0, int $length = null): AbstractString { $str = clone $this; - try { - $str->string = (string) grapheme_substr($this->string, $start, $length ?? 2147483647); - } catch (\ValueError $e) { - $str->string = ''; + + if (\PHP_VERSION_ID < 80000 && 0 > $start && grapheme_strlen($this->string) < -$start) { + $start = 0; } + $str->string = (string) grapheme_substr($this->string, $start, $length ?? 2147483647); return $str; } @@ -279,6 +279,10 @@ public function slice(int $start = 0, int $length = null): AbstractString public function splice(string $replacement, int $start = 0, int $length = null): AbstractString { $str = clone $this; + + if (\PHP_VERSION_ID < 80000 && 0 > $start && grapheme_strlen($this->string) < -$start) { + $start = 0; + } $start = $start ? \strlen(grapheme_substr($this->string, 0, $start)) : 0; $length = $length ? \strlen(grapheme_substr($this->string, $start, $length ?? 2147483647)) : $length; $str->string = substr_replace($this->string, $replacement, $start, $length ?? 2147483647);