misskey-dev / misskey

🌎 An interplanetary microblogging platform 🚀
https://misskey-hub.net/
GNU Affero General Public License v3.0
9.81k stars 1.32k forks source link

frontend: CW内のテキストに非BMP文字が入っていた場合UTF-16のコードポイント数が文字数として表示されてしまう #11761

Open KisaragiEffective opened 1 year ago

KisaragiEffective commented 1 year ago

💡 Summary

CW付きノートの本文にUnicodeのBMP外文字が含まれているとUTF-16でエンコードした時のコードポイントの数と実際に期待する「文字数」(※ここではUnicodeのコードポイントの数を指します)が食い違ってしまいます。

例: 「1️⃣」とだけ入力すると「1」になって欲しいですが「2」になります。

原因はString.prototype.lengthを使っていることです:

https://github.com/misskey-dev/misskey/blob/e82c2e7cf9c52c7b1bfeedebff291bb22ae064c3/packages/frontend/src/components/MkCwButton.vue#L30

これはspread operatorを使って[...text].lengthとすることで回避できます。

🥰 Expected Behavior

Unicodeコードポイントの数などのより「直感的な方法」でカウントする

🤬 Actual Behavior

UTF-16としてエンコードした時のワード数で表示されている

📝 Steps to Reproduce

  1. 「1️⃣」など何でもいいので入力する
  2. CWをつける
  3. 「2」と表示される

📌 Environment

💻 Frontend

🛰 Backend (for server admin)

yuriha-chan commented 1 year ago

私の環境(Chrome on Windows)ですが

文字 構成 str.length [...str].length
1️⃣ 1, バリエーションセレクタ16(0xFE0F), 組み合わせ囲み記号 3 3
辻󠄀 , バリエーションセレクタ17(0xE0100) 3 2
🍭 🍭 (0x1F36D) 2 1

(おそらく)パフォーマンスが問題になる場面でもないですし、とりあえず[...str].lengthの方がベターかと思います。