Date: Sun, 7 May 2000 11:11:02 +0300 (IDT) From: Eli Zaretskii X-Sender: eliz AT is To: djgpp AT delorie DOT com Subject: Re: reading text files In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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 Precedence: bulk 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.