双方向制御文字(Bidi)とは?混入リスクと安全なコピペ手順
双方向制御文字(Bidi)とは?混入リスクと安全なコピペ手順
“見た目は同じなのに検索がヒットしない”“レビューで謎の差分が出る”──その原因が 双方向制御文字(Bidi) の可能性は高いです。本記事ではBidiの基礎、混入で起きる不具合、安全なコピペとレビューの手順をまとめます。最短での検出・除去は Invisible Cleaner が便利です。
Bidi(双方向制御)とは
アラビア語・ヘブライ語のように 右→左(RTL)、英語や日本語のように 左→右(LTR) が混在する文章において、表示方向や文字の並びを制御するための特殊文字(不可視文字)です。
代表的なものは以下のとおりです(名称 / 役割 / 例):
- LRE/RLE (U+202A/U+202B):以降を LTR/RTL として埋め込み表示
- LRO/RLO (U+202D/U+202E):以降を LTR/RTL として 強制 表示(順序固定)
- PDF (U+202C):埋め込みや上書きを終了
- LRM/RLM (U+200E/U+200F):長さ0の LTR/RTL マーク(細かな流れ調整)
- LRI/RLI/FSI/PDI (U+2066/U+2067/U+2068/U+2069):分離された埋め込み(近年の安全な制御法)
- ALM (U+061C):アラビア文字用マーク(方向を補助)
本来は正しいレイアウトのために必要ですが、意図せぬ混入で「見た目」と「実体(コードポイント列)」がズレ、トラブルを招きます。
何が起こる?(表示と実体のズレ)
例:見た目が同じでも文字列が違う
見た目: abc(); // call
実体A: a b c ( ) ; / / c a l l
実体B: a b c ( ) ; / / l l a c
上は極端な例ですが、RLO/LRO 等によって表示順が変わると、検索・一致判定・パース・差分比較が意図通りに動きません。
よくある不具合
- 検索・置換が当たらない(実体の順序が異なる)
- リンクやURL、タグが壊れる(属性名中のBidiでパース崩れ)
- コードレビューで不可解な差分(見た目では同じなのに変更扱い)
- セキュリティ・リスク(コメント内から実行部を“見えにくく”する等)
どこで混入する?
- SNSやWebサイトからの コピペ(翻訳・要約ツールも含む)
- メール件名/署名 の引用
- 多言語資料 の編集(右→左言語混在)
- Word/Docs/コードエディタ間の 相互コピー(書式付き→プレーン化の過程で)
安全なコピペ手順(最短ルート)
- プレーンテキストで貼り付け(「形式を選択して貼り付け」やプレーン化ショートカットを使用)。
- 検出→プレビュー:
- ブラウザの Invisible Cleaner に貼り付け、Bidi を検出。
- 差分プレビューで意味が変わらないか確認。
- 最小限の置換:RLO/RLE/LRO/LRE/FSI/LRI/RLI/PDI 等の制御目的のない混入のみを削除。
- 再検証:検索や整形、ビルドが期待通り動くかを再チェック。
ポイント:無差別な削除は厳禁。LTR/RTL を本当に必要とする文章では、LRM/RLM/FSI…が意味を持つことがあります。
開発時・レビュー時のチェックリスト
- 差分は 表示用UIだけでなく Raw 表示 でも確認したか
- エディタの 不可視文字表示 をONにしているか
- 検索は コードポイント(正規表現) でも行ったか
- 外部テキストの流入(翻訳・SNS)部分は 一括検査 したか
- 変更の直前直後で ビルド/テスト を回して差分を確認したか
簡易検出パターン(JS/PCRE系想定)
[--] # Bidi制御の代表集合
-
… LRE/RLE/LRO/RLO/PDF-
… LRI/RLI/FSI/PDI
… LRM/RLM
…… ALM
まずは 検出のみ 実行し、削除はプレビューで問題ない箇所に限定しましょう。
チームに導入する運用
- コミットフック(pre-commit) で検出:対象拡張子に上記正規表現を当て、ヒット時は警告。
- リンター/CI に“不可視文字チェック”を追加:ログで位置を明示。
- 規約テンプレ:PR説明に「外部からのコピペ部分」「多言語テキスト」の有無を明記。
- 教育:短い社内ドキュメントで Bidiとは と 対処フロー を共有。
まとめ(運用の勘所)
- Bidi は“正しい表示”のための仕組みだが、意図せぬ混入は不具合やリスクに直結。
- コピペは プレーン化→検出→最小置換 の三段階で安全に。
- レビューは Raw表示+自動チェック を併用して見落としを減らす。
- 迷ったら Invisible Cleaner で見える化してから判断する。
付録:主なBidi制御文字の早見表
文字 | コードポイント | 役割の概要 |
---|---|---|
LRE | U+202A | LTR 埋め込み開始 |
RLE | U+202B | RTL 埋め込み開始 |
U+202C | 埋め込み終了 | |
LRO | U+202D | LTR 上書き(強制) |
RLO | U+202E | RTL 上書き(強制) |
LRM | U+200E | LTR マーク |
RLM | U+200F | RTL マーク |
LRI | U+2066 | 分離LTR埋め込み開始 |
RLI | U+2067 | 分離RTL埋め込み開始 |
FSI | U+2068 | 分離 埋め込み(方向未定)開始 |
PDI | U+2069 | 分離埋め込み終了 |
ALM | U+061C | アラビア文字向けマーク |
実運用では、FSI/LRI/RLI/PDI を中心とした「分離された埋め込み」の利用が推奨されるケースが多く、安全性が高い傾向にあります。