Skip to content

Commit 20266c3

Browse files
committed
fix: Less hacky junk detection for determining if 'precedingEndOfCentralDirectory' is valid
1 parent 2561a40 commit 20266c3

File tree

2 files changed

+9
-12
lines changed

2 files changed

+9
-12
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>software.coley</groupId>
88
<artifactId>lljzip</artifactId>
9-
<version>1.1.7</version>
9+
<version>1.1.8</version>
1010

1111
<properties>
1212
<junit.version>5.8.2</junit.version>

src/main/java/software/coley/llzip/strategy/JvmZipReaderStrategy.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)