From 19fe554bc8e033ce1001123d308262ea985f7f08 Mon Sep 17 00:00:00 2001 From: Pixel Perfect Date: Sun, 2 Aug 2026 01:22:03 -0700 Subject: [PATCH] fix(storage): only judge the profile-tree root absent sdProfileTreeContainsFile() re-stat'ed every recursive child with SD.exists() before opening it. The child came straight from openNextFile(), so it provably exists; the check can only ever produce a false negative, and false is the single verdict that lets a residual foreign subtree read as empty and the card get claimed. Every other uncertainty in this function already fails closed. Keep the check at the root, where "/meshcomod is absent" genuinely means there is nothing to conflict with, and let the open() fail-closed path govern below it. Signed-off-by: Pixel Perfect --- src/main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 6fcc2370..0189d221 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -237,7 +237,12 @@ static constexpr const char* kSdMigrationOwner = "/meshcomod/.spiffs-migration-v static constexpr const char* kSdMigrationOwnerTmp = "/meshcomod/.spiffs-migration-v1.owner.tmp"; static bool sdProfileTreeContainsFile(const char* path, uint8_t depth = 0) { - if (!SD.exists(path)) return false; + // Only the root may be judged absent. A recursive child came straight from + // openNextFile(), so it provably exists and re-stat'ing it can only produce a + // false negative — which would be the one verdict that lets a foreign + // residual subtree read as empty and get claimed. Below the root, let the + // open() fail-closed path govern instead. + if (depth == 0 && !SD.exists(path)) return false; if (depth >= 8) return true; // unexpected/deep content is not safe to adopt File dir = SD.open(path, FILE_READ); if (!dir) return true; // unreadable content is not an empty profile