mirror of
https://github.com/YGGverse/xash3d-fwgs.git
synced 2025-01-11 07:37:52 +00:00
filesystem: zip: fix memory leak (not freed info)
This commit is contained in:
parent
b04a48f126
commit
b32de42ab7
@ -152,6 +152,7 @@ static void FS_InitMemory( void );
|
|||||||
static searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedironly );
|
static searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedironly );
|
||||||
static dlumpinfo_t *W_FindLump( wfile_t *wad, const char *name, const char matchtype );
|
static dlumpinfo_t *W_FindLump( wfile_t *wad, const char *name, const char matchtype );
|
||||||
static dpackfile_t *FS_AddFileToPack( const char* name, pack_t *pack, fs_offset_t offset, fs_offset_t size );
|
static dpackfile_t *FS_AddFileToPack( const char* name, pack_t *pack, fs_offset_t offset, fs_offset_t size );
|
||||||
|
void Zip_Close( zip_t *zip );
|
||||||
static byte *W_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly );
|
static byte *W_LoadFile( const char *path, fs_offset_t *filesizeptr, qboolean gamedironly );
|
||||||
static wfile_t *W_Open( const char *filename, int *errorcode );
|
static wfile_t *W_Open( const char *filename, int *errorcode );
|
||||||
static qboolean FS_SysFolderExists( const char *path );
|
static qboolean FS_SysFolderExists( const char *path );
|
||||||
@ -714,6 +715,8 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
|
|||||||
if( ZIP_HEADER_EOCD != signature )
|
if( ZIP_HEADER_EOCD != signature )
|
||||||
{
|
{
|
||||||
Con_Reportf( "Cannot find EOCD in %s. Zip file corrupted.\n", zipfile );
|
Con_Reportf( "Cannot find EOCD in %s. Zip file corrupted.\n", zipfile );
|
||||||
|
if(error)
|
||||||
|
*error = ZIP_LOAD_BAD_HEADER;
|
||||||
Zip_Close( zip );
|
Zip_Close( zip );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -735,6 +738,9 @@ static zip_t *FS_LoadZip( const char *zipfile, int *error )
|
|||||||
if( header_cdf.signature != ZIP_HEADER_CDF )
|
if( header_cdf.signature != ZIP_HEADER_CDF )
|
||||||
{
|
{
|
||||||
Con_Reportf( "CDF signature mismatch in %s. Zip file corrupted.\n", zipfile );
|
Con_Reportf( "CDF signature mismatch in %s. Zip file corrupted.\n", zipfile );
|
||||||
|
if(error)
|
||||||
|
*error = ZIP_LOAD_BAD_HEADER;
|
||||||
|
Mem_Free( info );
|
||||||
Zip_Close( zip );
|
Zip_Close( zip );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -800,6 +806,10 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game
|
|||||||
int index;
|
int index;
|
||||||
zip_header_t header;
|
zip_header_t header;
|
||||||
zipfile_t *file = NULL;
|
zipfile_t *file = NULL;
|
||||||
|
byte *compressed_buffer = NULL, *decompressed_buffer = NULL;
|
||||||
|
unsigned long zlib_dest_size = 0;
|
||||||
|
int zlib_result = 0;
|
||||||
|
dword test_crc, final_crc;
|
||||||
|
|
||||||
if( sizeptr ) sizeptr == 0;
|
if( sizeptr ) sizeptr == 0;
|
||||||
|
|
||||||
@ -829,23 +839,21 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game
|
|||||||
if( header.extrafield_len )
|
if( header.extrafield_len )
|
||||||
FS_Seek( search->zip->handle, header.extrafield_len, SEEK_CUR );
|
FS_Seek( search->zip->handle, header.extrafield_len, SEEK_CUR );
|
||||||
|
|
||||||
byte *buffer = Mem_Malloc( search->zip->mempool, file->size + 1 );
|
decompressed_buffer = Mem_Malloc( search->zip->mempool, file->size + 1 );
|
||||||
|
|
||||||
buffer[file->size] = '\0';
|
decompressed_buffer[file->size] = '\0';
|
||||||
|
|
||||||
FS_Read( search->zip->handle, buffer, file->size );
|
FS_Read( search->zip->handle, decompressed_buffer, file->size );
|
||||||
|
|
||||||
dword test_crc;
|
|
||||||
|
|
||||||
CRC32_Init( &test_crc );
|
CRC32_Init( &test_crc );
|
||||||
CRC32_ProcessBuffer( &test_crc, buffer, file->size );
|
CRC32_ProcessBuffer( &test_crc, decompressed_buffer, file->size );
|
||||||
|
|
||||||
dword final_crc = CRC32_Final(test_crc);
|
final_crc = CRC32_Final(test_crc);
|
||||||
|
|
||||||
if(final_crc != header.crc32)
|
if( final_crc != header.crc32 )
|
||||||
{
|
{
|
||||||
Con_Reportf( S_ERROR "Zip_LoadFile: %s file crc32 mismatch\n", file->name );
|
Con_Reportf( S_ERROR "Zip_LoadFile: %s file crc32 mismatch\n", file->name );
|
||||||
Mem_Free( buffer );
|
Mem_Free( decompressed_buffer );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -853,7 +861,7 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game
|
|||||||
|
|
||||||
if( sizeptr ) *sizeptr = file->size;
|
if( sizeptr ) *sizeptr = file->size;
|
||||||
|
|
||||||
return buffer;
|
return decompressed_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( header.compression_flags == ZIP_COMPRESSION_DEFLATED )
|
if( header.compression_flags == ZIP_COMPRESSION_DEFLATED )
|
||||||
@ -865,54 +873,53 @@ static byte *Zip_LoadFile( const char *path, fs_offset_t *sizeptr, qboolean game
|
|||||||
if( header.extrafield_len )
|
if( header.extrafield_len )
|
||||||
FS_Seek( search->zip->handle, header.extrafield_len, SEEK_CUR );
|
FS_Seek( search->zip->handle, header.extrafield_len, SEEK_CUR );
|
||||||
|
|
||||||
byte *compresed_buffer = Mem_Malloc( search->zip->mempool, file->compressed_size + 1 );
|
compressed_buffer = Mem_Malloc( search->zip->mempool, file->compressed_size + 1 );
|
||||||
|
|
||||||
compresed_buffer[file->compressed_size] = '\0';
|
compressed_buffer[file->compressed_size] = '\0';
|
||||||
|
|
||||||
byte *decompresed_buffer = Mem_Malloc( search->zip->mempool, file->size + 1 );
|
decompressed_buffer = Mem_Malloc( search->zip->mempool, file->size + 1 );
|
||||||
|
|
||||||
compresed_buffer[file->size] = '\0';
|
compressed_buffer[file->size] = '\0';
|
||||||
|
|
||||||
FS_Read( search->zip->handle, compresed_buffer, file->compressed_size );
|
FS_Read( search->zip->handle, compressed_buffer, file->compressed_size );
|
||||||
|
|
||||||
unsigned long dest_size = file->size;
|
zlib_dest_size = file->size;
|
||||||
|
|
||||||
int zlib_result = uncompress( decompresed_buffer, &dest_size, compresed_buffer, file->compressed_size );
|
zlib_result = uncompress( decompressed_buffer, &zlib_dest_size, compressed_buffer, file->compressed_size );
|
||||||
|
|
||||||
ASSERT( file->size != dest_size );
|
ASSERT( file->size != zlib_dest_size );
|
||||||
|
|
||||||
if( zlib_result == Z_OK )
|
if( zlib_result == Z_OK )
|
||||||
{
|
{
|
||||||
Mem_Free( compresed_buffer ); // finaly free compressed buffer
|
Mem_Free( compressed_buffer ); // finaly free compressed buffer
|
||||||
|
|
||||||
dword test_crc;
|
|
||||||
|
|
||||||
CRC32_Init( &test_crc );
|
CRC32_Init( &test_crc );
|
||||||
CRC32_ProcessBuffer( &test_crc, decompresed_buffer, file->size );
|
CRC32_ProcessBuffer( &test_crc, decompressed_buffer, file->size );
|
||||||
|
|
||||||
dword final_crc = CRC32_Final( test_crc );
|
final_crc = CRC32_Final( test_crc );
|
||||||
|
|
||||||
if( final_crc != header.crc32 )
|
if( final_crc != header.crc32 )
|
||||||
{
|
{
|
||||||
Con_Reportf( S_ERROR "Zip_LoadFile: %s file crc32 mismatch\n", file->name );
|
Con_Reportf( S_ERROR "Zip_LoadFile: %s file crc32 mismatch\n", file->name );
|
||||||
Mem_Free( decompresed_buffer );
|
Mem_Free( decompressed_buffer );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( sizeptr ) *sizeptr = file->size;
|
if( sizeptr ) *sizeptr = file->size;
|
||||||
|
|
||||||
return decompresed_buffer;
|
return decompressed_buffer;
|
||||||
|
|
||||||
} else if( zlib_result == Z_DATA_ERROR )
|
} else if( zlib_result == Z_DATA_ERROR )
|
||||||
{
|
{
|
||||||
Con_Reportf( S_ERROR "Zip_LoadFile: %s : compressed file data corrupted.\n", file->name );
|
Con_Reportf( S_ERROR "Zip_LoadFile: %s : compressed file data corrupted.\n", file->name );
|
||||||
Mem_Free( compresed_buffer );
|
Mem_Free( compressed_buffer );
|
||||||
Mem_Free( decompresed_buffer );
|
Mem_Free( decompressed_buffer );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
Con_Reportf( S_ERROR "Zip_LoadFile: %s : file compressed with unknown algorithm.\n", file->name );
|
Con_Reportf( S_ERROR "Zip_LoadFile: %s : file compressed with unknown algorithm.\n", file->name );
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1068,7 +1075,9 @@ qboolean FS_AddZip_Fullpath( const char *zipfile, qboolean *already_loaded, int
|
|||||||
|
|
||||||
Con_Reportf( "Adding zipfile: %s (%i files)\n", zipfile, zip->numfiles );
|
Con_Reportf( "Adding zipfile: %s (%i files)\n", zipfile, zip->numfiles );
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if( errorcode != ZIP_LOAD_NO_FILES )
|
if( errorcode != ZIP_LOAD_NO_FILES )
|
||||||
Con_Reportf( S_ERROR "FS_AddZip_Fullpath: unable to load zip \"%s\"\n", zipfile );
|
Con_Reportf( S_ERROR "FS_AddZip_Fullpath: unable to load zip \"%s\"\n", zipfile );
|
||||||
return false;
|
return false;
|
||||||
@ -2380,9 +2389,9 @@ static searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedir
|
|||||||
return search;
|
return search;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(search->zip)
|
else if( search->zip )
|
||||||
{
|
{
|
||||||
for(int i = 0; search->zip->numfiles > i; i++)
|
for( int i = 0; search->zip->numfiles > i; i++)
|
||||||
{
|
{
|
||||||
if( !Q_stricmp( search->zip->files[i].name, name ) )
|
if( !Q_stricmp( search->zip->files[i].name, name ) )
|
||||||
{
|
{
|
||||||
@ -2391,7 +2400,8 @@ static searchpath_t *FS_FindFile( const char *name, int *index, qboolean gamedir
|
|||||||
return search;
|
return search;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
|
{
|
||||||
char netpath[MAX_SYSPATH];
|
char netpath[MAX_SYSPATH];
|
||||||
|
|
||||||
Q_sprintf( netpath, "%s%s", search->filename, name );
|
Q_sprintf( netpath, "%s%s", search->filename, name );
|
||||||
|
@ -139,68 +139,61 @@ typedef struct
|
|||||||
#pragma pack( 1 )
|
#pragma pack( 1 )
|
||||||
typedef struct zip_header_s
|
typedef struct zip_header_s
|
||||||
{
|
{
|
||||||
uint signature; // little endian ZIP_HEADER
|
unsigned int signature; // little endian ZIP_HEADER
|
||||||
u_int16_t version; // version of pkzip need to unpack
|
unsigned short version; // version of pkzip need to unpack
|
||||||
u_int16_t flags; // flags (16 bits == 16 flags)
|
unsigned short flags; // flags (16 bits == 16 flags)
|
||||||
u_int16_t compression_flags; // compression flags (bits)
|
unsigned short compression_flags; // compression flags (bits)
|
||||||
uint dos_date; // file modification time and file modification date
|
unsigned int dos_date; // file modification time and file modification date
|
||||||
uint crc32; //crc32
|
unsigned int crc32; //crc32
|
||||||
uint compressed_size;
|
unsigned int compressed_size;
|
||||||
uint uncompressed_size;
|
unsigned int uncompressed_size;
|
||||||
u_int16_t filename_len;
|
unsigned short filename_len;
|
||||||
u_int16_t extrafield_len;
|
unsigned short extrafield_len;
|
||||||
} zip_header_t;
|
} zip_header_t;
|
||||||
|
|
||||||
#pragma pack( )
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
in zip64 comp and uncompr size == 0xffffffff remeber this
|
in zip64 comp and uncompr size == 0xffffffff remeber this
|
||||||
compressed and uncompress filesize stored in extra field
|
compressed and uncompress filesize stored in extra field
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma pack( 1 )
|
|
||||||
typedef struct zip_header_extra_s
|
typedef struct zip_header_extra_s
|
||||||
{
|
{
|
||||||
uint signature; // ZIP_HEADER_SPANNED
|
unsigned int signature; // ZIP_HEADER_SPANNED
|
||||||
uint crc32;
|
unsigned int crc32;
|
||||||
uint compressed_size;
|
unsigned int compressed_size;
|
||||||
uint uncompressed_size;
|
unsigned int uncompressed_size;
|
||||||
} zip_header_extra_t;
|
} zip_header_extra_t;
|
||||||
#pragma pack( )
|
|
||||||
|
|
||||||
#pragma pack( 1 )
|
|
||||||
typedef struct zip_cdf_header_s
|
typedef struct zip_cdf_header_s
|
||||||
{
|
{
|
||||||
uint signature;
|
unsigned int signature;
|
||||||
u_int16_t version;
|
unsigned short version;
|
||||||
u_int16_t version_need;
|
unsigned short version_need;
|
||||||
u_int16_t generalPurposeBitFlag;
|
unsigned short generalPurposeBitFlag;
|
||||||
u_int16_t flags;
|
unsigned short flags;
|
||||||
u_int16_t modification_time;
|
unsigned short modification_time;
|
||||||
u_int16_t modification_date;
|
unsigned short modification_date;
|
||||||
uint crc32;
|
unsigned int crc32;
|
||||||
uint compressed_size;
|
unsigned int compressed_size;
|
||||||
uint uncompressed_size;
|
unsigned int uncompressed_size;
|
||||||
u_int16_t filename_len;
|
unsigned short filename_len;
|
||||||
u_int16_t extrafield_len;
|
unsigned short extrafield_len;
|
||||||
u_int16_t file_commentary_len;
|
unsigned short file_commentary_len;
|
||||||
u_int16_t disk_start;
|
unsigned short disk_start;
|
||||||
u_int16_t internal_attr;
|
unsigned short internal_attr;
|
||||||
uint external_attr;
|
unsigned int external_attr;
|
||||||
uint local_header_offset;
|
unsigned int local_header_offset;
|
||||||
} zip_cdf_header_t;
|
} zip_cdf_header_t;
|
||||||
#pragma pack ( )
|
|
||||||
|
|
||||||
#pragma pack( 1 )
|
|
||||||
typedef struct zip_header_eocd_s
|
typedef struct zip_header_eocd_s
|
||||||
{
|
{
|
||||||
u_int16_t disk_number;
|
unsigned short disk_number;
|
||||||
u_int16_t start_disk_number;
|
unsigned short start_disk_number;
|
||||||
u_int16_t number_central_directory_record;
|
unsigned short number_central_directory_record;
|
||||||
u_int16_t total_central_directory_record;
|
unsigned short total_central_directory_record;
|
||||||
uint size_of_central_directory;
|
unsigned int size_of_central_directory;
|
||||||
uint central_directory_offset;
|
unsigned int central_directory_offset;
|
||||||
u_int16_t commentary_len;
|
unsigned short commentary_len;
|
||||||
} zip_header_eocd_t;
|
} zip_header_eocd_t;
|
||||||
#pragma pack( )
|
#pragma pack( )
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user