shithub: choc

Download patch

ref: 9d01d090c48c74a29b4ef67e0cd204772a2193c3
parent: b42b5269e0ad5b22acd6043429ec4013a4e76ddd
author: Simon Howard <[email protected]>
date: Fri Oct 24 16:29:56 EDT 2014

Replace strdup() with M_StringDuplicate().

strdup() can theoretically fail and return NULL. This could lead to
a crash or undesirable behavior. Add M_StringDuplicate() which does
the same thing but exits with an error if a string cannot be
allocated.

This fixes #456. Thanks to Quasar for the suggestion.

--- a/HACKING
+++ b/HACKING
@@ -130,6 +130,7 @@
     strncpy()             M_StringCopy()
     strcat()              M_StringConcat()
     strncat()             M_StringConcat()
+    strdup()              M_StringDuplicate()
 
 Lots of the code includes calls to DEH_String() to simulate string
 replacement by the Dehacked tool. Be careful when using Dehacked
--- a/src/d_iwad.c
+++ b/src/d_iwad.c
@@ -413,7 +413,7 @@
 
     if (DirIsFile(dir, iwadname) && M_FileExists(dir))
     {
-        return strdup(dir);
+        return M_StringDuplicate(dir);
     }
 
     // Construct the full path to the IWAD if it is located in
@@ -421,7 +421,7 @@
 
     if (!strcmp(dir, "."))
     {
-        filename = strdup(iwadname);
+        filename = M_StringDuplicate(iwadname);
     }
     else
     {
@@ -523,7 +523,7 @@
         return;
     }
 
-    doomwadpath = strdup(doomwadpath);
+    doomwadpath = M_StringDuplicate(doomwadpath);
 
     // Add the initial directory
 
@@ -640,7 +640,7 @@
 
         if (DirIsFile(iwad_dirs[i], name) && M_FileExists(iwad_dirs[i]))
         {
-            return strdup(iwad_dirs[i]);
+            return M_StringDuplicate(iwad_dirs[i]);
         }
 
         // Construct a string for the full path
--- a/src/deh_io.c
+++ b/src/deh_io.c
@@ -97,7 +97,7 @@
 
     context->type = DEH_INPUT_FILE;
     context->stream = fstream;
-    context->filename = strdup(filename);
+    context->filename = M_StringDuplicate(filename);
 
     return context;
 }
--- a/src/doom/d_main.c
+++ b/src/doom/d_main.c
@@ -1123,7 +1123,7 @@
         }
         else
         {
-            chex_deh = strdup("chex.deh");
+            chex_deh = M_StringDuplicate("chex.deh");
         }
 
         // If the dehacked patch isn't found, try searching the WAD
--- a/src/gusconf.c
+++ b/src/gusconf.c
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <ctype.h>
 
+#include "m_misc.h"
 #include "w_wad.h"
 #include "z_zone.h"
 
@@ -122,7 +123,7 @@
     mapped_id = atoi(fields[MappingIndex()]);
 
     free(config->patch_names[instr_id]);
-    config->patch_names[instr_id] = strdup(fields[5]);
+    config->patch_names[instr_id] = M_StringDuplicate(fields[5]);
     config->mapping[instr_id] = mapped_id;
 }
 
--- a/src/heretic/g_game.c
+++ b/src/heretic/g_game.c
@@ -1429,7 +1429,7 @@
 
 void G_LoadGame(char *name)
 {
-    savename = strdup(name);
+    savename = M_StringDuplicate(name);
     gameaction = ga_loadgame;
 }
 
--- a/src/i_sdlmusic.c
+++ b/src/i_sdlmusic.c
@@ -498,7 +498,7 @@
     // so just return it.
     if (path[0] == DIR_SEPARATOR)
     {
-        return strdup(path);
+        return M_StringDuplicate(path);
     }
 
 #ifdef _WIN32
@@ -505,7 +505,7 @@
     // d:\path\...
     if (isalpha(path[0]) && path[1] == ':' && path[2] == DIR_SEPARATOR)
     {
-        return strdup(path);
+        return M_StringDuplicate(path);
     }
 #endif
 
@@ -516,7 +516,7 @@
 
     // Copy config filename and cut off the filename to just get the
     // parent dir.
-    basedir = strdup(base_filename);
+    basedir = M_StringDuplicate(base_filename);
     p = strrchr(basedir, DIR_SEPARATOR);
     if (p != NULL)
     {
@@ -525,7 +525,7 @@
     }
     else
     {
-        result = strdup(path);
+        result = M_StringDuplicate(path);
     }
     free(basedir);
     free(path);
@@ -672,7 +672,7 @@
 
     if (!strcmp(configdir, ""))
     {
-        musicdir = strdup("");
+        musicdir = M_StringDuplicate("");
     }
     else
     {
@@ -805,7 +805,7 @@
     p = strrchr(timidity_cfg_path, DIR_SEPARATOR);
     if (p != NULL)
     {
-        path = strdup(timidity_cfg_path);
+        path = M_StringDuplicate(timidity_cfg_path);
         path[p - timidity_cfg_path] = '\0';
         fprintf(fstream, "dir %s\n", path);
         free(path);
--- a/src/m_config.c
+++ b/src/m_config.c
@@ -1732,7 +1732,7 @@
     switch (def->type)
     {
         case DEFAULT_STRING:
-            * (char **) def->location = strdup(value);
+            * (char **) def->location = M_StringDuplicate(value);
             break;
 
         case DEFAULT_INT:
@@ -2062,7 +2062,7 @@
     else
 #endif /* #ifndef _WIN32 */
     {
-        return strdup("");
+        return M_StringDuplicate("");
     }
 }
 
@@ -2111,7 +2111,7 @@
 
     if (!strcmp(configdir, ""))
     {
-	savegamedir = strdup("");
+	savegamedir = M_StringDuplicate("");
     }
     else
     {
--- a/src/m_misc.c
+++ b/src/m_misc.c
@@ -285,6 +285,26 @@
 }
 
 //
+// Safe version of strdup() that checks the string was successfully
+// allocated.
+//
+
+char *M_StringDuplicate(const char *orig)
+{
+    char *result;
+
+    result = strdup(orig);
+
+    if (result == NULL)
+    {
+        I_Error("Failed to duplicate string (length %i)\n",
+                strlen(orig));
+    }
+
+    return result;
+}
+
+//
 // String replace function.
 //
 
--- a/src/m_misc.h
+++ b/src/m_misc.h
@@ -35,6 +35,7 @@
 void M_ExtractFileBase(char *path, char *dest);
 void M_ForceUppercase(char *text);
 char *M_StrCaseStr(char *haystack, char *needle);
+char *M_StringDuplicate(const char *orig);
 boolean M_StringCopy(char *dest, const char *src, size_t dest_size);
 boolean M_StringConcat(char *dest, const char *src, size_t dest_size);
 char *M_StringReplace(const char *haystack, const char *needle,
--- a/src/net_query.c
+++ b/src/net_query.c
@@ -22,6 +22,7 @@
 
 #include "i_system.h"
 #include "i_timer.h"
+#include "m_misc.h"
 
 #include "net_common.h"
 #include "net_defs.h"
@@ -900,7 +901,7 @@
 
             if (signature != NULL)
             {
-                securedemo_start_message = strdup(signature);
+                securedemo_start_message = M_StringDuplicate(signature);
                 result = true;
             }
         }
--- a/src/net_sdl.c
+++ b/src/net_sdl.c
@@ -325,7 +325,7 @@
 
     if (colon != NULL)
     {
-	addr_hostname = strdup(address);
+	addr_hostname = M_StringDuplicate(address);
 	addr_hostname[colon - address] = '\0';
 	addr_port = atoi(colon + 1);
     }
--- a/src/net_server.c
+++ b/src/net_server.c
@@ -563,7 +563,7 @@
     NET_Conn_InitServer(&client->connection, addr);
     client->addr = addr;
     client->last_send_time = -1;
-    client->name = strdup(player_name);
+    client->name = M_StringDuplicate(player_name);
 
     // init the ticcmd send queue
 
--- a/src/setup/execute.c
+++ b/src/setup/execute.c
@@ -268,7 +268,7 @@
 
     if (sep == NULL)
     {
-        result = strdup(program);
+        result = M_StringDuplicate(program);
     }
     else
     {
--- a/src/setup/multiplayer.c
+++ b/src/setup/multiplayer.c
@@ -856,7 +856,7 @@
     // Set address to connect to:
 
     free(connect_address);
-    connect_address = strdup(button->label);
+    connect_address = M_StringDuplicate(button->label);
 
     // Auto-choose IWAD if there is already a player connected.
 
@@ -1044,7 +1044,7 @@
     {
         if (chat_macros[i] == NULL)
         {
-            chat_macros[i] = strdup(defaults[i]);
+            chat_macros[i] = M_StringDuplicate(defaults[i]);
         }
     }
 }
@@ -1053,12 +1053,12 @@
 {
     if (net_player_name == NULL)
     {
-        net_player_name = strdup(getenv("USER"));
+        net_player_name = M_StringDuplicate(getenv("USER"));
     }
 
     if (net_player_name == NULL)
     {
-        net_player_name = strdup(getenv("USERNAME"));
+        net_player_name = M_StringDuplicate(getenv("USERNAME"));
     }
 
     // On Windows, environment variables are in OEM codepage
@@ -1073,7 +1073,7 @@
 
     if (net_player_name == NULL)
     {
-        net_player_name = strdup("player");
+        net_player_name = M_StringDuplicate("player");
     }
 }
 
--- a/src/setup/sound.c
+++ b/src/setup/sound.c
@@ -20,6 +20,7 @@
 
 #include "textscreen.h"
 #include "m_config.h"
+#include "m_misc.h"
 
 #include "mode.h"
 #include "sound.h"
@@ -324,8 +325,8 @@
         M_BindVariable("show_talk",       &show_talk);
     }
 
-    timidity_cfg_path = strdup("");
-    gus_patch_path = strdup("");
+    timidity_cfg_path = M_StringDuplicate("");
+    gus_patch_path = M_StringDuplicate("");
 
     // Default sound volumes - different games use different values.