6464*/
6565
6666
67+ #include <stdint.h>
6768#include <stdio.h>
6869#include <stdlib.h>
6970#include <string.h>
@@ -837,6 +838,7 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
837838 uLong uMagic ;
838839 long lSeek = 0 ;
839840 uLong uL ;
841+ uLong uFileNameCrc ;
840842
841843 if (file == NULL )
842844 return UNZ_PARAMERROR ;
@@ -908,21 +910,34 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
908910 file_info_internal .offset_curfile = uL ;
909911
910912 lSeek += file_info .size_filename ;
911- if (( err == UNZ_OK ) && ( szFileName != NULL ) )
913+ if (err == UNZ_OK )
912914 {
913- uLong uSizeRead ;
914- if (file_info .size_filename < fileNameBufferSize )
915+ char szCurrentFileName [UINT16_MAX ] = {0 };
916+
917+ if (file_info .size_filename > 0 )
915918 {
916- * (szFileName + file_info .size_filename )= '\0' ;
917- uSizeRead = file_info .size_filename ;
919+ if (ZREAD64 (s -> z_filefunc , s -> filestream , szCurrentFileName , file_info .size_filename ) != file_info .size_filename )
920+ {
921+ err = UNZ_ERRNO ;
922+ }
918923 }
919- else
920- uSizeRead = fileNameBufferSize ;
921924
922- if ((file_info .size_filename > 0 ) && (fileNameBufferSize > 0 ))
923- if (ZREAD64 (s -> z_filefunc , s -> filestream ,szFileName ,uSizeRead )!= uSizeRead )
924- err = UNZ_ERRNO ;
925- lSeek -= uSizeRead ;
925+ uFileNameCrc = crc32 (0 , (unsigned char * )szCurrentFileName , file_info .size_filename );
926+
927+ if (szFileName != NULL )
928+ {
929+ if (fileNameBufferSize <= file_info .size_filename )
930+ {
931+ memcpy (szFileName , szCurrentFileName , fileNameBufferSize );
932+ }
933+ else
934+ {
935+ memcpy (szFileName , szCurrentFileName , file_info .size_filename );
936+ szFileName [file_info .size_filename ] = '\0' ;
937+ }
938+ }
939+
940+ lSeek -= file_info .size_filename ;
926941 }
927942
928943 // Read extrafield
@@ -1012,7 +1027,15 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
10121027 {
10131028 int version = 0 ;
10141029
1015- if (unz64local_getByte (& s -> z_filefunc , s -> filestream , & version ) != UNZ_OK )
1030+ if (dataSize < 1 + 4 )
1031+ {
1032+ /* dataSize includes version (1 byte), uCrc (4 bytes), and
1033+ * the filename data. If it's too small, fileNameSize below
1034+ * would overflow. */
1035+ err = UNZ_ERRNO ;
1036+ break ;
1037+ }
1038+ else if (unz64local_getByte (& s -> z_filefunc , s -> filestream , & version ) != UNZ_OK )
10161039 {
10171040 err = UNZ_ERRNO ;
10181041 }
@@ -1025,16 +1048,16 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
10251048 }
10261049 else
10271050 {
1028- uLong uCrc , uHeaderCrc , fileNameSize ;
1051+ uLong uCrc , fileNameSize ;
10291052
10301053 if (unz64local_getLong (& s -> z_filefunc , s -> filestream , & uCrc ) != UNZ_OK )
10311054 {
10321055 err = UNZ_ERRNO ;
10331056 }
1034- uHeaderCrc = crc32 ( 0 , ( const unsigned char * ) szFileName , file_info . size_filename );
1035- fileNameSize = dataSize - ( 2 * sizeof ( short ) + 1 );
1057+ fileNameSize = dataSize - ( 1 + 4 ); /* 1 for version, 4 for uCrc */
1058+
10361059 /* Check CRC against file name in the header. */
1037- if (uHeaderCrc != uCrc )
1060+ if (uCrc != uFileNameCrc )
10381061 {
10391062 if (ZSEEK64 (s -> z_filefunc , s -> filestream , fileNameSize , ZLIB_FILEFUNC_SEEK_CUR ) != 0 )
10401063 {
@@ -1043,24 +1066,28 @@ local int unz64local_GetCurrentFileInfoInternal(unzFile file,
10431066 }
10441067 else
10451068 {
1046- uLong uSizeRead ;
1047-
10481069 file_info .size_filename = fileNameSize ;
10491070
1050- if (fileNameSize < fileNameBufferSize )
1051- {
1052- * (szFileName + fileNameSize ) = '\0' ;
1053- uSizeRead = fileNameSize ;
1054- }
1055- else
1071+ char szCurrentFileName [UINT16_MAX ] = {0 };
1072+
1073+ if (file_info .size_filename > 0 )
10561074 {
1057- uSizeRead = fileNameBufferSize ;
1075+ if (ZREAD64 (s -> z_filefunc , s -> filestream , szCurrentFileName , file_info .size_filename ) != file_info .size_filename )
1076+ {
1077+ err = UNZ_ERRNO ;
1078+ }
10581079 }
1059- if ((fileNameSize > 0 ) && (fileNameBufferSize > 0 ))
1080+
1081+ if (szFileName != NULL )
10601082 {
1061- if (ZREAD64 ( s -> z_filefunc , s -> filestream , szFileName , uSizeRead ) != uSizeRead )
1083+ if (fileNameBufferSize <= file_info . size_filename )
10621084 {
1063- err = UNZ_ERRNO ;
1085+ memcpy (szFileName , szCurrentFileName , fileNameBufferSize );
1086+ }
1087+ else
1088+ {
1089+ memcpy (szFileName , szCurrentFileName , file_info .size_filename );
1090+ szFileName [file_info .size_filename ] = '\0' ;
10641091 }
10651092 }
10661093 }
0 commit comments