php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #48048 Empty files corrupt zip
Submitted: 2009-04-22 14:38 UTC Modified: 2009-05-07 13:17 UTC
From: php at codecaster dot nl Assigned:
Status: Not a bug Package: Zip Related
PHP Version: 5.2.9 OS: FreeBSD 7
Private report: No CVE-ID: None
 [2009-04-22 14:38 UTC] php at codecaster dot nl
Description:
------------
When you use ZipArchive->addFile() on an empty file, the file will be compressed anyway. This is incorrectly read by some (older) decompression programs.

Reproduce code:
---------------
if (file_put_contents("empty.txt", "") === false) {
  die("Cannot write files");
}

$zip = new ZipArchive();
$zip->open("corrupt.zip", ZIPARCHIVE::CREATE);
$zip->addFile("empty.txt");
$zip->close();

Expected result:
----------------
A zip file containing empty.txt with a size of 0 bytes and a compressed size of 0 bytes.

Actual result:
--------------
A zip file containing empty.txt with a size of 0 bytes and a compressed size of 2 bytes.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-04-28 11:58 UTC] php at codecaster dot nl
I have installed the latest build, PHP 5.2.10-dev. Same results.

From phpinfo():
Zip 	enabled
Extension Version 	$Id: php_zip.c,v 1.1.2.50 2009/03/01 17:35:25 iliaa Exp $
Zip version 	1.8.11
Libzip version 	0.9.0 

Updated test script (will output 2, should be 0):

<?php

// create empty file
if (file_put_contents("empty.txt", "") === false) {
  die("Cannot write files");
}

// zip it using ZipArchive
$zip = new ZipArchive();
$zip->open("corrupt.zip", ZIPARCHIVE::CREATE);
$zip->addFile("empty.txt");
$zip->close();

// open the file, show compressed size (returns 2, should be 0)
if (($zip = zip_open("corrupt.zip"))) {
  // read first entry
  $zip_entry = zip_read($zip);
  echo "Compressed Size: " . zip_entry_compressedsize($zip_entry);
  zip_close($zip);
}

?>
 [2009-05-07 13:02 UTC] jani@php.net
RTFM:

"zip_entry_compressedsize()
Returns the compressed size of the specified directory entry."

When you use the correct function zip_entry_filesize() the output is 0 
as it should be. Also the "corrupt.zip" is not corrupt at all, you can 
unzip it just fine with regular unzip found in pretty much every *nix. 
:)
 [2009-05-07 13:17 UTC] php at codecaster dot nl
The function zip_entry_compressedsize returns the compressed file size (referred to as "directory entry" in the Manual), which is 2 bytes for a zero-size file. The actual (uncompressed) size returned by zip_entry_filesize indeed is 0, which is correct, but that was not the issue.

The problem is that the bsdtar program has only recently been patched for this issue as can be read here: http://code.google.com/p/libarchive/issues/detail?id=3

If you would have executed the provided code and opened the zip file in any program you would have seen the compressed size is 2 bytes, which is "a silly thing to do, as it only makes the file larger".

We are not always able to patch libarchive/bsdtar, neither are we always able to use other programs than tar.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 20:01:28 2024 UTC