1 /* 2 * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.util.zip; 27 28 import java.nio.ByteBuffer; 29 import java.nio.file.attribute.FileTime; 30 import java.time.DateTimeException; 31 import java.time.Instant; 32 import java.time.LocalDateTime; 33 import java.time.ZoneId; 34 import java.util.Date; 35 import java.util.concurrent.TimeUnit; 36 37 import static java.util.zip.ZipConstants.ENDHDR; 38 39 import jdk.internal.misc.Unsafe; 40 41 class ZipUtils { 42 43 // used to adjust values between Windows and java epoch 44 private static final long WINDOWS_EPOCH_IN_MICROSECONDS = -11644473600000000L; 45 46 // used to indicate the corresponding windows time is not available 47 public static final long WINDOWS_TIME_NOT_AVAILABLE = Long.MIN_VALUE; 48 49 // static final ByteBuffer defaultBuf = ByteBuffer.allocateDirect(0); 50 static final ByteBuffer defaultBuf = ByteBuffer.allocate(0); 51 52 /** 53 * Converts Windows time (in microseconds, UTC/GMT) time to FileTime. 54 */ winTimeToFileTime(long wtime)55 public static final FileTime winTimeToFileTime(long wtime) { 56 return FileTime.from(wtime / 10 + WINDOWS_EPOCH_IN_MICROSECONDS, 57 TimeUnit.MICROSECONDS); 58 } 59 60 /** 61 * Converts FileTime to Windows time. 62 */ fileTimeToWinTime(FileTime ftime)63 public static final long fileTimeToWinTime(FileTime ftime) { 64 return (ftime.to(TimeUnit.MICROSECONDS) - WINDOWS_EPOCH_IN_MICROSECONDS) * 10; 65 } 66 67 /** 68 * The upper bound of the 32-bit unix time, the "year 2038 problem". 69 */ 70 public static final long UPPER_UNIXTIME_BOUND = 0x7fffffff; 71 72 /** 73 * Converts "standard Unix time"(in seconds, UTC/GMT) to FileTime 74 */ unixTimeToFileTime(long utime)75 public static final FileTime unixTimeToFileTime(long utime) { 76 return FileTime.from(utime, TimeUnit.SECONDS); 77 } 78 79 /** 80 * Converts FileTime to "standard Unix time". 81 */ fileTimeToUnixTime(FileTime ftime)82 public static final long fileTimeToUnixTime(FileTime ftime) { 83 return ftime.to(TimeUnit.SECONDS); 84 } 85 86 /** 87 * Converts DOS time to Java time (number of milliseconds since epoch). 88 */ dosToJavaTime(long dtime)89 public static long dosToJavaTime(long dtime) { 90 int year = (int) (((dtime >> 25) & 0x7f) + 1980); 91 int month = (int) ((dtime >> 21) & 0x0f); 92 int day = (int) ((dtime >> 16) & 0x1f); 93 int hour = (int) ((dtime >> 11) & 0x1f); 94 int minute = (int) ((dtime >> 5) & 0x3f); 95 int second = (int) ((dtime << 1) & 0x3e); 96 97 if (month > 0 && month < 13 && day > 0 && hour < 24 && minute < 60 && second < 60) { 98 try { 99 LocalDateTime ldt = LocalDateTime.of(year, month, day, hour, minute, second); 100 return TimeUnit.MILLISECONDS.convert(ldt.toEpochSecond( 101 ZoneId.systemDefault().getRules().getOffset(ldt)), TimeUnit.SECONDS); 102 } catch (DateTimeException dte) { 103 // ignore 104 } 105 } 106 return overflowDosToJavaTime(year, month, day, hour, minute, second); 107 } 108 109 /* 110 * Deal with corner cases where an arguably mal-formed DOS time is used 111 */ 112 @SuppressWarnings("deprecation") // Use of Date constructor overflowDosToJavaTime(int year, int month, int day, int hour, int minute, int second)113 private static long overflowDosToJavaTime(int year, int month, int day, 114 int hour, int minute, int second) { 115 return new Date(year - 1900, month - 1, day, hour, minute, second).getTime(); 116 } 117 118 119 /** 120 * Converts extended DOS time to Java time, where up to 1999 milliseconds 121 * might be encoded into the upper half of the returned long. 122 * 123 * @param xdostime the extended DOS time value 124 * @return milliseconds since epoch 125 */ extendedDosToJavaTime(long xdostime)126 public static long extendedDosToJavaTime(long xdostime) { 127 long time = dosToJavaTime(xdostime); 128 return time + (xdostime >> 32); 129 } 130 131 /** 132 * Converts Java time to DOS time. 133 */ javaToDosTime(LocalDateTime ldt)134 private static long javaToDosTime(LocalDateTime ldt) { 135 int year = ldt.getYear() - 1980; 136 return (year << 25 | 137 ldt.getMonthValue() << 21 | 138 ldt.getDayOfMonth() << 16 | 139 ldt.getHour() << 11 | 140 ldt.getMinute() << 5 | 141 ldt.getSecond() >> 1) & 0xffffffffL; 142 } 143 144 /** 145 * Converts Java time to DOS time, encoding any milliseconds lost 146 * in the conversion into the upper half of the returned long. 147 * 148 * @param time milliseconds since epoch 149 * @return DOS time with 2s remainder encoded into upper half 150 */ javaToExtendedDosTime(long time)151 static long javaToExtendedDosTime(long time) { 152 LocalDateTime ldt = javaEpochToLocalDateTime(time); 153 if (ldt.getYear() >= 1980) { 154 return javaToDosTime(ldt) + ((time % 2000) << 32); 155 } 156 return ZipEntry.DOSTIME_BEFORE_1980; 157 } 158 javaEpochToLocalDateTime(long time)159 static LocalDateTime javaEpochToLocalDateTime(long time) { 160 Instant instant = Instant.ofEpochMilli(time); 161 return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()); 162 } 163 164 /** 165 * Fetches unsigned 16-bit value from byte array at specified offset. 166 * The bytes are assumed to be in Intel (little-endian) byte order. 167 */ get16(byte b[], int off)168 public static final int get16(byte b[], int off) { 169 return (b[off] & 0xff) | ((b[off + 1] & 0xff) << 8); 170 } 171 172 /** 173 * Fetches unsigned 32-bit value from byte array at specified offset. 174 * The bytes are assumed to be in Intel (little-endian) byte order. 175 */ get32(byte b[], int off)176 public static final long get32(byte b[], int off) { 177 return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL; 178 } 179 180 /** 181 * Fetches signed 64-bit value from byte array at specified offset. 182 * The bytes are assumed to be in Intel (little-endian) byte order. 183 */ get64(byte b[], int off)184 public static final long get64(byte b[], int off) { 185 return get32(b, off) | (get32(b, off+4) << 32); 186 } 187 188 /** 189 * Fetches signed 32-bit value from byte array at specified offset. 190 * The bytes are assumed to be in Intel (little-endian) byte order. 191 * 192 */ get32S(byte b[], int off)193 public static final int get32S(byte b[], int off) { 194 return (get16(b, off) | (get16(b, off+2) << 16)); 195 } 196 197 // fields access methods CH(byte[] b, int n)198 static final int CH(byte[] b, int n) { 199 return b[n] & 0xff ; 200 } 201 SH(byte[] b, int n)202 static final int SH(byte[] b, int n) { 203 return (b[n] & 0xff) | ((b[n + 1] & 0xff) << 8); 204 } 205 LG(byte[] b, int n)206 static final long LG(byte[] b, int n) { 207 return ((SH(b, n)) | (SH(b, n + 2) << 16)) & 0xffffffffL; 208 } 209 LL(byte[] b, int n)210 static final long LL(byte[] b, int n) { 211 return (LG(b, n)) | (LG(b, n + 4) << 32); 212 } 213 GETSIG(byte[] b)214 static final long GETSIG(byte[] b) { 215 return LG(b, 0); 216 } 217 218 /* 219 * File attribute compatibility types of CEN field "version made by" 220 */ 221 static final int FILE_ATTRIBUTES_UNIX = 3; // Unix 222 223 /* 224 * Base values for CEN field "version made by" 225 */ 226 static final int VERSION_MADE_BY_BASE_UNIX = FILE_ATTRIBUTES_UNIX << 8; // Unix 227 228 229 // local file (LOC) header fields LOCSIG(byte[] b)230 static final long LOCSIG(byte[] b) { return LG(b, 0); } // signature LOCVER(byte[] b)231 static final int LOCVER(byte[] b) { return SH(b, 4); } // version needed to extract LOCFLG(byte[] b)232 static final int LOCFLG(byte[] b) { return SH(b, 6); } // general purpose bit flags LOCHOW(byte[] b)233 static final int LOCHOW(byte[] b) { return SH(b, 8); } // compression method LOCTIM(byte[] b)234 static final long LOCTIM(byte[] b) { return LG(b, 10);} // modification time LOCCRC(byte[] b)235 static final long LOCCRC(byte[] b) { return LG(b, 14);} // crc of uncompressed data LOCSIZ(byte[] b)236 static final long LOCSIZ(byte[] b) { return LG(b, 18);} // compressed data size LOCLEN(byte[] b)237 static final long LOCLEN(byte[] b) { return LG(b, 22);} // uncompressed data size LOCNAM(byte[] b)238 static final int LOCNAM(byte[] b) { return SH(b, 26);} // filename length LOCEXT(byte[] b)239 static final int LOCEXT(byte[] b) { return SH(b, 28);} // extra field length 240 241 // extra local (EXT) header fields EXTCRC(byte[] b)242 static final long EXTCRC(byte[] b) { return LG(b, 4);} // crc of uncompressed data EXTSIZ(byte[] b)243 static final long EXTSIZ(byte[] b) { return LG(b, 8);} // compressed size EXTLEN(byte[] b)244 static final long EXTLEN(byte[] b) { return LG(b, 12);} // uncompressed size 245 246 // end of central directory header (END) fields ENDSUB(byte[] b)247 static final int ENDSUB(byte[] b) { return SH(b, 8); } // number of entries on this disk ENDTOT(byte[] b)248 static final int ENDTOT(byte[] b) { return SH(b, 10);} // total number of entries ENDSIZ(byte[] b)249 static final long ENDSIZ(byte[] b) { return LG(b, 12);} // central directory size ENDOFF(byte[] b)250 static final long ENDOFF(byte[] b) { return LG(b, 16);} // central directory offset ENDCOM(byte[] b)251 static final int ENDCOM(byte[] b) { return SH(b, 20);} // size of zip file comment ENDCOM(byte[] b, int off)252 static final int ENDCOM(byte[] b, int off) { return SH(b, off + 20);} 253 254 // zip64 end of central directory recoder fields ZIP64_ENDTOD(byte[] b)255 static final long ZIP64_ENDTOD(byte[] b) { return LL(b, 24);} // total number of entries on disk ZIP64_ENDTOT(byte[] b)256 static final long ZIP64_ENDTOT(byte[] b) { return LL(b, 32);} // total number of entries ZIP64_ENDSIZ(byte[] b)257 static final long ZIP64_ENDSIZ(byte[] b) { return LL(b, 40);} // central directory size ZIP64_ENDOFF(byte[] b)258 static final long ZIP64_ENDOFF(byte[] b) { return LL(b, 48);} // central directory offset ZIP64_LOCOFF(byte[] b)259 static final long ZIP64_LOCOFF(byte[] b) { return LL(b, 8);} // zip64 end offset 260 261 // central directory header (CEN) fields CENSIG(byte[] b, int pos)262 static final long CENSIG(byte[] b, int pos) { return LG(b, pos + 0); } CENVEM(byte[] b, int pos)263 static final int CENVEM(byte[] b, int pos) { return SH(b, pos + 4); } CENVEM_FA(byte[] b, int pos)264 static final int CENVEM_FA(byte[] b, int pos) { return CH(b, pos + 5); } // file attribute compatibility CENVER(byte[] b, int pos)265 static final int CENVER(byte[] b, int pos) { return SH(b, pos + 6); } CENFLG(byte[] b, int pos)266 static final int CENFLG(byte[] b, int pos) { return SH(b, pos + 8); } CENHOW(byte[] b, int pos)267 static final int CENHOW(byte[] b, int pos) { return SH(b, pos + 10);} CENTIM(byte[] b, int pos)268 static final long CENTIM(byte[] b, int pos) { return LG(b, pos + 12);} CENCRC(byte[] b, int pos)269 static final long CENCRC(byte[] b, int pos) { return LG(b, pos + 16);} CENSIZ(byte[] b, int pos)270 static final long CENSIZ(byte[] b, int pos) { return LG(b, pos + 20);} CENLEN(byte[] b, int pos)271 static final long CENLEN(byte[] b, int pos) { return LG(b, pos + 24);} CENNAM(byte[] b, int pos)272 static final int CENNAM(byte[] b, int pos) { return SH(b, pos + 28);} CENEXT(byte[] b, int pos)273 static final int CENEXT(byte[] b, int pos) { return SH(b, pos + 30);} CENCOM(byte[] b, int pos)274 static final int CENCOM(byte[] b, int pos) { return SH(b, pos + 32);} CENDSK(byte[] b, int pos)275 static final int CENDSK(byte[] b, int pos) { return SH(b, pos + 34);} CENATT(byte[] b, int pos)276 static final int CENATT(byte[] b, int pos) { return SH(b, pos + 36);} CENATX(byte[] b, int pos)277 static final long CENATX(byte[] b, int pos) { return LG(b, pos + 38);} CENATX_PERMS(byte[] b, int pos)278 static final int CENATX_PERMS(byte[] b, int pos) { return SH(b, pos + 40);} // posix permission data CENOFF(byte[] b, int pos)279 static final long CENOFF(byte[] b, int pos) { return LG(b, pos + 42);} 280 281 // The END header is followed by a variable length comment of size < 64k. 282 static final long END_MAXLEN = 0xFFFF + ENDHDR; 283 static final int READBLOCKSZ = 128; 284 285 // Android-removed: not available on Android. 286 /* 287 * Loads zip native library, if not already laoded 288 * 289 static void loadLibrary() { 290 jdk.internal.loader.BootLoader.loadLibrary("zip"); 291 } 292 */ 293 294 private static final Unsafe unsafe = Unsafe.getUnsafe(); 295 296 private static final long byteBufferArrayOffset = unsafe.objectFieldOffset(ByteBuffer.class, "hb"); 297 private static final long byteBufferOffsetOffset = unsafe.objectFieldOffset(ByteBuffer.class, "offset"); 298 getBufferArray(ByteBuffer byteBuffer)299 static byte[] getBufferArray(ByteBuffer byteBuffer) { 300 return (byte[]) unsafe.getReference(byteBuffer, byteBufferArrayOffset); 301 } 302 getBufferOffset(ByteBuffer byteBuffer)303 static int getBufferOffset(ByteBuffer byteBuffer) { 304 return unsafe.getInt(byteBuffer, byteBufferOffsetOffset); 305 } 306 } 307