From bac3c992798f17b40f6389180b3a3314f08258d6 Mon Sep 17 00:00:00 2001 From: Hsukqi Lee Date: Thu, 3 Sep 2026 15:35:43 +0800 Subject: [PATCH 1/2] fix(core): preserve UTF-8 system tag names Use UTF-8-aware byte truncation for system tag names so multibyte characters are not split when names are limited to 64 bytes. Add regression coverage for creating, retrieving, and updating tags with multibyte names. Assisted-by: OpenCode:gpt-5.6-sol Signed-off-by: Hsukqi Lee --- lib/private/SystemTag/SystemTagManager.php | 6 +++--- tests/lib/SystemTag/SystemTagManagerTest.php | 21 +++++++++++++++++++- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/private/SystemTag/SystemTagManager.php b/lib/private/SystemTag/SystemTagManager.php index c05062d6c1194..145f1bde12036 100644 --- a/lib/private/SystemTag/SystemTagManager.php +++ b/lib/private/SystemTag/SystemTagManager.php @@ -140,7 +140,7 @@ public function getAllTags($visibilityFilter = null, $nameSearchPattern = null): #[\Override] public function getTag(string $tagName, bool $userVisible, bool $userAssignable): ISystemTag { // Length of name column is 64 - $truncatedTagName = substr($tagName, 0, 64); + $truncatedTagName = mb_strcut($tagName, 0, 64, 'UTF-8'); $result = $this->selectTagQuery ->setParameter('name', $truncatedTagName) ->setParameter('visibility', $userVisible ? 1 : 0) @@ -185,7 +185,7 @@ public function createTag(string $tagName, bool $userVisible, bool $userAssignab } // Length of name column is 64 - $truncatedTagName = substr($tagName, 0, 64); + $truncatedTagName = mb_strcut($tagName, 0, 64, 'UTF-8'); $query = $this->connection->getQueryBuilder(); $query->insert(self::TAG_TABLE) ->values([ @@ -251,7 +251,7 @@ public function updateTag( $newName = Util::sanitizeWordsAndEmojis($newName); // Length of name column is 64 - $truncatedNewName = substr($newName, 0, 64); + $truncatedNewName = mb_strcut($newName, 0, 64, 'UTF-8'); $afterUpdate = new SystemTag( $tagId, $truncatedNewName, diff --git a/tests/lib/SystemTag/SystemTagManagerTest.php b/tests/lib/SystemTag/SystemTagManagerTest.php index 80f327fafb9ba..1aebe2c7b7bac 100644 --- a/tests/lib/SystemTag/SystemTagManagerTest.php +++ b/tests/lib/SystemTag/SystemTagManagerTest.php @@ -248,7 +248,26 @@ public function testCreateDuplicateWithDifferentFlags(): void { public function testCreateOverlongName(): void { $tag = $this->tagManager->createTag('Zona circundante do Palácio Nacional da Ajuda (Jardim das Damas, Salão de Física, Torre Sineira, Paço Velho e Jardim Botânico)', true, true); - $this->assertSame('Zona circundante do Palácio Nacional da Ajuda (Jardim das Damas', $tag->getName()); // 63 characters but 64 bytes due to "á" + $this->assertSame('Zona circundante do Palácio Nacional da Ajuda (Jardim das', $tag->getName()); + $this->assertSame($tag->getName(), $this->tagManager->getTag($tag->getName(), true, true)->getName()); + } + + public function testUpdateOverlongName(): void { + $tag = $this->tagManager->createTag('initial', true, true); + + $this->tagManager->updateTag( + $tag->getId(), + 'Zona circundante do Palácio Nacional da Ajuda (Jardim das Damas, Salão de Física, Torre Sineira, Paço Velho e Jardim Botânico)', + true, + true, + null, + ); + + $this->assertSame('Zona circundante do Palácio Nacional da Ajuda (Jardim das', $this->tagManager->getTag( + 'Zona circundante do Palácio Nacional da Ajuda (Jardim das', + true, + true, + )->getName()); } #[\PHPUnit\Framework\Attributes\DataProvider('oneTagMultipleFlagsProvider')] From 43442eb2203558fef05d42f21bf2862a53592ab5 Mon Sep 17 00:00:00 2001 From: Hsukqi Lee Date: Thu, 3 Sep 2026 16:45:58 +0800 Subject: [PATCH 2/2] test(core): cover UTF-8 system tag updates Add regression coverage for reading and updating multibyte system tag names. Assisted-by: OpenCode:gpt-5.6-sol Signed-off-by: Hsukqi Lee --- tests/lib/SystemTag/SystemTagManagerTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/lib/SystemTag/SystemTagManagerTest.php b/tests/lib/SystemTag/SystemTagManagerTest.php index 1aebe2c7b7bac..bc7655d8ef99e 100644 --- a/tests/lib/SystemTag/SystemTagManagerTest.php +++ b/tests/lib/SystemTag/SystemTagManagerTest.php @@ -248,7 +248,7 @@ public function testCreateDuplicateWithDifferentFlags(): void { public function testCreateOverlongName(): void { $tag = $this->tagManager->createTag('Zona circundante do Palácio Nacional da Ajuda (Jardim das Damas, Salão de Física, Torre Sineira, Paço Velho e Jardim Botânico)', true, true); - $this->assertSame('Zona circundante do Palácio Nacional da Ajuda (Jardim das', $tag->getName()); + $this->assertSame('Zona circundante do Palácio Nacional da Ajuda (Jardim das Damas', $tag->getName()); $this->assertSame($tag->getName(), $this->tagManager->getTag($tag->getName(), true, true)->getName()); } @@ -263,8 +263,8 @@ public function testUpdateOverlongName(): void { null, ); - $this->assertSame('Zona circundante do Palácio Nacional da Ajuda (Jardim das', $this->tagManager->getTag( - 'Zona circundante do Palácio Nacional da Ajuda (Jardim das', + $this->assertSame('Zona circundante do Palácio Nacional da Ajuda (Jardim das Damas', $this->tagManager->getTag( + 'Zona circundante do Palácio Nacional da Ajuda (Jardim das Damas', true, true, )->getName());