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

Compare with Current View Page History

« Previous Version 31 Next »

The fgets() function is typically used to read a newline-terminated line of input from a stream. The fgets() function takes a size parameter for the destination buffer and copies, at most, size-1 characters from a stream to a string. Truncation errors can occur if the programmer assumes that the last character in the destination string is a newline.

The fgetws() function is similarly affected.

Noncompliant Code Example

This noncompliant code example attempts to remove the trailing newline (\n) from an input line.

char buf[BUFSIZ + 1];

if (fgets(buf, sizeof(buf), stdin)) {
  if (*buf) { /* see FIO37-C */
    buf[strlen(buf) - 1] = '\0';
  }
}
else {
  /* Handle error condition */
}

However, if the last character in buf is not a newline, this code overwrites an otherwise-valid character.

Compliant Solution

This compliant solution uses strchr() to replace the newline character in the string (if it exists). The equivalent solution for fgetws() would use wcschr().

char buf[BUFSIZ + 1];
char *p;

if (fgets(buf, sizeof(buf), stdin)) {
  p = strchr(buf, '\n');
  if (p) {
    *p = '\0';
  }
}
else {
  /* handle error condition */
}

An obvious alternative is to leave room in the buffer for one more character, and when no newline is transferred, append a newline followed by a null-termination character. This approach is unsafe, because it quietly accepts an input that is not what was actually intended, with unknown consequences.

Risk Assessment

Assuming a newline character is read by fgets() or fgetws() can result in data truncation.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FIO36-C

medium

likely

medium

P12

L1

Related Vulnerabilities

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

References

[[Lai 06]]
[[Seacord 05a]] Chapter 2, "Strings"
[[ISO/IEC 9899:1999]] Section 7.19.7.2, "The fgets function"


FIO35-C. Use feof() and ferror() to detect end-of-file and file errors when sizeof(int) == sizeof(char)      09. Input Output (FIO)       FIO37-C. Don't assume character data has been read

  • No labels