【问题标题】:Boost Spirit parser crashes on inputBoost Spirit 解析器在输入时崩溃
【发布时间】:2015-01-06 02:11:45
【问题描述】:

我有一个使用 qi::double_ 数字解析器的 boost Spirit 解析器。我遇到用户数据包含 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
}

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

相关的boost代码正在崩溃(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)轻松地使任何解析双精度的精神应用程序崩溃。

【问题讨论】:

  • 指出了安全隐患。好消息是它是一个断言,但仍然如此。大额负债

标签: c++ parsing boost boost-spirit


【解决方案1】:

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

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

Joel de Guzman 于 11 月 7 日写道:

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

【讨论】:

  • 特别是,上面包含的测试用例现在将生成inf 而不是断言。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-01
  • 2012-01-17
  • 2015-01-25
  • 1970-01-01
相关资源
最近更新 更多