--- a/jdk/src/java.base/share/classes/java/util/zip/ZipOutputStream.java Fri Jul 22 16:05:23 2016 +0100
+++ b/jdk/src/java.base/share/classes/java/util/zip/ZipOutputStream.java Fri Jul 22 16:32:48 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -421,22 +421,36 @@
byte[] nameBytes = zc.getBytes(e.name);
writeShort(nameBytes.length);
- int elenEXTT = 0; // info-zip extended timestamp
+ int elenEXTT = 0; // info-zip extended timestamp
int flagEXTT = 0;
+ long umtime = -1;
+ long uatime = -1;
+ long uctime = -1;
if (e.mtime != null) {
elenEXTT += 4;
flagEXTT |= EXTT_FLAG_LMT;
+ umtime = fileTimeToUnixTime(e.mtime);
}
if (e.atime != null) {
elenEXTT += 4;
flagEXTT |= EXTT_FLAG_LAT;
+ uatime = fileTimeToUnixTime(e.atime);
}
if (e.ctime != null) {
elenEXTT += 4;
flagEXTT |= EXTT_FLAT_CT;
+ uctime = fileTimeToUnixTime(e.ctime);
}
- if (flagEXTT != 0)
- elen += (elenEXTT + 5); // headid(2) + size(2) + flag(1) + data
+ if (flagEXTT != 0) {
+ // to use ntfs time if any m/a/ctime is beyond unixtime upper bound
+ if (umtime > UPPER_UNIXTIME_BOUND ||
+ uatime > UPPER_UNIXTIME_BOUND ||
+ uctime > UPPER_UNIXTIME_BOUND) {
+ elen += 36; // NTFS time, total 36 bytes
+ } else {
+ elen += (elenEXTT + 5); // headid(2) + size(2) + flag(1) + data
+ }
+ }
writeShort(elen);
writeBytes(nameBytes, 0, nameBytes.length);
if (hasZip64) {
@@ -446,15 +460,31 @@
writeLong(e.csize);
}
if (flagEXTT != 0) {
- writeShort(EXTID_EXTT);
- writeShort(elenEXTT + 1); // flag + data
- writeByte(flagEXTT);
- if (e.mtime != null)
- writeInt(fileTimeToUnixTime(e.mtime));
- if (e.atime != null)
- writeInt(fileTimeToUnixTime(e.atime));
- if (e.ctime != null)
- writeInt(fileTimeToUnixTime(e.ctime));
+ if (umtime > UPPER_UNIXTIME_BOUND ||
+ uatime > UPPER_UNIXTIME_BOUND ||
+ uctime > UPPER_UNIXTIME_BOUND) {
+ writeShort(EXTID_NTFS); // id
+ writeShort(32); // data size
+ writeInt(0); // reserved
+ writeShort(0x0001); // NTFS attr tag
+ writeShort(24);
+ writeLong(e.mtime == null ? WINDOWS_TIME_NOT_AVAILABLE
+ : fileTimeToWinTime(e.mtime));
+ writeLong(e.atime == null ? WINDOWS_TIME_NOT_AVAILABLE
+ : fileTimeToWinTime(e.atime));
+ writeLong(e.ctime == null ? WINDOWS_TIME_NOT_AVAILABLE
+ : fileTimeToWinTime(e.ctime));
+ } else {
+ writeShort(EXTID_EXTT);
+ writeShort(elenEXTT + 1); // flag + data
+ writeByte(flagEXTT);
+ if (e.mtime != null)
+ writeInt(umtime);
+ if (e.atime != null)
+ writeInt(uatime);
+ if (e.ctime != null)
+ writeInt(uctime);
+ }
}
writeExtra(e.extra);
locoff = written;
@@ -528,18 +558,30 @@
// 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;
+ long uatime = -1;
+ long uctime = -1;
if (e.mtime != null) {
- elen += 4; // + mtime(4)
flagEXTT |= EXTT_FLAG_LMT;
+ umtime = fileTimeToUnixTime(e.mtime);
}
if (e.atime != null) {
flagEXTT |= EXTT_FLAG_LAT;
+ uatime = fileTimeToUnixTime(e.atime);
}
if (e.ctime != null) {
flagEXTT |= EXTT_FLAT_CT;
+ uctime = fileTimeToUnixTime(e.ctime);
}
if (flagEXTT != 0) {
- elen += 5; // headid + sz + flag
+ // to use ntfs time if any m/a/ctime is beyond unixtime upper bound
+ if (umtime > UPPER_UNIXTIME_BOUND ||
+ uatime > UPPER_UNIXTIME_BOUND ||
+ uctime > UPPER_UNIXTIME_BOUND) {
+ elen += 36; // NTFS time total 36 bytes
+ } else {
+ elen += 9; // headid(2) + sz(2) + flag(1) + mtime (4)
+ }
}
writeShort(elen);
byte[] commentBytes;
@@ -568,14 +610,30 @@
writeLong(xentry.offset);
}
if (flagEXTT != 0) {
- writeShort(EXTID_EXTT);
- if (e.mtime != null) {
- writeShort(5); // flag + mtime
- writeByte(flagEXTT);
- writeInt(fileTimeToUnixTime(e.mtime));
+ if (umtime > UPPER_UNIXTIME_BOUND ||
+ uatime > UPPER_UNIXTIME_BOUND ||
+ uctime > UPPER_UNIXTIME_BOUND) {
+ writeShort(EXTID_NTFS); // id
+ writeShort(32); // data size
+ writeInt(0); // reserved
+ writeShort(0x0001); // NTFS attr tag
+ writeShort(24);
+ writeLong(e.mtime == null ? WINDOWS_TIME_NOT_AVAILABLE
+ : fileTimeToWinTime(e.mtime));
+ writeLong(e.atime == null ? WINDOWS_TIME_NOT_AVAILABLE
+ : fileTimeToWinTime(e.atime));
+ writeLong(e.ctime == null ? WINDOWS_TIME_NOT_AVAILABLE
+ : fileTimeToWinTime(e.ctime));
} else {
- writeShort(1); // flag only
- writeByte(flagEXTT);
+ writeShort(EXTID_EXTT);
+ if (e.mtime != null) {
+ writeShort(5); // flag + mtime
+ writeByte(flagEXTT);
+ writeInt(umtime);
+ } else {
+ writeShort(1); // flag only
+ writeByte(flagEXTT);
+ }
}
}
writeExtra(e.extra);