< prev index next >
src/java.base/share/classes/java/util/zip/ZipInputStream.java
Print this page
*** 57,66 ****
--- 57,68 ----
// one entry
private boolean entryEOF = false;
private ZipCoder zc;
+ private ZipCryption zipCryption;
+
/**
* Check to make sure that this stream has not been closed
*/
private void ensureOpen() throws IOException {
if (closed) {
*** 111,127 ****
* @return the next ZIP file entry, or null if there are no more entries
* @exception ZipException if a ZIP file error has occurred
* @exception IOException if an I/O error has occurred
*/
public ZipEntry getNextEntry() throws IOException {
ensureOpen();
if (entry != null) {
closeEntry();
}
crc.reset();
inf.reset();
! if ((entry = readLOC()) == null) {
return null;
}
if (entry.method == STORED) {
remaining = entry.size;
}
--- 113,142 ----
* @return the next ZIP file entry, or null if there are no more entries
* @exception ZipException if a ZIP file error has occurred
* @exception IOException if an I/O error has occurred
*/
public ZipEntry getNextEntry() throws IOException {
+ return getNextEntry(null);
+ }
+
+ /**
+ * Reads the next ZIP file entry and positions the stream at the
+ * beginning of the entry data.
+ * @param zipCryption ZIP encrypt/decrypt engine. zip decryption will not
+ * work if this value set to null.
+ * @return the next ZIP file entry, or null if there are no more entries
+ * @exception ZipException if a ZIP file error has occurred
+ * @exception IOException if an I/O error has occurred
+ */
+ public ZipEntry getNextEntry(ZipCryption zipCryption) throws IOException {
ensureOpen();
if (entry != null) {
closeEntry();
}
crc.reset();
inf.reset();
! if ((entry = readLOC(zipCryption)) == null) {
return null;
}
if (entry.method == STORED) {
remaining = entry.size;
}
*** 211,220 ****
--- 226,238 ----
}
len = in.read(b, off, len);
if (len == -1) {
throw new ZipException("unexpected EOF");
}
+ if (zipCryption != null) {
+ zipCryption.decryptBytes(b, off, len);
+ }
crc.update(b, off, len);
remaining -= len;
if (remaining == 0 && entry.crc != crc.getValue()) {
throw new ZipException(
"invalid entry CRC (expected 0x" + Long.toHexString(entry.crc) +
*** 271,290 ****
private byte[] b = new byte[256];
/*
* Reads local file (LOC) header for next entry.
*/
! private ZipEntry readLOC() throws IOException {
try {
readFully(tmpbuf, 0, LOCHDR);
} catch (EOFException e) {
return null;
}
if (get32(tmpbuf, 0) != LOCSIG) {
return null;
}
! // get flag first, we need check EFS.
flag = get16(tmpbuf, LOCFLG);
// get the entry name and create the ZipEntry first
int len = get16(tmpbuf, LOCNAM);
int blen = b.length;
if (len > blen) {
--- 289,310 ----
private byte[] b = new byte[256];
/*
* Reads local file (LOC) header for next entry.
*/
! private ZipEntry readLOC(ZipCryption zipCryption) throws IOException {
! this.zipCryption = zipCryption;
!
try {
readFully(tmpbuf, 0, LOCHDR);
} catch (EOFException e) {
return null;
}
if (get32(tmpbuf, 0) != LOCSIG) {
return null;
}
! // get flag first, we need check EFS and encryption.
flag = get16(tmpbuf, LOCFLG);
// get the entry name and create the ZipEntry first
int len = get16(tmpbuf, LOCNAM);
int blen = b.length;
if (len > blen) {
*** 296,308 ****
readFully(b, 0, len);
// Force to use UTF-8 if the EFS bit is ON, even the cs is NOT UTF-8
ZipEntry e = createZipEntry(((flag & EFS) != 0)
? zc.toStringUTF8(b, len)
: zc.toString(b, len));
// now get the remaining fields for the entry
! if ((flag & 1) == 1) {
! throw new ZipException("encrypted ZIP entry not supported");
}
e.method = get16(tmpbuf, LOCHOW);
e.xdostime = get32(tmpbuf, LOCTIM);
if ((flag & 8) == 8) {
/* "Data Descriptor" present */
--- 316,329 ----
readFully(b, 0, len);
// Force to use UTF-8 if the EFS bit is ON, even the cs is NOT UTF-8
ZipEntry e = createZipEntry(((flag & EFS) != 0)
? zc.toStringUTF8(b, len)
: zc.toString(b, len));
+ e.flag = flag;
// now get the remaining fields for the entry
! if (((flag & 1) == 1) && (zipCryption == null)) {
! throw new ZipException("ZipCryption is required.");
}
e.method = get16(tmpbuf, LOCHOW);
e.xdostime = get32(tmpbuf, LOCTIM);
if ((flag & 8) == 8) {
/* "Data Descriptor" present */
*** 320,329 ****
--- 341,366 ----
byte[] extra = new byte[len];
readFully(extra, 0, len);
e.setExtra0(extra,
e.csize == ZIP64_MAGICVAL || e.size == ZIP64_MAGICVAL);
}
+
+ if (zipCryption != null) {
+ zipCryption.reset();
+ super.setZipCryption(zipCryption);
+
+ byte[] encryptionHeader =
+ new byte[zipCryption.getEncryptionHeaderSize()];
+ readFully(encryptionHeader, 0, encryptionHeader.length);
+ zipCryption.decryptBytes(encryptionHeader);
+
+ if (!zipCryption.isValid(e, encryptionHeader)) {
+ throw new ZipException("possibly incorrect passphrase");
+ }
+
+ }
+
return e;
}
/**
* Creates a new <code>ZipEntry</code> object for the specified
*** 353,363 ****
* compatibility."""
*/
private void readEnd(ZipEntry e) throws IOException {
int n = inf.getRemaining();
if (n > 0) {
! ((PushbackInputStream)in).unread(buf, len - n, n);
}
if ((flag & 8) == 8) {
/* "Data Descriptor" present */
if (inf.getBytesWritten() > ZIP64_MAGICVAL ||
inf.getBytesRead() > ZIP64_MAGICVAL) {
--- 390,401 ----
* compatibility."""
*/
private void readEnd(ZipEntry e) throws IOException {
int n = inf.getRemaining();
if (n > 0) {
! ((PushbackInputStream)in).unread(
! (zipCryption == null) ? buf : originBuf, len - n, n);
}
if ((flag & 8) == 8) {
/* "Data Descriptor" present */
if (inf.getBytesWritten() > ZIP64_MAGICVAL ||
inf.getBytesRead() > ZIP64_MAGICVAL) {
*** 394,403 ****
--- 432,444 ----
if (e.size != inf.getBytesWritten()) {
throw new ZipException(
"invalid entry size (expected " + e.size +
" but got " + inf.getBytesWritten() + " bytes)");
}
+ if (zipCryption != null) {
+ e.csize -= zipCryption.getEncryptionHeaderSize();
+ }
if (e.csize != inf.getBytesRead()) {
throw new ZipException(
"invalid entry compressed size (expected " + e.csize +
" but got " + inf.getBytesRead() + " bytes)");
}
< prev index next >