in src/main/java/org/apache/commons/compress/archivers/zip/ZipArchiveInputStream.java [662:809]
public ZipArchiveEntry getNextZipEntry() throws IOException {
uncompressedCount = 0;
boolean firstEntry = true;
if (closed || hitCentralDirectory) {
return null;
}
if (current != null) {
closeEntry();
firstEntry = false;
}
final long currentHeaderOffset = getBytesRead();
try {
if (firstEntry) {
// split archives have a special signature before the
// first local file header - look for it and fail with
// the appropriate error message if this is a split
// archive.
if (!readFirstLocalFileHeader()) {
hitCentralDirectory = true;
skipRemainderOfArchive();
return null;
}
} else {
readFully(lfhBuf);
}
} catch (final EOFException e) { // NOSONAR
return null;
}
final ZipLong sig = new ZipLong(lfhBuf);
if (!sig.equals(ZipLong.LFH_SIG)) {
if (sig.equals(ZipLong.CFH_SIG) || sig.equals(ZipLong.AED_SIG) || isApkSigningBlock(lfhBuf)) {
hitCentralDirectory = true;
skipRemainderOfArchive();
return null;
}
throw new ZipException(String.format("Unexpected record signature: 0x%x", sig.getValue()));
}
// off: go past the signature
int off = WORD;
current = new CurrentEntry();
// get version
final int versionMadeBy = ZipShort.getValue(lfhBuf, off);
off += SHORT;
current.entry.setPlatform(ZipFile.toPlatform(versionMadeBy));
final GeneralPurposeBit gpFlag = GeneralPurposeBit.parse(lfhBuf, off);
final boolean hasUTF8Flag = gpFlag.usesUTF8ForNames();
final ZipEncoding entryEncoding = hasUTF8Flag ? ZipEncodingHelper.ZIP_ENCODING_UTF_8 : zipEncoding;
current.hasDataDescriptor = gpFlag.usesDataDescriptor();
current.entry.setGeneralPurposeBit(gpFlag);
off += SHORT;
current.entry.setMethod(ZipShort.getValue(lfhBuf, off));
off += SHORT;
final long time = ZipUtil.dosToJavaTime(ZipLong.getValue(lfhBuf, off));
current.entry.setTime(time);
off += WORD;
ZipLong size = null;
ZipLong cSize = null;
if (!current.hasDataDescriptor) {
current.entry.setCrc(ZipLong.getValue(lfhBuf, off));
off += WORD;
cSize = new ZipLong(lfhBuf, off);
off += WORD;
size = new ZipLong(lfhBuf, off);
off += WORD;
} else {
off += 3 * WORD;
}
final int fileNameLen = ZipShort.getValue(lfhBuf, off);
off += SHORT;
final int extraLen = ZipShort.getValue(lfhBuf, off);
off += SHORT; // NOSONAR - assignment as documentation
final byte[] fileName = readRange(fileNameLen);
current.entry.setName(entryEncoding.decode(fileName), fileName);
if (hasUTF8Flag) {
current.entry.setNameSource(ZipArchiveEntry.NameSource.NAME_WITH_EFS_FLAG);
}
final byte[] extraData = readRange(extraLen);
try {
current.entry.setExtra(extraData);
} catch (final RuntimeException ex) {
throw ZipUtil.newZipException("Invalid extra data in entry " + current.entry.getName(), ex);
}
if (!hasUTF8Flag && useUnicodeExtraFields) {
ZipUtil.setNameAndCommentFromExtraFields(current.entry, fileName, null);
}
processZip64Extra(size, cSize);
current.entry.setLocalHeaderOffset(currentHeaderOffset);
current.entry.setDataOffset(getBytesRead());
current.entry.setStreamContiguous(true);
final ZipMethod m = ZipMethod.getMethodByCode(current.entry.getMethod());
if (current.entry.getCompressedSize() != ArchiveEntry.SIZE_UNKNOWN) {
if (ZipUtil.canHandleEntryData(current.entry) && m != ZipMethod.STORED && m != ZipMethod.DEFLATED) {
final InputStream bis = new BoundCountInputStream(in, current.entry.getCompressedSize());
switch (m) {
case UNSHRINKING:
current.inputStream = new UnshrinkingInputStream(bis);
break;
case IMPLODING:
try {
current.inputStream = new ExplodingInputStream(current.entry.getGeneralPurposeBit().getSlidingDictionarySize(),
current.entry.getGeneralPurposeBit().getNumberOfShannonFanoTrees(), bis);
} catch (final IllegalArgumentException ex) {
throw new IOException("bad IMPLODE data", ex);
}
break;
case BZIP2:
current.inputStream = new BZip2CompressorInputStream(bis);
break;
case ENHANCED_DEFLATED:
current.inputStream = new Deflate64CompressorInputStream(bis);
break;
case ZSTD:
case ZSTD_DEPRECATED:
current.inputStream = createZstdInputStream(bis);
break;
default:
// we should never get here as all supported methods have been covered
// will cause an error when read is invoked, don't throw an exception here so people can
// skip unsupported entries
break;
}
}
} else if (m == ZipMethod.ENHANCED_DEFLATED) {
current.inputStream = new Deflate64CompressorInputStream(in);
}
entriesRead++;
return current.entry;
}