22
33import org .slf4j .Logger ;
44import org .slf4j .LoggerFactory ;
5- import software .coley .llzip .format .model .ZipArchive ;
65import software .coley .llzip .format .ZipPatterns ;
7- import software .coley .llzip .format .model .CentralDirectoryFileHeader ;
8- import software .coley .llzip .format .model .EndOfCentralDirectory ;
9- import software .coley .llzip .format .model .JvmLocalFileHeader ;
10- import software .coley .llzip .format .model .LocalFileHeader ;
6+ import software .coley .llzip .format .model .*;
117import software .coley .llzip .util .ByteData ;
128import software .coley .llzip .util .ByteDataUtil ;
139import software .coley .llzip .util .OffsetComparator ;
@@ -37,16 +33,20 @@ public void read(ZipArchive zip, ByteData data) throws IOException {
3733 if (endOfCentralDirectoryOffset < 0L )
3834 throw new IOException ("No Central-Directory-File-Header found!" );
3935
36+ // Check for a prior end, indicating a preceding ZIP file.
37+ long precedingEndOfCentralDirectory = ByteDataUtil .lastIndexOf (data , endOfCentralDirectoryOffset - 1 , ZipPatterns .END_OF_CENTRAL_DIRECTORY );
38+
4039 // Read end header
4140 EndOfCentralDirectory end = new EndOfCentralDirectory ();
4241 end .read (data , endOfCentralDirectoryOffset );
4342 zip .getParts ().add (end );
4443
45- // Read central directories
44+ // Read central directories (going from the back to the front) up until the preceding ZIP file (if any)
4645 long len = data .length ();
4746 long centralDirectoryOffset = len - ZipPatterns .CENTRAL_DIRECTORY_FILE_HEADER .length ;
4847 long maxRelativeOffset = 0 ;
49- while (centralDirectoryOffset > 0L ) {
48+ long centralDirectoryOffsetScanEnd = Math .max (precedingEndOfCentralDirectory , 0 );
49+ while (centralDirectoryOffset > centralDirectoryOffsetScanEnd ) {
5050 centralDirectoryOffset = ByteDataUtil .lastIndexOf (data , centralDirectoryOffset - 1L , ZipPatterns .CENTRAL_DIRECTORY_FILE_HEADER );
5151 if (centralDirectoryOffset >= 0L ) {
5252 CentralDirectoryFileHeader directory = new CentralDirectoryFileHeader ();
@@ -60,7 +60,6 @@ public void read(ZipArchive zip, ByteData data) throws IOException {
6060 // Determine base offset for computing file header locations with.
6161 // - If there is a preceding block of another zip, start with that.
6262 long jvmBaseFileOffset ;
63- long precedingEndOfCentralDirectory = ByteDataUtil .lastIndexOf (data , endOfCentralDirectoryOffset - 1 , ZipPatterns .END_OF_CENTRAL_DIRECTORY );
6463 if (precedingEndOfCentralDirectory == endOfCentralDirectoryOffset ) {
6564 // The prior end part match is target end part, so we can't use it as a base offset.
6665 jvmBaseFileOffset = 0L ;
0 commit comments