Fog Creek Software
Discussion Board




Goodbye strcpy

Of course, not until Whidbey or VS 2005.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dncode/html/secure03102004.asp

BSharper
Wednesday, April 07, 2004

If you still use strcpy(), strcat(), strncpy(), or strncat(), then you have no business writing C code.

For static buffers, I always use strlcpy() and strlcat(). Fase, easy, and fast.

http://www.courtesan.com/todd/papers/strlcpy.html

Kassel v. Consolidated Freightways Corporation
Wednesday, April 07, 2004

MS is making the right decision, absolutely. strcpy should have been deprecated long ago along with scanf and all the others. Any review of strange code should include a search for all these functions and elimination of them.

Dennis Atkins
Wednesday, April 07, 2004

Hm, that's interesting about strncpy. I have a wrapper of it myself that always puts the NUL at the end because I did note the bizarre point in its doc that it does not always truncate (doh how stupid is that anyway obviously a bug bf Dennis Ritchie that should have been fixed don't tell be that someone relies on that behavior). However, I am quite skeptical that all strncpy's fill the remainder of the string with NULs; I have never heard of that. Seems to be precisely less than useless when coupled with the behavior that at least one NUL is not guaranteed.

Dennis Atkins
Wednesday, April 07, 2004

http://www.opengroup.org/onlinepubs/007908799/xsh/strncpy.html

"If the array pointed to by s2 is a string that is shorter than n bytes, null bytes are appended to the copy in the array pointed to by s1, until n bytes in all are written."

A small white object.
Wednesday, April 07, 2004

The filling up with NULs is mandated by ISO C.

I imagine the reason for strncpy not NULL terminating the destination buffer is a feature and not a bug. It allows you to copy arbitrary buffers (as long as you know their length) and not only null-terminated strings. I would think that a number of strncpy implementations use non-portable tricks to provide faster copying than the standard "while (*dst++=*src++)" idiom.

  -tim

a2800276
Thursday, April 08, 2004

Actually, what bugs me is, oracles pro*c precompiler changes strlcpy and strncpy to strcpy. In fact, it removes the line argument in the function too, so it must be aware of it removing this, so I have to run it through my post-oracles-precompiler , annoying.

fw
Thursday, April 08, 2004

What about the 'mem...' functions then?
memcpy, memmove?

Is there a site that possibly profiles all these 'string.h' functions in some comparison table?

sedwo
Thursday, April 08, 2004

strcpy has its uses. You just have to be very careful where and how you use it. Not every use is a possible buffer overflow. Worrying too much about it misses the point: the safe functions also have to be used carefully and correctly or you'll run into problems with them too.

Additionally, not every program written needs to be bulletproof secure. Sure, if you're writing something that's going to run as a service on some internet connected machine, you need to worry. If you're writing a quick 100 line hack that's only ever going to run on your own machine, there's no shame in using strcpy. It's the simplest function for copying C stryle strings from A to B!

I worry about the "silver bullet" idea that you can just use a safer function and never worry about buffer overruns. So long as you're using C or C++ or some other language with unchecked buffers, you always need to worry about buffer overruns. That's the nature of the beast.

Sum Dum Gai
Thursday, April 08, 2004

I would like to point out that those deprecated functions can be used safely, when string lengths are known, properly sized buffers are used, and the programmer takes pains to ensure that there is a terminating NULL.  It's a nuisance that the replacement functions make easier, but the business of calculating the length of strings to make sure you allocate a big enough buffer doesn't really go away.  They just make sure that you won't overflow and you will be NULL terminated.

Clay Dowling
Thursday, April 08, 2004

You can say "use it correctly" all you want, but using strcpy correctly basically results in you rewriting strncpy all ofer the place.

As for "quick one off" applications, those have a nasty tendency to grow dramatically get reused for years later.  Using strncpy takes about 10-20 seconds longer, and makes the code safer.  (Again, this is hardly sufficent to fix the problem, but it definately helps.)

As for C++, the problem there is that people are still treating it like C that has this funny "class" keyword.  Use exclusively string classes (std::string, etc) and you will take care of the issues.

Tito
Thursday, April 08, 2004

Nearly every C++ program in the real world has to deal with C libraries that expect C style strings. You can't just use std::string exclusively, so it's still a very real issue for C++ code.

As far as small programs becoming big programs, I guess it depends on your attitude. I'm a "cross that bridge when we come to it" style guy, I find that I'm more productive that way. Other people may be best served by doing more forward planning if that suits their style. For me though, I'll deal with the code being safe when it becomes production code, and not before, as I find it's a time consuming waste if you don't need it. I only bother up front if I KNOW it's going to be production code to start with.

Sum Dum Gai
Thursday, April 08, 2004

"oracles pro*c precompiler changes strlcpy and strncpy to strcpy"

Are you serious? So Oracle basically takes code you have carefully written to be secure and automatically inserts security holes into it? Sems this would have interesting liability issues...

Dennis Atkins
Thursday, April 08, 2004

<pedant>
Isn't NULL pointer sized and NUL character sized?
</pedant>

Dennis Atkins
Thursday, April 08, 2004

I understand clay's point but agree with Tito - strlcpy should be used with sizeof(bufername) when  fixed size buffer is involved. This is because buffer lengths have a tendency to get changed during maintenance, as do constant string lengths. Any 100 line program written by you today is a candidate for changes three years from now when the programmer who wrote it is not around and the code needs to be translated into Cherokee.

Dennis Atkins
Thursday, April 08, 2004

template <class T> T NULL() { return static_cast<T>(0); }


Thursday, April 08, 2004

Are you serious? Is that from a real C++ distribution? If that is really the official way to write 0 in C++ I am going to delete my C++ compiler and go live in the wilderness, husking cocoanuts.

Dennis Atkins
Thursday, April 08, 2004

That is definately not the "official" way to write NULL.  It's still #define'd to be 0.

There is a known issue regarding NULL vs 0 (zero) and when it is treated as a misc ptr and when it is treated as an integer type.  It is under discussion for the next meeting of the standards committe.
Reference the Stroustrup & Sutter reccomendation:
http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2004/n1601.pdf

As for C++ using alot of C string functions, that happens alot more in older code.  STL provides alot of functionality making relying on the C libraries unneccesary.  Of course there will always be existing code that uses it, but it is definately possible to write new code without using C style strings anywhere.  One of the big reasons that the old C style functions get used is that alot of people are already know those.

Tito
Friday, April 09, 2004

"For me though, I'll deal with the code being safe when it becomes production code, and not before, as I find it's a time consuming waste if you don't need it. I only bother up front if I KNOW it's going to be production code to start with. "

I can understand that attitude, but it is this idea that "I will retrofit security in later" that is the main cause of so many security problems today.

MikeMcNertney
Friday, April 09, 2004

*  Recent Topics

*  Fog Creek Home