--- old/src/share/classes/java/util/zip/ZipInputStream.java Wed Apr 1 08:39:31 2009 +++ new/src/share/classes/java/util/zip/ZipInputStream.java Wed Apr 1 08:39:30 2009 @@ -1,5 +1,5 @@ /* - * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -29,6 +29,7 @@ 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 @@ -285,6 +286,27 @@ 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; } @@ -375,18 +397,36 @@ } if ((flag & 8) == 8) { /* "Data Descriptor" present */ - readFully(tmpbuf, 0, EXTHDR); - long sig = get32(tmpbuf, 0); - if (sig != EXTSIG) { // no EXTSIG present - e.crc = sig; - e.csize = get32(tmpbuf, EXTSIZ - EXTCRC); - e.size = get32(tmpbuf, EXTLEN - EXTCRC); - ((PushbackInputStream)in).unread( - tmpbuf, EXTHDR - EXTCRC - 1, EXTCRC); + 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 { - e.crc = get32(tmpbuf, EXTCRC); - e.csize = get32(tmpbuf, EXTSIZ); - e.size = get32(tmpbuf, EXTLEN); + readFully(tmpbuf, 0, EXTHDR); + long sig = get32(tmpbuf, 0); + if (sig != EXTSIG) { // no EXTSIG present + e.crc = sig; + e.csize = get32(tmpbuf, EXTSIZ - EXTCRC); + e.size = get32(tmpbuf, EXTLEN - EXTCRC); + ((PushbackInputStream)in).unread( + tmpbuf, EXTHDR - EXTCRC - 1, EXTCRC); + } else { + e.crc = get32(tmpbuf, EXTCRC); + e.csize = get32(tmpbuf, EXTSIZ); + e.size = get32(tmpbuf, EXTLEN); + } } } if (e.size != inf.getBytesWritten()) { @@ -433,6 +473,14 @@ * 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); + 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); + } }