The function strncpy() doesn\'t always null terminate so I want to know what is the best alternative that always null terminates?
I want a function that if:
As an illustration of having to use an alternative to strncpy(), consider Git 2.19 (Q3 2018) which finds that it is too easy to misuse system API functions such as strcat(); strncpy(); ... these selected functions are now forbidden in this codebase and will cause a compilation failure.
That patch does list several alternatives, which makes it relevant for this question.
See commit e488b7a, commit cc8fdae, commit 1b11b64 (24 Jul 2018), and commit c8af66a (26 Jul 2018) by Jeff King (peff).
(Merged by Junio C Hamano -- gitster -- in commit e28daf2, 15 Aug 2018)
banned.h: markstrncpy()as bannedThe
strncpy()function is less horrible thanstrcpy(), but is still pretty easy to misuse because of its funny termination semantics.
Namely, that if it truncates it omits the NUL terminator, and you must remember to add it yourself. Even if you use it correctly, it's sometimes hard for a reader to verify this without hunting through the code.
If you're thinking about using it, consider instead:
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 fitstrbuforxstrfmt()if you need to handle arbitrary-length heap-allocated strings.Note that there is one instance of
strncpyincompat/regex/regcomp.c, which is fine (it allocates a sufficiently large string before copying).
But this doesn't trigger the ban-list even when compiling withNO_REGEX=1, because:
- we don't use git-compat-util.h when compiling it (instead we rely on the system includes from the upstream library); and
- It's in an "
#ifdef DEBUG" blockSince it's doesn't trigger the
banned.hcode, we're better off leaving it to keep our divergence from upstream minimal.
Note: 1+ year later, with Git 2.21 (Q1 2019), the "strncat()" function itself is now also among the banned functions.
See commit ace5707 (02 Jan 2019) by Eric Wong (ele828).
(Merged by Junio C Hamano -- gitster -- in commit 81bf66b, 18 Jan 2019)
banned.h: markstrncat()as banned
strncat()has the same quadratic behavior asstrcat()and is difficult-to-read and bug-prone. While it hasn't yet been a problem in Git iself,strncat()found it's way into 'master' ofcgitand caused segfaults on my system.
With Git 2.24 (Q4 2019), it uses the explicit form of 'vsprintf' as the banned version of itself, not 'sprintf'.
See commit 60d198d (25 Aug 2019) by Taylor Blau (ttaylorr).
(Merged by Junio C Hamano -- gitster -- in commit 37801f0, 30 Sep 2019)