From 3df8ce56de4e964a4502888a21ab164717f77a30 Mon Sep 17 00:00:00 2001 From: jpirnay Date: Mon, 4 May 2026 00:34:17 +0200 Subject: [PATCH] Font Manager Update Co-authored-by: Copilot --- .../settings/FontDownloadActivity.cpp | 16 ++++++++-- src/network/CrossPointWebServer.cpp | 29 ++++++++++++++++--- src/network/html/FilesPage.html | 1 + src/network/html/FontsPage.html | 2 +- src/network/html/HomePage.html | 1 + src/network/html/SettingsPage.html | 1 + 6 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/activities/settings/FontDownloadActivity.cpp b/src/activities/settings/FontDownloadActivity.cpp index ccdb4f3f..3aec928f 100644 --- a/src/activities/settings/FontDownloadActivity.cpp +++ b/src/activities/settings/FontDownloadActivity.cpp @@ -128,8 +128,14 @@ bool FontDownloadActivity::fetchAndParseManifest() { if (family.installed) { for (const auto& file : family.files) { + std::string localFilename = file.name; + std::string familyPrefix = family.name + "/"; + if (localFilename.find(familyPrefix) == 0) { + localFilename = localFilename.substr(familyPrefix.length()); + } + char path[128]; - FontInstaller::buildFontPath(family.name.c_str(), file.name.c_str(), path, sizeof(path)); + FontInstaller::buildFontPath(family.name.c_str(), localFilename.c_str(), path, sizeof(path)); FsFile f; if (Storage.openFileForRead("FONT", path, f)) { size_t actual = f.fileSize(); @@ -219,8 +225,14 @@ void FontDownloadActivity::downloadFamily(ManifestFamily& family) { } requestUpdateAndWait(); + std::string localFilename = file.name; + std::string familyPrefix = family.name + "/"; + if (localFilename.find(familyPrefix) == 0) { + localFilename = localFilename.substr(familyPrefix.length()); + } + char stagedPath[128]; - snprintf(stagedPath, sizeof(stagedPath), "%s/%s", stagingDir, file.name.c_str()); + snprintf(stagedPath, sizeof(stagedPath), "%s/%s", stagingDir, localFilename.c_str()); // Make sure parent directories exist for the file std::string stagedPathStr(stagedPath); diff --git a/src/network/CrossPointWebServer.cpp b/src/network/CrossPointWebServer.cpp index 911ed6ba..23fafea6 100644 --- a/src/network/CrossPointWebServer.cpp +++ b/src/network/CrossPointWebServer.cpp @@ -1441,7 +1441,8 @@ static constexpr size_t MAX_FONT_FILE_NAME_LEN = 60; bool isValidFontFileName(const std::string& name) { if (name.empty() || name.size() > MAX_FONT_FILE_NAME_LEN) return false; - if (name.find('/') != std::string::npos) return false; + // Allow '/' for subdirectories of font families, but prevent absolute paths + if (name[0] == '/') return false; if (name.find('\\') != std::string::npos) return false; if (name.find("..") != std::string::npos) return false; return true; @@ -1515,8 +1516,14 @@ bool fetchRemoteFontManifest(FontInstaller& installer, std::vector(f.size()); @@ -1583,13 +1590,27 @@ bool installRemoteFamily(const RemoteManifestFamily& family, const std::string& for (const auto& file : family.files) { esp_task_wdt_reset(); + std::string localFilename = file.name; + std::string familyPrefix = family.name + "/"; + if (localFilename.find(familyPrefix) == 0) { + localFilename = localFilename.substr(familyPrefix.length()); + } + char stagedPath[128]; - int sn = snprintf(stagedPath, sizeof(stagedPath), "%s/%s", stagingDir, file.name.c_str()); + int sn = snprintf(stagedPath, sizeof(stagedPath), "%s/%s", stagingDir, localFilename.c_str()); if (sn < 0 || static_cast(sn) >= sizeof(stagedPath)) { Storage.removeDir(stagingDir); - outError = std::string("File path too long: ") + file.name; + outError = std::string("File path too long: ") + localFilename; return false; } + + // Ensure intermediate subdirectories exist inside stagingDir + std::string stagedPathStr(stagedPath); + size_t lastSlash = stagedPathStr.find_last_of('/'); + if (lastSlash != std::string::npos) { + Storage.mkdir(stagedPathStr.substr(0, lastSlash).c_str()); + } + const std::string url = baseUrl + file.name; auto result = HttpDownloader::downloadToFile(url, stagedPath, nullptr); diff --git a/src/network/html/FilesPage.html b/src/network/html/FilesPage.html index 83b5da0b..6e4b1c37 100644 --- a/src/network/html/FilesPage.html +++ b/src/network/html/FilesPage.html @@ -1820,6 +1820,7 @@ diff --git a/src/network/html/FontsPage.html b/src/network/html/FontsPage.html index 37dd9da1..910d8fc1 100644 --- a/src/network/html/FontsPage.html +++ b/src/network/html/FontsPage.html @@ -156,7 +156,7 @@ diff --git a/src/network/html/HomePage.html b/src/network/html/HomePage.html index d1646949..2f1b6aba 100644 --- a/src/network/html/HomePage.html +++ b/src/network/html/HomePage.html @@ -173,6 +173,7 @@ diff --git a/src/network/html/SettingsPage.html b/src/network/html/SettingsPage.html index e74711b9..319d574e 100644 --- a/src/network/html/SettingsPage.html +++ b/src/network/html/SettingsPage.html @@ -300,6 +300,7 @@