docopt / docopt.cpp

C++11 port of docopt
Boost Software License 1.0
1.04k stars 146 forks source link

Crash inside regex #67

Closed jdukat closed 7 years ago

jdukat commented 7 years ago

This is my usage string:

static const char usage[] =
R"( Usage:
  my_app [-s] [-t <num_threads>] [--config <cfg_file>] [--ult | --test] [<client>]
  my_app (-h | --help)

 Options:
  -s                   Display users' stats.
  -t <num_threads>     Limit number of worker threads.
  --config <cfg_file>  Path to configuration file. [default: data/cfg_fimi.yaml]
  --ult                Run tests: unit level.
  --test               Run tests: full test suite.
  -h --help            Show this screen.
)";

It causes infinite recursion and a crash inside regex matcher. I run it on windows 10, visual studio 15 version as snipped below: image

Remove either of these lines from the options section:

  -t <num_threads>     Limit number of worker threads.
  --config <cfg_file>  Path to configuration file. [default: data/cfg_fimi.yaml]

and then it works fine. It looks like adding too many option lines causes some issue in the regex runtime. I have no idea if this is VS std library problem, something wrong with docopt or I'm doing something wrong with my usage string. Debugging the regex runtime is rather time consuming and after a quick try I didn't come to any conclusion.

jaredgrubb commented 7 years ago

Yes, the VS Regex is not very good quality (I've read the GCC one is bad too and clang's is just ok). The boost::regex is by far the best implementation. In any case, the recursion bug you're hitting is a bug with VS and is known.

I recommend using the boost::regex for VS. But this is a duplicate of #49, and we are discussing some workaround options there.

jdukat commented 7 years ago

Thanks for quick reply. I see you also prefer coding over celebrating xmas eve ;) I have no option to use gcc or clang with my project. Any hints on how to use boost regex with VS project without modifying docopt code or messing up with the standard library?

jaredgrubb commented 7 years ago

I am a nerd and love to code for fun :) You can download the boost library; it's pretty big, but there are some good things in there!

jdukat commented 7 years ago

I know what is boost, but not sure how to replace c++11 default implementation with boost, so docopt would use it by default. Is that even possible? Or do I need to change docopt includes to use <boost/regex.hpp> instead of just ?

jaredgrubb commented 7 years ago

You need to have your compiler define the "DOCTOPT_USE_BOOST_REGEX" macro. In GCC/clang, you'd add "-DDOCTOPT_USE_BOOST_REGEX" to your flags list, and I'm sure MS has something like that.

jdukat commented 7 years ago

FYI I decided to switch to boost. Good decision - not only docopt started to work properly, but my code has also sped up significantly.

@jaredgrubb one important note for you... you may want to document that VS2015 (up to update 3 as available now) doesn't work properly without it. With the example above, my usage string was this: my_app [-s] [-t <num_threads>] [--config <cfg_file>] [--ult | --test] [<client>]

With VS default regexp it was parsed correctly, but then I had to refer to parsed args:

if(args["-t"].asBool())
  num_threads = args["<num_threads>"].asLong();

With boost, the above code throws, and this works:

if(args["-t"])
  num_threads = args["-t"].asLong();

Is the latter expected?

jaredgrubb commented 7 years ago

That's weird. Sounds like maybe VS regex isnt matching groups correctly?

jdukat commented 7 years ago

Clarification: the problem in VS is when I remove this from options: -t <num_threads> Limit number of worker threads. I had to remove it to keep using docopt because otherwise it was crashing in the parser (the known issue). Anyway, VS regexps seem broken significantly enough to document it with docopt and always recommend using boost regexps.