Fixed infinite loop and crash which could occur when using "Import from cheat.db".

This commit is contained in:
Richard Ainger 2022-08-07 12:48:00 +10:00
parent 8478a8c86d
commit 7506fc9f00
2 changed files with 45 additions and 38 deletions

View file

@ -201,7 +201,6 @@ UI::EventReturn CwCheatScreen::OnImportCheat(UI::EventParams &params) {
}
std::string line;
std::vector<std::string> title;
bool finished = false;
std::vector<std::string> newList;
Path cheatFile = GetSysDirectory(DIRECTORY_CHEATS) / "cheat.db";
@ -215,43 +214,39 @@ UI::EventReturn CwCheatScreen::OnImportCheat(UI::EventParams &params) {
}
char linebuf[2048]{};
bool parseGameEntry = false;
bool parseCheatEntry = false;
while (in && !feof(in)) {
char *line = GetLineNoNewline(linebuf, sizeof(linebuf), in);
if (line && gameID == line) {
title.push_back(line);
line = GetLineNoNewline(linebuf, sizeof(linebuf), in);
if (line)
title.push_back(line);
do {
if (finished == false){
line = GetLineNoNewline(linebuf, sizeof(linebuf), in);
}
if (line && line[0] == '_' && line[1] == 'C') {
// Test if cheat already exists.
for (const auto &existing : fileInfo_) {
if (std::string(line).substr(4) == existing.name) {
finished = false;
goto loop;
}
}
newList.push_back(line);
line = GetLineNoNewline(linebuf, sizeof(linebuf), in);
do {
if (line)
newList.push_back(line);
line = GetLineNoNewline(linebuf, sizeof(linebuf), in);
} while ((line[0] == '_' && line[1] == 'L') || line[0] == '/' || line[0] == '#');
finished = true;
} else {
continue;
}
loop:;
} while (!feof(in) && ((line[0] == '_' && line[1] != 'S') || line[0] == '/' || line[0] == '#'));
finished = true;
if (!line) {
continue;
}
if (line[0] == '_' && line[1] == 'S') {
parseGameEntry = gameID == line;
parseCheatEntry = false;
} else if (parseGameEntry && line[0] == '_' && line[1] == 'C') {
// Test if cheat already exists.
parseCheatEntry = !HasCheatWithName(std::string(line).substr(4));
}
if (!parseGameEntry) {
if (newList.size() > 0) {
// Only parse the first matching game entry.
break;
} else {
// Haven't yet found a matching game entry, continue parsing.
continue;
}
}
if (line[0] == '_' && (line[1] == 'S' || line[1] == 'G') && title.size() < 2) {
title.push_back(line);
} else if (parseCheatEntry && (line[0] == '_' && (line[1] == 'C' || line[1] == 'L')) || line[0] == '/' || line[0] == '#') {
newList.push_back(line);
}
if (finished == true)
break;
}
fclose(in);
@ -270,12 +265,13 @@ UI::EventReturn CwCheatScreen::OnImportCheat(UI::EventParams &params) {
if (!append)
return UI::EVENT_SKIPPED;
auto it = title.begin();
if (((title2[0] == '_' && title2[1] != 'S') || title2[0] == '/' || title2[0] == '#') && it != title.end() && (++it) != title.end()) {
fprintf(append, "%s\n%s", title[0].c_str(), title[1].c_str());
if (title2.size() == 0 || title2[0] != '_' || title2[1] != 'S') {
for (int i = (int)title.size(); i > 0; i--) {
newList.insert(newList.begin(), title[i - 1]);
}
}
NOTICE_LOG(COMMON, "Imported %u entries from %s.\n", (int)newList.size(), cheatFile.c_str());
NOTICE_LOG(COMMON, "Imported %u lines from %s.\n", (int)newList.size(), cheatFile.c_str());
if (newList.size() != 0) {
fputc('\n', append);
}
@ -303,6 +299,16 @@ UI::EventReturn CwCheatScreen::OnCheckBox(int index) {
return UI::EVENT_DONE;
}
bool CwCheatScreen::HasCheatWithName(const std::string &name) {
for (const auto &existing : fileInfo_) {
if (name == existing.name) {
return true;
}
}
return false;
}
bool CwCheatScreen::RebuildCheatFile(int index) {
if (!engine_)
return false;