Skip to content

Commit f1762ed

Browse files
martenkoetsiertaylorotwell
authored andcommitted
Make string padding UTF-8 safe
The pad string could be truncated in the middle of a unicode code point. This is now fixed. Also updated unittest to test UTF-8 padding strings.
1 parent d65260d commit f1762ed

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

src/Illuminate/Support/Str.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,13 @@ public static function matchAll($pattern, $subject)
608608
*/
609609
public static function padBoth($value, $length, $pad = ' ')
610610
{
611-
return str_pad($value, strlen($value) - mb_strlen($value) + $length, $pad, STR_PAD_BOTH);
611+
$short = max(0, $length - mb_strlen($value));
612+
$short_left = floor($short / 2);
613+
$short_right = ceil($short / 2);
614+
return
615+
mb_substr(str_repeat($pad, $short_left), 0, $short_left) .
616+
$value .
617+
mb_substr(str_repeat($pad, $short_right), 0, $short_right);
612618
}
613619

614620
/**
@@ -621,7 +627,8 @@ public static function padBoth($value, $length, $pad = ' ')
621627
*/
622628
public static function padLeft($value, $length, $pad = ' ')
623629
{
624-
return str_pad($value, strlen($value) - mb_strlen($value) + $length, $pad, STR_PAD_LEFT);
630+
$short = max(0, $length - mb_strlen($value));
631+
return mb_substr(str_repeat($pad, $short), 0, $short) . $value;
625632
}
626633

627634
/**
@@ -634,7 +641,8 @@ public static function padLeft($value, $length, $pad = ' ')
634641
*/
635642
public static function padRight($value, $length, $pad = ' ')
636643
{
637-
return str_pad($value, strlen($value) - mb_strlen($value) + $length, $pad, STR_PAD_RIGHT);
644+
$short = max(0, $length - mb_strlen($value));
645+
return $value . mb_substr(str_repeat($pad, $short), 0, $short);
638646
}
639647

640648
/**

tests/Support/SupportStrTest.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,20 +781,23 @@ public function testPadBoth()
781781
$this->assertSame('__Alien___', Str::padBoth('Alien', 10, '_'));
782782
$this->assertSame(' Alien ', Str::padBoth('Alien', 10));
783783
$this->assertSame(' ❤MultiByte☆ ', Str::padBoth('❤MultiByte☆', 16));
784+
$this->assertSame('❤☆❤MultiByte☆❤☆❤', Str::padBoth('❤MultiByte☆', 16, '❤☆'));
784785
}
785786

786787
public function testPadLeft()
787788
{
788789
$this->assertSame('-=-=-Alien', Str::padLeft('Alien', 10, '-='));
789790
$this->assertSame(' Alien', Str::padLeft('Alien', 10));
790791
$this->assertSame(' ❤MultiByte☆', Str::padLeft('❤MultiByte☆', 16));
792+
$this->assertSame('❤☆❤☆❤❤MultiByte☆', Str::padLeft('❤MultiByte☆', 16, '❤☆'));
791793
}
792794

793795
public function testPadRight()
794796
{
795-
$this->assertSame('Alien-----', Str::padRight('Alien', 10, '-'));
797+
$this->assertSame('Alien-=-=-', Str::padRight('Alien', 10, '-='));
796798
$this->assertSame('Alien ', Str::padRight('Alien', 10));
797799
$this->assertSame('❤MultiByte☆ ', Str::padRight('❤MultiByte☆', 16));
800+
$this->assertSame('❤MultiByte☆❤☆❤☆❤', Str::padRight('❤MultiByte☆', 16, '❤☆'));
798801
}
799802

800803
public function testSwapKeywords(): void

0 commit comments

Comments
 (0)