remove #define NAME_MAX 255

check filename_inzip overflow
This commit is contained in:
Garux 2021-10-04 23:06:16 +03:00
parent 3960adf898
commit 1fe4ab8bd8

View File

@ -103,38 +103,21 @@ char g_strLoadedFileLocation[1024];
// ============================================================================= // =============================================================================
// Static functions // Static functions
//!\todo Define globally or use heap-allocated string.
#define NAME_MAX 255
static void vfsInitPakFile( const char *filename ){ static void vfsInitPakFile( const char *filename ){
unz_global_info gi; unzFile uf = unzOpen( filename );
unzFile uf; if ( uf != NULL ) {
guint32 i;
int err;
uf = unzOpen( filename );
if ( uf == NULL ) {
return;
}
VFS_PAK& pak = g_paks.emplace_front( uf, filename ); VFS_PAK& pak = g_paks.emplace_front( uf, filename );
err = unzGetGlobalInfo( uf,&gi ); if ( unzGoToFirstFile( uf ) == UNZ_OK ) {
if ( err != UNZ_OK ) { do {
return; char filename_inzip[256];
}
unzGoToFirstFile( uf );
for ( i = 0; i < gi.number_entry; i++ )
{
char filename_inzip[NAME_MAX];
unz_file_info file_info; unz_file_info file_info;
err = unzGetCurrentFileInfo( uf, &file_info, filename_inzip, sizeof( filename_inzip ), NULL, 0, NULL, 0 ); if ( unzGetCurrentFileInfo( uf, &file_info, filename_inzip, std::size( filename_inzip ), NULL, 0, NULL, 0 ) != UNZ_OK ) {
if ( err != UNZ_OK ) {
break; break;
} }
if( file_info.size_filename < std::size( filename_inzip ) ) {
FixDOSName( filename_inzip ); FixDOSName( filename_inzip );
strLower( filename_inzip ); strLower( filename_inzip );
@ -144,12 +127,8 @@ static void vfsInitPakFile( const char *filename ){
pak, pak,
file_info.uncompressed_size file_info.uncompressed_size
} ); } );
if ( ( i + 1 ) < gi.number_entry ) {
err = unzGoToNextFile( uf );
if ( err != UNZ_OK ) {
break;
} }
} while( unzGoToNextFile( uf ) == UNZ_OK );
} }
} }
} }
@ -262,25 +241,21 @@ void vfsShutdown(){
// return the number of files that match // return the number of files that match
int vfsGetFileCount( const char *filename ){ int vfsGetFileCount( const char *filename ){
int count = 0; int count = 0;
char fixed[NAME_MAX], tmp[NAME_MAX];
strcpy( fixed, filename ); auto fixed = StringOutputStream( 64 )( PathCleaned( filename ) );
FixDOSName( fixed ); strLower( fixed.c_str() );
strLower( fixed );
for ( const VFS_PAKFILE& file : g_pakFiles ) for ( const VFS_PAKFILE& file : g_pakFiles )
{ {
if ( strEqual( file.name.c_str(), fixed ) ) { if ( strEqual( file.name.c_str(), fixed ) ) {
count++; ++count;
} }
} }
for ( const auto& dir : g_strDirs ) for ( const auto& dir : g_strDirs )
{ {
strcpy( tmp, dir.c_str() ); if ( access( StringOutputStream( 256 )( dir, filename ), R_OK ) == 0 ) {
strcat( tmp, fixed ); ++count;
if ( access( tmp, R_OK ) == 0 ) {
count++;
} }
} }
@ -289,11 +264,9 @@ int vfsGetFileCount( const char *filename ){
// NOTE: when loading a file, you have to allocate one extra byte and set it to \0 // NOTE: when loading a file, you have to allocate one extra byte and set it to \0
int vfsLoadFile( const char *filename, void **bufferptr, int index ){ int vfsLoadFile( const char *filename, void **bufferptr, int index ){
int count = 0;
char tmp[NAME_MAX], fixed[NAME_MAX];
// filename is a full path const auto load_full_path = [bufferptr] ( const char *filename ) -> int
if ( index == -1 ) { {
strcpy( g_strLoadedFileLocation, filename ); strcpy( g_strLoadedFileLocation, filename );
FILE *f = fopen( filename, "rb" ); FILE *f = fopen( filename, "rb" );
@ -317,55 +290,28 @@ int vfsLoadFile( const char *filename, void **bufferptr, int index ){
( (char*) ( *bufferptr ) )[len] = 0; ( (char*) ( *bufferptr ) )[len] = 0;
return len; return len;
} };
*bufferptr = NULL; // filename is a full path
strcpy( fixed, filename ); if ( index == -1 ) {
FixDOSName( fixed ); return load_full_path( filename );
strLower( fixed ); }
for ( const auto& dir : g_strDirs ) for ( const auto& dir : g_strDirs )
{ {
strcpy( tmp, dir.c_str() ); const auto fullpath = StringOutputStream( 256 )( dir, filename );
strcat( tmp, filename ); if ( access( fullpath, R_OK ) == 0 && 0 == index-- ) {
if ( access( tmp, R_OK ) == 0 ) { return load_full_path( fullpath );
if ( count == index ) {
strcpy( g_strLoadedFileLocation, tmp );
FILE *f = fopen( tmp, "rb" );
if ( f == NULL ) {
return -1;
}
fseek( f, 0, SEEK_END );
const long len = ftell( f );
rewind( f );
*bufferptr = safe_malloc( len + 1 );
if ( fread( *bufferptr, 1, len, f ) != (size_t) len ) {
fclose( f );
return -1;
}
fclose( f );
// we need to end the buffer with a 0
( (char*) ( *bufferptr ) )[len] = 0;
return len;
}
count++;
} }
} }
auto fixed = StringOutputStream( 64 )( PathCleaned( filename ) );
strLower( fixed.c_str() );
for ( const VFS_PAKFILE& file : g_pakFiles ) for ( const VFS_PAKFILE& file : g_pakFiles )
{ {
if ( !strEqual( file.name.c_str(), fixed ) ) { if ( strEqual( file.name.c_str(), fixed ) && 0 == index-- )
continue; {
}
if ( count == index ) {
snprintf( g_strLoadedFileLocation, sizeof( g_strLoadedFileLocation ), "%s :: %s", file.pak.unzFilePath.c_str(), filename ); snprintf( g_strLoadedFileLocation, sizeof( g_strLoadedFileLocation ), "%s :: %s", file.pak.unzFilePath.c_str(), filename );
unzFile zipfile = file.pak.zipfile; unzFile zipfile = file.pak.zipfile;
@ -388,8 +334,6 @@ int vfsLoadFile( const char *filename, void **bufferptr, int index ){
return file.size; return file.size;
} }
} }
count++;
} }
return -1; return -1;
@ -399,56 +343,19 @@ int vfsLoadFile( const char *filename, void **bufferptr, int index ){
bool vfsPackFile( const char *filename, const char *packname, const int compLevel ){ bool vfsPackFile( const char *filename, const char *packname, const int compLevel ){
char tmp[NAME_MAX], fixed[NAME_MAX];
byte *bufferptr = NULL;
strcpy( fixed, filename );
FixDOSName( fixed );
strLower( fixed );
for ( const auto& dir : g_strDirs ) for ( const auto& dir : g_strDirs )
{ {
strcpy( tmp, dir.c_str() ); if( vfsPackFile_Absolute_Path( StringOutputStream( 256 )( dir, filename ), filename, packname, compLevel ) )
strcat( tmp, filename );
if ( access( tmp, R_OK ) == 0 ) {
if ( access( packname, R_OK ) == 0 ) {
mz_zip_archive zip;
memset( &zip, 0, sizeof(zip) );
mz_zip_reader_init_file( &zip, packname, 0 );
mz_zip_writer_init_from_reader( &zip, packname );
mz_bool success = MZ_TRUE;
success &= mz_zip_writer_add_file( &zip, filename, tmp, 0, 0, compLevel );
if ( !success || !mz_zip_writer_finalize_archive( &zip ) ){
Error( "Failed creating zip archive \"%s\"!\n", packname );
}
mz_zip_reader_end( &zip);
mz_zip_writer_end( &zip );
}
else{
mz_zip_archive zip;
memset( &zip, 0, sizeof(zip) );
if( !mz_zip_writer_init_file( &zip, packname, 0 ) ){
Error( "Failed creating zip archive \"%s\"!\n", packname );
}
mz_bool success = MZ_TRUE;
success &= mz_zip_writer_add_file( &zip, filename, tmp, 0, 0, compLevel );
if ( !success || !mz_zip_writer_finalize_archive( &zip ) ){
Error( "Failed creating zip archive \"%s\"!\n", packname );
}
mz_zip_writer_end( &zip );
}
return true; return true;
} }
}
auto fixed = StringOutputStream( 64 )( PathCleaned( filename ) );
strLower( fixed.c_str() );
for ( const VFS_PAKFILE& file : g_pakFiles ) for ( const VFS_PAKFILE& file : g_pakFiles )
{ {
if ( !strEqual( file.name.c_str(), fixed ) ) { if ( strEqual( file.name.c_str(), fixed ) )
continue; {
}
unzFile zipfile = file.pak.zipfile; unzFile zipfile = file.pak.zipfile;
*(unz_s*)zipfile = file.zipinfo; *(unz_s*)zipfile = file.zipinfo;
@ -456,7 +363,7 @@ bool vfsPackFile( const char *filename, const char *packname, const int compLeve
return false; return false;
} }
bufferptr = safe_malloc( file.size + 1 ); byte *bufferptr = safe_malloc( file.size + 1 );
// we need to end the buffer with a 0 // we need to end the buffer with a 0
bufferptr[file.size] = 0; bufferptr[file.size] = 0;
@ -466,32 +373,28 @@ bool vfsPackFile( const char *filename, const char *packname, const int compLeve
return false; return false;
} }
else{ else{
mz_bool success = MZ_TRUE; if ( !mz_zip_add_mem_to_archive_file_in_place_with_time( packname, filename, bufferptr, size, 0, 0, compLevel, file.zipinfo.cur_file_info.dosDate ) ){
success &= mz_zip_add_mem_to_archive_file_in_place_with_time( packname, filename, bufferptr, size, 0, 0, compLevel, file.zipinfo.cur_file_info.dosDate );
if ( !success ){
Error( "Failed creating zip archive \"%s\"!\n", packname ); Error( "Failed creating zip archive \"%s\"!\n", packname );
} }
free( bufferptr ); free( bufferptr );
return true; return true;
} }
} }
}
return false; return false;
} }
bool vfsPackFile_Absolute_Path( const char *filepath, const char *filename, const char *packname, const int compLevel ){ bool vfsPackFile_Absolute_Path( const char *filepath, const char *filename, const char *packname, const int compLevel ){
char tmp[NAME_MAX]; if ( access( filepath, R_OK ) == 0 ) {
strcpy( tmp, filepath );
if ( access( tmp, R_OK ) == 0 ) {
if ( access( packname, R_OK ) == 0 ) { if ( access( packname, R_OK ) == 0 ) {
mz_zip_archive zip; mz_zip_archive zip;
memset( &zip, 0, sizeof(zip) ); memset( &zip, 0, sizeof(zip) );
mz_zip_reader_init_file( &zip, packname, 0 );
mz_zip_writer_init_from_reader( &zip, packname );
mz_bool success = MZ_TRUE; if ( !mz_zip_reader_init_file( &zip, packname, 0 )
success &= mz_zip_writer_add_file( &zip, filename, tmp, 0, 0, compLevel ); || !mz_zip_writer_init_from_reader( &zip, packname )
if ( !success || !mz_zip_writer_finalize_archive( &zip ) ){ || !mz_zip_writer_add_file( &zip, filename, filepath, 0, 0, compLevel )
|| !mz_zip_writer_finalize_archive( &zip ) ){
Error( "Failed creating zip archive \"%s\"!\n", packname ); Error( "Failed creating zip archive \"%s\"!\n", packname );
} }
mz_zip_reader_end( &zip); mz_zip_reader_end( &zip);
@ -500,12 +403,10 @@ bool vfsPackFile_Absolute_Path( const char *filepath, const char *filename, cons
else{ else{
mz_zip_archive zip; mz_zip_archive zip;
memset( &zip, 0, sizeof(zip) ); memset( &zip, 0, sizeof(zip) );
if( !mz_zip_writer_init_file( &zip, packname, 0 ) ){
Error( "Failed creating zip archive \"%s\"!\n", packname ); if ( !mz_zip_writer_init_file( &zip, packname, 0 )
} || !mz_zip_writer_add_file( &zip, filename, filepath, 0, 0, compLevel )
mz_bool success = MZ_TRUE; || !mz_zip_writer_finalize_archive( &zip ) ){
success &= mz_zip_writer_add_file( &zip, filename, tmp, 0, 0, compLevel );
if ( !success || !mz_zip_writer_finalize_archive( &zip ) ){
Error( "Failed creating zip archive \"%s\"!\n", packname ); Error( "Failed creating zip archive \"%s\"!\n", packname );
} }
mz_zip_writer_end( &zip ); mz_zip_writer_end( &zip );