< 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 >