Menu

#167 長すぎるファイルパスのオープン・クローズで落ちる

closed
nobody
Source (92)
5
2012-11-09
2008-06-25
nasukoji
No

長すぎるパスのファイルを開いくと異常終了する。
また、保存しようとすると、絶対パスが _MAX_PATH
未満となるようにファイル名が切り詰められる。

ANSI版のGetOpenFileName()およびGetSaveFileName()
が _MAX_PATH以上の絶対パスが指定されてもエラーを
返さず、かつバッファ内に'\0'を書かないため、
バッファを突き抜けてしまう。

下記の関数において、GetOpenFileName()または
GetSaveFileName()を呼び出した後バッファの内容を
チェックし'\0'が無ければエラーを表示して指令を
キャンセルする。
unicode版では長いパスを正しく扱えるので、ANSI版
では無理に対応を試みない。

DoModalOpenDlg()
 DoModalSaveDlg()
 DoModal_GetOpenFileName()
 DoModal_GetSaveFileName()

関連議論
dev:5363
data:6689
dev:4733
data:5941

Discussion

  • nasukoji

    nasukoji - 2008-06-25

    長すぎるファイルパスのオープン・クローズで落ちる

     
  • Moca

    Moca - 2008-06-26

    Logged In: YES
    user_id=1393397
    Originator: NO

    ・エクスプローラ上のダブルクリック/実行ファイルへのD&D
    ・CMDからの直接起動
    ・タグジャンプでの起動
    などで、サクラ自体が落ちてしまっていたので、
    なすこじさんのパッチで未対処の部分をとりあえず別のパッチとして作りました。
    ついでにメニューでMAX_PATH近いファイル名が切れるのを修正しました。
     対処方法は、(Open|Save)FileName側と同じ、
    警告ダイアログを表示して、ファイル名を空にするだけです。
    相対パスを開いた場合で、フルにすると切れるときは
    そのまま相対パスになります。(現状維持)
    File Added: maxpath_cmd.diff

     
  • Moca

    Moca - 2008-06-26

    コマンドライン経由で長すぎるパスで落ちる対策パッチ

     
  • nasukoji

    nasukoji - 2008-06-27

    エラーとならないことがある不具合を修正、maxpath_cmdの取り込み

     
  • nasukoji

    nasukoji - 2008-06-27

    Logged In: YES
    user_id=1930530
    Originator: YES

    260バイト目がSJISの1バイト目だとエラーとならないことが
    あったのを修正しました。
    また、もかさん作成のmaxpath_cmd.diffを取り込みました。

    その他メモ:
    Windows98では妙なエラーで落ちることがありましたが、
    ファイルオープン・セーブで即座に異常終了することは
    ありませんでした。
    NULLを含まずに260バイト以上の絶対パスは指令が無視
    されます。
    また、ダイアログで指定した場合、API側にてパスがNULLを
    含まずに258バイトに切り詰められてしまいます。
    したがってWindows98は本修正の対象外です(修正が適用
    されても動作が変化しません)

    File Added: FixPathLengthOverflow02.patch

     
  • nasukoji

    nasukoji - 2008-07-27

    Logged In: YES
    user_id=1930530
    Originator: YES

    編集ウィンドウへのドロップ時の対応を追加しました。

    Win98では、'\0'を含めて261バイトちょうどのパスの
    場合にサクラエディタが落ちてしまうことがあります。
    落ちない場合もあります。
    262バイト以上のパスであれば落ちないようです。

    WinAPIのGetLongPathName()で落ちているのまでは
    分かりましたが、それ以上は調べていないので対処法は
    不明です。

    File Added: FixPathLengthOverflow03.patch

     
  • nasukoji

    nasukoji - 2008-07-27

    編集ウィンドウへのドロップに対応

     
  • Genta

    Genta - 2008-11-22

    CheckPathLengthOverflowを使ったチェックが4箇所ありますが
    GetOpenFileNameRecover/GetOpenFileNameRecover に入れてしまった方が
    スマートかなと思います.
    DlgOpenFail() のエラー処理を拡張しなくてもCommDlgExtendedError()の結果が0なら
    ユーザがキャンセルしたのと同様の扱いになるようなので問題ないように見えます.

    マクロでファイル名を扱うケースが抜けているのでは?と思ったのですが,
    開く方は一般的にGetLongFileName() で対策されていますね.
    反対の保存側を見てみると,CEditDoc::FileWrite() で呼び出される MakeBackUp() での
    チェックが行われていないようです.バックアップは元のファイル名より長くなる場合もありますので
    注意が必要です.

    # ローカルディスクでは長すぎるファイルというのは作れないんですね.
    # 長すぎるよとExplorerに怒られます.
    # なので動作試験はできていません.

     
  • nasukoji

    nasukoji - 2008-11-23

    チェック位置の変更とバックアップファイルへの対応の追加

     
  • nasukoji

    nasukoji - 2008-11-23

    チェックをDoModal...()の関数からGetOpenFileNameRecover()/GetSaveFileNameRecover()
    に移動しました。
    また、バックアップファイル作成時のファイルパスもチェックするようにしました。

    前回は気が付きませんでしたが、上書き確認の後にパス長確認になっています。
    なので、フックを使わない場合上書き確認でOKした後パス長でエラーとなります。
    フックを使う場合、プロシージャ内で_MAX_PATH未満にパスを切り詰めているので
    上書き確認できず、たまたまパス長エラーだけが表示されます。
    (切り詰めたパス名と同名ファイルがあると上書き確認される)

    セーブダイアログは必ずフックを使用しプロシージャ内でもパス長チェックする
    のが理想的と思いますが、今回そこまでは修正していません。

    260バイト以上のパス長のファイルは、"C:\a"のような1文字フォルダに長い
    ファイル名のファイルを作成しフォルダ名を変更すると作成可能です。

    File Added: FixPathLengthOverflow04.patch

     
  • nasukoji

    nasukoji - 2008-11-25

    バックアップファイルのパス作成時のチェックを強化しました。
    File Added: FixPathLengthOverflow05.patch

     
  • nasukoji

    nasukoji - 2008-11-25

    バックアップファイルのパス作成時のチェックを強化

     
  • Genta

    Genta - 2008-11-25

    CEditDoc 1799行目
    拡張子置換処理で,bOverflow = true;の後ろにbreak;が抜けてますね.
    バックアップパターンに *_*_*_*_*_*_* と入れると
    バッファオーバーランします.

    そこだけ修正すればcommitしても良いと思います.

     
  • nasukoji

    nasukoji - 2008-11-26

    breakが抜けていたので追加

     
  • nasukoji

    nasukoji - 2008-11-26

    抜けていたbreakを追加しrev1474でコミットしました。

    File Added: FixPathLengthOverflow06.patch

     

Log in to post a comment.

MongoDB Logo MongoDB