gpt4 book ai didi

c++ - libc++ std::istringstream 不会抛出异常。漏洞?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:38:11 26 4
gpt4 key购买 nike

在配置 std::istringstream 以在设置 failbit 时抛出异常后,我在 libc++ 中没有发生任何异常(这是在 linux 下,在 libcxxrt 的支持下编译的 libc++ ).我想这是 libc++ 或 libcxxrt 中的错误:

#include <iostream>
#include <sstream>

template<typename T> std::istream &getvalue(std::istream &is, T &value, const T &default_value = T())
{
std::stringstream ss;
std::string s;
std::getline(is, s, ',');
ss << s;
if((ss >> value).fail())
value = default_value;
return is;
}

int main()
{
std::string s = "123,456,789";
std::istringstream is(s);
unsigned n;

try
{
is.exceptions(std::ios::failbit | std::ios::eofbit);

getvalue(is, n);
std::cout << n << std::endl;

getvalue(is, n);
std::cout << n << std::endl;

// Disable EOF exception on last bit
is.exceptions(std::ios::failbit);

getvalue(is, n);
std::cout << n << std::endl;

// Force Fail reading after EOF
getvalue(is, n);
std::cout << n << std::endl;
}
catch(std::ios::failure &fail)
{
std::cout << "Fail" << std::endl;
}
}

libstdc++ 的输出:

123
456
789
Fail

libc++/libcxxrt 输出:

123
456
789
0

编辑

还在 OS X 上进行了测试。

错误提交:http://llvm.org/bugs/show_bug.cgi?id=15949

最佳答案

libc++ 正在响应 27.7.2.1 [istream]/p4,它描述了 basic_istream 解析 operator>> for unsigned:

If one of these called functions throws an exception, then unless explicitly noted otherwise, the input function sets badbit in error state. If badbit is on in exceptions(), the input function rethrows the exception without completing its actions, otherwise it does not throw anything and proceeds as if the called function had returned a failure indication.

如果:

is.exceptions(std::ios::failbit | std::ios::badbit);

然后获得所需的行为。

123
456
789
Fail

更新

chico 在下面的评论中正确地指出,他希望 getline(is, s, ',') 抛出,而不是 unsigned 提取器。

查看描述此 getline 的 21.4.8.9 [string.io]/p7:

Effects: Behaves as an unformatted input function (27.7.2.3), except that it does not affect the value returned by subsequent calls to basic_istream<>::gcount(). After constructing a sentry object, if the sentry converts to true, calls str.erase() and then extracts characters from is and appends them to str as if by calling str.append(1, c) until any of the following occurs: ...

那么问题就变成了:

How does an unformatted input function behave?

27.7.2.3 [istream.unformatted]/p1 说:

Each unformatted input function begins execution by constructing an object of class sentry with the default argument noskipws (second) argument true. If the sentry object returns true, when converted to a value of type bool, the function endeavors to obtain the requested input. Otherwise, if the sentry constructor exits by throwing an exception or if the sentry object returns false, when converted to a value of type bool, the function returns without attempting to obtain any input. In either case the number of extracted characters is set to 0; unformatted input functions taking a character array of non-zero size as an argument shall also store a null character (using charT()) in the first location of the array. If an exception is thrown during input then ios::badbit is turned on315 in *this’s error state. (Exceptions thrown from basic_ios<>::clear() are not caught or rethrown.) If (exceptions()&badbit) != 0 then the exception is rethrown. It also counts the number of characters extracted. If no exception has been thrown it ends by storing the count in a member object and returning the value specified. In any event the sentry object is destroyed before leaving the unformatted input function.

315) This is done without causing an ios::failure to be thrown.

(我为便于阅读而添加的重点)

因此,这再次表明,如果此解析操作需要异常,则必须在 exceptions 中设置 badbit

关于c++ - libc++ std::istringstream 不会抛出异常。漏洞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16468189/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com