mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
fixed possible uninitialised memory read in folderiterator for windows, and changed file folderiterator.cc to unix format
This commit is contained in:
parent
fb302002d6
commit
d433713bd0
@ -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
|
||||||
|
@ -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 ;
|
||||||
|
Loading…
Reference in New Issue
Block a user