@@ -43,12 +43,15 @@ public void read(ZipArchive zip, ByteData data) throws IOException {
43
43
// Read central directories
44
44
long len = data .length ();
45
45
long centralDirectoryOffset = len - ZipPatterns .CENTRAL_DIRECTORY_FILE_HEADER .length ;
46
+ long maxRelativeOffset = 0 ;
46
47
while (centralDirectoryOffset > 0L ) {
47
48
centralDirectoryOffset = ByteDataUtil .lastIndexOf (data , centralDirectoryOffset - 1L , ZipPatterns .CENTRAL_DIRECTORY_FILE_HEADER );
48
49
if (centralDirectoryOffset >= 0L ) {
49
50
CentralDirectoryFileHeader directory = new CentralDirectoryFileHeader ();
50
51
directory .read (data , centralDirectoryOffset );
51
52
zip .getParts ().add (directory );
53
+ if (directory .getRelativeOffsetOfLocalHeader () > maxRelativeOffset )
54
+ maxRelativeOffset = directory .getRelativeOffsetOfLocalHeader ();
52
55
}
53
56
}
54
57
// Determine base offset for computing file header locations with.
@@ -83,20 +86,14 @@ else if (ByteDataUtil.startsWith(data, jvmBaseFileOffset, ZipPatterns.CENTRAL_DI
83
86
// Make sure it isn't bogus before we use it as a reference point
84
87
EndOfCentralDirectory tempEnd = new EndOfCentralDirectory ();
85
88
tempEnd .read (data , precedingEndOfCentralDirectory );
86
-
87
-
89
+ // If we use this as a point of reference there must be enough data remaining
90
+ // to read the largest offset specified by our central directories.
91
+ long hypotheticalJvmBaseOffset = precedingEndOfCentralDirectory + tempEnd .length ();
92
+ if (len <= hypotheticalJvmBaseOffset + maxRelativeOffset )
93
+ throw new IllegalStateException ();
88
94
// TODO: Double check 'precedingEndOfCentralDirectory' points to a EndOfCentralDirectory that isn't bogus
89
95
// like some shit defined as a fake comment in another ZipPart.
90
96
// - Needs to be done in such a way where we do not get tricked by the '-trick.jar' samples
91
- // This is a quick hack.
92
- if (tempEnd .getCentralDirectorySize () > len )
93
- throw new IllegalStateException ();
94
- if (tempEnd .getCentralDirectoryOffset () > tempEnd .getNumEntries ())
95
- throw new IllegalStateException ();
96
- if (tempEnd .getDiskNumber () == 0 && tempEnd .getNumEntries () != tempEnd .getCentralDirectoryOffset ())
97
- throw new IllegalStateException ();
98
-
99
-
100
97
jvmBaseFileOffset = precedingEndOfCentralDirectory + tempEnd .length ();
101
98
} catch (Exception ex ) {
102
99
// It's bogus and the sig-match was a coincidence. Zero out the offset.
0 commit comments