Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

The fgets() function is typically used to read a newnewline-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.

...

Code Block
bgColor#FFCCCC
langc

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-linenewline, this code overwrites an otherwise valid character.

...

Code Block
bgColor#ccccff
langc

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 newline is transferred, append a new-line 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

Incorrectly assuming a new-line newline character is read by fgets() or fgetws() can result in data truncation.

...

CERT C++ Secure Coding Standard: FIO36-CPP. Do not assume a new-line character is read when using fgets()

ISO/IEC 9899:19992011 Section 7.1921.7.2, "The fgets function"

Bibliography

[Lai 2006]
[Seacord 205a] Chapter 2, "Strings"

...