fixed possible uninitialised memory read in folderiterator for windows, and changed file folderiterator.cc to unix format

This commit is contained in:
cyril soler 2016-11-14 14:10:49 +01:00
parent fb302002d6
commit d433713bd0
2 changed files with 210 additions and 181 deletions

View File

@ -1,179 +1,209 @@
#include <dirent.h> #include <dirent.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#ifdef WINDOWS_SYS #ifdef WINDOWS_SYS
#include "util/rswin.h" #include "util/rswin.h"
#endif #endif
#include "folderiterator.h" #include "folderiterator.h"
#include "rsstring.h" #include "rsstring.h"
//#define DEBUG_FOLDER_ITERATOR 1 //#define DEBUG_FOLDER_ITERATOR 1
namespace librs { namespace util { namespace librs { namespace util {
FolderIterator::FolderIterator(const std::string& folderName) FolderIterator::FolderIterator(const std::string& folderName)
: mFolderName(folderName) : mFolderName(folderName)
{ {
// Grab the last modification time for the directory is_open = false ;
validity = false ;
struct stat64 buf ; mFileModTime = 0;
mFolderModTime = 0;
#ifdef WINDOWS_SYS mFileSize = 0;
std::wstring wfullname; mType = TYPE_UNKNOWN;
librs::util::ConvertUtf8ToUtf16(folderName, wfullname);
if ( 0 == _wstati64(wfullname.c_str(), &buf)) // Grab the last modification time for the directory
#else
if ( 0 == stat64(folderName.c_str(), &buf)) struct stat64 buf ;
#endif
{ #ifdef WINDOWS_SYS
mFolderModTime = buf.st_mtime ; std::wstring wfullname;
} librs::util::ConvertUtf8ToUtf16(folderName, wfullname);
if ( 0 == _wstati64(wfullname.c_str(), &buf))
// Now open directory content and read the first entry #else
if ( 0 == stat64(folderName.c_str(), &buf))
#ifdef WINDOWS_SYS #endif
std::wstring utf16Name; {
if(! ConvertUtf8ToUtf16(folderName, utf16Name)) { mFolderModTime = buf.st_mtime ;
validity = false; }
return;
} // Now open directory content and read the first entry
utf16Name += L"/*.*"; #ifdef WINDOWS_SYS
std::wstring utf16Name;
handle = FindFirstFileW(utf16Name.c_str(), &fileInfo); if(! ConvertUtf8ToUtf16(folderName, utf16Name)) {
is_open = validity = handle != INVALID_HANDLE_VALUE; validity = false;
#else return;
handle = opendir(folderName.c_str()); }
is_open = validity = handle != NULL;
next(); utf16Name += L"/*.*";
#endif
} // FindFirstFileW does the "next" operation, so after calling it, we need to read the information
// for the current entry.
FolderIterator::~FolderIterator()
{ handle = FindFirstFileW(utf16Name.c_str(), &fileInfo);
closedir(); is_open = validity = handle != INVALID_HANDLE_VALUE;
}
bool should_skip ;
void FolderIterator::next() validity = validity && updateFileInfo(should_skip);
{
while(readdir()) if(validity && should_skip)
{ next();
#ifdef WINDOWS_SYS #else
ConvertUtf16ToUtf8(fileInfo.cFileName, mFileName) ; // On linux, we need to call "next()" once the dir is openned. next() will call updateFileInfo() itself.
#else
mFileName = ent->d_name ; handle = opendir(folderName.c_str());
#endif is_open = validity = handle != NULL;
next();
if(mFileName == "." || mFileName == "..") #endif
continue ; }
mFullPath = mFolderName + "/" + mFileName ; FolderIterator::~FolderIterator()
{
struct stat64 buf ; closedir();
}
#ifdef DEBUG_FOLDER_ITERATOR
std::cerr << "FolderIterator: next. Looking into file " << mFileName ; void FolderIterator::next()
#endif {
bool should_skip = false ;
#ifdef WINDOWS_SYS
std::wstring wfullname; while(readdir())
librs::util::ConvertUtf8ToUtf16(mFullPath, wfullname); if(updateFileInfo(should_skip) && !should_skip)
if ( 0 == _wstati64(wfullname.c_str(), &buf)) return ;
#else
if ( 0 == stat64(mFullPath.c_str(), &buf)) #ifdef DEBUG_FOLDER_ITERATOR
#endif std::cerr << "End of directory." << std::endl;
{ #endif
mFileModTime = buf.st_mtime ;
mStatInfoOk = true; mType = TYPE_UNKNOWN ;
mFileSize = 0 ;
if (S_ISDIR(buf.st_mode)) mFileModTime = 0;
{ validity = false ;
#ifdef DEBUG_FOLDER_ITERATOR }
std::cerr << ": is a directory" << std::endl;
#endif bool FolderIterator::updateFileInfo(bool& should_skip)
{
mType = TYPE_DIR ; should_skip = false;
mFileSize = 0 ; #ifdef WINDOWS_SYS
mFileModTime = buf.st_mtime; ConvertUtf16ToUtf8(fileInfo.cFileName, mFileName) ;
#else
return ; mFileName = ent->d_name ;
} #endif
if (S_ISREG(buf.st_mode)) if(mFileName == "." || mFileName == "..")
{ {
#ifdef DEBUG_FOLDER_ITERATOR should_skip = true ;
std::cerr << ": is a file" << std::endl; return true ;
#endif }
mType = TYPE_FILE ; mFullPath = mFolderName + "/" + mFileName ;
mFileSize = buf.st_size;
mFileModTime = buf.st_mtime; struct stat64 buf ;
return ; #ifdef DEBUG_FOLDER_ITERATOR
} std::cerr << "FolderIterator: next. Looking into file " << mFileName ;
} #endif
#ifdef DEBUG_FOLDER_ITERATOR #ifdef WINDOWS_SYS
std::cerr << ": is unknown skipping" << std::endl; std::wstring wfullname;
#endif librs::util::ConvertUtf8ToUtf16(mFullPath, wfullname);
if ( 0 == _wstati64(wfullname.c_str(), &buf))
mType = TYPE_UNKNOWN ; #else
mFileSize = 0 ; if ( 0 == stat64(mFullPath.c_str(), &buf))
mFileModTime = 0; #endif
} {
#ifdef DEBUG_FOLDER_ITERATOR mFileModTime = buf.st_mtime ;
std::cerr << "End of directory." << std::endl;
#endif if (S_ISDIR(buf.st_mode))
{
mType = TYPE_UNKNOWN ; #ifdef DEBUG_FOLDER_ITERATOR
mFileSize = 0 ; std::cerr << ": is a directory" << std::endl;
mFileModTime = 0; #endif
validity = false ;
} mType = TYPE_DIR ;
mFileSize = 0 ;
bool FolderIterator::readdir() mFileModTime = buf.st_mtime;
{
if(!validity) return true;
return false; }
#ifdef WINDOWS_SYS if (S_ISREG(buf.st_mode))
return FindNextFileW(handle, &fileInfo) != 0; {
#else #ifdef DEBUG_FOLDER_ITERATOR
ent = ::readdir(handle); std::cerr << ": is a file" << std::endl;
return ent != NULL; #endif
#endif
} mType = TYPE_FILE ;
mFileSize = buf.st_size;
time_t FolderIterator::dir_modtime() const { return mFolderModTime ; } mFileModTime = buf.st_mtime;
const std::string& FolderIterator::file_fullpath() { return mFullPath ; } return true;
const std::string& FolderIterator::file_name() { return mFileName ; } }
uint64_t FolderIterator::file_size() { return mFileSize ; } }
time_t FolderIterator::file_modtime() { return mFileModTime ; }
uint8_t FolderIterator::file_type() { return mType ; } #ifdef DEBUG_FOLDER_ITERATOR
std::cerr << ": is unknown skipping" << std::endl;
bool FolderIterator::closedir() #endif
{
validity = false; mType = TYPE_UNKNOWN ;
mFileSize = 0 ;
if(!is_open) mFileModTime = 0;
return true ;
return false;
is_open = false ; }
#ifdef WINDOWS_SYS bool FolderIterator::readdir()
return FindClose(handle) != 0; {
#else if(!validity)
return ::closedir(handle) == 0; return false;
#endif
} #ifdef WINDOWS_SYS
return FindNextFileW(handle, &fileInfo) != 0;
#else
ent = ::readdir(handle);
return ent != NULL;
} } // librs::util #endif
}
time_t FolderIterator::dir_modtime() const { return mFolderModTime ; }
const std::string& FolderIterator::file_fullpath() { return mFullPath ; }
const std::string& FolderIterator::file_name() { return mFileName ; }
uint64_t FolderIterator::file_size() { return mFileSize ; }
time_t FolderIterator::file_modtime() { return mFileModTime ; }
uint8_t FolderIterator::file_type() { return mType ; }
bool FolderIterator::closedir()
{
validity = false;
if(!is_open)
return true ;
is_open = false ;
#ifdef WINDOWS_SYS
return FindClose(handle) != 0;
#else
return ::closedir(handle) == 0;
#endif
}
} } // librs::util

View File

@ -59,9 +59,8 @@ private:
DIR* handle; DIR* handle;
struct dirent* ent; struct dirent* ent;
#endif #endif
void updateStatsInfo() ; bool updateFileInfo(bool &should_skip) ;
bool mStatInfoOk ;
time_t mFileModTime ; time_t mFileModTime ;
time_t mFolderModTime ; time_t mFolderModTime ;
uint64_t mFileSize ; uint64_t mFileSize ;