Fix memory leaks in Yaml parsing (PR #886)

This commit is contained in:
Andrea 2020-12-09 20:24:36 +00:00 committed by GitHub
parent 65b8f5fdbf
commit 8304c5738f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 26 deletions

View File

@ -51,10 +51,14 @@ void YamlHelper::FinaliseParser(void)
fclose(m_hFile); fclose(m_hFile);
m_hFile = NULL; m_hFile = NULL;
yaml_event_delete(&m_newEvent);
yaml_parser_delete(&m_parser);
} }
void YamlHelper::GetNextEvent(bool bInMap /*= false*/) void YamlHelper::GetNextEvent()
{ {
yaml_event_delete(&m_newEvent);
if (!yaml_parser_parse(&m_parser, &m_newEvent)) if (!yaml_parser_parse(&m_parser, &m_newEvent))
{ {
std::string error = std::string("Save-state parser error: "); std::string error = std::string("Save-state parser error: ");
@ -116,13 +120,13 @@ int YamlHelper::ParseMap(MapYaml& mapYaml)
const char*& pValue = (const char*&) m_newEvent.data.scalar.value; const char*& pValue = (const char*&) m_newEvent.data.scalar.value;
bool bKey = true; bool bKey = true;
char* pKey = NULL; std::string pKey;
int res = 1; int res = 1;
bool bDone = false; bool bDone = false;
while (!bDone) while (!bDone)
{ {
GetNextEvent(true); GetNextEvent();
switch(m_newEvent.type) switch(m_newEvent.type)
{ {
@ -135,7 +139,7 @@ int YamlHelper::ParseMap(MapYaml& mapYaml)
MapValue mapValue; MapValue mapValue;
mapValue.value = ""; mapValue.value = "";
mapValue.subMap = new MapYaml; mapValue.subMap = new MapYaml;
mapYaml[std::string(pKey)] = mapValue; mapYaml[pKey] = mapValue;
res = ParseMap(*mapValue.subMap); res = ParseMap(*mapValue.subMap);
if (!res) if (!res)
throw std::string("ParseMap: premature end of file during map parsing"); throw std::string("ParseMap: premature end of file during map parsing");
@ -148,15 +152,16 @@ int YamlHelper::ParseMap(MapYaml& mapYaml)
case YAML_SCALAR_EVENT: case YAML_SCALAR_EVENT:
if (bKey) if (bKey)
{ {
pKey = _strdup(pValue); _ASSERT(pValue); // std::string(NULL) generates AccessViolation
pKey = pValue;
} }
else else
{ {
MapValue mapValue; MapValue mapValue;
mapValue.value = pValue; mapValue.value = pValue;
mapValue.subMap = NULL; mapValue.subMap = NULL;
mapYaml[std::string(pKey)] = mapValue; mapYaml[pKey] = mapValue;
free(pKey); pKey = NULL; pKey.clear();
} }
bKey = bKey ? false : true; bKey = bKey ? false : true;
@ -167,13 +172,10 @@ int YamlHelper::ParseMap(MapYaml& mapYaml)
} }
} }
if (pKey)
free(pKey);
return res; return res;
} }
std::string YamlHelper::GetMapValue(MapYaml& mapYaml, const std::string key, bool& bFound) std::string YamlHelper::GetMapValue(MapYaml& mapYaml, const std::string& key, bool& bFound)
{ {
MapYaml::const_iterator iter = mapYaml.find(key); MapYaml::const_iterator iter = mapYaml.find(key);
if (iter == mapYaml.end() || iter->second.subMap != NULL) if (iter == mapYaml.end() || iter->second.subMap != NULL)
@ -190,7 +192,7 @@ std::string YamlHelper::GetMapValue(MapYaml& mapYaml, const std::string key, boo
return value; return value;
} }
bool YamlHelper::GetSubMap(MapYaml** mapYaml, const std::string key) bool YamlHelper::GetSubMap(MapYaml** mapYaml, const std::string& key)
{ {
MapYaml::const_iterator iter = (*mapYaml)->find(key); MapYaml::const_iterator iter = (*mapYaml)->find(key);
if (iter == (*mapYaml)->end() || iter->second.subMap == NULL) if (iter == (*mapYaml)->end() || iter->second.subMap == NULL)
@ -349,7 +351,7 @@ std::string YamlLoadHelper::LoadString(const std::string& key)
return value; return value;
} }
float YamlLoadHelper::LoadFloat(const std::string key) float YamlLoadHelper::LoadFloat(const std::string& key)
{ {
bool bFound; bool bFound;
std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound);
@ -365,7 +367,7 @@ float YamlLoadHelper::LoadFloat(const std::string key)
#endif #endif
} }
double YamlLoadHelper::LoadDouble(const std::string key) double YamlLoadHelper::LoadDouble(const std::string& key)
{ {
bool bFound; bool bFound;
std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound);
@ -575,7 +577,7 @@ void YamlSaveHelper::FileHdr(UINT version)
SaveInt(SS_YAML_KEY_VERSION, version); SaveInt(SS_YAML_KEY_VERSION, version);
} }
void YamlSaveHelper::UnitHdr(std::string type, UINT version) void YamlSaveHelper::UnitHdr(const std::string& type, UINT version)
{ {
fprintf(m_hFile, "\n%s:\n", SS_YAML_KEY_UNIT); fprintf(m_hFile, "\n%s:\n", SS_YAML_KEY_UNIT);
m_indent = 2; m_indent = 2;

View File

@ -30,13 +30,13 @@ public:
m_hFile(NULL) m_hFile(NULL)
{ {
memset(&m_parser, 0, sizeof(m_parser)); memset(&m_parser, 0, sizeof(m_parser));
memset(&m_newEvent, 0, sizeof(m_newEvent));
MakeAsciiToHexTable(); MakeAsciiToHexTable();
} }
~YamlHelper(void) ~YamlHelper(void)
{ {
if (m_hFile) FinaliseParser();
fclose(m_hFile);
} }
int InitParser(const char* pPathname); int InitParser(const char* pPathname);
@ -46,11 +46,11 @@ public:
void GetMapStartEvent(void); void GetMapStartEvent(void);
private: private:
void GetNextEvent(bool bInMap = false); void GetNextEvent();
int ParseMap(MapYaml& mapYaml); int ParseMap(MapYaml& mapYaml);
std::string GetMapValue(MapYaml& mapYaml, const std::string key, bool& bFound); std::string GetMapValue(MapYaml& mapYaml, const std::string &key, bool& bFound);
UINT LoadMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize); UINT LoadMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize);
bool GetSubMap(MapYaml** mapYaml, const std::string key); bool GetSubMap(MapYaml** mapYaml, const std::string &key);
void GetMapRemainder(std::string& mapName, MapYaml& mapYaml); void GetMapRemainder(std::string& mapName, MapYaml& mapYaml);
void MakeAsciiToHexTable(void); void MakeAsciiToHexTable(void);
@ -98,12 +98,12 @@ public:
bool LoadBool(const std::string key); bool LoadBool(const std::string key);
std::string LoadString_NoThrow(const std::string& key, bool& bFound); std::string LoadString_NoThrow(const std::string& key, bool& bFound);
std::string LoadString(const std::string& key); std::string LoadString(const std::string& key);
float LoadFloat(const std::string key); float LoadFloat(const std::string & key);
double LoadDouble(const std::string key); double LoadDouble(const std::string & key);
void LoadMemory(const LPBYTE pMemBase, const size_t size); void LoadMemory(const LPBYTE pMemBase, const size_t size);
void LoadMemory(std::vector<BYTE>& memory, const size_t size); void LoadMemory(std::vector<BYTE>& memory, const size_t size);
bool GetSubMap(const std::string key) bool GetSubMap(const std::string & key)
{ {
YamlStackItem item = {m_pMapYaml, m_currentMapName}; YamlStackItem item = {m_pMapYaml, m_currentMapName};
m_stackMap.push(item); m_stackMap.push(item);
@ -170,7 +170,7 @@ private:
class YamlSaveHelper class YamlSaveHelper
{ {
public: public:
YamlSaveHelper(std::string pathname) : YamlSaveHelper(const std::string & pathname) :
m_hFile(NULL), m_hFile(NULL),
m_indent(0), m_indent(0),
m_pWcStr(NULL), m_pWcStr(NULL),
@ -259,7 +259,7 @@ public:
class Slot : public Label class Slot : public Label
{ {
public: public:
Slot(YamlSaveHelper& rYamlSaveHelper, std::string type, UINT slot, UINT version) : Slot(YamlSaveHelper& rYamlSaveHelper, const std::string & type, UINT slot, UINT version) :
Label(rYamlSaveHelper, "%d:\n", slot) Label(rYamlSaveHelper, "%d:\n", slot)
{ {
rYamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_CARD, type.c_str()); rYamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_CARD, type.c_str());
@ -270,7 +270,7 @@ public:
}; };
void FileHdr(UINT version); void FileHdr(UINT version);
void UnitHdr(std::string type, UINT version); void UnitHdr(const std::string & type, UINT version);
private: private:
FILE* m_hFile; FILE* m_hFile;