文字コード総合スレ part15 (338レス)
前次1-
抽出解除 必死チェッカー(本家) (べ) 自ID レス栞 あぼーん

193: デフォルトの名無しさん [sage] 2025/01/20(月) 21:45:49.79 ID:fFffNKjx(1/9) AAS
勘違いしてる人がいるため正しい情報

まずRustの文字列つまりstr型とString型はvalidなUTF-8のみであることが必ず保証されている
そこには当然サロゲートもなければinvalidなUTF-8もないため問題は一切起きない
そこにWTF-8など他のものが混ざることも絶対にない
つまりどんな文字列操作をしても冗長表現のない
validなUTF-8となる安全が保証されている

つづく
194: デフォルトの名無しさん [sage] 2025/01/20(月) 21:46:25.68 ID:fFffNKjx(2/9) AAS
次に言語とは関係ない話
validなUTF-16は必ずサロゲートがペアとして対応するが
それに対してWindowsのUTF-16パス名などあちこちの環境でinvalidなUTF-16が使われている
つまり単なる16bitコード列として任意のものが通るinvalidなUTF-16を名付けてWTF-16と呼ぶ
UTFを擬してWTFはWobbly Transformation Formatの略である
集合としてはinvalidなものを含む分だけ大きくてWTF-16⊃UTF-16となる

つづく
195
(1): デフォルトの名無しさん [sage] 2025/01/20(月) 21:47:00.81 ID:fFffNKjx(3/9) AAS
UTF-16⇔UTF-8は常に可逆に変換できる
前述のWTF-16に対しても同様に可逆となるものとしてWTF-8が考えられる
つまりWTF-16⇔WTF-8は常に可逆に変換できる
前述のWTF-16⊃UTF-16と同様に
WTF-8⊃UTF-8となる
このWTF-8はあくまでもWTF-16との可逆を保証するための内部表現であり外で使われることはない

つづく
196: デフォルトの名無しさん [sage] 2025/01/20(月) 21:48:06.23 ID:fFffNKjx(4/9) AAS
このWTF-8には以下の利点がある
・WTF-16(=任意の16bit列)と可逆に1対1に変換できる
・元のWTF-16がUTF-16のみの場合は対応するWTF-8はUTF-8のみとなる
・特に元がアスキー文字のみならば対応するWTF-8は7bitアスキー文字となる

集合関係はWTF-8⊃UTF-8⊃7bitアスキー文字となる
つまり内部表現として非常に使い勝手が良いものとなっている

つづく
197: デフォルトの名無しさん [sage] 2025/01/20(月) 21:49:23.00 ID:fFffNKjx(5/9) AAS
そしてようやく再びRustの話
Rustでは言語の外の世界とをつなぐFFI (Foreign Function Initerface)の一つとして
OS環境依存の文字列型としてOsString型とOsStr型がある
これはvalidなUTF-8文字列型であるString型とstr型にそれぞれ対応する
集合的にはOsString⊃StringとOsStr⊃strとなりinvalidなUTF-8を含む分だけ大きな集合を表す
Windows環境ではこの内部表現として前述のWTF-8が使われている

つづく
198
(1): デフォルトの名無しさん [sage] 2025/01/20(月) 21:50:56.30 ID:fFffNKjx(6/9) AAS
>>177
177(5): デフォルトの名無しさん [sage] 2025/01/18(土) 03:52:04.02 ID:CaguG0TX(1/7) AAS
RustがWindowsでファイル名を扱う時のWTF-8、あれ脆弱性の元な気がするんだよな…
WTF-8状態でサロゲートペアの前後を結合してしまうとUTF-8のとはまた別の冗長表現が導入されてしまう
>>190
190(2): デフォルトの名無しさん [sage] 2025/01/18(土) 12:03:49.92 ID:CaguG0TX(7/7) AAS
>>188-189
型としてはOsStringとしてラップされてて、中身を取り出したらWindowsではWTF-8
不正な文字コードが入りうるのはどのOSでも同じだけどバイト列そのままな他OSと異なりWindowsだとUTF-16との変換も挟まって危なそうだなあって

(ちなmacOSやあとBSDのzfsなんかだと不正な文字コードは最初から入らないらしい?)
WTF-8を新たに作り出すにはvalidなUTF-8から作るか
あるいは16bit列から作るかのどちらかしか手段がない
つまり必ずWTF-16(=任意の16bit列)⇔WTF-8は1対1に対応する
したがってあなたが主張する
「別の冗長表現」は生じることはなく危険なことは絶対に起こらない
207
(1): デフォルトの名無しさん [sage] 2025/01/20(月) 23:19:38.23 ID:fFffNKjx(7/9) AAS
>>204
204(3): デフォルトの名無しさん [sage] 2025/01/20(月) 22:51:08.98 ID:uZ5HVjRv(1/3) AAS
WTF-8 どうしを結合するときは終端処理をしてサロゲートの変換をしないといけない
UTF-8 のように単純に結合することできない
両サロゲートが含まれてるものはWTF-8ではない
そこで問題は生じない
WTF-8の2つの文字(列)の結合は
個別にWTF-16へ変換してからWTF-16として結合してそれをWTF-8へ変換したもの
と同等になるように処理が定義されている
つまり結合後も必ずWTF-8とWTF-16は1対1に対応する

WTF-8の2つの文字(列)をAとBとし結合を+で表すと
A + B ≡ to-WTF-8(to-WTF-16(A) + to-WTF-16(B))
が常に成り立ち1対1に可逆が保証される
別の冗長表現は生じない
211: デフォルトの名無しさん [sage] 2025/01/20(月) 23:45:27.35 ID:fFffNKjx(8/9) AAS
>>209
209(3): デフォルトの名無しさん [sage] 2025/01/20(月) 23:27:17.08 ID:fw0guZsp(4/5) AAS
>>206
OSがファイル名として扱えるバイナリ列を作れないのはむしろそちらのほうが問題になるので
失敗させるのはナシでは

>>206-207
で、今ソースを追いかけていてpushに関しては
外部リンク[html]:stdrs.dev
>>204の処理がなされてるのを確認しました
つまりpushに関しては俺の杞憂でした(もちろん他の処理は別)
それは任意の16bit列に対応するWTF-8を作れるようになっているのでその場合も対応できて大丈夫
use std::os::windows::ffi::OsStringExt
OsString::from_wide(wide: &[u16])
つまりWTF-16⇔WTF-8は必ず1対1に対応するため別の冗長表現は生じず問題は起こらない
212
(1): デフォルトの名無しさん [sage] 2025/01/20(月) 23:52:28.98 ID:fFffNKjx(9/9) AAS
つまり話をまとめると
WTF-8の新規生成はUTF-8もしくはWTF-16(=任意の16bit列)からのみ生成できるため常にWTF-16と1対1に対応する
WTF-8の結合は個別にWTF-16にしてから結合してWTF-8に戻した処理と同等と定義されているため常にWTF-16と1対1に対応する
したがって問題が発生する箇所はない
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.895s*