Created originally on Bitbucket by standy66 (Andrew Stepanov)
Changesets for this Pull Request have not been imported, because it had been already declined on Bitbucket. Marked as closed by the import user.
On MacOS, it is illegal to call closedir(nullptr):
#include <dirent.h>
#include <stdio.h>
int main() {
printf("closedir(nullptr) = %d\n", closedir(0));
return 0;
}
$ gcc closedir_nullptr.c && ./a.out
[1] 35413 segmentation fault ./a.out
But on Linux it works fine and returns -1 (which indicates an error):
$ gcc closedir_nullptr.c && ./a.out
closedir(nullptr) = -1
Current implementation of os.scandir
in py3.6 branch does exactly that: when the iterator is exhausted, StopIteration
is raised by the means of self.fail()
call, which in turn calls closedir(self.dirp)
and then assigns it to NULL. But the exception handler that catches StopIteration
exception calls self._close()
that calls closedir(self.dirp)
again, this time on a null pointer, resulting in segfault on MacOS.
Actually, the cleanup logic is quite convoluted in W_ScandirIterator
, the cleanup happens in different places. This pull request adds a simple check before calling closedir the second time, but we may want to reconsider the cleanup logic of W_ScandirIterator