6 ms·
For someone being so pedantic it is puzzling that he doesn't address the actual title of his post. No one claims that strncpy is 'safe' they just say 'safer', t
by angry_octet 11y ago
For someone being so pedantic it is puzzling that he doesn't address the actual title of his post. No one claims that strncpy is 'safe' they just say 'safer', that is, less likely than normal strcpy to have catastrophic bugs. And I think that claim stands up: make sure your n in strncpy is the length of your buffer, do a strncpy, write a null at the end of the buffer. Voila, all those strcpyies from unexpectedly large strings writing in your heap are gone. No need to constantly strlen source strings to check the length -- which in itself can cause a segfault if they are not null terminated.
So yes, it is safer. You would be mad not to use it.
- unwind 11y agoReplacing one function call with a function call to a function that does almost the right thing in many cases, but potentially wastes time by pointlessly zero-filling a buffer, and an extra assigment statement is not an improvement. You would be mad to do that.
- kazinator 11y agoStarting in C99, you can do this: snprintf(buffer, size, "%s", source); This can be put into a #define macro or inline function. If what you want is a null terminated, truncated copy that fits into a given buffer size, and snprintf is available, you are mad to still use strncpy. Also, strncpy pads the destination with nulls, if there is remaining space. Because of this, the evident purpose of strncpy is to fill fixed-width text fields in "old school" fixed-field database records. Writing the extra nulls is wasteful if the data type in question is nothing but a C string.
- jedbrown 11y agoWith fixed-width records, writing the extra nulls may be important for data privacy reasons and in any case, it allows comparison using memcpy(3), diff(1), and checksums.
- _kst_ 11y agoSure, but then you have to make sure that you always maintain the extra nulls. diff(1) doesn't seem relevant; it operates on text files, which normally don't contain any null characters.
- maxlybbert 11y agoThe article also suggests using strncat for this: dest[0] = '\0'; strncat(dest, src, size);.
- angry_octet 11y agoI think we can agree that strncpy is not perfect. Perhaps we can rank by levels of sanity? my_string_cpy() < strcpy < strncpy < strncat < snprintf < strlcat I dislike the strncat approach because if the prior null termination gets lost then problems ensue, whereas with snprintf that won't happen. The BSD man page mentions that snprintf may not be safe for use in signal handlers on some systems; obviously snprintf is a much bigger piece of code. Personally I dislike using extensive macros, but I'll leave that for the flame war.
- pedrow 11y agoIt's worth noting that, quite often when this subject comes up, people suggest a straight replacement with strncpy, strlcpy, snprintf, or something similiar. This is safer because it doesn't overwrite memory or cause a segfault, BUT, that's not always enough. If the code just carries on with the truncated string that's data loss and it might cause trouble later. For example imagine a system designed for 8.3 filenames - if you pass a long filename and it gets truncated it may then refer to a completely different file. The man page for strlcpy (IIRC) reminds you of this.
- deleted 11y ago[deleted]
- brucedawson 11y agoPeople keep on misusing strncpy which is why people keep blogging about it. I wrote about it two years ago after running across one too many abuses: https://randomascii.wordpress.com/2013/04/03/stop-using-strncpy-already/ https://randomascii.wordpress.com/2013/04/03/stop-using-strn... I tried to give alternatives. Calling strncpy and then manually null-terminating is not a good alternative. Creating a wrapper that does this is better. That wrapper could optionally abort the program on string truncation. And, probably more importantly, a template wrapper can infer the destination size, thus getting rid of the error-prone specification of the destination size (I have seen it specified incorrectly many times). You'd be mad to use strncpy when better alternatives are so easy to find or create.
- _kst_ 11y ago(I'm the author of the linked blog post.) strcpy() can be used safely if you ensure that the destination array is big enough to contain the source string. (Yes, that can be non-trivial.) strncpy() by itself doesn't write past the end of the destination array (assuming you call it correctly) -- but it can easily leave the destination without a terminating null character. This causes undefined behavior if you then pass the destination array to another string function. strncpy() is not dangerous by itself, but it can leave a booby-trap that causes other string functions to be dangerous. This: strncpy(dest, source, size); can be replaced by this: dest[0] = '\0'; strncat(dest, source, size); which will leave the destination properly null-terminated. Note that this can still quietly truncate the string. Ignoring that possibility is rarely the right thing to do.