# HG changeset patch # User mikael # Date 1563363217 25200 # Node ID 2b4e14968afd537246f9b4615b5efa82e56acfcb # Parent 9a97b1393e723cc713d9e02aeb089ec35ca0d10a# Parent a5d52b0e3798d6ccfcc0eea599ce724419aba5f6 Merge diff -r 9a97b1393e72 -r 2b4e14968afd make/Images.gmk --- a/make/Images.gmk Wed Jul 17 12:35:46 2019 +0200 +++ b/make/Images.gmk Wed Jul 17 04:33:37 2019 -0700 @@ -102,7 +102,7 @@ WARN := Creating legacy jre image, \ DEPS := $(JMODS) $(BASE_RELEASE_FILE) \ $(call DependOnVariable, JDK_MODULES_LIST), \ - OUTPUT_DIR := $(JDK_IMAGE_DIR), \ + OUTPUT_DIR := $(JRE_IMAGE_DIR), \ SUPPORT_DIR := $(SUPPORT_OUTPUTDIR)/images/jre, \ PRE_COMMAND := $(RM) -r $(JRE_IMAGE_DIR), \ COMMAND := $(JLINK_TOOL) --add-modules $(JRE_MODULES_LIST) \ diff -r 9a97b1393e72 -r 2b4e14968afd src/hotspot/share/include/cds.h --- a/src/hotspot/share/include/cds.h Wed Jul 17 12:35:46 2019 +0200 +++ b/src/hotspot/share/include/cds.h Wed Jul 17 04:33:37 2019 -0700 @@ -33,10 +33,10 @@ // // Also, this is a C header file. Do not use C++ here. -#define NUM_CDS_REGIONS 9 +#define NUM_CDS_REGIONS 8 // this must be the same as MetaspaceShared::n_regions #define CDS_ARCHIVE_MAGIC 0xf00baba2 #define CDS_DYNAMIC_ARCHIVE_MAGIC 0xf00baba8 -#define CURRENT_CDS_ARCHIVE_VERSION 5 +#define CURRENT_CDS_ARCHIVE_VERSION 6 #define INVALID_CDS_ARCHIVE_VERSION -1 struct CDSFileMapRegion { diff -r 9a97b1393e72 -r 2b4e14968afd src/hotspot/share/memory/filemap.cpp --- a/src/hotspot/share/memory/filemap.cpp Wed Jul 17 12:35:46 2019 +0200 +++ b/src/hotspot/share/memory/filemap.cpp Wed Jul 17 04:33:37 2019 -0700 @@ -155,6 +155,8 @@ const char *vm_version = VM_Version::internal_vm_info_string(); const int version_len = (int)strlen(vm_version); + memset(header_version, 0, JVM_IDENT_MAX); + if (version_len < (JVM_IDENT_MAX-1)) { strcpy(header_version, vm_version); @@ -170,6 +172,8 @@ sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash); header_version[JVM_IDENT_MAX-1] = 0; // Null terminate. } + + assert(header_version[JVM_IDENT_MAX-1] == 0, "must be"); } FileMapInfo::FileMapInfo(bool is_static) { @@ -891,10 +895,59 @@ fail_continue("Unable to read the file header."); return false; } + + if (!Arguments::has_jimage()) { + FileMapInfo::fail_continue("The shared archive file cannot be used with an exploded module build."); + return false; + } + + unsigned int expected_magic = is_static ? CDS_ARCHIVE_MAGIC : CDS_DYNAMIC_ARCHIVE_MAGIC; + if (_header->_magic != expected_magic) { + log_info(cds)("_magic expected: 0x%08x", expected_magic); + log_info(cds)(" actual: 0x%08x", _header->_magic); + FileMapInfo::fail_continue("The shared archive file has a bad magic number."); + return false; + } + if (_header->_version != CURRENT_CDS_ARCHIVE_VERSION) { + log_info(cds)("_version expected: %d", CURRENT_CDS_ARCHIVE_VERSION); + log_info(cds)(" actual: %d", _header->_version); fail_continue("The shared archive file has the wrong version."); return false; } + + if (_header->_header_size != sz) { + log_info(cds)("_header_size expected: " SIZE_FORMAT, sz); + log_info(cds)(" actual: " SIZE_FORMAT, _header->_header_size); + FileMapInfo::fail_continue("The shared archive file has an incorrect header size."); + return false; + } + + if (_header->_jvm_ident[JVM_IDENT_MAX-1] != 0) { + FileMapInfo::fail_continue("JVM version identifier is corrupted."); + return false; + } + + char header_version[JVM_IDENT_MAX]; + get_header_version(header_version); + if (strncmp(_header->_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) { + log_info(cds)("_jvm_ident expected: %s", header_version); + log_info(cds)(" actual: %s", _header->_jvm_ident); + FileMapInfo::fail_continue("The shared archive file was created by a different" + " version or build of HotSpot"); + return false; + } + + if (VerifySharedSpaces) { + int expected_crc = _header->compute_crc(); + if (expected_crc != _header->_crc) { + log_info(cds)("_crc expected: %d", expected_crc); + log_info(cds)(" actual: %d", _header->_crc); + FileMapInfo::fail_continue("Header checksum verification failed."); + return false; + } + } + _file_offset = n; size_t info_size = _header->_paths_misc_info_size; @@ -909,10 +962,6 @@ _file_offset += n + _header->_base_archive_name_size; // accounts for the size of _base_archive_name if (is_static) { - if (_header->_magic != CDS_ARCHIVE_MAGIC) { - fail_continue("Incorrect static archive magic number"); - return false; - } // just checking the last region is sufficient since the archive is written // in sequential order size_t len = lseek(fd, 0, SEEK_END); @@ -1750,33 +1799,7 @@ // This function should only be called during run time with UseSharedSpaces enabled. bool FileMapHeader::validate() { - if (VerifySharedSpaces && compute_crc() != _crc) { - FileMapInfo::fail_continue("Header checksum verification failed."); - return false; - } - if (!Arguments::has_jimage()) { - FileMapInfo::fail_continue("The shared archive file cannot be used with an exploded module build."); - return false; - } - - if (_version != CURRENT_CDS_ARCHIVE_VERSION) { - FileMapInfo::fail_continue("The shared archive file is the wrong version."); - return false; - } - if (_magic != CDS_ARCHIVE_MAGIC && _magic != CDS_DYNAMIC_ARCHIVE_MAGIC) { - FileMapInfo::fail_continue("The shared archive file has a bad magic number."); - return false; - } - char header_version[JVM_IDENT_MAX]; - get_header_version(header_version); - if (strncmp(_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) { - log_info(class, path)("expected: %s", header_version); - log_info(class, path)("actual: %s", _jvm_ident); - FileMapInfo::fail_continue("The shared archive file was created by a different" - " version or build of HotSpot"); - return false; - } if (_obj_alignment != ObjectAlignmentInBytes) { FileMapInfo::fail_continue("The shared archive file's ObjectAlignmentInBytes of %d" " does not equal the current ObjectAlignmentInBytes of " INTX_FORMAT ".", diff -r 9a97b1393e72 -r 2b4e14968afd src/hotspot/share/prims/cdsoffsets.cpp --- a/src/hotspot/share/prims/cdsoffsets.cpp Wed Jul 17 12:35:46 2019 +0200 +++ b/src/hotspot/share/prims/cdsoffsets.cpp Wed Jul 17 04:33:37 2019 -0700 @@ -49,6 +49,7 @@ ADD_NEXT(_all, "FileMapHeader::_magic", offset_of(FileMapHeader, _magic)); \ ADD_NEXT(_all, "FileMapHeader::_crc", offset_of(FileMapHeader, _crc)); \ ADD_NEXT(_all, "FileMapHeader::_version", offset_of(FileMapHeader, _version)); \ + ADD_NEXT(_all, "FileMapHeader::_jvm_ident", offset_of(FileMapHeader, _jvm_ident)); \ ADD_NEXT(_all, "FileMapHeader::_space[0]", offset_of(FileMapHeader, _space)); \ ADD_NEXT(_all, "CDSFileMapRegion::_crc", offset_of(CDSFileMapRegion, _crc)); \ ADD_NEXT(_all, "CDSFileMapRegion::_used", offset_of(CDSFileMapRegion, _used)); \ diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java --- a/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java Wed Jul 17 04:33:37 2019 -0700 @@ -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 @@ -1363,8 +1363,11 @@ // Calculate and compare the tag. Only do the decryption // if and only if the tag matches. authFinalizeData(ctPlusTag, 0, ctLen, tag, 0); - if (Arrays.compare(ctPlusTag, ctLen, ctPlusTagLen, - tag, 0, tag.length) != 0) { + long tagCompare = ((long)asLongView.get(ctPlusTag, ctLen) ^ + (long)asLongView.get(tag, 0)) | + ((long)asLongView.get(ctPlusTag, ctLen + Long.BYTES) ^ + (long)asLongView.get(tag, Long.BYTES)); + if (tagCompare != 0) { throw new AEADBadTagException("Tag mismatch"); } chaCha20Transform(ctPlusTag, 0, ctLen, out, outOff); diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/java/lang/Throwable.java --- a/src/java.base/share/classes/java/lang/Throwable.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/java/lang/Throwable.java Wed Jul 17 04:33:37 2019 -0700 @@ -25,8 +25,8 @@ package java.lang; -import java.io.*; -import java.util.*; +import java.io.*; +import java.util.*; /** * The {@code Throwable} class is the superclass of all errors and @@ -904,24 +904,36 @@ private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); // read in all fields - if (suppressedExceptions != null) { - List suppressed = null; - if (suppressedExceptions.isEmpty()) { - // Use the sentinel for a zero-length list - suppressed = SUPPRESSED_SENTINEL; - } else { // Copy Throwables to new list - suppressed = new ArrayList<>(1); - for (Throwable t : suppressedExceptions) { + + // Set suppressed exceptions and stack trace elements fields + // to marker values until the contents from the serial stream + // are validated. + List candidateSuppressedExceptions = suppressedExceptions; + suppressedExceptions = SUPPRESSED_SENTINEL; + + StackTraceElement[] candidateStackTrace = stackTrace; + stackTrace = UNASSIGNED_STACK.clone(); + + if (candidateSuppressedExceptions != null) { + int suppressedSize = validateSuppressedExceptionsList(candidateSuppressedExceptions); + if (suppressedSize > 0) { // Copy valid Throwables to new list + var suppList = new ArrayList(Math.min(100, suppressedSize)); + + for (Throwable t : candidateSuppressedExceptions) { // Enforce constraints on suppressed exceptions in // case of corrupt or malicious stream. Objects.requireNonNull(t, NULL_CAUSE_MESSAGE); if (t == this) throw new IllegalArgumentException(SELF_SUPPRESSION_MESSAGE); - suppressed.add(t); + suppList.add(t); } + // If there are any invalid suppressed exceptions, + // implicitly use the sentinel value assigned earlier. + suppressedExceptions = suppList; } - suppressedExceptions = suppressed; - } // else a null suppressedExceptions field remains null + } else { + suppressedExceptions = null; + } /* * For zero-length stack traces, use a clone of @@ -932,24 +944,41 @@ * the stackTrace needs to be constructed from the information * in backtrace. */ - if (stackTrace != null) { - if (stackTrace.length == 0) { - stackTrace = UNASSIGNED_STACK.clone(); - } else if (stackTrace.length == 1 && + if (candidateStackTrace != null) { + // Work from a clone of the candidateStackTrace to ensure + // consistency of checks. + candidateStackTrace = candidateStackTrace.clone(); + if (candidateStackTrace.length >= 1) { + if (candidateStackTrace.length == 1 && // Check for the marker of an immutable stack trace - SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) { - stackTrace = null; - } else { // Verify stack trace elements are non-null. - for(StackTraceElement ste : stackTrace) { - Objects.requireNonNull(ste, "null StackTraceElement in serial stream."); + SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(candidateStackTrace[0])) { + stackTrace = null; + } else { // Verify stack trace elements are non-null. + for (StackTraceElement ste : candidateStackTrace) { + Objects.requireNonNull(ste, "null StackTraceElement in serial stream."); + } + stackTrace = candidateStackTrace; } } + } + // A null stackTrace field in the serial form can result from + // an exception serialized without that field in older JDK + // releases; treat such exceptions as having empty stack + // traces by leaving stackTrace assigned to a clone of + // UNASSIGNED_STACK. + } + + private int validateSuppressedExceptionsList(List deserSuppressedExceptions) + throws IOException { + if (!Object.class.getModule(). + equals(deserSuppressedExceptions.getClass().getModule())) { + throw new StreamCorruptedException("List implementation not in base module."); } else { - // A null stackTrace field in the serial form can result - // from an exception serialized without that field in - // older JDK releases; treat such exceptions as having - // empty stack traces. - stackTrace = UNASSIGNED_STACK.clone(); + int size = deserSuppressedExceptions.size(); + if (size < 0) { + throw new StreamCorruptedException("Negative list size reported."); + } + return size; } } diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/java/net/URL.java --- a/src/java.base/share/classes/java/net/URL.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/java/net/URL.java Wed Jul 17 04:33:37 2019 -0700 @@ -45,6 +45,7 @@ import jdk.internal.access.JavaNetURLAccess; import jdk.internal.access.SharedSecrets; +import sun.net.util.IPAddressUtil; import sun.security.util.SecurityConstants; import sun.security.action.GetPropertyAction; @@ -466,13 +467,19 @@ this.file = path; } - // Note: we don't do validation of the URL here. Too risky to change + // Note: we don't do full validation of the URL here. Too risky to change // right now, but worth considering for future reference. -br if (handler == null && (handler = getURLStreamHandler(protocol)) == null) { throw new MalformedURLException("unknown protocol: " + protocol); } this.handler = handler; + if (host != null && isBuiltinStreamHandler(handler)) { + String s = IPAddressUtil.checkExternalForm(this); + if (s != null) { + throw new MalformedURLException(s); + } + } } /** @@ -1038,7 +1045,12 @@ * @since 1.5 */ public URI toURI() throws URISyntaxException { - return new URI (toString()); + URI uri = new URI(toString()); + if (authority != null && isBuiltinStreamHandler(handler)) { + String s = IPAddressUtil.checkAuthority(this); + if (s != null) throw new URISyntaxException(authority, s); + } + return uri; } /** @@ -1635,6 +1647,10 @@ return replacementURL; } + boolean isBuiltinStreamHandler(URLStreamHandler handler) { + return isBuiltinStreamHandler(handler.getClass().getName()); + } + private boolean isBuiltinStreamHandler(String handlerClassName) { return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX)); } diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/java/net/URLStreamHandler.java --- a/src/java.base/share/classes/java/net/URLStreamHandler.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/java/net/URLStreamHandler.java Wed Jul 17 04:33:37 2019 -0700 @@ -516,12 +516,15 @@ * different from this one * @since 1.3 */ - protected void setURL(URL u, String protocol, String host, int port, + protected void setURL(URL u, String protocol, String host, int port, String authority, String userInfo, String path, String query, String ref) { if (this != u.handler) { throw new SecurityException("handler for url different from " + "this handler"); + } else if (host != null && u.isBuiltinStreamHandler(this)) { + String s = IPAddressUtil.checkHostString(host); + if (s != null) throw new IllegalArgumentException(s); } // ensure that no one can reset the protocol on a given URL. u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref); diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/java/security/AccessController.java --- a/src/java.base/share/classes/java/security/AccessController.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/java/security/AccessController.java Wed Jul 17 04:33:37 2019 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, 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 @@ -445,7 +445,8 @@ throw new NullPointerException("null permissions parameter"); } Class caller = Reflection.getCallerClass(); - return AccessController.doPrivileged(action, createWrapper(null, + DomainCombiner dc = (context == null) ? null : context.getCombiner(); + return AccessController.doPrivileged(action, createWrapper(dc, caller, parent, context, perms)); } @@ -860,7 +861,8 @@ throw new NullPointerException("null permissions parameter"); } Class caller = Reflection.getCallerClass(); - return AccessController.doPrivileged(action, createWrapper(null, caller, parent, context, perms)); + DomainCombiner dc = (context == null) ? null : context.getCombiner(); + return AccessController.doPrivileged(action, createWrapper(dc, caller, parent, context, perms)); } diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/java/util/Collections.java --- a/src/java.base/share/classes/java/util/Collections.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/java/util/Collections.java Wed Jul 17 04:33:37 2019 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, 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 @@ -26,6 +26,7 @@ package java.util; import java.io.IOException; +import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.lang.reflect.Array; @@ -39,6 +40,7 @@ import java.util.stream.IntStream; import java.util.stream.Stream; import java.util.stream.StreamSupport; +import jdk.internal.access.SharedSecrets; /** * This class consists exclusively of static methods that operate on or return @@ -5163,6 +5165,11 @@ public Spliterator spliterator() { return stream().spliterator(); } + + private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException { + ois.defaultReadObject(); + SharedSecrets.getJavaObjectInputStreamAccess().checkArray(ois, Object[].class, n); + } } /** diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/java/util/EnumSet.java --- a/src/java.base/share/classes/java/util/EnumSet.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/java/util/EnumSet.java Wed Jul 17 04:33:37 2019 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,11 +76,12 @@ * @since 1.5 * @see EnumMap */ -@SuppressWarnings("serial") // No serialVersionUID due to usage of - // serial proxy pattern public abstract class EnumSet> extends AbstractSet implements Cloneable, java.io.Serializable { + // declare EnumSet.class serialization compatibility with JDK 8 + private static final long serialVersionUID = 1009687484059888093L; + /** * The class of all the elements of this set. */ diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/net/util/IPAddressUtil.java --- a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java Wed Jul 17 04:33:37 2019 -0700 @@ -32,9 +32,11 @@ import java.net.InetSocketAddress; import java.net.NetworkInterface; import java.net.SocketException; +import java.net.URL; import java.security.AccessController; import java.security.PrivilegedExceptionAction; import java.security.PrivilegedActionException; +import java.util.Arrays; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @@ -372,4 +374,181 @@ return null; } } + + // See java.net.URI for more details on how to generate these + // masks. + // + // square brackets + private static final long L_IPV6_DELIMS = 0x0L; // "[]" + private static final long H_IPV6_DELIMS = 0x28000000L; // "[]" + // RFC 3986 gen-delims + private static final long L_GEN_DELIMS = 0x8400800800000000L; // ":/?#[]@" + private static final long H_GEN_DELIMS = 0x28000001L; // ":/?#[]@" + // These gen-delims can appear in authority + private static final long L_AUTH_DELIMS = 0x400000000000000L; // "@[]:" + private static final long H_AUTH_DELIMS = 0x28000001L; // "@[]:" + // colon is allowed in userinfo + private static final long L_COLON = 0x400000000000000L; // ":" + private static final long H_COLON = 0x0L; // ":" + // slash should be encoded in authority + private static final long L_SLASH = 0x800000000000L; // "/" + private static final long H_SLASH = 0x0L; // "/" + // backslash should always be encoded + private static final long L_BACKSLASH = 0x0L; // "\" + private static final long H_BACKSLASH = 0x10000000L; // "\" + // ASCII chars 0-31 + 127 - various controls + CRLF + TAB + private static final long L_NON_PRINTABLE = 0xffffffffL; + private static final long H_NON_PRINTABLE = 0x8000000000000000L; + // All of the above + private static final long L_EXCLUDE = 0x84008008ffffffffL; + private static final long H_EXCLUDE = 0x8000000038000001L; + + private static final char[] OTHERS = { + 8263,8264,8265,8448,8449,8453,8454,10868, + 65109,65110,65119,65131,65283,65295,65306,65311,65312 + }; + + // Tell whether the given character is found by the given mask pair + public static boolean match(char c, long lowMask, long highMask) { + if (c < 64) + return ((1L << c) & lowMask) != 0; + if (c < 128) + return ((1L << (c - 64)) & highMask) != 0; + return false; // other non ASCII characters are not filtered + } + + // returns -1 if the string doesn't contain any characters + // from the mask, the index of the first such character found + // otherwise. + public static int scan(String s, long lowMask, long highMask) { + int i = -1, len; + if (s == null || (len = s.length()) == 0) return -1; + boolean match = false; + while (++i < len && !(match = match(s.charAt(i), lowMask, highMask))); + if (match) return i; + return -1; + } + + public static int scan(String s, long lowMask, long highMask, char[] others) { + int i = -1, len; + if (s == null || (len = s.length()) == 0) return -1; + boolean match = false; + char c, c0 = others[0]; + while (++i < len && !(match = match((c=s.charAt(i)), lowMask, highMask))) { + if (c >= c0 && (Arrays.binarySearch(others, c) > -1)) { + match = true; break; + } + } + if (match) return i; + + return -1; + } + + private static String describeChar(char c) { + if (c < 32 || c == 127) { + if (c == '\n') return "LF"; + if (c == '\r') return "CR"; + return "control char (code=" + (int)c + ")"; + } + if (c == '\\') return "'\\'"; + return "'" + c + "'"; + } + + private static String checkUserInfo(String str) { + // colon is permitted in user info + int index = scan(str, L_EXCLUDE & ~L_COLON, + H_EXCLUDE & ~H_COLON); + if (index >= 0) { + return "Illegal character found in user-info: " + + describeChar(str.charAt(index)); + } + return null; + } + + private static String checkHost(String str) { + int index; + if (str.startsWith("[") && str.endsWith("]")) { + str = str.substring(1, str.length() - 1); + if (isIPv6LiteralAddress(str)) { + index = str.indexOf('%'); + if (index >= 0) { + index = scan(str = str.substring(index), + L_NON_PRINTABLE | L_IPV6_DELIMS, + H_NON_PRINTABLE | H_IPV6_DELIMS); + if (index >= 0) { + return "Illegal character found in IPv6 scoped address: " + + describeChar(str.charAt(index)); + } + } + return null; + } + return "Unrecognized IPv6 address format"; + } else { + index = scan(str, L_EXCLUDE, H_EXCLUDE); + if (index >= 0) { + return "Illegal character found in host: " + + describeChar(str.charAt(index)); + } + } + return null; + } + + private static String checkAuth(String str) { + int index = scan(str, + L_EXCLUDE & ~L_AUTH_DELIMS, + H_EXCLUDE & ~H_AUTH_DELIMS); + if (index >= 0) { + return "Illegal character found in authority: " + + describeChar(str.charAt(index)); + } + return null; + } + + // check authority of hierarchical URL. Appropriate for + // HTTP-like protocol handlers + public static String checkAuthority(URL url) { + String s, u, h; + if (url == null) return null; + if ((s = checkUserInfo(u = url.getUserInfo())) != null) { + return s; + } + if ((s = checkHost(h = url.getHost())) != null) { + return s; + } + if (h == null && u == null) { + return checkAuth(url.getAuthority()); + } + return null; + } + + // minimal syntax checks - deeper check may be performed + // by the appropriate protocol handler + public static String checkExternalForm(URL url) { + String s; + if (url == null) return null; + int index = scan(s = url.getUserInfo(), + L_NON_PRINTABLE | L_SLASH, + H_NON_PRINTABLE | H_SLASH); + if (index >= 0) { + return "Illegal character found in authority: " + + describeChar(s.charAt(index)); + } + if ((s = checkHostString(url.getHost())) != null) { + return s; + } + return null; + } + + public static String checkHostString(String host) { + if (host == null) return null; + int index = scan(host, + L_NON_PRINTABLE | L_SLASH, + H_NON_PRINTABLE | H_SLASH, + OTHERS); + if (index >= 0) { + return "Illegal character found in host: " + + describeChar(host.charAt(index)); + } + return null; + } } diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java --- a/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java Wed Jul 17 04:33:37 2019 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,6 +36,7 @@ import java.io.FilterInputStream; import java.io.FilterOutputStream; import java.io.FileNotFoundException; +import java.net.MalformedURLException; import java.net.URL; import java.net.SocketPermission; import java.net.UnknownHostException; @@ -48,6 +49,7 @@ import java.security.Permission; import java.util.Properties; import sun.net.NetworkClient; +import sun.net.util.IPAddressUtil; import sun.net.www.MessageHeader; import sun.net.www.MeteredStream; import sun.net.www.URLConnection; @@ -157,6 +159,21 @@ } } + static URL checkURL(URL u) throws IllegalArgumentException { + if (u != null) { + if (u.toExternalForm().indexOf('\n') > -1) { + Exception mfue = new MalformedURLException("Illegal character in URL"); + throw new IllegalArgumentException(mfue.getMessage(), mfue); + } + } + String s = IPAddressUtil.checkAuthority(u); + if (s != null) { + Exception mfue = new MalformedURLException(s); + throw new IllegalArgumentException(mfue.getMessage(), mfue); + } + return u; + } + /** * Creates an FtpURLConnection from a URL. * @@ -170,7 +187,7 @@ * Same as FtpURLconnection(URL) with a per connection proxy specified */ FtpURLConnection(URL url, Proxy p) { - super(url); + super(checkURL(url)); instProxy = p; host = url.getHost(); port = url.getPort(); diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Jul 17 04:33:37 2019 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -68,6 +68,7 @@ import jdk.internal.access.JavaNetHttpCookieAccess; import jdk.internal.access.SharedSecrets; import sun.net.*; +import sun.net.util.IPAddressUtil; import sun.net.www.*; import sun.net.www.http.HttpClient; import sun.net.www.http.PosterOutputStream; @@ -868,8 +869,13 @@ throw new MalformedURLException("Illegal character in URL"); } } + String s = IPAddressUtil.checkAuthority(u); + if (s != null) { + throw new MalformedURLException(s); + } return u; } + protected HttpURLConnection(URL u, Proxy p, Handler handler) throws IOException { super(checkURL(u)); diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/net/www/protocol/https/HttpsURLConnectionImpl.java --- a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsURLConnectionImpl.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsURLConnectionImpl.java Wed Jul 17 04:33:37 2019 -0700 @@ -37,6 +37,7 @@ import java.util.Map; import java.util.List; import java.util.Optional; +import sun.net.util.IPAddressUtil; import sun.net.www.http.HttpClient; /** @@ -69,6 +70,10 @@ throw new MalformedURLException("Illegal character in URL"); } } + String s = IPAddressUtil.checkAuthority(u); + if (s != null) { + throw new MalformedURLException(s); + } return u; } @@ -289,7 +294,7 @@ * @param key the keyword by which the request is known * (e.g., "accept"). * @param value the value associated with it. - * @see #getRequestProperties(java.lang.String) + * @see #getRequestProperty(java.lang.String) * @since 1.4 */ public void addRequestProperty(String key, String value) { diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/security/ssl/CertStatusExtension.java --- a/src/java.base/share/classes/sun/security/ssl/CertStatusExtension.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/security/ssl/CertStatusExtension.java Wed Jul 17 04:33:37 2019 -0700 @@ -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 @@ -724,12 +724,14 @@ // Update the context. chc.handshakeExtensions.put( SH_STATUS_REQUEST, CertStatusRequestSpec.DEFAULT); - chc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_STATUS.id, - SSLHandshake.CERTIFICATE_STATUS); // Since we've received a legitimate status_request in the // ServerHello, stapling is active if it's been enabled. chc.staplingActive = chc.sslContext.isStaplingEnabled(true); + if (chc.staplingActive) { + chc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_STATUS.id, + SSLHandshake.CERTIFICATE_STATUS); + } // No impact on session resumption. } @@ -1079,12 +1081,16 @@ // Update the context. chc.handshakeExtensions.put( SH_STATUS_REQUEST_V2, CertStatusRequestV2Spec.DEFAULT); - chc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_STATUS.id, - SSLHandshake.CERTIFICATE_STATUS); // Since we've received a legitimate status_request in the - // ServerHello, stapling is active if it's been enabled. + // ServerHello, stapling is active if it's been enabled. If it + // is active, make sure we add the CertificateStatus message + // consumer. chc.staplingActive = chc.sslContext.isStaplingEnabled(true); + if (chc.staplingActive) { + chc.handshakeConsumers.put(SSLHandshake.CERTIFICATE_STATUS.id, + SSLHandshake.CERTIFICATE_STATUS); + } // No impact on session resumption. } diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/security/ssl/CertificateRequest.java --- a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java Wed Jul 17 04:33:37 2019 -0700 @@ -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 @@ -330,6 +330,15 @@ // clean up this consumer chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_REQUEST.id); + SSLConsumer certStatCons = chc.handshakeConsumers.remove( + SSLHandshake.CERTIFICATE_STATUS.id); + if (certStatCons != null) { + // Stapling was active but no certificate status message + // was sent. We need to run the absence handler which will + // check the certificate chain. + CertificateStatus.handshakeAbsence.absent(context, null); + } + T10CertificateRequestMessage crm = new T10CertificateRequestMessage(chc, message); if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { @@ -647,6 +656,15 @@ // clean up this consumer chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_REQUEST.id); + SSLConsumer certStatCons = chc.handshakeConsumers.remove( + SSLHandshake.CERTIFICATE_STATUS.id); + if (certStatCons != null) { + // Stapling was active but no certificate status message + // was sent. We need to run the absence handler which will + // check the certificate chain. + CertificateStatus.handshakeAbsence.absent(context, null); + } + T12CertificateRequestMessage crm = new T12CertificateRequestMessage(chc, message); if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/security/ssl/CertificateStatus.java --- a/src/java.base/share/classes/sun/security/ssl/CertificateStatus.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/security/ssl/CertificateStatus.java Wed Jul 17 04:33:37 2019 -0700 @@ -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 @@ -287,12 +287,16 @@ } // Pin the received responses to the SSLSessionImpl. It will - // be retrieved by the X509TrustManagerImpl during the certficicate + // be retrieved by the X509TrustManagerImpl during the certificate // checking phase. chc.handshakeSession.setStatusResponses(cst.encodedResponses); // Now perform the check T12CertificateConsumer.checkServerCerts(chc, chc.deferredCerts); + + // Update the handshake consumers to remove this message, indicating + // that it has been processed. + chc.handshakeConsumers.remove(SSLHandshake.CERTIFICATE_STATUS.id); } } diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java --- a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Wed Jul 17 04:33:37 2019 -0700 @@ -1480,8 +1480,9 @@ checkAdditionalTrust(chain, authType, engine, false); } - private void checkAdditionalTrust(X509Certificate[] chain, String authType, - Socket socket, boolean isClient) throws CertificateException { + private void checkAdditionalTrust(X509Certificate[] chain, + String authType, Socket socket, + boolean checkClientTrusted) throws CertificateException { if (socket != null && socket.isConnected() && socket instanceof SSLSocket) { @@ -1495,9 +1496,8 @@ String identityAlg = sslSocket.getSSLParameters(). getEndpointIdentificationAlgorithm(); if (identityAlg != null && !identityAlg.isEmpty()) { - String hostname = session.getPeerHost(); - X509TrustManagerImpl.checkIdentity( - hostname, chain[0], identityAlg); + X509TrustManagerImpl.checkIdentity(session, chain, + identityAlg, checkClientTrusted); } // try the best to check the algorithm constraints @@ -1519,12 +1519,13 @@ constraints = new SSLAlgorithmConstraints(sslSocket, true); } - checkAlgorithmConstraints(chain, constraints, isClient); + checkAlgorithmConstraints(chain, constraints, checkClientTrusted); } } - private void checkAdditionalTrust(X509Certificate[] chain, String authType, - SSLEngine engine, boolean isClient) throws CertificateException { + private void checkAdditionalTrust(X509Certificate[] chain, + String authType, SSLEngine engine, + boolean checkClientTrusted) throws CertificateException { if (engine != null) { SSLSession session = engine.getHandshakeSession(); if (session == null) { @@ -1535,9 +1536,8 @@ String identityAlg = engine.getSSLParameters(). getEndpointIdentificationAlgorithm(); if (identityAlg != null && !identityAlg.isEmpty()) { - String hostname = session.getPeerHost(); - X509TrustManagerImpl.checkIdentity( - hostname, chain[0], identityAlg); + X509TrustManagerImpl.checkIdentity(session, chain, + identityAlg, checkClientTrusted); } // try the best to check the algorithm constraints @@ -1559,13 +1559,13 @@ constraints = new SSLAlgorithmConstraints(engine, true); } - checkAlgorithmConstraints(chain, constraints, isClient); + checkAlgorithmConstraints(chain, constraints, checkClientTrusted); } } private void checkAlgorithmConstraints(X509Certificate[] chain, AlgorithmConstraints constraints, - boolean isClient) throws CertificateException { + boolean checkClientTrusted) throws CertificateException { try { // Does the certificate chain end with a trusted certificate? int checkedLength = chain.length - 1; @@ -1584,7 +1584,7 @@ if (checkedLength >= 0) { AlgorithmChecker checker = new AlgorithmChecker(constraints, null, - (isClient ? Validator.VAR_TLS_CLIENT : + (checkClientTrusted ? Validator.VAR_TLS_CLIENT : Validator.VAR_TLS_SERVER)); checker.init(false); for (int i = checkedLength; i >= 0; i--) { diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/security/ssl/ServerHelloDone.java --- a/src/java.base/share/classes/sun/security/ssl/ServerHelloDone.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/security/ssl/ServerHelloDone.java Wed Jul 17 04:33:37 2019 -0700 @@ -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 @@ -133,6 +133,15 @@ // The consuming happens in client side only. ClientHandshakeContext chc = (ClientHandshakeContext)context; + SSLConsumer certStatCons = chc.handshakeConsumers.remove( + SSLHandshake.CERTIFICATE_STATUS.id); + if (certStatCons != null) { + // Stapling was active but no certificate status message + // was sent. We need to run the absence handler which will + // check the certificate chain. + CertificateStatus.handshakeAbsence.absent(context, null); + } + // clean up this consumer chc.handshakeConsumers.clear(); diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/security/ssl/ServerKeyExchange.java --- a/src/java.base/share/classes/sun/security/ssl/ServerKeyExchange.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/security/ssl/ServerKeyExchange.java Wed Jul 17 04:33:37 2019 -0700 @@ -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 @@ -92,6 +92,15 @@ // clean up this consumer chc.handshakeConsumers.remove(SSLHandshake.SERVER_KEY_EXCHANGE.id); + SSLConsumer certStatCons = chc.handshakeConsumers.remove( + SSLHandshake.CERTIFICATE_STATUS.id); + if (certStatCons != null) { + // Stapling was active but no certificate status message + // was sent. We need to run the absence handler which will + // check the certificate chain. + CertificateStatus.handshakeAbsence.absent(context, null); + } + SSLKeyExchange ke = SSLKeyExchange.valueOf( chc.negotiatedCipherSuite.keyExchange, chc.negotiatedProtocol); diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java --- a/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/security/ssl/X509TrustManagerImpl.java Wed Jul 17 04:33:37 2019 -0700 @@ -145,7 +145,7 @@ } private Validator checkTrustedInit(X509Certificate[] chain, - String authType, boolean isClient) { + String authType, boolean checkClientTrusted) { if (chain == null || chain.length == 0) { throw new IllegalArgumentException( "null or zero-length certificate chain"); @@ -157,7 +157,7 @@ } Validator v = null; - if (isClient) { + if (checkClientTrusted) { v = clientValidator; if (v == null) { validatorLock.lock(); @@ -192,9 +192,10 @@ return v; } - private void checkTrusted(X509Certificate[] chain, String authType, - Socket socket, boolean isClient) throws CertificateException { - Validator v = checkTrustedInit(chain, authType, isClient); + private void checkTrusted(X509Certificate[] chain, + String authType, Socket socket, + boolean checkClientTrusted) throws CertificateException { + Validator v = checkTrustedInit(chain, authType, checkClientTrusted); X509Certificate[] trustedChain = null; if ((socket != null) && socket.isConnected() && @@ -223,28 +224,23 @@ // Grab any stapled OCSP responses for use in validation List responseList = Collections.emptyList(); - if (!isClient && isExtSession) { + if (!checkClientTrusted && isExtSession) { responseList = ((ExtendedSSLSession)session).getStatusResponses(); } trustedChain = v.validate(chain, null, responseList, - constraints, isClient ? null : authType); - - // check if EE certificate chains to a public root CA (as - // pre-installed in cacerts) - boolean chainsToPublicCA = AnchorCertificates.contains( - trustedChain[trustedChain.length-1]); + constraints, checkClientTrusted ? null : authType); // check endpoint identity String identityAlg = sslSocket.getSSLParameters(). getEndpointIdentificationAlgorithm(); if (identityAlg != null && !identityAlg.isEmpty()) { - checkIdentity(session, trustedChain[0], identityAlg, isClient, - getRequestedServerNames(socket), chainsToPublicCA); + checkIdentity(session, + trustedChain, identityAlg, checkClientTrusted); } } else { trustedChain = v.validate(chain, null, Collections.emptyList(), - null, isClient ? null : authType); + null, checkClientTrusted ? null : authType); } if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) { @@ -253,9 +249,10 @@ } } - private void checkTrusted(X509Certificate[] chain, String authType, - SSLEngine engine, boolean isClient) throws CertificateException { - Validator v = checkTrustedInit(chain, authType, isClient); + private void checkTrusted(X509Certificate[] chain, + String authType, SSLEngine engine, + boolean checkClientTrusted) throws CertificateException { + Validator v = checkTrustedInit(chain, authType, checkClientTrusted); X509Certificate[] trustedChain = null; if (engine != null) { @@ -281,28 +278,23 @@ // Grab any stapled OCSP responses for use in validation List responseList = Collections.emptyList(); - if (!isClient && isExtSession) { + if (!checkClientTrusted && isExtSession) { responseList = ((ExtendedSSLSession)session).getStatusResponses(); } trustedChain = v.validate(chain, null, responseList, - constraints, isClient ? null : authType); - - // check if EE certificate chains to a public root CA (as - // pre-installed in cacerts) - boolean chainsToPublicCA = AnchorCertificates.contains( - trustedChain[trustedChain.length-1]); + constraints, checkClientTrusted ? null : authType); // check endpoint identity String identityAlg = engine.getSSLParameters(). getEndpointIdentificationAlgorithm(); if (identityAlg != null && !identityAlg.isEmpty()) { - checkIdentity(session, trustedChain[0], identityAlg, isClient, - getRequestedServerNames(engine), chainsToPublicCA); + checkIdentity(session, trustedChain, + identityAlg, checkClientTrusted); } } else { trustedChain = v.validate(chain, null, Collections.emptyList(), - null, isClient ? null : authType); + null, checkClientTrusted ? null : authType); } if (SSLLogger.isOn && SSLLogger.isOn("ssl,trustmanager")) { @@ -360,14 +352,8 @@ static List getRequestedServerNames(Socket socket) { if (socket != null && socket.isConnected() && socket instanceof SSLSocket) { - - SSLSocket sslSocket = (SSLSocket)socket; - SSLSession session = sslSocket.getHandshakeSession(); - - if (session != null && (session instanceof ExtendedSSLSession)) { - ExtendedSSLSession extSession = (ExtendedSSLSession)session; - return extSession.getRequestedServerNames(); - } + return getRequestedServerNames( + ((SSLSocket)socket).getHandshakeSession()); } return Collections.emptyList(); @@ -376,12 +362,16 @@ // Also used by X509KeyManagerImpl static List getRequestedServerNames(SSLEngine engine) { if (engine != null) { - SSLSession session = engine.getHandshakeSession(); + return getRequestedServerNames(engine.getHandshakeSession()); + } - if (session != null && (session instanceof ExtendedSSLSession)) { - ExtendedSSLSession extSession = (ExtendedSSLSession)session; - return extSession.getRequestedServerNames(); - } + return Collections.emptyList(); + } + + private static List getRequestedServerNames( + SSLSession session) { + if (session != null && (session instanceof ExtendedSSLSession)) { + return ((ExtendedSSLSession)session).getRequestedServerNames(); } return Collections.emptyList(); @@ -402,23 +392,28 @@ * the identity checking aginst the server_name extension if present, and * may failove to peer host checking. */ - private static void checkIdentity(SSLSession session, - X509Certificate cert, + static void checkIdentity(SSLSession session, + X509Certificate[] trustedChain, String algorithm, - boolean isClient, - List sniNames, - boolean chainsToPublicCA) throws CertificateException { + boolean checkClientTrusted) throws CertificateException { + + // check if EE certificate chains to a public root CA (as + // pre-installed in cacerts) + boolean chainsToPublicCA = AnchorCertificates.contains( + trustedChain[trustedChain.length - 1]); boolean identifiable = false; String peerHost = session.getPeerHost(); - if (isClient) { - String hostname = getHostNameInSNI(sniNames); - if (hostname != null) { + if (!checkClientTrusted) { + List sniNames = getRequestedServerNames(session); + String sniHostName = getHostNameInSNI(sniNames); + if (sniHostName != null) { try { - checkIdentity(hostname, cert, algorithm, chainsToPublicCA); + checkIdentity(sniHostName, + trustedChain[0], algorithm, chainsToPublicCA); identifiable = true; } catch (CertificateException ce) { - if (hostname.equalsIgnoreCase(peerHost)) { + if (sniHostName.equalsIgnoreCase(peerHost)) { throw ce; } @@ -428,7 +423,8 @@ } if (!identifiable) { - checkIdentity(peerHost, cert, algorithm, chainsToPublicCA); + checkIdentity(peerHost, + trustedChain[0], algorithm, chainsToPublicCA); } } diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/security/util/DerIndefLenConverter.java --- a/src/java.base/share/classes/sun/security/util/DerIndefLenConverter.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/security/util/DerIndefLenConverter.java Wed Jul 17 04:33:37 2019 -0700 @@ -92,8 +92,6 @@ * add the current position to the eocList vector. */ private void parseTag() throws IOException { - if (dataPos == dataSize) - return; if (isEOC(data[dataPos]) && (data[dataPos + 1] == 0)) { int numOfEncapsulatedLenBytes = 0; Object elem = null; @@ -332,6 +330,10 @@ // parse and set up the vectors of all the indefinite-lengths while (dataPos < dataSize) { + if (dataPos + 2 > dataSize) { + // There should be at least one tag and one length + return null; + } parseTag(); len = parseLength(); if (len < 0) { diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/security/util/HostnameChecker.java --- a/src/java.base/share/classes/sun/security/util/HostnameChecker.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/security/util/HostnameChecker.java Wed Jul 17 04:33:37 2019 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -260,28 +260,35 @@ * The matching is performed as per RFC 2818 rules for TLS and * RFC 2830 rules for LDAP.

* - * The name parameter should represent a DNS name. - * The template parameter - * may contain the wildcard character * + * The name parameter should represent a DNS name. The + * template parameter may contain the wildcard character '*'. */ private boolean isMatched(String name, String template, boolean chainsToPublicCA) { // Normalize to Unicode, because PSL is in Unicode. - name = IDN.toUnicode(IDN.toASCII(name)); - template = IDN.toUnicode(IDN.toASCII(template)); + try { + name = IDN.toUnicode(IDN.toASCII(name)); + template = IDN.toUnicode(IDN.toASCII(template)); + } catch (RuntimeException re) { + if (SSLLogger.isOn) { + SSLLogger.fine("Failed to normalize to Unicode: " + re); + } - if (hasIllegalWildcard(name, template, chainsToPublicCA)) { + return false; + } + + if (hasIllegalWildcard(template, chainsToPublicCA)) { return false; } // check the validity of the domain name template. try { - // Replacing wildcard character '*' with 'x' so as to check + // Replacing wildcard character '*' with 'z' so as to check // the domain name template validity. // // Using the checking implemented in SNIHostName - new SNIHostName(template.replace('*', 'x')); + new SNIHostName(template.replace('*', 'z')); } catch (IllegalArgumentException iae) { // It would be nice to add debug log if not matching. return false; @@ -299,8 +306,8 @@ /** * Returns true if the template contains an illegal wildcard character. */ - private static boolean hasIllegalWildcard(String domain, String template, - boolean chainsToPublicCA) { + private static boolean hasIllegalWildcard( + String template, boolean chainsToPublicCA) { // not ok if it is a single wildcard character or "*." if (template.equals("*") || template.equals("*.")) { if (SSLLogger.isOn) { @@ -331,25 +338,29 @@ return true; } - // If the wildcarded domain is a top-level domain under which names - // can be registered, then a wildcard is not allowed. - if (!chainsToPublicCA) { return false; // skip check for non-public certificates } - Optional rd = RegisteredDomain.from(domain) - .filter(d -> d.type() == RegisteredDomain.Type.ICANN); - if (rd.isPresent()) { - String wDomain = afterWildcard.substring(firstDotIndex + 1); - if (rd.get().publicSuffix().equalsIgnoreCase(wDomain)) { - if (SSLLogger.isOn) { - SSLLogger.fine( - "Certificate domain name has illegal " + - "wildcard for public suffix: " + template); - } - return true; + // If the wildcarded domain is a top-level domain under which names + // can be registered, then a wildcard is not allowed. + String wildcardedDomain = afterWildcard.substring(firstDotIndex + 1); + String templateDomainSuffix = + RegisteredDomain.from("z." + wildcardedDomain) + .filter(d -> d.type() == RegisteredDomain.Type.ICANN) + .map(RegisteredDomain::publicSuffix).orElse(null); + if (templateDomainSuffix == null) { + return false; // skip check if not known public suffix + } + + // Is it a top-level domain? + if (wildcardedDomain.equalsIgnoreCase(templateDomainSuffix)) { + if (SSLLogger.isOn) { + SSLLogger.fine( + "Certificate domain name has illegal " + + "wildcard for top-level public suffix: " + template); } + return true; } return false; diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java --- a/src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/share/classes/sun/security/util/KeyStoreDelegator.java Wed Jul 17 04:33:37 2019 -0700 @@ -269,6 +269,8 @@ throw (CertificateException)e; } else if (e instanceof NoSuchAlgorithmException) { throw (NoSuchAlgorithmException)e; + } else if (e instanceof RuntimeException){ + throw (RuntimeException)e; } } } diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java --- a/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.base/windows/classes/sun/net/www/protocol/file/Handler.java Wed Jul 17 04:33:37 2019 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -95,7 +95,7 @@ path = "\\\\" + host + path; File f = new File(path); if (f.exists()) { - return createFileURLConnection(url, f); + return new UNCFileURLConnection(url, f, path); } /* diff -r 9a97b1393e72 -r 2b4e14968afd src/java.base/windows/classes/sun/net/www/protocol/file/UNCFileURLConnection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.base/windows/classes/sun/net/www/protocol/file/UNCFileURLConnection.java Wed Jul 17 04:33:37 2019 -0700 @@ -0,0 +1,52 @@ +/* + * 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 sun.net.www.protocol.file; + +import java.io.File; +import java.io.FilePermission; +import java.net.URL; +import java.security.Permission; + +final class UNCFileURLConnection extends FileURLConnection { + + private final String effectivePath; + private volatile Permission permission; + + UNCFileURLConnection(URL u, File file, String effectivePath) { + super(u, file); + this.effectivePath = effectivePath; + } + + @Override + public Permission getPermission() { + Permission perm = permission; + if (perm == null) { + permission = perm = new FilePermission(effectivePath, "read"); + } + return perm; + } +} + diff -r 9a97b1393e72 -r 2b4e14968afd src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java Wed Jul 17 04:33:37 2019 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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,7 +34,6 @@ import javax.swing.JProgressBar; import javax.swing.JTabbedPane; import javax.swing.JSlider; -import javax.swing.JCheckBox; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -42,6 +41,7 @@ import static javax.accessibility.AccessibleContext.ACCESSIBLE_CARET_PROPERTY; import static javax.accessibility.AccessibleContext.ACCESSIBLE_SELECTION_PROPERTY; import static javax.accessibility.AccessibleContext.ACCESSIBLE_STATE_PROPERTY; +import static javax.accessibility.AccessibleContext.ACCESSIBLE_TABLE_MODEL_CHANGED; import static javax.accessibility.AccessibleContext.ACCESSIBLE_TEXT_PROPERTY; import static javax.accessibility.AccessibleContext.ACCESSIBLE_NAME_PROPERTY; @@ -129,6 +129,8 @@ valueChanged(ptr); } else if (name.compareTo(ACCESSIBLE_SELECTION_PROPERTY) == 0) { selectionChanged(ptr); + } else if (name.compareTo(ACCESSIBLE_TABLE_MODEL_CHANGED) == 0) { + valueChanged(ptr); } else if (name.compareTo(ACCESSIBLE_ACTIVE_DESCENDANT_PROPERTY) == 0 ) { if (newValue instanceof AccessibleContext) { activeDescendant = (AccessibleContext)newValue; diff -r 9a97b1393e72 -r 2b4e14968afd src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m --- a/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.desktop/macosx/native/libsplashscreen/splashscreen_sys.m Wed Jul 17 04:33:37 2019 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -214,7 +214,7 @@ splash->maskRequired = 0; - + //TODO: the following is too much of a hack but should work in 90% cases. // besides we don't use device-dependent drawing, so probably // that's very fine indeed @@ -282,9 +282,11 @@ SplashRedrawWindow(Splash * splash) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - SplashUpdateScreenData(splash); + [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ + // drop the reference to the old view and image + [splash->window setContentView: nil]; + SplashUpdateScreenData(splash); - [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){ // NSDeviceRGBColorSpace vs. NSCalibratedRGBColorSpace ? NSBitmapImageRep * rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: (unsigned char**)&splash->screenData @@ -311,7 +313,7 @@ size.height /= scaleFactor; [image setSize: size]; } - + NSImageView * view = [[NSImageView alloc] init]; [view setImage: image]; diff -r 9a97b1393e72 -r 2b4e14968afd src/java.desktop/share/classes/javax/swing/JTable.java --- a/src/java.desktop/share/classes/javax/swing/JTable.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.desktop/share/classes/javax/swing/JTable.java Wed Jul 17 04:33:37 2019 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, 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 @@ -5278,7 +5278,8 @@ // Don't start when just a modifier is pressed int code = e.getKeyCode(); if (code == KeyEvent.VK_SHIFT || code == KeyEvent.VK_CONTROL || - code == KeyEvent.VK_ALT) { + code == KeyEvent.VK_ALT || code == KeyEvent.VK_META || + code == KeyEvent.VK_ALT_GRAPH) { return false; } // Try to install the editor @@ -5302,7 +5303,9 @@ // If we have started an editor as a result of the user // pressing a key and the surrendersFocusOnKeystroke property // is true, give the focus to the new editor. - if (getSurrendersFocusOnKeystroke()) { + Object prop = getClientProperty("JTable.forceAutoStartsEdit"); + if (getSurrendersFocusOnKeystroke() + || Boolean.TRUE.equals(prop)) { editorComponent.requestFocus(); } } @@ -6668,6 +6671,7 @@ */ protected AccessibleJTable() { super(); + JTable.this.putClientProperty("JTable.forceAutoStartsEdit", true); JTable.this.addPropertyChangeListener(this); JTable.this.getSelectionModel().addListSelectionListener(this); TableColumnModel tcm = JTable.this.getColumnModel(); @@ -7104,15 +7108,12 @@ int row = rowAtPoint(p); if ((column != -1) && (row != -1)) { - TableColumn aColumn = getColumnModel().getColumn(column); - TableCellRenderer renderer = aColumn.getCellRenderer(); - if (renderer == null) { - Class columnClass = getColumnClass(column); - renderer = getDefaultRenderer(columnClass); - } - Component component = renderer.getTableCellRendererComponent( - JTable.this, null, false, false, - row, column); + if (row == getEditingRow() && column == getEditingColumn()) { + Component editor = getEditorComponent(); + if (editor instanceof Accessible) { + return (Accessible) editor; + } + } return new AccessibleJTableCell(JTable.this, row, column, getAccessibleIndexAt(row, column)); } @@ -7145,15 +7146,12 @@ int column = getAccessibleColumnAtIndex(i); int row = getAccessibleRowAtIndex(i); - TableColumn aColumn = getColumnModel().getColumn(column); - TableCellRenderer renderer = aColumn.getCellRenderer(); - if (renderer == null) { - Class columnClass = getColumnClass(column); - renderer = getDefaultRenderer(columnClass); - } - Component component = renderer.getTableCellRendererComponent( - JTable.this, null, false, false, - row, column); + if (row == getEditingRow() && column == getEditingColumn()) { + Component editor = getEditorComponent(); + if (editor instanceof Accessible) { + return (Accessible) editor; + } + } return new AccessibleJTableCell(JTable.this, row, column, getAccessibleIndexAt(row, column)); } diff -r 9a97b1393e72 -r 2b4e14968afd src/java.desktop/share/native/libsplashscreen/libpng/png.c --- a/src/java.desktop/share/native/libsplashscreen/libpng/png.c Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.desktop/share/native/libsplashscreen/libpng/png.c Wed Jul 17 04:33:37 2019 -0700 @@ -4622,8 +4622,7 @@ if (image != NULL && image->opaque != NULL && image->opaque->error_buf == NULL) { - /* Ignore errors here: */ - (void)png_safe_execute(image, png_image_free_function, image); + png_image_free_function(image); image->opaque = NULL; } } diff -r 9a97b1393e72 -r 2b4e14968afd src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceData.java Wed Jul 17 04:33:37 2019 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2013, 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,6 @@ import sun.java2d.pipe.ShapeDrawPipe; import sun.java2d.pipe.TextPipe; import sun.java2d.pipe.ValidatePipe; -import sun.java2d.x11.X11SurfaceData; import sun.java2d.x11.XSurfaceData; import sun.font.FontManagerNativeLibrary; @@ -244,7 +243,7 @@ */ public static XRWindowSurfaceData createData(X11ComponentPeer peer) { XRGraphicsConfig gc = getGC(peer); - return new XRWindowSurfaceData(peer, gc, X11SurfaceData.getSurfaceType(gc, Transparency.OPAQUE)); + return new XRWindowSurfaceData(peer, gc, gc.getSurfaceType()); } /** diff -r 9a97b1393e72 -r 2b4e14968afd src/java.security.jgss/macosx/native/libosxkrb5/SCDynamicStoreConfig.m --- a/src/java.security.jgss/macosx/native/libosxkrb5/SCDynamicStoreConfig.m Wed Jul 17 12:35:46 2019 +0200 +++ b/src/java.security.jgss/macosx/native/libosxkrb5/SCDynamicStoreConfig.m Wed Jul 17 04:33:37 2019 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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,8 @@ for (NSString *realm in realms) { CFTypeRef realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:@"Kerberos:%@", realm]); - if (CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) { + if (realmInfo == NULL || CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) { + if (realmInfo) CFRelease(realmInfo); return nil; } diff -r 9a97b1393e72 -r 2b4e14968afd src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Wed Jul 17 12:35:46 2019 +0200 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Wed Jul 17 04:33:37 2019 -0700 @@ -99,6 +99,10 @@ */ protected boolean shouldTranslateEscapes; + /** Has the string broken escapes? + */ + protected boolean hasBrokenEscapes; + protected ScannerFactory fac; // The set of lint options currently in effect. It is initialized @@ -261,6 +265,7 @@ case '\\': reader.putChar(true); break; default: + hasBrokenEscapes = true; lexError(reader.bp, Errors.IllegalEscChar); } } @@ -426,6 +431,7 @@ // Clear flags. shouldStripIndent = false; shouldTranslateEscapes = false; + hasBrokenEscapes = false; // Check if text block string methods are present. boolean hasTextBlockSupport = TextBlockSupport.hasSupport(); // Track the end of first line for error recovery. @@ -1038,7 +1044,7 @@ string = TextBlockSupport.stripIndent(string); } // Translate escape sequences if present. - if (shouldTranslateEscapes) { + if (shouldTranslateEscapes && !hasBrokenEscapes) { string = TextBlockSupport.translateEscapes(string); } // Build string token. diff -r 9a97b1393e72 -r 2b4e14968afd test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java --- a/test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java Wed Jul 17 12:35:46 2019 +0200 +++ b/test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java Wed Jul 17 04:33:37 2019 -0700 @@ -61,13 +61,17 @@ public class SharedArchiveConsistency { public static WhiteBox wb; - public static int offset_magic; // FileMapHeader::_magic - public static int sp_offset_crc; // CDSFileMapRegion::_crc + public static int offset_magic; // CDSFileMapHeaderBase::_magic + public static int offset_version; // CDSFileMapHeaderBase::_version + public static int offset_jvm_ident; // FileMapHeader::_jvm_ident + public static int sp_offset_crc; // CDSFileMapRegion::_crc + public static int offset_paths_misc_info_size; public static int file_header_size = -1;// total size of header, variant, need calculation public static int CDSFileMapRegion_size; // size of CDSFileMapRegion public static int sp_offset; // offset of CDSFileMapRegion public static int sp_used_offset; // offset of CDSFileMapRegion::_used public static int size_t_size; // size of size_t + public static int int_size; // size of int public static File jsa; // will be updated during test public static File orgJsaFile; // kept the original file not touched. @@ -94,6 +98,8 @@ public static void getFileOffsetInfo() throws Exception { wb = WhiteBox.getWhiteBox(); offset_magic = wb.getOffsetForName("FileMapHeader::_magic"); + offset_version = wb.getOffsetForName("FileMapHeader::_version"); + offset_jvm_ident = wb.getOffsetForName("FileMapHeader::_jvm_ident"); sp_offset_crc = wb.getOffsetForName("CDSFileMapRegion::_crc"); try { int nonExistOffset = wb.getOffsetForName("FileMapHeader::_non_exist_offset"); @@ -113,13 +119,13 @@ return file_header_size; } // this is not real header size, it is struct size - int int_size = wb.getOffsetForName("int_size"); + int_size = wb.getOffsetForName("int_size"); file_header_size = wb.getOffsetForName("file_header_size"); - int offset_path_misc_info = wb.getOffsetForName("FileMapHeader::_paths_misc_info_size") - + offset_paths_misc_info_size = wb.getOffsetForName("FileMapHeader::_paths_misc_info_size") - offset_magic; - int path_misc_info_size = (int)readInt(fc, offset_path_misc_info, int_size); - file_header_size += path_misc_info_size; //readInt(fc, offset_path_misc_info, size_t_size); - System.out.println("offset_path_misc_info = " + offset_path_misc_info); + int path_misc_info_size = (int)readInt(fc, offset_paths_misc_info_size, int_size); + file_header_size += path_misc_info_size; + System.out.println("offset_paths_misc_info_size = " + offset_paths_misc_info_size); System.out.println("path_misc_info_size = " + path_misc_info_size); System.out.println("file_header_size = " + file_header_size); file_header_size = (int)align_up_page(file_header_size); @@ -160,15 +166,15 @@ fc.force(true); } - public static FileChannel getFileChannel() throws Exception { + public static FileChannel getFileChannel(File jsaFile) throws Exception { List arry = new ArrayList(); arry.add(READ); arry.add(WRITE); - return FileChannel.open(jsa.toPath(), new HashSet(arry)); + return FileChannel.open(jsaFile.toPath(), new HashSet(arry)); } - public static void modifyJsaContentRandomly() throws Exception { - FileChannel fc = getFileChannel(); + public static void modifyJsaContentRandomly(File jsaFile) throws Exception { + FileChannel fc = getFileChannel(jsaFile); // corrupt random area in the data areas long[] used = new long[num_regions]; // record used bytes long start0, start, end, off; @@ -210,8 +216,8 @@ return used; } - public static boolean modifyJsaContent(int region) throws Exception { - FileChannel fc = getFileChannel(); + public static boolean modifyJsaContent(int region, File jsaFile) throws Exception { + FileChannel fc = getFileChannel(jsaFile); byte[] buf = new byte[4096]; ByteBuffer bbuf = ByteBuffer.wrap(buf); @@ -248,8 +254,8 @@ return true; } - public static void modifyJsaHeader() throws Exception { - FileChannel fc = getFileChannel(); + public static void modifyJsaHeader(File jsaFile) throws Exception { + FileChannel fc = getFileChannel(jsaFile); // screw up header info byte[] buf = new byte[getFileHeaderSize(fc)]; ByteBuffer bbuf = ByteBuffer.wrap(buf); @@ -259,6 +265,30 @@ } } + public static void modifyJvmIdent() throws Exception { + FileChannel fc = getFileChannel(jsa); + int headerSize = getFileHeaderSize(fc); + System.out.println(" offset_jvm_ident " + offset_jvm_ident); + byte[] buf = new byte[256]; + ByteBuffer bbuf = ByteBuffer.wrap(buf); + writeData(fc, (long)offset_jvm_ident, bbuf); + if (fc.isOpen()) { + fc.close(); + } + } + + public static void modifyHeaderIntField(long offset, int value) throws Exception { + FileChannel fc = getFileChannel(jsa); + int headerSize = getFileHeaderSize(fc); + System.out.println(" offset " + offset); + byte[] buf = ByteBuffer.allocate(4).putInt(value).array(); + ByteBuffer bbuf = ByteBuffer.wrap(buf); + writeData(fc, offset, bbuf); + if (fc.isOpen()) { + fc.close(); + } + } + public static void copyFile(File from, File to) throws Exception { if (to.exists()) { if(!to.delete()) { @@ -348,10 +378,10 @@ // test, should pass System.out.println("1. Normal, should pass but may fail\n"); - String[] execArgs = {"-cp", jarFile, "Hello"}; + String[] execArgs = {"-Xlog:cds", "-cp", jarFile, "Hello"}; // tests that corrupt contents of the archive need to run with // VerifySharedSpaces enabled to detect inconsistencies - String[] verifyExecArgs = {"-XX:+VerifySharedSpaces", "-cp", jarFile, "Hello"}; + String[] verifyExecArgs = {"-Xlog:cds", "-XX:+VerifySharedSpaces", "-cp", jarFile, "Hello"}; OutputAnalyzer output = TestCommon.execCommon(execArgs); @@ -373,10 +403,36 @@ orgJsaFile = new File(new File(currentDir), "appcds.jsa.bak"); copyFile(jsa, orgJsaFile); - // modify jsa header, test should fail System.out.println("\n2. Corrupt header, should fail\n"); - modifyJsaHeader(); + modifyJsaHeader(jsa); + output = TestCommon.execCommon(execArgs); + output.shouldContain("The shared archive file has a bad magic number"); + output.shouldNotContain("Checksum verification failed"); + + copyFile(orgJsaFile, jsa); + // modify _jvm_ident and _paths_misc_info_size, test should fail + System.out.println("\n2a. Corrupt _jvm_ident and _paths_misc_info_size, should fail\n"); + modifyJvmIdent(); + modifyHeaderIntField(offset_paths_misc_info_size, Integer.MAX_VALUE); + output = TestCommon.execCommon(execArgs); + output.shouldContain("The shared archive file was created by a different version or build of HotSpot"); + output.shouldNotContain("Checksum verification failed"); + + copyFile(orgJsaFile, jsa); + // modify _magic and _paths_misc_info_size, test should fail + System.out.println("\n2b. Corrupt _magic and _paths_misc_info_size, should fail\n"); + modifyHeaderIntField(offset_magic, 0x00000000); + modifyHeaderIntField(offset_paths_misc_info_size, Integer.MAX_VALUE); + output = TestCommon.execCommon(execArgs); + output.shouldContain("The shared archive file has a bad magic number"); + output.shouldNotContain("Checksum verification failed"); + + copyFile(orgJsaFile, jsa); + // modify _version and _paths_misc_info_size, test should fail + System.out.println("\n2c. Corrupt _version and _paths_misc_info_size, should fail\n"); + modifyHeaderIntField(offset_version, 0x00000000); + modifyHeaderIntField(offset_paths_misc_info_size, Integer.MAX_VALUE); output = TestCommon.execCommon(execArgs); output.shouldContain("The shared archive file has the wrong version"); output.shouldNotContain("Checksum verification failed"); @@ -387,8 +443,9 @@ for (int i=0; i IntStream + .range( + i * bpl, + Math.min(i * bpl + bpl, bytes.length) + ) + .mapToObj(ii -> { + String s = Integer.toHexString(bytes[ii] & 0xFF); + return s.length() == 1 ? "0x0" + s : "0x" + s; + }) + .collect(Collectors.joining(", ")) + ) + .collect(Collectors.joining(",\n ", "int[] bytes = {\n ", "\n};")) + ); + } + } +} diff -r 9a97b1393e72 -r 2b4e14968afd test/jdk/javax/accessibility/JTable/JTableCellEditor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/jdk/javax/accessibility/JTable/JTableCellEditor.java Wed Jul 17 04:33:37 2019 -0700 @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.EventQueue; +import java.lang.reflect.InvocationTargetException; +import java.util.Locale; + +import javax.accessibility.AccessibleRole; +import javax.accessibility.AccessibleTable; +import javax.swing.JFrame; +import javax.swing.JTable; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableModel; + +/** + * @test + * @bug 8226653 + * @key headful + * @summary The active cell editor should be reported as a child of the table. + * Note that the accessibility API ignores the real children of the + * table, but reports the "virtual" child per cell in the grid. + */ +public final class JTableCellEditor { + + private static final int COUNT = 3; + private static JTable table; + private static JFrame frame; + + public static void main(final String[] args) + throws InvocationTargetException, InterruptedException { + EventQueue.invokeAndWait(() -> { + frame = new JFrame(); + table = new JTable(testSelectionWithFilterTable()); + frame.add(table); + frame.pack(); + }); + EventQueue.invokeAndWait(() -> table.editCellAt(1, 1)); + EventQueue.invokeAndWait(() -> { + AccessibleTable aTable = table.getAccessibleContext() + .getAccessibleTable(); + int aColumns = aTable.getAccessibleColumnCount(); + int aRows = aTable.getAccessibleRowCount(); + // We cannot assume which component will be used as an editor of the + // table cell, but we can expect it will have the "text" role. + AccessibleRole role = aTable.getAccessibleAt(1, 1) + .getAccessibleContext() + .getAccessibleRole(); + frame.dispose(); + if (!role.toDisplayString(Locale.ENGLISH).equals("text")) { + throw new RuntimeException("Unexpected role: " + role); + } + if (aColumns != COUNT) { + throw new RuntimeException("Wrong columns: " + aColumns); + } + if (aRows != COUNT) { + throw new RuntimeException("Wrong rows: " + aRows); + } + }); + } + + /** + * Creates a dummy table model. + */ + private static TableModel testSelectionWithFilterTable() { + DefaultTableModel model = new DefaultTableModel(0, 3); + for (int i = 0; i < COUNT; i++) { + model.addRow(new Object[]{i + "x0", i + "x1", i + "x2"}); + } + return model; + } +} diff -r 9a97b1393e72 -r 2b4e14968afd test/langtools/tools/javac/TextBlockIllegalEscape.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/TextBlockIllegalEscape.java Wed Jul 17 04:33:37 2019 -0700 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8227640 + * @summary Verify that illegal escapes in text blocks do not crash the javac. + * @compile/fail/ref=TextBlockIllegalEscape.out --enable-preview -source ${jdk.version} -XDrawDiagnostics TextBlockIllegalEscape.java + */ + +public class TextBlockIllegalEscape { + static void test() { + EQ(""" + \! + """, ""); + } +} diff -r 9a97b1393e72 -r 2b4e14968afd test/langtools/tools/javac/TextBlockIllegalEscape.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/langtools/tools/javac/TextBlockIllegalEscape.out Wed Jul 17 04:33:37 2019 -0700 @@ -0,0 +1,4 @@ +TextBlockIllegalEscape.java:11:13: compiler.err.illegal.esc.char +- compiler.note.preview.filename: TextBlockIllegalEscape.java +- compiler.note.preview.recompile +1 error