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