You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 22 Next »

Invoking getc() and putc() with stream arguments that have side effects may cause unexpected results because these functions may be implemented as macros and the stream arguments to these macros may be evaluated more than once.

This does not apply to the character argument in putc(), which is guaranteed to be evaluated exactly once.

Non-Compliant Code Example: getc()

This code calls the getc() function with an expression as the stream argument. If getc() is implemented as a macro, the file may be opened several times (see FIO31-C. Do not simultaneously open the same file multiple times).

FILE *fptr;

int c = getc(fptr = fopen(file_name, "r"));

This non-compliant code example also violaties FIO33-C. Detect and handle input output errors resulting in undefined behavior.

Compliant Solution: getc()

In this compliant solution, getc() is no longer called with an expression as its argument.

FILE *fptr = fopen(file_name, "r");
if (fptr == NULL) {
  /* Handle Error */
}

int c = getc(fptr);

Non-Compliant Code Example: putc()

In this non-compliant example, putc() is called with c++ as an argument. If putc() is implemented as a macro, c++ could be evaluated several times within the macro expansion of putc() with unintended results.

FILE *fptr = NULL;
int c = 'a';
while (c <= 'z') {
  putc(c++, fptr ? fptr : (fptr = fopen(file_name, "w"));
}

Compliant Solution: putc()

In the compliant solution, c++ is no longer an argument to putc().

FILE *fptr = fopen(file_name, "w");
if (fptr == NULL) {
  /* Handle Error */
}

int c = 'a';

while (c <= 'z') {
  putc(c++, fptr);
}

The c++ is perfectly safe, since putc() guarantees to evaluate its character argument exactly once.

This example only illustrates the side-effect issue.  The output will differ depending on the character set.

Risk Assessment

Using an expression that has side effects as the argument to getc() or putc() can result in unexpected behavior and possibly abnormal program termination.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FIO41-C

1 (low)

1 (unlikely)

2 (medium)

P2

L3

Automated Detection

The LDRA tool suite V 7.6.0 is able to detect violations of this rule.

Related Vulnerabilities

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

References

[[ISO/IEC 9899-1999]] Section 7.19.7.5, "The getc function"; Section 7.19.7.8, "The putc function"


FIO40-C. Reset strings on fgets() failure      09. Input Output (FIO)       FIO42-C. Ensure files are properly closed when they are no longer needed

  • No labels