Boost logo

Boost Users :

Subject: Re: [Boost-users] [program_options][lexical_cast] Cannot cast from std::string to seastar::sstring.
From: Gavin Lambert (boost_at_[hidden])
Date: 2018-09-17 23:16:02


On 17/09/2018 16:48, José Guilherme Vanz wrote:
> I'm investigating a bug <https://github.com/scylladb/scylla/issues/2905>
> in the Seastar/lexical_cast and I got stuck. Let me introduce what's
> going on and the further investigation that I did.
> The Seastar framework uses the boost program options to parse the
> command line arguments. But when the user try to pass a command line
> argument of seastar::sstring (Seastar string type) with a white space,
> the lib tells us that is invalid value.
>
> Turns out the boost program options call lexical_cast to cast from
> std::string to seastar::sstring. This cast is failing. The lexical_cast
> uses a stream to extract the value from the source, but the operator>>
> stops in the white space. Making the second validation in the same line
> <https://github.com/boostorg/lexical_cast/blob/boost-1.66.0/include/boost/lexical_cast/detail/converter_lexical_streams.hpp#L600>
> false. Note, there is a call
> <https://github.com/boostorg/lexical_cast/blob/boost-1.66.0/include/boost/lexical_cast/detail/converter_lexical_streams.hpp#L597>
> to unsetf to ensure that the white space will be skipped:
> stream.unsetf(std::ios::skipws);.
>
> What's am I trying to do is figure out  where the problems live? Is
> there a bug in boost or is a sstring implemantion problem? Am I missing
> something?

stream.unsetf(std::ios::skipws) will prevent leading whitespace from
being stripped from the output. It will still terminate parsing at the
first whitespace found after any initial non-whitespace character.
That's just what iostreams do.

It will then throw bad_lexical_cast to indicate that parsing was
unsuccessful since it didn't consume all the input.

Using lexical_cast on std::string avoids this because there's an
optimised overload that simply calls assign on the whole string. Though
using lexical_cast on input with spaces is in general a bad idea to
begin with.

Either don't use spaces in the input, don't use a custom string type,
report the use of lexical_cast as a possible bug to
Boost.ProgramOptions, or perhaps try providing a custom specialisation
or overload of boost::conversion::detail::try_lexical_convert -- bearing
in mind that since this is in the detail namespace it's not public and
might break between Boost versions, so it's not recommended to rely on
that unless you're in control of which version is used and are willing
to patch it as needed.

(FWIW, the docs of ProgramOptions indicate the conversion is intended
for int/float types, so they would probably recommend not using an
unsupported custom string type.)


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net