Boost Spirit解析器在输入时崩溃

时间:2022-10-31 20:20:37

I have a boost spirit parser that uses the qi::double_ numeric parser. I have case where the user's data contains a uuid string:

我有一个使用qi :: double_数字解析器的boost精神解析器。我有用户的数据包含一个uuid字符串的情况:

"00573e443ef1ec10b5a1f23ac8a69c43c415cedf"

“00573e443ef1ec10b5a1f23ac8a69c43c415cedf”

And I am getting a crash inside the spirit pow10_helper() function below. Testing some more it appears to happen for any string starting with a number followed by e and another number. For example 1e999 also crashes. To reproduce the crash, try:

而且我在下面的精神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
}

I'm using spirit due to it's raw performance (qi::double_ is roughly 2x faster than strtod()). My question is, is there a way to workaround this limitation? Switching to a slower parser will be painful, but let me know if you have particular suggestions.

我正在使用精神,因为它的原始性能(qi :: double_比strtod()大约快2倍)。我的问题是,有没有办法解决这个限制?切换到较慢的解析器将是痛苦的,但如果您有特别的建议,请告诉我。

The relevant boost code is crashing (boost/spirit/home/support/detail/pow10.hpp) for reference:

相关的升级代码崩溃(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
    }
};

As a side note, this seems like a huge bug in the in spirit implementation. You should be able to easily crash any spirit app that parses doubles by passing in a dummy input value like 1e999.

作为旁注,这似乎是精神实施中的一个巨大的错误。您应该能够轻松地通过传入像1e999这样的虚拟输入值来解析任何解析双打的精神应用程序。

1 个解决方案

#1


3  

This is a known issue and has been fixed in 1_57_0 AFAIR

这是一个已知问题,已在1_57_0 AFAIR中修复

Here's the mailing list discussion about it:

这是关于它的邮件列表讨论:

On November 7th Joel de Guzman wrote:

11月7日Joel de Guzman写道:

This is now fixed in the develop branch along with a whole slew of improvements in floating point precision parsing (the corner cases). There are some backward incompatible changes, but it should only affect those who are using the real parser policies, in patrticular, those who specialize parse_frac_n. The changes will be documented in due time.

现在,这已经在开发分支中得到了修复,并且浮点精度解析(角点情况)有了一大堆改进。有一些向后不兼容的更改,但它应该只影响那些使用真正的解析器策略的人,特别是那些专门化parse_frac_n的人。这些变化将在适当的时候记录。

#1


3  

This is a known issue and has been fixed in 1_57_0 AFAIR

这是一个已知问题,已在1_57_0 AFAIR中修复

Here's the mailing list discussion about it:

这是关于它的邮件列表讨论:

On November 7th Joel de Guzman wrote:

11月7日Joel de Guzman写道:

This is now fixed in the develop branch along with a whole slew of improvements in floating point precision parsing (the corner cases). There are some backward incompatible changes, but it should only affect those who are using the real parser policies, in patrticular, those who specialize parse_frac_n. The changes will be documented in due time.

现在,这已经在开发分支中得到了修复,并且浮点精度解析(角点情况)有了一大堆改进。有一些向后不兼容的更改,但它应该只影响那些使用真正的解析器策略的人,特别是那些专门化parse_frac_n的人。这些变化将在适当的时候记录。