2015-01-06 44 views
3

我有一個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)輕鬆破壞任何解析雙精度的精神應用程序。

+0

現貨,也關於安全隱患。好消息是它是一個斷言,但仍然是。大型責任 – sehe

回答

3

這是一個已知的問題,並已固定在1_57_0 AFAIR

下面是關於它的郵件列表討論:

11月7日喬爾·古斯曼說:

這現在已經固定在開發分支以及一個整個 浮點精度解析(角落案例)的改進。 有一些向後不兼容的更改,但它應該隻影響那些正在使用實際解析器策略的人,特別是 那些專門研究parse_frac_n的人。這些更改將記錄在 到期時間。

+0

特別是,上面包含的測試用例現在將生成'inf'而不是斷言。 –

相關問題