Section Subclause 7.21.7.10 of C11 the C Standard [ISO/IEC 9899:2011] defines ungetc()
as follows:
...
Likewise, for ungetwc()
, C guarantees only one wide character of pushback (Section subclause 7.29.3.10). Consequently, multiple calls to ungetwc()
on the same stream must be separated by a call to a read function or a file-positioning function (which will discard any data pushed by ungetwc()
).
...
In this noncompliant code example, more than one character is pushed back on the stream referenced by fp
.:
Code Block | ||||
---|---|---|---|---|
| ||||
FILE *fp; char *file_name; /* initializeInitialize file_name */ fp = fopen(file_name, "rb"); if (fp == NULL) { /* Handle error */ } /* readRead data */ if (ungetc('\n', fp) == EOF) { /* Handle error */ } if (ungetc('\r', fp) == EOF) { /* Handle error */ } /* continue onContinue */ |
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 applies only applies if the input is seekable.
Code Block | ||||
---|---|---|---|---|
| ||||
FILE *fp; fpos_t pos; char *file_name; /* initializeInitialize file_name */ fp = fopen(file_name, "rb"); if (fp == NULL) { /* Handle error */ } /* readRead data */ if (fgetpos(fp, &pos)) { /* Handle error */ } /* readRead the data that will be "pushed back" */ if (fsetpos(fp, &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().)
...
If used improperly, ungetc()
and ungetwc()
can cause data to be truncated or lost.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
FIO13-C |
Medium |
Probable |
High | P4 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
CodeSonar |
| (customization) | Users can implement a custom check that triggers a warning when ungetc() is called twice on the same stream without an intervening call to a read function or a file-positioning function. | ||||||
Compass/ROSE |
Can detect simple violations of this recommendation. In particular, it warns when two calls to |
LDRA tool suite |
| 83 D | Partially implemented | ||||||
PC-lint Plus |
|
| 2470 | Fully supported |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
...
Bibliography
...
] | Subclause 7.21.7. |
...
10, "The ungetc |
...
Function" |
...