1
0
Fork 0

Memory overrun and C++11 updates

- Limit write length into buffer, and add comment about corner-case
- Use C++11's syntax to explicitly remove private copy and assignment operators
- Use C++11 container loop syntax to shorting a cleanup function
This commit is contained in:
krcroft 2019-12-07 09:36:37 -08:00 committed by Patryk Obara
parent 959417f6de
commit 8c6758c8d1
3 changed files with 56 additions and 47 deletions

View file

@ -119,19 +119,19 @@ private:
class localFile : public DOS_File {
public:
localFile(const char* name, FILE * handle);
bool Read(Bit8u * data,Bit16u * size);
bool Write(Bit8u * data,Bit16u * size);
bool Seek(Bit32u * pos,Bit32u type);
bool Close();
Bit16u GetInformation(void);
bool UpdateDateTimeFromHost(void);
void FlagReadOnlyMedium(void);
void Flush(void);
localFile (const char* name, FILE * handle);
localFile (const localFile&) = delete; // prevent copying
localFile& operator= (const localFile&) = delete; // prevent assignment
bool Read (Bit8u * data,Bit16u * size);
bool Write (Bit8u * data,Bit16u * size);
bool Seek (Bit32u * pos,Bit32u type);
bool Close (void);
Bit16u GetInformation (void);
bool UpdateDateTimeFromHost (void);
void FlagReadOnlyMedium (void);
void Flush (void);
FILE * fhandle; //todo handle this properly
private:
localFile(const localFile&); // prevent copying
localFile& operator= (const localFile&); // prevent assignment
bool read_only_medium;
enum { NONE,READ,WRITE } last_action;
};
@ -144,33 +144,34 @@ private:
class DOS_Drive_Cache {
public:
DOS_Drive_Cache (void);
DOS_Drive_Cache (const char* path);
~DOS_Drive_Cache (void);
enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV };
DOS_Drive_Cache (void);
DOS_Drive_Cache (const char* path);
DOS_Drive_Cache (const DOS_Drive_Cache&); // prevent copying
DOS_Drive_Cache& operator= (const DOS_Drive_Cache&); // prevent assignment
~DOS_Drive_Cache (void);
void SetBaseDir (const char* path);
void SetDirSort (TDirSort sort) { sortDirType = sort; };
bool OpenDir (const char* path, Bit16u& id);
bool ReadDir (Bit16u id, char* &result);
void SetBaseDir (const char* path);
void SetDirSort (TDirSort sort) { sortDirType = sort; };
bool OpenDir (const char* path, Bit16u& id);
bool ReadDir (Bit16u id, char* &result);
void ExpandName (char* path);
char* GetExpandName (const char* path);
bool GetShortName (const char* fullname, char* shortname);
void ExpandName (char* path);
char* GetExpandName (const char* path);
bool GetShortName (const char* fullname, char* shortname);
bool FindFirst (char* path, Bit16u& id);
bool FindNext (Bit16u id, char* &result);
bool FindFirst (char* path, Bit16u& id);
bool FindNext (Bit16u id, char* &result);
void CacheOut (const char* path, bool ignoreLastDir = false);
void AddEntry (const char* path, bool checkExist = false);
void AddEntryDirOverlay (const char* path, bool checkExist = false);
void CacheOut (const char* path, bool ignoreLastDir = false);
void AddEntry (const char* path, bool checkExist = false);
void AddEntryDirOverlay (const char* path, bool checkExist = false);
void DeleteEntry (const char* path, bool ignoreLastDir = false);
void DeleteEntry (const char* path, bool ignoreLastDir = false);
void EmptyCache (void);
void EmptyCache (void);
void SetLabel (const char* name,bool cdrom,bool allowupdate);
char* GetLabel (void) { return label; };
void SetLabel (const char* name,bool cdrom,bool allowupdate);
char* GetLabel (void) { return label; };
class CFileInfo {
public:
@ -187,25 +188,25 @@ public:
{
}
~CFileInfo(void) {
for (Bit32u i=0; i<fileList.size(); i++) delete fileList[i];
for (auto p : fileList) {
delete p;
}
fileList.clear();
longNameList.clear();
};
char orgname [CROSS_LEN];
char shortname [DOS_NAMELENGTH_ASCII];
bool isOverlayDir;
bool isDir;
Bit16u id;
Bitu nextEntry;
Bitu shortNr;
char orgname[CROSS_LEN];
char shortname[DOS_NAMELENGTH_ASCII];
bool isOverlayDir;
bool isDir;
Bit16u id;
Bitu nextEntry;
Bitu shortNr;
// contents
std::vector<CFileInfo*> fileList;
std::vector<CFileInfo*> longNameList;
std::vector<CFileInfo*> fileList;
std::vector<CFileInfo*> longNameList;
};
private:
DOS_Drive_Cache(const DOS_Drive_Cache&); // prevent copying
DOS_Drive_Cache& operator= (const DOS_Drive_Cache&); // prevent assignment
void ClearFileInfo(CFileInfo *dir);
void DeleteFileInfo(CFileInfo *dir);

View file

@ -51,8 +51,8 @@
template<size_t N>
char * safe_strcpy(char (& dst)[N], const char * src) noexcept {
snprintf(dst, N, "%s", src);
return & dst[0];
snprintf(dst, N, "%s", src);
return & dst[0];
}
#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0)

View file

@ -622,7 +622,15 @@ void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info) {
// Create number
char buffer[8];
info->shortNr = CreateShortNameID(curDir,tmpName);
sprintf(buffer,"%" PRIuPTR, info->shortNr);
// If processing a directory containing 10 million or more long files,
// then ten duplicate short filenames will be named ~1000000.ext,
// another 10 duplicates will be named ~1000001.ext, and so on, back
// through to ~9999999.ext if 999,999,999 files are present.
// Yes, this is a broken corner-case, but is still memory-safe.
// TODO: modify MOUNT/IMGMOUNT to exit with an error when encountering
// a directory having more than 65534 files, which is FAT32's limit.
snprintf(buffer, sizeof(buffer), "%" PRIuPTR, info->shortNr);
// Copy first letters
Bits tocopy = 0;
size_t buflen = strlen(buffer);
@ -941,7 +949,7 @@ bool DOS_Drive_Cache::FindFirst(char* path, Bit16u& id) {
}
assert(dirFindFirst[dirFindFirstID] == nullptr);
dirFindFirst[dirFindFirstID] = new CFileInfo();
dirFindFirst[dirFindFirstID]-> nextEntry = 0;
dirFindFirst[dirFindFirstID]->nextEntry = 0;
// Copy entries to use with FindNext
for (Bitu i=0; i<dirSearch[dirID]->fileList.size(); i++) {