@@ -58,28 +58,11 @@ public void read(ZipArchive zip, ByteData data) throws IOException {
5858 }
5959
6060 // Determine base offset for computing file header locations with.
61- // - If there is a preceding block of another zip, start with that.
62- long jvmBaseFileOffset ;
63- if (precedingEndOfCentralDirectory == -1L ) {
64- // There was no match for a prior end part. We will seek forwards until finding a *VALID* PK starting header.
65- jvmBaseFileOffset = ByteDataUtil .indexOf (data , ZipPatterns .PK );
66- while (jvmBaseFileOffset >= 0L ) {
67- // Check that the PK discovered represents a valid zip part
68- try {
69- if (ByteDataUtil .startsWith (data , jvmBaseFileOffset , ZipPatterns .LOCAL_FILE_HEADER ))
70- new LocalFileHeader ().read (data , jvmBaseFileOffset );
71- else if (ByteDataUtil .startsWith (data , jvmBaseFileOffset , ZipPatterns .CENTRAL_DIRECTORY_FILE_HEADER ))
72- new CentralDirectoryFileHeader ().read (data , jvmBaseFileOffset );
73- else
74- throw new IllegalStateException ("No match for LocalFileHeader/CentralDirectoryFileHeader" );
75- // Valid, we're good to go
76- break ;
77- } catch (Exception ex ) {
78- // Invalid, seek forward
79- jvmBaseFileOffset = ByteDataUtil .indexOf (data , jvmBaseFileOffset + 1L , ZipPatterns .PK );
80- }
81- }
82- } else {
61+ long jvmBaseFileOffset = 0 ;
62+ boolean priorZipEndWasBogus = false ;
63+
64+ // If there is a preceding block of another zip, start with that.
65+ if (precedingEndOfCentralDirectory != -1 ) {
8366 // There was a prior end part, so we will seek past it's length and use that as the base offset.
8467 try {
8568 // Make sure it isn't bogus before we use it as a reference point
@@ -97,8 +80,31 @@ else if (ByteDataUtil.startsWith(data, jvmBaseFileOffset, ZipPatterns.CENTRAL_DI
9780 // - Needs to be done in such a way where we do not get tricked by the '-trick.jar' samples
9881 jvmBaseFileOffset = precedingEndOfCentralDirectory + tempEnd .length ();
9982 } catch (Exception ex ) {
100- // It's bogus and the sig-match was a coincidence. Use the first PK match instead.
101- jvmBaseFileOffset = ByteDataUtil .indexOf (data , ZipPatterns .PK );
83+ // It's bogus and the sig-match was a coincidence.
84+ priorZipEndWasBogus = true ;
85+ }
86+ }
87+
88+ // Search for the first valid PK header if there was either no prior ZIP file
89+ // or if the prior ZIP detection was bogus.
90+ if (priorZipEndWasBogus || precedingEndOfCentralDirectory == -1L ) {
91+ // There was no match for a prior end part. We will seek forwards until finding a *VALID* PK starting header.
92+ jvmBaseFileOffset = ByteDataUtil .indexOf (data , ZipPatterns .PK );
93+ while (jvmBaseFileOffset >= 0L ) {
94+ // Check that the PK discovered represents a valid zip part
95+ try {
96+ if (ByteDataUtil .startsWith (data , jvmBaseFileOffset , ZipPatterns .LOCAL_FILE_HEADER ))
97+ new LocalFileHeader ().read (data , jvmBaseFileOffset );
98+ else if (ByteDataUtil .startsWith (data , jvmBaseFileOffset , ZipPatterns .CENTRAL_DIRECTORY_FILE_HEADER ))
99+ new CentralDirectoryFileHeader ().read (data , jvmBaseFileOffset );
100+ else
101+ throw new IllegalStateException ("No match for LocalFileHeader/CentralDirectoryFileHeader" );
102+ // Valid, we're good to go
103+ break ;
104+ } catch (Exception ex ) {
105+ // Invalid, seek forward
106+ jvmBaseFileOffset = ByteDataUtil .indexOf (data , jvmBaseFileOffset + 1L , ZipPatterns .PK );
107+ }
102108 }
103109 }
104110
0 commit comments