Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Clarified BUFSIZ in noncompliant examples and replaced it with BUFFERSIZE in compliant ones.

...

This example uses the getchar() function to read in a character at a time from stdin, instead of reading the entire line at once. The stdin stream is read until end-of-file is encountered or a new-line character is read. Any new-line character is discarded, and a null character is written immediately after the last character read into the array. Similar to the previous example, there are no guarantees that this code will not result in a buffer overflow. Note that BUFSIZ is a macro integer defined in cstdio which represents a suggested value for setbuf() and not the maximum size of such an input buffer.

Code Block
bgColor#FFCCCC
char buf[BUFSIZ], *p;
int ch;
p = buf;
while ( ((ch = getchar()) != '\n')
       && !feof(stdin)
       && !ferror(stdin))
{
  *p++ = ch;
}
*p++ = 0;

...

In this compliant solution, characters are no longer copied to buf once index = BUFSIZBUFFERSIZE, leaving room to null terminate the string. The loop continues to read through to the end of the line until the end of the file is encountered or an error occurs.

Code Block
bgColor#ccccff
unsigned char buf[BUFSIZBUFFERSIZE];
int ch;
int index = 0;
int chars_read = 0;
while ( ( (ch = getchar()) != '\n')
        && !feof(stdin)
        && !ferror(stderr) )
{
  if (index < BUFSIZBUFFERSIZE-1) {
    buf[index++] = (unsigned char)ch;
  }
  chars_read++;
} /* end while */
buf[index] = '\0';  /* terminate NTBS */
if (feof(stdin)) {
  /* handle EOF */
}
if (ferror(stdin)) {
  /* handle error */
}
if (chars_read > index) {
  /* handle truncation */
}

...

The gets() function is inherently unsafe, and should never be used as it provides no way to control how much data is read into a buffer from stdin. These two lines of code assume that gets() will not read more than BUFSIZ - 1 characters from stdin. This is an invalid assumption and the resulting operation can cause a buffer overflow. Again note that BUFSIZ is a macro from <cstdio> and does not represent the maximum size of an input buffer.

Wiki Markup
According to Section 7.19.7.7 of C99 \[[ISO/IEC 9899:1999|AA. C++ References#ISO/IEC 9899-1999]\], the {{gets()}} function reads characters from the {{stdin}} into a destination array until end-of-file is encountered or a new-line character is read.  Any new-line character is discarded, and a null character is written immediately after the last character read into the array.

...