C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 11-06-2009, 08:44 AM   #1
Registered User
 
penney's Avatar
 
Join Date: Jan 2003
Posts: 47
"The Insidious strncpy - Just an FYI"

The purpose of the strncpy is supposedly to perform safe copies so as to not exceed the limits of your string sizes. The problem with the strncpy is that if your source string is longer than your destination string, then the strncpy will NOT NULL terminate the destination string even though you may have been prudent in limiting the number of characters read from the source string to the total size of the destination string minus 1. This means that you must always ensure that your final destination strings are always NULL terminated prior to or just after using the strncpy function. For example: Let’s assume you have defined -> char str[5]; and you issued the command: strncpy(str,”my string”,4); You would have an non terminated str string with “my s” as the first 4 characters. You would have to perform a str[5]=’\0’; or some variation thereof to null terminate the string.
penney is offline   Reply With Quote
Old 11-06-2009, 08:55 AM   #2
The larch
 
Join Date: May 2006
Posts: 3,082
IMO, you probably just have a problem if the target string is too short, unless you are happy with getting a truncated string.

For this reason, I don't quite understand how strncpy can be considered a safe strcpy, since data integrity might be just as important as mechanically avoiding buffer overflows. In the general case, I make sure that I allocated enough memory for the target string and use strcpy, and reserve strncpy for other things than just making a plain copy of some string. (strncpy rather seems to me as providing substring extraction)
__________________
I might be wrong.

Quote:
Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
Quoted more than 1000 times (I hope).
anon is offline   Reply With Quote
Old 11-06-2009, 09:34 AM   #3
Jack of many languages
 
Join Date: Nov 2007
Location: Katy, Texas
Posts: 1,929
If you perform a str[5] = '\0' on a char str[5], you've become the storage corruptor yourself.
__________________
Mac and Windows cross platform programmer. Ruby lover.

Memorable Quotes From Recent Posts:

I can't remember.
Dino is offline   Reply With Quote
Old 11-06-2009, 09:38 AM   #4
Code Goddess
 
Prelude's Avatar
 
Join Date: Sep 2001
Posts: 9,661
>The purpose of the strncpy is supposedly to perform safe
>copies so as to not exceed the limits of your string sizes.

This is a common myth, and it's the key instigator in creating the very class of bugs you warn against in your post. In reality, strncpy was designed with fixed length fields in mind. For that purpose strncpy is well suited, and only when you try to use it as a "safe" strcpy does it start to become a wart. I see this as akin to not understanding that scanf was designed for strictly formatted input (not user input), then complaining that scanf has "problems". In other words, PEBKAC.

I strongly recommend that you use strncpy for what it was designed rather than as an ill suited band-aid to a problem that really stems from undisciplined use of strcpy. If you turn on your brain, strcpy can be used safely. If you don't believe that or don't trust yourself to do it well, there are many third party alternatives such as strlcpy that do what most people think strncpy does.
__________________
My best code is written with the delete key.
Prelude is offline   Reply With Quote
Old 11-06-2009, 10:04 AM   #5
Registered User
 
Join Date: Apr 2006
Posts: 36
If you are really paranoid about such stuff, you can try snprintf. But calling snprintf is probably more expensive than calling the string copy functions.

Code:
int snprintf(char *restrict s, size_t n, const char *restrict format, ...); 
The snprintf() function shall be equivalent to sprintf(), with the addition of the n argument which states the size of the buffer referred to by s.
If n is zero, nothing shall be written and s may be a null pointer. Other-wise, output bytes beyond the n-1st shall be discarded instead of being written to the array, and a null byte is written at the end of the bytes actually written into the array.


But in any case the man page does say "it is the user's responsibility to ensure that enough space is available."
samf is offline   Reply With Quote
Old 11-06-2009, 10:13 AM   #6
Guest
 
Sebastiani's Avatar
 
Join Date: Aug 2001
Posts: 4,923
Quote:
Originally Posted by Prelude View Post
In other words, PEBKAC.
Haven't heard that one in a while.
Sebastiani is offline   Reply With Quote
Old 11-06-2009, 10:59 AM   #7
Registered User
 
slingerland3g's Avatar
 
Join Date: Jan 2008
Location: Seattle
Posts: 476
As mentioned, one should not just code using functions, which do ease work and code a bit, without knowing all the ramifications that go with using that function call. This function does do what it is intended to do, you just have to be smart about using it. You should not trust any function within a library unless you have created it yourself and know what its purpose and limits are. This goes for any programming language, really, and not just for c.
slingerland3g is offline   Reply With Quote
Old 11-06-2009, 11:05 AM   #8
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,381
Quote:
Originally Posted by slingerland3g View Post
As mentioned, one should not just code using functions, which do ease work and code a bit, without knowing all the ramifications that go with using that function call.
True, but it also falls on the function's designer to provide an interface which is not confusing and error-prone. But strncpy() isn't the only function I could complain about.

You know what drives me crazy? The fact that the FILE * parameter to fwrite() is the last parameter in the list, while the FILE * parameter to fputc() is the first parameter in the list.

Programming in C for 17 years and I still need to look it up. Every. Single. Time.
__________________
"Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot
brewbuck is offline   Reply With Quote
Old 11-06-2009, 11:17 AM   #9
Registered User
 
Join Date: Sep 2006
Posts: 2,512
fputc() comes *FIRST*
fwrite() comes *LAST*

in the list of the two functions. OK, it's thin, but it's something to help remember it.
Adak is offline   Reply With Quote
Old 11-06-2009, 11:23 AM   #10
Registered User
 
slingerland3g's Avatar
 
Join Date: Jan 2008
Location: Seattle
Posts: 476
Quote:
Originally Posted by brewbuck View Post
True, but it also falls on the function's designer to provide an interface which is not confusing and error-prone. But strncpy() isn't the only function I could complain about.

You know what drives me crazy? The fact that the FILE * parameter to fwrite() is the last parameter in the list, while the FILE * parameter to fputc() is the first parameter in the list.

Programming in C for 17 years and I still need to look it up. Every. Single. Time.

Yes, very true. I still have issues in trying to understand the API for writing to the kernel to test the arp and or routing table limits for debugging.
slingerland3g is offline   Reply With Quote
Old 11-06-2009, 02:16 PM   #11
Guest
 
Sebastiani's Avatar
 
Join Date: Aug 2001
Posts: 4,923
Quote:
Originally Posted by brewbuck View Post
True, but it also falls on the function's designer to provide an interface which is not confusing and error-prone. But strncpy() isn't the only function I could complain about.

You know what drives me crazy? The fact that the FILE * parameter to fwrite() is the last parameter in the list, while the FILE * parameter to fputc() is the first parameter in the list.

Programming in C for 17 years and I still need to look it up. Every. Single. Time.
Heheh. So true.

Another one that's always gotten on my nerves is fgets - I can't think of a single case where I actually needed the newline (if it's even present; which means that if you really do need one you'll have to check anyway).

Last edited by Sebastiani; 11-06-2009 at 02:19 PM.
Sebastiani is offline   Reply With Quote
Old 11-06-2009, 02:58 PM   #12
Code Goddess
 
Prelude's Avatar
 
Join Date: Sep 2001
Posts: 9,661
>fgets - I can't think of a single case where I actually needed the newline
Actually, I've found myself using the newline for its intended purpose many a time. If the newline is present, the line is complete. If not present, fgets read a partial line and the application needs to do more work to avoid losing data or corrupting the flow of input. This is important information, considering that we're forced to use a fixed sized buffer with fgets in all cases.
__________________
My best code is written with the delete key.
Prelude is offline   Reply With Quote
Old 11-06-2009, 03:52 PM   #13
Senior software engineer
 
brewbuck's Avatar
 
Join Date: Mar 2007
Location: Portland, OR
Posts: 5,381
Quote:
Originally Posted by Prelude View Post
>fgets - I can't think of a single case where I actually needed the newline
Actually, I've found myself using the newline for its intended purpose many a time. If the newline is present, the line is complete. If not present, fgets read a partial line and the application needs to do more work to avoid losing data or corrupting the flow of input. This is important information, considering that we're forced to use a fixed sized buffer with fgets in all cases.
That's one possibility. Another possibility is that it's the last line of the file, and it happened to not have a trailing newline. To tell the difference, you have to try to get a character to check if it's EOF. If not, you need to unget it. Gross.
__________________
"Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously." -- raftpeople@slashdot
brewbuck is offline   Reply With Quote
Old 11-06-2009, 05:44 PM   #14
Guest
 
Sebastiani's Avatar
 
Join Date: Aug 2001
Posts: 4,923
Quote:
Originally Posted by Prelude View Post
>fgets - I can't think of a single case where I actually needed the newline
Actually, I've found myself using the newline for its intended purpose many a time. If the newline is present, the line is complete. If not present, fgets read a partial line and the application needs to do more work to avoid losing data or corrupting the flow of input. This is important information, considering that we're forced to use a fixed sized buffer with fgets in all cases.
Ah, that makes sense. Which explains why 'gets' discards it instead (no buffer limit).

Quote:
Originally Posted by Brewbuck
That's one possibility. Another possibility is that it's the last line of the file, and it happened to not have a trailing newline. To tell the difference, you have to try to get a character to check if it's EOF. If not, you need to unget it. Gross.
In that case though you could always use 'feof'. I always follow it up by an 'ferror' anyway to handle the however-rare-but-possible hard-disk failure (or maybe not so rare, considering the technologies in use today (usb, etc)).
Sebastiani is offline   Reply With Quote
Old 11-07-2009, 03:42 AM   #15
Registered User
 
Join Date: Apr 2006
Location: United States
Posts: 3,202
> In that case though you could always use 'feof'.

I don't see how that would be different than what brewbruck suggested. If you grabbed the last line of some file, you can't just check feof(), you have to read again to enter eof state. TBH, feof() would report a wrong result about as often as a hard-disk failure occurs anyway, since you would have to read exactly the amount of characters left in order to avoid eof state, but apples and oranges are possible.
__________________
Os iusti meditabitur sapientiam
Et lingua eius loquetur indicium

"There is nothing either good or bad, but thinking makes it so." (Shakespeare, Hamlet, Act II scene ii)

http://www.myspace.com/whiteflags99

Last edited by whiteflags; 11-07-2009 at 03:44 AM.
whiteflags is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
strcpy and strncpy roaan C Programming 5 07-26-2009 08:04 PM
why is strncpy segfaulting here? Calef13 C Programming 3 12-29-2008 03:27 PM
strncpy adavnced :P Joke C Programming 3 07-14-2008 11:14 AM
strncpy question, size -1?? fayte C Programming 16 03-16-2006 11:32 PM
strncpy doesn't seem to work linucksrox C++ Programming 3 09-08-2005 01:34 PM


All times are GMT -6. The time now is 04:59 AM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22