Fix(license): IP list truncated at 4KB causing permanent data loss
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
@@ -36,24 +37,20 @@ public:
|
|||||||
if (!filePath || !filePath[0])
|
if (!filePath || !filePath[0])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FILE* f = nullptr;
|
std::ifstream f(filePath);
|
||||||
#ifdef _MSC_VER
|
if (!f.is_open())
|
||||||
if (fopen_s(&f, filePath, "r") != 0 || !f)
|
|
||||||
return false;
|
return false;
|
||||||
#else
|
|
||||||
f = fopen(filePath, "r");
|
|
||||||
if (!f)
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
// 不再使用固定行缓冲:超过 4KB 的行(如团购授权数百个 IP 的列表)会被
|
||||||
|
// fgets 拆成多段,第二段不带 '=' 会被 ParseLine 丢弃 → 显示截断。
|
||||||
|
// std::getline 按行读 std::string,无长度上限。
|
||||||
std::string currentSection;
|
std::string currentSection;
|
||||||
char line[4096];
|
std::string line;
|
||||||
|
while (std::getline(f, line)) {
|
||||||
while (fgets(line, sizeof(line), f)) {
|
if (!line.empty()) {
|
||||||
ParseLine(line, currentSection);
|
ParseLine(&line[0], currentSection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,13 +73,11 @@ public:
|
|||||||
while (lineEnd < end && *lineEnd != '\n' && *lineEnd != '\r')
|
while (lineEnd < end && *lineEnd != '\n' && *lineEnd != '\r')
|
||||||
lineEnd++;
|
lineEnd++;
|
||||||
|
|
||||||
// 复制行内容
|
// 不再限制行长度(原 4096 上限会悄无声息地丢弃长行)
|
||||||
size_t lineLen = lineEnd - p;
|
size_t lineLen = lineEnd - p;
|
||||||
if (lineLen > 0 && lineLen < 4096) {
|
if (lineLen > 0) {
|
||||||
char line[4096];
|
std::string line(p, lineLen);
|
||||||
memcpy(line, p, lineLen);
|
ParseLine(&line[0], currentSection);
|
||||||
line[lineLen] = '\0';
|
|
||||||
ParseLine(line, currentSection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跳过换行符
|
// 跳过换行符
|
||||||
@@ -100,24 +95,17 @@ public:
|
|||||||
if (!filePath || !filePath[0])
|
if (!filePath || !filePath[0])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
FILE* f = nullptr;
|
std::ifstream f(filePath);
|
||||||
#ifdef _MSC_VER
|
if (!f.is_open())
|
||||||
if (fopen_s(&f, filePath, "r") != 0 || !f)
|
|
||||||
return false;
|
return false;
|
||||||
#else
|
|
||||||
f = fopen(filePath, "r");
|
|
||||||
if (!f)
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::string currentSection;
|
std::string currentSection;
|
||||||
char line[4096];
|
std::string line;
|
||||||
|
while (std::getline(f, line)) {
|
||||||
while (fgets(line, sizeof(line), f)) {
|
if (!line.empty()) {
|
||||||
ParseLine(line, currentSection);
|
ParseLine(&line[0], currentSection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -208,9 +208,25 @@ public:
|
|||||||
|
|
||||||
virtual std::string GetStr(const std::string& MainKey, const std::string& SubKey, const std::string& def = "")
|
virtual std::string GetStr(const std::string& MainKey, const std::string& SubKey, const std::string& def = "")
|
||||||
{
|
{
|
||||||
char buf[4096] = { 0 }; // 增大缓冲区以支持较长的值(如 IP 列表)
|
// 动态扩容读取:GetPrivateProfileStringA 在缓冲不够时会从中间截断,
|
||||||
DWORD n = ::GetPrivateProfileStringA(MainKey.c_str(), SubKey.c_str(), def.c_str(), buf, sizeof(buf), m_IniFilePath);
|
// 必须以"是否返回 bufSize-1"判断截断并翻倍重读,否则长值(如团购授权的
|
||||||
return std::string(buf);
|
// IP 列表)会被悄无声息地切断,且后续 read-modify-write 把截断结果写回时
|
||||||
|
// 造成永久数据丢失。
|
||||||
|
DWORD bufSize = 4096;
|
||||||
|
const DWORD kMaxBufSize = 1024 * 1024; // 1MB 兜底,避免失控
|
||||||
|
std::vector<char> buf;
|
||||||
|
for (;;) {
|
||||||
|
buf.assign(bufSize, 0);
|
||||||
|
DWORD n = ::GetPrivateProfileStringA(MainKey.c_str(), SubKey.c_str(),
|
||||||
|
def.c_str(), buf.data(), bufSize,
|
||||||
|
m_IniFilePath);
|
||||||
|
// 未截断:n < bufSize - 1
|
||||||
|
if (n + 1 < bufSize || bufSize >= kMaxBufSize) {
|
||||||
|
return std::string(buf.data(), n);
|
||||||
|
}
|
||||||
|
bufSize *= 2;
|
||||||
|
if (bufSize > kMaxBufSize) bufSize = kMaxBufSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool SetStr(const std::string& MainKey, const std::string& SubKey, const std::string& Data)
|
virtual bool SetStr(const std::string& MainKey, const std::string& SubKey, const std::string& Data)
|
||||||
|
|||||||
Reference in New Issue
Block a user