php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #57242 Files added with ZipArchive::addFile can't be opened (manually).
Submitted: 2006-09-15 08:50 UTC Modified: 2006-11-28 12:06 UTC
From: d dot o dot m dot e at gmx dot net Assigned: pajoye (profile)
Status: Closed Package: zip (PECL)
PHP Version: 5_2 CVS-2006-09-15 OS: Windows XP Home (SP2).
Private report: No CVE-ID: None
 [2006-09-15 08:50 UTC] d dot o dot m dot e at gmx dot net
Description:
------------
I want to add files to a newly created and not yet existing zip-archive by using the method 'ZipArchive::addFile'.

Reproduce code:
---------------
<?php
        
$zip = new ZipArchive();
$filename = 'zipfile.zip';

$testfile = $_SERVER['DOCUMENT_ROOT'] . '/foo.jpg';
$testfile2 = 'foo2.jpg';


if($zip->open($filename, ZIPARCHIVE::CREATE)===TRUE)
{
    $zip->addFromString('testfile.txt', 'This is a test string added.');
    if(file_exists($testfile)) $zip->addFile($testfile, 'foo.jpg');
    if(file_exists($testfile2)) $zip->addFile($testfile2, 'foo2.jpg');
    if(file_exists($testfile2)) $zip->addFile($testfile2, 'folder/foo2.jpg');
    $zip->close();
}
else die('Can\'t create Zip-archive.');

?>

Expected result:
----------------
I expected newly created zip-archive with the following document tree:

root
  |-foo.jpg
  |-foo2.jpg
  |-testfile.txt
  |-folder
      |-foo2.jpg

Actual result:
--------------
The actual result is the expected document tree, but the compressed files can't be opened by using the Windows decompression wizard. The error message of the wizard states 'Unexpected end of file'.

The only exception is the 'testfile.txt' which CAN be extracted and opened (which is beacause it uses a different method).

The method 'addFile' returns TRUE with all files.

Furthermore, it IS possible to browse through the zip-archive.

Even the file size and the compressed file size of the files are correct compared to a manually created zip archive, but the total size of the archive is bigger.

I also doublechecked the files 'foo.jpg' and 'foo2.jpg' that they are at the right position and not damaged.

Note: Probably is has something to do with the fact that the second parameter doesn't seem to be optional like it is said in the documentation. Leaving it out doesn't even add the file to the zip-archive.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-09-15 09:14 UTC] pierre dot php at gmail dot com
Please provide all files to reproduce the problem.

"Note: Probably is has something to do with the fact that the second parameter doesn't seem to be optional like it is said in the documentation. Leaving it out doesn't even add the file to the zip-archive."

Second parameter of which method?
 [2006-09-15 10:14 UTC] d dot o dot m dot e at gmx dot net
a) Please download the files here: http://www.jms-allgaeu.de/pecl-bugreport-tmp/8711.htm

b) Sorry, I meant the second parameter of the method 'addFile'. In the documentation it is marked as optional: 

ZipArchive::addFile ( string filename [, string localname] )

Thank you for your quick reaction.
 [2006-09-15 10:48 UTC] pierre dot php at gmail dot com
I cannot reproduce it on my windows, but I do not find this "windows decompression wizard".

Also the file "foo2.jpg" is added, with or without giving a local name (2nd argument).

A few questions:
- can you extract all or part of the archive (one or all files)?

- can you browse the archive?
 [2006-09-15 12:04 UTC] d dot o dot m dot e at gmx dot net
I don't know the exact translation of the 'decompression wizard', but it will be opened when you make a right click on the archive and select 'extract all files'. It uses the 'zipfldr.dll'. But it is definitely not the problem of this wizard, since WinZip also reports an error: 'invalid compressed data to inflate'.

When I don't give the second argument in 'addFile', the file won't be added, which means that it doesn't show up in the archive. Nevertheless, 'addFile' returns TRUE.

Regarding your questions:

a) Yes, I can extract and properly open parts of the archive, namely the 'testfile.txt' which was added with the 'addFromString' method. All other files and folders WON'T be extracted.

b) Yes, I can browse the entire archive (which includes opening the compressed folder) and every file is shown.

Greetings, Dominikus
 [2006-09-15 12:39 UTC] pierre dot php at gmail dot com
Ok, I managed to find a default windows XP setup, I tested the generated archives (many) with the "extract all" decompression wizard, compressed folder in explorer, winzip (10.0) with or without the explorer extensions, pkzip, and a couple of other zip tools, no issue. The zip works nicely.

Maybe you are mixing some DLLs, please try a newer snapshot, you shoud see the following lines in your phpinfo:

zip

Zip => enabled
Extension Version => $Id: php_zip.c,v 1.1.2.14 2006/09/15 12:12:25 pajoye Exp $
Zip version => 2.0.0
Libzip version => 0.7.1
 [2006-09-15 14:10 UTC] d dot o dot m dot e at gmx dot net
I updated my php version to the latest snapshot (Built On: Sep 15, 2006 14:30 GMT) and phpinfo() shows exactly the information you provided. But still, the same problem occures.

I tried to add a text file which I created with Notepad with 'addFile' and it worked. It didn't work with an OpenOffice document, though.

Greetings, Dominikus.

P.S. I guess, you can't open the (damaged) zip-archive, either.
 [2006-09-15 14:36 UTC] pierre dot php at gmail dot com
"It didn't work with an OpenOffice document, though."

What do you mean?

Are you modifying an openoffice document? or do you create an archive as OOo doc?

"P.S. I guess, you can't open the (damaged) zip-archive, either."

I have no damaned archive. The generated archives work.
 [2006-09-15 14:45 UTC] d dot o dot m dot e at gmx dot net
I just used an existing OpenOffice document to try out if 'addFile' only doesn't work with 'jpg', since a textfile will be compressed correctly. But the 'odt' can't be extracted after the compression. It was simply a test file which I have randomly choosen.

I meant the archive I provided. It is the file which was created with php and didn't work on my computer:

http://www.jms-allgaeu.de/pecl-bugreport-tmp/zipfile.zip

Greetings.
 [2006-09-15 20:12 UTC] pierre dot php at gmail dot com
It is confusing. I have hard time to understand what you are doing, with which files.

I used the files and script available here:
http://www.jms-allgaeu.de/pecl-bugreport-tmp/8711.htm

The generated zip works on all platforms. The zip are valid and readable by all zip tools (windows zip folder, winzip,pkzip, etc...), no matter from which platform it is generated.

Be sure you use the right zip.dll (from the php release) and that you create a new archive. Either remove the old "zipfile.zip" or use the ZIPARCHIVE::OVERWRITE, this flag always starts a fresh new archive with no entry.

I bogus this bug for now as it works everywhere else but on your box, feel free to reopen it if you can produce a reproduce script (try on another windows with a fresh php install).
 [2006-09-21 05:14 UTC] n-roeser at gmx dot net
Dominikus, your test file has CRLF (0x0d, 0x0a) where it should contain LF (0x0a) only. This *could* have been caused by downloading the file in ASCII mode via FTP, for example.

An attempt to repair the file by replacing CRLF with LF resulted in a too short file (according to the unzip program). So, indeed, this looks like a bug in the zip extension.


Just to make sure, please apply the following patch to your script:


--- zip.txt     2006-09-15 14:50:00.000000000 +0200
+++ zip.txt.new 2006-09-21 11:00:08.000000000 +0200
@@ -14,6 +14,8 @@
     if(file_exists($testfile2)) $zip->addFile($testfile2, 'foo2.jpg');
     if(file_exists($testfile2)) $zip->addFile($testfile2, 'folder/foo2.jpg');
     $zip->close();
+
+    echo sha1_file($filename) . "  $filename\n";
 }
 else die('Can\'t create Zip-archive.');



Then, remove your zip file on the server, and run the script to create it again. The SHA1 sum for the file on the server should be displayed. Download the file, and compare the SHA1 sums; they should be equal.

See <URL:http://lists.gnupg.org/pipermail/gnupg-announce/2004q4/000184.html> for where to get sha1sum.exe for Windows systems.


For the record, I tested this using the CVS sources from the PHP_5_2 branch, dated 2006-09-15T14:30:00+0200, module php5, compiled on Linux with configure --disable-all --enable-zip --disable-cgi --enable-cli --with-zend-vm=GOTO.


Looking into it a bit deeper shows that ext/zip/lib/zip_open_file.c with signature
$NiH: zip_source_file.c,v 1.2 2004/11/18 16:28:13 wiz Exp $
, line 60, *has* "b" in the mode flags for fopen(3). (I was told that *not* doing so could cause problems on Windows systems.) So I'm unsure where this bug originates.


Please run the test described above and report the result. Thanks.
 [2006-09-21 06:02 UTC] pierre dot php at gmail dot com
About the "b" mode, it is the binary read/write mode. It is the way to work in a binary safe way. It also works well on windows.
 [2006-10-31 10:47 UTC] php at dataweb dot no
It appears that I have the same or at least similar issue and I've been experiencing some really strange things. I was experimenting with the package yesterday, and some times it worked while other times it didn't. For example, it would sometimes work if I only added files of no more than 400 bytes. If I tried a file with 401 bytes, the zip archive would be corrupted. I can't reproduce this now though, so I'm just really confused over that behaviour which I saw yesterday.

I was especially trying to get multiple files and subdirectories into the archive, but with varying success. For example, I tried making all the files empty, and it would work. Then I readded some content and it would not work. I also tried changing the newline format (between \r\n and \n) in the added files, and at one point it seemed like that was the problem, but then found out at least it's not the entire problem.

Today I encountered another problem; it seemed like if the pathnames of the files/dirs were too long, the zip became corrupted unless I cut down the length of the filenames.

I'm using 7-zip to open the archives btw, and if the file is corrupt, it just lists the contents of the directory where the archive resides instead of opening the archive.


Here are the files I'm using: http://www.dataweb.no/dl/pecl-zip-bug-files.zip
That zip is created in 7-zip btw, not using ZipArchive. ;-) It contains a proper archive created in 7-zip, a corrupted archive created by ZipArchive, and a seemingly proper archive created by ZipArchive where all files are empty or almost empty.

The zip archive gets corrupted when I attempt to run the following script:

<?php
$pathToFiles = 'C:/projects/';

$filename = $pathToFiles . 'test.zip';

$arrFileList = array(
	'source/includes/auto_loaders/config.sid.php',
	'source/includes/foo.txt',
	'source/includes/init_includes/init_sid_redirect.php',
	'source/README.txt'
);

$zipArchive = new ZipArchive;
if ($zipArchive->open($filename, ZipArchive::OVERWRITE) !== true)
{
	die('Could not create zip archive');
}

foreach ($arrFileList as $localName)
{
	$file = $pathToFiles . $localName;
	if (!is_file($file))
	{
		echo "File '$file' does not exist<br>\n";
		continue;
	}
	$contents = file_get_contents($file);
	if ($zipArchive->addFile($file, $localName) === false)
	{
		die("Could not add file '$file' to archive");
	}
	echo "Added file '$file' to zip archive<br>\n";
}
if ($zipArchive->close() === false)
{
	die('Could not finish zip archive');
}
?>

However, if I delete the contents of all the files except source/includes/foo.txt so that I'm just adding empty or near-empty files to the archive, it actually works. foo.txt only contains this data: "just a test file", while the other files are between 1-3kB.


In case it helps, here's the zip output from phpinfo:

Zip 	enabled
Extension Version 	$Id: php_zip.c,v 1.77 2006/09/15 11:58:08 pajoye Exp $
Zip version 	@PACKAGE_VERSION@
Libzip version 	0.7.1

I notice that Zip version says "@PACKAGE_VERSION@", but I somehow doubt that it's the problem, since it works -some- times.
 [2006-10-31 11:12 UTC] pierre dot php at gmail dot com
"@PACKAGE_VERSION@" comes from CVS. pecl4win builds dll using CVS not the package release.

"it would sometimes work if I only added files of no more
than 400 bytes. If I tried a file with 401 bytes"

Where is this file with 401bytes?

" For example, I tried making all the files empty, and it would work. Then I readded some content and it would not work."

I need a script and data to reproduce what you describe here.

"Today I encountered another problem; it seemed like if the pathnames of the files/dirs were too long, the zip became corrupted unless I cut down the length of the filenames."

What do you mean by "too long"? Please provide a script to reproduce *this* problem.


" while the other files are between 1-3kB."

I need this file. I just run your script with the data you provided and it works just fine.

Which PHP version do you use? What is your OS?

Please try to describe one problem with one script not ten problems with one working scripts :)
 [2006-11-01 04:36 UTC] php at dataweb dot no
"" while the other files are between 1-3kB."

I need this file. I just run your script with the data you provided and
it works just fine."

Did you compare the included ZipArchive-corrupted.zip with the new archive you created from my data though? And could you please send me a copy of the archive you created with my script? Maybe it's just my system that can't properly open the archive after creating it for some reason.. Just want to rule out that option.

"Which PHP version do you use? What is your OS?"
PHP 5.1.6, from latest Xampp bundle (1.5.4a). OS is WinXP Home SP2, same as original poster.

"Please try to describe one problem with one script not ten problems with
one working scripts :)"
Sorry, I didn't know where to start. ;-)
 [2006-11-01 04:39 UTC] php at dataweb dot no
"" while the other files are between 1-3kB."

I need this file."

Those files are included in the package I provided:
http://www.dataweb.no/dl/pecl-zip-bug-files.zip

They're all in the source dir, and listed in the array $arrFileList in the script I included in the previous post.
 [2006-11-07 07:24 UTC] pierre dot php at gmail dot com
I tried on many system (linux, fbsd, XP, XP pro, 32/64), it works with the files you provided.

Do you have a way to reproduce your problem (not randomly)? The files and the script you use to create the corrupted archive. Please provide only these information:
- the files required to require the archive
- a script to create it
- a description of the problem. Which file(s) does not work, ie. the script works if you change this file.
 [2006-11-15 11:30 UTC] pierre dot php at gmail dot com
Please try using the next PHP 5.2 snapshot. I just commited a fix which may solve this problem.
 [2006-11-17 13:09 UTC] ned at lucksdigital dot com
I had similar problem on Win2k server Apache 2.0, PHP 5.2.0 production release.  Replaced php_zip.dll with latest snap from http://snaps.php.net/ and the problem went away.
 [2006-11-17 13:27 UTC] pierre dot php at gmail dot com
Great news, that means both bugs were related to the same windows bug. Windows ignore the binary mode given to fopen and fdopen (or alter it at some point), it is now forced to binary using a lower level function.

I will close this bug after the release (zip 1.8.1).
 [2006-11-28 12:06 UTC] pierre dot php at gmail dot com
Thank you for your bug report. This issue has been fixed
in the latest released version of the package, which you can download at
http://pecl.php.net/get/zip


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 11:01:30 2024 UTC