diff --git a/src/d_iwad.c b/src/d_iwad.c
index 5bf8c5e9d..781ad6672 100644
--- a/src/d_iwad.c
+++ b/src/d_iwad.c
@@ -754,8 +754,7 @@ char *D_FindIWADFile(void)
 
         char *iwadfile = myargv[iwadparm + 1];
 
-        char *file = malloc(strlen(iwadfile) + 5);
-        AddDefaultExtension(strcpy(file, iwadfile), ".wad");
+        char *file = AddDefaultExtension(iwadfile, ".wad");
 
         result = D_FindWADByName(file);
 
diff --git a/src/d_main.c b/src/d_main.c
index 619147a5e..643882971 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -973,8 +973,7 @@ void FindResponseFile (void)
         // READ THE RESPONSE FILE INTO MEMORY
 
         // killough 10/98: add default .rsp extension
-        char *filename = malloc(strlen(myargv[i])+5);
-        AddDefaultExtension(strcpy(filename,&myargv[i][1]),".rsp");
+        char *filename = AddDefaultExtension(&myargv[i][1],".rsp");
 
         handle = M_fopen(filename,"rb");
         if (!handle)
@@ -1336,14 +1335,15 @@ static void D_ProcessDehCommandLine(void)
           if (deh)
             {
               char *probe;
-              char *file = malloc(strlen(myargv[p]) + 5);      // killough
-              AddDefaultExtension(strcpy(file, myargv[p]), ".bex");
+              char *file = AddDefaultExtension(myargv[p], ".bex");
               probe = D_TryFindWADByName(file);
+              free(file);
               if (M_access(probe, F_OK))  // nope
                 {
                   free(probe);
-                  AddDefaultExtension(strcpy(file, myargv[p]), ".deh");
+                  file = AddDefaultExtension(myargv[p], ".deh");
                   probe = D_TryFindWADByName(file);
+                  free(file);
                   if (M_access(probe, F_OK))  // still nope
                   {
                     free(probe);
@@ -1355,7 +1355,6 @@ static void D_ProcessDehCommandLine(void)
               // (apparently, this was never removed after Boom beta-killough)
               ProcessDehFile(probe, D_dehout(), 0);  // killough 10/98
               free(probe);
-              free(file);
             }
     }
   // ty 03/09/98 end of do dehacked stuff
diff --git a/src/g_game.c b/src/g_game.c
index 72e8bccbe..4ab793158 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -3981,9 +3981,13 @@ void G_RecordDemo(char *name)
   demo_insurance = 0;
       
   usergame = false;
-  demoname_size = strlen(name) + 5 + 6; // [crispy] + 6 for "-00000"
+  if (demoname)
+  {
+    free(demoname);
+  }
+  demoname = AddDefaultExtension(name, ".lmp");  // 1/18/98 killough
+  demoname_size = strlen(demoname) + 6; // [crispy] + 6 for "-00000"
   demoname = I_Realloc(demoname, demoname_size);
-  AddDefaultExtension(strcpy(demoname, name), ".lmp");  // 1/18/98 killough
 
   for(; j <= 99999 && !M_access(demoname, F_OK); ++j)
   {
diff --git a/src/m_misc.c b/src/m_misc.c
index ce2bdde14..2af9fa42c 100644
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -562,30 +562,19 @@ void M_CopyLumpName(char *dest, const char *src)
 
 //
 // 1/18/98 killough: adds a default extension to a path
-// Note: Backslashes are treated specially, for MS-DOS.
 //
 
-char *AddDefaultExtension(char *path, const char *ext)
+char *AddDefaultExtension(const char *path, const char *ext)
 {
-    char *p = path;
-
-    while (*p++)
-        ;
-
-    while (p-- > path && *p != '/' && *p != '\\')
+    if (strrchr(M_BaseName(path), '.') != NULL)
     {
-        if (*p == '.')
-        {
-            return path;
-        }
+        // path already has an extension
+        return M_StringDuplicate(path);
     }
-
-    if (*ext != '.')
+    else
     {
-        strcat(path, ".");
+        return M_StringJoin(path, ext);
     }
-
-    return strcat(path, ext);
 }
 
 //
diff --git a/src/m_misc.h b/src/m_misc.h
index a0e02a474..e8a948433 100644
--- a/src/m_misc.h
+++ b/src/m_misc.h
@@ -56,7 +56,7 @@ int M_vsnprintf(char *buf, size_t buf_len, const char *s, va_list args)
 int M_snprintf(char *buf, size_t buf_len, const char *s, ...) PRINTF_ATTR(3, 4);
 
 void M_CopyLumpName(char *dest, const char *src);
-char *AddDefaultExtension(char *path, const char *ext);
+char *AddDefaultExtension(const char *path, const char *ext);
 boolean M_WriteFile(const char *name, void *source, int length);
 int M_ReadFile(const char *name, byte **buffer);
 boolean M_StringToDigest(const char *string, byte *digest, int size);
diff --git a/src/r_data.c b/src/r_data.c
index 183c91051..1570548cb 100644
--- a/src/r_data.c
+++ b/src/r_data.c
@@ -1055,9 +1055,7 @@ void R_InitTranMap(int progress)
   int p = M_CheckParmWithArgs("-dumptranmap", 1);
   if (p > 0)
   {
-      char *path = malloc(strlen(myargv[p + 1]) + 5);
-      strcpy(path, myargv[p + 1]);
-      AddDefaultExtension(path, ".lmp");
+      char *path = AddDefaultExtension(myargv[p + 1], ".lmp");
 
       M_WriteFile(path, main_tranmap, 256 * 256);