From 79789735676f27d2c0bf054ef4f403f0e6edd180 Mon Sep 17 00:00:00 2001 From: albertlast Date: Fri, 4 Sep 2026 23:32:15 +0200 Subject: [PATCH] Measures a display name against the column that has to hold it The display name limit is 60 characters, counted with entityStrlen() on a value that has already been entity encoded, so it counts what was typed. What real_name stores is the encoded form, where a double quote is six characters and an ampersand five, and that column holds 255. A name of 43 double quotes is therefore 43 characters to the validator, comfortably inside the limit, and 258 in the column. Saving it dies with "Data too long for column 'real_name'" out of User::updateMemberData(). Registration has the same gap from the other direction: it checks the raw value against 60 and encodes it afterwards. Checks the encoded width alongside the typed length in both places, so a name that cannot be stored is refused by the form that offered it. Co-Authored-By: Claude Opus 5 Signed-off-by: albertlast --- Sources/Actions/Register2.php | 7 ++++++- Sources/Profile.php | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Sources/Actions/Register2.php b/Sources/Actions/Register2.php index d70f3a486a..a0f27cd102 100644 --- a/Sources/Actions/Register2.php +++ b/Sources/Actions/Register2.php @@ -212,8 +212,13 @@ function (&$value, $key) { Db::$db->free_result($request); } + // What gets stored is the entity encoded form of the name, which is + // wider than what was typed wherever a character needs an entity, + // and real_name holds 255 characters. + $encoded_name = Utils::htmlspecialchars($_POST['real_name'], ENT_QUOTES); + // Only set it if you can and if we are sure it is good - if ($can_edit_display_name && Utils::htmlTrim($_POST['real_name']) != '' && !Security::isReservedName($_POST['real_name']) && Utils::entityStrlen($_POST['real_name']) < 60) { + if ($can_edit_display_name && Utils::htmlTrim($_POST['real_name']) != '' && !Security::isReservedName($_POST['real_name']) && Utils::entityStrlen($_POST['real_name']) < 60 && mb_strlen($encoded_name) <= 255) { $this->possible_strings[] = 'real_name'; } } diff --git a/Sources/Profile.php b/Sources/Profile.php index 0ddd3d12ce..2711ccb38a 100644 --- a/Sources/Profile.php +++ b/Sources/Profile.php @@ -698,7 +698,12 @@ public function loadStandardFields(bool $force_reload = false): void return 'no_name'; } - if (Utils::entityStrlen($value) > 60) { + // The name is stored with entities in place of the characters + // that need them, so it is wider in the column than it was in + // the box: a double quote costs six characters there, an + // ampersand five. real_name holds 255, and a name inside the + // 60 character limit can still be wider than that. + if (Utils::entityStrlen($value) > 60 || mb_strlen($value) > 255) { return 'name_too_long'; }