The ungetc() function pushes a character onto an input stream. This pushed character can then be read by subsequent calls to functions that read from that stream. However, the ungetc() function has serious limitations. A call to a file positioning function, such as fseek(), will discard any character pushed back by ungetc(). Also, the C standard only guarantees that the pushing back of one character will succeed. Consequently, subsequent calls to ungetc() must be separated by a call to a read function or a file-positioning function (which will discard any data pushed by ungetc()).
Non-Compliant Code Example
In this non-compliant code example, more than one character is pushed back on the stream referenced by fptr.
FILE* fptr = fopen(file_name, "rb");
if (fptr == NULL) {
/* Handle Error */
}
/* Read data */
ungetc('\n', fptr);
ungetc('\r', fptr);
/* Continue on */
Compliant Solution
If more than one character needs to be pushed by ungetc(), then fgetpos() and fsetpos() should be used before and after reading the data instead of pushing it back with ungetc(). Note that this solution can only be used if the input is seekable.
FILE* fptr = fopen(file_name, "rb");
fpos_t pos;
if (fptr == NULL) {
/* Handle Error */
}
/* Read data */
if (fgetpos(fptr, &pos)) {
/* Handle Error */
}
/* Read the data that will be "pushed back" */
if (fsetpos(fptr, &pos)) {
/* Handle Error */
}
/* Continue on */
Remember to always call fgetpos() before fsetpos() (see FIO44-C. Only use values for fsetpos() that are returned from fgetpos()).
Risk Assessment
If used improperly, ungetc() can cause data to be truncated or lost.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
FIO13-A |
medium |
probable |
high |
P4 |
L3 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Reference
[[ISO/IEC 9899:1999]] Section 7.19.7.11, "The ungetc function"
FIO12-A. Prefer setvbuf() to setbuf() 09. Input Output (FIO) FIO14-A. Understand the difference between text mode and binary mode with file streams