From ae1eed1caead944dcc27a93edf9afb85e7fbc8c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Apr 2026 12:50:02 +0000 Subject: [PATCH 1/7] Fix robustness issue with empty JSON in cfg.json and wsec.json Agent-Logs-Url: https://github.com/MoonModules/WLED-MM/sessions/f446b25c-8344-4ded-8cb3-61c246c5ab5b Co-authored-by: softhack007 <91616163+softhack007@users.noreply.github.com> --- wled00/cfg.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 653da685c9..9762ea4f74 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -659,7 +659,7 @@ void deserializeConfigFromFS() { DEBUG_PRINTLN(F("Reading settings from /cfg.json...")); success = readObjectFromFile("/cfg.json", nullptr, &doc); - if (!success) { // if file does not exist, optionally try reading from EEPROM and then save defaults to FS + if (!success || doc.size() == 0) { // if file does not exist or contains only empty JSON (e.g. "{}"), optionally try reading from EEPROM and then save defaults to FS releaseJSONBufferLock(); #ifdef WLED_ADD_EEPROM_SUPPORT deEEPSettings(); @@ -1122,7 +1122,7 @@ bool deserializeConfigSec() { if (!requestJSONBufferLock(3)) return false; bool success = readObjectFromFile("/wsec.json", nullptr, &doc); - if (!success) { + if (!success || doc.size() == 0) { // treat empty JSON (e.g. "{}") the same as a missing file releaseJSONBufferLock(); return false; } From ba6716930533609a403741d3807bb724c03b7044 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Apr 2026 13:16:03 +0000 Subject: [PATCH 2/7] Fix robustness issue with empty presets.json containing only {} Agent-Logs-Url: https://github.com/MoonModules/WLED-MM/sessions/92f2e0c0-5bab-4607-9e9f-7f48416a7da3 Co-authored-by: softhack007 <91616163+softhack007@users.noreply.github.com> --- wled00/presets.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/wled00/presets.cpp b/wled00/presets.cpp index 4d118f196b..55c4e5b17f 100644 --- a/wled00/presets.cpp +++ b/wled00/presets.cpp @@ -123,7 +123,15 @@ bool getPresetName(byte index, String& name) void initPresetsFile() { - if (WLED_FS.exists(getFileName())) return; + if (WLED_FS.exists(getFileName())) { + // treat an empty JSON file (e.g. "{}") the same as a missing file: + // f.size() < 3 is the same threshold used in appendObjectToFile() to detect an uninitialized file + File f = WLED_FS.open(getFileName(), "r"); + bool empty = f && f.size() < 3; + if (f) f.close(); + if (!empty) return; + WLED_FS.remove(getFileName()); // remove the empty file so it can be recreated below + } StaticJsonDocument<64> doc; JsonObject sObj = doc.to(); From abeb8b7a0ff19afe9b0110af2337b518f1712fb3 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Apr 2026 13:18:57 +0000 Subject: [PATCH 3/7] Address code review: cleaner file handle pattern and clarify EEPROM comment Agent-Logs-Url: https://github.com/MoonModules/WLED-MM/sessions/92f2e0c0-5bab-4607-9e9f-7f48416a7da3 Co-authored-by: softhack007 <91616163+softhack007@users.noreply.github.com> --- wled00/cfg.cpp | 2 +- wled00/presets.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wled00/cfg.cpp b/wled00/cfg.cpp index 9762ea4f74..e8e75ca91d 100644 --- a/wled00/cfg.cpp +++ b/wled00/cfg.cpp @@ -659,7 +659,7 @@ void deserializeConfigFromFS() { DEBUG_PRINTLN(F("Reading settings from /cfg.json...")); success = readObjectFromFile("/cfg.json", nullptr, &doc); - if (!success || doc.size() == 0) { // if file does not exist or contains only empty JSON (e.g. "{}"), optionally try reading from EEPROM and then save defaults to FS + if (!success || doc.size() == 0) { // if file does not exist or contains only empty JSON (e.g. "{}"), try reading from EEPROM (if supported) and then save defaults to FS releaseJSONBufferLock(); #ifdef WLED_ADD_EEPROM_SUPPORT deEEPSettings(); diff --git a/wled00/presets.cpp b/wled00/presets.cpp index 55c4e5b17f..3824a286ea 100644 --- a/wled00/presets.cpp +++ b/wled00/presets.cpp @@ -127,9 +127,9 @@ void initPresetsFile() // treat an empty JSON file (e.g. "{}") the same as a missing file: // f.size() < 3 is the same threshold used in appendObjectToFile() to detect an uninitialized file File f = WLED_FS.open(getFileName(), "r"); - bool empty = f && f.size() < 3; + size_t sz = f ? f.size() : 3; // default to 3 (valid) if open fails, to avoid spurious deletion if (f) f.close(); - if (!empty) return; + if (sz >= 3) return; WLED_FS.remove(getFileName()); // remove the empty file so it can be recreated below } From 215648a8138851338e1e21ec45bceed099fdaaa8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 5 Apr 2026 13:29:16 +0000 Subject: [PATCH 4/7] Simplify initPresetsFile: use inline bool empty instead of sz variable Agent-Logs-Url: https://github.com/MoonModules/WLED-MM/sessions/3ceab8b4-0b22-4361-8e78-9b95793cf1c2 Co-authored-by: softhack007 <91616163+softhack007@users.noreply.github.com> --- wled00/presets.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wled00/presets.cpp b/wled00/presets.cpp index 3824a286ea..55c4e5b17f 100644 --- a/wled00/presets.cpp +++ b/wled00/presets.cpp @@ -127,9 +127,9 @@ void initPresetsFile() // treat an empty JSON file (e.g. "{}") the same as a missing file: // f.size() < 3 is the same threshold used in appendObjectToFile() to detect an uninitialized file File f = WLED_FS.open(getFileName(), "r"); - size_t sz = f ? f.size() : 3; // default to 3 (valid) if open fails, to avoid spurious deletion + bool empty = f && f.size() < 3; if (f) f.close(); - if (sz >= 3) return; + if (!empty) return; WLED_FS.remove(getFileName()); // remove the empty file so it can be recreated below } From 662442861c7f74dbcd03316f917fa2d9cebdf253 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 5 Apr 2026 16:41:38 +0200 Subject: [PATCH 5/7] clarify logic in initPresetFile(), raise "empty" threshold to 3 bytes. * clarify the logic inside the "early return" path * use "<4" as threshold for "empty" --- wled00/file.cpp | 2 +- wled00/presets.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/wled00/file.cpp b/wled00/file.cpp index 56af35cc75..102be02d3e 100644 --- a/wled00/file.cpp +++ b/wled00/file.cpp @@ -223,7 +223,7 @@ bool appendObjectToFile(const char* key, JsonDocument* content, uint32_t s, uint uint32_t pos = 0; if (!f) return false; - if (f.size() < 3) { + if (f.size() < 4) { // file uninitialized -> write minimal preset char init[12]; strcpy_P(init, PSTR("{\"0\":{}}")); f.print(init); diff --git a/wled00/presets.cpp b/wled00/presets.cpp index 55c4e5b17f..6995a6ee7c 100644 --- a/wled00/presets.cpp +++ b/wled00/presets.cpp @@ -124,13 +124,13 @@ bool getPresetName(byte index, String& name) void initPresetsFile() { if (WLED_FS.exists(getFileName())) { - // treat an empty JSON file (e.g. "{}") the same as a missing file: - // f.size() < 3 is the same threshold used in appendObjectToFile() to detect an uninitialized file + // treat an empty JSON file (e.g. "{}", "{ }") the same as a missing file: + // f.size() < 4 is the same threshold used in appendObjectToFile() to detect an uninitialized file File f = WLED_FS.open(getFileName(), "r"); - bool empty = f && f.size() < 3; + bool empty = f && f.size() < 4; // file does exist due to previous "if" if (f) f.close(); - if (!empty) return; - WLED_FS.remove(getFileName()); // remove the empty file so it can be recreated below + if (!empty) return; // file not empty -> keep (nothing to init) + WLED_FS.remove(getFileName()); // remove the empty file so it can be recreated below } StaticJsonDocument<64> doc; From eff4bbf792ecaeedae7980e0ebc136fd36141302 Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 5 Apr 2026 16:50:06 +0200 Subject: [PATCH 6/7] comment clarification --- wled00/file.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/file.cpp b/wled00/file.cpp index 102be02d3e..2480f110b4 100644 --- a/wled00/file.cpp +++ b/wled00/file.cpp @@ -223,7 +223,7 @@ bool appendObjectToFile(const char* key, JsonDocument* content, uint32_t s, uint uint32_t pos = 0; if (!f) return false; - if (f.size() < 4) { // file uninitialized -> write minimal preset + if (f.size() < 4) { // file uninitialized -> write minimal skeleton char init[12]; strcpy_P(init, PSTR("{\"0\":{}}")); f.print(init); From 3a0d636368f8d6a4ed630201495c443e15a7fffe Mon Sep 17 00:00:00 2001 From: Frank <91616163+softhack007@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:11:53 +0200 Subject: [PATCH 7/7] clarify "early return" logic in initPresetsFile() --- wled00/presets.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wled00/presets.cpp b/wled00/presets.cpp index 6995a6ee7c..35436018d9 100644 --- a/wled00/presets.cpp +++ b/wled00/presets.cpp @@ -127,10 +127,10 @@ void initPresetsFile() // treat an empty JSON file (e.g. "{}", "{ }") the same as a missing file: // f.size() < 4 is the same threshold used in appendObjectToFile() to detect an uninitialized file File f = WLED_FS.open(getFileName(), "r"); - bool empty = f && f.size() < 4; // file does exist due to previous "if" + bool empty = f && f.size() < 4; // file does exist due to previous "if" if (f) f.close(); - if (!empty) return; // file not empty -> keep (nothing to init) - WLED_FS.remove(getFileName()); // remove the empty file so it can be recreated below + if (empty) WLED_FS.remove(getFileName()); // remove the empty file so it can be recreated below + else return; // file not empty -> keep (nothing to init) } StaticJsonDocument<64> doc;