@@ -43,12 +43,15 @@ public void read(ZipArchive zip, ByteData data) throws IOException {
4343 // Read central directories
4444 long len = data .length ();
4545 long centralDirectoryOffset = len - ZipPatterns .CENTRAL_DIRECTORY_FILE_HEADER .length ;
46+ long maxRelativeOffset = 0 ;
4647 while (centralDirectoryOffset > 0L ) {
4748 centralDirectoryOffset = ByteDataUtil .lastIndexOf (data , centralDirectoryOffset - 1L , ZipPatterns .CENTRAL_DIRECTORY_FILE_HEADER );
4849 if (centralDirectoryOffset >= 0L ) {
4950 CentralDirectoryFileHeader directory = new CentralDirectoryFileHeader ();
5051 directory .read (data , centralDirectoryOffset );
5152 zip .getParts ().add (directory );
53+ if (directory .getRelativeOffsetOfLocalHeader () > maxRelativeOffset )
54+ maxRelativeOffset = directory .getRelativeOffsetOfLocalHeader ();
5255 }
5356 }
5457 // Determine base offset for computing file header locations with.
@@ -83,20 +86,14 @@ else if (ByteDataUtil.startsWith(data, jvmBaseFileOffset, ZipPatterns.CENTRAL_DI
8386 // Make sure it isn't bogus before we use it as a reference point
8487 EndOfCentralDirectory tempEnd = new EndOfCentralDirectory ();
8588 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 ();
8894 // TODO: Double check 'precedingEndOfCentralDirectory' points to a EndOfCentralDirectory that isn't bogus
8995 // like some shit defined as a fake comment in another ZipPart.
9096 // - 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-
10097 jvmBaseFileOffset = precedingEndOfCentralDirectory + tempEnd .length ();
10198 } catch (Exception ex ) {
10299 // It's bogus and the sig-match was a coincidence. Zero out the offset.
0 commit comments