Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added PC-lint Plus to Automated Detection Table

Wiki MarkupSection Subclause 7.1921.7.11 of C99 defines {{ungetc()}} as follows \[10 of the C Standard [ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999]\]2011] defines ungetc() as follows:

The ungetc function pushes the character specified by c (converted to an unsigned char) back onto the input stream pointed to by stream. Pushed-back characters will be returned by subsequent reads on that stream in the reverse order of their pushing. A successful intervening call (with the stream pointed to by stream) to a file positioning function (fseek, fsetpos, or rewind) discards any pushed-back characters for the stream. The external storage corresponding to the stream is unchanged.

One character of pushback is guaranteed.

Consequently, multiple calls to ungetc() 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 ungetc()).

Likewise, for ungetwc(), C99 C guarantees only guarantees one wide character of pushback (Section subclause 7.2429.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
bgColor#ffcccc
langc

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
bgColor#ccccff
langc

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 rule 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

Medium

probable

Probable

high

High

P4

L3

Automated Detection

Tool

Version

Checker

Description

section
CodeSonar

Compass/ROSE

Include Page
CodeSonar_V
CodeSonar_V
(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

 

 

Sectioncan

detect simple violations of this recommendation. In particular, it warns when two calls to ungetc() on the same stream are not interspersed with a file-positioning or file-read function.

It is unable to

It cannot handle cases where ungetc() is called from inside a loop

LDRA tool suite
Include Page
LDRA_V
LDRA_V

83 D

Partially implemented

PC-lint Plus

Include Page
PC-lint Plus_V
PC-lint Plus_V

2470

Fully supported

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

...

Bibliography

...

2011]Subclause 7.

...

21.7.

...

10, "The ungetc

...

Function"


...

Image Added Image Added

Bibliography

FIO12-C. Prefer setvbuf() to setbuf()      09. Input Output (FIO)      Image Modified