Problem/Motivation
The username uniqueness validation in Drupal core has a critical issue with accent-sensitive characters. The implementation of case-insensitive username validation through \Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator::caseInsensitiveArrayIntersect() inadvertently affects accent character handling. When creating users with accented variations of existing usernames, the validation passes incorrectly, leading to database integrity constraint violations and White Screen of Death (WSOD).
The problematic logic was introduced in #3415582: Unhandled exception when trying to register a duplicate username with different case.
Steps to reproduce
- Create a user with username "dezso".
- Create a user with username "dezső"
Expect behavior, the second user creation fails with a "The username dezső is already taken. " constraint violation error when the db insert would also fail due to the duplicate value.
Actual behavior:
Drupal\Core\Entity\EntityStorageException: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'dezső-en' for key 'user__name': INSERT INTO "users_field_data" ("uid", "langcode", "preferred_langcode", "preferred_admin_langcode", "name", "pass", "mail", "timezone", "status", "created", "changed", "access", "login", "init", "default_langcode") VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8, :db_insert_placeholder_9, :db_insert_placeholder_10, :db_insert_placeholder_11, :db_insert_placeholder_12, :db_insert_placeholder_13, :db_insert_placeholder_14); Array ( [:db_insert_placeholder_0] => 11 [:db_insert_placeholder_1] => en [:db_insert_placeholder_2] => en [:db_insert_placeholder_3] => en [:db_insert_placeholder_4] => dezső [:db_insert_placeholder_5] => $2y...... [:db_insert_placeholder_6] => [:db_insert_placeholder_7] => UTC [:db_insert_placeholder_8] => 1 [:db_insert_placeholder_9] => 1739975168 [:db_insert_placeholder_10] => 1739975168 [:db_insert_placeholder_11] => 0 [:db_insert_placeholder_12] => 0 [:db_insert_placeholder_13] => [:db_insert_placeholder_14] => 1 ) in Drupal\Core\Entity\Sql\SqlContentEntityStorage->save() (line 817 of core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php).
Proposed resolution
The UniqueFieldValueValidator::caseInsensitiveArrayIntersect() method needs to be modified to respect accent-sensitive characters while maintaining case-insensitive validation. The validation should treat accented characters as distinct from their non-accented counterparts.
Remaining tasks
As CI builds indicates this issue is database engine and maybe engine configuration specific - this has to be double checked and identified whether the new normalization logic should always run or not.
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
Issue fork drupal-3507777
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3507777-user-names-unique-accent-sensitive
changes, plain diff MR !11243
Comments
Comment #2
mxr576Comment #4
mxr576FTR, originally we thought this is a collision issue but actually it is not, because the db returned the duplicates.
(Original Slack thread: https://drupal.slack.com/archives/C079NQPQUEN/p1739955491188989)
Comment #5
mxr576Comment #6
mxr576Since this is not my expert area, I have asked one of the AI-s how to fix the
\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator::caseInsensitiveArrayIntersect()implementation:*
\Normalizer::normalize($value, \Normalizer::FORM_NFKD)was suggested but that adds a dependecy on intl: https://www.php.net/manual/it/class.normalizer.php - could not make it work on my ddev local, but did not invested too much time either* https://packagist.org/packages/wikimedia/utfnormal which introduces a new package dependency, haven't checked
*
iconv("UTF-8", "ASCII//TRANSLIT", $text)as a quick solution, currently used in MR.and this is just one way to address the problem, I am unsure at this moment if the idea behind the
\Drupal\Core\Validation\Plugin\Validation\Constraint\UniqueFieldValueValidator::caseInsensitiveArrayIntersect()should be reconsidered after this finding.Comment #7
mxr576Comment #8
mxr576Comment #9
mxr576Adding #1144644: Enable specifying the collation when creating a database table because comment 1 explains to potential root cause perfectly (@catch called my attention to it on Slack).
Comment #10
mxr576Increasing to major just like the issue that introduced this problem, because user registration is blocked by this.
Comment #11
nico.b commentedI think this is the same issue as https://www.drupal.org/project/drupal/issues/3456964
Comment #12
cilefen commentedComment #13
mxr576Yes, this is a duplicate of #3456964: Unhandled exception when trying to register a duplicate username with equality mismatch between php and database layer. Thanks for letting me know!
Let's continue in that ticket.