fix(util): correct off-by-one OOB write in strncopy() when src fills buffer (#448)

Fixes #447

When \`strlen(src) >= obuf\`, the old code set \`len = obuf\` then wrote
\`dst[obuf] = '\0'\` one byte past the end of the buffer. A
\`-Wstringop-overflow\` pragma was suppressing the compiler warning.

Fix: cap copy length at \`obuf - 1\` so the NUL terminator always fits
within the buffer. Remove the pragma so the compiler can flag similar
patterns in future. Add an \`obuf == 0\` guard for the degenerate case.

Rename \`len\` to \`src_len\` for clarity -- the value is the source
length being copied, not a generic counter.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: netniV <netniv@hotmail.com>
This commit is contained in:
Thomas VincentandnetniV authored and GitHub committed 2026-03-11 20:48:53 +00:00
1 parent b61b1423df
commit 80d6763344
2 files changed
+11 -10

No files matched your search

+10 -10
View File
@@ -1691,25 +1691,25 @@ char *add_slashes(char *string) {
* \return pointer to destination string
*
*/
#pragma GCC diagnostic push
#if (defined(__GNUC__) && (__GNUC__ > 7)) || (__GNUC__ == 7 && defined(__GNUC_MINOR__) && __GNUC_MINOR__ > 1)
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
char *strncopy(char *dst, const char *src, size_t obuf) {
size_t len;
size_t copy_len;
assert(dst != 0);
assert(src != 0);
len = (strlen(src) < obuf) ? strlen(src) : obuf;
if (len) {
strncpy(dst, src, len);
if (obuf == 0) return dst;
/* Cap the scan at obuf-1: no need to walk past the usable copy capacity,
* and avoids a full strlen when src is large or unterminated near obuf. */
copy_len = strnlen(src, obuf - 1);
if (copy_len) {
strncpy(dst, src, copy_len);
}
dst[len] = '\0';
dst[copy_len] = '\0';
return dst;
}
#pragma GCC diagnostic pop
/*! \fn double get_time_as_double()
* \brief fetches system time as a double-precision value