php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #40711 RecursiveIteratorIterator unable to successfully clean up after itself
Submitted: 2007-03-03 17:25 UTC Modified: 2007-03-04 12:34 UTC
From: hannes dot magnusson at gmail dot com Assigned: helly (profile)
Status: Not a bug Package: Reproducible crash
PHP Version: * OS: *
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: hannes dot magnusson at gmail dot com
New email:
PHP Version: OS:

 

 [2007-03-03 17:25 UTC] hannes dot magnusson at gmail dot com
Description:
------------
Run the code below with reasonable low memory_limit on, for 
instance, PHP5.2 source directory.

Reproduce code:
---------------
<?php
class rfi extends RecursiveFilterIterator {
  public function __construct($path) {
    parent::__construct(new RecursiveDirectoryIterator($path));
  }
}
class rii extends RecursiveIteratorIterator {
}

$rii = new rii(new rfi("."));
foreach($rii as $obj) {
}


Actual result:
--------------
#0  0x081d6e23 in spl_RecursiveIteratorIterator_free_storage 
(_object=0x850464c, tsrm_ls=0x84e82b0) 
at /usr/src/php/5.2/ext/spl/spl_iterators.c:719
719                             sub_iter->funcs->dtor(sub_iter 
TSRMLS_CC);
[New LWP 100098]
(gdb) bt
#0  0x081d6e23 in spl_RecursiveIteratorIterator_free_storage 
(_object=0x850464c, tsrm_ls=0x84e82b0) 
at /usr/src/php/5.2/ext/spl/spl_iterators.c:719
#1  0x0836d384 in zend_objects_store_free_object_storage 
(objects=0x84f2618, tsrm_ls=0x84e82b0) 
at /usr/src/php/5.2/Zend/zend_objects_API.c:89
#2  0x0833d2db in shutdown_executor (tsrm_ls=0x84e82b0) 
at /usr/src/php/5.2/Zend/zend_execute_API.c:299
#3  0x0834c77e in zend_deactivate (tsrm_ls=0x84e82b0) 
at /usr/src/php/5.2/Zend/zend.c:860
#4  0x082f5354 in php_request_shutdown (dummy=0x0) 
at /usr/src/php/5.2/main/main.c:1311
#5  0x083bd0d8 in main (argc=2, argv=0xbfbfe960) 
at /usr/src/php/5.2/sapi/cli/php_cli.c:1294


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-03-04 12:34 UTC] helly@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

First thanks for filing this because I found an error in the class layout. RecursiveFilterIterator::accept must be abstract. And instead you want to use ParentIterator (PI). Another issue is actually in your code. RecursiveIteratorIterator (RII) does not return parents until you specify so by changing its mode (for instance RII::SELF_FIRST). The next issue in the code is that PI::getChildren returns a RecursiveIterator (RI) since it calls RDI::geChildren. This is then passed to PI::__construct becuase it needs to keep the structure. Now in you rcode RFI::__construct you create another RDI. That is the ctor receives a PI that contains an RDI instance and creates a new RDI from it. While doing so the inner RDI is being rewound to its first element which is ".". Now as far as I can tell there will be a recursion somehow with this approach. For me it actually aborts with an exception message like, too many open files.

Given the fact that we don't fix recursions I'd say this is expected behavior. If you feel different reopen this report.

The correct code to get the directories is below:

<?php

class RDI extends RecursiveDirectoryIterator {}

class PI extends ParentIterator {}

class RII extends RecursiveIteratorIterator {}

$rii = new RII(new PI(new RDI($argv[1])), RII::SELF_FIRST);

foreach($rii as $f) {
	echo "$f\n";
}


 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Wed May 27 16:01:25 2020 UTC