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