From ef8ab2c986187f8b8d17996a5ff232df79db96b3 Mon Sep 17 00:00:00 2001 From: WrinklyNinja Date: Sun, 7 Sep 2014 17:24:39 +0100 Subject: [PATCH] Fixed crash when reading malformed plugins. Error message now gets displayed in the LOOT GUI. Fixes #269. --- resources/report/js/script.js | 8 +++ src/backend/metadata.cpp | 100 +++++++++++++++++----------------- src/gui/handler.cpp | 22 +++++++- 3 files changed, 78 insertions(+), 52 deletions(-) diff --git a/resources/report/js/script.js b/resources/report/js/script.js index f9d56aa9..0c74fe86 100644 --- a/resources/report/js/script.js +++ b/resources/report/js/script.js @@ -464,6 +464,10 @@ function getConflictingPluginsFromFilter() { if (loot.game.plugins[i].name == key) { loot.game.plugins[i].crc = result[key].crc; loot.game.plugins[i].isDummy = result[key].isDummy; + + loot.game.plugins[i].messages = result[key].messages; + loot.game.plugins[i].tags = result[key].tags; + loot.game.plugins[i].isDirty = result[key].isDirty; break; } } @@ -811,6 +815,10 @@ function sortPlugins(evt) { if (loot.game.plugins[i].name == plugin.name) { loot.game.plugins[i].crc = plugin.crc; loot.game.plugins[i].isDummy = plugin.isDummy; + + loot.game.plugins[i].messages = plugin.messages; + loot.game.plugins[i].tags = plugin.tags; + loot.game.plugins[i].isDirty = plugin.isDirty; break; } } diff --git a/src/backend/metadata.cpp b/src/backend/metadata.cpp index 747f2b34..86fc5195 100644 --- a/src/backend/metadata.cpp +++ b/src/backend/metadata.cpp @@ -357,6 +357,57 @@ namespace loot { file = new espm::fo3::File(filepath, game.espm_settings, false, headerOnly); else file = new espm::fonv::File(filepath, game.espm_settings, false, headerOnly); + + BOOST_LOG_TRIVIAL(trace) << name << ": " << "Checking master flag."; + isMaster = file->isMaster(game.espm_settings); + + BOOST_LOG_TRIVIAL(trace) << name << ": " << "Getting masters."; + masters = file->getMasters(); + + BOOST_LOG_TRIVIAL(trace) << name << ": " << "Number of masters: " << masters.size(); + + BOOST_LOG_TRIVIAL(trace) << name << ": " << "Getting CRC."; + crc = file->crc; + game.crcCache.insert(pair(n, crc)); + + BOOST_LOG_TRIVIAL(trace) << name << ": " << "Getting the FormIDs."; + vector records = file->getFormIDs(); + vector plugins = masters; + plugins.push_back(name); + for (const auto &record : records) { + FormID fid = FormID(plugins, record); + formIDs.insert(fid); + if (!boost::iequals(fid.Plugin(), name)) + ++numOverrideRecords; + } + + //Also read Bash Tags applied and version string in description. + BOOST_LOG_TRIVIAL(trace) << name << ": " << "Reading the description."; + string text = file->getDescription(); + + delete file; + + BOOST_LOG_TRIVIAL(trace) << name << ": " << "Attempting to read the version from the description."; + for (size_t i = 0; i < 7; ++i) { + smatch what; + if (regex_search(text, what, version_checks[i])) { + //Use the first sub-expression match. + version = string(what[1].first, what[1].second); + break; + } + } + BOOST_LOG_TRIVIAL(trace) << name << ": " << "Attempting to extract Bash Tags from the description."; + smatch results; + if (regex_search(text, results, bash_tag_check)) { + // Regex requires there to be at least one sub-expression match, + // so skip the first (which is the full expression. + for (size_t i = 1; i < results.size(); ++i) { + // Tags in the description must be addition tags, because there's + // nowhere else to remove them from. + auto tag = tags.insert(Tag(string(results[i].first, results[i].second))); + BOOST_LOG_TRIVIAL(trace) << name << ": " << "Extracted Bash Tag: " << tag.first->Name(); + } + } } catch (std::exception& e) { BOOST_LOG_TRIVIAL(error) << "Cannot read plugin file \"" << name << "\". Details: " << e.what(); @@ -369,55 +420,6 @@ namespace loot { name = name.substr(0, name.length() - 6); } - BOOST_LOG_TRIVIAL(trace) << name << ": " << "Checking master flag."; - isMaster = file->isMaster(game.espm_settings); - - BOOST_LOG_TRIVIAL(trace) << name << ": " << "Getting masters."; - masters = file->getMasters(); - - BOOST_LOG_TRIVIAL(trace) << name << ": " << "Number of masters: " << masters.size(); - - crc = file->crc; - game.crcCache.insert(pair(n, crc)); - - BOOST_LOG_TRIVIAL(trace) << name << ": " << "Getting the FormIDs."; - vector records = file->getFormIDs(); - vector plugins = masters; - plugins.push_back(name); - for (const auto &record : records) { - FormID fid = FormID(plugins, record); - formIDs.insert(fid); - if (!boost::iequals(fid.Plugin(), name)) - ++numOverrideRecords; - } - - //Also read Bash Tags applied and version string in description. - BOOST_LOG_TRIVIAL(trace) << name << ": " << "Reading the description."; - string text = file->getDescription(); - - delete file; - - BOOST_LOG_TRIVIAL(trace) << name << ": " << "Attempting to read the version from the description."; - for (size_t i = 0; i < 7; ++i) { - smatch what; - if (regex_search(text, what, version_checks[i])) { - //Use the first sub-expression match. - version = string(what[1].first, what[1].second); - break; - } - } - BOOST_LOG_TRIVIAL(trace) << name << ": " << "Attempting to extract Bash Tags from the description."; - smatch results; - if (regex_search(text, results, bash_tag_check)) { - // Regex requires there to be at least one sub-expression match, - // so skip the first (which is the full expression. - for (size_t i = 1; i < results.size(); ++i) { - // Tags in the description must be addition tags, because there's - // nowhere else to remove them from. - auto tag = tags.insert(Tag(string(results[i].first, results[i].second))); - BOOST_LOG_TRIVIAL(trace) << name << ": " << "Extracted Bash Tag: " << tag.first->Name(); - } - } BOOST_LOG_TRIVIAL(trace) << name << ": " << "Plugin loading complete."; } diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp index 2c54f042..aa6cd171 100644 --- a/src/gui/handler.cpp +++ b/src/gui/handler.cpp @@ -363,6 +363,14 @@ namespace loot { else { pluginNode["conflicts"] = false; } + + // Plugin loading may have produced an error message, so rederive displayed data. + YAML::Node derivedNode = GenerateDerivedMetadata(pluginPair.second.Name()); + for (const auto &pair : derivedNode) { + const string key = pair.first.as(); + pluginNode[key] = pair.second; + } + node[pluginPair.second.Name()] = pluginNode; } @@ -800,9 +808,9 @@ namespace loot { // putting any resulting metadata into the base of the pluginNode. YAML::Node derivedNode = GenerateDerivedMetadata(pluginPair.second.Name()); - for (auto it = derivedNode.begin(); it != derivedNode.end(); ++it) { - const string key = it->first.as(); - pluginNode[key] = it->second; + for (const auto &pair : derivedNode) { + const string key = pair.first.as(); + pluginNode[key] = pair.second; } gameNode["plugins"].push_back(pluginNode); @@ -895,6 +903,14 @@ namespace loot { pluginNode["name"] = plugin.Name(); pluginNode["crc"] = plugin.Crc(); pluginNode["isDummy"] = plugin.FormIDs().size() == 0; + + // Sorting may have produced a plugin loading error message, so rederive displayed data. + YAML::Node derivedNode = GenerateDerivedMetadata(plugin.Name()); + for (const auto &pair : derivedNode) { + const string key = pair.first.as(); + pluginNode[key] = pair.second; + } + node.push_back(pluginNode); } g_app_state.isMidSort = true;