fix: refact KeyFile::loadFile

To void invalid memory access issues.

Signed-off-by: black-desk <me@black-desk.cn>
This commit is contained in:
tsic404 2023-05-11 17:34:59 +08:00 committed by 爱折腾的小竹同学
parent c0b424cedc
commit 611bc0e092
2 changed files with 59 additions and 62 deletions

View File

@ -8,22 +8,19 @@
#include "macro.h" #include "macro.h"
#include <cstring> #include <cstring>
#include <fstream>
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <algorithm>
KeyFile::KeyFile(char separtor) KeyFile::KeyFile(char separtor)
: m_fp(nullptr) : m_modified(false)
, m_modified(false)
, m_listSeparator(separtor) , m_listSeparator(separtor)
{ {
} }
KeyFile::~KeyFile() KeyFile::~KeyFile()
{ {
if (m_fp) {
fclose(m_fp);
m_fp = nullptr;
}
} }
bool KeyFile::getBool(const std::string &section, const std::string &key, bool defaultValue) bool KeyFile::getBool(const std::string &section, const std::string &key, bool defaultValue)
@ -205,51 +202,57 @@ bool KeyFile::writeSectionToFile(const std::string& sectionName, const KeyMap& k
bool KeyFile::loadFile(const std::string &filePath) bool KeyFile::loadFile(const std::string &filePath)
{ {
m_mainKeyMap.clear(); m_mainKeyMap.clear();
if (m_fp) {
fclose(m_fp);
m_fp = nullptr;
}
std::string lastSection; std::string lastSection;
m_fp = fopen(filePath.data(), "r"); std::ifstream fs(filePath);
if (!m_fp) { if (!fs.is_open()) {
perror("open file failed: "); perror("open file failed: ");
return false; return false;
} }
char line[MAX_LINE_LEN] = {0}; std::string line;
while (fgets(line, MAX_LINE_LEN, m_fp)) { while (std::getline(fs, line)) {
char *start = &line[0]; line.erase(
char *end = start; line.begin(),
while (!strneq(end, "\0", 1)) std::find_if(
end++; line.begin(), line.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))
)
);
end--; // 返回'\0'前一个字符 if (line.front() == '#') {
// 移除行首
while (strneq(start, " ", 1) || strneq(start, "\t", 1))
start++;
// 过滤注释行
if (strneq(start, "#", 1))
continue; continue;
}
// 移除行尾 line.erase(
while (strneq(end, "\n", 1) || strneq(end, "\r", 1) std::find_if(
|| strneq(end, " ", 1) || strneq(end, "\t", 1)) line.rbegin(), line.rend(),
end--; std::not1(std::ptr_fun<int, int>(std::isspace))
).base(),
line.end()
);
char *lPos = strchr(start, '['); if (line.front() == '[') {
char *rPos = strchr(start, ']'); auto rPos = line.find_first_of(']');
if (lPos && rPos && rPos - lPos > 0 && lPos == start && rPos == end) { if ( rPos != std::string::npos && 0 < rPos ) {
// 主键
std::string section(lPos + 1, size_t(rPos - lPos - 1)); lastSection = line.substr(1, rPos-1);
m_mainKeyMap.insert({section, KeyMap()});
lastSection = section; m_mainKeyMap.insert({
} else { lastSection,
char *equal = strchr(start, '='); KeyMap()
if (!equal) });
}
continue; continue;
}
auto equalPos = line.find_first_of('=');
if (equalPos == std::string::npos) {
continue;
}
// 文件格式错误 // 文件格式错误
if (lastSection.empty()) { if (lastSection.empty()) {
@ -258,18 +261,13 @@ bool KeyFile::loadFile(const std::string &filePath)
} }
// 子键 // 子键
std::string key(start, size_t(equal - start)); std::string key = line.substr(0, equalPos);
std::string value(equal + 1, size_t(end - equal)); std::string value = equalPos + 1 < line.length() ?
for (auto &iter : m_mainKeyMap) { line.substr(equalPos + 1) :
if (iter.first != lastSection) "";
continue; m_mainKeyMap[lastSection][key] = value;
}
iter.second[key] = value;
}
}
}
fclose(m_fp);
m_fp = nullptr;
m_filePath = filePath; m_filePath = filePath;
return true; return true;

View File

@ -49,7 +49,6 @@ public:
protected: protected:
MainKeyMap m_mainKeyMap; // section -> key : value MainKeyMap m_mainKeyMap; // section -> key : value
std::string m_filePath; std::string m_filePath;
FILE *m_fp;
bool m_modified; bool m_modified;
char m_listSeparator; char m_listSeparator;