]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - fs.c
334
[xonotic/darkplaces.git] / fs.c
diff --git a/fs.c b/fs.c
index 8298a5e9968ecfbdf88be0de80b9a02cda45f3ac..218a85e4b6dd3410e9617e4fea7d7f6d37b4b32c 100644 (file)
--- a/fs.c
+++ b/fs.c
@@ -354,6 +354,8 @@ qboolean PK3_OpenLibrary (void)
 
 #ifdef WIN32
        dllname = "zlib.dll";
+#elif defined(MACOSX)
+       dllname = "libz.dylib";
 #else
        dllname = "libz.so";
 #endif
@@ -543,7 +545,9 @@ int PK3_BuildFileList (pack_t *pack, const pk3_endOfCentralDir_t *eocd)
                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;
 }
 
@@ -602,7 +606,7 @@ pack_t *FS_LoadPackPK3 (const char *packfile)
        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);
@@ -1031,6 +1035,10 @@ void FS_Init (void)
                        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));
 }
 
 
@@ -1122,6 +1130,39 @@ qfile_t *FS_OpenRead (const char *path, int offs, int len)
        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 to parent directory
+       // after all these checks we're pretty sure it's a / separated filename
+       // and won't do much if any harm
+       return false;
+}
+
 
 /*
 ====================
@@ -1313,6 +1354,12 @@ Open a file. The syntax is the same as fopen
 */
 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'))
        {