*BSD News Article 34493


Return to BSD News archive

Xref: sserve comp.os.386bsd.questions:12447 comp.os.386bsd.development:2392 comp.os.386bsd.misc:3254
Path: sserve!newshost.anu.edu.au!harbinger.cc.monash.edu.au!bunyip.cc.uq.oz.au!munnari.oz.au!news.Hawaii.Edu!ames!hookup!swrinde!emory!europa.eng.gtefsd.com!MathWorks.Com!news.duke.edu!convex!cs.utexas.edu!math.ohio-state.edu!jussieu.fr!univ-lyon1.fr!swidir.switch.ch!newsfeed.ACO.net!Austria.EU.net!EU.net!Germany.EU.net!netmbx.de!zelator!deadline.bln.sub.org!boavista.panic.bln.sub.org!boavista.bln.sub.org!erdmann
From: erdmann@boavista.bln.sub.org (Michael Erdmann)
Newsgroups: comp.os.386bsd.questions,comp.os.386bsd.development,comp.os.386bsd.misc
Subject: Re: Why does FreeBSD 1.1.5 say gets() is unsafe?
Date: 8 Aug 1994 09:48:27 GMT
Organization: none
Lines: 100
Distribution: world
Message-ID: <324v1b$14g@boavista.bln.sub.org>
References: <30lrf3$2ii@acmez.gatech.edu> <311m2e$o33@agate.berkeley.edu> <jmonroyCtMGq2.IC6@netcom.com> <Ctn5yy.3I0@cs.vu.nl> <31cf70$3c@Starbase.NeoSoft.COM> <CturD6.3C1@cs.vu.nl>
Reply-To: erdmann@boavista.bln.sub.org (Michael Erdmann)
NNTP-Posting-Host: 200.0.0.1

In article <CturD6.3C1@cs.vu.nl>, kjb@cs.vu.nl (Kees J. Bot) writes:
|> 
|> I personally don't use gets() or fgets() ever.  Typical example of my
|> code attached below.  (allocate() and fatal() are left to your
|> imagination.)
|> --
|> 	                        Kees J. Bot  (kjb@cs.vu.nl)
|> 	              Systems Programmer, Vrije Universiteit Amsterdam
|> _._. .._ _   ._ ._.. ___ _. __.   _ .... .   _.. ___ _ _ . _..   ._.. .. _. .
|> 
|> char *read1line(char *file, FILE *fp)
|> /* Read one line from a file.  Result is a malloc()'d string or NULL for EOF */
|> {
|> 	:::::
|> }

1. Fixed sized buffers in C
---------------------------
I think in general the whole concept of using fixed sized buffer for 
reading character input of variable length is a bad idea in  it self.
But there are a lot of functions like sprintf, gets, strcpy etc..  which 
are working on fixed sized buffers of which they do not know the size.
For example if you write a function do_something which has to perform some 
work on a string like shown below, you have a problem!

do_something(String buffer)
{
      for(i=0; i< what ???; ++i )
	   buffer [i] = perform_work(...);
}

Such an function allways requieres a second parameter which indicates the 
the size of the buffer.
So i think what we are talking here about is a conceptual problem of
strings and buffers in C. So far i know there is no dynamic concept for 
strings for c in sight,  or does some body know?


2. The function read1line
-------------------------
I have to agree with Kees J. Bot, i am using also some function like
he has given with some slight changes:

1. The allocation stratagy was to expensive. Allways when the string
   was reallocated twice the current size was allocated leaving lots
   of unused memory in the return string (but how cares these days). 

   I have introduced an intermediate buffer which is dynmicaly 
   increased by a fixed  increment. 
   And the final string is returned via strdup.

2. Upon EOF the function schould not check for the error. This should
   allways be done by the caller, because only he knows what to do 
   in case of an error.

#include <stdio.h>
#include <strings.h>
#include <stdlib.h>

char *read1line(FILE *fp)
/* Read one line from a file.  Result is a malloc()'d string or NULL for EOF */
{
	static char *line = NULL;
        size_t  lineLength=80;
	size_t idx;
	int c;

        if( line ==NULL )
	   line = malloc(lineLength*sizeof(char));
        
	for(idx=0; (c= getc(fp)) != EOF && c != '\n'; ++idx) {
	    if (idx == lineLength ) {
		lineLength += lineLength ;
		line= realloc(line, lineLength*sizeof(char));
	    }
	    line[idx]= c;
	}
	if (c == EOF) {   /* at  the end of the file we dont need th buffer  */
			  /* any more.					     */
	    free(line);
            line = NULL;

	    return NULL;
	}
	line[idx]= 0;

	return strdup(line);
}




   

 

-- 
============================================================================
! Michael Erdmann  (never touch a running system) ! Tel. 030 741 11 54	   !
============================================================================