--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipInfo.java Tue Sep 12 19:03:39 2017 +0200
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2009, 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nio.zipfs;
+
+import java.nio.file.Paths;
+import java.util.Collections;
+import java.util.Map;
+import static jdk.nio.zipfs.ZipConstants.*;
+import static jdk.nio.zipfs.ZipUtils.*;
+
+/**
+ * Print all loc and cen headers of the ZIP file
+ *
+ * @author Xueming Shen
+ */
+
+public class ZipInfo {
+
+ public static void main(String[] args) throws Throwable {
+ if (args.length < 1) {
+ print("Usage: java ZipInfo zfname");
+ } else {
+ Map<String, ?> env = Collections.emptyMap();
+ ZipFileSystem zfs = (ZipFileSystem)(new ZipFileSystemProvider()
+ .newFileSystem(Paths.get(args[0]), env));
+ byte[] cen = zfs.cen;
+ if (cen == null) {
+ print("zip file is empty%n");
+ return;
+ }
+ int pos = 0;
+ byte[] buf = new byte[1024];
+ int no = 1;
+ while (pos + CENHDR < cen.length) {
+ print("----------------#%d--------------------%n", no++);
+ printCEN(cen, pos);
+
+ // use size CENHDR as the extra bytes to read, just in case the
+ // loc.extra is bigger than the cen.extra, try to avoid to read
+ // twice
+ long len = LOCHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENHDR;
+ if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
+ ZipFileSystem.zerror("read loc header failed");
+ if (LOCEXT(buf) > CENEXT(cen, pos) + CENHDR) {
+ // have to read the second time;
+ len = LOCHDR + LOCNAM(buf) + LOCEXT(buf);
+ if (zfs.readFullyAt(buf, 0, len, locoff(cen, pos)) != len)
+ ZipFileSystem.zerror("read loc header failed");
+ }
+ printLOC(buf);
+ pos += CENHDR + CENNAM(cen, pos) + CENEXT(cen, pos) + CENCOM(cen, pos);
+ }
+ zfs.close();
+ }
+ }
+
+ static void print(String fmt, Object... objs) {
+ System.out.printf(fmt, objs);
+ }
+
+ static void printLOC(byte[] loc) {
+ print("%n");
+ print("[Local File Header]%n");
+ print(" Signature : %#010x%n", LOCSIG(loc));
+ if (LOCSIG(loc) != LOCSIG) {
+ print(" Wrong signature!");
+ return;
+ }
+ print(" Version : %#6x [%d.%d]%n",
+ LOCVER(loc), LOCVER(loc) / 10, LOCVER(loc) % 10);
+ print(" Flag : %#6x%n", LOCFLG(loc));
+ print(" Method : %#6x%n", LOCHOW(loc));
+ print(" LastMTime : %#10x [%tc]%n",
+ LOCTIM(loc), dosToJavaTime(LOCTIM(loc)));
+ print(" CRC : %#10x%n", LOCCRC(loc));
+ print(" CSize : %#10x%n", LOCSIZ(loc));
+ print(" Size : %#10x%n", LOCLEN(loc));
+ print(" NameLength : %#6x [%s]%n",
+ LOCNAM(loc), new String(loc, LOCHDR, LOCNAM(loc)));
+ print(" ExtraLength : %#6x%n", LOCEXT(loc));
+ if (LOCEXT(loc) != 0)
+ printExtra(loc, LOCHDR + LOCNAM(loc), LOCEXT(loc));
+ }
+
+ static void printCEN(byte[] cen, int off) {
+ print("[Central Directory Header]%n");
+ print(" Signature : %#010x%n", CENSIG(cen, off));
+ if (CENSIG(cen, off) != CENSIG) {
+ print(" Wrong signature!");
+ return;
+ }
+ print(" VerMadeby : %#6x [%d, %d.%d]%n",
+ CENVEM(cen, off), (CENVEM(cen, off) >> 8),
+ (CENVEM(cen, off) & 0xff) / 10,
+ (CENVEM(cen, off) & 0xff) % 10);
+ print(" VerExtract : %#6x [%d.%d]%n",
+ CENVER(cen, off), CENVER(cen, off) / 10, CENVER(cen, off) % 10);
+ print(" Flag : %#6x%n", CENFLG(cen, off));
+ print(" Method : %#6x%n", CENHOW(cen, off));
+ print(" LastMTime : %#10x [%tc]%n",
+ CENTIM(cen, off), dosToJavaTime(CENTIM(cen, off)));
+ print(" CRC : %#10x%n", CENCRC(cen, off));
+ print(" CSize : %#10x%n", CENSIZ(cen, off));
+ print(" Size : %#10x%n", CENLEN(cen, off));
+ print(" NameLen : %#6x [%s]%n",
+ CENNAM(cen, off), new String(cen, off + CENHDR, CENNAM(cen, off)));
+ print(" ExtraLen : %#6x%n", CENEXT(cen, off));
+ if (CENEXT(cen, off) != 0)
+ printExtra(cen, off + CENHDR + CENNAM(cen, off), CENEXT(cen, off));
+ print(" CommentLen : %#6x%n", CENCOM(cen, off));
+ print(" DiskStart : %#6x%n", CENDSK(cen, off));
+ print(" Attrs : %#6x%n", CENATT(cen, off));
+ print(" AttrsEx : %#10x%n", CENATX(cen, off));
+ print(" LocOff : %#10x%n", CENOFF(cen, off));
+
+ }
+
+ static long locoff(byte[] cen, int pos) {
+ long locoff = CENOFF(cen, pos);
+ if (locoff == ZIP64_MINVAL) { //ZIP64
+ int off = pos + CENHDR + CENNAM(cen, pos);
+ int end = off + CENEXT(cen, pos);
+ while (off + 4 < end) {
+ int tag = SH(cen, off);
+ int sz = SH(cen, off + 2);
+ if (tag != EXTID_ZIP64) {
+ off += 4 + sz;
+ continue;
+ }
+ off += 4;
+ if (CENLEN(cen, pos) == ZIP64_MINVAL)
+ off += 8;
+ if (CENSIZ(cen, pos) == ZIP64_MINVAL)
+ off += 8;
+ return LL(cen, off);
+ }
+ // should never be here
+ }
+ return locoff;
+ }
+
+ static void printExtra(byte[] extra, int off, int len) {
+ int end = off + len;
+ while (off + 4 <= end) {
+ int tag = SH(extra, off);
+ int sz = SH(extra, off + 2);
+ print(" [tag=0x%04x, sz=%d, data= ", tag, sz);
+ if (off + sz > end) {
+ print(" Error: Invalid extra data, beyond extra length");
+ break;
+ }
+ off += 4;
+ for (int i = 0; i < sz; i++)
+ print("%02x ", extra[off + i]);
+ print("]%n");
+ switch (tag) {
+ case EXTID_ZIP64 :
+ print(" ->ZIP64: ");
+ int pos = off;
+ while (pos + 8 <= off + sz) {
+ print(" *0x%x ", LL(extra, pos));
+ pos += 8;
+ }
+ print("%n");
+ break;
+ case EXTID_NTFS:
+ print(" ->PKWare NTFS%n");
+ // 4 bytes reserved
+ if (SH(extra, off + 4) != 0x0001 || SH(extra, off + 6) != 24)
+ print(" Error: Invalid NTFS sub-tag or subsz");
+ print(" mtime:%tc%n",
+ winToJavaTime(LL(extra, off + 8)));
+ print(" atime:%tc%n",
+ winToJavaTime(LL(extra, off + 16)));
+ print(" ctime:%tc%n",
+ winToJavaTime(LL(extra, off + 24)));
+ break;
+ case EXTID_EXTT:
+ print(" ->Info-ZIP Extended Timestamp: flag=%x%n",extra[off]);
+ pos = off + 1 ;
+ while (pos + 4 <= off + sz) {
+ print(" *%tc%n",
+ unixToJavaTime(LG(extra, pos)));
+ pos += 4;
+ }
+ break;
+ default:
+ print(" ->[tag=%x, size=%d]%n", tag, sz);
+ }
+ off += sz;
+ }
+ }
+}