Boost C++ Libraries: Ticket #850: program_options strips off escaped quotes in some situations https://svn.boost.org/trac10/ticket/850 <pre class="wiki">boost::program_options strips off escaped quotes from command line strings like -a "\"quoted value\"". A command line string like -a "\"quoted value\" unquoted_value" does not have its escaped quotes striped out. I am using program_options in Windows to parse the command line of my application. One of the requirements is that I be able to pass in the command line of a different application such as the following: myapp -c "\"c:\App versions\App v1\App.exe\" -a \"A Value\" -b Another_Value" In this case, program_options will correctly parse out the value of the parameter c to be: "c:\App versions\App v1\App.exe" -a "A Value" -b Another_Value However, if I pass in the following: myapp -c "\"c:\App versions\App v1\App.exe\"" program_options parses c as: c:\App versions\App v1\App.exe Note that the escaped quotes were stripped off instead of preserved like you would expect. This is a problem because my application immediately turns around and calls ::CreateProcess using the value of the c parameter. ::CreateProcess' documented behavior is that it executes the first match it can find of c:\App.exe, c:\App versions\App.exe, and c:\App versions\App v1\App.exe. The only way you can stop this behavior is by enclosing the file path in quotes. The code I'm using to get the options is pasted below. Please email me with any questions. Thanks! -------------------- pair&lt;string, bool&gt; CCmdLineParser::GetParam(const string&amp; sParamName) { Run(); // Make sure we're parsed if (!Impl_.bOptionsDescribed &amp;&amp; !Impl_.bPositionalOptionsDescribed) return GetUnregisteredParam_(sParamName); return Impl_.RegisteredOptions.count(sParamName) ? make_pair(Impl_.RegisteredOptions[sParamName].as&lt;string&gt;(), true) : make_pair("", false); } void CCmdLineParser::Run(void) { if (Impl_.bInitialized) return; Impl_.bInitialized = true; // Create parser command_line_parser Parser(split_winmain(AfxGetApp()-&gt;m_lpCmdLine)); bool bUnregistered = !Impl_.bOptionsDescribed &amp;&amp; !Impl_.bPositionalOptionsDescribed; // Setup parser Parser.options(Impl_.OptionsDesc); // Always required (even if empty) because command_line_parser::run() asserts it if (Impl_.bPositionalOptionsDescribed) Parser.positional(Impl_.PositionalOptionsDesc); if (bUnregistered) Parser.allow_unregistered(); // Parse parsed_options ParsedOptions = Parser.run(); // Retrieve // We can't call store on something with unregistered options. It throws an exception even if you specifically // call allow_unregistered(). This is a known bug. It is fixed in the boost CVS tree, but not released yet. // What all of this basically means if that we can't mix registered and unregistered options (yet). if (bUnregistered) Impl_.UnregisteredOptions = collect_unrecognized(ParsedOptions.options, include_positional); else { store(ParsedOptions, Impl_.RegisteredOptions); // notify() is required for automatic value storage and default values notify(Impl_.RegisteredOptions); } } </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/850 Trac 1.4.3 gardnermj@… Wed, 25 Jul 2007 17:06:13 GMT <link>https://svn.boost.org/trac10/ticket/850#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/850#comment:1</guid> <description> <p> I can confirm this on Linux, and add my vote for it to be fixed as well. My application is a type of search engine, and this behavior breaks phrase searches when the entire query is a phrase. </p> <p> I believe this behavior is new as of boost 1.33, as I didn't observe it with version 1.32. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Daryle Walker</dc:creator> <pubDate>Fri, 03 Aug 2007 12:24:50 GMT</pubDate> <title>component changed; severity set https://svn.boost.org/trac10/ticket/850#comment:2 https://svn.boost.org/trac10/ticket/850#comment:2 <ul> <li><strong>component</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">program_options</span> </li> <li><strong>severity</strong> → <span class="trac-field-new">Problem</span> </li> </ul> Ticket Vladimir Prus Tue, 25 Mar 2008 16:19:20 GMT type changed https://svn.boost.org/trac10/ticket/850#comment:3 https://svn.boost.org/trac10/ticket/850#comment:3 <ul> <li><strong>type</strong> <span class="trac-field-old">Support Requests</span> → <span class="trac-field-new">Bugs</span> </li> </ul> Ticket anonymous Wed, 16 Apr 2008 20:19:20 GMT <link>https://svn.boost.org/trac10/ticket/850#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/850#comment:4</guid> <description> <p> I notice a similar problem (in a similar application). Not that in order to preserve quotes, I need to add an extra (third) level of quotes. This is in boost 1.34. First example is single quote, double quote. Second example is single quote, double quote, double quote. </p> <pre class="wiki">$ ./search --query='"a test"' Query: a test $ ./search --query='""a test""' Query: "a test" </pre> </description> <category>Ticket</category> </item> <item> <author>s.ochsenknecht@…</author> <pubDate>Fri, 30 Oct 2009 16:08:51 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/850 https://svn.boost.org/trac10/ticket/850 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">patch_ticket850.txt</span> </li> </ul> <p> patch </p> Ticket s.ochsenknecht@… Fri, 30 Oct 2009 16:12:38 GMT cc set https://svn.boost.org/trac10/ticket/850#comment:5 https://svn.boost.org/trac10/ticket/850#comment:5 <ul> <li><strong>cc</strong> <span class="trac-author">s.ochsenknecht@…</span> added </li> </ul> <p> There is some code which is removing quotes like '"' and <strong> if they occur and the begin and at the of the option value. Maybe there is a good reason for this? I don't know (maybe because of config files?). </strong></p> <p> Anyhow, I attached a patch which removes this code and keeps the value as it come from the command line (expect the quotas which were removed by the shell). </p> Ticket Vladimir Prus Mon, 09 Nov 2009 18:09:41 GMT <link>https://svn.boost.org/trac10/ticket/850#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/850#comment:6</guid> <description> <p> The code in question dates back to 2004-05-14, and I no longer have any idea why it's here. Let's try to back it out. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Vladimir Prus</dc:creator> <pubDate>Mon, 09 Nov 2009 18:12:12 GMT</pubDate> <title>status, resolution changed https://svn.boost.org/trac10/ticket/850#comment:7 https://svn.boost.org/trac10/ticket/850#comment:7 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">fixed</span> </li> </ul> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/57519" title="Don't strip quotes from values. Fixes #850. Patch from Sascha ...">[57519]</a>) Don't strip quotes from values. </p> <p> Fixes <a class="reopened ticket" href="https://svn.boost.org/trac10/ticket/850" title="#850: Bugs: program_options strips off escaped quotes in some situations (reopened)">#850</a>. Patch from Sascha Ochsenknecht. </p> Ticket Sascha Ochsenknecht Sun, 06 Dec 2009 12:18:33 GMT milestone set https://svn.boost.org/trac10/ticket/850#comment:8 https://svn.boost.org/trac10/ticket/850#comment:8 <ul> <li><strong>milestone</strong> → <span class="trac-field-new">Boost 1.42.0</span> </li> </ul> Ticket thomas.jarosch@… Wed, 29 Sep 2010 09:00:23 GMT status changed; resolution deleted https://svn.boost.org/trac10/ticket/850#comment:9 https://svn.boost.org/trac10/ticket/850#comment:9 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">fixed</span> </li> </ul> <p> Hello, </p> <p> I just updated from boost version 1.39.0 to boost 1.44.0 (on linux) and this change broke the config file parsers. </p> <p> Imagine a simple config file like this: </p> <p> <a class="missing wiki">WorkDir</a>= "/some/where" </p> <p> The new code keeps the quotes on the directory name string and so the open() call for the directory fails. </p> <p> So I could change my code to manually strip the quotes or remove the quotes in the config file (which get generated automatically). </p> <p> Though there's one case where this won't work as good as before. Imagine a config line like this: </p> <p> <a class="missing wiki">WorkDir</a> = "/some/where " </p> <p> This can't be express with the changed code as: <a class="missing wiki">WorkDir</a> = /some/where </p> <p> -&gt; It will strip all the spaces, so you can't have config file values ending on spaces anymore. </p> <p> So the code was broken for the CLI parser but needed for the config file parser (as suspected above...). </p> <p> Any chance we can restore the behavior for the config file parser only? </p> <p> Cheers, Thomas </p> Ticket Olaf van der Spek <olafvdspek@…> Thu, 02 Feb 2012 22:29:39 GMT <link>https://svn.boost.org/trac10/ticket/850#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/850#comment:10</guid> <description> <p> Hi Vladimir, </p> <p> Any updates? </p> </description> <category>Ticket</category> </item> </channel> </rss>