mirror of https://github.com/aria2/aria2
				
				
				
			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.ccpull/1/head
							parent
							
								
									e56f2afbbf
								
							
						
					
					
						commit
						d56459bb88
					
				| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue