Skip to content

Commit e30df91

Browse files
ini_text: handle UTF-8 BOM in ReShade.ini
ReShade Setup writes ReShade.ini with a UTF-8 BOM (the runtime rewrites it without on first game exit), so the exact-case section matcher saw 'BOM[GENERAL]' and never found the keys - normalize_search_paths silently no-op'd on fresh installs, leaving the malformed **\** search paths in place (error 123 again). The BOM is now stripped for parsing and preserved on write. Verified against a live headless-setup run in a sandbox folder: setup writes Shaders\**\**, FeedKit normalizes to Shaders\**.
1 parent 685883b commit e30df91

1 file changed

Lines changed: 24 additions & 16 deletions

File tree

src/ini_text.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,18 @@ namespace fk {
88

99
namespace {
1010

11-
std::vector<std::wstring> split_lines(const std::string& data, bool& trailing_newline) {
11+
// ReShade Setup writes ReShade.ini with a UTF-8 BOM; the runtime rewrites it
12+
// without. Track the BOM so section matching sees the real first line.
13+
bool load_ini_lines(const std::wstring& file, std::vector<std::wstring>& lines, bool& trailing_newline, bool& had_bom) {
14+
std::string data;
15+
if (!read_file(file, data))
16+
return false;
17+
had_bom = data.size() >= 3 && (unsigned char)data[0] == 0xEF && (unsigned char)data[1] == 0xBB &&
18+
(unsigned char)data[2] == 0xBF;
19+
if (had_bom)
20+
data.erase(0, 3);
21+
1222
std::wstring w = to_wide(data);
13-
std::vector<std::wstring> lines;
1423
size_t start = 0;
1524
while (start < w.size()) {
1625
size_t nl = w.find(L'\n', start);
@@ -21,18 +30,20 @@ std::vector<std::wstring> split_lines(const std::string& data, bool& trailing_ne
2130
start = nl + 1;
2231
}
2332
trailing_newline = !w.empty() && w.back() == L'\n';
24-
if (lines.empty()) trailing_newline = false;
25-
return lines;
33+
return true;
2634
}
2735

28-
std::string join_lines(const std::vector<std::wstring>& lines, bool trailing_newline) {
36+
bool save_ini_lines(const std::wstring& file, const std::vector<std::wstring>& lines,
37+
bool trailing_newline, bool had_bom) {
2938
std::wstring w;
3039
for (size_t i = 0; i < lines.size(); i++) {
3140
w += lines[i];
3241
if (i + 1 < lines.size() || trailing_newline)
3342
w += L"\r\n";
3443
}
35-
return to_utf8(w);
44+
std::string out = to_utf8(w);
45+
std::string bom = had_bom ? "\xEF\xBB\xBF" : "";
46+
return write_file(file, (bom + out).c_str(), bom.size() + out.size());
3647
}
3748

3849
bool find_key_line(const std::vector<std::wstring>& lines, const std::wstring& section,
@@ -58,11 +69,10 @@ bool find_key_line(const std::vector<std::wstring>& lines, const std::wstring& s
5869
bool ini_get_exact(const std::wstring& file, const std::wstring& section,
5970
const std::wstring& key, std::wstring& value) {
6071
value.clear();
61-
std::string data;
62-
if (!read_file(file, data))
72+
bool trailing = false, had_bom = false;
73+
std::vector<std::wstring> lines;
74+
if (!load_ini_lines(file, lines, trailing, had_bom))
6375
return false;
64-
bool trailing;
65-
std::vector<std::wstring> lines = split_lines(data, trailing);
6676
size_t idx = 0;
6777
if (!find_key_line(lines, section, key, idx))
6878
return false;
@@ -73,11 +83,10 @@ bool ini_get_exact(const std::wstring& file, const std::wstring& section,
7383

7484
bool ini_set_exact(const std::wstring& file, const std::wstring& section,
7585
const std::wstring& key, const std::wstring& value) {
76-
std::string data;
77-
if (!read_file(file, data))
86+
bool trailing = false, had_bom = false;
87+
std::vector<std::wstring> lines;
88+
if (!load_ini_lines(file, lines, trailing, had_bom))
7889
return false;
79-
bool trailing;
80-
std::vector<std::wstring> lines = split_lines(data, trailing);
8190

8291
size_t idx = 0;
8392
if (find_key_line(lines, section, key, idx)) {
@@ -110,8 +119,7 @@ bool ini_set_exact(const std::wstring& file, const std::wstring& section,
110119
lines.insert(lines.begin() + insert_at, key + L"=" + value);
111120
}
112121

113-
const std::string out = join_lines(lines, trailing);
114-
return write_file(file, out.c_str(), out.size());
122+
return save_ini_lines(file, lines, trailing, had_bom);
115123
}
116124

117125
} // namespace fk

0 commit comments

Comments
 (0)