[m-rev.] for review: Fix incorrect uses of strncat.

Peter Wang novalazy at gmail.com
Thu Apr 24 17:18:17 AEST 2025


Fix incorrect uses of strncat.

The size argument to strncat() gives the number of characters to copy
from the input string, *not* the size of the destination buffer.

runtime/mercury_deep_profiling.c:
    Add a safe string concatenation function, safecat.

    Use safecat instead of strncat.

diff --git a/runtime/mercury_deep_profiling.c b/runtime/mercury_deep_profiling.c
index 75a3b1e41..c71e7a111 100644
--- a/runtime/mercury_deep_profiling.c
+++ b/runtime/mercury_deep_profiling.c
@@ -374,6 +374,27 @@ static  FILE        *debug_fp;
 
 #define MR_FILENAME_BUF_LEN     1024
 
+// Append the string pointed to by src into the buffer pointed to by dst.
+// sz is the size of the destination buffer. If there is not enough space in
+// the destination buffer, the source string will be truncated to fit,
+// and the destination string will be null-terminated.
+//
+// Returns 0 on success, or -1 if there was insufficient space.
+static int
+safecat(char dst[], size_t sz, const char *src)
+{
+    size_t dst_len = strnlen(dst, sz);
+    if (dst_len >= sz)
+        return -1;
+
+    size_t rem = sz - dst_len - 1;
+    size_t src_len = strlen(src);
+    size_t to_copy = (src_len < rem) ? src_len : rem;
+    memcpy(dst + dst_len, src, to_copy);
+    dst[dst_len + to_copy] = '\0';
+    return 0;
+}
+
 void
 MR_write_out_profiling_tree(void)
 {
@@ -425,13 +446,13 @@ MR_write_out_profiling_tree(void)
                     "_on_%04d-%02d-%02d_at_%02d-%02d-%02d",
                     tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
                     tm->tm_hour, tm->tm_min, tm->tm_sec);
-                strncat(data_filename, date_name, MR_FILENAME_BUF_LEN);
-                strncat(procrep_filename, date_name, MR_FILENAME_BUF_LEN);
+                safecat(data_filename, MR_FILENAME_BUF_LEN, date_name);
+                safecat(procrep_filename, MR_FILENAME_BUF_LEN, date_name);
             }
         }
 
-        strncat(data_filename, ".data", MR_FILENAME_BUF_LEN);
-        strncat(procrep_filename, ".procrep", MR_FILENAME_BUF_LEN);
+        safecat(data_filename, MR_FILENAME_BUF_LEN, ".data");
+        safecat(procrep_filename, MR_FILENAME_BUF_LEN, ".procrep");
     }
 
     #if defined(MR_WIN32) && !defined(MR_CYGWIN)
-- 
2.49.0



More information about the reviews mailing list