Skip to content

Commit

Permalink
More defensive fs::exception handing in FX load (#7286)
Browse files Browse the repository at this point in the history
Potentially addresses #7221
  • Loading branch information
baconpaul authored Nov 4, 2023
1 parent a69c023 commit 20069f8
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 101 deletions.
148 changes: 74 additions & 74 deletions src/common/FxPresetAndClipboardManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<Preset>();
if (scannedPresets.find(preset.type) == scannedPresets.end())
{
scannedPresets[preset.type] = std::vector<Preset>();
}

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");
}
}

Expand Down
66 changes: 39 additions & 27 deletions src/surge-xt/gui/widgets/XMLConfiguredMenus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string> 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<std::string> 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)
Expand Down

0 comments on commit 20069f8

Please sign in to comment.