Skip to content

Commit 172c123

Browse files
committed
Expose ability for LocalFileHeader to pull values from CEN
Can be done by extending the zip-reader strategies and calling the method in the post-process protected method.
1 parent 1fef763 commit 172c123

File tree

4 files changed

+54
-2
lines changed

4 files changed

+54
-2
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.9</version>
9+
<version>1.2.0</version>
1010

1111
<name>LL Java ZIP</name>
1212
<description>Lower level ZIP support for Java</description>

src/main/java/software/coley/llzip/part/LocalFileHeader.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import java.io.IOException;
99

10-
import static software.coley.llzip.ZipCompressions.*;
10+
import static software.coley.llzip.ZipCompressions.STORED;
1111

1212
/**
1313
* ZIP LocalFileHeader structure.
@@ -35,8 +35,11 @@ public class LocalFileHeader implements ZipPart, ZipRead {
3535

3636
private transient String fileNameCache;
3737

38+
private ByteData data;
39+
3840
@Override
3941
public void read(ByteData data, long offset) {
42+
this.data = data;
4043
this.offset = offset;
4144
versionNeededToExtract = ByteDataUtil.readWord(data, offset + 4);
4245
generalPurposeBitFlag = ByteDataUtil.readWord(data, offset + 6);
@@ -59,6 +62,43 @@ public void read(ByteData data, long offset) {
5962
fileData = data.sliceOf(offset + 30 + fileNameLength + extraFieldLength, fileDataLength);
6063
}
6164

65+
/**
66+
* When called before being {@link #freeze() frozen} values can be adopted from the linked
67+
* {@link #getLinkedDirectoryFileHeader() CentralDirectoryFileHeader}.
68+
* <br>
69+
* In some cases the {@link LocalFileHeader} file size may be 0, but the authoritative CEN states a non-0 value,
70+
* which you may want to adopt.
71+
*/
72+
public void adoptLinkedCentralDirectoryValues() {
73+
if (data != null && linkedDirectoryFileHeader != null) {
74+
versionNeededToExtract = linkedDirectoryFileHeader.getVersionNeededToExtract();
75+
generalPurposeBitFlag = linkedDirectoryFileHeader.getGeneralPurposeBitFlag();
76+
setCompressionMethod(linkedDirectoryFileHeader.getCompressionMethod());
77+
lastModFileTime = linkedDirectoryFileHeader.getLastModFileTime();
78+
lastModFileDate = linkedDirectoryFileHeader.getLastModFileDate();
79+
setCrc32(linkedDirectoryFileHeader.getCrc32());
80+
setCompressedSize(linkedDirectoryFileHeader.getCompressedSize());
81+
setUncompressedSize(linkedDirectoryFileHeader.getUncompressedSize());
82+
setFileNameLength(linkedDirectoryFileHeader.getFileNameLength());
83+
setFileName(data.sliceOf(offset + 30, fileNameLength));
84+
extraField = data.sliceOf(offset + 30 + fileNameLength, extraFieldLength);
85+
long fileDataLength;
86+
if (compressionMethod == STORED) {
87+
fileDataLength = uncompressedSize;
88+
} else {
89+
fileDataLength = compressedSize;
90+
}
91+
fileData = data.sliceOf(offset + 30 + fileNameLength + extraFieldLength, fileDataLength);
92+
}
93+
}
94+
95+
/**
96+
* Clears the reference to the source {@link ByteData}, preventing further modification.
97+
*/
98+
public void freeze() {
99+
data = null;
100+
}
101+
62102
@Override
63103
public long length() {
64104
return MIN_FIXED_SIZE + fileName.length() + extraField.length() + fileData.length();

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public void read(ZipArchive zip, ByteData data) throws IOException {
5353
zip.getParts().add(file);
5454
directory.link(file);
5555
file.link(directory);
56+
postProcessLocalFileHeader(file);
57+
file.freeze();
5658
offsets.add(offset);
5759
} else {
5860
logger.warn("Central-Directory-File-Header's offset[{}] to Local-File-Header does not match the Local-File-Header magic!", offset);
@@ -61,4 +63,8 @@ public void read(ZipArchive zip, ByteData data) throws IOException {
6163
// Sort based on order
6264
zip.getParts().sort(new OffsetComparator());
6365
}
66+
67+
protected void postProcessLocalFileHeader(LocalFileHeader file) {
68+
// no-op
69+
}
6470
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ else if (ByteDataUtil.startsWith(data, jvmBaseFileOffset, ZipPatterns.CENTRAL_DI
120120
zip.getParts().add(file);
121121
directory.link(file);
122122
file.link(directory);
123+
postProcessLocalFileHeader(file);
124+
file.freeze();
123125
offsets.add(offset);
124126
} catch (Exception ex) {
125127
logger.warn("Failed to read 'local file header' at offset[{}]", offset, ex);
@@ -131,4 +133,8 @@ else if (ByteDataUtil.startsWith(data, jvmBaseFileOffset, ZipPatterns.CENTRAL_DI
131133
// Sort based on order
132134
zip.getParts().sort(new OffsetComparator());
133135
}
136+
137+
protected void postProcessLocalFileHeader(LocalFileHeader file) {
138+
// no-op
139+
}
134140
}

0 commit comments

Comments
 (0)