< prev index next >

src/java.base/share/classes/java/util/zip/ZipOutputStream.java

Print this page

        

*** 79,94 **** private boolean closed = false; private final ZipCoder zc; ! private static int version(ZipEntry e) throws ZipException { switch (e.method) { ! case DEFLATED: return 20; ! case STORED: return 10; ! default: throw new ZipException("unsupported compression method"); } } /** * Checks to make sure that this stream has not been closed. */ --- 79,116 ---- private boolean closed = false; private final ZipCoder zc; ! private ZipCryption zipCryption; ! ! private int version(ZipEntry e) throws ZipException { ! int result; ! switch (e.method) { ! case DEFLATED: ! result = 20; ! break; ! ! case STORED: ! result = 10; ! break; ! ! default: ! throw new ZipException("unsupported compression method"); } + + /* + * Zip Crypto is defined version 2.0 or later. + * 4.4.3.2 Current minimum feature versions + * https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT + */ + if (zipCryption != null) { + result = 20; + } + + return result; } /** * Checks to make sure that this stream has not been closed. */
*** 165,176 **** } this.method = method; } /** - * Sets the compression level for subsequent entries which are DEFLATED. * The default setting is DEFAULT_COMPRESSION. * @param level the compression level (0-9) * @exception IllegalArgumentException if the compression level is invalid */ public void setLevel(int level) { def.setLevel(level); --- 187,198 ---- } this.method = method; } /** * The default setting is DEFAULT_COMPRESSION. + * Sets the compression level for subsequent entries which are DEFLATED. * @param level the compression level (0-9) * @exception IllegalArgumentException if the compression level is invalid */ public void setLevel(int level) { def.setLevel(level);
*** 189,198 **** --- 211,225 ---- public void putNextEntry(ZipEntry e) throws IOException { ensureOpen(); if (current != null) { closeEntry(); // close previous entry } + zipCryption = e.zipCryption; + super.setZipCryption(zipCryption); + if (zipCryption != null) { + zipCryption.reset(); + } if (e.xdostime == -1) { // by default, do NOT use extended timestamps in extra // data, for now. e.setTime(System.currentTimeMillis()); }
*** 222,243 **** --- 249,281 ---- } if (e.size == -1 || e.crc == -1) { throw new ZipException( "STORED entry missing size, compressed size, or crc-32"); } + if (zipCryption != null) { + e.csize += zipCryption.getEncryptionHeaderSize(); + } break; default: throw new ZipException("unsupported compression method"); } if (! names.add(e.name)) { throw new ZipException("duplicate entry: " + e.name); } if (zc.isUTF8()) e.flag |= EFS; + if (zipCryption != null) + e.flag |= 1; // Bit 0: If set, indicates that the file is encrypted. current = new XEntry(e, written); xentries.add(current); writeLOC(current); + + if (zipCryption != null) { + byte[] encryptionHeader = zipCryption.getEncryptionHeader(e); + writeBytes(encryptionHeader, 0, encryptionHeader.length); + locoff += encryptionHeader.length; + } } /** * Closes the current ZIP entry and positions the stream for writing * the next entry.
*** 278,287 **** --- 316,334 ---- e.crc = crc.getValue(); writeEXT(e); } def.reset(); written += e.csize; + + if (zipCryption != null) { + /* Substruct sizeof encryption header. + * This value adds in writeBytes() when encryption header + * is written. + */ + written -= zipCryption.getEncryptionHeaderSize(); + } + break; case STORED: // we already know that both e.size and e.csize are the same if (e.size != written - locoff) { throw new ZipException(
*** 327,349 **** } ZipEntry entry = current.entry; switch (entry.method) { case DEFLATED: super.write(b, off, len); break; case STORED: written += len; if (written - locoff > entry.size) { throw new ZipException( "attempt to write past end of STORED entry"); } out.write(b, off, len); break; default: throw new ZipException("invalid compression method"); } - crc.update(b, off, len); } /** * Finishes writing the contents of the ZIP output stream without closing * the underlying stream. Use this method when applying multiple filters --- 374,403 ---- } ZipEntry entry = current.entry; switch (entry.method) { case DEFLATED: super.write(b, off, len); + crc.update(b, off, len); break; case STORED: written += len; if (written - locoff > entry.size) { throw new ZipException( "attempt to write past end of STORED entry"); } + + crc.update(b, off, len); + + if (zipCryption != null) { + zipCryption.encryptBytes(b, off, len); + } + out.write(b, off, len); break; default: throw new ZipException("invalid compression method"); } } /** * Finishes writing the contents of the ZIP output stream without closing * the underlying stream. Use this method when applying multiple filters
*** 465,474 **** --- 519,533 ---- * Writes extra data descriptor (EXT) for specified entry. */ private void writeEXT(ZipEntry e) throws IOException { writeInt(EXTSIG); // EXT header signature writeInt(e.crc); // crc-32 + + if (zipCryption != null) { + e.csize += zipCryption.getEncryptionHeaderSize(); + } + if (e.csize >= ZIP64_MAGICVAL || e.size >= ZIP64_MAGICVAL) { writeLong(e.csize); writeLong(e.size); } else { writeInt(e.csize); // compressed size
< prev index next >