1 /*
2 * Copyright (c) 1996, 2012, 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
271 private byte[] b = new byte[256];
272
273 /*
274 * Reads local file (LOC) header for next entry.
275 */
276 private ZipEntry readLOC() throws IOException {
277 try {
278 readFully(tmpbuf, 0, LOCHDR);
279 } catch (EOFException e) {
280 return null;
281 }
282 if (get32(tmpbuf, 0) != LOCSIG) {
283 return null;
284 }
285 // get flag first, we need check EFS.
286 flag = get16(tmpbuf, LOCFLG);
287 // get the entry name and create the ZipEntry first
288 int len = get16(tmpbuf, LOCNAM);
289 int blen = b.length;
290 if (len > blen) {
291 do
292 blen = blen * 2;
293 while (len > blen);
294 b = new byte[blen];
295 }
296 readFully(b, 0, len);
297 // Force to use UTF-8 if the EFS bit is ON, even the cs is NOT UTF-8
298 ZipEntry e = createZipEntry(((flag & EFS) != 0)
299 ? zc.toStringUTF8(b, len)
300 : zc.toString(b, len));
301 // now get the remaining fields for the entry
302 if ((flag & 1) == 1) {
303 throw new ZipException("encrypted ZIP entry not supported");
304 }
305 e.method = get16(tmpbuf, LOCHOW);
306 e.mtime = dosToJavaTime(get32(tmpbuf, LOCTIM));
307 if ((flag & 8) == 8) {
308 /* "Data Descriptor" present */
309 if (e.method != DEFLATED) {
310 throw new ZipException(
311 "only DEFLATED entries can have EXT descriptor");
312 }
313 } else {
314 e.crc = get32(tmpbuf, LOCCRC);
315 e.csize = get32(tmpbuf, LOCSIZ);
316 e.size = get32(tmpbuf, LOCLEN);
317 }
318 len = get16(tmpbuf, LOCEXT);
319 if (len > 0) {
320 byte[] extra = new byte[len];
321 readFully(extra, 0, len);
322 e.setExtra(extra);
323 // extra fields are in "HeaderID(2)DataSize(2)Data... format
324 int off = 0;
325 while (off + 4 < len) {
326 int pos = off;
327 int tag = get16(extra, pos);
328 int sz = get16(extra, pos + 2);
329 pos += 4;
330 if (pos + sz > len) // invalid data
331 break;
332 switch (tag) {
333 case EXTID_ZIP64 :
334 // LOC extra zip64 entry MUST include BOTH original and
335 // compressed file size fields.
336 //
337 // If invalid zip64 extra fields, simply skip. Even it's
338 // rare, it's possible the entry size happens to be
339 // the magic value and it "accidently" has some bytes
340 // in extra match the id.
341 if (sz >= 16 && (pos + sz) <= len ) {
342 e.size = get64(extra, pos);
343 e.csize = get64(extra, pos + 8);
344 }
345 break;
346 case EXTID_NTFS:
347 pos += 4; // reserved 4 bytes
348 if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24)
349 break;
350 // override the loc field, NTFS time has 'microsecond' granularity
351 e.mtime = winToJavaTime(get64(extra, pos + 4));
352 break;
353 case EXTID_EXTT:
354 int flag = Byte.toUnsignedInt(extra[pos++]);
355 if ((flag & 0x1) != 0) {
356 e.mtime = unixToJavaTime(get32(extra, pos));
357 pos += 4;
358 }
359 break;
360 default: // unknown tag
361 }
362 off += (sz + 4);
363 }
364
365 }
366 return e;
367 }
368
369 /**
370 * Creates a new <code>ZipEntry</code> object for the specified
371 * entry name.
372 *
373 * @param name the ZIP file entry name
374 * @return the ZipEntry just created
375 */
376 protected ZipEntry createZipEntry(String name) {
377 return new ZipEntry(name);
378 }
379
380 /*
381 * Reads end of deflated entry as well as EXT descriptor if present.
382 */
383 private void readEnd(ZipEntry e) throws IOException {
384 int n = inf.getRemaining();
|
1 /*
2 * Copyright (c) 1996, 2013, 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
271 private byte[] b = new byte[256];
272
273 /*
274 * Reads local file (LOC) header for next entry.
275 */
276 private ZipEntry readLOC() throws IOException {
277 try {
278 readFully(tmpbuf, 0, LOCHDR);
279 } catch (EOFException e) {
280 return null;
281 }
282 if (get32(tmpbuf, 0) != LOCSIG) {
283 return null;
284 }
285 // get flag first, we need check EFS.
286 flag = get16(tmpbuf, LOCFLG);
287 // get the entry name and create the ZipEntry first
288 int len = get16(tmpbuf, LOCNAM);
289 int blen = b.length;
290 if (len > blen) {
291 do {
292 blen = blen * 2;
293 } while (len > blen);
294 b = new byte[blen];
295 }
296 readFully(b, 0, len);
297 // Force to use UTF-8 if the EFS bit is ON, even the cs is NOT UTF-8
298 ZipEntry e = createZipEntry(((flag & EFS) != 0)
299 ? zc.toStringUTF8(b, len)
300 : zc.toString(b, len));
301 // now get the remaining fields for the entry
302 if ((flag & 1) == 1) {
303 throw new ZipException("encrypted ZIP entry not supported");
304 }
305 e.method = get16(tmpbuf, LOCHOW);
306 e.time = dosToJavaTime(get32(tmpbuf, LOCTIM));
307 if ((flag & 8) == 8) {
308 /* "Data Descriptor" present */
309 if (e.method != DEFLATED) {
310 throw new ZipException(
311 "only DEFLATED entries can have EXT descriptor");
312 }
313 } else {
314 e.crc = get32(tmpbuf, LOCCRC);
315 e.csize = get32(tmpbuf, LOCSIZ);
316 e.size = get32(tmpbuf, LOCLEN);
317 }
318 len = get16(tmpbuf, LOCEXT);
319 if (len > 0) {
320 byte[] extra = new byte[len];
321 readFully(extra, 0, len);
322 e.setExtra0(extra, true);
323 }
324 return e;
325 }
326
327 /**
328 * Creates a new <code>ZipEntry</code> object for the specified
329 * entry name.
330 *
331 * @param name the ZIP file entry name
332 * @return the ZipEntry just created
333 */
334 protected ZipEntry createZipEntry(String name) {
335 return new ZipEntry(name);
336 }
337
338 /*
339 * Reads end of deflated entry as well as EXT descriptor if present.
340 */
341 private void readEnd(ZipEntry e) throws IOException {
342 int n = inf.getRemaining();
|