我有一個boost spirit解析器,它使用qi::double_
數字解析器。我已經在用戶的數據包含一個UUID字符串大小寫:Boost Spirit解析器在輸入上崩潰
"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_
大約是2倍比strtod()
更快)。我的問題是,有沒有辦法解決這個限制?切換到較慢的解析器會很痛苦,但是如果您有特別的建議,請告訴我。
相關升壓代碼崩潰(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
)輕鬆破壞任何解析雙精度的精神應用程序。
現貨,也關於安全隱患。好消息是它是一個斷言,但仍然是。大型責任 – sehe