FIO50-CPP. 在没有获取文件定位调用前,不要从一个文件流交替地读写
原文链接:
C++ 标准,[filebuf],段落 2 [ISO/IEC 14882-2014],叙述如下:
受类
basic_filebuf<charT, traits>
的对象控制的读写限制和 C 标准库FILES
是一样
C 标准,分条款 7.19.5.3,段落 6 [ISO/IEC 9899:1999],当需要对一个打开的文件流同时读写时,遵循以下限制:
当一个文件正被以更新的模式打开时……,相关数据流可能同时执行输入和输出操作。然而,当没有
fflush
函数或获取文件位置函数(fseek
,fsetpos
,rewind
)的介入调用(intervening call),输出不应该直接接着输入,除非输入操作遇到了文件结束符。
所以,下述情景可能导致 未定义行为:
如果文件并不处于结束符,那么在输出到数据流操作后紧接着从该数据流输入,而没有
std::basic_filebuf<T>::seekoff()
的介入调用如果文件并不处于结束符,那么在从数据流输入后紧接着输出到该数据流,而没有
std::basic_filebuf<T>::seekoff()
的介入调用
除 std::basic_filebuf<T>::seekoff()
之外,没有其他函数能保证行为和调用 C 标准库的文件定位函数一致,或 std::fflush()
。
对一个文件流调用 std::basic_ostream<T>::seekp()
或 std::basic_istream<T>::seekg()
最终还是会调用到 std::basic_filebuf<T>::seekoff()
. 考虑到 std::basic_iostream<T>
同时从继承于 std::basic_ostream<T>
和 std::basic_istream<T>
, 并且 std::fstream
继承于 std::basic_iostream
, 用来保证文件流在被后续 I/O 操作前处于合法状态的任何函数调用都是可接受的。
不合规的代码示例
这个不合规的例子在文件末尾附加了数据,然后从同一个文件里读取。然而,由于在格式化输出和输入调用之间没有介入位置的调用,该行为是 未定义 的。
1 |
|
合规方案
在这个合规方案中, std::basic_istream<T>::seekg()
函数在输入和输出之间被调用,消除了 未定义行为
1 |
|
Risk Assessment
Alternately inputting and outputting from a stream without an intervening flush or positioning call is undefined behavior.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
FIO50-CPP | Low | Likely | Medium | P6 | L2 |
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
Axivion Bauhaus Suite | 7.2.0 | CertC++-FIO50 | |
Helix QAC | 2021.2 | C++4711, C++4712, C++4713 | |
Parasoft C/C++test | 2021.1 | CERT_CPP-FIO50-a | Do not alternately input and output from a stream without an intervening flush or positioning call |
Polyspace Bug Finder | R2021b | CERT C++: FIO50-CPP | Checks for alternating input and output from a stream without flush or positioning call (rule fully covered) |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
This rule supplements FIO39-C. Do not alternately input and output from a stream without an intervening flush or positioning call.
本文标题:FIO50-CPP. 在没有获取文件定位调用前,不要从一个文件流交替地读写
文章作者:xwnb
发布时间:2021-11-07
最后更新:2023-04-17
原始链接:https://xwnb.github.io/posts/3587208904/
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!并保留本声明。感谢您的阅读和支持!
分享