< prev index next >

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

Print this page

        

*** 321,331 **** --- 321,359 ---- * @throws ZipException if a ZIP format error has occurred * @throws IOException if an I/O error has occurred * @throws IllegalStateException if the zip file has been closed */ public InputStream getInputStream(ZipEntry entry) throws IOException { + return getInputStream(entry, null); + } + + /** + * Returns an input stream for reading the contents of the specified + * zip file entry. + * <p> + * Closing this ZIP file will, in turn, close all input streams that + * have been returned by invocations of this method. + * + * @param entry the zip file entry + * @param zipCryption ZIP encrypt/decrypt engine. zip decryption will not + * work if this value set to null. + * @return the input stream for reading the contents of the specified + * zip file entry. + * @throws ZipException if a ZIP format error has occurred + * @throws IOException if an I/O error has occurred + * @throws IllegalStateException if the zip file has been closed + * @since 1.9 + */ + public InputStream getInputStream(ZipEntry entry, ZipCryption zipCryption) + throws IOException { Objects.requireNonNull(entry, "entry"); + + if ((entry.flag & 1) == 1) { + Objects.requireNonNull(zipCryption, "Passphrase is required"); + zipCryption.reset(); + } + int pos = -1; ZipFileInputStream in = null; synchronized (this) { ensureOpen(); if (!zc.isUTF8() && (entry.flag & EFS) != 0) {
*** 334,346 **** pos = zsrc.getEntryPos(zc.getBytes(entry.name), false); } if (pos == -1) { return null; } ! in = new ZipFileInputStream(zsrc.cen, pos); switch (CENHOW(zsrc.cen, pos)) { case STORED: synchronized (streams) { streams.put(in, null); } return in; case DEFLATED: --- 362,384 ---- pos = zsrc.getEntryPos(zc.getBytes(entry.name), false); } if (pos == -1) { return null; } ! in = new ZipFileInputStream(zsrc.cen, pos, zipCryption); switch (CENHOW(zsrc.cen, pos)) { case STORED: + if((entry.flag & 1) == 1) { + byte[] encryptionHeader = + new byte[zipCryption.getEncryptionHeaderSize()]; + in.readRaw(encryptionHeader, 0, encryptionHeader.length); + zipCryption.decryptBytes(encryptionHeader); + + if (!zipCryption.isValid(entry, encryptionHeader)) { + throw new ZipException("possibly incorrect passphrase"); + } + } synchronized (streams) { streams.put(in, null); } return in; case DEFLATED:
*** 352,361 **** --- 390,411 ---- } if (size <= 0) { size = 4096; } Inflater inf = getInflater(); + + if((entry.flag & 1) == 1) { + byte[] encryptionHeader = + new byte[zipCryption.getEncryptionHeaderSize()]; + in.readRaw(encryptionHeader, 0, encryptionHeader.length); + zipCryption.decryptBytes(encryptionHeader); + + if (!zipCryption.isValid(entry, encryptionHeader)) { + throw new ZipException("possibly incorrect passphrase"); + } + } + InputStream is = new ZipFileInflaterInputStream(in, inf, (int)size); synchronized (streams) { streams.put(is, inf); } return is;
*** 655,676 **** private class ZipFileInputStream extends InputStream { private volatile boolean closeRequested = false; private long pos; // current position within entry data protected long rem; // number of remaining bytes within entry protected long size; // uncompressed size of this entry ! ZipFileInputStream(byte[] cen, int cenpos) throws IOException { rem = CENSIZ(cen, cenpos); size = CENLEN(cen, cenpos); pos = CENOFF(cen, cenpos); // zip64 if (rem == ZIP64_MAGICVAL || size == ZIP64_MAGICVAL || pos == ZIP64_MAGICVAL) { checkZIP64(cen, cenpos); } // negative for lazy initialization, see getDataOffset(); pos = - (pos + ZipFile.this.zsrc.locpos); } private void checkZIP64(byte[] cen, int cenpos) throws IOException { int off = cenpos + CENHDR + CENNAM(cen, cenpos); int end = off + CENEXT(cen, cenpos); --- 705,729 ---- private class ZipFileInputStream extends InputStream { private volatile boolean closeRequested = false; private long pos; // current position within entry data protected long rem; // number of remaining bytes within entry protected long size; // uncompressed size of this entry + private ZipCryption zipCryption; // ZIP encrypt/decrypt engine ! ZipFileInputStream(byte[] cen, int cenpos, ZipCryption zipCryption) ! throws IOException { rem = CENSIZ(cen, cenpos); size = CENLEN(cen, cenpos); pos = CENOFF(cen, cenpos); // zip64 if (rem == ZIP64_MAGICVAL || size == ZIP64_MAGICVAL || pos == ZIP64_MAGICVAL) { checkZIP64(cen, cenpos); } // negative for lazy initialization, see getDataOffset(); pos = - (pos + ZipFile.this.zsrc.locpos); + this.zipCryption = zipCryption; } private void checkZIP64(byte[] cen, int cenpos) throws IOException { int off = cenpos + CENHDR + CENNAM(cen, cenpos); int end = off + CENEXT(cen, cenpos);
*** 728,737 **** --- 781,800 ---- } return pos; } public int read(byte b[], int off, int len) throws IOException { + len = readRaw(b, off, len); + + if (zipCryption != null) { + zipCryption.decryptBytes(b, off, len); + } + + return len; + } + + public int readRaw(byte b[], int off, int len) throws IOException { synchronized (ZipFile.this) { ensureOpenOrZipException(); initDataOffset(); if (rem == 0) { return -1;
*** 1177,1188 **** zerror("invalid CEN header (bad signature)"); int method = CENHOW(cen, pos); int nlen = CENNAM(cen, pos); int elen = CENEXT(cen, pos); int clen = CENCOM(cen, pos); - if ((CENFLG(cen, pos) & 1) != 0) - zerror("invalid CEN header (encrypted entry)"); if (method != STORED && method != DEFLATED) zerror("invalid CEN header (bad compression method: " + method + ")"); if (pos + CENHDR + nlen > limit) zerror("invalid CEN header (bad header size)"); // Record the CEN offset and the name hash in our hash cell. --- 1240,1249 ----
< prev index next >