# HG changeset patch # User Andrew John Hughes # Date 1445970874 0 # Node ID ae390d52ddebdee6908811c43a1f928cf3a0ce3c # Parent 53d2442cfbecf19701ab937733cc32384509dbac Add backports destined for the next update, 1.13.9. S6440786, PR363: Cannot create a ZIP file containing zero entries S6599383, PR363: Unable to open zip files more than 2GB in size S6929479, PR363: Add a system property sun.zip.disableMemoryMapping to disable mmap use in ZipFile S7105461, PR2662: Large JTables are not rendered correctly with Xrender pipeline S7150134, PR2662: JCK api/java_awt/Graphics/index.html#DrawLine fails with OOM for jdk8 with XRender pipeline PR2513: Reset success following calls in LayoutManager.cpp 2015-10-12 Andrew John Hughes * Makefile.am: (ICEDTEA_PATCHES): Add new patches. * NEWS: Updated. * patches/openjdk/6440786-pr363-zero_entry_zips.patch, * patches/openjdk/6599383-pr363-large_zip_files.patch, * patches/openjdk/6929479-pr363-disable_mmap_zip.patch, * patches/openjdk/7105461-pr2662-xrender_jtables.patch, * patches/openjdk/7150134-pr2662-xrender_drawline_oom.patch, * patches/pr2513-layoutengine_reset.patch: New backports for issues to be fixed in 1.13.9. diff -r 53d2442cfbec -r ae390d52ddeb ChangeLog --- a/ChangeLog Sat Aug 15 00:52:55 2015 +0100 +++ b/ChangeLog Tue Oct 27 18:34:34 2015 +0000 @@ -1,3 +1,16 @@ +2015-10-12 Andrew John Hughes + + * Makefile.am: + (ICEDTEA_PATCHES): Add new patches. + * NEWS: Updated. + * patches/openjdk/6440786-pr363-zero_entry_zips.patch, + * patches/openjdk/6599383-pr363-large_zip_files.patch, + * patches/openjdk/6929479-pr363-disable_mmap_zip.patch, + * patches/openjdk/7105461-pr2662-xrender_jtables.patch, + * patches/openjdk/7150134-pr2662-xrender_drawline_oom.patch, + * patches/pr2513-layoutengine_reset.patch: + New backports for issues to be fixed in 1.13.9. + 2015-08-15 Andrew John Hughes * NEWS: Add 1.13.9 section. Correct diff -r 53d2442cfbec -r ae390d52ddeb Makefile.am --- a/Makefile.am Sat Aug 15 00:52:55 2015 +0100 +++ b/Makefile.am Tue Oct 27 18:34:34 2015 +0000 @@ -634,7 +634,11 @@ patches/pr2460-policy_jar_timestamp.patch \ patches/pr2481_sysconfig_clock_spaces.patch \ patches/pr2486-768_dh.patch \ - patches/pr2488-1024_dh.patch + patches/pr2488-1024_dh.patch \ + patches/openjdk/6440786-pr363-zero_entry_zips.patch \ + patches/openjdk/6599383-pr363-large_zip_files.patch \ + patches/openjdk/6929479-pr363-disable_mmap_zip.patch \ + patches/pr2513-layoutengine_reset.patch if WITH_RHINO ICEDTEA_PATCHES += \ @@ -664,7 +668,9 @@ if ENABLE_XRENDER ICEDTEA_PATCHES += patches/openjdk/6307603-xrender-01.patch \ patches/openjdk/6961633-xrender-02.patch \ - patches/openjdk/7018387-xrender_gc_leak.patch + patches/openjdk/7018387-xrender_gc_leak.patch \ + patches/openjdk/7150134-pr2662-xrender_drawline_oom.patch \ + patches/openjdk/7105461-pr2662-xrender_jtables.patch endif if ENABLE_SYSTEMTAP diff -r 53d2442cfbec -r ae390d52ddeb NEWS --- a/NEWS Sat Aug 15 00:52:55 2015 +0100 +++ b/NEWS Tue Oct 27 18:34:34 2015 +0000 @@ -12,7 +12,16 @@ CVE-XXXX-YYYY: http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=XXXX-YYYY -New in release 1.13.8 (2015-10-XX): +New in release 1.13.9 (2015-10-XX): + +* Backports + - S6440786, PR363: Cannot create a ZIP file containing zero entries + - S6599383, PR363: Unable to open zip files more than 2GB in size + - S6929479, PR363: Add a system property sun.zip.disableMemoryMapping to disable mmap use in ZipFile + - S7105461, PR2662: Large JTables are not rendered correctly with Xrender pipeline + - S7150134, PR2662: JCK api/java_awt/Graphics/index.html#DrawLine fails with OOM for jdk8 with XRender pipeline +* Bug fixes + - PR2513: Reset success following calls in LayoutManager.cpp New in release 1.13.8 (2015-07-29): diff -r 53d2442cfbec -r ae390d52ddeb patches/openjdk/6440786-pr363-zero_entry_zips.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6440786-pr363-zero_entry_zips.patch Tue Oct 27 18:34:34 2015 +0000 @@ -0,0 +1,237 @@ +# HG changeset patch +# User bristor +# Date 1221170337 25200 +# Thu Sep 11 14:58:57 2008 -0700 +# Node ID bee470ba5b243162ca0f84e49f794e94381876cd +# Parent 3e7b9a0f3a6f40b1feb22990ed005e15e6ab6b5e +6440786, PR363: Cannot create a ZIP file containing zero entries +Summary: Allow reading and writing of ZIP files with zero entries. +Reviewed-by: alanb + +diff -Nru openjdk.orig/jdk/src/share/classes/java/util/zip/ZipOutputStream.java openjdk/jdk/src/share/classes/java/util/zip/ZipOutputStream.java +--- openjdk.orig/jdk/src/share/classes/java/util/zip/ZipOutputStream.java 2015-07-20 17:22:20.000000000 +0100 ++++ openjdk/jdk/src/share/classes/java/util/zip/ZipOutputStream.java 2015-10-05 01:17:22.830735488 +0100 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. ++ * Copyright (c) 1996, 2008, 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 +@@ -317,9 +317,6 @@ + if (current != null) { + closeEntry(); + } +- if (xentries.size() < 1) { +- throw new ZipException("ZIP file must have at least one entry"); +- } + // write central directory + long off = written; + for (XEntry xentry : xentries) +diff -Nru openjdk.orig/jdk/src/share/native/java/util/zip/zip_util.c openjdk/jdk/src/share/native/java/util/zip/zip_util.c +--- openjdk.orig/jdk/src/share/native/java/util/zip/zip_util.c 2015-07-20 17:22:14.000000000 +0100 ++++ openjdk/jdk/src/share/native/java/util/zip/zip_util.c 2015-10-05 01:17:05.587024552 +0100 +@@ -730,16 +730,22 @@ + } + + len = zip->len = ZFILE_Lseek(zfd, 0, SEEK_END); +- if (len == -1) { +- if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0) +- *pmsg = errbuf; ++ if (len <= 0) { ++ if (len == 0) { /* zip file is empty */ ++ if (pmsg) { ++ *pmsg = "zip file is empty"; ++ } ++ } else { /* error */ ++ if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0) ++ *pmsg = errbuf; ++ } + ZFILE_Close(zfd); + freeZip(zip); + return NULL; + } + + zip->zfd = zfd; +- if (readCEN(zip, -1) <= 0) { ++ if (readCEN(zip, -1) < 0) { + /* An error occurred while trying to read the zip file */ + if (pmsg != 0) { + /* Set the zip error message */ +@@ -955,10 +961,15 @@ + ZIP_GetEntry(jzfile *zip, char *name, jint ulen) + { + unsigned int hsh = hash(name); +- jint idx = zip->table[hsh % zip->tablelen]; +- jzentry *ze; ++ jint idx; ++ jzentry *ze = 0; + + ZIP_Lock(zip); ++ if (zip->total == 0) { ++ goto Finally; ++ } ++ ++ idx = zip->table[hsh % zip->tablelen]; + + /* + * This while loop is an optimization where a double lookup +@@ -1033,6 +1044,7 @@ + ulen = 0; + } + ++Finally: + ZIP_Unlock(zip); + return ze; + } +diff -Nru openjdk.orig/jdk/test/java/util/zip/TestEmptyZip.java openjdk/jdk/test/java/util/zip/TestEmptyZip.java +--- openjdk.orig/jdk/test/java/util/zip/TestEmptyZip.java 1970-01-01 01:00:00.000000000 +0100 ++++ openjdk/jdk/test/java/util/zip/TestEmptyZip.java 2015-10-05 01:19:15.676843719 +0100 +@@ -0,0 +1,147 @@ ++/* ++ * Copyright (c) 2008, 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. ++ * ++ * 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. ++ */ ++ ++/* @test ++ * @bug 6334003 6440786 ++ * @summary Test ability to write and read zip files that have no entries. ++ * @author Dave Bristor ++ */ ++ ++import java.io.*; ++import java.util.*; ++import java.util.zip.*; ++ ++public class TestEmptyZip { ++ public static void realMain(String[] args) throws Throwable { ++ String zipName = "foo.zip"; ++ File f = new File(System.getProperty("test.scratch", "."), zipName); ++ if (f.exists() && !f.delete()) { ++ throw new Exception("failed to delete " + zipName); ++ } ++ ++ // Verify 0-length file cannot be read ++ f.createNewFile(); ++ ZipFile zf = null; ++ try { ++ zf = new ZipFile(f); ++ fail(); ++ } catch (Exception ex) { ++ check(ex.getMessage().contains("zip file is empty")); ++ } finally { ++ if (zf != null) { ++ zf.close(); ++ } ++ } ++ ++ ZipInputStream zis = null; ++ try { ++ zis = new ZipInputStream(new FileInputStream(f)); ++ ZipEntry ze = zis.getNextEntry(); ++ check(ze == null); ++ } catch (Exception ex) { ++ unexpected(ex); ++ } finally { ++ if (zis != null) { ++ zis.close(); ++ } ++ } ++ ++ f.delete(); ++ ++ // Verify 0-entries file can be written ++ write(f); ++ ++ // Verify 0-entries file can be read ++ readFile(f); ++ readStream(f); ++ ++ f.delete(); ++ } ++ ++ static void write(File f) throws Exception { ++ ZipOutputStream zos = null; ++ try { ++ zos = new ZipOutputStream(new FileOutputStream(f)); ++ zos.finish(); ++ zos.close(); ++ pass(); ++ } catch (Exception ex) { ++ unexpected(ex); ++ } finally { ++ if (zos != null) { ++ zos.close(); ++ } ++ } ++ } ++ ++ static void readFile(File f) throws Exception { ++ ZipFile zf = null; ++ try { ++ zf = new ZipFile(f); ++ ++ Enumeration e = zf.entries(); ++ while (e.hasMoreElements()) { ++ ZipEntry entry = (ZipEntry) e.nextElement(); ++ fail(); ++ } ++ zf.close(); ++ pass(); ++ } catch (Exception ex) { ++ unexpected(ex); ++ } finally { ++ if (zf != null) { ++ zf.close(); ++ } ++ } ++ } ++ ++ static void readStream(File f) throws Exception { ++ ZipInputStream zis = null; ++ try { ++ zis = new ZipInputStream(new FileInputStream(f)); ++ ZipEntry ze = zis.getNextEntry(); ++ check(ze == null); ++ byte[] buf = new byte[1024]; ++ check(zis.read(buf, 0, 1024) == -1); ++ } finally { ++ if (zis != null) { ++ zis.close(); ++ } ++ } ++ } ++ ++ //--------------------- Infrastructure --------------------------- ++ static volatile int passed = 0, failed = 0; ++ static boolean pass() {passed++; return true;} ++ static boolean fail() {failed++; Thread.dumpStack(); return false;} ++ static boolean fail(String msg) {System.out.println(msg); return fail();} ++ static void unexpected(Throwable t) {failed++; t.printStackTrace();} ++ static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;} ++ static boolean equal(Object x, Object y) { ++ if (x == null ? y == null : x.equals(y)) return pass(); ++ else return fail(x + " not equal to " + y);} ++ public static void main(String[] args) throws Throwable { ++ try {realMain(args);} catch (Throwable t) {unexpected(t);} ++ System.out.println("\nPassed = " + passed + " failed = " + failed); ++ if (failed > 0) throw new AssertionError("Some tests failed");} ++} diff -r 53d2442cfbec -r ae390d52ddeb patches/openjdk/6599383-pr363-large_zip_files.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6599383-pr363-large_zip_files.patch Tue Oct 27 18:34:34 2015 +0000 @@ -0,0 +1,214 @@ +# HG changeset patch +# User kevinw +# Date 1235485328 0 +# Tue Feb 24 14:22:08 2009 +0000 +# Node ID dc237aecf7cf5669588bb2d82e9baca88936fb62 +# Parent abe5e7125bd3b57b7a0c8f5786530695f0d61075 +6599383, PR363: Unable to open zip files more than 2GB in size +Reviewed-by: alanb + +diff -r abe5e7125bd3 -r dc237aecf7cf src/share/native/java/util/zip/zip_util.c +--- openjdk/jdk/src/share/native/java/util/zip/zip_util.c Tue Feb 24 11:33:25 2009 +0000 ++++ openjdk/jdk/src/share/native/java/util/zip/zip_util.c Tue Feb 24 14:22:08 2009 +0000 +@@ -135,11 +135,6 @@ + #endif + } + +-static jlong +-ZFILE_Lseek(ZFILE zfd, off_t offset, int whence) { +- return IO_Lseek(zfd, offset, whence); +-} +- + static int + ZFILE_read(ZFILE zfd, char *buf, jint nbytes) { + #ifdef WIN32 +@@ -216,7 +211,7 @@ + static int + readFullyAt(ZFILE zfd, void *buf, jlong len, jlong offset) + { +- if (ZFILE_Lseek(zfd, (off_t) offset, SEEK_SET) == -1) { ++ if (IO_Lseek(zfd, offset, SEEK_SET) == -1) { + return -1; /* lseek failure. */ + } + +@@ -476,7 +471,7 @@ + unsigned char *cp; + #ifdef USE_MMAP + static jlong pagesize; +- off_t offset; ++ jlong offset; + #endif + unsigned char endbuf[ENDHDR]; + jzcell *entries; +@@ -534,7 +529,7 @@ + */ + zip->mlen = cenpos - offset + cenlen + ENDHDR; + zip->offset = offset; +- mappedAddr = mmap(0, zip->mlen, PROT_READ, MAP_SHARED, zip->zfd, offset); ++ mappedAddr = mmap64(0, zip->mlen, PROT_READ, MAP_SHARED, zip->zfd, (off64_t) offset); + zip->maddr = (mappedAddr == (void*) MAP_FAILED) ? NULL : + (unsigned char*)mappedAddr; + +@@ -720,7 +715,7 @@ + return NULL; + } + +- len = zip->len = ZFILE_Lseek(zfd, 0, SEEK_END); ++ len = zip->len = IO_Lseek(zfd, 0, SEEK_END); + if (len <= 0) { + if (len == 0) { /* zip file is empty */ + if (pmsg) { +diff -r abe5e7125bd3 -r dc237aecf7cf src/share/native/java/util/zip/zip_util.h +--- openjdk/jdk/src/share/native/java/util/zip/zip_util.h Tue Feb 24 11:33:25 2009 +0000 ++++ openjdk/jdk/src/share/native/java/util/zip/zip_util.h Tue Feb 24 14:22:08 2009 +0000 +@@ -174,7 +174,7 @@ + #ifdef USE_MMAP + unsigned char *maddr; /* beginning address of the CEN & ENDHDR */ + jlong mlen; /* length (in bytes) mmaped */ +- off_t offset; /* offset of the mmapped region from the ++ jlong offset; /* offset of the mmapped region from the + start of the file. */ + #else + cencache cencache; /* CEN header cache */ +diff -r abe5e7125bd3 -r dc237aecf7cf test/java/util/zip/ZipFile/LargeZipFile.java +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ openjdk/jdk/test/java/util/zip/ZipFile/LargeZipFile.java Tue Feb 24 14:22:08 2009 +0000 +@@ -0,0 +1,138 @@ ++import java.io.*; ++import java.nio.*; ++import java.util.*; ++import java.util.zip.*; ++ ++public class LargeZipFile { ++ // If true, don't delete large ZIP file created for test. ++ static final boolean debug = System.getProperty("debug") != null; ++ ++ static final int DATA_LEN = 1024 * 1024; ++ static final int DATA_SIZE = 8; ++ ++ static long fileSize = 3L * 1024L * 1024L * 1024L; // 3GB ++ ++ static boolean userFile = false; ++ ++ static byte[] data; ++ static File largeFile; ++ static String lastEntryName; ++ ++ /* args can be empty, in which case check a 3 GB file which is created for ++ * this test (and then deleted). Or it can be a number, in which case ++ * that designates the size of the file that's created for this test (and ++ * then deleted). Or it can be the name of a file to use for the test, in ++ * which case it is *not* deleted. Note that in this last case, the data ++ * comparison might fail. ++ */ ++ static void realMain (String[] args) throws Throwable { ++ if (args.length > 0) { ++ try { ++ fileSize = Long.parseLong(args[0]); ++ System.out.println("Testing with file of size " + fileSize); ++ } catch (NumberFormatException ex) { ++ largeFile = new File(args[0]); ++ if (!largeFile.exists()) { ++ throw new Exception("Specified file " + args[0] + " does not exist"); ++ } ++ userFile = true; ++ System.out.println("Testing with user-provided file " + largeFile); ++ } ++ } ++ File testDir = null; ++ if (largeFile == null) { ++ testDir = new File(System.getProperty("test.scratch", "."), ++ "LargeZip"); ++ if (testDir.exists()) { ++ if (!testDir.delete()) { ++ throw new Exception("Cannot delete already-existing test directory"); ++ } ++ } ++ check(!testDir.exists() && testDir.mkdirs()); ++ largeFile = new File(testDir, "largezip.zip"); ++ createLargeZip(); ++ } ++ ++ readLargeZip(); ++ ++ if (!userFile && !debug) { ++ check(largeFile.delete()); ++ check(testDir.delete()); ++ } ++ } ++ ++ static void createLargeZip() throws Throwable { ++ int iterations = DATA_LEN / DATA_SIZE; ++ ByteBuffer bb = ByteBuffer.allocate(DATA_SIZE); ++ ByteArrayOutputStream baos = new ByteArrayOutputStream(); ++ for (int i = 0; i < iterations; i++) { ++ bb.putDouble(0, Math.random()); ++ baos.write(bb.array(), 0, DATA_SIZE); ++ } ++ data = baos.toByteArray(); ++ ++ ZipOutputStream zos = new ZipOutputStream( ++ new BufferedOutputStream(new FileOutputStream(largeFile))); ++ long length = 0; ++ while (length < fileSize) { ++ ZipEntry ze = new ZipEntry("entry-" + length); ++ lastEntryName = ze.getName(); ++ zos.putNextEntry(ze); ++ zos.write(data, 0, data.length); ++ zos.closeEntry(); ++ length = largeFile.length(); ++ } ++ System.out.println("Last entry written is " + lastEntryName); ++ zos.close(); ++ } ++ ++ static void readLargeZip() throws Throwable { ++ ZipFile zipFile = new ZipFile(largeFile); ++ ZipEntry entry = null; ++ String entryName = null; ++ int count = 0; ++ Enumeration entries = zipFile.entries(); ++ while (entries.hasMoreElements()) { ++ entry = entries.nextElement(); ++ entryName = entry.getName(); ++ count++; ++ } ++ System.out.println("Number of entries read: " + count); ++ System.out.println("Last entry read is " + entryName); ++ check(!entry.isDirectory()); ++ if (check(entryName.equals(lastEntryName))) { ++ ByteArrayOutputStream baos = new ByteArrayOutputStream(); ++ InputStream is = zipFile.getInputStream(entry); ++ byte buf[] = new byte[4096]; ++ int len; ++ while ((len = is.read(buf)) >= 0) { ++ baos.write(buf, 0, len); ++ } ++ baos.close(); ++ is.close(); ++ check(Arrays.equals(data, baos.toByteArray())); ++ } ++ try { ++ zipFile.close(); ++ } catch (IOException ioe) {/* what can you do */ } ++ } ++ ++ //--------------------- Infrastructure --------------------------- ++ static volatile int passed = 0, failed = 0; ++ static void pass() {passed++;} ++ static void pass(String msg) {System.out.println(msg); passed++;} ++ static void fail() {failed++; Thread.dumpStack();} ++ static void fail(String msg) {System.out.println(msg); fail();} ++ static void unexpected(Throwable t) {failed++; t.printStackTrace();} ++ static void unexpected(Throwable t, String msg) { ++ System.out.println(msg); failed++; t.printStackTrace();} ++ static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;} ++ static void equal(Object x, Object y) { ++ if (x == null ? y == null : x.equals(y)) pass(); ++ else fail(x + " not equal to " + y);} ++ public static void main(String[] args) throws Throwable { ++ try {realMain(args);} catch (Throwable t) {unexpected(t);} ++ System.out.println("\nPassed = " + passed + " failed = " + failed); ++ if (failed > 0) throw new AssertionError("Some tests failed");} ++} ++ diff -r 53d2442cfbec -r ae390d52ddeb patches/openjdk/6929479-pr363-disable_mmap_zip.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/6929479-pr363-disable_mmap_zip.patch Tue Oct 27 18:34:34 2015 +0000 @@ -0,0 +1,331 @@ +# HG changeset patch +# User sherman +# Date 1268345169 28800 +# Thu Mar 11 14:06:09 2010 -0800 +# Node ID ee385b4e2ffb8b05bbbb2d13fc2b5a2f52e82c1b +# Parent c6f8c58ed51a54ec68cac33031aa743ad2810231 +6929479, PR363: Add a system property sun.zip.disableMemoryMapping to disable mmap use in ZipFile +Summary: system property sun.zip.disableMemoryMapping to disable mmap use +Reviewed-by: alanb + +diff -Nru openjdk.orig/jdk/src/share/classes/java/util/zip/ZipFile.java openjdk/jdk/src/share/classes/java/util/zip/ZipFile.java +--- openjdk.orig/jdk/src/share/classes/java/util/zip/ZipFile.java 2015-07-20 17:22:20.000000000 +0100 ++++ openjdk/jdk/src/share/classes/java/util/zip/ZipFile.java 2015-10-05 01:22:49.405289000 +0100 +@@ -32,6 +32,8 @@ + import java.util.Vector; + import java.util.Enumeration; + import java.util.NoSuchElementException; ++import java.security.AccessController; ++import sun.security.action.GetPropertyAction; + + /** + * This class is used to read entries from a zip file. +@@ -74,6 +76,17 @@ + + private static native void initIDs(); + ++ private static final boolean usemmap; ++ ++ static { ++ // A system prpperty to disable mmap use to avoid vm crash when ++ // in-use zip file is accidently overwritten by others. ++ String prop = AccessController.doPrivileged( ++ new GetPropertyAction("sun.zip.disableMemoryMapping")); ++ usemmap = (prop == null || ++ !(prop.length() == 0 || prop.equalsIgnoreCase("true"))); ++ } ++ + /** + * Opens a zip file for reading. + * +@@ -129,7 +142,7 @@ + sm.checkDelete(name); + } + } +- jzfile = open(name, mode, file.lastModified()); ++ jzfile = open(name, mode, file.lastModified(), usemmap); + + this.name = name; + this.total = getTotal(jzfile); +@@ -154,7 +167,8 @@ + return locsig; + } + +- private static native long open(String name, int mode, long lastModified); ++ private static native long open(String name, int mode, long lastModified, ++ boolean usemmap); + private static native int getTotal(long jzfile); + private static native boolean startsWithLOC(long jzfile); + +diff -Nru openjdk.orig/jdk/src/share/native/java/util/zip/ZipFile.c openjdk/jdk/src/share/native/java/util/zip/ZipFile.c +--- openjdk.orig/jdk/src/share/native/java/util/zip/ZipFile.c 2015-07-20 17:22:14.000000000 +0100 ++++ openjdk/jdk/src/share/native/java/util/zip/ZipFile.c 2015-10-05 01:22:49.405289000 +0100 +@@ -79,7 +79,8 @@ + + JNIEXPORT jlong JNICALL + Java_java_util_zip_ZipFile_open(JNIEnv *env, jclass cls, jstring name, +- jint mode, jlong lastModified) ++ jint mode, jlong lastModified, ++ jboolean usemmap) + { + const char *path = JNU_GetStringPlatformChars(env, name, 0); + char *msg = 0; +@@ -105,7 +106,7 @@ + #endif + + if (zfd >= 0) { +- zip = ZIP_Put_In_Cache(path, zfd, &msg, lastModified); ++ zip = ZIP_Put_In_Cache0(path, zfd, &msg, lastModified, usemmap); + } + } + +diff -Nru openjdk.orig/jdk/src/share/native/java/util/zip/zip_util.c openjdk/jdk/src/share/native/java/util/zip/zip_util.c +--- openjdk.orig/jdk/src/share/native/java/util/zip/zip_util.c 2015-10-05 01:21:13.782879361 +0100 ++++ openjdk/jdk/src/share/native/java/util/zip/zip_util.c 2015-10-05 01:26:14.377878666 +0100 +@@ -251,11 +251,16 @@ + if (zip->lock != NULL) MDESTROY(zip->lock); + free(zip->name); + freeCEN(zip); ++ + #ifdef USE_MMAP +- if (zip->maddr != NULL) munmap((char *)zip->maddr, zip->mlen); +-#else +- free(zip->cencache.data); ++ if (zip->usemmap) { ++ if (zip->maddr != NULL) ++ munmap((char *)zip->maddr, zip->mlen); ++ } else + #endif ++ { ++ free(zip->cencache.data); ++ } + if (zip->zfd != -1) ZFILE_Close(zip->zfd); + free(zip); + } +@@ -502,49 +507,52 @@ + ZIP_FORMAT_ERROR("invalid END header (bad central directory offset)"); + + #ifdef USE_MMAP +- /* On Solaris & Linux prior to JDK 6, we used to mmap the whole jar file to +- * read the jar file contents. However, this greatly increased the perceived +- * footprint numbers because the mmap'ed pages were adding into the totals shown +- * by 'ps' and 'top'. We switched to mmaping only the central directory of jar +- * file while calling 'read' to read the rest of jar file. Here are a list of +- * reasons apart from above of why we are doing so: +- * 1. Greatly reduces mmap overhead after startup complete; +- * 2. Avoids dual path code maintainance; +- * 3. Greatly reduces risk of address space (not virtual memory) exhaustion. +- */ +- if (pagesize == 0) { +- pagesize = (jlong)sysconf(_SC_PAGESIZE); +- if (pagesize == 0) goto Catch; +- } +- if (cenpos > pagesize) { +- offset = cenpos & ~(pagesize - 1); +- } else { +- offset = 0; +- } +- /* When we are not calling recursively, knownTotal is -1. */ +- if (knownTotal == -1) { +- void* mappedAddr; +- /* Mmap the CEN and END part only. We have to figure +- out the page size in order to make offset to be multiples of +- page size. +- */ +- zip->mlen = cenpos - offset + cenlen + ENDHDR; +- zip->offset = offset; +- mappedAddr = mmap64(0, zip->mlen, PROT_READ, MAP_SHARED, zip->zfd, (off64_t) offset); +- zip->maddr = (mappedAddr == (void*) MAP_FAILED) ? NULL : +- (unsigned char*)mappedAddr; +- +- if (zip->maddr == NULL) { +- jio_fprintf(stderr, "mmap failed for CEN and END part of zip file\n"); +- goto Catch; +- } +- } +- cenbuf = zip->maddr + cenpos - offset; +-#else +- if ((cenbuf = malloc((size_t) cenlen)) == NULL || +- (readFullyAt(zip->zfd, cenbuf, cenlen, cenpos) == -1)) +- goto Catch; ++ if (zip->usemmap) { ++ /* On Solaris & Linux prior to JDK 6, we used to mmap the whole jar file to ++ * read the jar file contents. However, this greatly increased the perceived ++ * footprint numbers because the mmap'ed pages were adding into the totals shown ++ * by 'ps' and 'top'. We switched to mmaping only the central directory of jar ++ * file while calling 'read' to read the rest of jar file. Here are a list of ++ * reasons apart from above of why we are doing so: ++ * 1. Greatly reduces mmap overhead after startup complete; ++ * 2. Avoids dual path code maintainance; ++ * 3. Greatly reduces risk of address space (not virtual memory) exhaustion. ++ */ ++ if (pagesize == 0) { ++ pagesize = (jlong)sysconf(_SC_PAGESIZE); ++ if (pagesize == 0) goto Catch; ++ } ++ if (cenpos > pagesize) { ++ offset = cenpos & ~(pagesize - 1); ++ } else { ++ offset = 0; ++ } ++ /* When we are not calling recursively, knownTotal is -1. */ ++ if (knownTotal == -1) { ++ void* mappedAddr; ++ /* Mmap the CEN and END part only. We have to figure ++ out the page size in order to make offset to be multiples of ++ page size. ++ */ ++ zip->mlen = cenpos - offset + cenlen + ENDHDR; ++ zip->offset = offset; ++ mappedAddr = mmap64(0, zip->mlen, PROT_READ, MAP_SHARED, zip->zfd, (off64_t) offset); ++ zip->maddr = (mappedAddr == (void*) MAP_FAILED) ? NULL : ++ (unsigned char*)mappedAddr; ++ ++ if (zip->maddr == NULL) { ++ jio_fprintf(stderr, "mmap failed for CEN and END part of zip file\n"); ++ goto Catch; ++ } ++ } ++ cenbuf = zip->maddr + cenpos - offset; ++ } else + #endif ++ { ++ if ((cenbuf = malloc((size_t) cenlen)) == NULL || ++ (readFullyAt(zip->zfd, cenbuf, cenlen, cenpos) == -1)) ++ goto Catch; ++ } + cenend = cenbuf + cenlen; + + /* Initialize zip file data structures based on the total number +@@ -613,9 +621,11 @@ + cenpos = -1; + + Finally: +-#ifndef USE_MMAP +- free(cenbuf); ++#ifdef USE_MMAP ++ if (!zip->usemmap) + #endif ++ free(cenbuf); ++ + return cenpos; + } + +@@ -695,9 +705,17 @@ + * If a zip error occurs, then *pmsg will be set to the error message text if + * pmsg != 0. Otherwise, *pmsg will be set to NULL. + */ ++ + jzfile * + ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified) + { ++ return ZIP_Put_In_Cache0(name, zfd, pmsg, lastModified, JNI_TRUE); ++} ++ ++jzfile * ++ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified, ++ jboolean usemmap) ++{ + static char errbuf[256]; + jlong len; + jzfile *zip; +@@ -706,6 +724,9 @@ + return NULL; + } + ++#ifdef USE_MMAP ++ zip->usemmap = usemmap; ++#endif + zip->refs = 1; + zip->lastModified = lastModified; + +@@ -798,8 +819,6 @@ + return; + } + +-#ifndef USE_MMAP +- + /* Empirically, most CEN headers are smaller than this. */ + #define AMPLE_CEN_HEADER_SIZE 160 + +@@ -849,7 +868,6 @@ + cache->pos = cenpos; + return cen; + } +-#endif /* not USE_MMAP */ + + typedef enum { ACCESS_RANDOM, ACCESS_SEQUENTIAL } AccessHint; + +@@ -873,14 +891,17 @@ + ze->comment = NULL; + + #ifdef USE_MMAP +- cen = (char*) zip->maddr + zc->cenpos - zip->offset; +-#else +- if (accessHint == ACCESS_RANDOM) +- cen = readCENHeader(zip, zc->cenpos, AMPLE_CEN_HEADER_SIZE); +- else +- cen = sequentialAccessReadCENHeader(zip, zc->cenpos); +- if (cen == NULL) goto Catch; ++ if (zip->usemmap) { ++ cen = (char*) zip->maddr + zc->cenpos - zip->offset; ++ } else + #endif ++ { ++ if (accessHint == ACCESS_RANDOM) ++ cen = readCENHeader(zip, zc->cenpos, AMPLE_CEN_HEADER_SIZE); ++ else ++ cen = sequentialAccessReadCENHeader(zip, zc->cenpos); ++ if (cen == NULL) goto Catch; ++ } + + nlen = CENNAM(cen); + elen = CENEXT(cen); +@@ -919,9 +940,10 @@ + ze = NULL; + + Finally: +-#ifndef USE_MMAP +- if (cen != NULL && accessHint == ACCESS_RANDOM) free(cen); ++#ifdef USE_MMAP ++ if (!zip->usemmap) + #endif ++ if (cen != NULL && accessHint == ACCESS_RANDOM) free(cen); + return ze; + } + +diff -Nru openjdk.orig/jdk/src/share/native/java/util/zip/zip_util.h openjdk/jdk/src/share/native/java/util/zip/zip_util.h +--- openjdk.orig/jdk/src/share/native/java/util/zip/zip_util.h 2015-10-05 01:21:13.786879294 +0100 ++++ openjdk/jdk/src/share/native/java/util/zip/zip_util.h 2015-10-05 01:23:43.816383879 +0100 +@@ -41,9 +41,6 @@ + /* + * Header sizes including signatures + */ +-#ifdef USE_MMAP +-#define SIGSIZ 4 +-#endif + #define LOCHDR 30 + #define EXTHDR 16 + #define CENHDR 46 +@@ -176,9 +173,9 @@ + jlong mlen; /* length (in bytes) mmaped */ + jlong offset; /* offset of the mmapped region from the + start of the file. */ +-#else +- cencache cencache; /* CEN header cache */ ++ jboolean usemmap; /* if mmap is used. */ + #endif ++ cencache cencache; /* CEN header cache */ + jboolean locsig; /* if zip file starts with LOCSIG */ + ZFILE zfd; /* open file descriptor */ + void *lock; /* read lock */ +@@ -224,6 +221,9 @@ + jzfile * + ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified); + ++jzfile * ++ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified, jboolean usemmap); ++ + void JNICALL + ZIP_Close(jzfile *zip); + diff -r 53d2442cfbec -r ae390d52ddeb patches/openjdk/7105461-pr2662-xrender_jtables.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/7105461-pr2662-xrender_jtables.patch Tue Oct 27 18:34:34 2015 +0000 @@ -0,0 +1,117 @@ +# HG changeset patch +# User ceisserer +# Date 1352851930 28800 +# Tue Nov 13 16:12:10 2012 -0800 +# Node ID 96b5c3822ce9ff27bce5977e55ba36d5d15c524c +# Parent b0194003cf27684b07bbcfdb94d5a7f9594f5978 +7105461, PR2662: Large JTables are not rendered correctly with Xrender pipeline +Reviewed-by: flar, prr + +diff -r b0194003cf27 -r 96b5c3822ce9 src/solaris/classes/sun/java2d/xr/XRRenderer.java +--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java Mon Apr 09 15:49:33 2012 -0700 ++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java Tue Nov 13 16:12:10 2012 -0800 +@@ -27,7 +27,6 @@ + + import java.awt.*; + import java.awt.geom.*; +- + import sun.awt.SunToolkit; + import sun.java2d.SunGraphics2D; + import sun.java2d.loops.*; +@@ -39,6 +38,9 @@ + import sun.java2d.pipe.ShapeSpanIterator; + import sun.java2d.pipe.LoopPipe; + ++import static sun.java2d.xr.XRUtils.clampToShort; ++import static sun.java2d.xr.XRUtils.clampToUShort; ++ + /** + * XRender provides only accalerated rectangles. To emulate higher "order" + * geometry we have to pass everything else to DoPath/FillSpans. +@@ -70,17 +72,16 @@ + + public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2) { + Region compClip = sg2d.getCompClip(); +- int transX1 = x1 + sg2d.transX; +- int transY1 = y1 + sg2d.transY; +- int transX2 = x2 + sg2d.transX; +- int transY2 = y2 + sg2d.transY; ++ int transX1 = Region.clipAdd(x1, sg2d.transX); ++ int transY1 = Region.clipAdd(y1, sg2d.transY); ++ int transX2 = Region.clipAdd(x2, sg2d.transX); ++ int transY2 = Region.clipAdd(y2, sg2d.transY); + + // Non clipped fast path + if (compClip.contains(transX1, transY1) + && compClip.contains(transX2, transY2)) { ++ SunToolkit.awtLock(); + try { +- SunToolkit.awtLock(); +- + validateSurface(sg2d); + tileManager.addLine(transX1, transY1, transX2, transY2); + tileManager.fillMask((XRSurfaceData) sg2d.surfaceData); +@@ -115,20 +116,40 @@ + draw(sg2d, new Polygon(xpoints, ypoints, npoints)); + } + +- public synchronized void fillRect(SunGraphics2D sg2d, +- int x, int y, int width, int height) { ++ public void fillRect(SunGraphics2D sg2d, int x, int y, int width, int height) { ++ x = Region.clipAdd(x, sg2d.transX); ++ y = Region.clipAdd(y, sg2d.transY); ++ ++ /* ++ * Limit x/y to signed short, width/height to unsigned short, ++ * to match the X11 coordinate limits for rectangles. ++ * Correct width/height in case x/y have been modified by clipping. ++ */ ++ if (x > Short.MAX_VALUE || y > Short.MAX_VALUE) { ++ return; ++ } ++ ++ int x2 = Region.dimAdd(x, width); ++ int y2 = Region.dimAdd(y, height); ++ ++ if (x2 < Short.MIN_VALUE || y2 < Short.MIN_VALUE) { ++ return; ++ } ++ ++ x = clampToShort(x); ++ y = clampToShort(y); ++ width = clampToUShort(x2 - x); ++ height = clampToUShort(y2 - y); ++ ++ if (width == 0 || height == 0) { ++ return; ++ } ++ + SunToolkit.awtLock(); + try { + validateSurface(sg2d); +- +- XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData; +- +- x += sg2d.transform.getTranslateX(); +- y += sg2d.transform.getTranslateY(); +- + tileManager.addRect(x, y, width, height); +- tileManager.fillMask(xrsd); +- ++ tileManager.fillMask((XRSurfaceData) sg2d.surfaceData); + } finally { + SunToolkit.awtUnlock(); + } +diff -r b0194003cf27 -r 96b5c3822ce9 src/solaris/classes/sun/java2d/xr/XRUtils.java +--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java Mon Apr 09 15:49:33 2012 -0700 ++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRUtils.java Tue Nov 13 16:12:10 2012 -0800 +@@ -255,7 +255,7 @@ + : (x < Short.MIN_VALUE ? Short.MIN_VALUE : x)); + } + +- public static short clampToUShort(int x) { +- return (short) (x > 65535 ? 65535 : (x < 0) ? 0 : x); ++ public static int clampToUShort(int x) { ++ return (x > 65535 ? 65535 : (x < 0) ? 0 : x); + } + } diff -r 53d2442cfbec -r ae390d52ddeb patches/openjdk/7150134-pr2662-xrender_drawline_oom.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/openjdk/7150134-pr2662-xrender_drawline_oom.patch Tue Oct 27 18:34:34 2015 +0000 @@ -0,0 +1,51 @@ +# HG changeset patch +# User ceisserer +# Date 1334011773 25200 +# Mon Apr 09 15:49:33 2012 -0700 +# Node ID b0194003cf27684b07bbcfdb94d5a7f9594f5978 +# Parent 32f25e4cc4aa55ed72c9d2d92cdc54d085a0b851 +7150134, PR2662: JCK api/java_awt/Graphics/index.html#DrawLine fails with OOM for jdk8 with XRender pipeline +Reviewed-by: prr + +diff -r 32f25e4cc4aa -r b0194003cf27 src/solaris/classes/sun/java2d/xr/XRRenderer.java +--- openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java Sat Oct 03 19:28:14 2015 +0100 ++++ openjdk/jdk/src/solaris/classes/sun/java2d/xr/XRRenderer.java Mon Apr 09 15:49:33 2012 -0700 +@@ -69,20 +69,26 @@ + } + + public void drawLine(SunGraphics2D sg2d, int x1, int y1, int x2, int y2) { +- try { +- SunToolkit.awtLock(); ++ Region compClip = sg2d.getCompClip(); ++ int transX1 = x1 + sg2d.transX; ++ int transY1 = y1 + sg2d.transY; ++ int transX2 = x2 + sg2d.transX; ++ int transY2 = y2 + sg2d.transY; + +- validateSurface(sg2d); +- int transx = sg2d.transX; +- int transy = sg2d.transY; ++ // Non clipped fast path ++ if (compClip.contains(transX1, transY1) ++ && compClip.contains(transX2, transY2)) { ++ try { ++ SunToolkit.awtLock(); + +- XRSurfaceData xrsd = (XRSurfaceData) sg2d.surfaceData; +- +- tileManager.addLine(x1 + transx, y1 + transy, +- x2 + transx, y2 + transy); +- tileManager.fillMask(xrsd); +- } finally { +- SunToolkit.awtUnlock(); ++ validateSurface(sg2d); ++ tileManager.addLine(transX1, transY1, transX2, transY2); ++ tileManager.fillMask((XRSurfaceData) sg2d.surfaceData); ++ } finally { ++ SunToolkit.awtUnlock(); ++ } ++ } else { ++ draw(sg2d, new Line2D.Float(x1, y1, x2, y2)); + } + } + diff -r 53d2442cfbec -r ae390d52ddeb patches/pr2513-layoutengine_reset.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/pr2513-layoutengine_reset.patch Tue Oct 27 18:34:34 2015 +0000 @@ -0,0 +1,22 @@ +# HG changeset patch +# User andrew +# Date 1443896894 -3600 +# Sat Oct 03 19:28:14 2015 +0100 +# Node ID 32f25e4cc4aa55ed72c9d2d92cdc54d085a0b851 +# Parent 7dd31da3f90a3f631be8ee3083264f9815c10973 +PR2513: Reset success following calls in LayoutManager.cpp + +diff -Nru openjdk.orig/jdk/src/share/native/sun/font/layout/LayoutEngine.cpp openjdk/jdk/src/share/native/sun/font/layout/LayoutEngine.cpp +--- openjdk.orig/jdk/src/share/native/sun/font/layout/LayoutEngine.cpp 2015-07-20 17:22:21.000000000 +0100 ++++ openjdk/jdk/src/share/native/sun/font/layout/LayoutEngine.cpp 2015-10-05 01:40:33.895560477 +0100 +@@ -661,6 +661,10 @@ + break; + } + } else { ++ if (LE_FAILURE(success)) { ++ // Reset if gsubTable failed ++ success = LE_NO_ERROR; ++ } + LEReferenceTo mortTable(fontInstance, mortTableTag, success); + + if (LE_SUCCESS(success) && mortTable.isValid() && SWAPL(mortTable->version)==0x00010000) { // mort