Ticket #27774

ホスト側UTF-8ファイルのSJIS変換ダウンロードでクラッシュ

오픈 날짜: 2012-03-07 23:40 마지막 업데이트: 2012-07-02 22:19

Reporter:
(Anonymous)
소유자:
(None)
Type:
Status:
Closed
Component:
(None)
MileStone:
(None)
Priority:
5 - Medium
Severity:
5 - Medium
Resolution:
None
File:
3

Details

Windows7SP1(x64)で1.98eを使用(他のバージョンはチェックしていません)。ホスト側文字コードUTF-8、ローカル側文字コードSJISでファイルをダウンロードするとクラッシュ(動作を停止しました)する場合があります。

【再現方法】

1. ホスト側コードをUTF-8、ローカル側コードをSJISとする

2. ローカル側のffftp-1.98e-src\doc\jpn\FFFTP.txtをアップロード(UTF-8に変換)

3. ホスト側FFFTP.txtをダウンロードすると(SJISに変換を期待)、「動作を停止しました」ダイアログで終了となります。

デバッガで追いかけた限りだと、ConvUTF8NtoSJIS()の変換中にpUTF16バッファ終端にU+FFFDが現れた場合に文字数カウントがずれてcInfo->StrLenがマイナスになり、次回読み込みで巨大なmalloc()を試みてしまっているようです。バッファ内の条件に依存するようで、history.txtはうまくいきます。

Ticket History (3/12 Histories)

2012-03-07 23:40 Updated by: None
  • New Ticket "ホスト側UTF-8ファイルのSJIS変換ダウンロードでクラッシュ" created
2012-03-09 13:32 Updated by: s_kawamoto
댓글 올리기

ご報告ありがとうございます。 変換できたUTF-16から元のUTF-8の長さを求めるコードに問題があったようで、testブランチで修正しました。 http://git.sourceforge.jp/view?p=ffftp/ffftp.git;a=commit;h=a7acbb14a190ab47c087c1059b1d4742e637ef34

2012-03-09 22:42 Updated by: None
댓글 올리기

s_kawamoto への返信

ご報告ありがとうございます。 変換できたUTF-16から元のUTF-8の長さを求めるコードに問題があったようで、testブランチで修正しました。 http://git.sourceforge.jp/view?p=ffftp/ffftp.git;a=commit;h=a7acbb14a190ab47c087c1059b1d4742e637ef34

修正ありがとうございます。転送は終わるようになりましたが、境界にひっかかった箇所(以前はクラッシュ)の1文字で???への文字化けが発生しています。こう直せばよいってところまで追いきれていませんが、まずは現象だけの報告です。

2012-03-10 00:58 Updated by: s_kawamoto
댓글 올리기

修正前は潜在的なバグがあったものの、まず初めの報告の内容が再現できないのですが、修正後も不具合があるとするとお使いの環境に問題があるような気がします。 とりあえずコードページを明示的に指定してみました。 http://git.sourceforge.jp/view?p=ffftp/ffftp.git;a=commit;h=607cd5899fe0ff3692e440cc5fd27e1b21a6cd77

2012-03-11 12:43 Updated by: santa_report
댓글 올리기

s_kawamoto への返信

修正前は潜在的なバグがあったものの、まず初めの報告の内容が再現できないのですが、修正後も不具合があるとするとお使いの環境に問題があるような気がします。

再現できないとのことですので、1.98eのソース(testブランチではないです)に対してパッチを作成してみました。 ConvUTF8NtoSJIS()のみ修正しています。他のコード変換関数は見ていません。 ホスト側に置いたUTF-8のFFFTP.txtをUTF-8⇒SJIS変換で転送。初回0xd90バイト読み込みで試しています。Windows7で試しているので、WindowsXP以前で悪影響が無いかは未確認ですごめんなさい。

2012-03-12 00:48 Updated by: s_kawamoto
댓글 올리기

わざわざパッチまで作成していただきありがとうございます。 diffのコメントを読むと原因はWindows Vista以降で不完全な文字がU+FFFDに変換されることのようですが、U+FFFDを特別扱いすると、UTF-8側にU+FFFDが含まれている場合に処理できなくなるので、UTF-8とUTF-16 LE間の変換の処理を自前で実装し、Windows XPのMultiByteToWideChar()とWideCharToMultiByte()をエミュレートしてみました。 http://git.sourceforge.jp/view?p=ffftp/ffftp.git;a=commit;h=2fb62f9065c1e3df9d82414f4055f2d0747ae7ed

2012-03-12 22:01 Updated by: santa_report
댓글 올리기

s_kawamoto への返信

わざわざパッチまで作成していただきありがとうございます。 diffのコメントを読むと原因はWindows Vista以降で不完全な文字がU+FFFDに変換されることのようですが、U+FFFDを特別扱いすると、UTF-8側にU+FFFDが含まれている場合に処理できなくなるので、UTF-8とUTF-16 LE間の変換の処理を自前で実装し、Windows XPのMultiByteToWideChar()とWideCharToMultiByte()をエミュレートしてみました。 http://git.sourceforge.jp/view?p=ffftp/ffftp.git;a=commit;h=2fb62f9065c1e3df9d82414f4055f2d0747ae7ed

ご指摘の通り、UTF-8にU+FFFD(EF BF BD)が含まれている場合はUTF-16変換時に(FFFD)になっているのでパッチとしてはまずかったです。 また、その後みつけた文字コードまわりのセキュリティの話( http://gihyo.jp/admin/serial/01/charcode )を見ると、もっとよくよく考えてパッチかかないとダメでした。変なパッチ書いてごめんなさい。

一方、修正されたバージョンのRelease版EXEをダウンロードして試してみましたが0xd90バイト読み込んだ後の次の文字が化けてしまいました。

ソースからVC++2008 Express Editionでデバッグビルドして追いかけると、なぜか標準ランタイムのMultiByteToWideChar()とWideCharToMultiByte()が呼ばれていたようなので、それぞれAlternative()付きに書き換えてみましたが、UTF16Length = MultiByteToWideCharAlternative(CP_UTF8, 0, pUTF8, UTF8Length, pUTF16, UTF16Length); の戻り値が0になってしまってダメでした。

再現できないような環境依存の問題で、他の方で問題が起きないようでしたら、UTF-8/UTF-16間とはいえ自前変換はセキュリティリスクがあるので以前のバージョンで結構です。

2012-07-01 22:23 Updated by: s_kawamoto
댓글 올리기

ご迷惑おかけしました。 Windows Vista以降でUTF-8のテキストファイルやファイル名をShift_JISに変換する時に破損するバグを1.98fブランチで修正しましたのでご確認ください。 http://git.sourceforge.jp/view?p=ffftp/ffftp.git;a=commit;h=6e2f6a0d16d98a75a7e1f80470d01b1672e64727

2012-07-02 22:19 Updated by: s_kawamoto
  • Status Update from Open to Closed
  • Ticket Close date is changed to 2012-07-02 22:19

Attachment File List

  • 1.diff(4KB)
    • 1.98eに対するパッチ
  • FFFTP.txt(15KB)
    • ホスト側に置いたUTF-8のFFFTP.txt
  • 2.diff(4KB)
    • 1.98eに対するパッチ訂正版(memmove使用)

Edit

You are not logged in. I you are not logged in, your comment will be treated as an anonymous post. » Login