*/
qboolean PK3_OpenLibrary (void)
{
- const char* dllname;
+ const char* dllnames [] =
+ {
+#ifdef WIN32
+ "zlib.dll",
+#elif defined(MACOSX)
+ "libz.dylib",
+#else
+ "libz.so.1",
+ "libz.so",
+#endif
+ NULL
+ };
// Already loaded?
if (zlib_dll)
return true;
-#ifdef WIN32
- dllname = "zlib.dll";
-#else
- dllname = "libz.so";
-#endif
-
// Load the DLL
- if (! Sys_LoadLibrary (dllname, &zlib_dll, zlibfuncs))
+ if (! Sys_LoadLibrary (dllnames, &zlib_dll, zlibfuncs))
{
Con_Printf ("Compressed files support disabled\n");
return false;
remaining -= count;
}
- Mem_Free (central_dir);
+ // If the package is empty, central_dir is NULL here
+ if (central_dir != NULL)
+ Mem_Free (central_dir);
return pack->numfiles;
}
packlist = pack;
real_nb_files = PK3_BuildFileList (pack, &eocd);
- if (real_nb_files <= 0)
+ if (real_nb_files < 0)
Sys_Error ("%s is not a valid PK3 file", packfile);
Con_Printf("Added packfile %s (%i files)\n", packfile, real_nb_files);
then loads and adds pak1.pak pak2.pak ...
================
*/
-void FS_AddGameDirectory (char *dir)
+void FS_AddGameDirectory (const char *dir)
{
stringlist_t *list, *current;
searchpath_t *search;
}
+/*
+================
+FS_AddGameHierarchy
+================
+*/
+void FS_AddGameHierarchy (const char *dir)
+{
+ const char *homedir;
+
+ strlcpy (com_modname, dir, sizeof (com_modname));
+
+ // Add the common game directory
+ FS_AddGameDirectory (va("%s/%s", fs_basedir, dir));
+
+ // Add the personal game directory
+ homedir = getenv ("HOME");
+ if (homedir != NULL && homedir[0] != '\0')
+ FS_AddGameDirectory (va("%s/.darkplaces/%s", homedir, dir));
+}
+
+
/*
============
FS_FileExtension
}
// start up with GAMENAME by default (id1)
- strlcpy (com_modname, GAMENAME, sizeof (com_modname));
- FS_AddGameDirectory (va("%s/"GAMENAME, fs_basedir));
+ FS_AddGameHierarchy (GAMENAME);
Cvar_SetQuick (&scr_screenshot_name, gamescreenshotname);
// add the game-specific path, if any
if (gamedirname[0])
{
fs_modified = true;
- strlcpy (com_modname, gamedirname, sizeof (com_modname));
- FS_AddGameDirectory (va("%s/%s", fs_basedir, gamedirname));
+ FS_AddGameHierarchy (gamedirname);
}
// -game <gamedir>
{
i++;
fs_modified = true;
- strlcpy (com_modname, com_argv[i], sizeof (com_modname));
- FS_AddGameDirectory (va("%s/%s", fs_basedir, com_argv[i]));
+ FS_AddGameHierarchy (com_argv[i]);
Cvar_SetQuick (&scr_screenshot_name, com_modname);
}
}
+
+ // If "-condebug" is in the command line, remove the previous log file
+ if (COM_CheckParm ("-condebug") != 0)
+ unlink (va("%s/qconsole.log", fs_gamedir));
}
+/*
+================
+FS_Shutdown
+================
+*/
+void FS_Shutdown (void)
+{
+ Mem_FreePool (&pak_mempool);
+ Mem_FreePool (&fs_mempool);
+}
/*
====================
return file;
}
+/*
+====================
+FS_CheckNastyPath
+
+Return true if the path should be rejected due to one of the following:
+1: path elements that are non-portable
+2: path elements that would allow access to files outside the game directory,
+ or are just not a good idea for a mod to be using.
+====================
+*/
+int FS_CheckNastyPath (const char *path)
+{
+ // Windows: don't allow \ in filenames (windows-only), period.
+ // (on Windows \ is a directory separator, but / is also supported)
+ if (strstr(path, "\\"))
+ return 1; // non-portable
+ // Mac: don't allow Mac-only filenames - : is a directory separator
+ // instead of /, but we rely on / working already, so there's no reason to
+ // support a Mac-only path
+ // Amiga and Windows: : tries to go to root of drive
+ if (strstr(path, ":"))
+ return 1; // non-portable attempt to go to root of drive
+ // Amiga: // is parent directory
+ if (strstr(path, "//"))
+ return 1; // non-portable attempt to go to parent directory
+ // all: don't allow going to current directory (./) or parent directory (../ or /../)
+ if (strstr(path, "./"))
+ return 2; // attempt to go outside the game directory
+ // Windows and UNIXes: don't allow absolute paths
+ if (path[0] == '/')
+ return 2; // attempt to go outside the game directory
+ // after all these checks we're pretty sure it's a / separated filename
+ // and won't do much if any harm
+ return false;
+}
+
/*
====================
*/
qfile_t* FS_Open (const char* filepath, const char* mode, qboolean quiet)
{
+ if (FS_CheckNastyPath(filepath))
+ {
+ Con_Printf("FS_Open(\"%s\", \"%s\", %s): nasty filename rejected\n", filepath, mode, quiet ? "true" : "false");
+ return NULL;
+ }
+
// If the file is opened in "write" or "append" mode
if (strchr (mode, 'w') || strchr (mode, 'a'))
{