FX_GetNextFile: use stat.st_mode instead of dirent.d_type
According to the manpage of readdir(3), dirent.d_type is "not
supported by all filesystem types", using it to predicate if a dirent
is a directory fails on some FS, e.g., XFS. This commit uses stat(2)
to do the predication.
Change-Id: I0561db8b7caf304aa07cc2a2d6b7c4dd0aca9acb
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/51993
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fxcrt/fx_stream.cpp b/core/fxcrt/fx_stream.cpp
index ac8c0ec..6f30521 100644
--- a/core/fxcrt/fx_stream.cpp
+++ b/core/fxcrt/fx_stream.cpp
@@ -123,7 +123,13 @@
pData->m_bEnd = false;
return pData.release();
#else
- return opendir(path);
+ DIR* dir = opendir(path);
+ if (!dir)
+ return nullptr;
+ auto handle = pdfium::MakeUnique<FX_FolderHandle>();
+ handle->m_Path = path;
+ handle->m_Dir = dir;
+ return handle.release();
#endif
}
@@ -144,11 +150,16 @@
handle->m_bEnd = true;
return true;
#else
- struct dirent* de = readdir(handle);
+ struct dirent* de = readdir(handle->m_Dir);
if (!de)
return false;
+ ByteString fullpath = handle->m_Path + "/" + de->d_name;
+ struct stat deStat;
+ if (stat(fullpath.c_str(), &deStat) < 0)
+ return false;
+
*filename = de->d_name;
- *bFolder = de->d_type == DT_DIR;
+ *bFolder = S_ISDIR(deStat.st_mode);
return true;
#endif
}
@@ -159,8 +170,8 @@
#if _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
FindClose(handle->m_Handle);
- delete handle;
#else
- closedir(handle);
+ closedir(handle->m_Dir);
#endif
+ delete handle;
}
diff --git a/core/fxcrt/fx_stream.h b/core/fxcrt/fx_stream.h
index 3fec402..8ce75fd 100644
--- a/core/fxcrt/fx_stream.h
+++ b/core/fxcrt/fx_stream.h
@@ -19,8 +19,14 @@
#else // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
#include <dirent.h>
+#include <sys/stat.h>
#include <sys/types.h>
-typedef DIR FX_FolderHandle;
+#include <unistd.h>
+
+struct FX_FolderHandle {
+ ByteString m_Path;
+ DIR* m_Dir;
+};
#endif // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_