From 473debef0e5c4229d9fdd5a7418e6e9bd7cdd51c Mon Sep 17 00:00:00 2001 From: thilo Date: Mon, 19 Oct 2009 22:36:17 +0000 Subject: 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 --- code/qcommon/files.c | 72 +++++++++++++++++++++++++++++++++++++++----------- code/qcommon/qcommon.h | 1 + 2 files changed, 58 insertions(+), 15 deletions(-) (limited to 'code/qcommon') 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 ); @@ -1762,6 +1760,50 @@ static pack_t *FS_LoadZipFile( char *zipfile, const char *basename ) return pack; } +/* +================= +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; +} + /* ================================================================================= @@ -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 ); -- cgit v1.2.3