Search code examples
c++parsingboostboost-spirit

Boost Spirit parser crashes on input


I have a boost spirit parser that uses the qi::double_ numeric parser. I have case where the user's data contains a uuid string:

"00573e443ef1ec10b5a1f23ac8a69c43c415cedf"

And I am getting a crash inside the spirit pow10_helper() function below. Testing some more it appears to happen for any string starting with a number followed by e and another number. For example 1e999 also crashes. To reproduce the crash, try:

#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
int main()
{
    double x;
    std::string s = "1e999";
    auto a = s.begin();
    auto b = s.end();
    qi::parse(a, b, qi::double_, x); // <--- crash/assert in debug mode
}

I'm using spirit due to it's raw performance (qi::double_ is roughly 2x faster than strtod()). My question is, is there a way to workaround this limitation? Switching to a slower parser will be painful, but let me know if you have particular suggestions.

The relevant boost code is crashing (boost/spirit/home/support/detail/pow10.hpp) for reference:

template <>
struct pow10_helper<double>
{
    static double call(unsigned dim)
    {
        static double const exponents[] =
        {
            1e0,   1e1,   1e2,   1e3,   1e4,   1e5,   1e6,   1e7,   1e8,    1e9,
            ...
            1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308,
        };
        BOOST_ASSERT(dim < sizeof(exponents)/sizeof(double));
        return exponents[dim]; // <--- crash here, dim is 999 which is >308
    }
};

As a side note, this seems like a huge bug in the in spirit implementation. You should be able to easily crash any spirit app that parses doubles by passing in a dummy input value like 1e999.


Solution

  • This is a known issue and has been fixed in 1_57_0 AFAIR

    Here's the mailing list discussion about it:

    On November 7th Joel de Guzman wrote:

    This is now fixed in the develop branch along with a whole slew of improvements in floating point precision parsing (the corner cases). There are some backward incompatible changes, but it should only affect those who are using the real parser policies, in patrticular, those who specialize parse_frac_n. The changes will be documented in due time.