Skip to content

Commit 92d708a

Browse files
committed
Fix JvmZipReaderStrategy including data beyond the bounds of the current ZIP
If you have 2 zips concatenated, it was seeking into the first when it should only access headers from the second. Zip 1: - A.class Zip 2: - B.class If Zip 2 says the main class is A using 'java -jar' will not find it because it won't read the contents of the first zip.
1 parent 0fa0a0d commit 92d708a

File tree

2 files changed

+7
-8
lines changed

2 files changed

+7
-8
lines changed

src/main/java/software/coley/llzip/format/read/JvmZipReaderStrategy.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@
22

33
import org.slf4j.Logger;
44
import org.slf4j.LoggerFactory;
5-
import software.coley.llzip.format.model.ZipArchive;
65
import 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.*;
117
import software.coley.llzip.util.ByteData;
128
import software.coley.llzip.util.ByteDataUtil;
139
import 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;

src/test/resources/xxx.jar

1.22 KB
Binary file not shown.

0 commit comments

Comments
 (0)