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

Compare with Current View Page History

« Previous Version 35 Next »

The fgets() function is typically used to read a new-line 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 new-line, 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 new-line is transferred, append a new-line 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

Incorrectly assuming a new-line 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.

Other Languages

This rule appears in the C++ Secure Coding Standard as FIO36-CPP. Do not assume a new-line character is read when using fgets().

References

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


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. Do not assume character data has been read

  • No labels