v05i053: A "safe" replacement for gets()

ok at quintus ok at quintus
Wed Nov 16 19:35:04 AEST 1988


The getsafe()/fgetsafe() functions recently posted to comp.sources.misc
contain two bugs:  the "number of characters consumed" count is off by
1 in some cases, and it was possible for a hacker to break them just
like the old ones, by providing more than 2**32 characters of input.

Context diffs to be applied to getsafe.c:

*** getsafe.old.c	Fri Nov 14 01:34:43 1988
--- getsafe.c	Tue Nov 15 23:24:39 1988
***************
*** 1,7 ****
  /*  File   : getsafe.c
      Author : Richard A. O'Keefe @ Quintus Computer Systems, Inc.
!     Updated: 11 November 1988
! 
      Defines: getsafe() and fgetsafe() -- safe replacements for gets()
  
      This file is not covered by a copyright.  Do what you like with it.
--- 1,6 ----
  /*  File   : getsafe.c
      Author : Richard A. O'Keefe @ Quintus Computer Systems, Inc.
!     Updated: 15 November 1988
      Defines: getsafe() and fgetsafe() -- safe replacements for gets()
  
      This file is not covered by a copyright.  Do what you like with it.
***************
*** 30,35 ****
--- 29,37 ----
  	n = getsafe(buffer, sizeof buffer);
  	if (n > sizeof buffer) { the line was truncated }
  
+     If the line was not truncated, and if the input contained no NUL
+     characters, getsafe()'s return value will be strlen(buffer)+1.
+ 
      If a new-line character is not encountered, characters will have been
      read until the end of the stream was reached, and the return value is
      0 to indicate end of stream.  This means that a last "line" which is
***************
*** 41,46 ****
--- 43,51 ----
      can be converted to
  	while (getsafe(buffer, sizeof buffer)) { process line }
  
+     BEWARE:  if the input line is _really_ long, C's pathetic arithmetic
+     would make n wrap around.  fgetsafe() checks for that, and makes n
+     stick at the most positive integer.
  #endif 0
  
  int fgetsafe(buffer, length, stream)
***************
*** 51,63 ****
  	register int c;
  	register int n;
  
! 	for (n = 0;;) {
! 	    c = getc(stream);
! 	    if (c == EOF ) { *buffer = '\0'; return 0; }
! 	    if (c == '\n') { *buffer = '\0'; return n; }
! 	    n++;
! 	    if (n < length) *buffer++ = c;
  	}
      }
  
  
--- 56,71 ----
  	register int c;
  	register int n;
  
! 	for (n = 0; ; *buffer++ = c) {
! 	    if ((c = getc(stream)) == EOF) break;
! 	    if (++n >= length || c == '\n') break;
  	}
+ 	*buffer++ = '\0';
+ 	while (c != '\n') {
+ 	    if ((c = getc(stream)) == EOF) return 0;
+ 	    if (++n < 0) --n;
+ 	}
+ 	return n;
      }
  
-- 



More information about the Comp.sources.bugs mailing list