private void resolveLocalFileHeaderData( final Map<ZipEntry, NameAndComment> entriesWithoutUTF8Flag) throws IOException { for (final Entry ze : this.entries) { final OffsetEntry offsetEntry = ze.getOffsetEntry(); final long offset = offsetEntry.headerOffset; this.archive.seek(offset + 26L); this.archive.readFully(this.SHORT_BUF); final int fileNameLen = ZipShort.getValue(this.SHORT_BUF); this.archive.readFully(this.SHORT_BUF); final int extraFieldLen = ZipShort.getValue(this.SHORT_BUF); int skipped; for (int lenToSkip = fileNameLen; lenToSkip > 0; lenToSkip -= skipped) { skipped = this.archive.skipBytes(lenToSkip); if (skipped <= 0) { throw new IOException("failed to skip file name in local file header"); } } final byte[] localExtraData = new byte[extraFieldLen]; this.archive.readFully(localExtraData); ze.setExtra(localExtraData); offsetEntry.dataOffset = offset + 26L + 2L + 2L + fileNameLen + extraFieldLen; if (entriesWithoutUTF8Flag.containsKey(ze)) { final NameAndComment nc = entriesWithoutUTF8Flag.get(ze); ZipUtil.setNameAndCommentFromExtraFields(ze, nc.name, nc.comment); } final String name = ze.getName(); LinkedList<ZipEntry> entriesOfThatName = this.nameMap.get(name); if (entriesOfThatName == null) { entriesOfThatName = new LinkedList<ZipEntry>(); this.nameMap.put(name, entriesOfThatName); } entriesOfThatName.addLast(ze); } }
private void readCentralDirectoryEntry(final Map<ZipEntry, NameAndComment> noUTF8Flag) throws IOException { this.archive.readFully(this.CFH_BUF); int off = 0; final OffsetEntry offset = new OffsetEntry(); final Entry ze = new Entry(offset); final int versionMadeBy = ZipShort.getValue(this.CFH_BUF, off); off += 2; ze.setPlatform(versionMadeBy >> 8 & 0xF); off += 2; final GeneralPurposeBit gpFlag = GeneralPurposeBit.parse(this.CFH_BUF, off); final boolean hasUTF8Flag = gpFlag.usesUTF8ForNames(); final ZipEncoding entryEncoding = hasUTF8Flag ? ZipEncodingHelper.UTF8_ZIP_ENCODING : this.zipEncoding; ze.setGeneralPurposeBit(gpFlag); off += 2; ze.setMethod(ZipShort.getValue(this.CFH_BUF, off)); off += 2; final long time = ZipUtil.dosToJavaTime(ZipLong.getValue(this.CFH_BUF, off)); ze.setTime(time); off += 4; ze.setCrc(ZipLong.getValue(this.CFH_BUF, off)); off += 4; ze.setCompressedSize(ZipLong.getValue(this.CFH_BUF, off)); off += 4; ze.setSize(ZipLong.getValue(this.CFH_BUF, off)); off += 4; final int fileNameLen = ZipShort.getValue(this.CFH_BUF, off); off += 2; final int extraLen = ZipShort.getValue(this.CFH_BUF, off); off += 2; final int commentLen = ZipShort.getValue(this.CFH_BUF, off); off += 2; final int diskStart = ZipShort.getValue(this.CFH_BUF, off); off += 2; ze.setInternalAttributes(ZipShort.getValue(this.CFH_BUF, off)); off += 2; ze.setExternalAttributes(ZipLong.getValue(this.CFH_BUF, off)); off += 4; final byte[] fileName = new byte[fileNameLen]; this.archive.readFully(fileName); ze.setName(entryEncoding.decode(fileName), fileName); offset.headerOffset = ZipLong.getValue(this.CFH_BUF, off); this.entries.add(ze); final byte[] cdExtraData = new byte[extraLen]; this.archive.readFully(cdExtraData); ze.setCentralDirectoryExtra(cdExtraData); this.setSizesAndOffsetFromZip64Extra(ze, offset, diskStart); final byte[] comment = new byte[commentLen]; this.archive.readFully(comment); ze.setComment(entryEncoding.decode(comment)); if (!hasUTF8Flag && this.useUnicodeExtraFields) { noUTF8Flag.put(ze, new NameAndComment(fileName, comment)); } }
private void setSizesAndOffsetFromZip64Extra( final ZipEntry ze, final OffsetEntry offset, final int diskStart) throws IOException { final Zip64ExtendedInformationExtraField z64 = (Zip64ExtendedInformationExtraField) ze.getExtraField(Zip64ExtendedInformationExtraField.HEADER_ID); if (z64 != null) { final boolean hasUncompressedSize = ze.getSize() == 4294967295L; final boolean hasCompressedSize = ze.getCompressedSize() == 4294967295L; final boolean hasRelativeHeaderOffset = offset.headerOffset == 4294967295L; z64.reparseCentralDirectoryData( hasUncompressedSize, hasCompressedSize, hasRelativeHeaderOffset, diskStart == 65535); if (hasUncompressedSize) { ze.setSize(z64.getSize().getLongValue()); } else if (hasCompressedSize) { z64.setSize(new ZipEightByteInteger(ze.getSize())); } if (hasCompressedSize) { ze.setCompressedSize(z64.getCompressedSize().getLongValue()); } else if (hasUncompressedSize) { z64.setCompressedSize(new ZipEightByteInteger(ze.getCompressedSize())); } if (hasRelativeHeaderOffset) { offset.headerOffset = z64.getRelativeHeaderOffset().getLongValue(); } } }