www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2000/05/07/03:12:19

Date: Sun, 7 May 2000 11:11:02 +0300 (IDT)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
X-Sender: eliz AT is
To: djgpp AT delorie DOT com
Subject: Re: reading text files
In-Reply-To: <ikc9hsc1q0d54vjj15rlgj5f6bkfl198lq@4ax.com>
Message-ID: <Pine.SUN.3.91.1000507111040.21782F-100000@is>
MIME-Version: 1.0
Reply-To: djgpp AT delorie DOT com
Errors-To: nobody AT delorie DOT com
X-Mailing-List: djgpp AT delorie DOT com
X-Unsubscribes-To: listserv AT delorie DOT com

On Sun, 7 May 2000, Damian Yerrick wrote:

> >>   fscanf(fp, "%s", foo);
> >>   printf("read word: %s\n", foo);
> >>   return 0;
> >
> >If you replace fscanf with fgets+sscanf in this case, without changing
> >the format or anything else, it will blow up the stack in exactly the
> >same way.  Did you try it?
> 
> But if you tell fscanf to read only n characters, where n is small
> enough to fit comfortably into your buffer, everything will be nice.

That's true, but I don't see how is it relevant to this discussion.
The issue here was whether `sscanf' is any safer than `fscanf' in
that it avoids writing beyond array boundaries.

> char foo[16];
> char bar[16];
> 
> fgets(foo, 16, fp);
> sscanf(foo, "%s", bar);
> 
> This will never return more than 16 characters in bar
> because foo can never have more than 16 characters.

Sorry, that's a cooked-up example ;-).  If you *know* you will have at
most 16 characters, "%16s" is a simpler solution.  In fact, you don't
need `sscanf' at all in this case, it just copies a string from one
16-byte buffer to another.

I submit that the above snippet will never happen in real life.  The
size of the two arrays foo[] and bar[] will always be different in any
real-life program, and the maximum size is rarely ever known in
advance.  So the possibility of `sscanf' and `fscanf' overwriting the
target array is identical.

> >Also, the reason for the crash in the program you posted is that
> >the buffer foo[] is too small to accept the input from the file.
> 
> Exactly my point. Using fscanf() can result in buffer overflows
> because there is no maximum size for the output buffers.

The same happens with `sscanf'.

> >`sscanf' cannot solve this problem, since it doesn't know how large
> >is its third argument.  It only knows how large is its first argument.
> 
> Yes, but the other arguments can be made large enough to hold the
> largest thing that sscanf() can put into them; they're never larger
> than the first argument, and if the first argument has a known maximum
> size (thanks to fgets()), sscanf() cannot overflow the buffer.

If you know the max size in advance, you can make the format string
safer, and solve the problem.

Again, the issue is the difference between `sscanf' and `fscanf'.
I'm saying that whatever you can do with the former, you can do with
the latter.  If you fail to do it, both functions will blow in the
same way.

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019