1 /* |
1 /* |
2 * Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved. |
2 * Copyright 1996-2009 Sun Microsystems, Inc. All Rights Reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Sun designates this |
7 * published by the Free Software Foundation. Sun designates this |
27 |
27 |
28 import java.io.InputStream; |
28 import java.io.InputStream; |
29 import java.io.IOException; |
29 import java.io.IOException; |
30 import java.io.EOFException; |
30 import java.io.EOFException; |
31 import java.io.PushbackInputStream; |
31 import java.io.PushbackInputStream; |
|
32 import static java.util.zip.ZipConstants64.*; |
32 |
33 |
33 /** |
34 /** |
34 * This class implements an input stream filter for reading files in the |
35 * This class implements an input stream filter for reading files in the |
35 * ZIP file format. Includes support for both compressed and uncompressed |
36 * ZIP file format. Includes support for both compressed and uncompressed |
36 * entries. |
37 * entries. |
283 len = get16(tmpbuf, LOCEXT); |
284 len = get16(tmpbuf, LOCEXT); |
284 if (len > 0) { |
285 if (len > 0) { |
285 byte[] bb = new byte[len]; |
286 byte[] bb = new byte[len]; |
286 readFully(bb, 0, len); |
287 readFully(bb, 0, len); |
287 e.setExtra(bb); |
288 e.setExtra(bb); |
|
289 // extra fields are in "HeaderID(2)DataSize(2)Data... format |
|
290 if (e.csize == ZIP64_MAGICVAL || e.size == ZIP64_MAGICVAL) { |
|
291 int off = 0; |
|
292 while (off + 4 < len) { |
|
293 int sz = get16(bb, off + 2); |
|
294 if (get16(bb, off) == ZIP64_EXTID) { |
|
295 off += 4; |
|
296 // LOC extra zip64 entry MUST include BOTH original and |
|
297 // compressed file size fields |
|
298 if (sz < 16 || (off + sz) > len ) { |
|
299 // Invalid zip64 extra fields, simply skip. Even it's |
|
300 // rare, it's possible the entry size happens to be |
|
301 // the magic value and it "accidnetly" has some bytes |
|
302 // in extra match the id. |
|
303 return e; |
|
304 } |
|
305 e.size = get64(bb, off); |
|
306 e.csize = get64(bb, off + 8); |
|
307 break; |
|
308 } |
|
309 off += (sz + 4); |
|
310 } |
|
311 } |
288 } |
312 } |
289 return e; |
313 return e; |
290 } |
314 } |
291 |
315 |
292 /* |
316 /* |
373 if (n > 0) { |
397 if (n > 0) { |
374 ((PushbackInputStream)in).unread(buf, len - n, n); |
398 ((PushbackInputStream)in).unread(buf, len - n, n); |
375 } |
399 } |
376 if ((flag & 8) == 8) { |
400 if ((flag & 8) == 8) { |
377 /* "Data Descriptor" present */ |
401 /* "Data Descriptor" present */ |
378 readFully(tmpbuf, 0, EXTHDR); |
402 if (inf.getBytesWritten() > ZIP64_MAGICVAL || |
379 long sig = get32(tmpbuf, 0); |
403 inf.getBytesRead() > ZIP64_MAGICVAL) { |
380 if (sig != EXTSIG) { // no EXTSIG present |
404 // ZIP64 format |
381 e.crc = sig; |
405 readFully(tmpbuf, 0, ZIP64_EXTHDR); |
382 e.csize = get32(tmpbuf, EXTSIZ - EXTCRC); |
406 long sig = get32(tmpbuf, 0); |
383 e.size = get32(tmpbuf, EXTLEN - EXTCRC); |
407 if (sig != EXTSIG) { // no EXTSIG present |
384 ((PushbackInputStream)in).unread( |
408 e.crc = sig; |
385 tmpbuf, EXTHDR - EXTCRC - 1, EXTCRC); |
409 e.csize = get64(tmpbuf, ZIP64_EXTSIZ - ZIP64_EXTCRC); |
|
410 e.size = get64(tmpbuf, ZIP64_EXTLEN - ZIP64_EXTCRC); |
|
411 ((PushbackInputStream)in).unread( |
|
412 tmpbuf, ZIP64_EXTHDR - ZIP64_EXTCRC - 1, ZIP64_EXTCRC); |
|
413 } else { |
|
414 e.crc = get32(tmpbuf, ZIP64_EXTCRC); |
|
415 e.csize = get64(tmpbuf, ZIP64_EXTSIZ); |
|
416 e.size = get64(tmpbuf, ZIP64_EXTLEN); |
|
417 } |
386 } else { |
418 } else { |
387 e.crc = get32(tmpbuf, EXTCRC); |
419 readFully(tmpbuf, 0, EXTHDR); |
388 e.csize = get32(tmpbuf, EXTSIZ); |
420 long sig = get32(tmpbuf, 0); |
389 e.size = get32(tmpbuf, EXTLEN); |
421 if (sig != EXTSIG) { // no EXTSIG present |
|
422 e.crc = sig; |
|
423 e.csize = get32(tmpbuf, EXTSIZ - EXTCRC); |
|
424 e.size = get32(tmpbuf, EXTLEN - EXTCRC); |
|
425 ((PushbackInputStream)in).unread( |
|
426 tmpbuf, EXTHDR - EXTCRC - 1, EXTCRC); |
|
427 } else { |
|
428 e.crc = get32(tmpbuf, EXTCRC); |
|
429 e.csize = get32(tmpbuf, EXTSIZ); |
|
430 e.size = get32(tmpbuf, EXTLEN); |
|
431 } |
390 } |
432 } |
391 } |
433 } |
392 if (e.size != inf.getBytesWritten()) { |
434 if (e.size != inf.getBytesWritten()) { |
393 throw new ZipException( |
435 throw new ZipException( |
394 "invalid entry size (expected " + e.size + |
436 "invalid entry size (expected " + e.size + |
431 /* |
473 /* |
432 * Fetches unsigned 32-bit value from byte array at specified offset. |
474 * Fetches unsigned 32-bit value from byte array at specified offset. |
433 * The bytes are assumed to be in Intel (little-endian) byte order. |
475 * The bytes are assumed to be in Intel (little-endian) byte order. |
434 */ |
476 */ |
435 private static final long get32(byte b[], int off) { |
477 private static final long get32(byte b[], int off) { |
436 return get16(b, off) | ((long)get16(b, off+2) << 16); |
478 return (get16(b, off) | ((long)get16(b, off+2) << 16)) & 0xffffffffL; |
|
479 } |
|
480 |
|
481 /* |
|
482 * Fetches signed 64-bit value from byte array at specified offset. |
|
483 * The bytes are assumed to be in Intel (little-endian) byte order. |
|
484 */ |
|
485 private static final long get64(byte b[], int off) { |
|
486 return get32(b, off) | (get32(b, off+4) << 32); |
437 } |
487 } |
438 } |
488 } |