I noticed this bug when trying to upgrade modules with Drupal 7.15 on PHP 5.4.6 with nginx 1.2.3. There were errors about not being able to delete token/. and token/tests/. etc.

I haven't had the chance to fully investigate the issue, but it appears the following code (snippets from includes/filetransfer/local.inc and includes/filetransfer/filetransfer.inc):

foreach (new RecursiveIteratorIterator(new SkipDotsRecursiveDirectoryIterator('./')) as $filename => $file) {
  echo $filename . '<br />';
}

class SkipDotsRecursiveDirectoryIterator extends RecursiveDirectoryIterator {
  function __construct($path) {
    parent::__construct($path);
  }

  function next() {
    parent::next();
    while ($this->isDot()) {
      parent::next();
    }
  }
}

...runs differently in PHP 5.4.6 than this:

foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator('./', RecursiveDirectoryIterator::SKIP_DOTS)) as $filename => $file) {
  echo $filename . '<br />';
}

In that the first example no longer skips single dots. I don't know if this is a PHP bug. The isDot() method still seems to work, but somehow it's not moving the iterator to the next file.

Comments

dwieeb’s picture

Version: 7.15 » 7.16

Persists.

bripatand’s picture

Ran into the same issue using xampp 1.8.1 (php 5.4.7) on Windows 7 64 bits, Drupal 7.17.

The problem seems to appear when the first item in the directory listing is a dot, the iterator method next of class SkipDotsRecursiveDirectoryIterator which is supposed to skip the dots is not called yet.

dwieeb’s picture

Version: 7.16 » 7.17

Isn't the dot the first item of every directory listing?

The problem persists in 7.17. I feel like any patch to this would be ugly, because it seems to work differently in different PHP versions. Not sure how to proceed, otherwise I'd try patching it.

PedroKTFC’s picture

Wish I'd come across this earlier, just spent the whole afternoon realising this is the issue that's stopping the web drupal module updater working. I thought it was a user privileges issue but eventually tracked it down to drupal trying to delete a directory what isn't empty as it hasn't recursively deleted all its contents.

Is there any progress on this anywhere? I'm no php expert so reluctant to try a fix.

PedroKTFC’s picture

And rudely replying to my post, I've come across this fix: https://drupal.org/node/1313560 which has fixed it for me.

But I assume it's not generic enough since if you're using an older version of PHP, I'm guessing it won't work?

dwieeb’s picture

Yes, that fix is highlighted in the original post of this issue.

The SKIP_DOTS flag requires PHP 5.3 (http://php.net/manual/en/class.filesystemiterator.php). So, no, it won't work with PHP 5.2.5 which is the minimum PHP version for Drupal 7 (http://drupal.org/requirements).

So while the patch in #1313560: Remove SkipDotsRecursiveDirectoryIterator in favor of builtin FilesystemIterator::SKIP_DOTS flag will work for you, it won't work for some people. That's why I don't know how to proceed. This issue is getting very little attention because Drupal 8 will have a minimum PHP version of 5.3.5, so it will be fixed at that time.

PedroKTFC’s picture

I was looking for a "fix" I could apply (and even that patch doesn't work directly in Drupal 7).

Is there any way of querying your PHP version in PHP and then running the right version of the line depending on the outcome? Then rather than applying the whole patch, we simply add that check and have the versions in the code for Drupal 7?

openminds’s picture

I reported this as another issue, and attached a patch: http://drupal.org/node/1915088

Crell’s picture

Seems like this was sufficiently fixed in the linked issue.