From 6736ff5fa6a1d5b3f8d9a339d65c1f39d9cae7b8 Mon Sep 17 00:00:00 2001 From: Joseph Lenox Date: Tue, 19 Jul 2016 00:31:10 -0500 Subject: [PATCH] Catch exception thrown when loading config files. Thrown exception has been changed to be std::runtime_error, includes regression test (program does not crash when loading unknown keys). Sends error/diagnostic message to std::cerr. Addresses #3430 --- xs/src/libslic3r/Config.cpp | 14 ++++++++++---- xs/t/22_config.t | 17 +++++++++++++++++ xs/t/inc/22_config_bad_config_options.ini | 7 +++++++ 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 xs/t/22_config.t create mode 100644 xs/t/inc/22_config_bad_config_options.ini diff --git a/xs/src/libslic3r/Config.cpp b/xs/src/libslic3r/Config.cpp index cac2010f4..39fb4bbe7 100644 --- a/xs/src/libslic3r/Config.cpp +++ b/xs/src/libslic3r/Config.cpp @@ -4,6 +4,7 @@ #include #include #include +#include // std::runtime_error #include #include #include @@ -124,7 +125,7 @@ ConfigBase::serialize(const t_config_option_key &opt_key) const { bool ConfigBase::set_deserialize(const t_config_option_key &opt_key, std::string str, bool append) { const ConfigOptionDef* optdef = this->def->get(opt_key); - if (optdef == NULL) throw "Calling set_deserialize() on unknown option"; + if (optdef == NULL) throw std::runtime_error("Calling set_deserialize() on unknown option"); if (!optdef->shortcut.empty()) { for (std::vector::const_iterator it = optdef->shortcut.begin(); it != optdef->shortcut.end(); ++it) { if (!this->set_deserialize(*it, str)) return false; @@ -202,7 +203,12 @@ ConfigBase::load(const std::string &file) pt::ptree tree; pt::read_ini(file, tree); BOOST_FOREACH(const pt::ptree::value_type &v, tree) { - this->set_deserialize(v.first.c_str(), v.second.get_value().c_str()); + try { + this->set_deserialize(v.first.c_str(), v.second.get_value().c_str()); + } catch (std::runtime_error& e) { + // skip over errors in the config file but print a warning. + std::cerr << "Caught exception at option " << v.first.c_str() << ".\n"; + } } } @@ -212,7 +218,7 @@ ConfigBase::save(const std::string &file) const using namespace std; ofstream c; c.open(file.c_str(), ios::out | ios::trunc); - + { time_t now; time(&now); @@ -220,7 +226,7 @@ ConfigBase::save(const std::string &file) const strftime(buf, sizeof buf, "%F %T", gmtime(&now)); c << "# generated by Slic3r " << SLIC3R_VERSION << " on " << buf << endl; } - + t_config_option_keys my_keys = this->keys(); for (t_config_option_keys::const_iterator opt_key = my_keys.begin(); opt_key != my_keys.end(); ++opt_key) c << *opt_key << " = " << this->serialize(*opt_key) << endl; diff --git a/xs/t/22_config.t b/xs/t/22_config.t new file mode 100644 index 000000000..1201f1942 --- /dev/null +++ b/xs/t/22_config.t @@ -0,0 +1,17 @@ +#!/usr/bin/perl +use strict; +use warnings; + +use Slic3r::XS; + +use Test::More tests => 1; +{ + use Cwd qw(abs_path); + use File::Basename qw(dirname); + my $class = Slic3r::Config->new; + my $path = abs_path($0); + my $config = $class->_load(dirname($path)."/inc/22_config_bad_config_options.ini"); + ok 1, 'did not crash on reading invalid items in config'; +} + +__END__ diff --git a/xs/t/inc/22_config_bad_config_options.ini b/xs/t/inc/22_config_bad_config_options.ini new file mode 100644 index 000000000..b28c62479 --- /dev/null +++ b/xs/t/inc/22_config_bad_config_options.ini @@ -0,0 +1,7 @@ +# generated by Slic3r 1.1.7 on Tue Aug 19 21:49:50 2014 +avoid_crossing_perimeters = 1 +bed_size = 200,180 +g0 = 0 +perimeter_acceleration = 0 +support_material_extruder = 1 +support_material_extrusion_width = 0