1 /*
2 * Copyright (c) 1995, 2017, 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
505
506 /**
507 * Sets the optional extra field data for the entry.
508 *
509 * <p> Invoking this method may change this entry's last modification
510 * time, last access time and creation time, if the {@code extra} field
511 * data includes the extensible timestamp fields, such as {@code NTFS tag
512 * 0x0001} or {@code Info-ZIP Extended Timestamp}, as specified in
513 * <a href="http://www.info-zip.org/doc/appnote-19970311-iz.zip">Info-ZIP
514 * Application Note 970311</a>.
515 *
516 * @param extra
517 * The extra field data bytes
518 *
519 * @throws IllegalArgumentException if the length of the specified
520 * extra field data is greater than 0xFFFF bytes
521 *
522 * @see #getExtra()
523 */
524 public void setExtra(byte[] extra) {
525 setExtra0(extra, false);
526 }
527
528 /**
529 * Sets the optional extra field data for the entry.
530 *
531 * @param extra
532 * the extra field data bytes
533 * @param doZIP64
534 * if true, set size and csize from ZIP64 fields if present
535 */
536 void setExtra0(byte[] extra, boolean doZIP64) {
537 if (extra != null) {
538 if (extra.length > 0xFFFF) {
539 throw new IllegalArgumentException("invalid extra field length");
540 }
541 // extra fields are in "HeaderID(2)DataSize(2)Data... format
542 int off = 0;
543 int len = extra.length;
544 while (off + 4 < len) {
545 int tag = get16(extra, off);
546 int sz = get16(extra, off + 2);
547 off += 4;
548 if (off + sz > len) // invalid data
549 break;
550 switch (tag) {
551 case EXTID_ZIP64:
552 if (doZIP64) {
553 // LOC extra zip64 entry MUST include BOTH original
554 // and compressed file size fields.
555 // If invalid zip64 extra fields, simply skip. Even
556 // it's rare, it's possible the entry size happens to
557 // be the magic value and it "accidently" has some
558 // bytes in extra match the id.
559 if (sz >= 16) {
560 size = get64(extra, off);
561 csize = get64(extra, off + 8);
562 }
563 }
564 break;
565 case EXTID_NTFS:
566 if (sz < 32) // reserved 4 bytes + tag 2 bytes + size 2 bytes
567 break; // m[a|c]time 24 bytes
568 int pos = off + 4; // reserved 4 bytes
569 if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24)
570 break;
571 long wtime = get64(extra, pos + 4);
572 if (wtime != WINDOWS_TIME_NOT_AVAILABLE) {
573 mtime = winTimeToFileTime(wtime);
574 }
575 wtime = get64(extra, pos + 12);
576 if (wtime != WINDOWS_TIME_NOT_AVAILABLE) {
577 atime = winTimeToFileTime(wtime);
578 }
579 wtime = get64(extra, pos + 20);
580 if (wtime != WINDOWS_TIME_NOT_AVAILABLE) {
581 ctime = winTimeToFileTime(wtime);
582 }
|
1 /*
2 * Copyright (c) 1995, 2019, 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
505
506 /**
507 * Sets the optional extra field data for the entry.
508 *
509 * <p> Invoking this method may change this entry's last modification
510 * time, last access time and creation time, if the {@code extra} field
511 * data includes the extensible timestamp fields, such as {@code NTFS tag
512 * 0x0001} or {@code Info-ZIP Extended Timestamp}, as specified in
513 * <a href="http://www.info-zip.org/doc/appnote-19970311-iz.zip">Info-ZIP
514 * Application Note 970311</a>.
515 *
516 * @param extra
517 * The extra field data bytes
518 *
519 * @throws IllegalArgumentException if the length of the specified
520 * extra field data is greater than 0xFFFF bytes
521 *
522 * @see #getExtra()
523 */
524 public void setExtra(byte[] extra) {
525 setExtra0(extra, false, true);
526 }
527
528 /**
529 * Sets the optional extra field data for the entry.
530 *
531 * @param extra
532 * the extra field data bytes
533 * @param doZIP64
534 * if true, set size and csize from ZIP64 fields if present
535 * @param isLOC
536 * true if setting the extra field for a LOC, false if for
537 * a CEN
538 */
539 void setExtra0(byte[] extra, boolean doZIP64, boolean isLOC) {
540 if (extra != null) {
541 if (extra.length > 0xFFFF) {
542 throw new IllegalArgumentException("invalid extra field length");
543 }
544 // extra fields are in "HeaderID(2)DataSize(2)Data... format
545 int off = 0;
546 int len = extra.length;
547 while (off + 4 < len) {
548 int tag = get16(extra, off);
549 int sz = get16(extra, off + 2);
550 off += 4;
551 if (off + sz > len) // invalid data
552 break;
553 switch (tag) {
554 case EXTID_ZIP64:
555 if (doZIP64) {
556 if (isLOC) {
557 // LOC extra zip64 entry MUST include BOTH original
558 // and compressed file size fields.
559 // If invalid zip64 extra fields, simply skip. Even
560 // it's rare, it's possible the entry size happens to
561 // be the magic value and it "accidently" has some
562 // bytes in extra match the id.
563 if (sz >= 16) {
564 size = get64(extra, off);
565 csize = get64(extra, off + 8);
566 }
567 } else {
568 // CEN extra zip64
569 if (size == ZIP64_MAGICVAL) {
570 if (off + 8 > len) // invalid zip64 extra
571 break; // fields, just skip
572 size = get64(extra, off);
573 }
574 if (csize == ZIP64_MAGICVAL) {
575 if (off + 16 > len) // invalid zip64 extra
576 break; // fields, just skip
577 csize = get64(extra, off + 8);
578 }
579 }
580 }
581 break;
582 case EXTID_NTFS:
583 if (sz < 32) // reserved 4 bytes + tag 2 bytes + size 2 bytes
584 break; // m[a|c]time 24 bytes
585 int pos = off + 4; // reserved 4 bytes
586 if (get16(extra, pos) != 0x0001 || get16(extra, pos + 2) != 24)
587 break;
588 long wtime = get64(extra, pos + 4);
589 if (wtime != WINDOWS_TIME_NOT_AVAILABLE) {
590 mtime = winTimeToFileTime(wtime);
591 }
592 wtime = get64(extra, pos + 12);
593 if (wtime != WINDOWS_TIME_NOT_AVAILABLE) {
594 atime = winTimeToFileTime(wtime);
595 }
596 wtime = get64(extra, pos + 20);
597 if (wtime != WINDOWS_TIME_NOT_AVAILABLE) {
598 ctime = winTimeToFileTime(wtime);
599 }
|