What should I use instead of these things if they're so dangerous?
What should I use instead of these things if they're so dangerous?
strcpy -> strncpy (or strlcpy on BSD)
strcat -> strncat (or strlcat on BSD)
sprintf -> snprintf (but still watch out for printf format attacks)
gets -> something else entirely. The man page says "programs should NEVER use gets()".
They told me that... ˚sob˚ but they were wrong.
Programs (often) handle text. Apparently, that pretty much means you're fucked. So what is a reasonable way to write such programs?
Edited to add:
Apparently there is this: http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/cordh...
The problem isn't necessarily the functions themselves, it's coders who make assumptions that don't pan out to be true.
struct string {
char *str;
unsigned length;
} "%.*s"
or possibly even "%*.*s"
if you want it space padded. In principle you can bound your space usage and avoid an snprintf with such constructs; in practice, it's probably better to still use snprintf (if you're using standard-library string functions at all).This is useful for copying a string into a fixed size buffer that is sent over the network, to give an example. It's not what the programmer generally means when using strncpy.
Many programmers are surprised when they learn that strncpy() really writes 1M-strlen("abc") zeros in the 1M char array every time it's called...
This is false.
From the man page: "The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated."
And the following code prints foo:ar on my system.
char buffer[10];
strcpy(buffer, "foobar");
strcpy(buffer, "foo");
printf("%s:%s\n", buffer, buffer+4);
Edited to add: huh, scratch that. Obvious error in above test :-P. Testing it with strncat like I had meant to, it seems it is in fact padded, not just (possibly) terminated. Interesting, and very worth knowing if you are trying to move a probably small string to a large buffer under time pressure.Not sure what you want to say with the example code. Maybe swap it for strncpy and strlcpy and see whether that matches your expectations?
However, despite the n functions being generally safer, you're still propagating misinformation by touting them as secure alternatives.
The original use of the n functions was to manipulate strings in matters of fixed size arrays. If you don't know what you're doing and just blindly use strncpy() as a strcpy() replacement, you could end up truncating your strings.
OpenBSD's l functions, on the other hand, were specifically designed with security in mind.
* http://natashenka.ca/strcpy/
* http://natashenka.ca/strcat/
* http://natashenka.ca/sprintf/
The people who brought us the [in]famous "Why Pascal is not my favorite language" article would have done well to look at their own glass house.
OTOH, C does make a great portable assembler if you are using it to implement another language (which is exactly what we did at one of my jobs in the early 90s)
... Had to explain to my daughter this morning why I was laughing at the "abstinence" posters ...
For you younger people reading this who have never been exposed to pascel, go dig up that article and scroll down to section 2.1 and just think about that for a minute. Ask yourself 'is this the kind of computing environment I want to work in?'
2.4 - separate compilation was added in Turbo Pascal 4. (one could argue that the result is Modula, rather than Pascal - so be it)
2.2 - initialization of module data was added in Turbo Pascal 5. Yes, "static" data has to be at the module level instead of hidden within individual routines. Bug or feature? (let the jihad/crusade commence...)
As the commentary on http://c2.com/cgi/wiki?WhyPascalIsNotMyFavoriteProgrammingLa... points out, the critique was against the 1981 academic version of Pascal.
There are many, but here's one such example from last year: http://osvdb.org/show/osvdb/94336