diff --git a/CHANGELOG b/CHANGELOG index e1615c91d..a949ef23a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,6 @@ # 3.30.0 (2026-XX-XX) + * Report a clear error when `random`, `reverse`, `shuffle`, and `split` receive a string that is not valid UTF-8 * Fix the deprecation about omitting parentheses when calling a macro being reported twice for the same call * Add the macro name to the deprecation about omitting parentheses when calling a macro * Deprecate cloning a `Twig\Environment` instance diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php index 5fd56e9eb..9c05fee9e 100644 --- a/src/Extension/CoreExtension.php +++ b/src/Extension/CoreExtension.php @@ -495,9 +495,7 @@ final class CoreExtension extends AbstractExtension $values = self::convertEncoding($values, 'UTF-8', $charset); } - // unicode version of str_split() - // split at all positions, but not after the start and not before the end - $values = preg_split('/(? $value) { @@ -897,7 +895,7 @@ final class CoreExtension extends AbstractExtension } if ($limit <= 1) { - return preg_split('/(? + * + * @throws RuntimeError When the string cannot be split into characters + */ + private static function splitIntoCharacters(string $string, string $name): array + { + if (false === $characters = preg_split('/(? "\xC3\x28abc"] +--EXCEPTION-- +Twig\Error\RuntimeError: Unable to split the string passed to "reverse" into characters: Malformed UTF-8 characters, possibly incorrectly encoded in "index.twig" at line 2. diff --git a/tests/Fixtures/filters/shuffle_invalid_utf8.test b/tests/Fixtures/filters/shuffle_invalid_utf8.test new file mode 100644 index 000000000..774b1e9e3 --- /dev/null +++ b/tests/Fixtures/filters/shuffle_invalid_utf8.test @@ -0,0 +1,8 @@ +--TEST-- +"shuffle" filter with a string that is not valid UTF-8 +--TEMPLATE-- +{{ value|shuffle }} +--DATA-- +return ['value' => "\xC3\x28abc"] +--EXCEPTION-- +Twig\Error\RuntimeError: Unable to split the string passed to "shuffle" into characters: Malformed UTF-8 characters, possibly incorrectly encoded in "index.twig" at line 2. diff --git a/tests/Fixtures/filters/split_invalid_utf8.test b/tests/Fixtures/filters/split_invalid_utf8.test new file mode 100644 index 000000000..ac2ef1873 --- /dev/null +++ b/tests/Fixtures/filters/split_invalid_utf8.test @@ -0,0 +1,8 @@ +--TEST-- +"split" filter with an empty delimiter and a string that is not valid UTF-8 +--TEMPLATE-- +{{ value|split('')|join('-') }} +--DATA-- +return ['value' => "\xC3\x28abc"] +--EXCEPTION-- +Twig\Error\RuntimeError: Unable to split the string passed to "split" into characters: Malformed UTF-8 characters, possibly incorrectly encoded in "index.twig" at line 2. diff --git a/tests/Fixtures/functions/random_invalid_utf8.test b/tests/Fixtures/functions/random_invalid_utf8.test new file mode 100644 index 000000000..da22905fd --- /dev/null +++ b/tests/Fixtures/functions/random_invalid_utf8.test @@ -0,0 +1,8 @@ +--TEST-- +"random" function with a string that is not valid UTF-8 +--TEMPLATE-- +{{ random(value) }} +--DATA-- +return ['value' => "\xC3\x28abc"] +--EXCEPTION-- +Twig\Error\RuntimeError: Unable to split the string passed to "random" into characters: Malformed UTF-8 characters, possibly incorrectly encoded in "index.twig" at line 2.