< prev index next >

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

Print this page
rev 51866 : 6194856: Zip Files lose ALL ownership and permissions of the files

*** 1,7 **** /* ! * Copyright (c) 1996, 2016, Oracle and/or its affiliates. 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. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 1996, 2018, Oracle and/or its affiliates. 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. Oracle designates this
*** 23,40 **** * questions. */ package java.util.zip; ! import java.io.OutputStream; import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; - import java.util.Vector; import java.util.HashSet; ! import static java.util.zip.ZipConstants64.*; ! import static java.util.zip.ZipUtils.*; import sun.security.action.GetPropertyAction; /** * This class implements an output stream filter for writing files in the * ZIP file format. Includes support for both compressed and uncompressed --- 23,42 ---- * questions. */ package java.util.zip; ! import static java.util.zip.ZipConstants64.*; ! import static java.util.zip.ZipUtils.*; ! import java.io.IOException; + import java.io.OutputStream; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.HashSet; ! import java.util.Vector; ! import sun.security.action.GetPropertyAction; /** * This class implements an output stream filter for writing files in the * ZIP file format. Includes support for both compressed and uncompressed
*** 65,74 **** --- 67,78 ---- this.entry = entry; this.offset = offset; } } + private static int VERSION_BASE_UNIX = ZipFile.FILE_ATTRIBUTES_UNIX << 8; + private XEntry current; private Vector<XEntry> xentries = new Vector<>(); private HashSet<String> names = new HashSet<>(); private CRC32 crc = new CRC32(); private long written = 0;
*** 79,97 **** 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. */ private void ensureOpen() throws IOException { if (closed) { throw new IOException("Stream closed"); --- 83,115 ---- private boolean closed = false; private final ZipCoder zc; ! private static int version(ZipEntry e, boolean zip64) ! throws ZipException ! { ! if (zip64) { ! return 45; ! } switch (e.method) { case DEFLATED: return 20; case STORED: return 10; default: throw new ZipException("unsupported compression method"); } } /** + * Adds information about compatibility of file attribute information + * to a version value. + */ + private static int versionMadeBy(ZipEntry e, int version) { + return (e.posixPerms < 0) ? version : + VERSION_BASE_UNIX | (version & 0xff); + } + + /** * Checks to make sure that this stream has not been closed. */ private void ensureOpen() throws IOException { if (closed) { throw new IOException("Stream closed");
*** 384,419 **** * Writes local file (LOC) header for specified entry. */ private void writeLOC(XEntry xentry) throws IOException { ZipEntry e = xentry.entry; int flag = e.flag; ! boolean hasZip64 = false; int elen = getExtraLen(e.extra); writeInt(LOCSIG); // LOC header signature if ((flag & 8) == 8) { ! writeShort(version(e)); // version needed to extract writeShort(flag); // general purpose bit flag writeShort(e.method); // compression method writeInt(e.xdostime); // last modification time // store size, uncompressed size, and crc-32 in data descriptor // immediately following compressed entry data writeInt(0); writeInt(0); writeInt(0); } else { if (e.csize >= ZIP64_MAGICVAL || e.size >= ZIP64_MAGICVAL) { ! hasZip64 = true; ! writeShort(45); // ver 4.5 for zip64 ! } else { ! writeShort(version(e)); // version needed to extract } writeShort(flag); // general purpose bit flag writeShort(e.method); // compression method writeInt(e.xdostime); // last modification time writeInt(e.crc); // crc-32 ! if (hasZip64) { writeInt(ZIP64_MAGICVAL); writeInt(ZIP64_MAGICVAL); elen += 20; //headid(2) + size(2) + size(8) + csize(8) } else { writeInt(e.csize); // compressed size --- 402,435 ---- * Writes local file (LOC) header for specified entry. */ private void writeLOC(XEntry xentry) throws IOException { ZipEntry e = xentry.entry; int flag = e.flag; ! boolean zip64 = false; int elen = getExtraLen(e.extra); writeInt(LOCSIG); // LOC header signature if ((flag & 8) == 8) { ! writeShort(version(e, zip64)); // version needed to extract writeShort(flag); // general purpose bit flag writeShort(e.method); // compression method writeInt(e.xdostime); // last modification time // store size, uncompressed size, and crc-32 in data descriptor // immediately following compressed entry data writeInt(0); writeInt(0); writeInt(0); } else { if (e.csize >= ZIP64_MAGICVAL || e.size >= ZIP64_MAGICVAL) { ! zip64 = true; } + writeShort(version(e, zip64)); // version needed to extract writeShort(flag); // general purpose bit flag writeShort(e.method); // compression method writeInt(e.xdostime); // last modification time writeInt(e.crc); // crc-32 ! if (zip64) { writeInt(ZIP64_MAGICVAL); writeInt(ZIP64_MAGICVAL); elen += 20; //headid(2) + size(2) + size(8) + csize(8) } else { writeInt(e.csize); // compressed size
*** 453,463 **** elen += (elenEXTT + 5); // headid(2) + size(2) + flag(1) + data } } writeShort(elen); writeBytes(nameBytes, 0, nameBytes.length); ! if (hasZip64) { writeShort(ZIP64_EXTID); writeShort(16); writeLong(e.size); writeLong(e.csize); } --- 469,479 ---- elen += (elenEXTT + 5); // headid(2) + size(2) + flag(1) + data } } writeShort(elen); writeBytes(nameBytes, 0, nameBytes.length); ! if (zip64) { writeShort(ZIP64_EXTID); writeShort(16); writeLong(e.size); writeLong(e.csize); }
*** 510,563 **** /* * Write central directory (CEN) header for specified entry. * REMIND: add support for file attributes */ private void writeCEN(XEntry xentry) throws IOException { ! ZipEntry e = xentry.entry; int flag = e.flag; - int version = version(e); long csize = e.csize; long size = e.size; long offset = xentry.offset; int elenZIP64 = 0; ! boolean hasZip64 = false; ! if (e.csize >= ZIP64_MAGICVAL) { csize = ZIP64_MAGICVAL; ! elenZIP64 += 8; // csize(8) ! hasZip64 = true; } if (e.size >= ZIP64_MAGICVAL) { size = ZIP64_MAGICVAL; // size(8) elenZIP64 += 8; ! hasZip64 = true; } if (xentry.offset >= ZIP64_MAGICVAL) { offset = ZIP64_MAGICVAL; ! elenZIP64 += 8; // offset(8) ! hasZip64 = true; } writeInt(CENSIG); // CEN header signature ! if (hasZip64) { ! writeShort(45); // ver 4.5 for zip64 ! writeShort(45); ! } else { ! writeShort(version); // version made by ! writeShort(version); // version needed to extract ! } writeShort(flag); // general purpose bit flag writeShort(e.method); // compression method writeInt(e.xdostime); // last modification time writeInt(e.crc); // crc-32 writeInt(csize); // compressed size writeInt(size); // uncompressed size byte[] nameBytes = zc.getBytes(e.name); writeShort(nameBytes.length); int elen = getExtraLen(e.extra); ! if (hasZip64) { ! elen += (elenZIP64 + 4);// + headid(2) + datasize(2) } // cen info-zip extended timestamp only outputs mtime // but set the flag for a/ctime, if present in loc int flagEXTT = 0; long umtime = -1; --- 526,574 ---- /* * Write central directory (CEN) header for specified entry. * REMIND: add support for file attributes */ private void writeCEN(XEntry xentry) throws IOException { ! ZipEntry e = xentry.entry; int flag = e.flag; long csize = e.csize; long size = e.size; long offset = xentry.offset; int elenZIP64 = 0; ! boolean zip64 = false; if (e.csize >= ZIP64_MAGICVAL) { csize = ZIP64_MAGICVAL; ! elenZIP64 += 8; // csize(8) ! zip64 = true; } if (e.size >= ZIP64_MAGICVAL) { size = ZIP64_MAGICVAL; // size(8) elenZIP64 += 8; ! zip64 = true; } if (xentry.offset >= ZIP64_MAGICVAL) { offset = ZIP64_MAGICVAL; ! elenZIP64 += 8; // offset(8) ! zip64 = true; } + int version = version(e, zip64); + writeInt(CENSIG); // CEN header signature ! writeShort(versionMadeBy(e, version)); // version made by ! writeShort(version); // version needed to extract writeShort(flag); // general purpose bit flag writeShort(e.method); // compression method writeInt(e.xdostime); // last modification time writeInt(e.crc); // crc-32 writeInt(csize); // compressed size writeInt(size); // uncompressed size byte[] nameBytes = zc.getBytes(e.name); writeShort(nameBytes.length); int elen = getExtraLen(e.extra); ! if (zip64) { ! elen += (elenZIP64 + 4); // + headid(2) + datasize(2) } // cen info-zip extended timestamp only outputs mtime // but set the flag for a/ctime, if present in loc int flagEXTT = 0; long umtime = -1;
*** 596,611 **** commentBytes = null; writeShort(0); } writeShort(0); // starting disk number writeShort(0); // internal file attributes (unused) ! writeInt(0); // external file attributes (unused) writeInt(offset); // relative offset of local header writeBytes(nameBytes, 0, nameBytes.length); // take care of EXTID_ZIP64 and EXTID_EXTT ! if (hasZip64) { writeShort(ZIP64_EXTID);// Zip64 extra writeShort(elenZIP64); if (size == ZIP64_MAGICVAL) writeLong(e.size); if (csize == ZIP64_MAGICVAL) --- 607,624 ---- commentBytes = null; writeShort(0); } writeShort(0); // starting disk number writeShort(0); // internal file attributes (unused) ! writeInt(e.posixPerms > 0 ? e.posixPerms << 16 : 0); // external file ! // attributes, used for storing posix ! // permissions writeInt(offset); // relative offset of local header writeBytes(nameBytes, 0, nameBytes.length); // take care of EXTID_ZIP64 and EXTID_EXTT ! if (zip64) { writeShort(ZIP64_EXTID);// Zip64 extra writeShort(elenZIP64); if (size == ZIP64_MAGICVAL) writeLong(e.size); if (csize == ZIP64_MAGICVAL)
*** 648,676 **** /* * Writes end of central directory (END) header. */ private void writeEND(long off, long len) throws IOException { ! boolean hasZip64 = false; long xlen = len; long xoff = off; if (xlen >= ZIP64_MAGICVAL) { xlen = ZIP64_MAGICVAL; ! hasZip64 = true; } if (xoff >= ZIP64_MAGICVAL) { xoff = ZIP64_MAGICVAL; ! hasZip64 = true; } int count = xentries.size(); if (count >= ZIP64_MAGICCOUNT) { ! hasZip64 |= !inhibitZip64; ! if (hasZip64) { count = ZIP64_MAGICCOUNT; } } ! if (hasZip64) { long off64 = written; //zip64 end of central directory record writeInt(ZIP64_ENDSIG); // zip64 END record signature writeLong(ZIP64_ENDHDR - 12); // size of zip64 end writeShort(45); // version made by --- 661,689 ---- /* * Writes end of central directory (END) header. */ private void writeEND(long off, long len) throws IOException { ! boolean zip64 = false; long xlen = len; long xoff = off; if (xlen >= ZIP64_MAGICVAL) { xlen = ZIP64_MAGICVAL; ! zip64 = true; } if (xoff >= ZIP64_MAGICVAL) { xoff = ZIP64_MAGICVAL; ! zip64 = true; } int count = xentries.size(); if (count >= ZIP64_MAGICCOUNT) { ! zip64 |= !inhibitZip64; ! if (zip64) { count = ZIP64_MAGICCOUNT; } } ! if (zip64) { long off64 = written; //zip64 end of central directory record writeInt(ZIP64_ENDSIG); // zip64 END record signature writeLong(ZIP64_ENDHDR - 12); // size of zip64 end writeShort(45); // version made by
< prev index next >