Hacker News new | past | comments | ask | show | jobs | submit login

strncpy() is not a "safer" strcpy(). It can avoid some errors involving writing past the end of the target array (if you tell it the correct length for that array), but it's not a true string function, and it can leave the target unterminated and therefore not a valid string.

http://the-flat-trantor-society.blogspot.com/2012/03/no-strn...




This is true, and many people don't realize it. I used to call a wrapper function that would always set the last byte to 0.


I never could really understand the point of strncpy()... we always end up wrapping to deal with writing an unterminated string.

Was it intended for fixed length records?


It is for fixed length records, which is why it also zeroes the remaining space.


Arguably naming it with “str” is itself a security vulnerability.


No argument. At best it is a "string to fixed record" function, hence the name, but it is not a string function.


Yes. strncpy was intended for copying file names into a buffer that was only zero terminated when the name was shorter than the maximum length of a file name in Unix (14 bytes. See https://stackoverflow.com/a/1454071, https://devblogs.microsoft.com/oldnewthing/20050107-00/?p=36...)

You can also use it to overwrite part of an existing string, but I think that’s a side effect of the above.


Yes it was. On early Unix systems, each entry in a directory was bascially:

    struct dir
    {
      char name[14];
      int  inode;
    };
Adding a NUL byte might waste a full byte that could otherwise be used---remember, back when C was first developed, 10M disks were large and very expensive.


In the interest of satisfying pedantry I think we can agree that strncpy() is intended to be a safer strcpy() for a subset of uses.

As you say, it does in fact obviate some errors. A value judgement as to which behaviors are more or less safe may be subjective, but the intent is not.


strncpy was never intended to be a safer strcpy. It was created for a very specialized use case in the Unix kernel--copying a string-ish identifier to a fixed-size char field that only uses NUL termination if the identifier is shorter than the field size. Because of how the C language and the Unix kernel coevolved, it became part of the standard C library by default. I've seen it used for it's original semantics in only a handful of places, but in general it's almost always misused.

To be clear, strncpy does not guarantee NUL termination. It takes a C string as the source argument, but it doesn't write out a C string; it writes out a very esoteric data structure that is unfortunately easily confused with a C string.

By contrast, strlcpy was intended to be a safer string copy routine: https://www.usenix.org/legacy/event/usenix99/full_papers/mil... In particular, it was designed to be what people seem think strncpy is. Its return value semantics are controversial, though mostly only among the glibc crowd as every other Unix libc, including musl and Solaris, now provide it. But the semantics were designed based on experience in fixing old C code, and observations about how developers tend to write C code, not based on prescriptive theories about how people should manipulate C strings in C code.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: