ref: 9d01d090c48c74a29b4ef67e0cd204772a2193c3
parent: b42b5269e0ad5b22acd6043429ec4013a4e76ddd
author: Simon Howard <fraggle@gmail.com>
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.