src/share/classes/java/util/zip/ZipInputStream.java
Print this page
*** 1,7 ****
/*
! * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
--- 1,7 ----
/*
! * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
*** 27,36 ****
--- 27,37 ----
import java.io.InputStream;
import java.io.IOException;
import java.io.EOFException;
import java.io.PushbackInputStream;
+ import static java.util.zip.ZipConstants64.*;
/**
* This class implements an input stream filter for reading files in the
* ZIP file format. Includes support for both compressed and uncompressed
* entries.
*** 283,293 ****
--- 284,315 ----
len = get16(tmpbuf, LOCEXT);
if (len > 0) {
byte[] bb = new byte[len];
readFully(bb, 0, len);
e.setExtra(bb);
+ // extra fields are in "HeaderID(2)DataSize(2)Data... format
+ if (e.csize == ZIP64_MAGICVAL || e.size == ZIP64_MAGICVAL) {
+ int off = 0;
+ while (off + 4 < len) {
+ int sz = get16(bb, off + 2);
+ if (get16(bb, off) == ZIP64_EXTID) {
+ off += 4;
+ // LOC extra zip64 entry MUST include BOTH original and
+ // compressed file size fields
+ if (sz < 16 || (off + sz) > len ) {
+ // invalid zip64 extra fields, simply skip.
+ // throw new ZipException("invalid Zip64 extra fields in LOC");
+ return e;
}
+ e.size = get64(bb, off);
+ e.csize = get64(bb, off + 8);
+ break;
+ }
+ off += (sz + 4);
+ }
+ }
+ }
return e;
}
/*
* Fetches a UTF8-encoded String from the specified byte array.
*** 373,382 ****
--- 395,421 ----
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) {
+ // ZIP64 format
+ readFully(tmpbuf, 0, ZIP64_EXTHDR);
+ long sig = get32(tmpbuf, 0);
+ if (sig != EXTSIG) { // no EXTSIG present
+ e.crc = sig;
+ e.csize = get64(tmpbuf, ZIP64_EXTSIZ - ZIP64_EXTCRC);
+ e.size = get64(tmpbuf, ZIP64_EXTLEN - ZIP64_EXTCRC);
+ ((PushbackInputStream)in).unread(
+ tmpbuf, ZIP64_EXTHDR - ZIP64_EXTCRC - 1, ZIP64_EXTCRC);
+ } else {
+ e.crc = get32(tmpbuf, ZIP64_EXTCRC);
+ e.csize = get64(tmpbuf, ZIP64_EXTSIZ);
+ e.size = get64(tmpbuf, ZIP64_EXTLEN);
+ }
+ } else {
readFully(tmpbuf, 0, EXTHDR);
long sig = get32(tmpbuf, 0);
if (sig != EXTSIG) { // no EXTSIG present
e.crc = sig;
e.csize = get32(tmpbuf, EXTSIZ - EXTCRC);
*** 387,396 ****
--- 426,436 ----
e.crc = get32(tmpbuf, EXTCRC);
e.csize = get32(tmpbuf, EXTSIZ);
e.size = get32(tmpbuf, EXTLEN);
}
}
+ }
if (e.size != inf.getBytesWritten()) {
throw new ZipException(
"invalid entry size (expected " + e.size +
" but got " + inf.getBytesWritten() + " bytes)");
}
*** 431,438 ****
/*
* Fetches unsigned 32-bit value from byte array at specified offset.
* The bytes are assumed to be in Intel (little-endian) byte order.
*/
private static final long get32(byte b[], int off) {
! return get16(b, off) | ((long)get16(b, off+2) << 16);
}
}
--- 471,486 ----
/*
* Fetches unsigned 32-bit value from byte array at specified offset.
* The bytes are assumed to be in Intel (little-endian) byte order.
*/
private static final long get32(byte b[], int off) {
! return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL;
}
+
+ /*
+ * Fetches signed 64-bit value from byte array at specified offset.
+ * The bytes are assumed to be in Intel (little-endian) byte order.
+ */
+ private static final long get64(byte b[], int off) {
+ return get32(b, off) | (get32(b, off+4) << 32);
+ }
}