From 033c94d076e3340a4a472d1b3f61ade5f22009ea Mon Sep 17 00:00:00 2001
From: Valerio Ponte <valerio.ponte@gmail.com>
Date: Wed, 20 Mar 2013 22:37:02 +0100
Subject: [PATCH] fixed xsendfile zip generation race condition

---
 lib/files.php  | 18 ++++++++----------
 lib/helper.php | 24 ++++++++++++++----------
 2 files changed, 22 insertions(+), 20 deletions(-)

diff --git a/lib/files.php b/lib/files.php
index 04ba51d9d2..ab7fa1ed09 100644
--- a/lib/files.php
+++ b/lib/files.php
@@ -59,11 +59,7 @@ class OC_Files {
 			$executionTime = intval(ini_get('max_execution_time'));
 			set_time_limit(0);
 			$zip = new ZipArchive();
-			if ($xsendfile) {
-				$filename = OC_Helper::tmpFileNoClean('.zip');
-			}else{
-				$filename = OC_Helper::tmpFile('.zip');
-			}
+			$filename = OC_Helper::tmpFile('.zip');
 			if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) {
 				exit("cannot open <$filename>\n");
 			}
@@ -78,6 +74,9 @@ class OC_Files {
 				}
 			}
 			$zip->close();
+			if ($xsendfile) {
+				$filename = OC_Helper::moveToNoClean($filename);
+			}
 			$basename = basename($dir);
 			if ($basename) {
 				$name = $basename . '.zip';
@@ -91,17 +90,16 @@ class OC_Files {
 			$executionTime = intval(ini_get('max_execution_time'));
 			set_time_limit(0);
 			$zip = new ZipArchive();
-			if ($xsendfile) {
-				$filename = OC_Helper::tmpFileNoClean('.zip');
-			}else{
-				$filename = OC_Helper::tmpFile('.zip');
-			}
+			$filename = OC_Helper::tmpFile('.zip');
 			if ($zip->open($filename, ZIPARCHIVE::CREATE | ZIPARCHIVE::OVERWRITE)!==true) {
 				exit("cannot open <$filename>\n");
 			}
 			$file = $dir . '/' . $files;
 			self::zipAddDir($file, $zip);
 			$zip->close();
+			if ($xsendfile) {
+				$filename = OC_Helper::moveToNoClean($filename);
+			}
 			$name = $files . '.zip';
 			set_time_limit($executionTime);
 		} else {
diff --git a/lib/helper.php b/lib/helper.php
index 73484ad913..d178c3dc50 100644
--- a/lib/helper.php
+++ b/lib/helper.php
@@ -541,13 +541,15 @@ class OC_Helper {
 	}
 
 	/**
-	 * create a temporary file with an unique filename. It will not be deleted
-	 * automatically
-	 * @param string $postfix
-	 * @return string
+	 * move a file to oc-noclean temp dir
+	 * @param string $filename
+	 * @return mixed
 	 *
 	 */
-	public static function tmpFileNoClean($postfix='') {
+	public static function moveToNoClean($filename='') {
+		if ($filename == '') {
+			return false;
+		}
 		$tmpDirNoClean=get_temp_dir().'/oc-noclean/';
 		if (!file_exists($tmpDirNoClean) || !is_dir($tmpDirNoClean)) {
 			if (file_exists($tmpDirNoClean)) {
@@ -555,10 +557,12 @@ class OC_Helper {
 			}
 			mkdir($tmpDirNoClean);
 		}
-		$file=$tmpDirNoClean.md5(time().rand()).$postfix;
-		$fh=fopen($file, 'w');
-		fclose($fh);
-		return $file;
+		$newname=$tmpDirNoClean.basename($filename);
+		if (rename($filename, $newname)) {
+			return $newname;
+		} else {
+			return false;
+		}
 	}
 
 	/**
@@ -597,7 +601,7 @@ class OC_Helper {
 	}
 
 	/**
-	 * remove all files created by self::tmpFileNoClean
+	 * remove all files in PHP /oc-noclean temp dir 
 	 */
 	public static function cleanTmpNoClean() {
 		$tmpDirNoCleanFile=get_temp_dir().'/oc-noclean/';
-- 
GitLab