[quake3-commits] r1686 - in trunk/code: client qcommon

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Mon Oct 19 18:36:18 EDT 2009


Author: thilo
Date: 2009-10-19 18:36:17 -0400 (Mon, 19 Oct 2009)
New Revision: 1686

Modified:
   trunk/code/client/cl_curl.c
   trunk/code/client/cl_main.c
   trunk/code/client/cl_parse.c
   trunk/code/qcommon/files.c
   trunk/code/qcommon/qcommon.h
Log:
Fix infinite loop in case an invalid pk3 file has been downloaded from the server. Thanks tjw for reporting (#3074)


Modified: trunk/code/client/cl_curl.c
===================================================================
--- trunk/code/client/cl_curl.c	2009-10-19 18:54:09 UTC (rev 1685)
+++ trunk/code/client/cl_curl.c	2009-10-19 22:36:17 UTC (rev 1686)
@@ -332,8 +332,7 @@
 			qcurl_easy_strerror(msg->data.result),
 			code, clc.downloadURL);
 	}
-	*clc.downloadTempName = *clc.downloadName = 0;
-	Cvar_Set( "cl_downloadName", "" );
+
 	CL_NextDownload();
 }
 #endif /* USE_CURL */

Modified: trunk/code/client/cl_main.c
===================================================================
--- trunk/code/client/cl_main.c	2009-10-19 18:54:09 UTC (rev 1685)
+++ trunk/code/client/cl_main.c	2009-10-19 22:36:17 UTC (rev 1686)
@@ -1916,11 +1916,25 @@
 A download completed or failed
 =================
 */
-void CL_NextDownload(void) {
+void CL_NextDownload(void)
+{
 	char *s;
 	char *remoteName, *localName;
 	qboolean useCURL = qfalse;
 
+	// A download has finished, check whether this matches a referenced checksum
+	if(*clc.downloadName)
+	{
+		char *zippath = FS_BuildOSPath(Cvar_VariableString("fs_homepath"), clc.downloadName, "");
+		zippath[strlen(zippath)-1] = '\0';
+
+		if(!FS_CompareZipChecksum(zippath))
+			Com_Error(ERR_DROP, "Incorrect checksum for file: %s", clc.downloadName);
+	}
+
+	*clc.downloadTempName = *clc.downloadName = 0;
+	Cvar_Set("cl_downloadName", "");
+
 	// We are looking to start a download here
 	if (*clc.downloadList) {
 		s = clc.downloadList;
@@ -2027,6 +2041,10 @@
 		if ( *clc.downloadList ) {
 			// if autodownloading is not enabled on the server
 			cls.state = CA_CONNECTED;
+
+			*clc.downloadTempName = *clc.downloadName = 0;
+			Cvar_Set( "cl_downloadName", "" );
+
 			CL_NextDownload();
 			return;
 		}

Modified: trunk/code/client/cl_parse.c
===================================================================
--- trunk/code/client/cl_parse.c	2009-10-19 18:54:09 UTC (rev 1685)
+++ trunk/code/client/cl_parse.c	2009-10-19 22:36:17 UTC (rev 1686)
@@ -619,8 +619,6 @@
 			// rename the file
 			FS_SV_Rename ( clc.downloadTempName, clc.downloadName );
 		}
-		*clc.downloadTempName = *clc.downloadName = 0;
-		Cvar_Set( "cl_downloadName", "" );
 
 		// send intentions now
 		// We need this because without it, we would hold the last nextdl and then start

Modified: trunk/code/qcommon/files.c
===================================================================
--- trunk/code/qcommon/files.c	2009-10-19 18:54:09 UTC (rev 1685)
+++ trunk/code/qcommon/files.c	2009-10-19 22:36:17 UTC (rev 1686)
@@ -1660,7 +1660,7 @@
 of a zip file.
 =================
 */
-static pack_t *FS_LoadZipFile( char *zipfile, const char *basename )
+static pack_t *FS_LoadZipFile(const char *zipfile, const char *basename)
 {
 	fileInPack_t	*buildBuffer;
 	pack_t			*pack;
@@ -1683,8 +1683,6 @@
 	if (err != UNZ_OK)
 		return NULL;
 
-	fs_packFiles += gi.number_entry;
-
 	len = 0;
 	unzGoToFirstFile(uf);
 	for (i = 0; i < gi.number_entry; i++)
@@ -1751,8 +1749,8 @@
 		unzGoToNextFile(uf);
 	}
 
-	pack->checksum = Com_BlockChecksum( &fs_headerLongs[ 1 ], 4 * ( fs_numHeaderLongs - 1 ) );
-	pack->pure_checksum = Com_BlockChecksum( fs_headerLongs, 4 * fs_numHeaderLongs );
+	pack->checksum = Com_BlockChecksum( &fs_headerLongs[ 1 ], sizeof(*fs_headerLongs) * ( fs_numHeaderLongs - 1 ) );
+	pack->pure_checksum = Com_BlockChecksum( fs_headerLongs, sizeof(*fs_headerLongs) * fs_numHeaderLongs );
 	pack->checksum = LittleLong( pack->checksum );
 	pack->pure_checksum = LittleLong( pack->pure_checksum );
 
@@ -1763,6 +1761,50 @@
 }
 
 /*
+=================
+FS_FreePak
+
+Frees a pak structure and releases all associated resources
+=================
+*/
+
+static void FS_FreePak(pack_t *thepak)
+{
+	unzClose(thepak->handle);
+	Z_Free(thepak->buildBuffer);
+	Z_Free(thepak);
+}
+
+/*
+=================
+FS_GetZipChecksum
+
+Compares whether the given pak file matches a referenced checksum
+=================
+*/
+qboolean FS_CompareZipChecksum(const char *zipfile)
+{
+	pack_t *thepak;
+	int index, checksum;
+	
+	thepak = FS_LoadZipFile(zipfile, "");
+	
+	if(!thepak)
+		return qfalse;
+	
+	checksum = thepak->checksum;
+	FS_FreePak(thepak);
+	
+	for(index = 0; index < fs_numServerReferencedPaks; index++)
+	{
+		if(checksum == fs_serverReferencedPaks[index])
+			return qtrue;
+	}
+	
+	return qfalse;
+}
+
+/*
 =================================================================================
 
 DIRECTORY SCANNING FUNCTIONS
@@ -2466,6 +2508,8 @@
 			continue;
 		// store the game name for downloading
 		strcpy(pak->pakGamename, dir);
+		
+		fs_packFiles += pak->numfiles;
 
 		search = Z_Malloc (sizeof(searchpath_t));
 		search->pack = pak;
@@ -2655,18 +2699,16 @@
 	}
 
 	// free everything
-	for ( p = fs_searchpaths ; p ; p = next ) {
+	for(p = fs_searchpaths; p; p = next)
+	{
 		next = p->next;
 
-		if ( p->pack ) {
-			unzClose(p->pack->handle);
-			Z_Free( p->pack->buildBuffer );
-			Z_Free( p->pack );
-		}
-		if ( p->dir ) {
-			Z_Free( p->dir );
-		}
-		Z_Free( p );
+		if(p->pack)
+			FS_FreePak(p->pack);
+		if (p->dir)
+			Z_Free(p->dir);
+
+		Z_Free(p);
 	}
 
 	// any FS_ calls will now be an error until reinitialized

Modified: trunk/code/qcommon/qcommon.h
===================================================================
--- trunk/code/qcommon/qcommon.h	2009-10-19 18:54:09 UTC (rev 1685)
+++ trunk/code/qcommon/qcommon.h	2009-10-19 22:36:17 UTC (rev 1686)
@@ -605,6 +605,7 @@
 
 qboolean FS_CreatePath (char *OSPath);
 char   *FS_BuildOSPath( const char *base, const char *game, const char *qpath );
+qboolean FS_CompareZipChecksum(const char *zipfile);
 
 int		FS_LoadStack( void );
 



More information about the quake3-commits mailing list