Section Subclause 7.21.7.10 of 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;
/* Initialize file_name */
fp = fopen(file_name, "rb");
if (fp == NULL) {
/* Handle error */
}
/* Read data */
if (ungetc('\n', fp) == EOF) {
/* Handle error */
}
if (ungetc('\r', fp) == EOF) {
/* Handle error */
}
/* 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 applies only if the input is seekable.
Code Block | ||||
---|---|---|---|---|
| ||||
FILE *fp;
fpos_t pos;
char *file_name;
/* Initialize file_name */
fp = fopen(file_name, "rb");
if (fp == NULL) {
/* Handle error */
}
/* Read data */
if (fgetpos(fp, &pos)) {
/* Handle error */
}
/* Read 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
...