aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthilo <thilo@edf5b092-35ff-0310-97b2-ce42778d08ea>2009-10-19 22:36:17 +0000
committerthilo <thilo@edf5b092-35ff-0310-97b2-ce42778d08ea>2009-10-19 22:36:17 +0000
commit473debef0e5c4229d9fdd5a7418e6e9bd7cdd51c (patch)
tree5cbbbffd84c6dab9b223b6e16cff1f4a6168435c
parent54af38d7f47e4135aab626496e2de9e71dd49cff (diff)
downloadioquake3-aero-473debef0e5c4229d9fdd5a7418e6e9bd7cdd51c.tar.gz
ioquake3-aero-473debef0e5c4229d9fdd5a7418e6e9bd7cdd51c.zip
Fix infinite loop in case an invalid pk3 file has been downloaded from the server. Thanks tjw for reporting (#3074)
git-svn-id: svn://svn.icculus.org/quake3/trunk@1686 edf5b092-35ff-0310-97b2-ce42778d08ea
-rw-r--r--code/client/cl_curl.c3
-rw-r--r--code/client/cl_main.c20
-rw-r--r--code/client/cl_parse.c2
-rw-r--r--code/qcommon/files.c72
-rw-r--r--code/qcommon/qcommon.h1
5 files changed, 78 insertions, 20 deletions
diff --git a/code/client/cl_curl.c b/code/client/cl_curl.c
index a7f0879..170e97b 100644
--- a/code/client/cl_curl.c
+++ b/code/client/cl_curl.c
@@ -332,8 +332,7 @@ void CL_cURL_PerformDownload(void)
qcurl_easy_strerror(msg->data.result),
code, clc.downloadURL);
}
- *clc.downloadTempName = *clc.downloadName = 0;
- Cvar_Set( "cl_downloadName", "" );
+
CL_NextDownload();
}
#endif /* USE_CURL */
diff --git a/code/client/cl_main.c b/code/client/cl_main.c
index f435be0..029dba4 100644
--- a/code/client/cl_main.c
+++ b/code/client/cl_main.c
@@ -1916,11 +1916,25 @@ CL_NextDownload
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 @@ void CL_InitDownloads(void) {
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;
}
diff --git a/code/client/cl_parse.c b/code/client/cl_parse.c
index 588fe39..687cb5f 100644
--- a/code/client/cl_parse.c
+++ b/code/client/cl_parse.c
@@ -619,8 +619,6 @@ void CL_ParseDownload ( msg_t *msg ) {
// 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
diff --git a/code/qcommon/files.c b/code/qcommon/files.c
index 249470b..3584e30 100644
--- a/code/qcommon/files.c
+++ b/code/qcommon/files.c
@@ -1660,7 +1660,7 @@ Creates a new pak_t in the search chain for the contents
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 @@ static pack_t *FS_LoadZipFile( char *zipfile, const char *basename )
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 @@ static pack_t *FS_LoadZipFile( char *zipfile, const char *basename )
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 @@ static pack_t *FS_LoadZipFile( char *zipfile, const char *basename )
}
/*
+=================
+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 @@ void FS_AddGameDirectory( const char *path, const char *dir ) {
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 @@ void FS_Shutdown( qboolean closemfp ) {
}
// 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
diff --git a/code/qcommon/qcommon.h b/code/qcommon/qcommon.h
index d1cc2fd..566687c 100644
--- a/code/qcommon/qcommon.h
+++ b/code/qcommon/qcommon.h
@@ -605,6 +605,7 @@ qboolean FS_FileExists( const char *file );
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 );