Skip to content

Commit

Permalink
Make string padding UTF-8 safe
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
martenkoetsier authored and taylorotwell committed Aug 22, 2022
1 parent d65260d commit f1762ed
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 4 deletions.
14 changes: 11 additions & 3 deletions src/Illuminate/Support/Str.php
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,13 @@ public static function matchAll($pattern, $subject)
*/
public static function padBoth($value, $length, $pad = ' ')
{
return str_pad($value, strlen($value) - mb_strlen($value) + $length, $pad, STR_PAD_BOTH);
$short = max(0, $length - mb_strlen($value));
$short_left = floor($short / 2);
$short_right = ceil($short / 2);
return
mb_substr(str_repeat($pad, $short_left), 0, $short_left) .
$value .
mb_substr(str_repeat($pad, $short_right), 0, $short_right);
}

/**
Expand All @@ -621,7 +627,8 @@ public static function padBoth($value, $length, $pad = ' ')
*/
public static function padLeft($value, $length, $pad = ' ')
{
return str_pad($value, strlen($value) - mb_strlen($value) + $length, $pad, STR_PAD_LEFT);
$short = max(0, $length - mb_strlen($value));
return mb_substr(str_repeat($pad, $short), 0, $short) . $value;
}

/**
Expand All @@ -634,7 +641,8 @@ public static function padLeft($value, $length, $pad = ' ')
*/
public static function padRight($value, $length, $pad = ' ')
{
return str_pad($value, strlen($value) - mb_strlen($value) + $length, $pad, STR_PAD_RIGHT);
$short = max(0, $length - mb_strlen($value));
return $value . mb_substr(str_repeat($pad, $short), 0, $short);
}

/**
Expand Down
5 changes: 4 additions & 1 deletion tests/Support/SupportStrTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -781,20 +781,23 @@ public function testPadBoth()
$this->assertSame('__Alien___', Str::padBoth('Alien', 10, '_'));
$this->assertSame(' Alien ', Str::padBoth('Alien', 10));
$this->assertSame(' ❤MultiByte☆ ', Str::padBoth('❤MultiByte☆', 16));
$this->assertSame('❤☆❤MultiByte☆❤☆❤', Str::padBoth('❤MultiByte☆', 16, '❤☆'));
}

public function testPadLeft()
{
$this->assertSame('-=-=-Alien', Str::padLeft('Alien', 10, '-='));
$this->assertSame(' Alien', Str::padLeft('Alien', 10));
$this->assertSame(' ❤MultiByte☆', Str::padLeft('❤MultiByte☆', 16));
$this->assertSame('❤☆❤☆❤❤MultiByte☆', Str::padLeft('❤MultiByte☆', 16, '❤☆'));
}

public function testPadRight()
{
$this->assertSame('Alien-----', Str::padRight('Alien', 10, '-'));
$this->assertSame('Alien-=-=-', Str::padRight('Alien', 10, '-='));
$this->assertSame('Alien ', Str::padRight('Alien', 10));
$this->assertSame('❤MultiByte☆ ', Str::padRight('❤MultiByte☆', 16));
$this->assertSame('❤MultiByte☆❤☆❤☆❤', Str::padRight('❤MultiByte☆', 16, '❤☆'));
}

public function testSwapKeywords(): void
Expand Down

0 comments on commit f1762ed

Please sign in to comment.