Bug->Doc #69291 [Opn]: SPL directory tests fail under some conditions

From: Date: Tue, 14 Sep 2021 10:05:50 +0000
Subject: Bug->Doc #69291 [Opn]: SPL directory tests fail under some conditions
References: 1  Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-19179@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=69291&edit=1 ID: 69291 Updated by: cmb@php.net Reported by: danack@php.net Summary: SPL directory tests fail under some conditions Status: Open -Type: Bug +Type: Documentation Problem Package: SPL related Operating System: Centos PHP Version: 5.5.23 Block user comment: N Private report: N New Comment: dit_004.phpt has been improved[1] in the meantime, and dit_005.phpt has a respective comment[2]. So the issue that iterating over modified directories may not yield stable results is known. To explain: DirectoryIterator uses readdir()[3] under the hood, and POSIX states: | If a file is removed from or added to the directory after the | most recent call to opendir() or rewinddir(), whether a subsequent | call to readdir() returns an entry for that file is unspecified. Even worse, POSIX also states: | The readdir() function may buffer several directory entries per | actual read operation; […] So yes, obviously DirectoryIterator clones may not behave as expected. I don't see a way to fix this, short off prohibiting cloning such objects altogether. Regarding the ordering: this looks strange to me, since POSIX mandates (emphasis mine): | The type DIR, which is defined in the <dirent.h> header, | represents a directory stream, which is an **ordered** sequence of | all the directory entries in a particular directory. While it does not specify which order, the order should not change, I think. Anyway, that directory entries are not necessarily ordered alphabetically is also a known issue, and either partly documented or tracked by another ticket. So this issue is best categorized as documentation problem, and maybe it's worthwhile to improve dit_005.phpt similar to what has been done with dit_004.phpt. [1] <https://github.com/php/php-src/commit/0535872b7cd50be8b40ad06154b287749315eb27> [2] <https://github.com/php/php-src/blob/PHP-7.4.23/ext/spl/tests/dit_005.phpt#L5> [3] <https://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html> Previous Comments: ------------------------------------------------------------------------ [2020-04-24 20:31:29] danack@php.net Hi Alex, I'm pretty sure the bad assumption is still there: https://github.com/php/php-src/blob/826a7456717b8fab22d43deedf7b6ab1b1f426be/ext/spl/spl_directory.c#L371 Below is an example of how cloning a directoryIterator doesn't result in an object that is actually a clone <?php $a = new DirectoryIterator(__DIR__); $baseName = basename(__FILE__); $found = false; while($found == false) { $a->next(); if ($baseName === (string)$a) { $found = true; } }; file_put_contents('created_file.txt', 'feel free to delete'); $b = clone $a; // Cloning should result in same object, right? if ((string)$b != (string)$a) { // surprise! // output is "file 1: dir_bug.php file 2: created_file.txt" printf( "file 1: %s file 2: %s", (string)$a, (string)$b ); } unlink('created_file.txt'); ------------------------------------------------------------------------ [2020-04-24 18:54:07] alexinbeijing at gmail dot com Can't reproduce the failure described here. Both of the tests run fine whether run through php run-tests.php or not, and whether run under valgrind or not. 5 years have passed, a lot has changed, and whatever was causing this bug has probably been fixed. The ticket should be closed. ------------------------------------------------------------------------ [2015-04-03 19:45:07] tyrael@php.net I've deleted the link to the wrong PR. ------------------------------------------------------------------------ [2015-04-02 14:47:40] danack@php.net Okay - I understand what is happening, but can't tell what the 'correct' behaviour should be. The code is assuming that DirectoryIterator will return objects alphabetically. It isn't doing so. Instead the file entries are listed alphabetically within 'blocks', but the blocks are ordered in reverse. i.e. the first entry in the cloned iterator is SplObjectStorage_getHash.phpt, while the first entry in the original iterator is array_001.phpt The full output is https://gist.github.com/Danack/e9c7ca12958cdd180197. TL:DR the test assumes that DirectoryIterator always returns values in the same alphabetical order, it doesn't. And so the test fails sometimes. ------------------------------------------------------------------------ [2015-03-27 18:23:40] danack@php.net Whoop - I added the PR to the wrong issue. The PR is for something else entirely, but apparently there is no way to delete it. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at https://bugs.php.net/bug.php?id=69291 -- Edit this bug report at https://bugs.php.net/bug.php?id=69291&edit=1

« previous php.doc.bugs (#19179) next »