添付ファイルダウンロードで日本語ファイル名が文字化けする

  • ページ: BugTrack2
  • 投稿者: umorigu
  • 優先順位: 重要
  • 状態: 完了
  • カテゴリー: 本体バグ
  • 投稿日: 2014-07-08 (火) 07:10:10
  • バージョン: 1.4.7_notb -> 1.5.0 で修正済み

メッセージ

添付ファイルが日本語ファイル名である場合、ダウンロード時に文字化けが発生します。

また、PHP5.4で動作させた場合、含まれている文字によっては "index" というファイル名でダウンロードされます。

環境

  • Internet Explorer 9以降 (IE8以前は文字化けしない)
  • Chrome, Firefox, Safari など他の多くのブラウザ

原因

attach.inc.php : 709 の open() で

 709  case 'MSIE/default':
 710    $filename = mb_convert_encoding($filename, 'SJIS', 'auto');
 711    break;
    ...
 714 $filename = htmlsc($filename);
 
 720 header('Content-Disposition: inline; filename="' . $filename . '"');

710行目で SJIS に変換しているが、これは古いIE(IE8以前)の動作にあわせた実装

714行目の htmlsc(htmlspecialchars)は、ここで使うのは適切でない。 SJISバイナリそのままhttp_outputに渡すのが元の意図と思われる。

ref.inc.php にも同じ問題がある。

解決策

2014年7月現在、多くのWebブラウザが RFC 6266 に対応しているので、RFC 6266 (Content-Disposition: filename*=utf-8''<rawurlencode_file_name>) を実装することで日本語を含むnon-ASCII文字を含むファイル名を正しくダウンロードできる。

また、旧実装(filename=)を残しておくことで古いブラウザに対しては今まで通りの動作となる。

リポジトリに取り込まれた実装

修正実装案

plugin/attach.inc.php

diff --git a/plugin/attach.inc.php b/plugin/attach.inc.php
index ce7f70e..355a428 100644
--- a/plugin/attach.inc.php
+++ b/plugin/attach.inc.php
@@ -711,13 +711,13 @@ EOD;
 				break;
 			}
 		}
-		$filename = htmlsc($filename);
+		$utf8filename = mb_convert_encoding($filename, 'UTF-8', 'auto');
 
 		ini_set('default_charset', '');
 		mb_http_output('pass');
 
 		pkwk_common_headers();
-		header('Content-Disposition: inline; filename="' . $filename . '"');
+		header('Content-Disposition: inline; filename="' . $filename . '"; filename*=utf-8\'\'' . rawurlencode($utf8filename));
 		header('Content-Length: ' . $this->size);
 		header('Content-Type: '   . $this->type);

URL: sourceforge.jp/users/umorigu/pf/pukiwiki15/scm/commits/b8dda6bf557989c0324c3002f242d997cd91cebd

plugin/ref.inc.php

diff --git a/plugin/ref.inc.php b/plugin/ref.inc.php
index cb3fe32..f0095cf 100644
--- a/plugin/ref.inc.php
+++ b/plugin/ref.inc.php
@@ -420,12 +420,12 @@ function plugin_ref_action()
 			break;
 		}
 	}
-	$file = htmlsc($filename);
+	$utf8filename = mb_convert_encoding($filename, 'UTF-8', 'auto');
 	$size = filesize($ref);
 
 	// Output
 	pkwk_common_headers();
-	header('Content-Disposition: inline; filename="' . $filename . '"');
+	header('Content-Disposition: inline; filename="' . $filename . '"; filename*=utf-8\'\'' . rawurlencode($utf8filename));
 	header('Content-Length: ' . $size);
 	header('Content-Type: '   . $type);
 	@readfile($ref);

URL: sourceforge.jp/users/umorigu/pf/pukiwiki15/scm/commits/b8dda6bf557989c0324c3002f242d997cd91cebd

補足

  • Safariなど、RFC 6266 に対応していないブラウザでは文字化けしたまま

  • たぶん関連: 開発日記/2004-11-11BugTrack/687BugTrack/743。 -- 2014-07-09 (水) 00:31:40
  • 今ではUTF-8標準が当たり前になっているので、原因の箇所でswitch-case分岐のdefaultをUTF-8変換にして、Mozilla/4.0以下(pukiwiki.ini.php のUser-Agent settings にはMozilla/3.0の古いブラウザもリストに残っている)などのHTML5に非対応のうち必要なものだけSJISで渡すぐらいでもいいのかもしれない? -- 2014-07-09 (水) 00:44:01
  • 関連BugTrackで気が付きました。refプラグインにも同じ実装がありますね。残念・・・ -- umorigu 2014-07-09 (水) 23:53:04
  • refプラグインの対応も追加しました。 -- umorigu 2014-07-12 (土) 10:56:00
  • 1.5.0 で修正されているので完了とします -- umorigu 2014-10-29 (水) 20:36:52
  • mb_convert_encodingのfrom_encodingパラメータがautoになっていたので、文字コード検知に失敗する可能性がありました(現象が確認されたわけではないですが)。明示的にSOURCE_ENCODINGを指定するように修正しました。この変更は1.5.1リリースに含まれる予定です -- umorigu 2016-02-07 (日) 18:23:21


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-02-07 (日) 18:23:21
Site admin: PukiWiki Development Team

PukiWiki 1.5.2+ © 2001-2019 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u7. HTML convert time: 0.190 sec.

OSDN