Boost Spirit解析器在输入时崩溃

时间:2015-01-06 02:11:45

标签: c++ parsing boost boost-spirit

我有一个使用qi::double_数字解析器的boost精神解析器。我的情况是用户的数据包含一个uuid字符串:

"00573e443ef1ec10b5a1f23ac8a69c43c415cedf"

我在下面的精神pow10_helper()功能中遇到了崩溃。对于以数字后跟e和另一个数字开头的任何字符串,似乎会进行更多测试。例如,1e999也会崩溃。要重现崩溃,请尝试:

#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
}

我正在使用精神,因为它的原始性能(qi::double_大约比strtod()快2倍)。我的问题是,有没有办法解决这个限制?切换到较慢的解析器会很痛苦,但如果您有特别的建议,请告诉我。

相关的提升代码崩溃(boost/spirit/home/support/detail/pow10.hpp)以供参考:

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
    }
};

作为旁注,这在精神实现中似乎是一个巨大的错误。您应该能够通过传递像1e999这样的虚拟输入值轻松地崩溃任何解析双精神的精神应用程序。

1 个答案:

答案 0 :(得分:3)

这是一个已知问题,已在1_57_0 AFAIR

中修复

这是关于它的邮件列表讨论:

11月7日,Joel de Guzman写道:

  

现在已经在开发分支中修复了这个问题   浮点精度解析(角点情况)的改进。   有一些向后不兼容的变化,但它应该只   影响那些使用真正的解析器策略的人,特别是   那些专门研究parse_frac_n的人。这些变化将记录在案   到期时间。