我有一个使用 qi::double_
数字解析器的 boost spirit 解析器。我遇到过用户数据包含 uuid 字符串的情况:
“00573e443ef1ec10b5a1f23ac8a69c43c415cedf”
我在下面的 spirit 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
}
};
作为旁注,这似乎是 in spirit 实现中的一个巨大错误。您应该能够通过传入一个虚拟输入值(如 1e999
)轻松地使任何解析 double 的 spirit 应用程序崩溃。
最佳答案
这是一个已知问题,已在 1_57_0 AFAIR 中修复
这是关于它的邮件列表讨论:
11 月 7 日,Joel de Guzman 写道:
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.
关于c++ - Boost Spirit 解析器在输入时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27791080/