DirectoryIterator bug


#1

The DirectoryIterator class has a bug that prevents regular files to be filtered against a file mask.

The DirectoryIterator::next function contains the following code:

// if recursive, we're not relying on the OS iterator to do the wildcard match, so do it now..
if (matches && isRecursive)
    matches = fileMatches (wildCards, filename);

...that should be changed to:

// if recursive, we're not relying on the OS iterator to do the wildcard match, so do it now..
if (matches && ((isDirectory && isRecursive) || !isDirectory))
    matches = fileMatches (wildCards, filename);

 

I hope this fix is useful, Julian.

Best regards.


#2

No.. I think you've misunderstood that. If the item is not a directory, then there's no need to call fileMatches(), because the match will already have been done by the OS-specific file iterator. If there's a bug, maybe give me an example of some code that I can use to reproduce it, and I'll take a look?


#3

Here is the code that reproduces the problem:


int main (int argc, char* argv[])
{
    File baseDir("C:/Temp/Test");

    DirectoryIterator di(baseDir, false, String("*.jpg;*.png;*.gif"));

    while (di.next())
        std::cout << di.getFile().getFullPathName() << std::endl;

    return 0;
}

...and the partial output of its execution is:


...
C:\Temp\Test\aldus-logo.tif
C:\Temp\Test\cute-puppy-dog-wallpapers_0.jpg
C:\Temp\Test\Desktop.ini
C:\Temp\Test\dogs_100.jpg
...

Do you see the "aldus-logo.tif" and "Desktop.ini" files?

------------------------------------

P.S. OS Windows 8 / 64-bit


#4

Thanks - looks like the problem was caused when it had multiple wildcards. Try it again now..


#5

Thank you, Julian! It works!


#6

In OSX if you choose *.* as your filter DirectoryIterator::next() ignores all files. This does not happen on Windows. I see you have it trapped in WildcardFileFilter::parse but not in DirectoryIterator::next().

BTW, I have not checked this against the latest tip.


#7

It's not really a bug. I vaguely remember reluctantly adding the hack in WildcardFileFilter for reasons that I forget (something to do with file choosers, I think...), but you should never actually use *.* yourself - always use * if you want all the files.

And if you're making this request because you think your users might enter *.* somewhere, then it's the job of your own app to detect and replace that string - it's not a policy that should be hard-coded into a fundamental class like DirectoryIterator. (If I did that, how would someone write an algorithm that searches for only those filenames which contain a dot!?)


#8

That is what I did, just like your hack and it seems to work. thankfully I don't have users entering wild card fields.