in src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java [1475:1587]
private void readCentralDirectoryEntry(final Map<ZipArchiveEntry, NameAndComment> noUTF8Flag) throws IOException {
cfhBbuf.rewind();
IOUtils.readFully(archive, cfhBbuf);
int off = 0;
final Entry ze = new Entry();
final int versionMadeBy = ZipShort.getValue(cfhBuf, off);
off += ZipConstants.SHORT;
ze.setVersionMadeBy(versionMadeBy);
ze.setPlatform(toPlatform(versionMadeBy));
ze.setVersionRequired(ZipShort.getValue(cfhBuf, off));
off += ZipConstants.SHORT; // version required
final GeneralPurposeBit gpFlag = GeneralPurposeBit.parse(cfhBuf, off);
final boolean hasUTF8Flag = gpFlag.usesUTF8ForNames();
final ZipEncoding entryEncoding = hasUTF8Flag ? ZipEncodingHelper.ZIP_ENCODING_UTF_8 : zipEncoding;
if (hasUTF8Flag) {
ze.setNameSource(ZipArchiveEntry.NameSource.NAME_WITH_EFS_FLAG);
}
ze.setGeneralPurposeBit(gpFlag);
ze.setRawFlag(ZipShort.getValue(cfhBuf, off));
off += ZipConstants.SHORT;
// noinspection MagicConstant
ze.setMethod(ZipShort.getValue(cfhBuf, off));
off += ZipConstants.SHORT;
final long time = ZipUtil.dosToJavaTime(ZipLong.getValue(cfhBuf, off));
ze.setTime(time);
off += ZipConstants.WORD;
ze.setCrc(ZipLong.getValue(cfhBuf, off));
off += ZipConstants.WORD;
long size = ZipLong.getValue(cfhBuf, off);
if (size < 0) {
throw new IOException("broken archive, entry with negative compressed size");
}
ze.setCompressedSize(size);
off += ZipConstants.WORD;
size = ZipLong.getValue(cfhBuf, off);
if (size < 0) {
throw new IOException("broken archive, entry with negative size");
}
ze.setSize(size);
off += ZipConstants.WORD;
final int fileNameLen = ZipShort.getValue(cfhBuf, off);
off += ZipConstants.SHORT;
if (fileNameLen < 0) {
throw new IOException("broken archive, entry with negative fileNameLen");
}
final int extraLen = ZipShort.getValue(cfhBuf, off);
off += ZipConstants.SHORT;
if (extraLen < 0) {
throw new IOException("broken archive, entry with negative extraLen");
}
final int commentLen = ZipShort.getValue(cfhBuf, off);
off += ZipConstants.SHORT;
if (commentLen < 0) {
throw new IOException("broken archive, entry with negative commentLen");
}
ze.setDiskNumberStart(ZipShort.getValue(cfhBuf, off));
off += ZipConstants.SHORT;
ze.setInternalAttributes(ZipShort.getValue(cfhBuf, off));
off += ZipConstants.SHORT;
ze.setExternalAttributes(ZipLong.getValue(cfhBuf, off));
off += ZipConstants.WORD;
final byte[] fileName = IOUtils.readRange(archive, fileNameLen);
if (fileName.length < fileNameLen) {
throw new EOFException();
}
ze.setName(entryEncoding.decode(fileName), fileName);
// LFH offset,
ze.setLocalHeaderOffset(ZipLong.getValue(cfhBuf, off) + firstLocalFileHeaderOffset);
// data offset will be filled later
entries.add(ze);
final byte[] cdExtraData = IOUtils.readRange(archive, extraLen);
if (cdExtraData.length < extraLen) {
throw new EOFException();
}
try {
ze.setCentralDirectoryExtra(cdExtraData);
} catch (final RuntimeException e) {
throw ZipUtil.newZipException("Invalid extra data in entry " + ze.getName(), e);
}
setSizesAndOffsetFromZip64Extra(ze);
sanityCheckLFHOffset(ze);
final byte[] comment = IOUtils.readRange(archive, commentLen);
if (comment.length < commentLen) {
throw new EOFException();
}
ze.setComment(entryEncoding.decode(comment));
if (!hasUTF8Flag && useUnicodeExtraFields) {
noUTF8Flag.put(ze, new NameAndComment(fileName, comment));
}
ze.setStreamContiguous(true);
}