Merge
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index a47005a..81e454f 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -658,3 +658,6 @@
bebb5ab92c46792b4736c2a9b1a71259d66177fc jdk7u291-b01
bebb5ab92c46792b4736c2a9b1a71259d66177fc jdk7u291-ga
bebb5ab92c46792b4736c2a9b1a71259d66177fc jdk7u301-b00
+69eb8e28a42df1cbcd30c4f1f3714bb2a199394a jdk7u301-b01
+69eb8e28a42df1cbcd30c4f1f3714bb2a199394a jdk7u301-ga
+69eb8e28a42df1cbcd30c4f1f3714bb2a199394a jdk7u311-b00
diff --git a/corba/.hgtags b/corba/.hgtags
index 92cb01a..59a980f 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -660,3 +660,6 @@
6e512d6f5ba82c817e84ca9ca1d5eed0aa26fa9e jdk7u291-b01
6e512d6f5ba82c817e84ca9ca1d5eed0aa26fa9e jdk7u291-ga
6e512d6f5ba82c817e84ca9ca1d5eed0aa26fa9e jdk7u301-b00
+ea96e8115e5e113e6d3a30097c1155ba430f7613 jdk7u301-b01
+ea96e8115e5e113e6d3a30097c1155ba430f7613 jdk7u301-ga
+ea96e8115e5e113e6d3a30097c1155ba430f7613 jdk7u311-b00
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index 00c038c..6799d08 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -896,3 +896,6 @@
e228cf201f8eb70da0bdb1f6821eac48d6eb2620 jdk7u291-b01
e228cf201f8eb70da0bdb1f6821eac48d6eb2620 jdk7u291-ga
e228cf201f8eb70da0bdb1f6821eac48d6eb2620 jdk7u301-b00
+35022cb9d7788c3afb3e41c09680ad8a2652910b jdk7u301-b01
+35022cb9d7788c3afb3e41c09680ad8a2652910b jdk7u301-ga
+35022cb9d7788c3afb3e41c09680ad8a2652910b jdk7u311-b00
diff --git a/hotspot/src/share/vm/code/dependencies.cpp b/hotspot/src/share/vm/code/dependencies.cpp
index ec473b1..4b26c13 100644
--- a/hotspot/src/share/vm/code/dependencies.cpp
+++ b/hotspot/src/share/vm/code/dependencies.cpp
@@ -884,8 +884,8 @@
klassOop find_witness_in(KlassDepChange& changes,
klassOop context_type,
bool participants_hide_witnesses);
- bool witnessed_reabstraction_in_supers(klassOop k);
public:
+ bool witnessed_reabstraction_in_supers(klassOop k);
klassOop find_witness_subtype(klassOop context_type, KlassDepChange* changes = NULL) {
assert(doing_subtype_search(), "must set up a subtype search");
// When looking for unexpected concrete types,
@@ -997,15 +997,8 @@
}
}
- if (is_witness(new_type)) {
- if (!ignore_witness(new_type)) {
- return new_type;
- }
- } else if (!doing_subtype_search()) {
- // No witness found, but is_witness() doesn't detect method re-abstraction in case of spot-checking.
- if (witnessed_reabstraction_in_supers(new_type)) {
- return new_type;
- }
+ if (is_witness(new_type) && !ignore_witness(new_type)) {
+ return new_type;
}
return NULL;
@@ -1384,16 +1377,87 @@
return num;
}
+
+// Try to determine whether root method in some context is concrete or not based on the information about the unique method
+// in that context. It exploits the fact that concrete root method is always inherited into the context when there's a unique method.
+// Hence, unique method holder is always a supertype of the context class when root method is concrete.
+// Examples for concrete_root_method
+// C (C.m uniqm)
+// |
+// CX (ctxk) uniqm is inherited into context.
+//
+// CX (ctxk) (CX.m uniqm) here uniqm is defined in ctxk.
+// Examples for !concrete_root_method
+// CX (ctxk)
+// |
+// C (C.m uniqm) uniqm is in subtype of ctxk.
+bool Dependencies::is_concrete_root_method(methodOop uniqm, klassOop ctxk) {
+ if (uniqm == NULL) {
+ return false; // match Dependencies::is_concrete_method() behavior
+ }
+ // Theoretically, the "direction" of subtype check matters here.
+ // On one hand, in case of interface context with a single implementor, uniqm can be in a superclass of the implementor which
+ // is not related to context class.
+ // On another hand, uniqm could come from an interface unrelated to the context class, but right now it is not possible:
+ // it is required that uniqm->method_holder() is the participant (uniqm->method_holder() <: ctxk), hence a default method
+ // can't be used as unique.
+ if (ctxk->klass_part()->is_interface()) {
+ klassOop implementor = instanceKlass::cast(ctxk)->implementor();
+ assert(implementor != ctxk, "single implementor only"); // should have been invalidated earlier
+ ctxk = implementor;
+ }
+ klassOop holder = uniqm->method_holder();
+ assert(!holder->is_interface(), "no default methods allowed");
+ assert(ctxk->klass_part()->is_subclass_of(holder) || holder->klass_part()->is_subclass_of(ctxk), "not related");
+ return ctxk->klass_part()->is_subclass_of(holder);
+}
+
// If a class (or interface) has a unique concrete method uniqm, return NULL.
// Otherwise, return a class that contains an interfering method.
klassOop Dependencies::check_unique_concrete_method(klassOop ctxk, methodOop uniqm,
KlassDepChange* changes) {
- // Here is a missing optimization: If uniqm->is_final(),
- // we don't really need to search beneath it for overrides.
- // This is probably not important, since we don't use dependencies
- // to track final methods. (They can't be "definalized".)
ClassHierarchyWalker wf(uniqm->method_holder(), uniqm);
- return wf.find_witness_definer(ctxk, changes);
+ klassOop witness = wf.find_witness_definer(ctxk, changes);
+ if (witness != NULL) {
+ return witness;
+ }
+ if (!Dependencies::is_concrete_root_method(uniqm, ctxk) || changes != NULL) {
+ klassOop conck = find_witness_AME(ctxk, uniqm, changes);
+ if (conck != NULL) {
+ // Found a concrete subtype 'conck' which does not override abstract root method.
+ return conck;
+ }
+ }
+ return NULL;
+}
+
+// Search for AME.
+// There are two version of checks.
+// 1) Spot checking version(Classload time). Newly added class is checked for AME.
+// Checks whether abstract/overpass method is inherited into/declared in newly added concrete class.
+// 2) Compile time analysis for abstract/overpass(abstract klass) root_m. The non uniqm subtrees are checked for concrete classes.
+klassOop Dependencies::find_witness_AME(klassOop ctxk, methodOop m, KlassDepChange* changes) {
+ if (m != NULL) {
+ if (changes != NULL) {
+ // Spot checking version.
+ ClassHierarchyWalker wf(m);
+ klassOop new_type = changes->new_type();
+ if (wf.witnessed_reabstraction_in_supers(new_type)) {
+ return new_type;
+ }
+ } else {
+ // Note: It is required that uniqm->method_holder() is the participant (see ClassHierarchyWalker::found_method()).
+ ClassHierarchyWalker wf(m->method_holder());
+ klassOop conck = wf.find_witness_subtype(ctxk);
+ if (conck != NULL) {
+ methodOop cm = instanceKlass::cast(conck)->find_instance_method(m->name(), m->signature(), Klass::skip_private);
+ if (!Dependencies::is_concrete_method(cm)) {
+ return conck;
+ }
+ }
+ }
+ }
+ return NULL;
}
// Find the set of all non-abstract methods under ctxk that match m.
@@ -1416,7 +1480,11 @@
// (This can happen if m is inherited into ctxk and fm overrides it.)
return NULL;
}
+ } else if (Dependencies::find_witness_AME(ctxk, fm) != NULL) {
+ // Found a concrete subtype which does not override abstract root method.
+ return NULL;
}
+ assert(Dependencies::is_concrete_root_method(fm, ctxk) == Dependencies::is_concrete_method(m, ctxk), "mismatch");
#ifndef PRODUCT
// Make sure the dependency mechanism will pass this discovery:
if (VerifyDependencies && fm != NULL) {
diff --git a/hotspot/src/share/vm/code/dependencies.hpp b/hotspot/src/share/vm/code/dependencies.hpp
index 860d69e..a4cd655 100644
--- a/hotspot/src/share/vm/code/dependencies.hpp
+++ b/hotspot/src/share/vm/code/dependencies.hpp
@@ -290,6 +290,9 @@
static bool is_concrete_method(methodOop m); // m is invocable
static Klass* find_finalizable_subclass(Klass* k);
+ static bool is_concrete_root_method(methodOop uniqm, klassOop ctxk);
+ static klassOop find_witness_AME(klassOop ctxk, methodOop m, KlassDepChange* changes = NULL);
+
// These versions of the concreteness queries work through the CI.
// The CI versions are allowed to skew sometimes from the VM
// (oop-based) versions. The cost of such a difference is a
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index c1a16a3..41c5674 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -1074,60 +1074,66 @@
// find_instance_method looks up the name/signature in the local methods array
// and skips over static methods
-methodOop instanceKlass::find_instance_method(Symbol* name, Symbol* signature) {
- return instanceKlass::find_instance_method(methods(), name, signature);
+methodOop instanceKlass::find_instance_method(Symbol* name, Symbol* signature,
+ PrivateLookupMode private_mode)
+{
+ return instanceKlass::find_instance_method(methods(), name, signature, private_mode);
}
// find_instance_method looks up the name/signature in the local methods array
// and skips over static methods
-methodOop instanceKlass::find_instance_method(objArrayOop methods, Symbol* name, Symbol* signature) {
- methodOop meth = instanceKlass::find_method_impl(methods, name, signature, true);
+methodOop instanceKlass::find_instance_method(objArrayOop methods, Symbol* name, Symbol* signature,
+ PrivateLookupMode private_mode)
+{
+ methodOop meth = instanceKlass::find_method_impl(methods, name, signature, true, private_mode == skip_private);
return meth;
}
// find_method looks up the name/signature in the local methods array
methodOop instanceKlass::find_method(objArrayOop methods, Symbol* name, Symbol* signature) {
- return instanceKlass::find_method_impl(methods, name, signature, false);
+ return instanceKlass::find_method_impl(methods, name, signature, false, false);
}
-methodOop instanceKlass::find_method_impl(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static) {
- int hit = find_method_index(methods, name, signature, skipping_static);
+methodOop instanceKlass::find_method_impl(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static, bool skipping_private) {
+ int hit = find_method_index(methods, name, signature, skipping_static, skipping_private);
return hit >= 0 ? (methodOop) methods->obj_at(hit): NULL;
}
-bool instanceKlass::method_matches(methodOop m, Symbol* signature, bool skipping_static) {
- return (m->signature() == signature) && (!skipping_static || !m->is_static());
+bool instanceKlass::method_matches(methodOop m, Symbol* signature, bool skipping_static, bool skipping_private) {
+ return ((m->signature() == signature) &&
+ (!skipping_static || !m->is_static()) &&
+ (!skipping_private || !m->is_private()));
}
// Used indirectly by find_method
// find_method_index looks in the local methods array to return the index
// of the matching name/signature
-int instanceKlass::find_method_index(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static) {
+int instanceKlass::find_method_index(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static, bool skipping_private) {
int hit = binary_search(methods, name);
if (hit != -1) {
methodOop m = (methodOop) methods->obj_at(hit);
// Do linear search to find matching signature. First, quick check
// for common case
- if (method_matches(m, signature, skipping_static)) return hit;
+ if (method_matches(m, signature, skipping_static, skipping_private)) return hit;
// search downwards through overloaded methods
int i;
for (i = hit - 1; i >= 0; --i) {
methodOop m = (methodOop) methods->obj_at(i);
assert(m->is_method(), "must be method");
if (m->name() != name) break;
- if (method_matches(m, signature, skipping_static)) return i;
+ if (method_matches(m, signature, skipping_static, skipping_private)) return i;
}
// search upwards
for (i = hit + 1; i < methods->length(); ++i) {
methodOop m = (methodOop) methods->obj_at(i);
assert(m->is_method(), "must be method");
if (m->name() != name) break;
- if (method_matches(m, signature, skipping_static)) return i;
+ if (method_matches(m, signature, skipping_static, skipping_private)) return i;
}
// not found
#ifdef ASSERT
- int index = skipping_static ? -1 : linear_search(methods, name, signature);
+ int index = (skipping_static || skipping_private) ? -1 : linear_search(methods, name, signature);
assert(index == -1, err_msg("binary search should have found entry %d", index));
#endif
}
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index ace5129..63bdd9e 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -495,14 +495,17 @@
static methodOop find_method(objArrayOop methods, Symbol* name, Symbol* signature);
// find a local method, but skip static methods
- methodOop find_instance_method(Symbol* name, Symbol* signature);
- static methodOop find_instance_method(objArrayOop methods, Symbol* name, Symbol* signature);
+ methodOop find_instance_method(Symbol* name, Symbol* signature,
+ PrivateLookupMode private_mode = Klass::find_private);
+ static methodOop find_instance_method(objArrayOop methods, Symbol* name, Symbol* signature,
+ PrivateLookupMode private_mode = Klass::find_private);
// true if method matches signature and conforms to skipping_X conditions.
- static bool method_matches(methodOop m, Symbol* signature, bool skipping_static);
+ static bool method_matches(methodOop m, Symbol* signature, bool skipping_static, bool skipping_private);
// find a local method index in default_methods (returns -1 if not found)
- static int find_method_index(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static);
+
+ static int find_method_index(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static, bool skipping_private);
// lookup operation (returns NULL if not found)
methodOop uncached_lookup_method(Symbol* name, Symbol* signature) const;
@@ -986,7 +989,7 @@
klassOop array_klass_impl(bool or_null, TRAPS);
// find a local method (returns NULL if not found)
- static methodOop find_method_impl(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static);
+ static methodOop find_method_impl(objArrayOop methods, Symbol* name, Symbol* signature, bool skipping_static, bool skipping_private);
public:
// sharing support
diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp
index ed7f6cb..879cf35 100644
--- a/hotspot/src/share/vm/oops/klass.hpp
+++ b/hotspot/src/share/vm/oops/klass.hpp
@@ -276,6 +276,8 @@
}
public:
+ enum PrivateLookupMode { find_private, skip_private };
+
// Allocation
const Klass_vtbl& vtbl_value() const { return *this; } // used only on "example instances"
static KlassHandle base_create_klass(KlassHandle& klass, int size, const Klass_vtbl& vtbl, TRAPS);
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index cb8401c..762d377 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -661,3 +661,6 @@
4ffef5b738a8c07a734fd89e819f456a3711d7e4 jdk7u291-b01
4ffef5b738a8c07a734fd89e819f456a3711d7e4 jdk7u291-ga
4ffef5b738a8c07a734fd89e819f456a3711d7e4 jdk7u301-b00
+f5d08bc7dff82930a843070ef437cea93bb4ae64 jdk7u301-b01
+f5d08bc7dff82930a843070ef437cea93bb4ae64 jdk7u301-ga
+f5d08bc7dff82930a843070ef437cea93bb4ae64 jdk7u311-b00
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java
index ac26f80..95b5e5a 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XML11EntityScanner.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -40,6 +40,8 @@
* @author Michael Glavassevich, IBM
* @author Neil Graham, IBM
* @version $Id: XML11EntityScanner.java,v 1.5 2010-11-01 04:39:40 joehw Exp $
+ *
+ * @LastModified: Apr 2021
*/
public class XML11EntityScanner
@@ -697,7 +699,7 @@
sawIncompleteSurrogatePair)){
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"IllegalQName",
- null,
+ new Object[]{rawname},
XMLErrorReporter.SEVERITY_FATAL_ERROR);
}
//check the result: localpart
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
index 2c81d5c..a9c49fb 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -55,6 +55,7 @@
* @author Arnaud Le Hors, IBM
* @author K.Venugopal Sun Microsystems
*
+ * @LastModified: Apr 2021
*/
public class XMLEntityScanner implements XMLLocator {
@@ -860,6 +861,14 @@
prefix = fSymbolTable.addSymbol(fCurrentEntity.ch,
offset, prefixLength);
int len = length - prefixLength - 1;
+ int startLocal = index +1;
+ if (!XMLChar.isNCNameStart(fCurrentEntity.ch[startLocal])){
+ fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
+ "IllegalQName",
+ new Object[]{rawname},
+ XMLErrorReporter.SEVERITY_FATAL_ERROR);
+ }
+
//check the result: localpart
checkLimit(Limit.MAX_NAME_LIMIT, fCurrentEntity, index + 1, len);
localpart = fSymbolTable.addSymbol(fCurrentEntity.ch,
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
index c7a23c2..b7bbf67 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties
@@ -277,7 +277,7 @@
# Namespaces support
# 4. Using Qualified Names
- IllegalQName = Element or attribute do not match QName production: QName::=(NCName':')?NCName.
+ IllegalQName = Element or attribute \"{0}\" do not match QName production: QName::=(NCName':')?NCName.
ElementXMLNSPrefix = Element \"{0}\" cannot have \"xmlns\" as its prefix.
ElementPrefixUnbound = The prefix \"{0}\" for element \"{1}\" is not bound.
AttributePrefixUnbound = The prefix \"{2}\" for attribute \"{1}\" associated with an element type \"{0}\" is not bound.
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToStream.java b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToStream.java
index 2301763..20f87a9 100644
--- a/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToStream.java
+++ b/jaxp/src/com/sun/org/apache/xml/internal/serializer/ToStream.java
@@ -39,6 +39,7 @@
import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
import com.sun.org.apache.xml.internal.serializer.utils.Utils;
import com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException;
+import jdk.xml.internal.JdkXmlUtils;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
@@ -51,6 +52,7 @@
* serializers (xml, html, text ...) that write output to a stream.
*
* @xsl.usage internal
+ * @LastModified: Apr 2021
*/
abstract public class ToStream extends SerializerBase
{
@@ -1882,21 +1884,21 @@
String doctypeSystem = getDoctypeSystem();
if (null != doctypeSystem)
{
- if (null == doctypePublic)
- writer.write(" SYSTEM \"");
- else
- writer.write(" \"");
+ char quote = JdkXmlUtils.getQuoteChar(doctypeSystem);
+ if (null == doctypePublic) {
+ writer.write(" SYSTEM");
+ }
+ writer.write(" ");
+ writer.write(quote);
writer.write(doctypeSystem);
-
+ writer.write(quote);
if (closeDecl)
{
- writer.write("\">");
+ writer.write(">");
writer.write(m_lineSep, 0, m_lineSepLen);
closeDecl = false; // done closing
}
- else
- writer.write('\"');
}
boolean dothis = false;
if (dothis)
diff --git a/jaxp/src/jdk/xml/internal/JdkXmlUtils.java b/jaxp/src/jdk/xml/internal/JdkXmlUtils.java
index 35ff206..012fa77 100644
--- a/jaxp/src/jdk/xml/internal/JdkXmlUtils.java
+++ b/jaxp/src/jdk/xml/internal/JdkXmlUtils.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2021, 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
@@ -249,6 +249,22 @@
return tf;
}
+ /**
+ * Returns the character to be used to quote the input content. Between
+ * single and double quotes, this method returns the one that is not found
+ * in the input. Returns double quote by default.
+ *
+ * @param s the input string
+ * @return returns the quote not found in the input
+ */
+ public static char getQuoteChar(String s) {
+ if (s != null && s.indexOf('"') > -1) {
+ return '\'';
+ } else {
+ return '"';
+ }
+ }
+
private static XMLReader getXMLReaderWSAXFactory(boolean overrideDefaultParser) {
SAXParserFactory saxFactory = getSAXFactory(overrideDefaultParser);
try {
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index af75dc2..2d4ff90 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -660,3 +660,6 @@
156d24d6052eba8c7f4364c3b0b5eb558da9df43 jdk7u291-b01
156d24d6052eba8c7f4364c3b0b5eb558da9df43 jdk7u291-ga
156d24d6052eba8c7f4364c3b0b5eb558da9df43 jdk7u301-b00
+d28a9f888fb98f05e44e77dff7dde7384dbe6e30 jdk7u301-b01
+d28a9f888fb98f05e44e77dff7dde7384dbe6e30 jdk7u301-ga
+d28a9f888fb98f05e44e77dff7dde7384dbe6e30 jdk7u311-b00
diff --git a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/org/objectweb/asm/ClassReader.java b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/org/objectweb/asm/ClassReader.java
index ed98247..67ec13c 100644
--- a/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/org/objectweb/asm/ClassReader.java
+++ b/jaxws/src/share/jaxws_classes/com/sun/xml/internal/ws/org/objectweb/asm/ClassReader.java
@@ -561,6 +561,9 @@
access |= Opcodes.ACC_SYNTHETIC;
} else if ("SourceDebugExtension".equals(attrName)) {
int len = readInt(v + 2);
+ if (len > b.length - (v + 6)) {
+ throw new IllegalArgumentException();
+ }
sourceDebug = readUTF(v + 6, len, new char[len]);
} else if (ANNOTATIONS && "RuntimeInvisibleAnnotations".equals(attrName)) {
ianns = v + 6;
@@ -896,6 +899,9 @@
int maxLocals = readUnsignedShort(v + 2);
int codeLength = readInt(v + 4);
v += 8;
+ if (codeLength > b.length - v) {
+ throw new IllegalArgumentException();
+ }
int codeStart = v;
int codeEnd = v + codeLength;
diff --git a/jdk/.hgtags b/jdk/.hgtags
index 7c66dc4..8740346 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -651,3 +651,6 @@
da9f439a68d68914ff36e55e516a94f596a627fe jdk7u291-b01
da9f439a68d68914ff36e55e516a94f596a627fe jdk7u291-ga
da9f439a68d68914ff36e55e516a94f596a627fe jdk7u301-b00
+95f660595bd2d7bd008fedf68222ed558caf6185 jdk7u301-b01
+95f660595bd2d7bd008fedf68222ed558caf6185 jdk7u301-ga
+95f660595bd2d7bd008fedf68222ed558caf6185 jdk7u311-b00
diff --git a/jdk/make/java/zip/mapfile-vers b/jdk/make/java/zip/mapfile-vers
index 7c29865..f83f96d 100644
--- a/jdk/make/java/zip/mapfile-vers
+++ b/jdk/make/java/zip/mapfile-vers
@@ -65,6 +65,7 @@
Java_java_util_zip_ZipFile_open;
Java_java_util_zip_ZipFile_read;
Java_java_util_zip_ZipFile_startsWithLOC;
+ Java_java_util_zip_ZipFile_getManifestNum;
ZIP_Close;
ZIP_CRC32;
diff --git a/jdk/make/java/zip/reorder-i586 b/jdk/make/java/zip/reorder-i586
index 73ea674..7eec24f 100644
--- a/jdk/make/java/zip/reorder-i586
+++ b/jdk/make/java/zip/reorder-i586
@@ -20,6 +20,7 @@
text: .text%Java_java_util_zip_ZipFile_open;
text: .text%Java_java_util_zip_ZipFile_getTotal;
text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
+text: .text%Java_java_util_zip_ZipFile_getManifestNum;
text: .text%Java_java_util_zip_ZipFile_getEntry;
text: .text%Java_java_util_zip_ZipFile_freeEntry;
text: .text%Java_java_util_zip_ZipFile_getEntryTime;
diff --git a/jdk/make/java/zip/reorder-sparc b/jdk/make/java/zip/reorder-sparc
index a5cde39..4656386 100644
--- a/jdk/make/java/zip/reorder-sparc
+++ b/jdk/make/java/zip/reorder-sparc
@@ -19,6 +19,7 @@
text: .text%Java_java_util_zip_ZipFile_open;
text: .text%Java_java_util_zip_ZipFile_getTotal;
text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
+text: .text%Java_java_util_zip_ZipFile_getManifestNum;
text: .text%Java_java_util_zip_ZipFile_getEntry;
text: .text%Java_java_util_zip_ZipFile_freeEntry;
text: .text%Java_java_util_zip_ZipFile_getEntryTime;
diff --git a/jdk/make/java/zip/reorder-sparcv9 b/jdk/make/java/zip/reorder-sparcv9
index 32ebae1..45c00b1 100644
--- a/jdk/make/java/zip/reorder-sparcv9
+++ b/jdk/make/java/zip/reorder-sparcv9
@@ -19,6 +19,7 @@
text: .text%Java_java_util_zip_ZipFile_open;
text: .text%Java_java_util_zip_ZipFile_getTotal;
text: .text%Java_java_util_zip_ZipFile_startsWithLOC;
+text: .text%Java_java_util_zip_ZipFile_getManifestNum;
text: .text%Java_java_util_zip_ZipFile_getEntry;
text: .text%Java_java_util_zip_ZipFile_freeEntry;
text: .text%Java_java_util_zip_ZipFile_getEntryTime;
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java b/jdk/src/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java
new file mode 100644
index 0000000..b6d32b4
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java
@@ -0,0 +1,85 @@
+/*
+ * 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
+ * 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 com.sun.jndi.ldap;
+
+import com.sun.jndi.ldap.spi.LdapDnsProvider;
+import com.sun.jndi.ldap.spi.LdapDnsProviderResult;
+import javax.naming.NamingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class DefaultLdapDnsProvider {
+
+ public LdapDnsProviderResult lookupEndpoints(String url,
+ Map<?,?> env)
+ throws NamingException
+ {
+ if (url == null || env == null) {
+ throw new NullPointerException();
+ }
+
+ String domainName;
+ List<String> endpoints = new ArrayList<>();
+ LdapURL ldapUrl = new LdapURL(url);
+ String dn = ldapUrl.getDN();
+ String host = ldapUrl.getHost();
+ int port = ldapUrl.getPort();
+ String[] hostports;
+
+ // handle a URL with no hostport (ldap:/// or ldaps:///)
+ // locate the LDAP service using the URL's distinguished name
+ if (host == null
+ && port == -1
+ && dn != null
+ && (domainName = ServiceLocator.mapDnToDomainName(dn)) != null
+ && (hostports = ServiceLocator.getLdapService(domainName, env)) != null) {
+ // Generate new URLs that include the discovered hostports.
+ // Reuse the original URL scheme.
+ String scheme = ldapUrl.getScheme() + "://";
+ String query = ldapUrl.getQuery();
+ String urlSuffix = ldapUrl.getPath() + (query != null ? query : "");
+ for (String hostPort : hostports) {
+ // the hostports come from the DNS SRV records
+ // we assume the SRV record is scheme aware
+ endpoints.add(scheme + hostPort + urlSuffix);
+ }
+ } else {
+ // we don't have enough information to set the domain name
+ // correctly
+ domainName = "";
+ endpoints.add(url);
+ }
+
+ LdapDnsProviderResult res = new LdapDnsProviderResult(domainName, endpoints);
+ if (res.getEndpoints().isEmpty() && res.getDomainName().isEmpty()) {
+ return null;
+ } else {
+ return res;
+ }
+ }
+
+}
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java b/jdk/src/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java
index d6ab731..fe05a59 100644
--- a/jdk/src/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/LdapCtxFactory.java
@@ -35,6 +35,7 @@
import javax.naming.spi.InitialContextFactory;
import javax.naming.ldap.Control;
+import com.sun.jndi.ldap.spi.LdapDnsProviderResult;
import com.sun.jndi.url.ldap.ldapURLContextFactory;
final public class LdapCtxFactory implements ObjectFactory, InitialContextFactory {
@@ -158,41 +159,73 @@
}
private static DirContext getUsingURL(String url, Hashtable<?,?> env)
- throws NamingException {
- DirContext ctx = null;
- LdapURL ldapUrl = new LdapURL(url);
- String dn = ldapUrl.getDN();
- String host = ldapUrl.getHost();
- int port = ldapUrl.getPort();
- String[] hostports;
- String domainName = null;
+ throws NamingException
+ {
+ try {
+ LdapDnsProviderResult r =
+ LdapDnsProviderService.getInstance().lookupEndpoints(url, env);
+ LdapCtx ctx;
+ NamingException lastException = null;
- // handle a URL with no hostport (ldap:/// or ldaps:///)
- // locate the LDAP service using the URL's distinguished name
- if (host == null &&
- port == -1 &&
- dn != null &&
- (domainName = ServiceLocator.mapDnToDomainName(dn)) != null &&
- (hostports = ServiceLocator.getLdapService(domainName, env))
- != null) {
- // Generate new URLs that include the discovered hostports.
- // Reuse the original URL scheme.
- String scheme = ldapUrl.getScheme() + "://";
- String[] newUrls = new String[hostports.length];
- String query = ldapUrl.getQuery();
- String urlSuffix = ldapUrl.getPath() + (query != null ? query : "");
- for (int i = 0; i < hostports.length; i++) {
- newUrls[i] = scheme + hostports[i] + urlSuffix;
+ /*
+ * Prior to this change we had been assuming that the url.getDN()
+ * should be converted to a domain name via
+ * ServiceLocator.mapDnToDomainName(url.getDN())
+ *
+ * However this is incorrect as we can't assume that the supplied
+ * url.getDN() is the same as the dns domain for the directory
+ * server.
+ *
+ * This means that we depend on the dnsProvider to return both
+ * the list of urls of individual hosts from which we attempt to
+ * create an LdapCtx from *AND* the domain name that they serve
+ *
+ * In order to do this the dnsProvider must return an
+ * {@link LdapDnsProviderResult}.
+ *
+ */
+ for (String u : r.getEndpoints()) {
+ try {
+ ctx = getLdapCtxFromUrl(
+ r.getDomainName(), url, new LdapURL(u), env);
+ return ctx;
+ } catch (NamingException e) {
+ // try the next element
+ lastException = e;
+ }
}
- ctx = getUsingURLs(newUrls, env);
- // Associate the derived domain name with the context
- ((LdapCtx)ctx).setDomainName(domainName);
- } else {
- ctx = new LdapCtx(dn, host, port, env, ldapUrl.useSsl());
- // Record the URL that created the context
- ((LdapCtx)ctx).setProviderUrl(url);
+ if (lastException != null) {
+ throw lastException;
+ }
+
+ // lookupEndpoints returned an LdapDnsProviderResult with an empty
+ // list of endpoints
+ throw new NamingException("Could not resolve a valid ldap host");
+ } catch (NamingException e) {
+ // lookupEndpoints(url, env) may throw a NamingException, which
+ // there is no need to wrap.
+ throw e;
+ } catch (Exception e) {
+ NamingException ex = new NamingException();
+ ex.setRootCause(e);
+ throw ex;
}
+ }
+
+ private static LdapCtx getLdapCtxFromUrl(String domain,
+ String url,
+ LdapURL u,
+ Hashtable<?,?> env)
+ throws NamingException
+ {
+ String dn = u.getDN();
+ String host = u.getHost();
+ int port = u.getPort();
+ LdapCtx ctx = new LdapCtx(dn, host, port, env, u.useSsl());
+ ctx.setDomainName(domain);
+ // Record the URL that created the context
+ ctx.setProviderUrl(url);
return ctx;
}
@@ -202,19 +235,17 @@
* Not pretty, but potentially more informative than returning null.
*/
private static DirContext getUsingURLs(String[] urls, Hashtable<?,?> env)
- throws NamingException {
- NamingException ne = null;
- DirContext ctx = null;
- for (int i = 0; i < urls.length; i++) {
+ throws NamingException
+ {
+ NamingException ex = null;
+ for (String u : urls) {
try {
- return getUsingURL(urls[i], env);
- } catch (AuthenticationException e) {
- throw e;
+ return getUsingURL(u, env);
} catch (NamingException e) {
- ne = e;
+ ex = e;
}
}
- throw ne;
+ throw ex;
}
/**
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java b/jdk/src/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java
new file mode 100644
index 0000000..a8b5cc3
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java
@@ -0,0 +1,126 @@
+/*
+ * 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
+ * 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 com.sun.jndi.ldap;
+
+import java.security.PrivilegedAction;
+import java.util.*;
+import javax.naming.NamingException;
+import com.sun.jndi.ldap.spi.LdapDnsProvider;
+import com.sun.jndi.ldap.spi.LdapDnsProviderResult;
+import sun.misc.JavaSecurityAccess;
+import sun.misc.SharedSecrets;
+import sun.security.util.SecurityConstants;
+
+/**
+ * The {@code LdapDnsProviderService} is responsible for creating and providing
+ * access to the registered {@code LdapDnsProvider}s. The {@link ServiceLoader}
+ * is used to find and register any implementations of {@link LdapDnsProvider}.
+ *
+ * <p> Instances of this class are safe for use by multiple threads.
+ */
+final class LdapDnsProviderService {
+
+ private static volatile LdapDnsProviderService service;
+ private static final Object LOCK = new int[0];
+ private final ServiceLoader<LdapDnsProvider> providers;
+
+ /**
+ * Creates a new instance of LdapDnsProviderService
+ */
+ private LdapDnsProviderService() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm == null) {
+ providers = ServiceLoader.load(
+ LdapDnsProvider.class,
+ ClassLoader.getSystemClassLoader());
+ } else {
+ final PrivilegedAction<ServiceLoader<LdapDnsProvider>> pa =
+ new PrivilegedAction<ServiceLoader<LdapDnsProvider>>() {
+ @Override
+ public ServiceLoader<LdapDnsProvider> run() {
+ return ServiceLoader.load(
+ LdapDnsProvider.class,
+ ClassLoader.getSystemClassLoader());
+ }
+ };
+
+ JavaSecurityAccess jsa = SharedSecrets.getJavaSecurityAccess();
+ providers = jsa.doPrivileged(
+ pa,
+ null,
+ new RuntimePermission("ldapDnsProvider"),
+ SecurityConstants.GET_CLASSLOADER_PERMISSION);
+ }
+ }
+
+ /**
+ * Retrieves the singleton instance of LdapDnsProviderService.
+ */
+ static LdapDnsProviderService getInstance() {
+ if (service != null) return service;
+ synchronized (LOCK) {
+ if (service != null) return service;
+ service = new LdapDnsProviderService();
+ }
+ return service;
+ }
+
+ /**
+ * Retrieves result from the first provider that successfully resolves
+ * the endpoints. If no results are found when calling installed
+ * subclasses of {@code LdapDnsProvider} then this method will fall back
+ * to the {@code DefaultLdapDnsProvider}.
+ *
+ * @throws NamingException if the {@code url} in not valid or an error
+ * occurred while performing the lookup.
+ */
+ LdapDnsProviderResult lookupEndpoints(String url, Hashtable<?,?> env)
+ throws NamingException
+ {
+ LdapDnsProviderResult result = null;
+ Hashtable<?, ?> envCopy = new Hashtable<>(env);
+
+ synchronized (LOCK) {
+ Iterator<LdapDnsProvider> iterator = providers.iterator();
+ while (result == null && iterator.hasNext()) {
+ result = iterator.next().lookupEndpoints(url, envCopy);
+ if (result != null && result.getEndpoints().isEmpty()) {
+ result = null;
+ }
+ }
+ }
+
+ if (result == null) {
+ result = new DefaultLdapDnsProvider().lookupEndpoints(url, env);
+ if (result == null) {
+ return new LdapDnsProviderResult("", Collections.<String>emptyList());
+ }
+ }
+
+ return result;
+ }
+
+}
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/ServiceLocator.java b/jdk/src/share/classes/com/sun/jndi/ldap/ServiceLocator.java
index 5bbd58d..09c6fe5 100644
--- a/jdk/src/share/classes/com/sun/jndi/ldap/ServiceLocator.java
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/ServiceLocator.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -25,11 +25,7 @@
package com.sun.jndi.ldap;
-import java.util.Arrays;
-import java.util.Hashtable;
-import java.util.Random;
-import java.util.StringTokenizer;
-import java.util.List;
+import java.util.*;
import javax.naming.*;
import javax.naming.directory.*;
@@ -113,6 +109,23 @@
* @return An ordered list of hostports for the LDAP service or null if
* the service has not been located.
*/
+ static String[] getLdapService(String domainName, Map<?,?> environment) {
+ if (environment instanceof Hashtable) {
+ return getLdapService(domainName, (Hashtable)environment);
+ }
+ return getLdapService(domainName, new Hashtable<>(environment));
+ }
+
+ /**
+ * Locates the LDAP service for a given domain.
+ * Queries DNS for a list of LDAP Service Location Records (SRV) for a
+ * given domain name.
+ *
+ * @param domainName A string domain name.
+ * @param environment The possibly null environment of the context.
+ * @return An ordered list of hostports for the LDAP service or null if
+ * the service has not been located.
+ */
static String[] getLdapService(String domainName, Hashtable<?,?> environment) {
if (domainName == null || domainName.length() == 0) {
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/spi/LdapDnsProvider.java b/jdk/src/share/classes/com/sun/jndi/ldap/spi/LdapDnsProvider.java
new file mode 100644
index 0000000..8642f26
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/spi/LdapDnsProvider.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 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. 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 com.sun.jndi.ldap.spi;
+
+import javax.naming.Context;
+import javax.naming.NamingException;
+import java.util.Map;
+
+/**
+ * Service-provider class for DNS lookups when performing LDAP operations.
+ *
+ * <p> An LDAP DNS provider is a concrete subclass of this class that
+ * has a zero-argument constructor. LDAP DNS providers are located using the
+ * ServiceLoader facility, as specified by
+ * {@linkplain javax.naming.directory.InitialDirContext InitialDirectContext}.
+ *
+ * The
+ * {@link java.util.ServiceLoader ServiceLoader} is used to create and register
+ * implementations of {@code LdapDnsProvider}.
+ *
+ * <p> An LDAP DNS provider can be used in environments where the default
+ * DNS resolution mechanism is not sufficient to accurately pinpoint the
+ * correct LDAP servers needed to perform LDAP operations. For example, in an
+ * environment containing a mix of {@code ldap} and {@code ldaps} servers
+ * you may want the {@linkplain javax.naming.ldap.LdapContext LdapContext}
+ * to query {@code ldaps} servers only.
+ *
+ * @since 12
+ */
+public abstract class LdapDnsProvider {
+
+ // The {@code RuntimePermission("ldapDnsProvider")} is
+ // necessary to subclass and instantiate the {@code LdapDnsProvider} class.
+ private static final RuntimePermission DNSPROVIDER_PERMISSION =
+ new RuntimePermission("ldapDnsProvider");
+
+ /**
+ * Creates a new instance of {@code LdapDnsProvider}.
+ *
+ * @throws SecurityException if a security manager is present and its
+ * {@code checkPermission} method doesn't allow
+ * the {@code RuntimePermission("ldapDnsProvider")}.
+ */
+ protected LdapDnsProvider() {
+ this(checkPermission());
+ }
+
+ private LdapDnsProvider(Void unused) {
+ // nothing to do.
+ }
+
+ private static Void checkPermission() {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(DNSPROVIDER_PERMISSION);
+ }
+ return null;
+ }
+
+ /**
+ * Lookup the endpoints and domain name for the given {@link Context}
+ * {@link Context#PROVIDER_URL provider URL} and environment. The resolved
+ * endpoints and domain name are returned as an
+ * {@link LdapDnsProviderResult}.
+ *
+ * <p> An endpoint is a {@code String} representation of an LDAP URL which
+ * points to an LDAP server to be used for LDAP operations. The syntax of
+ * an LDAP URL is defined by <a href="http://www.ietf.org/rfc/rfc2255.txt">
+ * <i>RFC 2255: The LDAP URL Format</i></a>.
+ *
+ * @param url The {@link Context} {@link Context#PROVIDER_URL provider URL}
+ * @param env The {@link Context} environment.
+ *
+ * @return an {@link LdapDnsProviderResult} or null if the lookup fails.
+ *
+ * @throws NamingException if the {@code url} is not valid or an error
+ * occurred while performing the lookup.
+ * @throws NullPointerException if either {@code url} or {@code env} are
+ * {@code null}.
+ */
+ public abstract LdapDnsProviderResult lookupEndpoints(
+ String url, Map<?,?> env) throws NamingException;
+
+}
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/spi/LdapDnsProviderResult.java b/jdk/src/share/classes/com/sun/jndi/ldap/spi/LdapDnsProviderResult.java
new file mode 100644
index 0000000..066e044
--- /dev/null
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/spi/LdapDnsProviderResult.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 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. 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 com.sun.jndi.ldap.spi;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * The result of a DNS lookup for an LDAP URL.
+ *
+ * <p> This class is used by an {@link LdapDnsProvider} to return the result
+ * of a DNS lookup for a given LDAP URL. The result consists of a domain name
+ * and its associated ldap server endpoints.
+ *
+ * <p> A {@code null} {@code domainName} is equivalent to and represented
+ * by an empty string.
+ *
+ * @since 12
+ */
+public final class LdapDnsProviderResult {
+
+ private final String domainName;
+ private final List<String> endpoints;
+
+ /**
+ * Construct an LdapDnsProviderResult consisting of a resolved domain name
+ * and the ldap server endpoints that serve the domain.
+ *
+ * @param domainName the resolved domain name; can be null.
+ * @param endpoints the possibly empty list of resolved ldap server
+ * endpoints
+ *
+ * @throws NullPointerException if {@code endpoints} contains {@code null}
+ * elements.
+ * @throws ClassCastException if {@code endpoints} contains non-
+ * {@code String} elements.
+ */
+ public LdapDnsProviderResult(String domainName, List<String> endpoints) {
+ this.domainName = (domainName == null) ? "" : domainName;
+ this.endpoints = new ArrayList<>(endpoints);
+ }
+
+ /**
+ * Returns the domain name resolved from the ldap URL. This method returns
+ * the empty string if the {@code LdapDnsProviderResult} is created with a
+ * null domain name.
+ *
+ * @return the resolved domain name
+ */
+ public String getDomainName() {
+ return domainName;
+ }
+
+ /**
+ * Returns the possibly empty list of individual server endpoints resolved
+ * from the ldap URL.
+ *
+ * @return a possibly empty unmodifiable {@link List} containing the
+ * resolved ldap server endpoints
+ */
+ public List<String> getEndpoints() {
+ return endpoints;
+ }
+
+}
diff --git a/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java b/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java
index 24f58af..b846830 100644
--- a/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java
+++ b/jdk/src/share/classes/com/sun/security/ntlm/NTLM.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2021, 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
@@ -149,7 +149,7 @@
int readShort(int offset) throws NTLMException {
try {
return (internal[offset] & 0xff) +
- ((internal[offset+1] & 0xff << 8));
+ (((internal[offset+1] & 0xff) << 8));
} catch (ArrayIndexOutOfBoundsException ex) {
throw new NTLMException(NTLMException.PACKET_READ_ERROR,
"Input message incorrect size");
diff --git a/jdk/src/share/classes/java/awt/datatransfer/MimeType.java b/jdk/src/share/classes/java/awt/datatransfer/MimeType.java
index f58cffb..0cd52b2 100644
--- a/jdk/src/share/classes/java/awt/datatransfer/MimeType.java
+++ b/jdk/src/share/classes/java/awt/datatransfer/MimeType.java
@@ -25,6 +25,7 @@
package java.awt.datatransfer;
+import java.io.ByteArrayOutputStream;
import java.io.Externalizable;
import java.io.ObjectOutput;
import java.io.ObjectInput;
@@ -325,9 +326,12 @@
ClassNotFoundException {
String s = in.readUTF();
if (s == null || s.length() == 0) { // long mime type
- byte[] ba = new byte[in.readInt()];
- in.readFully(ba);
- s = new String(ba);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int len = in.readInt();
+ while (len-- > 0) {
+ baos.write(in.readByte());
+ }
+ s = baos.toString();
}
try {
parse(s);
diff --git a/jdk/src/share/classes/java/util/jar/JarFile.java b/jdk/src/share/classes/java/util/jar/JarFile.java
index 4232ac0..775fdc6 100644
--- a/jdk/src/share/classes/java/util/jar/JarFile.java
+++ b/jdk/src/share/classes/java/util/jar/JarFile.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2021, 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
@@ -73,6 +73,9 @@
SharedSecrets.setJavaUtilJarAccess(new JavaUtilJarAccessImpl());
}
+ private static final sun.misc.JavaUtilZipFileAccess JUZFA =
+ sun.misc.SharedSecrets.getJavaUtilZipFileAccess();
+
/**
* The JAR manifest file name.
*/
@@ -179,7 +182,13 @@
if (verify) {
byte[] b = getBytes(manEntry);
if (!jvInitialized) {
- jv = new JarVerifier(b);
+ if (JUZFA.getManifestNum(this) == 1) {
+ jv = new JarVerifier(manEntry.getName(), b);
+ } else {
+ if (JarVerifier.debug != null) {
+ JarVerifier.debug.println("Multiple MANIFEST.MF found. Treat JAR file as unsigned");
+ }
+ }
}
man = new Manifest(jv, new ByteArrayInputStream(b));
} else {
diff --git a/jdk/src/share/classes/java/util/jar/JarInputStream.java b/jdk/src/share/classes/java/util/jar/JarInputStream.java
index 67f27be..3bda111 100644
--- a/jdk/src/share/classes/java/util/jar/JarInputStream.java
+++ b/jdk/src/share/classes/java/util/jar/JarInputStream.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2021, 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 @@
man.read(new ByteArrayInputStream(bytes));
closeEntry();
if (doVerify) {
- jv = new JarVerifier(bytes);
+ jv = new JarVerifier(e.getName(), bytes);
mev = new ManifestEntryVerifier(man);
}
return (JarEntry)super.getNextEntry();
diff --git a/jdk/src/share/classes/java/util/jar/JarVerifier.java b/jdk/src/share/classes/java/util/jar/JarVerifier.java
index 34bf00c..f528de4 100644
--- a/jdk/src/share/classes/java/util/jar/JarVerifier.java
+++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java
@@ -84,6 +84,9 @@
/** the bytes for the manDig object */
byte manifestRawBytes[] = null;
+ /** the manifest name this JarVerifier is created upon */
+ final String manifestName;
+
/** controls eager signature validation */
boolean eagerValidation;
@@ -93,7 +96,8 @@
/** collect -DIGEST-MANIFEST values for blacklist */
private List<Object> manifestDigests;
- public JarVerifier(byte rawBytes[]) {
+ public JarVerifier(String name, byte rawBytes[]) {
+ manifestName = name;
manifestRawBytes = rawBytes;
sigFileSigners = new Hashtable<>();
verifiedSigners = new Hashtable<>();
@@ -180,7 +184,7 @@
// only set the jev object for entries that have a signature
// (either verified or not)
- if (!name.equals(JarFile.MANIFEST_NAME)) {
+ if (!name.equalsIgnoreCase(JarFile.MANIFEST_NAME)) {
if (sigFileSigners.get(name) != null ||
verifiedSigners.get(name) != null) {
mev.setEntry(name, je);
@@ -272,7 +276,8 @@
}
sfv.setSignatureFile(bytes);
- sfv.process(sigFileSigners, manifestDigests);
+ sfv.process(sigFileSigners, manifestDigests,
+ manifestName);
}
}
return;
@@ -315,7 +320,7 @@
sfv.setSignatureFile(bytes);
}
}
- sfv.process(sigFileSigners, manifestDigests);
+ sfv.process(sigFileSigners, manifestDigests, manifestName);
} catch (IOException ioe) {
// e.g. sun.security.pkcs.ParsingException
@@ -430,9 +435,9 @@
manDig = null;
// MANIFEST.MF is always treated as signed and verified,
// move its signers from sigFileSigners to verifiedSigners.
- if (sigFileSigners.containsKey(JarFile.MANIFEST_NAME)) {
- CodeSigner[] codeSigners = sigFileSigners.remove(JarFile.MANIFEST_NAME);
- verifiedSigners.put(JarFile.MANIFEST_NAME, codeSigners);
+ if (sigFileSigners.containsKey(manifestName)) {
+ CodeSigner[] codeSigners = sigFileSigners.remove(manifestName);
+ verifiedSigners.put(manifestName, codeSigners);
}
}
@@ -886,7 +891,7 @@
*/
boolean isTrustedManifestEntry(String name) {
// How many signers? MANIFEST.MF is always verified
- CodeSigner[] forMan = verifiedSigners.get(JarFile.MANIFEST_NAME);
+ CodeSigner[] forMan = verifiedSigners.get(manifestName);
if (forMan == null) {
return true;
}
diff --git a/jdk/src/share/classes/java/util/zip/ZipFile.java b/jdk/src/share/classes/java/util/zip/ZipFile.java
index 2978b37..8d0cd17 100644
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2021, 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
@@ -39,6 +39,7 @@
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.WeakHashMap;
+import java.util.jar.JarFile;
import java.security.AccessController;
import sun.security.action.GetPropertyAction;
import static java.util.zip.ZipConstants64.*;
@@ -59,6 +60,7 @@
private final int total; // total number of entries
private final boolean locsig; // if zip file starts with LOCSIG (usually true)
private volatile boolean closeRequested = false;
+ private int manifestNum = 0; // number of META-INF/MANIFEST.MF, case insensitive
private static final int STORED = ZipEntry.STORED;
private static final int DEFLATED = ZipEntry.DEFLATED;
@@ -207,6 +209,7 @@
Integer.toHexString(mode));
}
String name = file.getPath();
+ file = new File(name);
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkRead(name);
@@ -224,6 +227,7 @@
this.name = name;
this.total = getTotal(jzfile);
this.locsig = startsWithLOC(jzfile);
+ this.manifestNum = getManifestNum(jzfile);
}
/**
@@ -762,6 +766,9 @@
public boolean startsWithLocHeader(ZipFile zip) {
return zip.startsWithLocHeader();
}
+ public int getManifestNum(JarFile zip) {
+ return ((ZipFile)zip).getManifestNum();
+ }
}
);
}
@@ -774,10 +781,23 @@
return locsig;
}
+ /*
+ * Returns the number of the META-INF/MANIFEST.MF entries, case insensitive.
+ * When this number is greater than 1, JarVerifier will treat a file as
+ * unsigned.
+ */
+ private int getManifestNum() {
+ synchronized (this) {
+ ensureOpen();
+ return manifestNum;
+ }
+ }
+
private static native long open(String name, int mode, long lastModified,
boolean usemmap) throws IOException;
private static native int getTotal(long jzfile);
private static native boolean startsWithLOC(long jzfile);
+ private static native int getManifestNum(long jzfile);
private static native int read(long jzfile, long jzentry,
long pos, byte[] b, int off, int len);
diff --git a/jdk/src/share/classes/sun/font/TrueTypeFont.java b/jdk/src/share/classes/sun/font/TrueTypeFont.java
index 443f0df..ff80214 100644
--- a/jdk/src/share/classes/sun/font/TrueTypeFont.java
+++ b/jdk/src/share/classes/sun/font/TrueTypeFont.java
@@ -547,6 +547,10 @@
throw new FontFormatException("bad table, tag="+table.tag);
}
}
+ ByteBuffer maxpTable = getTableBuffer(maxpTag);
+ if (maxpTable.getChar(4) == 0) {
+ throw new FontFormatException("zero glyphs");
+ }
initNames();
} catch (Exception e) {
if (FontUtilities.isLogging()) {
@@ -1007,24 +1011,36 @@
private void setStrikethroughMetrics(ByteBuffer os_2Table, int upem) {
if (os_2Table == null || os_2Table.capacity() < 30 || upem < 0) {
- stSize = .05f;
- stPos = -.4f;
+ stSize = 0.05f;
+ stPos = -0.4f;
return;
}
ShortBuffer sb = os_2Table.asShortBuffer();
stSize = sb.get(13) / (float)upem;
stPos = -sb.get(14) / (float)upem;
+ if (stSize < 0f) {
+ stSize = 0.05f;
+ }
+ if (Math.abs(stPos) > 2.0f) {
+ stPos = -0.4f;
+ }
}
private void setUnderlineMetrics(ByteBuffer postTable, int upem) {
if (postTable == null || postTable.capacity() < 12 || upem < 0) {
- ulSize = .05f;
- ulPos = .1f;
+ ulSize = 0.05f;
+ ulPos = 0.1f;
return;
}
ShortBuffer sb = postTable.asShortBuffer();
ulSize = sb.get(5) / (float)upem;
ulPos = -sb.get(4) / (float)upem;
+ if (ulSize < 0f) {
+ ulSize = 0.05f;
+ }
+ if (Math.abs(ulPos) > 2.0f) {
+ ulPos = 0.1f;
+ }
}
@Override
diff --git a/jdk/src/share/classes/sun/misc/JavaUtilZipFileAccess.java b/jdk/src/share/classes/sun/misc/JavaUtilZipFileAccess.java
index f7f878b..29334d8 100644
--- a/jdk/src/share/classes/sun/misc/JavaUtilZipFileAccess.java
+++ b/jdk/src/share/classes/sun/misc/JavaUtilZipFileAccess.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,10 @@
package sun.misc;
+import java.util.jar.JarFile;
import java.util.zip.ZipFile;
public interface JavaUtilZipFileAccess {
public boolean startsWithLocHeader(ZipFile zip);
+ public int getManifestNum(JarFile zip);
}
diff --git a/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java b/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java
index 9197a79..3b67c64 100644
--- a/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java
+++ b/jdk/src/share/classes/sun/net/ftp/impl/FtpClient.java
@@ -24,8 +24,25 @@
*/
package sun.net.ftp.impl;
-import java.net.*;
-import java.io.*;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.UnknownHostException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
@@ -33,6 +50,7 @@
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
@@ -45,7 +63,11 @@
import javax.net.ssl.SSLSocketFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
-import sun.net.ftp.*;
+import sun.net.ftp.FtpDirEntry;
+import sun.net.ftp.FtpDirParser;
+import sun.net.ftp.FtpProtocolException;
+import sun.net.ftp.FtpReplyCode;
+import sun.net.util.IPAddressUtil;
import sun.util.logging.PlatformLogger;
@@ -108,15 +130,16 @@
private static Pattern[] patterns;
private static Pattern linkp = Pattern.compile("(\\p{Print}+) \\-\\> (\\p{Print}+)$");
private DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, java.util.Locale.US);
-
+ private static final boolean acceptPasvAddressVal;
static {
final int vals[] = {0, 0};
final String encs[] = {null};
-
+ final String acceptPasvAddress[] = {null};
AccessController.doPrivileged(
new PrivilegedAction<Object>() {
public Object run() {
+ acceptPasvAddress[0] = System.getProperty("jdk.net.ftp.trustPasvAddress", "false");
vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 300_000).intValue();
vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 300_000).intValue();
encs[0] = System.getProperty("file.encoding", "ISO8859_1");
@@ -148,6 +171,8 @@
for (int i = 0; i < patStrings.length; i++) {
patterns[i] = Pattern.compile(patStrings[i]);
}
+
+ acceptPasvAddressVal = Boolean.parseBoolean(acceptPasvAddress[0]);
}
/**
@@ -625,7 +650,6 @@
//
// The regular expression is a bit more complex this time, because
// the parenthesis are optionals and we have to use 3 groups.
-
if (pasvPat == null) {
pasvPat = Pattern.compile("227 .* \\(?(\\d{1,3},\\d{1,3},\\d{1,3},\\d{1,3}),(\\d{1,3}),(\\d{1,3})\\)?");
}
@@ -637,8 +661,15 @@
port = Integer.parseInt(m.group(3)) + (Integer.parseInt(m.group(2)) << 8);
// IP address is simple
String s = m.group(1).replace(',', '.');
- dest = new InetSocketAddress(s, port);
+ if (!IPAddressUtil.isIPv4LiteralAddress(s))
+ throw new FtpProtocolException("PASV failed : " + serverAnswer);
+ if (acceptPasvAddressVal) {
+ dest = new InetSocketAddress(s, port);
+ } else {
+ dest = validatePasvAddress(port, s, server.getInetAddress());
+ }
}
+
// Got everything, let's open the socket!
Socket s;
if (proxy != null) {
@@ -701,6 +732,86 @@
return s;
}
+ static final String ERROR_MSG = "Address should be the same as originating server";
+
+ /**
+ * Returns an InetSocketAddress, based on value of acceptPasvAddressVal
+ * and other conditions such as the server address returned by pasv
+ * is not a hostname, is a socks proxy, or the loopback. An exception
+ * is thrown if none of the valid conditions are met.
+ */
+ private InetSocketAddress validatePasvAddress(int port, String s, InetAddress address)
+ throws FtpProtocolException
+ {
+ if (address == null) {
+ return InetSocketAddress.createUnresolved(serverAddr.getHostName(), port);
+ }
+ String serverAddress = address.getHostAddress();
+ if (serverAddress.equals(s)) {
+ return new InetSocketAddress(s, port);
+ } else if (address.isLoopbackAddress() && s.startsWith("127.")) { // can be 127.0
+ return new InetSocketAddress(s, port);
+ } else if (address.isLoopbackAddress()) {
+ if (privilegedLocalHost().getHostAddress().equals(s)) {
+ return new InetSocketAddress(s, port);
+ } else {
+ throw new FtpProtocolException(ERROR_MSG);
+ }
+ } else if (s.startsWith("127.")) {
+ if (privilegedLocalHost().equals(address)) {
+ return new InetSocketAddress(s, port);
+ } else {
+ throw new FtpProtocolException(ERROR_MSG);
+ }
+ }
+ String hostName = address.getHostName();
+ if (!(IPAddressUtil.isIPv4LiteralAddress(hostName) || IPAddressUtil.isIPv6LiteralAddress(hostName))) {
+ InetAddress[] names = privilegedGetAllByName(hostName);
+ String resAddress = null;
+ for (int i = 0; i < names.length; i++) {
+ String nameHostAddress = names[i].getHostAddress();
+ if (s.equalsIgnoreCase(nameHostAddress)) {
+ resAddress = nameHostAddress;
+ break;
+ }
+ }
+ if (resAddress != null) {
+ return new InetSocketAddress(s, port);
+ }
+ }
+ throw new FtpProtocolException(ERROR_MSG);
+ }
+
+ private static InetAddress privilegedLocalHost() throws FtpProtocolException {
+ try {
+ return AccessController.doPrivileged(
+ new PrivilegedExceptionAction<InetAddress>() {
+ public InetAddress run() throws UnknownHostException {
+ return InetAddress.getLocalHost();
+ }
+ });
+ } catch (Exception e) {
+ FtpProtocolException ftpEx = new FtpProtocolException(ERROR_MSG);
+ ftpEx.initCause(e);
+ throw ftpEx;
+ }
+ }
+
+ private static InetAddress[] privilegedGetAllByName(final String hostName) throws FtpProtocolException {
+ try {
+ return AccessController.doPrivileged(
+ new PrivilegedExceptionAction<InetAddress[]>() {
+ public InetAddress[] run() throws UnknownHostException {
+ return InetAddress.getAllByName(hostName);
+ }
+ });
+ } catch (Exception e) {
+ FtpProtocolException ftpEx = new FtpProtocolException(ERROR_MSG);
+ ftpEx.initCause(e);
+ throw ftpEx;
+ }
+ }
+
/**
* Opens a data connection with the server according to the set mode
* (ACTIVE or PASSIVE) then send the command passed as an argument.
@@ -711,7 +822,6 @@
*/
private Socket openDataConnection(String cmd) throws sun.net.ftp.FtpProtocolException, IOException {
Socket clientSocket;
-
if (passiveMode) {
try {
return openPassiveDataConnection(cmd);
diff --git a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java
index 5b1e1d2..14f6ad3 100644
--- a/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java
+++ b/jdk/src/share/classes/sun/net/httpserver/ServerImpl.java
@@ -559,17 +559,42 @@
start = space+1;
String version = requestLine.substring (start);
Headers headers = req.headers();
- String s = headers.getFirst ("Transfer-encoding");
+ /* check key for illegal characters */
+ for (String k : headers.keySet()) {
+ if (!isValidHeaderKey(k)) {
+ reject(Code.HTTP_BAD_REQUEST, requestLine,
+ "Header key contains illegal characters");
+ return;
+ }
+ }
+ /* checks for unsupported combinations of lengths and encodings */
+ if (headers.containsKey("Content-Length") &&
+ (headers.containsKey("Transfer-encoding") || headers.get("Content-Length").size() > 1)) {
+ reject(Code.HTTP_BAD_REQUEST, requestLine,
+ "Conflicting or malformed headers detected");
+ return;
+ }
long clen = 0L;
- if (s !=null && s.equalsIgnoreCase ("chunked")) {
- clen = -1L;
+ String headerValue = null;
+ List<String> teValueList = headers.get("Transfer-encoding");
+ if (teValueList != null && !teValueList.isEmpty()) {
+ headerValue = teValueList.get(0);
+ }
+ if (headerValue != null) {
+ if (headerValue.equalsIgnoreCase("chunked") && teValueList.size() == 1) {
+ clen = -1L;
+ } else {
+ reject(Code.HTTP_NOT_IMPLEMENTED,
+ requestLine, "Unsupported Transfer-Encoding value");
+ return;
+ }
} else {
- s = headers.getFirst ("Content-Length");
- if (s != null) {
- clen = Long.parseLong(s);
+ headerValue = headers.getFirst("Content-Length");
+ if (headerValue != null) {
+ clen = Long.parseLong(headerValue);
}
if (clen == 0) {
- requestCompleted (connection);
+ requestCompleted(connection);
}
}
ctx = contexts.findContext (protocol, uri.getPath());
@@ -877,4 +902,24 @@
return secs * 1000;
}
}
+
+ /*
+ * Validates a RFC 7230 header-key.
+ */
+ static boolean isValidHeaderKey(String token) {
+ if (token == null) return false;
+
+ boolean isValidChar;
+ char[] chars = token.toCharArray();
+ String validSpecialChars = "!#$%&'*+-.^_`|~";
+ for (char c : chars) {
+ isValidChar = ((c >= 'a') && (c <= 'z')) ||
+ ((c >= 'A') && (c <= 'Z')) ||
+ ((c >= '0') && (c <= '9'));
+ if (!isValidChar && validSpecialChars.indexOf(c) == -1) {
+ return false;
+ }
+ }
+ return !token.isEmpty();
+ }
}
diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java
index 28cde7b..f40b54a 100644
--- a/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java
+++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Main.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2021, 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
@@ -705,8 +705,12 @@
CodeSigner[] signers = je.getCodeSigners();
boolean isSigned = (signers != null);
anySigned |= isSigned;
- hasUnsignedEntry |= !je.isDirectory() && !isSigned
- && !signatureRelated(name);
+
+ boolean unsignedEntry = !isSigned
+ && ((!je.isDirectory() && !signatureRelated(name))
+ // a directory entry but with a suspicious size
+ || (je.isDirectory() && je.getSize() > 0));
+ hasUnsignedEntry |= unsignedEntry;
int inStoreOrScope = inKeyStore(signers);
@@ -731,7 +735,9 @@
(inManifest ? rb.getString("m") : rb.getString("SPACE")) +
(inStore ? rb.getString("k") : rb.getString("SPACE")) +
(inScope ? rb.getString("i") : rb.getString("SPACE")) +
- ((inStoreOrScope & NOT_ALIAS) != 0 ?"X":" ") +
+ ((inStoreOrScope & NOT_ALIAS) != 0 ?
+ rb.getString("X") : rb.getString("SPACE")) +
+ (unsignedEntry ? rb.getString("q") : rb.getString("SPACE")) +
rb.getString("SPACE"));
sb.append("|");
}
@@ -756,9 +762,13 @@
if (signatureRelated(name)) {
sb.append("\n" + tab + rb.getString(
".Signature.related.entries.") + "\n\n");
+ } else if (unsignedEntry) {
+ sb.append('\n').append(tab)
+ .append(rb.getString(".Unsigned.entries."))
+ .append("\n\n");
} else {
sb.append("\n" + tab + rb.getString(
- ".Unsigned.entries.") + "\n\n");
+ ".Directory.entries.") + "\n\n");
}
}
@@ -835,6 +845,11 @@
System.out.println(rb.getString(
".X.not.signed.by.specified.alias.es."));
}
+
+ if (hasUnsignedEntry) {
+ System.out.println(rb.getString(
+ ".q.unsigned.entry"));
+ }
}
if (man == null) {
System.out.println();
diff --git a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java
index da460ca..0e3f5240 100644
--- a/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java
+++ b/jdk/src/share/classes/sun/security/tools/jarsigner/Resources.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -121,6 +121,8 @@
{"m", "m"},
{"k", "k"},
{"i", "i"},
+ {"X", "X"},
+ {"q", "?"},
{".and.d.more.", "(and %d more)"},
{".s.signature.was.verified.",
" s = signature was verified "},
@@ -132,9 +134,12 @@
" i = at least one certificate was found in identity scope"},
{".X.not.signed.by.specified.alias.es.",
" X = not signed by specified alias(es)"},
+ {".q.unsigned.entry",
+ " ? = unsigned entry"},
{"no.manifest.", "no manifest."},
{".Signature.related.entries.","(Signature related entries)"},
{".Unsigned.entries.", "(Unsigned entries)"},
+ {".Directory.entries.", "(Directory entries)"},
{"jar.is.unsigned",
"jar is unsigned."},
{"jar.treated.unsigned",
diff --git a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java
index 024af90..5a97fa6 100644
--- a/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java
+++ b/jdk/src/share/classes/sun/security/util/SignatureFileVerifier.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2021, 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
@@ -250,7 +250,7 @@
*
*/
public void process(Hashtable<String, CodeSigner[]> signers,
- List<Object> manifestDigests)
+ List<Object> manifestDigests, String manifestName)
throws IOException, SignatureException, NoSuchAlgorithmException,
JarException, CertificateException
{
@@ -259,7 +259,7 @@
Object obj = null;
try {
obj = Providers.startJarVerification();
- processImpl(signers, manifestDigests);
+ processImpl(signers, manifestDigests, manifestName);
} finally {
Providers.stopJarVerification(obj);
}
@@ -267,7 +267,7 @@
}
private void processImpl(Hashtable<String, CodeSigner[]> signers,
- List<Object> manifestDigests)
+ List<Object> manifestDigests, String manifestName)
throws IOException, SignatureException, NoSuchAlgorithmException,
JarException, CertificateException
{
@@ -350,7 +350,7 @@
}
// MANIFEST.MF is always regarded as signed
- updateSigners(newSigners, signers, JarFile.MANIFEST_NAME);
+ updateSigners(newSigners, signers, manifestName);
}
/**
diff --git a/jdk/src/share/native/java/util/zip/ZipFile.c b/jdk/src/share/native/java/util/zip/ZipFile.c
index cf9ded9..04990d5 100644
--- a/jdk/src/share/native/java/util/zip/ZipFile.c
+++ b/jdk/src/share/native/java/util/zip/ZipFile.c
@@ -147,6 +147,14 @@
return zip->locsig;
}
+JNIEXPORT jint JNICALL
+Java_java_util_zip_ZipFile_getManifestNum(JNIEnv *env, jclass cls, jlong zfile)
+{
+ jzfile *zip = jlong_to_ptr(zfile);
+
+ return zip->manifestNum;
+}
+
JNIEXPORT void JNICALL
Java_java_util_zip_ZipFile_close(JNIEnv *env, jclass cls, jlong zfile)
{
diff --git a/jdk/src/share/native/java/util/zip/zip_util.c b/jdk/src/share/native/java/util/zip/zip_util.c
index 54d35f1..79c52b2 100644
--- a/jdk/src/share/native/java/util/zip/zip_util.c
+++ b/jdk/src/share/native/java/util/zip/zip_util.c
@@ -74,6 +74,8 @@
#define PATH_MAX 1024
#endif
+#define META_INF_LEN 9 /* "META-INF/".length() */
+
static jint INITIAL_META_COUNT = 2; /* initial number of entries in meta name array */
/*
@@ -444,6 +446,25 @@
}
/*
+ * Check if the bytes represents a name equals to MANIFEST.MF
+ */
+static int
+isManifestName(const char *name, int length)
+{
+ const char *s;
+ if (length != (int)sizeof("MANIFEST.MF") - 1)
+ return 0;
+ for (s = "MANIFEST.MF"; *s != '\0'; s++) {
+ char c = *name++;
+ // Avoid toupper; it's locale-dependent
+ if (c >= 'a' && c <= 'z') c += 'A' - 'a';
+ if (*s != c)
+ return 0;
+ }
+ return 1;
+}
+
+/*
* Increases the capacity of zip->metanames.
* Returns non-zero in case of allocation error.
*/
@@ -513,6 +534,7 @@
{
free(zip->entries); zip->entries = NULL;
free(zip->table); zip->table = NULL;
+ zip->manifestNum = 0;
freeMetaNames(zip);
}
@@ -663,6 +685,8 @@
for (j = 0; j < tablelen; j++)
table[j] = ZIP_ENDCHAIN;
+ zip->manifestNum = 0;
+
/* Iterate through the entries in the central directory */
for (i = 0, cp = cenbuf; cp <= cenend - CENHDR; i++, cp += CENSIZE(cp)) {
/* Following are unsigned 16-bit */
@@ -690,9 +714,12 @@
ZIP_FORMAT_ERROR("invalid CEN header (bad header size)");
/* if the entry is metadata add it to our metadata names */
- if (isMetaName((char *)cp+CENHDR, nlen))
+ if (isMetaName((char *)cp+CENHDR, nlen)) {
+ if (isManifestName((char *)cp+CENHDR+META_INF_LEN, nlen-META_INF_LEN))
+ zip->manifestNum++;
if (addMetaName(zip, (char *)cp+CENHDR, nlen) != 0)
goto Catch;
+ }
/* Record the CEN offset and the name hash in our hash cell. */
entries[i].cenpos = cenpos + (cp - cenbuf);
diff --git a/jdk/src/share/native/java/util/zip/zip_util.h b/jdk/src/share/native/java/util/zip/zip_util.h
index 124e3f7..0441e9a8 100644
--- a/jdk/src/share/native/java/util/zip/zip_util.h
+++ b/jdk/src/share/native/java/util/zip/zip_util.h
@@ -227,6 +227,7 @@
char **metanames; /* array of meta names (may have null names) */
jint metacurrent; /* the next empty slot in metanames array */
jint metacount; /* number of slots in metanames array */
+ jint manifestNum; /* number of META-INF/MANIFEST.MF, case insensitive */
jlong lastModified; /* last modified time */
jlong locpos; /* position of first LOC header (usually 0) */
} jzfile;
diff --git a/jdk/test/com/sun/jndi/ldap/LdapDnsProviderTest.java b/jdk/test/com/sun/jndi/ldap/LdapDnsProviderTest.java
new file mode 100644
index 0000000..1bc4a30
--- /dev/null
+++ b/jdk/test/com/sun/jndi/ldap/LdapDnsProviderTest.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 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. 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.
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.security.Permission;
+import java.util.Hashtable;
+import java.util.concurrent.Callable;
+import java.util.concurrent.FutureTask;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.directory.InitialDirContext;
+import javax.naming.directory.SearchControls;
+
+/**
+ * @test
+ * @bug 8160768
+ * @summary ctx provider tests for ldap
+ * @compile dnsprovider/TestDnsProvider.java
+ * @run main/othervm LdapDnsProviderTest
+ * @run main/othervm LdapDnsProviderTest nosm
+ * @run main/othervm LdapDnsProviderTest smnodns
+ * @run main/othervm LdapDnsProviderTest smdns
+ * @run main/othervm LdapDnsProviderTest nosmbaddns
+ */
+
+class DNSSecurityManager extends SecurityManager {
+
+
+
+ /* run main/othervm LdapDnsProviderTest
+
+ * run main/othervm LdapDnsProviderTest nosm
+ * run main/othervm LdapDnsProviderTest smnodns
+ * run main/othervm LdapDnsProviderTest smdns
+ * run main/othervm LdapDnsProviderTest nosmbaddns
+ */
+
+ private boolean dnsProvider = false;
+
+ public void setAllowDnsProvider(boolean allow) {
+ dnsProvider = allow;
+ }
+
+ @Override
+ public void checkPermission(Permission p) {
+ if (p.getName().equals("ldapDnsProvider") && !dnsProvider) {
+ throw new SecurityException(p.getName());
+ }
+ }
+}
+
+class ProviderTest implements Callable<Boolean> {
+
+ private final String url;
+ private final String expected;
+ private final Hashtable<String, String> env = new Hashtable<>(11);
+
+ public ProviderTest(String url, String expected) {
+ this.url = url;
+ this.expected = expected;
+ env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
+ }
+
+ boolean shutItDown(InitialContext ctx) {
+ try {
+ if (ctx != null) ctx.close();
+ return true;
+ } catch (NamingException ex) {
+ return false;
+ }
+ }
+
+ public Boolean call() {
+ boolean passed;
+ InitialContext ctx = null;
+
+ if (url != null) {
+ env.put(Context.PROVIDER_URL, url);
+ }
+
+ try {
+ ctx = new InitialDirContext(env);
+ SearchControls scl = new SearchControls();
+ scl.setSearchScope(SearchControls.SUBTREE_SCOPE);
+ ((InitialDirContext)ctx).search(
+ "ou=People,o=Test", "(objectClass=*)", scl);
+ throw new RuntimeException("Search should not complete");
+ } catch (NamingException e) {
+ e.printStackTrace();
+ passed = e.toString().contains(expected);
+ } finally {
+ shutItDown(ctx);
+ }
+ return passed;
+ }
+}
+
+public class LdapDnsProviderTest {
+
+ private static final String TEST_CLASSES =
+ System.getProperty("test.classes", ".");
+
+ public static void writeFile(String content, File dstFile)
+ throws IOException
+ {
+ try (FileOutputStream dst = new FileOutputStream(dstFile)) {
+ byte[] buf = content.getBytes();
+ dst.write(buf, 0, buf.length);
+ }
+ }
+
+ public static void installServiceConfigurationFile(String content) {
+ String filename = "com.sun.jndi.ldap.spi.LdapDnsProvider";
+
+ File dstDir = new File(TEST_CLASSES, "META-INF/services");
+ if (!dstDir.exists()) {
+ if (!dstDir.mkdirs()) {
+ throw new RuntimeException(
+ "could not create META-INF/services directory " + dstDir);
+ }
+ }
+ File dstFile = new File(dstDir, filename);
+
+ try {
+ writeFile(content, dstFile);
+ } catch (IOException e) {
+ throw new RuntimeException("could not install " + dstFile, e);
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (args.length > 0 && args[0].equals("nosm")) {
+ // no security manager, serviceloader
+ installServiceConfigurationFile("dnsprovider.TestDnsProvider");
+ runTest("ldap:///dc=example,dc=com", "yupyupyup:389");
+ } else if (args.length > 0 && args[0].equals("smnodns")) {
+ // security manager & serviceloader
+ installServiceConfigurationFile("dnsprovider.TestDnsProvider");
+ // install security manager
+ System.setSecurityManager(new DNSSecurityManager());
+ runTest("ldap:///dc=example,dc=com", "ServiceConfigurationError");
+ } else if (args.length > 0 && args[0].equals("smdns")) {
+ // security manager & serviceloader
+ DNSSecurityManager sm = new DNSSecurityManager();
+ installServiceConfigurationFile("dnsprovider.TestDnsProvider");
+ // install security manager
+ System.setSecurityManager(sm);
+ sm.setAllowDnsProvider(true);
+ runTest("ldap:///dc=example,dc=com", "yupyupyup:389");
+ } else if (args.length > 0 && args[0].equals("nosmbaddns")) {
+ // no security manager, no serviceloader
+ // DefaultLdapDnsProvider
+ installServiceConfigurationFile("dnsprovider.MissingDnsProvider");
+ // no SecurityManager
+ runTest("ldap:///dc=example,dc=com", "not found");
+ } else {
+ // no security manager, no serviceloader
+ // DefaultLdapDnsProvider
+ System.err.println("TEST_CLASSES:");
+ System.err.println(TEST_CLASSES);
+ File f = new File(
+ TEST_CLASSES, "META-INF/services/com.sun.jndi.ldap.spi.LdapDnsProvider");
+ if (f.exists()) {
+ f.delete();
+ }
+
+ // no SecurityManager
+ runTest("ldap:///dc=example,dc=com", "localhost:389");
+ runTest("ldap://localhost/dc=example,dc=com", "localhost:389");
+ runTest("ldap://localhost:111/dc=example,dc=com", "localhost:111");
+ runTest("ldaps://localhost:111/dc=example,dc=com", "localhost:111");
+ runTest("ldaps://localhost/dc=example,dc=com", "localhost:636");
+ runTest(null, "localhost:389");
+ runTest("", "ConfigurationException");
+ }
+ }
+
+ private static void runTest(String url, String expected) {
+ FutureTask<Boolean> future =
+ new FutureTask<>(
+ new ProviderTest(url, expected));
+ new Thread(future).start();
+
+ System.err.println("Testing: " + url + ", " + expected);
+ while (!future.isDone()) {
+ try {
+ if (!future.get()) {
+ System.err.println("Test failed");
+ throw new RuntimeException(
+ "Test failed, ProviderTest returned false");
+ }
+ } catch (Exception e) {
+ if (!e.toString().contains(expected)) {
+ System.err.println("Test failed");
+ throw new RuntimeException(
+ "Test failed, unexpected result");
+ }
+ }
+ }
+ System.err.println("Test passed");
+ }
+
+}
+
diff --git a/jdk/test/com/sun/jndi/ldap/dnsprovider/TestDnsProvider.java b/jdk/test/com/sun/jndi/ldap/dnsprovider/TestDnsProvider.java
new file mode 100644
index 0000000..6a8798d
--- /dev/null
+++ b/jdk/test/com/sun/jndi/ldap/dnsprovider/TestDnsProvider.java
@@ -0,0 +1,18 @@
+package dnsprovider;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import com.sun.jndi.ldap.spi.LdapDnsProvider;
+import com.sun.jndi.ldap.spi.LdapDnsProviderResult;
+
+public class TestDnsProvider extends LdapDnsProvider {
+ @Override
+ public LdapDnsProviderResult lookupEndpoints(String url,
+ Map<?, ?> env)
+ {
+ List<String> endpoints = new ArrayList<>();
+ endpoints.add("ldap://yupyupyup:389");
+ return new LdapDnsProviderResult("test.com", endpoints);
+ }
+}
diff --git a/jdk/test/com/sun/security/auth/module/LdapLoginModule/CheckConfigs.policy b/jdk/test/com/sun/security/auth/module/LdapLoginModule/CheckConfigs.policy
index 8febfcd..b022858 100644
--- a/jdk/test/com/sun/security/auth/module/LdapLoginModule/CheckConfigs.policy
+++ b/jdk/test/com/sun/security/auth/module/LdapLoginModule/CheckConfigs.policy
@@ -6,6 +6,7 @@
//permission java.net.SocketPermission "*:389", "connect";
//permission java.net.SocketPermission "*:636", "connect";
//permission javax.security.auth.AuthPermission "modifyPrincipals";
+ permission java.lang.RuntimePermission "ldapDnsProvider";
};
diff --git a/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh b/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh
index 89681df..17619d6 100644
--- a/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh
+++ b/jdk/test/sun/security/tools/jarsigner/concise_jarsigner.sh
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
#
# @test
-# @bug 6802846 8172529 8227758
+# @bug 6802846 8172529 8227758 8260960
# @summary jarsigner needs enhanced cert validation(options)
#
# @run shell/timeout=240 concise_jarsigner.sh
@@ -106,17 +106,20 @@
LINES=`$JARSIGNER -verify a.jar -verbose:grouped | grep $YEAR | wc -l`
[ $LINES = 12 ] || exit $LINENO
-# 4 groups: MANIFST, unrelated, signed, unsigned
+# 5 groups: MANIFEST, signature related entries, directory entries,
+# signed entries, and unsigned entries.
LINES=`$JARSIGNER -verify a.jar -verbose:summary | grep $YEAR | wc -l`
-[ $LINES = 4 ] || exit $LINENO
+[ $LINES = 5 ] || exit $LINENO
-# still 4 groups, but MANIFEST group has no other file
+# still 5 groups, but MANIFEST group and directory entry group
+# have no other file
LINES=`$JARSIGNER -verify a.jar -verbose:summary | grep "more)" | wc -l`
[ $LINES = 3 ] || exit $LINENO
-# 5 groups: MANIFEST, unrelated, signed by a1/a2, signed by a2, unsigned
+# 6 groups: MANIFEST, signature related entries, directory entries,
+# signed entries by a1/a2, signed entries by a2, and unsigned entries.
LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep $YEAR | wc -l`
-[ $LINES = 5 ] || exit $LINENO
+[ $LINES = 6 ] || exit $LINENO
# 2 for MANIFEST, 2*2 for A1/A2, 2 for A3/A4
LINES=`$JARSIGNER -verify a.jar -verbose -certs | grep "\[certificate" | wc -l`
@@ -130,7 +133,8 @@
LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep "\[certificate" | wc -l`
[ $LINES = 5 ] || exit $LINENO
-# still 5 groups, but MANIFEST group has no other file
+# still 6 groups, but MANIFEST group and directory entry group
+# have no other file
LINES=`$JARSIGNER -verify a.jar -verbose:summary -certs | grep "more)" | wc -l`
[ $LINES = 4 ] || exit $LINENO
diff --git a/langtools/.hgtags b/langtools/.hgtags
index e1e4e08..8c5cae16 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -660,3 +660,6 @@
92eaf0cd9396049f8807b7aaede5ac3f662745e7 jdk7u291-b01
92eaf0cd9396049f8807b7aaede5ac3f662745e7 jdk7u291-ga
92eaf0cd9396049f8807b7aaede5ac3f662745e7 jdk7u301-b00
+c573fe30d9f3729801c776d1f615517292604524 jdk7u301-b01
+c573fe30d9f3729801c776d1f615517292604524 jdk7u301-ga
+c573fe30d9f3729801c776d1f615517292604524 jdk7u311-b00
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/legacy.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/legacy.properties
index 2504451..7583047 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/legacy.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/legacy.properties
@@ -143,6 +143,7 @@
com.sun.jndi.ldap.ext = tiger legacy
com.sun.jndi.ldap.pool = tiger legacy
com.sun.jndi.ldap.sasl = tiger legacy
+com.sun.jndi.ldap.spi = tiger legacy
com.sun.jndi.rmi.registry = tiger legacy
com.sun.jndi.toolkit.corba = tiger legacy
com.sun.jndi.toolkit.ctx = tiger legacy
diff --git a/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java b/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java
index 9ee550e..1cf1af3 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java
@@ -476,6 +476,7 @@
"org.w3c.dom.css",
"org.w3c.dom.events",
"org.w3c.dom.views",
+ "com.sun.jndi.ldap.spi",
"com.sun.management",
"com.sun.security.auth",
"com.sun.security.auth.callback",