特定の環境下においてファイル名に濁音文字を含むファイルをアップロードした際、濁音文字がサロゲートペアとして扱われValidationに引っかかる問題
こちらの記事にまとめました
画像では、ファイル名の「パ(E3 83 91
)」が「パ」(=「ハ(E3 83 8F
)」+「・(E3 82 9A
)」)として扱われてる。Slackの絵文字追加では、サロゲートペア(結合文字)を弾いているので怒られる。
修正:(@2023/08/20 03:34 JST)
原文
本事象が発生する環境は以下の通り。
OS | Chip | Browser | |
---|---|---|---|
Ventura 13.5.1 | Apple M2 Pro | Chrome v116.0.5845.96 | |
Ventura 13.2 | Apple M2 Pro | Chrome v115.0.5790.170 | ※1 |
Monterey 12.6.4 | Apple M1 Max | Chrome v116.0.5845.96 |
逆に発生しない環境は以下の通り
OS | Chip | Browser | |
---|---|---|---|
Ventura 13.5.1 | Apple M2 Pro | Safari v16.6 (18615.3.12.11.2) | |
Ventura 13.4 | Apple M1 | Chrome v115.0.5790.170 | ※1 |
この条件から考えると、
特定環境下のChromeでのみ発生し、Safariでは発生しない、ただし、※1のように同一バージョンのChromeでも発生しないことがある模様。
以下、「特定環境下のChrome環境」を単に「特定環境下」と呼ぶ
本事象が発生する環境は以下の通り。
OS | Chip | Browser | |
---|---|---|---|
Ventura 13.5.1 | Apple M2 Pro | Chrome v116.0.5845.96 | |
Ventura 13.2 | Apple M2 Pro | Chrome v115.0.5790.170 | ※1 |
Ventura 13.4 | Apple M1 | Chrome v115.0.5790.170 | ※1 |
Monterey 12.6.4 | Apple M1 Max | Chrome v116.0.5845.96 |
逆に発生しない環境は以下の通り
OS | Chip | Browser | |
---|---|---|---|
Ventura 13.5.1 | Apple M2 Pro | Safari v16.6 (18615.3.12.11.2) |
この条件から考えると、
特定環境下のChromeでのみ発生し、Safariでは発生しない、 ただし、※1のように同一バージョンのChromeでも発生しないことがある 模様。
「パ(
E3 83 91
)」が「パ」(=「ハ(E3 83 8F
)」+「・(E3 82 9A
)」)として扱われる。
このことをUnicode正規化と言うらしい。
アップロード元のファイル名には「パ(E3 83 91
)」とされている。(確認方法があっているのかわからないが、、、finderからファイル名をコピーorVSCodeからファイル名をコピーして文字コードを確認)
特定環境下ではUnicode→UTF-8で正規化を行なっているのか?
単に<input type="file" />
でアップロードしたファイル名においても同様の事象が発生する。
なので、おそらくChromeのファイルアップロードの問題
この事象に遭遇したきっかけは、WindowsでZIPされた画像フォルダをmacでUNZIPしたときにファイル名の濁音文字が本事象のように結合文字として扱われ、Slack絵文字追加が行えなかったことがきっかけ。
ファイル名を直接書き換えたり、UNZIPの際に多種多様なツールを使ったりし、ファイル名に結合文字を含まない状況を作ることができた。
しかし、濁音文字だけ常にvalidationに引っかかったため、zipの問題ではなくフォームの問題と仮説を置いて本スクラップの調査を始めた。
お?
finderの一覧から名前を編集→「パ」=(E3 83 91
)
finderで情報を見る→「パ」(=「ハ(E3 83 8F
)」+「・(E3 82 9A
)」)
関係ありそう
NFC : Normalization Form Canonical Composition (合成した文字)
▶”が.txt”は”U+304C.txt”
NFD : Normalization Form Canonical Decomposition (結合文字列)
▶”が.txt”は”U+304C&U+3099.txt”
さてはmacが悪いな?
追記:
finderでファイルが開けない問題は解消されたみたいだけど、内部的にはNFDで扱っているからファイルアップロードで問題になるのか。
NFD→NFCに変換すれば良さそうではある
→結局ファイル名をNFDで管理するから意味ないか
いつかはApple側で修正してくれるだろうけど現段階ではmacユーザが気にしないといけないのか???
結合文字をvalidationしていないアプリなんてごまんとあるだろうから、同じ文字だけど文字コードは違う文字がDBに保存されている(=WHERE検索できない)プロダクトが大量にありそう。。。
ここまでまとめると
結論
- macではファイル名の文字コードをNFDで扱っている。
- そのためNFC/NFD問題が発生していた。
- finderで開けない問題は解消されている。
- Chromeでアップロードする際にはNFDのままファイル名を参照しているため、結合文字(二文字目の特殊文字)を良しとしないアプリではvalidationエラーが発生する。
- safariでは対応済み
解決策
- なし
その他、問題点
- NFDをvalidationしていないアプリはごまんとあるから、同じ文字だが文字コードが違い検索ヒットしないような文字列がDBに保存されているプロダクトが大量に存在する恐れあり?
- NFDをvalidationしていないアプリはごまんとあるから、同じ文字だが文字コードが違い検索ヒットしないような文字列がDBに保存されているプロダクトが大量に存在する恐れあり?
PostgreSQL 15.4でNFC/NFD問題の影響を確認してみた。
$ select * from hoge;
name
------
パ # E3 83 91
パ # E3 83 8F E3 82 9A
(2 rows)
$ select * from hoge where name='パ'; # E3 83 91
name
------
パ # E3 83 91
(1 row)
$ select * from hoge where name='パ'; # E3 83 8F E3 82 9A
name
------
パ # E3 83 8F E3 82 9A
(1 row)
当然引っかからない。
記事にまとめた