Subclause 7The C Standard, 7.21.5.3 of the C Standard , paragraph 7 [ISO/IEC 9899:2011], places the following restrictions on update streams:
...
The following scenarios can result in undefined behavior (see undefined behavior 151):
- Receiving input from a stream directly following an output to that stream without an intervening call to
fflush(),fseek(),fsetpos(), orrewind()if the file is not at end-of-file - Outputting to a stream after receiving input from that stream without a call to
fseek(),fsetpos(), orrewind()if the file is not at end-of-file
Consequently, a call to fseek(), fflush(), or fsetpos() is necessary between input and output to the same stream. See ERR07-C. Prefer functions that support error checking over equivalent functions that don't for more information on why fseek() is preferred over rewind().
Noncompliant Code Example
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h>
enum { BUFFERSIZE = 32 };
extern void initialize_data(char *data, size_t size);
void func(const char *file_name) {
char data[BUFFERSIZE];
char append_data[BUFFERSIZE];
FILE *file;
file = fopen(file_name, "a+");
if (file == NULL) {
/* Handle error */
}
initialize_data(append_data, BUFFERSIZE);
if (fwrite(append_data, BUFFERSIZE1, 1BUFFERSIZE, file) != BUFFERSIZE) {
/* Handle error */
}
if (fread(data, BUFFERSIZE1, 1BUFFERSIZE, file) !=< 0BUFFERSIZE) {
/* Handle there not being data */
}
if (fclose(file) == EOF) {
/* Handle error */
}
} |
However, because the stream is not flushed between the call Because there is no intervening flush or positioning call between the calls to fread() and fwrite(), the behavior is undefined.
Compliant Solution
In this compliant solution, fseek() is called between the output and input, eliminating the undefined behavior:
...
Alternately inputting and outputting from a stream without an intervening flush or positioning call is undefined behavior.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
FIO39-C | Low | Likely | Medium | P6 | L2 |
...
Related Guidelines
| CERT C++ Secure Coding Standard | FIO39FIO50-CPP. Do not alternately input and output from a file stream without an intervening flush or positioning call | CERT C Secure Coding Standard | void FIO07-C. Prefer fseek() to rewind()|
| ISO/IEC TS 17961:2013 | Interleaving stream inputs and outputs without a flush or positioning call [ioileave] |
Bibliography
| [ISO/IEC 9899:2011] | Subclause 7.21.5.3, "The fopen Function" |
...