From ffd5385d1510e7da8a5479700aec54ac21339f80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net>
Date: Fri, 22 Mar 2024 14:37:35 -0400
Subject: [PATCH] Use strlcpy() for X?SAFECOPY() macros.

Also, for DEBUG builds, add a static assertion that
sizeof(dst) != sizeof(void*) to catch the most common breakage.
---
 src/xpdev/gen_defs.h | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/xpdev/gen_defs.h b/src/xpdev/gen_defs.h
index 9582e1dacd..d49f4f73ff 100644
--- a/src/xpdev/gen_defs.h
+++ b/src/xpdev/gen_defs.h
@@ -23,6 +23,9 @@
 #define _GEN_DEFS_H
 
 #include "cp437defs.h"
+#ifdef _DEBUG
+#include <assert.h>
+#endif
 #include <errno.h>
 
 /* Resolve multi-named errno constants */
@@ -427,9 +430,24 @@ typedef struct {
 #define TERMINATE(str)                      str[sizeof(str)-1]=0
 
 /* This is a bound-safe version of strcpy basically - only works with fixed-length arrays */
+#ifdef _DEBUG
+#define SAFECOPY(dst,src) do { \
+	_Static_assert(sizeof(dst) != sizeof(void*), "SAFECOPY() on pointer-sized dst, use strlcpy"); \
+	strlcpy(dst,src,sizeof(dst)); \
+} while(0)
+#else
 #define SAFECOPY(dst,src)                   strlcpy(dst,src,sizeof(dst))
+#endif
+
 /* Extra-safe SAFECOPY doesn't pass NULL-pointer to strncpy */
-#define XSAFECOPY(dst,src)                  strlcpy(dst,(src)==NULL?"(null)":(src),sizeof(dst))
+#ifdef _DEBUG
+#define XSAFECOPY(dst,src) do { \
+	_Static_assert(sizeof(dst) != sizeof(void*), "SAFECOPY() on pointer-sized dst, use strlcpy"); \
+	strlcpy(dst,(src)==NULL?"(null)":(src),sizeof(dst)); \
+} while(0)
+#else
+#define XSAFECOPY(dst,src) strlcpy(dst,(src)==NULL?"(null)":(src),sizeof(dst))
+#endif
 
 #define SAFECAT(dst, src) do { \
 	if(strlen((char*)(dst)) + strlen((char*)(src)) < sizeof(dst)) { \
-- 
GitLab