From 7e5c485eb09ce5aef51605cec5582ca7a6581c0b Mon Sep 17 00:00:00 2001 From: igerasim Date: Fri, 21 Jul 2017 20:03:30 -0700 Subject: [PATCH] 8184993: Jar file verification failing with SecurityException: digest missing xxx Reviewed-by: sherman, mullan --- src/share/classes/java/util/zip/ZipFile.java | 21 ++++++++- test/java/util/zip/ZipFile/ReadZip.java | 48 ++++++++++++++++++-- 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/src/share/classes/java/util/zip/ZipFile.java b/src/share/classes/java/util/zip/ZipFile.java index adf805714..7e4059812 100644 --- a/src/share/classes/java/util/zip/ZipFile.java +++ b/src/share/classes/java/util/zip/ZipFile.java @@ -90,12 +90,18 @@ class ZipFile implements ZipConstants, Closeable { private static final boolean usemmap; + private static final boolean ensuretrailingslash; + static { // A system prpperty to disable mmap use to avoid vm crash when // in-use zip file is accidently overwritten by others. String prop = sun.misc.VM.getSavedProperty("sun.zip.disableMemoryMapping"); usemmap = (prop == null || !(prop.length() == 0 || prop.equalsIgnoreCase("true"))); + + // see getEntry() for details + prop = sun.misc.VM.getSavedProperty("jdk.util.zip.ensureTrailingSlash"); + ensuretrailingslash = prop == null || !prop.equalsIgnoreCase("false"); } /** @@ -309,7 +315,16 @@ class ZipFile implements ZipConstants, Closeable { ensureOpen(); jzentry = getEntry(jzfile, zc.getBytes(name), true); if (jzentry != 0) { - ZipEntry ze = getZipEntry(name, jzentry); + // If no entry is found for the specified 'name' and + // the 'name' does not end with a forward slash '/', + // the implementation tries to find the entry with a + // slash '/' appended to the end of the 'name', before + // returning null. When such entry is found, the name + // that actually is found (with a slash '/' attached) + // is used + // (disabled if jdk.util.zip.ensureTrailingSlash=false) + ZipEntry ze = ensuretrailingslash ? getZipEntry(null, jzentry) + : getZipEntry(name, jzentry); freeEntry(jzfile, jzentry); return ze; } @@ -560,7 +575,9 @@ class ZipFile implements ZipConstants, Closeable { e.name = name; } else { byte[] bname = getEntryBytes(jzentry, JZENTRY_NAME); - if (!zc.isUTF8() && (e.flag & EFS) != 0) { + if (bname == null) { + e.name = ""; // length 0 empty name + } else if (!zc.isUTF8() && (e.flag & EFS) != 0) { e.name = zc.toStringUTF8(bname, bname.length); } else { e.name = zc.toString(bname, bname.length); diff --git a/test/java/util/zip/ZipFile/ReadZip.java b/test/java/util/zip/ZipFile/ReadZip.java index 44f1d9ed9..0ca63463c 100644 --- a/test/java/util/zip/ZipFile/ReadZip.java +++ b/test/java/util/zip/ZipFile/ReadZip.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2017, 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 @@ -22,8 +22,11 @@ */ /* @test - @bug 4241361 4842702 4985614 6646605 5032358 6923692 - @summary Make sure we can read a zip file. + * @bug 4241361 4842702 4985614 6646605 5032358 6923692 6233323 8144977 8184993 + * @summary Make sure we can read a zip file. + * @run main/othervm ReadZip + * @run main/othervm -Djdk.util.zip.ensureTrailingSlash=true ReadZip + * @run main/othervm -Djdk.util.zip.ensureTrailingSlash=false ReadZip */ import java.io.*; @@ -103,6 +106,45 @@ public class ReadZip { newZip.delete(); } + // Read directory entry + try { + try (FileOutputStream fos = new FileOutputStream(newZip); + ZipOutputStream zos = new ZipOutputStream(fos)) + { + ZipEntry ze = new ZipEntry("directory/"); + zos.putNextEntry(ze); + zos.closeEntry(); + } + try (ZipFile zf = new ZipFile(newZip)) { + ZipEntry ze = zf.getEntry("directory/"); + if (ze == null || !ze.isDirectory()) + throw new RuntimeException("read entry \"directory/\" failed"); + try (InputStream is = zf.getInputStream(ze)) { + is.available(); + } catch (Exception x) { + x.printStackTrace(); + } + + ze = zf.getEntry("directory"); + + boolean legacyBehavior = + System.getProperty("jdk.util.zip.ensureTrailingSlash", "true") + .equalsIgnoreCase("false"); + + if (ze == null || (!legacyBehavior && !ze.isDirectory())) + throw new RuntimeException("read entry \"directory\" failed"); + try (InputStream is = zf.getInputStream(ze)) { + is.available(); + } catch (Exception x) { + x.printStackTrace(); + } + } + } finally { + newZip.delete(); + } + + + // Throw a FNF exception when read a non-existing zip file try { unreached (new ZipFile( new File(System.getProperty("test.src", "."), -- GitLab