4 ms·
I wonder how they copy strings with strcpy and strncpy both banned. strlcpy? But it is not conforming to major standards. Or just memcpy with extra code?
by attractivechaos 6y ago
I wonder how they copy strings with strcpy and strncpy both banned. strlcpy? But it is not conforming to major standards. Or just memcpy with extra code?
- dgentile 6y agoEdited: Looks like they have safe alternatives: " - strlcpy() if you really just need a truncated but NUL-terminated string (we provide a compat version, so it's always available) - xsnprintf() if you're sure that what you're copying should fit - strbuf or xstrfmt() if you need to handle arbitrary-length heap-allocated strings "
- lights0123 6y agohttps://github.com/git/git/commit/e488b7aba743d23b830d239dcc33d9ca0745a9ad https://github.com/git/git/commit/e488b7aba743d23b830d239dcc... Yes: > we provide a compat version, so it's always available
- deleted 6y ago[deleted]
- attractivechaos 6y agoThis gets me interested. Link [1] below shows their implementation of strlcpy(). This is a questionable implementation. With strncpy, the source string "src" may not be NULL terminated IIRC. The git implementation requires "src" to be NULL terminated. If not, an invalid read. EDIT: according to the strlcpy manpage [2], "src" is required to be NULL terminated, so strlcpy imposes more restrictions and is not a proper replacement of strncpy. Furthermore, imagine "src" has 1Mb characters but we only want to copy the first 3 chars. The git implementation would traverse the entire 1Mb to find the length first, but a proper implementation only needs to look at the first 3 chars. So, they banned strncpy and provided a worse solution to that. [1]: https://github.com/git/git/blob/master/compat/strlcpy.c https://github.com/git/git/blob/master/compat/strlcpy.c [2]: https://linux.die.net/man/3/strlcpy https://linux.die.net/man/3/strlcpy
- kzrdude 6y agoYou have found the answer - strlcpy is not a replacement for strncpy at all (it's arguably a safer version of strcpy), and git people didn't invent this, it's the existing BSD strlcpy interface.
- attractivechaos 6y agoThanks for the confirmation. But my concern remains: they banned strncpy without a proper replacement. In addition, I didn't know the extra restriction of strlcpy until today (I have never used it before because it is not conforming to C99/POSIX). I might have fallen into this trap.
- notaplumber 6y agoThe problem is the actually often the opposite, in the real world many treat strncpy as if it behaves like strlcpy. Note that strlcpy is equivalent to: snprintf(buf, sizeof(buf), "%s", string); strlcpy is on track for future standardization in POSIX, for Issue 8, but even as a de facto standard, it exists in libc on *BSD, macOS, Android, Solaris, QNX, and even Linux using musl. https://www.austingroupbugs.net/view.php?id=986#c5050 https://www.austingroupbugs.net/view.php?id=986#c5050 But you're correct in that it is not a replacement for strncpy because no code should be using strncpy.
- tedunangst 6y agoTake a step back and consider strlcpy isn't supposed to be a drop in replacement for strncpy (a function which already exists).
- alcover 6y agoAgreed. It's O(n) inefficient. I guess looping though chars up to `size` would perform better on average. I see this `strlcpy` recommanded everywhere.
- attractivechaos 6y ago
- deleted 6y ago[deleted]
- jabl 6y agomemccpy? Most platforms have it, and it's being added to C2X. See https://developers.redhat.com/blog/2019/08/12/efficient-string-copying-and-concatenation-in-c/ https://developers.redhat.com/blog/2019/08/12/efficient-stri...
- syncsynchalt 6y agostrncpy is a dangerous function because it doesn't nul terminate on overflow. The danger is that it's named misleadingly (str* functions otherwise always work in nul-terminated strings). (strcpy is just banned because there's no bounds check, and they want to force use of strlcpy instead).
- loeg 6y agostrncpy also has the dubious behavior of zero-filling out to N even if strlen(src) is much shorter than N.