diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2010-01-09 09:35:18 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2010-01-09 09:35:18 +0000 |
| commit | d56459bb8830ea8df10c06a8fd6b16f4dff54371 (patch) | |
| tree | 6f3b3aeab6e92295db1276e9d7d9d6bc81bb4bf9 | |
| parent | e56f2afbbfee341cc1454f576495c79298f8f26c (diff) | |
2010-01-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Fixed the bug that causes segmentation fault if unknown option is
put in aria2.conf file. BUG#2928303
* src/OptionParser.cc
* src/OptionParser.h
* src/option_processing.cc
* test/OptionParserTest.cc
| -rw-r--r-- | ChangeLog | 9 | ||||
| -rw-r--r-- | src/OptionParser.cc | 17 | ||||
| -rw-r--r-- | src/OptionParser.h | 3 | ||||
| -rw-r--r-- | src/option_processing.cc | 11 | ||||
| -rw-r--r-- | test/OptionParserTest.cc | 16 |
5 files changed, 48 insertions, 8 deletions
@@ -1,3 +1,12 @@ +2010-01-09 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net> + + Fixed the bug that causes segmentation fault if unknown option is + put in aria2.conf file. BUG#2928303 + * src/OptionParser.cc + * src/OptionParser.h + * src/option_processing.cc + * test/OptionParserTest.cc + 2010-01-07 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net> Ignore port message with port=0. diff --git a/src/OptionParser.cc b/src/OptionParser.cc index 5216bd60..02f30dc8 100644 --- a/src/OptionParser.cc +++ b/src/OptionParser.cc @@ -48,10 +48,15 @@ #include "a2functional.h" #include "array_fun.h" #include "OptionHandlerFactory.h" +#include "Logger.h" +#include "LogFactory.h" namespace aria2 { -OptionParser::OptionParser():_idCounter(0) {} +OptionParser::OptionParser(): + _idCounter(0), + _logger(LogFactory::getInstance()) +{} template<typename InputIterator> static size_t countPublicOption(InputIterator first, InputIterator last) @@ -167,6 +172,9 @@ void OptionParser::parse(Option& option, std::istream& is) continue; } std::pair<std::string, std::string> nv = util::split(line, A2STR::EQUAL_C); + if(nv.first.empty()) { + continue; + } OptionHandlerHandle handler = getOptionHandlerByName(nv.first); handler->parse(option, nv.second); } @@ -191,10 +199,11 @@ OptionHandlerHandle OptionParser::getOptionHandlerByName std::vector<SharedHandle<OptionHandler> >::const_iterator i = std::lower_bound(_optionHandlers.begin(), _optionHandlers.end(), handler, OptionHandlerNameLesser()); - if(i == _optionHandlers.end()) { - handler.reset(new NullOptionHandler()); - } else { + if(i != _optionHandlers.end() && (*i)->canHandle(optName)) { handler = *i; + } else { + handler.reset(new NullOptionHandler()); + _logger->warn("Skipped unknown option --%s.", optName.c_str()); } return handler; } diff --git a/src/OptionParser.h b/src/OptionParser.h index f9ec3ddc..57ced8f3 100644 --- a/src/OptionParser.h +++ b/src/OptionParser.h @@ -48,11 +48,14 @@ namespace aria2 { class Option; class OptionHandler; +class Logger; class OptionParser { private: int _idCounter; + Logger* _logger; + // _optionHandlers is sorted by OptionHandler::getName() in // ascending order. std::vector<SharedHandle<OptionHandler> > _optionHandlers; diff --git a/src/option_processing.cc b/src/option_processing.cc index 51021605..d97652b4 100644 --- a/src/option_processing.cc +++ b/src/option_processing.cc @@ -136,10 +136,13 @@ void option_processing(Option& op, std::deque<std::string>& uris, oparser.parse(op, cfstream); } catch(OptionHandlerException& e) { std::cerr << "Parse error in " << cfname << "\n" - << e.stackTrace() << "\n" - << "Usage:" << "\n" - << oparser.findByName(e.getOptionName())->getDescription() - << std::endl; + << e.stackTrace() << std::endl; + SharedHandle<OptionHandler> h = oparser.findByName(e.getOptionName()); + if(!h.isNull()) { + std::cerr << "Usage:" << "\n" + << oparser.findByName(e.getOptionName())->getDescription() + << std::endl; + } exit(downloadresultcode::UNKNOWN_ERROR); } catch(Exception& e) { std::cerr << "Parse error in " << cfname << "\n" diff --git a/test/OptionParserTest.cc b/test/OptionParserTest.cc index 3d5f51f5..eb5e31b3 100644 --- a/test/OptionParserTest.cc +++ b/test/OptionParserTest.cc @@ -24,6 +24,7 @@ class OptionParserTest:public CppUnit::TestFixture { CPPUNIT_TEST(testFindByID); CPPUNIT_TEST(testParseDefaultValues); CPPUNIT_TEST(testParseArg); + CPPUNIT_TEST(testParse); CPPUNIT_TEST_SUITE_END(); private: SharedHandle<OptionParser> _oparser; @@ -67,6 +68,7 @@ public: void testFindByID(); void testParseDefaultValues(); void testParseArg(); + void testParse(); }; @@ -174,4 +176,18 @@ void OptionParserTest::testParseArg() CPPUNIT_ASSERT_EQUAL(std::string("nonopt2"), nonopts[1]); } +void OptionParserTest::testParse() +{ + Option option; + std::istringstream in("alpha=Hello\n" + "UNKNOWN=x\n" + "\n" + "bravo=World"); + _oparser->parse(option, in); + CPPUNIT_ASSERT_EQUAL + ((ptrdiff_t)2, std::distance(option.begin(), option.end())); + CPPUNIT_ASSERT_EQUAL(std::string("Hello"), option.get("alpha")); + CPPUNIT_ASSERT_EQUAL(std::string("World"), option.get("bravo")); +} + } // namespace aria2 |
