Merge
authorhenryjen
Tue, 15 Oct 2019 21:33:54 +0000
changeset 58639 e0bb6b38a6f6
parent 58638 7be56b2ac50d (diff)
parent 58609 fbfc72ec8e6b (current diff)
child 58641 55fe0d93bdd3
Merge
src/java.desktop/unix/native/common/awt/awt_Font.h
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Tue Oct 15 21:33:54 2019 +0000
@@ -6352,7 +6352,7 @@
   movptr(result, str1);
   if (UseAVX >= 2) {
     cmpl(cnt1, stride);
-    jcc(Assembler::less, SCAN_TO_CHAR_LOOP);
+    jcc(Assembler::less, SCAN_TO_CHAR);
     cmpl(cnt1, 2*stride);
     jcc(Assembler::less, SCAN_TO_8_CHAR_INIT);
     movdl(vec1, ch);
@@ -6379,10 +6379,8 @@
   }
   bind(SCAN_TO_8_CHAR);
   cmpl(cnt1, stride);
-  if (UseAVX >= 2) {
-    jcc(Assembler::less, SCAN_TO_CHAR);
-  } else {
-    jcc(Assembler::less, SCAN_TO_CHAR_LOOP);
+  jcc(Assembler::less, SCAN_TO_CHAR);
+  if (UseAVX < 2) {
     movdl(vec1, ch);
     pshuflw(vec1, vec1, 0x00);
     pshufd(vec1, vec1, 0);
--- a/src/java.base/share/classes/java/io/FilePermission.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/classes/java/io/FilePermission.java	Tue Oct 15 21:33:54 2019 +0000
@@ -367,12 +367,22 @@
             this.mask = mask;
 
             if (cpath.equals("<<ALL FILES>>")) {
+                allFiles = true;
                 directory = true;
                 recursive = true;
                 cpath = "";
                 return;
             }
 
+            // Validate path by platform's default file system
+            try {
+                String name = cpath.endsWith("*") ? cpath.substring(0, cpath.length() - 1) + "-" : cpath;
+                builtInFS.getPath(new File(name).getPath());
+            } catch (InvalidPathException ipe) {
+                invalid = true;
+                return;
+            }
+
             // store only the canonical cpath if possible
             cpath = AccessController.doPrivileged(new PrivilegedAction<>() {
                 public String run() {
@@ -463,6 +473,9 @@
      * <P>
      * The default value of the {@code jdk.io.permissionsUseCanonicalPath}
      * system property is {@code false} in this implementation.
+     * <p>
+     * The value can also be set with a security property using the same name,
+     * but setting a system property will override the security property value.
      *
      * @param path the pathname of the file/directory.
      * @param actions the action string.
@@ -573,19 +586,19 @@
      * @return the effective mask
      */
     boolean impliesIgnoreMask(FilePermission that) {
+        if (this == that) {
+            return true;
+        }
+        if (allFiles) {
+            return true;
+        }
+        if (this.invalid || that.invalid) {
+            return false;
+        }
+        if (that.allFiles) {
+            return false;
+        }
         if (FilePermCompat.nb) {
-            if (this == that) {
-                return true;
-            }
-            if (allFiles) {
-                return true;
-            }
-            if (this.invalid || that.invalid) {
-                return false;
-            }
-            if (that.allFiles) {
-                return false;
-            }
             // Left at least same level of wildness as right
             if ((this.recursive && that.recursive) != that.recursive
                     || (this.directory && that.directory) != that.directory) {
@@ -783,10 +796,10 @@
 
         FilePermission that = (FilePermission) obj;
 
+        if (this.invalid || that.invalid) {
+            return false;
+        }
         if (FilePermCompat.nb) {
-            if (this.invalid || that.invalid) {
-                return false;
-            }
             return (this.mask == that.mask) &&
                     (this.allFiles == that.allFiles) &&
                     this.npath.equals(that.npath) &&
@@ -795,6 +808,7 @@
                     (this.recursive == that.recursive);
         } else {
             return (this.mask == that.mask) &&
+                    (this.allFiles == that.allFiles) &&
                     this.cpath.equals(that.cpath) &&
                     (this.directory == that.directory) &&
                     (this.recursive == that.recursive);
--- a/src/java.base/share/classes/java/net/NetPermission.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/classes/java/net/NetPermission.java	Tue Oct 15 21:33:54 2019 +0000
@@ -145,6 +145,15 @@
  *   </tr>
  *
  * <tr>
+ *   <th scope="row">setSocketImpl</th>
+ *   <td>The ability to create a sub-class of Socket or ServerSocket with a
+ *   user specified SocketImpl.</td>
+ *   <td>Malicious user-defined SocketImpls can change the behavior of
+ *   Socket and ServerSocket in surprising ways, by virtue of their
+ *   ability to access the protected fields of SocketImpl.</td>
+ *   </tr>
+ *
+ * <tr>
  *   <th scope="row">specifyStreamHandler</th>
  *   <td>The ability
  *   to specify a stream handler when constructing a URL</td>
--- a/src/java.base/share/classes/java/net/ServerSocket.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/classes/java/net/ServerSocket.java	Tue Oct 15 21:33:54 2019 +0000
@@ -32,6 +32,7 @@
 import java.util.Set;
 import java.util.Collections;
 
+import sun.security.util.SecurityConstants;
 import sun.net.PlatformSocketImpl;
 
 /**
@@ -73,13 +74,25 @@
      *
      * @throws     NullPointerException if impl is {@code null}.
      *
+     * @throws     SecurityException if a security manager is set and
+     *             its {@code checkPermission} method doesn't allow
+     *             {@code NetPermission("setSocketImpl")}.
      * @since 12
      */
     protected ServerSocket(SocketImpl impl) {
         Objects.requireNonNull(impl);
+        checkPermission();
         this.impl = impl;
     }
 
+    private static Void checkPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION);
+        }
+        return null;
+    }
+
     /**
      * Creates an unbound server socket.
      *
--- a/src/java.base/share/classes/java/net/Socket.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/classes/java/net/Socket.java	Tue Oct 15 21:33:54 2019 +0000
@@ -25,6 +25,8 @@
 
 package java.net;
 
+import sun.security.util.SecurityConstants;
+
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.IOException;
@@ -182,12 +184,28 @@
      *
      * @throws    SocketException if there is an error in the underlying protocol,
      * such as a TCP error.
+     *
+     * @throws SecurityException if {@code impl} is non-null and a security manager is set
+     * and its {@code checkPermission} method doesn't allow {@code NetPermission("setSocketImpl")}.
+     *
      * @since   1.1
      */
     protected Socket(SocketImpl impl) throws SocketException {
+        checkPermission(impl);
         this.impl = impl;
     }
 
+    private static Void checkPermission(SocketImpl impl) {
+        if (impl == null) {
+            return null;
+        }
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION);
+        }
+        return null;
+    }
+
     /**
      * Creates a stream socket and connects it to the specified port
      * number on the named host.
--- a/src/java.base/share/classes/java/net/URL.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/classes/java/net/URL.java	Tue Oct 15 21:33:54 2019 +0000
@@ -484,6 +484,16 @@
                 throw new MalformedURLException(s);
             }
         }
+        if ("jar".equalsIgnoreCase(protocol)) {
+            if (handler instanceof sun.net.www.protocol.jar.Handler) {
+                // URL.openConnection() would throw a confusing exception
+                // so generate a better exception here instead.
+                String s = ((sun.net.www.protocol.jar.Handler) handler).checkNestedProtocol(file);
+                if (s != null) {
+                    throw new MalformedURLException(s);
+                }
+            }
+        }
     }
 
     /**
--- a/src/java.base/share/classes/java/util/regex/Pattern.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/classes/java/util/regex/Pattern.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1427,7 +1427,11 @@
         localTCNCount = 0;
 
         if (!pattern.isEmpty()) {
-            compile();
+            try {
+                compile();
+            } catch (StackOverflowError soe) {
+                throw error("Stack overflow during pattern compilation");
+            }
         } else {
             root = new Start(lastAccept);
             matchRoot = lastAccept;
@@ -1965,6 +1969,10 @@
         int ch = temp[cursor++];
         while (ch != 0 && !isLineSeparator(ch))
             ch = temp[cursor++];
+        if (ch == 0 && cursor > patternLength) {
+            cursor = patternLength;
+            ch = temp[cursor++];
+        }
         return ch;
     }
 
@@ -1975,6 +1983,10 @@
         int ch = temp[++cursor];
         while (ch != 0 && !isLineSeparator(ch))
             ch = temp[++cursor];
+        if (ch == 0 && cursor > patternLength) {
+            cursor = patternLength;
+            ch = temp[cursor];
+        }
         return ch;
     }
 
@@ -3415,9 +3427,10 @@
     private int N() {
         if (read() == '{') {
             int i = cursor;
-            while (cursor < patternLength && read() != '}') {}
-            if (cursor > patternLength)
-                throw error("Unclosed character name escape sequence");
+            while (read() != '}') {
+                if (cursor >= patternLength)
+                    throw error("Unclosed character name escape sequence");
+            }
             String name = new String(temp, i, cursor - i - 1);
             try {
                 return Character.codePointOf(name);
--- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Tue Oct 15 21:33:54 2019 +0000
@@ -2171,6 +2171,10 @@
             } while (retryTunnel < maxRedirects);
 
             if (retryTunnel >= maxRedirects || (respCode != HTTP_OK)) {
+                if (respCode != HTTP_PROXY_AUTH) {
+                    // remove all but authenticate responses
+                    responses.reset();
+                }
                 throw new IOException("Unable to tunnel through proxy."+
                                       " Proxy returns \"" +
                                       statusLine + "\"");
--- a/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/classes/sun/net/www/protocol/jar/Handler.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, 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
@@ -121,6 +121,13 @@
         return h;
     }
 
+    public String checkNestedProtocol(String spec) {
+        if (spec.regionMatches(true, 0, "jar:", 0, 4)) {
+            return "Nested JAR URLs are not supported";
+        } else {
+            return null;
+        }
+    }
 
     @Override
     @SuppressWarnings("deprecation")
@@ -146,6 +153,12 @@
                 : false;
         spec = spec.substring(start, limit);
 
+        String exceptionMessage = checkNestedProtocol(spec);
+        if (exceptionMessage != null) {
+            // NPE will be transformed into MalformedURLException by the caller
+            throw new NullPointerException(exceptionMessage);
+        }
+
         if (absoluteSpec) {
             file = parseAbsoluteSpec(spec);
         } else if (!refOnly) {
--- a/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java	Tue Oct 15 21:33:54 2019 +0000
@@ -37,6 +37,9 @@
 import java.nio.channels.IllegalBlockingModeException;
 import java.nio.channels.ServerSocketChannel;
 import java.nio.channels.SocketChannel;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 import java.util.Set;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -59,7 +62,12 @@
     private volatile int timeout;
 
     static ServerSocket create(ServerSocketChannelImpl ssc) {
-        return new ServerSocketAdaptor(ssc);
+        PrivilegedExceptionAction<ServerSocket> pa = () -> new ServerSocketAdaptor(ssc);
+        try {
+            return AccessController.doPrivileged(pa);
+        } catch (PrivilegedActionException pae) {
+            throw new InternalError("Should not reach here", pae);
+        }
     }
 
     private ServerSocketAdaptor(ServerSocketChannelImpl ssc) {
--- a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java	Tue Oct 15 21:33:54 2019 +0000
@@ -36,6 +36,9 @@
 import java.net.SocketOption;
 import java.net.StandardSocketOptions;
 import java.nio.channels.SocketChannel;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 import java.util.Set;
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -61,10 +64,11 @@
     }
 
     static Socket create(SocketChannelImpl sc) {
+        PrivilegedExceptionAction<Socket> pa = () -> new SocketAdaptor(sc);
         try {
-            return new SocketAdaptor(sc);
-        } catch (SocketException e) {
-            throw new InternalError("Should not reach here");
+            return AccessController.doPrivileged(pa);
+        } catch (PrivilegedActionException pae) {
+            throw new InternalError("Should not reach here", pae);
         }
     }
 
--- a/src/java.base/share/classes/sun/security/ssl/SupportedGroupsExtension.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/classes/sun/security/ssl/SupportedGroupsExtension.java	Tue Oct 15 21:33:54 2019 +0000
@@ -201,7 +201,7 @@
                         // Primary XDH (RFC 7748) curves
                         NamedGroup.X25519,
 
-                        // Primary NIST curves (e.g. used in TLSv1.3)
+                        // Primary NIST Suite B curves
                         NamedGroup.SECP256_R1,
                         NamedGroup.SECP384_R1,
                         NamedGroup.SECP521_R1,
@@ -209,17 +209,6 @@
                         // Secondary XDH curves
                         NamedGroup.X448,
 
-                        // Secondary NIST curves
-                        NamedGroup.SECT283_K1,
-                        NamedGroup.SECT283_R1,
-                        NamedGroup.SECT409_K1,
-                        NamedGroup.SECT409_R1,
-                        NamedGroup.SECT571_K1,
-                        NamedGroup.SECT571_R1,
-
-                        // non-NIST curves
-                        NamedGroup.SECP256_K1,
-
                         // FFDHE (RFC 7919)
                         NamedGroup.FFDHE_2048,
                         NamedGroup.FFDHE_3072,
--- a/src/java.base/share/classes/sun/security/util/FilePermCompat.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/classes/sun/security/util/FilePermCompat.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -42,8 +42,11 @@
     public static final boolean compat;
 
     static {
-        String flag = GetPropertyAction.privilegedGetProperty(
-                "jdk.io.permissionsUseCanonicalPath", "false");
+        String flag = SecurityProperties.privilegedGetOverridable(
+                "jdk.io.permissionsUseCanonicalPath");
+        if (flag == null) {
+            flag = "false";
+        }
         switch (flag) {
             case "true":
                 nb = false;
--- a/src/java.base/share/classes/sun/security/util/SecurityConstants.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/classes/sun/security/util/SecurityConstants.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -97,6 +97,10 @@
     public static final NetPermission GET_RESPONSECACHE_PERMISSION =
        new NetPermission("getResponseCache");
 
+    // java.net.ServerSocket, java.net.Socket
+    public static final NetPermission SET_SOCKETIMPL_PERMISSION =
+        new NetPermission("setSocketImpl");
+
     // java.lang.SecurityManager, sun.applet.AppletPanel
     public static final RuntimePermission CREATE_CLASSLOADER_PERMISSION =
         new RuntimePermission("createClassLoader");
--- a/src/java.base/share/conf/security/java.security	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/share/conf/security/java.security	Tue Oct 15 21:33:54 2019 +0000
@@ -1213,3 +1213,51 @@
 # if this property is not enabled.
 #
 jdk.security.caDistrustPolicies=SYMANTEC_TLS
+
+#
+# FilePermission path canonicalization
+#
+# This security property dictates how the path argument is processed and stored
+# while constructing a FilePermission object. If the value is set to true, the
+# path argument is canonicalized and FilePermission methods (such as implies,
+# equals, and hashCode) are implemented based on this canonicalized result.
+# Otherwise, the path argument is not canonicalized and FilePermission methods are
+# implemented based on the original input. See the implementation note of the
+# FilePermission class for more details.
+#
+# If a system property of the same name is also specified, it supersedes the
+# security property value defined here.
+#
+# The default value for this property is false.
+#
+jdk.io.permissionsUseCanonicalPath=false
+
+
+#
+# Policies for the proxy_impersonator Kerberos ccache configuration entry
+#
+# The proxy_impersonator ccache configuration entry indicates that the ccache
+# is a synthetic delegated credential for use with S4U2Proxy by an intermediate
+# server. The ccache file should also contain the TGT of this server and
+# an evidence ticket from the default principal of the ccache to this server.
+#
+# This security property determines how Java uses this configuration entry.
+# There are 3 possible values:
+#
+#  no-impersonate     - Ignore this configuration entry, and always act as
+#                       the owner of the TGT (if it exists).
+#
+#  try-impersonate    - Try impersonation when this configuration entry exists.
+#                       If no matching TGT or evidence ticket is found,
+#                       fallback to no-impersonate.
+#
+#  always-impersonate - Always impersonate when this configuration entry exists.
+#                       If no matching TGT or evidence ticket is found,
+#                       no initial credential is read from the ccache.
+#
+# The default value is "always-impersonate".
+#
+# If a system property of the same name is also specified, it supersedes the
+# security property value defined here.
+#
+#jdk.security.krb5.default.initiate.credential=always-impersonate
--- a/src/java.base/windows/classes/java/lang/ProcessImpl.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.base/windows/classes/java/lang/ProcessImpl.java	Tue Oct 15 21:33:54 2019 +0000
@@ -38,6 +38,7 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
+import java.util.Locale;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
@@ -46,6 +47,8 @@
 import jdk.internal.access.JavaIOFileDescriptorAccess;
 import jdk.internal.access.SharedSecrets;
 import jdk.internal.ref.CleanerFactory;
+import sun.security.action.GetBooleanAction;
+import sun.security.action.GetPropertyAction;
 
 /* This class is for the exclusive use of ProcessBuilder.start() to
  * create new processes.
@@ -209,12 +212,15 @@
 
     private static final int VERIFICATION_CMD_BAT = 0;
     private static final int VERIFICATION_WIN32 = 1;
-    private static final int VERIFICATION_LEGACY = 2;
+    private static final int VERIFICATION_WIN32_SAFE = 2; // inside quotes not allowed
+    private static final int VERIFICATION_LEGACY = 3;
+    // See Command shell overview for documentation of special characters.
+    // https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb490954(v=technet.10)
     private static final char ESCAPE_VERIFICATION[][] = {
         // We guarantee the only command file execution for implicit [cmd.exe] run.
         //    http://technet.microsoft.com/en-us/library/bb490954.aspx
         {' ', '\t', '<', '>', '&', '|', '^'},
-
+        {' ', '\t', '<', '>'},
         {' ', '\t', '<', '>'},
         {' ', '\t'}
     };
@@ -231,8 +237,25 @@
             cmdbuf.append(' ');
             String s = cmd[i];
             if (needsEscaping(verificationType, s)) {
-                cmdbuf.append('"').append(s);
+                cmdbuf.append('"');
 
+                if (verificationType == VERIFICATION_WIN32_SAFE) {
+                    // Insert the argument, adding '\' to quote any interior quotes
+                    int length = s.length();
+                    for (int j = 0; j < length; j++) {
+                        char c = s.charAt(j);
+                        if (c == DOUBLEQUOTE) {
+                            int count = countLeadingBackslash(verificationType, s, j);
+                            while (count-- > 0) {
+                                cmdbuf.append(BACKSLASH);   // double the number of backslashes
+                            }
+                            cmdbuf.append(BACKSLASH);       // backslash to quote the quote
+                        }
+                        cmdbuf.append(c);
+                    }
+                } else {
+                    cmdbuf.append(s);
+                }
                 // The code protects the [java.exe] and console command line
                 // parser, that interprets the [\"] combination as an escape
                 // sequence for the ["] char.
@@ -245,8 +268,9 @@
                 // command line parser. The case of the [""] tail escape
                 // sequence could not be realized due to the argument validation
                 // procedure.
-                if ((verificationType != VERIFICATION_CMD_BAT) && s.endsWith("\\")) {
-                    cmdbuf.append('\\');
+                int count = countLeadingBackslash(verificationType, s, s.length());
+                while (count-- > 0) {
+                    cmdbuf.append(BACKSLASH);   // double the number of backslashes
                 }
                 cmdbuf.append('"');
             } else {
@@ -256,26 +280,16 @@
         return cmdbuf.toString();
     }
 
-    private static boolean isQuoted(boolean noQuotesInside, String arg,
-            String errorMessage) {
-        int lastPos = arg.length() - 1;
-        if (lastPos >=1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
-            // The argument has already been quoted.
-            if (noQuotesInside) {
-                if (arg.indexOf('"', 1) != lastPos) {
-                    // There is ["] inside.
-                    throw new IllegalArgumentException(errorMessage);
-                }
-            }
-            return true;
-        }
-        if (noQuotesInside) {
-            if (arg.indexOf('"') >= 0) {
-                // There is ["] inside.
-                throw new IllegalArgumentException(errorMessage);
-            }
-        }
-        return false;
+    /**
+     * Return the argument without quotes (1st and last) if present, else the arg.
+     * @param str a string
+     * @return the string without 1st and last quotes
+     */
+    private static String unQuote(String str) {
+        int len = str.length();
+        return (len >= 2 && str.charAt(0) == DOUBLEQUOTE && str.charAt(len - 1) == DOUBLEQUOTE)
+                ? str.substring(1, len - 1)
+                : str;
     }
 
     private static boolean needsEscaping(int verificationType, String arg) {
@@ -286,9 +300,26 @@
 
         // For [.exe] or [.com] file the unpaired/internal ["]
         // in the argument is not a problem.
-        boolean argIsQuoted = isQuoted(
-            (verificationType == VERIFICATION_CMD_BAT),
-            arg, "Argument has embedded quote, use the explicit CMD.EXE call.");
+        String unquotedArg = unQuote(arg);
+        boolean argIsQuoted = !arg.equals(unquotedArg);
+        boolean embeddedQuote = unquotedArg.indexOf(DOUBLEQUOTE) >= 0;
+
+        switch (verificationType) {
+            case VERIFICATION_CMD_BAT:
+                if (embeddedQuote) {
+                    throw new IllegalArgumentException("Argument has embedded quote, " +
+                            "use the explicit CMD.EXE call.");
+                }
+                break;  // break determine whether to quote
+            case VERIFICATION_WIN32_SAFE:
+                if (argIsQuoted && embeddedQuote)  {
+                    throw new IllegalArgumentException("Malformed argument has embedded quote: "
+                            + unquotedArg);
+                }
+                break;
+            default:
+                break;
+        }
 
         if (!argIsQuoted) {
             char testEscape[] = ESCAPE_VERIFICATION[verificationType];
@@ -304,13 +335,13 @@
     private static String getExecutablePath(String path)
         throws IOException
     {
-        boolean pathIsQuoted = isQuoted(true, path,
-                "Executable name has embedded quote, split the arguments");
-
+        String name = unQuote(path);
+        if (name.indexOf(DOUBLEQUOTE) >= 0) {
+            throw new IllegalArgumentException("Executable name has embedded quote, " +
+                    "split the arguments: " + name);
+        }
         // Win32 CreateProcess requires path to be normalized
-        File fileToRun = new File(pathIsQuoted
-            ? path.substring(1, path.length() - 1)
-            : path);
+        File fileToRun = new File(name);
 
         // From the [CreateProcess] function documentation:
         //
@@ -325,13 +356,26 @@
         // sequence:..."
         //
         // In practice ANY non-existent path is extended by [.exe] extension
-        // in the [CreateProcess] funcion with the only exception:
+        // in the [CreateProcess] function with the only exception:
         // the path ends by (.)
 
         return fileToRun.getPath();
     }
 
+    /**
+     * An executable is any program that is an EXE or does not have an extension
+     * and the Windows createProcess will be looking for .exe.
+     * The comparison is case insensitive based on the name.
+     * @param executablePath the executable file
+     * @return true if the path ends in .exe or does not have an extension.
+     */
+    private boolean isExe(String executablePath) {
+        File file = new File(executablePath);
+        String upName = file.getName().toUpperCase(Locale.ROOT);
+        return (upName.endsWith(".EXE") || upName.indexOf('.') < 0);
+    }
 
+    // Old version that can be bypassed
     private boolean isShellFile(String executablePath) {
         String upPath = executablePath.toUpperCase();
         return (upPath.endsWith(".CMD") || upPath.endsWith(".BAT"));
@@ -342,6 +386,21 @@
         return argbuf.append('"').append(arg).append('"').toString();
     }
 
+    // Count backslashes before start index of string.
+    // .bat files don't include backslashes as part of the quote
+    private static int countLeadingBackslash(int verificationType,
+                                             CharSequence input, int start) {
+        if (verificationType == VERIFICATION_CMD_BAT)
+            return 0;
+        int j;
+        for (j = start - 1; j >= 0 && input.charAt(j) == BACKSLASH; j--) {
+            // just scanning backwards
+        }
+        return (start - 1) - j;  // number of BACKSLASHES
+    }
+
+    private static final char DOUBLEQUOTE = '\"';
+    private static final char BACKSLASH = '\\';
 
     private final long handle;
     private final ProcessHandle processHandle;
@@ -358,15 +417,13 @@
         throws IOException
     {
         String cmdstr;
-        SecurityManager security = System.getSecurityManager();
-        boolean allowAmbiguousCommands = false;
-        if (security == null) {
-            allowAmbiguousCommands = true;
-            String value = System.getProperty("jdk.lang.Process.allowAmbiguousCommands");
-            if (value != null)
-                allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
-        }
-        if (allowAmbiguousCommands) {
+        final SecurityManager security = System.getSecurityManager();
+        final String value = GetPropertyAction.
+                privilegedGetProperty("jdk.lang.Process.allowAmbiguousCommands",
+                        (security == null ? "true" : "false"));
+        final boolean allowAmbiguousCommands = !"false".equalsIgnoreCase(value);
+
+        if (allowAmbiguousCommands && security == null) {
             // Legacy mode.
 
             // Normalize path if possible.
@@ -413,11 +470,12 @@
             // Quotation protects from interpretation of the [path] argument as
             // start of longer path with spaces. Quotation has no influence to
             // [.exe] extension heuristic.
+            boolean isShell = allowAmbiguousCommands ? isShellFile(executablePath)
+                    : !isExe(executablePath);
             cmdstr = createCommandLine(
-                    // We need the extended verification procedure for CMD files.
-                    isShellFile(executablePath)
-                        ? VERIFICATION_CMD_BAT
-                        : VERIFICATION_WIN32,
+                    // We need the extended verification procedures
+                    isShell ? VERIFICATION_CMD_BAT
+                            : (allowAmbiguousCommands ? VERIFICATION_WIN32 : VERIFICATION_WIN32_SAFE),
                     quoteString(executablePath),
                     cmd);
         }
--- a/src/java.desktop/share/classes/java/awt/Font.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/share/classes/java/awt/Font.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1929,6 +1929,7 @@
         // value is the default.
 
         if (fRequestedAttributes != null) {
+            try {
             values = getAttributeValues(); // init
             AttributeValues extras =
                 AttributeValues.fromSerializableHashtable(fRequestedAttributes);
@@ -1938,10 +1939,13 @@
             values = getAttributeValues().merge(extras);
             this.nonIdentityTx = values.anyNonDefault(EXTRA_MASK);
             this.hasLayoutAttributes =  values.anyNonDefault(LAYOUT_MASK);
-
+            } catch (Throwable t) {
+                throw new IOException(t);
+            } finally {
             fRequestedAttributes = null; // don't need it any more
         }
     }
+    }
 
     /**
      * Returns the number of glyphs in this {@code Font}. Glyph codes
--- a/src/java.desktop/share/classes/sun/font/CMap.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/share/classes/sun/font/CMap.java	Tue Oct 15 21:33:54 2019 +0000
@@ -130,7 +130,7 @@
 
     static final char noSuchChar = (char)0xfffd;
     static final int SHORTMASK = 0x0000ffff;
-    static final int INTMASK   = 0xffffffff;
+    static final int INTMASK   = 0x7fffffff;
 
     static final char[][] converterMaps = new char[7][];
 
@@ -919,7 +919,11 @@
 
              bbuffer.position(12);
              bbuffer.get(is32);
-             nGroups = bbuffer.getInt();
+             nGroups = bbuffer.getInt() & INTMASK;
+             // A map group record is three uint32's making for 12 bytes total
+             if (bbuffer.remaining() < (12 * (long)nGroups)) {
+                 throw new RuntimeException("Format 8 table exceeded");
+             }
              startCharCode = new int[nGroups];
              endCharCode   = new int[nGroups];
              startGlyphID  = new int[nGroups];
@@ -947,9 +951,13 @@
 
          CMapFormat10(ByteBuffer bbuffer, int offset, char[] xlat) {
 
+             bbuffer.position(offset+12);
              firstCode = bbuffer.getInt() & INTMASK;
              entryCount = bbuffer.getInt() & INTMASK;
-             bbuffer.position(offset+20);
+             // each glyph is a uint16, so 2 bytes per value.
+             if (bbuffer.remaining() < (2 * (long)entryCount)) {
+                 throw new RuntimeException("Format 10 table exceeded");
+             }
              CharBuffer buffer = bbuffer.asCharBuffer();
              glyphIdArray = new char[entryCount];
              for (int i=0; i< entryCount; i++) {
@@ -989,11 +997,15 @@
                 throw new RuntimeException("xlat array for cmap fmt=12");
             }
 
-            numGroups = buffer.getInt(offset+12);
+            buffer.position(offset+12);
+            numGroups = buffer.getInt() & INTMASK;
+            // A map group record is three uint32's making for 12 bytes total
+            if (buffer.remaining() < (12 * (long)numGroups)) {
+                throw new RuntimeException("Format 12 table exceeded");
+            }
             startCharCode = new long[numGroups];
             endCharCode = new long[numGroups];
             startGlyphID = new int[numGroups];
-            buffer.position(offset+16);
             buffer = buffer.slice();
             IntBuffer ibuffer = buffer.asIntBuffer();
             for (int i=0; i<numGroups; i++) {
@@ -1110,7 +1122,13 @@
         char[][] glyphID;
 
         UVS(ByteBuffer buffer, int offset) {
-            numSelectors = buffer.getInt(offset+6);
+            buffer.position(offset+6);
+            numSelectors = buffer.getInt() & INTMASK;
+            // A variation selector record is one 3 byte int + two int32's
+            // making for 11 bytes per record.
+            if (buffer.remaining() < (11 * (long)numSelectors)) {
+                throw new RuntimeException("Variations exceed buffer");
+            }
             selector = new int[numSelectors];
             numUVSMapping = new int[numSelectors];
             unicodeValue = new int[numSelectors][];
@@ -1131,6 +1149,11 @@
                 } else if (tableOffset > 0) {
                     buffer.position(offset+tableOffset);
                     numUVSMapping[i] = buffer.getInt() & INTMASK;
+                    // a UVS mapping record is one 3 byte int + uint16
+                    // making for 5 bytes per record.
+                    if (buffer.remaining() < (5 * (long)numUVSMapping[i])) {
+                        throw new RuntimeException("Variations exceed buffer");
+                    }
                     unicodeValue[i] = new int[numUVSMapping[i]];
                     glyphID[i] = new char[numUVSMapping[i]];
 
--- a/src/java.desktop/share/classes/sun/font/FileFont.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/share/classes/sun/font/FileFont.java	Tue Oct 15 21:33:54 2019 +0000
@@ -172,7 +172,7 @@
             }
         }
         if (scaler != null) {
-            scaler.dispose();
+            scaler.disposeScaler();
         }
         scaler = FontScaler.getNullScaler();
     }
--- a/src/java.desktop/share/classes/sun/font/FontScaler.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/share/classes/sun/font/FontScaler.java	Tue Oct 15 21:33:54 2019 +0000
@@ -173,6 +173,12 @@
              scaler context objects! */
     public void dispose() {}
 
+    /**
+     * Used when the native resources held by the scaler need
+     * to be released before the 2D disposer runs.
+     */
+    public void disposeScaler() {}
+
     /* At the moment these 3 methods are needed for Type1 fonts only.
      * For Truetype fonts we extract required info outside of scaler
      * on java layer.
--- a/src/java.desktop/share/classes/sun/font/FreetypeFontScaler.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/share/classes/sun/font/FreetypeFontScaler.java	Tue Oct 15 21:33:54 2019 +0000
@@ -163,6 +163,9 @@
             .getNullScaler().getGlyphVectorOutline(0L, glyphs, numGlyphs, x, y);
     }
 
+    /* This method should not be called directly, in case
+     * it is being invoked from a thread with a native context.
+     */
     public synchronized void dispose() {
         if (nativeScaler != 0L) {
             disposeNativeScaler(font.get(), nativeScaler);
@@ -170,6 +173,21 @@
         }
     }
 
+    public synchronized void disposeScaler() {
+        if (nativeScaler != 0L) {
+           /*
+            * The current thread may be calling this method from the context
+            * of a JNI up-call. It will hold the native lock from the
+            * original down-call so can directly enter dispose and free
+            * the resources. So we need to schedule the disposal to happen
+            * only once we've returned from native. So by running the dispose
+            * on another thread which does nothing except that disposal we
+            * are sure that this is safe.
+            */
+            new Thread(null, () -> dispose(), "free scaler", 0, false).start();
+        }
+    }
+
     synchronized int getNumGlyphs() throws FontScalerException {
         if (nativeScaler != 0L) {
             return getNumGlyphsNative(nativeScaler);
@@ -206,7 +224,7 @@
         return getUnitsPerEMNative(nativeScaler);
     }
 
-    long createScalerContext(double[] matrix,
+    synchronized long createScalerContext(double[] matrix,
             int aa, int fm, float boldness, float italic,
             boolean disableHinting) {
         if (nativeScaler != 0L) {
@@ -236,7 +254,7 @@
     private native GeneralPath getGlyphVectorOutlineNative(Font2D font,
             long pScalerContext, long pScaler,
             int[] glyphs, int numGlyphs, float x, float y);
-    native Point2D.Float getGlyphPointNative(Font2D font,
+    private native Point2D.Float getGlyphPointNative(Font2D font,
             long pScalerContext, long pScaler, int glyphCode, int ptNumber);
 
     private native void disposeNativeScaler(Font2D font2D, long pScaler);
@@ -247,7 +265,7 @@
 
     private native long getUnitsPerEMNative(long pScaler);
 
-    native long createScalerContextNative(long pScaler, double[] matrix,
+    private native long createScalerContextNative(long pScaler, double[] matrix,
             int aa, int fm, float boldness, float italic);
 
     /* Freetype scaler context does not contain any pointers that
--- a/src/java.desktop/share/classes/sun/font/GlyphList.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/share/classes/sun/font/GlyphList.java	Tue Oct 15 21:33:54 2019 +0000
@@ -303,6 +303,14 @@
      */
     public void setGlyphIndex(int i) {
         glyphindex = i;
+        if (images[i] == 0L) {
+           metrics[0] = (int)gposx;
+           metrics[1] = (int)gposy;
+           metrics[2] = 0;
+           metrics[3] = 0;
+           metrics[4] = 0;
+           return;
+        }
         float gx =
             StrikeCache.unsafe.getFloat(images[i]+StrikeCache.topLeftXOffset);
         float gy =
@@ -341,6 +349,9 @@
                 graybits = new byte[len];
             }
         }
+        if (images[glyphindex] == 0L) {
+            return graybits;
+        }
         long pixelDataAddress =
             StrikeCache.unsafe.getAddress(images[glyphindex] +
                                           StrikeCache.pixelDataOffset);
@@ -448,6 +459,9 @@
         char gw, gh;
         float gx, gy, gx0, gy0, gx1, gy1;
         for (int i=0; i<len; i++) {
+            if (images[i] == 0L) {
+                continue;
+            }
             gx = StrikeCache.unsafe.getFloat(images[i]+xOffset);
             gy = StrikeCache.unsafe.getFloat(images[i]+yOffset);
             gw = StrikeCache.unsafe.getChar(images[i]+wOffset);
--- a/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java	Tue Oct 15 21:33:54 2019 +0000
@@ -3021,7 +3021,8 @@
         if (data == null) {
             throw new NullPointerException("char data is null");
         }
-        if (offset < 0 || length < 0 || offset + length > data.length) {
+        if (offset < 0 || length < 0 || offset + length < length ||
+            offset + length > data.length) {
             throw new ArrayIndexOutOfBoundsException("bad offset/length");
         }
         if (font.hasLayoutAttributes()) {
@@ -3053,7 +3054,8 @@
         if (data == null) {
             throw new NullPointerException("byte data is null");
         }
-        if (offset < 0 || length < 0 || offset + length > data.length) {
+        if (offset < 0 || length < 0 || offset + length < length ||
+            offset + length > data.length) {
             throw new ArrayIndexOutOfBoundsException("bad offset/length");
         }
         /* Byte data is interpreted as 8-bit ASCII. Re-use drawChars loops */
--- a/src/java.desktop/share/native/common/java2d/opengl/OGLBlitLoops.c	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/share/native/common/java2d/opengl/OGLBlitLoops.c	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -208,21 +208,22 @@
 
     j2d_glPixelZoom(scalex, -scaley);
 
+    GLvoid *pSrc = PtrCoord(srcInfo->rasBase, sx1, srcInfo->pixelStride,
+                                              sy1, srcInfo->scanStride);
+
     // in case pixel stride is not a multiple of scanline stride the copy
     // has to be done line by line (see 6207877)
     if (srcInfo->scanStride % srcInfo->pixelStride != 0) {
         jint width = sx2-sx1;
         jint height = sy2-sy1;
-        GLvoid *pSrc = srcInfo->rasBase;
-
         while (height > 0) {
             j2d_glDrawPixels(width, 1, pf->format, pf->type, pSrc);
-            j2d_glBitmap(0, 0, 0, 0, (GLfloat)0, (GLfloat)-1, NULL);
+            j2d_glBitmap(0, 0, 0, 0, (GLfloat)0, (GLfloat)-scaley, NULL);
             pSrc = PtrAddBytes(pSrc, srcInfo->scanStride);
             height--;
         }
     } else {
-        j2d_glDrawPixels(sx2-sx1, sy2-sy1, pf->format, pf->type, srcInfo->rasBase);
+        j2d_glDrawPixels(sx2-sx1, sy2-sy1, pf->format, pf->type, pSrc);
     }
 
     j2d_glPixelZoom(1.0, 1.0);
@@ -317,12 +318,11 @@
             ty2 = ((GLdouble)sh) / th;
 
             if (swsurface) {
+                GLvoid *pSrc = PtrCoord(srcInfo->rasBase,
+                                        sx, srcInfo->pixelStride,
+                                        sy, srcInfo->scanStride);
                 if (slowPath) {
                     jint tmph = sh;
-                    GLvoid *pSrc = PtrCoord(srcInfo->rasBase,
-                                            sx, srcInfo->pixelStride,
-                                            sy, srcInfo->scanStride);
-
                     while (tmph > 0) {
                         j2d_glTexSubImage2D(GL_TEXTURE_2D, 0,
                                             0, sh - tmph, sw, 1,
@@ -332,16 +332,10 @@
                         tmph--;
                     }
                 } else {
-                    j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx);
-                    j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, sy);
-
                     j2d_glTexSubImage2D(GL_TEXTURE_2D, 0,
                                         0, 0, sw, sh,
                                         pf->format, pf->type,
-                                        srcInfo->rasBase);
-
-                    j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
-                    j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+                                        pSrc);
                 }
 
                 // the texture image is "right side up", so we align the
@@ -638,8 +632,9 @@
             J2dTraceLn4(J2D_TRACE_VERBOSE, "  dx1=%f dy1=%f dx2=%f dy2=%f",
                         dx1, dy1, dx2, dy2);
 
-            j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, sx1);
-            j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, sy1);
+            // Note: we will calculate x/y positions in the raster manually
+            j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+            j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
             j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH,
                               srcInfo.scanStride / srcInfo.pixelStride);
             j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, pf.alignment);
@@ -696,8 +691,6 @@
                 }
             }
 
-            j2d_glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
-            j2d_glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
             j2d_glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
             j2d_glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
         }
@@ -717,8 +710,8 @@
     juint step = 0;
     // vertical flip and convert argbpre to argb if necessary
     for (; i < h / 2; ++i) {
-        juint *r1 = PtrAddBytes(pDst, (i * scanStride));
-        juint *r2 = PtrAddBytes(pDst, (h - i - 1) * scanStride);
+        juint *r1 = PtrPixelsRow(pDst, i, scanStride);
+        juint *r2 = PtrPixelsRow(pDst, h - i - 1, scanStride);
         if (tempRow) {
             // fast path
             memcpy(tempRow, r1, clippedStride);
@@ -740,7 +733,7 @@
     }
     // convert the middle line if necessary
     if (convert && h % 2) {
-        juint *r1 = PtrAddBytes(pDst, (i * scanStride));
+        juint *r1 = PtrPixelsRow(pDst, i, scanStride);
         for (step = 0; step < w; ++step) {
             LoadIntArgbPreTo1IntArgb(r1, 0, step, r1[step]);
         }
@@ -813,7 +806,7 @@
             height = srcInfo.bounds.y2 - srcInfo.bounds.y1;
 
             pDst = PtrAddBytes(pDst, dstx * dstInfo.pixelStride);
-            pDst = PtrAddBytes(pDst, dsty * dstInfo.scanStride);
+            pDst = PtrPixelsRow(pDst, dsty, dstInfo.scanStride);
 
             j2d_glPixelStorei(GL_PACK_ROW_LENGTH,
                               dstInfo.scanStride / dstInfo.pixelStride);
--- a/src/java.desktop/share/native/libawt/java2d/loops/GraphicsPrimitiveMgr.h	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/share/native/libawt/java2d/loops/GraphicsPrimitiveMgr.h	Tue Oct 15 21:33:54 2019 +0000
@@ -490,6 +490,8 @@
 #define PtrCoord(p, x, xinc, y, yinc)   PtrAddBytes(p, \
                                                     ((ptrdiff_t)(y))*(yinc) + \
                                                     ((ptrdiff_t)(x))*(xinc))
+#define PtrPixelsRow(p, y, scanStride)    PtrAddBytes(p, \
+    ((intptr_t) (y)) * (scanStride))
 
 /*
  * The function to call with an array of NativePrimitive structures
--- a/src/java.desktop/share/native/libawt/java2d/loops/LoopMacros.h	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/share/native/libawt/java2d/loops/LoopMacros.h	Tue Oct 15 21:33:54 2019 +0000
@@ -137,7 +137,7 @@
         do { \
             juint w = WIDTH; \
             jint tmpsxloc = SXLOC; \
-            SRCPTR = PtrAddBytes(SRCBASE, ((SYLOC >> SHIFT) * srcScan)); \
+            SRCPTR = PtrPixelsRow(SRCBASE, (SYLOC >> SHIFT), srcScan); \
             Init ## DSTTYPE ## StoreVarsX(DSTPREFIX, DSTINFO); \
             do { \
                 jint XVAR = (tmpsxloc >> SHIFT); \
@@ -2067,7 +2067,7 @@
  \
     Init ## SRC ## LoadVars(SrcRead, pSrcInfo); \
     while (pRGB < pEnd) { \
-        SRC ## DataType *pRow = PtrAddBytes(pBase, WholeOfLong(ylong) * scan); \
+        SRC ## DataType *pRow = PtrPixelsRow(pBase, WholeOfLong(ylong), scan); \
         Copy ## SRC ## ToIntArgbPre(pRGB, 0, \
                                     SrcRead, pRow, WholeOfLong(xlong)); \
         pRGB++; \
@@ -2115,7 +2115,7 @@
         ydelta &= scan; \
  \
         xwhole += cx; \
-        pRow = PtrAddBytes(pSrcInfo->rasBase, (ywhole + cy) * scan); \
+        pRow = PtrPixelsRow(pSrcInfo->rasBase, ywhole + cy, scan); \
         Copy ## SRC ## ToIntArgbPre(pRGB, 0, SrcRead, pRow, xwhole); \
         Copy ## SRC ## ToIntArgbPre(pRGB, 1, SrcRead, pRow, xwhole+xdelta); \
         pRow = PtrAddBytes(pRow, ydelta); \
@@ -2173,7 +2173,7 @@
         ydelta1 += (isneg & -scan); \
  \
         xwhole += cx; \
-        pRow = PtrAddBytes(pSrcInfo->rasBase, (ywhole + cy) * scan); \
+        pRow = PtrPixelsRow(pSrcInfo->rasBase, ywhole + cy, scan); \
         pRow = PtrAddBytes(pRow, ydelta0); \
         Copy ## SRC ## ToIntArgbPre(pRGB,  0, SrcRead, pRow, xwhole+xdelta0); \
         Copy ## SRC ## ToIntArgbPre(pRGB,  1, SrcRead, pRow, xwhole        ); \
--- a/src/java.desktop/share/native/libfontmanager/DrawGlyphList.c	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/share/native/libfontmanager/DrawGlyphList.c	Tue Oct 15 21:33:54 2019 +0000
@@ -532,6 +532,12 @@
      */
     if (subPixPos && len > 0) {
         ginfo = (GlyphInfo*)imagePtrs[0];
+        if (ginfo == NULL) {
+            (*env)->ReleasePrimitiveArrayCritical(env, glyphImages,
+                                                  imagePtrs, JNI_ABORT);
+            free(gbv);
+            return (GlyphBlitVector*)NULL;
+        }
         /* rowBytes==width tests if its a B&W or LCD glyph */
         if (ginfo->width == ginfo->rowBytes) {
             subPixPos = JNI_FALSE;
@@ -561,6 +567,12 @@
             jfloat px, py;
 
             ginfo = (GlyphInfo*)imagePtrs[g];
+            if (ginfo == NULL) {
+                (*env)->ReleasePrimitiveArrayCritical(env, glyphImages,
+                                                  imagePtrs, JNI_ABORT);
+                free(gbv);
+                return (GlyphBlitVector*)NULL;
+            }
             gbv->glyphs[g].glyphInfo = ginfo;
             gbv->glyphs[g].pixels = ginfo->image;
             gbv->glyphs[g].width = ginfo->width;
@@ -636,6 +648,12 @@
     } else {
         for (g=0; g<len; g++) {
             ginfo = (GlyphInfo*)imagePtrs[g];
+            if (ginfo == NULL) {
+                (*env)->ReleasePrimitiveArrayCritical(env, glyphImages,
+                                                  imagePtrs, JNI_ABORT);
+                free(gbv);
+                return (GlyphBlitVector*)NULL;
+            }
             gbv->glyphs[g].glyphInfo = ginfo;
             gbv->glyphs[g].pixels = ginfo->image;
             gbv->glyphs[g].width = ginfo->width;
--- a/src/java.desktop/share/native/libfontmanager/freetypeScaler.c	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/share/native/libfontmanager/freetypeScaler.c	Tue Oct 15 21:33:54 2019 +0000
@@ -154,7 +154,31 @@
     jobject bBuffer;
     int bread = 0;
 
-    if (numBytes == 0) return 0;
+    /* A call with numBytes == 0 is a seek. It should return 0 if the
+     * seek position is within the file and non-zero otherwise.
+     * For all other cases, ie numBytes !=0, return the number of bytes
+     * actually read. This applies to truncated reads and also failed reads.
+     */
+
+    if (numBytes == 0) {
+        if (offset > scalerInfo->fileSize) {
+            return -1;
+        } else {
+            return 0;
+       }
+    }
+
+    if (offset + numBytes < offset) {
+        return 0; // ft should not do this, but just in case.
+    }
+
+    if (offset >= scalerInfo->fileSize) {
+        return 0;
+    }
+
+    if (offset + numBytes > scalerInfo->fileSize) {
+        numBytes = scalerInfo->fileSize - offset;
+    }
 
     /* Large reads will bypass the cache and data copying */
     if (numBytes > FILEDATACACHESIZE) {
@@ -164,7 +188,11 @@
                                           scalerInfo->font2D,
                                           sunFontIDs.ttReadBlockMID,
                                           bBuffer, offset, numBytes);
-            return bread;
+            if (bread < 0) {
+                return 0;
+            } else {
+               return bread;
+            }
         } else {
             /* We probably hit bug 4845371. For reasons that
              * are currently unclear, the call stacks after the initial
@@ -179,9 +207,18 @@
             (*env)->CallObjectMethod(env, scalerInfo->font2D,
                                      sunFontIDs.ttReadBytesMID,
                                      offset, numBytes);
-            (*env)->GetByteArrayRegion(env, byteArray,
-                                       0, numBytes, (jbyte*)destBuffer);
-            return numBytes;
+            /* If there's an OutofMemoryError then byteArray will be null */
+            if (byteArray == NULL) {
+                return 0;
+            } else {
+                jsize len = (*env)->GetArrayLength(env, byteArray);
+                if (len < numBytes) {
+                    numBytes = len; // don't get more bytes than there are ..
+                }
+                (*env)->GetByteArrayRegion(env, byteArray,
+                                           0, numBytes, (jbyte*)destBuffer);
+                return numBytes;
+            }
         }
     } /* Do we have a cache hit? */
       else if (scalerInfo->fontDataOffset <= offset &&
@@ -203,6 +240,11 @@
                                       sunFontIDs.ttReadBlockMID,
                                       bBuffer, offset,
                                       scalerInfo->fontDataLength);
+        if (bread <= 0) {
+            return 0;
+        } else if (bread < numBytes) {
+           numBytes = bread;
+        }
         memcpy(destBuffer, scalerInfo->fontData, numBytes);
         return numBytes;
     }
@@ -593,16 +635,17 @@
       to avoid unnecesary work with bitmaps. */
 
     GlyphInfo *info;
-    jfloat advance;
+    jfloat advance = 0.0f;
     jlong image;
 
     image = Java_sun_font_FreetypeFontScaler_getGlyphImageNative(
                  env, scaler, font2D, pScalerContext, pScaler, glyphCode);
     info = (GlyphInfo*) jlong_to_ptr(image);
 
-    advance = info->advanceX;
-
-    free(info);
+    if (info != NULL) {
+        advance = info->advanceX;
+        free(info);
+    }
 
     return advance;
 }
@@ -740,6 +783,13 @@
 }
 
 
+/* JDK does not use glyph images for fonts with a
+ * pixel size > 100 (see THRESHOLD in OutlineTextRenderer.java)
+ * so if the glyph bitmap image dimension is > 1024 pixels,
+ * something is up.
+ */
+#define MAX_GLYPH_DIM 1024
+
 /*
  * Class:     sun_font_FreetypeFontScaler
  * Method:    getGlyphImageNative
@@ -813,6 +863,14 @@
     /* generate bitmap if it is not done yet
      e.g. if algorithmic styling is performed and style was added to outline */
     if (ftglyph->format == FT_GLYPH_FORMAT_OUTLINE) {
+        FT_BBox bbox;
+        FT_Outline_Get_CBox(&(ftglyph->outline), &bbox);
+        int w = (int)((bbox.xMax>>6)-(bbox.xMin>>6));
+        int h = (int)((bbox.yMax>>6)-(bbox.yMin>>6));
+        if (w > MAX_GLYPH_DIM || h > MAX_GLYPH_DIM) {
+            glyphInfo = getNullGlyphImage();
+            return ptr_to_jlong(glyphInfo);
+        }
         error = FT_Render_Glyph(ftglyph, FT_LOAD_TARGET_MODE(target));
         if (error != 0) {
             return ptr_to_jlong(getNullGlyphImage());
@@ -821,6 +879,11 @@
 
     width  = (UInt16) ftglyph->bitmap.width;
     height = (UInt16) ftglyph->bitmap.rows;
+    if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) {
+        glyphInfo = getNullGlyphImage();
+        return ptr_to_jlong(glyphInfo);
+    }
+
 
     imageSize = width*height;
     glyphInfo = (GlyphInfo*) malloc(sizeof(GlyphInfo) + imageSize);
--- a/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/share/native/libfontmanager/hb-jdk-font.cc	Tue Oct 15 21:33:54 2019 +0000
@@ -351,6 +351,9 @@
   }
   length = env->GetArrayLength(tableBytes);
   buffer = calloc(length, sizeof(jbyte));
+  if (buffer == NULL) {
+      return NULL;
+  }
   env->GetByteArrayRegion(tableBytes, 0, length, (jbyte*)buffer);
 
   return hb_blob_create((const char *)buffer, length,
--- a/src/java.desktop/unix/classes/sun/font/XRGlyphCache.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/unix/classes/sun/font/XRGlyphCache.java	Tue Oct 15 21:33:54 2019 +0000
@@ -114,6 +114,9 @@
         for (int i = 0; i < glyphList.getNumGlyphs(); i++) {
             XRGlyphCacheEntry glyph;
 
+            if (imgPtrs[i] == 0L) {
+                continue;
+            }
             // Find uncached glyphs and queue them for upload
             if ((glyph = getEntryForPointer(imgPtrs[i])) == null) {
                 glyph = new XRGlyphCacheEntry(imgPtrs[i], glyphList);
--- a/src/java.desktop/unix/classes/sun/font/XRTextRenderer.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/unix/classes/sun/font/XRTextRenderer.java	Tue Oct 15 21:33:54 2019 +0000
@@ -88,6 +88,9 @@
             for (int i = 0; i < gl.getNumGlyphs(); i++) {
                 gl.setGlyphIndex(i);
                 XRGlyphCacheEntry cacheEntry = cachedGlyphs[i];
+                if (cacheEntry == null) {
+                    continue;
+                }
 
                 eltList.getGlyphs().addInt(cacheEntry.getGlyphID());
                 int glyphSet = cacheEntry.getGlyphSet();
--- a/src/java.desktop/unix/native/common/java2d/x11/X11FontScaler_md.c	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/unix/native/common/java2d/x11/X11FontScaler_md.c	Tue Oct 15 21:33:54 2019 +0000
@@ -273,6 +273,7 @@
     unsigned int imageSize;
     JNIEnv *env;
 
+
     FONT_AWT_LOCK();
 /*     XTextExtents16(xFont, xChar, 1, &direction, &ascent, &descent, &xcs); */
     XQueryTextExtents16(awt_display,xFont->fid, xChar, 1,
@@ -280,8 +281,11 @@
     width = xcs.rbearing - xcs.lbearing;
     height = xcs.ascent+xcs.descent;
     imageSize = width*height;
-
     glyphInfo = (GlyphInfo*)malloc(sizeof(GlyphInfo)+imageSize);
+    if (glyphInfo == NULL) {
+        AWT_UNLOCK();
+        return (jlong)(uintptr_t)NULL;
+    }
     glyphInfo->cellInfo = NULL;
     glyphInfo->width = width;
     glyphInfo->height = height;
--- a/src/java.desktop/windows/native/libawt/java2d/d3d/D3DContext.cpp	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.desktop/windows/native/libawt/java2d/d3d/D3DContext.cpp	Tue Oct 15 21:33:54 2019 +0000
@@ -1092,7 +1092,9 @@
 {
 #ifndef PtrAddBytes
 #define PtrAddBytes(p, b)               ((void *) (((intptr_t) (p)) + (b)))
-#define PtrCoord(p, x, xinc, y, yinc)   PtrAddBytes(p, (y)*(yinc) + (x)*(xinc))
+#define PtrCoord(p, x, xinc, y, yinc)   PtrAddBytes(p, \
+                                                    ((ptrdiff_t)(y))*(yinc) + \
+                                                    ((ptrdiff_t)(x))*(xinc))
 #endif // PtrAddBytes
 
     HRESULT res = S_OK;
--- a/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl_Skel.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl_Skel.java	Tue Oct 15 21:33:54 2019 +0000
@@ -27,13 +27,8 @@
 package sun.rmi.registry;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.rmi.AccessException;
-import java.rmi.server.RemoteCall;
 
-import sun.rmi.transport.Connection;
 import sun.rmi.transport.StreamRemoteCall;
-import sun.rmi.transport.tcp.TCPConnection;
 
 /**
  * Skeleton to dispatch RegistryImpl methods.
@@ -56,7 +51,7 @@
         return operations.clone();
     }
 
-    public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash)
+    public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall remoteCall, int opnum, long hash)
             throws java.lang.Exception {
         if (opnum < 0) {
             if (hash == 7583982177005850366L) {
@@ -78,6 +73,7 @@
         }
 
         sun.rmi.registry.RegistryImpl server = (sun.rmi.registry.RegistryImpl) obj;
+        StreamRemoteCall call = (StreamRemoteCall) remoteCall;
         switch (opnum) {
             case 0: // bind(String, Remote)
             {
@@ -90,7 +86,8 @@
                     java.io.ObjectInput in = call.getInputStream();
                     $param_String_1 = (java.lang.String) in.readObject();
                     $param_Remote_2 = (java.rmi.Remote) in.readObject();
-                } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+                } catch (ClassCastException | IOException | ClassNotFoundException e) {
+                    call.discardPendingRefs();
                     throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
                 } finally {
                     call.releaseInputStream();
@@ -123,7 +120,8 @@
                 try {
                     java.io.ObjectInput in = call.getInputStream();
                     $param_String_1 = (java.lang.String) in.readObject();
-                } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+                } catch (ClassCastException | IOException | ClassNotFoundException e) {
+                    call.discardPendingRefs();
                     throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
                 } finally {
                     call.releaseInputStream();
@@ -149,7 +147,8 @@
                     java.io.ObjectInput in = call.getInputStream();
                     $param_String_1 = (java.lang.String) in.readObject();
                     $param_Remote_2 = (java.rmi.Remote) in.readObject();
-                } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+                } catch (ClassCastException | IOException | java.lang.ClassNotFoundException e) {
+                    call.discardPendingRefs();
                     throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
                 } finally {
                     call.releaseInputStream();
@@ -172,7 +171,8 @@
                 try {
                     java.io.ObjectInput in = call.getInputStream();
                     $param_String_1 = (java.lang.String) in.readObject();
-                } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+                } catch (ClassCastException | IOException | ClassNotFoundException e) {
+                    call.discardPendingRefs();
                     throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
                 } finally {
                     call.releaseInputStream();
--- a/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl_Stub.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl_Stub.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -24,6 +24,11 @@
  */
 
 package sun.rmi.registry;
+
+import java.io.IOException;
+
+import sun.rmi.transport.StreamRemoteCall;
+
 /**
  * Stubs to invoke RegistryImpl remote methods.
  * Originally generated from RMIC but frozen to match RegistryImpl_Skel.
@@ -57,7 +62,7 @@
     public void bind(java.lang.String $param_String_1, java.rmi.Remote $param_Remote_2)
             throws java.rmi.AccessException, java.rmi.AlreadyBoundException, java.rmi.RemoteException {
         try {
-            java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash);
+            StreamRemoteCall call = (StreamRemoteCall)ref.newCall(this, operations, 0, interfaceHash);
             try {
                 java.io.ObjectOutput out = call.getOutputStream();
                 out.writeObject($param_String_1);
@@ -82,15 +87,14 @@
     public java.lang.String[] list()
             throws java.rmi.AccessException, java.rmi.RemoteException {
         try {
-            java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash);
+            StreamRemoteCall call = (StreamRemoteCall)ref.newCall(this, operations, 1, interfaceHash);
             ref.invoke(call);
             java.lang.String[] $result;
             try {
                 java.io.ObjectInput in = call.getInputStream();
                 $result = (java.lang.String[]) in.readObject();
-            } catch (java.io.IOException e) {
-                throw new java.rmi.UnmarshalException("error unmarshalling return", e);
-            } catch (java.lang.ClassNotFoundException e) {
+            } catch (ClassCastException | IOException | ClassNotFoundException e) {
+                call.discardPendingRefs();
                 throw new java.rmi.UnmarshalException("error unmarshalling return", e);
             } finally {
                 ref.done(call);
@@ -109,7 +113,7 @@
     public java.rmi.Remote lookup(java.lang.String $param_String_1)
             throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException {
         try {
-            java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash);
+            StreamRemoteCall call = (StreamRemoteCall)ref.newCall(this, operations, 2, interfaceHash);
             try {
                 java.io.ObjectOutput out = call.getOutputStream();
                 out.writeObject($param_String_1);
@@ -121,9 +125,8 @@
             try {
                 java.io.ObjectInput in = call.getInputStream();
                 $result = (java.rmi.Remote) in.readObject();
-            } catch (java.io.IOException e) {
-                throw new java.rmi.UnmarshalException("error unmarshalling return", e);
-            } catch (java.lang.ClassNotFoundException e) {
+            } catch (ClassCastException | IOException | ClassNotFoundException e) {
+                call.discardPendingRefs();
                 throw new java.rmi.UnmarshalException("error unmarshalling return", e);
             } finally {
                 ref.done(call);
@@ -144,7 +147,7 @@
     public void rebind(java.lang.String $param_String_1, java.rmi.Remote $param_Remote_2)
             throws java.rmi.AccessException, java.rmi.RemoteException {
         try {
-            java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 3, interfaceHash);
+            StreamRemoteCall call = (StreamRemoteCall)ref.newCall(this, operations, 3, interfaceHash);
             try {
                 java.io.ObjectOutput out = call.getOutputStream();
                 out.writeObject($param_String_1);
@@ -167,7 +170,7 @@
     public void unbind(java.lang.String $param_String_1)
             throws java.rmi.AccessException, java.rmi.NotBoundException, java.rmi.RemoteException {
         try {
-            java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 4, interfaceHash);
+            StreamRemoteCall call = (StreamRemoteCall)ref.newCall(this, operations, 4, interfaceHash);
             try {
                 java.io.ObjectOutput out = call.getOutputStream();
                 out.writeObject($param_String_1);
--- a/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Skel.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Skel.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -25,6 +25,8 @@
 
 package sun.rmi.transport;
 
+import java.io.IOException;
+
 /**
  * Skeleton to dispatch DGC methods.
  * Originally generated by RMIC but frozen to match the stubs.
@@ -43,12 +45,13 @@
         return operations.clone();
     }
 
-    public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash)
+    public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall remoteCall, int opnum, long hash)
             throws java.lang.Exception {
         if (hash != interfaceHash)
             throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch");
 
         sun.rmi.transport.DGCImpl server = (sun.rmi.transport.DGCImpl) obj;
+        StreamRemoteCall call = (StreamRemoteCall) remoteCall;
         switch (opnum) {
             case 0: // clean(ObjID[], long, VMID, boolean)
             {
@@ -62,9 +65,8 @@
                     $param_long_2 = in.readLong();
                     $param_VMID_3 = (java.rmi.dgc.VMID) in.readObject();
                     $param_boolean_4 = in.readBoolean();
-                } catch (java.io.IOException e) {
-                    throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
-                } catch (java.lang.ClassNotFoundException e) {
+                } catch (ClassCastException | IOException | ClassNotFoundException e) {
+                    call.discardPendingRefs();
                     throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
                 } finally {
                     call.releaseInputStream();
@@ -88,9 +90,8 @@
                     $param_arrayOf_ObjID_1 = (java.rmi.server.ObjID[]) in.readObject();
                     $param_long_2 = in.readLong();
                     $param_Lease_3 = (java.rmi.dgc.Lease) in.readObject();
-                } catch (java.io.IOException e) {
-                    throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
-                } catch (java.lang.ClassNotFoundException e) {
+                } catch (ClassCastException | IOException | ClassNotFoundException e) {
+                    call.discardPendingRefs();
                     throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
                 } finally {
                     call.releaseInputStream();
--- a/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Stub.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Stub.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -25,16 +25,17 @@
 
 package sun.rmi.transport;
 
+import sun.rmi.transport.tcp.TCPConnection;
+
+import java.io.IOException;
 import java.io.ObjectInputFilter;
-import java.io.ObjectInputStream;
+import java.rmi.RemoteException;
 import java.rmi.dgc.Lease;
 import java.rmi.dgc.VMID;
 import java.rmi.server.UID;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
-
-import sun.rmi.server.UnicastRef;
-import sun.rmi.transport.tcp.TCPConnection;
+import java.util.ArrayList;
 
 /**
  * Stubs to invoke DGC remote methods.
@@ -72,7 +73,9 @@
     public void clean(java.rmi.server.ObjID[] $param_arrayOf_ObjID_1, long $param_long_2, java.rmi.dgc.VMID $param_VMID_3, boolean $param_boolean_4)
             throws java.rmi.RemoteException {
         try {
-            java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash);
+            StreamRemoteCall call = (StreamRemoteCall)ref.newCall((java.rmi.server.RemoteObject) this,
+                    operations, 0, interfaceHash);
+            call.setObjectInputFilter(DGCImpl_Stub::leaseFilter);
             try {
                 java.io.ObjectOutput out = call.getOutputStream();
                 out.writeObject($param_arrayOf_ObjID_1);
@@ -97,7 +100,10 @@
     public java.rmi.dgc.Lease dirty(java.rmi.server.ObjID[] $param_arrayOf_ObjID_1, long $param_long_2, java.rmi.dgc.Lease $param_Lease_3)
             throws java.rmi.RemoteException {
         try {
-            java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash);
+            StreamRemoteCall call =
+                    (StreamRemoteCall)ref.newCall((java.rmi.server.RemoteObject) this,
+                            operations, 1, interfaceHash);
+            call.setObjectInputFilter(DGCImpl_Stub::leaseFilter);
             try {
                 java.io.ObjectOutput out = call.getOutputStream();
                 out.writeObject($param_arrayOf_ObjID_1);
@@ -108,26 +114,16 @@
             }
             ref.invoke(call);
             java.rmi.dgc.Lease $result;
-            Connection connection = ((StreamRemoteCall) call).getConnection();
+            Connection connection = call.getConnection();
             try {
                 java.io.ObjectInput in = call.getInputStream();
-
-                if (in instanceof ObjectInputStream) {
-                    /**
-                     * Set a filter on the stream for the return value.
-                     */
-                    ObjectInputStream ois = (ObjectInputStream) in;
-                    AccessController.doPrivileged((PrivilegedAction<Void>)() -> {
-                        ois.setObjectInputFilter(DGCImpl_Stub::leaseFilter);
-                        return null;
-                    });
-                }
                 $result = (java.rmi.dgc.Lease) in.readObject();
-            } catch (java.io.IOException | java.lang.ClassNotFoundException e) {
+            } catch (ClassCastException | IOException | ClassNotFoundException e) {
                 if (connection instanceof TCPConnection) {
                     // Modified to prevent re-use of the connection after an exception
                     ((TCPConnection) connection).getChannel().free(connection, false);
                 }
+                call.discardPendingRefs();
                 throw new java.rmi.UnmarshalException("error unmarshalling return", e);
             } finally {
                 ref.done(call);
@@ -146,6 +142,11 @@
      * ObjectInputFilter to filter DGCClient return value (a Lease).
      * The list of acceptable classes is very short and explicit.
      * The depth and array sizes are limited.
+     * <p>
+     * The filter must accept normal and exception returns.
+     * A DGC server may throw exceptions that may have a cause
+     * and suppressed exceptions.
+     * Only exceptions in {@code java.base} and {@code java.rmi} are allowed.
      *
      * @param filterInfo access to class, arrayLength, etc.
      * @return  {@link ObjectInputFilter.Status#ALLOWED} if allowed,
@@ -172,7 +173,14 @@
             }
             return (clazz == UID.class ||
                     clazz == VMID.class ||
-                    clazz == Lease.class)
+                    clazz == Lease.class ||
+                    (Throwable.class.isAssignableFrom(clazz) &&
+                            (Object.class.getModule() == clazz.getModule() ||
+                                    RemoteException.class.getModule() == clazz.getModule())) ||
+                    clazz == StackTraceElement.class ||
+                    clazz == ArrayList.class ||     // for suppressed exceptions, if any
+                    clazz == Object.class ||
+                    clazz.getName().equals("java.util.Collections$EmptyList"))
                     ? ObjectInputFilter.Status.ALLOWED
                     : ObjectInputFilter.Status.REJECTED;
         }
--- a/src/java.rmi/share/classes/sun/rmi/transport/StreamRemoteCall.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.rmi/share/classes/sun/rmi/transport/StreamRemoteCall.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, 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
@@ -29,6 +29,7 @@
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.io.ObjectInput;
+import java.io.ObjectInputFilter;
 import java.io.ObjectOutput;
 import java.io.StreamCorruptedException;
 import java.rmi.RemoteException;
@@ -36,6 +37,9 @@
 import java.rmi.UnmarshalException;
 import java.rmi.server.ObjID;
 import java.rmi.server.RemoteCall;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
 import sun.rmi.runtime.Log;
 import sun.rmi.server.UnicastRef;
 import sun.rmi.transport.tcp.TCPEndpoint;
@@ -50,6 +54,7 @@
     private ConnectionInputStream in = null;
     private ConnectionOutputStream out = null;
     private Connection conn;
+    private ObjectInputFilter filter = null;
     private boolean resultStarted = false;
     private Exception serverException = null;
 
@@ -123,6 +128,13 @@
         }
     }
 
+    public void setObjectInputFilter(ObjectInputFilter filter) {
+        if (in != null) {
+            throw new IllegalStateException("set filter must occur before calling getInputStream");
+        }
+        this.filter = filter;
+    }
+
     /**
      * Get the InputStream the stub/skeleton should get results/arguments
      * from.
@@ -132,6 +144,12 @@
             Transport.transportLog.log(Log.VERBOSE, "getting input stream");
 
             in = new ConnectionInputStream(conn.getInputStream());
+            if (filter != null) {
+                AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
+                    in.setObjectInputFilter(filter);
+                    return null;
+                });
+            }
         }
         return in;
     }
@@ -251,6 +269,7 @@
             try {
                 ex = in.readObject();
             } catch (Exception e) {
+                discardPendingRefs();
                 throw new UnmarshalException("Error unmarshaling return", e);
             }
 
@@ -259,6 +278,7 @@
             if (ex instanceof Exception) {
                 exceptionReceivedFromServer((Exception) ex);
             } else {
+                discardPendingRefs();
                 throw new UnmarshalException("Return type not Exception");
             }
             // Exception is thrown before fallthrough can occur
--- a/src/java.security.jgss/macosx/native/libosxkrb5/nativeccache.c	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/macosx/native/libosxkrb5/nativeccache.c	Tue Oct 15 21:33:54 2019 +0000
@@ -247,6 +247,7 @@
 
     int netypes;
     jint *etypes = NULL;
+    int proxy_flag = 0;
 
     /* Initialize the Kerberos 5 context */
     err = krb5_init_context (&kcontext);
@@ -259,6 +260,48 @@
         err = krb5_cc_set_flags (kcontext, ccache, flags); /* turn off OPENCLOSE */
     }
 
+    // First round read. The proxy_impersonator config flag is not supported.
+    // This ccache will not be used if this flag exists.
+    if (!err) {
+        err = krb5_cc_start_seq_get (kcontext, ccache, &cursor);
+    }
+
+    if (!err) {
+        while ((err = krb5_cc_next_cred (kcontext, ccache, &cursor, &creds)) == 0) {
+            char *serverName = NULL;
+
+            if (!err) {
+                err = krb5_unparse_name (kcontext, creds.server, &serverName);
+                printiferr (err, "while unparsing server name");
+            }
+
+            if (!err) {
+                if (!strcmp(serverName, "krb5_ccache_conf_data/proxy_impersonator@X-CACHECONF:")) {
+                    proxy_flag = 1;
+                }
+            }
+
+            if (serverName != NULL) { krb5_free_unparsed_name (kcontext, serverName); }
+
+            krb5_free_cred_contents (kcontext, &creds);
+
+            if (proxy_flag) break;
+        }
+
+        if (err == KRB5_CC_END) { err = 0; }
+        printiferr (err, "while retrieving a ticket");
+    }
+
+    if (!err) {
+        err = krb5_cc_end_seq_get (kcontext, ccache, &cursor);
+        printiferr (err, "while finishing ticket retrieval");
+    }
+
+    if (proxy_flag) {
+        goto outer_cleanup;
+    }
+    // End of first round read
+
     if (!err) {
         err = krb5_cc_start_seq_get (kcontext, ccache, &cursor);
     }
@@ -388,6 +431,7 @@
         printiferr (err, "while finishing ticket retrieval");
     }
 
+outer_cleanup:
     if (!err) {
         flags = KRB5_TC_OPENCLOSE; /* restore OPENCLOSE mode */
         err = krb5_cc_set_flags (kcontext, ccache, flags);
--- a/src/java.security.jgss/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/javax/security/auth/kerberos/JavaxSecurityAuthKerberosAccessImpl.java	Tue Oct 15 21:33:54 2019 +0000
@@ -49,4 +49,12 @@
     public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a) {
         t.serverAlias = a;
     }
+
+    public KerberosTicket kerberosTicketGetProxy(KerberosTicket t) {
+        return t.proxy;
+    }
+
+    public void kerberosTicketSetProxy(KerberosTicket t, KerberosTicket p) {
+        t.proxy = p;
+    }
 }
--- a/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java	Tue Oct 15 21:33:54 2019 +0000
@@ -29,11 +29,13 @@
 import java.util.Date;
 import java.util.Arrays;
 import java.net.InetAddress;
+import java.util.Objects;
 import javax.crypto.SecretKey;
 import javax.security.auth.Refreshable;
 import javax.security.auth.Destroyable;
 import javax.security.auth.RefreshFailedException;
 import javax.security.auth.DestroyFailedException;
+
 import sun.security.util.HexDumpEncoder;
 
 /**
@@ -190,8 +192,13 @@
      * @serial
      */
 
+    private InetAddress[] clientAddresses;
 
-    private InetAddress[] clientAddresses;
+    /**
+     * Evidence ticket if proxy_impersonator. This field can be accessed
+     * by KerberosSecrets. It's serialized.
+     */
+    KerberosTicket proxy = null;
 
     private transient boolean destroyed = false;
 
@@ -711,6 +718,7 @@
                 "Renew Till = " + String.valueOf(renewTill) + "\n" +
                 "Client Addresses " +
                 (clientAddresses == null ? " Null " : caddrString.toString() +
+                (proxy == null ? "" : "\nwith a proxy ticket") +
                 "\n"));
     }
 
@@ -748,6 +756,10 @@
 
         // clientAddress may be null, the array's hashCode is 0
         result = result * 37 + Arrays.hashCode(clientAddresses);
+
+        if (proxy != null) {
+            result = result * 37 + proxy.hashCode();
+        }
         return result * 37 + Arrays.hashCode(flags);
     }
 
@@ -820,6 +832,10 @@
             }
         }
 
+        if (!Objects.equals(proxy, otherTicket.proxy)) {
+            return false;
+        }
+
         return true;
     }
 
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java	Tue Oct 15 21:33:54 2019 +0000
@@ -617,6 +617,8 @@
                     if (myCred == null) {
                         myCred = Krb5InitCredential.getInstance(caller, myName,
                                               GSSCredential.DEFAULT_LIFETIME);
+                        myCred = Krb5ProxyCredential.tryImpersonation(
+                                caller, (Krb5InitCredential)myCred);
                     } else if (!myCred.isInitiatorCredential()) {
                         throw new GSSException(errorCode, -1,
                                            "No TGT available");
@@ -653,8 +655,8 @@
                                     // highly consider just calling:
                                     // Subject.getSubject
                                     // SubjectComber.find
-                                    // instead of Krb5Util.getTicket
-                                    return Krb5Util.getTicket(
+                                    // instead of Krb5Util.getServiceTicket
+                                    return Krb5Util.getServiceTicket(
                                         GSSCaller.CALLER_UNKNOWN,
                                         // since it's useSubjectCredsOnly here,
                                         // don't worry about the null
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java	Tue Oct 15 21:33:54 2019 +0000
@@ -57,6 +57,7 @@
     private Krb5NameElement name;
     @SuppressWarnings("serial") // Not statically typed as Serializable
     private Credentials krb5Credentials;
+    public KerberosTicket proxyTicket;
 
     private Krb5InitCredential(Krb5NameElement name,
                                byte[] asn1Encoding,
@@ -175,7 +176,7 @@
         KerberosPrincipal serverAlias = KerberosSecrets
                 .getJavaxSecurityAuthKerberosAccess()
                 .kerberosTicketGetServerAlias(tgt);
-        return new Krb5InitCredential(name,
+        Krb5InitCredential result = new Krb5InitCredential(name,
                                       tgt.getEncoded(),
                                       tgt.getClient(),
                                       clientAlias,
@@ -189,6 +190,9 @@
                                       tgt.getEndTime(),
                                       tgt.getRenewTill(),
                                       tgt.getClientAddresses());
+        result.proxyTicket = KerberosSecrets.getJavaxSecurityAuthKerberosAccess().
+            kerberosTicketGetProxy(tgt);
+        return result;
     }
 
     static Krb5InitCredential getInstance(Krb5NameElement name,
@@ -371,9 +375,9 @@
                 public KerberosTicket run() throws Exception {
                     // It's OK to use null as serverPrincipal. TGT is almost
                     // the first ticket for a principal and we use list.
-                    return Krb5Util.getTicket(
+                    return Krb5Util.getInitialTicket(
                         realCaller,
-                        clientPrincipal, null, acc);
+                        clientPrincipal, acc);
                         }});
         } catch (PrivilegedActionException e) {
             GSSException ge =
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -124,6 +124,8 @@
                 usage == GSSCredential.INITIATE_AND_ACCEPT) {
                 credElement = Krb5InitCredential.getInstance
                     (caller, (Krb5NameElement) name, initLifetime);
+                credElement = Krb5ProxyCredential.tryImpersonation(
+                        caller, (Krb5InitCredential)credElement);
                 checkInitCredPermission
                     ((Krb5NameElement) credElement.getName());
             } else if (usage == GSSCredential.ACCEPT_ONLY) {
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5NameElement.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5NameElement.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -144,7 +144,7 @@
         return new Krb5NameElement(principalName, gssNameStr, gssNameType);
     }
 
-    static Krb5NameElement getInstance(PrincipalName principalName) {
+    public static Krb5NameElement getInstance(PrincipalName principalName) {
         return new Krb5NameElement(principalName,
                                    principalName.getName(),
                                    Krb5MechFactory.NT_GSS_KRB5_PRINCIPAL);
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5ProxyCredential.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5ProxyCredential.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, 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
@@ -26,10 +26,17 @@
 package sun.security.jgss.krb5;
 
 import org.ietf.jgss.*;
+import sun.security.jgss.GSSCaller;
 import sun.security.jgss.spi.*;
-import java.util.Date;
+
+import java.io.IOException;
+
+import sun.security.krb5.Credentials;
+import sun.security.krb5.KrbException;
 import sun.security.krb5.internal.Ticket;
 
+import javax.security.auth.kerberos.KerberosTicket;
+
 /**
  * Implements the krb5 proxy credential element used in constrained
  * delegation. It is used in both impersonation (where there is no Kerberos 5
@@ -112,4 +119,24 @@
         throw new GSSException(GSSException.FAILURE, -1,
                 "Only an initiate credentials can impersonate");
     }
+
+    // Try to see if a default credential should act as an impersonator.
+    static Krb5CredElement tryImpersonation(GSSCaller caller,
+            Krb5InitCredential initiator) throws GSSException {
+
+        try {
+            KerberosTicket proxy = initiator.proxyTicket;
+            if (proxy != null) {
+                Credentials proxyCreds = Krb5Util.ticketToCreds(proxy);
+                return new Krb5ProxyCredential(initiator,
+                        Krb5NameElement.getInstance(proxyCreds.getClient()),
+                        proxyCreds.getTicket());
+            } else {
+                return initiator;
+            }
+        } catch (KrbException | IOException e) {
+            throw new GSSException(GSSException.DEFECTIVE_CREDENTIAL, -1,
+                    "Cannot create proxy credential");
+        }
+    }
 }
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Util.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Util.java	Tue Oct 15 21:33:54 2019 +0000
@@ -60,11 +60,8 @@
     /**
      * Retrieves the ticket corresponding to the client/server principal
      * pair from the Subject in the specified AccessControlContext.
-     * If the ticket can not be found in the Subject, and if
-     * useSubjectCredsOnly is false, then obtain ticket from
-     * a LoginContext.
      */
-    static KerberosTicket getTicket(GSSCaller caller,
+    static KerberosTicket getServiceTicket(GSSCaller caller,
         String clientPrincipal, String serverPrincipal,
         AccessControlContext acc) throws LoginException {
 
@@ -74,11 +71,31 @@
             SubjectComber.find(accSubj, serverPrincipal, clientPrincipal,
                   KerberosTicket.class);
 
+        return ticket;
+    }
+
+    /**
+     * Retrieves the initial TGT corresponding to the client principal
+     * from the Subject in the specified AccessControlContext.
+     * If the ticket can not be found in the Subject, and if
+     * useSubjectCredsOnly is false, then obtain ticket from
+     * a LoginContext.
+     */
+    static KerberosTicket getInitialTicket(GSSCaller caller,
+            String clientPrincipal,
+            AccessControlContext acc) throws LoginException {
+
+        // Try to get ticket from acc's Subject
+        Subject accSubj = Subject.getSubject(acc);
+        KerberosTicket ticket =
+                SubjectComber.find(accSubj, null, clientPrincipal,
+                        KerberosTicket.class);
+
         // Try to get ticket from Subject obtained from GSSUtil
         if (ticket == null && !GSSUtil.useSubjectCredsOnly(caller)) {
             Subject subject = GSSUtil.login(caller, GSSUtil.GSS_KRB5_MECH_OID);
             ticket = SubjectComber.find(subject,
-                serverPrincipal, clientPrincipal, KerberosTicket.class);
+                    null, clientPrincipal, KerberosTicket.class);
         }
         return ticket;
     }
--- a/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java	Tue Oct 15 21:33:54 2019 +0000
@@ -59,13 +59,23 @@
     KerberosTime endTime;
     KerberosTime renewTill;
     HostAddresses cAddr;
-    EncryptionKey serviceKey;
     AuthorizationData authzData;
     private static boolean DEBUG = Krb5.DEBUG;
     private static CredentialsCache cache;
     static boolean alreadyLoaded = false;
     private static boolean alreadyTried = false;
 
+    private Credentials proxy = null;
+
+    public Credentials getProxy() {
+        return proxy;
+    }
+
+    public Credentials setProxy(Credentials proxy) {
+        this.proxy = proxy;
+        return this;
+    }
+
     // Read native ticket with session key type in the given list
     private static native Credentials acquireDefaultNativeCreds(int[] eTypes);
 
@@ -361,20 +371,19 @@
             return null;
         }
 
-        sun.security.krb5.internal.ccache.Credentials tgtCred  =
-            ccache.getDefaultCreds();
+        Credentials tgtCred = ccache.getInitialCreds();
 
         if (tgtCred == null) {
             return null;
         }
 
-        if (EType.isSupported(tgtCred.getEType())) {
-            return tgtCred.setKrbCreds();
+        if (EType.isSupported(tgtCred.key.getEType())) {
+            return tgtCred;
         } else {
             if (DEBUG) {
                 System.out.println(
                     ">>> unsupported key type found the default TGT: " +
-                    tgtCred.getEType());
+                    tgtCred.key.getEType());
             }
             return null;
         }
@@ -409,20 +418,19 @@
             cache = CredentialsCache.getInstance();
         }
         if (cache != null) {
-            sun.security.krb5.internal.ccache.Credentials temp =
-                cache.getDefaultCreds();
+            Credentials temp = cache.getInitialCreds();
             if (temp != null) {
                 if (DEBUG) {
                     System.out.println(">>> KrbCreds found the default ticket"
                             + " granting ticket in credential cache.");
                 }
-                if (EType.isSupported(temp.getEType())) {
-                    result = temp.setKrbCreds();
+                if (EType.isSupported(temp.key.getEType())) {
+                    result = temp;
                 } else {
                     if (DEBUG) {
                         System.out.println(
                             ">>> unsupported key type found the default TGT: " +
-                            temp.getEType());
+                            temp.key.getEType());
                     }
                 }
             }
@@ -499,10 +507,6 @@
         return cache;
     }
 
-    public EncryptionKey getServiceKey() {
-        return serviceKey;
-    }
-
     /*
      * Prints out debug info.
      */
--- a/src/java.security.jgss/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/JavaxSecurityAuthKerberosAccess.java	Tue Oct 15 21:33:54 2019 +0000
@@ -28,8 +28,6 @@
 import javax.security.auth.kerberos.KerberosPrincipal;
 import javax.security.auth.kerberos.KerberosTicket;
 import javax.security.auth.kerberos.KeyTab;
-import sun.security.krb5.EncryptionKey;
-import sun.security.krb5.PrincipalName;
 
 /**
  * An unsafe tunnel to get non-public access to classes in the
@@ -49,4 +47,13 @@
     public KerberosPrincipal kerberosTicketGetServerAlias(KerberosTicket t);
 
     public void kerberosTicketSetServerAlias(KerberosTicket t, KerberosPrincipal a);
+    /**
+     * Returns the proxy for a KerberosTicket.
+     */
+    public KerberosTicket kerberosTicketGetProxy(KerberosTicket t);
+
+    /**
+     * Sets the proxy for a KerberosTicket.
+     */
+    public void kerberosTicketSetProxy(KerberosTicket t, KerberosTicket p);
 }
--- a/src/java.security.jgss/share/classes/sun/security/krb5/Realm.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/Realm.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -186,7 +186,6 @@
             return false;
         for (int i = 0; i < name.length(); i++) {
             if (name.charAt(i) == '/' ||
-                name.charAt(i) == ':' ||
                 name.charAt(i) == '\0') {
                 return false;
             }
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java	Tue Oct 15 21:33:54 2019 +0000
@@ -325,16 +325,13 @@
     }
 
     /**
-     * Reads the next cred in stream.
-     * @return the next cred, null if ticket or second_ticket unparseable.
+     * Reads the next cred or config entry in stream.
+     * @return the next cred or config entry, null if data unparseable.
      *
-     * Note: MIT krb5 1.8.1 might generate a config entry with server principal
-     * X-CACHECONF:/krb5_ccache_conf_data/fast_avail/krbtgt/REALM@REALM. The
-     * entry is used by KDC to inform the client that it support certain
-     * features. Its ticket is not a valid krb5 ticket and thus this method
-     * returns null.
+     * When data is unparseable, this method makes sure the correct number of
+     * bytes are consumed so it's safe to start reading the next element.
      */
-    Credentials readCred(int version) throws IOException,RealmException, KrbApErrException, Asn1Exception {
+    Object readCred(int version) throws IOException,RealmException, KrbApErrException, Asn1Exception {
         PrincipalName cpname = null;
         try {
             cpname = readPrincipal(version);
@@ -396,12 +393,23 @@
         }
 
         try {
+            if (spname.getRealmString().equals("X-CACHECONF:")) {
+                String[] nameParts = spname.getNameStrings();
+                if (nameParts[0].equals("krb5_ccache_conf_data")) {
+                    return new CredentialsCache.ConfigEntry(nameParts[1],
+                            nameParts.length > 2 ? new PrincipalName(nameParts[2]) : null,
+                            ticketData);
+                }
+            }
             return new Credentials(cpname, spname, key, authtime, starttime,
-                endtime, renewTill, skey, tFlags,
-                addrs, auData,
-                ticketData != null ? new Ticket(ticketData) : null,
-                ticketData2 != null ? new Ticket(ticketData2) : null);
+                    endtime, renewTill, skey, tFlags,
+                    addrs, auData,
+                    ticketData != null ? new Ticket(ticketData) : null,
+                    ticketData2 != null ? new Ticket(ticketData2) : null);
         } catch (Exception e) {     // If any of new Ticket(*) fails.
+            if (DEBUG) {
+                e.printStackTrace(System.out);
+            }
             return null;
         }
     }
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheOutputStream.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheOutputStream.java	Tue Oct 15 21:33:54 2019 +0000
@@ -31,7 +31,6 @@
 package sun.security.krb5.internal.ccache;
 
 import java.io.IOException;
-import java.io.FileOutputStream;
 import java.io.OutputStream;
 import sun.security.krb5.internal.util.KrbDataOutputStream;
 import sun.security.krb5.*;
@@ -98,6 +97,21 @@
         writeTicket(creds.secondTicket);
     }
 
+    public void addConfigEntry(PrincipalName cname, CredentialsCache.ConfigEntry e)
+            throws IOException {
+        cname.writePrincipal(this);
+        e.getSName().writePrincipal(this);
+        write16(0); write16(0); write32(0);
+        write32(0); write32(0); write32(0); write32(0);
+        write8(0);
+        write32(0);
+        write32(0);
+        write32(0);
+        write32(e.getData().length);
+        write(e.getData());
+        write32(0);
+    }
+
     void writeTicket(Ticket t) throws IOException, Asn1Exception {
         if (t == null) {
             write32(0);
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/Credentials.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/Credentials.java	Tue Oct 15 21:33:54 2019 +0000
@@ -169,6 +169,18 @@
         return sname;
     }
 
+    public Ticket getTicket() throws RealmException {
+        return ticket;
+    }
+
+    public PrincipalName getServicePrincipal2() throws RealmException {
+        return secondTicket == null ? null : secondTicket.sname;
+    }
+
+    public PrincipalName getClientPrincipal() throws RealmException {
+        return cname;
+    }
+
     public sun.security.krb5.Credentials setKrbCreds() {
         // Note: We will not pass authorizationData to s.s.k.Credentials. The
         // field in that class will be passed to Krb5Context as the return
@@ -209,7 +221,15 @@
         return key.getEType();
     }
 
+    public EncryptionKey getKey() {
+        return key;
+    }
+
     public int getTktEType() {
         return ticket.encPart.getEType();
     }
+
+    public int getTktEType2() {
+        return (secondTicket == null) ? 0 : secondTicket.encPart.getEType();
+    }
 }
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CredentialsCache.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CredentialsCache.java	Tue Oct 15 21:33:54 2019 +0000
@@ -32,14 +32,9 @@
 
 import sun.security.krb5.*;
 import sun.security.krb5.internal.*;
-import java.util.StringTokenizer;
-import java.util.Vector;
+
+import java.util.List;
 import java.io.IOException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
 
 /**
  * CredentialsCache stores credentials(tickets, session keys, etc) in a semi-permanent store
@@ -120,6 +115,62 @@
     public abstract void save() throws IOException, KrbException;
     public abstract Credentials[] getCredsList();
     public abstract Credentials getDefaultCreds();
+    public abstract sun.security.krb5.Credentials getInitialCreds();
     public abstract Credentials getCreds(PrincipalName sname);
     public abstract Credentials getCreds(LoginOptions options, PrincipalName sname);
+    public abstract void addConfigEntry(ConfigEntry e);
+    public abstract List<ConfigEntry> getConfigEntries();
+
+    public ConfigEntry getConfigEntry(String name) {
+        List<ConfigEntry> entries = getConfigEntries();
+        if (entries != null) {
+            for (ConfigEntry e : entries) {
+                if (e.getName().equals(name)) {
+                    return e;
+                }
+            }
+        }
+        return null;
+    }
+
+    public static class ConfigEntry {
+
+        public ConfigEntry(String name, PrincipalName princ, byte[] data) {
+            this.name = name;
+            this.princ = princ;
+            this.data = data;
+        }
+
+        private final String name;
+        private final PrincipalName princ;
+        private final byte[] data; // not worth cloning
+
+        public String getName() {
+            return name;
+        }
+
+        public PrincipalName getPrinc() {
+            return princ;
+        }
+
+        public byte[] getData() {
+            return data;
+        }
+
+        @Override
+        public String toString() {
+            return name + (princ != null ? ("." + princ) : "")
+                    + ": " + new String(data);
+        }
+
+        public PrincipalName getSName() {
+            try {
+                return new PrincipalName("krb5_ccache_conf_data/" + name
+                        + (princ != null ? ("/" + princ) : "")
+                        + "@X-CACHECONF:");
+            } catch (RealmException e) {
+                throw new AssertionError(e);
+            }
+        }
+    }
 }
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -36,6 +36,12 @@
 import sun.security.action.GetPropertyAction;
 import sun.security.krb5.*;
 import sun.security.krb5.internal.*;
+import sun.security.util.SecurityProperties;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.StringTokenizer;
 import java.util.Vector;
 import java.io.IOException;
@@ -182,9 +188,13 @@
                 primaryPrincipal = p;
             credentialsList = new Vector<Credentials>();
             while (cis.available() > 0) {
-                Credentials cred = cis.readCred(version);
+                Object cred = cis.readCred(version);
                 if (cred != null) {
-                    credentialsList.addElement(cred);
+                    if (cred instanceof Credentials) {
+                        credentialsList.addElement((Credentials)cred);
+                    } else {
+                        addConfigEntry((CredentialsCache.ConfigEntry)cred);
+                    }
                 }
             }
         }
@@ -255,6 +265,9 @@
                     cos.addCreds(tmp[i]);
                 }
             }
+            for (ConfigEntry e : getConfigEntries()) {
+                cos.addConfigEntry(primaryPrincipal, e);
+            }
         }
     }
 
@@ -307,6 +320,17 @@
         }
     }
 
+    private List<ConfigEntry> configEntries = new ArrayList<>();
+
+    @Override
+    public void addConfigEntry(ConfigEntry e) {
+        configEntries.add(e);
+    }
+
+    @Override
+    public List<ConfigEntry> getConfigEntries() {
+        return Collections.unmodifiableList(configEntries);
+    }
 
     /**
      * Gets a credentials for a specified service.
@@ -326,6 +350,81 @@
         return null;
     }
 
+    public sun.security.krb5.Credentials getInitialCreds() {
+
+        Credentials defaultCreds = getDefaultCreds();
+        if (defaultCreds == null) {
+            return null;
+        }
+        sun.security.krb5.Credentials tgt = defaultCreds.setKrbCreds();
+
+        CredentialsCache.ConfigEntry entry = getConfigEntry("proxy_impersonator");
+        if (entry == null) {
+            if (DEBUG) {
+                System.out.println("get normal credential");
+            }
+            return tgt;
+        }
+
+        boolean force;
+        String prop = SecurityProperties.privilegedGetOverridable(
+                "jdk.security.krb5.default.initiate.credential");
+        if (prop == null) {
+            prop = "always-impersonate";
+        }
+        switch (prop) {
+            case "no-impersonate": // never try impersonation
+                if (DEBUG) {
+                    System.out.println("get normal credential");
+                }
+                return tgt;
+            case "try-impersonate":
+                force = false;
+                break;
+            case "always-impersonate":
+                force = true;
+                break;
+            default:
+                throw new RuntimeException(
+                        "Invalid jdk.security.krb5.default.initiate.credential");
+        }
+
+        try {
+            PrincipalName service = new PrincipalName(
+                    new String(entry.getData(), StandardCharsets.UTF_8));
+            if (!tgt.getClient().equals(service)) {
+                if (DEBUG) {
+                    System.out.println("proxy_impersonator does not match service name");
+                }
+                return force ? null : tgt;
+            }
+            PrincipalName client = getPrimaryPrincipal();
+            Credentials proxy = null;
+            for (Credentials c : getCredsList()) {
+                if (c.getClientPrincipal().equals(client)
+                        && c.getServicePrincipal().equals(service)) {
+                    proxy = c;
+                    break;
+                }
+            }
+            if (proxy == null) {
+                if (DEBUG) {
+                    System.out.println("Cannot find evidence ticket in ccache");
+                }
+                return force ? null : tgt;
+            }
+            if (DEBUG) {
+                System.out.println("Get proxied credential");
+            }
+            return tgt.setProxy(proxy.setKrbCreds());
+        } catch (KrbException e) {
+            if (DEBUG) {
+                System.out.println("Impersonation with ccache failed");
+            }
+            return force ? null : tgt;
+        }
+    }
+
     public Credentials getDefaultCreds() {
         Credentials[] list = getCredsList();
         if (list == null) {
--- a/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Klist.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.security.jgss/windows/classes/sun/security/krb5/internal/tools/Klist.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -31,6 +31,8 @@
 package sun.security.krb5.internal.tools;
 
 import java.net.InetAddress;
+import java.util.List;
+
 import sun.security.krb5.*;
 import sun.security.krb5.internal.*;
 import sun.security.krb5.internal.ccache.*;
@@ -249,6 +251,8 @@
                     String endtime;
                     String renewTill;
                     String servicePrincipal;
+                    PrincipalName servicePrincipal2;
+                    String clientPrincipal;
                     if (creds[i].getStartTime() != null) {
                         starttime = format(creds[i].getStartTime());
                     } else {
@@ -260,6 +264,18 @@
                     System.out.println("[" + (i + 1) + "] " +
                                        " Service Principal:  " +
                                        servicePrincipal);
+                    servicePrincipal2 =
+                            creds[i].getServicePrincipal2();
+                    if (servicePrincipal2 != null) {
+                        System.out.println("     Second Service:     "
+                                + servicePrincipal2);
+                    }
+                    clientPrincipal =
+                            creds[i].getClientPrincipal().toString();
+                    if (!clientPrincipal.equals(defaultPrincipal)) {
+                        System.out.println("     Client Principal:   " +
+                                clientPrincipal);
+                    }
                     System.out.println("     Valid starting:     " + starttime);
                     System.out.println("     Expires:            " + endtime);
                     if (creds[i].getRenewTill() != null) {
@@ -270,8 +286,15 @@
                     if (options[0] == 'e') {
                         String eskey = EType.toString(creds[i].getEType());
                         String etkt = EType.toString(creds[i].getTktEType());
-                        System.out.println("     EType (skey, tkt):  "
-                                + eskey + ", " + etkt);
+                        if (creds[i].getTktEType2() == 0) {
+                            System.out.println("     EType (skey, tkt):  "
+                                    + eskey + ", " + etkt);
+                        } else {
+                            String etkt2 = EType.toString(creds[i].getTktEType2());
+                            System.out.println("     EType (skey, tkts): "
+                                    + eskey + ", " + etkt
+                                    + ", " + etkt2);
+                        }
                     }
                     if (options[1] == 'f') {
                         System.out.println("     Flags:              " +
@@ -310,6 +333,15 @@
         } else {
             System.out.println("\nNo entries found.");
         }
+
+        List<CredentialsCache.ConfigEntry> configEntries
+                = cache.getConfigEntries();
+        if (configEntries != null && !configEntries.isEmpty()) {
+            System.out.println("\nConfig entries:");
+            for (CredentialsCache.ConfigEntry e : configEntries) {
+                System.out.println("     " + e);
+            }
+        }
     }
 
     void displayMessage(String target) {
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPath.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/XPath.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -40,7 +40,7 @@
  * The XPath class wraps an expression object and provides general services
  * for execution of that expression.
  * @xsl.usage advanced
- * @LastModified: Oct 2017
+ * @LastModified: May 2019
  */
 public class XPath implements Serializable, ExpressionOwner
 {
@@ -179,10 +179,12 @@
     else if (MATCH == type)
       parser.initMatchPattern(compiler, exprString, prefixResolver);
     else
-      throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_CANNOT_DEAL_XPATH_TYPE, new Object[]{Integer.toString(type)})); //"Can not deal with XPath type: " + type);
+      throw new RuntimeException(XSLMessages.createXPATHMessage(
+              XPATHErrorResources.ER_CANNOT_DEAL_XPATH_TYPE,
+              new Object[]{Integer.toString(type)}));
 
     // System.out.println("----------------");
-    Expression expr = compiler.compile(0);
+    Expression expr = compiler.compileExpression(0);
 
     // System.out.println("expr: "+expr);
     this.setExpression(expr);
@@ -234,7 +236,7 @@
             //"Can not deal with XPath type: " + type);
 
     // System.out.println("----------------");
-    Expression expr = compiler.compile(0);
+    Expression expr = compiler.compileExpression(0);
 
     // System.out.println("expr: "+expr);
     this.setExpression(expr);
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/FilterExprWalker.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -37,7 +37,7 @@
  * Walker for the OP_VARIABLE, or OP_EXTFUNCTION, or OP_FUNCTION, or OP_GROUP,
  * op codes.
  * @see <a href="http://www.w3.org/TR/xpath#NT-FilterExpr">XPath FilterExpr descriptions</a>
- * @LastModified: Oct 2017
+ * @LastModified: May 2019
  */
 public class FilterExprWalker extends AxesWalker
 {
@@ -77,7 +77,7 @@
         m_mustHardReset = true;
     case OpCodes.OP_GROUP :
     case OpCodes.OP_VARIABLE :
-      m_expr = compiler.compile(opPos);
+      m_expr = compiler.compileExpression(opPos);
       m_expr.exprSetParent(this);
       //if((OpCodes.OP_FUNCTION == stepType) && (m_expr instanceof com.sun.org.apache.xalan.internal.templates.FuncKey))
       if(m_expr instanceof com.sun.org.apache.xpath.internal.operations.Variable)
@@ -87,7 +87,7 @@
       }
       break;
     default :
-      m_expr = compiler.compile(opPos + 2);
+      m_expr = compiler.compileExpression(opPos + 2);
       m_expr.exprSetParent(this);
     }
 //    if(m_expr instanceof WalkingIterator)
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/axes/WalkerFactory.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -41,7 +41,7 @@
  * which are built from the opcode map output, and an analysis engine
  * for the location path expressions in order to provide optimization hints.
  *
- * @LastModified: Oct 2017
+ * @LastModified: May 2019
  */
 public class WalkerFactory
 {
@@ -1008,10 +1008,10 @@
       case OpCodes.OP_EXTFUNCTION :
       case OpCodes.OP_FUNCTION :
       case OpCodes.OP_GROUP :
-        expr = compiler.compile(opPos);
+        expr = compiler.compileExpression(opPos);
         break;
       default :
-        expr = compiler.compile(opPos + 2);
+        expr = compiler.compileExpression(opPos + 2);
       }
 
       axis = Axis.FILTEREDLIST;
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Compiler.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/Compiler.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -70,9 +69,12 @@
  * of operation codes (op map) and then builds from that into an Expression
  * tree.
  * @xsl.usage advanced
+ * @LastModified: May 2019
  */
 public class Compiler extends OpMap
 {
+  // count the number of operations or calls to compileOperation
+  int countOp;
 
   /**
    * Construct a Compiler object with a specific ErrorListener and
@@ -106,15 +108,40 @@
 
   /**
    * Execute the XPath object from a given opcode position.
+   *
+   * Note that this method is added so that when StackOverflowError is caught
+   * the address space can be freed to this point allowing further activities
+   * such as reporting the error.
+   *
    * @param opPos The current position in the xpath.m_opMap array.
    * @return The result of the XPath.
    *
    * @throws TransformerException if there is a syntax or other error.
    * @xsl.usage advanced
    */
-  public Expression compile(int opPos) throws TransformerException
+   public Expression compileExpression(int opPos) throws TransformerException
+   {
+       try {
+           countOp = 0;
+           return compile(opPos);
+       } catch (StackOverflowError sof) {
+           error(XPATHErrorResources.ER_COMPILATION_TOO_MANY_OPERATION, new Object[]{countOp});
+       }
+       return null;
+   }
+
+  /**
+   * This method handles the actual compilation process. It is called from the
+   * compileExpression method as well as the subsequent processes. See the note
+   * for compileExpression.
+   *
+   * @param opPos The current position in the xpath.m_opMap array.
+   * @return The result of the XPath.
+   *
+   * @throws TransformerException if there is a syntax or other error.
+   */
+  private Expression compile(int opPos) throws TransformerException
   {
-
     int op = getOp(opPos);
 
     Expression expr = null;
@@ -210,6 +237,7 @@
   private Expression compileOperation(Operation operation, int opPos)
           throws TransformerException
   {
+    ++countOp;
 
     int leftPos = getFirstChildPos(opPos);
     int rightPos = getNextOpPos(leftPos);
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/XPathParser.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/XPathParser.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -34,6 +34,7 @@
  * Tokenizes and parses XPath expressions. This should really be named
  * XPathParserImpl, and may be renamed in the future.
  * @xsl.usage general
+ * @LastModified: May 2019
  */
 public class XPathParser
 {
@@ -71,6 +72,9 @@
   protected final static int FILTER_MATCH_PRIMARY    = 1;
   protected final static int FILTER_MATCH_PREDICATES = 2;
 
+  // counts open predicates
+  private int countPredicate;
+
   /**
    * The parser constructor.
    */
@@ -157,6 +161,9 @@
           }
           else
                 throw e;
+    } catch (StackOverflowError sof) {
+        error(XPATHErrorResources.ER_PREDICATE_TOO_MANY_OPEN,
+              new Object[]{m_token, m_queueMark, countPredicate});
     }
 
     compiler.shrink();
@@ -190,7 +197,12 @@
     m_ops.setOp(OpMap.MAPINDEX_LENGTH, 2);
 
     nextToken();
-    Pattern();
+    try {
+        Pattern();
+    } catch (StackOverflowError sof) {
+        error(XPATHErrorResources.ER_PREDICATE_TOO_MANY_OPEN,
+              new Object[]{m_token, m_queueMark, countPredicate});
+    }
 
     if (null != m_token)
     {
@@ -741,7 +753,7 @@
    */
   protected void Expr() throws javax.xml.transform.TransformerException
   {
-    OrExpr();
+       OrExpr();
   }
 
   /**
@@ -1883,11 +1895,12 @@
    */
   protected void Predicate() throws javax.xml.transform.TransformerException
   {
-
     if (tokenIs('['))
     {
+      countPredicate++;
       nextToken();
       PredicateExpr();
+      countPredicate--;
       consumeExpected(']');
     }
   }
--- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,6 +1,5 @@
 /*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -32,6 +31,7 @@
   * Also you need to  update the count of messages(MAX_CODE)or
  * the count of warnings(MAX_WARNING) [ Information purpose only]
  * @xsl.usage advanced
+ * @LastModified: May 2019
  */
 public class XPATHErrorResources extends ListResourceBundle
 {
@@ -150,6 +150,10 @@
          "ER_FOUND_COMMA_BUT_NO_FOLLOWING_ARG";
   public static final String ER_PREDICATE_ILLEGAL_SYNTAX =
          "ER_PREDICATE_ILLEGAL_SYNTAX";
+  public static final String ER_PREDICATE_TOO_MANY_OPEN =
+         "ER_PREDICATE_TOO_MANY_OPEN";
+  public static final String ER_COMPILATION_TOO_MANY_OPERATION =
+         "ER_COMPILATION_TOO_MANY_OPERATION";
   public static final String ER_ILLEGAL_AXIS_NAME = "ER_ILLEGAL_AXIS_NAME";
   public static final String ER_UNKNOWN_NODETYPE = "ER_UNKNOWN_NODETYPE";
   public static final String ER_PATTERN_LITERAL_NEEDS_BE_QUOTED =
@@ -464,6 +468,12 @@
   { ER_PREDICATE_ILLEGAL_SYNTAX,
       "'..[predicate]' or '.[predicate]' is illegal syntax.  Use 'self::node()[predicate]' instead."},
 
+  { ER_PREDICATE_TOO_MANY_OPEN,
+      "Stack overflow while parsing {0} at {1}. Too many open predicates({2})."},
+
+  { ER_COMPILATION_TOO_MANY_OPERATION,
+      "Stack overflow while compiling the expression. Too many operations({0})."},
+
   { ER_ILLEGAL_AXIS_NAME,
      "illegal axis name: {0}"},
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/JavaScriptScanner.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/JavaScriptScanner.java	Tue Oct 15 21:33:54 2019 +0000
@@ -61,34 +61,8 @@
     public Void visitAttribute(AttributeTree tree, Consumer<DocTreePath> f) {
         String name = tree.getName().toString().toLowerCase(Locale.ENGLISH);
         switch (name) {
-            // See https://www.w3.org/TR/html-markup/global-attributes.html#common.attrs.event-handler
-            case "onabort":  case "onblur":  case "oncanplay":  case "oncanplaythrough":
-            case "onchange":  case "onclick":  case "oncontextmenu":  case "ondblclick":
-            case "ondrag":  case "ondragend":  case "ondragenter":  case "ondragleave":
-            case "ondragover":  case "ondragstart":  case "ondrop":  case "ondurationchange":
-            case "onemptied":  case "onended":  case "onerror":  case "onfocus":  case "oninput":
-            case "oninvalid":  case "onkeydown":  case "onkeypress":  case "onkeyup":
-            case "onload":  case "onloadeddata":  case "onloadedmetadata":  case "onloadstart":
-            case "onmousedown":  case "onmousemove":  case "onmouseout":  case "onmouseover":
-            case "onmouseup":  case "onmousewheel":  case "onpause":  case "onplay":
-            case "onplaying":  case "onprogress":  case "onratechange":  case "onreadystatechange":
-            case "onreset":  case "onscroll":  case "onseeked":  case "onseeking":
-            case "onselect":  case "onshow":  case "onstalled":  case "onsubmit":  case "onsuspend":
-            case "ontimeupdate":  case "onvolumechange":  case "onwaiting":
-
             // See https://www.w3.org/TR/html4/sgml/dtd.html
-            // Most of the attributes that take a %Script are also defined as event handlers
-            // in HTML 5. The one exception is onunload.
-            // case "onchange":  case "onclick":   case "ondblclick":  case "onfocus":
-            // case "onkeydown":  case "onkeypress":  case "onkeyup":  case "onload":
-            // case "onmousedown":  case "onmousemove":  case "onmouseout":  case "onmouseover":
-            // case "onmouseup":  case "onreset":  case "onselect":  case "onsubmit":
-            case "onunload":
-                f.accept(getCurrentPath());
-                break;
-
-            // See https://www.w3.org/TR/html4/sgml/dtd.html
-            //     https://www.w3.org/TR/html5/
+            //     https://www.w3.org/TR/html52/fullindex.html#attributes-table
             // These are all the attributes that take a %URI or a valid URL potentially surrounded
             // by spaces
             case "action":  case "cite":  case "classid":  case "codebase":  case "data":
@@ -102,6 +76,14 @@
                     }
                 }
                 break;
+            // See https://www.w3.org/TR/html52/webappapis.html#events-event-handlers
+            // An event handler has a name, which always starts with "on" and is followed by
+            // the name of the event for which it is intended.
+            default:
+                if (name.startsWith("on")) {
+                    f.accept(getCurrentPath());
+                }
+                break;
         }
         return super.visitAttribute(tree, f);
     }
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/regexp/JdkRegExp.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/regexp/JdkRegExp.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, 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
@@ -82,6 +82,8 @@
             }
         } catch (final PatternSyntaxException e2) {
             throwParserException("syntax", e2.getMessage());
+        } catch (StackOverflowError e3) {
+            throw new RuntimeException(e3);
         }
     }
 
--- a/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2019, 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
@@ -82,6 +82,8 @@
             }
         } catch (final PatternSyntaxException | JOniException e2) {
             throwParserException("syntax", e2.getMessage());
+        } catch (StackOverflowError e3) {
+            throw new RuntimeException(e3);
         }
     }
 
--- a/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -644,6 +644,7 @@
                         // renew if ticket is old.
                         Credentials newCred = renewCredentials(cred);
                         if (newCred != null) {
+                            newCred.setProxy(cred.getProxy());
                             cred = newCred;
                         }
                     }
@@ -1070,6 +1071,10 @@
             // create Kerberos Ticket
             if (isInitiator) {
                 kerbTicket = Krb5Util.credsToTicket(cred);
+                if (cred.getProxy() != null) {
+                    KerberosSecrets.getJavaxSecurityAuthKerberosAccess()
+                            .kerberosTicketSetProxy(kerbTicket,Krb5Util.credsToTicket(cred.getProxy()));
+                }
             }
 
             if (storeKey && encKeys != null) {
--- a/test/hotspot/jtreg/serviceability/logging/TestQuotedLogOutputs.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/test/hotspot/jtreg/serviceability/logging/TestQuotedLogOutputs.java	Tue Oct 15 21:33:54 2019 +0000
@@ -26,6 +26,7 @@
  * @summary Ensure proper parsing of quoted output names for -Xlog arguments.
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
+ * @run main/othervm TestQuotedLogOutputs
  */
 
 import java.io.File;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/FontMetrics/SpaceAdvance.java	Tue Oct 15 21:33:54 2019 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019, 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 8227662
+ */
+
+import java.awt.Font;
+import java.awt.FontMetrics ;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+
+public class SpaceAdvance {
+    public static void main(String[] args) throws Exception {
+
+        BufferedImage bi = new BufferedImage(1,1,1);
+        Graphics2D g2d = bi.createGraphics();
+        Font font = new Font(Font.DIALOG, Font.PLAIN, 12);
+        if (!font.canDisplay(' ')) {
+            return;
+        }
+        g2d.setFont(font);
+        FontMetrics fm = g2d.getFontMetrics();
+        if (fm.charWidth(' ') == 0) {
+            throw new RuntimeException("Space has char width of 0");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/image/DrawImage/IncorrectManagedImageSourceOffset.java	Tue Oct 15 21:33:54 2019 +0000
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2014, 2019, 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.
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import sun.awt.image.SunWritableRaster;
+
+import static java.awt.Transparency.BITMASK;
+import static java.awt.Transparency.OPAQUE;
+import static java.awt.Transparency.TRANSLUCENT;
+import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
+import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
+import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED;
+import static java.awt.image.BufferedImage.TYPE_CUSTOM;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
+import static java.awt.image.BufferedImage.TYPE_INT_BGR;
+import static java.awt.image.BufferedImage.TYPE_INT_RGB;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8029253 6207877
+ * @summary Tests asymmetric source offsets when managed image is drawn to VI.
+ *          Results of the blit to compatibleImage are used for comparison.
+ * @author Sergey Bylokhov
+ * @modules java.desktop/sun.awt.image
+ * @run main/othervm -Dsun.java2d.accthreshold=0 IncorrectManagedImageSourceOffset
+ * @run main/othervm -Dsun.java2d.accthreshold=0 -Dsun.java2d.uiScale=1 IncorrectManagedImageSourceOffset
+ * @run main/othervm -Dsun.java2d.accthreshold=0 -Dsun.java2d.uiScale=2 IncorrectManagedImageSourceOffset
+ */
+public final class IncorrectManagedImageSourceOffset {
+
+    // See the same test for unmanaged images: IncorrectUnmanagedImageSourceOffset
+
+    private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB,
+                                        TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
+                                        TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR,
+                                        TYPE_4BYTE_ABGR_PRE,
+                                        /*TYPE_USHORT_565_RGB,
+                                        TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
+                                        TYPE_USHORT_GRAY,*/ TYPE_BYTE_BINARY,
+                                        TYPE_BYTE_INDEXED, TYPE_CUSTOM};
+    private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT};
+
+    public static void main(final String[] args) throws IOException {
+        for (final int viType : TRANSPARENCIES) {
+            for (final int biType : TYPES) {
+                BufferedImage bi = makeManagedBI(biType);
+                fill(bi);
+                test(bi, viType);
+            }
+        }
+    }
+
+    private static void test(BufferedImage bi, int type)
+            throws IOException {
+        GraphicsEnvironment ge = GraphicsEnvironment
+                .getLocalGraphicsEnvironment();
+        GraphicsConfiguration gc = ge.getDefaultScreenDevice()
+                                     .getDefaultConfiguration();
+        VolatileImage vi = gc.createCompatibleVolatileImage(511, 255, type);
+        BufferedImage gold = gc.createCompatibleImage(511, 255, type);
+        // draw to compatible Image
+        Graphics2D big = gold.createGraphics();
+        // force scaled blit
+        big.drawImage(bi, 7, 11, 127, 111, 7, 11, 127 * 2, 111, null);
+        big.dispose();
+        // draw to volatile image
+        BufferedImage snapshot;
+        while (true) {
+            vi.validate(gc);
+            if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
+                try {
+                    Thread.sleep(100);
+                } catch (final InterruptedException ignored) {
+                }
+                continue;
+            }
+            Graphics2D vig = vi.createGraphics();
+            // force scaled blit
+            vig.drawImage(bi, 7, 11, 127, 111, 7, 11, 127 * 2, 111, null);
+            vig.dispose();
+            snapshot = vi.getSnapshot();
+            if (vi.contentsLost()) {
+                try {
+                    Thread.sleep(100);
+                } catch (final InterruptedException ignored) {
+                }
+                continue;
+            }
+            break;
+        }
+        // validate images
+        for (int x = 7; x < 127; ++x) {
+            for (int y = 11; y < 111; ++y) {
+                if (gold.getRGB(x, y) != snapshot.getRGB(x, y)) {
+                    ImageIO.write(gold, "png", new File("gold.png"));
+                    ImageIO.write(snapshot, "png", new File("bi.png"));
+                    throw new RuntimeException("Test failed.");
+                }
+            }
+        }
+    }
+
+    private static BufferedImage makeManagedBI(final int type) {
+        final BufferedImage bi;
+        if (type == TYPE_CUSTOM) {
+            bi = makeCustomManagedBI();
+        } else {
+            bi = new BufferedImage(511, 255, type);
+        }
+        bi.setAccelerationPriority(1.0f);
+        return bi;
+    }
+
+    /**
+     * Returns the custom buffered image, which mostly identical to
+     * BufferedImage.(w,h,TYPE_3BYTE_BGR), but uses the bigger scanlineStride.
+     * This means that the raster will have gaps, between the rows.
+     */
+    private static BufferedImage makeCustomManagedBI() {
+        int w = 511, h = 255;
+        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        int[] nBits = {8, 8, 8};
+        int[] bOffs = {2, 1, 0};
+        ColorModel colorModel = new ComponentColorModel(cs, nBits, false, false,
+                                                        Transparency.OPAQUE,
+                                                        DataBuffer.TYPE_BYTE);
+        WritableRaster raster =
+                Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h,
+                                               w * 3 + 2, 3, bOffs, null);
+        BufferedImage bi = new BufferedImage(colorModel, raster, true, null);
+        SunWritableRaster.makeTrackable(raster.getDataBuffer());
+        SunWritableRaster.markDirty(bi);
+        return bi;
+    }
+
+    private static void fill(final Image image) {
+        final Graphics2D graphics = (Graphics2D) image.getGraphics();
+        graphics.setComposite(AlphaComposite.Src);
+        for (int i = 0; i < image.getHeight(null); ++i) {
+            graphics.setColor(new Color(i, 0, 0));
+            graphics.fillRect(0, i, image.getWidth(null), 1);
+        }
+        graphics.dispose();
+    }
+}
--- a/test/jdk/java/awt/image/DrawImage/IncorrectUnmanagedImageSourceOffset.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/test/jdk/java/awt/image/DrawImage/IncorrectUnmanagedImageSourceOffset.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, 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
@@ -27,30 +27,52 @@
 import java.awt.GraphicsConfiguration;
 import java.awt.GraphicsEnvironment;
 import java.awt.Image;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
 import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
 import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferByte;
 import java.awt.image.DataBufferInt;
 import java.awt.image.DataBufferShort;
+import java.awt.image.Raster;
 import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
 import java.io.File;
 import java.io.IOException;
 
 import javax.imageio.ImageIO;
 
-import static java.awt.Transparency.*;
-import static java.awt.image.BufferedImage.*;
+import static java.awt.Transparency.BITMASK;
+import static java.awt.Transparency.OPAQUE;
+import static java.awt.Transparency.TRANSLUCENT;
+import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
+import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
+import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED;
+import static java.awt.image.BufferedImage.TYPE_CUSTOM;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
+import static java.awt.image.BufferedImage.TYPE_INT_BGR;
+import static java.awt.image.BufferedImage.TYPE_INT_RGB;
 
 /**
  * @test
  * @key headful
- * @bug 8029253
+ * @bug 8029253 6207877
  * @summary Tests asymmetric source offsets when unmanaged image is drawn to VI.
  *          Results of the blit to compatibleImage are used for comparison.
  * @author Sergey Bylokhov
+ * @run main/othervm IncorrectUnmanagedImageSourceOffset
+ * @run main/othervm -Dsun.java2d.uiScale=1 IncorrectUnmanagedImageSourceOffset
+ * @run main/othervm -Dsun.java2d.uiScale=2 IncorrectUnmanagedImageSourceOffset
  */
 public final class IncorrectUnmanagedImageSourceOffset {
 
+    // See the same test for managed images: IncorrectManagedImageSourceOffset
+
     private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB,
                                         TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
                                         TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR,
@@ -58,7 +80,7 @@
                                         /*TYPE_USHORT_565_RGB,
                                         TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
                                         TYPE_USHORT_GRAY,*/ TYPE_BYTE_BINARY,
-                                        TYPE_BYTE_INDEXED};
+                                        TYPE_BYTE_INDEXED, TYPE_CUSTOM};
     private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT};
 
     public static void main(final String[] args) throws IOException {
@@ -122,7 +144,12 @@
     }
 
     private static BufferedImage makeUnmanagedBI(final int type) {
-        final BufferedImage bi = new BufferedImage(511, 255, type);
+        final BufferedImage bi;
+        if (type == TYPE_CUSTOM) {
+            bi = makeCustomUnmanagedBI();
+        } else {
+            bi = new BufferedImage(511, 255, type);
+        }
         final DataBuffer db = bi.getRaster().getDataBuffer();
         if (db instanceof DataBufferInt) {
             ((DataBufferInt) db).getData();
@@ -130,15 +157,30 @@
             ((DataBufferShort) db).getData();
         } else if (db instanceof DataBufferByte) {
             ((DataBufferByte) db).getData();
-        } else {
-            try {
-                bi.setAccelerationPriority(0.0f);
-            } catch (final Throwable ignored) {
-            }
         }
+        bi.setAccelerationPriority(0.0f);
         return bi;
     }
 
+    /**
+     * Returns the custom buffered image, which mostly identical to
+     * BufferedImage.(w,h,TYPE_3BYTE_BGR), but uses the bigger scanlineStride.
+     * This means that the raster will have gaps, between the rows.
+     */
+    private static BufferedImage makeCustomUnmanagedBI() {
+        int w = 511, h = 255;
+        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        int[] nBits = {8, 8, 8};
+        int[] bOffs = {2, 1, 0};
+        ColorModel colorModel = new ComponentColorModel(cs, nBits, false, false,
+                                                        Transparency.OPAQUE,
+                                                        DataBuffer.TYPE_BYTE);
+        WritableRaster raster =
+                Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h,
+                                               w * 3 + 2, 3, bOffs, null);
+        return new BufferedImage(colorModel, raster, true, null);
+    }
+
     private static void fill(final Image image) {
         final Graphics2D graphics = (Graphics2D) image.getGraphics();
         graphics.setComposite(AlphaComposite.Src);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/image/DrawImage/SimpleManagedImage.java	Tue Oct 15 21:33:54 2019 +0000
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2014, 2019, 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.
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import sun.awt.image.SunWritableRaster;
+
+import static java.awt.Transparency.BITMASK;
+import static java.awt.Transparency.OPAQUE;
+import static java.awt.Transparency.TRANSLUCENT;
+import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
+import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
+import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED;
+import static java.awt.image.BufferedImage.TYPE_CUSTOM;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
+import static java.awt.image.BufferedImage.TYPE_INT_BGR;
+import static java.awt.image.BufferedImage.TYPE_INT_RGB;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8029253 6207877
+ * @summary Tests the case when managed image is drawn to VI.
+ *          Results of the blit to compatibleImage are used for comparison.
+ * @author Sergey Bylokhov
+ * @modules java.desktop/sun.awt.image
+ * @run main/othervm -Dsun.java2d.accthreshold=0 SimpleManagedImage
+ * @run main/othervm -Dsun.java2d.accthreshold=0 -Dsun.java2d.uiScale=1 SimpleManagedImage
+ * @run main/othervm -Dsun.java2d.accthreshold=0 -Dsun.java2d.uiScale=2 SimpleManagedImage
+ */
+public final class SimpleManagedImage {
+
+    // See the same test for unmanaged images: SimpleUnmanagedImage
+
+    private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB,
+                                        TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
+                                        TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR,
+                                        TYPE_4BYTE_ABGR_PRE,
+                                        /*TYPE_USHORT_565_RGB,
+                                        TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
+                                        TYPE_USHORT_GRAY,*/ TYPE_BYTE_BINARY,
+                                        TYPE_BYTE_INDEXED, TYPE_CUSTOM};
+    private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT};
+
+    public static void main(final String[] args) throws IOException {
+        for (final int viType : TRANSPARENCIES) {
+            for (final int biType : TYPES) {
+                BufferedImage bi = makeManagedBI(biType);
+                fill(bi);
+                test(bi, viType);
+            }
+        }
+    }
+
+    private static void test(BufferedImage bi, int type)
+            throws IOException {
+        GraphicsEnvironment ge = GraphicsEnvironment
+                .getLocalGraphicsEnvironment();
+        GraphicsConfiguration gc = ge.getDefaultScreenDevice()
+                                     .getDefaultConfiguration();
+        VolatileImage vi = gc.createCompatibleVolatileImage(1000, 1000, type);
+        BufferedImage gold = gc.createCompatibleImage(1000, 1000, type);
+        // draw to compatible Image
+        init(gold);
+        Graphics2D big = gold.createGraphics();
+        big.drawImage(bi, 7, 11, null);
+        big.dispose();
+        // draw to volatile image
+        BufferedImage snapshot;
+        while (true) {
+            vi.validate(gc);
+            if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
+                try {
+                    Thread.sleep(100);
+                } catch (final InterruptedException ignored) {
+                }
+                continue;
+            }
+            init(vi);
+            Graphics2D vig = vi.createGraphics();
+            vig.drawImage(bi, 7, 11, null);
+            vig.dispose();
+            snapshot = vi.getSnapshot();
+            if (vi.contentsLost()) {
+                try {
+                    Thread.sleep(100);
+                } catch (final InterruptedException ignored) {
+                }
+                continue;
+            }
+            break;
+        }
+        // validate images
+        for (int x = 0; x < 1000; ++x) {
+            for (int y = 0; y < 1000; ++y) {
+                if (gold.getRGB(x, y) != snapshot.getRGB(x, y)) {
+                    ImageIO.write(gold, "png", new File("gold.png"));
+                    ImageIO.write(snapshot, "png", new File("bi.png"));
+                    throw new RuntimeException("Test failed.");
+                }
+            }
+        }
+    }
+
+    private static BufferedImage makeManagedBI(final int type) {
+        final BufferedImage bi;
+        if (type == TYPE_CUSTOM) {
+            bi = makeCustomManagedBI();
+        } else {
+            bi = new BufferedImage(511, 255, type);
+        }
+        bi.setAccelerationPriority(1.0f);
+        return bi;
+    }
+
+    /**
+     * Returns the custom buffered image, which mostly identical to
+     * BufferedImage.(w,h,TYPE_3BYTE_BGR), but uses the bigger scanlineStride.
+     * This means that the raster will have gaps, between the rows.
+     */
+    private static BufferedImage makeCustomManagedBI() {
+        int w = 511, h = 255;
+        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        int[] nBits = {8, 8, 8};
+        int[] bOffs = {2, 1, 0};
+        ColorModel colorModel = new ComponentColorModel(cs, nBits, false, false,
+                                                        Transparency.OPAQUE,
+                                                        DataBuffer.TYPE_BYTE);
+        WritableRaster raster =
+                Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h,
+                                               w * 3 + 2, 3, bOffs, null);
+        BufferedImage bi = new BufferedImage(colorModel, raster, true, null);
+        SunWritableRaster.makeTrackable(raster.getDataBuffer());
+        SunWritableRaster.markDirty(bi);
+        return bi;
+    }
+
+    private static void init(final Image image) {
+        final Graphics2D graphics = (Graphics2D) image.getGraphics();
+        graphics.setComposite(AlphaComposite.Src);
+        graphics.setColor(new Color(0, 0, 0, 0));
+        graphics.fillRect(0, 0, image.getWidth(null), image.getHeight(null));
+        graphics.dispose();
+    }
+
+    private static void fill(final Image image) {
+        final Graphics2D graphics = (Graphics2D) image.getGraphics();
+        graphics.setComposite(AlphaComposite.Src);
+        for (int i = 0; i < image.getHeight(null); ++i) {
+            graphics.setColor(new Color(i, 0, 0));
+            graphics.fillRect(0, i, image.getWidth(null), 1);
+        }
+        graphics.dispose();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/awt/image/DrawImage/SimpleUnmanagedImage.java	Tue Oct 15 21:33:54 2019 +0000
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2014, 2019, 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.
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Image;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.Raster;
+import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
+import java.io.File;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import static java.awt.Transparency.BITMASK;
+import static java.awt.Transparency.OPAQUE;
+import static java.awt.Transparency.TRANSLUCENT;
+import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
+import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
+import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
+import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED;
+import static java.awt.image.BufferedImage.TYPE_CUSTOM;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
+import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
+import static java.awt.image.BufferedImage.TYPE_INT_BGR;
+import static java.awt.image.BufferedImage.TYPE_INT_RGB;
+
+/**
+ * @test
+ * @key headful
+ * @bug 8029253 6207877
+ * @summary Tests the case when unmanaged image is drawn to VI.
+ *          Results of the blit to compatibleImage are used for comparison.
+ * @author Sergey Bylokhov
+ * @run main/othervm SimpleUnmanagedImage
+ * @run main/othervm -Dsun.java2d.uiScale=1 SimpleUnmanagedImage
+ * @run main/othervm -Dsun.java2d.uiScale=2 SimpleUnmanagedImage
+ */
+public final class SimpleUnmanagedImage {
+
+    // See the same test for managed images: SimpleManagedImage
+
+    private static final int[] TYPES = {TYPE_INT_RGB, TYPE_INT_ARGB,
+                                        TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
+                                        TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR,
+                                        TYPE_4BYTE_ABGR_PRE,
+                                        /*TYPE_USHORT_565_RGB,
+                                        TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
+                                        TYPE_USHORT_GRAY,*/ TYPE_BYTE_BINARY,
+                                        TYPE_BYTE_INDEXED, TYPE_CUSTOM};
+    private static final int[] TRANSPARENCIES = {OPAQUE, BITMASK, TRANSLUCENT};
+
+    public static void main(final String[] args) throws IOException {
+        for (final int viType : TRANSPARENCIES) {
+            for (final int biType : TYPES) {
+                BufferedImage bi = makeUnmanagedBI(biType);
+                fill(bi);
+                test(bi, viType);
+            }
+        }
+    }
+
+    private static void test(BufferedImage bi, int type)
+            throws IOException {
+        GraphicsEnvironment ge = GraphicsEnvironment
+                .getLocalGraphicsEnvironment();
+        GraphicsConfiguration gc = ge.getDefaultScreenDevice()
+                                     .getDefaultConfiguration();
+        VolatileImage vi = gc.createCompatibleVolatileImage(1000, 1000, type);
+        BufferedImage gold = gc.createCompatibleImage(1000, 1000, type);
+        // draw to compatible Image
+        init(gold);
+        Graphics2D big = gold.createGraphics();
+        big.drawImage(bi, 7, 11, null);
+        big.dispose();
+        // draw to volatile image
+        BufferedImage snapshot;
+        while (true) {
+            vi.validate(gc);
+            if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
+                try {
+                    Thread.sleep(100);
+                } catch (final InterruptedException ignored) {
+                }
+                continue;
+            }
+            init(vi);
+            Graphics2D vig = vi.createGraphics();
+            vig.drawImage(bi, 7, 11, null);
+            vig.dispose();
+            snapshot = vi.getSnapshot();
+            if (vi.contentsLost()) {
+                try {
+                    Thread.sleep(100);
+                } catch (final InterruptedException ignored) {
+                }
+                continue;
+            }
+            break;
+        }
+        // validate images
+        for (int x = 0; x < 1000; ++x) {
+            for (int y = 0; y < 1000; ++y) {
+                if (gold.getRGB(x, y) != snapshot.getRGB(x, y)) {
+                    ImageIO.write(gold, "png", new File("gold.png"));
+                    ImageIO.write(snapshot, "png", new File("bi.png"));
+                    throw new RuntimeException("Test failed.");
+                }
+            }
+        }
+    }
+
+    private static BufferedImage makeUnmanagedBI(final int type) {
+        final BufferedImage bi;
+        if (type == TYPE_CUSTOM) {
+            bi = makeCustomUnmanagedBI();
+        } else {
+            bi = new BufferedImage(511, 255, type);
+        }
+        final DataBuffer db = bi.getRaster().getDataBuffer();
+        if (db instanceof DataBufferInt) {
+            ((DataBufferInt) db).getData();
+        } else if (db instanceof DataBufferShort) {
+            ((DataBufferShort) db).getData();
+        } else if (db instanceof DataBufferByte) {
+            ((DataBufferByte) db).getData();
+        }
+        bi.setAccelerationPriority(0.0f);
+        return bi;
+    }
+
+    /**
+     * Returns the custom buffered image, which mostly identical to
+     * BufferedImage.(w,h,TYPE_3BYTE_BGR), but uses the bigger scanlineStride.
+     * This means that the raster will have gaps, between the rows.
+     */
+    private static BufferedImage makeCustomUnmanagedBI() {
+        int w = 511, h = 255;
+        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+        int[] nBits = {8, 8, 8};
+        int[] bOffs = {2, 1, 0};
+        ColorModel colorModel = new ComponentColorModel(cs, nBits, false, false,
+                                                        Transparency.OPAQUE,
+                                                        DataBuffer.TYPE_BYTE);
+        WritableRaster raster =
+                Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, w, h,
+                                               w * 3 + 2, 3, bOffs, null);
+        return new BufferedImage(colorModel, raster, true, null);
+    }
+
+    private static void init(final Image image) {
+        final Graphics2D graphics = (Graphics2D) image.getGraphics();
+        graphics.setComposite(AlphaComposite.Src);
+        graphics.setColor(new Color(0, 0, 0, 0));
+        graphics.fillRect(0, 0, image.getWidth(null), image.getHeight(null));
+        graphics.dispose();
+    }
+
+    private static void fill(final Image image) {
+        final Graphics2D graphics = (Graphics2D) image.getGraphics();
+        graphics.setComposite(AlphaComposite.Src);
+        for (int i = 0; i < image.getHeight(null); ++i) {
+            graphics.setColor(new Color(i, 0, 0));
+            graphics.fillRect(0, i, image.getWidth(null), 1);
+        }
+        graphics.dispose();
+    }
+}
--- a/test/jdk/java/rmi/testlibrary/TestSocketFactory.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/test/jdk/java/rmi/testlibrary/TestSocketFactory.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, 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
@@ -92,7 +92,8 @@
 
     static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
 
-    public static final boolean DEBUG = false;
+    // True to enable logging of matches and replacements.
+    private static volatile boolean debugLogging = false;
 
     /**
      * Debugging output can be synchronized with logging of RMI actions.
@@ -100,8 +101,8 @@
      * @param format a printf format
      * @param args   any args
      */
-    private static void DEBUG(String format, Object... args) {
-        if (DEBUG) {
+    public static void DEBUG(String format, Object... args) {
+        if (debugLogging) {
             System.err.printf(format, args);
         }
     }
@@ -117,6 +118,17 @@
     }
 
     /**
+     * Set debug to true to generate logging output of matches and substitutions.
+     * @param debug {@code true} to generate logging output
+     * @return the previous value
+     */
+    public static boolean setDebug(boolean debug) {
+        boolean oldDebug = debugLogging;
+        debugLogging = debug;
+        return oldDebug;
+    }
+
+    /**
      * Set the match and replacement bytes, with an empty trigger.
      * The match and replacements are propagated to all existing sockets.
      *
--- a/test/jdk/java/security/testlibrary/Proc.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/test/jdk/java/security/testlibrary/Proc.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, 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
@@ -25,6 +25,9 @@
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UncheckedIOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
@@ -110,6 +113,7 @@
     private List<String> args = new ArrayList<>();
     private Map<String,String> env = new HashMap<>();
     private Map<String,String> prop = new HashMap();
+    private Map<String,String> secprop = new HashMap();
     private boolean inheritIO = false;
     private boolean noDump = false;
 
@@ -176,6 +180,11 @@
         prop.put(a, b);
         return this;
     }
+    // Specifies a security property. Can be called multiple times.
+    public Proc secprop(String a, String b) {
+        secprop.put(a, b);
+        return this;
+    }
     // Inherit the value of a system property
     public Proc inheritProp(String k) {
         String v = System.getProperty(k);
@@ -282,6 +291,17 @@
             cmd.add(cp.stream().collect(Collectors.joining(File.pathSeparator)));
         }
 
+        if (!secprop.isEmpty()) {
+            Path p = Path.of(getId("security"));
+            try (OutputStream fos = Files.newOutputStream(p);
+                 PrintStream ps = new PrintStream(fos)) {
+                secprop.forEach((k,v) -> ps.println(k + "=" + v));
+            } catch (IOException e) {
+                throw new UncheckedIOException(e);
+            }
+            prop.put("java.security.properties", p.toString());
+        }
+
         for (Entry<String,String> e: prop.entrySet()) {
             cmd.add("-D" + e.getKey() + "=" + e.getValue());
         }
@@ -380,6 +400,12 @@
         }
         return p.waitFor();
     }
+    // Wait for process end with expected exit code
+    public void waitFor(int expected) throws Exception {
+        if (p.waitFor() != expected) {
+            throw new RuntimeException("Exit code not " + expected);
+        }
+    }
 
     // The following methods are used inside a proc
 
--- a/test/jdk/sun/security/util/FilePermCompat/Flag.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/test/jdk/sun/security/util/FilePermCompat/Flag.java	Tue Oct 15 21:33:54 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, 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
@@ -23,22 +23,84 @@
 
 /*
  * @test
- * @bug 8164705
+ * @bug 8164705 8209901
+ * @library /test/jdk/java/security/testlibrary
+ * @modules java.base/jdk.internal.misc
  * @summary check jdk.filepermission.canonicalize
- * @run main/othervm/policy=flag.policy
-  *     -Djdk.io.permissionsUseCanonicalPath=true Flag true true
- * @run main/othervm/policy=flag.policy
-  *     -Djdk.io.permissionsUseCanonicalPath=false Flag false true
- * @run main/othervm/policy=flag.policy Flag false true
  */
 
 import java.io.File;
 import java.io.FilePermission;
 import java.lang.*;
+import java.nio.file.Path;
 
 public class Flag {
     public static void main(String[] args) throws Exception {
 
+        if (args.length == 0) {
+            String policy = Path.of(
+                    System.getProperty("test.src"), "flag.policy").toString();
+
+            // effectively true
+            Proc.create("Flag")
+                    .prop("java.security.manager", "")
+                    .prop("java.security.policy", policy)
+                    .prop("jdk.io.permissionsUseCanonicalPath", "true")
+                    .args("run", "true", "true")
+                    .start()
+                    .waitFor(0);
+            Proc.create("Flag")
+                    .prop("java.security.manager", "")
+                    .prop("java.security.policy", policy)
+                    .secprop("jdk.io.permissionsUseCanonicalPath", "true")
+                    .args("run", "true", "true")
+                    .start()
+                    .waitFor(0);
+            Proc.create("Flag")
+                    .prop("java.security.manager", "")
+                    .prop("java.security.policy", policy)
+                    .secprop("jdk.io.permissionsUseCanonicalPath", "false")
+                    .prop("jdk.io.permissionsUseCanonicalPath", "true")
+                    .args("run", "true", "true")
+                    .start()
+                    .waitFor(0);
+
+            // effectively false
+            Proc.create("Flag")
+                    .prop("java.security.manager", "")
+                    .prop("java.security.policy", policy)
+                    .prop("jdk.io.permissionsUseCanonicalPath", "false")
+                    .args("run", "false", "true")
+                    .start()
+                    .waitFor(0);
+            Proc.create("Flag")
+                    .prop("java.security.manager", "")
+                    .prop("java.security.policy", policy)
+                    .secprop("jdk.io.permissionsUseCanonicalPath", "false")
+                    .args("run", "false", "true")
+                    .start()
+                    .waitFor(0);
+            Proc.create("Flag")
+                    .prop("java.security.manager", "")
+                    .prop("java.security.policy", policy)
+                    .secprop("jdk.io.permissionsUseCanonicalPath", "true")
+                    .prop("jdk.io.permissionsUseCanonicalPath", "false")
+                    .args("run", "false", "true")
+                    .start()
+                    .waitFor(0);
+            Proc.create("Flag")
+                    .prop("java.security.manager", "")
+                    .prop("java.security.policy", policy)
+                    .args("run", "false", "true")
+                    .start()
+                    .waitFor(0);
+        } else {
+            run(args);
+        }
+    }
+
+    static void run(String[] args) throws Exception {
+
         boolean test1;
         boolean test2;
 
@@ -55,8 +117,8 @@
             test2 = false;
         }
 
-        if (test1 != Boolean.parseBoolean(args[0]) ||
-                test2 != Boolean.parseBoolean(args[1])) {
+        if (test1 != Boolean.parseBoolean(args[1]) ||
+                test2 != Boolean.parseBoolean(args[2])) {
             throw new Exception("Test failed: " + test1 + " " + test2);
         }
     }
--- a/test/langtools/jdk/javadoc/tool/TestScriptInComment.java	Tue Oct 15 13:25:57 2019 -0700
+++ b/test/langtools/jdk/javadoc/tool/TestScriptInComment.java	Tue Oct 15 21:33:54 2019 +0000
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8138725
+ * @bug 8138725 8226765
  * @summary test --allow-script-in-comments
  * @modules jdk.javadoc/jdk.javadoc.internal.tool
  */
@@ -63,6 +63,10 @@
         WS("< script >#ALERT</script>", false, "-Xdoclint:none"), // script tag with invalid white space
         SP("<script src=\"file\"> #ALERT </script>", true), // script tag with an attribute
         ON("<a onclick='#ALERT'>x</a>", true), // event handler attribute
+        OME("<img alt='1' onmouseenter='#ALERT'>", true), // onmouseenter event handler attribute
+        OML("<img alt='1' onmouseleave='#ALERT'>", true), // onmouseleave event handler attribute
+        OFI("<a href='#' onfocusin='#ALERT'>x</a>", true), // onfocusin event handler attribute
+        OBE("<a onbogusevent='#ALERT'>x</a>", true), // bogus/future event handler attribute
         URI("<a href='javascript:#ALERT'>x</a>", true); // javascript URI
 
         /**