我有一个使用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
这样的虚拟输入值轻松地崩溃任何解析双精神的精神应用程序。
答案 0 :(得分:3)
这是一个已知问题,已在1_57_0 AFAIR
中修复这是关于它的邮件列表讨论:
11月7日,Joel de Guzman写道:
现在已经在开发分支中修复了这个问题 浮点精度解析(角点情况)的改进。 有一些向后不兼容的变化,但它应该只 影响那些使用真正的解析器策略的人,特别是 那些专门研究parse_frac_n的人。这些变化将记录在案 到期时间。