From 53e10c709821b684ae5891640074ac9a10734dbd Mon Sep 17 00:00:00 2001 From: Ozkan Sezer Date: Sat, 26 Apr 2014 07:50:54 +0000 Subject: [PATCH] Avoid using COM_DefaultExtension() whenever possible: it may lead to unpredictable results. Use a new procedure COM_AddExtension() which appends the given extension to the path if the one it has, if any, doesn't match. In Host_Game_f(), reject "." as the path. git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@902 af15c1b1-3010-417e-b628-4374ebc0bcbd --- Quake/cl_demo.c | 4 ++-- Quake/common.c | 31 ++++++++++++++++++++----------- Quake/common.h | 1 + Quake/console.c | 2 +- Quake/host_cmd.c | 12 +++++++----- 5 files changed, 31 insertions(+), 19 deletions(-) diff --git a/Quake/cl_demo.c b/Quake/cl_demo.c index 2a546a23..8fe8b262 100644 --- a/Quake/cl_demo.c +++ b/Quake/cl_demo.c @@ -283,7 +283,7 @@ void CL_Record_f (void) } // open the demo file - COM_DefaultExtension (name, ".dem", sizeof(name)); + COM_AddExtension (name, ".dem", sizeof(name)); Con_Printf ("recording to %s.\n", name); cls.demofile = fopen (name, "wb"); @@ -398,7 +398,7 @@ void CL_PlayDemo_f (void) // open the demo file q_strlcpy (name, Cmd_Argv(1), sizeof(name)); - COM_DefaultExtension (name, ".dem", sizeof(name)); + COM_AddExtension (name, ".dem", sizeof(name)); Con_Printf ("Playing demo from %s.\n", name); diff --git a/Quake/common.c b/Quake/common.c index 321b35a5..366669e9 100644 --- a/Quake/common.c +++ b/Quake/common.c @@ -1052,31 +1052,40 @@ void COM_FileBase (const char *in, char *out, size_t outsize) /* ================== COM_DefaultExtension +if path doesn't have a .EXT, append extension +(extension should include the leading ".") ================== */ void COM_DefaultExtension (char *path, const char *extension, size_t len) { char *src; - size_t l; -// -// if path doesn't have a .EXT, append extension -// (extension should include the .) -// - if (!*path) - return; - l = strlen(path); - src = path + l - 1; - while (*src != '/' && src != path) + if (!*path) return; + src = path + strlen(path) - 1; + + while (*src != '/' && *src != '\\' && src != path) { if (*src == '.') - return; // it has an extension + return; // it has an extension src--; } q_strlcat(path, extension, len); } +/* +================== +COM_AddExtension +if path extension doesn't match .EXT, append it +(extension should include the leading ".") +================== +*/ +void COM_AddExtension (char *path, const char *extension, size_t len) +{ + if (strcmp(COM_FileGetExtension(path), extension + 1) != 0) + q_strlcat(path, extension, len); +} + /* ============== diff --git a/Quake/common.h b/Quake/common.h index 4cfc36d3..35464bfb 100644 --- a/Quake/common.h +++ b/Quake/common.h @@ -179,6 +179,7 @@ void COM_InitFilesystem (void); const char *COM_SkipPath (const char *pathname); void COM_StripExtension (const char *in, char *out, size_t outsize); void COM_FileBase (const char *in, char *out, size_t outsize); +void COM_AddExtension (char *path, const char *extension, size_t len); void COM_DefaultExtension (char *path, const char *extension, size_t len); const char *COM_FileGetExtension (const char *in); /* doesn't return NULL */ void COM_ExtractExtension (const char *in, char *out, size_t outsize); diff --git a/Quake/console.c b/Quake/console.c index 4e663558..c730633f 100644 --- a/Quake/console.c +++ b/Quake/console.c @@ -174,7 +174,7 @@ static void Con_Dump_f (void) return; } q_snprintf (name, sizeof(name), "%s/%s", com_gamedir, Cmd_Argv(1)); - COM_DefaultExtension (name, ".txt", sizeof(name)); + COM_AddExtension (name, ".txt", sizeof(name)); } else q_snprintf (name, sizeof(name), "%s/condump.txt", com_gamedir); diff --git a/Quake/host_cmd.c b/Quake/host_cmd.c index 03e54a49..7a011128 100644 --- a/Quake/host_cmd.c +++ b/Quake/host_cmd.c @@ -136,19 +136,21 @@ void Host_Game_f (void) if (Cmd_Argc() > 1) { + const char *p = Cmd_Argv(1); + if (!registered.value) //disable command for shareware quake { Con_Printf("You must have the registered version to use modified games\n"); return; } - if (strstr(Cmd_Argv(1), "..")) + if (!strcmp(p, ".") || strstr(p, "..")) { Con_Printf ("Relative pathnames are not allowed.\n"); return; } - q_strlcpy (pakfile, va("%s/%s", host_parms->basedir, Cmd_Argv(1)), sizeof(pakfile)); + q_strlcpy (pakfile, va("%s/%s", host_parms->basedir, p), sizeof(pakfile)); if (!q_strcasecmp(pakfile, com_gamedir)) //no change { Con_Printf("\"game\" is already \"%s\"\n", COM_SkipPath(com_gamedir)); @@ -170,7 +172,7 @@ void Host_Game_f (void) q_strlcpy (com_gamedir, pakfile, sizeof(com_gamedir)); - if (q_strcasecmp(Cmd_Argv(1), GAMENAME)) //game is not id1 + if (q_strcasecmp(p, GAMENAME)) //game is not id1 { // assign a path_id to this game directory if (com_searchpaths) @@ -1046,7 +1048,7 @@ void Host_Savegame_f (void) } q_snprintf (name, sizeof(name), "%s/%s", com_gamedir, Cmd_Argv(1)); - COM_DefaultExtension (name, ".sav", sizeof(name)); + COM_AddExtension (name, ".sav", sizeof(name)); Con_Printf ("Saving game to %s...\n", name); f = fopen (name, "w"); @@ -1118,7 +1120,7 @@ void Host_Loadgame_f (void) cls.demonum = -1; // stop demo loop in case this fails q_snprintf (name, sizeof(name), "%s/%s", com_gamedir, Cmd_Argv(1)); - COM_DefaultExtension (name, ".sav", sizeof(name)); + COM_AddExtension (name, ".sav", sizeof(name)); // we can't call SCR_BeginLoadingPlaque, because too much stack space has // been used. The menu calls it before stuffing loadgame command