ofxDirList::listDir file extension filtering broken

I had files with different extensions in the same directory (including sample1.aif and sample1.gif). One objects in my program (inherited from the ofSoundPlayer) set the allowed extensions on the ofxDirList ::allowExt method to look for audio files (aif and wav). Another object in my program (inherited from the ofVideoPlayer – and with it’s own instance of the ofxDirList class) set the allowed extensions on the ofxDirList ::allowExt method to movies and images (bmp, gif, jpg, mov, mpg). I found that sample1.gif was incorrectly appearing in the list of soundfiles when I called ofxDirList::listDir. Again, each of my objects contain separate instances of the ofxDirList class, so the solution wasn’t as easy as simply calling ofxDirList::reset.

I couldn’t figure out what was going on until I stepped into ofxDirList::listDir. It looks like there is a very subtle bug there.

on line 115 in ofxdirlist.cpp, there is a for () loop which iterates a variable j from 0 to the length of the current file extension being compared, so for my files, j ranges from 0 - 3.

on line 117, a conditional statement is supposed to compare each character of the extension from the allowed extensions array to the extension of the current file read from the directory:

if( tolower(entry->d_name[fileLen - j] ) != tolower(allowedFileExt[i][extLen - j]) ) {  
   checkExt = false; break;   

as far as I can tell, however, the conditional is incorrect. For my files, which are each 11 characters long

sample1.aif   sample1.gif  
12345678911   12345678911  
         01            01  

when j = 0, (fileLen - 0) = 11, which means that the code is trying to access d_name[11] (which is the string terminator). The last character of d_name is located at index 10 (fileLen - 1), so code only compares the last two characters of a file’s extension with the allowedFileExt array. Since my files’ extensions have the same last two characters, the code returns that both of them meet the allowed file extension criteria.

work around:
In my local copy of ofxDirList.cpp, I changed line 117 to

if( tolower(entry->d_name[(fileLen - 1) - j] ) != tolower(allowedFileExt[i][(extLen - 1) - j]) ) {  

wow - that is a very subtle bug - thanks for tracking it down!
it totally makes sense.

it was matching .a[i][f][\0] with .g[i][f][\0] - ugh c string matching and a off by 1 error :slight_smile:

we would actually move ofDirList over to use c++ strings (which would be a little less ghetto looking) but the likely forthcoming integration with the poco library will result in much more powerful file/directory listing options.

I’ll add that fix to the svn!

**update: added to svn

thanks again