LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-25-2013, 02:09 PM   #1
atlantis43
Member
 
Registered: Feb 2013
Posts: 289

Rep: Reputation: Disabled
fgets() and buffer overflow


Wondering if someone can help solve my confusion in the following:
Code:
#include <stdio.h>

int main(void)
{
char sentence[100];

while(fgets(sentence, sizeof(sentence), stdin)!= NULL)
    {
    printf("%s\n", sentence); 
    }

return 0;
}
Fgets(), I understand, has the advantage to prevent buffer overflow as a result of the buffer size inclusion in its arguments. However, if I enter a string of >99 chars in the above program, the first 99 chars are displayed in one string, and then the remaining chars which I entered are returned in a following string. If the buffer established is only SIZE ==100, then where are the other chars that I entered getting stored. Is a new buffer being created after I exceed 99 chars, or what is happening to store these additional chars?
Thanks for any attempts at explanation.
 
Old 06-25-2013, 03:19 PM   #2
tronayne
Senior Member
 
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541

Rep: Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065
fgets() will read at most one less than sizeof (buf) characters (it will terminate the string with a null); it will read to a NL character or to one less than the size of the buffer (the NL character will be included in the buffer and the string will be terminated with a NULL).

Your loop reads 99 characters, prints them, then reads whatever is left in the system buffer (not your buffer, the I/O buffer maintained by the system) and prints those.

A slightly more "standard" way might be something like this (which is reading from a file rather than the keyboard):
Code:
#include <stdio.h>
#include <stdlib.h>

void    main    (void)
{
        char    buf [BUFSIZ];
        FILE    *helpfile;

        if ((helpfile = fopen ("instructions", "r")) == (FILE *) NULL) {
                (void) fprintf (stderr, "can't open instructions\n");
                exit (EXIT_FAILURE);
        }
        while (fgets (buf, BUFSIZ, helpfile) != (char *) NULL)
                (void) fputs (buf, stdout);
        (void) fclose (helpfile);
        exit (EXIT_SUCCESS);
}
The token, BUFSIZ, is a numeric value (defined as 8192 on many 64-bit systems) -- it doesn't hurt anything (and can be beneficial) to use BUFSIZ for I/O buffering as above; 8K isn't a heck of lot of memory to allocate for this purpose (and you can use the same buffer space again and again throughout a program).

Also, read the manual page for fgets for more information.

Hope this helps some.

[EDIT]
Duh! I typed NULL instead of NL (fixed above), fumble-fingers!

fgest() will read to a NL, EOF or to one less than size.

NL is the ASCII abbreviation of new line, ASCII EOT is usually EOF in Unix/Linux.
Code:
	Dec	Hex	Octal	Binary		ASCII
	004	004	0004	00000100	EOT	(Ctrl-D)
	010	00a	0012	00001010	NL	(Ctrl-J)
Thanks to http://www.linuxquestions.org/questi...2/#post4978966 for pointing that out.
[/EDIT]

Last edited by tronayne; 06-26-2013 at 08:32 AM.
 
1 members found this post helpful.
Old 06-25-2013, 04:24 PM   #3
atlantis43
Member
 
Registered: Feb 2013
Posts: 289

Original Poster
Rep: Reputation: Disabled
helps a lot! Now I get a better idea of the existence of the system buffer vs. mybuffer.
 
Old 06-25-2013, 04:26 PM   #4
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
There may be a few buffers between your keyboard and your code. In particular, if you are just typing on your terminal, it is very likely that it is set in line-buffering mode which means that it won't send any data until you press Return.

Then, the TTY device in the kernel will read data to its own buffer and offer it on standard input of your program.

If you've typed more then the TTY driver is willing to handle in one go, then it may read only part of the data and then block in which case the data that has not yet been consumed will still reside in terminal's buffer.

Of course things get much more complicated if you are connected via SSH.

It is also worth nothing that as tronayne has said, 8K isn't a heck of a lot of memory, and if you are reading data from a file, then kernel will most likely read in chunks of multiples of 4K anyway. So a simple fgetc() which returns a single byte may cause operating system to read 4K page anyway.
 
1 members found this post helpful.
Old 06-26-2013, 03:58 AM   #5
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,880
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
Or you could use getline(3), which is a GNU extension.
 
Old 06-26-2013, 07:16 AM   #6
tronayne
Senior Member
 
Registered: Oct 2003
Location: Northeastern Michigan, where Carhartt is a Designer Label
Distribution: Slackware 32- & 64-bit Stable
Posts: 3,541

Rep: Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065Reputation: 1065
If you're serious about C programming, let me recommend an excellent book you might want to pick up: Stephen G. Kochan, Patrick H. Wood, Topics in C Programming (revised ed.). The ISBN is 0-471-53404-8 and it is available from Amazon and other providers (there may be a newer edition).

It's written to teach C programmers how to program and, in my opinion, is the best single-source guide available detailing advanced C programming for a Unix/Linux environment. There are hundreds of working examples (yeah, really, working useable examples). Kochan and Wood come from Bell Labs and write clearly and concisely -- it's an easy read and well worth your time.

I would urge that you write programs to ANSI/POSIX standards -- if you do, they're going to work on pretty much any platform you may need to support. Avoid "handy" extensions -- they're expedient when programming but will come back and haunt you if you need to port from, say, Linux to Solaris (Solaris' C compiler is not GNU). Stick with the standards and you won't be reinventing the wheel (and getting telephone calls at three in the morning, either). And, if you need to port to Microsoft, heaven help you if you don't stick to standards.

Hope this helps some.
 
1 members found this post helpful.
Old 06-26-2013, 07:55 AM   #7
linosaurusroot
Member
 
Registered: Oct 2012
Distribution: OpenSuSE,RHEL,Fedora,OpenBSD
Posts: 982
Blog Entries: 2

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by tronayne View Post
it will terminate the string with a null); it will read to a NULL character or to one less than the size of the buffer
Also, read the manual page for fgets for more information.
http://linux.die.net/man/3/fgets

Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] recordmydesktop buffer overflow splintercdo Slackware 7 04-09-2011 12:30 PM
What is a buffer overflow Joey.Dale Linux - Security 4 07-12-2004 05:12 PM
Buffer Overflow pymehta Linux - Security 7 02-24-2004 01:19 PM
buffer overflow cxel91a Programming 3 08-14-2003 05:23 PM
Q. What is a buffer overflow? auslew Linux - Security 2 11-08-2002 05:36 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:10 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration