From f65a4ecaffa8d4f0787cca73b4a5a0163be42e63 Mon Sep 17 00:00:00 2001 From: Paul Walker Date: Sat, 4 Nov 2023 14:00:28 -0400 Subject: [PATCH] More defensive fs::exception handing in FX load Potentially addresses #7221 --- src/common/FxPresetAndClipboardManager.cpp | 148 +++++++++--------- .../gui/widgets/XMLConfiguredMenus.cpp | 66 ++++---- 2 files changed, 113 insertions(+), 101 deletions(-) diff --git a/src/common/FxPresetAndClipboardManager.cpp b/src/common/FxPresetAndClipboardManager.cpp index 49a86119ee0..105387fa913 100644 --- a/src/common/FxPresetAndClipboardManager.cpp +++ b/src/common/FxPresetAndClipboardManager.cpp @@ -74,106 +74,106 @@ void FxUserPreset::doPresetRescan(SurgeStorage *storage, bool forceRescan) } } } - } - catch (const fs::filesystem_error &e) - { - std::ostringstream oss; - oss << "Experienced file system error when scanning user FX. " << e.what(); - if (storage) - storage->reportError(oss.str(), "FileSystem Error"); - } - - for (const auto &f : sfxfiles) - { + for (const auto &f : sfxfiles) { - Preset preset; - preset.file = path_to_string(f.first); + { + Preset preset; + preset.file = path_to_string(f.first); - TiXmlDocument d; - int t; + TiXmlDocument d; + int t; - if (!d.LoadFile(f.first)) - goto badPreset; + if (!d.LoadFile(f.first)) + goto badPreset; - auto r = TINYXML_SAFE_TO_ELEMENT(d.FirstChild("single-fx")); + auto r = TINYXML_SAFE_TO_ELEMENT(d.FirstChild("single-fx")); - if (!r) - goto badPreset; + if (!r) + goto badPreset; - preset.streamingVersion = ff_revision; - int sv; - if (r->QueryIntAttribute("streaming_version", &sv) == TIXML_SUCCESS) - { - preset.streamingVersion = sv; - } + preset.streamingVersion = ff_revision; + int sv; + if (r->QueryIntAttribute("streaming_version", &sv) == TIXML_SUCCESS) + { + preset.streamingVersion = sv; + } - auto s = TINYXML_SAFE_TO_ELEMENT(r->FirstChild("snapshot")); + auto s = TINYXML_SAFE_TO_ELEMENT(r->FirstChild("snapshot")); - if (!s) - goto badPreset; + if (!s) + goto badPreset; - if (s->QueryIntAttribute("type", &t) != TIXML_SUCCESS) - goto badPreset; + if (s->QueryIntAttribute("type", &t) != TIXML_SUCCESS) + goto badPreset; - preset.type = t; - preset.isFactory = f.second; + preset.type = t; + preset.isFactory = f.second; - fs::path rpath; + fs::path rpath; - if (f.second) - rpath = f.first.lexically_relative(fd).parent_path(); - else - rpath = f.first.lexically_relative(storage->userFXPath).parent_path(); + if (f.second) + rpath = f.first.lexically_relative(fd).parent_path(); + else + rpath = f.first.lexically_relative(storage->userFXPath).parent_path(); - auto startCatPath = rpath.begin(); - if (*(startCatPath) == fx_type_shortnames[t]) - { - startCatPath++; - } + auto startCatPath = rpath.begin(); + if (*(startCatPath) == fx_type_shortnames[t]) + { + startCatPath++; + } - while (startCatPath != rpath.end()) - { - preset.subPath /= *startCatPath; - startCatPath++; - } + while (startCatPath != rpath.end()) + { + preset.subPath /= *startCatPath; + startCatPath++; + } - if (!readFromXMLSnapshot(preset, s)) - goto badPreset; + if (!readFromXMLSnapshot(preset, s)) + goto badPreset; - if (scannedPresets.find(preset.type) == scannedPresets.end()) - { - scannedPresets[preset.type] = std::vector(); + if (scannedPresets.find(preset.type) == scannedPresets.end()) + { + scannedPresets[preset.type] = std::vector(); + } + + scannedPresets[preset.type].push_back(preset); } - scannedPresets[preset.type].push_back(preset); + badPreset:; } - badPreset:; - } - - for (auto &a : scannedPresets) - { - std::sort(a.second.begin(), a.second.end(), [](const Preset &a, const Preset &b) { - if (a.type == b.type) - { - if (a.isFactory != b.isFactory) + for (auto &a : scannedPresets) + { + std::sort(a.second.begin(), a.second.end(), [](const Preset &a, const Preset &b) { + if (a.type == b.type) { - return a.isFactory; - } + if (a.isFactory != b.isFactory) + { + return a.isFactory; + } + + if (a.subPath != b.subPath) + { + return a.subPath < b.subPath; + } - if (a.subPath != b.subPath) + return _stricmp(a.name.c_str(), b.name.c_str()) < 0; + } + else { - return a.subPath < b.subPath; + return a.type < b.type; } + }); + } + } + catch (const fs::filesystem_error &e) + { + std::ostringstream oss; + oss << "Experienced file system error when scanning user FX. " << e.what(); - return _stricmp(a.name.c_str(), b.name.c_str()) < 0; - } - else - { - return a.type < b.type; - } - }); + if (storage) + storage->reportError(oss.str(), "FileSystem Error"); } } diff --git a/src/surge-xt/gui/widgets/XMLConfiguredMenus.cpp b/src/surge-xt/gui/widgets/XMLConfiguredMenus.cpp index d664b800321..9555ddd50af 100644 --- a/src/surge-xt/gui/widgets/XMLConfiguredMenus.cpp +++ b/src/surge-xt/gui/widgets/XMLConfiguredMenus.cpp @@ -925,40 +925,52 @@ void FxMenu::loadUserPreset(const Surge::Storage::FxUserPreset::Preset &p) void FxMenu::scanExtraPresets() { - storage->fxUserPreset->doPresetRescan(storage); - for (const auto &tp : storage->fxUserPreset->getPresetsByType()) + try { - // So let's run all presets until we find the first item with type tp.first - auto alit = allPresets.begin(); - while (alit->itemType != tp.first && alit != allPresets.end()) - alit++; - std::vector rootPath; - rootPath.push_back(alit->pathElements[0]); + storage->fxUserPreset->doPresetRescan(storage); + for (const auto &tp : storage->fxUserPreset->getPresetsByType()) + { + // So let's run all presets until we find the first item with type tp.first + auto alit = allPresets.begin(); + while (alit->itemType != tp.first && alit != allPresets.end()) + alit++; + std::vector rootPath; + rootPath.push_back(alit->pathElements[0]); - while (alit != allPresets.end() && alit->itemType == tp.first) - alit++; + while (alit != allPresets.end() && alit->itemType == tp.first) + alit++; - // OK so alit now points at the end of the list - alit = allPresets.insert(alit, tp.second.size(), Item()); + // OK so alit now points at the end of the list + alit = allPresets.insert(alit, tp.second.size(), Item()); - // OK so insert 'size' into all presets at the end of the position of the type + // OK so insert 'size' into all presets at the end of the position of the type - for (const auto ps : tp.second) - { - alit->itemType = tp.first; - alit->name = ps.name; - alit->isUser = !ps.isFactory; - alit->path = string_to_path(ps.file); - auto thisPath = rootPath; - for (const auto &q : ps.subPath) - thisPath.push_back(path_to_string(q)); - - alit->pathElements = thisPath; - alit->hasFxUserPreset = true; - alit->fxPreset = ps; - alit++; + for (const auto ps : tp.second) + { + alit->itemType = tp.first; + alit->name = ps.name; + alit->isUser = !ps.isFactory; + alit->path = string_to_path(ps.file); + auto thisPath = rootPath; + for (const auto &q : ps.subPath) + thisPath.push_back(path_to_string(q)); + + alit->pathElements = thisPath; + alit->hasFxUserPreset = true; + alit->fxPreset = ps; + alit++; + } } } + catch (const fs::filesystem_error &e) + { + // really nothing to do about this other than continue without the preset + std::ostringstream oss; + oss << "Experienced file system error when scanning user FX. " << e.what(); + + if (storage) + storage->reportError(oss.str(), "FileSystem Error"); + } } void FxMenu::loadByIndex(const std::string &name, int index)