changeset 57714:c1d9b0adeafd

Merge
author jwilhelm
date Thu, 16 Jan 2020 04:09:50 +0100
parents f44806ce1cfe 7149d2c974ee
children 1922c31f1dcc
files .hgtags src/java.security.jgss/share/classes/sun/security/krb5/Checksum.java src/java.security.jgss/share/classes/sun/security/krb5/KrbTgsReq.java src/java.security.jgss/share/classes/sun/security/krb5/internal/PAForUserEnc.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java test/jdk/sun/security/krb5/auto/KDC.java test/jdk/sun/security/krb5/auto/SaslGSS.java
diffstat 102 files changed, 2025 insertions(+), 935 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu Jan 16 03:19:32 2020 +0100
+++ b/.hgtags	Thu Jan 16 04:09:50 2020 +0100
@@ -610,4 +610,5 @@
 bb0a7975b31ded63d594ee8dbfc4d4ead587f79b jdk-15+4
 decd3d2953b640f1043ee76953ff89238bff92e8 jdk-14+31
 b97c1773ccafae4a8c16cc6aedb10b2a4f9a07ed jdk-15+5
+2776da28515e087cc8849acf1e131a65ea7e77b6 jdk-14+32
 ef7d53b4fccd4a0501b17d974e84f37aa99fa813 jdk-15+6
--- a/src/hotspot/share/oops/klassVtable.cpp	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/hotspot/share/oops/klassVtable.cpp	Thu Jan 16 04:09:50 2020 +0100
@@ -291,23 +291,26 @@
                             int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) {
   InstanceKlass* superk = initialsuper;
   while (superk != NULL && superk->super() != NULL) {
-    InstanceKlass* supersuperklass = InstanceKlass::cast(superk->super());
-    klassVtable ssVtable = supersuperklass->vtable();
+    klassVtable ssVtable = (superk->super())->vtable();
     if (vtable_index < ssVtable.length()) {
       Method* super_method = ssVtable.method_at(vtable_index);
+      // get the class holding the matching method
+      // make sure you use that class for is_override
+      InstanceKlass* supermethodholder = super_method->method_holder();
 #ifndef PRODUCT
       Symbol* name= target_method()->name();
       Symbol* signature = target_method()->signature();
       assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch");
 #endif
-      if (supersuperklass->is_override(methodHandle(THREAD, super_method), target_loader, target_classname, THREAD)) {
+
+      if (supermethodholder->is_override(methodHandle(THREAD, super_method), target_loader, target_classname, THREAD)) {
         if (log_develop_is_enabled(Trace, vtables)) {
           ResourceMark rm(THREAD);
           LogTarget(Trace, vtables) lt;
           LogStream ls(lt);
           char* sig = target_method()->name_and_sig_as_C_string();
           ls.print("transitive overriding superclass %s with %s index %d, original flags: ",
-                       supersuperklass->internal_name(),
+                       supermethodholder->internal_name(),
                        sig, vtable_index);
           super_method->print_linkage_flags(&ls);
           ls.print("overriders flags: ");
--- a/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java	Thu Jan 16 04:09:50 2020 +0100
@@ -26,6 +26,7 @@
 package com.sun.crypto.provider;
 
 import sun.security.util.Debug;
+import sun.security.util.IOUtils;
 
 import java.io.*;
 import java.util.*;
@@ -73,7 +74,7 @@
     private static final class PrivateKeyEntry {
         Date date; // the creation date of this entry
         byte[] protectedKey;
-        Certificate chain[];
+        Certificate[] chain;
     };
 
     // Secret key
@@ -742,23 +743,11 @@
                         entry.date = new Date(dis.readLong());
 
                         // read the private key
-                        try {
-                            entry.protectedKey = new byte[dis.readInt()];
-                        } catch (OutOfMemoryError e) {
-                            throw new IOException("Keysize too big");
-                        }
-                        dis.readFully(entry.protectedKey);
+                        entry.protectedKey = IOUtils.readExactlyNBytes(dis, dis.readInt());
 
                         // read the certificate chain
                         int numOfCerts = dis.readInt();
-                        try {
-                            if (numOfCerts > 0) {
-                                entry.chain = new Certificate[numOfCerts];
-                            }
-                        } catch (OutOfMemoryError e) {
-                            throw new IOException("Too many certificates in "
-                                                  + "chain");
-                        }
+                        List<Certificate> tmpCerts = new ArrayList<>();
                         for (int j = 0; j < numOfCerts; j++) {
                             if (xVersion == 2) {
                                 // read the certificate type, and instantiate a
@@ -766,27 +755,24 @@
                                 // existing factory if possible)
                                 String certType = dis.readUTF();
                                 if (cfs.containsKey(certType)) {
-                                // reuse certificate factory
+                                    // reuse certificate factory
                                     cf = cfs.get(certType);
                                 } else {
-                                // create new certificate factory
+                                    // create new certificate factory
                                     cf = CertificateFactory.getInstance(
                                         certType);
-                                // store the certificate factory so we can
-                                // reuse it later
+                                    // store the certificate factory so we can
+                                    // reuse it later
                                     cfs.put(certType, cf);
                                 }
                             }
                             // instantiate the certificate
-                            try {
-                                encoded = new byte[dis.readInt()];
-                            } catch (OutOfMemoryError e) {
-                                throw new IOException("Certificate too big");
-                            }
-                            dis.readFully(encoded);
+                            encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
                             bais = new ByteArrayInputStream(encoded);
-                            entry.chain[j] = cf.generateCertificate(bais);
+                            tmpCerts.add(cf.generateCertificate(bais));
                         }
+                        entry.chain = tmpCerts.toArray(
+                                new Certificate[numOfCerts]);
 
                         // Add the entry to the list
                         entries.put(alias, entry);
@@ -818,12 +804,7 @@
                                 cfs.put(certType, cf);
                             }
                         }
-                        try {
-                            encoded = new byte[dis.readInt()];
-                        } catch (OutOfMemoryError e) {
-                            throw new IOException("Certificate too big");
-                        }
-                        dis.readFully(encoded);
+                        encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
                         bais = new ByteArrayInputStream(encoded);
                         entry.cert = cf.generateCertificate(bais);
 
@@ -882,18 +863,14 @@
                  * with
                  */
                 if (password != null) {
-                    byte computed[], actual[];
-                    computed = md.digest();
-                    actual = new byte[computed.length];
-                    dis.readFully(actual);
-                    for (int i = 0; i < computed.length; i++) {
-                        if (computed[i] != actual[i]) {
-                            throw new IOException(
+                    byte[] computed = md.digest();
+                    byte[] actual = IOUtils.readExactlyNBytes(dis, computed.length);
+                    if (!MessageDigest.isEqual(computed, actual)) {
+                        throw new IOException(
                                 "Keystore was tampered with, or "
                                         + "password was incorrect",
-                                    new UnrecoverableKeyException(
-                                            "Password verification failed"));
-                        }
+                                new UnrecoverableKeyException(
+                                        "Password verification failed"));
                     }
                 }
             }  finally {
--- a/src/java.base/share/classes/java/io/ObjectInputFilter.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/java/io/ObjectInputFilter.java	Thu Jan 16 04:09:50 2020 +0100
@@ -35,6 +35,7 @@
 import java.util.function.Function;
 
 import jdk.internal.access.SharedSecrets;
+import jdk.internal.util.StaticProperty;
 
 /**
  * Filter classes, array lengths, and graph metrics during deserialization.
@@ -205,15 +206,17 @@
      * <p>
      * The filter is configured during the initialization of the {@code ObjectInputFilter.Config}
      * class. For example, by calling {@link #getSerialFilter() Config.getSerialFilter}.
-     * If the system property {@systemProperty jdk.serialFilter} is defined, it is used
-     * to configure the filter.
-     * If the system property is not defined, and the {@link java.security.Security}
-     * property {@code jdk.serialFilter} is defined then it is used to configure the filter.
-     * Otherwise, the filter is not configured during initialization.
+     * If the system property {@systemProperty jdk.serialFilter} is defined on the command line,
+     * it is used to configure the filter.
+     * If the system property is not defined on the command line, and the
+     * {@link java.security.Security} property {@code jdk.serialFilter} is defined
+     * then it is used to configure the filter.
+     * Otherwise, the filter is not configured during initialization and
+     * can be set with {@link #setSerialFilter(ObjectInputFilter) Config.setSerialFilter}.
+     * Setting the {@code jdk.serialFilter} with {@link System#setProperty(String, String)
+     * System.setProperty} <em>does not set the filter</em>.
      * The syntax for each property is the same as for the
      * {@link #createFilter(String) createFilter} method.
-     * If a filter is not configured, it can be set with
-     * {@link #setSerialFilter(ObjectInputFilter) Config.setSerialFilter}.
      *
      * @since 9
      */
@@ -256,7 +259,7 @@
         static {
             configuredFilter = AccessController
                     .doPrivileged((PrivilegedAction<ObjectInputFilter>) () -> {
-                        String props = System.getProperty(SERIAL_FILTER_PROPNAME);
+                        String props = StaticProperty.jdkSerialFilter();
                         if (props == null) {
                             props = Security.getProperty(SERIAL_FILTER_PROPNAME);
                         }
--- a/src/java.base/share/classes/java/io/ObjectInputStream.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/java/io/ObjectInputStream.java	Thu Jan 16 04:09:50 2020 +0100
@@ -453,16 +453,50 @@
      * @throws  IOException Any of the usual Input/Output related exceptions.
      */
     public final Object readObject()
+        throws IOException, ClassNotFoundException {
+        return readObject(Object.class);
+    }
+
+    /**
+     * Reads a String and only a string.
+     *
+     * @return  the String read
+     * @throws  EOFException If end of file is reached.
+     * @throws  IOException If other I/O error has occurred.
+     */
+    private String readString() throws IOException {
+        try {
+            return (String) readObject(String.class);
+        } catch (ClassNotFoundException cnf) {
+            throw new IllegalStateException(cnf);
+        }
+    }
+
+    /**
+     * Internal method to read an object from the ObjectInputStream of the expected type.
+     * Called only from {@code readObject()} and {@code readString()}.
+     * Only {@code Object.class} and {@code String.class} are supported.
+     *
+     * @param type the type expected; either Object.class or String.class
+     * @return an object of the type
+     * @throws  IOException Any of the usual Input/Output related exceptions.
+     * @throws  ClassNotFoundException Class of a serialized object cannot be
+     *          found.
+     */
+    private final Object readObject(Class<?> type)
         throws IOException, ClassNotFoundException
     {
         if (enableOverride) {
             return readObjectOverride();
         }
 
+        if (! (type == Object.class || type == String.class))
+            throw new AssertionError("internal error");
+
         // if nested read, passHandle contains handle of enclosing object
         int outerHandle = passHandle;
         try {
-            Object obj = readObject0(false);
+            Object obj = readObject0(type, false);
             handles.markDependency(outerHandle, passHandle);
             ClassNotFoundException ex = handles.lookupException(passHandle);
             if (ex != null) {
@@ -557,7 +591,7 @@
         // if nested read, passHandle contains handle of enclosing object
         int outerHandle = passHandle;
         try {
-            Object obj = readObject0(true);
+            Object obj = readObject0(Object.class, true);
             handles.markDependency(outerHandle, passHandle);
             ClassNotFoundException ex = handles.lookupException(passHandle);
             if (ex != null) {
@@ -1577,8 +1611,10 @@
 
     /**
      * Underlying readObject implementation.
+     * @param type a type expected to be deserialized; non-null
+     * @param unshared true if the object can not be a reference to a shared object, otherwise false
      */
-    private Object readObject0(boolean unshared) throws IOException {
+    private Object readObject0(Class<?> type, boolean unshared) throws IOException {
         boolean oldMode = bin.getBlockDataMode();
         if (oldMode) {
             int remain = bin.currentBlockRemaining();
@@ -1610,13 +1646,20 @@
                     return readNull();
 
                 case TC_REFERENCE:
-                    return readHandle(unshared);
+                    // check the type of the existing object
+                    return type.cast(readHandle(unshared));
 
                 case TC_CLASS:
+                    if (type == String.class) {
+                        throw new ClassCastException("Cannot cast a class to java.lang.String");
+                    }
                     return readClass(unshared);
 
                 case TC_CLASSDESC:
                 case TC_PROXYCLASSDESC:
+                    if (type == String.class) {
+                        throw new ClassCastException("Cannot cast a class to java.lang.String");
+                    }
                     return readClassDesc(unshared);
 
                 case TC_STRING:
@@ -1624,15 +1667,27 @@
                     return checkResolve(readString(unshared));
 
                 case TC_ARRAY:
+                    if (type == String.class) {
+                        throw new ClassCastException("Cannot cast an array to java.lang.String");
+                    }
                     return checkResolve(readArray(unshared));
 
                 case TC_ENUM:
+                    if (type == String.class) {
+                        throw new ClassCastException("Cannot cast an enum to java.lang.String");
+                    }
                     return checkResolve(readEnum(unshared));
 
                 case TC_OBJECT:
+                    if (type == String.class) {
+                        throw new ClassCastException("Cannot cast an object to java.lang.String");
+                    }
                     return checkResolve(readOrdinaryObject(unshared));
 
                 case TC_EXCEPTION:
+                    if (type == String.class) {
+                        throw new ClassCastException("Cannot cast an exception to java.lang.String");
+                    }
                     IOException ex = readFatalException();
                     throw new WriteAbortedException("writing aborted", ex);
 
@@ -2004,7 +2059,7 @@
 
         if (ccl == null) {
             for (int i = 0; i < len; i++) {
-                readObject0(false);
+                readObject0(Object.class, false);
             }
         } else if (ccl.isPrimitive()) {
             if (ccl == Integer.TYPE) {
@@ -2029,7 +2084,7 @@
         } else {
             Object[] oa = (Object[]) array;
             for (int i = 0; i < len; i++) {
-                oa[i] = readObject0(false);
+                oa[i] = readObject0(Object.class, false);
                 handles.markDependency(arrayHandle, passHandle);
             }
         }
@@ -2393,7 +2448,7 @@
                     return;
 
                 default:
-                    readObject0(false);
+                    readObject0(Object.class, false);
                     break;
             }
         }
@@ -2438,7 +2493,7 @@
             int numPrimFields = fields.length - objVals.length;
             for (int i = 0; i < objVals.length; i++) {
                 ObjectStreamField f = fields[numPrimFields + i];
-                objVals[i] = readObject0(f.isUnshared());
+                objVals[i] = readObject0(Object.class, f.isUnshared());
                 if (f.getField() != null) {
                     handles.markDependency(objHandle, passHandle);
                 }
@@ -2479,7 +2534,7 @@
             throw new InternalError();
         }
         clear();
-        return (IOException) readObject0(false);
+        return (IOException) readObject0(Object.class, false);
     }
 
     /**
@@ -2601,7 +2656,7 @@
             int numPrimFields = fields.length - objVals.length;
             for (int i = 0; i < objVals.length; i++) {
                 objVals[i] =
-                    readObject0(fields[numPrimFields + i].isUnshared());
+                    readObject0(Object.class, fields[numPrimFields + i].isUnshared());
                 objHandles[i] = passHandle;
             }
             passHandle = oldHandle;
@@ -4090,6 +4145,7 @@
 
     static {
         SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::checkArray);
+        SharedSecrets.setJavaObjectInputStreamReadString(ObjectInputStream::readString);
     }
 
 }
--- a/src/java.base/share/classes/java/math/BigDecimal.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/java/math/BigDecimal.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, 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
@@ -2119,7 +2119,7 @@
             // approximately a 15 digit approximation to the square
             // root, it is helpful to instead normalize this so that
             // the significand portion is to right of the decimal
-            // point by roughly (scale() - precision() +1).
+            // point by roughly (scale() - precision() + 1).
 
             // Now the precision / scale adjustment
             int scaleAdjust = 0;
@@ -2147,7 +2147,7 @@
             // than 15 digits were needed, it might be faster to do
             // the loop entirely in BigDecimal arithmetic.
             //
-            // (A double value might have as much many as 17 decimal
+            // (A double value might have as many as 17 decimal
             // digits of precision; it depends on the relative density
             // of binary and decimal numbers at different regions of
             // the number line.)
@@ -2171,7 +2171,25 @@
             if (originalPrecision == 0) {
                 targetPrecision = stripped.precision()/2 + 1;
             } else {
-                targetPrecision = originalPrecision;
+                /*
+                 * To avoid the need for post-Newton fix-up logic, in
+                 * the case of half-way rounding modes, double the
+                 * target precision so that the "2p + 2" property can
+                 * be relied on to accomplish the final rounding.
+                 */
+                switch (mc.getRoundingMode()) {
+                case HALF_UP:
+                case HALF_DOWN:
+                case HALF_EVEN:
+                    targetPrecision = 2 * originalPrecision;
+                    if (targetPrecision < 0) // Overflow
+                        targetPrecision = Integer.MAX_VALUE - 2;
+                    break;
+
+                default:
+                    targetPrecision = originalPrecision;
+                    break;
+                }
             }
 
             // When setting the precision to use inside the Newton
@@ -2199,33 +2217,81 @@
 
                 // If result*result != this numerically, the square
                 // root isn't exact
-                if (this.subtract(result.multiply(result)).compareTo(ZERO) != 0) {
+                if (this.subtract(result.square()).compareTo(ZERO) != 0) {
                     throw new ArithmeticException("Computed square root not exact.");
                 }
             } else {
                 result = approx.scaleByPowerOfTen(-scaleAdjust/2).round(mc);
+
+                switch (targetRm) {
+                case DOWN:
+                case FLOOR:
+                    // Check if too big
+                    if (result.square().compareTo(this) > 0) {
+                        BigDecimal ulp = result.ulp();
+                        // Adjust increment down in case of 1.0 = 10^0
+                        // since the next smaller number is only 1/10
+                        // as far way as the next larger at exponent
+                        // boundaries. Test approx and *not* result to
+                        // avoid having to detect an arbitrary power
+                        // of ten.
+                        if (approx.compareTo(ONE) == 0) {
+                            ulp = ulp.multiply(ONE_TENTH);
+                        }
+                        result = result.subtract(ulp);
+                    }
+                    break;
+
+                case UP:
+                case CEILING:
+                    // Check if too small
+                    if (result.square().compareTo(this) < 0) {
+                        result = result.add(result.ulp());
+                    }
+                    break;
+
+                default:
+                    // No additional work, rely on "2p + 2" property
+                    // for correct rounding. Alternatively, could
+                    // instead run the Newton iteration to around p
+                    // digits and then do tests and fix-ups on the
+                    // rounded value. One possible set of tests and
+                    // fix-ups is given in the Hull and Abrham paper;
+                    // however, additional half-way cases can occur
+                    // for BigDecimal given the more varied
+                    // combinations of input and output precisions
+                    // supported.
+                    break;
+                }
+
             }
 
+            // Test numerical properties at full precision before any
+            // scale adjustments.
+            assert squareRootResultAssertions(result, mc);
             if (result.scale() != preferredScale) {
                 // The preferred scale of an add is
                 // max(addend.scale(), augend.scale()). Therefore, if
                 // the scale of the result is first minimized using
                 // stripTrailingZeros(), adding a zero of the
-                // preferred scale rounding the correct precision will
-                // perform the proper scale vs precision tradeoffs.
+                // preferred scale rounding to the correct precision
+                // will perform the proper scale vs precision
+                // tradeoffs.
                 result = result.stripTrailingZeros().
                     add(zeroWithFinalPreferredScale,
                         new MathContext(originalPrecision, RoundingMode.UNNECESSARY));
             }
-            assert squareRootResultAssertions(result, mc);
             return result;
         } else {
+            BigDecimal result = null;
             switch (signum) {
             case -1:
                 throw new ArithmeticException("Attempted square root " +
                                               "of negative BigDecimal");
             case 0:
-                return valueOf(0L, scale()/2);
+                result = valueOf(0L, scale()/2);
+                assert squareRootResultAssertions(result, mc);
+                return result;
 
             default:
                 throw new AssertionError("Bad value from signum");
@@ -2233,6 +2299,10 @@
         }
     }
 
+    private BigDecimal square() {
+        return this.multiply(this);
+    }
+
     private boolean isPowerOfTen() {
         return BigInteger.ONE.equals(this.unscaledValue());
     }
@@ -2241,10 +2311,16 @@
      * For nonzero values, check numerical correctness properties of
      * the computed result for the chosen rounding mode.
      *
-     * For the directed roundings, for DOWN and FLOOR, result^2 must
-     * be {@code <=} the input and (result+ulp)^2 must be {@code >} the
-     * input. Conversely, for UP and CEIL, result^2 must be {@code >=} the
-     * input and (result-ulp)^2 must be {@code <} the input.
+     * For the directed rounding modes:
+     *
+     * <ul>
+     *
+     * <li> For DOWN and FLOOR, result^2 must be {@code <=} the input
+     * and (result+ulp)^2 must be {@code >} the input.
+     *
+     * <li>Conversely, for UP and CEIL, result^2 must be {@code >=}
+     * the input and (result-ulp)^2 must be {@code <} the input.
+     * </ul>
      */
     private boolean squareRootResultAssertions(BigDecimal result, MathContext mc) {
         if (result.signum() == 0) {
@@ -2254,52 +2330,68 @@
             BigDecimal ulp = result.ulp();
             BigDecimal neighborUp   = result.add(ulp);
             // Make neighbor down accurate even for powers of ten
-            if (this.isPowerOfTen()) {
+            if (result.isPowerOfTen()) {
                 ulp = ulp.divide(TEN);
             }
             BigDecimal neighborDown = result.subtract(ulp);
 
             // Both the starting value and result should be nonzero and positive.
-            if (result.signum() != 1 ||
-                this.signum() != 1) {
-                return false;
-            }
+            assert (result.signum() == 1 &&
+                    this.signum() == 1) :
+                "Bad signum of this and/or its sqrt.";
 
             switch (rm) {
             case DOWN:
             case FLOOR:
-                return
-                    result.multiply(result).compareTo(this)         <= 0 &&
-                    neighborUp.multiply(neighborUp).compareTo(this) > 0;
+                assert
+                    result.square().compareTo(this)     <= 0 &&
+                    neighborUp.square().compareTo(this) > 0:
+                "Square of result out for bounds rounding " + rm;
+                return true;
 
             case UP:
             case CEILING:
-                return
-                    result.multiply(result).compareTo(this)             >= 0 &&
-                    neighborDown.multiply(neighborDown).compareTo(this) < 0;
+                assert
+                    result.square().compareTo(this)       >= 0 &&
+                    neighborDown.square().compareTo(this) < 0:
+                "Square of result out for bounds rounding " + rm;
+                return true;
+
 
             case HALF_DOWN:
             case HALF_EVEN:
             case HALF_UP:
-                BigDecimal err = result.multiply(result).subtract(this).abs();
-                BigDecimal errUp = neighborUp.multiply(neighborUp).subtract(this);
-                BigDecimal errDown =  this.subtract(neighborDown.multiply(neighborDown));
+                BigDecimal err = result.square().subtract(this).abs();
+                BigDecimal errUp = neighborUp.square().subtract(this);
+                BigDecimal errDown =  this.subtract(neighborDown.square());
                 // All error values should be positive so don't need to
                 // compare absolute values.
 
                 int err_comp_errUp = err.compareTo(errUp);
                 int err_comp_errDown = err.compareTo(errDown);
 
-                return
+                assert
                     errUp.signum()   == 1 &&
-                    errDown.signum() == 1 &&
-
-                    err_comp_errUp   <= 0 &&
-                    err_comp_errDown <= 0 &&
-
+                    errDown.signum() == 1 :
+                "Errors of neighbors squared don't have correct signs";
+
+                // For breaking a half-way tie, the return value may
+                // have a larger error than one of the neighbors. For
+                // example, the square root of 2.25 to a precision of
+                // 1 digit is either 1 or 2 depending on how the exact
+                // value of 1.5 is rounded. If 2 is returned, it will
+                // have a larger rounding error than its neighbor 1.
+                assert
+                    err_comp_errUp   <= 0 ||
+                    err_comp_errDown <= 0 :
+                "Computed square root has larger error than neighbors for " + rm;
+
+                assert
                     ((err_comp_errUp   == 0 ) ? err_comp_errDown < 0 : true) &&
-                    ((err_comp_errDown == 0 ) ? err_comp_errUp   < 0 : true);
+                    ((err_comp_errDown == 0 ) ? err_comp_errUp   < 0 : true) :
+                        "Incorrect error relationships";
                 // && could check for digit conditions for ties too
+                return true;
 
             default: // Definition of UNNECESSARY already verified.
                 return true;
--- a/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Thu Jan 16 04:09:50 2020 +0100
@@ -97,7 +97,7 @@
         fd = new FileDescriptor();
         try {
             datagramSocketCreate();
-            SocketCleanable.register(fd);
+            SocketCleanable.register(fd, false);
         } catch (SocketException ioe) {
             ResourceManager.afterUdpClose();
             fd = null;
--- a/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/java/net/AbstractPlainSocketImpl.java	Thu Jan 16 04:09:50 2020 +0100
@@ -127,7 +127,7 @@
             fd = new FileDescriptor();
             try {
                 socketCreate(false);
-                SocketCleanable.register(fd);
+                SocketCleanable.register(fd, false);
             } catch (IOException ioe) {
                 ResourceManager.afterUdpClose();
                 fd = null;
@@ -136,7 +136,7 @@
         } else {
             fd = new FileDescriptor();
             socketCreate(true);
-            SocketCleanable.register(fd);
+            SocketCleanable.register(fd, true);
         }
     }
 
@@ -580,7 +580,7 @@
         } finally {
             releaseFD();
         }
-        SocketCleanable.register(si.fd);
+        SocketCleanable.register(si.fd, true);
     }
 
     /**
@@ -683,9 +683,6 @@
     protected void close() throws IOException {
         synchronized(fdLock) {
             if (fd != null) {
-                if (!stream) {
-                    ResourceManager.afterUdpClose();
-                }
                 if (fdUseCount == 0) {
                     if (closePending) {
                         return;
@@ -840,7 +837,13 @@
      */
     protected void socketClose() throws IOException {
         SocketCleanable.unregister(fd);
-        socketClose0(false);
+        try {
+            socketClose0(false);
+        } finally {
+            if (!stream) {
+                ResourceManager.afterUdpClose();
+            }
+        }
     }
 
     abstract void socketCreate(boolean stream) throws IOException;
--- a/src/java.base/share/classes/java/net/SocketCleanable.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/java/net/SocketCleanable.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 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
@@ -34,6 +34,7 @@
 import java.io.UncheckedIOException;
 import java.lang.ref.Cleaner;
 
+import sun.net.ResourceManager;
 
 /**
  * Cleanable for a socket/datagramsocket FileDescriptor when it becomes phantom reachable.
@@ -56,17 +57,22 @@
     // The raw fd to close
     private final int fd;
 
+    // true for socket, false for datagram socket
+    private final boolean stream;
+
     /**
      * Register a socket specific Cleanable with the FileDescriptor
      * if the FileDescriptor is non-null and the raw fd is != -1.
      *
-     * @param fdo the FileDescriptor; may be null
+     * @param fdo     the FileDescriptor; may be null
+     * @param stream  false for datagram socket
      */
-    static void register(FileDescriptor fdo) {
+    static void register(FileDescriptor fdo, boolean stream) {
         if (fdo != null && fdo.valid()) {
             int fd = fdAccess.get(fdo);
             fdAccess.registerCleanup(fdo,
-                    new SocketCleanable(fdo, CleanerFactory.cleaner(), fd));
+                    new SocketCleanable(fdo, CleanerFactory.cleaner(),
+                                        fd, stream));
         }
     }
 
@@ -86,10 +92,13 @@
      * @param obj     the object to monitor
      * @param cleaner the cleaner
      * @param fd      file descriptor to close
+     * @param stream  false for datagram socket
      */
-    private SocketCleanable(FileDescriptor obj, Cleaner cleaner, int fd) {
+    private SocketCleanable(FileDescriptor obj, Cleaner cleaner,
+                            int fd, boolean stream) {
         super(obj, cleaner);
         this.fd = fd;
+        this.stream = stream;
     }
 
     /**
@@ -101,6 +110,10 @@
             cleanupClose0(fd);
         } catch (IOException ioe) {
             throw new UncheckedIOException("close", ioe);
+        } finally {
+            if (!stream) {
+                ResourceManager.afterUdpClose();
+            }
         }
     }
 }
--- a/src/java.base/share/classes/java/net/URL.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/java/net/URL.java	Thu Jan 16 04:09:50 2020 +0100
@@ -45,6 +45,7 @@
 
 import jdk.internal.access.JavaNetURLAccess;
 import jdk.internal.access.SharedSecrets;
+import jdk.internal.misc.VM;
 import sun.net.util.IPAddressUtil;
 import sun.security.util.SecurityConstants;
 import sun.security.action.GetPropertyAction;
@@ -1431,7 +1432,7 @@
         boolean checkedWithFactory = false;
         boolean overrideableProtocol = isOverrideable(protocol);
 
-        if (overrideableProtocol && jdk.internal.misc.VM.isBooted()) {
+        if (overrideableProtocol && VM.isBooted()) {
             // Use the factory (if any). Volatile read makes
             // URLStreamHandlerFactory appear fully initialized to current thread.
             fac = factory;
@@ -1665,7 +1666,9 @@
     }
 
     boolean isBuiltinStreamHandler(URLStreamHandler handler) {
-       return isBuiltinStreamHandler(handler.getClass().getName());
+       Class<?> handlerClass = handler.getClass();
+       return isBuiltinStreamHandler(handlerClass.getName())
+                 || VM.isSystemDomainLoader(handlerClass.getClassLoader());
     }
 
     private boolean isBuiltinStreamHandler(String handlerClassName) {
--- a/src/java.base/share/classes/java/nio/file/Files.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/java/nio/file/Files.java	Thu Jan 16 04:09:50 2020 +0100
@@ -3348,6 +3348,8 @@
         Objects.requireNonNull(cs);
 
         byte[] ba = readAllBytes(path);
+        if (path.getClass().getModule() != Object.class.getModule())
+            ba = ba.clone();
         return JLA.newStringNoRepl(ba, cs);
     }
 
--- a/src/java.base/share/classes/java/security/CodeSource.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/java/security/CodeSource.java	Thu Jan 16 04:09:50 2020 +0100
@@ -598,7 +598,7 @@
                 cfs.put(certType, cf);
             }
             // parse the certificate
-            byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
+            byte[] encoded = IOUtils.readExactlyNBytes(ois, ois.readInt());
             ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
             try {
                 certList.add(cf.generateCertificate(bais));
--- a/src/java.base/share/classes/java/security/UnresolvedPermission.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/java/security/UnresolvedPermission.java	Thu Jan 16 04:09:50 2020 +0100
@@ -594,7 +594,7 @@
                 cfs.put(certType, cf);
             }
             // parse the certificate
-            byte[] encoded = IOUtils.readNBytes(ois, ois.readInt());
+            byte[] encoded = IOUtils.readExactlyNBytes(ois, ois.readInt());
             ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
             try {
                 certList.add(cf.generateCertificate(bais));
--- a/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/java/security/cert/CertificateRevokedException.java	Thu Jan 16 04:09:50 2020 +0100
@@ -244,7 +244,7 @@
         for (int i = 0; i < size; i++) {
             String oid = (String) ois.readObject();
             boolean critical = ois.readBoolean();
-            byte[] extVal = IOUtils.readNBytes(ois, ois.readInt());
+            byte[] extVal = IOUtils.readExactlyNBytes(ois, ois.readInt());
             Extension ext = sun.security.x509.Extension.newExtension
                 (new ObjectIdentifier(oid), critical, extVal);
             extensions.put(oid, ext);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/access/JavaObjectInputStreamReadString.java	Thu Jan 16 04:09:50 2020 +0100
@@ -0,0 +1,38 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.access;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/**
+ * Interface to specify methods for accessing {@code ObjectInputStream}.
+ */
+@FunctionalInterface
+public interface JavaObjectInputStreamReadString {
+    String readString(ObjectInputStream ois) throws IOException;
+}
+
--- a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java	Thu Jan 16 04:09:50 2020 +0100
@@ -62,6 +62,7 @@
     private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
     private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
     private static JavaIORandomAccessFileAccess javaIORandomAccessFileAccess;
+    private static JavaObjectInputStreamReadString javaObjectInputStreamReadString;
     private static JavaObjectInputStreamAccess javaObjectInputStreamAccess;
     private static JavaObjectInputFilterAccess javaObjectInputFilterAccess;
     private static JavaNetInetAddressAccess javaNetInetAddressAccess;
@@ -283,6 +284,17 @@
         javaUtilResourceBundleAccess = access;
     }
 
+    public static JavaObjectInputStreamReadString getJavaObjectInputStreamReadString() {
+        if (javaObjectInputStreamReadString == null) {
+            unsafe.ensureClassInitialized(ObjectInputStream.class);
+        }
+        return javaObjectInputStreamReadString;
+    }
+
+    public static void setJavaObjectInputStreamReadString(JavaObjectInputStreamReadString access) {
+        javaObjectInputStreamReadString = access;
+    }
+
     public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() {
         if (javaObjectInputStreamAccess == null) {
             unsafe.ensureClassInitialized(ObjectInputStream.class);
--- a/src/java.base/share/classes/jdk/internal/util/StaticProperty.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/jdk/internal/util/StaticProperty.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 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,6 +42,7 @@
     private static final String USER_HOME = initProperty("user.home");
     private static final String USER_DIR  = initProperty("user.dir");
     private static final String USER_NAME = initProperty("user.name");
+    private static final String JDK_SERIAL_FILTER = System.getProperty("jdk.serialFilter");
 
     private StaticProperty() {}
 
@@ -104,4 +105,17 @@
     public static String userName() {
         return USER_NAME;
     }
+
+    /**
+     * Return the {@code jdk.serialFilter} system property.
+     *
+     * <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
+     * in this method. The caller of this method should take care to ensure
+     * that the returned property is not made accessible to untrusted code.</strong>
+     *
+     * @return the {@code user.name} system property
+     */
+    public static String jdkSerialFilter() {
+        return JDK_SERIAL_FILTER;
+    }
 }
--- a/src/java.base/share/classes/sun/security/provider/JavaKeyStore.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/sun/security/provider/JavaKeyStore.java	Thu Jan 16 04:09:50 2020 +0100
@@ -697,7 +697,7 @@
 
                     // Read the private key
                     entry.protectedPrivKey =
-                            IOUtils.readFully(dis, dis.readInt(), true);
+                            IOUtils.readExactlyNBytes(dis, dis.readInt());
 
                     // Read the certificate chain
                     int numOfCerts = dis.readInt();
@@ -722,7 +722,7 @@
                                 }
                             }
                             // instantiate the certificate
-                            encoded = IOUtils.readFully(dis, dis.readInt(), true);
+                            encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
                             bais = new ByteArrayInputStream(encoded);
                             certs.add(cf.generateCertificate(bais));
                             bais.close();
@@ -761,7 +761,7 @@
                             cfs.put(certType, cf);
                         }
                     }
-                    encoded = IOUtils.readFully(dis, dis.readInt(), true);
+                    encoded = IOUtils.readExactlyNBytes(dis, dis.readInt());
                     bais = new ByteArrayInputStream(encoded);
                     entry.cert = cf.generateCertificate(bais);
                     bais.close();
@@ -787,16 +787,13 @@
              */
             if (password != null) {
                 byte[] computed = md.digest();
-                byte[] actual = new byte[computed.length];
-                dis.readFully(actual);
-                for (int i = 0; i < computed.length; i++) {
-                    if (computed[i] != actual[i]) {
-                        Throwable t = new UnrecoverableKeyException
+                byte[] actual = IOUtils.readExactlyNBytes(dis, computed.length);
+                if (!MessageDigest.isEqual(computed, actual)) {
+                    Throwable t = new UnrecoverableKeyException
                             ("Password verification failed");
-                        throw (IOException)new IOException
+                    throw (IOException) new IOException
                             ("Keystore was tampered with, or "
-                            + "password was incorrect").initCause(t);
-                    }
+                                    + "password was incorrect").initCause(t);
                 }
             }
         }
--- a/src/java.base/share/classes/sun/security/ssl/Alert.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/sun/security/ssl/Alert.java	Thu Jan 16 04:09:50 2020 +0100
@@ -271,8 +271,14 @@
                                     ClientAuthType.CLIENT_AUTH_REQUESTED)) {
                         throw tc.fatal(Alert.HANDSHAKE_FAILURE,
                             "received handshake warning: " + alert.description);
-                    }  // Otherwise, ignore the warning
-                }   // Otherwise, ignore the warning.
+                    } else {
+                        // Otherwise ignore the warning but remove the
+                        // CertificateVerify handshake consumer so the state
+                        // machine doesn't expect it.
+                        tc.handshakeContext.handshakeConsumers.remove(
+                                SSLHandshake.CERTIFICATE_VERIFY.id);
+                    }
+                }  // Otherwise, ignore the warning
             } else {    // fatal or unknown
                 String diagnostic;
                 if (alert == null) {
--- a/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java	Thu Jan 16 04:09:50 2020 +0100
@@ -371,6 +371,10 @@
                 T12CertificateMessage certificateMessage )throws IOException {
             List<byte[]> encodedCerts = certificateMessage.encodedCertChain;
             if (encodedCerts == null || encodedCerts.isEmpty()) {
+                // For empty Certificate messages, we should not expect
+                // a CertificateVerify message to follow
+                shc.handshakeConsumers.remove(
+                        SSLHandshake.CERTIFICATE_VERIFY.id);
                 if (shc.sslConfig.clientAuthType !=
                         ClientAuthType.CLIENT_AUTH_REQUESTED) {
                     // unexpected or require client authentication
@@ -1165,6 +1169,10 @@
                 T13CertificateMessage certificateMessage )throws IOException {
             if (certificateMessage.certEntries == null ||
                     certificateMessage.certEntries.isEmpty()) {
+                // For empty Certificate messages, we should not expect
+                // a CertificateVerify message to follow
+                shc.handshakeConsumers.remove(
+                        SSLHandshake.CERTIFICATE_VERIFY.id);
                 if (shc.sslConfig.clientAuthType == CLIENT_AUTH_REQUIRED) {
                     throw shc.conContext.fatal(Alert.BAD_CERTIFICATE,
                         "Empty client certificate chain");
--- a/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/sun/security/ssl/CertificateVerify.java	Thu Jan 16 04:09:50 2020 +0100
@@ -287,6 +287,17 @@
                 ByteBuffer message) throws IOException {
             // The consuming happens in server side only.
             ServerHandshakeContext shc = (ServerHandshakeContext)context;
+
+            // Clean up this consumer
+            shc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_VERIFY.id);
+
+            // Ensure that the CV message follows the CKE
+            if (shc.handshakeConsumers.containsKey(
+                    SSLHandshake.CLIENT_KEY_EXCHANGE.id)) {
+                throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
+                        "Unexpected CertificateVerify handshake message");
+            }
+
             S30CertificateVerifyMessage cvm =
                     new S30CertificateVerifyMessage(shc, message);
             if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
@@ -529,6 +540,17 @@
                 ByteBuffer message) throws IOException {
             // The consuming happens in server side only.
             ServerHandshakeContext shc = (ServerHandshakeContext)context;
+
+            // Clean up this consumer
+            shc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_VERIFY.id);
+
+            // Ensure that the CV message follows the CKE
+            if (shc.handshakeConsumers.containsKey(
+                    SSLHandshake.CLIENT_KEY_EXCHANGE.id)) {
+                throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
+                        "Unexpected CertificateVerify handshake message");
+            }
+
             T10CertificateVerifyMessage cvm =
                     new T10CertificateVerifyMessage(shc, message);
             if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
@@ -767,6 +789,17 @@
                 ByteBuffer message) throws IOException {
             // The consuming happens in server side only.
             ServerHandshakeContext shc = (ServerHandshakeContext)context;
+
+            // Clean up this consumer
+            shc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_VERIFY.id);
+
+            // Ensure that the CV message follows the CKE
+            if (shc.handshakeConsumers.containsKey(
+                    SSLHandshake.CLIENT_KEY_EXCHANGE.id)) {
+                throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
+                        "Unexpected CertificateVerify handshake message");
+            }
+
             T12CertificateVerifyMessage cvm =
                     new T12CertificateVerifyMessage(shc, message);
             if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
@@ -1120,6 +1153,10 @@
                 ByteBuffer message) throws IOException {
             // The producing happens in handshake context only.
             HandshakeContext hc = (HandshakeContext)context;
+
+            // Clean up this consumer
+            hc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_VERIFY.id);
+
             T13CertificateVerifyMessage cvm =
                     new T13CertificateVerifyMessage(hc, message);
             if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
--- a/src/java.base/share/classes/sun/security/ssl/ClientHello.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/sun/security/ssl/ClientHello.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1140,6 +1140,15 @@
             ServerHandshakeContext shc = (ServerHandshakeContext)context;
             ClientHelloMessage clientHello = (ClientHelloMessage)message;
 
+            // [RFC 8446] TLS 1.3 forbids renegotiation. If a server has
+            // negotiated TLS 1.3 and receives a ClientHello at any other
+            // time, it MUST terminate the connection with an
+            // "unexpected_message" alert.
+            if (shc.conContext.isNegotiated) {
+                throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
+                        "Received unexpected renegotiation handshake message");
+            }
+
             // The client may send a dummy change_cipher_spec record
             // immediately after the first ClientHello.
             shc.conContext.consumers.putIfAbsent(
--- a/src/java.base/share/classes/sun/security/ssl/Finished.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/sun/security/ssl/Finished.java	Thu Jan 16 04:09:50 2020 +0100
@@ -589,6 +589,16 @@
 
         private void onConsumeFinished(ServerHandshakeContext shc,
                 ByteBuffer message) throws IOException {
+            // Make sure that any expected CertificateVerify message
+            // has been received and processed.
+            if (!shc.isResumption) {
+                if (shc.handshakeConsumers.containsKey(
+                        SSLHandshake.CERTIFICATE_VERIFY.id)) {
+                    throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
+                            "Unexpected Finished handshake message");
+                }
+            }
+
             FinishedMessage fm = new FinishedMessage(shc, message);
             if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
                 SSLLogger.fine(
@@ -883,6 +893,16 @@
 
         private void onConsumeFinished(ClientHandshakeContext chc,
                 ByteBuffer message) throws IOException {
+            // Make sure that any expected CertificateVerify message
+            // has been received and processed.
+            if (!chc.isResumption) {
+                if (chc.handshakeConsumers.containsKey(
+                        SSLHandshake.CERTIFICATE_VERIFY.id)) {
+                    throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
+                            "Unexpected Finished handshake message");
+                }
+            }
+
             FinishedMessage fm = new FinishedMessage(chc, message);
             if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
                 SSLLogger.fine(
@@ -1005,6 +1025,16 @@
 
         private void onConsumeFinished(ServerHandshakeContext shc,
                 ByteBuffer message) throws IOException {
+            // Make sure that any expected CertificateVerify message
+            // has been received and processed.
+            if (!shc.isResumption) {
+                if (shc.handshakeConsumers.containsKey(
+                        SSLHandshake.CERTIFICATE_VERIFY.id)) {
+                    throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,
+                            "Unexpected Finished handshake message");
+                }
+            }
+
             FinishedMessage fm = new FinishedMessage(shc, message);
             if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
                 SSLLogger.fine(
--- a/src/java.base/share/classes/sun/security/util/DerValue.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/sun/security/util/DerValue.java	Thu Jan 16 04:09:50 2020 +0100
@@ -395,7 +395,7 @@
         if (fullyBuffered && in.available() != length)
             throw new IOException("extra data given to DerValue constructor");
 
-        byte[] bytes = IOUtils.readFully(in, length, true);
+        byte[] bytes = IOUtils.readExactlyNBytes(in, length);
 
         buffer = new DerInputBuffer(bytes, allowBER);
         return new DerInputStream(buffer);
--- a/src/java.base/share/classes/sun/security/util/IOUtils.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/sun/security/util/IOUtils.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -32,68 +32,34 @@
 import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.Arrays;
 
 public class IOUtils {
 
     /**
-     * Read up to {@code length} of bytes from {@code in}
-     * until EOF is detected.
+     * Read exactly {@code length} of bytes from {@code in}.
+     *
+     * <p> Note that this method is safe to be called with unknown large
+     * {@code length} argument. The memory used is proportional to the
+     * actual bytes available. An exception is thrown if there are not
+     * enough bytes in the stream.
+     *
      * @param is input stream, must not be null
      * @param length number of bytes to read
-     * @param readAll if true, an EOFException will be thrown if not enough
-     *        bytes are read.
      * @return bytes read
-     * @throws IOException Any IO error or a premature EOF is detected
+     * @throws EOFException if there are not enough bytes in the stream
+     * @throws IOException if an I/O error occurs or {@code length} is negative
+     * @throws OutOfMemoryError if an array of the required size cannot be
+     *         allocated.
      */
-    public static byte[] readFully(InputStream is, int length, boolean readAll)
+    public static byte[] readExactlyNBytes(InputStream is, int length)
             throws IOException {
         if (length < 0) {
-            throw new IOException("Invalid length");
-        }
-        byte[] output = {};
-        int pos = 0;
-        while (pos < length) {
-            int bytesToRead;
-            if (pos >= output.length) { // Only expand when there's no room
-                bytesToRead = Math.min(length - pos, output.length + 1024);
-                if (output.length < pos + bytesToRead) {
-                    output = Arrays.copyOf(output, pos + bytesToRead);
-                }
-            } else {
-                bytesToRead = output.length - pos;
-            }
-            int cc = is.read(output, pos, bytesToRead);
-            if (cc < 0) {
-                if (readAll) {
-                    throw new EOFException("Detect premature EOF");
-                } else {
-                    if (output.length != pos) {
-                        output = Arrays.copyOf(output, pos);
-                    }
-                    break;
-                }
-            }
-            pos += cc;
-        }
-        return output;
-    }
-
-    /**
-     * Read {@code length} of bytes from {@code in}. An exception is
-     * thrown if there are not enough bytes in the stream.
-     *
-     * @param is input stream, must not be null
-     * @param length number of bytes to read, must not be negative
-     * @return bytes read
-     * @throws IOException if any IO error or a premature EOF is detected, or
-     *      if {@code length} is negative since this length is usually also
-     *      read from {@code is}.
-     */
-    public static byte[] readNBytes(InputStream is, int length) throws IOException {
-        if (length < 0) {
             throw new IOException("length cannot be negative: " + length);
         }
-        return readFully(is, length, true);
+        byte[] data = is.readNBytes(length);
+        if (data.length < length) {
+            throw new EOFException();
+        }
+        return data;
     }
 }
--- a/src/java.base/share/classes/sun/security/validator/PKIXValidator.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/sun/security/validator/PKIXValidator.java	Thu Jan 16 04:09:50 2020 +0100
@@ -32,6 +32,7 @@
 
 import javax.security.auth.x500.X500Principal;
 import sun.security.action.GetBooleanAction;
+import sun.security.action.GetPropertyAction;
 import sun.security.provider.certpath.AlgorithmChecker;
 import sun.security.provider.certpath.PKIXExtendedParameters;
 
@@ -60,6 +61,18 @@
     private static final boolean checkTLSRevocation = GetBooleanAction
             .privilegedGetProperty("com.sun.net.ssl.checkRevocation");
 
+    /**
+     * System property that if set (or set to "true"), allows trust anchor
+     * certificates to be used if they do not have the proper CA extensions.
+     * Set to false if prop is not set, or set to any other value.
+     */
+    private static final boolean ALLOW_NON_CA_ANCHOR = allowNonCaAnchor();
+    private static boolean allowNonCaAnchor() {
+        String prop = GetPropertyAction
+            .privilegedGetProperty("jdk.security.allowNonCaAnchor");
+        return prop != null && (prop.isEmpty() || prop.equalsIgnoreCase("true"));
+    }
+
     private final Set<X509Certificate> trustedCerts;
     private final PKIXBuilderParameters parameterTemplate;
     private int certPathLength = -1;
@@ -195,6 +208,7 @@
                 ("null or zero-length certificate chain");
         }
 
+
         // Use PKIXExtendedParameters for timestamp and variant additions
         PKIXBuilderParameters pkixParameters = null;
         try {
@@ -224,28 +238,30 @@
         for (int i = 0; i < chain.length; i++) {
             X509Certificate cert = chain[i];
             X500Principal dn = cert.getSubjectX500Principal();
-            if (i != 0 && !dn.equals(prevIssuer)) {
-                // chain is not ordered correctly, call builder instead
-                return doBuild(chain, otherCerts, pkixParameters);
-            }
 
-            // Check if chain[i] is already trusted. It may be inside
-            // trustedCerts, or has the same dn and public key as a cert
-            // inside trustedCerts. The latter happens when a CA has
-            // updated its cert with a stronger signature algorithm in JRE
-            // but the weak one is still in circulation.
-
-            if (trustedCerts.contains(cert) ||          // trusted cert
-                    (trustedSubjects.containsKey(dn) && // replacing ...
-                     trustedSubjects.get(dn).contains(  // ... weak cert
-                        cert.getPublicKey()))) {
-                if (i == 0) {
+            if (i == 0) {
+                if (trustedCerts.contains(cert)) {
                     return new X509Certificate[] {chain[0]};
                 }
-                // Remove and call validator on partial chain [0 .. i-1]
-                X509Certificate[] newChain = new X509Certificate[i];
-                System.arraycopy(chain, 0, newChain, 0, i);
-                return doValidate(newChain, pkixParameters);
+            } else {
+                if (!dn.equals(prevIssuer)) {
+                    // chain is not ordered correctly, call builder instead
+                    return doBuild(chain, otherCerts, pkixParameters);
+                }
+                // Check if chain[i] is already trusted. It may be inside
+                // trustedCerts, or has the same dn and public key as a cert
+                // inside trustedCerts. The latter happens when a CA has
+                // updated its cert with a stronger signature algorithm in JRE
+                // but the weak one is still in circulation.
+                if (trustedCerts.contains(cert) ||          // trusted cert
+                        (trustedSubjects.containsKey(dn) && // replacing ...
+                         trustedSubjects.get(dn).contains(  // ... weak cert
+                            cert.getPublicKey()))) {
+                    // Remove and call validator on partial chain [0 .. i-1]
+                    X509Certificate[] newChain = new X509Certificate[i];
+                    System.arraycopy(chain, 0, newChain, 0, i);
+                    return doValidate(newChain, pkixParameters);
+                }
             }
             prevIssuer = cert.getIssuerX500Principal();
         }
@@ -308,15 +324,18 @@
 
     private static X509Certificate[] toArray(CertPath path, TrustAnchor anchor)
             throws CertificateException {
-        List<? extends java.security.cert.Certificate> list =
-                                                path.getCertificates();
-        X509Certificate[] chain = new X509Certificate[list.size() + 1];
-        list.toArray(chain);
         X509Certificate trustedCert = anchor.getTrustedCert();
         if (trustedCert == null) {
             throw new ValidatorException
                 ("TrustAnchor must be specified as certificate");
         }
+
+        verifyTrustAnchor(trustedCert);
+
+        List<? extends java.security.cert.Certificate> list =
+                                                path.getCertificates();
+        X509Certificate[] chain = new X509Certificate[list.size() + 1];
+        list.toArray(chain);
         chain[chain.length - 1] = trustedCert;
         return chain;
     }
@@ -351,6 +370,41 @@
         }
     }
 
+    /**
+     * Verify that a trust anchor certificate is a CA certificate.
+     */
+    private static void verifyTrustAnchor(X509Certificate trustedCert)
+        throws ValidatorException {
+
+        // skip check if jdk.security.allowNonCAAnchor system property is set
+        if (ALLOW_NON_CA_ANCHOR) {
+            return;
+        }
+
+        // allow v1 trust anchor certificates
+        if (trustedCert.getVersion() < 3) {
+            return;
+        }
+
+        // check that the BasicConstraints cA field is not set to false
+        if (trustedCert.getBasicConstraints() == -1) {
+            throw new ValidatorException
+                ("TrustAnchor with subject \"" +
+                 trustedCert.getSubjectX500Principal() +
+                 "\" is not a CA certificate");
+        }
+
+        // check that the KeyUsage extension, if included, asserts the
+        // keyCertSign bit
+        boolean[] keyUsageBits = trustedCert.getKeyUsage();
+        if (keyUsageBits != null && !keyUsageBits[5]) {
+            throw new ValidatorException
+                ("TrustAnchor with subject \"" +
+                 trustedCert.getSubjectX500Principal() +
+                 "\" does not have keyCertSign bit set in KeyUsage extension");
+        }
+    }
+
     private X509Certificate[] doBuild(X509Certificate[] chain,
         Collection<X509Certificate> otherCerts,
         PKIXBuilderParameters params) throws CertificateException {
--- a/src/java.base/share/classes/sun/security/x509/AVA.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/sun/security/x509/AVA.java	Thu Jan 16 04:09:50 2020 +0100
@@ -599,7 +599,7 @@
         if (derval.tag != DerValue.tag_Sequence) {
             throw new IOException("AVA not a sequence");
         }
-        oid = X500Name.intern(derval.data.getOID());
+        oid = derval.data.getOID();
         value = derval.data.getDerValue();
 
         if (derval.data.available() != 0) {
--- a/src/java.base/share/classes/sun/security/x509/X500Name.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/share/classes/sun/security/x509/X500Name.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, 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
@@ -1098,18 +1098,6 @@
     /****************************************************************/
 
     /*
-     * Maybe return a preallocated OID, to reduce storage costs
-     * and speed recognition of common X.500 attributes.
-     */
-    static ObjectIdentifier intern(ObjectIdentifier oid) {
-        ObjectIdentifier interned = internedOIDs.putIfAbsent(oid, oid);
-        return (interned == null) ? oid : interned;
-    }
-
-    private static final Map<ObjectIdentifier,ObjectIdentifier> internedOIDs
-                        = new HashMap<ObjectIdentifier,ObjectIdentifier>();
-
-    /*
      * Selected OIDs from X.520
      * Includes all those specified in RFC 5280 as MUST or SHOULD
      * be recognized
@@ -1136,92 +1124,82 @@
         { 0, 9, 2342, 19200300, 100, 1, 1 };
 
 
-    public static final ObjectIdentifier commonName_oid;
-    public static final ObjectIdentifier countryName_oid;
-    public static final ObjectIdentifier localityName_oid;
-    public static final ObjectIdentifier orgName_oid;
-    public static final ObjectIdentifier orgUnitName_oid;
-    public static final ObjectIdentifier stateName_oid;
-    public static final ObjectIdentifier streetAddress_oid;
-    public static final ObjectIdentifier title_oid;
-    public static final ObjectIdentifier DNQUALIFIER_OID;
-    public static final ObjectIdentifier SURNAME_OID;
-    public static final ObjectIdentifier GIVENNAME_OID;
-    public static final ObjectIdentifier INITIALS_OID;
-    public static final ObjectIdentifier GENERATIONQUALIFIER_OID;
-    public static final ObjectIdentifier ipAddress_oid;
-    public static final ObjectIdentifier DOMAIN_COMPONENT_OID;
-    public static final ObjectIdentifier userid_oid;
-    public static final ObjectIdentifier SERIALNUMBER_OID;
+    // OID for the "CN=" attribute, denoting a person's common name.
+    public static final ObjectIdentifier commonName_oid =
+            ObjectIdentifier.newInternal(commonName_data);
 
-    static {
-    /** OID for the "CN=" attribute, denoting a person's common name. */
-        commonName_oid = intern(ObjectIdentifier.newInternal(commonName_data));
+    // OID for the "SERIALNUMBER=" attribute, denoting a serial number for.
+    // a name. Do not confuse with PKCS#9 issuerAndSerialNumber or the
+    // certificate serial number.
+    public static final ObjectIdentifier SERIALNUMBER_OID =
+            ObjectIdentifier.newInternal(SERIALNUMBER_DATA);
 
-    /** OID for the "SERIALNUMBER=" attribute, denoting a serial number for.
-        a name. Do not confuse with PKCS#9 issuerAndSerialNumber or the
-        certificate serial number. */
-        SERIALNUMBER_OID = intern(ObjectIdentifier.newInternal(SERIALNUMBER_DATA));
+    // OID for the "C=" attribute, denoting a country.
+    public static final ObjectIdentifier countryName_oid =
+            ObjectIdentifier.newInternal(countryName_data);
 
-    /** OID for the "C=" attribute, denoting a country. */
-        countryName_oid = intern(ObjectIdentifier.newInternal(countryName_data));
+    // OID for the "L=" attribute, denoting a locality (such as a city).
+    public static final ObjectIdentifier localityName_oid =
+            ObjectIdentifier.newInternal(localityName_data);
 
-    /** OID for the "L=" attribute, denoting a locality (such as a city) */
-        localityName_oid = intern(ObjectIdentifier.newInternal(localityName_data));
+    // OID for the "O=" attribute, denoting an organization name.
+    public static final ObjectIdentifier orgName_oid =
+            ObjectIdentifier.newInternal(orgName_data);
 
-    /** OID for the "O=" attribute, denoting an organization name */
-        orgName_oid = intern(ObjectIdentifier.newInternal(orgName_data));
+    // OID for the "OU=" attribute, denoting an organizational unit name.
+    public static final ObjectIdentifier orgUnitName_oid =
+            ObjectIdentifier.newInternal(orgUnitName_data);
 
-    /** OID for the "OU=" attribute, denoting an organizational unit name */
-        orgUnitName_oid = intern(ObjectIdentifier.newInternal(orgUnitName_data));
+    // OID for the "S=" attribute, denoting a state (such as Delaware).
+    public static final ObjectIdentifier stateName_oid =
+            ObjectIdentifier.newInternal(stateName_data);
 
-    /** OID for the "S=" attribute, denoting a state (such as Delaware) */
-        stateName_oid = intern(ObjectIdentifier.newInternal(stateName_data));
+    // OID for the "STREET=" attribute, denoting a street address.
+    public static final ObjectIdentifier streetAddress_oid =
+            ObjectIdentifier.newInternal(streetAddress_data);
 
-    /** OID for the "STREET=" attribute, denoting a street address. */
-        streetAddress_oid = intern(ObjectIdentifier.newInternal(streetAddress_data));
+    // OID for the "T=" attribute, denoting a person's title.
+    public static final ObjectIdentifier title_oid =
+            ObjectIdentifier.newInternal(title_data);
 
-    /** OID for the "T=" attribute, denoting a person's title. */
-        title_oid = intern(ObjectIdentifier.newInternal(title_data));
+    // OID for the "DNQUALIFIER=" or "DNQ=" attribute, denoting DN
+    // disambiguating information.
+    public static final ObjectIdentifier DNQUALIFIER_OID =
+            ObjectIdentifier.newInternal(DNQUALIFIER_DATA);
 
-    /** OID for the "DNQUALIFIER=" or "DNQ=" attribute, denoting DN
-        disambiguating information.*/
-        DNQUALIFIER_OID = intern(ObjectIdentifier.newInternal(DNQUALIFIER_DATA));
+    // OID for the "SURNAME=" attribute, denoting a person's surname.
+    public static final ObjectIdentifier SURNAME_OID =
+            ObjectIdentifier.newInternal(SURNAME_DATA);
 
-    /** OID for the "SURNAME=" attribute, denoting a person's surname.*/
-        SURNAME_OID = intern(ObjectIdentifier.newInternal(SURNAME_DATA));
+    // OID for the "GIVENNAME=" attribute, denoting a person's given name.
+    public static final ObjectIdentifier GIVENNAME_OID =
+            ObjectIdentifier.newInternal(GIVENNAME_DATA);
 
-    /** OID for the "GIVENNAME=" attribute, denoting a person's given name.*/
-        GIVENNAME_OID = intern(ObjectIdentifier.newInternal(GIVENNAME_DATA));
+    // OID for the "INITIALS=" attribute, denoting a person's initials.
+    public static final ObjectIdentifier INITIALS_OID =
+            ObjectIdentifier.newInternal(INITIALS_DATA);
 
-    /** OID for the "INITIALS=" attribute, denoting a person's initials.*/
-        INITIALS_OID = intern(ObjectIdentifier.newInternal(INITIALS_DATA));
+    // OID for the "GENERATION=" attribute, denoting Jr., II, etc.
+    public static final ObjectIdentifier GENERATIONQUALIFIER_OID =
+            ObjectIdentifier.newInternal(GENERATIONQUALIFIER_DATA);
 
-    /** OID for the "GENERATION=" attribute, denoting Jr., II, etc.*/
-        GENERATIONQUALIFIER_OID =
-            intern(ObjectIdentifier.newInternal(GENERATIONQUALIFIER_DATA));
+    // OIDs from other sources which show up in X.500 names we
+    // expect to deal with often.
+    //
+    // OID for "IP=" IP address attributes, used with SKIP.
+    public static final ObjectIdentifier ipAddress_oid =
+            ObjectIdentifier.newInternal(ipAddress_data);
 
-    /*
-     * OIDs from other sources which show up in X.500 names we
-     * expect to deal with often
-     */
-    /** OID for "IP=" IP address attributes, used with SKIP. */
-        ipAddress_oid = intern(ObjectIdentifier.newInternal(ipAddress_data));
+    // Domain component OID from RFC 1274, RFC 2247, RFC 5280.
+    //
+    // OID for "DC=" domain component attributes, used with DNSNames in DN
+    // format.
+    public static final ObjectIdentifier DOMAIN_COMPONENT_OID =
+            ObjectIdentifier.newInternal(DOMAIN_COMPONENT_DATA);
 
-    /*
-     * Domain component OID from RFC 1274, RFC 2247, RFC 5280
-     */
-
-    /*
-     * OID for "DC=" domain component attributes, used with DNSNames in DN
-     * format
-     */
-        DOMAIN_COMPONENT_OID =
-            intern(ObjectIdentifier.newInternal(DOMAIN_COMPONENT_DATA));
-
-    /** OID for "UID=" denoting a user id, defined in RFCs 1274 & 2798. */
-        userid_oid = intern(ObjectIdentifier.newInternal(userid_data));
-    }
+    // OID for "UID=" denoting a user id, defined in RFCs 1274 & 2798.
+    public static final ObjectIdentifier userid_oid =
+            ObjectIdentifier.newInternal(userid_data);
 
     /**
      * Return constraint type:<ul>
--- a/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.base/windows/classes/java/net/TwoStacksPlainDatagramSocketImpl.java	Thu Jan 16 04:09:50 2020 +0100
@@ -87,7 +87,9 @@
         fd1 = new FileDescriptor();
         try {
             super.create();
-            SocketCleanable.register(fd1);
+            // make SocketCleanable treat fd1 as a stream socket
+            // to avoid touching the counter in ResourceManager
+            SocketCleanable.register(fd1, true);
         } catch (SocketException e) {
             fd1 = null;
             throw e;
@@ -114,8 +116,10 @@
 
         bind0(lport, laddr, exclusiveBind);
 
-        SocketCleanable.register(fd);
-        SocketCleanable.register(fd1);
+        SocketCleanable.register(fd, false);
+        // make SocketCleanable treat fd1 as a stream socket
+        // to avoid touching the counter in ResourceManager
+        SocketCleanable.register(fd1, true);
     }
 
     protected synchronized void receive(DatagramPacket p)
--- a/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java	Thu Jan 16 04:09:50 2020 +0100
@@ -35,6 +35,7 @@
 
 package java.awt.color;
 
+import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -1017,42 +1018,25 @@
 
 
     static byte[] getProfileDataFromStream(InputStream s) throws IOException {
-    byte[] profileData;
-    int profileSize;
 
-        byte[] header = new byte[128];
-        int bytestoread = 128;
-        int bytesread = 0;
-        int n;
+        BufferedInputStream bis = new BufferedInputStream(s);
+        bis.mark(128);
 
-        while (bytestoread != 0) {
-            if ((n = s.read(header, bytesread, bytestoread)) < 0) {
-                return null;
-            }
-            bytesread += n;
-            bytestoread -= n;
-        }
+        byte[] header = bis.readNBytes(128);
         if (header[36] != 0x61 || header[37] != 0x63 ||
             header[38] != 0x73 || header[39] != 0x70) {
             return null;   /* not a valid profile */
         }
-        profileSize = ((header[0] & 0xff) << 24) |
-                      ((header[1] & 0xff) << 16) |
-                      ((header[2] & 0xff) <<  8) |
-                       (header[3] & 0xff);
-        profileData = new byte[profileSize];
-        System.arraycopy(header, 0, profileData, 0, 128);
-        bytestoread = profileSize - 128;
-        bytesread = 128;
-        while (bytestoread != 0) {
-            if ((n = s.read(profileData, bytesread, bytestoread)) < 0) {
-                return null;
-            }
-            bytesread += n;
-            bytestoread -= n;
+        int profileSize = ((header[0] & 0xff) << 24) |
+                          ((header[1] & 0xff) << 16) |
+                          ((header[2] & 0xff) << 8) |
+                          (header[3] & 0xff);
+        bis.reset();
+        try {
+            return bis.readNBytes(profileSize);
+        } catch (OutOfMemoryError e) {
+            throw new IOException("Color profile is too big");
         }
-
-        return profileData;
     }
 
     /**
--- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextSupport.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, 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
@@ -1032,18 +1032,8 @@
         int count = serializable;
 
         while (count-- > 0) {
-            Object                      child = null;
-            BeanContextSupport.BCSChild bscc  = null;
-
-            try {
-                child = ois.readObject();
-                bscc  = (BeanContextSupport.BCSChild)ois.readObject();
-            } catch (IOException ioe) {
-                continue;
-            } catch (ClassNotFoundException cnfe) {
-                continue;
-            }
-
+            Object child = ois.readObject();
+            BCSChild bscc = (BCSChild) ois.readObject();
 
             synchronized(child) {
                 BeanContextChild bcc = null;
--- a/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c	Thu Jan 16 04:09:50 2020 +0100
@@ -74,6 +74,7 @@
 static XImage * X11SD_GetImage(JNIEnv *env, X11SDOps *xsdo,
                                SurfaceDataBounds *bounds,
                                jint lockFlags);
+static int X11SD_GetBitmapPad(int pixelStride);
 
 extern jfieldID validID;
 
@@ -390,11 +391,33 @@
         xsdo->drawable = drawable;
         xsdo->isPixmap = JNI_FALSE;
     } else {
+        jboolean sizeIsInvalid = JNI_FALSE;
+        jlong scan = 0;
+
         /*
          * width , height must be nonzero otherwise XCreatePixmap
          * generates BadValue in error_handler
          */
         if (width <= 0 || height <= 0 || width > 32767 || height > 32767) {
+            sizeIsInvalid = JNI_TRUE;
+        } else {
+            XImage* tmpImg = NULL;
+
+            AWT_LOCK();
+            tmpImg = XCreateImage(awt_display,
+                xsdo->configData->awt_visInfo.visual,
+                depth, ZPixmap, 0, NULL, width, height,
+                X11SD_GetBitmapPad(xsdo->configData->pixelStride), 0);
+            if (tmpImg) {
+                scan = (jlong) tmpImg->bytes_per_line;
+                XDestroyImage(tmpImg);
+                tmpImg = NULL;
+            }
+            AWT_UNLOCK();
+            JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);
+        }
+
+        if (sizeIsInvalid || (scan * height > 0x7FFFFFFFL)) {
             JNU_ThrowOutOfMemoryError(env,
                                   "Can't create offscreen surface");
             return JNI_FALSE;
@@ -405,7 +428,7 @@
         xsdo->pmHeight = height;
 
 #ifdef MITSHM
-        xsdo->shmPMData.pmSize = width * height * depth;
+        xsdo->shmPMData.pmSize = (jlong) width * height * depth;
         xsdo->shmPMData.pixelsReadThreshold = width * height / 8;
         if (forceSharedPixmaps) {
             AWT_LOCK();
@@ -508,7 +531,7 @@
         return NULL;
     }
     shminfo->shmid =
-        shmget(IPC_PRIVATE, height * img->bytes_per_line,
+        shmget(IPC_PRIVATE, (size_t) height * img->bytes_per_line,
                IPC_CREAT|mitShmPermissionMask);
     if (shminfo->shmid < 0) {
         J2dRlsTraceLn1(J2D_TRACE_ERROR,
@@ -570,7 +593,7 @@
         XSync(awt_display, False);
         retImage = cachedXImage;
         cachedXImage = (XImage *)NULL;
-    } else if (width * height * xsdo->depth > 0x10000) {
+    } else if ((jlong) width * height * xsdo->depth > 0x10000) {
         retImage = X11SD_CreateSharedImage(xsdo, width, height);
     }
     return retImage;
@@ -870,7 +893,7 @@
             int scan = xpriv->img->bytes_per_line;
             xpriv->x = x;
             xpriv->y = y;
-            pRasInfo->rasBase = xpriv->img->data - x * mult - y * scan;
+            pRasInfo->rasBase = xpriv->img->data - x * mult - (intptr_t) y * scan;
             pRasInfo->pixelStride = mult;
             pRasInfo->pixelBitOffset = 0;
             pRasInfo->scanStride = scan;
@@ -1029,8 +1052,8 @@
 
 static void
 X11SD_SwapBytes(X11SDOps *xsdo, XImage * img, int depth, int bpp) {
-    int lengthInBytes = img->height * img->bytes_per_line;
-    int i;
+    jlong lengthInBytes = (jlong) img->height * img->bytes_per_line;
+    jlong i;
 
     switch (depth) {
     case 12:
@@ -1103,7 +1126,7 @@
     Drawable drawable;
     int depth = xsdo->depth;
     int mult = xsdo->configData->pixelStride;
-    int pad = (mult == 3) ? 32 : mult * 8; // pad must be 8, 16, or 32
+    int pad = X11SD_GetBitmapPad(mult);
     jboolean readBits = lockFlags & SD_LOCK_NEED_PIXELS;
 
     x = bounds->x1;
@@ -1169,7 +1192,7 @@
             }
 
             scan = img->bytes_per_line;
-            img->data = malloc(h * scan);
+            img->data = malloc((size_t) h * scan);
             if (img->data == NULL) {
                 XFree(img);
                 return NULL;
@@ -1204,7 +1227,7 @@
                     int i;
 
                     img_addr = img->data +
-                        (temp.y1 - y) * scan + (temp.x1 - x) * mult;
+                        (intptr_t) (temp.y1 - y) * scan + (temp.x1 - x) * mult;
                     temp_scan = temp_image->bytes_per_line;
                     temp_addr = temp_image->data;
                     bytes_to_copy = (temp.x2 - temp.x1) * mult;
@@ -1238,7 +1261,7 @@
                 return NULL;
             }
 
-            img->data = malloc(h * img->bytes_per_line);
+            img->data = malloc((size_t) h * img->bytes_per_line);
             if (img->data == NULL) {
                 XFree(img);
                 return NULL;
@@ -1379,6 +1402,11 @@
 #endif /* MITSHM */
 }
 
+static int X11SD_GetBitmapPad(int pixelStride) {
+    // pad must be 8, 16, or 32
+    return (pixelStride == 3) ? 32 : pixelStride * 8;
+}
+
 #endif /* !HEADLESS */
 
 /*
--- a/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.h	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.h	Thu Jan 16 04:09:50 2020 +0100
@@ -79,7 +79,7 @@
     XShmSegmentInfo     *shmSegInfo;    /* Shared Memory Segment Info */
     jint                bytesPerLine;   /* needed for ShMem lock */
     jboolean            xRequestSent;   /* true if x request is sent w/o XSync */
-    jint                pmSize;
+    jlong               pmSize;
 
     jboolean            usingShmPixmap;
     Drawable            pixmap;
--- a/src/java.rmi/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.rmi/share/classes/java/rmi/server/RemoteObjectInvocationHandler.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2015, 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
@@ -29,6 +29,7 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.rmi.Remote;
+import java.rmi.RemoteException;
 import java.rmi.UnexpectedException;
 import java.rmi.activation.Activatable;
 import java.util.Map;
@@ -206,6 +207,13 @@
                 throw new IllegalArgumentException(
                     "proxy not Remote instance");
             }
+
+            // Verify that the method is declared on an interface that extends Remote
+            Class<?> decl = method.getDeclaringClass();
+            if (!Remote.class.isAssignableFrom(decl)) {
+                throw new RemoteException("Method is not Remote: " + decl + "::" + method);
+            }
+
             return ref.invoke((Remote) proxy, method, args,
                               getMethodHash(method));
         } catch (Exception e) {
--- a/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl_Skel.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl_Skel.java	Thu Jan 16 04:09:50 2020 +0100
@@ -27,7 +27,9 @@
 package sun.rmi.registry;
 
 import java.io.IOException;
+import java.io.ObjectInputStream;
 
+import jdk.internal.access.SharedSecrets;
 import sun.rmi.transport.StreamRemoteCall;
 
 /**
@@ -83,8 +85,9 @@
                 java.lang.String $param_String_1;
                 java.rmi.Remote $param_Remote_2;
                 try {
-                    java.io.ObjectInput in = call.getInputStream();
-                    $param_String_1 = (java.lang.String) in.readObject();
+                    ObjectInputStream in = (ObjectInputStream)call.getInputStream();
+                    $param_String_1 =
+                            SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
                     $param_Remote_2 = (java.rmi.Remote) in.readObject();
                 } catch (ClassCastException | IOException | ClassNotFoundException e) {
                     call.discardPendingRefs();
@@ -118,9 +121,10 @@
             {
                 java.lang.String $param_String_1;
                 try {
-                    java.io.ObjectInput in = call.getInputStream();
-                    $param_String_1 = (java.lang.String) in.readObject();
-                } catch (ClassCastException | IOException | ClassNotFoundException e) {
+                    ObjectInputStream in = (ObjectInputStream)call.getInputStream();
+                    $param_String_1 =
+                            SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
+                } catch (ClassCastException | IOException e) {
                     call.discardPendingRefs();
                     throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
                 } finally {
@@ -144,8 +148,9 @@
                 java.lang.String $param_String_1;
                 java.rmi.Remote $param_Remote_2;
                 try {
-                    java.io.ObjectInput in = call.getInputStream();
-                    $param_String_1 = (java.lang.String) in.readObject();
+                    ObjectInputStream in = (ObjectInputStream)call.getInputStream();
+                    $param_String_1 =
+                            SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
                     $param_Remote_2 = (java.rmi.Remote) in.readObject();
                 } catch (ClassCastException | IOException | java.lang.ClassNotFoundException e) {
                     call.discardPendingRefs();
@@ -169,9 +174,10 @@
 
                 java.lang.String $param_String_1;
                 try {
-                    java.io.ObjectInput in = call.getInputStream();
-                    $param_String_1 = (java.lang.String) in.readObject();
-                } catch (ClassCastException | IOException | ClassNotFoundException e) {
+                    ObjectInputStream in = (ObjectInputStream)call.getInputStream();
+                    $param_String_1 =
+                            SharedSecrets.getJavaObjectInputStreamReadString().readString(in);
+                } catch (ClassCastException | IOException e) {
                     call.discardPendingRefs();
                     throw new java.rmi.UnmarshalException("error unmarshalling arguments", e);
                 } finally {
--- a/src/java.rmi/share/classes/sun/rmi/server/UnicastRef.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.rmi/share/classes/sun/rmi/server/UnicastRef.java	Thu Jan 16 04:09:50 2020 +0100
@@ -27,6 +27,7 @@
 
 import java.io.IOException;
 import java.io.ObjectInput;
+import java.io.ObjectInputStream;
 import java.io.ObjectOutput;
 import java.lang.reflect.Method;
 import java.rmi.MarshalException;
@@ -39,6 +40,8 @@
 import java.rmi.server.RemoteRef;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+
+import jdk.internal.access.SharedSecrets;
 import sun.rmi.runtime.Log;
 import sun.rmi.transport.Connection;
 import sun.rmi.transport.LiveRef;
@@ -318,6 +321,8 @@
             } else {
                 throw new Error("Unrecognized primitive type: " + type);
             }
+        } else if (type == String.class && in instanceof ObjectInputStream) {
+            return SharedSecrets.getJavaObjectInputStreamReadString().readString((ObjectInputStream)in);
         } else {
             return in.readObject();
         }
--- a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, 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.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
+import java.lang.reflect.Proxy;
 import java.net.InetAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
@@ -553,6 +554,9 @@
             host = in.readUTF();
             port = in.readInt();
             csf = (RMIClientSocketFactory) in.readObject();
+            if (Proxy.isProxyClass(csf.getClass())) {
+                throw new IOException("Invalid SocketFactory");
+            }
           break;
 
           default:
--- a/src/java.security.jgss/share/classes/sun/security/krb5/Checksum.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/Checksum.java	Thu Jan 16 04:09:50 2020 +0100
@@ -73,6 +73,7 @@
     // draft-brezak-win2k-krb-rc4-hmac-04.txt
     public static final int CKSUMTYPE_HMAC_MD5_ARCFOUR = -138;
 
+    // default checksum type, -1 if not set
     static int CKSUMTYPE_DEFAULT;
     static int SAFECKSUMTYPE_DEFAULT;
 
@@ -87,26 +88,19 @@
         try {
             cfg = Config.getInstance();
             temp = cfg.get("libdefaults", "default_checksum");
-            if (temp != null)
-                {
-                    CKSUMTYPE_DEFAULT = Config.getType(temp);
-                } else {
-                    /*
-                     * If the default checksum is not
-                     * specified in the configuration we
-                     * set it to RSA_MD5. We follow the MIT and
-                     * SEAM implementation.
-                     */
-                    CKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5;
-                }
+            if (temp != null) {
+                CKSUMTYPE_DEFAULT = Config.getType(temp);
+            } else {
+                CKSUMTYPE_DEFAULT = -1;
+            }
         } catch (Exception exc) {
             if (DEBUG) {
                 System.out.println("Exception in getting default checksum "+
                                    "value from the configuration. " +
-                                   "Setting default checksum to be RSA-MD5");
+                                   "No default checksum set.");
                 exc.printStackTrace();
             }
-            CKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5;
+            CKSUMTYPE_DEFAULT = -1;
         }
 
 
@@ -116,117 +110,100 @@
                 {
                     SAFECKSUMTYPE_DEFAULT = Config.getType(temp);
                 } else {
-                    SAFECKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5_DES;
+                    SAFECKSUMTYPE_DEFAULT = -1;
                 }
         } catch (Exception exc) {
             if (DEBUG) {
                 System.out.println("Exception in getting safe default " +
                                    "checksum value " +
-                                   "from the configuration. Setting " +
-                                   "safe default checksum to be RSA-MD5");
+                                   "from the configuration Setting. " +
+                                   "No safe default checksum set.");
                 exc.printStackTrace();
             }
-            SAFECKSUMTYPE_DEFAULT = CKSUMTYPE_RSA_MD5_DES;
+            SAFECKSUMTYPE_DEFAULT = -1;
         }
     }
 
     /**
      * Constructs a new Checksum using the raw data and type.
+     *
+     * This constructor is only used by Authenticator Checksum
+     * {@link sun.security.jgss.krb5.InitialToken.OverloadedChecksum}
+     * where the checksum type must be 0x8003
+     * (see https://tools.ietf.org/html/rfc4121#section-4.1.1)
+     * and checksum field/value is used to convey service flags,
+     * channel bindings, and optional delegation information.
+     * This special type does NOT have a {@link CksumType} and has its
+     * own calculating and verification rules. It does has the same
+     * ASN.1 encoding though.
+     *
      * @param data the byte array of checksum.
      * @param new_cksumType the type of checksum.
-     *
      */
-         // used in InitialToken
     public Checksum(byte[] data, int new_cksumType) {
         cksumType = new_cksumType;
         checksum = data;
     }
 
     /**
-     * Constructs a new Checksum by calculating the checksum over the data
-     * using specified checksum type.
-     * @param new_cksumType the type of checksum.
-     * @param data the data that needs to be performed a checksum calculation on.
+     * Constructs a new Checksum by calculating over the data using
+     * the specified checksum type. If the checksum is unkeyed, key
+     * and usage are ignored.
+     *
+     * @param new_cksumType the type of checksum. If set to -1, the
+     *      {@linkplain EType#checksumType() mandatory checksum type}
+     *      for the encryption type of {@code key} will be used
+     * @param data the data that needs to be performed a checksum calculation on
+     * @param key the key used by a keyed checksum
+     * @param usage the usage used by a keyed checksum
      */
-    public Checksum(int new_cksumType, byte[] data)
-        throws KdcErrException, KrbCryptoException {
-
-        cksumType = new_cksumType;
-        CksumType cksumEngine = CksumType.getInstance(cksumType);
-        if (!cksumEngine.isSafe()) {
-            checksum = cksumEngine.calculateChecksum(data, data.length);
+    public Checksum(int new_cksumType, byte[] data,
+                    EncryptionKey key, int usage)
+            throws KdcErrException, KrbApErrException, KrbCryptoException {
+        if (new_cksumType == -1) {
+            cksumType = EType.getInstance(key.getEType()).checksumType();
         } else {
-            throw new KdcErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
+            cksumType = new_cksumType;
         }
-    }
-
-    /**
-     * Constructs a new Checksum by calculating the keyed checksum
-     * over the data using specified checksum type.
-     * @param new_cksumType the type of checksum.
-     * @param data the data that needs to be performed a checksum calculation on.
-     */
-         // KrbSafe, KrbTgsReq
-    public Checksum(int new_cksumType, byte[] data,
-                        EncryptionKey key, int usage)
-        throws KdcErrException, KrbApErrException, KrbCryptoException {
-        cksumType = new_cksumType;
-        CksumType cksumEngine = CksumType.getInstance(cksumType);
-        if (!cksumEngine.isSafe())
-            throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
-        checksum =
-            cksumEngine.calculateKeyedChecksum(data,
-                data.length,
-                key.getBytes(),
-                usage);
+        checksum = CksumType.getInstance(cksumType).calculateChecksum(
+                    data, data.length, key.getBytes(), usage);
     }
 
     /**
      * Verifies the keyed checksum over the data passed in.
      */
-    public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key,
-                                        int usage)
-        throws KdcErrException, KrbApErrException, KrbCryptoException {
+    public boolean verifyKeyedChecksum(byte[] data, EncryptionKey key, int usage)
+            throws KdcErrException, KrbApErrException, KrbCryptoException {
         CksumType cksumEngine = CksumType.getInstance(cksumType);
-        if (!cksumEngine.isSafe())
+        if (!cksumEngine.isKeyed()) {
             throw new KrbApErrException(Krb5.KRB_AP_ERR_INAPP_CKSUM);
-        return cksumEngine.verifyKeyedChecksum(data,
-                                               data.length,
-                                               key.getBytes(),
-                                               checksum,
-            usage);
-    }
-
-    // ===============  ATTENTION! Use with care  ==================
-    // According to https://tools.ietf.org/html/rfc3961#section-6.1,
-    // An unkeyed checksum should only be used "in limited circumstances
-    // where the lack of a key does not provide a window for an attack,
-    // preferably as part of an encrypted message".
-    public boolean verifyAnyChecksum(byte[] data, EncryptionKey key,
-            int usage)
-            throws KdcErrException, KrbCryptoException {
-        CksumType cksumEngine = CksumType.getInstance(cksumType);
-        if (!cksumEngine.isSafe()) {
-            return cksumEngine.verifyChecksum(data, checksum);
         } else {
-            return cksumEngine.verifyKeyedChecksum(data,
-                    data.length,
-                    key.getBytes(),
-                    checksum,
-                    usage);
+            return cksumEngine.verifyChecksum(
+                    data, data.length, key.getBytes(), checksum, usage);
         }
     }
 
-    /*
-    public Checksum(byte[] data) throws KdcErrException, KrbCryptoException {
-        this(Checksum.CKSUMTYPE_DEFAULT, data);
+
+    /**
+     * Verifies the checksum over the data passed in. The checksum might
+     * be a keyed or not.
+     *
+     * ===============  ATTENTION! Use with care  ==================
+     * According to https://tools.ietf.org/html/rfc3961#section-6.1,
+     * An unkeyed checksum should only be used "in limited circumstances
+     * where the lack of a key does not provide a window for an attack,
+     * preferably as part of an encrypted message".
+     */
+    public boolean verifyAnyChecksum(byte[] data, EncryptionKey key, int usage)
+            throws KdcErrException, KrbCryptoException {
+        return CksumType.getInstance(cksumType).verifyChecksum(
+                data, data.length, key.getBytes(), checksum, usage);
     }
-    */
 
     boolean isEqual(Checksum cksum) throws KdcErrException {
-        if (cksumType != cksum.cksumType)
+        if (cksumType != cksum.cksumType) {
             return false;
-        CksumType cksumEngine = CksumType.getInstance(cksumType);
+        }
         return CksumType.isChecksumEqual(checksum, cksum.checksum);
     }
 
--- a/src/java.security.jgss/share/classes/sun/security/krb5/KrbTgsReq.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/KrbTgsReq.java	Thu Jan 16 04:09:50 2020 +0100
@@ -318,28 +318,8 @@
         byte[] temp = reqBody.asn1Encode(Krb5.KRB_TGS_REQ);
         // if the checksum type is one of the keyed checksum types,
         // use session key.
-        Checksum cksum;
-        switch (Checksum.CKSUMTYPE_DEFAULT) {
-        case Checksum.CKSUMTYPE_RSA_MD4_DES:
-        case Checksum.CKSUMTYPE_DES_MAC:
-        case Checksum.CKSUMTYPE_DES_MAC_K:
-        case Checksum.CKSUMTYPE_RSA_MD4_DES_K:
-        case Checksum.CKSUMTYPE_RSA_MD5_DES:
-        case Checksum.CKSUMTYPE_HMAC_SHA1_DES3_KD:
-        case Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR:
-        case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128:
-        case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256:
-        case Checksum.CKSUMTYPE_HMAC_SHA256_128_AES128:
-        case Checksum.CKSUMTYPE_HMAC_SHA384_192_AES256:
-            cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp, key,
+        Checksum cksum  = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp, key,
                 KeyUsage.KU_PA_TGS_REQ_CKSUM);
-            break;
-        case Checksum.CKSUMTYPE_CRC32:
-        case Checksum.CKSUMTYPE_RSA_MD4:
-        case Checksum.CKSUMTYPE_RSA_MD5:
-        default:
-            cksum = new Checksum(Checksum.CKSUMTYPE_DEFAULT, temp);
-        }
 
         // Usage will be KeyUsage.KU_PA_TGS_REQ_AUTHENTICATOR
 
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/NetClient.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/NetClient.java	Thu Jan 16 04:09:50 2020 +0100
@@ -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
@@ -102,7 +102,7 @@
         }
 
         try {
-            return IOUtils.readFully(in, len, true);
+            return IOUtils.readExactlyNBytes(in, len);
         } catch (IOException ioe) {
             if (Krb5.DEBUG) {
                 System.out.println(
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/PAForUserEnc.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/PAForUserEnc.java	Thu Jan 16 04:09:50 2020 +0100
@@ -135,6 +135,7 @@
         bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), name.getRealm().asn1Encode());
 
         try {
+            // MS-SFU 2.2.1: use hmac-md5 checksum regardless of key type
             Checksum cks = new Checksum(
                     Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR,
                     getS4UByteArray(),
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/CCacheInputStream.java	Thu Jan 16 04:09:50 2020 +0100
@@ -128,7 +128,7 @@
             length--;
         for (int i = 0; i <= length; i++) {
             namelength = readLength4();
-            byte[] bytes = IOUtils.readFully(this, namelength, true);
+            byte[] bytes = IOUtils.readExactlyNBytes(this, namelength);
             result.add(new String(bytes));
         }
         if (result.isEmpty()) {
@@ -186,7 +186,7 @@
         if (version == KRB5_FCC_FVNO_3)
             read(2); /* keytype recorded twice in fvno 3 */
         keyLen = readLength4();
-        byte[] bytes = IOUtils.readFully(this, keyLen, true);
+        byte[] bytes = IOUtils.readExactlyNBytes(this, keyLen);
         return new EncryptionKey(bytes, keyType, version);
     }
 
@@ -239,7 +239,7 @@
             for (int i = 0; i < num; i++) {
                 adtype = read(2);
                 adlength = readLength4();
-                data = IOUtils.readFully(this, adlength, true);
+                data = IOUtils.readExactlyNBytes(this, adlength);
                 auData.add(new AuthorizationDataEntry(adtype, data));
             }
             return auData.toArray(new AuthorizationDataEntry[auData.size()]);
@@ -253,7 +253,7 @@
         if (length == 0) {
             return null;
         } else {
-            return IOUtils.readFully(this, length, true);
+            return IOUtils.readExactlyNBytes(this, length);
         }
     }
 
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/CksumType.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/CksumType.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, 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
@@ -31,10 +31,7 @@
 
 package sun.security.krb5.internal.crypto;
 
-import sun.security.krb5.Config;
 import sun.security.krb5.Checksum;
-import sun.security.krb5.EncryptedData;
-import sun.security.krb5.KrbException;
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
 
@@ -81,12 +78,25 @@
             cksumTypeName =
                 "sun.security.krb5.internal.crypto.HmacSha1Aes128CksumType";
             break;
+
         case Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256:
             cksumType = new HmacSha1Aes256CksumType();
             cksumTypeName =
                 "sun.security.krb5.internal.crypto.HmacSha1Aes256CksumType";
             break;
 
+        case Checksum.CKSUMTYPE_HMAC_SHA256_128_AES128:
+            cksumType = new HmacSha2Aes128CksumType();
+            cksumTypeName =
+                    "sun.security.krb5.internal.crypto.HmacSha2Aes128CksumType";
+            break;
+
+        case Checksum.CKSUMTYPE_HMAC_SHA384_192_AES256:
+            cksumType = new HmacSha2Aes256CksumType();
+            cksumTypeName =
+                    "sun.security.krb5.internal.crypto.HmacSha2Aes256CksumType";
+            break;
+
         case Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR:
             cksumType = new HmacMd5ArcFourCksumType();
             cksumTypeName =
@@ -117,32 +127,11 @@
         return cksumType;
     }
 
-
-    /**
-     * Returns default checksum type.
-     */
-    public static CksumType getInstance() throws KdcErrException {
-        // this method provided for Kerberos applications.
-        int cksumType = Checksum.CKSUMTYPE_RSA_MD5; // default
-        try {
-            Config c = Config.getInstance();
-            if ((cksumType = (Config.getType(c.get("libdefaults",
-                    "ap_req_checksum_type")))) == - 1) {
-                if ((cksumType = Config.getType(c.get("libdefaults",
-                        "checksum_type"))) == -1) {
-                    cksumType = Checksum.CKSUMTYPE_RSA_MD5; // default
-                }
-            }
-        } catch (KrbException e) {
-        }
-        return getInstance(cksumType);
-    }
-
     public abstract int confounderSize();
 
     public abstract int cksumType();
 
-    public abstract boolean isSafe();
+    public abstract boolean isKeyed();
 
     public abstract int cksumSize();
 
@@ -150,18 +139,12 @@
 
     public abstract int keySize();
 
-    public abstract byte[] calculateChecksum(byte[] data, int size)
-        throws KrbCryptoException;
-
-    public abstract byte[] calculateKeyedChecksum(byte[] data, int size,
+    // Note: key and usage will be ignored for an unkeyed checksum.
+    public abstract byte[] calculateChecksum(byte[] data, int size,
         byte[] key, int usage) throws KrbCryptoException;
 
-    public boolean verifyChecksum(byte[] data, byte[] checksum)
-            throws KrbCryptoException {
-        throw new UnsupportedOperationException("Not supported");
-    }
-
-    public abstract boolean verifyKeyedChecksum(byte[] data, int size,
+    // Note: key and usage will be ignored for an unkeyed checksum.
+    public abstract boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException;
 
     public static boolean isChecksumEqual(byte[] cksum1, byte[] cksum2) {
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/Crc32CksumType.java	Thu Jan 16 04:09:50 2020 +0100
@@ -32,7 +32,6 @@
 
 import sun.security.krb5.*;
 import sun.security.krb5.internal.*;
-import java.util.zip.CRC32;
 
 public class Crc32CksumType extends CksumType {
 
@@ -47,7 +46,7 @@
         return Checksum.CKSUMTYPE_CRC32;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return false;
     }
 
@@ -63,18 +62,15 @@
         return 0;
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
+    public byte[] calculateChecksum(byte[] data, int size,
+            byte[] key, int usage) {
         return crc32.byte2crc32sum_bytes(data, size);
     }
 
-    public byte[] calculateKeyedChecksum(byte[] data, int size,
-                                         byte[] key, int usage) {
-                                             return null;
-                                         }
-
-    public boolean verifyKeyedChecksum(byte[] data, int size,
-                                       byte[] key, byte[] checksum, int usage) {
-        return false;
+    public boolean verifyChecksum(byte[] data, int size,
+            byte[] key, byte[] checksum, int usage) {
+        return CksumType.isChecksumEqual(checksum,
+                crc32.byte2crc32sum_bytes(data));
     }
 
     public static byte[] int2quad(long input) {
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/DesCbcCrcEType.java	Thu Jan 16 04:09:50 2020 +0100
@@ -53,7 +53,7 @@
     }
 
     public int checksumType() {
-        return Checksum.CKSUMTYPE_CRC32;
+        return Checksum.CKSUMTYPE_RSA_MD5;
     }
 
     public int checksumSize() {
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/DesMacCksumType.java	Thu Jan 16 04:09:50 2020 +0100
@@ -49,7 +49,7 @@
         return Checksum.CKSUMTYPE_DES_MAC;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -65,10 +65,6 @@
         return 8;
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -78,7 +74,7 @@
      *
      * @modified by Yanni Zhang, 12/08/99.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
         byte[] new_data = new byte[size + confounderSize()];
         byte[] conf = Confounder.bytes(confounderSize());
@@ -130,7 +126,7 @@
      *
      * @modified by Yanni Zhang, 12/08/99.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
         byte[] cksum = decryptKeyedChecksum(checksum, key);
 
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/DesMacKCksumType.java	Thu Jan 16 04:09:50 2020 +0100
@@ -48,7 +48,7 @@
         return Checksum.CKSUMTYPE_DES_MAC_K;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -64,10 +64,6 @@
         return 8;
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -77,7 +73,7 @@
      *
      * @modified by Yanni Zhang, 12/08/99.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
         //check for weak keys
         try {
@@ -93,9 +89,9 @@
         return cksum;
     }
 
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
-        byte[] new_cksum = calculateKeyedChecksum(data, data.length, key, usage);
+        byte[] new_cksum = calculateChecksum(data, data.length, key, usage);
         return isChecksumEqual(checksum, new_cksum);
     }
 
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/HmacMd5ArcFourCksumType.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -28,8 +28,6 @@
 import sun.security.krb5.Checksum;
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
-import javax.crypto.spec.DESKeySpec;
-import java.security.InvalidKeyException;
 import java.security.GeneralSecurityException;
 
 /**
@@ -51,7 +49,7 @@
         return Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -67,10 +65,6 @@
         return 16;   // bytes
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -78,7 +72,7 @@
      * @param key the key used to encrypt the checksum.
      * @return keyed checksum.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
 
          try {
@@ -98,7 +92,7 @@
      * @param checksum the checksum.
      * @return true if verification is successful.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
 
          try {
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes128CksumType.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -28,8 +28,6 @@
 import sun.security.krb5.Checksum;
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
-import javax.crypto.spec.DESKeySpec;
-import java.security.InvalidKeyException;
 import java.security.GeneralSecurityException;
 
 /*
@@ -51,7 +49,7 @@
         return Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -67,10 +65,6 @@
         return 16;   // bytes
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -78,7 +72,7 @@
      * @param key the key used to encrypt the checksum.
      * @return keyed checksum.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
 
          try {
@@ -98,7 +92,7 @@
      * @param checksum the checksum.
      * @return true if verification is successful.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
 
          try {
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/HmacSha1Aes256CksumType.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -28,8 +28,6 @@
 import sun.security.krb5.Checksum;
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
-import javax.crypto.spec.DESKeySpec;
-import java.security.InvalidKeyException;
 import java.security.GeneralSecurityException;
 
 /*
@@ -51,7 +49,7 @@
         return Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -67,10 +65,6 @@
         return 32;   // bytes
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -78,7 +72,7 @@
      * @param key the key used to encrypt the checksum.
      * @return keyed checksum.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
 
          try {
@@ -98,7 +92,7 @@
      * @param checksum the checksum.
      * @return true if verification is successful.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
 
          try {
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/HmacSha1Des3KdCksumType.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 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
@@ -28,8 +28,6 @@
 import sun.security.krb5.Checksum;
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
-import javax.crypto.spec.DESKeySpec;
-import java.security.InvalidKeyException;
 import java.security.GeneralSecurityException;
 
 public class HmacSha1Des3KdCksumType extends CksumType {
@@ -45,7 +43,7 @@
         return Checksum.CKSUMTYPE_HMAC_SHA1_DES3_KD;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -61,10 +59,6 @@
         return 24;   // bytes
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -72,7 +66,7 @@
      * @param key the key used to encrypt the checksum.
      * @return keyed checksum.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
 
          try {
@@ -92,7 +86,7 @@
      * @param checksum the checksum.
      * @return true if verification is successful.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
 
          try {
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/HmacSha2Aes128CksumType.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/HmacSha2Aes128CksumType.java	Thu Jan 16 04:09:50 2020 +0100
@@ -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
@@ -47,7 +47,7 @@
         return Checksum.CKSUMTYPE_HMAC_SHA256_128_AES128;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -63,10 +63,6 @@
         return 16;   // bytes
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -74,7 +70,7 @@
      * @param key the key used to encrypt the checksum.
      * @return keyed checksum.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
 
          try {
@@ -94,7 +90,7 @@
      * @param checksum the checksum.
      * @return true if verification is successful.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
 
          try {
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/HmacSha2Aes256CksumType.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/HmacSha2Aes256CksumType.java	Thu Jan 16 04:09:50 2020 +0100
@@ -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
@@ -47,7 +47,7 @@
         return Checksum.CKSUMTYPE_HMAC_SHA384_192_AES256;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -63,10 +63,6 @@
         return 32;   // bytes
     }
 
-    public byte[] calculateChecksum(byte[] data, int size) {
-        return null;
-    }
-
     /**
      * Calculates keyed checksum.
      * @param data the data used to generate the checksum.
@@ -74,7 +70,7 @@
      * @param key the key used to encrypt the checksum.
      * @return keyed checksum.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
 
          try {
@@ -94,7 +90,7 @@
      * @param checksum the checksum.
      * @return true if verification is successful.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
 
          try {
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/RsaMd5CksumType.java	Thu Jan 16 04:09:50 2020 +0100
@@ -33,8 +33,6 @@
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
 import java.security.MessageDigest;
-import java.security.Provider;
-import java.security.Security;
 
 public final class RsaMd5CksumType extends CksumType {
 
@@ -49,7 +47,7 @@
         return Checksum.CKSUMTYPE_RSA_MD5;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return false;
     }
 
@@ -74,7 +72,8 @@
      * @modified by Yanni Zhang, 12/08/99.
      */
 
-    public byte[] calculateChecksum(byte[] data, int size) throws KrbCryptoException{
+    public byte[] calculateChecksum(byte[] data, int size,
+            byte[] key, int usage) throws KrbCryptoException{
         MessageDigest md5;
         byte[] result = null;
         try {
@@ -91,18 +90,9 @@
         return result;
     }
 
-    public byte[] calculateKeyedChecksum(byte[] data, int size,
-        byte[] key, int usage) throws KrbCryptoException {
-                                             return null;
-                                         }
-
-    public boolean verifyKeyedChecksum(byte[] data, int size,
-        byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
-        return false;
-    }
-
     @Override
-    public boolean verifyChecksum(byte[] data, byte[] checksum)
+    public boolean verifyChecksum(byte[] data, int size,
+            byte[] key, byte[] checksum, int usage)
             throws KrbCryptoException {
         try {
             byte[] calculated = MessageDigest.getInstance("MD5").digest(data);
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/RsaMd5DesCksumType.java	Thu Jan 16 04:09:50 2020 +0100
@@ -33,12 +33,8 @@
 import sun.security.krb5.Confounder;
 import sun.security.krb5.KrbCryptoException;
 import sun.security.krb5.internal.*;
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
 import javax.crypto.spec.DESKeySpec;
 import java.security.MessageDigest;
-import java.security.Provider;
-import java.security.Security;
 import java.security.InvalidKeyException;
 
 public final class RsaMd5DesCksumType extends CksumType {
@@ -54,7 +50,7 @@
         return Checksum.CKSUMTYPE_RSA_MD5_DES;
     }
 
-    public boolean isSafe() {
+    public boolean isKeyed() {
         return true;
     }
 
@@ -79,7 +75,7 @@
      *
      * @modified by Yanni Zhang, 12/08/99.
      */
-    public byte[] calculateKeyedChecksum(byte[] data, int size, byte[] key,
+    public byte[] calculateChecksum(byte[] data, int size, byte[] key,
         int usage) throws KrbCryptoException {
         //prepend confounder
         byte[] new_data = new byte[size + confounderSize()];
@@ -88,7 +84,7 @@
         System.arraycopy(data, 0, new_data, confounderSize(), size);
 
         //calculate md5 cksum
-        byte[] mdc_cksum = calculateChecksum(new_data, new_data.length);
+        byte[] mdc_cksum = calculateRawChecksum(new_data, new_data.length);
         byte[] cksum = new byte[cksumSize()];
         System.arraycopy(conf, 0, cksum, 0, confounderSize());
         System.arraycopy(mdc_cksum, 0, cksum, confounderSize(),
@@ -125,7 +121,7 @@
      *
      * @modified by Yanni Zhang, 12/08/99.
      */
-    public boolean verifyKeyedChecksum(byte[] data, int size,
+    public boolean verifyChecksum(byte[] data, int size,
         byte[] key, byte[] checksum, int usage) throws KrbCryptoException {
         //decrypt checksum
         byte[] cksum = decryptKeyedChecksum(checksum, key);
@@ -135,7 +131,7 @@
         System.arraycopy(cksum, 0, new_data, 0, confounderSize());
         System.arraycopy(data, 0, new_data, confounderSize(), size);
 
-        byte[] new_cksum = calculateChecksum(new_data, new_data.length);
+        byte[] new_cksum = calculateRawChecksum(new_data, new_data.length);
         //extract original cksum value
         byte[] orig_cksum = new byte[cksumSize() - confounderSize()];
         System.arraycopy(cksum,  confounderSize(), orig_cksum, 0,
@@ -181,7 +177,7 @@
      *
      * @modified by Yanni Zhang, 12/08/99.
      */
-    public byte[] calculateChecksum(byte[] data, int size) throws KrbCryptoException{
+    private byte[] calculateRawChecksum(byte[] data, int size) throws KrbCryptoException{
         MessageDigest md5;
         byte[] result = null;
         try {
@@ -197,5 +193,4 @@
         }
         return result;
     }
-
 }
--- a/src/java.security.jgss/windows/native/libsspi_bridge/sspi.cpp	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/java.security.jgss/windows/native/libsspi_bridge/sspi.cpp	Thu Jan 16 04:09:50 2020 +0100
@@ -132,8 +132,9 @@
         return 0;
     }
     ULONGLONG diff = (time->QuadPart - uiLocal.QuadPart) / 10000000;
-    if (diff > (ULONGLONG)~(OM_uint32)0)
+    if (diff > (ULONGLONG)~(OM_uint32)0) {
         return GSS_C_INDEFINITE;
+    }
     return (OM_uint32)diff;
 }
 
@@ -177,8 +178,10 @@
 new_cred()
 {
     gss_cred_id_t out = new gss_cred_id_struct;
-    out->phCredK = out->phCredS = NULL;
-    out->time = 0L;
+    if (out) {
+        out->phCredK = out->phCredS = NULL;
+        out->time = 0L;
+    }
     return out;
 }
 
@@ -864,6 +867,7 @@
     SecBufferDesc outBuffDesc;
     SecBuffer outSecBuff;
     BOOLEAN isSPNEGO = is_same_oid(mech_type, &SPNEGO_OID);
+    CredHandle* newCred = NULL;
 
     gss_ctx_id_t pc;
 
@@ -928,7 +932,10 @@
             pc->isLocalCred = FALSE;
         } else {
             PP("No credentials provided, acquire myself");
-            CredHandle* newCred = new CredHandle;
+            newCred = new CredHandle;
+            if (!newCred) {
+                goto err;
+            }
             SEC_WINNT_AUTH_IDENTITY_EX auth;
             ZeroMemory(&auth, sizeof(auth));
             auth.Version = SEC_WINNT_AUTH_IDENTITY_VERSION;
@@ -947,7 +954,6 @@
                     newCred,
                     &lifeTime);
             if (!(SEC_SUCCESS(ss))) {
-                delete newCred;
                 goto err;
             }
             pc->phCred = newCred;
@@ -989,7 +995,6 @@
         output_token->value = new char[outSecBuff.cbBuffer];
         if (!output_token->value) {
             FreeContextBuffer(outSecBuff.pvBuffer);
-            output_token->length = 0;
             goto err;
         }
         memcpy(output_token->value, outSecBuff.pvBuffer, outSecBuff.cbBuffer);
@@ -1009,14 +1014,17 @@
         return GSS_S_COMPLETE;
     }
 err:
+    if (newCred) {
+        delete newCred;
+    }
     if (firstTime) {
         OM_uint32 dummy;
         gss_delete_sec_context(&dummy, context_handle, GSS_C_NO_BUFFER);
     }
     if (output_token->value) {
         gss_release_buffer(NULL, output_token);
-        output_token = GSS_C_NO_BUFFER;
     }
+    output_token = GSS_C_NO_BUFFER;
     return GSS_S_FAILURE;
 }
 
@@ -1233,17 +1241,26 @@
     secBuff[1].cbBuffer = context_handle->SecPkgContextSizes.cbMaxSignature;
     secBuff[1].pvBuffer = msg_token->value = new char[secBuff[1].cbBuffer];
 
+    if (!secBuff[1].pvBuffer) {
+        goto err;
+    }
+
     ss = MakeSignature((PCtxtHandle)&context_handle->hCtxt, 0, &buffDesc, 0);
 
     if (!SEC_SUCCESS(ss)) {
-        msg_token->length = 0;
-        msg_token->value = NULL;
-        delete[] secBuff[1].pvBuffer;
-        return GSS_S_FAILURE;
+        goto err;
     }
 
     msg_token->length = secBuff[1].cbBuffer;
     return GSS_S_COMPLETE;
+
+err:
+    msg_token->length = 0;
+    msg_token->value = NULL;
+    if (secBuff[1].pvBuffer) {
+        delete[] secBuff[1].pvBuffer;
+    }
+    return GSS_S_FAILURE;
 }
 
 __declspec(dllexport) OM_uint32
@@ -1317,16 +1334,25 @@
             context_handle->SecPkgContextSizes.cbSecurityTrailer
                     + input_message_buffer->length
                     + context_handle->SecPkgContextSizes.cbBlockSize);;
+    if (!output_message_buffer->value) {
+        goto err;
+    }
 
     secBuff[1].BufferType = SECBUFFER_DATA;
     secBuff[1].cbBuffer = (ULONG)input_message_buffer->length;
     secBuff[1].pvBuffer = malloc(secBuff[1].cbBuffer);
+    if (!secBuff[1].pvBuffer) {
+        goto err;
+    }
     memcpy_s(secBuff[1].pvBuffer, secBuff[1].cbBuffer,
             input_message_buffer->value, input_message_buffer->length);
 
     secBuff[2].BufferType = SECBUFFER_PADDING;
     secBuff[2].cbBuffer = context_handle->SecPkgContextSizes.cbBlockSize;
     secBuff[2].pvBuffer = malloc(secBuff[2].cbBuffer);
+    if (!secBuff[2].pvBuffer) {
+        goto err;
+    }
 
     ss = EncryptMessage((PCtxtHandle)&context_handle->hCtxt,
             conf_req_flag ? 0 : SECQOP_WRAP_NO_ENCRYPT,
@@ -1336,12 +1362,7 @@
     }
 
     if (!SEC_SUCCESS(ss)) {
-        free(secBuff[0].pvBuffer);
-        free(secBuff[1].pvBuffer);
-        free(secBuff[2].pvBuffer);
-        output_message_buffer->length = 0;
-        output_message_buffer->value = NULL;
-        return GSS_S_FAILURE;
+        goto err;
     }
 
     memcpy_s((PBYTE)secBuff[0].pvBuffer + secBuff[0].cbBuffer,
@@ -1359,6 +1380,20 @@
     free(secBuff[2].pvBuffer);
 
     return GSS_S_COMPLETE;
+
+err:
+    if (secBuff[0].pvBuffer) {
+        free(secBuff[0].pvBuffer);
+    }
+    if (secBuff[1].pvBuffer) {
+        free(secBuff[1].pvBuffer);
+    }
+    if (secBuff[2].pvBuffer) {
+        free(secBuff[2].pvBuffer);
+    }
+    output_message_buffer->length = 0;
+    output_message_buffer->value = NULL;
+    return GSS_S_FAILURE;
 }
 
 __declspec(dllexport) OM_uint32
@@ -1386,6 +1421,11 @@
     secBuff[0].BufferType = SECBUFFER_STREAM;
     secBuff[0].cbBuffer = (ULONG)input_message_buffer->length;
     secBuff[0].pvBuffer = malloc(input_message_buffer->length);
+
+    if (!secBuff[0].pvBuffer) {
+        goto err;
+    }
+
     memcpy_s(secBuff[0].pvBuffer, input_message_buffer->length,
             input_message_buffer->value, input_message_buffer->length);
 
@@ -1398,21 +1438,31 @@
         *qop_state = ulQop;
     }
     if (!SEC_SUCCESS(ss)) {
-        free(secBuff[0].pvBuffer);
-        output_message_buffer->length = 0;
-        output_message_buffer->value = NULL;
-        return GSS_S_FAILURE;
+        goto err;
     }
 
     // Must allocate a new memory block so client can release it correctly
     output_message_buffer->length = secBuff[1].cbBuffer;
     output_message_buffer->value = new char[secBuff[1].cbBuffer];
+
+    if (!output_message_buffer->value) {
+        goto err;
+    }
+
     memcpy_s(output_message_buffer->value, secBuff[1].cbBuffer,
             secBuff[1].pvBuffer, secBuff[1].cbBuffer);
     *conf_state = ulQop == SECQOP_WRAP_NO_ENCRYPT ? 0 : 1;
 
     free(secBuff[0].pvBuffer);
     return GSS_S_COMPLETE;
+
+err:
+    if (secBuff[0].pvBuffer) {
+        free(secBuff[0].pvBuffer);
+    }
+    output_message_buffer->length = 0;
+    output_message_buffer->value = NULL;
+    return GSS_S_FAILURE;
 }
 
 __declspec(dllexport) OM_uint32
@@ -1544,11 +1594,19 @@
             msg, 256, 0);
     if (len > 0) {
         status_string->value = new char[len + 20];
+        if (!status_string->value) {
+            status_string = GSS_C_NO_BUFFER;
+            return GSS_S_FAILURE;
+        }
         status_string->length = sprintf_s(
                 (LPSTR)status_string->value, len + 19,
                 "(%lx) %ls", status_value, msg);
     } else {
         status_string->value = new char[33];
+        if (!status_string->value) {
+            status_string = GSS_C_NO_BUFFER;
+            return GSS_S_FAILURE;
+        }
         status_string->length = sprintf_s(
                 (LPSTR)status_string->value, 32,
                 "status is %lx", status_value);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java	Thu Jan 16 04:09:50 2020 +0100
@@ -505,14 +505,15 @@
     /**
      * Attribute the given tree, mostly reverting side-effects applied to shared
      * compiler state. Exceptions include the ArgumentAttr.argumentTypeCache,
-     * changes to which may be preserved if localCache is null.
+     * changes to which may be preserved if localCache is null and errors reported
+     * outside of the speculatively attributed tree.
      */
     <Z> JCTree attribSpeculative(JCTree tree, Env<AttrContext> env, ResultInfo resultInfo,
                               Supplier<DiagnosticHandler> diagHandlerCreator, AttributionMode attributionMode,
                               LocalCacheContext localCache) {
         Env<AttrContext> speculativeEnv = env.dup(tree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner)));
         speculativeEnv.info.attributionMode = attributionMode;
-        Log.DiagnosticHandler deferredDiagnosticHandler = diagHandlerCreator != null ? diagHandlerCreator.get() : new DeferredDiagnosticHandler(log);
+        Log.DiagnosticHandler deferredDiagnosticHandler = diagHandlerCreator != null ? diagHandlerCreator.get() : new DeferredAttrDiagHandler(log, tree);
         DeferredCompletionFailureHandler.Handler prevCFHandler = dcfh.setHandler(dcfh.speculativeCodeHandler);
         Queues prevQueues = annotate.setQueues(new Queues());
         int nwarnings = log.nwarnings;
@@ -531,6 +532,35 @@
             }
         }
     }
+    //where
+        static class DeferredAttrDiagHandler extends Log.DeferredDiagnosticHandler {
+
+            static class PosScanner extends TreeScanner {
+                DiagnosticPosition pos;
+                boolean found = false;
+
+                PosScanner(DiagnosticPosition pos) {
+                    this.pos = pos;
+                }
+
+                @Override
+                public void scan(JCTree tree) {
+                    if (tree != null &&
+                            tree.pos() == pos) {
+                        found = true;
+                    }
+                    super.scan(tree);
+                }
+            }
+
+            DeferredAttrDiagHandler(Log log, JCTree newTree) {
+                super(log, d -> {
+                    PosScanner posScanner = new PosScanner(d.getDiagnosticPosition());
+                    posScanner.scan(newTree);
+                    return posScanner.found;
+                });
+            }
+        }
 
     /**
      * A deferred context is created on each method check. A deferred context is
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java	Thu Jan 16 04:09:50 2020 +0100
@@ -733,6 +733,8 @@
             container.close();
         }
         containers.clear();
+        pathsAndContainersByLocationAndRelativeDirectory.clear();
+        nonIndexingContainersByLocation.clear();
         contentCache.clear();
     }
 
--- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/AbstractLayout.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/AbstractLayout.java	Thu Jan 16 04:09:50 2020 +0100
@@ -93,6 +93,11 @@
     }
 
     @Override
+    public boolean hasSize() {
+        return size.isPresent();
+    }
+
+    @Override
     public long bitSize() {
         return size.orElseThrow(this::badSizeException);
     }
--- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java	Thu Jan 16 04:09:50 2020 +0100
@@ -31,7 +31,7 @@
 /**
  * A memory address encodes an offset within a given {@link MemorySegment}. Memory addresses are typically obtained
  * using the {@link MemorySegment#baseAddress()} method; such addresses can then be adjusted as required,
- * using {@link MemoryAddress#offset(long)}.
+ * using {@link MemoryAddress#addOffset(long)}.
  * <p>
  * A memory address is typically used as the first argument in a memory access var handle call, to perform some operation
  * on the underlying memory backing a given memory segment. Since a memory address is always associated with a memory segment,
@@ -53,11 +53,11 @@
  */
 public interface MemoryAddress {
     /**
-     * Creates a new memory address with given offset (in bytes) from current one.
-     * @param l specified offset (in bytes), relative to this address, which should be used to create the new address.
+     * Creates a new memory address with given offset (in bytes), which might be negative, from current one.
+     * @param offset specified offset (in bytes), relative to this address, which should be used to create the new address.
      * @return a new memory address with given offset from current one.
      */
-    MemoryAddress offset(long l);
+    MemoryAddress addOffset(long offset);
 
     /**
      * The offset of this memory address into the underlying segment.
--- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java	Thu Jan 16 04:09:50 2020 +0100
@@ -26,16 +26,21 @@
 package jdk.incubator.foreign;
 
 import jdk.internal.foreign.LayoutPath;
+import jdk.internal.foreign.LayoutPath.PathElementImpl.PathKind;
 import jdk.internal.foreign.Utils;
 
 import java.lang.constant.Constable;
 import java.lang.constant.DynamicConstantDesc;
 import java.lang.invoke.VarHandle;
 import java.nio.ByteOrder;
+import java.util.EnumSet;
 import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.OptionalLong;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.function.UnaryOperator;
 
 /**
  * A memory layout can be used to describe the contents of a memory segment in a <em>language neutral</em> fashion.
@@ -87,9 +92,11 @@
  * at a layout nested within the root layout - this is the layout <em>selected</em> by the layout path.
  * Layout paths are typically expressed as a sequence of one or more {@link PathElement} instances.
  * <p>
- * Layout paths are useful in order to e.g. to obtain offset of leaf elements inside arbitrarily nested layouts
- * (see {@link MemoryLayout#offset(PathElement...)}), or to quickly obtain a memory access handle corresponding to the selected
- * layout (see {@link MemoryLayout#varHandle(Class, PathElement...)}).
+ * Layout paths are for example useful in order to obtain offsets of arbitrarily nested layouts inside another layout
+ * (see {@link MemoryLayout#offset(PathElement...)}), to quickly obtain a memory access handle corresponding to the selected
+ * layout (see {@link MemoryLayout#varHandle(Class, PathElement...)}), to select an arbitrarily nested layout inside
+ * another layout (see {@link MemoryLayout#select(PathElement...)}, or to transform a nested layout element inside
+ * another layout (see {@link MemoryLayout#map(UnaryOperator, PathElement...)}).
  * <p>
  * Such <em>layout paths</em> can be constructed programmatically using the methods in this class.
  * For instance, given a layout constructed as follows:
@@ -106,11 +113,37 @@
 long valueOffset = seq.offset(PathElement.sequenceElement(), PathElement.groupElement("value"));
  * }</pre></blockquote>
  *
+ * Similarly, we can select the member layout named {@code value}, as follows:
+ * <blockquote><pre>{@code
+MemoryLayout value = seq.select(PathElement.sequenceElement(), PathElement.groupElement("value"));
+ * }</pre></blockquote>
+ *
+ * And, we can also replace the layout named {@code value} with another layout, as follows:
+ * <blockquote><pre>{@code
+MemoryLayout newSeq = seq.map(l -> MemoryLayout.ofPadding(32), PathElement.sequenceElement(), PathElement.groupElement("value"));
+ * }</pre></blockquote>
+ *
+ * That is, the above declaration is identical to the following, more verbose one:
+ * <blockquote><pre>{@code
+MemoryLayout newSeq = MemoryLayout.ofSequence(5,
+    MemoryLayout.ofStruct(
+        MemoryLayout.ofPaddingBits(32),
+        MemoryLayout.ofPaddingBits(32)
+));
+ * }</pre></blockquote>
+ *
  * Layout paths can feature one or more <em>free dimensions</em>. For instance, a layout path traversing
  * an unspecified sequence element (that is, where one of the path component was obtained with the
- * {@link PathElement#sequenceElement()} method) features an additional free dimension, which will have to be bound at runtime;
- * that is, the memory access var handle associated with such a layout path expression will feature an extra {@code long}
- * access coordinate. The layout path constructed in the above example features exactly one free dimension.
+ * {@link PathElement#sequenceElement()} method) features an additional free dimension, which will have to be bound at runtime.
+ * This is important when obtaining memory access var handle from layouts, as in the following code:
+ *
+ * <blockquote><pre>{@code
+VarHandle valueHandle = seq.map(int.class, PathElement.sequenceElement(), PathElement.groupElement("value"));
+ * }</pre></blockquote>
+ *
+ * Since the layout path {@code seq} constructed in the above example features exactly one free dimension,
+ * it follows that the memory access var handle {@code valueHandle} will feature an extra {@code long}
+ * access coordinate.
  *
  * @apiNote In the future, if the Java language permits, {@link MemoryLayout}
  * may become a {@code sealed} interface, which would prohibit subclassing except by
@@ -133,6 +166,17 @@
     Optional<? extends DynamicConstantDesc<? extends MemoryLayout>> describeConstable();
 
     /**
+     * Does this layout have a specified size? A layout does not have a specified size if it is (or contains) a sequence layout whose
+     * size is unspecified (see {@link SequenceLayout#elementCount()}).
+     *
+     * Value layouts (see {@link ValueLayout}) and padding layouts (see {@link MemoryLayout#ofPaddingBits(long)})
+     * <em>always</em> have a specified size, therefore this method always returns {@code true} in these cases.
+     *
+     * @return {@code true}, if this layout has a specified size.
+     */
+    boolean hasSize();
+
+    /**
      * Computes the layout size, in bits.
      *
      * @return the layout size, in bits.
@@ -219,23 +263,21 @@
     MemoryLayout withBitAlignment(long bitAlignment);
 
     /**
-     * Computes the offset of the layout selected by a given layout path, where the path is considered rooted in this
+     * Computes the offset, in bits, of the layout selected by a given layout path, where the path is considered rooted in this
      * layout.
      *
      * @apiNote if the layout path has one (or more) free dimensions,
      * the offset is computed as if all the indices corresponding to such dimensions were set to {@code 0}.
      *
      * @param elements the layout path elements.
-     * @return The offset of layout selected by a the layout path obtained by concatenating the path elements in {@code elements}.
-     * @throws IllegalArgumentException if the layout path obtained by concatenating the path elements in {@code elements}
-     * does not select a valid layout element.
+     * @return The offset, in bits, of the layout selected by the layout path in {@code elements}.
+     * @throws IllegalArgumentException if the layout path does not select any layout nested in this layout, or if the
+     * layout path contains one or more path elements that select multiple sequence element indices
+     * (see {@link PathElement#sequenceElement()} and {@link PathElement#sequenceElement(long, long)}).
+     * @throws UnsupportedOperationException if one of the layouts traversed by the layout path has unspecified size.
      */
     default long offset(PathElement... elements) {
-        LayoutPath path = LayoutPath.rootPath(this);
-        for (PathElement e : elements) {
-            path = ((LayoutPath.PathElementImpl)e).apply(path);
-        }
-        return path.offset();
+        return computePathOp(LayoutPath.rootPath(this, MemoryLayout::bitSize), LayoutPath::offset, EnumSet.of(PathKind.SEQUENCE_ELEMENT, PathKind.SEQUENCE_RANGE), elements);
     }
 
     /**
@@ -248,19 +290,59 @@
      *
      * @param carrier the var handle carrier type.
      * @param elements the layout path elements.
-     * @return a var handle which can be used to dereference memory at the layout denoted by given layout path.
-     * @throws UnsupportedOperationException if the layout path has one or more elements with incompatible alignment constraints.
+     * @return a var handle which can be used to dereference memory at the (possibly nested) layout selected by the layout path in {@code elements}.
+     * @throws UnsupportedOperationException if the layout path has one or more elements with incompatible alignment constraints,
+     * or if one of the layouts traversed by the layout path has unspecified size.
      * @throws IllegalArgumentException if the carrier does not represent a primitive type, if the carrier is {@code void},
-     * {@code boolean}, or if the layout path obtained by concatenating the path elements in {@code elements}
-     * does not select a value layout (see {@link ValueLayout}), or if the selected value layout has a size that
-     * that does not match that of the specified carrier type.
+     * {@code boolean}, or if the layout path in {@code elements} does not select a value layout (see {@link ValueLayout}),
+     * or if the selected value layout has a size that that does not match that of the specified carrier type.
      */
     default VarHandle varHandle(Class<?> carrier, PathElement... elements) {
-        LayoutPath path = LayoutPath.rootPath(this);
+        return computePathOp(LayoutPath.rootPath(this, MemoryLayout::bitSize), path -> path.dereferenceHandle(carrier),
+                Set.of(), elements);
+    }
+
+    /**
+     * Selects the layout from a path rooted in this layout.
+     *
+     * @param elements the layout path elements.
+     * @return the layout selected by the layout path in {@code elements}.
+     * @throws IllegalArgumentException if the layout path does not select any layout nested in this layout,
+     * or if the layout path contains one or more path elements that select one or more sequence element indices
+     * (see {@link PathElement#sequenceElement(long)} and {@link PathElement#sequenceElement(long, long)}).
+     */
+    default MemoryLayout select(PathElement... elements) {
+        return computePathOp(LayoutPath.rootPath(this, l -> 0L), LayoutPath::layout,
+                EnumSet.of(PathKind.SEQUENCE_ELEMENT_INDEX, PathKind.SEQUENCE_RANGE), elements);
+    }
+
+    /**
+     * Creates a transformed copy of this layout where a selected layout, from a path rooted in this layout,
+     * is replaced with the result of applying the given operation.
+     *
+     * @param op the unary operation to be applied to the selected layout.
+     * @param elements the layout path elements.
+     * @return a new layout where the layout selected by the layout path in {@code elements},
+     * has been replaced by the result of applying {@code op} to the selected layout.
+     * @throws IllegalArgumentException if the layout path does not select any layout nested in this layout,
+     * or if the layout path contains one or more path elements that select one or more sequence element indices
+     * (see {@link PathElement#sequenceElement(long)} and {@link PathElement#sequenceElement(long, long)}).
+     */
+    default MemoryLayout map(UnaryOperator<MemoryLayout> op, PathElement... elements) {
+        return computePathOp(LayoutPath.rootPath(this, l -> 0L), path -> path.map(op),
+                EnumSet.of(PathKind.SEQUENCE_ELEMENT_INDEX, PathKind.SEQUENCE_RANGE), elements);
+    }
+
+    private static <Z> Z computePathOp(LayoutPath path, Function<LayoutPath, Z> finalizer,
+                                       Set<LayoutPath.PathElementImpl.PathKind> badKinds, PathElement... elements) {
         for (PathElement e : elements) {
-            path = ((LayoutPath.PathElementImpl)e).apply(path);
+            LayoutPath.PathElementImpl pathElem = (LayoutPath.PathElementImpl)e;
+            if (badKinds.contains(pathElem.kind())) {
+                throw new IllegalArgumentException(String.format("Invalid %s selection in layout path", pathElem.kind().description()));
+            }
+            path = pathElem.apply(path);
         }
-        return path.dereferenceHandle(carrier);
+        return finalizer.apply(path);
     }
 
     /**
@@ -297,7 +379,8 @@
          */
         static PathElement groupElement(String name) {
             Objects.requireNonNull(name);
-            return new LayoutPath.PathElementImpl(path -> path.groupElement(name));
+            return new LayoutPath.PathElementImpl(LayoutPath.PathElementImpl.PathKind.GROUP_ELEMENT,
+                                                  path -> path.groupElement(name));
         }
 
         /**
@@ -313,7 +396,8 @@
             if (index < 0) {
                 throw new IllegalArgumentException("Index must be positive: " + index);
             }
-            return new LayoutPath.PathElementImpl(path -> path.sequenceElement(index));
+            return new LayoutPath.PathElementImpl(LayoutPath.PathElementImpl.PathKind.SEQUENCE_ELEMENT_INDEX,
+                                                  path -> path.sequenceElement(index));
         }
 
         /**
@@ -341,7 +425,8 @@
             if (step == 0) {
                 throw new IllegalArgumentException("Step must be != 0: " + step);
             }
-            return new LayoutPath.PathElementImpl(path -> path.sequenceElement(start, step));
+            return new LayoutPath.PathElementImpl(LayoutPath.PathElementImpl.PathKind.SEQUENCE_RANGE,
+                                                  path -> path.sequenceElement(start, step));
         }
 
         /**
@@ -352,7 +437,8 @@
          * @return a path element which selects an unspecified sequence element layout.
          */
         static PathElement sequenceElement() {
-            return new LayoutPath.PathElementImpl(LayoutPath::sequenceElement);
+            return new LayoutPath.PathElementImpl(LayoutPath.PathElementImpl.PathKind.SEQUENCE_ELEMENT,
+                                                  LayoutPath::sequenceElement);
         }
     }
 
--- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayouts.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayouts.java	Thu Jan 16 04:09:50 2020 +0100
@@ -32,7 +32,7 @@
  * This class defines useful layout constants. Some of the constants defined in this class are explicit in both
  * size and byte order (see {@link #BITS_64_BE}), and can therefore be used to explicitly and unambiguously specify the
  * contents of a memory segment. Other constants make implicit byte order assumptions (see
- * {@link #JAVA_INT}); as such, these constants make it easy to interoperate with other serialization-centric APIs,
+ * {@link #JAVA_INT}); as such, these constants make it easy to work with other serialization-centric APIs,
  * such as {@link java.nio.ByteBuffer}.
  */
 public final class MemoryLayouts {
--- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java	Thu Jan 16 04:09:50 2020 +0100
@@ -145,10 +145,10 @@
     MemorySegment acquire();
 
     /**
-     * Is this segment accessible from the current thread?
-     * @return true, if this segment is accessible from the current thread.
+     * The thread owning this segment.
+     * @return the thread owning this segment.
      */
-    boolean isAccessible();
+    Thread ownerThread();
 
     /**
      * The size (in bytes) of this memory segment.
--- a/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java	Thu Jan 16 04:09:50 2020 +0100
@@ -95,6 +95,18 @@
         return elemCount;
     }
 
+    /**
+     * Obtains a new sequence layout with same element layout, alignment constraints and name as this sequence layout
+     * but with the new specified element count.
+     * @param elementCount the new element count.
+     * @return a new sequence with given element count.
+     * @throws IllegalArgumentException if {@code elementCount < 0}.
+     */
+    public SequenceLayout withElementCount(long elementCount) {
+        AbstractLayout.checkSize(elementCount, true);
+        return new SequenceLayout(OptionalLong.of(elementCount), elementLayout, alignment, name());
+    }
+
     @Override
     public String toString() {
         return decorateLayoutString(String.format("[%s:%s]",
--- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/LayoutPath.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/LayoutPath.java	Thu Jan 16 04:09:50 2020 +0100
@@ -34,6 +34,9 @@
 import jdk.incubator.foreign.SequenceLayout;
 import jdk.incubator.foreign.ValueLayout;
 import java.lang.invoke.VarHandle;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.ToLongFunction;
 import java.util.function.UnaryOperator;
 import java.util.stream.LongStream;
 
@@ -53,12 +56,16 @@
     private final long offset;
     private final LayoutPath enclosing;
     private final long[] strides;
+    private final long elementIndex;
+    private final ToLongFunction<MemoryLayout> sizeFunc;
 
-    private LayoutPath(MemoryLayout layout, long offset, long[] strides, LayoutPath enclosing) {
+    private LayoutPath(MemoryLayout layout, long offset, long[] strides, long elementIndex, LayoutPath enclosing, ToLongFunction<MemoryLayout> sizeFunc) {
         this.layout = layout;
         this.offset = offset;
         this.strides = strides;
         this.enclosing = enclosing;
+        this.elementIndex = elementIndex;
+        this.sizeFunc = sizeFunc;
     }
 
     // Layout path selector methods
@@ -67,7 +74,7 @@
         check(SequenceLayout.class, "attempting to select a sequence element from a non-sequence layout");
         SequenceLayout seq = (SequenceLayout)layout;
         MemoryLayout elem = seq.elementLayout();
-        return LayoutPath.nestedPath(elem, offset, addStride(elem.bitSize()), this);
+        return LayoutPath.nestedPath(elem, offset, addStride(sizeFunc.applyAsLong(elem)), -1, this);
     }
 
     public LayoutPath sequenceElement(long start, long step) {
@@ -75,8 +82,8 @@
         SequenceLayout seq = (SequenceLayout)layout;
         checkSequenceBounds(seq, start);
         MemoryLayout elem = seq.elementLayout();
-        long elemSize = elem.bitSize();
-        return LayoutPath.nestedPath(elem, offset + (start * elemSize), addStride(elemSize * step), this);
+        long elemSize = sizeFunc.applyAsLong(elem);
+        return LayoutPath.nestedPath(elem, offset + (start * elemSize), addStride(elemSize * step), -1, this);
     }
 
     public LayoutPath sequenceElement(long index) {
@@ -86,10 +93,10 @@
         long elemOffset = 0;
         if (index > 0) {
             //if index == 0, we do not depend on sequence element size, so skip
-            long elemSize = seq.elementLayout().bitSize();
+            long elemSize = sizeFunc.applyAsLong(seq.elementLayout());
             elemOffset = elemSize * index;
         }
-        return LayoutPath.nestedPath(seq.elementLayout(), offset + elemOffset, strides, this);
+        return LayoutPath.nestedPath(seq.elementLayout(), offset + elemOffset, strides, index, this);
     }
 
     public LayoutPath groupElement(String name) {
@@ -97,20 +104,22 @@
         GroupLayout g = (GroupLayout)layout;
         long offset = 0;
         MemoryLayout elem = null;
+        int index = -1;
         for (int i = 0; i < g.memberLayouts().size(); i++) {
             MemoryLayout l = g.memberLayouts().get(i);
             if (l.name().isPresent() &&
                 l.name().get().equals(name)) {
                 elem = l;
+                index = i;
                 break;
-            } else {
-                offset += l.bitSize();
+            } else if (g.isStruct()) {
+                offset += sizeFunc.applyAsLong(l);
             }
         }
         if (elem == null) {
             throw badLayoutPath("cannot resolve '" + name + "' in layout " + layout);
         }
-        return LayoutPath.nestedPath(elem, this.offset + offset, strides, this);
+        return LayoutPath.nestedPath(elem, this.offset + offset, strides, index, this);
     }
 
     // Layout path projections
@@ -139,14 +148,52 @@
                 LongStream.of(strides).map(s -> Utils.bitsToBytesOrThrow(s, IllegalStateException::new)).toArray());
     }
 
+    public MemoryLayout layout() {
+        return layout;
+    }
+
+    public MemoryLayout map(UnaryOperator<MemoryLayout> op) {
+        MemoryLayout newLayout = op.apply(layout);
+        if (enclosing == null) {
+            return newLayout;
+        } else if (enclosing.layout instanceof SequenceLayout) {
+            SequenceLayout seq = (SequenceLayout)enclosing.layout;
+            if (seq.elementCount().isPresent()) {
+                return enclosing.map(l -> dup(l, MemoryLayout.ofSequence(seq.elementCount().getAsLong(), newLayout)));
+            } else {
+                return enclosing.map(l -> dup(l, MemoryLayout.ofSequence(newLayout)));
+            }
+        } else if (enclosing.layout instanceof GroupLayout) {
+            GroupLayout g = (GroupLayout)enclosing.layout;
+            List<MemoryLayout> newElements = new ArrayList<>(g.memberLayouts());
+            //if we selected a layout in a group we must have a valid index
+            newElements.set((int)elementIndex, newLayout);
+            if (g.isUnion()) {
+                return enclosing.map(l -> dup(l, MemoryLayout.ofUnion(newElements.toArray(new MemoryLayout[0]))));
+            } else {
+                return enclosing.map(l -> dup(l, MemoryLayout.ofStruct(newElements.toArray(new MemoryLayout[0]))));
+            }
+        } else {
+            return newLayout;
+        }
+    }
+
+    private MemoryLayout dup(MemoryLayout oldLayout, MemoryLayout newLayout) {
+        newLayout = newLayout.withBitAlignment(oldLayout.bitAlignment());
+        if (oldLayout.name().isPresent()) {
+            newLayout.withName(oldLayout.name().get());
+        }
+        return newLayout;
+    }
+
     // Layout path construction
 
-    public static LayoutPath rootPath(MemoryLayout layout) {
-        return new LayoutPath(layout, 0L, EMPTY_STRIDES, null);
+    public static LayoutPath rootPath(MemoryLayout layout, ToLongFunction<MemoryLayout> sizeFunc) {
+        return new LayoutPath(layout, 0L, EMPTY_STRIDES, -1, null, sizeFunc);
     }
 
-    private static LayoutPath nestedPath(MemoryLayout layout, long offset, long[] strides, LayoutPath encl) {
-        return new LayoutPath(layout, offset, strides, encl);
+    private static LayoutPath nestedPath(MemoryLayout layout, long offset, long[] strides, long elementIndex, LayoutPath encl) {
+        return new LayoutPath(layout, offset, strides, elementIndex, encl, encl.sizeFunc);
     }
 
     // Helper methods
@@ -202,9 +249,28 @@
      */
     public static class PathElementImpl implements MemoryLayout.PathElement, UnaryOperator<LayoutPath> {
 
+        public enum PathKind {
+            SEQUENCE_ELEMENT("unbound sequence element"),
+            SEQUENCE_ELEMENT_INDEX("bound sequence element"),
+            SEQUENCE_RANGE("sequence range"),
+            GROUP_ELEMENT("group element");
+
+            final String description;
+
+            PathKind(String description) {
+                this.description = description;
+            }
+
+            public String description() {
+                return description;
+            }
+        }
+
+        final PathKind kind;
         final UnaryOperator<LayoutPath> pathOp;
 
-        public PathElementImpl(UnaryOperator<LayoutPath> pathOp) {
+        public PathElementImpl(PathKind kind, UnaryOperator<LayoutPath> pathOp) {
+            this.kind = kind;
             this.pathOp = pathOp;
         }
 
@@ -212,5 +278,9 @@
         public LayoutPath apply(LayoutPath layoutPath) {
             return pathOp.apply(layoutPath);
         }
+
+        public PathKind kind() {
+            return kind;
+        }
     }
 }
--- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/MemoryAddressImpl.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/MemoryAddressImpl.java	Thu Jan 16 04:09:50 2020 +0100
@@ -74,7 +74,7 @@
     }
 
     @Override
-    public MemoryAddress offset(long bytes) {
+    public MemoryAddress addOffset(long bytes) {
         return new MemoryAddressImpl(segment, offset + bytes);
     }
 
--- a/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/MemorySegmentImpl.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/MemorySegmentImpl.java	Thu Jan 16 04:09:50 2020 +0100
@@ -110,8 +110,8 @@
     }
 
     @Override
-    public boolean isAccessible() {
-        return owner == Thread.currentThread();
+    public Thread ownerThread() {
+        return owner;
     }
 
     @Override
--- a/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Base.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2017, 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
@@ -106,8 +106,12 @@
         }
 
         try {
-            MessageProp msgProp = new MessageProp(JGSS_QOP, privacy);
+            MessageProp msgProp = new MessageProp(JGSS_QOP, false);
             byte[] answer = secCtx.unwrap(incoming, start, len, msgProp);
+            if (privacy && !msgProp.getPrivacy()) {
+                throw new SaslException("Privacy not protected");
+            }
+            checkMessageProp("", msgProp);
             if (logger.isLoggable(Level.FINEST)) {
                 traceOutput(myClassName, "KRB501:Unwrap", "incoming: ",
                     incoming, start, len);
@@ -162,4 +166,20 @@
     protected void finalize() throws Throwable {
         dispose();
     }
+
+    void checkMessageProp(String label, MessageProp msgProp)
+            throws SaslException {
+        if (msgProp.isDuplicateToken()) {
+            throw new SaslException(label + "Duplicate token");
+        }
+        if (msgProp.isGapToken()) {
+            throw new SaslException(label + "Gap token");
+        }
+        if (msgProp.isOldToken()) {
+            throw new SaslException(label + "Old token");
+        }
+        if (msgProp.isUnseqToken()) {
+            throw new SaslException(label + "Token not in sequence");
+        }
+    }
 }
--- a/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Client.java	Thu Jan 16 04:09:50 2020 +0100
@@ -228,8 +228,10 @@
 
             // Received S1 (security layer, server max recv size)
 
+            MessageProp msgProp = new MessageProp(false);
             byte[] gssOutToken = secCtx.unwrap(challengeData, 0,
-                challengeData.length, new MessageProp(0, false));
+                challengeData.length, msgProp);
+            checkMessageProp("Handshake failure: ", msgProp);
 
             // First octet is a bit-mask specifying the protections
             // supported by the server
--- a/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/GssKrb5Server.java	Thu Jan 16 04:09:50 2020 +0100
@@ -252,8 +252,10 @@
         try {
             // Expecting 4 octets from client selected protection
             // and client's receive buffer size
+            MessageProp msgProp = new MessageProp(false);
             byte[] gssOutToken = secCtx.unwrap(responseData, 0,
-                responseData.length, new MessageProp(0, false));
+                responseData.length, msgProp);
+            checkMessageProp("Handshake failure: ", msgProp);
 
             if (logger.isLoggable(Level.FINER)) {
                 traceOutput(MY_CLASS_NAME, "doHandshake2",
--- a/test/hotspot/jtreg/ProblemList-aot.txt	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/hotspot/jtreg/ProblemList-aot.txt	Thu Jan 16 04:09:50 2020 +0100
@@ -81,3 +81,5 @@
 compiler/intrinsics/sha/sanity/TestSHA1MultiBlockIntrinsics.java    8167430 generic-all
 compiler/intrinsics/sha/sanity/TestSHA512MultiBlockIntrinsics.java  8167430 generic-all
 
+vmTestbase/vm/mlvm/indy/stress/java/relinkMutableCallSiteFreq/Test.java   8226689 generic-all
+vmTestbase/vm/mlvm/indy/stress/java/relinkVolatileCallSiteFreq/Test.java  8226689 generic-all
--- a/test/jdk/java/foreign/TestLayoutPaths.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/java/foreign/TestLayoutPaths.java	Thu Jan 16 04:09:50 2020 +0100
@@ -34,6 +34,10 @@
 import jdk.incubator.foreign.SequenceLayout;
 
 import org.testng.annotations.*;
+
+import java.util.List;
+import java.util.function.Function;
+
 import static org.testng.Assert.*;
 
 public class TestLayoutPaths {
@@ -133,5 +137,146 @@
             throw new AssertionError(ex); //should fail!
         }
     }
+
+    @Test
+    public void testBadSequencePathInOffset() {
+        SequenceLayout seq = MemoryLayout.ofSequence(10, MemoryLayouts.JAVA_INT);
+        // bad path elements
+        for (PathElement e : List.of( PathElement.sequenceElement(), PathElement.sequenceElement(0, 2) )) {
+            try {
+                seq.offset(e);
+                fail();
+            } catch (IllegalArgumentException ex) {
+                assertTrue(true);
+            }
+        }
+    }
+
+    @Test
+    public void testBadSequencePathInSelect() {
+        SequenceLayout seq = MemoryLayout.ofSequence(10, MemoryLayouts.JAVA_INT);
+        for (PathElement e : List.of( PathElement.sequenceElement(0), PathElement.sequenceElement(0, 2) )) {
+            try {
+                seq.select(e);
+                fail();
+            } catch (IllegalArgumentException ex) {
+                assertTrue(true);
+            }
+        }
+    }
+
+    @Test
+    public void testBadSequencePathInMap() {
+        SequenceLayout seq = MemoryLayout.ofSequence(10, MemoryLayouts.JAVA_INT);
+        for (PathElement e : List.of( PathElement.sequenceElement(0), PathElement.sequenceElement(0, 2) )) {
+            try {
+                seq.map(l -> l, e);
+                fail();
+            } catch (IllegalArgumentException ex) {
+                assertTrue(true);
+            }
+        }
+    }
+
+    @Test
+    public void testStructPaths() {
+        long[] offsets = { 0, 8, 24, 56 };
+        GroupLayout g = MemoryLayout.ofStruct(
+                MemoryLayouts.JAVA_BYTE.withName("1"),
+                MemoryLayouts.JAVA_CHAR.withName("2"),
+                MemoryLayouts.JAVA_FLOAT.withName("3"),
+                MemoryLayouts.JAVA_LONG.withName("4")
+        );
+
+        // test select
+
+        for (int i = 1 ; i <= 4 ; i++) {
+            MemoryLayout selected = g.select(PathElement.groupElement(String.valueOf(i)));
+            assertTrue(selected == g.memberLayouts().get(i - 1));
+        }
+
+        // test offset
+
+        for (int i = 1 ; i <= 4 ; i++) {
+            long offset = g.offset(PathElement.groupElement(String.valueOf(i)));
+            assertEquals(offsets[i - 1], offset);
+        }
+
+        // test map
+
+        for (int i = 1 ; i <= 4 ; i++) {
+            GroupLayout g2 = (GroupLayout)g.map(l -> MemoryLayouts.JAVA_DOUBLE, PathElement.groupElement(String.valueOf(i)));
+            assertTrue(g2.isStruct());
+            for (int j = 0 ; j < 4 ; j++) {
+                if (j == i - 1) {
+                    assertEquals(g2.memberLayouts().get(j), MemoryLayouts.JAVA_DOUBLE);
+                } else {
+                    assertEquals(g2.memberLayouts().get(j), g.memberLayouts().get(j));
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testUnionPaths() {
+        long[] offsets = { 0, 0, 0, 0 };
+        GroupLayout g = MemoryLayout.ofUnion(
+                MemoryLayouts.JAVA_BYTE.withName("1"),
+                MemoryLayouts.JAVA_CHAR.withName("2"),
+                MemoryLayouts.JAVA_FLOAT.withName("3"),
+                MemoryLayouts.JAVA_LONG.withName("4")
+        );
+
+        // test select
+
+        for (int i = 1 ; i <= 4 ; i++) {
+            MemoryLayout selected = g.select(PathElement.groupElement(String.valueOf(i)));
+            assertTrue(selected == g.memberLayouts().get(i - 1));
+        }
+
+        // test offset
+
+        for (int i = 1 ; i <= 4 ; i++) {
+            long offset = g.offset(PathElement.groupElement(String.valueOf(i)));
+            assertEquals(offsets[i - 1], offset);
+        }
+
+        // test map
+
+        for (int i = 1 ; i <= 4 ; i++) {
+            GroupLayout g2 = (GroupLayout)g.map(l -> MemoryLayouts.JAVA_DOUBLE, PathElement.groupElement(String.valueOf(i)));
+            assertTrue(g2.isUnion());
+            for (int j = 0 ; j < 4 ; j++) {
+                if (j == i - 1) {
+                    assertEquals(g2.memberLayouts().get(j), MemoryLayouts.JAVA_DOUBLE);
+                } else {
+                    assertEquals(g2.memberLayouts().get(j), g.memberLayouts().get(j));
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testSequencePaths() {
+        long[] offsets = { 0, 8, 16, 24 };
+        SequenceLayout g = MemoryLayout.ofSequence(4, MemoryLayouts.JAVA_BYTE);
+
+        // test select
+
+        MemoryLayout selected = g.select(PathElement.sequenceElement());
+        assertTrue(selected == MemoryLayouts.JAVA_BYTE);
+
+        // test offset
+
+        for (int i = 0 ; i < 4 ; i++) {
+            long offset = g.offset(PathElement.sequenceElement(i));
+            assertEquals(offsets[i], offset);
+        }
+
+        // test map
+
+        SequenceLayout seq2 = (SequenceLayout)g.map(l -> MemoryLayouts.JAVA_DOUBLE, PathElement.sequenceElement());
+        assertTrue(seq2.elementLayout() == MemoryLayouts.JAVA_DOUBLE);
+    }
 }
 
--- a/test/jdk/java/foreign/TestLayouts.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/java/foreign/TestLayouts.java	Thu Jan 16 04:09:50 2020 +0100
@@ -34,6 +34,7 @@
 import java.util.function.LongFunction;
 
 import jdk.incubator.foreign.MemorySegment;
+import jdk.incubator.foreign.SequenceLayout;
 import org.testng.annotations.*;
 import static org.testng.Assert.*;
 
@@ -55,11 +56,13 @@
                 MemoryLayouts.JAVA_INT.withName("size"),
                 MemoryLayout.ofPaddingBits(32),
                 MemoryLayout.ofSequence(MemoryLayouts.JAVA_DOUBLE).withName("arr"));
+        assertFalse(layout.hasSize());
         VarHandle size_handle = layout.varHandle(int.class, MemoryLayout.PathElement.groupElement("size"));
         VarHandle array_elem_handle = layout.varHandle(double.class,
                 MemoryLayout.PathElement.groupElement("arr"),
                 MemoryLayout.PathElement.sequenceElement());
-        try (MemorySegment segment = MemorySegment.allocateNative(8 + 8 * 4)) {
+        try (MemorySegment segment = MemorySegment.allocateNative(
+                layout.map(l -> ((SequenceLayout)l).withElementCount(4), MemoryLayout.PathElement.groupElement("arr")))) {
             size_handle.set(segment.baseAddress(), 4);
             for (int i = 0 ; i < 4 ; i++) {
                 array_elem_handle.set(segment.baseAddress(), i, (double)i);
@@ -78,12 +81,14 @@
                 MemoryLayouts.JAVA_INT.withName("size"),
                 MemoryLayout.ofPaddingBits(32),
                 MemoryLayout.ofSequence(1, MemoryLayout.ofSequence(MemoryLayouts.JAVA_DOUBLE)).withName("arr"));
+        assertFalse(layout.hasSize());
         VarHandle size_handle = layout.varHandle(int.class, MemoryLayout.PathElement.groupElement("size"));
         VarHandle array_elem_handle = layout.varHandle(double.class,
                 MemoryLayout.PathElement.groupElement("arr"),
                 MemoryLayout.PathElement.sequenceElement(0),
                 MemoryLayout.PathElement.sequenceElement());
-        try (MemorySegment segment = MemorySegment.allocateNative(8 + 8 * 4)) {
+        try (MemorySegment segment = MemorySegment.allocateNative(
+                layout.map(l -> ((SequenceLayout)l).withElementCount(4), MemoryLayout.PathElement.groupElement("arr"), MemoryLayout.PathElement.sequenceElement()))) {
             size_handle.set(segment.baseAddress(), 4);
             for (int i = 0 ; i < 4 ; i++) {
                 array_elem_handle.set(segment.baseAddress(), i, (double)i);
@@ -135,6 +140,18 @@
         layout.hashCode();
     }
 
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testBadUnboundSequenceLayoutResize() {
+        SequenceLayout seq = MemoryLayout.ofSequence(MemoryLayouts.JAVA_INT);
+        seq.withElementCount(-1);
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testBadBoundSequenceLayoutResize() {
+        SequenceLayout seq = MemoryLayout.ofSequence(10, MemoryLayouts.JAVA_INT);
+        seq.withElementCount(-1);
+    }
+
     @Test
     public void testEmptyGroup() {
         MemoryLayout struct = MemoryLayout.ofStruct();
--- a/test/jdk/java/foreign/TestMemoryAccess.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/java/foreign/TestMemoryAccess.java	Thu Jan 16 04:09:50 2020 +0100
@@ -94,7 +94,7 @@
                 return;
             }
             try {
-                checker.check(handle, addr.offset(layout.byteSize()));
+                checker.check(handle, addr.addOffset(layout.byteSize()));
                 throw new AssertionError(); //not ok, out of bounds
             } catch (IndexOutOfBoundsException ex) {
                 //ok, should fail (out of bounds)
--- a/test/jdk/java/foreign/TestMemoryAlignment.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/java/foreign/TestMemoryAlignment.java	Thu Jan 16 04:09:50 2020 +0100
@@ -69,7 +69,7 @@
         VarHandle vh = aligned.varHandle(int.class);
         try (MemorySegment segment = MemorySegment.allocateNative(alignedGroup)) {
             MemoryAddress addr = segment.baseAddress();
-            vh.set(addr.offset(1L), -42);
+            vh.set(addr.addOffset(1L), -42);
             assertEquals(align, 8); //this is the only case where access is aligned
         } catch (IllegalStateException ex) {
             assertNotEquals(align, 8); //if align != 8, access is always unaligned
--- a/test/jdk/java/foreign/TestMemoryCopy.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/java/foreign/TestMemoryCopy.java	Thu Jan 16 04:09:50 2020 +0100
@@ -28,7 +28,6 @@
  */
 
 import jdk.incubator.foreign.MemoryAddress;
-import jdk.incubator.foreign.MemoryHandles;
 import jdk.incubator.foreign.MemoryLayouts;
 import jdk.incubator.foreign.MemorySegment;
 import org.testng.annotations.DataProvider;
@@ -36,11 +35,8 @@
 
 import java.lang.invoke.VarHandle;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.function.IntFunction;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
 
 import static org.testng.Assert.*;
 
@@ -55,16 +51,16 @@
         int size = Math.min(s1.size(), s2.size());
         //prepare source and target segments
         for (int i = 0 ; i < size ; i++) {
-            BYTE_HANDLE.set(addr2.offset(i), (byte)0);
+            BYTE_HANDLE.set(addr2.addOffset(i), (byte)0);
         }
         for (int i = 0 ; i < size ; i++) {
-            BYTE_HANDLE.set(addr1.offset(i), (byte) i);
+            BYTE_HANDLE.set(addr1.addOffset(i), (byte) i);
         }
         //perform copy
         MemoryAddress.copy(addr1, addr2, size);
         //check that copy actually worked
         for (int i = 0 ; i < size ; i++) {
-            assertEquals((byte)i, BYTE_HANDLE.get(addr2.offset(i)));
+            assertEquals((byte)i, BYTE_HANDLE.get(addr2.addOffset(i)));
         }
     }
 
--- a/test/jdk/java/foreign/TestSegments.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/java/foreign/TestSegments.java	Thu Jan 16 04:09:50 2020 +0100
@@ -26,11 +26,11 @@
  * @run testng TestSegments
  */
 
+import jdk.incubator.foreign.MemoryAddress;
 import jdk.incubator.foreign.MemoryLayout;
 import jdk.incubator.foreign.MemoryLayouts;
 import jdk.incubator.foreign.MemorySegment;
 
-import java.awt.font.LayoutPath;
 import java.lang.invoke.VarHandle;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
@@ -41,7 +41,6 @@
 import java.util.function.LongFunction;
 import java.util.stream.Stream;
 
-import jdk.incubator.foreign.SequenceLayout;
 import org.testng.annotations.*;
 
 import static org.testng.Assert.*;
@@ -96,6 +95,32 @@
         }
     }
 
+    @Test
+    public void testSlices() {
+        VarHandle byteHandle = MemoryLayout.ofSequence(MemoryLayouts.JAVA_BYTE)
+                .varHandle(byte.class, MemoryLayout.PathElement.sequenceElement());
+        try (MemorySegment segment = MemorySegment.allocateNative(10)) {
+            //init
+            for (byte i = 0 ; i < segment.byteSize() ; i++) {
+                byteHandle.set(segment.baseAddress(), (long)i, i);
+            }
+            long start = 0;
+            MemoryAddress base = segment.baseAddress();
+            MemoryAddress last = base.addOffset(10);
+            while (!base.equals(last)) {
+                MemorySegment slice = segment.asSlice(base.offset(), 10 - start);
+                for (long i = start ; i < 10 ; i++) {
+                    assertEquals(
+                            byteHandle.get(segment.baseAddress(), i),
+                            byteHandle.get(slice.baseAddress(), i - start)
+                    );
+                }
+                base = base.addOffset(1);
+                start++;
+            }
+        }
+    }
+
     @DataProvider(name = "badSizeAndAlignments")
     public Object[][] sizesAndAlignments() {
         return new Object[][] {
--- a/test/jdk/java/foreign/TestVarHandleCombinators.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/java/foreign/TestVarHandleCombinators.java	Thu Jan 16 04:09:50 2020 +0100
@@ -162,7 +162,7 @@
                 for (long j = 0; j < inner_size; j++) {
                     outer_vh.set(segment.baseAddress(), i, j, count);
                     assertEquals(
-                            (int)inner_vh.get(segment.baseAddress().offset(i * inner_size * 8), j),
+                            (int)inner_vh.get(segment.baseAddress().addOffset(i * inner_size * 8), j),
                             count);
                     count++;
                 }
--- a/test/jdk/java/io/Reader/TransferTo.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/java/io/Reader/TransferTo.java	Thu Jan 16 04:09:50 2020 +0100
@@ -6,15 +6,15 @@
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.
  *
- * This code is distributed source the hope that it will be useful, but WITHOUT
+ * 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 source the LICENSE file that
+ * 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 Franklsource St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 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
--- a/test/jdk/java/io/Serializable/serialFilter/GlobalFilterTest.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/java/io/Serializable/serialFilter/GlobalFilterTest.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 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
@@ -41,9 +41,11 @@
 import org.testng.annotations.DataProvider;
 
 /* @test
+ * @bug 8231422
  * @build GlobalFilterTest SerialFilterTest
  * @run testng/othervm GlobalFilterTest
- * @run testng/othervm -Djdk.serialFilter=java.** GlobalFilterTest
+ * @run testng/othervm -Djdk.serialFilter=java.**
+ *          -Dexpected-jdk.serialFilter=java.** GlobalFilterTest
  * @run testng/othervm/policy=security.policy GlobalFilterTest
  * @run testng/othervm/policy=security.policy
  *        -Djava.security.properties=${test.src}/java.security-extra1
@@ -53,6 +55,10 @@
  */
 @Test
 public class GlobalFilterTest {
+    private static final String serialPropName = "jdk.serialFilter";
+    private static final String badSerialFilter = "java.lang.StringBuffer;!*";
+    private static final String origSerialFilterProperty =
+            System.setProperty(serialPropName, badSerialFilter);
 
     /**
      * DataProvider of patterns and objects derived from the configured process-wide filter.
@@ -61,8 +67,8 @@
     @DataProvider(name="globalPatternElements")
     Object[][] globalPatternElements() {
         String globalFilter =
-                System.getProperty("jdk.serialFilter",
-                        Security.getProperty("jdk.serialFilter"));
+                System.getProperty("expected-" + serialPropName,
+                        Security.getProperty(serialPropName));
         if (globalFilter == null) {
             return new Object[0][];
         }
@@ -99,12 +105,20 @@
      */
     @Test()
     static void globalFilter() {
+        ObjectInputFilter filter = ObjectInputFilter.Config.getSerialFilter();
+
+        // Check that the System.setProperty(jdk.serialFilter) DOES NOT affect the filter.
+        String asSetSystemProp = System.getProperty(serialPropName,
+                Security.getProperty(serialPropName));
+        Assert.assertNotEquals(Objects.toString(filter, null), asSetSystemProp,
+                "System.setProperty(\"jdk.serialfilter\", ...) should not change filter: " +
+                asSetSystemProp);
+
         String pattern =
-                System.getProperty("jdk.serialFilter",
-                        Security.getProperty("jdk.serialFilter"));
-        ObjectInputFilter filter = ObjectInputFilter.Config.getSerialFilter();
+                System.getProperty("expected-" + serialPropName,
+                        Security.getProperty(serialPropName));
         System.out.printf("global pattern: %s, filter: %s%n", pattern, filter);
-        Assert.assertEquals(pattern, Objects.toString(filter, null),
+        Assert.assertEquals(Objects.toString(filter, null), pattern,
                 "process-wide filter pattern does not match");
     }
 
--- a/test/jdk/java/io/Serializable/serialFilter/security.policy	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/java/io/Serializable/serialFilter/security.policy	Thu Jan 16 04:09:50 2020 +0100
@@ -4,7 +4,7 @@
         permission java.io.SerializablePermission "serialFilter";
 
         // Permissions needed to run the test
-        permission java.util.PropertyPermission "*", "read";
+        permission java.util.PropertyPermission "*", "read,write";
         permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
         permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
         permission java.security.SecurityPermission "*";
--- a/test/jdk/java/math/BigDecimal/SquareRootTests.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/java/math/BigDecimal/SquareRootTests.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, 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,23 +23,41 @@
 
 /*
  * @test
- * @bug 4851777
+ * @bug 4851777 8233452
  * @summary Tests of BigDecimal.sqrt().
  */
 
 import java.math.*;
 import java.util.*;
 
+import static java.math.BigDecimal.ONE;
+import static java.math.BigDecimal.TEN;
+import static java.math.BigDecimal.ZERO;
+import static java.math.BigDecimal.valueOf;
+
 public class SquareRootTests {
+    private static BigDecimal TWO = new BigDecimal(2);
+
+    /**
+     * The value 0.1, with a scale of 1.
+     */
+    private static final BigDecimal ONE_TENTH = valueOf(1L, 1);
 
     public static void main(String... args) {
         int failures = 0;
 
         failures += negativeTests();
         failures += zeroTests();
+        failures += oneDigitTests();
+        failures += twoDigitTests();
         failures += evenPowersOfTenTests();
         failures += squareRootTwoTests();
         failures += lowPrecisionPerfectSquares();
+        failures += almostFourRoundingDown();
+        failures += almostFourRoundingUp();
+        failures += nearTen();
+        failures += nearOne();
+        failures += halfWay();
 
         if (failures > 0 ) {
             throw new RuntimeException("Incurred " + failures + " failures" +
@@ -84,6 +102,74 @@
     }
 
     /**
+     * Probe inputs with one digit of precision, 1 ... 9 and those
+     * values scaled by 10^-1, 0.1, ... 0.9.
+     */
+    private static int oneDigitTests() {
+        int failures = 0;
+
+        List<BigDecimal> oneToNine =
+            List.of(ONE,        TWO,        valueOf(3),
+                    valueOf(4), valueOf(5), valueOf(6),
+                    valueOf(7), valueOf(8), valueOf(9));
+
+        List<RoundingMode> modes =
+            List.of(RoundingMode.UP,      RoundingMode.DOWN,
+                    RoundingMode.CEILING, RoundingMode.FLOOR,
+                    RoundingMode.HALF_UP, RoundingMode.HALF_DOWN, RoundingMode.HALF_EVEN);
+
+        for (int i = 1; i < 20; i++) {
+            for (RoundingMode rm : modes) {
+                for (BigDecimal bd  : oneToNine) {
+                    MathContext mc = new MathContext(i, rm);
+
+                    failures += compareSqrtImplementations(bd, mc);
+                    bd = bd.multiply(ONE_TENTH);
+                    failures += compareSqrtImplementations(bd, mc);
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    /**
+     * Probe inputs with two digits of precision, (10 ... 99) and
+     * those values scaled by 10^-1 (1, ... 9.9) and scaled by 10^-2
+     * (0.1 ... 0.99).
+     */
+    private static int twoDigitTests() {
+        int failures = 0;
+
+        List<RoundingMode> modes =
+            List.of(RoundingMode.UP,      RoundingMode.DOWN,
+                    RoundingMode.CEILING, RoundingMode.FLOOR,
+                    RoundingMode.HALF_UP, RoundingMode.HALF_DOWN, RoundingMode.HALF_EVEN);
+
+        for (int i = 10; i < 100; i++) {
+            BigDecimal bd0 = BigDecimal.valueOf(i);
+            BigDecimal bd1 = bd0.multiply(ONE_TENTH);
+            BigDecimal bd2 = bd1.multiply(ONE_TENTH);
+
+            for (BigDecimal bd : List.of(bd0, bd1, bd2)) {
+                for (int precision = 1; i < 20; i++) {
+                    for (RoundingMode rm : modes) {
+                        MathContext mc = new MathContext(precision, rm);
+                        failures += compareSqrtImplementations(bd, mc);
+                    }
+                }
+            }
+        }
+
+        return failures;
+    }
+
+    private static int compareSqrtImplementations(BigDecimal bd, MathContext mc) {
+        return equalNumerically(BigSquareRoot.sqrt(bd, mc),
+                                bd.sqrt(mc), "sqrt(" + bd + ") under " + mc);
+    }
+
+    /**
      * sqrt(10^2N) is 10^N
      * Both numerical value and representation should be verified
      */
@@ -92,28 +178,26 @@
         MathContext oneDigitExactly = new MathContext(1, RoundingMode.UNNECESSARY);
 
         for (int scale = -100; scale <= 100; scale++) {
-            BigDecimal testValue       = BigDecimal.valueOf(1, 2*scale);
-            BigDecimal expectedNumericalResult = BigDecimal.valueOf(1, scale);
+            BigDecimal testValue               = BigDecimal.valueOf(1, 2*scale);
+            BigDecimal expectedNumericalResult = BigDecimal.valueOf(1,   scale);
 
             BigDecimal result;
 
-
             failures += equalNumerically(expectedNumericalResult,
-                                           result = testValue.sqrt(MathContext.DECIMAL64),
-                                           "Even powers of 10, DECIMAL64");
+                                         result = testValue.sqrt(MathContext.DECIMAL64),
+                                         "Even powers of 10, DECIMAL64");
 
             // Can round to one digit of precision exactly
             failures += equalNumerically(expectedNumericalResult,
-                                           result = testValue.sqrt(oneDigitExactly),
-                                           "even powers of 10, 1 digit");
+                                         result = testValue.sqrt(oneDigitExactly),
+                                         "even powers of 10, 1 digit");
+
             if (result.precision() > 1) {
                 failures += 1;
                 System.err.println("Excess precision for " + result);
             }
 
-
             // If rounding to more than one digit, do precision / scale checking...
-
         }
 
         return failures;
@@ -121,30 +205,31 @@
 
     private static int squareRootTwoTests() {
         int failures = 0;
-        BigDecimal TWO = new BigDecimal(2);
 
         // Square root of 2 truncated to 65 digits
         BigDecimal highPrecisionRoot2 =
             new BigDecimal("1.41421356237309504880168872420969807856967187537694807317667973799");
 
-
         RoundingMode[] modes = {
             RoundingMode.UP,       RoundingMode.DOWN,
             RoundingMode.CEILING, RoundingMode.FLOOR,
             RoundingMode.HALF_UP, RoundingMode.HALF_DOWN, RoundingMode.HALF_EVEN
         };
 
-        // For each iteresting rounding mode, for precisions 1 to, say
+
+        // For each interesting rounding mode, for precisions 1 to, say,
         // 63 numerically compare TWO.sqrt(mc) to
-        // highPrecisionRoot2.round(mc)
-
+        // highPrecisionRoot2.round(mc) and the alternative internal high-precision
+        // implementation of square root.
         for (RoundingMode mode : modes) {
             for (int precision = 1; precision < 63; precision++) {
                 MathContext mc = new MathContext(precision, mode);
                 BigDecimal expected = highPrecisionRoot2.round(mc);
                 BigDecimal computed = TWO.sqrt(mc);
+                BigDecimal altComputed = BigSquareRoot.sqrt(TWO, mc);
 
-                equalNumerically(expected, computed, "sqrt(2)");
+                failures += equalNumerically(expected, computed, "sqrt(2)");
+                failures += equalNumerically(computed, altComputed, "computed & altComputed");
             }
         }
 
@@ -181,8 +266,8 @@
                         int computedScale = computedRoot.scale();
                         if (precision >=  expectedScale + 1 &&
                             computedScale != expectedScale) {
-                        System.err.printf("%s\tprecision=%d\trm=%s%n",
-                                          computedRoot.toString(), precision, rm);
+                            System.err.printf("%s\tprecision=%d\trm=%s%n",
+                                              computedRoot.toString(), precision, rm);
                             failures++;
                             System.err.printf("\t%s does not have expected scale of %d%n.",
                                               computedRoot, expectedScale);
@@ -195,6 +280,134 @@
         return failures;
     }
 
+    /**
+     * Test around 3.9999 that the sqrt doesn't improperly round-up to
+     * a numerical value of 2.
+     */
+    private static int almostFourRoundingDown() {
+        int failures = 0;
+        BigDecimal nearFour = new BigDecimal("3.999999999999999999999999999999");
+
+        // Sqrt is 1.9999...
+
+        for (int i = 1; i < 64; i++) {
+            MathContext mc = new MathContext(i, RoundingMode.FLOOR);
+            BigDecimal result = nearFour.sqrt(mc);
+            BigDecimal expected = BigSquareRoot.sqrt(nearFour, mc);
+            failures += equalNumerically(expected, result, "near four rounding down");
+            failures += (result.compareTo(TWO) < 0) ? 0  : 1 ;
+        }
+
+        return failures;
+    }
+
+    /**
+     * Test around 4.000...1 that the sqrt doesn't improperly
+     * round-down to a numerical value of 2.
+     */
+    private static int almostFourRoundingUp() {
+        int failures = 0;
+        BigDecimal nearFour = new BigDecimal("4.000000000000000000000000000001");
+
+        // Sqrt is 2.0000....<non-zero digits>
+
+        for (int i = 1; i < 64; i++) {
+            MathContext mc = new MathContext(i, RoundingMode.CEILING);
+            BigDecimal result = nearFour.sqrt(mc);
+            BigDecimal expected = BigSquareRoot.sqrt(nearFour, mc);
+            failures += equalNumerically(expected, result, "near four rounding up");
+            failures += (result.compareTo(TWO) > 0) ? 0  : 1 ;
+        }
+
+        return failures;
+    }
+
+    private static int nearTen() {
+        int failures = 0;
+
+         BigDecimal near10 = new BigDecimal("9.99999999999999999999");
+
+         BigDecimal near10sq = near10.multiply(near10);
+
+         BigDecimal near10sq_ulp = near10sq.add(near10sq.ulp());
+
+        for (int i = 10; i < 23; i++) {
+            MathContext mc = new MathContext(i, RoundingMode.HALF_EVEN);
+
+            failures += equalNumerically(BigSquareRoot.sqrt(near10sq_ulp, mc),
+                                         near10sq_ulp.sqrt(mc),
+                                         "near 10 rounding half even");
+        }
+
+        return failures;
+    }
+
+
+    /*
+     * Probe for rounding failures near a power of ten, 1 = 10^0,
+     * where an ulp has a different size above and below the value.
+     */
+    private static int nearOne() {
+        int failures = 0;
+
+         BigDecimal near1 = new BigDecimal(".999999999999999999999");
+         BigDecimal near1sq = near1.multiply(near1);
+         BigDecimal near1sq_ulp = near1sq.add(near1sq.ulp());
+
+         for (int i = 10; i < 23; i++) {
+             for (RoundingMode rm : List.of(RoundingMode.HALF_EVEN,
+                                            RoundingMode.UP,
+                                            RoundingMode.DOWN )) {
+                 MathContext mc = new MathContext(i, rm);
+                 failures += equalNumerically(BigSquareRoot.sqrt(near1sq_ulp, mc),
+                                              near1sq_ulp.sqrt(mc),
+                                              mc.toString());
+             }
+         }
+
+         return failures;
+    }
+
+
+    private static int halfWay() {
+        int failures = 0;
+
+        /*
+         * Use enough digits that the exact result cannot be computed
+         * from the sqrt of a double.
+         */
+        BigDecimal[] halfWayCases = {
+            // Odd next digit, truncate on HALF_EVEN
+            new BigDecimal("123456789123456789.5"),
+
+             // Even next digit, round up on HALF_EVEN
+            new BigDecimal("123456789123456788.5"),
+        };
+
+        for (BigDecimal halfWayCase : halfWayCases) {
+            // Round result to next-to-last place
+            int precision = halfWayCase.precision() - 1;
+            BigDecimal square = halfWayCase.multiply(halfWayCase);
+
+            for (RoundingMode rm : List.of(RoundingMode.HALF_EVEN,
+                                           RoundingMode.HALF_UP,
+                                           RoundingMode.HALF_DOWN)) {
+                MathContext mc = new MathContext(precision, rm);
+
+                System.out.println("\nRounding mode " + rm);
+                System.out.println("\t" + halfWayCase.round(mc) + "\t" + halfWayCase);
+                System.out.println("\t" + BigSquareRoot.sqrt(square, mc));
+
+                failures += equalNumerically(/*square.sqrt(mc),*/
+                                             BigSquareRoot.sqrt(square, mc),
+                                             halfWayCase.round(mc),
+                                             "Rounding halway " + rm);
+            }
+        }
+
+        return failures;
+    }
+
     private static int compare(BigDecimal a, BigDecimal b, boolean expected, String prefix) {
         boolean result = a.equals(b);
         int failed = (result==expected) ? 0 : 1;
@@ -224,4 +437,306 @@
         return failed;
     }
 
+    /**
+     * Alternative implementation of BigDecimal square root which uses
+     * higher-precision for a simpler set of termination conditions
+     * for the Newton iteration.
+     */
+    private static class BigSquareRoot {
+
+        /**
+         * The value 0.5, with a scale of 1.
+         */
+        private static final BigDecimal ONE_HALF = valueOf(5L, 1);
+
+        public static boolean isPowerOfTen(BigDecimal bd) {
+            return BigInteger.ONE.equals(bd.unscaledValue());
+        }
+
+        public static BigDecimal square(BigDecimal bd) {
+            return bd.multiply(bd);
+        }
+
+        public static BigDecimal sqrt(BigDecimal bd, MathContext mc) {
+            int signum = bd.signum();
+            if (signum == 1) {
+                /*
+                 * The following code draws on the algorithm presented in
+                 * "Properly Rounded Variable Precision Square Root," Hull and
+                 * Abrham, ACM Transactions on Mathematical Software, Vol 11,
+                 * No. 3, September 1985, Pages 229-237.
+                 *
+                 * The BigDecimal computational model differs from the one
+                 * presented in the paper in several ways: first BigDecimal
+                 * numbers aren't necessarily normalized, second many more
+                 * rounding modes are supported, including UNNECESSARY, and
+                 * exact results can be requested.
+                 *
+                 * The main steps of the algorithm below are as follows,
+                 * first argument reduce the value to the numerical range
+                 * [1, 10) using the following relations:
+                 *
+                 * x = y * 10 ^ exp
+                 * sqrt(x) = sqrt(y) * 10^(exp / 2) if exp is even
+                 * sqrt(x) = sqrt(y/10) * 10 ^((exp+1)/2) is exp is odd
+                 *
+                 * Then use Newton's iteration on the reduced value to compute
+                 * the numerical digits of the desired result.
+                 *
+                 * Finally, scale back to the desired exponent range and
+                 * perform any adjustment to get the preferred scale in the
+                 * representation.
+                 */
+
+                // The code below favors relative simplicity over checking
+                // for special cases that could run faster.
+
+                int preferredScale = bd.scale()/2;
+                BigDecimal zeroWithFinalPreferredScale =
+                    BigDecimal.valueOf(0L, preferredScale);
+
+                // First phase of numerical normalization, strip trailing
+                // zeros and check for even powers of 10.
+                BigDecimal stripped = bd.stripTrailingZeros();
+                int strippedScale = stripped.scale();
+
+                // Numerically sqrt(10^2N) = 10^N
+                if (isPowerOfTen(stripped) &&
+                    strippedScale % 2 == 0) {
+                    BigDecimal result = BigDecimal.valueOf(1L, strippedScale/2);
+                    if (result.scale() != preferredScale) {
+                        // Adjust to requested precision and preferred
+                        // scale as appropriate.
+                        result = result.add(zeroWithFinalPreferredScale, mc);
+                    }
+                    return result;
+                }
+
+                // After stripTrailingZeros, the representation is normalized as
+                //
+                // unscaledValue * 10^(-scale)
+                //
+                // where unscaledValue is an integer with the mimimum
+                // precision for the cohort of the numerical value. To
+                // allow binary floating-point hardware to be used to get
+                // approximately a 15 digit approximation to the square
+                // root, it is helpful to instead normalize this so that
+                // the significand portion is to right of the decimal
+                // point by roughly (scale() - precision() + 1).
+
+                // Now the precision / scale adjustment
+                int scaleAdjust = 0;
+                int scale = stripped.scale() - stripped.precision() + 1;
+                if (scale % 2 == 0) {
+                    scaleAdjust = scale;
+                } else {
+                    scaleAdjust = scale - 1;
+                }
+
+                BigDecimal working = stripped.scaleByPowerOfTen(scaleAdjust);
+
+                assert  // Verify 0.1 <= working < 10
+                    ONE_TENTH.compareTo(working) <= 0 && working.compareTo(TEN) < 0;
+
+                // Use good ole' Math.sqrt to get the initial guess for
+                // the Newton iteration, good to at least 15 decimal
+                // digits. This approach does incur the cost of a
+                //
+                // BigDecimal -> double -> BigDecimal
+                //
+                // conversion cycle, but it avoids the need for several
+                // Newton iterations in BigDecimal arithmetic to get the
+                // working answer to 15 digits of precision. If many fewer
+                // than 15 digits were needed, it might be faster to do
+                // the loop entirely in BigDecimal arithmetic.
+                //
+                // (A double value might have as much many as 17 decimal
+                // digits of precision; it depends on the relative density
+                // of binary and decimal numbers at different regions of
+                // the number line.)
+                //
+                // (It would be possible to check for certain special
+                // cases to avoid doing any Newton iterations. For
+                // example, if the BigDecimal -> double conversion was
+                // known to be exact and the rounding mode had a
+                // low-enough precision, the post-Newton rounding logic
+                // could be applied directly.)
+
+                BigDecimal guess = new BigDecimal(Math.sqrt(working.doubleValue()));
+                int guessPrecision = 15;
+                int originalPrecision = mc.getPrecision();
+                int targetPrecision;
+
+                // If an exact value is requested, it must only need
+                // about half of the input digits to represent since
+                // multiplying an N digit number by itself yield a (2N
+                // - 1) digit or 2N digit result.
+                if (originalPrecision == 0) {
+                    targetPrecision = stripped.precision()/2 + 1;
+                } else {
+                    targetPrecision = originalPrecision;
+                }
+
+                // When setting the precision to use inside the Newton
+                // iteration loop, take care to avoid the case where the
+                // precision of the input exceeds the requested precision
+                // and rounding the input value too soon.
+                BigDecimal approx = guess;
+                int workingPrecision = working.precision();
+                // Use "2p + 2" property to guarantee enough
+                // intermediate precision so that a double-rounding
+                // error does not occur when rounded to the final
+                // destination precision.
+                int loopPrecision =
+                    Math.max(2 * Math.max(targetPrecision, workingPrecision) + 2,
+                             34); // Force at least two Netwon
+                                  // iterations on the Math.sqrt
+                                  // result.
+                do {
+                    MathContext mcTmp = new MathContext(loopPrecision, RoundingMode.HALF_EVEN);
+                    // approx = 0.5 * (approx + fraction / approx)
+                    approx = ONE_HALF.multiply(approx.add(working.divide(approx, mcTmp), mcTmp));
+                    guessPrecision *= 2;
+                } while (guessPrecision < loopPrecision);
+
+                BigDecimal result;
+                RoundingMode targetRm = mc.getRoundingMode();
+                if (targetRm == RoundingMode.UNNECESSARY || originalPrecision == 0) {
+                    RoundingMode tmpRm =
+                        (targetRm == RoundingMode.UNNECESSARY) ? RoundingMode.DOWN : targetRm;
+                    MathContext mcTmp = new MathContext(targetPrecision, tmpRm);
+                    result = approx.scaleByPowerOfTen(-scaleAdjust/2).round(mcTmp);
+
+                    // If result*result != this numerically, the square
+                    // root isn't exact
+                    if (bd.subtract(square(result)).compareTo(ZERO) != 0) {
+                        throw new ArithmeticException("Computed square root not exact.");
+                    }
+                } else {
+                    result = approx.scaleByPowerOfTen(-scaleAdjust/2).round(mc);
+                }
+
+                assert squareRootResultAssertions(bd, result, mc);
+                if (result.scale() != preferredScale) {
+                    // The preferred scale of an add is
+                    // max(addend.scale(), augend.scale()). Therefore, if
+                    // the scale of the result is first minimized using
+                    // stripTrailingZeros(), adding a zero of the
+                    // preferred scale rounding the correct precision will
+                    // perform the proper scale vs precision tradeoffs.
+                    result = result.stripTrailingZeros().
+                        add(zeroWithFinalPreferredScale,
+                            new MathContext(originalPrecision, RoundingMode.UNNECESSARY));
+                }
+                return result;
+            } else {
+                switch (signum) {
+                case -1:
+                    throw new ArithmeticException("Attempted square root " +
+                                                  "of negative BigDecimal");
+                case 0:
+                    return valueOf(0L, bd.scale()/2);
+
+                default:
+                    throw new AssertionError("Bad value from signum");
+                }
+            }
+        }
+
+        /**
+         * For nonzero values, check numerical correctness properties of
+         * the computed result for the chosen rounding mode.
+         *
+         * For the directed roundings, for DOWN and FLOOR, result^2 must
+         * be {@code <=} the input and (result+ulp)^2 must be {@code >} the
+         * input. Conversely, for UP and CEIL, result^2 must be {@code >=} the
+         * input and (result-ulp)^2 must be {@code <} the input.
+         */
+        private static boolean squareRootResultAssertions(BigDecimal input, BigDecimal result, MathContext mc) {
+            if (result.signum() == 0) {
+                return squareRootZeroResultAssertions(input, result, mc);
+            } else {
+                RoundingMode rm = mc.getRoundingMode();
+                BigDecimal ulp = result.ulp();
+                BigDecimal neighborUp   = result.add(ulp);
+                // Make neighbor down accurate even for powers of ten
+                if (isPowerOfTen(result)) {
+                    ulp = ulp.divide(TEN);
+                }
+                BigDecimal neighborDown = result.subtract(ulp);
+
+                // Both the starting value and result should be nonzero and positive.
+                if (result.signum() != 1 ||
+                    input.signum() != 1) {
+                    return false;
+                }
+
+                switch (rm) {
+                case DOWN:
+                case FLOOR:
+                    assert
+                        square(result).compareTo(input)    <= 0 &&
+                        square(neighborUp).compareTo(input) > 0:
+                    "Square of result out for bounds rounding " + rm;
+                    return true;
+
+                case UP:
+                case CEILING:
+                    assert
+                        square(result).compareTo(input) >= 0 :
+                    "Square of result too small rounding " + rm;
+
+                    assert
+                        square(neighborDown).compareTo(input) < 0 :
+                    "Square of down neighbor too large rounding  " + rm + "\n" +
+                        "\t input: " + input + "\t neighborDown: " +  neighborDown +"\t sqrt: " + result +
+                        "\t" + mc;
+                    return true;
+
+
+                case HALF_DOWN:
+                case HALF_EVEN:
+                case HALF_UP:
+                    BigDecimal err = square(result).subtract(input).abs();
+                    BigDecimal errUp = square(neighborUp).subtract(input);
+                    BigDecimal errDown =  input.subtract(square(neighborDown));
+                    // All error values should be positive so don't need to
+                    // compare absolute values.
+
+                    int err_comp_errUp = err.compareTo(errUp);
+                    int err_comp_errDown = err.compareTo(errDown);
+
+                    assert
+                        errUp.signum()   == 1 &&
+                        errDown.signum() == 1 :
+                    "Errors of neighbors squared don't have correct signs";
+
+                    // At least one of these must be true, but not both
+//                     assert
+//                         err_comp_errUp   <= 0 : "Upper neighbor is closer than result: " + rm +
+//                         "\t" + input + "\t result" + result;
+//                     assert
+//                         err_comp_errDown <= 0 : "Lower neighbor is closer than result: " + rm +
+//                         "\t" + input + "\t result " + result + "\t lower neighbor: " + neighborDown;
+
+                    assert
+                        ((err_comp_errUp   == 0 ) ? err_comp_errDown < 0 : true) &&
+                        ((err_comp_errDown == 0 ) ? err_comp_errUp   < 0 : true) :
+                            "Incorrect error relationships";
+                        // && could check for digit conditions for ties too
+                        return true;
+
+                default: // Definition of UNNECESSARY already verified.
+                    return true;
+                }
+            }
+        }
+
+        private static boolean squareRootZeroResultAssertions(BigDecimal input,
+                                                              BigDecimal result,
+                                                              MathContext mc) {
+            return input.compareTo(ZERO) == 0;
+        }
+    }
 }
+
--- a/test/jdk/java/nio/Buffer/Basic.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/java/nio/Buffer/Basic.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2020, 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,7 +26,7 @@
  * @bug 4413135 4414911 4416536 4416562 4418782 4471053 4472779 4490253 4523725
  *      4526177 4463011 4660660 4661219 4663521 4782970 4804304 4938424 5029431
  *      5071718 6231529 6221101 6234263 6535542 6591971 6593946 6795561 7190219
- *      7199551 8065556 8149469
+ *      7199551 8065556 8149469 8230665
  * @modules java.base/java.nio:open
  *          java.base/jdk.internal.misc
  * @author Mark Reinhold
--- a/test/jdk/sun/security/krb5/auto/KDC.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/krb5/auto/KDC.java	Thu Jan 16 04:09:50 2020 +0100
@@ -720,7 +720,7 @@
      * @return the key
      * @throws sun.security.krb5.KrbException for unknown/unsupported etype
      */
-    private EncryptionKey keyForUser(PrincipalName p, int etype, boolean server)
+    EncryptionKey keyForUser(PrincipalName p, int etype, boolean server)
             throws KrbException {
         try {
             // Do not call EncryptionKey.acquireSecretKeys(), otherwise
@@ -801,7 +801,7 @@
             int e2 = eTypes[0];     // etype for outgoing session key
             int e3 = eTypes[0];     // etype for outgoing ticket
 
-            PAData[] pas = KDCReqDotPAData(tgsReq);
+            PAData[] pas = tgsReq.pAData;
 
             Ticket tkt = null;
             EncTicketPart etp = null;
@@ -832,7 +832,6 @@
                 for (PAData pa: pas) {
                     if (pa.getType() == Krb5.PA_TGS_REQ) {
                         APReq apReq = new APReq(pa.getValue());
-                        EncryptedData ed = apReq.authenticator;
                         tkt = apReq.ticket;
                         int te = tkt.encPart.getEType();
                         EncryptionKey kkey = keyForUser(tkt.sname, te, true);
@@ -1276,7 +1275,7 @@
                 outPAs.add(new PAData(Krb5.PA_ETYPE_INFO, eid.toByteArray()));
             }
 
-            PAData[] inPAs = KDCReqDotPAData(asReq);
+            PAData[] inPAs = asReq.pAData;
             List<PAData> enc_outPAs = new ArrayList<>();
 
             byte[] paEncTimestamp = null;
@@ -1988,7 +1987,6 @@
     }
 
     // Calling private methods thru reflections
-    private static final Field getPADataField;
     private static final Field getEType;
     private static final Constructor<EncryptedData> ctorEncryptedData;
     private static final Method stringToKey;
@@ -1998,8 +1996,6 @@
         try {
             ctorEncryptedData = EncryptedData.class.getDeclaredConstructor(DerValue.class);
             ctorEncryptedData.setAccessible(true);
-            getPADataField = KDCReq.class.getDeclaredField("pAData");
-            getPADataField.setAccessible(true);
             getEType = KDCReqBody.class.getDeclaredField("eType");
             getEType.setAccessible(true);
             stringToKey = EncryptionKey.class.getDeclaredMethod(
@@ -2021,13 +2017,6 @@
             throw new AssertionError(e);
         }
     }
-    private static PAData[] KDCReqDotPAData(KDCReq req) {
-        try {
-            return (PAData[])getPADataField.get(req);
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
     private static int[] KDCReqBodyDotEType(KDCReqBody body) {
         try {
             return (int[]) getEType.get(body);
--- a/test/jdk/sun/security/krb5/auto/SaslGSS.java	Thu Jan 16 03:19:32 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2013, 2018, 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 8012082 8019267 8194486
- * @summary SASL: auth-conf negotiated, but unencrypted data is accepted,
-  *         reset to unencrypt
- * @library /test/lib
- * @compile -XDignore.symbol.file SaslGSS.java
- * @run main jdk.test.lib.FileInstaller TestHosts TestHosts
- * @run main/othervm -Djdk.net.hosts.file=TestHosts SaslGSS
- */
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.sasl.AuthorizeCallback;
-import javax.security.sasl.RealmCallback;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslServer;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.HashMap;
-import java.util.logging.ConsoleHandler;
-import java.util.logging.Handler;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.ietf.jgss.*;
-import sun.security.jgss.GSSUtil;
-
-public class SaslGSS {
-
-    public static void main(String[] args) throws Exception {
-
-        String name = "host." + OneKDC.REALM_LOWER_CASE;
-
-        new OneKDC(null).writeJAASConf();
-        System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
-
-        // Client in JGSS so that it can control wrap privacy mode
-        GSSManager m = GSSManager.getInstance();
-        GSSContext sc = m.createContext(
-                        m.createName(OneKDC.SERVER, GSSUtil.NT_GSS_KRB5_PRINCIPAL),
-                        GSSUtil.GSS_KRB5_MECH_OID,
-                        null,
-                        GSSContext.DEFAULT_LIFETIME);
-        sc.requestMutualAuth(false);
-
-        // Server in SASL
-        final HashMap props = new HashMap();
-        props.put(Sasl.QOP, "auth-conf");
-        SaslServer ss = Sasl.createSaslServer("GSSAPI", "server",
-                name, props,
-                new CallbackHandler() {
-                    public void handle(Callback[] callbacks)
-                            throws IOException, UnsupportedCallbackException {
-                        for (Callback cb : callbacks) {
-                            if (cb instanceof RealmCallback) {
-                                ((RealmCallback) cb).setText(OneKDC.REALM);
-                            } else if (cb instanceof AuthorizeCallback) {
-                                ((AuthorizeCallback) cb).setAuthorized(true);
-                            }
-                        }
-                    }
-                });
-
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        PrintStream oldErr = System.err;
-        System.setErr(new PrintStream(bout));
-
-        Logger.getLogger("javax.security.sasl").setLevel(Level.ALL);
-        Handler h = new ConsoleHandler();
-        h.setLevel(Level.ALL);
-        Logger.getLogger("javax.security.sasl").addHandler(h);
-
-        byte[] token = new byte[0];
-
-        try {
-            // Handshake
-            token = sc.initSecContext(token, 0, token.length);
-            token = ss.evaluateResponse(token);
-            token = sc.unwrap(token, 0, token.length, new MessageProp(0, false));
-            token[0] = (byte)(((token[0] & 4) != 0) ? 4 : 2);
-            token = sc.wrap(token, 0, token.length, new MessageProp(0, false));
-            ss.evaluateResponse(token);
-        } finally {
-            System.setErr(oldErr);
-        }
-
-        // Talk
-        // 1. Client sends a auth-int message
-        byte[] hello = "hello".getBytes();
-        MessageProp qop = new MessageProp(0, false);
-        token = sc.wrap(hello, 0, hello.length, qop);
-        // 2. Server accepts it anyway
-        ss.unwrap(token, 0, token.length);
-        // 3. Server sends a message
-        token = ss.wrap(hello, 0, hello.length);
-        // 4. Client accepts, should be auth-conf
-        sc.unwrap(token, 0, token.length, qop);
-        if (!qop.getPrivacy()) {
-            throw new Exception();
-        }
-
-        for (String s: bout.toString().split("\\n")) {
-            if (s.contains("KRB5SRV04") && s.contains("NULL")) {
-                return;
-            }
-        }
-        System.out.println("=======================");
-        System.out.println(bout.toString());
-        System.out.println("=======================");
-        throw new Exception("Haven't seen KRB5SRV04 with NULL");
-    }
-}
--- a/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/ConciseJarsigner.java	Thu Jan 16 04:09:50 2020 +0100
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6802846 8172529
+ * @bug 6802846 8172529 8227758
  * @summary jarsigner needs enhanced cert validation(options)
  * @library /test/lib
  * @run main/timeout=240 ConciseJarsigner
@@ -227,17 +227,11 @@
                 + "a.jar altchain")
                 .shouldHaveExitValue(0);
 
-        // if ca2 is removed, -certchain still work because altchain is a
-        // self-signed entry and it is trusted by jarsigner
+        // if ca2 is removed and cert is imported, -certchain won't work
+        // because this certificate entry is not trusted
         // save ca2.cert for easy replay
         kt("-exportcert -file ca2.cert -alias ca2");
         kt("-delete -alias ca2");
-        js("-strict -keystore ks -storepass changeit "
-                + "-certchain certchain a.jar altchain")
-                .shouldHaveExitValue(0);
-
-        // if cert is imported, -certchain won't work because this
-        // certificate entry is not trusted
         kt("-importcert -file certchain -alias altchain -noprompt");
         js("-strict -keystore ks -storepass changeit "
                 + "-certchain certchain a.jar altchain")
@@ -250,8 +244,8 @@
         // ==========================================================
 
         kt("-genkeypair -alias ee -dname CN=ee");
-        kt("-genkeypair -alias caone -dname CN=caone");
-        kt("-genkeypair -alias catwo -dname CN=catwo");
+        kt("-genkeypair -alias caone -dname CN=caone -ext bc:c");
+        kt("-genkeypair -alias catwo -dname CN=catwo -ext bc:c");
 
         kt("-certreq -alias ee -file ee.req");
         kt("-certreq -alias catwo -file catwo.req");
--- a/test/jdk/sun/security/tools/jarsigner/DefaultOptions.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/DefaultOptions.java	Thu Jan 16 04:09:50 2020 +0100
@@ -59,7 +59,7 @@
     public static void main(String[] args) throws Throwable {
         keytool("-genkeypair -dname CN=A -alias a -keyalg rsa")
                 .shouldHaveExitValue(0);
-        keytool("-genkeypair -dname CN=CA -alias ca -keyalg rsa")
+        keytool("-genkeypair -dname CN=CA -alias ca -keyalg rsa -ext bc:c")
                 .shouldHaveExitValue(0);
         keytool("-alias a -certreq -file a.req");
         keytool("-alias ca -gencert -infile a.req -outfile a.cert");
--- a/test/jdk/sun/security/tools/jarsigner/EC.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/EC.java	Thu Jan 16 04:09:50 2020 +0100
@@ -59,7 +59,7 @@
         Files.write(Path.of("A"), List.of("A"));
         JarUtils.createJarFile(Path.of("a.jar"), Path.of("."), Path.of("A"));
 
-        kt("-alias ca -dname CN=ca -keyalg ec -genkey -validity 300")
+        kt("-alias ca -dname CN=ca -keyalg ec -genkey -validity 300 -ext bc:c")
                 .shouldHaveExitValue(0);
         kt("-alias a -dname CN=a -keyalg ec -genkey")
                 .shouldHaveExitValue(0);
--- a/test/jdk/sun/security/tools/jarsigner/JavaKeyStoreAliasCaseInsensitive.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/JavaKeyStoreAliasCaseInsensitive.java	Thu Jan 16 04:09:50 2020 +0100
@@ -90,7 +90,7 @@
                 + " test-alias-storeHash-case.jks -storepass changeit";
         SecurityTools.keytool(KEYSTORE_OPTIONS + " -genkeypair -keyalg DSA"
                 + " -keypass changeit -alias " + ALIAS + "1 -dname CN=" +
-                ALIAS + "1").shouldHaveExitValue(0);
+                ALIAS + "1" + " -ext bc:c").shouldHaveExitValue(0);
         SecurityTools.keytool(KEYSTORE_OPTIONS + " -genkeypair -keyalg DSA"
                 + " -keypass changeit -alias " + ALIAS + "2 -dname CN="
                 + ALIAS + "2").shouldHaveExitValue(0);
--- a/test/jdk/sun/security/tools/jarsigner/OnlyManifest.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/OnlyManifest.java	Thu Jan 16 04:09:50 2020 +0100
@@ -52,7 +52,7 @@
         Files.write(Path.of("manifest"), List.of("Key: Value"));
         SecurityTools.jar("cvfm a.jar manifest");
 
-        kt("-alias ca -dname CN=ca -genkey -validity 300")
+        kt("-alias ca -dname CN=ca -genkey -validity 300 -ext bc:c")
                 .shouldHaveExitValue(0);
         kt("-alias a -dname CN=a -genkey -validity 300")
                 .shouldHaveExitValue(0);
--- a/test/jdk/sun/security/tools/jarsigner/TsacertOptionTest.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/TsacertOptionTest.java	Thu Jan 16 04:09:50 2020 +0100
@@ -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
@@ -74,6 +74,7 @@
                 "-storepass", PASSWORD,
                 "-keypass", PASSWORD,
                 "-dname", "CN=CA",
+                "-ext", "bc:c",
                 "-validity", Integer.toString(VALIDITY)).shouldHaveExitValue(0);
         keytool(
                 "-genkey",
--- a/test/jdk/sun/security/tools/jarsigner/Warning.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/Warning.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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
@@ -44,7 +44,7 @@
 
         Files.deleteIfExists(Paths.get("ks"));
 
-        newCert("ca", "-validity 365000");
+        newCert("ca", "-validity 365000", "-ext bc:c");
 
         recreateJar();
 
--- a/test/jdk/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/warnings/BadExtendedKeyUsageTest.java	Thu Jan 16 04:09:50 2020 +0100
@@ -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
@@ -53,7 +53,7 @@
         // create a certificate whose signer certificate's
         // ExtendedKeyUsage extension doesn't allow code signing
         // create key pair for jar signing
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(KEY_ALIAS);
 
         issueCert(
--- a/test/jdk/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/warnings/BadNetscapeCertTypeTest.java	Thu Jan 16 04:09:50 2020 +0100
@@ -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
@@ -54,7 +54,7 @@
         // create a certificate whose signer certificate's
         // NetscapeCertType extension doesn't allow code signing
         // create key pair for jar signing
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(KEY_ALIAS);
 
         issueCert(
--- a/test/jdk/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/warnings/ChainNotValidatedTest.java	Thu Jan 16 04:09:50 2020 +0100
@@ -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
@@ -54,7 +54,7 @@
         // Root CA is not checked at all. If the intermediate CA has
         // BasicConstraints extension set to true, it will be valid.
         // Otherwise, chain validation will fail.
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(CA2_KEY_ALIAS);
         issueCert(CA2_KEY_ALIAS,
                 "-ext",
--- a/test/jdk/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/warnings/HasExpiringCertTest.java	Thu Jan 16 04:09:50 2020 +0100
@@ -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
@@ -52,7 +52,7 @@
         JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
 
         // create key pair for jar signing
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(KEY_ALIAS);
 
         issueCert(
--- a/test/jdk/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/warnings/HasUnsignedEntryTest.java	Thu Jan 16 04:09:50 2020 +0100
@@ -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
@@ -51,7 +51,7 @@
         JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
 
         // create key pair for signing
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(KEY_ALIAS);
         issueCert(
                 KEY_ALIAS,
--- a/test/jdk/sun/security/tools/jarsigner/warnings/NoTimestampTest.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/warnings/NoTimestampTest.java	Thu Jan 16 04:09:50 2020 +0100
@@ -72,7 +72,7 @@
         JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
 
         // create key pair
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
         createAlias(KEY_ALIAS);
         issueCert(KEY_ALIAS,
                 "-validity", Integer.toString(VALIDITY));
--- a/test/jdk/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/tools/jarsigner/warnings/NotSignedByAliasTest.java	Thu Jan 16 04:09:50 2020 +0100
@@ -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
@@ -49,7 +49,7 @@
         Utils.createFiles(FIRST_FILE);
         JarUtils.createJar(UNSIGNED_JARFILE, FIRST_FILE);
 
-        createAlias(CA_KEY_ALIAS);
+        createAlias(CA_KEY_ALIAS, "-ext", "bc:c");
 
         // create first key pair for signing
         createAlias(FIRST_KEY_ALIAS);
--- a/test/jdk/sun/security/util/DerValue/BadValue.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/util/DerValue/BadValue.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -35,23 +35,23 @@
 
     public static void main(String[] args) throws Exception {
 
-        // Test IOUtils.readFully
+        // Test IOUtils.
 
         // We have 4 bytes
         InputStream in = new ByteArrayInputStream(new byte[10]);
-        byte[] bs = IOUtils.readFully(in, 4, true);
+        byte[] bs = IOUtils.readExactlyNBytes(in, 4);
         if (bs.length != 4 || in.available() != 6) {
             throw new Exception("First read error");
         }
         // But only 6 left
-        bs = IOUtils.readFully(in, 10, false);
+        bs = in.readNBytes(10);
         if (bs.length != 6 || in.available() != 0) {
             throw new Exception("Second read error");
         }
         // MAX length results in exception
         in = new ByteArrayInputStream(new byte[10]);
         try {
-            bs = IOUtils.readFully(in, Integer.MAX_VALUE, true);
+            bs = IOUtils.readExactlyNBytes(in, Integer.MAX_VALUE);
             throw new Exception("No exception on MAX_VALUE length");
         } catch (EOFException ex) {
             // this is expected
@@ -61,7 +61,7 @@
         // -1 length results in exception
         in = new ByteArrayInputStream(new byte[10]);
         try {
-            bs = IOUtils.readFully(in, -1, true);
+            bs = IOUtils.readExactlyNBytes(in, -1);
             throw new Exception("No exception on -1 length");
         } catch (IOException ex) {
             // this is expected
@@ -70,13 +70,13 @@
         // 20>10, readAll means failure
         in = new ByteArrayInputStream(new byte[10]);
         try {
-            bs = IOUtils.readFully(in, 20, true);
+            bs = IOUtils.readExactlyNBytes(in, 20);
             throw new Exception("No exception on EOF");
         } catch (EOFException e) {
             // OK
         }
         int bignum = 10 * 1024 * 1024;
-        bs = IOUtils.readFully(new SuperSlowStream(bignum), bignum, true);
+        bs = IOUtils.readExactlyNBytes(new SuperSlowStream(bignum), bignum);
         if (bs.length != bignum) {
             throw new Exception("Read returned small array");
         }
--- a/test/jdk/sun/security/validator/EndEntityExtensionCheck.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/jdk/sun/security/validator/EndEntityExtensionCheck.java	Thu Jan 16 04:09:50 2020 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 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,6 +27,7 @@
  * @summary EndEntityChecker should not process custom extensions
  *          after PKIX validation
  * @modules java.base/sun.security.validator
+ * @run main/othervm -Djdk.security.allowNonCaAnchor EndEntityExtensionCheck
  */
 
 import java.io.ByteArrayInputStream;
--- a/test/langtools/tools/javac/T8177068/NoCompletionFailureSkipOnSpeculativeAttribution.java	Thu Jan 16 03:19:32 2020 +0100
+++ b/test/langtools/tools/javac/T8177068/NoCompletionFailureSkipOnSpeculativeAttribution.java	Thu Jan 16 04:09:50 2020 +0100
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8177068
+ * @bug 8177068 8233655
  * @summary CompletionFailures occurring during speculative attribution should
  *          not be lost forever.
  * @library /tools/lib
@@ -72,6 +72,7 @@
 
     public static void main(String[] args) throws Exception {
         new NoCompletionFailureSkipOnSpeculativeAttribution().test();
+        new NoCompletionFailureSkipOnSpeculativeAttribution().test8233655();
     }
 
     public void test() throws Exception {
@@ -101,4 +102,32 @@
 
         Assert.check(output.equals(expectedOutput));
     }
+
+    public void test8233655() throws Exception {
+        ToolBox tb = new ToolBox();
+        tb.writeJavaFiles(Paths.get("."),
+                          "public class Test {" +
+                          "    private <T> T test(Class<?> c) {\n" +
+                          "        Class<?> c2 = test(test(Helper.class));\n" +
+                          "        return null;\n" +
+                          "    }\n" +
+                          "}",
+                          "public class Helper extends Unknown {}");
+
+        List<String> output = new JavacTask(tb)
+                .sourcepath(".")
+                .options("-XDrawDiagnostics")
+                .classpath(".")
+                .files("Test.java")
+                .run(Task.Expect.FAIL)
+                .writeAll()
+                .getOutputLines(Task.OutputKind.DIRECT);
+
+        List<String> expectedOutput = List.of(
+                "Helper.java:1:29: compiler.err.cant.resolve: kindname.class, Unknown, , ",
+                "1 error"
+        );
+
+        Assert.check(output.equals(expectedOutput));
+    }
 }