diff --git a/progs/infocmp.c b/progs/infocmp.c
--- a/progs/infocmp.c
+++ b/progs/infocmp.c
@@ -1297,19 +1297,29 @@ static char *
 safe_name(const char *format, const char *prefix, const char *name)
 {
     static char *result;
     static size_t need;
+    size_t want;
     char *s;
 
-    if (result == NULL) {
-	need = (strlen(prefix)
-		+ strlen(name)
-		+ strlen(format));
-	result = (char *) malloc(need + 1);
+    /*
+     * Leave room for the optional "ti_" prefix, optional leading '_',
+     * the formatted name, and the trailing NUL.
+     */
+    want = strlen(prefix) + strlen(name) + strlen(format) + 5;
+    if (want > need) {
+	char *next = (char *) realloc(result, want);
+	if (next == NULL)
+	    failed("safe_name");
+	result = next;
+	need = want;
+    }
+    if (result == NULL) {
+	result = (char *) malloc(need);
 	if (result == NULL)
 	    failed("safe_name");
     }
 
     _nc_STRCPY(result, "", need);
@@ -1320,7 +1330,7 @@ safe_name(const char *format, const char *prefix, const char *name)
     *s = 0;
     if (isdigit(UChar(*name)) && !*prefix)
 	*s++ = '_';
-    _nc_SPRINTF(s, _nc_SLIMIT(need) format, name);
+    _nc_SPRINTF(s, _nc_SLIMIT(need - (size_t) (s - result)) format, name);
     return result;
 }
