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" |
...