From:             
Operating system: Unix/POSIX, maybe Windows
PHP version:      master-Git-2012-05-22 (Git)
Package:          Zip Related
Bug Type:         Bug
Bug description:zip can (and will, in real-life cases) leak huge tempfiles

Description:
------------
I’ve been investigating a disc full case on some of our servers, which
was 
fixed by removing eight Gibibytes (!) of *.zip.?????? files (about a dozen

files) that looked like mkstemp(3)-generated, and investigated this
problem.

To cut a long story short: an instance of the ZipArchive class does 
its “action” when the close() method is called. (There should also be
an 
abort() method which frees all ressources and unlocks all files, for if an

error is detected in between open/addfile and further addfile calls or the

close call, but that’s not the problem at hand, it just irritated me.)
This 
ends up being [php-src.git] / ext / zip / lib / zip_close.c (I’ve just
looked 
at gitweb master to reconfirm this), which has the following problem:

zip_close() forcibly allocates a temporary file, operates on that and then

atomically renames the temporary file to the desired output filename. This
may 
be a good thing in a regular Unix environment (and looking at the authors,
I 
know at least one of them from NetBSD®, so the code probably does come
from a 
Unix environment). HOWEVER, this is a PHP environment, not a regular Unix 
environment, even if it may run on Unix, and PHP, when running in a
webserver, 
but also as CLI, asserts certain resource limits – execution time (not in

CLI), memory size, etc.

When the script is terminated due to such a limit (in our case, probably
the 
execution time limit in apache2 mod_php), the tempfile is not cleaned up. 
Period. And when you were zipping up 400 MiB, and the termination happens
when 
300 MiB of that are already written to disc… well, not nice.

The cleanest way would probably be for the PHP core to offer an extension
(C, 
but PHP would also make sense) to register cleanup hooks that run when
script 
execution is terminated. This would be more generically usable than just a

method with which an extension could register tempfiles which were then 
removed, as cleanup may involve other tasks. (As a general suggestion,
cleanup 
execution time could be limited to the greater of 5 seconds and a tenth of
the 
script execution time limit, and memory size should be similarly extended
by a 
small amount so it won’t terminate abnormally during the cleanup phase.)

Test script:
---------------
createNewestReleaseFilesAsZip method (at the end of the file) in:

https://evolvis.org/scm/viewvc.php/trunk/gforge_base/evolvisforge-5.1/src/common/frs/FRSPackage.class.php?revision=18116&root=evolvis&view=markup

Note how a later revision of the same file already contains some attempts
at error handling, and how it the lack of an abort method makes that
awkward.

Expected result:
----------------
No tempfile leak. If no resource limit is hit, the .zip file is created; if

one is hit, the .zip file is either untouched or removed (unlinked).

Actual result:
--------------
If a resource limit is hit, a tempfile of arbitrary size (at least several

hundred Mebibytes confirmed) is leaked.

-- 
Edit bug report at https://bugs.php.net/bug.php?id=62106&edit=1
-- 
Try a snapshot (PHP 5.4):            
https://bugs.php.net/fix.php?id=62106&r=trysnapshot54
Try a snapshot (PHP 5.3):            
https://bugs.php.net/fix.php?id=62106&r=trysnapshot53
Try a snapshot (trunk):              
https://bugs.php.net/fix.php?id=62106&r=trysnapshottrunk
Fixed in SVN:                        
https://bugs.php.net/fix.php?id=62106&r=fixed
Fixed in SVN and need be documented: 
https://bugs.php.net/fix.php?id=62106&r=needdocs
Fixed in release:                    
https://bugs.php.net/fix.php?id=62106&r=alreadyfixed
Need backtrace:                      
https://bugs.php.net/fix.php?id=62106&r=needtrace
Need Reproduce Script:               
https://bugs.php.net/fix.php?id=62106&r=needscript
Try newer version:                   
https://bugs.php.net/fix.php?id=62106&r=oldversion
Not developer issue:                 
https://bugs.php.net/fix.php?id=62106&r=support
Expected behavior:                   
https://bugs.php.net/fix.php?id=62106&r=notwrong
Not enough info:                     
https://bugs.php.net/fix.php?id=62106&r=notenoughinfo
Submitted twice:                     
https://bugs.php.net/fix.php?id=62106&r=submittedtwice
register_globals:                    
https://bugs.php.net/fix.php?id=62106&r=globals
PHP 4 support discontinued:          
https://bugs.php.net/fix.php?id=62106&r=php4
Daylight Savings:                    https://bugs.php.net/fix.php?id=62106&r=dst
IIS Stability:                       
https://bugs.php.net/fix.php?id=62106&r=isapi
Install GNU Sed:                     
https://bugs.php.net/fix.php?id=62106&r=gnused
Floating point limitations:          
https://bugs.php.net/fix.php?id=62106&r=float
No Zend Extensions:                  
https://bugs.php.net/fix.php?id=62106&r=nozend
MySQL Configuration Error:           
https://bugs.php.net/fix.php?id=62106&r=mysqlcfg

Reply via email to