添付ファイルのリネーム時、バックアップファイルとログファイルがリネームがされない

  • ページ: BugTrack2
  • 投稿者: umorigu
  • 優先順位: 普通
  • 状態: 完了
  • カテゴリー: プラグイン
  • 投稿日: 2011-05-08 (日) 13:07:06
  • バージョン: 1.4.7
  • リリース予定バージョン: 1.5.1

メッセージ

内容

attachプラグインで添付ファイルのリネームができますが、物理ファイルのリネームは最新の1ファイルのみにしか行われておらず、過去に削除されたバックアップファイル(拡張子 .1, .2, ...)とステータスファイル(拡張子 .log)のリネームが行われていません。

結果として、バックアップファイルが失われる、ダウンロードカウンタがリセットされる、などの不具合が発生します。

条件

  • バックアップファイルの場合:
    • PLUGIN_ATTACH_DELETE_ADMIN_NOBACKUP が FALSE で、添付ファイル削除時にバックアップが残るケースにて
  • ステータスファイルの場合:
    • 常に

対策

diff --git a/attach.inc.php b/attach.inc.php
--- a/attach.inc.php
+++ b/attach.inc.php
@@ -672,10 +672,40 @@
 		if (file_exists($newbase)) {
 			return array('msg'=>$_attach_messages['err_exists']);
 		}
-		if (! PLUGIN_ATTACH_RENAME_ENABLE || ! rename($this->basename, $newbase)) {
+		if (! PLUGIN_ATTACH_RENAME_ENABLE) {
 			return array('msg'=>$_attach_messages['err_rename']);
+		} else {
+			if (! rename($this->basename, $newbase)) {
+				return array('msg'=>$_attach_messages['err_rename']);
+			}
+			// リネーム成功
+			// バックアップファイル・ログファイルもリネームする
+			// エラー処理は省略
+			$rename_targets = array();
+			if ($dir = opendir(UPLOAD_DIR)) {
+				$matches_leaf = array();
+				if (preg_match('/(((?:[0-9A-F]{2})+)_((?:[0-9A-F]{2})+))$/', $this->basename, $matches_leaf)) {
+					$attachfile_leafname = $matches_leaf[1];
+					$attachfile_leafname_pattern = preg_quote($attachfile_leafname, '/');
+					$pattern = "/^({$attachfile_leafname_pattern})(\.((\d+)|(log)))$/";
+					
+					$matches = array();
+					while ($file = readdir($dir)) {
+						if (! preg_match($pattern, $file, $matches))
+							continue;
+						$basename2 = $matches[0];
+						$newbase2 = $newbase . $matches[2];
+						$rename_targets[$basename2] = $newbase2;
+					}
+				}
+				closedir($dir);
+			}
+			foreach ($rename_targets as $basename2=>$newbase2) {
+				$basename2path = UPLOAD_DIR . $basename2;
+				echo "rename '$basename2path' to '$newbase2'<br>\n";
+				rename($basename2path, $newbase2);
+			}
 		}
-
 		return array('msg'=>$_attach_messages['msg_renamed']);
 	}

バックアップファイルを持つ a.txt を b.txt にリネームしたとき:

rename 'attach/41_612E747874.1' to 'attach/41_622E747874.1'
rename 'attach/41_612E747874.log' to 'attach/41_622E747874.log'

実装


コメント

  • 関連:
  • エラー処理・・・? -- henoheno 2011-05-08 (日) 23:06:17
  • echo "rename '$basename2path' to '$newbase2'<br>\n";とリネームログ?を直に出力してるから、スキン→(pkwk_common_headers()→pkwk_headers_sent())→PHPのheaders already sentエラーって意味ではないよなたぶん。
    if (! rename($this->basename, $newbase)) {
    	return array('msg'=>$_attach_messages['err_rename']);
    }
    のようなエラーメッセージ処理を入れていないという意味かなとエスパーしてみる -- 2011-05-09 (月) 03:40:39
  • ↑そういう意味です。(rename の失敗を無視している).ここはエラーになっても処理続行が望ましいと思いました。一番重要なrenameが成功した後なので -- umorigu 2011-05-09 (月) 22:37:24
  • (5年前の自分に対してですが)添付ファイルがリネームされたときに過去に削除された同名ファイルをリネームするのは一般的には正しくありませんね。statusファイル(.log)がリネームされないのはバグですので修正します -- umorigu 2016-01-26 (火) 02:48:43
  • (当時、EUC_JP→UTF-8移行を行っていて添付ファイル名を短くしたかったので問題をとり違えました) -- umorigu 2016-01-26 (火) 03:01:07
  • ↑と、書きましたが調査したところ、現状では同名の添付ファイルは.logファイルを共有するなど、まとめて扱うような設計になっています。今のタイミングで大幅な構造変更はしたくないので、リネームの際も追従してしまうことは仕様(現状の制約)として扱いたいと思います -- umorigu 2016-01-27 (水) 00:38:37
  • 修正しました -- umorigu 2016-01-27 (水) 01:00:01


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-01-27 (水) 01:00:01
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.223 sec.

OSDN