Fixed crash when reading malformed plugins.

Error message now gets displayed in the LOOT GUI. Fixes #269.
This commit is contained in:
WrinklyNinja
2014-09-07 17:24:39 +01:00
parent c201ea8b5d
commit ef8ab2c986
3 changed files with 78 additions and 52 deletions
+8
View File
@@ -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;
}
}
+51 -49
View File
@@ -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<string, uint32_t>(n, crc));
BOOST_LOG_TRIVIAL(trace) << name << ": " << "Getting the FormIDs.";
vector<uint32_t> records = file->getFormIDs();
vector<string> 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<string, uint32_t>(n, crc));
BOOST_LOG_TRIVIAL(trace) << name << ": " << "Getting the FormIDs.";
vector<uint32_t> records = file->getFormIDs();
vector<string> 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.";
}
+19 -3
View File
@@ -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<string>();
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<string>();
pluginNode[key] = it->second;
for (const auto &pair : derivedNode) {
const string key = pair.first.as<string>();
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<string>();
pluginNode[key] = pair.second;
}
node.push_back(pluginNode);
}
g_app_state.isMidSort = true;