且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

libc ++ std :: istringstream不会引发异常.漏洞?

更新时间:2023-11-12 11:52:28

libc ++响应27.7.2.1 [istream]/p4,它描述了unsignedbasic_istream解析operator>>:

libc++ is responding to 27.7.2.1 [istream]/p4 which describes the basic_istream parse operator>> for unsigned:

如果这些被调用函数之一引发异常,则除非 明确指出,否则,输入函数会将badbit设置为错误 状态.如果在exceptions()中打开badbit,则输入函数重新抛出 没有完成其动作的异常,否则不会 抛出任何东西并继续进行,就好像被调用函数返回了一个 故障指示.

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提取器.

chico rightly pointed out in the comments below that he expected getline(is, s, ',') to throw, not the unsigned extractor.

查看21.4.8.9 [string.io]/p7,它描述了此getline:

Looking at 21.4.8.9 [string.io]/p7 which describes this getline:

效果:表现为未格式化的输入函数(27.7.2.3),除了 它不会影响后续对的调用返回的值 basic_istream<> :: gcount().构造哨兵对象后,如果 哨兵转换为true,调用str.erase()然后提取 来自is的字符,并通过调用将它们附加到str str.append(1,c)直到出现以下任何一种情况:...

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说:

27.7.2.3 [istream.unformatted]/p1 says:

每个未格式化的输入函数都通过构造一个 带有默认参数noskipws的sendry类的对象(第二个) 说法正确.如果哨兵对象返回true,则转换为 类型为bool的值,该函数将努力获取所请求的 输入.否则,如果哨兵构造函数通过抛出 异常,或者当哨兵对象返回false时,将其转换为 类型为bool的值,该函数将返回而不会尝试获取 任何输入.无论哪种情况,提取的字符数均设置为 0;未格式化的输入函数,其字符数组为非零 size作为参数还应存储一个空字符(使用charT()) 在数组的第一个位置. 如果在此期间引发异常 输入,然后在错误状态为 315 上打开ios :: badbit. (从basic_ios<> :: clear()引发的异常不会被捕获或 如果(exceptions()& badbit)!= 0,则异常为 .它还计算提取的字符数.如果不 引发异常,它通过将计数存储在成员中而结束 对象并返回指定的值.无论如何,哨兵 对象在离开未格式化的输入函数之前被销毁.

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)这样做不会导致ios :: failure抛出.

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

(出于可读性考虑,我加了强调)

(emphasis added by me for readability purposes)

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

So this again appears to indicate that if an exception is desired from this parse operation, badbit has to be set in exceptions.