php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login

Patch 0001-Zip-fix-creating-archive-if-an-added-file-is-removed.patch for Zip Related Bug #66786

Patch version 2014-02-26 23:18 UTC

Return to Bug #66786 | Download this patch
Patch Revisions:

Developer: lists.ban@herbesfolles.org

From cdcebe7dd352f0cc6c356fd89af95481ee84643a Mon Sep 17 00:00:00 2001
From: Colomban Wendling <ban@herbesfolles.org>
Date: Thu, 27 Feb 2014 00:08:28 +0100
Subject: [PATCH] Zip: fix creating archive if an added file is removed before
 close()

To fix this, open the file right away when adding it, so later code
don't rely on its path.
---
 ext/zip/php_zip.c                |  8 +++---
 ext/zip/tests/removed_files.phpt | 53 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 58 insertions(+), 3 deletions(-)
 create mode 100644 ext/zip/tests/removed_files.phpt

diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c
index a4bdaf7..4da9d1a 100644
--- a/ext/zip/php_zip.c
+++ b/ext/zip/php_zip.c
@@ -327,6 +327,7 @@ static int php_zip_add_file(struct zip *za, const char *filename, size_t filenam
 	struct zip_source *zs;
 	char resolved_path[MAXPATHLEN];
 	zval exists_flag;
+	FILE *fp;
 
 
 	if (ZIP_OPENBASEDIR_CHECKPATH(filename)) {
@@ -337,13 +338,14 @@ static int php_zip_add_file(struct zip *za, const char *filename, size_t filenam
 		return -1;
 	}
 
-	php_stat(resolved_path, strlen(resolved_path), FS_EXISTS, &exists_flag TSRMLS_CC);
-	if (!Z_BVAL(exists_flag)) {
+	fp = fopen(resolved_path, "rb");
+	if (!fp) {
 		return -1;
 	}
 
-	zs = zip_source_file(za, resolved_path, offset_start, offset_len);
+	zs = zip_source_filep(za, fp, offset_start, offset_len);
 	if (!zs) {
+		fclose(fp);
 		return -1;
 	}
 	if (zip_file_add(za, entry_name, zs, ZIP_FL_OVERWRITE) < 0) {
diff --git a/ext/zip/tests/removed_files.phpt b/ext/zip/tests/removed_files.phpt
new file mode 100644
index 0000000..50cc080
--- /dev/null
+++ b/ext/zip/tests/removed_files.phpt
@@ -0,0 +1,53 @@
+--TEST--
+ZipArchive::addFile() should handle files removed after it but before ::close()
+--SKIPIF--
+<?php
+	if(!extension_loaded('zip')) die('skip');
+?>
+--FILE--
+<?php
+
+$file = dirname(__FILE__) . '/removed_files.zip';
+$zip = new ZipArchive;
+$res = $zip->open($file, ZipArchive::CREATE | ZipArchive::OVERWRITE);
+if ($res === TRUE) {
+	$f = tempnam(dirname(__FILE__), 'removed_files');
+	echo "$f\n";
+	file_put_contents($f, 'hello');
+	$res = $zip->addFile($f, 'sample');
+	unlink($f);
+	if (true == $res) {
+		echo "add ok\n";
+	} else {
+		echo "add failed\n";
+	}
+	$res = $zip->close();
+	if (true == $res) {
+		echo "close ok\n";
+	} else {
+		echo "close failed\n";
+	}
+	$s = filesize($file);
+	if ($s === false) {
+		echo "zip file doesn't exist\n";
+	} else if ($s > 0) {
+		echo "zip file size is $s\n";
+	} else {
+		echo "zip file is empty\n";
+	}
+} else {
+	echo "open failed\n";
+}
+
+?>
+DONE
+--CLEAN--
+<?php
+
+@unlink(dirname(__FILE__) . '/removed_files.zip');
+--EXPECTF--
+%sremoved_files%s
+add ok
+close ok
+zip file size is %d
+DONE
-- 
1.9.0

 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Tue Jun 18 09:01:27 2019 UTC