v05i053: A "safe" replacement for gets()

ok at quintus.UUCP ok at quintus.UUCP
Wed Nov 16 09:28:26 AEST 1988


Posting-number: Volume 5, Issue 53
Submitted-by: "A. Nonymous" <ok at quintus.UUCP>
Archive-name: getsafe

[Aaaaagh.  I always suspected gets() was a potential bomb.  How about

#define gets(s) fgets(s, sizeof s, stdin)

as a quick fix?  ++bsa]

#!/bin/sh
# This is a shell archive, meaning:                              
# 1. Remove everything above the #!/bin/sh line.                
# 2. Save the resulting test in a file.                          
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	README
#	getsafe.c
sed -e 's/^X//' >README <<'------ EOF ------'
XThe recent Usenet worm demonstrated yet again that using gets() is asking
Xfor trouble.  However, gets() is often much more convenient than fgets().
XIt would be pleasant to combine the convenience of gets() with the safety
Xof fgets().  getsafe() -- reading from stdin -- and fgetsafe -- reading
Xfrom a stream passed as an argument -- are such combinations.
X
XJust compile with
X	cc -c getsafe.c
Xand use.  No warrentees, no promises, no copyrights.
------ EOF ------
ls -l README
sed -e 's/^X//' >getsafe.c <<'------ EOF ------'
X/*  File   : getsafe.c
X    Author : Richard A. O'Keefe @ Quintus Computer Systems, Inc.
X    Updated: 11 November 1988
X
X    Defines: getsafe() and fgetsafe() -- safe replacements for gets()
X
X    This file is not covered by a copyright.  Do what you like with it.
X*/
X
X#include <stdio.h>
X
X#if	0
X
X    int getsafe(char *buffer, int length)
X    int fgetsafe(char *buffer, int length, FILE *stream)
X
X    The functions read characters (getsafe reads from the standard input
X    stream, fgetsafe from its stream argument) until a new-line character
X    is read or the end of the stream is reached.  Characters are stored
X    in buffer until length-1 of them have been stored, and a NUL is put
X    after the stored characters.  The terminating new-line character is
X    not stored in the buffer.  If the input line has more than length-1
X    characters preceding the new-line, the excess characters are lost.
X
X    If a new-line character is encountered, the return value is the
X    number of characters which were read, including the new-line.  This
X    result also includes characters which were not stored, so you can
X    tell whether the line was truncated by doing
X
X	n = getsafe(buffer, sizeof buffer);
X	if (n > sizeof buffer) { the line was truncated }
X
X    If a new-line character is not encountered, characters will have been
X    read until the end of the stream was reached, and the return value is
X    0 to indicate end of stream.  This means that a last "line" which is
X    not terminated by a new-line will be lost.
X
X    Loops which used to read
X	char buffer[ITSIZE];
X	while (gets(buffer)) { process line }
X    can be converted to
X	while (getsafe(buffer, sizeof buffer)) { process line }
X
X#endif 0
X
Xint fgetsafe(buffer, length, stream)
X    register char *buffer;
X             int   length;
X    register FILE *stream;
X    {
X	register int c;
X	register int n;
X
X	for (n = 0;;) {
X	    c = getc(stream);
X	    if (c == EOF ) { *buffer = '\0'; return 0; }
X	    if (c == '\n') { *buffer = '\0'; return n; }
X	    n++;
X	    if (n < length) *buffer++ = c;
X	}
X    }
X
X
Xint getsafe(buffer, length)
X    char *buffer;
X    int   length;
X    {
X	return fgetsafe(buffer, length, stdin);
X    }
X
X
X#ifdef	TEST
X
X/*  To test this, I did
X	cc -O -DTEST getsafe.c
X	cat /usr/dict/words | paste - - - - - - - - - - | a.out
X*/
X
Xmain()
X    {
X	char buffer[81];
X	int n;
X
X	while (n = getsafe(buffer, sizeof buffer))
X	    printf("%7d %7d\n", n, strlen(buffer));
X	exit(0);
X    }
X
X#endif	TEST
X
------ EOF ------
ls -l getsafe.c
exit 0



More information about the Comp.sources.misc mailing list