2015-01-06 2 views
3

У меня есть синтаксический анализатор синтаксиса, который использует численный парсер 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

Вот список рассылки обсуждение об этом:

На 7 ноября Джоэл де Гузман писал:

Это теперь зафиксировано в ветке разработки вместе с целое число улучшений в анализе точности с плавающей запятой (угловые случаи). Есть некоторые обратные несовместимые изменения, но они должны только влиять на тех, кто использует политику реального парсера, в patrticular, тех, кто специализируется на parse_frac_n. Изменения будут задокументированы в .

+0

И, в частности, тестовый пример, который включен выше, теперь будет производить 'inf' вместо утверждения. –

 Смежные вопросы

  • Нет связанных вопросов^_^