From 672732db2f0c2fe69379eb019b0676554536fac2 Mon Sep 17 00:00:00 2001 From: Bastien Chevreux Date: Thu, 8 Sep 2016 09:56:37 -0400 Subject: [PATCH] testprog.cpp: test case and fix for segfaults when using OptionGroup Class OptionParser stored only pointers to option groups when using add_option_group(). This can lead to the case where arguments are parsed long after an OptionGroup went out of scope, leading to memory access to freed memory and often to segmentation faults (the changed testprog.cpp demonstrates this). This can easily happen if a parser is configured in an external function like this auto parser = optparse::OptionParser(); setupParser(parser); Fix: Class OptionParser now stores option groups instead of pointers to them. Pro: - least amount of changes to the code Con: - Option groups cannot be changed after they were added to the parser via add_option_group(). Should this be needed, then a bigger rewrite would be necessary where the parser uses a factory function which creates and stores new option groups and returns a pointer/reference to them. --- OptionParser.cpp | 10 +++++----- OptionParser.h | 2 +- testprog.cpp | 24 +++++++++++++----------- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/OptionParser.cpp b/OptionParser.cpp index 799ffdc..1a3119d 100644 --- a/OptionParser.cpp +++ b/OptionParser.cpp @@ -195,7 +195,7 @@ OptionParser& OptionParser::add_option_group(const OptionGroup& group) { for (set::const_iterator it = option._long_opts.begin(); it != option._long_opts.end(); ++it) _optmap_l[*it] = &option; } - _groups.push_back(&group); + _groups.push_back(group); return *this; } @@ -322,8 +322,8 @@ Values& OptionParser::parse_args(const vector& v) { _values[it->dest()] = it->get_default(); } - for (list::iterator group_it = _groups.begin(); group_it != _groups.end(); ++group_it) { - for (list