From 979e992010e09e02dbe91b2beab81abe87e28dc1 Mon Sep 17 00:00:00 2001 From: brandonkelly Date: Sun, 22 Sep 2024 11:49:06 -0700 Subject: [PATCH] Only allow alphanumeric/underscore characters through StringHelper::toHandle() Resolves #15772 --- CHANGELOG.md | 1 + src/helpers/StringHelper.php | 3 +++ tests/unit/helpers/StringHelperTest.php | 4 ++++ 3 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfac9abe837..424f751957c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Auto-generated handles, slugs, etc. now update immediately when the source input is changed. ([#15754](https://github.com/craftcms/cms/issues/15754)) - Fixed a bug where Table fields’ Default Values table could lose existing rows if they only consisted of Dropdown columns without configured options. - Fixed a bug where custom fields’ `required` properties were always `false`. ([#15752](https://github.com/craftcms/cms/issues/15752)) +- Fixed a bug where `craft\helpers\StringHelper::toHandle()` was allowing non-alphanumeric/underscore characters through. ([#15772](https://github.com/craftcms/cms/pull/15772)) ## 4.12.3 - 2024-09-14 diff --git a/src/helpers/StringHelper.php b/src/helpers/StringHelper.php index 178ce395f0d..330707afd21 100644 --- a/src/helpers/StringHelper.php +++ b/src/helpers/StringHelper.php @@ -1811,6 +1811,9 @@ public static function toHandle(string $str): string // Handle must start with a letter $handle = preg_replace('/^[^a-z]+/', '', $handle); + // Replace any remaining non-alphanumeric or underscore characters with spaces + $handle = preg_replace('/[^a-z0-9_]/', ' ', $handle); + return static::toCamelCase($handle); } diff --git a/tests/unit/helpers/StringHelperTest.php b/tests/unit/helpers/StringHelperTest.php index 9d2b7bded4c..753f6703bfc 100644 --- a/tests/unit/helpers/StringHelperTest.php +++ b/tests/unit/helpers/StringHelperTest.php @@ -2206,6 +2206,10 @@ public function toHandleDataProvider(): array ['fooBar', 'Fo’o Bar'], ['fooBarBaz', 'Foo Ba’r Baz'], ['fooBar', '0 Foo Bar'], + ['fooBar', 'Foo!Bar'], + ['fooBar', 'Foo,Bar'], + ['fooBar', 'Foo/Bar'], + ['fooBar', 'Foo\\Bar'], ]; }