Opened 7 years ago
Last modified 7 years ago
#11935 new Bugs
boost::program_options::error_with_option_name.what() throws std::out_of_range when an empty option is used in the command input
Reported by: | Owned by: | Vladimir Prus | |
---|---|---|---|
Milestone: | To Be Determined | Component: | program_options |
Version: | Boost 1.60.0 | Severity: | Problem |
Keywords: | program_options | Cc: |
Description
Hi,
After accidentally typing "-v . -" (without the quotes) into a Windows command line app written with boost::po, it crashed. The app's catch block (code below) calls boost::po::error_with_option_name.what() and this subsequently throws std::out_of_range().
It appears as though the empty option "-" confuses boost::program_options::strip_prefixes(const std::string& text) which is called with text value of "-", resulting in text.substr being called with a value of npos:
inline std::string strip_prefixes(const std::string& text) { // "--foo-bar" -> "foo-bar"[[BR]] return text.substr(text.find_first_not_of("-/")); }
Here's my code.
po::variables_map vm; po::options_description desc("Options"); desc.add_options() ("folder,f", po::wvalue<wstring>()->required(), "Specify the name of the folder containing the C++ projects to check") ("list,l", "List the project file names as they're checked") ("verbose,v", "Verbose; Show the node values when finding non-SAK SCC values") ("help,?", "Show usage information") ; po::positional_options_description pod; pod.add("folder", -1); try { po::store(po::wcommand_line_parser(argc, argv).options(desc).positional(pod).run(), vm); po::notify(vm); } catch (const boost::program_options::error & e) { cerr << w32::fg_red << e.what() << w32::restore << endl; return ERROR_UNHANDLED_EXCEPTION; }
I am using Boost 1.60 on Windows 7 (64-bit) with Visual Studio 2015 Update 1.
Cheers
Mark.
I just ran into this problem too, though in my case I didn't pass in an empty option. I was testing a parameter with a length validator:
When passed a value longer than the limit the code threw a boost::program_options::error_with_option_name, as expected. Calling that exception's what() method crashed the program in the same way as the original reporter of this bug described, except that in this case the "original_token" value in the error's m_substitutions map was empty. When passed an empty string, strip_prefixes() throws the same out_of_range exception as above.
The following patch will fix the problem:
I'm using boost 1.58 on Linux.