SIN@SAPPOROWORKSの覚書

C#を中心に、夜な夜な試行錯誤したコードの記録です。

System.Uri.UnescapeDataString は、Firefoxで例外発生の可能性がある (#C)

URLエンコード/デコードを行う場合、「.NET 4.0」だとSystem.Web.HttpUtility.UrlDecode、
「.NET 4.0 Client Profile」の場合、System.Uri.UnescapeDataStringを使用することになります。

この際、UrlDecodeは、エンコード形式を選びませんが、UnescapeDataString は、UTF-8以外でエンコードされたURLを飲み込み例外が発生します。

http://smdn.jp/programming/tips/urlunescape_netfx2/




現在、一般に使用されているブラウザでUTF-8以外のURLエンコードを送ってくるのは、Firefoxぐらいのようなので、問題に気が付かないまま、リリースされる可能性があるかもしれません。

なお、Firefoxのデフォルト設定では、表示中のページのエンコードに合わせてURLエンコードの形式を決定するようなので、表示しているページが、たまたまUTF-8だったら問題が発生しないので、さらに気が付きにくいと思われます。

Firefoxで常にURL-8でURLエンコードするオプションも存在します。(デフォルト値の変更)
http://translate.googleusercontent.com/translate_c?hl=ja&langpair=en%7Cja&rurl=translate.google.co.jp&u=http://kb.mozillazine.org/Network.standard-url.encode-utf8&usg=ALkJrhivx6vm5GCnJQEHOt61hGyVUQpVbQ

「.NET 4.0 Client Profile」をターゲットにした場合、URLのデコードで、UnescapeDataStringを使用する事になりますが、UTF-8のみ使用する」と決め打ちできない場合、これを使用する事は危険かも知れません。

下記は、URLデコードをライブラリを使用せず自前で実装した例です。

string UrlDecode(string s,Encoding enc) {
  var b = new List<byte>();
  for (int i = 0; i < s.Length; i++) {
    switch (s[i]) {
      case '%':
        b.Add((byte)int.Parse(s[++i].ToString() + s[++i].ToString(), NumberStyles.HexNumber));
        break;
      case '+':
        b.Add((byte)0x20);
        break;
      default:
        b.Add((byte)s[i]);
        break;
    }
  }
  return enc.GetString(b.ToArray(),0,b.Count);
}
エンコード形式を検出するコードは別途必要です。