extract logic that calculates data offset in ZipFile
import java.util.zip.Inflater;
import java.util.zip.ZipException;
+import org.apache.commons.compress.archivers.EntryStreamOffsets;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.commons.compress.compressors.deflate64.Deflate64CompressorInputStream;
import org.apache.commons.compress.utils.CountingInputStream;
@@ -441,6 +442,9 @@ public InputStream getRawInputStream(final ZipArchiveEntry ze) {
return null;
}
final long start = ze.getDataOffset();
+ if (start == EntryStreamOffsets.OFFSET_UNKNOWN) {
+ return null;
+ }
return createBoundedInputStream(start, ze.getCompressedSize());
}
@@ -480,7 +484,7 @@ public InputStream getInputStream(final ZipArchiveEntry ze)
}
// cast validity is checked just above
ZipUtil.checkRequestedFeatures(ze);
- final long start = ze.getDataOffset();
+ final long start = getDataOffset(ze);
// doesn't get closed if the method is not supported - which
// should never happen because of the checkRequestedFeatures
@@ -1045,21 +1049,13 @@ private void resolveLocalFileHeaderData(final Map<ZipArchiveEntry, NameAndCommen
// entries is filled in populateFromCentralDirectory and
// never modified
final Entry ze = (Entry) zipArchiveEntry;
- final long offset = ze.getLocalHeaderOffset();
- archive.position(offset + LFH_OFFSET_FOR_FILENAME_LENGTH);
- wordBbuf.rewind();
- IOUtils.readFully(archive, wordBbuf);
- wordBbuf.flip();
- wordBbuf.get(shortBuf);
- final int fileNameLen = ZipShort.getValue(shortBuf);
- wordBbuf.get(shortBuf);
- final int extraFieldLen = ZipShort.getValue(shortBuf);
+ int[] lens = setDataOffset(ze);
+ final int fileNameLen = lens[0];
+ final int extraFieldLen = lens[1];
skipBytes(fileNameLen);
final byte[] localExtraData = new byte[extraFieldLen];
IOUtils.readFully(archive, ByteBuffer.wrap(localExtraData));
ze.setExtra(localExtraData);
- ze.setDataOffset(offset + LFH_OFFSET_FOR_FILENAME_LENGTH
- + SHORT + SHORT + fileNameLen + extraFieldLen);
ze.setStreamContiguous(true);
if (entriesWithoutUTF8Flag.containsKey(ze)) {
@@ -1078,6 +1074,30 @@ private void resolveLocalFileHeaderData(final Map<ZipArchiveEntry, NameAndCommen
}
}
+ private int[] setDataOffset(ZipArchiveEntry ze) throws IOException {
+ final long offset = ze.getLocalHeaderOffset();
+ archive.position(offset + LFH_OFFSET_FOR_FILENAME_LENGTH);
+ wordBbuf.rewind();
+ IOUtils.readFully(archive, wordBbuf);
+ wordBbuf.flip();
+ wordBbuf.get(shortBuf);
+ final int fileNameLen = ZipShort.getValue(shortBuf);
+ wordBbuf.get(shortBuf);
+ final int extraFieldLen = ZipShort.getValue(shortBuf);
+ ze.setDataOffset(offset + LFH_OFFSET_FOR_FILENAME_LENGTH
+ + SHORT + SHORT + fileNameLen + extraFieldLen);
+ return new int[] { fileNameLen, extraFieldLen };
+ }
+
+ private long getDataOffset(ZipArchiveEntry ze) throws IOException {
+ long s = ze.getDataOffset();
+ if (s == EntryStreamOffsets.OFFSET_UNKNOWN) {
+ setDataOffset(ze);
+ return ze.getDataOffset();
+ }
+ return s;
+ }
+
/**
* Checks whether the archive starts with a LFH. If it doesn't,
* it may be an empty archive.
