A good gets() i.e. ggets() and fggets(FILE)

68 views
Skip to first unread message

CBFalconer

unread,
Jun 23, 2002, 10:34:52 PM6/23/02
to
Since people have the urge to use gets because of the simplicity
of the call, here is a version that is perfectly safe.

Note the simple file copying loop in the test program.

while (temp = ggets()) {
puts(temp);
free(temp);
}

I have thrashed this fairly well, including splint, and am
satisfied it functions as advertised. At any rate I have mounted
it, together with the testing programs, at:

<http://cbfalconer.home.att.net/download>

look for the ggets.zip file. Only 7.5k.

testall.bat is a kludgy MSDOS batch file to compile and test the
routines. It should be easily modified to check on any system.
The testing uses diff to validate the results.

malloc.xrf is a file with long lines, to test the extension of the
input buffers. It has no other redeeming virtues.

The whole point is that ggets (and fggets) allows the easy usage
of the evil gets() routine, without the insecurities. They return
an allocated buffer holding the complete input line, with the
terminal \n removed, and suitable for output via puts(). They
will never create a buffer overrun.

The fact that no storage is supplied to them should emphasize the
fact that the lines returned need to be freed eventually.

The routines return NULL for any error, else a pointer to the
allocated storage, which has been cut back to the minimum needed.
THERE IS NO SPARE SPACE for extending the returned lines.
However, their space may be extended via realloc().

The only thing of eventual use is the ggets.* files.

The two test files tggets and freverse will give some idea of
usage.

I have put this in the public domain. Use as you will. I would
appreciate attribution when used. Also comments.

--
Chuck F (cbfal...@yahoo.com) (cbfal...@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
--
comp.lang.c.moderated - moderation address: cl...@plethora.net

Douglas A. Gwyn

unread,
Jun 25, 2002, 11:41:10 AM6/25/02
to
CBFalconer wrote:
> Since people have the urge to use gets because of the simplicity
> of the call, here is a version that is perfectly safe.

I applaud your making this available, but I have to take issue
with the characterization as "safe":

> Note the simple file copying loop in the test program.
> while (temp = ggets()) {
> puts(temp);
> free(temp);
> }

What happens if ggets() cannot allocate the buffer? The loop
terminates the same as if EOF had been encountered, thereby
silently truncating the copy of the file.

I would prefer that ggets() have the added feature of throwing
an exception upon error, or at least change the interface so
as to have more than a 1-bit status return:
while (status = ggets(&temp)) { // no tuples in C, alas
puts(temp);
free(temp);
}
if (status != EOF )
handle_error(status);

The idea that malloc()ing functions should be passed a handle
so that failure to test for success will be flagged by lint etc.
is a useful one, although it reduces slightly the compiler's
ability to make best use of registers.

CBFalconer

unread,
Jun 25, 2002, 6:42:25 PM6/25/02
to
"Douglas A. Gwyn" wrote:
> CBFalconer wrote:
>
> > Since people have the urge to use gets because of the simplicity
> > of the call, here is a version that is perfectly safe.
>
> I applaud your making this available, but I have to take issue
> with the characterization as "safe":
>
> > Note the simple file copying loop in the test program.
> > while (temp = ggets()) {
> > puts(temp);
> > free(temp);
> > }
>
> What happens if ggets() cannot allocate the buffer? The loop
> terminates the same as if EOF had been encountered, thereby
> silently truncating the copy of the file.

Well, safe in that it cannot write wildly into forbidden areas.

>
> I would prefer that ggets() have the added feature of throwing
> an exception upon error, or at least change the interface so
> as to have more than a 1-bit status return:
> while (status = ggets(&temp)) { // no tuples in C, alas
> puts(temp);
> free(temp);
> }
> if (status != EOF )
> handle_error(status);
>
> The idea that malloc()ing functions should be passed a handle
> so that failure to test for success will be flagged by lint etc.
> is a useful one, although it reduces slightly the compiler's
> ability to make best use of registers.

My initial reaction was that that disturbed the simplicity of the
call, and thus encouraged misuse. On second thoughts I think you
are right, and I will change it accordingly in the next few days.
However I expect to have it return 0 on success, EOF for EOF, and
something else, positive, for allocation problems or other errors.

Thus the proposed parent function prototype will be:

int fggets(char* *buffer, FILE *f);

It has the added advantage of not losing the returned pointer by
accident. Unfortunately it doesn't read quite as well from the
point of view of the tyro.

That would make the condition above:

while (0 == (status = ggets(&temp))) { ...

I don't think exceptions are a good idea here.

I am amused by the idea of a cracker trying to find the overflow
point by entering ever lengthening lines at the terminal.
Especially if the system echoes back his completed input lines, so
that he continues to look for the end of the buffer.

--
Chuck F (cbfal...@yahoo.com) (cbfal...@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

CBFalconer

unread,
Jun 29, 2002, 8:29:03 PM6/29/02
to
CBFalconer wrote:

*** This is a revision of my original announcement ***
*** The revised code is available at the same place ***

I suggest that this be made available in a future C standard
library.

>
> Since people have the urge to use gets because of the simplicity
> of the call, here is a version that is perfectly safe.
>
> Note the simple file copying loop in the test program.
>

char *temp;

> while (0 == ggets(&temp)) {


> puts(temp);
> free(temp);
> }
>
> I have thrashed this fairly well, including splint, and am
> satisfied it functions as advertised. At any rate I have mounted
> it, together with the testing programs, at:
>
> <http://cbfalconer.home.att.net/download>
>

> look for the ggets.zip file. Only 10k


>
> testall.bat is a kludgy MSDOS batch file to compile and test the
> routines. It should be easily modified to check on any system.
> The testing uses diff to validate the results.
>
> malloc.xrf is a file with long lines, to test the extension of the

> input buffers. It has no other redeeming virtues. The same goes for various other text and .cpy files.


>
> The whole point is that ggets (and fggets) allows the easy usage
> of the evil gets() routine, without the insecurities. They return
> an allocated buffer holding the complete input line, with the
> terminal \n removed, and suitable for output via puts(). They
> will never create a buffer overrun.
>
> The fact that no storage is supplied to them should emphasize the
> fact that the lines returned need to be freed eventually.
>

Reply all
Reply to author
Forward
0 new messages