Cannot cast from std::string to seastar::sstring.
Hi guys, 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/lex...) false. Note, there is a [call](https://github.com/boostorg/lexical_cast/blob/boost-1.66.0/include/boost/lex...) 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? Thanks!
On 17 September 2018 at 05:48, José Guilherme Vanz via Boost-users < boost-users@lists.boost.org> wrote:
Hi guys,
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/lex... false. Note, there is a call https://github.com/boostorg/lexical_cast/blob/boost-1.66.0/include/boost/lex... 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?
Overload validate, cf the documentation https://www.boost.org/doc/libs/1_68_0/doc/html/program_options/howto.html#id...
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/lex... false. Note, there is a call https://github.com/boostorg/lexical_cast/blob/boost-1.66.0/include/boost/lex... 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.)
participants (3)
-
Gavin Lambert
-
José Guilherme Vanz
-
Mathias Gaunard