3 ms·
The information in the strncpy() / strncat() section is incorrect. Firstly, strncpy() was not designed to be a "safer strcpy()" at all. It was designed for st
by caf 15y ago
The information in the strncpy() / strncat() section is incorrect.
Firstly, strncpy() was not designed to be a "safer strcpy()" at all. It was designed for storing strings in the manner of original UNIX directory entries: in a fixed size buffer, null-padded only if the stored string is shorter than the buffer. This is why it fills the buffer with nulls, and why it doesn't necessarily null-terminate the destination.
Secondly, contrary to what the article implies, strncat() does not work this way: strncat() always null-terminates the destination, and it doesn't write any extra nulls.
- byuu 15y agoThanks, I will make the necessary corrections shortly. The strncat() behavior is quite confusing. I can understand expecting the buffer to already be null-padded and skipping that step, but always null-terminating the result seems to go against strncpy()'s expected behavior. It also looks mildly dangerous, as the NUL-write can be one after the size given.
- caf 15y agoIt's not confusing when you realise that strncat() is not a concatenating analogue of strncpy(). It's just a version of strcat() that accepts an upper bound on the number of characters copied.
- acqq 15y agoExactly: old Unix directory filename entries were, at least at some time, exactly 1 to 14 characters long. http://computing.fnal.gov/unixatfermilab/html/filesys.html http://computing.fnal.gov/unixatfermilab/html/filesys.html Having the size so fixed, storing the 15th character that would always be null on the disks (and also in memory) was a pure waste. Note that earliest versions of Unix run in less than 64 KB. When copying the name to a fixed buffer of 14 characters which is to be stored on the disk, padding the buffer with nulls was also not a performance issue and had a benefit of not leaving "junk" in the buffer. The problems only happen when people expect from such routines with very specific usage scenarios something for which they were not designed. So the strncpy was never meant to be "a safer veriant for strcpy." Moreover, strcpy_s is also not a replacement for strncpy, but for a strcpy -- it was introduced to be replaced instead of strcpy in the old code bases as a part of reducing the number of security issues in the old code. Of course there is (in Microsoft's CRT) strncpy_s, the rationale behind all _s functions is here: http://msdn.microsoft.com/en-us/library/8ef0s5kh(v=vs.80).aspx http://msdn.microsoft.com/en-us/library/8ef0s5kh(v=vs.80).as... "Sized Buffers. The secure functions require that the buffer size be passed to any function that writes to a buffer. The secure versions validate that the buffer is large enough before writing to it, helping to avoid dangerous buffer overrun errors that could allow malicious code to execute. These functions usually return an errno type of error code and invoke the invalid parameter handler if the size of the buffer is too small. Functions that read from input buffers, such as gets, have secure versions that require you to specify a maximum size. (...) Null termination. Some functions that left potentially non-terminated strings have secure versions which ensure that strings are properly null terminated." The article is based on the wrong premises. Advice: if you work low level with substrings and concatenations, where the performance matters, don't try to fix the str routines, use the pointers. Maintain the pointer to the last character of the area to which you concatenate. Traverse only the characters you need from the source. If you don't care about the performance or exact storage aspects, use much higher level approaches, some string libraries.