php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #57720 RARCloseArchive(rar->extract_handle) not called
Submitted: 2007-06-25 03:23 UTC Modified: 2007-06-25 07:59 UTC
From: leshi at list dot ru Assigned:
Status: Closed Package: rar (PECL)
PHP Version: 5.2.3 OS: WinXP
Private report: No CVE-ID:
 [2007-06-25 03:23 UTC] leshi at list dot ru
Description:
------------
The example code is not working unlink (), because it does not free file handlde.
PHP: 5.2.3
rar: from pecl package

Reproduce code:
---------------
<?php
	$rar_file = rar_open('1.rar') or die("&#1053;&#1077;&#1074;&#1086;&#1079;&#1084;&#1086;&#1078;&#1085;&#1086; &#1086;&#1090;&#1082;&#1088;&#1099;&#1090;&#1100; &#1072;&#1088;&#1093;&#1080;&#1074;");
	$entries = rar_list($rar_file);

	foreach ($entries AS $e) 
	{
		// will work fine if it's remove
		$e->extract('.');// &#1045;&#1089;&#1083;&#1080; &#1101;&#1090;&#1086; &#1091;&#1073;&#1088;&#1072;&#1090;&#1100;, &#1090;&#1086; &#1074;&#1089;&#1077; &#1093;&#1086;&#1088;&#1086;&#1096;&#1086; &#1073;&#1091;&#1076;&#1077;&#1090; (&#1074; &#1089;&#1084;&#1099;&#1089;&#1083;&#1077; &#1092;&#1072;&#1081;&#1083; &#1091;&#1076;&#1072;&#1083;&#1080;&#1090;&#1100;&#1089;&#1103;)
	}
	// will called N+1 times, where N is the count of $e->extract()
	while(rar_close($rar_file)) echo '.';// &#1041;&#1091;&#1076;&#1077;&#1090; &#1091;&#1089;&#1087;&#1077;&#1096;&#1085;&#1086; &#1074;&#1099;&#1087;&#1086;&#1083;&#1085;&#1077;&#1085;&#1086; N+1 &#1088;&#1072;&#1079;, &#1075;&#1076;&#1077; N &#1082;&#1086;&#1083;&#1080;&#1095;&#1077;&#1089;&#1090;&#1074;&#1086; &#1074;&#1083;&#1086;&#1078;&#1077;&#1085;&#1080;&#1082;, &#1082;&#1086;&#1090;&#1086;&#1088;&#1099;&#1077; &#1073;&#1099;&#1083;&#1080; &#1076;&#1077;&#1088;&#1085;&#1091;&#1090;&#1099;

	unlink('1.rar');
?>

Expected result:
----------------
removed file 1.rar

Actual result:
--------------
X-Powered-By: PHP/5.2.3

... (I have 2 files in archive)

Warning:  unlink(1.rar): Permission denied in \test.php on line 12


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-06-25 05:29 UTC] tony2001 at phpclub dot net
>Warning:  unlink(1.rar): Permission denied in \test.php on line 12

It clearly says "Permission denied", which means you don't have enough privileges to delete this file.
Also please try to provide some more information than just a piece of code and one sentence.
 [2007-06-25 05:57 UTC] leshi at list dot ru
Ok. 
	
I find it difficult to explain in English, I will try the case code step by step. 

1. I have file 1.rar. If I try <?php unlink('1.rar');?>, it's work fine. File heve been removed.
2. Same file, code:
<?php
 $rar_file = rar_open('1.rar') or die("Can't open file");
 rar_close($rar_file);
 unlink('1.rar');
?> work file again.
3. Same file, code:
<?php
 $rar_file = rar_open('1.rar') or die("Can't open file");
 $entries = rar_list($rar_file);
 rar_close($rar_file);
 unlink('1.rar');
?> have problem "Permission denied". But if rar_close() will call twice (or more, depend on the count of file in archive), work fine. I.e.
<?php
 $rar_file = rar_open('1.rar') or die("Can't open file");
 $entries = rar_list($rar_file);
 while (@rar_close($rar_file)) echo '.';
 unlink('1.rar');
?> work fine. In my case, output whill be '...'. One for rar_open and one for each file in archive. It's bug, but can be resolved by cheet.
Another way,  unset( $entries); I.e.
<?php
 $rar_file = rar_open('1.rar') or die("Can't open file");
 $entries = rar_list($rar_file);
 unset($entries);
 rar_close($rar_file);
 unlink('1.rar');
?> work fine too;

4. Same file, code:
<?php
 $rar_file = rar_open('1.rar') or die("Can't open file");
 $entries = rar_list($rar_file);
 foreach ($entries AS $e) 
 {
   $e->extract('.'); // This is problem string.
 }

 unset($entries);
 rar_close($rar_file);
 unlink('1.rar');
?> I have no idea how to make this work. 
If comment line $e->extract('.'); work fine, but I want to extract files.

PHP work as apache module. While apache running file 1.rar still open. And I can't delete them. When apache stop (or restart), I can delete file.
Whith PHP as CGI file still open while script runnig.

I hope I understand explained. (Thanx http://www.google.com/translate_t)
 [2007-06-25 06:05 UTC] tony2001 at phpclub dot net
That's right, each RarEntry instance refers to the rar file resource and increases the refcount of it, so that if you close it using rar_close(), the RarEntry would be still usable and the resource would not refer to already freed memory.
So you need to unset/destroy all the RarEntry instances first and after that the refcount of rar resource would be 1 and rar_close() would free it.
This is expected behaviour.
 [2007-06-25 06:48 UTC] leshi at list dot ru
Wow! Suddenly.. But what about samle 4?
How to make this work?
Code like
<?php
 $rar_file = rar_open('1.rar') or die("Can't open file");
 $entries = rar_list($rar_file);
 $imax = count($entries);
 for($i=0;$i<$imax;$i++)
 {
   $entries[$i]->extract('.');
   unset($entries[$i]); // unset each entry? That's right?
 }

 unset($entries); // unset entries array
 rar_close($rar_file);
 unlink('1.rar');
?>
still _not_ work.
 [2007-06-25 07:46 UTC] leshi at list dot ru
I find that's when call RarEntry::extract called RAROpenArchive(rar->extract_handle);
and nowere called RARCloseArchive(rar->extract_handle);

In case of rar->list_handle that's do.

I think this is my problem. Is not it?
 [2007-06-25 07:59 UTC] tony2001 at phpclub dot net
This bug has been fixed in CVS.

In case this was a documentation problem, the fix will show up at the
end of next Sunday (CET) on pecl.php.net.

In case this was a pecl.php.net website problem, the change will show
up on the website in short time.
 
Thank you for the report, and for helping us make PECL better.

Fixed in CVS, try the next PECL build.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Thu Apr 24 02:02:10 2014 UTC