--- a/.hgtags-top-repo Thu Oct 20 18:38:09 2016 +0000
+++ b/.hgtags-top-repo Wed Jul 05 22:22:15 2017 +0200
@@ -383,3 +383,4 @@
67c4388142bdf58aec8fefa4475faaa8a5d7380c jdk-9+138
7dcf453eacae79ee86a6bcc75fd0b546fc99b48a jdk-9+139
a5815c6098a241d3a1df64d22b84b3524e4a77df jdk-9+140
+f64afae7f1a5608e438585bbf0bc23785e69cba0 jdk-9+141
--- a/common/autoconf/flags.m4 Thu Oct 20 18:38:09 2016 +0000
+++ b/common/autoconf/flags.m4 Wed Jul 05 22:22:15 2017 +0200
@@ -895,7 +895,7 @@
elif test "x$OPENJDK_$1_OS" = xsolaris; then
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -DSOLARIS"
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -template=no%extdef -features=no%split_init \
- -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+ -D_Crun_inline_placement -library=%none -KPIC -mt -features=no%except"
elif test "x$OPENJDK_$1_OS" = xmacosx; then
$2COMMON_CCXXFLAGS_JDK="[$]$2COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_ALLBSD_SOURCE"
--- a/common/autoconf/generated-configure.sh Thu Oct 20 18:38:09 2016 +0000
+++ b/common/autoconf/generated-configure.sh Wed Jul 05 22:22:15 2017 +0200
@@ -5093,7 +5093,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1476275292
+DATE_WHEN_GENERATED=1477108079
###############################################################################
#
@@ -50077,7 +50077,7 @@
elif test "x$OPENJDK_TARGET_OS" = xsolaris; then
JVM_CFLAGS="$JVM_CFLAGS -DSOLARIS"
JVM_CFLAGS="$JVM_CFLAGS -template=no%extdef -features=no%split_init \
- -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+ -D_Crun_inline_placement -library=%none -KPIC -mt -features=no%except"
elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
COMMON_CCXXFLAGS_JDK="$COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
JVM_CFLAGS="$JVM_CFLAGS -D_ALLBSD_SOURCE"
@@ -50892,7 +50892,7 @@
elif test "x$OPENJDK_BUILD_OS" = xsolaris; then
OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -DSOLARIS"
OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -template=no%extdef -features=no%split_init \
- -D_Crun_inline_placement -library=%none -KPIC -mt -xwe -features=no%except"
+ -D_Crun_inline_placement -library=%none -KPIC -mt -features=no%except"
elif test "x$OPENJDK_BUILD_OS" = xmacosx; then
OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK="$OPENJDK_BUILD_COMMON_CCXXFLAGS_JDK -D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_ALLBSD_SOURCE"
--- a/corba/.hgtags Thu Oct 20 18:38:09 2016 +0000
+++ b/corba/.hgtags Wed Jul 05 22:22:15 2017 +0200
@@ -383,3 +383,4 @@
27bb44be32076861a0951bcefb07a1d92509a4b6 jdk-9+138
8c9da7fc5b07c606afd571c7012441b77dda83b2 jdk-9+139
9f3fc931bc230f44f2a58d75f7f6360af98bb113 jdk-9+140
+b32f998da32b488ec7c4e9dbb3c750841b48e74d jdk-9+141
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java Thu Oct 20 18:38:09 2016 +0000
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPInputStream.java Wed Jul 05 22:22:15 2017 +0200
@@ -31,22 +31,17 @@
package com.sun.corba.se.impl.io;
-import java.io.InputStream;
import java.io.IOException;
import java.io.StreamCorruptedException;
import java.io.ObjectInputValidation;
import java.io.NotActiveException;
import java.io.InvalidObjectException;
import java.io.InvalidClassException;
-import java.io.DataInputStream;
import java.io.OptionalDataException;
-import java.io.WriteAbortedException;
import java.io.Externalizable;
import java.io.EOFException;
import java.lang.reflect.*;
import java.util.Vector;
-import java.util.Stack;
-import java.util.Hashtable;
import java.util.Enumeration;
import sun.corba.Bridge ;
@@ -54,7 +49,6 @@
import java.security.AccessController ;
import java.security.PrivilegedAction ;
-import com.sun.corba.se.impl.io.ObjectStreamClass;
import com.sun.corba.se.impl.util.Utility;
import org.omg.CORBA.portable.ValueInputStream;
@@ -71,14 +65,12 @@
import com.sun.org.omg.CORBA.ValueDefPackage.FullValueDescription;
import com.sun.org.omg.SendingContext.CodeBase;
-import javax.rmi.PortableRemoteObject;
import javax.rmi.CORBA.Util;
import javax.rmi.CORBA.ValueHandler;
import java.security.*;
import java.util.*;
-import com.sun.corba.se.impl.orbutil.ObjectUtility ;
import com.sun.corba.se.impl.logging.OMGSystemException ;
import com.sun.corba.se.impl.logging.UtilSystemException ;
@@ -182,75 +174,6 @@
private byte streamFormatVersion;
- // Since java.io.OptionalDataException's constructors are
- // package private, but we need to throw it in some special
- // cases, we try to do it by reflection.
- private static final Constructor OPT_DATA_EXCEPTION_CTOR;
-
- private Object[] readObjectArgList = { this } ;
-
- static {
- OPT_DATA_EXCEPTION_CTOR = getOptDataExceptionCtor();
- }
-
- // Grab the OptionalDataException boolean ctor and make
- // it accessible. Note that any exceptions
- // will be wrapped in ExceptionInInitializerErrors.
- private static Constructor getOptDataExceptionCtor() {
-
- try {
-
- Constructor result =
-
- (Constructor) AccessController.doPrivileged(
- new PrivilegedExceptionAction() {
- public java.lang.Object run()
- throws NoSuchMethodException,
- SecurityException {
-
- Constructor boolCtor
- = OptionalDataException.class.getDeclaredConstructor(
- new Class[] {
- Boolean.TYPE });
-
- boolCtor.setAccessible(true);
-
- return boolCtor;
- }});
-
- if (result == null)
- // XXX I18N, logging needed.
- throw new Error("Unable to find OptionalDataException constructor");
-
- return result;
-
- } catch (Exception ex) {
- // XXX I18N, logging needed.
- throw new ExceptionInInitializerError(ex);
- }
- }
-
- // Create a new OptionalDataException with the EOF marker
- // set to true. See handleOptionalDataMarshalException.
- private OptionalDataException createOptionalDataException() {
- try {
- OptionalDataException result
- = (OptionalDataException)
- OPT_DATA_EXCEPTION_CTOR.newInstance(new Object[] {
- Boolean.TRUE });
-
- if (result == null)
- // XXX I18N, logging needed.
- throw new Error("Created null OptionalDataException");
-
- return result;
-
- } catch (Exception ex) {
- // XXX I18N, logging needed.
- throw new Error("Couldn't create OptionalDataException", ex);
- }
- }
-
// Return the stream format version currently being used
// to deserialize an object
protected byte getStreamFormatVersion() {
@@ -395,7 +318,6 @@
int offset)
/* throws OptionalDataException, ClassNotFoundException, IOException */
{
-
/* Save the current state and get ready to read an object. */
Object prevObject = currentObject;
ObjectStreamClass prevClassDesc = currentClassDesc;
@@ -947,7 +869,7 @@
if (!objectRead)
result = new EOFException("No more optional data");
else
- result = createOptionalDataException();
+ result = bridge.newOptionalDataExceptionForSerialization(true);
result.initCause(marshalException);
@@ -1230,8 +1152,7 @@
readObjectState.beginUnmarshalCustomValue(this,
calledDefaultWriteObject,
- (currentClassDesc.readObjectMethod
- != null));
+ currentClassDesc.hasReadObject());
} else {
if (currentClassDesc.hasReadObject())
setState(IN_READ_OBJECT_REMOTE_NOT_CUSTOM_MARSHALED);
@@ -1556,8 +1477,7 @@
readObjectState.beginUnmarshalCustomValue(this,
calledDefaultWriteObject,
- (currentClassDesc.readObjectMethod
- != null));
+ currentClassDesc.hasReadObject());
}
boolean usedReadObject = false;
@@ -1714,13 +1634,8 @@
throws InvalidClassException, StreamCorruptedException,
ClassNotFoundException, IOException
{
- if (osc.readObjectMethod == null) {
- return false;
- }
-
try {
- osc.readObjectMethod.invoke( obj, readObjectArgList ) ;
- return true;
+ return osc.invokeReadObject( obj, this ) ;
} catch (InvocationTargetException e) {
Throwable t = e.getTargetException();
if (t instanceof ClassNotFoundException)
@@ -1734,8 +1649,6 @@
else
// XXX I18N, logging needed.
throw new Error("internal error");
- } catch (IllegalAccessException e) {
- return false;
}
}
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java Thu Oct 20 18:38:09 2016 +0000
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/IIOPOutputStream.java Wed Jul 05 22:22:15 2017 +0200
@@ -31,33 +31,23 @@
package com.sun.corba.se.impl.io;
-import org.omg.CORBA.INTERNAL;
import org.omg.CORBA.portable.OutputStream;
import java.security.AccessController ;
import java.security.PrivilegedAction ;
import java.io.IOException;
-import java.io.DataOutputStream;
-import java.io.Serializable;
import java.io.InvalidClassException;
-import java.io.StreamCorruptedException;
import java.io.Externalizable;
-import java.io.ObjectStreamException;
import java.io.NotSerializableException;
import java.io.NotActiveException;
import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Field;
-
-import java.util.Stack;
import javax.rmi.CORBA.Util;
-import javax.rmi.CORBA.ValueHandlerMultiFormat;
import sun.corba.Bridge ;
-import com.sun.corba.se.impl.io.ObjectStreamClass;
import com.sun.corba.se.impl.util.Utility;
import com.sun.corba.se.impl.util.RepositoryId;
@@ -621,7 +611,7 @@
writeObjectState.enterWriteObject(this);
// writeObject(obj, c, this);
- osc.writeObjectMethod.invoke( obj, writeObjectArgList ) ;
+ osc.invokeWriteObject( obj, this ) ;
writeObjectState.exitWriteObject(this);
@@ -636,8 +626,6 @@
else
// XXX I18N, Logging needed.
throw new Error("invokeObjectWriter internal error",e);
- } catch (IllegalAccessException e) {
- // cannot happen
}
}
@@ -761,59 +749,52 @@
*/
private void outputClassFields(Object o, Class cl,
ObjectStreamField[] fields)
- throws IOException, InvalidClassException {
+ throws IOException {
for (int i = 0; i < fields.length; i++) {
if (fields[i].getField() == null)
- // XXX I18N, Logging needed.
throw new InvalidClassException(cl.getName(),
"Nonexistent field " + fields[i].getName());
-
- try {
- switch (fields[i].getTypeCode()) {
- case 'B':
- byte byteValue = fields[i].getField().getByte( o ) ;
- orbStream.write_octet(byteValue);
- break;
- case 'C':
- char charValue = fields[i].getField().getChar( o ) ;
- orbStream.write_wchar(charValue);
- break;
- case 'F':
- float floatValue = fields[i].getField().getFloat( o ) ;
- orbStream.write_float(floatValue);
- break;
- case 'D' :
- double doubleValue = fields[i].getField().getDouble( o ) ;
- orbStream.write_double(doubleValue);
- break;
- case 'I':
- int intValue = fields[i].getField().getInt( o ) ;
- orbStream.write_long(intValue);
- break;
- case 'J':
- long longValue = fields[i].getField().getLong( o ) ;
- orbStream.write_longlong(longValue);
- break;
- case 'S':
- short shortValue = fields[i].getField().getShort( o ) ;
- orbStream.write_short(shortValue);
- break;
- case 'Z':
- boolean booleanValue = fields[i].getField().getBoolean( o ) ;
- orbStream.write_boolean(booleanValue);
- break;
- case '[':
- case 'L':
- Object objectValue = fields[i].getField().get( o ) ;
- writeObjectField(fields[i], objectValue);
- break;
- default:
- // XXX I18N, Logging needed.
- throw new InvalidClassException(cl.getName());
- }
- } catch (IllegalAccessException exc) {
- throw wrapper.illegalFieldAccess( exc, fields[i].getName() ) ;
+ switch (fields[i].getTypeCode()) {
+ case 'B':
+ byte byteValue = bridge.getByte(o, fields[i].getFieldID()) ;
+ orbStream.write_octet(byteValue);
+ break;
+ case 'C':
+ char charValue = bridge.getChar(o, fields[i].getFieldID()) ;
+ orbStream.write_wchar(charValue);
+ break;
+ case 'F':
+ float floatValue = bridge.getFloat(o, fields[i].getFieldID()) ;
+ orbStream.write_float(floatValue);
+ break;
+ case 'D' :
+ double doubleValue = bridge.getDouble(o, fields[i].getFieldID()) ;
+ orbStream.write_double(doubleValue);
+ break;
+ case 'I':
+ int intValue = bridge.getInt(o, fields[i].getFieldID()) ;
+ orbStream.write_long(intValue);
+ break;
+ case 'J':
+ long longValue = bridge.getLong(o, fields[i].getFieldID()) ;
+ orbStream.write_longlong(longValue);
+ break;
+ case 'S':
+ short shortValue = bridge.getShort(o, fields[i].getFieldID()) ;
+ orbStream.write_short(shortValue);
+ break;
+ case 'Z':
+ boolean booleanValue = bridge.getBoolean(o, fields[i].getFieldID()) ;
+ orbStream.write_boolean(booleanValue);
+ break;
+ case '[':
+ case 'L':
+ Object objectValue = bridge.getObject(o, fields[i].getFieldID()) ;
+ writeObjectField(fields[i], objectValue);
+ break;
+ default:
+ throw new InvalidClassException(cl.getName());
}
}
}
--- a/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java Thu Oct 20 18:38:09 2016 +0000
+++ b/corba/src/java.corba/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java Wed Jul 05 22:22:15 2017 +0200
@@ -31,16 +31,16 @@
package com.sun.corba.se.impl.io;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.invoke.MethodHandle;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.DigestOutputStream;
import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-import java.security.PrivilegedActionException;
import java.security.PrivilegedAction;
import java.lang.reflect.Modifier;
-import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
@@ -80,9 +80,6 @@
public static final long kDefaultUID = -1;
- private static Object noArgsList[] = {};
- private static Class<?> noTypesList[] = {};
-
/** true if represents enum type */
private boolean isEnum;
@@ -311,12 +308,37 @@
return null;
}
+ public final boolean invokeWriteObject(Object obj, ObjectOutputStream ois) throws InvocationTargetException {
+ if (!hasWriteObject()) {
+ return false;
+ }
+ try {
+ writeObjectMethod.invoke(obj, ois);
+ } catch (Throwable t) {
+ throw new InvocationTargetException(t, "writeObject");
+ }
+ return true;
+ }
+
+ public final boolean invokeReadObject(Object obj, ObjectInputStream ois) throws InvocationTargetException {
+ if (hasReadObject()) {
+ try {
+ readObjectMethod.invoke(obj, ois);
+ return true;
+ } catch (Throwable t) {
+ throw new InvocationTargetException(t, "readObject");
+ }
+ } else {
+ return false;
+ }
+ }
+
public Serializable writeReplace(Serializable value) {
if (writeReplaceObjectMethod != null) {
try {
- return (Serializable) writeReplaceObjectMethod.invoke(value,noArgsList);
- } catch(Throwable t) {
- throw new RuntimeException(t);
+ return (Serializable) writeReplaceObjectMethod.invoke(value);
+ } catch (Throwable t) {
+ throw new InternalError("unexpected error", t);
}
}
else return value;
@@ -325,9 +347,9 @@
public Object readResolve(Object value) {
if (readResolveObjectMethod != null) {
try {
- return readResolveObjectMethod.invoke(value,noArgsList);
- } catch(Throwable t) {
- throw new RuntimeException(t);
+ return readResolveObjectMethod.invoke(value);
+ } catch (Throwable t) {
+ throw new InternalError("unexpected error", t);
}
}
else return value;
@@ -382,31 +404,34 @@
*/
}
- private static final class PersistentFieldsValue
+ static final class PersistentFieldsValue
extends ClassValue<ObjectStreamField[]> {
PersistentFieldsValue() { }
protected ObjectStreamField[] computeValue(Class<?> type) {
try {
+ bridge.ensureClassInitialized(type);
Field pf = type.getDeclaredField("serialPersistentFields");
int mods = pf.getModifiers();
if (Modifier.isPrivate(mods) && Modifier.isStatic(mods) &&
Modifier.isFinal(mods)) {
- pf.setAccessible(true);
+ long offset = bridge.staticFieldOffset(pf);
java.io.ObjectStreamField[] fields =
- (java.io.ObjectStreamField[])pf.get(type);
+ (java.io.ObjectStreamField[])bridge.getObject(type, offset);
return translateFields(fields);
}
- } catch (NoSuchFieldException | IllegalAccessException |
+ } catch (NoSuchFieldException |
IllegalArgumentException | ClassCastException e) {
}
return null;
}
- private static ObjectStreamField[] translateFields(
- java.io.ObjectStreamField[] fields) {
+ private static ObjectStreamField[] translateFields(java.io.ObjectStreamField[] fields) {
+ if (fields == null) {
+ return null;
+ }
ObjectStreamField[] translation =
- new ObjectStreamField[fields.length];
+ new ObjectStreamField[fields.length];
for (int i = 0; i < fields.length; i++) {
translation[i] = new ObjectStreamField(fields[i].getName(),
fields[i].getType());
@@ -450,13 +475,11 @@
* If it is declared, use the declared serialPersistentFields.
* Otherwise, extract the fields from the class itself.
*/
- fields = persistentFieldsValue.get(cl);
+ fields = persistentFieldsValue.get(cl);
if (fields == null) {
- /* Get all of the declared fields for this
- * Class. setAccessible on all fields so they
- * can be accessed later. Create a temporary
- * ObjectStreamField array to hold each
+ /* Get all of the declared fields for this Class.
+ * Create a temporary ObjectStreamField array to hold each
* non-static, non-transient field. Then copy the
* temporary array into an array of the correct
* size once the number of fields is known.
@@ -471,7 +494,6 @@
int modifiers = fld.getModifiers();
if (!Modifier.isStatic(modifiers) &&
!Modifier.isTransient(modifiers)) {
- fld.setAccessible(true) ;
tempFields[numFields++] = new ObjectStreamField(fld);
}
}
@@ -487,7 +509,6 @@
try {
Field reflField = cl.getDeclaredField(fields[j].getName());
if (fields[j].getType() == reflField.getType()) {
- reflField.setAccessible(true);
fields[j].setField(reflField);
}
} catch (NoSuchFieldException e) {
@@ -527,8 +548,8 @@
int mods = f.getModifiers();
// SerialBug 5: static final SUID should be read
if (Modifier.isStatic(mods) && Modifier.isFinal(mods) ) {
- f.setAccessible(true);
- suid = f.getLong(cl);
+ long offset = bridge.staticFieldOffset(f);
+ suid = bridge.getLong(cl, offset);
// SerialBug 2: should be computed after writeObject
// actualSuid = computeStructuralUID(cl);
} else {
@@ -540,16 +561,12 @@
suid = _computeSerialVersionUID(cl);
// SerialBug 2: should be computed after writeObject
// actualSuid = computeStructuralUID(cl);
- } catch (IllegalAccessException ex) {
- suid = _computeSerialVersionUID(cl);
}
}
- writeReplaceObjectMethod = ObjectStreamClass.getInheritableMethod(cl,
- "writeReplace", noTypesList, Object.class);
+ writeReplaceObjectMethod = bridge.writeReplaceForSerialization(cl);
- readResolveObjectMethod = ObjectStreamClass.getInheritableMethod(cl,
- "readResolve", noTypesList, Object.class);
+ readResolveObjectMethod = bridge.readResolveForSerialization(cl);
if (externalizable)
cons = getExternalizableConstructor(cl) ;
@@ -557,14 +574,8 @@
cons = getSerializableConstructor(cl) ;
if (serializable && !forProxyClass) {
- /* Look for the writeObject method
- * Set the accessible flag on it here. ObjectOutputStream
- * will call it as necessary.
- */
- writeObjectMethod = getPrivateMethod( cl, "writeObject",
- new Class<?>[] { java.io.ObjectOutputStream.class }, Void.TYPE ) ;
- readObjectMethod = getPrivateMethod( cl, "readObject",
- new Class<?>[] { java.io.ObjectInputStream.class }, Void.TYPE ) ;
+ writeObjectMethod = bridge.writeObjectForSerialization(cl) ;
+ readObjectMethod = bridge.readObjectForSerialization(cl);
}
return null;
}
@@ -585,27 +596,6 @@
}
}
- /**
- * Returns non-static private method with given signature defined by given
- * class, or null if none found. Access checks are disabled on the
- * returned method (if any).
- */
- private static Method getPrivateMethod(Class<?> cl, String name,
- Class<?>[] argTypes,
- Class<?> returnType)
- {
- try {
- Method meth = cl.getDeclaredMethod(name, argTypes);
- meth.setAccessible(true);
- int mods = meth.getModifiers();
- return ((meth.getReturnType() == returnType) &&
- ((mods & Modifier.STATIC) == 0) &&
- ((mods & Modifier.PRIVATE) != 0)) ? meth : null;
- } catch (NoSuchMethodException ex) {
- return null;
- }
- }
-
// Specific to RMI-IIOP
/**
* Java to IDL ptc-02-01-12 1.5.1
@@ -849,6 +839,22 @@
}
/**
+ * Returns true if represented class is serializable or externalizable and
+ * defines a conformant writeReplace method. Otherwise, returns false.
+ */
+ boolean hasWriteReplaceMethod() {
+ return (writeReplaceObjectMethod != null);
+ }
+
+ /**
+ * Returns true if represented class is serializable or externalizable and
+ * defines a conformant readResolve method. Otherwise, returns false.
+ */
+ boolean hasReadResolveMethod() {
+ return (readResolveObjectMethod != null);
+ }
+
+ /**
* Returns when or not this class should be custom
* marshaled (use chunking). This should happen if
* it is Externalizable OR if it or
@@ -904,7 +910,7 @@
{
if (cons != null) {
try {
- return cons.newInstance(new Object[0]);
+ return cons.newInstance();
} catch (IllegalAccessException ex) {
// should not occur, as access checks have been suppressed
InternalError ie = new InternalError();
@@ -912,7 +918,7 @@
throw ie ;
}
} else {
- throw new UnsupportedOperationException();
+ throw new UnsupportedOperationException("no constructor for " + ofClass);
}
}
@@ -921,15 +927,8 @@
* Access checks are disabled on the returned constructor (if any), since
* the defining class may still be non-public.
*/
- private static Constructor getExternalizableConstructor(Class<?> cl) {
- try {
- Constructor cons = cl.getDeclaredConstructor(new Class<?>[0]);
- cons.setAccessible(true);
- return ((cons.getModifiers() & Modifier.PUBLIC) != 0) ?
- cons : null;
- } catch (NoSuchMethodException ex) {
- return null;
- }
+ private static Constructor<?> getExternalizableConstructor(Class<?> cl) {
+ return bridge.newConstructorForExternalization(cl);
}
/**
@@ -937,28 +936,8 @@
* superclass, or null if none found. Access checks are disabled on the
* returned constructor (if any).
*/
- private static Constructor getSerializableConstructor(Class<?> cl) {
- Class<?> initCl = cl;
- while (Serializable.class.isAssignableFrom(initCl)) {
- if ((initCl = initCl.getSuperclass()) == null) {
- return null;
- }
- }
- try {
- Constructor cons = initCl.getDeclaredConstructor(new Class<?>[0]);
- int mods = cons.getModifiers();
- if ((mods & Modifier.PRIVATE) != 0 ||
- ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
- !packageEquals(cl, initCl)))
- {
- return null;
- }
- cons = bridge.newConstructorForSerialization(cl, cons);
- cons.setAccessible(true);
- return cons;
- } catch (NoSuchMethodException ex) {
- return null;
- }
+ private static Constructor<?> getSerializableConstructor(Class<?> cl) {
+ return bridge.newConstructorForSerialization(cl);
}
/*
@@ -1522,11 +1501,11 @@
* @since JDK 1.2
*/
private boolean hasExternalizableBlockData;
- Method writeObjectMethod;
- Method readObjectMethod;
- private transient Method writeReplaceObjectMethod;
- private transient Method readResolveObjectMethod;
- private Constructor cons ;
+ private transient MethodHandle writeObjectMethod;
+ private transient MethodHandle readObjectMethod;
+ private transient MethodHandle writeReplaceObjectMethod;
+ private transient MethodHandle readResolveObjectMethod;
+ private transient Constructor<?> cons;
/**
* Beginning in Java to IDL ptc/02-01-12, RMI-IIOP has a
@@ -1543,44 +1522,12 @@
*/
private ObjectStreamClass localClassDesc;
- /* Find out if the class has a static class initializer <clinit> */
- private static Method hasStaticInitializerMethod = null;
/**
* Returns true if the given class defines a static initializer method,
* false otherwise.
*/
private static boolean hasStaticInitializer(Class<?> cl) {
- if (hasStaticInitializerMethod == null) {
- Class<?> classWithThisMethod = null;
-
- try {
- if (classWithThisMethod == null)
- classWithThisMethod = java.io.ObjectStreamClass.class;
-
- hasStaticInitializerMethod =
- classWithThisMethod.getDeclaredMethod("hasStaticInitializer",
- new Class<?>[] { Class.class });
- } catch (NoSuchMethodException ex) {
- }
-
- if (hasStaticInitializerMethod == null) {
- // XXX I18N, logging needed
- throw new InternalError("Can't find hasStaticInitializer method on "
- + classWithThisMethod.getName());
- }
- hasStaticInitializerMethod.setAccessible(true);
- }
-
- try {
- Boolean retval = (Boolean)
- hasStaticInitializerMethod.invoke(null, new Object[] { cl });
- return retval.booleanValue();
- } catch (Exception ex) {
- // XXX I18N, logging needed
- InternalError ie = new InternalError( "Error invoking hasStaticInitializer" ) ;
- ie.initCause( ex ) ;
- throw ie ;
- }
+ return bridge.hasStaticInitializerForSerialization(cl);
}
@@ -1754,7 +1701,6 @@
if ((meth == null) || (meth.getReturnType() != returnType)) {
return null;
}
- meth.setAccessible(true);
int mods = meth.getModifiers();
if ((mods & (Modifier.STATIC | Modifier.ABSTRACT)) != 0) {
return null;
--- a/corba/src/java.corba/share/classes/module-info.java Thu Oct 20 18:38:09 2016 +0000
+++ b/corba/src/java.corba/share/classes/module-info.java Wed Jul 05 22:22:15 2017 +0200
@@ -32,6 +32,7 @@
requires java.logging;
requires java.naming;
requires java.transaction;
+ requires jdk.unsupported;
exports javax.activity;
exports javax.rmi;
--- a/corba/src/java.corba/share/classes/sun/corba/Bridge.java Thu Oct 20 18:38:09 2016 +0000
+++ b/corba/src/java.corba/share/classes/sun/corba/Bridge.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2016, 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,25 +25,24 @@
package sun.corba ;
+import java.io.OptionalDataException;
+import java.lang.invoke.MethodHandle;
import java.lang.reflect.Field ;
-import java.lang.reflect.Method ;
import java.lang.reflect.Constructor ;
-import java.lang.reflect.InvocationTargetException ;
-
-import java.io.ObjectInputStream ;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
-import jdk.internal.misc.Unsafe ;
-import jdk.internal.reflect.ReflectionFactory;
+import sun.misc.Unsafe;
+import sun.reflect.ReflectionFactory;
/** This class provides the methods for fundamental JVM operations
* needed in the ORB that are not part of the public Java API. This includes:
* <ul>
* <li>throwException, which can throw undeclared checked exceptions.
- * This is needed to handle throwing arbitrary exceptions across a standardized OMG interface that (incorrectly) does not specify appropriate exceptions.</li>
+ * This is needed to handle throwing arbitrary exceptions across a standardized
+ * OMG interface that (incorrectly) does not specify appropriate exceptions.</li>
* <li>putXXX/getXXX methods that allow unchecked access to fields of objects.
* This is used for setting uninitialzed non-static final fields (which is
* impossible with reflection) and for speed.</li>
@@ -71,88 +70,28 @@
*/
public final class Bridge
{
- private static final Class[] NO_ARGS = new Class[] {};
private static final Permission getBridgePermission =
- new BridgePermission( "getBridge" ) ;
+ new BridgePermission("getBridge");
private static Bridge bridge = null ;
- // latestUserDefinedLoader() is a private static method
- // in ObjectInputStream in JDK 1.3 through 1.5.
- // We use reflection in a doPrivileged block to get a
- // Method reference and make it accessible.
- private final Method latestUserDefinedLoaderMethod ;
- private final Unsafe unsafe ;
- private final ReflectionFactory reflectionFactory ;
+ /** Access to Unsafe to read/write fields. */
+ private static final Unsafe unsafe = AccessController.doPrivileged(
+ (PrivilegedAction<Unsafe>)() -> {
+ try {
+ Field field = Unsafe.class.getDeclaredField("theUnsafe");
+ field.setAccessible(true);
+ return (Unsafe)field.get(null);
- private Method getLatestUserDefinedLoaderMethod()
- {
- return (Method) AccessController.doPrivileged(
- new PrivilegedAction()
- {
- public Object run()
- {
- Method result = null;
-
- try {
- Class io = ObjectInputStream.class;
- result = io.getDeclaredMethod(
- "latestUserDefinedLoader", NO_ARGS);
- result.setAccessible(true);
- } catch (NoSuchMethodException nsme) {
- Error err = new Error( "java.io.ObjectInputStream" +
- " latestUserDefinedLoader " + nsme );
- err.initCause(nsme) ;
- throw err ;
- }
-
- return result;
+ } catch (NoSuchFieldException |IllegalAccessException ex) {
+ throw new InternalError("Unsafe.theUnsafe field not available", ex);
}
}
- );
- }
-
- private Unsafe getUnsafe() {
- Field fld = (Field)AccessController.doPrivileged(
- new PrivilegedAction()
- {
- public Object run()
- {
- Field fld = null ;
+ ) ;
- try {
- Class unsafeClass = jdk.internal.misc.Unsafe.class ;
- fld = unsafeClass.getDeclaredField( "theUnsafe" ) ;
- fld.setAccessible( true ) ;
- return fld ;
- } catch (NoSuchFieldException exc) {
- Error err = new Error( "Could not access Unsafe" ) ;
- err.initCause( exc ) ;
- throw err ;
- }
- }
- }
- ) ;
-
- Unsafe unsafe = null;
+ private final ReflectionFactory reflectionFactory ;
- try {
- unsafe = (Unsafe)(fld.get( null )) ;
- } catch (Throwable t) {
- Error err = new Error( "Could not access Unsafe" ) ;
- err.initCause( t ) ;
- throw err ;
- }
-
- return unsafe ;
- }
-
-
- private Bridge()
- {
- latestUserDefinedLoaderMethod = getLatestUserDefinedLoaderMethod();
- unsafe = getUnsafe() ;
- reflectionFactory = (ReflectionFactory)AccessController.doPrivileged(
- new ReflectionFactory.GetReflectionFactoryAction());
+ private Bridge() {
+ reflectionFactory = ReflectionFactory.getReflectionFactory();
}
/** Fetch the Bridge singleton. This requires the following
@@ -182,23 +121,8 @@
/** Obtain the latest user defined ClassLoader from the call stack.
* This is required by the RMI-IIOP specification.
*/
- public final ClassLoader getLatestUserDefinedLoader()
- {
- try {
- // Invoke the ObjectInputStream.latestUserDefinedLoader method
- return (ClassLoader)latestUserDefinedLoaderMethod.invoke(null,
- (Object[])NO_ARGS);
- } catch (InvocationTargetException ite) {
- Error err = new Error(
- "sun.corba.Bridge.latestUserDefinedLoader: " + ite ) ;
- err.initCause( ite ) ;
- throw err ;
- } catch (IllegalAccessException iae) {
- Error err = new Error(
- "sun.corba.Bridge.latestUserDefinedLoader: " + iae ) ;
- err.initCause( iae ) ;
- throw err ;
- }
+ public final ClassLoader getLatestUserDefinedLoader() {
+ return jdk.internal.misc.VM.latestUserDefinedLoader();
}
/**
@@ -345,6 +269,23 @@
return unsafe.objectFieldOffset( f ) ;
}
+ /**
+ * Returns the offset of a static field.
+ */
+ public final long staticFieldOffset(Field f)
+ {
+ return unsafe.staticFieldOffset( f ) ;
+ }
+
+ /**
+ * Ensure that the class has been initalized.
+ * @param cl the class to ensure is initialized
+ */
+ public final void ensureClassInitialized(Class<?> cl) {
+ unsafe.ensureClassInitialized(cl);
+ }
+
+
/** Throw the exception.
* The exception may be an undeclared checked exception.
*/
@@ -353,16 +294,55 @@
unsafe.throwException( ee ) ;
}
- /** Obtain a constructor for Class cl using constructor cons which
- * may be the constructor defined in a superclass of cl. This is
- * used to create a constructor for Serializable classes that
- * constructs an instance of the Serializable class using the
+ /**
+ * Obtain a constructor for Class cl.
+ * This is used to create a constructor for Serializable classes that
+ * construct an instance of the Serializable class using the
* no args constructor of the first non-Serializable superclass
* of the Serializable class.
*/
- public final Constructor newConstructorForSerialization( Class cl,
- Constructor cons )
- {
- return reflectionFactory.newConstructorForSerialization( cl, cons ) ;
+ public final Constructor<?> newConstructorForSerialization( Class<?> cl ) {
+ return reflectionFactory.newConstructorForSerialization( cl ) ;
+ }
+
+ public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
+ return reflectionFactory.newConstructorForExternalization( cl ) ;
+ }
+
+ /**
+ * Returns true if the given class defines a static initializer method,
+ * false otherwise.
+ */
+ public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
+ return reflectionFactory.hasStaticInitializerForSerialization(cl);
+ }
+
+ public final MethodHandle writeObjectForSerialization(Class<?> cl) {
+ return reflectionFactory.writeObjectForSerialization(cl);
+ }
+
+ public final MethodHandle readObjectForSerialization(Class<?> cl) {
+ return reflectionFactory.readObjectForSerialization(cl);
}
+
+ public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
+ return reflectionFactory.readObjectNoDataForSerialization(cl);
+ }
+
+ public final MethodHandle readResolveForSerialization(Class<?> cl) {
+ return reflectionFactory.readResolveForSerialization(cl);
+ }
+
+ public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
+ return reflectionFactory.writeReplaceForSerialization(cl);
+ }
+
+ /**
+ * Return a new OptionalDataException instance.
+ * @return a new OptionalDataException instance
+ */
+ public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) {
+ return reflectionFactory.newOptionalDataExceptionForSerialization(bool);
+ }
+
}
--- a/corba/src/java.corba/share/classes/sun/corba/SharedSecrets.java Thu Oct 20 18:38:09 2016 +0000
+++ b/corba/src/java.corba/share/classes/sun/corba/SharedSecrets.java Wed Jul 05 22:22:15 2017 +0200
@@ -25,13 +25,13 @@
package sun.corba;
-import com.sun.corba.se.impl.io.ValueUtility;
-import jdk.internal.misc.Unsafe;
-
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import com.sun.corba.se.impl.io.ValueUtility;
+import sun.misc.Unsafe;
+
/** A repository of "shared secrets", which are a mechanism for
calling implementation-private methods in another package without
using reflection. A package-private class implements a public
@@ -43,22 +43,22 @@
// SharedSecrets cloned in corba repo to avoid build issues
public class SharedSecrets {
- private static final Unsafe unsafe = getUnsafe();
- private static JavaCorbaAccess javaCorbaAccess;
- private static Unsafe getUnsafe() {
- PrivilegedAction<Unsafe> pa = () -> {
- Class<?> unsafeClass = jdk.internal.misc.Unsafe.class ;
- try {
- Field f = unsafeClass.getDeclaredField("theUnsafe");
- f.setAccessible(true);
- return (Unsafe) f.get(null);
- } catch (Exception e) {
- throw new Error(e);
- }
- };
- return AccessController.doPrivileged(pa);
- }
+ /** Access to Unsafe to read/write fields. */
+ private static final Unsafe unsafe = AccessController.doPrivileged(
+ (PrivilegedAction<Unsafe>)() -> {
+ try {
+ Field field = Unsafe.class.getDeclaredField("theUnsafe");
+ field.setAccessible(true);
+ return (Unsafe)field.get(null);
+
+ } catch (NoSuchFieldException |IllegalAccessException ex) {
+ throw new InternalError("Unsafe.theUnsafe field not available", ex);
+ }
+ }
+ );
+
+ private static JavaCorbaAccess javaCorbaAccess;
public static JavaCorbaAccess getJavaCorbaAccess() {
if (javaCorbaAccess == null) {
--- a/hotspot/.hgtags Thu Oct 20 18:38:09 2016 +0000
+++ b/hotspot/.hgtags Wed Jul 05 22:22:15 2017 +0200
@@ -543,3 +543,4 @@
fc0956308c7a586267c5dd35dff74f773aa9c3eb jdk-9+138
08492e67bf3226784dab3bf9ae967382ddbc1af5 jdk-9+139
fec31089c2ef5a12dd64f401b0bf2e00f56ee0d0 jdk-9+140
+160a00bc6ed0af1fdf8418fc65e6bddbbc0c536d jdk-9+141
--- a/hotspot/src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/hotspot/src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -1894,6 +1894,22 @@
__ beq(combined_check, slow);
}
+ if (flags & LIR_OpArrayCopy::type_check) {
+ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::dst_objarray)) {
+ __ load_klass(tmp, dst);
+ __ lwz(tmp2, in_bytes(Klass::layout_helper_offset()), tmp);
+ __ cmpwi(CCR0, tmp2, Klass::_lh_neutral_value);
+ __ bge(CCR0, slow);
+ }
+
+ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::src_objarray)) {
+ __ load_klass(tmp, src);
+ __ lwz(tmp2, in_bytes(Klass::layout_helper_offset()), tmp);
+ __ cmpwi(CCR0, tmp2, Klass::_lh_neutral_value);
+ __ bge(CCR0, slow);
+ }
+ }
+
// Higher 32bits must be null.
__ extsw(length, length);
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -2034,6 +2034,27 @@
__ delayed()->nop();
}
+ // If the compiler was not able to prove that exact type of the source or the destination
+ // of the arraycopy is an array type, check at runtime if the source or the destination is
+ // an instance type.
+ if (flags & LIR_OpArrayCopy::type_check) {
+ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::dst_objarray)) {
+ __ load_klass(dst, tmp);
+ __ lduw(tmp, in_bytes(Klass::layout_helper_offset()), tmp2);
+ __ cmp(tmp2, Klass::_lh_neutral_value);
+ __ br(Assembler::greaterEqual, false, Assembler::pn, *stub->entry());
+ __ delayed()->nop();
+ }
+
+ if (!(flags & LIR_OpArrayCopy::LIR_OpArrayCopy::src_objarray)) {
+ __ load_klass(src, tmp);
+ __ lduw(tmp, in_bytes(Klass::layout_helper_offset()), tmp2);
+ __ cmp(tmp2, Klass::_lh_neutral_value);
+ __ br(Assembler::greaterEqual, false, Assembler::pn, *stub->entry());
+ __ delayed()->nop();
+ }
+ }
+
if (flags & LIR_OpArrayCopy::src_pos_positive_check) {
// test src_pos register
__ cmp_zero_and_br(Assembler::less, src_pos, *stub->entry());
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -3146,6 +3146,23 @@
__ jcc(Assembler::zero, *stub->entry());
}
+ // If the compiler was not able to prove that exact type of the source or the destination
+ // of the arraycopy is an array type, check at runtime if the source or the destination is
+ // an instance type.
+ if (flags & LIR_OpArrayCopy::type_check) {
+ if (!(flags & LIR_OpArrayCopy::dst_objarray)) {
+ __ load_klass(tmp, dst);
+ __ cmpl(Address(tmp, in_bytes(Klass::layout_helper_offset())), Klass::_lh_neutral_value);
+ __ jcc(Assembler::greaterEqual, *stub->entry());
+ }
+
+ if (!(flags & LIR_OpArrayCopy::src_objarray)) {
+ __ load_klass(tmp, src);
+ __ cmpl(Address(tmp, in_bytes(Klass::layout_helper_offset())), Klass::_lh_neutral_value);
+ __ jcc(Assembler::greaterEqual, *stub->entry());
+ }
+ }
+
// check if negative
if (flags & LIR_OpArrayCopy::src_pos_positive_check) {
__ testl(src_pos, src_pos);
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -5859,6 +5859,11 @@
assert(cp != NULL, "invariant");
assert(_loader_data != NULL, "invariant");
+ if (_class_name == vmSymbols::java_lang_Object()) {
+ check_property(_local_interfaces == Universe::the_empty_klass_array(),
+ "java.lang.Object cannot implement an interface in class file %s",
+ CHECK);
+ }
// We check super class after class file is parsed and format is checked
if (_super_class_index > 0 && NULL ==_super_klass) {
Symbol* const super_class_name = cp->klass_name_at(_super_class_index);
--- a/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp Thu Oct 20 18:38:09 2016 +0000
+++ b/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, 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
@@ -203,6 +203,7 @@
inline bool verify(address start, address end) const;
inline void print_on(outputStream* st, int current_offset) const;
+ inline void print_truncated(outputStream* st, int current_offset) const;
// Create as_xxx and is_xxx methods for the subtypes
#define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \
@@ -263,6 +264,10 @@
void print_on(outputStream* st, int current_offset = -1) const {
st->print("same_frame(@%d)", offset_delta() + current_offset);
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ print_on(st, current_offset);
+ }
};
class same_frame_extended : public stack_map_frame {
@@ -309,6 +314,10 @@
void print_on(outputStream* st, int current_offset = -1) const {
st->print("same_frame_extended(@%d)", offset_delta() + current_offset);
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ print_on(st, current_offset);
+ }
};
class same_locals_1_stack_item_frame : public stack_map_frame {
@@ -381,6 +390,11 @@
types()->print_on(st);
st->print(")");
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ st->print("same_locals_1_stack_item_frame(@%d), output truncated, Stackmap exceeds table size.",
+ offset_delta() + current_offset);
+ }
};
class same_locals_1_stack_item_extended : public stack_map_frame {
@@ -446,6 +460,11 @@
types()->print_on(st);
st->print(")");
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ st->print("same_locals_1_stack_item_extended(@%d), output truncated, Stackmap exceeds table size.",
+ offset_delta() + current_offset);
+ }
};
class chop_frame : public stack_map_frame {
@@ -511,6 +530,10 @@
void print_on(outputStream* st, int current_offset = -1) const {
st->print("chop_frame(@%d,%d)", offset_delta() + current_offset, chops());
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ print_on(st, current_offset);
+ }
};
class append_frame : public stack_map_frame {
@@ -619,6 +642,11 @@
}
st->print(")");
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ st->print("append_frame(@%d), output truncated, Stackmap exceeds table size.",
+ offset_delta() + current_offset);
+ }
};
class full_frame : public stack_map_frame {
@@ -784,6 +812,11 @@
}
st->print("})");
}
+
+ void print_truncated(outputStream* st, int current_offset = -1) const {
+ st->print("full_frame(@%d), output truncated, Stackmap exceeds table size.",
+ offset_delta() + current_offset);
+ }
};
#define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
@@ -841,6 +874,10 @@
FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st, offs));
}
+void stack_map_frame::print_truncated(outputStream* st, int offs = -1) const {
+ FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_truncated, (st, offs));
+}
+
#undef VIRTUAL_DISPATCH
#undef VOID_VIRTUAL_DISPATCH
--- a/hotspot/src/share/vm/classfile/verifier.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -541,8 +541,19 @@
stack_map_frame* sm_frame = sm_table->entries();
streamIndentor si2(ss);
int current_offset = -1;
+ // Subtract two from StackMapAttribute length because the length includes
+ // two bytes for number of table entries.
+ size_t sm_table_space = method->stackmap_data()->length() - 2;
for (u2 i = 0; i < sm_table->number_of_entries(); ++i) {
ss->indent();
+ size_t sm_frame_size = sm_frame->size();
+ // If the size of the next stackmap exceeds the length of the entire
+ // stackmap table then print a truncated message and return.
+ if (sm_frame_size > sm_table_space) {
+ sm_frame->print_truncated(ss, current_offset);
+ return;
+ }
+ sm_table_space -= sm_frame_size;
sm_frame->print_on(ss, current_offset);
ss->cr();
current_offset += sm_frame->offset_delta();
--- a/hotspot/src/share/vm/prims/jvm.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/hotspot/src/share/vm/prims/jvm.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -2524,7 +2524,6 @@
switch (cp->tag_at(cp_index).value()) {
case JVM_CONSTANT_InterfaceMethodref:
case JVM_CONSTANT_Methodref:
- case JVM_CONSTANT_NameAndType: // for invokedynamic
return cp->uncached_name_ref_at(cp_index)->as_utf8();
default:
fatal("JVM_GetCPMethodNameUTF: illegal constant");
@@ -2542,7 +2541,6 @@
switch (cp->tag_at(cp_index).value()) {
case JVM_CONSTANT_InterfaceMethodref:
case JVM_CONSTANT_Methodref:
- case JVM_CONSTANT_NameAndType: // for invokedynamic
return cp->uncached_signature_ref_at(cp_index)->as_utf8();
default:
fatal("JVM_GetCPMethodSignatureUTF: illegal constant");
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -794,9 +794,10 @@
} else if (new_len == 0) {
value = old_value;
} else {
- char* buf = NEW_C_HEAP_ARRAY(char, old_len + 1 + new_len + 1, mtArguments);
+ size_t length = old_len + 1 + new_len + 1;
+ char* buf = NEW_C_HEAP_ARRAY(char, length, mtArguments);
// each new setting adds another LINE to the switch:
- sprintf(buf, "%s\n%s", old_value, new_value);
+ jio_snprintf(buf, length, "%s\n%s", old_value, new_value);
value = buf;
free_this_too = buf;
}
@@ -1014,15 +1015,17 @@
if (args == NULL || count == 0) {
return NULL;
}
- size_t length = strlen(args[0]) + 1; // add 1 for the null terminator
- for (int i = 1; i < count; i++) {
- length += strlen(args[i]) + 1; // add 1 for a space
+ size_t length = 0;
+ for (int i = 0; i < count; i++) {
+ length += strlen(args[i]) + 1; // add 1 for a space or NULL terminating character
}
char* s = NEW_RESOURCE_ARRAY(char, length);
- strcpy(s, args[0]);
- for (int j = 1; j < count; j++) {
- strcat(s, " ");
- strcat(s, args[j]);
+ char* dst = s;
+ for (int j = 0; j < count; j++) {
+ size_t offset = strlen(args[j]) + 1; // add 1 for a space or NULL terminating character
+ jio_snprintf(dst, length, "%s ", args[j]); // jio_snprintf will replace the last space character with NULL character
+ dst += offset;
+ length -= offset;
}
return (const char*) s;
}
@@ -1106,9 +1109,8 @@
// Only make the obsolete check for valid arguments.
if (arg_len <= BUFLEN) {
// Construct a string which consists only of the argument name without '+', '-', or '='.
- char stripped_argname[BUFLEN+1];
- strncpy(stripped_argname, argname, arg_len);
- stripped_argname[arg_len] = '\0'; // strncpy may not null terminate.
+ char stripped_argname[BUFLEN+1]; // +1 for '\0'
+ jio_snprintf(stripped_argname, arg_len+1, "%s", argname); // +1 for '\0'
if (is_obsolete_flag(stripped_argname, &since)) {
char version[256];
since.to_string(version, sizeof(version));
@@ -1260,8 +1262,7 @@
size_t key_len = eq - prop;
char* tmp_key = AllocateHeap(key_len + 1, mtArguments);
- strncpy(tmp_key, prop, key_len);
- tmp_key[key_len] = '\0';
+ jio_snprintf(tmp_key, key_len + 1, "%s", prop);
key = tmp_key;
value = &prop[key_len + 1];
@@ -2256,7 +2257,7 @@
// Feed the cache size setting into the JDK
char buffer[1024];
- sprintf(buffer, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax);
+ jio_snprintf(buffer, 1024, "java.lang.Integer.IntegerCache.high=" INTX_FORMAT, AutoBoxCacheMax);
if (!add_property(buffer)) {
return JNI_ENOMEM;
}
@@ -2777,8 +2778,8 @@
if (tail != NULL) {
const char* pos = strchr(tail, ':');
size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
- char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtArguments), tail, len);
- name[len] = '\0';
+ char* name = NEW_C_HEAP_ARRAY(char, len + 1, mtArguments);
+ jio_snprintf(name, len + 1, "%s", tail);
char *options = NULL;
if(pos != NULL) {
@@ -2854,7 +2855,9 @@
return JNI_ERR;
#else
if (tail != NULL) {
- char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtArguments), tail);
+ size_t length = strlen(tail) + 1;
+ char *options = NEW_C_HEAP_ARRAY(char, length, mtArguments);
+ jio_snprintf(options, length, "%s", tail);
add_init_agent("instrument", options, false);
// java agents need module java.instrument
if (!create_numbered_property("jdk.module.addmods", "java.instrument", addmods_count++)) {
@@ -3512,7 +3515,7 @@
// check if the default lib/endorsed directory exists; if so, error
char path[JVM_MAXPATHLEN];
const char* fileSep = os::file_separator();
- sprintf(path, "%s%slib%sendorsed", Arguments::get_java_home(), fileSep, fileSep);
+ jio_snprintf(path, JVM_MAXPATHLEN, "%s%slib%sendorsed", Arguments::get_java_home(), fileSep, fileSep);
if (CheckEndorsedAndExtDirs) {
int nonEmptyDirs = 0;
@@ -3534,7 +3537,7 @@
return JNI_ERR;
}
- sprintf(path, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep);
+ jio_snprintf(path, JVM_MAXPATHLEN, "%s%slib%sext", Arguments::get_java_home(), fileSep, fileSep);
dir = os::opendir(path);
if (dir != NULL) {
jio_fprintf(defaultStream::output_stream(),
@@ -3899,6 +3902,13 @@
void Arguments::set_shared_spaces_flags() {
if (DumpSharedSpaces) {
+ if (FailOverToOldVerifier) {
+ // Don't fall back to the old verifier on verification failure. If a
+ // class fails verification with the split verifier, it might fail the
+ // CDS runtime verifier constraint check. In that case, we don't want
+ // to share the class. We only archive classes that pass the split verifier.
+ FLAG_SET_DEFAULT(FailOverToOldVerifier, false);
+ }
if (RequireSharedSpaces) {
warning("Cannot dump shared archive while using shared archive");
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -2881,8 +2881,6 @@
char *s = sig->as_C_string();
int len = (int)strlen(s);
s++; len--; // Skip opening paren
- char *t = s+len;
- while (*(--t) != ')'); // Find close paren
BasicType *sig_bt = NEW_RESOURCE_ARRAY(BasicType, 256);
VMRegPair *regs = NEW_RESOURCE_ARRAY(VMRegPair, 256);
@@ -2891,7 +2889,7 @@
sig_bt[cnt++] = T_OBJECT; // Receiver is argument 0; not in signature
}
- while (s < t) {
+ while (*s != ')') { // Find closing right paren
switch (*s++) { // Switch on signature character
case 'B': sig_bt[cnt++] = T_BYTE; break;
case 'C': sig_bt[cnt++] = T_CHAR; break;
--- a/hotspot/src/share/vm/runtime/signature.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/hotspot/src/share/vm/runtime/signature.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -224,7 +224,49 @@
_index = 0;
expect('(');
Symbol* sig = _signature;
- while (sig->byte_at(_index) != ')') _index++;
+ // Need to skip over each type in the signature's argument list until a
+ // closing ')' is found., then get the return type. We cannot just scan
+ // for the first ')' because ')' is a legal character in a type name.
+ while (sig->byte_at(_index) != ')') {
+ switch(sig->byte_at(_index)) {
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'I':
+ case 'J':
+ case 'S':
+ case 'Z':
+ case 'V':
+ {
+ _index++;
+ }
+ break;
+ case 'L':
+ {
+ while (sig->byte_at(_index++) != ';') ;
+ }
+ break;
+ case '[':
+ {
+ int begin = ++_index;
+ skip_optional_size();
+ while (sig->byte_at(_index) == '[') {
+ _index++;
+ skip_optional_size();
+ }
+ if (sig->byte_at(_index) == 'L') {
+ while (sig->byte_at(_index++) != ';') ;
+ } else {
+ _index++;
+ }
+ }
+ break;
+ default:
+ ShouldNotReachHere();
+ break;
+ }
+ }
expect(')');
// Parse return type
_parameter_index = -1;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/c1/TestArrayCopyToFromObject.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8160591
+ * @summary C1-generated code for System.arraycopy() does not throw an ArrayStoreException if 'dst' is no a "proper" array (i.e., it is java.lang.Object)
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xcomp -XX:-UseCompressedClassPointers -XX:CompileOnly=TestArrayCopyToFromObject.test TestArrayCopyToFromObject
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -Xcomp -XX:+UseCompressedClassPointers -XX:CompileOnly=TestArrayCopyToFromObject.test TestArrayCopyToFromObject
+ */
+public class TestArrayCopyToFromObject {
+
+ public void test(Object aArray[]) {
+ Object a = new Object();
+
+ try {
+ System.arraycopy(aArray, 0, a, 0, 1);
+ throw new RuntimeException ("FAILED: Expected ArrayStoreException " +
+ "(due to destination not being an array) " +
+ "was not thrown");
+ } catch (ArrayStoreException e) {
+ System.out.println("PASSED: Expected ArrayStoreException was thrown");
+ }
+
+ try {
+ System.arraycopy(a, 0, aArray, 0, 1);
+ throw new RuntimeException ("FAILED: Expected ArrayStoreException " +
+ "(due to source not being an array) " +
+ "was not thrown");
+ } catch (ArrayStoreException e) {
+ System.out.println("PASSED: Expected ArrayStoreException was thrown");
+ }
+
+ }
+
+ public static void main(String args[]) {
+ System.out.println("TestArrayCopyToFromObject");
+ Object aArray[] = new Object[10];
+ for (int i = 0; i < 10; i++) {
+ aArray[i] = new Object();
+ }
+ new TestArrayCopyToFromObject().test(aArray);
+ }
+}
--- a/jaxp/.hgtags Thu Oct 20 18:38:09 2016 +0000
+++ b/jaxp/.hgtags Wed Jul 05 22:22:15 2017 +0200
@@ -383,3 +383,4 @@
69c3b12ba75b2e321dee731ac545e7fbff608451 jdk-9+138
8991d71c5316bde259e6a417c1199b008ca3cdf0 jdk-9+139
8d100cb9b04819b5bd09f33c7fd5b8628d1a456f jdk-9+140
+037c095ba0c345edbeaaab52fda913a76c3930c0 jdk-9+141
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Stylesheet.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Stylesheet.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -31,6 +31,7 @@
import com.sun.org.apache.bcel.internal.generic.GETSTATIC;
import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE;
import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL;
+import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC;
import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL;
import com.sun.org.apache.bcel.internal.generic.ISTORE;
import com.sun.org.apache.bcel.internal.generic.InstructionHandle;
@@ -1252,6 +1253,10 @@
classGen.getConstantPool());
transf.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException");
+ // call resetPrefixIndex at the beginning of transform
+ final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "resetPrefixIndex", "()V");
+ il.append(new INVOKESTATIC(check));
+
// Define and initialize current with the root node
final LocalVariableGen current =
transf.addLocalVariable("current",
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -31,6 +31,7 @@
import java.text.NumberFormat;
import java.util.Locale;
import java.util.ResourceBundle;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.transform.dom.DOMSource;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
@@ -1533,16 +1534,25 @@
}
/**
- * This function is used in the execution of xsl:element
+ * These functions are used in the execution of xsl:element to generate
+ * and reset namespace prefix index local to current transformation process
*/
- private static int prefixIndex = 0;
-
public static String generatePrefix() {
- synchronized (BasisLibrary.class) {
- return ("ns" + prefixIndex++);
- }
+ return ("ns" + threadLocalPrefixIndex.get().getAndIncrement());
+ }
+
+ public static void resetPrefixIndex() {
+ threadLocalPrefixIndex.get().set(0);
}
+ private static final ThreadLocal<AtomicInteger> threadLocalPrefixIndex =
+ new ThreadLocal<AtomicInteger>() {
+ @Override
+ protected AtomicInteger initialValue() {
+ return new AtomicInteger();
+ }
+ };
+
public static final String RUN_TIME_INTERNAL_ERR =
"RUN_TIME_INTERNAL_ERR";
public static final String RUN_TIME_COPY_ERR =
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/NamespacePrefixTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+package transform;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertTrue;
+import static jaxp.library.JAXPTestUtilities.runWithAllPerm;
+
+/*
+ * @test
+ * @bug 8167179
+ * @library /javax/xml/jaxp/libs
+ * @run testng/othervm -DrunSecMngr=true transform.NamespacePrefixTest
+ * @run testng/othervm transform.NamespacePrefixTest
+ * @summary This class tests the generation of namespace prefixes
+ */
+public class NamespacePrefixTest {
+
+ @Test
+ public void testReuseTemplates() throws Exception {
+ final TransformerFactory tf = TransformerFactory.newInstance();
+ final Source xslsrc = new StreamSource(new StringReader(XSL));
+ final Templates tmpl = tf.newTemplates(xslsrc);
+ for (int i = 0; i < TRANSF_COUNT; i++) {
+ checkResult(doTransformation(tmpl.newTransformer()));
+ }
+ }
+
+ @Test
+ public void testReuseTransformer() throws Exception {
+ final TransformerFactory tf = TransformerFactory.newInstance();
+ final Source xslsrc = new StreamSource(new StringReader(XSL));
+ final Transformer t = tf.newTransformer(xslsrc);
+ for (int i = 0; i < TRANSF_COUNT; i++) {
+ checkResult(doTransformation(t));
+ }
+ }
+
+ @Test
+ public void testConcurrentTransformations() throws Exception {
+ final TransformerFactory tf = TransformerFactory.newInstance();
+ final Source xslsrc = new StreamSource(new StringReader(XSL));
+ final Templates tmpl = tf.newTemplates(xslsrc);
+ concurrentTestPassed.set(true);
+
+ // Execute multiple TestWorker tasks
+ for (int id = 0; id < THREADS_COUNT; id++) {
+ EXECUTOR.execute(new TransformerThread(tmpl.newTransformer(), id));
+ }
+ // Initiate shutdown of previously submitted task
+ runWithAllPerm(EXECUTOR::shutdown);
+ // Wait for termination of submitted tasks
+ if (!EXECUTOR.awaitTermination(THREADS_COUNT, TimeUnit.SECONDS)) {
+ // If not all tasks terminates during the time out force them to shutdown
+ runWithAllPerm(EXECUTOR::shutdownNow);
+ }
+ // Check if all transformation threads generated the correct namespace prefix
+ assertTrue(concurrentTestPassed.get());
+ }
+
+ // Do one transformation with the provided transformer
+ private static String doTransformation(Transformer t) throws Exception {
+ StringWriter resWriter = new StringWriter();
+ Source xmlSrc = new StreamSource(new StringReader(XML));
+ t.transform(xmlSrc, new StreamResult(resWriter));
+ return resWriter.toString();
+ }
+
+ // Check if the transformation result string contains the
+ // element with the exact namespace prefix generated.
+ private static void checkResult(String result) {
+ // Check prefix of 'Element2' element, it should always be the same
+ assertTrue(result.contains(EXPECTED_CONTENT));
+ }
+
+ // Check if the transformation result string contains the element with
+ // the exact namespace prefix generated by current thread.
+ // If the expected prefix is not found and there was no failures observed by
+ // other test threads then mark concurrent test as failed.
+ private static void checkThreadResult(String result, int id) {
+ boolean res = result.contains(EXPECTED_CONTENT);
+ System.out.printf("%d: transformation result: %s%n", id, res ? "Pass" : "Fail");
+ if (!res) {
+ System.out.printf("%d result:%s%n", id, result);
+ }
+ concurrentTestPassed.compareAndSet(true, res);
+ }
+
+ // TransformerThread task that does the transformation similar
+ // to testReuseTransformer test method
+ private class TransformerThread implements Runnable {
+
+ private final Transformer transformer;
+ private final int id;
+
+ TransformerThread(Transformer transformer, int id) {
+ this.transformer = transformer;
+ this.id = id;
+ }
+
+ @Override
+ public void run() {
+ try {
+ System.out.printf("%d: waiting for barrier%n", id);
+ //Synchronize startup of all tasks
+ BARRIER.await();
+ System.out.printf("%d: starting transformation%n", id);
+ checkThreadResult(doTransformation(transformer), id);
+ } catch (Exception ex) {
+ throw new RuntimeException("TransformerThread " + id + " failed", ex);
+ }
+ }
+ }
+
+ // Number of subsequent transformations
+ private static final int TRANSF_COUNT = 10;
+
+ // Number of transformer threads running concurently
+ private static final int THREADS_COUNT = 10;
+
+ // Variable for storing the concurrent transformation test result. It is
+ // updated by transformer threads
+ private static final AtomicBoolean concurrentTestPassed = new AtomicBoolean(true);
+
+ // Cyclic barrier for threads startup synchronization
+ private static final CyclicBarrier BARRIER = new CyclicBarrier(THREADS_COUNT);
+
+ // Thread pool
+ private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool();
+
+ // XSL that transforms XML and produces unique namespace prefixes for each element
+ private final static String XSL = "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n"
+ + " <xsl:template match=\"node()|@*\" priority=\"1\">\n"
+ + " <xsl:copy>\n"
+ + " <xsl:apply-templates select=\"node()|@*\"/>\n"
+ + " </xsl:copy>\n"
+ + " </xsl:template>\n"
+ + " <xsl:template match=\"*\" priority=\"2\">\n"
+ + " <xsl:element name=\"{name()}\" namespace=\"{namespace-uri()}\">\n"
+ + " <xsl:apply-templates select=\"node()|@*\"/>\n"
+ + " </xsl:element>\n"
+ + " </xsl:template>\n"
+ + "</xsl:stylesheet>";
+
+ // Simple XML content with root and two child elements
+ private final static String XML = "<TestRoot xmlns=\"test.xmlns\">\n"
+ + " <Element1 xmlns=\"test.xmlns\">\n"
+ + " </Element1>\n"
+ + " <Element2 xmlns=\"test.xmlns\">\n"
+ + " </Element2>\n"
+ + "</TestRoot>";
+
+ // With thread local namespace prefix index each transformation result should
+ // be the same and contain the same prefix for Element2
+ private final static String EXPECTED_CONTENT = "</ns2:Element2>";
+
+}
--- a/jdk/.hgtags Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/.hgtags Wed Jul 05 22:22:15 2017 +0200
@@ -383,3 +383,4 @@
665096863382bf23ce891307cf2a7511e77c1c88 jdk-9+138
5518ac2f2ead5e594bd983f2047178136aafdfd0 jdk-9+139
e93b7ea559759f036c9f69fd2ddaf47bb4e98385 jdk-9+140
+8d752af5f61d41f226adf2cda72a20faa9ad620a jdk-9+141
--- a/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/io/ObjectStreamClass.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -1413,27 +1413,7 @@
* returned constructor (if any).
*/
private static Constructor<?> getSerializableConstructor(Class<?> cl) {
- Class<?> initCl = cl;
- while (Serializable.class.isAssignableFrom(initCl)) {
- if ((initCl = initCl.getSuperclass()) == null) {
- return null;
- }
- }
- try {
- Constructor<?> cons = initCl.getDeclaredConstructor((Class<?>[]) null);
- int mods = cons.getModifiers();
- if ((mods & Modifier.PRIVATE) != 0 ||
- ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
- !packageEquals(cl, initCl)))
- {
- return null;
- }
- cons = reflFactory.newConstructorForSerialization(cl, cons);
- cons.setAccessible(true);
- return cons;
- } catch (NoSuchMethodException ex) {
- return null;
- }
+ return reflFactory.newConstructorForSerialization(cl);
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Wed Jul 05 22:22:15 2017 +0200
@@ -557,7 +557,7 @@
Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
int modifiers = tmpConstructor.getModifiers();
- Reflection.ensureMemberAccess(caller, this, null, modifiers);
+ Reflection.ensureMemberAccess(caller, this, this, modifiers);
newInstanceCallerCache = caller;
}
// Run constructor
--- a/jdk/src/java.base/share/classes/java/lang/Deprecated.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/Deprecated.java Wed Jul 05 22:22:15 2017 +0200
@@ -79,7 +79,7 @@
/**
* Returns the version in which the annotated element became deprecated.
* The version string is in the same format and namespace as the value of
- * the {@code @since} javadoc tag. The default value is the empty
+ * the {@code @since} javadoc tag. The default value is the empty
* string.
*
* @return the version string
--- a/jdk/src/java.base/share/classes/java/lang/Thread.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/Thread.java Wed Jul 05 22:22:15 2017 +0200
@@ -504,11 +504,12 @@
}
/**
- * Creates a new Thread that inherits the given AccessControlContext.
+ * Creates a new Thread that inherits the given AccessControlContext
+ * but thread-local variables are not inherited.
* This is not a public constructor.
*/
Thread(Runnable target, AccessControlContext acc) {
- init(null, target, "Thread-" + nextThreadNum(), 0, acc, true);
+ init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java Wed Jul 05 22:22:15 2017 +0200
@@ -44,6 +44,8 @@
import jdk.internal.jimage.ImageLocation;
import jdk.internal.jimage.ImageReader;
import jdk.internal.jimage.ImageReaderFactory;
+import jdk.internal.misc.JavaNetUriAccess;
+import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.ModuleHashes;
import jdk.internal.module.ModuleHashes.HashSupplier;
import jdk.internal.module.SystemModules;
@@ -71,6 +73,8 @@
// ImageReader used to access all modules in the image
private static final ImageReader imageReader;
+ private static final JavaNetUriAccess jnua = SharedSecrets.getJavaNetUriAccess();
+
// the set of modules in the run-time image
private static final Set<ModuleReference> modules;
@@ -166,7 +170,8 @@
HashSupplier hash)
{
String mn = md.name();
- URI uri = URI.create("jrt:/" + mn);
+
+ URI uri = jnua.create("jrt", "/".concat(mn));
Supplier<ModuleReader> readerSupplier = new Supplier<>() {
@Override
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Wed Jul 05 22:22:15 2017 +0200
@@ -312,22 +312,22 @@
// (See also Class.newInstance(), which uses a similar method.)
//
// A more complicated security check cache is needed for Method and Field
- // The cache can be either null (empty cache), a 2-array of {caller,target},
- // or a caller (with target implicitly equal to this.clazz).
- // In the 2-array case, the target is always different from the clazz.
+ // The cache can be either null (empty cache), a 2-array of {caller,targetClass},
+ // or a caller (with targetClass implicitly equal to memberClass).
+ // In the 2-array case, the targetClass is always different from the memberClass.
volatile Object securityCheckCache;
- void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers)
+ final void checkAccess(Class<?> caller, Class<?> memberClass,
+ Class<?> targetClass, int modifiers)
throws IllegalAccessException
{
- if (caller == clazz) { // quick check
+ if (caller == memberClass) { // quick check
return; // ACCESS IS OK
}
Object cache = securityCheckCache; // read volatile
- Class<?> targetClass = clazz;
- if (obj != null
+ if (targetClass != null // instance member or constructor
&& Modifier.isProtected(modifiers)
- && ((targetClass = obj.getClass()) != clazz)) {
+ && targetClass != memberClass) {
// Must match a 2-list of { caller, targetClass }.
if (cache instanceof Class[]) {
Class<?>[] cache2 = (Class<?>[]) cache;
@@ -339,25 +339,27 @@
// subsumes range check for [0].)
}
} else if (cache == caller) {
- // Non-protected case (or obj.class == this.clazz).
+ // Non-protected case (or targetClass == memberClass or static member).
return; // ACCESS IS OK
}
// If no return, fall through to the slow path.
- slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);
+ slowCheckMemberAccess(caller, memberClass, targetClass, modifiers);
}
// Keep all this slow stuff out of line:
- void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers,
- Class<?> targetClass)
+ void slowCheckMemberAccess(Class<?> caller, Class<?> memberClass,
+ Class<?> targetClass, int modifiers)
throws IllegalAccessException
{
- Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
+ Reflection.ensureMemberAccess(caller, memberClass, targetClass, modifiers);
// Success: Update the cache.
- Object cache = ((targetClass == clazz)
- ? caller
- : new Class<?>[] { caller, targetClass });
+ Object cache = (targetClass != null
+ && Modifier.isProtected(modifiers)
+ && targetClass != memberClass)
+ ? new Class<?>[] { caller, targetClass }
+ : caller;
// Note: The two cache elements are not volatile,
// but they are effectively final. The Java memory model
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java Wed Jul 05 22:22:15 2017 +0200
@@ -443,7 +443,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, null, modifiers);
+ checkAccess(caller, clazz, clazz, modifiers);
}
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Wed Jul 05 22:22:15 2017 +0200
@@ -403,7 +403,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).get(obj);
}
@@ -437,7 +437,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getBoolean(obj);
}
@@ -471,7 +471,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getByte(obj);
}
@@ -507,7 +507,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getChar(obj);
}
@@ -543,7 +543,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getShort(obj);
}
@@ -579,7 +579,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getInt(obj);
}
@@ -615,7 +615,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getLong(obj);
}
@@ -651,7 +651,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getFloat(obj);
}
@@ -687,7 +687,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getDouble(obj);
}
@@ -765,7 +765,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).set(obj, value);
}
@@ -801,7 +801,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setBoolean(obj, z);
}
@@ -837,7 +837,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setByte(obj, b);
}
@@ -873,7 +873,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setChar(obj, c);
}
@@ -909,7 +909,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setShort(obj, s);
}
@@ -945,7 +945,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setInt(obj, i);
}
@@ -981,7 +981,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setLong(obj, l);
}
@@ -1017,7 +1017,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setFloat(obj, f);
}
@@ -1053,11 +1053,20 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setDouble(obj, d);
}
+ // check access to field
+ private void checkAccess(Class<?> caller, Object obj)
+ throws IllegalAccessException
+ {
+ checkAccess(caller, clazz,
+ Modifier.isStatic(modifiers) ? null : obj.getClass(),
+ modifiers);
+ }
+
// security check is done before calling this method
private FieldAccessor getFieldAccessor(Object obj)
throws IllegalAccessException
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Wed Jul 05 22:22:15 2017 +0200
@@ -526,7 +526,9 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, clazz,
+ Modifier.isStatic(modifiers) ? null : obj.getClass(),
+ modifiers);
}
MethodAccessor ma = methodAccessor; // read volatile
if (ma == null) {
--- a/jdk/src/java.base/share/classes/java/net/InetAddress.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/net/InetAddress.java Wed Jul 05 22:22:15 2017 +0200
@@ -321,6 +321,13 @@
public String getOriginalHostName(InetAddress ia) {
return ia.holder.getOriginalHostName();
}
+
+ public InetAddress getByName(String hostName,
+ InetAddress hostAddress)
+ throws UnknownHostException
+ {
+ return InetAddress.getByName(hostName, hostAddress);
+ }
}
);
init();
--- a/jdk/src/java.base/share/classes/java/net/URI.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/net/URI.java Wed Jul 05 22:22:15 2017 +0200
@@ -37,6 +37,9 @@
import java.nio.charset.CodingErrorAction;
import java.nio.charset.CharacterCodingException;
import java.text.Normalizer;
+import jdk.internal.loader.URLClassPath;
+import jdk.internal.misc.JavaNetUriAccess;
+import jdk.internal.misc.SharedSecrets;
import sun.nio.cs.ThreadLocalCoders;
import java.lang.Character; // for javadoc
@@ -820,6 +823,25 @@
}
/**
+ * Constructs a simple URI consisting of only a scheme and a pre-validated
+ * path. Provides a fast-path for some internal cases.
+ */
+ URI(String scheme, String path) {
+ assert validSchemeAndPath(scheme, path);
+ this.scheme = scheme;
+ this.path = path;
+ }
+
+ private static boolean validSchemeAndPath(String scheme, String path) {
+ try {
+ URI u = new URI(scheme + ":" + path);
+ return scheme.equals(u.scheme) && path.equals(u.path);
+ } catch (URISyntaxException e) {
+ return false;
+ }
+ }
+
+ /**
* Creates a URI by parsing the given string.
*
* <p> This convenience factory method works as if by invoking the {@link
@@ -3571,5 +3593,13 @@
}
}
-
+ static {
+ SharedSecrets.setJavaNetUriAccess(
+ new JavaNetUriAccess() {
+ public URI create(String scheme, String path) {
+ return new URI(scheme, path);
+ }
+ }
+ );
+ }
}
--- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -51,7 +51,7 @@
import jdk.internal.loader.Resource;
import jdk.internal.loader.URLClassPath;
-import jdk.internal.misc.JavaNetAccess;
+import jdk.internal.misc.JavaNetURLClassLoaderAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.perf.PerfCounter;
import sun.net.www.ParseUtil;
@@ -767,10 +767,11 @@
}
static {
- SharedSecrets.setJavaNetAccess(
- new JavaNetAccess() {
- public URLClassPath getURLClassPath(URLClassLoader u) {
- return u.ucp;
+ SharedSecrets.setJavaNetURLClassLoaderAccess(
+ new JavaNetURLClassLoaderAccess() {
+ @Override
+ public AccessControlContext getAccessControlContext(URLClassLoader u) {
+ return u.acc;
}
}
);
--- a/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/security/ProtectionDomain.java Wed Jul 05 22:22:15 2017 +0200
@@ -89,6 +89,11 @@
AccessController.getContext(), context);
}
+ @Override
+ public ProtectionDomain[] getProtectDomains(AccessControlContext context) {
+ return context.getContext();
+ }
+
private static AccessControlContext getCombinedACC(
AccessControlContext context, AccessControlContext stack) {
AccessControlContext acc =
--- a/jdk/src/java.base/share/classes/java/time/chrono/HijrahDate.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/time/chrono/HijrahDate.java Wed Jul 05 22:22:15 2017 +0200
@@ -368,7 +368,7 @@
if (field instanceof ChronoField) {
switch ((ChronoField) field) {
case DAY_OF_WEEK: return getDayOfWeek();
- case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((getDayOfWeek() - 1) % 7) + 1;
+ case ALIGNED_DAY_OF_WEEK_IN_MONTH: return ((dayOfMonth - 1) % 7) + 1;
case ALIGNED_DAY_OF_WEEK_IN_YEAR: return ((getDayOfYear() - 1) % 7) + 1;
case DAY_OF_MONTH: return this.dayOfMonth;
case DAY_OF_YEAR: return this.getDayOfYear();
--- a/jdk/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeTextProvider.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -349,25 +349,40 @@
if (field == MONTH_OF_YEAR) {
for (TextStyle textStyle : TextStyle.values()) {
- Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
- "gregory", Calendar.MONTH, textStyle.toCalendarStyle(), locale);
Map<Long, String> map = new HashMap<>();
- if (displayNames != null) {
- for (Entry<String, Integer> entry : displayNames.entrySet()) {
- map.put((long) (entry.getValue() + 1), entry.getKey());
- }
-
- } else {
- // Narrow names may have duplicated names, such as "J" for January, Jun, July.
- // Get names one by one in that case.
+ // Narrow names may have duplicated names, such as "J" for January, June, July.
+ // Get names one by one in that case.
+ if ((textStyle.equals(TextStyle.NARROW) ||
+ textStyle.equals(TextStyle.NARROW_STANDALONE))) {
for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
String name;
name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
- "gregory", Calendar.MONTH, month, textStyle.toCalendarStyle(), locale);
+ "gregory", Calendar.MONTH,
+ month, textStyle.toCalendarStyle(), locale);
if (name == null) {
break;
}
- map.put((long) (month + 1), name);
+ map.put((month + 1L), name);
+ }
+ } else {
+ Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
+ "gregory", Calendar.MONTH, textStyle.toCalendarStyle(), locale);
+ if (displayNames != null) {
+ for (Entry<String, Integer> entry : displayNames.entrySet()) {
+ map.put((long)(entry.getValue() + 1), entry.getKey());
+ }
+ } else {
+ // Although probability is very less, but if other styles have duplicate names.
+ // Get names one by one in that case.
+ for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
+ String name;
+ name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
+ "gregory", Calendar.MONTH, month, textStyle.toCalendarStyle(), locale);
+ if (name == null) {
+ break;
+ }
+ map.put((month + 1L), name);
+ }
}
}
if (!map.isEmpty()) {
@@ -379,26 +394,41 @@
if (field == DAY_OF_WEEK) {
for (TextStyle textStyle : TextStyle.values()) {
- Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
- "gregory", Calendar.DAY_OF_WEEK, textStyle.toCalendarStyle(), locale);
Map<Long, String> map = new HashMap<>();
- if (displayNames != null) {
- for (Entry<String, Integer> entry : displayNames.entrySet()) {
- map.put((long)toWeekDay(entry.getValue()), entry.getKey());
- }
-
- } else {
- // Narrow names may have duplicated names, such as "S" for Sunday and Saturday.
- // Get names one by one in that case.
+ // Narrow names may have duplicated names, such as "S" for Sunday and Saturday.
+ // Get names one by one in that case.
+ if ((textStyle.equals(TextStyle.NARROW) ||
+ textStyle.equals(TextStyle.NARROW_STANDALONE))) {
for (int wday = Calendar.SUNDAY; wday <= Calendar.SATURDAY; wday++) {
String name;
name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
- "gregory", Calendar.DAY_OF_WEEK, wday, textStyle.toCalendarStyle(), locale);
+ "gregory", Calendar.DAY_OF_WEEK,
+ wday, textStyle.toCalendarStyle(), locale);
if (name == null) {
break;
}
map.put((long)toWeekDay(wday), name);
}
+ } else {
+ Map<String, Integer> displayNames = CalendarDataUtility.retrieveJavaTimeFieldValueNames(
+ "gregory", Calendar.DAY_OF_WEEK, textStyle.toCalendarStyle(), locale);
+ if (displayNames != null) {
+ for (Entry<String, Integer> entry : displayNames.entrySet()) {
+ map.put((long)toWeekDay(entry.getValue()), entry.getKey());
+ }
+ } else {
+ // Although probability is very less, but if other styles have duplicate names.
+ // Get names one by one in that case.
+ for (int wday = Calendar.SUNDAY; wday <= Calendar.SATURDAY; wday++) {
+ String name;
+ name = CalendarDataUtility.retrieveJavaTimeFieldValueName(
+ "gregory", Calendar.DAY_OF_WEEK, wday, textStyle.toCalendarStyle(), locale);
+ if (name == null) {
+ break;
+ }
+ map.put((long)toWeekDay(wday), name);
+ }
+ }
}
if (!map.isEmpty()) {
styleMap.put(textStyle, map);
--- a/jdk/src/java.base/share/classes/java/util/Optional.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/Optional.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, 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
@@ -236,7 +236,7 @@
* present, otherwise an empty {@code Optional}
* @throws NullPointerException if the mapping function is {@code null}
*/
- public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
+ public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
@@ -264,12 +264,14 @@
* @throws NullPointerException if the mapping function is {@code null} or
* returns a {@code null} result
*/
- public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
+ public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
- return Objects.requireNonNull(mapper.apply(value));
+ @SuppressWarnings("unchecked")
+ Optional<U> r = (Optional<U>) mapper.apply(value);
+ return Objects.requireNonNull(r);
}
}
@@ -286,12 +288,14 @@
* produces a {@code null} result
* @since 9
*/
- public Optional<T> or(Supplier<Optional<T>> supplier) {
+ public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier) {
Objects.requireNonNull(supplier);
if (isPresent()) {
return this;
} else {
- return Objects.requireNonNull(supplier.get());
+ @SuppressWarnings("unchecked")
+ Optional<T> r = (Optional<T>) supplier.get();
+ return Objects.requireNonNull(r);
}
}
--- a/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/PropertyResourceBundle.java Wed Jul 05 22:22:15 2017 +0200
@@ -63,7 +63,7 @@
* files containing the resource data. <code>ResourceBundle.getBundle</code>
* will automatically look for the appropriate properties file and create a
* <code>PropertyResourceBundle</code> that refers to it. See
- * {@link ResourceBundle#getBundle(java.lang.String, java.util.Locale, java.lang.ClassLoader) ResourceBundle.getBundle}
+ * {@link ResourceBundle#getBundle(String, Locale, ClassLoader) ResourceBundle.getBundle}
* for a complete description of the search and instantiation strategy.
*
* <p>
@@ -105,19 +105,14 @@
* </pre>
* </blockquote>
*
- * <p>
- * The implementation of a {@code PropertyResourceBundle} subclass must be
- * thread-safe if it's simultaneously used by multiple threads. The default
- * implementations of the non-abstract methods in this class are thread-safe.
- *
- * <p>
- * <strong>Note:</strong> PropertyResourceBundle can be constructed either
- * from an InputStream or a Reader, which represents a property file.
- * Constructing a PropertyResourceBundle instance from an InputStream requires
- * that the input stream be encoded in UTF-8. By default, if a
+ * @apiNote
+ * {@code PropertyResourceBundle} can be constructed either
+ * from an {@code InputStream} or a {@code Reader}, which represents a property file.
+ * Constructing a {@code PropertyResourceBundle} instance from an {@code InputStream}
+ * requires that the input stream be encoded in {@code UTF-8}. By default, if a
* {@link java.nio.charset.MalformedInputException} or an
* {@link java.nio.charset.UnmappableCharacterException} occurs on reading the
- * input stream, then the PropertyResourceBundle instance resets to the state
+ * input stream, then the {@code PropertyResourceBundle} instance resets to the state
* before the exception, re-reads the input stream in {@code ISO-8859-1}, and
* continues reading. If the system property
* {@code java.util.PropertyResourceBundle.encoding} is set to either
@@ -126,8 +121,15 @@
* If "ISO-8859-1" is specified, characters that cannot be represented in
* ISO-8859-1 encoding must be represented by Unicode Escapes as defined in section
* 3.3 of <cite>The Java™ Language Specification</cite>
- * whereas the other constructor which takes a Reader does not have that limitation.
+ * whereas the other constructor which takes a {@code Reader} does not have that limitation.
* Other encoding values are ignored for this system property.
+ * The system property is read and evaluated when initializing this class.
+ * Changing or removing the property has no effect after the initialization.
+ *
+ * @implSpec
+ * The implementation of a {@code PropertyResourceBundle} subclass must be
+ * thread-safe if it's simultaneously used by multiple threads. The default
+ * implementations of the non-abstract methods in this class are thread-safe.
*
* @see ResourceBundle
* @see ListResourceBundle
@@ -144,16 +146,18 @@
/**
* Creates a property resource bundle from an {@link java.io.InputStream
- * InputStream}. This constructor reads the property file in UTF-8 by default.
- * If a {@link java.nio.charset.MalformedInputException} or an
- * {@link java.nio.charset.UnmappableCharacterException} occurs on reading the
- * input stream, then the PropertyResourceBundle instance resets to the state
- * before the exception, re-reads the input stream in {@code ISO-8859-1} and
- * continues reading. If the system property
- * {@code java.util.PropertyResourceBundle.encoding} is set to either
- * "ISO-8859-1" or "UTF-8", the input stream is solely read in that encoding,
- * and throws the exception if it encounters an invalid sequence. Other
- * encoding values are ignored for this system property.
+ * InputStream}. This constructor reads the property file in UTF-8 by default.
+ * If a {@link java.nio.charset.MalformedInputException} or an
+ * {@link java.nio.charset.UnmappableCharacterException} occurs on reading the
+ * input stream, then the PropertyResourceBundle instance resets to the state
+ * before the exception, re-reads the input stream in {@code ISO-8859-1} and
+ * continues reading. If the system property
+ * {@code java.util.PropertyResourceBundle.encoding} is set to either
+ * "ISO-8859-1" or "UTF-8", the input stream is solely read in that encoding,
+ * and throws the exception if it encounters an invalid sequence. Other
+ * encoding values are ignored for this system property.
+ * The system property is read and evaluated when initializing this class.
+ * Changing or removing the property has no effect after the initialization.
*
* @param stream an InputStream that represents a property file
* to read from.
--- a/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Wed Jul 05 22:22:15 2017 +0200
@@ -71,7 +71,9 @@
NATIVE_LIBS("native"),
NATIVE_CMDS("bin"),
CLASSES("classes"),
- CONFIG("conf");
+ CONFIG("conf"),
+ HEADER_FILES("include"),
+ MAN_PAGES("man");
private final String jmodDir;
private Section(String jmodDir) {
@@ -151,6 +153,10 @@
return Section.CLASSES;
case "conf":
return Section.CONFIG;
+ case "include":
+ return Section.HEADER_FILES;
+ case "man":
+ return Section.MAN_PAGES;
default:
throw new IllegalArgumentException("invalid section: " + s);
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetAccess.java Thu Oct 20 18:38:09 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.internal.misc;
-
-import java.net.URLClassLoader;
-import jdk.internal.loader.URLClassPath;
-
-public interface JavaNetAccess {
- /**
- * return the URLClassPath belonging to the given loader
- */
- URLClassPath getURLClassPath (URLClassLoader u);
-}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetInetAddressAccess.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetInetAddressAccess.java Wed Jul 05 22:22:15 2017 +0200
@@ -26,6 +26,7 @@
package jdk.internal.misc;
import java.net.InetAddress;
+import java.net.UnknownHostException;
public interface JavaNetInetAddressAccess {
/**
@@ -33,4 +34,13 @@
* the given InetAddress object.
*/
String getOriginalHostName(InetAddress ia);
+
+ /**
+ * Get the InetAddress of the provided host. If an InetAddress is provided
+ * then it will be the default address returned for all calls to either
+ * form of getByName. This is required to maintain consistency when
+ * caching addresses and hostnames.
+ */
+ InetAddress getByName(String hostName, InetAddress hostAddress)
+ throws UnknownHostException;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetURLClassLoaderAccess.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.misc;
+
+import java.net.URLClassLoader;
+import java.security.AccessControlContext;
+
+public interface JavaNetURLClassLoaderAccess {
+ AccessControlContext getAccessControlContext(URLClassLoader u);;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetUriAccess.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.misc;
+
+import java.net.URI;
+
+public interface JavaNetUriAccess {
+ /**
+ * Create a URI of pre-validated scheme and path.
+ */
+ URI create(String scheme, String path);
+}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaSecurityAccess.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaSecurityAccess.java Wed Jul 05 22:22:15 2017 +0200
@@ -27,6 +27,7 @@
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
public interface JavaSecurityAccess {
@@ -37,4 +38,5 @@
<T> T doIntersectionPrivilege(PrivilegedAction<T> action,
AccessControlContext context);
+ ProtectionDomain[] getProtectDomains(AccessControlContext context);
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Wed Jul 05 22:22:15 2017 +0200
@@ -53,10 +53,11 @@
private static JavaLangInvokeAccess javaLangInvokeAccess;
private static JavaLangRefAccess javaLangRefAccess;
private static JavaIOAccess javaIOAccess;
- private static JavaNetAccess javaNetAccess;
private static JavaNetInetAddressAccess javaNetInetAddressAccess;
private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
private static JavaNetSocketAccess javaNetSocketAccess;
+ private static JavaNetUriAccess javaNetUriAccess;
+ private static JavaNetURLClassLoaderAccess javaNetURLClassLoaderAccess;
private static JavaNioAccess javaNioAccess;
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
@@ -134,14 +135,24 @@
return javaLangRefAccess;
}
- public static void setJavaNetAccess(JavaNetAccess jna) {
- javaNetAccess = jna;
+ public static void setJavaNetUriAccess(JavaNetUriAccess jnua) {
+ javaNetUriAccess = jnua;
}
- public static JavaNetAccess getJavaNetAccess() {
- if (javaNetAccess == null)
+ public static JavaNetUriAccess getJavaNetUriAccess() {
+ if (javaNetUriAccess == null)
+ unsafe.ensureClassInitialized(java.net.URI.class);
+ return javaNetUriAccess;
+ }
+
+ public static void setJavaNetURLClassLoaderAccess(JavaNetURLClassLoaderAccess jnua) {
+ javaNetURLClassLoaderAccess = jnua;
+ }
+
+ public static JavaNetURLClassLoaderAccess getJavaNetURLClassLoaderAccess() {
+ if (javaNetURLClassLoaderAccess == null)
unsafe.ensureClassInitialized(java.net.URLClassLoader.class);
- return javaNetAccess;
+ return javaNetURLClassLoaderAccess;
}
public static void setJavaNetInetAddressAccess(JavaNetInetAddressAccess jna) {
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Wed Jul 05 22:22:15 2017 +0200
@@ -84,9 +84,22 @@
public static native int getClassAccessFlags(Class<?> c);
+ /**
+ * Ensures that access to a member is granted and throws
+ * IllegalAccessException if not.
+ *
+ * @param currentClass the class performing the access
+ * @param memberClass the declaring class of the member being accessed
+ * @param targetClass the class of target object if accessing instance
+ * field or method;
+ * or the declaring class if accessing constructor;
+ * or null if accessing static field or method
+ * @param modifiers the member's access modifiers
+ * @throws IllegalAccessException if access to member is denied
+ */
public static void ensureMemberAccess(Class<?> currentClass,
Class<?> memberClass,
- Object target,
+ Class<?> targetClass,
int modifiers)
throws IllegalAccessException
{
@@ -94,18 +107,15 @@
throw new InternalError();
}
- if (!verifyMemberAccess(currentClass, memberClass, target, modifiers)) {
- throwIllegalAccessException(currentClass, memberClass, target, modifiers);
+ if (!verifyMemberAccess(currentClass, memberClass, targetClass, modifiers)) {
+ throwIllegalAccessException(currentClass, memberClass, targetClass, modifiers);
}
}
- public static boolean verifyMemberAccess(Class<?> currentClass,
- // Declaring class of field
- // or method
- Class<?> memberClass,
- // May be NULL in case of statics
- Object target,
- int modifiers)
+ private static boolean verifyMemberAccess(Class<?> currentClass,
+ Class<?> memberClass,
+ Class<?> targetClass,
+ int modifiers)
{
// Verify that currentClass can access a field, method, or
// constructor of memberClass, where that member's access bits are
@@ -162,18 +172,18 @@
return false;
}
- if (Modifier.isProtected(modifiers)) {
- // Additional test for protected members: JLS 6.6.2
- Class<?> targetClass = (target == null ? memberClass : target.getClass());
- if (targetClass != currentClass) {
- if (!gotIsSameClassPackage) {
- isSameClassPackage = isSameClassPackage(currentClass, memberClass);
- gotIsSameClassPackage = true;
- }
- if (!isSameClassPackage) {
- if (!isSubclassOf(targetClass, currentClass)) {
- return false;
- }
+ // Additional test for protected instance members
+ // and protected constructors: JLS 6.6.2
+ if (targetClass != null && Modifier.isProtected(modifiers) &&
+ targetClass != currentClass)
+ {
+ if (!gotIsSameClassPackage) {
+ isSameClassPackage = isSameClassPackage(currentClass, memberClass);
+ gotIsSameClassPackage = true;
+ }
+ if (!isSameClassPackage) {
+ if (!isSubclassOf(targetClass, currentClass)) {
+ return false;
}
}
}
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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,14 +25,25 @@
package jdk.internal.reflect;
+import java.io.Externalizable;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamClass;
+import java.io.OptionalDataException;
+import java.io.Serializable;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field;
import java.lang.reflect.Executable;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.security.Permission;
import java.security.PrivilegedAction;
+import java.util.Objects;
import java.util.Properties;
+
import sun.reflect.misc.ReflectUtil;
import sun.security.action.GetPropertyAction;
@@ -57,6 +68,9 @@
// Provides access to package-private mechanisms in java.lang.reflect
private static volatile LangReflectAccess langReflectAccess;
+ /* Method for static class initializer <clinit>, or null */
+ private static volatile Method hasStaticInitializerMethod;
+
//
// "Inflation" mechanism. Loading bytecodes to implement
// Method.invoke() and Constructor.newInstance() currently costs
@@ -337,16 +351,41 @@
//
//
- public Constructor<?> newConstructorForSerialization
- (Class<?> classToInstantiate, Constructor<?> constructorToCall)
- {
- // Fast path
- if (constructorToCall.getDeclaringClass() == classToInstantiate) {
- return constructorToCall;
+ public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
+ if (!Externalizable.class.isAssignableFrom(cl)) {
+ return null;
+ }
+ try {
+ Constructor<?> cons = cl.getConstructor();
+ cons.setAccessible(true);
+ return cons;
+ } catch (NoSuchMethodException ex) {
+ return null;
+ }
+ }
+
+ public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
+ Class<?> initCl = cl;
+ while (Serializable.class.isAssignableFrom(initCl)) {
+ if ((initCl = initCl.getSuperclass()) == null) {
+ return null;
+ }
+ }
+ Constructor<?> constructorToCall;
+ try {
+ constructorToCall = initCl.getDeclaredConstructor();
+ int mods = constructorToCall.getModifiers();
+ if ((mods & Modifier.PRIVATE) != 0 ||
+ ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
+ !packageEquals(cl, initCl))) {
+ return null;
+ }
+ } catch (NoSuchMethodException ex) {
+ return null;
}
ConstructorAccessor acc = new MethodAccessorGenerator().
- generateSerializationConstructor(classToInstantiate,
+ generateSerializationConstructor(cl,
constructorToCall.getParameterTypes(),
constructorToCall.getExceptionTypes(),
constructorToCall.getModifiers(),
@@ -364,9 +403,151 @@
langReflectAccess().
getConstructorParameterAnnotations(constructorToCall));
setConstructorAccessor(c, acc);
+ c.setAccessible(true);
return c;
}
+ public final MethodHandle readObjectForSerialization(Class<?> cl) {
+ return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class);
+ }
+
+ public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
+ return findReadWriteObjectForSerialization(cl, "readObjectNoData", ObjectInputStream.class);
+ }
+
+ public final MethodHandle writeObjectForSerialization(Class<?> cl) {
+ return findReadWriteObjectForSerialization(cl, "writeObject", ObjectOutputStream.class);
+ }
+
+ private final MethodHandle findReadWriteObjectForSerialization(Class<?> cl,
+ String methodName,
+ Class<?> streamClass) {
+ if (!Serializable.class.isAssignableFrom(cl)) {
+ return null;
+ }
+
+ try {
+ Method meth = cl.getDeclaredMethod(methodName, streamClass);
+ int mods = meth.getModifiers();
+ if (meth.getReturnType() != Void.TYPE ||
+ Modifier.isStatic(mods) ||
+ !Modifier.isPrivate(mods)) {
+ return null;
+ }
+ meth.setAccessible(true);
+ return MethodHandles.lookup().unreflect(meth);
+ } catch (NoSuchMethodException ex) {
+ return null;
+ } catch (IllegalAccessException ex1) {
+ throw new InternalError("Error", ex1);
+ }
+ }
+
+ /**
+ * Returns a MethodHandle for {@code writeReplace} on the serializable class
+ * or null if no match found.
+ * @param cl a serializable class
+ * @returnss the {@code writeReplace} MethodHandle or {@code null} if not found
+ */
+ public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
+ return getReplaceResolveForSerialization(cl, "writeReplace");
+ }
+
+ /**
+ * Returns a MethodHandle for {@code readResolve} on the serializable class
+ * or null if no match found.
+ * @param cl a serializable class
+ * @returns the {@code writeReplace} MethodHandle or {@code null} if not found
+ */
+ public final MethodHandle readResolveForSerialization(Class<?> cl) {
+ return getReplaceResolveForSerialization(cl, "readResolve");
+ }
+
+ /**
+ * Lookup readResolve or writeReplace on a class with specified
+ * signature constraints.
+ * @param cl a serializable class
+ * @param methodName the method name to find
+ * @returns a MethodHandle for the method or {@code null} if not found or
+ * has the wrong signature.
+ */
+ private MethodHandle getReplaceResolveForSerialization(Class<?> cl,
+ String methodName) {
+ if (!Serializable.class.isAssignableFrom(cl)) {
+ return null;
+ }
+
+ Class<?> defCl = cl;
+ while (defCl != null) {
+ try {
+ Method m = defCl.getDeclaredMethod(methodName);
+ if (m.getReturnType() != Object.class) {
+ return null;
+ }
+ int mods = m.getModifiers();
+ if (Modifier.isStatic(mods) | Modifier.isAbstract(mods)) {
+ return null;
+ } else if (Modifier.isPublic(mods) | Modifier.isProtected(mods)) {
+ // fall through
+ } else if (Modifier.isPrivate(mods) && (cl != defCl)) {
+ return null;
+ } else if (!packageEquals(cl, defCl)) {
+ return null;
+ }
+ try {
+ // Normal return
+ m.setAccessible(true);
+ return MethodHandles.lookup().unreflect(m);
+ } catch (IllegalAccessException ex0) {
+ // setAccessible should prevent IAE
+ throw new InternalError("Error", ex0);
+ }
+ } catch (NoSuchMethodException ex) {
+ defCl = defCl.getSuperclass();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns true if the given class defines a static initializer method,
+ * false otherwise.
+ */
+ public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
+ Method m = hasStaticInitializerMethod;
+ if (m == null) {
+ try {
+ m = ObjectStreamClass.class.getDeclaredMethod("hasStaticInitializer",
+ new Class<?>[]{Class.class});
+ m.setAccessible(true);
+ hasStaticInitializerMethod = m;
+ } catch (NoSuchMethodException ex) {
+ throw new InternalError("No such method hasStaticInitializer on "
+ + ObjectStreamClass.class, ex);
+ }
+ }
+ try {
+ return (Boolean) m.invoke(null, cl);
+ } catch (InvocationTargetException | IllegalAccessException ex) {
+ throw new InternalError("Exception invoking hasStaticInitializer", ex);
+ }
+ }
+
+ /**
+ * Return the accessible constructor for OptionalDataException signaling eof.
+ * @returns the eof constructor for OptionalDataException
+ */
+ public final Constructor<OptionalDataException> newOptionalDataExceptionForSerialization() {
+ try {
+ Constructor<OptionalDataException> boolCtor =
+ OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE);
+ boolCtor.setAccessible(true);
+ return boolCtor;
+ } catch (NoSuchMethodException ex) {
+ throw new InternalError("Constructor not found", ex);
+ }
+ }
+
//--------------------------------------------------------------------------
//
// Internals only below this point
@@ -426,4 +607,17 @@
}
return langReflectAccess;
}
+
+ /**
+ * Returns true if classes are defined in the classloader and same package, false
+ * otherwise.
+ * @param cl1 a class
+ * @param cl2 another class
+ * @returns true if the two classes are in the same classloader and package
+ */
+ private static boolean packageEquals(Class<?> cl1, Class<?> cl2) {
+ return cl1.getClassLoader() == cl2.getClassLoader() &&
+ Objects.equals(cl1.getPackage(), cl2.getPackage());
+ }
+
}
--- a/jdk/src/java.base/share/classes/module-info.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/module-info.java Wed Jul 05 22:22:15 2017 +0200
@@ -171,8 +171,10 @@
jdk.jartool,
jdk.jdeps,
jdk.jlink,
+ jdk.jshell,
jdk.net,
jdk.scripting.nashorn,
+ jdk.scripting.nashorn.shell,
jdk.unsupported,
jdk.vm.ci;
exports jdk.internal.perf to
@@ -238,8 +240,7 @@
java.xml.ws;
exports sun.security.action to
java.desktop,
- java.security.jgss,
- jdk.crypto.pkcs11;
+ java.security.jgss;
exports sun.security.internal.interfaces to
jdk.crypto.pkcs11;
exports sun.security.internal.spec to
@@ -265,6 +266,8 @@
jdk.crypto.pkcs11;
exports sun.security.ssl to
java.security.jgss;
+ exports sun.security.timestamp to
+ jdk.jartool;
exports sun.security.tools to
jdk.jartool;
exports sun.security.util to
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java Wed Jul 05 22:22:15 2017 +0200
@@ -25,8 +25,11 @@
package sun.net.www.protocol.http;
+import java.util.Collections;
import java.util.Iterator;
import java.util.HashMap;
+import java.util.Set;
+
import sun.net.www.*;
import sun.security.action.GetPropertyAction;
@@ -67,8 +70,8 @@
* -Dhttp.auth.preference="scheme"
*
* which in this case, specifies that "scheme" should be used as the auth scheme when offered
- * disregarding the default prioritisation. If scheme is not offered then the default priority
- * is used.
+ * disregarding the default prioritisation. If scheme is not offered, or explicitly
+ * disabled, by {@code disabledSchemes}, then the default priority is used.
*
* Attention: when http.auth.preference is set as SPNEGO or Kerberos, it's actually "Negotiate
* with SPNEGO" or "Negotiate with Kerberos", which means the user will prefer the Negotiate
@@ -113,17 +116,32 @@
String hdrname; // Name of the header to look for
/**
- * parse a set of authentication headers and choose the preferred scheme
- * that we support for a given host
+ * Parses a set of authentication headers and chooses the preferred scheme
+ * that is supported for a given host.
*/
public AuthenticationHeader (String hdrname, MessageHeader response,
HttpCallerInfo hci, boolean dontUseNegotiate) {
+ this(hdrname, response, hci, dontUseNegotiate, Collections.emptySet());
+ }
+
+ /**
+ * Parses a set of authentication headers and chooses the preferred scheme
+ * that is supported for a given host.
+ *
+ * <p> The {@code disabledSchemes} parameter is a, possibly empty, set of
+ * authentication schemes that are disabled.
+ */
+ public AuthenticationHeader(String hdrname,
+ MessageHeader response,
+ HttpCallerInfo hci,
+ boolean dontUseNegotiate,
+ Set<String> disabledSchemes) {
this.hci = hci;
this.dontUseNegotiate = dontUseNegotiate;
- rsp = response;
+ this.rsp = response;
this.hdrname = hdrname;
- schemes = new HashMap<>();
- parse();
+ this.schemes = new HashMap<>();
+ parse(disabledSchemes);
}
public HttpCallerInfo getHttpCallerInfo() {
@@ -143,10 +161,11 @@
* then the last one will be used. The
* preferred scheme that we support will be used.
*/
- private void parse () {
+ private void parse(Set<String> disabledSchemes) {
Iterator<String> iter = rsp.multiValueIterator(hdrname);
while (iter.hasNext()) {
String raw = iter.next();
+ // HeaderParser lower cases everything, so can be used case-insensitively
HeaderParser hp = new HeaderParser(raw);
Iterator<String> keys = hp.keys();
int i, lastSchemeIndex;
@@ -156,7 +175,8 @@
if (lastSchemeIndex != -1) {
HeaderParser hpn = hp.subsequence (lastSchemeIndex, i);
String scheme = hpn.findKey(0);
- schemes.put (scheme, new SchemeMapValue (hpn, raw));
+ if (!disabledSchemes.contains(scheme))
+ schemes.put(scheme, new SchemeMapValue (hpn, raw));
}
lastSchemeIndex = i;
}
@@ -164,7 +184,8 @@
if (i > lastSchemeIndex) {
HeaderParser hpn = hp.subsequence (lastSchemeIndex, i);
String scheme = hpn.findKey(0);
- schemes.put(scheme, new SchemeMapValue (hpn, raw));
+ if (!disabledSchemes.contains(scheme))
+ schemes.put(scheme, new SchemeMapValue (hpn, raw));
}
}
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Jul 05 22:22:15 2017 +0200
@@ -25,6 +25,7 @@
package sun.net.www.protocol.http;
+import java.security.PrivilegedAction;
import java.util.Arrays;
import java.net.URL;
import java.net.URLConnection;
@@ -109,6 +110,14 @@
static final boolean validateProxy;
static final boolean validateServer;
+ /** A, possibly empty, set of authentication schemes that are disabled
+ * when proxying plain HTTP ( not HTTPS ). */
+ static final Set<String> disabledProxyingSchemes;
+
+ /** A, possibly empty, set of authentication schemes that are disabled
+ * when setting up a tunnel for HTTPS ( HTTP CONNECT ). */
+ static final Set<String> disabledTunnelingSchemes;
+
private StreamingOutputStream strOutputStream;
private static final String RETRY_MSG1 =
"cannot retry due to proxy authentication, in streaming mode";
@@ -206,6 +215,22 @@
"Via"
};
+ private static String getNetProperty(String name) {
+ PrivilegedAction<String> pa = () -> NetProperties.get(name);
+ return AccessController.doPrivileged(pa);
+ }
+
+ private static Set<String> schemesListToSet(String list) {
+ if (list == null || list.isEmpty())
+ return Collections.emptySet();
+
+ Set<String> s = new HashSet<>();
+ String[] parts = list.split("\\s*,\\s*");
+ for (String part : parts)
+ s.add(part.toLowerCase(Locale.ROOT));
+ return s;
+ }
+
static {
Properties props = GetPropertyAction.privilegedGetProperties();
maxRedirects = GetIntegerAction.privilegedGetProperty(
@@ -218,6 +243,14 @@
agent = agent + " Java/"+version;
}
userAgent = agent;
+
+ // A set of net properties to control the use of authentication schemes
+ // when proxing/tunneling.
+ String p = getNetProperty("jdk.http.auth.tunneling.disabledSchemes");
+ disabledTunnelingSchemes = schemesListToSet(p);
+ p = getNetProperty("jdk.http.auth.proxying.disabledSchemes");
+ disabledProxyingSchemes = schemesListToSet(p);
+
validateProxy = Boolean.parseBoolean(
props.getProperty("http.auth.digest.validateProxy"));
validateServer = Boolean.parseBoolean(
@@ -1575,10 +1608,13 @@
// altered in similar ways.
AuthenticationHeader authhdr = new AuthenticationHeader (
- "Proxy-Authenticate", responses,
- new HttpCallerInfo(url, http.getProxyHostUsed(),
- http.getProxyPortUsed()),
- dontUseNegotiate
+ "Proxy-Authenticate",
+ responses,
+ new HttpCallerInfo(url,
+ http.getProxyHostUsed(),
+ http.getProxyPortUsed()),
+ dontUseNegotiate,
+ disabledProxyingSchemes
);
if (!doingNTLMp2ndStage) {
@@ -2024,11 +2060,14 @@
}
}
- AuthenticationHeader authhdr = new AuthenticationHeader (
- "Proxy-Authenticate", responses,
- new HttpCallerInfo(url, http.getProxyHostUsed(),
- http.getProxyPortUsed()),
- dontUseNegotiate
+ AuthenticationHeader authhdr = new AuthenticationHeader(
+ "Proxy-Authenticate",
+ responses,
+ new HttpCallerInfo(url,
+ http.getProxyHostUsed(),
+ http.getProxyPortUsed()),
+ dontUseNegotiate,
+ disabledTunnelingSchemes
);
if (!doingNTLMp2ndStage) {
proxyAuthentication =
--- a/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java Wed Jul 05 22:22:15 2017 +0200
@@ -44,9 +44,21 @@
return Class.forName(name);
}
- /*
- * Reflection.ensureMemberAccess is overly-restrictive
- * due to a bug. We awkwardly work around it for now.
+ /**
+ * Ensures that access to a method or field is granted and throws
+ * IllegalAccessException if not. This method is not suitable for checking
+ * access to constructors.
+ *
+ * @param currentClass the class performing the access
+ * @param memberClass the declaring class of the member being accessed
+ * @param target the target object if accessing instance field or method;
+ * or null if accessing static field or method or if target
+ * object access rights will be checked later
+ * @param modifiers the member's access modifiers
+ * @throws IllegalAccessException if access to member is denied
+ * @implNote Delegates directly to
+ * {@link Reflection#ensureMemberAccess(Class, Class, Class, int)}
+ * which should be used instead.
*/
public static void ensureMemberAccess(Class<?> currentClass,
Class<?> memberClass,
@@ -54,62 +66,10 @@
int modifiers)
throws IllegalAccessException
{
- if (target == null && Modifier.isProtected(modifiers)) {
- int mods = modifiers;
- mods = mods & (~Modifier.PROTECTED);
- mods = mods | Modifier.PUBLIC;
-
- /*
- * See if we fail because of class modifiers
- */
- Reflection.ensureMemberAccess(currentClass,
- memberClass,
- target,
- mods);
- try {
- /*
- * We're still here so class access was ok.
- * Now try with default field access.
- */
- mods = mods & (~Modifier.PUBLIC);
- Reflection.ensureMemberAccess(currentClass,
- memberClass,
- target,
- mods);
- /*
- * We're still here so access is ok without
- * checking for protected.
- */
- return;
- } catch (IllegalAccessException e) {
- /*
- * Access failed but we're 'protected' so
- * if the test below succeeds then we're ok.
- */
- if (isSubclassOf(currentClass, memberClass)) {
- return;
- } else {
- throw e;
- }
- }
- } else {
- Reflection.ensureMemberAccess(currentClass,
- memberClass,
- target,
- modifiers);
- }
- }
-
- private static boolean isSubclassOf(Class<?> queryClass,
- Class<?> ofClass)
- {
- while (queryClass != null) {
- if (queryClass == ofClass) {
- return true;
- }
- queryClass = queryClass.getSuperclass();
- }
- return false;
+ Reflection.ensureMemberAccess(currentClass,
+ memberClass,
+ target == null ? null : target.getClass(),
+ modifiers);
}
/**
--- a/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,20 +28,38 @@
import java.io.OutputStream;
import java.io.IOException;
import java.math.BigInteger;
+import java.security.CryptoPrimitive;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.Timestamp;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
-import java.security.*;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
import sun.security.timestamp.TimestampToken;
-import sun.security.util.*;
+import sun.security.util.Debug;
+import sun.security.util.DerEncoder;
+import sun.security.util.DerInputStream;
+import sun.security.util.DerOutputStream;
+import sun.security.util.DerValue;
+import sun.security.util.DisabledAlgorithmConstraints;
+import sun.security.util.HexDumpEncoder;
+import sun.security.util.KeyUtil;
+import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId;
import sun.security.x509.X500Name;
import sun.security.x509.KeyUsageExtension;
-import sun.security.util.HexDumpEncoder;
/**
* A SignerInfo, as defined in PKCS#7's signedData type.
@@ -50,6 +68,17 @@
*/
public class SignerInfo implements DerEncoder {
+ // Digest and Signature restrictions
+ private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET =
+ Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
+
+ private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET =
+ Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
+
+ private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
+ new DisabledAlgorithmConstraints(
+ DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
+
BigInteger version;
X500Name issuerName;
BigInteger certificateSerialNumber;
@@ -318,6 +347,13 @@
if (messageDigest == null) // fail if there is no message digest
return null;
+ // check that algorithm is not restricted
+ if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET,
+ digestAlgname, null)) {
+ throw new SignatureException("Digest check failed. " +
+ "Disabled algorithm used: " + digestAlgname);
+ }
+
MessageDigest md = MessageDigest.getInstance(digestAlgname);
byte[] computedMessageDigest = md.digest(data);
@@ -349,12 +385,26 @@
String algname = AlgorithmId.makeSigAlg(
digestAlgname, encryptionAlgname);
- Signature sig = Signature.getInstance(algname);
+ // check that algorithm is not restricted
+ if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, algname, null)) {
+ throw new SignatureException("Signature check failed. " +
+ "Disabled algorithm used: " + algname);
+ }
+
X509Certificate cert = getCertificate(block);
-
+ PublicKey key = cert.getPublicKey();
if (cert == null) {
return null;
}
+
+ // check if the public key is restricted
+ if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
+ throw new SignatureException("Public key check failed. " +
+ "Disabled key used: " +
+ KeyUtil.getKeySize(key) + " bit " +
+ key.getAlgorithm());
+ }
+
if (cert.hasUnsupportedCriticalExtension()) {
throw new SignatureException("Certificate has unsupported "
+ "critical extension(s)");
@@ -391,11 +441,9 @@
}
}
- PublicKey key = cert.getPublicKey();
+ Signature sig = Signature.getInstance(algname);
sig.initVerify(key);
-
sig.update(dataSigned);
-
if (sig.verify(encryptedDigest)) {
return this;
}
@@ -450,6 +498,23 @@
return unauthenticatedAttributes;
}
+ /**
+ * Returns the timestamp PKCS7 data unverified.
+ * @return a PKCS7 object
+ */
+ public PKCS7 getTsToken() throws IOException {
+ if (unauthenticatedAttributes == null) {
+ return null;
+ }
+ PKCS9Attribute tsTokenAttr =
+ unauthenticatedAttributes.getAttribute(
+ PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
+ if (tsTokenAttr == null) {
+ return null;
+ }
+ return new PKCS7((byte[])tsTokenAttr.getValue());
+ }
+
/*
* Extracts a timestamp from a PKCS7 SignerInfo.
*
@@ -477,19 +542,12 @@
if (timestamp != null || !hasTimestamp)
return timestamp;
- if (unauthenticatedAttributes == null) {
- hasTimestamp = false;
- return null;
- }
- PKCS9Attribute tsTokenAttr =
- unauthenticatedAttributes.getAttribute(
- PKCS9Attribute.SIGNATURE_TIMESTAMP_TOKEN_OID);
- if (tsTokenAttr == null) {
+ PKCS7 tsToken = getTsToken();
+ if (tsToken == null) {
hasTimestamp = false;
return null;
}
- PKCS7 tsToken = new PKCS7((byte[])tsTokenAttr.getValue());
// Extract the content (an encoded timestamp token info)
byte[] encTsTokenInfo = tsToken.getContentInfo().getData();
// Extract the signer (the Timestamping Authority)
@@ -515,9 +573,16 @@
*/
private void verifyTimestamp(TimestampToken token)
throws NoSuchAlgorithmException, SignatureException {
+ String digestAlgname = token.getHashAlgorithm().getName();
+ // check that algorithm is not restricted
+ if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, digestAlgname,
+ null)) {
+ throw new SignatureException("Timestamp token digest check failed. " +
+ "Disabled algorithm used: " + digestAlgname);
+ }
MessageDigest md =
- MessageDigest.getInstance(token.getHashAlgorithm().getName());
+ MessageDigest.getInstance(digestAlgname);
if (!Arrays.equals(token.getHashedMessage(),
md.digest(encryptedDigest))) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Wed Jul 05 22:22:15 2017 +0200
@@ -185,20 +185,22 @@
AlgorithmConstraints constraints,
Date pkixdate) {
- if (anchor == null) {
- throw new IllegalArgumentException(
- "The trust anchor cannot be null");
- }
-
- if (anchor.getTrustedCert() != null) {
- this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
- // Check for anchor certificate restrictions
- trustedMatch = checkFingerprint(anchor.getTrustedCert());
- if (trustedMatch && debug != null) {
- debug.println("trustedMatch = true");
+ if (anchor != null) {
+ if (anchor.getTrustedCert() != null) {
+ this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
+ // Check for anchor certificate restrictions
+ trustedMatch = checkFingerprint(anchor.getTrustedCert());
+ if (trustedMatch && debug != null) {
+ debug.println("trustedMatch = true");
+ }
+ } else {
+ this.trustedPubKey = anchor.getCAPublicKey();
}
} else {
- this.trustedPubKey = anchor.getCAPublicKey();
+ this.trustedPubKey = null;
+ if (debug != null) {
+ debug.println("TrustAnchor is null, trustedMatch is false.");
+ }
}
this.prevPubKey = trustedPubKey;
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -816,18 +816,22 @@
/**
* Verifies whether the input certificate completes the path.
- * Checks the cert against each trust anchor that was specified, in order,
- * and returns true as soon as it finds a valid anchor.
- * Returns true if the cert matches a trust anchor specified as a
- * certificate or if the cert verifies with a trust anchor that
- * was specified as a trusted {pubkey, caname} pair. Returns false if none
- * of the trust anchors are valid for this cert.
+ * First checks the cert against each trust anchor that was specified,
+ * in order, and returns true if the cert matches the trust anchor
+ * specified as a certificate or has the same key and subject of an anchor
+ * specified as a trusted {pubkey, caname} pair.
+ * If no match has been found, does a second check of the cert against
+ * anchors specified as a trusted {pubkey, caname} pair to see if the cert
+ * was issued by that anchor.
+ * Returns false if none of the trust anchors are valid for this cert.
*
* @param cert the certificate to test
* @return a boolean value indicating whether the cert completes the path.
*/
@Override
boolean isPathCompleted(X509Certificate cert) {
+ List<TrustAnchor> otherAnchors = new ArrayList<>();
+ // first, check if cert is already trusted
for (TrustAnchor anchor : trustAnchors) {
if (anchor.getTrustedCert() != null) {
if (cert.equals(anchor.getTrustedCert())) {
@@ -849,7 +853,12 @@
}
// else, it is a self-issued certificate of the anchor
}
-
+ otherAnchors.add(anchor);
+ }
+ // next, check if cert is issued by anchor specified by key/name
+ for (TrustAnchor anchor : otherAnchors) {
+ X500Principal principal = anchor.getCA();
+ PublicKey publicKey = anchor.getCAPublicKey();
// Check subject/issuer name chaining
if (principal == null ||
!principal.equals(cert.getIssuerX500Principal())) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java Wed Jul 05 22:22:15 2017 +0200
@@ -35,6 +35,7 @@
import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.CRLReason;
import java.security.cert.Extension;
+import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collections;
@@ -164,6 +165,15 @@
Date date, List<Extension> extensions)
throws IOException, CertPathValidatorException
{
+ return check(cert, responderURI, null, issuerCert, responderCert, date, extensions);
+ }
+
+ public static RevocationStatus check(X509Certificate cert,
+ URI responderURI, TrustAnchor anchor, X509Certificate issuerCert,
+ X509Certificate responderCert, Date date,
+ List<Extension> extensions)
+ throws IOException, CertPathValidatorException
+ {
CertId certId = null;
try {
X509CertImpl certImpl = X509CertImpl.toImpl(cert);
@@ -173,8 +183,8 @@
("Exception while encoding OCSPRequest", e);
}
OCSPResponse ocspResponse = check(Collections.singletonList(certId),
- responderURI, new OCSPResponse.IssuerInfo(issuerCert),
- responderCert, date, extensions);
+ responderURI, new OCSPResponse.IssuerInfo(anchor, issuerCert),
+ responderCert, date, extensions);
return (RevocationStatus) ocspResponse.getSingleResponse(certId);
}
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java Wed Jul 05 22:22:15 2017 +0200
@@ -507,9 +507,8 @@
// Check algorithm constraints specified in security property
// "jdk.certpath.disabledAlgorithms".
- AlgorithmChecker algChecker = new AlgorithmChecker(
- new TrustAnchor(issuerInfo.getName(),
- issuerInfo.getPublicKey(), null));
+ AlgorithmChecker algChecker =
+ new AlgorithmChecker(issuerInfo.getAnchor(), date);
algChecker.init(false);
algChecker.check(signerCert, Collections.<String>emptySet());
@@ -982,36 +981,38 @@
/**
* Helper class that allows consumers to pass in issuer information. This
* will always consist of the issuer's name and public key, but may also
- * contain a certificate if the originating data is in that form.
+ * contain a certificate if the originating data is in that form. The
+ * trust anchor for the certificate chain will be included for certpath
+ * disabled algorithm checking.
*/
static final class IssuerInfo {
+ private final TrustAnchor anchor;
private final X509Certificate certificate;
private final X500Principal name;
private final PublicKey pubKey;
+ IssuerInfo(TrustAnchor anchor) {
+ this(anchor, (anchor != null) ? anchor.getTrustedCert() : null);
+ }
+
IssuerInfo(X509Certificate issuerCert) {
- certificate = Objects.requireNonNull(issuerCert,
- "Constructor requires non-null certificate");
- name = certificate.getSubjectX500Principal();
- pubKey = certificate.getPublicKey();
+ this(null, issuerCert);
}
- IssuerInfo(X500Principal subjectName, PublicKey key) {
- certificate = null;
- name = Objects.requireNonNull(subjectName,
- "Constructor requires non-null subject");
- pubKey = Objects.requireNonNull(key,
- "Constructor requires non-null public key");
- }
-
- IssuerInfo(TrustAnchor anchor) {
- certificate = anchor.getTrustedCert();
- if (certificate != null) {
- name = certificate.getSubjectX500Principal();
- pubKey = certificate.getPublicKey();
+ IssuerInfo(TrustAnchor anchor, X509Certificate issuerCert) {
+ if (anchor == null && issuerCert == null) {
+ throw new NullPointerException("TrustAnchor and issuerCert " +
+ "cannot be null");
+ }
+ this.anchor = anchor;
+ if (issuerCert != null) {
+ name = issuerCert.getSubjectX500Principal();
+ pubKey = issuerCert.getPublicKey();
+ certificate = issuerCert;
} else {
name = anchor.getCA();
pubKey = anchor.getCAPublicKey();
+ certificate = anchor.getTrustedCert();
}
}
@@ -1047,6 +1048,15 @@
}
/**
+ * Get the TrustAnchor for the certificate chain.
+ *
+ * @return a {@code TrustAnchor}.
+ */
+ TrustAnchor getAnchor() {
+ return anchor;
+ }
+
+ /**
* Create a string representation of this IssuerInfo.
*
* @return a {@code String} form of this IssuerInfo object.
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Wed Jul 05 22:22:15 2017 +0200
@@ -437,7 +437,7 @@
private void updateState(X509Certificate cert)
throws CertPathValidatorException
{
- issuerInfo = new OCSPResponse.IssuerInfo(cert);
+ issuerInfo = new OCSPResponse.IssuerInfo(anchor, cert);
// Make new public key if parameters are missing
PublicKey pubKey = cert.getPublicKey();
@@ -740,8 +740,8 @@
}
response = OCSP.check(Collections.singletonList(certId),
- responderURI, issuerInfo,
- responderCert, null, ocspExtensions);
+ responderURI, issuerInfo, responderCert, params.date(),
+ ocspExtensions);
}
} catch (IOException e) {
throw new CertPathValidatorException(
--- a/jdk/src/java.base/share/classes/sun/security/util/CurveDB.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/CurveDB.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, 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
@@ -664,6 +664,74 @@
0xFF70, nameSplitPattern);
*/
+ /*
+ * Brainpool curves (RFC 5639)
+ * (Twisted curves are not included)
+ */
+
+ add("brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1", P,
+ "E95E4A5F737059DC60DFC7AD95B3D8139515620F",
+ "340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
+ "1E589A8595423412134FAA2DBDEC95C8D8675E58",
+ "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3",
+ "1667CB477A1A8EC338F94741669C976316DA6321",
+ "E95E4A5F737059DC60DF5991D45029409E60FC09",
+ 1, nameSplitPattern);
+
+ add("brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", P,
+ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
+ "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
+ "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
+ "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6",
+ "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F",
+ "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
+ 1, nameSplitPattern);
+
+ add("brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", P,
+ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
+ "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
+ "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
+ "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D",
+ "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD",
+ "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
+ 1, nameSplitPattern);
+
+ add("brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", P,
+ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
+ "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
+ "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
+ "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262",
+ "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
+ "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
+ 1, nameSplitPattern);
+
+ add("brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", P,
+ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
+ "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
+ "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
+ "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611",
+ "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1",
+ "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
+ 1, nameSplitPattern);
+
+ add("brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", P,
+ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
+ "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
+ "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
+ "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E",
+ "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
+ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
+ 1, nameSplitPattern);
+
+ add("brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", P,
+ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
+ "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
+ "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
+ "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822",
+ "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
+ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
+ 1, nameSplitPattern);
+
specCollection = Collections.unmodifiableCollection(oidMap.values());
}
}
--- a/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Wed Jul 05 22:22:15 2017 +0200
@@ -60,6 +60,10 @@
public static final String PROPERTY_TLS_DISABLED_ALGS =
"jdk.tls.disabledAlgorithms";
+ // the known security property, jdk.jar.disabledAlgorithms
+ public static final String PROPERTY_JAR_DISABLED_ALGS =
+ "jdk.jar.disabledAlgorithms";
+
private final String[] disabledAlgorithms;
private final Constraints algorithmConstraints;
@@ -73,6 +77,14 @@
this(propertyName, new AlgorithmDecomposer());
}
+ /**
+ * Initialize algorithm constraints with the specified security property
+ * for a specific usage type.
+ *
+ * @param propertyName the security property name that define the disabled
+ * algorithm constraints
+ * @param decomposer an alternate AlgorithmDecomposer.
+ */
public DisabledAlgorithmConstraints(String propertyName,
AlgorithmDecomposer decomposer) {
super(decomposer);
@@ -530,7 +542,8 @@
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on certificate " +
- "anchor limits",
+ "anchor limits. " + algorithm + " used with " +
+ cp.getCertificate().getSubjectX500Principal(),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@@ -611,8 +624,8 @@
return;
}
throw new CertPathValidatorException(
- "denyAfter constraint check failed. " +
- "Constraint date: " +
+ "denyAfter constraint check failed: " + algorithm +
+ " used with Constraint date: " +
dateFormat.format(denyAfterDate) + "; "
+ errmsg + dateFormat.format(currentDate),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
@@ -644,6 +657,7 @@
private int minSize; // the minimal available key size
private int maxSize; // the maximal available key size
private int prohibitedSize = -1; // unavailable key sizes
+ private int size;
public KeySizeConstraint(String algo, Operator operator, int length) {
algorithm = algo;
@@ -695,7 +709,9 @@
return;
}
throw new CertPathValidatorException(
- "Algorithm constraints check failed on keysize limits",
+ "Algorithm constraints check failed on keysize limits. "
+ + algorithm + " " + size + "bit key used with "
+ + cp.getCertificate().getSubjectX500Principal(),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@@ -722,7 +738,7 @@
return true;
}
- int size = KeyUtil.getKeySize(key);
+ size = KeyUtil.getKeySize(key);
if (size == 0) {
return false; // we don't allow any key of size 0.
} else if (size > 0) {
--- a/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, 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,26 +25,49 @@
package sun.security.util;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.CodeSigner;
+import java.security.CryptoPrimitive;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SignatureException;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
-import java.security.*;
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-
-import sun.security.pkcs.*;
+import java.util.ArrayList;
import java.util.Base64;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.Attributes;
+import java.util.jar.JarException;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
import sun.security.jca.Providers;
+import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.SignerInfo;
public class SignatureFileVerifier {
/* Are we debugging ? */
private static final Debug debug = Debug.getInstance("jar");
- /* cache of CodeSigner objects */
+ private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET =
+ Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
+
+ private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
+ new DisabledAlgorithmConstraints(
+ DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
+
private ArrayList<CodeSigner[]> signerCache;
private static final String ATTR_DIGEST =
@@ -199,8 +222,15 @@
/** get digest from cache */
- private MessageDigest getDigest(String algorithm)
- {
+ private MessageDigest getDigest(String algorithm) throws SignatureException {
+ // check that algorithm is not restricted
+ if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, algorithm, null)) {
+ SignatureException e =
+ new SignatureException("SignatureFile check failed. " +
+ "Disabled algorithm used: " + algorithm);
+ throw e;
+ }
+
if (createdDigests == null)
createdDigests = new HashMap<>();
@@ -320,7 +350,7 @@
private boolean verifyManifestHash(Manifest sf,
ManifestDigester md,
List<Object> manifestDigests)
- throws IOException
+ throws IOException, SignatureException
{
Attributes mattr = sf.getMainAttributes();
boolean manifestSigned = false;
@@ -364,7 +394,7 @@
private boolean verifyManifestMainAttrs(Manifest sf,
ManifestDigester md)
- throws IOException
+ throws IOException, SignatureException
{
Attributes mattr = sf.getMainAttributes();
boolean attrsVerified = true;
@@ -430,14 +460,14 @@
private boolean verifySection(Attributes sfAttr,
String name,
ManifestDigester md)
- throws IOException
+ throws IOException, SignatureException
{
boolean oneDigestVerified = false;
ManifestDigester.Entry mde = md.get(name,block.isOldStyle());
if (mde == null) {
throw new SecurityException(
- "no manifiest section for signature file entry "+name);
+ "no manifest section for signature file entry "+name);
}
if (sfAttr != null) {
--- a/jdk/src/java.base/share/conf/net.properties Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/conf/net.properties Wed Jul 05 22:22:15 2017 +0200
@@ -72,3 +72,30 @@
# value is 10).
# http.KeepAlive.remainingData=512
# http.KeepAlive.queuedConnections=10
+
+# Authentication Scheme restrictions for HTTP and HTTPS.
+#
+# In some environments certain authentication schemes may be undesirable
+# when proxying HTTP or HTTPS. For example, "Basic" results in effectively the
+# cleartext transmission of the user's password over the physical network.
+# This section describes the mechanism for disabling authentication schemes
+# based on the scheme name. Disabled schemes will be treated as if they are not
+# supported by the implementation.
+#
+# The 'jdk.http.auth.tunneling.disabledSchemes' property lists the authentication
+# schemes that will be disabled when tunneling HTTPS over a proxy, HTTP CONNECT.
+# The 'jdk.http.auth.proxying.disabledSchemes' property lists the authentication
+# schemes that will be disabled when proxying HTTP.
+#
+# In both cases the property is a comma-separated list of, case-insensitive,
+# authentication scheme names, as defined by their relevant RFCs. An
+# implementation may, but is not required to, support common schemes whose names
+# include: 'Basic', 'Digest', 'NTLM', 'Kerberos', 'Negotiate'. A scheme that
+# is not known, or not supported, by the implementation is ignored.
+#
+# Note: This property is currently used by the JDK Reference implementation. It
+# is not guaranteed to be examined and used by other implementations.
+#
+#jdk.http.auth.proxying.disabledSchemes=
+jdk.http.auth.tunneling.disabledSchemes=Basic
+
--- a/jdk/src/java.base/share/conf/security/java.security Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/conf/security/java.security Wed Jul 05 22:22:15 2017 +0200
@@ -655,6 +655,44 @@
jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & denyAfter 2017-01-01, \
RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
+# Algorithm restrictions for signed JAR files
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# for signed JAR validation. For example, "MD2" is generally no longer
+# considered to be a secure hash algorithm. This section describes the
+# mechanism for disabling algorithms based on algorithm name and/or key length.
+# JARs signed with any of the disabled algorithms or key sizes will be treated
+# as unsigned.
+#
+# The syntax of the disabled algorithm string is described as follows:
+# DisabledAlgorithms:
+# " DisabledAlgorithm { , DisabledAlgorithm } "
+#
+# DisabledAlgorithm:
+# AlgorithmName [Constraint]
+#
+# AlgorithmName:
+# (see below)
+#
+# Constraint:
+# KeySizeConstraint
+#
+# KeySizeConstraint:
+# keySize Operator KeyLength
+#
+# Operator:
+# <= | < | == | != | >= | >
+#
+# KeyLength:
+# Integer value of the algorithm's key length in bits
+#
+# Note: This property is currently used by the JDK Reference
+# implementation. It is not guaranteed to be examined and used by other
+# implementations.
+#
+jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
+ DSA keySize < 1024
+
# Algorithm restrictions for Secure Socket Layer/Transport Layer Security
# (SSL/TLS/DTLS) processing
#
@@ -935,3 +973,4 @@
# Otherwise, the status is UNDECIDED.
#
#jdk.serialFilter=pattern;pattern
+
--- a/jdk/src/java.base/share/lib/security/default.policy Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/lib/security/default.policy Wed Jul 05 22:22:15 2017 +0200
@@ -103,7 +103,6 @@
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.*";
permission java.lang.RuntimePermission "loadLibrary.sunec";
- permission java.util.PropertyPermission "*", "read";
permission java.security.SecurityPermission "putProviderProperty.SunEC";
permission java.security.SecurityPermission "clearProviderProperties.SunEC";
permission java.security.SecurityPermission "removeProviderProperty.SunEC";
@@ -112,11 +111,11 @@
grant codeBase "jrt:/jdk.crypto.pkcs11" {
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.*";
- permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
permission java.lang.RuntimePermission "loadLibrary.j2pkcs11";
- // needs "security.pkcs11.allowSingleThreadedModules"
- permission java.util.PropertyPermission "*", "read";
+ permission java.util.PropertyPermission "sun.security.pkcs11.allowSingleThreadedModules", "read";
+ permission java.util.PropertyPermission "os.name", "read";
+ permission java.util.PropertyPermission "os.arch", "read";
permission java.security.SecurityPermission "putProviderProperty.*";
permission java.security.SecurityPermission "clearProviderProperties.*";
permission java.security.SecurityPermission "removeProviderProperty.*";
--- a/jdk/src/java.base/share/native/libverify/check_code.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/share/native/libverify/check_code.c Wed Jul 05 22:22:15 2017 +0200
@@ -1293,14 +1293,13 @@
case JVM_OPC_invokevirtual:
case JVM_OPC_invokespecial:
case JVM_OPC_invokestatic:
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokeinterface: {
/* Make sure the constant pool item is the right type. */
int key = (code[offset + 1] << 8) + code[offset + 2];
const char *methodname;
jclass cb = context->class;
fullinfo_type clazz_info;
- int is_constructor, is_internal, is_invokedynamic;
+ int is_constructor, is_internal;
int kind;
switch (opcode ) {
@@ -1309,9 +1308,6 @@
? (1 << JVM_CONSTANT_Methodref)
: ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref)));
break;
- case JVM_OPC_invokedynamic:
- kind = 1 << JVM_CONSTANT_NameAndType;
- break;
case JVM_OPC_invokeinterface:
kind = 1 << JVM_CONSTANT_InterfaceMethodref;
break;
@@ -1319,7 +1315,6 @@
kind = 1 << JVM_CONSTANT_Methodref;
}
- is_invokedynamic = opcode == JVM_OPC_invokedynamic;
/* Make sure the constant pool item is the right type. */
verify_constant_pool_type(context, key, kind);
methodname = JVM_GetCPMethodNameUTF(env, cb, key);
@@ -1328,11 +1323,8 @@
is_internal = methodname[0] == '<';
pop_and_free(context);
- if (is_invokedynamic)
- clazz_info = context->object_info; // anything will do
- else
- clazz_info = cp_index_to_class_fullinfo(context, key,
- JVM_CONSTANT_Methodref);
+ clazz_info = cp_index_to_class_fullinfo(context, key,
+ JVM_CONSTANT_Methodref);
this_idata->operand.i = key;
this_idata->operand2.fi = clazz_info;
if (is_constructor) {
@@ -1387,17 +1379,15 @@
"Fourth operand byte of invokeinterface must be zero");
}
pop_and_free(context);
- } else if (opcode == JVM_OPC_invokedynamic) {
- if (code[offset + 3] != 0 || code[offset + 4] != 0) {
- CCerror(context,
- "Third and fourth operand bytes of invokedynamic must be zero");
- }
} else if (opcode == JVM_OPC_invokevirtual
|| opcode == JVM_OPC_invokespecial)
set_protected(context, inumber, key, opcode);
break;
}
+ case JVM_OPC_invokedynamic:
+ CCerror(context,
+ "invokedynamic bytecode is not supported in this class file version");
case JVM_OPC_instanceof:
case JVM_OPC_checkcast:
@@ -2085,7 +2075,6 @@
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit: /* invokespecial call to <init> */
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokestatic: case JVM_OPC_invokeinterface: {
/* The top stuff on the stack depends on the method signature */
int operand = this_idata->operand.i;
@@ -2101,8 +2090,7 @@
print_formatted_methodname(context, operand);
}
#endif
- if (opcode != JVM_OPC_invokestatic &&
- opcode != JVM_OPC_invokedynamic)
+ if (opcode != JVM_OPC_invokestatic)
/* First, push the object */
*ip++ = (opcode == JVM_OPC_invokeinit ? '@' : 'A');
for (p = signature + 1; *p != JVM_SIGNATURE_ENDFUNC; ) {
@@ -2388,7 +2376,6 @@
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit:
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokeinterface: case JVM_OPC_invokestatic: {
int operand = this_idata->operand.i;
const char *signature =
@@ -2398,8 +2385,7 @@
int item;
const char *p;
check_and_push(context, signature, VM_STRING_UTF);
- if (opcode == JVM_OPC_invokestatic ||
- opcode == JVM_OPC_invokedynamic) {
+ if (opcode == JVM_OPC_invokestatic) {
item = 0;
} else if (opcode == JVM_OPC_invokeinit) {
fullinfo_type init_type = this_idata->operand2.fi;
@@ -2795,7 +2781,6 @@
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit:
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokestatic: case JVM_OPC_invokeinterface: {
/* Look to signature to determine correct result. */
int operand = this_idata->operand.i;
--- a/jdk/src/java.base/solaris/lib/security/default.policy Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/solaris/lib/security/default.policy Wed Jul 05 22:22:15 2017 +0200
@@ -4,7 +4,10 @@
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
permission java.lang.RuntimePermission "loadLibrary.j2ucrypto";
// need "com.oracle.security.ucrypto.debug" for debugging
- permission java.util.PropertyPermission "*", "read";
+ permission java.util.PropertyPermission "com.oracle.security.ucrypto.debug", "read";
+ permission java.util.PropertyPermission "file.separator", "read";
+ permission java.util.PropertyPermission "java.home", "read";
+ permission java.util.PropertyPermission "os.name", "read";
permission java.security.SecurityPermission
"putProviderProperty.OracleUcrypto";
permission java.security.SecurityPermission
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.c Wed Jul 05 22:22:15 2017 +0200
@@ -273,13 +273,10 @@
#endif
-
void
NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
const char *defaultDetail) {
- char errmsg[255];
- sprintf(errmsg, "errno: %d, error: %s\n", errno, defaultDetail);
- JNU_ThrowByNameWithLastError(env, name, errmsg);
+ JNU_ThrowByNameWithMessageAndLastError(env, name, defaultDetail);
}
void
--- a/jdk/src/java.base/windows/native/libjli/java_md.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/windows/native/libjli/java_md.c Wed Jul 05 22:22:15 2017 +0200
@@ -48,6 +48,10 @@
char *jvmpath, jint jvmpathsize);
static jboolean GetJREPath(char *path, jint pathsize);
+#ifdef USE_REGISTRY_LOOKUP
+jboolean GetPublicJREHome(char *buf, jint bufsize);
+#endif
+
/* We supports warmup for UI stack that is performed in parallel
* to VM initialization.
* This helps to improve startup of UI application as warmup phase
@@ -346,6 +350,14 @@
}
}
+#ifdef USE_REGISTRY_LOOKUP
+ /* Lookup public JRE using Windows registry. */
+ if (GetPublicJREHome(path, pathsize)) {
+ JLI_TraceLauncher("JRE path is %s\n", path);
+ return JNI_TRUE;
+ }
+#endif
+
JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
return JNI_FALSE;
}
--- a/jdk/src/java.base/windows/native/libnet/NetworkInterface_winXP.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/NetworkInterface_winXP.c Wed Jul 05 22:22:15 2017 +0200
@@ -554,14 +554,20 @@
* Create a NetworkInterface object and populate it
*/
netifObj = (*env)->NewObject(env, ni_class, ni_ctor);
+ if (netifObj == NULL) {
+ return NULL;
+ }
name = (*env)->NewStringUTF(env, ifs->name);
+ if (name == NULL) {
+ return NULL;
+ }
if (ifs->dNameIsUnicode) {
displayName = (*env)->NewString(env, (PWCHAR)ifs->displayName,
(jsize)wcslen ((PWCHAR)ifs->displayName));
} else {
displayName = (*env)->NewStringUTF(env, ifs->displayName);
}
- if (netifObj == NULL || name == NULL || displayName == NULL) {
+ if (displayName == NULL) {
return NULL;
}
(*env)->SetObjectField(env, netifObj, ni_nameID, name);
@@ -621,26 +627,28 @@
(*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
} else /* AF_INET6 */ {
int scope;
+ jboolean ret;
iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
- if (iaObj) {
- jboolean ret = setInet6Address_ipaddress(env, iaObj, (jbyte *)&(addrs->addr.sa6.sin6_addr.s6_addr));
- if (ret == JNI_FALSE) {
- return NULL;
- }
- scope = addrs->addr.sa6.sin6_scope_id;
- if (scope != 0) { /* zero is default value, no need to set */
- setInet6Address_scopeid(env, iaObj, scope);
- setInet6Address_scopeifname(env, iaObj, netifObj);
- }
- ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
- if (ibObj == NULL) {
- free_netaddr(netaddrP);
- return NULL;
- }
- (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
- (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
- (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
+ if (iaObj == NULL) {
+ return NULL;
+ }
+ ret = setInet6Address_ipaddress(env, iaObj, (jbyte *)&(addrs->addr.sa6.sin6_addr.s6_addr));
+ if (ret == JNI_FALSE) {
+ return NULL;
}
+ scope = addrs->addr.sa6.sin6_scope_id;
+ if (scope != 0) { /* zero is default value, no need to set */
+ setInet6Address_scopeid(env, iaObj, scope);
+ setInet6Address_scopeifname(env, iaObj, netifObj);
+ }
+ ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
+ if (ibObj == NULL) {
+ free_netaddr(netaddrP);
+ return NULL;
+ }
+ (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
+ (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
+ (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
}
(*env)->SetObjectArrayElement(env, addrArr, addr_index, iaObj);
addrs = addrs->next;
--- a/jdk/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/TwoStacksPlainDatagramSocketImpl.c Wed Jul 05 22:22:15 2017 +0200
@@ -830,6 +830,7 @@
}
if (IS_NULL(addressObj)) {
JNU_ThrowNullPointerException(env, "Null address in peek()");
+ return -1;
} else {
address = getInetAddress_addr(env, addressObj);
/* We only handle IPv4 for now. Will support IPv6 once its in the os */
@@ -1127,11 +1128,23 @@
}
if (n == -1) {
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
+ if (packetBufferLen > MAX_BUFFER_LEN) {
+ free(fullPacket);
+ }
+ return -1;
} else if (n == -2) {
JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
"operation interrupted");
+ if (packetBufferLen > MAX_BUFFER_LEN) {
+ free(fullPacket);
+ }
+ return -1;
} else if (n < 0) {
NET_ThrowCurrent(env, "Datagram receive failed");
+ if (packetBufferLen > MAX_BUFFER_LEN) {
+ free(fullPacket);
+ }
+ return -1;
} else {
jobject packetAddress;
@@ -1882,7 +1895,7 @@
default :
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"Socket option not supported by PlainDatagramSocketImp");
- break;
+ return;
}
@@ -2325,6 +2338,7 @@
if (NET_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ittl,
sizeof (ittl)) < 0) {
NET_ThrowCurrent(env, "set IP_MULTICAST_TTL failed");
+ return;
}
}
@@ -2518,6 +2532,9 @@
} else {
ifindex = getIndexFromIf (env, niObj);
if (ifindex == -1) {
+ if ((*env)->ExceptionOccurred(env)) {
+ return;
+ }
NET_ThrowCurrent(env, "get ifindex failed");
return;
}
--- a/jdk/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/TwoStacksPlainSocketImpl.c Wed Jul 05 22:22:15 2017 +0200
@@ -108,7 +108,7 @@
psi_portID = (*env)->GetFieldID(env, cls, "port", "I");
CHECK_NULL(psi_portID);
psi_lastfdID = (*env)->GetFieldID(env, cls, "lastfd", "I");
- CHECK_NULL(psi_portID);
+ CHECK_NULL(psi_lastfdID);
psi_localportID = (*env)->GetFieldID(env, cls, "localport", "I");
CHECK_NULL(psi_localportID);
psi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I");
@@ -153,17 +153,17 @@
fd1Obj = (*env)->GetObjectField(env, this, psi_fd1ID);
if (IS_NULL(fd1Obj)) {
+ (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
+ NET_SocketClose(fd);
JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
"null fd1 object");
- (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
- NET_SocketClose(fd);
return;
}
fd1 = socket(AF_INET6, (stream ? SOCK_STREAM: SOCK_DGRAM), 0);
if (fd1 == -1) {
- NET_ThrowCurrent(env, "create");
(*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
NET_SocketClose(fd);
+ NET_ThrowCurrent(env, "create");
return;
} else {
/* Set socket attribute so it is not passed to any child process */
@@ -907,6 +907,7 @@
isRcvTimeoutSupported = JNI_FALSE;
} else {
NET_ThrowCurrent(env, "setsockopt SO_RCVTIMEO");
+ return;
}
}
if (fd1 != -1) {
--- a/jdk/src/java.base/windows/native/libnet/net_util_md.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnet/net_util_md.c Wed Jul 05 22:22:15 2017 +0200
@@ -205,9 +205,7 @@
void
NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
const char *defaultDetail) {
- char errmsg[255];
- sprintf(errmsg, "errno: %d, error: %s\n", WSAGetLastError(), defaultDetail);
- JNU_ThrowByNameWithLastError(env, name, errmsg);
+ JNU_ThrowByNameWithMessageAndLastError(env, name, defaultDetail);
}
jfieldID
--- a/jdk/src/java.base/windows/native/libnio/ch/FileDispatcherImpl.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.base/windows/native/libnio/ch/FileDispatcherImpl.c Wed Jul 05 22:22:15 2017 +0200
@@ -202,6 +202,7 @@
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
+ return IOS_THROWN;
}
return convertReturnVal(env, (jint)written, JNI_FALSE);
@@ -250,6 +251,7 @@
if ((h == INVALID_HANDLE_VALUE) || (result == 0)) {
JNU_ThrowIOExceptionWithLastError(env, "Write failed");
+ return IOS_THROWN;
}
return convertLongReturnVal(env, totalWritten, JNI_FALSE);
--- a/jdk/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_PCM.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_PCM.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -817,6 +817,10 @@
ERROR1("<<DAUDIO_Open: ERROR: unsupported encoding (%d)\n", encoding);
return NULL;
}
+ if (channels <= 0) {
+ ERROR1("<<DAUDIO_Open: ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
OSX_DirectAudioDevice *device = new OSX_DirectAudioDevice();
--- a/jdk/src/java.desktop/share/classes/sun/applet/AppletSecurity.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/applet/AppletSecurity.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, 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
@@ -40,36 +40,25 @@
import java.util.StringTokenizer;
import java.security.*;
import java.lang.reflect.*;
+import jdk.internal.misc.JavaNetURLClassLoaderAccess;
+import jdk.internal.misc.JavaSecurityAccess;
+import jdk.internal.misc.SharedSecrets;
import sun.awt.AWTSecurityManager;
import sun.awt.AppContext;
import sun.awt.AWTPermissions;
import sun.security.util.SecurityConstants;
+
/**
* This class defines an applet security policy
*
*/
public
class AppletSecurity extends AWTSecurityManager {
-
- //URLClassLoader.acc
- private static Field facc = null;
-
- //AccessControlContext.context;
- private static Field fcontext = null;
-
- static {
- try {
- facc = URLClassLoader.class.getDeclaredField("acc");
- facc.setAccessible(true);
- fcontext = AccessControlContext.class.getDeclaredField("context");
- fcontext.setAccessible(true);
- } catch (NoSuchFieldException e) {
- throw new UnsupportedOperationException(e);
- }
- }
-
+ private static final JavaNetURLClassLoaderAccess JNUCLA
+ = SharedSecrets.getJavaNetURLClassLoaderAccess();
+ private static final JavaSecurityAccess JSA = SharedSecrets.getJavaSecurityAccess();
/**
* Construct and initialize.
@@ -148,6 +137,7 @@
final ClassLoader currentLoader = context[i].getClassLoader();
if (currentLoader instanceof URLClassLoader) {
+ URLClassLoader ld = (URLClassLoader)currentLoader;
loader = AccessController.doPrivileged(
new PrivilegedAction<ClassLoader>() {
public ClassLoader run() {
@@ -156,12 +146,12 @@
ProtectionDomain[] pds = null;
try {
- acc = (AccessControlContext) facc.get(currentLoader);
+ acc = JNUCLA.getAccessControlContext(ld);
if (acc == null) {
return null;
}
- pds = (ProtectionDomain[]) fcontext.get(acc);
+ pds = JSA.getProtectDomains(acc);
if (pds == null) {
return null;
}
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -46,6 +46,7 @@
ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor(morphSubtableHeader, success), entryTable(), contextualGlyphSubstitutionHeader(morphSubtableHeader, success)
{
+ if (LE_FAILURE(success)) return;
contextualGlyphSubstitutionHeader.orphan();
substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset);
@@ -66,10 +67,10 @@
markGlyph = 0;
}
-ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
+ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success)
{
- LEErrorCode success = LE_NO_ERROR;
const ContextualGlyphSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
+ if (LE_FAILURE(success)) return 0;
ByteOffset newState = SWAPW(entry->newStateOffset);
le_int16 flags = SWAPW(entry->flags);
WordOffset markOffset = SWAPW(entry->markOffset);
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.h Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.h Wed Jul 05 22:22:15 2017 +0200
@@ -52,7 +52,7 @@
public:
virtual void beginStateTable();
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success);
virtual void endStateTable();
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -63,10 +63,10 @@
lastGlyph = 0;
}
-ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
+ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success)
{
- LEErrorCode success = LE_NO_ERROR; // todo- make a param?
- const IndicRearrangementStateEntry *entry = entryTable.getAlias(index,success);
+ const IndicRearrangementStateEntry *entry = entryTable.getAlias(index, success);
+ if (LE_FAILURE(success)) return 0;
ByteOffset newState = SWAPW(entry->newStateOffset);
IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.h Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.h Wed Jul 05 22:22:15 2017 +0200
@@ -52,7 +52,7 @@
public:
virtual void beginStateTable();
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success);
virtual void endStateTable();
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -67,9 +67,8 @@
m = -1;
}
-ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
+ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success)
{
- LEErrorCode success = LE_NO_ERROR;
const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
if (LE_FAILURE(success)) {
currGlyph++;
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.h Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.h Wed Jul 05 22:22:15 2017 +0200
@@ -54,7 +54,7 @@
public:
virtual void beginStateTable();
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success);
virtual void endStateTable();
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -81,6 +81,7 @@
while (currGlyph <= glyphCount) {
if(LE_STATE_PATIENCE_DECR()) break; // patience exceeded.
+ if (LE_FAILURE(success)) break;
ClassCode classCode = classCodeOOB;
if (currGlyph == glyphCount) {
// XXX: How do we handle EOT vs. EOL?
@@ -100,7 +101,7 @@
EntryTableIndex entryTableIndex = stateArray.getObject((le_uint8)classCode, success);
if (LE_FAILURE(success)) { break; }
LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
- currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
+ currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex, success);
LE_STATE_PATIENCE_INCR(currGlyph);
}
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.h Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.h Wed Jul 05 22:22:15 2017 +0200
@@ -53,7 +53,7 @@
virtual void beginStateTable() = 0;
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index) = 0;
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success) = 0;
virtual void endStateTable() = 0;
--- a/jdk/src/java.desktop/share/native/liblcms/cmsintrp.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsintrp.c Wed Jul 05 22:22:15 2017 +0200
@@ -244,7 +244,7 @@
// To prevent out of bounds indexing
cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v)
{
- return v < 0.0f ? 0.0f : (v > 1.0f ? 1.0f : v);
+ return v < 0.0f || v != v ? 0.0f : (v > 1.0f ? 1.0f : v);
}
// Floating-point version of 1D interpolation
--- a/jdk/src/java.desktop/share/native/liblcms/cmsio0.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsio0.c Wed Jul 05 22:22:15 2017 +0200
@@ -1543,6 +1543,13 @@
// If the element is already in memory, return the pointer
if (Icc -> TagPtrs[n]) {
+ if (Icc -> TagTypeHandlers[n] == NULL) goto Error;
+ BaseType = Icc -> TagTypeHandlers[n]->Signature;
+ if (BaseType == 0) goto Error;
+ TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
+ if (TagDescriptor == NULL) goto Error;
+ if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
+
if (Icc ->TagSaveAsRaw[n]) goto Error; // We don't support read raw tags as cooked
_cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
--- a/jdk/src/java.desktop/share/native/liblcms/cmstypes.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/share/native/liblcms/cmstypes.c Wed Jul 05 22:22:15 2017 +0200
@@ -4313,7 +4313,10 @@
// Copy MAX_INPUT_DIMENSIONS at most. Expand to cmsUInt32Number
nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? MAX_INPUT_DIMENSIONS : InputChans;
- for (i=0; i < nMaxGrids; i++) GridPoints[i] = (cmsUInt32Number) Dimensions8[i];
+ for (i=0; i < nMaxGrids; i++) {
+ if (Dimensions8[i] == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least
+ GridPoints[i] = (cmsUInt32Number)Dimensions8[i];
+ }
// Allocate the true CLUT
mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL);
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java Wed Jul 05 22:22:15 2017 +0200
@@ -102,10 +102,13 @@
int w, int h)
{
if (cachedData == null) {
- // Bitmask will be created lazily during the blit phase
- cachedData = X11SurfaceData.createData(x11gc, w, h,
- x11gc.getColorModel(),
- null, 0, getTransparency());
+ try {
+ // Bitmask will be created lazily during the blit phase
+ cachedData = X11SurfaceData.createData(x11gc, w, h,
+ x11gc.getColorModel(),
+ null, 0, getTransparency());
+ } catch (OutOfMemoryError oome) {
+ }
}
return cachedData;
}
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPMBlitLoops.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPMBlitLoops.java Wed Jul 05 22:22:15 2017 +0200
@@ -138,6 +138,9 @@
vImg = (SunVolatileImage) dst.getGraphicsConfig().createCompatibleVolatileImage(w, h, src.getTransparency());
vImg.setAccelerationPriority(1.0f);
+ if (!(vImg.getDestSurface() instanceof XRSurfaceData)) {
+ throw new InvalidPipeException("Could not create XRSurfaceData");
+ }
if (src.getTransparency() == SurfaceData.OPAQUE) {
rgbTmpPM = new WeakReference<SunVolatileImage>(vImg);
} else {
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java Wed Jul 05 22:22:15 2017 +0200
@@ -59,9 +59,12 @@
public SurfaceData validateSurfaceData(SurfaceData srcData,
SurfaceData cachedData, int w, int h) {
if (cachedData == null) {
- cachedData = XRSurfaceData.createData(xrgc, w, h,
- xrgc.getColorModel(), null, 0,
- getTransparency(), true);
+ try {
+ cachedData = XRSurfaceData.createData(xrgc, w, h,
+ xrgc.getColorModel(), null, 0,
+ getTransparency(), true);
+ } catch (OutOfMemoryError oome) {
+ }
}
return cachedData;
}
--- a/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c Wed Jul 05 22:22:15 2017 +0200
@@ -441,7 +441,7 @@
* width , height must be nonzero otherwise XCreatePixmap
* generates BadValue in error_handler
*/
- if (width <= 0 || height <= 0) {
+ if (width <= 0 || height <= 0 || width > 32767 || height > 32767) {
JNU_ThrowOutOfMemoryError(env,
"Can't create offscreen surface");
return JNI_FALSE;
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCM.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCM.c Wed Jul 05 22:22:15 2017 +0200
@@ -434,7 +434,10 @@
snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
}
#endif
-
+ if (channels <= 0) {
+ ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
if (!info) {
ERROR0("Out of memory\n");
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c Wed Jul 05 22:22:15 2017 +0200
@@ -434,7 +434,10 @@
snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
}
#endif
-
+ if (channels <= 0) {
+ ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
if (!info) {
ERROR0("Out of memory\n");
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c Wed Jul 05 22:22:15 2017 +0200
@@ -182,6 +182,10 @@
ERROR1(" DAUDIO_Open: invalid encoding %d\n", (int) encoding);
return NULL;
}
+ if (channels <= 0) {
+ ERROR1(" DAUDIO_Open: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
info = (SolPcmInfo*) malloc(sizeof(SolPcmInfo));
if (!info) {
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -153,6 +153,19 @@
@Override
public void setMenuBar(MenuBar mb) {
WMenuBarPeer mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(mb);
+ if (mbPeer != null) {
+ if (mbPeer.framePeer != this) {
+ mb.removeNotify();
+ mb.addNotify();
+ mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(mb);
+ if (mbPeer != null && mbPeer.framePeer != this) {
+ throw new IllegalStateException("Wrong parent peer");
+ }
+ }
+ if (mbPeer != null) {
+ addChildPeer(mbPeer);
+ }
+ }
setMenuBar0(mbPeer);
updateInsets(insets_);
}
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuBarPeer.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuBarPeer.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,8 @@
// MenuBarPeer implementation
+ final WFramePeer framePeer;
+
@Override
public native void addMenu(Menu m);
@Override
@@ -44,8 +46,11 @@
// Toolkit & peer internals
WMenuBarPeer(MenuBar target) {
this.target = target;
- WFramePeer framePeer = (WFramePeer)
+ framePeer = (WFramePeer)
WToolkit.targetToPeer(target.getParent());
+ if (framePeer != null) {
+ framePeer.addChildPeer(this);
+ }
create(framePeer);
// fix for 5088782: check if menu object is created successfully
checkMenuCreation();
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -107,6 +107,7 @@
this.target = target;
this.parent = (WMenuPeer) WToolkit.targetToPeer(target.getParent());
this.isCheckbox = isCheckbox;
+ parent.addChildPeer(this);
create(parent);
// fix for 5088782: check if menu object is created successfully
checkMenuCreation();
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuPeer.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuPeer.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -51,10 +51,12 @@
if (parent instanceof MenuBar) {
WMenuBarPeer mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(parent);
this.parent = mbPeer;
+ mbPeer.addChildPeer(this);
createMenu(mbPeer);
}
else if (parent instanceof Menu) {
this.parent = (WMenuPeer) WToolkit.targetToPeer(parent);
+ this.parent.addChildPeer(this);
createSubMenu(this.parent);
}
else {
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,9 @@
*/
package sun.awt.windows;
+import java.util.Map;
+import java.util.WeakHashMap;
+
abstract class WObjectPeer {
static {
@@ -45,6 +48,8 @@
// used to synchronize the state of this peer
private final Object stateLock = new Object();
+ private volatile Map<WObjectPeer, WObjectPeer> childPeers;
+
public static WObjectPeer getPeerForTarget(Object t) {
WObjectPeer peer = (WObjectPeer) WToolkit.targetToPeer(t);
return peer;
@@ -77,6 +82,9 @@
}
if (call_disposeImpl) {
+ if (childPeers != null) {
+ disposeChildPeers();
+ }
disposeImpl();
}
}
@@ -88,4 +96,33 @@
* Initialize JNI field and method IDs
*/
private static native void initIDs();
+
+ // if a child peer existence depends on this peer, add it to this collection
+ final void addChildPeer(WObjectPeer child) {
+ synchronized (getStateLock()) {
+ if (childPeers == null) {
+ childPeers = new WeakHashMap<>();
+ }
+ if (isDisposed()) {
+ throw new IllegalStateException("Parent peer is disposed");
+ }
+ childPeers.put(child, this);
+ }
+ }
+
+ // called to dispose dependent child peers
+ private void disposeChildPeers() {
+ synchronized (getStateLock()) {
+ for (WObjectPeer child : childPeers.keySet()) {
+ if (child != null) {
+ try {
+ child.dispose();
+ }
+ catch (Exception e) {
+ // ignored
+ }
+ }
+ }
+ }
+ }
}
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPopupMenuPeer.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPopupMenuPeer.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -58,6 +58,7 @@
parent = WToolkit.getNativeContainer((Component)parent);
parentPeer = (WComponentPeer) WToolkit.targetToPeer(parent);
}
+ parentPeer.addChildPeer(this);
createMenu(parentPeer);
// fix for 5088782: check if menu object is created successfully
checkMenuCreation();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -640,7 +640,7 @@
int AwtFont::getFontDescriptorNumber(JNIEnv *env, jobject font,
jobject fontDescriptor)
{
- int i, num;
+ int i, num = 0;
jobject refFontDescriptor;
jobjectArray array;
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -1113,11 +1113,19 @@
void AwtFrame::SetMenuBar(AwtMenuBar* mb)
{
+ if (menuBar) {
+ menuBar->SetFrame(NULL);
+ }
menuBar = mb;
if (mb == NULL) {
// Remove existing menu bar, if any.
::SetMenu(GetHWnd(), NULL);
} else {
+ AwtFrame* oldFrame = menuBar->GetFrame();
+ if (oldFrame && oldFrame != this) {
+ oldFrame->SetMenuBar(NULL);
+ }
+ menuBar->SetFrame(this);
if (menuBar->GetHMenu() != NULL) {
::SetMenu(GetHWnd(), menuBar->GetHMenu());
}
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -58,6 +58,9 @@
void AwtMenuBar::Dispose()
{
+ if (m_frame != NULL && m_frame->GetMenuBar() == this) {
+ m_frame->SetMenuBar(NULL);
+ }
m_frame = NULL;
AwtMenu::Dispose();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, 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
@@ -63,6 +63,9 @@
virtual AwtMenuBar* GetMenuBar() { return this; }
INLINE AwtFrame* GetFrame() { return m_frame; }
+ INLINE void SetFrame(AwtFrame* frame) {
+ m_frame = frame;
+ }
virtual HWND GetOwnerHWnd();
virtual void RedrawMenuBar();
--- a/jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -859,6 +859,10 @@
ERROR1("DAUDIO_Open: ERROR: cannot open the device with encoding=%d!\n", encoding);
return NULL;
}
+ if (channels <= 0) {
+ ERROR1("DAUDIO_Open: ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
if (sampleSizeInBits > 8 &&
#ifdef _LITTLE_ENDIAN
isBigEndian
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java Wed Jul 05 22:22:15 2017 +0200
@@ -39,8 +39,9 @@
}
protected Class<?> findClass(String name) throws ClassNotFoundException {
+ Class<?> cls;
try {
- return repository.loadClass(name);
+ cls = repository.loadClass(name);
} catch (ClassNotFoundException cne) {
if (cl2 != null) {
return cl2.loadClass(name);
@@ -48,6 +49,15 @@
throw cne;
}
}
+
+ if(!cls.getName().equals(name)){
+ if (cl2 != null) {
+ return cl2.loadClass(name);
+ } else {
+ throw new ClassNotFoundException(name);
+ }
+ }
+ return cls;
}
private ClassLoaderRepository repository;
--- a/jdk/src/java.scripting/share/classes/javax/script/ScriptContext.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptContext.java Wed Jul 05 22:22:15 2017 +0200
@@ -85,7 +85,8 @@
public Bindings getBindings(int scope);
/**
- * Sets the value of an attribute in a given scope.
+ * Sets the value of an attribute in a given scope. If the scope is <code>GLOBAL_SCOPE</code>
+ * and no Bindings is set for <code>GLOBAL_SCOPE</code>, then setAttribute call is a no-op.
*
* @param name The name of the attribute to set
* @param value The value of the attribute
--- a/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Wed Jul 05 22:22:15 2017 +0200
@@ -216,8 +216,9 @@
* @param statements The statements to be executed. May be return values of
* calls to the <code>getMethodCallSyntax</code> and <code>getOutputStatement</code> methods.
* @return The Program
+ *
+ * @throws NullPointerException if the <code>statements</code> array or any of its elements is null
*/
-
public String getProgram(String... statements);
/**
--- a/jdk/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java Wed Jul 05 22:22:15 2017 +0200
@@ -213,7 +213,8 @@
}
/**
- * Sets the value of an attribute in a given scope.
+ * Sets the value of an attribute in a given scope. If the scope is <code>GLOBAL_SCOPE</code>
+ * and no Bindings is set for <code>GLOBAL_SCOPE</code>, then setAttribute call is a no-op.
*
* @param name The name of the attribute to set
* @param value The value of the attribute
--- a/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java Wed Jul 05 22:22:15 2017 +0200
@@ -694,7 +694,7 @@
"Proxy Ticket " + flags[PROXY_TICKET_FLAG] + "\n" +
"Postdated Ticket " + flags[POSTDATED_TICKET_FLAG] + "\n" +
"Renewable Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
- "Initial Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
+ "Initial Ticket " + flags[INITIAL_TICKET_FLAG] + "\n" +
"Auth Time = " + String.valueOf(authTime) + "\n" +
"Start Time = " + String.valueOf(startTime) + "\n" +
"End Time = " + endTime.toString() + "\n" +
--- a/jdk/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -36,6 +36,7 @@
#include <BaseTsd.h>
#include <wincrypt.h>
#include <stdio.h>
+#include <memory>
#define OID_EKU_ANY "2.5.29.37.0"
@@ -48,6 +49,7 @@
#define KEYSTORE_EXCEPTION "java/security/KeyStoreException"
#define PROVIDER_EXCEPTION "java/security/ProviderException"
#define SIGNATURE_EXCEPTION "java/security/SignatureException"
+#define OUT_OF_MEMORY_ERROR "java/lang/OutOfMemoryError"
extern "C" {
@@ -57,10 +59,22 @@
DEF_STATIC_JNI_OnLoad
/*
+ * Throws an arbitrary Java exception with the given message.
+ */
+void ThrowExceptionWithMessage(JNIEnv *env, const char *exceptionName,
+ const char *szMessage)
+{
+ jclass exceptionClazz = env->FindClass(exceptionName);
+ if (exceptionClazz != NULL) {
+ env->ThrowNew(exceptionClazz, szMessage);
+ }
+}
+
+/*
* Throws an arbitrary Java exception.
* The exception message is a Windows system error message.
*/
-void ThrowException(JNIEnv *env, char *exceptionName, DWORD dwError)
+void ThrowException(JNIEnv *env, const char *exceptionName, DWORD dwError)
{
char szMessage[1024];
szMessage[0] = '\0';
@@ -71,12 +85,22 @@
strcpy(szMessage, "Unknown error");
}
- jclass exceptionClazz = env->FindClass(exceptionName);
- if (exceptionClazz != NULL) {
- env->ThrowNew(exceptionClazz, szMessage);
- }
+ ThrowExceptionWithMessage(env, exceptionName, szMessage);
}
+/*
+ * Overloaded 'operator new[]' variant, which will raise Java's
+ * OutOfMemoryError in the case of a failure.
+ */
+static void* operator new[](std::size_t size, JNIEnv *env)
+{
+ void* buf = ::operator new[](size, std::nothrow);
+ if (buf == NULL) {
+ ThrowExceptionWithMessage(env, OUT_OF_MEMORY_ERROR,
+ "Native memory allocation failed");
+ }
+ return buf;
+}
/*
* Maps the name of a hash algorithm to an algorithm identifier.
@@ -211,7 +235,10 @@
} else if (length > 0) {
- pbData = new BYTE[length];
+ pbData = new (env) BYTE[length];
+ if (pbData == NULL) {
+ __leave;
+ }
if (::CryptGenRandom(
hCryptProv,
@@ -441,7 +468,11 @@
NULL, 0)) > 1) {
// Found friendly name
- pszNameString = new char[cchNameString];
+ pszNameString = new (env) char[cchNameString];
+ if (pszNameString == NULL) {
+ __leave;
+ }
+
CertGetNameString(pc,
CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL,
pszNameString, cchNameString);
@@ -578,7 +609,10 @@
}
// Copy hash from Java to native buffer
- pHashBuffer = new jbyte[jHashSize];
+ pHashBuffer = new (env) jbyte[jHashSize];
+ if (pHashBuffer == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
// Set hash value in the hash object
@@ -616,7 +650,10 @@
__leave;
}
- pSignedHashBuffer = new jbyte[dwBufLen];
+ pSignedHashBuffer = new (env) jbyte[dwBufLen];
+ if (pSignedHashBuffer == NULL) {
+ __leave;
+ }
if (::CryptSignHash(hHash, dwKeySpec, NULL, dwFlags, (BYTE*)pSignedHashBuffer, &dwBufLen) == FALSE)
{
ThrowException(env, SIGNATURE_EXCEPTION, GetLastError());
@@ -704,9 +741,16 @@
}
// Copy hash and signedHash from Java to native buffer
- pHashBuffer = new jbyte[jHashSize];
+ pHashBuffer = new (env) jbyte[jHashSize];
+ if (pHashBuffer == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jHash, 0, jHashSize, pHashBuffer);
- pSignedHashBuffer = new jbyte[jSignedHashSize];
+
+ pSignedHashBuffer = new (env) jbyte[jSignedHashSize];
+ if (pSignedHashBuffer == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jSignedHash, 0, jSignedHashSize,
pSignedHashBuffer);
@@ -919,7 +963,10 @@
}
// Copy encoding from Java to native buffer
- pbCertEncoding = new jbyte[jCertEncodingSize];
+ pbCertEncoding = new (env) jbyte[jCertEncodingSize];
+ if (pbCertEncoding == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding);
// Create a certificate context from the encoded cert
@@ -932,7 +979,10 @@
// Set the certificate's friendly name
int size = env->GetStringLength(jCertAliasName);
- pszCertAliasName = new WCHAR[size + 1];
+ pszCertAliasName = new (env) WCHAR[size + 1];
+ if (pszCertAliasName == NULL) {
+ __leave;
+ }
jCertAliasChars = env->GetStringChars(jCertAliasName, NULL);
memcpy(pszCertAliasName, jCertAliasChars, size * sizeof(WCHAR));
@@ -970,7 +1020,10 @@
__leave;
}
- pszContainerName = new char[dwDataLen];
+ pszContainerName = new (env) char[dwDataLen];
+ if (pszContainerName == NULL) {
+ __leave;
+ }
if (! ::CryptGetProvParam(
(HCRYPTPROV) hCryptProv,
@@ -984,7 +1037,10 @@
}
// Convert to a wide char string
- pwszContainerName = new WCHAR[dwDataLen];
+ pwszContainerName = new (env) WCHAR[dwDataLen];
+ if (pwszContainerName == NULL) {
+ __leave;
+ }
if (mbstowcs(pwszContainerName, pszContainerName, dwDataLen) == 0) {
ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
@@ -1007,7 +1063,10 @@
__leave;
}
- pszProviderName = new char[dwDataLen];
+ pszProviderName = new (env) char[dwDataLen];
+ if (pszProviderName == NULL) {
+ __leave;
+ }
if (! ::CryptGetProvParam(
(HCRYPTPROV) hCryptProv,
@@ -1021,7 +1080,10 @@
}
// Convert to a wide char string
- pwszProviderName = new WCHAR[dwDataLen];
+ pwszProviderName = new (env) WCHAR[dwDataLen];
+ if (pwszProviderName == NULL) {
+ __leave;
+ }
if (mbstowcs(pwszProviderName, pszProviderName, dwDataLen) == 0) {
ThrowException(env, KEYSTORE_EXCEPTION, GetLastError());
@@ -1161,7 +1223,10 @@
}
// Copy encoding from Java to native buffer
- pbCertEncoding = new jbyte[jCertEncodingSize];
+ pbCertEncoding = new (env) jbyte[jCertEncodingSize];
+ if (pbCertEncoding == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jCertEncoding, 0, jCertEncodingSize, pbCertEncoding);
// Create a certificate context from the encoded cert
@@ -1184,7 +1249,10 @@
if ((cchNameString = ::CertGetNameString(pTBDCertContext,
CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0)) > 1) {
- pszNameString = new char[cchNameString];
+ pszNameString = new (env) char[cchNameString];
+ if (pszNameString == NULL) {
+ __leave;
+ }
::CertGetNameString(pTBDCertContext,
CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString,
@@ -1334,7 +1402,10 @@
continue; // not found
}
- pszNameString = new char[cchNameString];
+ pszNameString = new (env) char[cchNameString];
+ if (pszNameString == NULL) {
+ __leave;
+ }
if (::CertGetNameString(pCertContext,
CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszNameString,
@@ -1510,7 +1581,10 @@
__try
{
// Copy data from Java buffer to native buffer
- pData = new jbyte[dwBufLen];
+ pData = new (env) jbyte[dwBufLen];
+ if (pData == NULL) {
+ __leave;
+ }
env->GetByteArrayRegion(jData, 0, dwBufLen, pData);
if (doEncrypt == JNI_TRUE) {
@@ -1584,7 +1658,10 @@
__leave;
}
- pbKeyBlob = new BYTE[dwBlobLen];
+ pbKeyBlob = new (env) BYTE[dwBlobLen];
+ if (pbKeyBlob == NULL) {
+ __leave;
+ }
// Generate key blob
if (! ::CryptExportKey((HCRYPTKEY) hCryptKey, 0, PUBLICKEYBLOB, 0,
@@ -1638,8 +1715,12 @@
RSAPUBKEY* pRsaPubKey =
(RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC));
+
int len = sizeof(pRsaPubKey->pubexp);
- exponentBytes = new jbyte[len];
+ exponentBytes = new (env) jbyte[len];
+ if (exponentBytes == NULL) {
+ __leave;
+ }
// convert from little-endian while copying from blob
for (int i = 0, j = len - 1; i < len; i++, j--) {
@@ -1690,9 +1771,12 @@
RSAPUBKEY* pRsaPubKey =
(RSAPUBKEY *) (keyBlob + sizeof(PUBLICKEYSTRUC));
+
int len = pRsaPubKey->bitlen / 8;
-
- modulusBytes = new jbyte[len];
+ modulusBytes = new (env) jbyte[len];
+ if (modulusBytes == NULL) {
+ __leave;
+ }
BYTE * pbModulus =
(BYTE *) (keyBlob + sizeof(PUBLICKEYSTRUC) + sizeof(RSAPUBKEY));
@@ -1813,12 +1897,16 @@
(jKeyBitLength / 8);
}
- jbyte* jBlobBytes = new jbyte[jBlobLength];
+ jbyte* jBlobBytes = NULL;
jbyte* jBlobElement;
jbyteArray jBlob = NULL;
jsize jElementLength;
__try {
+ jBlobBytes = new (env) jbyte[jBlobLength];
+ if (jBlobBytes == NULL) {
+ __leave;
+ }
BLOBHEADER *pBlobHeader = (BLOBHEADER *) jBlobBytes;
if (bGeneratePrivateKeyBlob) {
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Config.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/Config.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,6 @@
import java.security.*;
-import sun.security.action.GetPropertyAction;
import sun.security.util.PropertyExpander;
import sun.security.pkcs11.wrapper.*;
@@ -58,15 +57,30 @@
// will accept single threaded modules regardless of the setting in their
// config files.
private static final boolean staticAllowSingleThreadedModules;
+ private static final String osName;
+ private static final String osArch;
static {
- String p = "sun.security.pkcs11.allowSingleThreadedModules";
- String s = AccessController.doPrivileged(new GetPropertyAction(p));
- if ("false".equalsIgnoreCase(s)) {
+ List<String> props = AccessController.doPrivileged(
+ new PrivilegedAction<>() {
+ @Override
+ public List<String> run() {
+ return List.of(
+ System.getProperty(
+ "sun.security.pkcs11.allowSingleThreadedModules",
+ "true"),
+ System.getProperty("os.name"),
+ System.getProperty("os.arch"));
+ }
+ }
+ );
+ if ("false".equalsIgnoreCase(props.get(0))) {
staticAllowSingleThreadedModules = false;
} else {
staticAllowSingleThreadedModules = true;
}
+ osName = props.get(1);
+ osArch = props.get(2);
}
private final static boolean DEBUG = false;
@@ -650,8 +664,6 @@
// replace "/$ISA/" with "/sparcv9/" on 64-bit Solaris SPARC
// and with "/amd64/" on Solaris AMD64.
// On all other platforms, just turn it into a "/"
- String osName = System.getProperty("os.name", "");
- String osArch = System.getProperty("os.arch", "");
String prefix = lib.substring(0, i);
String suffix = lib.substring(i + 5);
if (osName.equals("SunOS") && osArch.equals("sparcv9")) {
--- a/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/wrapper/Constants.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.crypto.pkcs11/share/classes/sun/security/pkcs11/wrapper/Constants.java Wed Jul 05 22:22:15 2017 +0200
@@ -58,7 +58,7 @@
*/
public class Constants {
- public static final String NEWLINE = System.getProperty("line.separator");
+ public static final String NEWLINE = System.lineSeparator();
public static final String INDENT = " ";
--- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java Wed Jul 05 22:22:15 2017 +0200
@@ -50,12 +50,13 @@
try {
// cannot use LoadLibraryAction because that would make the native
// library available to the bootclassloader, but we run in the
- // extension classloader.
- String osname = System.getProperty("os.name");
- if (osname.startsWith("SunOS")) {
- provProp = AccessController.doPrivileged
- (new PrivilegedAction<HashMap<String, ServiceDesc>>() {
- public HashMap<String, ServiceDesc> run() {
+ // platform classloader.
+ provProp = AccessController.doPrivileged
+ (new PrivilegedAction<>() {
+ @Override
+ public HashMap<String, ServiceDesc> run() {
+ String osname = System.getProperty("os.name");
+ if (osname.startsWith("SunOS")) {
try {
DEBUG = Boolean.parseBoolean(System.getProperty("com.oracle.security.ucrypto.debug"));
String javaHome = System.getProperty("java.home");
@@ -66,14 +67,13 @@
return new HashMap<>();
} catch (Error err) {
if (DEBUG) err.printStackTrace();
- return null;
} catch (SecurityException se) {
if (DEBUG) se.printStackTrace();
- return null;
}
}
- });
- }
+ return null;
+ }
+ });
if (provProp != null) {
boolean[] result = loadLibraries();
if (result.length == 2) {
--- a/jdk/src/jdk.httpserver/share/classes/module-info.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.httpserver/share/classes/module-info.java Wed Jul 05 22:22:15 2017 +0200
@@ -24,7 +24,6 @@
*/
module jdk.httpserver {
- requires java.logging;
exports com.sun.net.httpserver;
exports com.sun.net.httpserver.spi;
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ExchangeImpl.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ExchangeImpl.java Wed Jul 05 22:22:15 2017 +0200
@@ -29,7 +29,8 @@
import java.net.*;
import javax.net.ssl.*;
import java.util.*;
-import java.util.logging.Logger;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import java.text.*;
import com.sun.net.httpserver.*;
@@ -221,7 +222,7 @@
Logger logger = server.getLogger();
String msg = "sendResponseHeaders: rCode = "+ rCode
+ ": forcing contentLen = -1";
- logger.warning (msg);
+ logger.log (Level.WARNING, msg);
}
contentLen = -1;
}
@@ -234,7 +235,7 @@
final Logger logger = server.getLogger();
String msg =
"sendResponseHeaders: being invoked with a content length for a HEAD request";
- logger.warning (msg);
+ logger.log (Level.WARNING, msg);
}
noContentToSend = true;
contentLen = 0;
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpConnection.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpConnection.java Wed Jul 05 22:22:15 2017 +0200
@@ -28,7 +28,8 @@
import java.io.*;
import javax.net.ssl.*;
import java.nio.channels.*;
-import java.util.logging.Logger;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import com.sun.net.httpserver.*;
import com.sun.net.httpserver.spi.*;
@@ -119,7 +120,7 @@
}
closed = true;
if (logger != null && chan != null) {
- logger.finest ("Closing connection: " + chan.toString());
+ logger.log (Level.TRACE, "Closing connection: " + chan.toString());
}
if (!chan.isOpen()) {
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpContextImpl.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/HttpContextImpl.java Wed Jul 05 22:22:15 2017 +0200
@@ -26,7 +26,7 @@
package sun.net.httpserver;
import java.io.*;
import java.util.*;
-import java.util.logging.Logger;
+import java.lang.System.Logger;
import com.sun.net.httpserver.*;
import com.sun.net.httpserver.spi.*;
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerConfig.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerConfig.java Wed Jul 05 22:22:15 2017 +0200
@@ -25,7 +25,8 @@
package sun.net.httpserver;
-import java.util.logging.Logger;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import java.security.PrivilegedAction;
/**
@@ -115,7 +116,8 @@
if (System.getProperty("sun.net.httpserver.readTimeout")
!=null)
{
- logger.warning ("sun.net.httpserver.readTimeout "+
+ logger.log (Level.WARNING,
+ "sun.net.httpserver.readTimeout "+
"property is no longer used. "+
"Use sun.net.httpserver.maxReqTime instead."
);
@@ -123,7 +125,8 @@
if (System.getProperty("sun.net.httpserver.writeTimeout")
!=null)
{
- logger.warning ("sun.net.httpserver.writeTimeout "+
+ logger.log (Level.WARNING,
+ "sun.net.httpserver.writeTimeout "+
"property is no longer used. Use "+
"sun.net.httpserver.maxRspTime instead."
);
@@ -131,7 +134,8 @@
if (System.getProperty("sun.net.httpserver.selCacheTimeout")
!=null)
{
- logger.warning ("sun.net.httpserver.selCacheTimeout "+
+ logger.log (Level.WARNING,
+ "sun.net.httpserver.selCacheTimeout "+
"property is no longer used."
);
}
--- a/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java Wed Jul 05 22:22:15 2017 +0200
@@ -30,8 +30,8 @@
import java.nio.channels.*;
import java.util.*;
import java.util.concurrent.*;
-import java.util.logging.Logger;
-import java.util.logging.Level;
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
import javax.net.ssl.*;
import com.sun.net.httpserver.*;
import java.security.AccessController;
@@ -81,7 +81,7 @@
final static boolean timer1Enabled = MAX_REQ_TIME != -1 || MAX_RSP_TIME != -1;
private Timer timer, timer1;
- private Logger logger;
+ private final Logger logger;
private Thread dispatcherThread;
ServerImpl (
@@ -90,7 +90,7 @@
this.protocol = protocol;
this.wrapper = wrapper;
- this.logger = Logger.getLogger ("com.sun.net.httpserver");
+ this.logger = System.getLogger ("com.sun.net.httpserver");
ServerConfig.checkLegacyProperties (logger);
https = protocol.equalsIgnoreCase ("https");
this.address = addr;
@@ -115,12 +115,12 @@
if (timer1Enabled) {
timer1 = new Timer ("server-timer1", true);
timer1.schedule (new ServerTimerTask1(),TIMER_MILLIS,TIMER_MILLIS);
- logger.config ("HttpServer timer1 enabled period in ms: "+TIMER_MILLIS);
- logger.config ("MAX_REQ_TIME: "+MAX_REQ_TIME);
- logger.config ("MAX_RSP_TIME: "+MAX_RSP_TIME);
+ logger.log (Level.DEBUG, "HttpServer timer1 enabled period in ms: ", TIMER_MILLIS);
+ logger.log (Level.DEBUG, "MAX_REQ_TIME: "+MAX_REQ_TIME);
+ logger.log (Level.DEBUG, "MAX_RSP_TIME: "+MAX_RSP_TIME);
}
events = new LinkedList<Event>();
- logger.config ("HttpServer created "+protocol+" "+ addr);
+ logger.log (Level.DEBUG, "HttpServer created "+protocol+" "+ addr);
}
public void bind (InetSocketAddress addr, int backlog) throws IOException {
@@ -211,7 +211,7 @@
dispatcherThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
- logger.log(Level.FINER, "ServerImpl.stop: ", e);
+ logger.log (Level.TRACE, "ServerImpl.stop: ", e);
}
}
}
@@ -224,7 +224,7 @@
}
HttpContextImpl context = new HttpContextImpl (protocol, path, handler, this);
contexts.add (context);
- logger.config ("context created: " + path);
+ logger.log (Level.DEBUG, "context created: " + path);
return context;
}
@@ -234,7 +234,7 @@
}
HttpContextImpl context = new HttpContextImpl (protocol, path, null, this);
contexts.add (context);
- logger.config ("context created: " + path);
+ logger.log (Level.DEBUG, "context created: " + path);
return context;
}
@@ -243,7 +243,7 @@
throw new NullPointerException ("null path parameter");
}
contexts.remove (protocol, path);
- logger.config ("context removed: " + path);
+ logger.log (Level.DEBUG, "context removed: " + path);
}
public synchronized void removeContext (HttpContext context) throws IllegalArgumentException {
@@ -251,7 +251,7 @@
throw new IllegalArgumentException ("wrong HttpContext type");
}
contexts.remove ((HttpContextImpl)context);
- logger.config ("context removed: " + context.getPath());
+ logger.log (Level.DEBUG, "context removed: " + context.getPath());
}
public InetSocketAddress getAddress() {
@@ -310,7 +310,7 @@
}
} catch (IOException e) {
logger.log (
- Level.FINER, "Dispatcher (1)", e
+ Level.TRACE, "Dispatcher (1)", e
);
c.close();
}
@@ -331,7 +331,7 @@
idleConnections.add (c);
} catch (IOException e) {
dprint(e);
- logger.log(Level.FINER, "Dispatcher(8)", e);
+ logger.log (Level.TRACE, "Dispatcher(8)", e);
c.close();
}
}
@@ -416,9 +416,9 @@
// call the selector just to process the cancelled keys
selector.selectNow();
} catch (IOException e) {
- logger.log (Level.FINER, "Dispatcher (4)", e);
+ logger.log (Level.TRACE, "Dispatcher (4)", e);
} catch (Exception e) {
- logger.log (Level.FINER, "Dispatcher (7)", e);
+ logger.log (Level.TRACE, "Dispatcher (7)", e);
}
}
try {selector.close(); } catch (Exception e) {}
@@ -427,7 +427,7 @@
private void handleException (SelectionKey key, Exception e) {
HttpConnection conn = (HttpConnection)key.attachment();
if (e != null) {
- logger.log (Level.FINER, "Dispatcher (2)", e);
+ logger.log (Level.TRACE, "Dispatcher (2)", e);
}
closeConnection(conn);
}
@@ -439,10 +439,10 @@
Exchange t = new Exchange (chan, protocol, conn);
executor.execute (t);
} catch (HttpError e1) {
- logger.log (Level.FINER, "Dispatcher (4)", e1);
+ logger.log (Level.TRACE, "Dispatcher (4)", e1);
closeConnection(conn);
} catch (IOException e) {
- logger.log (Level.FINER, "Dispatcher (5)", e);
+ logger.log (Level.TRACE, "Dispatcher (5)", e);
closeConnection(conn);
}
}
@@ -522,7 +522,8 @@
newconnection = true;
if (https) {
if (sslContext == null) {
- logger.warning ("SSL connection received. No https contxt created");
+ logger.log (Level.WARNING,
+ "SSL connection received. No https contxt created");
throw new HttpError ("No SSL context established");
}
sslStreams = new SSLStreams (ServerImpl.this, sslContext, chan);
@@ -657,7 +658,7 @@
}
} catch (IOException e1) {
- logger.log (Level.FINER, "ServerImpl.Exchange (1)", e1);
+ logger.log (Level.TRACE, "ServerImpl.Exchange (1)", e1);
closeConnection(connection);
} catch (NumberFormatException e3) {
reject (Code.HTTP_BAD_REQUEST,
@@ -666,7 +667,7 @@
reject (Code.HTTP_BAD_REQUEST,
requestLine, "URISyntaxException thrown");
} catch (Exception e4) {
- logger.log (Level.FINER, "ServerImpl.Exchange (2)", e4);
+ logger.log (Level.TRACE, "ServerImpl.Exchange (2)", e4);
closeConnection(connection);
}
}
@@ -722,7 +723,7 @@
closeConnection(connection);
}
} catch (IOException e) {
- logger.log (Level.FINER, "ServerImpl.sendReply", e);
+ logger.log (Level.TRACE, "ServerImpl.sendReply", e);
closeConnection(connection);
}
}
@@ -730,7 +731,7 @@
}
void logReply (int code, String requestStr, String text) {
- if (!logger.isLoggable(Level.FINE)) {
+ if (!logger.isLoggable(Level.DEBUG)) {
return;
}
if (text == null) {
@@ -744,7 +745,7 @@
}
String message = r + " [" + code + " " +
Code.msg(code) + "] ("+text+")";
- logger.fine (message);
+ logger.log (Level.DEBUG, message);
}
long getTicks() {
@@ -843,7 +844,7 @@
}
}
for (HttpConnection c : toClose) {
- logger.log (Level.FINE, "closing: no request: " + c);
+ logger.log (Level.DEBUG, "closing: no request: " + c);
reqConnections.remove (c);
allConnections.remove (c);
c.close();
@@ -859,7 +860,7 @@
}
}
for (HttpConnection c : toClose) {
- logger.log (Level.FINE, "closing: no response: " + c);
+ logger.log (Level.DEBUG, "closing: no response: " + c);
rspConnections.remove (c);
allConnections.remove (c);
c.close();
@@ -870,13 +871,13 @@
}
void logStackTrace (String s) {
- logger.finest (s);
+ logger.log (Level.TRACE, s);
StringBuilder b = new StringBuilder ();
StackTraceElement[] e = Thread.currentThread().getStackTrace();
for (int i=0; i<e.length; i++) {
b.append (e[i].toString()).append("\n");
}
- logger.finest (b.toString());
+ logger.log (Level.TRACE, b.toString());
}
static long getTimeMillis(long secs) {
--- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java Wed Jul 05 22:22:15 2017 +0200
@@ -50,6 +50,9 @@
import jdk.security.jarsigner.JarSigner;
import jdk.security.jarsigner.JarSignerException;
+import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.SignerInfo;
+import sun.security.timestamp.TimestampToken;
import sun.security.tools.KeyStoreUtil;
import sun.security.x509.*;
import sun.security.util.*;
@@ -87,6 +90,15 @@
private static final long SIX_MONTHS = 180*24*60*60*1000L; //milliseconds
+ private static final DisabledAlgorithmConstraints DISABLED_CHECK =
+ new DisabledAlgorithmConstraints(
+ DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
+
+ private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET = Collections
+ .unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
+ private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET = Collections
+ .unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
+
// Attention:
// This is the entry that get launched by the security tool jarsigner.
public static void main(String args[]) throws Exception {
@@ -163,6 +175,8 @@
private Throwable chainNotValidatedReason = null;
+ private boolean seeWeak = false;
+
CertificateFactory certificateFactory;
CertPathValidator validator;
PKIXParameters pkixParameters;
@@ -628,6 +642,10 @@
{
boolean anySigned = false; // if there exists entry inside jar signed
JarFile jf = null;
+ Map<String,String> digestMap = new HashMap<>();
+ Map<String,PKCS7> sigMap = new HashMap<>();
+ Map<String,String> sigNameMap = new HashMap<>();
+ Map<String,String> unparsableSignatures = new HashMap<>();
try {
jf = new JarFile(jarName, true);
@@ -638,21 +656,50 @@
while (entries.hasMoreElements()) {
JarEntry je = entries.nextElement();
entriesVec.addElement(je);
- InputStream is = null;
- try {
- is = jf.getInputStream(je);
- while (is.read(buffer, 0, buffer.length) != -1) {
- // we just read. this will throw a SecurityException
- // if a signature/digest check fails.
- }
- } finally {
- if (is != null) {
- is.close();
+ try (InputStream is = jf.getInputStream(je)) {
+ String name = je.getName();
+ if (signatureRelated(name)
+ && SignatureFileVerifier.isBlockOrSF(name)) {
+ String alias = name.substring(name.lastIndexOf('/') + 1,
+ name.lastIndexOf('.'));
+ try {
+ if (name.endsWith(".SF")) {
+ Manifest sf = new Manifest(is);
+ boolean found = false;
+ for (Object obj : sf.getMainAttributes().keySet()) {
+ String key = obj.toString();
+ if (key.endsWith("-Digest-Manifest")) {
+ digestMap.put(alias,
+ key.substring(0, key.length() - 16));
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ unparsableSignatures.putIfAbsent(alias,
+ String.format(
+ rb.getString("history.unparsable"),
+ name));
+ }
+ } else {
+ sigNameMap.put(alias, name);
+ sigMap.put(alias, new PKCS7(is));
+ }
+ } catch (IOException ioe) {
+ unparsableSignatures.putIfAbsent(alias, String.format(
+ rb.getString("history.unparsable"), name));
+ }
+ } else {
+ while (is.read(buffer, 0, buffer.length) != -1) {
+ // we just read. this will throw a SecurityException
+ // if a signature/digest check fails.
+ }
}
}
}
Manifest man = jf.getManifest();
+ boolean hasSignature = false;
// The map to record display info, only used when -verbose provided
// key: signer info string
@@ -668,6 +715,10 @@
while (e.hasMoreElements()) {
JarEntry je = e.nextElement();
String name = je.getName();
+
+ hasSignature = hasSignature
+ || SignatureFileVerifier.isBlockOrSF(name);
+
CodeSigner[] signers = je.getCodeSigners();
boolean isSigned = (signers != null);
anySigned |= isSigned;
@@ -800,10 +851,11 @@
System.out.println(rb.getString(
".X.not.signed.by.specified.alias.es."));
}
- System.out.println();
}
- if (man == null)
+ if (man == null) {
+ System.out.println();
System.out.println(rb.getString("no.manifest."));
+ }
// If signer is a trusted cert or private entry in user's own
// keystore, it can be self-signed.
@@ -811,9 +863,103 @@
signerSelfSigned = false;
}
+ // Even if the verbose option is not specified, all out strings
+ // must be generated so seeWeak can be updated.
+ if (!digestMap.isEmpty()
+ || !sigMap.isEmpty()
+ || !unparsableSignatures.isEmpty()) {
+ if (verbose != null) {
+ System.out.println();
+ }
+ for (String s : sigMap.keySet()) {
+ if (!digestMap.containsKey(s)) {
+ unparsableSignatures.putIfAbsent(s, String.format(
+ rb.getString("history.nosf"), s));
+ }
+ }
+ for (String s : digestMap.keySet()) {
+ PKCS7 p7 = sigMap.get(s);
+ if (p7 != null) {
+ String history;
+ try {
+ SignerInfo si = p7.getSignerInfos()[0];
+ X509Certificate signer = si.getCertificate(p7);
+ String digestAlg = digestMap.get(s);
+ String sigAlg = AlgorithmId.makeSigAlg(
+ si.getDigestAlgorithmId().getName(),
+ si.getDigestEncryptionAlgorithmId().getName());
+ PublicKey key = signer.getPublicKey();
+ PKCS7 tsToken = si.getTsToken();
+ if (tsToken != null) {
+ SignerInfo tsSi = tsToken.getSignerInfos()[0];
+ X509Certificate tsSigner = tsSi.getCertificate(tsToken);
+ byte[] encTsTokenInfo = tsToken.getContentInfo().getData();
+ TimestampToken tsTokenInfo = new TimestampToken(encTsTokenInfo);
+ PublicKey tsKey = tsSigner.getPublicKey();
+ String tsDigestAlg = tsTokenInfo.getHashAlgorithm().getName();
+ String tsSigAlg = AlgorithmId.makeSigAlg(
+ tsSi.getDigestAlgorithmId().getName(),
+ tsSi.getDigestEncryptionAlgorithmId().getName());
+ Calendar c = Calendar.getInstance(
+ TimeZone.getTimeZone("UTC"),
+ Locale.getDefault(Locale.Category.FORMAT));
+ c.setTime(tsTokenInfo.getDate());
+ history = String.format(
+ rb.getString("history.with.ts"),
+ signer.getSubjectX500Principal(),
+ withWeak(digestAlg, DIGEST_PRIMITIVE_SET),
+ withWeak(sigAlg, SIG_PRIMITIVE_SET),
+ withWeak(key),
+ c,
+ tsSigner.getSubjectX500Principal(),
+ withWeak(tsDigestAlg, DIGEST_PRIMITIVE_SET),
+ withWeak(tsSigAlg, SIG_PRIMITIVE_SET),
+ withWeak(tsKey));
+ } else {
+ history = String.format(
+ rb.getString("history.without.ts"),
+ signer.getSubjectX500Principal(),
+ withWeak(digestAlg, DIGEST_PRIMITIVE_SET),
+ withWeak(sigAlg, SIG_PRIMITIVE_SET),
+ withWeak(key));
+ }
+ } catch (Exception e) {
+ // The only usage of sigNameMap, remember the name
+ // of the block file if it's invalid.
+ history = String.format(
+ rb.getString("history.unparsable"),
+ sigNameMap.get(s));
+ }
+ if (verbose != null) {
+ System.out.println(history);
+ }
+ } else {
+ unparsableSignatures.putIfAbsent(s, String.format(
+ rb.getString("history.nobk"), s));
+ }
+ }
+ if (verbose != null) {
+ for (String s : unparsableSignatures.keySet()) {
+ System.out.println(unparsableSignatures.get(s));
+ }
+ }
+ }
+ System.out.println();
if (!anySigned) {
- System.out.println(rb.getString(
- "jar.is.unsigned.signatures.missing.or.not.parsable."));
+ if (seeWeak) {
+ if (verbose != null) {
+ System.out.println(rb.getString("jar.treated.unsigned.see.weak.verbose"));
+ System.out.println("\n " +
+ DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS +
+ "=" + Security.getProperty(DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS));
+ } else {
+ System.out.println(rb.getString("jar.treated.unsigned.see.weak"));
+ }
+ } else if (hasSignature) {
+ System.out.println(rb.getString("jar.treated.unsigned"));
+ } else {
+ System.out.println(rb.getString("jar.is.unsigned"));
+ }
} else {
boolean warningAppeared = false;
boolean errorAppeared = false;
@@ -837,7 +983,9 @@
if (weakAlg != 0) {
// In fact, jarsigner verification did not catch this
// since it has not read the JarFile content itself.
- // Everything is done with JarFile API.
+ // Everything is done with JarFile API. The signing
+ // history (digestMap etc) will show these info and
+ // print out proper warnings.
}
if (badKeyUsage) {
@@ -928,6 +1076,26 @@
System.exit(1);
}
+ private String withWeak(String alg, Set<CryptoPrimitive> primitiveSet) {
+ if (DISABLED_CHECK.permits(primitiveSet, alg, null)) {
+ return alg;
+ } else {
+ seeWeak = true;
+ return String.format(rb.getString("with.weak"), alg);
+ }
+ }
+
+ private String withWeak(PublicKey key) {
+ if (DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
+ return String.format(
+ rb.getString("key.bit"), KeyUtil.getKeySize(key));
+ } else {
+ seeWeak = true;
+ return String.format(
+ rb.getString("key.bit.weak"), KeyUtil.getKeySize(key));
+ }
+ }
+
private static MessageFormat validityTimeForm = null;
private static MessageFormat notYetTimeForm = null;
private static MessageFormat expiredTimeForm = null;
@@ -1117,22 +1285,22 @@
void signJar(String jarName, String alias)
throws Exception {
- DisabledAlgorithmConstraints dac =
- new DisabledAlgorithmConstraints(
- DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
-
- if (digestalg != null && !dac.permits(
- Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), digestalg, null)) {
+ if (digestalg != null && !DISABLED_CHECK.permits(
+ DIGEST_PRIMITIVE_SET, digestalg, null)) {
weakAlg |= 1;
}
- if (tSADigestAlg != null && !dac.permits(
- Collections.singleton(CryptoPrimitive.MESSAGE_DIGEST), tSADigestAlg, null)) {
+ if (tSADigestAlg != null && !DISABLED_CHECK.permits(
+ DIGEST_PRIMITIVE_SET, tSADigestAlg, null)) {
weakAlg |= 4;
}
- if (sigalg != null && !dac.permits(
- Collections.singleton(CryptoPrimitive.SIGNATURE), sigalg, null)) {
+ if (sigalg != null && !DISABLED_CHECK.permits(
+ SIG_PRIMITIVE_SET , sigalg, null)) {
weakAlg |= 2;
}
+ if (!DISABLED_CHECK.permits(
+ SIG_PRIMITIVE_SET, privateKey)) {
+ weakAlg |= 8;
+ }
boolean aliasUsed = false;
X509Certificate tsaCert = null;
@@ -1377,6 +1545,11 @@
rb.getString("The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk."),
tSADigestAlg, "-tsadigestalg"));
}
+ if ((weakAlg & 8) == 8) {
+ System.out.println(String.format(
+ rb.getString("The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk."),
+ privateKey.getAlgorithm(), KeyUtil.getKeySize(privateKey)));
+ }
} else {
System.out.println(rb.getString("jar.signed."));
}
--- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java Wed Jul 05 22:22:15 2017 +0200
@@ -142,12 +142,29 @@
{"no.manifest.", "no manifest."},
{".Signature.related.entries.","(Signature related entries)"},
{".Unsigned.entries.", "(Unsigned entries)"},
- {"jar.is.unsigned.signatures.missing.or.not.parsable.",
- "jar is unsigned. (signatures missing or not parsable)"},
+ {"jar.is.unsigned",
+ "jar is unsigned."},
+ {"jar.treated.unsigned",
+ "WARNING: Signature is either not parsable or not verifiable, and the jar will be treated as unsigned. For more information, re-run jarsigner with debug enabled (-J-Djava.security.debug=jar)."},
+ {"jar.treated.unsigned.see.weak",
+ "The jar will be treated as unsigned, because it is signed with a weak algorithm that is now disabled.\n\nRe-run jarsigner with the -verbose option for more details."},
+ {"jar.treated.unsigned.see.weak.verbose",
+ "WARNING: The jar will be treated as unsigned, because it is signed with a weak algorithm that is now disabled by the security property:"},
{"jar.signed.", "jar signed."},
{"jar.signed.with.signer.errors.", "jar signed, with signer errors."},
{"jar.verified.", "jar verified."},
{"jar.verified.with.signer.errors.", "jar verified, with signer errors."},
+
+ {"history.with.ts", "- Signed by \"%1$s\"\n Digest algorithm: %2$s\n Signature algorithm: %3$s, %4$s\n Timestamped by \"%6$s\" on %5$tc\n Timestamp digest algorithm: %7$s\n Timestamp signature algorithm: %8$s, %9$s"},
+ {"history.without.ts", "- Signed by \"%1$s\"\n Digest algorithm: %2$s\n Signature algorithm: %3$s, %4$s"},
+ {"history.unparsable", "- Unparsable signature-related file %s"},
+ {"history.nosf", "- Missing signature-related file META-INF/%s.SF"},
+ {"history.nobk", "- Missing block file for signature-related file META-INF/%s.SF"},
+
+ {"with.weak", "%s (weak)"},
+ {"key.bit", "%d-bit key"},
+ {"key.bit.weak", "%d-bit key (weak)"},
+
{"jarsigner.", "jarsigner: "},
{"signature.filename.must.consist.of.the.following.characters.A.Z.0.9.or.",
"signature filename must consist of the following characters: A-Z, 0-9, _ or -"},
@@ -246,6 +263,8 @@
"The signer's certificate is self-signed."},
{"The.1.algorithm.specified.for.the.2.option.is.considered.a.security.risk.",
"The %1$s algorithm specified for the %2$s option is considered a security risk."},
+ {"The.1.signing.key.has.a.keysize.of.2.which.is.considered.a.security.risk.",
+ "The %s signing key has a keysize of %d which is considered a security risk."},
{"This.jar.contains.entries.whose.certificate.chain.is.not.validated.reason.1",
"This jar contains entries whose certificate chain is not validated. Reason: %s"},
{"no.timestamp.signing",
--- a/jdk/src/jdk.jdwp.agent/share/native/include/jdwpTransport.h Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jdwp.agent/share/native/include/jdwpTransport.h Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, 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
@@ -96,6 +96,11 @@
*/
enum {
+ /*
+ * If additional flags are added that apply to jdwpCmdPacket,
+ * then debugLoop.c: reader() will need to be updated to
+ * accept more than JDWPTRANSPORT_FLAGS_NONE.
+ */
JDWPTRANSPORT_FLAGS_NONE = 0x0,
JDWPTRANSPORT_FLAGS_REPLY = 0x80
};
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugLoop.c Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugLoop.c Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, 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
@@ -218,6 +218,20 @@
if (rc != 0 || (rc == 0 && packet.type.cmd.len == 0)) {
shouldListen = JNI_FALSE;
notifyTransportError();
+ } else if (packet.type.cmd.flags != JDWPTRANSPORT_FLAGS_NONE) {
+ /*
+ * Close the connection when we get a jdwpCmdPacket with an
+ * invalid flags field value. This is a protocol violation
+ * so we drop the connection. Also this could be a web
+ * browser generating an HTTP request that passes the JDWP
+ * handshake. HTTP requests requires that everything be in
+ * the ASCII printable range so a flags value of
+ * JDWPTRANSPORT_FLAGS_NONE(0) cannot be generated via HTTP.
+ */
+ ERROR_MESSAGE(("Received jdwpPacket with flags != 0x%d (actual=0x%x) when a jdwpCmdPacket was expected.",
+ JDWPTRANSPORT_FLAGS_NONE, packet.type.cmd.flags));
+ shouldListen = JNI_FALSE;
+ notifyTransportError();
} else {
cmd = &packet.type.cmd;
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/Jlink.java Thu Oct 20 18:38:09 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jlink;
-
-import java.lang.reflect.Layer;
-import java.nio.ByteOrder;
-import java.nio.file.Path;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import jdk.tools.jlink.internal.ExecutableImage;
-import jdk.tools.jlink.internal.JlinkTask;
-import jdk.tools.jlink.plugin.Plugin;
-import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.builder.ImageBuilder;
-import jdk.tools.jlink.internal.PluginRepository;
-
-/**
- * API to call jlink.
- */
-public final class Jlink {
-
- /**
- * Create a plugin.
- *
- * @param name Plugin name
- * @param configuration Plugin configuration.
- * @param pluginsLayer Plugins Layer. null means boot layer.
- * @return A new plugin or null if plugin is unknown.
- */
- public static Plugin newPlugin(String name,
- Map<String, String> configuration, Layer pluginsLayer) {
- Objects.requireNonNull(name);
- Objects.requireNonNull(configuration);
- pluginsLayer = pluginsLayer == null ? Layer.boot() : pluginsLayer;
- return PluginRepository.newPlugin(configuration, name, pluginsLayer);
- }
-
- /**
- * A complete plugin configuration. Instances of this class are used to
- * configure jlink.
- */
- public static final class PluginsConfiguration {
-
- private final List<Plugin> plugins;
- private final ImageBuilder imageBuilder;
- private final String lastSorterPluginName;
-
- /**
- * Empty plugins configuration.
- */
- public PluginsConfiguration() {
- this(Collections.emptyList());
- }
-
- /**
- * Plugins configuration.
- *
- * @param plugins List of plugins.
- */
- public PluginsConfiguration(List<Plugin> plugins) {
- this(plugins, null, null);
- }
-
- /**
- * Plugins configuration with a last sorter and an ImageBuilder. No
- * sorting can occur after the last sorter plugin. The ImageBuilder is
- * in charge to layout the image content on disk.
- *
- * @param plugins List of transformer plugins.
- * @param imageBuilder Image builder.
- * @param lastSorterPluginName Name of last sorter plugin, no sorting
- * can occur after it.
- */
- public PluginsConfiguration(List<Plugin> plugins,
- ImageBuilder imageBuilder, String lastSorterPluginName) {
- this.plugins = plugins == null ? Collections.emptyList()
- : plugins;
- this.imageBuilder = imageBuilder;
- this.lastSorterPluginName = lastSorterPluginName;
- }
-
- /**
- * @return the plugins
- */
- public List<Plugin> getPlugins() {
- return plugins;
- }
-
- /**
- * @return the imageBuilder
- */
- public ImageBuilder getImageBuilder() {
- return imageBuilder;
- }
-
- /**
- * @return the lastSorterPluginName
- */
- public String getLastSorterPluginName() {
- return lastSorterPluginName;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("imagebuilder=").append(imageBuilder).append("\n");
- StringBuilder pluginsBuilder = new StringBuilder();
- for (Plugin p : plugins) {
- pluginsBuilder.append(p).append(",");
- }
- builder.append("plugins=").append(pluginsBuilder).append("\n");
- builder.append("lastsorter=").append(lastSorterPluginName).append("\n");
-
- return builder.toString();
- }
- }
-
- /**
- * Jlink configuration. Instances of this class are used to configure jlink.
- */
- public static final class JlinkConfiguration {
-
- private final List<Path> modulepaths;
- private final Path output;
- private final Set<String> modules;
- private final Set<String> limitmods;
-
- private final ByteOrder endian;
-
- /**
- * jlink configuration,
- *
- * @param output Output directory, must not exist.
- * @param modulepaths Modules paths
- * @param modules Root modules to resolve
- * @param limitmods Limit the universe of observable modules
- * @param endian Jimage byte order. Native order by default
- */
- public JlinkConfiguration(Path output,
- List<Path> modulepaths,
- Set<String> modules,
- Set<String> limitmods,
- ByteOrder endian) {
- this.output = output;
- this.modulepaths = modulepaths == null ? Collections.emptyList() : modulepaths;
- this.modules = modules == null ? Collections.emptySet() : modules;
- this.limitmods = limitmods == null ? Collections.emptySet() : limitmods;
- this.endian = endian == null ? ByteOrder.nativeOrder() : endian;
- }
-
- /**
- * jlink configuration,
- *
- * @param output Output directory, must not exist.
- * @param modulepaths Modules paths
- * @param modules Root modules to resolve
- * @param limitmods Limit the universe of observable modules
- */
- public JlinkConfiguration(Path output,
- List<Path> modulepaths,
- Set<String> modules,
- Set<String> limitmods) {
- this(output, modulepaths, modules, limitmods,
- ByteOrder.nativeOrder());
- }
-
- /**
- * @return the modulepaths
- */
- public List<Path> getModulepaths() {
- return modulepaths;
- }
-
- /**
- * @return the byte ordering
- */
- public ByteOrder getByteOrder() {
- return endian;
- }
-
- /**
- * @return the output
- */
- public Path getOutput() {
- return output;
- }
-
- /**
- * @return the modules
- */
- public Set<String> getModules() {
- return modules;
- }
-
- /**
- * @return the limitmods
- */
- public Set<String> getLimitmods() {
- return limitmods;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
-
- builder.append("output=").append(output).append("\n");
- StringBuilder pathsBuilder = new StringBuilder();
- for (Path p : modulepaths) {
- pathsBuilder.append(p).append(",");
- }
- builder.append("modulepaths=").append(pathsBuilder).append("\n");
-
- StringBuilder modsBuilder = new StringBuilder();
- for (String p : modules) {
- modsBuilder.append(p).append(",");
- }
- builder.append("modules=").append(modsBuilder).append("\n");
-
- StringBuilder limitsBuilder = new StringBuilder();
- for (String p : limitmods) {
- limitsBuilder.append(p).append(",");
- }
- builder.append("limitmodules=").append(limitsBuilder).append("\n");
- builder.append("endian=").append(endian).append("\n");
- return builder.toString();
- }
- }
-
- /**
- * Jlink instance constructor, if a security manager is set, the jlink
- * permission is checked.
- */
- public Jlink() {
- if (System.getSecurityManager() != null) {
- System.getSecurityManager().
- checkPermission(new JlinkPermission("jlink"));
- }
- }
-
- /**
- * Build the image.
- *
- * @param config Jlink config, must not be null.
- * @throws PluginException
- */
- public void build(JlinkConfiguration config) {
- build(config, null);
- }
-
- /**
- * Build the image with a plugin configuration.
- *
- * @param config Jlink config, must not be null.
- * @param pluginsConfig Plugins config, can be null
- * @throws PluginException
- */
- public void build(JlinkConfiguration config, PluginsConfiguration pluginsConfig) {
- Objects.requireNonNull(config);
- try {
- JlinkTask.createImage(config, pluginsConfig);
- } catch (Exception ex) {
- throw new PluginException(ex);
- }
- }
-
- /**
- * Post process the image with a plugin configuration.
- *
- * @param image Existing image.
- * @param plugins Plugins cannot be null
- */
- public void postProcess(ExecutableImage image, List<Plugin> plugins) {
- Objects.requireNonNull(image);
- Objects.requireNonNull(plugins);
- try {
- JlinkTask.postProcessImage(image, plugins);
- } catch (Exception ex) {
- throw new PluginException(ex);
- }
- }
-}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/JlinkPermission.java Thu Oct 20 18:38:09 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jlink;
-
-import java.security.BasicPermission;
-
-/**
- * The permission required to use jlink API. The permission target_name is
- * "jlink". e.g.: permission jdk.tools.jlink.plugins.JlinkPermission "jlink";
- *
- */
-public final class JlinkPermission extends BasicPermission {
-
- private static final long serialVersionUID = -3687912306077727801L;
-
- public JlinkPermission(String name) {
- super(name);
- }
-
-}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Wed Jul 05 22:22:15 2017 +0200
@@ -37,17 +37,17 @@
import java.io.UncheckedIOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
-import java.io.UncheckedIOException;
import java.io.Writer;
import java.lang.module.ModuleDescriptor;
import java.nio.charset.StandardCharsets;
+import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
-import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
-import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -55,7 +55,8 @@
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
-import java.util.stream.Collectors;
+import static java.util.stream.Collectors.*;
+
import jdk.tools.jlink.internal.BasicImageWriter;
import jdk.tools.jlink.internal.plugins.FileCopierPlugin.SymImageFile;
import jdk.tools.jlink.internal.ExecutableImage;
@@ -171,15 +172,36 @@
Properties release = releaseProperties(files);
Path bin = root.resolve("bin");
- files.entries().forEach(f -> {
- if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
+ // check any duplicated resource files
+ Map<Path, Set<String>> duplicates = new HashMap<>();
+ files.entries()
+ .filter(f -> f.type() != ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+ .collect(groupingBy(this::entryToImagePath,
+ mapping(ResourcePoolEntry::moduleName, toSet())))
+ .entrySet()
+ .stream()
+ .filter(e -> e.getValue().size() > 1)
+ .forEach(e -> duplicates.put(e.getKey(), e.getValue()));
+
+ // write non-classes resource files to the image
+ files.entries()
+ .filter(f -> f.type() != ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+ .forEach(f -> {
try {
accept(f);
+ } catch (FileAlreadyExistsException e) {
+ // error for duplicated entries
+ Path path = entryToImagePath(f);
+ UncheckedIOException x =
+ new UncheckedIOException(path + " duplicated in " +
+ duplicates.get(path), e);
+ x.addSuppressed(e);
+ throw x;
} catch (IOException ioExp) {
throw new UncheckedIOException(ioExp);
}
- }
- });
+ });
+
files.moduleView().modules().forEach(m -> {
// Only add modules that contain packages
if (!m.packages().isEmpty()) {
@@ -226,7 +248,7 @@
version().
stream().
map(Object::toString).
- collect(Collectors.joining("."));
+ collect(joining("."));
}
private static String quote(String str) {
@@ -344,28 +366,69 @@
}
}
+ /**
+ * Returns the file name of this entry
+ */
+ private String entryToFileName(ResourcePoolEntry entry) {
+ if (entry.type() == ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+ throw new IllegalArgumentException("invalid type: " + entry);
+
+ String module = "/" + entry.moduleName() + "/";
+ String filename = entry.path().substring(module.length());
+ // Remove radical native|config|...
+ return filename.substring(filename.indexOf('/') + 1);
+ }
+
+ /**
+ * Returns the path of the given entry to be written in the image
+ */
+ private Path entryToImagePath(ResourcePoolEntry entry) {
+ switch (entry.type()) {
+ case NATIVE_LIB:
+ String filename = entryToFileName(entry);
+ return Paths.get(nativeDir(filename), filename);
+ case NATIVE_CMD:
+ return Paths.get("bin", entryToFileName(entry));
+ case CONFIG:
+ return Paths.get("conf", entryToFileName(entry));
+ case HEADER_FILE:
+ return Paths.get("include", entryToFileName(entry));
+ case MAN_PAGE:
+ return Paths.get("man", entryToFileName(entry));
+ case TOP:
+ return Paths.get(entryToFileName(entry));
+ case OTHER:
+ return Paths.get("other", entryToFileName(entry));
+ default:
+ throw new IllegalArgumentException("invalid type: " + entry);
+ }
+ }
+
private void accept(ResourcePoolEntry file) throws IOException {
- String fullPath = file.path();
- String module = "/" + file.moduleName() + "/";
- String filename = fullPath.substring(module.length());
- // Remove radical native|config|...
- filename = filename.substring(filename.indexOf('/') + 1);
try (InputStream in = file.content()) {
switch (file.type()) {
case NATIVE_LIB:
- writeEntry(in, destFile(nativeDir(filename), filename));
+ Path dest = root.resolve(entryToImagePath(file));
+ writeEntry(in, dest);
break;
case NATIVE_CMD:
- Path path = destFile("bin", filename);
- writeEntry(in, path);
- path.toFile().setExecutable(true);
+ Path p = root.resolve(entryToImagePath(file));
+ writeEntry(in, p);
+ p.toFile().setExecutable(true);
break;
case CONFIG:
- writeEntry(in, destFile("conf", filename));
+ writeEntry(in, root.resolve(entryToImagePath(file)));
+ break;
+ case HEADER_FILE:
+ writeEntry(in, root.resolve(entryToImagePath(file)));
+ break;
+ case MAN_PAGE:
+ writeEntry(in, root.resolve(entryToImagePath(file)));
break;
case TOP:
break;
case OTHER:
+ String filename = entryToFileName(file);
if (file instanceof SymImageFile) {
SymImageFile sym = (SymImageFile) file;
Path target = root.resolve(sym.getTargetPath());
@@ -379,15 +442,11 @@
}
break;
default:
- throw new InternalError("unexpected entry: " + fullPath);
+ throw new InternalError("unexpected entry: " + file.path());
}
}
}
- private Path destFile(String dir, String filename) {
- return root.resolve(dir).resolve(filename);
- }
-
private void writeEntry(InputStream in, Path dstFile) throws IOException {
Objects.requireNonNull(in);
Objects.requireNonNull(dstFile);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Archive.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Archive.java Wed Jul 05 22:22:15 2017 +0200
@@ -44,9 +44,11 @@
public static enum EntryType {
MODULE_NAME,
CLASS_OR_RESOURCE,
+ CONFIG,
NATIVE_LIB,
NATIVE_CMD,
- CONFIG,
+ HEADER_FILE,
+ MAN_PAGE,
SERVICE;
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ArchiveEntryResourcePoolEntry.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ArchiveEntryResourcePoolEntry.java Wed Jul 05 22:22:15 2017 +0200
@@ -73,6 +73,10 @@
return ResourcePoolEntry.Type.NATIVE_CMD;
case NATIVE_LIB:
return ResourcePoolEntry.Type.NATIVE_LIB;
+ case HEADER_FILE:
+ return ResourcePoolEntry.Type.HEADER_FILE;
+ case MAN_PAGE:
+ return ResourcePoolEntry.Type.MAN_PAGE;
default:
return ResourcePoolEntry.Type.OTHER;
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java Wed Jul 05 22:22:15 2017 +0200
@@ -33,7 +33,6 @@
import java.util.Map;
import java.util.Map.Entry;
import jdk.tools.jlink.builder.ImageBuilder;
-import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Plugin.Category;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Jlink.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.internal;
+
+import java.lang.reflect.Layer;
+import java.nio.ByteOrder;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import jdk.tools.jlink.plugin.Plugin;
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.builder.ImageBuilder;
+
+/**
+ * API to call jlink.
+ */
+public final class Jlink {
+
+ /**
+ * Create a plugin.
+ *
+ * @param name Plugin name
+ * @param configuration Plugin configuration.
+ * @param pluginsLayer Plugins Layer. null means boot layer.
+ * @return A new plugin or null if plugin is unknown.
+ */
+ public static Plugin newPlugin(String name,
+ Map<String, String> configuration, Layer pluginsLayer) {
+ Objects.requireNonNull(name);
+ Objects.requireNonNull(configuration);
+ pluginsLayer = pluginsLayer == null ? Layer.boot() : pluginsLayer;
+ return PluginRepository.newPlugin(configuration, name, pluginsLayer);
+ }
+
+ /**
+ * A complete plugin configuration. Instances of this class are used to
+ * configure jlink.
+ */
+ public static final class PluginsConfiguration {
+
+ private final List<Plugin> plugins;
+ private final ImageBuilder imageBuilder;
+ private final String lastSorterPluginName;
+
+ /**
+ * Empty plugins configuration.
+ */
+ public PluginsConfiguration() {
+ this(Collections.emptyList());
+ }
+
+ /**
+ * Plugins configuration.
+ *
+ * @param plugins List of plugins.
+ */
+ public PluginsConfiguration(List<Plugin> plugins) {
+ this(plugins, null, null);
+ }
+
+ /**
+ * Plugins configuration with a last sorter and an ImageBuilder. No
+ * sorting can occur after the last sorter plugin. The ImageBuilder is
+ * in charge to layout the image content on disk.
+ *
+ * @param plugins List of transformer plugins.
+ * @param imageBuilder Image builder.
+ * @param lastSorterPluginName Name of last sorter plugin, no sorting
+ * can occur after it.
+ */
+ public PluginsConfiguration(List<Plugin> plugins,
+ ImageBuilder imageBuilder, String lastSorterPluginName) {
+ this.plugins = plugins == null ? Collections.emptyList()
+ : plugins;
+ this.imageBuilder = imageBuilder;
+ this.lastSorterPluginName = lastSorterPluginName;
+ }
+
+ /**
+ * @return the plugins
+ */
+ public List<Plugin> getPlugins() {
+ return plugins;
+ }
+
+ /**
+ * @return the imageBuilder
+ */
+ public ImageBuilder getImageBuilder() {
+ return imageBuilder;
+ }
+
+ /**
+ * @return the lastSorterPluginName
+ */
+ public String getLastSorterPluginName() {
+ return lastSorterPluginName;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("imagebuilder=").append(imageBuilder).append("\n");
+ StringBuilder pluginsBuilder = new StringBuilder();
+ for (Plugin p : plugins) {
+ pluginsBuilder.append(p).append(",");
+ }
+ builder.append("plugins=").append(pluginsBuilder).append("\n");
+ builder.append("lastsorter=").append(lastSorterPluginName).append("\n");
+
+ return builder.toString();
+ }
+ }
+
+ /**
+ * Jlink configuration. Instances of this class are used to configure jlink.
+ */
+ public static final class JlinkConfiguration {
+
+ private final List<Path> modulepaths;
+ private final Path output;
+ private final Set<String> modules;
+ private final Set<String> limitmods;
+
+ private final ByteOrder endian;
+
+ /**
+ * jlink configuration,
+ *
+ * @param output Output directory, must not exist.
+ * @param modulepaths Modules paths
+ * @param modules Root modules to resolve
+ * @param limitmods Limit the universe of observable modules
+ * @param endian Jimage byte order. Native order by default
+ */
+ public JlinkConfiguration(Path output,
+ List<Path> modulepaths,
+ Set<String> modules,
+ Set<String> limitmods,
+ ByteOrder endian) {
+ this.output = output;
+ this.modulepaths = modulepaths == null ? Collections.emptyList() : modulepaths;
+ this.modules = modules == null ? Collections.emptySet() : modules;
+ this.limitmods = limitmods == null ? Collections.emptySet() : limitmods;
+ this.endian = endian == null ? ByteOrder.nativeOrder() : endian;
+ }
+
+ /**
+ * jlink configuration,
+ *
+ * @param output Output directory, must not exist.
+ * @param modulepaths Modules paths
+ * @param modules Root modules to resolve
+ * @param limitmods Limit the universe of observable modules
+ */
+ public JlinkConfiguration(Path output,
+ List<Path> modulepaths,
+ Set<String> modules,
+ Set<String> limitmods) {
+ this(output, modulepaths, modules, limitmods,
+ ByteOrder.nativeOrder());
+ }
+
+ /**
+ * @return the modulepaths
+ */
+ public List<Path> getModulepaths() {
+ return modulepaths;
+ }
+
+ /**
+ * @return the byte ordering
+ */
+ public ByteOrder getByteOrder() {
+ return endian;
+ }
+
+ /**
+ * @return the output
+ */
+ public Path getOutput() {
+ return output;
+ }
+
+ /**
+ * @return the modules
+ */
+ public Set<String> getModules() {
+ return modules;
+ }
+
+ /**
+ * @return the limitmods
+ */
+ public Set<String> getLimitmods() {
+ return limitmods;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("output=").append(output).append("\n");
+ StringBuilder pathsBuilder = new StringBuilder();
+ for (Path p : modulepaths) {
+ pathsBuilder.append(p).append(",");
+ }
+ builder.append("modulepaths=").append(pathsBuilder).append("\n");
+
+ StringBuilder modsBuilder = new StringBuilder();
+ for (String p : modules) {
+ modsBuilder.append(p).append(",");
+ }
+ builder.append("modules=").append(modsBuilder).append("\n");
+
+ StringBuilder limitsBuilder = new StringBuilder();
+ for (String p : limitmods) {
+ limitsBuilder.append(p).append(",");
+ }
+ builder.append("limitmodules=").append(limitsBuilder).append("\n");
+ builder.append("endian=").append(endian).append("\n");
+ return builder.toString();
+ }
+ }
+
+ /**
+ * Jlink instance constructor, if a security manager is set, the jlink
+ * permission is checked.
+ */
+ public Jlink() {
+ if (System.getSecurityManager() != null) {
+ System.getSecurityManager().
+ checkPermission(new JlinkPermission("jlink"));
+ }
+ }
+
+ /**
+ * Build the image.
+ *
+ * @param config Jlink config, must not be null.
+ * @throws PluginException
+ */
+ public void build(JlinkConfiguration config) {
+ build(config, null);
+ }
+
+ /**
+ * Build the image with a plugin configuration.
+ *
+ * @param config Jlink config, must not be null.
+ * @param pluginsConfig Plugins config, can be null
+ * @throws PluginException
+ */
+ public void build(JlinkConfiguration config, PluginsConfiguration pluginsConfig) {
+ Objects.requireNonNull(config);
+ try {
+ JlinkTask.createImage(config, pluginsConfig);
+ } catch (Exception ex) {
+ throw new PluginException(ex);
+ }
+ }
+
+ /**
+ * Post process the image with a plugin configuration.
+ *
+ * @param image Existing image.
+ * @param plugins Plugins cannot be null
+ */
+ public void postProcess(ExecutableImage image, List<Plugin> plugins) {
+ Objects.requireNonNull(image);
+ Objects.requireNonNull(plugins);
+ try {
+ JlinkTask.postProcessImage(image, plugins);
+ } catch (Exception ex) {
+ throw new PluginException(ex);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkPermission.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.internal;
+
+import java.security.BasicPermission;
+
+/**
+ * The permission required to use jlink API. The permission target_name is
+ * "jlink". e.g.: permission jdk.tools.jlink.plugins.JlinkPermission "jlink";
+ *
+ */
+public final class JlinkPermission extends BasicPermission {
+
+ private static final long serialVersionUID = -3687912306077727801L;
+
+ public JlinkPermission(String name) {
+ super(name);
+ }
+
+}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Wed Jul 05 22:22:15 2017 +0200
@@ -46,11 +46,11 @@
import jdk.internal.module.ConfigurableModuleFinder.Phase;
import jdk.tools.jlink.internal.TaskHelper.BadArgs;
import static jdk.tools.jlink.internal.TaskHelper.JLINK_BUNDLE;
+import jdk.tools.jlink.internal.Jlink.JlinkConfiguration;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.TaskHelper.Option;
import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
import jdk.tools.jlink.internal.ImagePluginStack.ImageProvider;
-import jdk.tools.jlink.Jlink.JlinkConfiguration;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.plugin.Plugin;
@@ -213,8 +213,8 @@
}
return EXIT_OK;
- } catch (UncheckedIOException | PluginException | IllegalArgumentException |
- IOException | ResolutionException e) {
+ } catch (PluginException | IllegalArgumentException |
+ UncheckedIOException |IOException | ResolutionException e) {
log.println(taskHelper.getMessage("error.prefix") + " " + e.getMessage());
if (DEBUG) {
e.printStackTrace(log);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JmodArchive.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JmodArchive.java Wed Jul 05 22:22:15 2017 +0200
@@ -128,12 +128,16 @@
switch (section) {
case CLASSES:
return EntryType.CLASS_OR_RESOURCE;
+ case CONFIG:
+ return EntryType.CONFIG;
case NATIVE_LIBS:
return EntryType.NATIVE_LIB;
case NATIVE_CMDS:
return EntryType.NATIVE_CMD;
- case CONFIG:
- return EntryType.CONFIG;
+ case HEADER_FILES:
+ return EntryType.HEADER_FILE;
+ case MAN_PAGES:
+ return EntryType.MAN_PAGE;
default:
throw new InternalError("unexpected entry: " + section);
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java Wed Jul 05 22:22:15 2017 +0200
@@ -30,9 +30,9 @@
public class Main {
public static void main(String... args) throws Exception {
- JlinkTask t = new JlinkTask();
- int rc = t.run(args);
- System.exit(rc);
+ System.exit(run(new PrintWriter(System.out, true),
+ new PrintWriter(System.err, true),
+ args));
}
/**
@@ -44,6 +44,11 @@
* @return an exit code. 0 means success, non-zero means an error occurred.
*/
public static int run(PrintWriter out, PrintWriter err, String... args) {
+ if (System.getSecurityManager() != null) {
+ System.getSecurityManager().
+ checkPermission(new JlinkPermission("jlink"));
+ }
+
JlinkTask t = new JlinkTask();
t.setLog(out, err);
return t.run(args);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Wed Jul 05 22:22:15 2017 +0200
@@ -49,13 +49,14 @@
import jdk.internal.module.ConfigurableModuleFinder;
import jdk.internal.module.ConfigurableModuleFinder.Phase;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
+import jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin;
+import jdk.tools.jlink.internal.plugins.ExcludeJmodSectionPlugin;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.Plugin.Category;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.builder.ImageBuilder;
import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.plugins.PluginsResourceBundle;
import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin;
import jdk.tools.jlink.internal.plugins.StripDebugPlugin;
@@ -323,6 +324,20 @@
addArgumentMap(plugin);
}, "-G");
mainOptions.add(plugOption);
+ } else if (plugin instanceof ExcludeJmodSectionPlugin) {
+ plugOption = new PlugOption(false, (task, opt, arg) -> {
+ Map<String, String> m = addArgumentMap(plugin);
+ m.put(ExcludeJmodSectionPlugin.NAME,
+ ExcludeJmodSectionPlugin.MAN_PAGES);
+ }, "--no-man-pages");
+ mainOptions.add(plugOption);
+
+ plugOption = new PlugOption(false, (task, opt, arg) -> {
+ Map<String, String> m = addArgumentMap(plugin);
+ m.put(ExcludeJmodSectionPlugin.NAME,
+ ExcludeJmodSectionPlugin.INCLUDE_HEADER_FILES);
+ }, "--no-header-files");
+ mainOptions.add(plugOption);
}
}
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java Wed Jul 05 22:22:15 2017 +0200
@@ -26,8 +26,8 @@
package jdk.tools.jlink.internal.packager;
-import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.builder.DefaultImageBuilder;
+import jdk.tools.jlink.internal.Jlink;
import jdk.tools.jlink.internal.JlinkTask;
import jdk.tools.jlink.plugin.Plugin;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeJmodSectionPlugin.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.internal.plugins;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import jdk.tools.jlink.plugin.Plugin;
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry.Type;
+
+/**
+ *
+ * A plugin to exclude a JMOD section such as man pages or header files
+ */
+public final class ExcludeJmodSectionPlugin implements Plugin {
+
+ public static final String NAME = "exclude-jmod-section";
+ public static final String MAN_PAGES = "man";
+ public static final String INCLUDE_HEADER_FILES = "headers";
+
+ private final Set<Type> filters = new HashSet<>();
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public void configure(Map<String, String> config) {
+ String arg = config.get(NAME);
+ if (arg.isEmpty()) {
+ throw new PluginException("Section name must be specified");
+ }
+
+ switch (arg) {
+ case MAN_PAGES:
+ filters.add(Type.MAN_PAGE);
+ break;
+ case INCLUDE_HEADER_FILES:
+ filters.add(Type.HEADER_FILE);
+ break;
+ default:
+ throw new PluginException("Invalid section name: " + arg);
+ }
+ }
+
+ @Override
+ public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
+ in.transformAndCopy(entry -> {
+ // filter entries whose type corresponds to the specified JMOD section
+ if (filters.contains(entry.type())) {
+ entry = null;
+ }
+ return entry;
+ }, out);
+ return out.build();
+ }
+
+ @Override
+ public Category getType() {
+ return Category.FILTER;
+ }
+
+ @Override
+ public String getDescription() {
+ return PluginsResourceBundle.getDescription(NAME);
+ }
+
+ @Override
+ public boolean hasArguments() {
+ return true;
+ }
+
+ @Override
+ public String getArgumentsDescription() {
+ return PluginsResourceBundle.getArgument(NAME);
+ }
+}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolEntry.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolEntry.java Wed Jul 05 22:22:15 2017 +0200
@@ -24,13 +24,12 @@
*/
package jdk.tools.jlink.plugin;
-import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
-import java.nio.file.Files;
import java.nio.file.Path;
+
import jdk.tools.jlink.internal.ResourcePoolEntryFactory;
/**
@@ -64,6 +63,8 @@
CONFIG,
NATIVE_CMD,
NATIVE_LIB,
+ HEADER_FILE,
+ MAN_PAGE,
TOP,
OTHER
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Wed Jul 05 22:22:15 2017 +0200
@@ -68,6 +68,12 @@
exclude-resources.description=\
Specify resources to exclude. e.g.: **.jcov,glob:**/META-INF/**
+exclude-jmod-section.argument=<section-name>\n\
+where <section-name> is \"man\" or \"headers".
+
+exclude-jmod-section.description=\
+Specify a JMOD section to exclude
+
generate-jli-classes.argument=<none|@filename>
generate-jli-classes.description=\
@@ -145,6 +151,12 @@
plugin.opt.G=\
\ -G, --strip-debug Strip debug information
+plugin.opt.no-man-pages=\
+\ --no-man-pages Exclude man pages
+
+plugin.opt.no-header-files=\
+\ --no-header-files Exclude include header files
+
main.plugin.name=\
\Plugin Name
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Wed Jul 05 22:22:15 2017 +0200
@@ -165,6 +165,8 @@
List<Path> cmds;
List<Path> configs;
List<Path> libs;
+ List<Path> headerFiles;
+ List<Path> manPages;
ModuleFinder moduleFinder;
Version moduleVersion;
String mainClass;
@@ -346,6 +348,9 @@
final List<Path> libs = options.libs;
final List<Path> configs = options.configs;
final List<Path> classpath = options.classpath;
+ final List<Path> headerFiles = options.headerFiles;
+ final List<Path> manPages = options.manPages;
+
final Version moduleVersion = options.moduleVersion;
final String mainClass = options.mainClass;
final String osName = options.osName;
@@ -369,6 +374,9 @@
processSection(out, Section.NATIVE_CMDS, cmds);
processSection(out, Section.NATIVE_LIBS, libs);
processSection(out, Section.CONFIG, configs);
+ processSection(out, Section.HEADER_FILES, headerFiles);
+ processSection(out, Section.MAN_PAGES, manPages);
+
}
/**
@@ -596,7 +604,7 @@
return "";
}
- void processClasses(JmodOutputStream zos, List<Path> classpaths)
+ void processClasses(JmodOutputStream out, List<Path> classpaths)
throws IOException
{
if (classpaths == null)
@@ -604,24 +612,24 @@
for (Path p : classpaths) {
if (Files.isDirectory(p)) {
- processSection(zos, Section.CLASSES, p);
+ processSection(out, Section.CLASSES, p);
} else if (Files.isRegularFile(p) && p.toString().endsWith(".jar")) {
try (JarFile jf = new JarFile(p.toFile())) {
- JarEntryConsumer jec = new JarEntryConsumer(zos, jf);
+ JarEntryConsumer jec = new JarEntryConsumer(out, jf);
jf.stream().filter(jec).forEach(jec);
}
}
}
}
- void processSection(JmodOutputStream zos, Section section, List<Path> paths)
+ void processSection(JmodOutputStream out, Section section, List<Path> paths)
throws IOException
{
if (paths == null)
return;
for (Path p : paths)
- processSection(zos, section, p);
+ processSection(out, section, p);
}
void processSection(JmodOutputStream out, Section section, Path top)
@@ -1195,6 +1203,12 @@
= parser.acceptsAll(Set.of("h", "help"), getMessage("main.opt.help"))
.forHelp();
+ OptionSpec<Path> headerFiles
+ = parser.accepts("header-files", getMessage("main.opt.header-files"))
+ .withRequiredArg()
+ .withValuesSeparatedBy(File.pathSeparatorChar)
+ .withValuesConvertedBy(DirPathConverter.INSTANCE);
+
OptionSpec<Path> libs
= parser.accepts("libs", getMessage("main.opt.libs"))
.withRequiredArg()
@@ -1206,6 +1220,12 @@
.withRequiredArg()
.describedAs(getMessage("main.opt.main-class.arg"));
+ OptionSpec<Path> manPages
+ = parser.accepts("man-pages", getMessage("main.opt.man-pages"))
+ .withRequiredArg()
+ .withValuesSeparatedBy(File.pathSeparatorChar)
+ .withValuesConvertedBy(DirPathConverter.INSTANCE);
+
OptionSpec<Path> modulePath
= parser.acceptsAll(Set.of("p", "module-path"),
getMessage("main.opt.module-path"))
@@ -1272,6 +1292,10 @@
options.excludes = opts.valuesOf(excludes);
if (opts.has(libs))
options.libs = opts.valuesOf(libs);
+ if (opts.has(headerFiles))
+ options.headerFiles = opts.valuesOf(headerFiles);
+ if (opts.has(manPages))
+ options.manPages = opts.valuesOf(manPages);
if (opts.has(modulePath)) {
Path[] dirs = opts.valuesOf(modulePath).toArray(new Path[0]);
options.moduleFinder = ModuleFinder.of(dirs);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Wed Jul 05 22:22:15 2017 +0200
@@ -54,9 +54,11 @@
main.opt.exclude=Exclude files matching the supplied comma separated pattern\
\ list, each element using one the following forms: <glob-pattern>,\
\ glob:<glob-pattern> or regex:<regex-pattern>
+main.opt.header-files=Location of header files
main.opt.module-version= Module version
main.opt.main-class=Main class
main.opt.main-class.arg=class-name
+main.opt.man-pages=Location of man pages
main.opt.os-name=Operating system name
main.opt.os-name.arg=os-name
main.opt.os-arch=Operating system architecture
--- a/jdk/src/jdk.jlink/share/classes/module-info.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/module-info.java Wed Jul 05 22:22:15 2017 +0200
@@ -38,6 +38,7 @@
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.StripDebugPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.ExcludePlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin;
+ provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.ExcludeJmodSectionPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.SystemModuleDescriptorPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.StripNativeCommandsPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.OrderResourcesPlugin;
--- a/jdk/src/jdk.pack200/share/native/common-unpack/unpack.cpp Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.pack200/share/native/common-unpack/unpack.cpp Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, 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
@@ -174,7 +174,10 @@
const char* utf8String() {
assert(tagMatches(CONSTANT_Utf8));
- assert(value.b.len == strlen((const char*)value.b.ptr));
+ if (value.b.len != strlen((const char*)value.b.ptr)) {
+ unpack_abort("bad utf8 encoding");
+ // and fall through
+ }
return (const char*)value.b.ptr;
}
@@ -1319,10 +1322,10 @@
CHECK;
int nc = 0;
- for ( const char* ncp = form.utf8String() ; *ncp; ncp++) {
- if (*ncp == 'L') nc++;
+ for (int j = 0; j < (int)form.value.b.len; j++) {
+ int c = form.value.b.ptr[j];
+ if (c == 'L') nc++;
}
-
ncTotal += nc;
e.refs = U_NEW(entry*, cpMap[i].nrefs = 1 + nc);
CHECK;
@@ -2830,6 +2833,7 @@
}
assert(!b.le_bci || prevBCI == (int)to_bci(prevBII));
+ CHECK;
switch (b.le_len) {
case 0: break;
case 1: putu1(x); break;
@@ -4026,6 +4030,10 @@
uint len = bcimap.length();
uint* map = (uint*) bcimap.base();
assert(len > 0); // must be initialized before using to_bci
+ if (len == 0) {
+ abort("bad bcimap");
+ return 0;
+ }
if (bii < len)
return map[bii];
// Else it's a fractional or out-of-range BCI.
@@ -4048,6 +4056,7 @@
break;
case 8: // (8) [PH]
putu2(to_bci(code_StackMapTable_P.getInt()));
+ CHECK;
break;
}
}
@@ -4095,6 +4104,7 @@
CHECK;
for (int curIP = 0; ; curIP++) {
+ CHECK;
int curPC = (int)(wpoffset() - codeBase);
bcimap.add(curPC);
ensure_put_space(10); // covers most instrs w/o further bounds check
@@ -4336,6 +4346,7 @@
int curIP = code_fixup_source.get(i);
int destIP = curIP + bc_label.getInt();
int span = to_bci(destIP) - to_bci(curIP);
+ CHECK;
switch (type) {
case 2: putu2_at(bp, (ushort)span); break;
case 4: putu4_at(bp, span); break;
@@ -4532,11 +4543,13 @@
if (tag <= 127) {
// (64-127) [(2)]
if (tag >= 64) put_stackmap_type();
+ CHECK_0;
} else if (tag <= 251) {
// (247) [(1)(2)]
// (248-251) [(1)]
if (tag >= 247) putu2(code_StackMapTable_offset.getInt());
if (tag == 247) put_stackmap_type();
+ CHECK_0;
} else if (tag <= 254) {
// (252) [(1)(2)]
// (253) [(1)(2)(2)]
@@ -4563,6 +4576,7 @@
putu2(count = code_LineNumberTable_N.getInt());
for (j = 0; j < count; j++) {
putu2(to_bci(code_LineNumberTable_bci_P.getInt()));
+ CHECK_0;
putu2(code_LineNumberTable_line.getInt());
}
break;
@@ -4573,9 +4587,11 @@
for (j = 0; j < count; j++) {
int bii = code_LocalVariableTable_bci_P.getInt();
int bci = to_bci(bii);
+ CHECK_0;
putu2(bci);
bii += code_LocalVariableTable_span_O.getInt();
putu2(to_bci(bii) - bci);
+ CHECK_0;
putref(code_LocalVariableTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTable_type_RS.getRefN());
@@ -4590,9 +4606,11 @@
for (j = 0; j < count; j++) {
int bii = code_LocalVariableTypeTable_bci_P.getInt();
int bci = to_bci(bii);
+ CHECK_0;
putu2(bci);
bii += code_LocalVariableTypeTable_span_O.getInt();
putu2(to_bci(bii) - bci);
+ CHECK_0;
putref(code_LocalVariableTypeTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTypeTable_type_RS.getRefN());
@@ -5036,6 +5054,7 @@
entry* e = file_name.getRef();
CHECK_0;
cur_file.name = e->utf8String();
+ CHECK_0;
bool haveLongSize = (testBit(archive_options, AO_HAVE_FILE_SIZE_HI));
cur_file.size = file_size_hi.getLong(file_size_lo, haveLongSize);
if (testBit(archive_options, AO_HAVE_FILE_MODTIME))
--- a/jdk/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java Wed Jul 05 22:22:15 2017 +0200
@@ -25,24 +25,34 @@
package sun.reflect;
+import java.io.OptionalDataException;
+import java.lang.invoke.MethodHandle;
import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
+/**
+ * ReflectionFactory supports custom serialization.
+ * Its methods support the creation of uninitialized objects, invoking serialization
+ * private methods for readObject, writeObject, readResolve, and writeReplace.
+ * <p>
+ * ReflectionFactory access is restricted, if a security manager is active,
+ * unless the permission {@code RuntimePermission("reflectionFactoryAccess")}
+ * is granted.
+ */
public class ReflectionFactory {
private static final ReflectionFactory soleInstance = new ReflectionFactory();
- private final jdk.internal.reflect.ReflectionFactory delegate;
-
- private ReflectionFactory() {
- delegate = AccessController.doPrivileged(
+ private static final jdk.internal.reflect.ReflectionFactory delegate = AccessController.doPrivileged(
new PrivilegedAction<jdk.internal.reflect.ReflectionFactory>() {
public jdk.internal.reflect.ReflectionFactory run() {
return jdk.internal.reflect.ReflectionFactory.getReflectionFactory();
}
- });
- }
+ });
+
+ private ReflectionFactory() {}
private static final Permission REFLECTION_FACTORY_ACCESS_PERM
= new RuntimePermission("reflectionFactoryAccess");
@@ -53,7 +63,7 @@
*
* <p> First, if there is a security manager, its {@code checkPermission}
* method is called with a {@link java.lang.RuntimePermission} with target
- * {@code "reflectionFactoryAccess"}. This may result in a securit
+ * {@code "reflectionFactoryAccess"}. This may result in a security
* exception.
*
* <p> The returned {@code ReflectionFactory} object should be carefully
@@ -61,6 +71,7 @@
* data and invoke private methods, as well as to load unverified bytecodes.
* It must never be passed to untrusted code.
*
+ * @return the ReflectionFactory
* @throws SecurityException if a security manager exists and its
* {@code checkPermission} method doesn't allow access to
* the RuntimePermission "reflectionFactoryAccess".
@@ -73,11 +84,129 @@
return soleInstance;
}
- public Constructor<?> newConstructorForSerialization(Class<?> classToInstantiate,
- Constructor<?> constructorToCall)
+ /**
+ * Returns an accessible no-arg constructor for a class.
+ * The no-arg constructor is found searching the class and its supertypes.
+ *
+ * @param cl the class to instantiate
+ * @return a no-arg constructor for the class or {@code null} if
+ * the class or supertypes do not have a suitable no-arg constructor
+ */
+ public final Constructor<?> newConstructorForSerialization(Class<?> cl)
{
- return delegate.newConstructorForSerialization(classToInstantiate,
- constructorToCall);
+ return delegate.newConstructorForSerialization(cl);
+ }
+
+ /**
+ * Returns an accessible no-arg constructor for an externalizable class to be
+ * initialized using a public no-argument constructor.
+ *
+ * @param cl the class to instantiate
+ * @return A no-arg constructor for the class; returns {@code null} if
+ * the class does not implement {@link java.io.Externalizable}
+ */
+ public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
+ return delegate.newConstructorForExternalization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code readObject} method on
+ * a Serializable class.
+ * The first argument of {@link MethodHandle#invoke} is the serializable
+ * object and the second argument is the {@code ObjectInputStream} passed to
+ * {@code readObject}.
+ *
+ * @param cl a Serializable class
+ * @return a direct MethodHandle for the {@code readObject} method of the class or
+ * {@code null} if the class does not have a {@code readObject} method
+ */
+ public final MethodHandle readObjectForSerialization(Class<?> cl) {
+ return delegate.readObjectForSerialization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code readObjectNoData} method on
+ * a Serializable class.
+ * The first argument of {@link MethodHandle#invoke} is the serializable
+ * object and the second argument is the {@code ObjectInputStream} passed to
+ * {@code readObjectNoData}.
+ *
+ * @param cl a Serializable class
+ * @return a direct MethodHandle for the {@code readObjectNoData} method
+ * of the class or {@code null} if the class does not have a
+ * {@code readObjectNoData} method
+ */
+ public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
+ return delegate.readObjectNoDataForSerialization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code writeObject} method on
+ * a Serializable class.
+ * The first argument of {@link MethodHandle#invoke} is the serializable
+ * object and the second argument is the {@code ObjectOutputStream} passed to
+ * {@code writeObject}.
+ *
+ * @param cl a Serializable class
+ * @return a direct MethodHandle for the {@code writeObject} method of the class or
+ * {@code null} if the class does not have a {@code writeObject} method
+ */
+ public final MethodHandle writeObjectForSerialization(Class<?> cl) {
+ return delegate.writeObjectForSerialization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code readResolve} method on
+ * a serializable class.
+ * The single argument of {@link MethodHandle#invoke} is the serializable
+ * object.
+ *
+ * @param cl the Serializable class
+ * @return a direct MethodHandle for the {@code readResolve} method of the class or
+ * {@code null} if the class does not have a {@code readResolve} method
+ */
+ public final MethodHandle readResolveForSerialization(Class<?> cl) {
+ return delegate.readResolveForSerialization(cl);
+ }
+
+ /**
+ * Returns a direct MethodHandle for the {@code writeReplace} method on
+ * a serializable class.
+ * The single argument of {@link MethodHandle#invoke} is the serializable
+ * object.
+ *
+ * @param cl the Serializable class
+ * @return a direct MethodHandle for the {@code writeReplace} method of the class or
+ * {@code null} if the class does not have a {@code writeReplace} method
+ */
+ public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
+ return delegate.writeReplaceForSerialization(cl);
+ }
+
+ /**
+ * Returns true if the class has a static initializer.
+ * The presence of a static initializer is used to compute the serialVersionUID.
+ * @param cl a serializable class
+ * @return {@code true} if the class has a static initializer,
+ * otherwise {@code false}
+ */
+ public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
+ return delegate.hasStaticInitializerForSerialization(cl);
+ }
+
+ /**
+ * Returns a new OptionalDataException with {@code eof} set to {@code true}
+ * or {@code false}.
+ * @param bool the value of {@code eof} in the created OptionalDataException
+ * @return a new OptionalDataException
+ */
+ public final OptionalDataException newOptionalDataExceptionForSerialization(boolean bool) {
+ Constructor<OptionalDataException> cons = delegate.newOptionalDataExceptionForSerialization();
+ try {
+ return cons.newInstance(bool);
+ } catch (InstantiationException|IllegalAccessException|InvocationTargetException ex) {
+ throw new InternalError("unable to create OptionalDataException", ex);
+ }
}
}
--- a/jdk/test/com/oracle/security/ucrypto/TestAES.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/com/oracle/security/ucrypto/TestAES.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,11 @@
/*
* @test
- * @bug 7088989 8014374
+ * @bug 7088989 8014374 8167512
* @summary Ensure the AES ciphers of OracleUcrypto provider works correctly
* @key randomness
+ * @run main TestAES
+ * @run main/othervm/java.security.policy==empty.policy TestAES
*/
import java.io.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/serialization/ObjectStreamTest$_Echo_Stub.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016, 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.rmi.UnexpectedException;
+
+import javax.rmi.CORBA.Stub;
+import javax.rmi.CORBA.Util;
+
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.ApplicationException;
+import org.omg.CORBA.portable.OutputStream;
+import org.omg.CORBA.portable.RemarshalException;
+import org.omg.CORBA.portable.ServantObject;
+
+
+/**
+ * ObjectStreamTest$Echo Stub class generated by rmic, do not edit.
+ */
+public class ObjectStreamTest$_Echo_Stub extends Stub implements ObjectStreamTest.Echo {
+
+ private static final String[] _type_ids = {
+ "RMI:ObjectStreamTest\\U0024Echo:0000000000000000"
+ };
+
+ private static final long serialVersionUID = 5217577841494640354L;
+
+ public String[] _ids() {
+ return _type_ids.clone();
+ }
+
+ public Object echo(Object arg0) throws java.rmi.RemoteException {
+ if (!Util.isLocal(this)) {
+ try {
+ org.omg.CORBA.portable.InputStream in = null;
+ try {
+ OutputStream out = _request("echo", true);
+ Util.writeAny(out,arg0);
+ in = _invoke(out);
+ return Util.readAny(in);
+ } catch (ApplicationException ex) {
+ in = ex.getInputStream();
+ String $_id = in.read_string();
+ throw new UnexpectedException($_id);
+ } catch (RemarshalException ex) {
+ return echo(arg0);
+ } finally {
+ _releaseReply(in);
+ }
+ } catch (SystemException ex) {
+ throw Util.mapSystemException(ex);
+ }
+ } else {
+ ServantObject so = _servant_preinvoke("echo",ObjectStreamTest.Echo.class);
+ if (so == null) {
+ return echo(arg0);
+ }
+ try {
+ Object arg0Copy = Util.copyObject(arg0,_orb());
+ Object result = ((ObjectStreamTest.Echo)so.servant).echo(arg0Copy);
+ return Util.copyObject(result,_orb());
+ } catch (Throwable ex) {
+ Throwable exCopy = (Throwable)Util.copyObject(ex,_orb());
+ throw Util.wrapException(exCopy);
+ } finally {
+ _servant_postinvoke(so);
+ }
+ }
+ }
+ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/serialization/ObjectStreamTest$_Server_Tie.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2016, 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.rmi.Remote;
+
+import javax.rmi.CORBA.Tie;
+import javax.rmi.CORBA.Util;
+
+import org.omg.CORBA.BAD_OPERATION;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.SystemException;
+import org.omg.CORBA.portable.InputStream;
+import org.omg.CORBA.portable.OutputStream;
+import org.omg.CORBA.portable.ResponseHandler;
+import org.omg.CORBA.portable.UnknownException;
+import org.omg.CORBA_2_3.portable.ObjectImpl;
+
+
+/**
+ * ObjectStreamClass$Echo server tie class generated by rmic, do not edit.
+ */
+public class ObjectStreamTest$_Server_Tie extends ObjectImpl implements Tie {
+
+ volatile private ObjectStreamTest.Server target = null;
+
+ private static final String[] _type_ids = {
+ "RMI:ObjectStreamTest\\U0024Echo:0000000000000000"
+ };
+
+ public void setTarget(Remote target) {
+ this.target = (ObjectStreamTest.Server) target;
+ }
+
+ public Remote getTarget() {
+ return target;
+ }
+
+ public org.omg.CORBA.Object thisObject() {
+ return this;
+ }
+
+ public void deactivate() {
+ _orb().disconnect(this);
+ _set_delegate(null);
+ target = null;
+ }
+
+ public ORB orb() {
+ return _orb();
+ }
+
+ public void orb(ORB orb) {
+ orb.connect(this);
+ }
+
+ public String[] _ids() {
+ return _type_ids.clone();
+ }
+
+ public OutputStream _invoke(String method, InputStream _in, ResponseHandler reply) throws SystemException {
+ try {
+ ObjectStreamTest.Server target = this.target;
+ if (target == null) {
+ throw new java.io.IOException();
+ }
+ org.omg.CORBA_2_3.portable.InputStream in =
+ (org.omg.CORBA_2_3.portable.InputStream) _in;
+ if (method.equals("echo")) {
+ Object arg0 = Util.readAny(in);
+ Object result = target.echo(arg0);
+ OutputStream out = reply.createReply();
+ Util.writeAny(out,result);
+ return out;
+ }
+ throw new BAD_OPERATION();
+ } catch (SystemException ex) {
+ throw ex;
+ } catch (Throwable ex) {
+ throw new UnknownException(ex);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/serialization/ObjectStreamTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2016, 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.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.time.LocalTime;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.HashMap;
+import java.util.Objects;
+import java.util.PropertyPermission;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+
+import javax.naming.CommunicationException;
+import javax.naming.InitialContext;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.rmi.CORBA.Util;
+import javax.rmi.PortableRemoteObject;
+
+import org.omg.CORBA_2_3.ORB;
+import org.omg.CORBA_2_3.portable.OutputStream;
+import org.omg.CORBA_2_3.portable.InputStream;
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.JDKToolLauncher;
+
+import org.testng.Assert;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import org.testng.TestNG;
+
+/*
+ * @test
+ * @library /test/lib
+ * @build jdk.test.lib.*
+ * @compile ObjectStreamTest.java ObjectStreamTest$_Echo_Stub.java ObjectStreamTest$_Server_Tie.java
+ * @modules java.corba/com.sun.corba.se.impl.io java.base/java.io java.corba/com.sun.corba.se.impl.activation
+ * @summary Tests of ReflectionFactory use in IIOP Serialization
+ * @run testng/othervm
+ * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ * -Djava.naming.provider.url=iiop://localhost:1050 ObjectStreamTest
+ * @run testng/othervm/policy=security.policy
+ * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ * -Djava.naming.provider.url=iiop://localhost:1050 ObjectStreamTest
+ */
+
+@Test
+public class ObjectStreamTest {
+
+ enum Colors {RED, GREEN, YELLOW}
+
+ static Set<Colors> colorSet = new HashSet<>();
+
+ static {
+ colorSet.add(Colors.RED);
+ colorSet.add(Colors.GREEN);
+ }
+
+ /**
+ * The process spawned to run orbd.
+ */
+ static Process orbdProcess;
+ static Thread orbThread;
+
+ @DataProvider(name = "Objects")
+ static Object[][] patterns() {
+ BigInteger bigInteger = new BigInteger("8943892002309239");
+ InetAddress inetAddr;
+ try {
+ inetAddr = java.net.InetAddress.getByAddress(new byte[]{127, 0, 0, 1});
+ } catch (UnknownHostException ignored) {
+ inetAddr = null;
+ // ignored
+ }
+ HashMap<String, Object> hashMap = new HashMap<>();
+ hashMap.put("BigInteger", bigInteger);
+ hashMap.put("InetAddress", inetAddr);
+ hashMap.put("String", "bString");
+ Object[][] patterns = new Object[][]{
+ {"aString"},
+ {Integer.valueOf(5)},
+ {new SimpleObject(4, 4.0f)},
+ {Arrays.asList("a", "b", "c")},
+ {new String[]{"x", "y", "z"}},
+ {new ArrayList<Object>(1)}, // uses readObject/writeObject
+ {new StringBuffer("abc")}, // Has serialPersistentFields
+ {new StringBuilder("abc")},
+ {Colors.RED},
+ {inetAddr},
+ {LocalTime.MIDNIGHT}, // uses writeReplace/readResolve
+ {new LongAdder()}, // uses writeReplace/readResolve
+ {EnumSet.allOf(Colors.class)}, // used writeReplace/readResolve
+ {bigInteger},
+ {new BigDecimal(bigInteger)},
+ {hashMap},
+ {new PropertyPermission("abc", "read")}, // has serialPersistentFields
+ };
+ return patterns;
+ }
+
+
+ /**
+ * Check ObjectStreamClass facts match between core serialization and CORBA.
+ *
+ * @param value
+ */
+ @Test(dataProvider = "Objects")
+ static void factCheck(Serializable value) {
+ Class<?> clazz = value.getClass();
+ java.io.ObjectStreamClass sOSC = java.io.ObjectStreamClass.lookup(clazz);
+ java.io.ObjectStreamField[] sFields = sOSC.getFields();
+ com.sun.corba.se.impl.io.ObjectStreamClass cOSC = corbaLookup(clazz);
+ com.sun.corba.se.impl.io.ObjectStreamField[] cFields = cOSC.getFields();
+
+ Assert.assertEquals(sFields.length, cFields.length, "Different number of fields");
+ for (int i = 0; i < sFields.length; i++) {
+ Assert.assertEquals(sFields[i].getName(), cFields[i].getName(), "different field names " + cFields[i].getName());
+ Assert.assertEquals(sFields[i].getType(), cFields[i].getType(), "different field types " + cFields[i].getName());
+ Assert.assertEquals(sFields[i].getTypeString(), cFields[i].getTypeString(), "different field typestrings " + cFields[i].getName());
+ }
+
+ Assert.assertEquals(baseMethod("hasReadObjectMethod", sOSC, (Class<?>[]) null),
+ corbaMethod("hasReadObject", cOSC, (Class<?>[]) null), "hasReadObject: " + value.getClass());
+
+ Assert.assertEquals(baseMethod("hasWriteObjectMethod", sOSC, (Class<?>[]) null),
+ corbaMethod("hasWriteObject", cOSC, (Class<?>[]) null), "hasWriteObject: " + value.getClass());
+
+ Assert.assertEquals(baseMethod("hasWriteReplaceMethod", sOSC, (Class<?>[]) null),
+ corbaMethod("hasWriteReplaceMethod", cOSC, (Class<?>[]) null), "hasWriteReplace: " + value.getClass());
+
+ Assert.assertEquals(baseMethod("hasReadResolveMethod", sOSC, (Class<?>[]) null),
+ corbaMethod("hasReadResolveMethod", cOSC, (Class<?>[]) null), "hasReadResolve: " + value.getClass());
+
+ Assert.assertEquals(baseMethod("getSerialVersionUID", sOSC, (Class<?>[]) null),
+ corbaMethod("getSerialVersionUID", cOSC, (Class<?>[]) null), "getSerialVersionUID: " + value.getClass());
+
+ }
+
+
+ /**
+ * Test that objects written using Util.writeAny can be serialized
+ * and deserialized using Util.readAny to equivalent objects.
+ */
+ @Test(dataProvider = "Objects", enabled = true, dependsOnMethods = {"factCheck"})
+ static void WriteValueObjectStreamTest01(Serializable value) throws Exception {
+ ORB orb = (ORB) ORB.init(new String[0], null);
+
+ OutputStream out = (OutputStream) orb.create_output_stream();
+ Util.writeAny(out, value);
+
+ InputStream in = (InputStream) out.create_input_stream();
+ Object actual = Util.readAny(in);
+
+ checkEquals(actual, value);
+ }
+
+ /**
+ * Test that objects can be echoed to a server and come back equivalent.
+ */
+ @Test(dataProvider = "Objects", enabled = false, dependsOnMethods = {"factCheck"})
+ static void echoObjects(Serializable value) throws Exception {
+ Context initialNamingContext = Server.init();
+ Echo echo = (Echo) PortableRemoteObject.narrow(
+ initialNamingContext.lookup(Server.serverID), Echo.class);
+ Object actual = echo.echo(value);
+ checkEquals(actual, value);
+ }
+
+ /**
+ * Check if the value and result are equals, with some tests depending on the type.
+ * @param expected the expected value
+ * @param actual the actual value
+ */
+ static void checkEquals(Object actual, Object expected) {
+ Class<?> cl = expected.getClass();
+ Assert.assertEquals(actual.getClass(), cl, "type of value not equal to class of result");
+ try {
+ if (cl.isArray() || !(cl.getDeclaredMethod("equals", cl) == null)) {
+ Assert.assertEquals(actual, expected, "echo'd object not equal");
+ } else {
+ Assert.assertEquals(toString(actual), toString(expected), "toString values not equal");
+ }
+ } catch (NoSuchMethodException ex) {
+ Assert.assertEquals(toString(actual), toString(expected), "toString values not equal");
+ }
+ }
+
+ /**
+ * Convert an object to a String, and correctly for arrays.
+ * @param obj an object
+ * @return the tostring for the object.
+ */
+ static String toString(Object obj) {
+ return obj.getClass().isArray()
+ ? Arrays.toString((Object[]) obj)
+ : Objects.toString(obj);
+ }
+
+ /**
+ * SimpleObject to test round trip.
+ */
+ static class SimpleObject implements Serializable {
+ private static final long serialVersionUID = 5217577841494640354L;
+
+ private int i = 0;
+ private float f = 0.0f;
+
+ SimpleObject(int i, float f) {
+ this.i = i;
+ this.f = f;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ SimpleObject that = (SimpleObject) o;
+
+ if (i != that.i) return false;
+ return Float.compare(that.f, f) == 0;
+
+ }
+
+ @Override
+ public int hashCode() {
+ int result = i;
+ result = 31 * result + (f != +0.0f ? Float.floatToIntBits(f) : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "SimpleObject{" +
+ "i=" + i +
+ ", f=" + f +
+ '}';
+ }
+ }
+
+
+ /**
+ * Lookup the CORBA ObjectStreamClass instance for a class.
+ * @param clazz the class
+ * @return the CORBA ObjectStreamClass instance for the class
+ */
+ static com.sun.corba.se.impl.io.ObjectStreamClass corbaLookup(Class<?> clazz) {
+ Class<?> oscClass = com.sun.corba.se.impl.io.ObjectStreamClass.class;
+
+ try {
+ Method meth = oscClass.getDeclaredMethod("lookup", Class.class);
+ meth.setAccessible(true);
+ return (com.sun.corba.se.impl.io.ObjectStreamClass) meth.invoke(null, clazz);
+ } catch (NoSuchMethodException noMeth) {
+ throw new RuntimeException("missing method", noMeth);
+ } catch (IllegalAccessException | InvocationTargetException rex) {
+ throw new RuntimeException("invocation failed", rex);
+ }
+ }
+
+ /**
+ * Lookup aand invoke method on a serializable object via the CORBA ObjectStreamClass.
+ * @param methodName method name
+ * @param osc CORBA ObjectStreamClass
+ * @param argClasses method arguments
+ * @return the value returned from invoking the method
+ */
+ static Object corbaMethod(String methodName, com.sun.corba.se.impl.io.ObjectStreamClass osc, Class<?>... argClasses) {
+ Class<?> oscClass = com.sun.corba.se.impl.io.ObjectStreamClass.class;
+
+ try {
+ Method meth = oscClass.getDeclaredMethod(methodName, argClasses);
+ meth.setAccessible(true);
+ return meth.invoke(osc);
+
+ } catch (NoSuchMethodException noMeth) {
+ throw new RuntimeException("missing method" + osc.getName()
+ + "::" + methodName, noMeth);
+ } catch (IllegalAccessException | InvocationTargetException rex) {
+ throw new RuntimeException("invocation failed", rex);
+ }
+ }
+
+
+ /**
+ * Lookup aand invoke method on a serializable object via java.io.ObjectStreamClass.
+ * @param methodName method name
+ * @param osc java.io.ObjectStreamClass
+ * @param argClasses method arguments
+ * @return the value returned from invoking the method
+ */
+ static Object baseMethod(String methodName, java.io.ObjectStreamClass osc, Class<?>... argClasses) {
+ Class<?> oscClass = java.io.ObjectStreamClass.class;
+
+ try {
+ Method meth = oscClass.getDeclaredMethod(methodName, argClasses);
+ meth.setAccessible(true);
+ return meth.invoke(osc);
+
+ } catch (NoSuchMethodException noMeth) {
+ throw new RuntimeException("missing method: " + osc.getName()
+ + "::" + methodName, noMeth);
+ } catch (IllegalAccessException | InvocationTargetException rex) {
+ throw new RuntimeException("invocation failed", rex);
+ }
+ }
+
+ /**
+ * Simple echo interface to check serialization/deserialization.
+ */
+ interface Echo extends Remote {
+ Object echo(Object obj) throws RemoteException;
+ }
+
+ static class Server extends PortableRemoteObject implements Echo {
+
+ public static final String serverID = "ObjectStreamTestServer";
+
+ private static Context initialNamingContext;
+
+ private static Server server;
+
+ public Server() throws RemoteException {
+ super();
+ }
+
+ public Object echo(Object obj) {
+ return obj;
+ }
+
+
+ public static Context init() {
+ if (initialNamingContext == null) {
+ try {
+ startOrbd();
+ Thread.sleep(5000L); // Give it 5 seconds
+ } catch (Exception eex) {
+ throw new RuntimeException("Orbd", eex);
+ }
+ for (int i = 0; i < 1; i++) {
+ try {
+ Thread.sleep(1L);
+ initialNamingContext = new InitialContext();
+ server = new Server();
+ initialNamingContext.rebind(serverID, server);
+ } catch (CommunicationException | InterruptedException cex) {
+ System.out.printf("retry #%d sec: ex: %s%n", i, cex);
+ } catch (NamingException ex) {
+ throw new RuntimeException("can't initialize naming context", ex);
+ } catch (RemoteException rex) {
+ throw new RuntimeException("can't initialize server", rex);
+ }
+ }
+ }
+ if (initialNamingContext == null) {
+ Assert.fail("Can't initialize the Orb, no naming context");
+ }
+ return initialNamingContext;
+ }
+ }
+
+ static void startOrbd() throws Exception {
+ System.out.println("\nStarting orbd with NS port 1050 ");
+ JDKToolLauncher orbdLauncher = JDKToolLauncher.create("orbd")
+ .addToolArg("-ORBInitialHost").addToolArg("localhost")
+ .addToolArg("-ORBInitialPort").addToolArg("1050");
+
+ System.out.println("ObjectStreamTest: Executing: " + Arrays.asList(orbdLauncher.getCommand()));
+ ProcessBuilder pb = new ProcessBuilder(orbdLauncher.getCommand());
+
+ pb.redirectError(ProcessBuilder.Redirect.INHERIT);
+ orbdProcess = pb.start();
+ }
+
+ @AfterSuite
+ static void killOrbd() throws Exception {
+ if (orbdProcess != null) {
+ orbdProcess.destroyForcibly();
+ orbdProcess.waitFor();
+ System.out.printf("destroyed orbd, pid: %d, exitValue: %d%n",
+ orbdProcess.getPid(), orbdProcess.exitValue());
+ }
+ }
+
+
+
+ // Main can be used to run the tests from the command line with only testng.jar.
+ @SuppressWarnings("raw_types")
+ @Test(enabled = false)
+ public static void main(String[] args) {
+ Class<?>[] testclass = {ObjectStreamTest.class};
+ TestNG testng = new TestNG();
+ testng.setTestClasses(testclass);
+ testng.run();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/corba/serialization/security.policy Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,15 @@
+// Individual Permissions for ObjectStreamTest
+grant {
+ // Permissions needed to run the test
+ permission java.util.PropertyPermission "*", "read";
+ permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete,execute";
+ permission java.net.SocketPermission "*", "resolve,connect,listen,accept";
+
+ // Permissions to allow ObjectTest to use IIOP ObjectStreamClass
+ permission java.lang.RuntimePermission "accessClassInPackage.com.sun.corba.se.impl.io";
+ permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+ permission java.lang.RuntimePermission "accessDeclaredMembers";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
+ permission java.io.SerializablePermission "enableSubclassImplementation";
+};
--- a/jdk/test/java/io/Serializable/serialFilter/FilterWithSecurityManagerTest.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/java/io/Serializable/serialFilter/FilterWithSecurityManagerTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -28,6 +28,7 @@
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import org.testng.Assert;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
@@ -65,20 +66,21 @@
*/
@Test
public void testGlobalFilter() throws Exception {
- if (ObjectInputFilter.Config.getSerialFilter() == null) {
- return;
- }
- try (ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
- ObjectInputStream ois = new ObjectInputStream(bais)) {
+ ObjectInputFilter global = ObjectInputFilter.Config.getSerialFilter();
+
+ try {
ObjectInputFilter.Config.setSerialFilter(filter);
assertFalse(setSecurityManager,
"When SecurityManager exists, without "
- + "java.security.SerializablePermission(serialFilter) Exception should be thrown");
- Object o = ois.readObject();
+ + "java.io.SerializablePermission(serialFilter) "
+ + "IllegalStateException should be thrown");
} catch (AccessControlException ex) {
assertTrue(setSecurityManager);
assertTrue(ex.getMessage().contains("java.io.SerializablePermission"));
assertTrue(ex.getMessage().contains("serialFilter"));
+ } catch (IllegalStateException ise) {
+ // ISE should occur only if global filter already set
+ Assert.assertNotNull(global, "Global filter should be non-null");
}
}
--- a/jdk/test/java/io/Serializable/serialFilter/GlobalFilterTest.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/java/io/Serializable/serialFilter/GlobalFilterTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -126,9 +126,7 @@
ObjectInputFilter.Config.setSerialFilter(filter);
Assert.fail("set only once process-wide filter");
} catch (IllegalStateException ise) {
- if (sm != null) {
- Assert.fail("wrong exception when security manager is set", ise);
- }
+ // Normal, once set can never be re-set even if no security manager
} catch (SecurityException se) {
if (sm == null) {
Assert.fail("wrong exception when security manager is not set", se);
--- a/jdk/test/java/io/Serializable/serialFilter/security.policy Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/java/io/Serializable/serialFilter/security.policy Wed Jul 05 22:22:15 2017 +0200
@@ -1,7 +1,8 @@
-// Individual Permissions to for GlobalFilterTest
+// Individual Permissions to for GlobalFilterTest and FilterWithSecurityManager
grant {
// Specific permission under test
- permission java.security.SerializablePermission "serialFilter";
+ permission java.io.SerializablePermission "serialFilter";
+
// Permissions needed to run the test
permission java.util.PropertyPermission "*", "read";
permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete";
--- a/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java Wed Jul 05 22:22:15 2017 +0200
@@ -26,6 +26,7 @@
* @bug 8157464
* @summary Basic test for StackWalker.getCallerClass()
* @library src
+ * @modules java.base/jdk.internal.reflect
* @build java.base/java.util.CSM csm/*
* @run main/othervm csm/jdk.test.CallerSensitiveTest
* @run main/othervm csm/jdk.test.CallerSensitiveTest sm
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/AccessControlTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,454 @@
+/*
+ * Copyright (c) 2016, 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 util.ClassSupplier;
+import util.MemberFactory;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.mapping;
+import static java.util.stream.Collectors.toCollection;
+import static util.MemberFactory.*;
+import static util.MemberFactory.Group.*;
+import static util.ClassSupplier.*;
+
+/**
+ * @test
+ * @summary An exhaustive test of reflective access controls
+ * @bug 6378384
+ * @build a.PublicSuper a.Package b.PublicSub b.Package
+ * util.MemberFactory util.ClassSupplier
+ * @run main AccessControlTest
+ */
+public class AccessControlTest {
+
+ public static void main(String[] args) throws Exception {
+ boolean ok = true;
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(PUBLIC_MEMBERS, PROTECTED_STATIC_F_M)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_INSTANCE_F_M,
+ PROTECTED_C)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS, PROTECTED_INSTANCE_F_M, PROTECTED_STATIC_F_M)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_C)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(ALL)
+ .perform();
+
+ if (ok) {
+ System.out.println("\nAll cases passed.");
+ } else {
+ throw new RuntimeException("Some cases failed - see log.");
+ }
+ }
+
+ // use this for generating an exhaustive set of test cases on stdout
+ public static class Generate {
+ public static void main(String[] args) {
+ for (ClassSupplier current : ClassSupplier.values()) {
+ for (ClassSupplier member : ClassSupplier.values()) {
+ for (ClassSupplier target : ClassSupplier.values()) {
+ if (member.get().isAssignableFrom(target.get())) {
+ new Test()
+ .current(current).member(member).target(target)
+ .allowed(ALL)
+ .perform(true);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ static class Test {
+
+ ClassSupplier currentClassSupplier, memberClassSupplier, targetClassSupplier;
+ EnumSet<MemberFactory> expectAllowedMembers = EnumSet.noneOf(MemberFactory.class);
+ EnumSet<MemberFactory> expectDeniedMembers = EnumSet.noneOf(MemberFactory.class);
+
+ Test current(ClassSupplier current) {
+ currentClassSupplier = current;
+ return this;
+ }
+
+ Test member(ClassSupplier member) {
+ memberClassSupplier = member;
+ return this;
+ }
+
+ Test target(ClassSupplier target) {
+ targetClassSupplier = target;
+ return this;
+ }
+
+ Test allowed(MemberFactory... allowed) {
+ expectAllowedMembers = MemberFactory.asSet(allowed);
+ return this;
+ }
+
+ Test allowed(MemberFactory.Group... allowedGroups) {
+ expectAllowedMembers = MemberFactory.groupsToMembers(
+ MemberFactory.Group.asSet(allowedGroups));
+ return this;
+ }
+
+ Test denied(MemberFactory... denied) {
+ expectDeniedMembers = MemberFactory.asSet(denied);
+ return this;
+ }
+
+ Test denied(MemberFactory.Group... deniedGroups) {
+ expectDeniedMembers = MemberFactory.groupsToMembers(
+ MemberFactory.Group.asSet(deniedGroups));
+ return this;
+ }
+
+ boolean perform() {
+ return perform(false);
+ }
+
+ boolean perform(boolean generateCases) {
+
+ // some validation 1st
+ EnumSet<MemberFactory> intersection = EnumSet.copyOf(expectAllowedMembers);
+ intersection.retainAll(expectDeniedMembers);
+ if (!intersection.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Expected allowed and denied MemberFactories have non-empty intersection: " +
+ intersection);
+ }
+
+ EnumSet<MemberFactory> missing = EnumSet.allOf(MemberFactory.class);
+ missing.removeAll(expectAllowedMembers);
+ missing.removeAll(expectDeniedMembers);
+ if (!missing.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Union of expected allowed and denied MemberFactories is missing elements: " +
+ missing);
+ }
+
+ // retrieve method that will perform reflective access
+ Method checkAccessMethod;
+ try {
+ checkAccessMethod = currentClassSupplier.get().getDeclaredMethod(
+ "checkAccess", AccessibleObject.class, Object.class);
+ // in case of inaccessible currentClass
+ checkAccessMethod.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ }
+
+ // construct a target object (for instance field/method)
+ Object target;
+ Constructor<?> targetConstructor =
+ (Constructor<?>) PUBLIC_CONSTRUCTOR.apply(targetClassSupplier.get());
+ // in case of inaccessible targetClass
+ targetConstructor.setAccessible(true);
+ try {
+ target = targetConstructor.newInstance(
+ new Object[targetConstructor.getParameterCount()]);
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+
+ Class<?> memberClass = memberClassSupplier.get();
+
+ Map<Boolean, EnumSet<MemberFactory>> actualMembers = Stream.concat(
+
+ expectAllowedMembers.stream().map(member -> new Trial(member, true)),
+ expectDeniedMembers.stream().map(member -> new Trial(member, false))
+
+ ).map(trial -> {
+
+ // obtain AccessibleObject to be used to perform reflective access
+ AccessibleObject accessibleObject = trial.member.apply(memberClass);
+
+ // only need target 'obj' for instance fields and methods
+ Object obj =
+ (accessibleObject instanceof Field &&
+ !Modifier.isStatic(((Field) accessibleObject).getModifiers())
+ ||
+ accessibleObject instanceof Method &&
+ !Modifier.isStatic(((Method) accessibleObject).getModifiers())
+ )
+ ? target : null;
+
+ // invoke checkAccess method and let it perform the reflective access
+ try {
+ checkAccessMethod.invoke(null, accessibleObject, obj);
+ trial.actualAllowed = true;
+ } catch (IllegalAccessException e) {
+ // should not happen as checkAccessMethod.isAccessible()
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ if (e.getTargetException() instanceof IllegalAccessException) {
+ trial.actualAllowed = false;
+ } else {
+ // any other Exception is a fault in test or infrastructure - fail fast
+ throw new RuntimeException(e.getTargetException());
+ }
+ }
+
+ if (!generateCases) {
+ System.out.printf(
+ "%-26s accessing %26s's %-25s %-43s - expected %s, actual %s: %s\n",
+ currentClassSupplier, memberClassSupplier, trial.member.name(),
+ (obj == null ? "" : "with instance of " + targetClassSupplier),
+ (trial.expectAllowed ? "allowed" : "denied "),
+ (trial.actualAllowed ? "allowed" : "denied "),
+ (trial.expectAllowed == trial.actualAllowed ? "OK" : "FAILURE")
+ );
+ }
+
+ return trial;
+
+ }).collect(
+ groupingBy(
+ Trial::isActualAllowed,
+ mapping(
+ Trial::getMember,
+ toCollection(() -> EnumSet.noneOf(MemberFactory.class))))
+ );
+
+ EnumSet<MemberFactory> actualAllowedMembers =
+ Optional.ofNullable(actualMembers.get(true))
+ .orElse(EnumSet.noneOf(MemberFactory.class));
+ EnumSet<MemberFactory> actualDeniedMembers =
+ Optional.ofNullable(actualMembers.get(false))
+ .orElse(EnumSet.noneOf(MemberFactory.class));
+
+ if (generateCases) {
+ System.out.printf(
+ " ok &= new Test()\n" +
+ " .current(%s)\n" +
+ " .member (%s).target(%s)\n",
+ currentClassSupplier,
+ memberClassSupplier, targetClassSupplier
+ );
+
+ if (!actualAllowedMembers.isEmpty()) {
+ EnumSet<? extends Enum> actualAllowed =
+ MemberFactory.membersToGroupsOrNull(actualAllowedMembers);
+ if (actualAllowed == null)
+ actualAllowed = actualAllowedMembers;
+ System.out.print(
+ chunkBy(3, actualAllowed.stream().map(Enum::name))
+ .map(chunk -> chunk.collect(joining(", ")))
+ .collect(joining(",\n" +
+ " ",
+ " .allowed(",
+ ")\n"))
+ );
+ }
+
+ if (!actualDeniedMembers.isEmpty()) {
+ EnumSet<? extends Enum> actualDenied =
+ MemberFactory.membersToGroupsOrNull(actualDeniedMembers);
+ if (actualDenied == null)
+ actualDenied = actualAllowedMembers;
+ System.out.print(
+ chunkBy(3, actualDenied.stream().map(Enum::name))
+ .map(chunk -> chunk.collect(joining(", ")))
+ .collect(joining(",\n" +
+ " ",
+ " .denied (",
+ ")\n"))
+ );
+ }
+
+ System.out.print(
+ " .perform();\n"
+ );
+ }
+
+ return expectAllowedMembers.equals(actualAllowedMembers) &&
+ expectDeniedMembers.equals(actualDeniedMembers);
+ }
+ }
+
+ private static <T> Stream<Stream<T>> chunkBy(int chunkSize, Stream<T> stream) {
+ Iterator<T> elements = stream.iterator();
+ Stream.Builder<Stream<T>> b1 = Stream.builder();
+ while (elements.hasNext()) {
+ Stream.Builder<T> b2 = Stream.builder();
+ for (int i = 0; i < chunkSize && elements.hasNext(); i++) {
+ b2.accept(elements.next());
+ }
+ b1.accept(b2.build());
+ }
+ return b1.build();
+ }
+
+ private static class Trial {
+ final MemberFactory member;
+ final boolean expectAllowed;
+ boolean actualAllowed;
+
+ Trial(MemberFactory member, boolean expectAllowed) {
+ this.member = member;
+ this.expectAllowed = expectAllowed;
+ }
+
+ MemberFactory getMember() {
+ return member;
+ }
+
+ boolean isActualAllowed() {
+ return actualAllowed;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/a/Package.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+package a;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A package-private class in a.
+ */
+class Package {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private Package(Void _1, Void _2, Void _3) {}
+ Package(Void _1, Void _2) {}
+ protected Package(Void _1) {}
+ public Package() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/a/PublicSuper.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+package a;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A public class in a which is a superclass of public class in b.
+ */
+public class PublicSuper {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private PublicSuper(Void _1, Void _2, Void _3) {}
+ PublicSuper(Void _1, Void _2) {}
+ protected PublicSuper(Void _1) {}
+ public PublicSuper() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/b/Package.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+package b;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A package-private class in b.
+ */
+class Package {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private Package(Void _1, Void _2, Void _3) {}
+ Package(Void _1, Void _2) {}
+ protected Package(Void _1) {}
+ public Package() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/b/PublicSub.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+package b;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * A public class in b which is a subclass of public class in a.
+ */
+public class PublicSub extends a.PublicSuper {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private PublicSub(Void _1, Void _2, Void _3) {}
+ PublicSub(Void _1, Void _2) {}
+ protected PublicSub(Void _1) {}
+ public PublicSub() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/util/ClassSupplier.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+package util;
+
+import java.util.function.Supplier;
+
+/**
+ * An enumeration of suppliers of test classes.
+ */
+public enum ClassSupplier implements Supplier<Class<?>> {
+ PACKAGE_CLASS_IN_PKG_A("a.Package"),
+ PUBLIC_SUPERCLASS_IN_PKG_A("a.PublicSuper"),
+ PACKAGE_CLASS_IN_PKG_B("b.Package"),
+ PUBLIC_SUBCLASS_IN_PKG_B("b.PublicSub");
+
+ private final String className;
+
+ ClassSupplier(String className) {
+ this.className = className;
+ }
+
+ @Override
+ public Class<?> get() {
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ throw (Error) new NoClassDefFoundError(className).initCause(e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/util/MemberFactory.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+package util;
+
+import java.lang.reflect.AccessibleObject;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import static util.MemberFactory.Kind.CONSTRUCTOR;
+import static util.MemberFactory.Kind.FIELD;
+import static util.MemberFactory.Kind.METHOD;
+
+/**
+ * Enumeration of:
+ * <p>
+ * {private, package, protected, public} x {instance, static} x {field, method}
+ * <p>
+ * and:
+ * <p>
+ * {private, package, protected, public} x {constructor},
+ * <p>
+ * with each element acting as a factory of AccessibleObject(s)
+ * declared by given declaringClass(es).
+ */
+public enum MemberFactory implements Function<Class<?>, AccessibleObject> {
+ // instance fields
+ PRIVATE_INSTANCE_FIELD(FIELD, "privateInstance"),
+ PACKAGE_INSTANCE_FIELD(FIELD, "packageInstance"),
+ PROTECTED_INSTANCE_FIELD(FIELD, "protectedInstance"),
+ PUBLIC_INSTANCE_FIELD(FIELD, "publicInstance"),
+ // instance methods
+ PRIVATE_INSTANCE_METHOD(METHOD, "privateInstance"),
+ PACKAGE_INSTANCE_METHOD(METHOD, "packageInstance"),
+ PROTECTED_INSTANCE_METHOD(METHOD, "protectedInstance"),
+ PUBLIC_INSTANCE_METHOD(METHOD, "publicInstance"),
+ // static fields
+ PRIVATE_STATIC_FIELD(FIELD, "privateStatic"),
+ PACKAGE_STATIC_FIELD(FIELD, "packageStatic"),
+ PROTECTED_STATIC_FIELD(FIELD, "protectedStatic"),
+ PUBLIC_STATIC_FIELD(FIELD, "publicStatic"),
+ // static methods
+ PRIVATE_STATIC_METHOD(METHOD, "privateStatic"),
+ PACKAGE_STATIC_METHOD(METHOD, "packageStatic"),
+ PROTECTED_STATIC_METHOD(METHOD, "protectedStatic"),
+ PUBLIC_STATIC_METHOD(METHOD, "publicStatic"),
+ // constructors
+ PRIVATE_CONSTRUCTOR(CONSTRUCTOR, null, Void.class, Void.class, Void.class),
+ PACKAGE_CONSTRUCTOR(CONSTRUCTOR, null, Void.class, Void.class),
+ PROTECTED_CONSTRUCTOR(CONSTRUCTOR, null, Void.class),
+ PUBLIC_CONSTRUCTOR(CONSTRUCTOR, null),;
+
+ final Kind kind;
+ final String name;
+ final Class<?>[] parameterTypes;
+
+ MemberFactory(Kind kind, String name, Class<?>... parameterTypes) {
+ this.kind = kind;
+ this.name = name;
+ this.parameterTypes = parameterTypes;
+ }
+
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass) {
+ return kind.apply(declaringClass, this);
+ }
+
+ public static EnumSet<MemberFactory> asSet(MemberFactory... members) {
+ return members.length == 0 ? EnumSet.noneOf(MemberFactory.class)
+ : EnumSet.copyOf(Arrays.asList(members));
+ }
+
+ /**
+ * @param members the set of MemberFactory(s) to convert to set of
+ * MemberFactory.Group(s).
+ * @return a set of groups that cover all elements of the members set if
+ * such set of groups exists or null if it doesn't.
+ */
+ public static EnumSet<Group> membersToGroupsOrNull(EnumSet<MemberFactory> members) {
+ EnumSet<MemberFactory> mSet = members.clone();
+ EnumSet<Group> gSet = EnumSet.allOf(Group.class);
+ Iterator<Group> gIter = gSet.iterator();
+ while (gIter.hasNext()) {
+ Group g = gIter.next();
+ if (mSet.containsAll(g.members)) {
+ mSet.removeAll(g.members);
+ } else {
+ gIter.remove();
+ }
+ }
+ return mSet.isEmpty() ? gSet : null;
+ }
+
+ /**
+ * @param groups the set of MemberFactory.Group(s) to convert to set of
+ * MemberFactory(s).
+ * @return a set of members as a union of members of all groups.
+ */
+ public static EnumSet<MemberFactory> groupsToMembers(EnumSet<Group> groups) {
+ EnumSet<MemberFactory> mSet = EnumSet.noneOf(MemberFactory.class);
+ for (Group g : groups) {
+ mSet.addAll(g.members);
+ }
+ return mSet;
+ }
+
+ enum Kind implements BiFunction<Class<?>, MemberFactory, AccessibleObject> {
+ FIELD {
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredField(factory.name);
+ } catch (NoSuchFieldException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ },
+ METHOD {
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredMethod(factory.name, factory.parameterTypes);
+ } catch (NoSuchMethodException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ },
+ CONSTRUCTOR {
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredConstructor(factory.parameterTypes);
+ } catch (NoSuchMethodException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ }
+ }
+
+ /**
+ * We define groups of MemberFactory(s) for members that commonly
+ * exhibit same access restrictions in various cases in order to allow
+ * specifying groups instead of individual members in the test cases,
+ * making them less verbose.
+ */
+ public enum Group {
+ // all members
+ ALL(MemberFactory.values()),
+ // all private members
+ PRIVATE_MEMBERS(PRIVATE_INSTANCE_FIELD, PRIVATE_INSTANCE_METHOD,
+ PRIVATE_STATIC_FIELD, PRIVATE_STATIC_METHOD,
+ PRIVATE_CONSTRUCTOR),
+ // all package members
+ PACKAGE_MEMBERS(PACKAGE_INSTANCE_FIELD, PACKAGE_INSTANCE_METHOD,
+ PACKAGE_STATIC_FIELD, PACKAGE_STATIC_METHOD,
+ PACKAGE_CONSTRUCTOR),
+ // all protected members
+ PROTECTED_MEMBERS(PROTECTED_INSTANCE_FIELD, PROTECTED_INSTANCE_METHOD,
+ PROTECTED_STATIC_FIELD, PROTECTED_STATIC_METHOD,
+ PROTECTED_CONSTRUCTOR),
+ // all public members
+ PUBLIC_MEMBERS(PUBLIC_INSTANCE_FIELD, PUBLIC_INSTANCE_METHOD,
+ PUBLIC_STATIC_FIELD, PUBLIC_STATIC_METHOD,
+ PUBLIC_CONSTRUCTOR),
+ // instance field and method pairs
+ PRIVATE_INSTANCE_F_M(PRIVATE_INSTANCE_FIELD, PRIVATE_INSTANCE_METHOD),
+ PACKAGE_INSTANCE_F_M(PACKAGE_INSTANCE_FIELD, PACKAGE_INSTANCE_METHOD),
+ PROTECTED_INSTANCE_F_M(PROTECTED_INSTANCE_FIELD, PROTECTED_INSTANCE_METHOD),
+ PUBLIC_INSTANCE_F_M(PUBLIC_INSTANCE_FIELD, PUBLIC_INSTANCE_METHOD),
+ // static field and method pairs
+ PRIVATE_STATIC_F_M(PRIVATE_STATIC_FIELD, PRIVATE_STATIC_METHOD),
+ PACKAGE_STATIC_F_M(PACKAGE_STATIC_FIELD, PACKAGE_STATIC_METHOD),
+ PROTECTED_STATIC_F_M(PROTECTED_STATIC_FIELD, PROTECTED_STATIC_METHOD),
+ PUBLIC_STATIC_F_M(PUBLIC_STATIC_FIELD, PUBLIC_STATIC_METHOD),
+ // constructor singles
+ PRIVATE_C(PRIVATE_CONSTRUCTOR),
+ PACKAGE_C(PACKAGE_CONSTRUCTOR),
+ PROTECTED_C(PROTECTED_CONSTRUCTOR),
+ PUBLIC_C(PUBLIC_CONSTRUCTOR);
+
+ final EnumSet<MemberFactory> members;
+
+ Group(MemberFactory... members) {
+ this.members = EnumSet.copyOf(Arrays.asList(members));
+ }
+
+ public static EnumSet<Group> asSet(Group... groups) {
+ return groups.length == 0 ? EnumSet.noneOf(Group.class)
+ : EnumSet.copyOf(Arrays.asList(groups));
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/server/UnicastRemoteObject/serialFilter/FilterUROTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2016, 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.io.InvalidClassException;
+import java.io.ObjectInputFilter;
+import java.io.Serializable;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.UnmarshalException;
+import java.rmi.server.UnicastRemoteObject;
+
+import java.util.Objects;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @run testng/othervm FilterUROTest
+ * @summary Check that objects are exported with ObjectInputFilters via UnicastRemoteObject
+ */
+public class FilterUROTest {
+
+ /**
+ * Data to test serialFilter call counts.
+ * - name
+ * - Object
+ * - expected count of calls to checkInput.
+ *
+ * @return array of test data
+ */
+ @DataProvider(name = "bindData")
+ static Object[][] bindObjects() {
+ Object[][] data = {
+ {"SimpleString", "SimpleString", 0},
+ {"String", new XX("now is the time"), 1},
+ {"String[]", new XX(new String[3]), 3},
+ {"Long[4]", new XX(new Long[4]), 3},
+ {"RejectME", new XX(new RejectME()), -1},
+ };
+ return data;
+ }
+
+ /*
+ * Test exporting an object with a serialFilter using exportObject().
+ * Send some objects and check the number of calls to the serialFilter.
+ */
+ @Test(dataProvider = "bindData")
+ public void useExportObject(String name, Object obj, int expectedFilterCount) throws RemoteException {
+ try {
+ RemoteImpl impl = RemoteImpl.create();
+ Echo client = (Echo) UnicastRemoteObject
+ .exportObject(impl, 0, impl.checker);
+ int count = client.filterCount(obj);
+ System.out.printf("count: %d, obj: %s%n", count, obj);
+ Assert.assertEquals(count, expectedFilterCount, "wrong number of filter calls");
+ } catch (RemoteException rex) {
+ if (expectedFilterCount == -1 &&
+ UnmarshalException.class.equals(rex.getCause().getClass()) &&
+ InvalidClassException.class.equals(rex.getCause().getCause().getClass())) {
+ return; // normal expected exception
+ }
+ rex.printStackTrace();
+ Assert.fail("unexpected remote exception", rex);
+ } catch (Exception rex) {
+ Assert.fail("unexpected exception", rex);
+ }
+ }
+
+ /*
+ * Test exporting an object with a serialFilter using exportObject()
+ * with explicit (but null) SocketFactories.
+ * Send some objects and check the number of calls to the serialFilter.
+ */
+ @Test(dataProvider = "bindData")
+ public void useExportObject2(String name, Object obj, int expectedFilterCount) throws RemoteException {
+ try {
+ RemoteImpl impl = RemoteImpl.create();
+ Echo client = (Echo) UnicastRemoteObject
+ .exportObject(impl, 0, null, null, impl.checker);
+ int count = client.filterCount(obj);
+ System.out.printf("count: %d, obj: %s%n", count, obj);
+ Assert.assertEquals(count, expectedFilterCount, "wrong number of filter calls");
+ } catch (RemoteException rex) {
+ if (expectedFilterCount == -1 &&
+ UnmarshalException.class.equals(rex.getCause().getClass()) &&
+ InvalidClassException.class.equals(rex.getCause().getCause().getClass())) {
+ return; // normal expected exception
+ }
+ rex.printStackTrace();
+ Assert.fail("unexpected remote exception", rex);
+ } catch (Exception rex) {
+ Assert.fail("unexpected exception", rex);
+ }
+ }
+
+ /**
+ * A simple Serializable holding an object that is passed by value.
+ * It and its contents are checked by the filter.
+ */
+ static class XX implements Serializable {
+ private static final long serialVersionUID = 362498820763181265L;
+
+ final Object obj;
+
+ XX(Object obj) {
+ this.obj = obj;
+ }
+
+ public String toString() {
+ return super.toString() + "//" + Objects.toString(obj);
+ }
+ }
+
+ interface Echo extends Remote {
+ int filterCount(Object obj) throws RemoteException;
+ }
+
+ /**
+ * This remote object just counts the calls to the serialFilter
+ * and returns it. The caller can check the number against
+ * what was expected for the object passed as an argument.
+ * A new RemoteImpl is used for each test so the count starts at zero again.
+ */
+ static class RemoteImpl implements Echo {
+
+ private static final long serialVersionUID = -6999613679881262446L;
+
+ transient Checker checker;
+
+ static RemoteImpl create() throws RemoteException {
+ RemoteImpl impl = new RemoteImpl(new Checker());
+ return impl;
+ }
+
+ private RemoteImpl(Checker checker) throws RemoteException {
+ this.checker = checker;
+ }
+
+ public int filterCount(Object obj) throws RemoteException {
+ return checker.count();
+ }
+
+ }
+
+ /**
+ * A ObjectInputFilter that just counts when it is called.
+ */
+ static class Checker implements ObjectInputFilter {
+ int count;
+
+ @Override
+ public Status checkInput(FilterInfo filterInfo) {
+ if (filterInfo.serialClass() == RejectME.class) {
+ return Status.REJECTED;
+ }
+ count++;
+ return Status.UNDECIDED;
+ }
+
+ public int count() {
+ return count;
+ }
+ }
+
+ /**
+ * A class to be rejected by the filter.
+ */
+ static class RejectME implements Serializable {
+ private static final long serialVersionUID = 2L;
+ }
+}
--- a/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/java/time/test/java/time/chrono/TestUmmAlQuraChronology.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -624,7 +624,7 @@
@Test
public void test_chronoFields() {
ChronoLocalDate hdate = HijrahChronology.INSTANCE.date(1434, 6, 28);
- assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), 3);
+ assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), 7);
assertEquals(hdate.get(ChronoField.ALIGNED_DAY_OF_WEEK_IN_YEAR), 7);
assertEquals(hdate.get(ChronoField.ALIGNED_WEEK_OF_MONTH), 4);
assertEquals(hdate.get(ChronoField.ALIGNED_WEEK_OF_YEAR), 25);
@@ -785,4 +785,32 @@
public void test_hijrahToJapanese(HijrahDate hijrah, String japanese) {
assertEquals(JapaneseChronology.INSTANCE.date(hijrah).toString(), japanese);
}
+
+ @DataProvider(name="alignedDayOfWeekInMonthTestDates")
+ Object[][] data_alignedDayOfWeekInMonth() {
+ return new Object[][] {
+ {1437, 9, 1, 1, 1},
+ {1437, 10, 1, 1, 1},
+ {1437, 10, 11, 2, 4},
+ {1437, 10, 29, 5, 1},
+ };
+ }
+
+ //-----------------------------------------------------------------------
+ // Test for aligned-week-of-month calculation based on the day-of-month
+ //-----------------------------------------------------------------------
+ @Test(dataProvider="alignedDayOfWeekInMonthTestDates")
+ public void test_alignedWeekOfMonth(int year, int month, int dom, int wom, int dowm) {
+ HijrahDate date = HijrahChronology.INSTANCE.date(year, month, dom);
+ assertEquals(date.getLong(ChronoField.ALIGNED_WEEK_OF_MONTH), wom);
+ }
+
+ //-----------------------------------------------------------------------
+ // Test for aligned-day-of-week calculation based on the day-of-month
+ //-----------------------------------------------------------------------
+ @Test(dataProvider="alignedDayOfWeekInMonthTestDates")
+ public void test_alignedDayOfWeekInMonth(int year, int month, int dom, int wom, int dowm) {
+ HijrahDate date = HijrahChronology.INSTANCE.date(year, month, dom);
+ assertEquals(date.getLong(ChronoField.ALIGNED_DAY_OF_WEEK_IN_MONTH), dowm);
+ }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/format/TestNarrowMonthNamesAndDayNames.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+package test.java.time.format;
+
+/*
+ * @test
+ * @bug 8146750
+ * @summary Test Narrow and NarrowStandalone month names are retrieved correctly.
+ */
+import static org.testng.Assert.assertEquals;
+
+import java.time.DayOfWeek;
+import java.time.Month;
+import java.time.format.TextStyle;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class TestNarrowMonthNamesAndDayNames {
+
+ static {
+ System.setProperty("java.locale.providers", "COMPAT");
+ }
+
+ private static final List<Month> MONTHVALUES = Arrays.asList(Month.values());
+ private static final List<DayOfWeek> DAYVALUES = Arrays.asList(DayOfWeek.values());
+ private static final List<TextStyle> TEXTSTYLELIST = Arrays.asList(TextStyle.NARROW,
+ TextStyle.NARROW_STANDALONE);
+ private static final List<Locale> LOCARR = Arrays.asList(Locale.US,
+ Locale.GERMANY,
+ Locale.FRANCE,
+ new Locale("no", "NO"));
+
+ /**
+ * Locale en_US, de_DE, fr_FR, no_NO will have same Narrow and
+ * Narrow_Standalone month Names for COMPAT Provider.
+ */
+ @DataProvider(name = "MonthNarrows")
+ public Object[][] monthNameData() {
+ return new Object[][]{{new String[]{
+ "J",
+ "F",
+ "M",
+ "A",
+ "M",
+ "J",
+ "J",
+ "A",
+ "S",
+ "O",
+ "N",
+ "D"
+ }},};
+ }
+
+ //-----------------------------------------------------------------------
+ // Check Narrow and Narrow_standalone month name values
+ //-----------------------------------------------------------------------
+ @Test(dataProvider = "MonthNarrows")
+ public void compareMonthNarrowValues(String[] monthNarrowExpected) {
+ LOCARR.forEach((loc) -> {
+ TEXTSTYLELIST.forEach((style) -> {
+ MONTHVALUES.forEach((value) -> {
+ String result = value.getDisplayName(style, loc);
+ int index = value.ordinal();
+ assertEquals(result, monthNarrowExpected[index], "Test failed"
+ + " for COMPAT Provider for locale "
+ + loc + " for style " + style.name()
+ + " with Month value " + value.name());
+ });
+ });
+ });
+ }
+
+ /**
+ * Locale en_US, de_DE, fr_FR, no_NO will have different Narrow and
+ * Narrow_Standalone Day Names for COMPAT Provider.
+ */
+ @DataProvider(name = "DayNarrows")
+ public Object[][] dayNameData() {
+ return new Object[][]{
+ {Locale.US, new String[]{"M", "T", "W", "T", "F", "S", "S"}},
+ {Locale.GERMANY, new String[]{"M", "D", "M", "D", "F", "S", "S"}},
+ {Locale.FRANCE, new String[]{"L", "M", "M", "J", "V", "S", "D"}},
+ {new Locale("no", "NO"), new String[]{"M", "T", "O", "T", "F", "L", "S"}},};
+ }
+
+ //-----------------------------------------------------------------------
+ // Check Narrow and Narrow_standalone Day name values
+ //-----------------------------------------------------------------------
+ @Test(dataProvider = "DayNarrows")
+ public void compareDayNarrowValues(Locale locale, String[] dayNarrowExpected) {
+ TEXTSTYLELIST.forEach((style) -> {
+ DAYVALUES.forEach((value) -> {
+ String result = value.getDisplayName(style, locale);
+ int index = value.ordinal();
+ assertEquals(result, dayNarrowExpected[index], "Test failed"
+ + " for COMPAT Provider for locale "
+ + locale + " for style " + style.name()
+ + " with Day value " + value.name());
+ });
+ });
+ }
+}
--- a/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Wed Jul 05 22:22:15 2017 +0200
@@ -88,6 +88,7 @@
${TESTJAVA}${FS}bin${FS}java \
${TESTVMOPTS} \
+ -Djava.security.properties=${TESTSRC}${FS}security.properties \
-classpath "${TESTSRC}${FS}P1.jar${PS}${TESTSRC}${FS}P2.jar${PS}." \
FailOverTest
result=$?
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/crypto/SecretKeyFactory/security.properties Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,6 @@
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+
+jdk.security.provider.preferred=
+jdk.jar.disabledAlgorithms=
+
--- a/jdk/test/javax/net/ssl/templates/SSLTest.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/javax/net/ssl/templates/SSLTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -94,12 +94,22 @@
/*
* Is the server ready to serve?
*/
- private final CountDownLatch serverCondition = new CountDownLatch(1);
+ private final CountDownLatch serverReadyCondition = new CountDownLatch(1);
/*
* Is the client ready to handshake?
*/
- private final CountDownLatch clientCondition = new CountDownLatch(1);
+ private final CountDownLatch clientReadyCondition = new CountDownLatch(1);
+
+ /*
+ * Is the server done?
+ */
+ private final CountDownLatch serverDoneCondition = new CountDownLatch(1);
+
+ /*
+ * Is the client done?
+ */
+ private final CountDownLatch clientDoneCondition = new CountDownLatch(1);
/*
* Public API.
@@ -162,6 +172,25 @@
return keystore;
}
+ // Try to accept a connection in 30 seconds.
+ public static SSLSocket accept(SSLServerSocket sslServerSocket)
+ throws IOException {
+
+ return accept(sslServerSocket, SERVER_TIMEOUT);
+ }
+
+ public static SSLSocket accept(SSLServerSocket sslServerSocket, int timeout)
+ throws IOException {
+
+ try {
+ sslServerSocket.setSoTimeout(timeout);
+ return (SSLSocket) sslServerSocket.accept();
+ } catch (SocketTimeoutException ste) {
+ sslServerSocket.close();
+ return null;
+ }
+ }
+
public SSLTest setSeparateServerThread(boolean separateServerThread) {
this.separateServerThread = separateServerThread;
return this;
@@ -202,33 +231,61 @@
}
public void signalServerReady() {
- serverCondition.countDown();
+ serverReadyCondition.countDown();
+ }
+
+ public void signalServerDone() {
+ serverDoneCondition.countDown();
}
public boolean waitForClientSignal(long timeout, TimeUnit unit)
throws InterruptedException {
- return clientCondition.await(timeout, unit);
+ return clientReadyCondition.await(timeout, unit);
}
public boolean waitForClientSignal() throws InterruptedException {
return waitForClientSignal(CLIENT_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
}
+ public boolean waitForClientDone(long timeout, TimeUnit unit)
+ throws InterruptedException {
+
+ return clientDoneCondition.await(timeout, unit);
+ }
+
+ public boolean waitForClientDone() throws InterruptedException {
+ return waitForClientDone(CLIENT_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
+ }
+
public void signalClientReady() {
- clientCondition.countDown();
+ clientReadyCondition.countDown();
+ }
+
+ public void signalClientDone() {
+ clientDoneCondition.countDown();
}
public boolean waitForServerSignal(long timeout, TimeUnit unit)
throws InterruptedException {
- return serverCondition.await(timeout, unit);
+ return serverReadyCondition.await(timeout, unit);
}
public boolean waitForServerSignal() throws InterruptedException {
return waitForServerSignal(SERVER_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
}
+ public boolean waitForServerDone(long timeout, TimeUnit unit)
+ throws InterruptedException {
+
+ return serverDoneCondition.await(timeout, unit);
+ }
+
+ public boolean waitForServerDone() throws InterruptedException {
+ return waitForServerDone(SERVER_SIGNAL_TIMEOUT, TimeUnit.SECONDS);
+ }
+
public SSLTest setServerPeer(Peer serverPeer) {
this.serverPeer = serverPeer;
return this;
@@ -310,19 +367,14 @@
test.signalServerReady();
// Try to accept a connection in 30 seconds.
- SSLSocket sslSocket;
- try {
- sslServerSocket.setSoTimeout(SERVER_TIMEOUT);
- sslSocket = (SSLSocket) sslServerSocket.accept();
- print("Server accepted connection");
- } catch (SocketTimeoutException ste) {
- sslServerSocket.close();
-
+ SSLSocket sslSocket = accept(sslServerSocket);
+ if (sslSocket == null) {
// Ignore the test case if no connection within 30 seconds.
print("No incoming client connection in 30 seconds. "
- + "Ignore in server side.", ste);
+ + "Ignore in server side.");
return;
}
+ print("Server accepted connection");
// handle the connection
try {
@@ -353,6 +405,8 @@
sslSocket.close();
sslServerSocket.close();
}
+
+ test.signalServerDone();
}
/*
@@ -419,6 +473,8 @@
print("Run client application");
test.getClientApplication().run(sslSocket, test);
}
+
+ test.signalClientDone();
}
/*
--- a/jdk/test/javax/script/DummyScriptEngineFactory.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/javax/script/DummyScriptEngineFactory.java Wed Jul 05 22:22:15 2017 +0200
@@ -91,9 +91,10 @@
}
public String getProgram(String... statements) {
+ Objects.requireNonNull(statements);
StringBuffer buf = new StringBuffer();
- for (int i = 0; i < statements.length; i++) {
- buf.append(statements[i]);
+ for (String stat : statements) {
+ buf.append(Objects.requireNonNull(stat));
}
return buf.toString();
}
--- a/jdk/test/lib/testlibrary/jdk/testlibrary/JarUtils.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/JarUtils.java Wed Jul 05 22:22:15 2017 +0200
@@ -24,6 +24,7 @@
package jdk.testlibrary;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
@@ -40,7 +41,8 @@
public final class JarUtils {
/**
- * Create jar file with specified files.
+ * Create jar file with specified files. If a specified file does not exist,
+ * a new jar entry will be created with the file name itself as the content.
*/
public static void createJar(String dest, String... files)
throws IOException {
@@ -54,6 +56,8 @@
jos.putNextEntry(new JarEntry(file));
try (FileInputStream fis = new FileInputStream(file)) {
fis.transferTo(jos);
+ } catch (FileNotFoundException e) {
+ jos.write(file.getBytes());
}
}
}
@@ -61,7 +65,17 @@
}
/**
- * Add specified files to existing jar file.
+ * Add or remove specified files to existing jar file. If a specified file
+ * to be updated or added does not exist, the jar entry will be created
+ * with the file name itself as the content.
+ *
+ * @param src the original jar file name
+ * @param dest the new jar file name
+ * @param files the files to update. The list is broken into 2 groups
+ * by a "-" string. The files before in the 1st group will
+ * be either updated or added. The files in the 2nd group
+ * will be removed. If no "-" exists, all files belong to
+ * the 1st group.
*/
public static void updateJar(String src, String dest, String... files)
throws IOException {
@@ -77,8 +91,11 @@
JarEntry entry = entries.nextElement();
String name = entry.getName();
boolean found = false;
+ boolean update = true;
for (String file : files) {
- if (name.equals(file)) {
+ if (file.equals("-")) {
+ update = false;
+ } else if (name.equals(file)) {
updatedFiles.add(file);
found = true;
break;
@@ -86,11 +103,18 @@
}
if (found) {
- System.out.println(String.format("Updating %s with %s",
- dest, name));
- jos.putNextEntry(new JarEntry(name));
- try (FileInputStream fis = new FileInputStream(name)) {
- fis.transferTo(jos);
+ if (update) {
+ System.out.println(String.format("Updating %s with %s",
+ dest, name));
+ jos.putNextEntry(new JarEntry(name));
+ try (FileInputStream fis = new FileInputStream(name)) {
+ fis.transferTo(jos);
+ } catch (FileNotFoundException e) {
+ jos.write(name.getBytes());
+ }
+ } else {
+ System.out.println(String.format("Removing %s from %s",
+ name, dest));
}
} else {
System.out.println(String.format("Copying %s to %s",
@@ -103,12 +127,17 @@
// append new files
for (String file : files) {
+ if (file.equals("-")) {
+ break;
+ }
if (!updatedFiles.contains(file)) {
System.out.println(String.format("Adding %s with %s",
dest, file));
jos.putNextEntry(new JarEntry(file));
try (FileInputStream fis = new FileInputStream(file)) {
fis.transferTo(jos);
+ } catch (FileNotFoundException e) {
+ jos.write(file.getBytes());
}
}
}
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/OriginServer.java Thu Oct 20 18:38:09 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2001, 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.
- */
-
-/*
- *
- * This is a HTTP test server used by the regression test
- * for the bug fixes: 4323990, 4413069
- */
-
-import java.io.*;
-import java.net.*;
-import javax.net.*;
-
-/*
- * OriginServer.java -- a simple server that can serve
- * Http get request in both clear and secure channel
- */
-
-public abstract class OriginServer implements Runnable {
-
- private ServerSocket server = null;
- Exception serverException = null;
- /**
- * Constructs a OriginServer based on ss and
- * obtains a response data's bytecodes using the method
- * getBytes.
- */
- protected OriginServer(ServerSocket ss) throws Exception
- {
- server = ss;
- newListener();
- if (serverException != null)
- throw serverException;
- }
-
- /**
- * Returns an array of bytes containing the bytes for
- * the data sent in the response.
- *
- * @return the bytes for the information that is being sent
- */
- public abstract byte[] getBytes();
-
- /**
- * The "listen" thread that accepts a connection to the
- * server, parses the header and sends back the response
- */
- public void run()
- {
- Socket socket;
-
- // accept a connection
- try {
- socket = server.accept();
- } catch (IOException e) {
- System.out.println("Class Server died: " + e.getMessage());
- serverException = e;
- return;
- }
- try {
- DataOutputStream out =
- new DataOutputStream(socket.getOutputStream());
- try {
- BufferedReader in =
- new BufferedReader(new InputStreamReader(
- socket.getInputStream()));
- // read the request
- readRequest(in);
- // retrieve bytecodes
- byte[] bytecodes = getBytes();
- // send bytecodes in response (assumes HTTP/1.0 or later)
- try {
- out.writeBytes("HTTP/1.0 200 OK\r\n");
- out.writeBytes("Content-Length: " + bytecodes.length +
- "\r\n");
- out.writeBytes("Content-Type: text/html\r\n\r\n");
- out.write(bytecodes);
- out.flush();
- } catch (IOException ie) {
- serverException = ie;
- return;
- }
-
- } catch (Exception e) {
- // write out error response
- out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");
- out.writeBytes("Content-Type: text/html\r\n\r\n");
- out.flush();
- }
-
- } catch (IOException ex) {
- System.out.println("error writing response: " + ex.getMessage());
- serverException = ex;
-
- } finally {
- try {
- socket.close();
- } catch (IOException e) {
- serverException = e;
- }
- }
- }
-
- /**
- * Create a new thread to listen.
- */
- private void newListener()
- {
- (new Thread(this)).start();
- }
-
- /**
- * read the response, don't care for the syntax of the request-line
- * for this testing
- */
- private static void readRequest(BufferedReader in)
- throws IOException
- {
- String line = null;
- System.out.println("Server received: ");
- do {
- if (line != null)
- System.out.println(line);
- line = in.readLine();
- } while ((line.length() != 0) &&
- (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
- }
-}
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyAuthTest.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyAuthTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,22 +23,38 @@
/*
* @test
- * @bug 4323990 4413069
+ * @bug 4323990 4413069 8160838
* @summary HttpsURLConnection doesn't send Proxy-Authorization on CONNECT
* Incorrect checking of proxy server response
* @modules java.base/sun.net.www
- * @run main/othervm ProxyAuthTest
- *
- * No way to reserve and restore java.lang.Authenticator, need to run this
- * test in othervm mode.
+ * @library /javax/net/ssl/templates
+ * @run main/othervm ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic, ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=BAsIc ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic,Digest ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Unknown,bAsIc ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes= ProxyAuthTest succeed
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Digest,NTLM,Negotiate ProxyAuthTest succeed
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=UNKNOWN,notKnown ProxyAuthTest succeed
*/
-import java.io.*;
-import java.net.*;
-import java.security.KeyStore;
-import javax.net.*;
-import javax.net.ssl.*;
-import java.security.cert.*;
+// No way to reserve and restore java.lang.Authenticator, as well as read-once
+// system properties, so this tests needs to run in othervm mode.
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.Authenticator;
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.Proxy;
+import java.net.URL;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+import static java.nio.charset.StandardCharsets.US_ASCII;
/*
* ProxyAuthTest.java -- includes a simple server that can serve
@@ -56,132 +72,167 @@
static String trustStoreFile = "truststore";
static String passwd = "passphrase";
- volatile private static int serverPort = 0;
-
- /*
- * The TestServer implements a OriginServer that
- * processes HTTP requests and responses.
+ /**
+ * read the response, don't care for the syntax of the request-line
+ * for this testing
*/
- static class TestServer extends OriginServer {
- public TestServer(ServerSocket ss) throws Exception {
- super(ss);
- }
-
- /*
- * Returns an array of bytes containing the bytes for
- * the data sent in the response.
- *
- * @return bytes for the data in the response
- */
- public byte[] getBytes() {
- return "Proxy authentication for tunneling succeeded ..".
- getBytes();
- }
+ private static void readRequest(BufferedReader in) throws IOException {
+ String line = null;
+ System.out.println("Server received: ");
+ do {
+ if (line != null) {
+ System.out.println(line);
+ }
+ line = in.readLine();
+ } while ((line.length() != 0) &&
+ (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
}
/*
* Main method to create the server and the client
*/
public static void main(String args[]) throws Exception {
+ boolean expectSuccess;
+ expectSuccess = args[0].equals("succeed");
+
String keyFilename =
- System.getProperty("test.src", "./") + "/" + pathToStores +
- "/" + keyStoreFile;
+ SSLTest.TEST_SRC + "/" + pathToStores + "/" + keyStoreFile;
String trustFilename =
- System.getProperty("test.src", "./") + "/" + pathToStores +
- "/" + trustStoreFile;
+ SSLTest.TEST_SRC + "/" + pathToStores + "/" + trustStoreFile;
+
+ SSLTest.setup(keyFilename, trustFilename, passwd);
+
+ new SSLTest()
+ .setServerApplication((socket, test) -> {
+ DataOutputStream out = new DataOutputStream(
+ socket.getOutputStream());
- System.setProperty("javax.net.ssl.keyStore", keyFilename);
- System.setProperty("javax.net.ssl.keyStorePassword", passwd);
- System.setProperty("javax.net.ssl.trustStore", trustFilename);
- System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+ try {
+ BufferedReader in = new BufferedReader(
+ new InputStreamReader(socket.getInputStream()));
+
+ // read the request
+ readRequest(in);
+
+ // retrieve bytecodes
+ byte[] bytecodes =
+ "Proxy authentication for tunneling succeeded .."
+ .getBytes(US_ASCII);
- boolean useSSL = true;
- /*
- * setup the server
- */
- try {
- ServerSocketFactory ssf =
- ProxyAuthTest.getServerSocketFactory(useSSL);
- ServerSocket ss = ssf.createServerSocket(serverPort);
- serverPort = ss.getLocalPort();
- new TestServer(ss);
- } catch (Exception e) {
- System.out.println("Server side failed:" +
- e.getMessage());
- throw e;
- }
- // trigger the client
- try {
- doClientSide();
- } catch (Exception e) {
- System.out.println("Client side failed: " + e.getMessage());
- throw e;
- }
+ // send bytecodes in response (assumes HTTP/1.0 or later)
+ out.writeBytes("HTTP/1.0 200 OK\r\n");
+ out.writeBytes("Content-Length: " + bytecodes.length +
+ "\r\n");
+ out.writeBytes("Content-Type: text/html\r\n\r\n");
+ out.write(bytecodes);
+ out.flush();
+ } catch (IOException e) {
+ // write out error response
+ out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");
+ out.writeBytes("Content-Type: text/html\r\n\r\n");
+ out.flush();
+ }
+ })
+ .setClientPeer(test -> {
+ try {
+ doClientSide(test);
+ if (!expectSuccess) {
+ throw new RuntimeException("Expected exception/failure "
+ + "to connect, but succeeded.");
+ }
+ } catch (IOException e) {
+ if (expectSuccess) {
+ System.out.println("Client side failed: "
+ + e.getMessage());
+ throw e;
+ }
+
+ if (! (e.getMessage().contains(
+ "Unable to tunnel through proxy") &&
+ e.getMessage().contains("407")) ) {
+
+ throw new RuntimeException(
+ "Expected exception about cannot tunnel, "
+ + "407, etc, but got", e);
+ } else {
+ // Informative
+ System.out.println("Caught expected exception: "
+ + e.getMessage());
+ }
+ }
+ })
+ .runTest();
}
- private static ServerSocketFactory getServerSocketFactory
- (boolean useSSL) throws Exception {
- if (useSSL) {
- SSLServerSocketFactory ssf = null;
- // set up key manager to do server authentication
- SSLContext ctx;
- KeyManagerFactory kmf;
- KeyStore ks;
- char[] passphrase = passwd.toCharArray();
-
- ctx = SSLContext.getInstance("TLS");
- kmf = KeyManagerFactory.getInstance("SunX509");
- ks = KeyStore.getInstance("JKS");
+ static void doClientSide(SSLTest test) throws IOException {
- ks.load(new FileInputStream(System.getProperty(
- "javax.net.ssl.keyStore")), passphrase);
- kmf.init(ks, passphrase);
- ctx.init(kmf.getKeyManagers(), null, null);
+ // Wait for server to get started.
+ //
+ // The server side takes care of the issue if the server cannot
+ // get started in 90 seconds. The client side would just ignore
+ // the test case if the serer is not ready.
+ try {
+ if (!test.waitForServerSignal()) {
+ System.out.print("The server is not ready yet in 90 seconds. "
+ + "Ignore in client side.");
+ return;
+ }
+ } catch (InterruptedException e) {
+ System.out.print("InterruptedException occured. "
+ + "Ignore in client side.");
+ return;
+ }
- ssf = ctx.getServerSocketFactory();
- return ssf;
- } else {
- return ServerSocketFactory.getDefault();
- }
- }
-
- static void doClientSide() throws Exception {
/*
* setup up a proxy with authentication information
*/
- setupProxy();
+ ProxyTunnelServer ps = setupProxy();
/*
* we want to avoid URLspoofCheck failures in cases where the cert
* DN name does not match the hostname in the URL.
*/
- HttpsURLConnection.setDefaultHostnameVerifier(
- new NameVerifier());
- URL url = new URL("https://" + "localhost:" + serverPort
- + "/index.html");
- BufferedReader in = null;
- try {
- in = new BufferedReader(new InputStreamReader(
- url.openStream()));
+ HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
+
+ InetSocketAddress paddr = new InetSocketAddress(
+ "localhost", ps.getPort());
+ Proxy proxy = new Proxy(Proxy.Type.HTTP, paddr);
+
+ URL url = new URL("https://" + "localhost:" + test.getServerPort()
+ + "/index.html");
+
+ // Signal the server, the client is ready to communicate.
+ test.signalClientReady();
+
+ HttpsURLConnection uc = (HttpsURLConnection) url.openConnection(proxy);
+ try (BufferedReader in = new BufferedReader(
+ new InputStreamReader(uc.getInputStream()))) {
+
String inputLine;
System.out.print("Client recieved from the server: ");
- while ((inputLine = in.readLine()) != null)
+ while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
- in.close();
- } catch (SSLException e) {
- if (in != null)
- in.close();
+ }
+ } catch (IOException e) {
+ // Assert that the error stream is not accessible from the failed
+ // tunnel setup.
+ if (uc.getErrorStream() != null) {
+ throw new RuntimeException("Unexpected error stream.");
+ }
+
throw e;
}
}
static class NameVerifier implements HostnameVerifier {
+
+ @Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
- static void setupProxy() throws IOException {
+ static ProxyTunnelServer setupProxy() throws IOException {
ProxyTunnelServer pserver = new ProxyTunnelServer();
/*
* register a system wide authenticator and setup the proxy for
@@ -194,16 +245,14 @@
pserver.setUserAuth("Test", "test123");
pserver.start();
- System.setProperty("https.proxyHost", "localhost");
- System.setProperty("https.proxyPort", String.valueOf(
- pserver.getPort()));
+ return pserver;
}
public static class TestAuthenticator extends Authenticator {
+ @Override
public PasswordAuthentication getPasswordAuthentication() {
- return new PasswordAuthentication("Test",
- "test123".toCharArray());
+ return new PasswordAuthentication("Test", "test123".toCharArray());
}
}
}
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyTunnelServer.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyTunnelServer.java Wed Jul 05 22:22:15 2017 +0200
@@ -65,6 +65,7 @@
ss = (ServerSocket) ServerSocketFactory.getDefault().
createServerSocket(0);
}
+ setDaemon(true);
}
public void needUserAuth(boolean auth) {
@@ -211,6 +212,7 @@
this.sockOut = sockOut;
input = sockIn.getInputStream();
output = sockOut.getOutputStream();
+ setDaemon(true);
}
public void run() {
--- a/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Wed Jul 05 22:22:15 2017 +0200
@@ -57,5 +57,6 @@
${TESTSRC}${FS}ProxyTunnelServer.java \
${TESTSRC}${FS}PostThruProxyWithAuth.java
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} ${EXTRAOPTS} \
+ -Djdk.http.auth.tunneling.disabledSchemes= \
PostThruProxyWithAuth ${HOSTNAME} ${TESTSRC}
exit
--- a/jdk/test/sun/net/www/protocol/jar/B4957695.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/sun/net/www/protocol/jar/B4957695.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
/**
* @test
* @bug 4957695
+ * @run main/othervm -Djava.io.tmpdir=. B4957695
* @summary URLJarFile.retrieve does not delete tmpFile on IOException
*/
--- a/jdk/test/sun/reflect/ReflectionFactory/NewConstructorForSerialization.java Thu Oct 20 18:38:09 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8137058
- * @summary Basic test for the unsupported newConstructorForSerialization
- * @modules jdk.unsupported
- */
-
-import java.lang.reflect.Constructor;
-import sun.reflect.ReflectionFactory;
-
-public class NewConstructorForSerialization {
-
- private static Constructor<?> getConstructor(Class<?> type)
- throws NoSuchMethodException
- {
- ReflectionFactory factory = ReflectionFactory.getReflectionFactory();
- Constructor<?> objectConstructor = type.getConstructor((Class[]) null);
-
- @SuppressWarnings("unchecked")
- Constructor<?> c = (Constructor<?>) factory
- .newConstructorForSerialization(type, objectConstructor);
- return c;
- }
-
- public static void main(String[] args) throws Exception {
- System.out.println(getConstructor(Object.class).newInstance());
- System.out.println(getConstructor(Foo.class).newInstance());
- System.out.println(getConstructor(Bar.class).newInstance());
- }
-
- static class Foo {
- public Foo() { }
- }
-
- static class Bar extends Foo {
- public Bar() { }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/reflect/ReflectionFactory/ReflectionFactoryTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2016, 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.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.io.OptionalDataException;
+import java.io.Serializable;
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import sun.reflect.ReflectionFactory;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.testng.annotations.DataProvider;
+import org.testng.TestNG;
+
+/*
+ * @test
+ * @bug 8137058 8164908
+ * @run testng ReflectionFactoryTest
+ * @run testng/othervm/policy=security.policy ReflectionFactoryTest
+ * @summary Basic test for the unsupported ReflectionFactory
+ * @modules jdk.unsupported
+ */
+
+public class ReflectionFactoryTest {
+
+ // Initialized by init()
+ static ReflectionFactory factory;
+
+ @DataProvider(name = "ClassConstructors")
+ static Object[][] classConstructors() {
+ return new Object[][] {
+ {Object.class},
+ {Foo.class},
+ {Bar.class},
+ };
+ }
+
+ @BeforeClass
+ static void init() {
+ factory = ReflectionFactory.getReflectionFactory();
+ }
+
+ /**
+ * Test that the correct Constructor is selected and run.
+ * @param type type of object to create
+ * @throws NoSuchMethodException - error
+ * @throws InstantiationException - error
+ * @throws IllegalAccessException - error
+ * @throws InvocationTargetException - error
+ */
+ @Test(dataProvider="ClassConstructors")
+ static void testConstructor(Class<?> type)
+ throws NoSuchMethodException, InstantiationException,
+ IllegalAccessException, InvocationTargetException
+ {
+ @SuppressWarnings("unchecked")
+ Constructor<?> c = factory.newConstructorForSerialization(type);
+
+ Object o = c.newInstance();
+ Assert.assertEquals(o.getClass(), type, "Instance is wrong type");
+ if (o instanceof Foo) {
+ Foo foo = (Foo)o;
+ foo.check();
+ }
+ }
+
+ static class Foo {
+ private int foo;
+ public Foo() {
+ this.foo = 1;
+ }
+
+ public String toString() {
+ return "foo: " + foo;
+ }
+
+ public void check() {
+ int expectedFoo = 1;
+ Assert.assertEquals(foo, expectedFoo, "foo() constructor not run");
+ }
+ }
+
+ static class Bar extends Foo implements Serializable {
+ private int bar;
+ public Bar() {
+ this.bar = 1;
+ }
+
+ public String toString() {
+ return super.toString() + ", bar: " + bar;
+ }
+
+ public void check() {
+ super.check();
+ int expectedBar = 0;
+ Assert.assertEquals(bar, expectedBar, "bar() constructor not run");
+ }
+ }
+
+ /**
+ * Test newConstructorForExternalization returns the constructor and it can be called.
+ * @throws NoSuchMethodException - error
+ * @throws InstantiationException - error
+ * @throws IllegalAccessException - error
+ * @throws InvocationTargetException - error
+ */
+ @Test
+ static void newConstructorForExternalization()
+ throws NoSuchMethodException, InstantiationException,
+ IllegalAccessException, InvocationTargetException {
+ Constructor<?> cons = factory.newConstructorForExternalization(Ext.class);
+ Ext ext = (Ext)cons.newInstance();
+ Assert.assertEquals(ext.ext, 1, "Constructor not run");
+ }
+
+ static class Ext implements Externalizable {
+ private static final long serialVersionUID = 1L;
+
+ int ext;
+
+ public Ext() {
+ ext = 1;
+ }
+
+ @Override
+ public void writeExternal(ObjectOutput out) throws IOException {}
+
+ @Override
+ public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {}
+ }
+
+ @Test
+ static void testReadWriteObjectForSerialization() throws Throwable {
+ MethodHandle readObjectMethod = factory.readObjectForSerialization(Ser.class);
+ Assert.assertNotNull(readObjectMethod, "readObjectMethod not found");
+
+ MethodHandle readObjectNoDataMethod = factory.readObjectNoDataForSerialization(Ser.class);
+ Assert.assertNotNull(readObjectNoDataMethod, "readObjectNoDataMethod not found");
+
+ MethodHandle writeObjectMethod = factory.writeObjectForSerialization(Ser.class);
+ Assert.assertNotNull(writeObjectMethod, "writeObjectMethod not found");
+
+ MethodHandle readResolveMethod = factory.readResolveForSerialization(Ser.class);
+ Assert.assertNotNull(readResolveMethod, "readResolveMethod not found");
+
+ MethodHandle writeReplaceMethod = factory.writeReplaceForSerialization(Ser.class);
+ Assert.assertNotNull(writeReplaceMethod, "writeReplaceMethod not found");
+
+ byte[] data = null;
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+ Ser ser = new Ser();
+
+ writeReplaceMethod.invoke(ser);
+ Assert.assertTrue(ser.writeReplaceCalled, "writeReplace not called");
+ Assert.assertFalse(ser.writeObjectCalled, "writeObject should not have been called");
+
+ writeObjectMethod.invoke(ser, oos);
+ Assert.assertTrue(ser.writeReplaceCalled, "writeReplace should have been called");
+ Assert.assertTrue(ser.writeObjectCalled, "writeObject not called");
+ oos.flush();
+ data = baos.toByteArray();
+ }
+
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
+ ObjectInputStream ois = new ObjectInputStream(bais)) {
+ Ser ser2 = new Ser();
+
+ readObjectMethod.invoke(ser2, ois);
+ Assert.assertTrue(ser2.readObjectCalled, "readObject not called");
+ Assert.assertFalse(ser2.readObjectNoDataCalled, "readObjectNoData should not be called");
+ Assert.assertFalse(ser2.readResolveCalled, "readResolve should not be called");
+
+ readObjectNoDataMethod.invoke(ser2, ois);
+ Assert.assertTrue(ser2.readObjectCalled, "readObject should have been called");
+ Assert.assertTrue(ser2.readObjectNoDataCalled, "readObjectNoData not called");
+ Assert.assertFalse(ser2.readResolveCalled, "readResolve should not be called");
+
+ readResolveMethod.invoke(ser2);
+ Assert.assertTrue(ser2.readObjectCalled, "readObject should have been called");
+ Assert.assertTrue(ser2.readObjectNoDataCalled, "readObjectNoData not called");
+ Assert.assertTrue(ser2.readResolveCalled, "readResolve not called");
+ }
+ }
+
+ @Test
+ static void hasStaticInitializer() {
+ boolean actual = factory.hasStaticInitializerForSerialization(Ser.class);
+ Assert.assertTrue(actual, "hasStaticInitializerForSerialization is wrong");
+ }
+
+ static class Ser implements Serializable {
+ private static final long serialVersionUID = 2L;
+ static {
+ // Define a static class initialization method
+ }
+
+ boolean readObjectCalled = false;
+ boolean readObjectNoDataCalled = false;
+ boolean writeObjectCalled = false;
+ boolean readResolveCalled = false;
+ boolean writeReplaceCalled = false;
+
+ public Ser() {}
+
+ private void readObject(ObjectInputStream ois) throws IOException {
+ Assert.assertFalse(writeObjectCalled, "readObject called too many times");
+ readObjectCalled = ois.readBoolean();
+ }
+
+ private void readObjectNoData(ObjectInputStream ois) throws IOException {
+ Assert.assertFalse(readObjectNoDataCalled, "readObjectNoData called too many times");
+ readObjectNoDataCalled = true;
+ }
+
+ private void writeObject(ObjectOutputStream oos) throws IOException {
+ Assert.assertFalse(writeObjectCalled, "writeObject called too many times");
+ writeObjectCalled = true;
+ oos.writeBoolean(writeObjectCalled);
+ }
+
+ private Object writeReplace() {
+ Assert.assertFalse(writeReplaceCalled, "writeReplace called too many times");
+ writeReplaceCalled = true;
+ return this;
+ }
+
+ private Object readResolve() {
+ Assert.assertFalse(readResolveCalled, "readResolve called too many times");
+ readResolveCalled = true;
+ return this;
+ }
+ }
+
+ /**
+ * Test the constructor of OptionalDataExceptions.
+ */
+ @Test
+ static void newOptionalDataException() {
+ OptionalDataException ode = factory.newOptionalDataExceptionForSerialization(true);
+ Assert.assertTrue(ode.eof, "eof wrong");
+ ode = factory.newOptionalDataExceptionForSerialization(false);
+ Assert.assertFalse(ode.eof, "eof wrong");
+
+ }
+
+
+
+ // Main can be used to run the tests from the command line with only testng.jar.
+ @SuppressWarnings("raw_types")
+ @Test(enabled = false)
+ public static void main(String[] args) {
+ Class<?>[] testclass = {ReflectionFactoryTest.class};
+ TestNG testng = new TestNG();
+ testng.setTestClasses(testclass);
+ testng.run();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/reflect/ReflectionFactory/security.policy Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,11 @@
+// Individual Permissions for ReflectionFactoryTest
+grant {
+ // Permissions needed to run the test
+ permission java.util.PropertyPermission "*", "read";
+ permission java.io.FilePermission "<<ALL FILES>>", "read,write,delete,execute";
+
+ permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+ permission java.lang.RuntimePermission "accessDeclaredMembers";
+ permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
+ permission java.lang.RuntimePermission "reflectionFactoryAccess";
+};
--- a/jdk/test/sun/security/ec/TestEC.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/sun/security/ec/TestEC.java Wed Jul 05 22:22:15 2017 +0200
@@ -28,7 +28,7 @@
/**
* @test
- * @bug 6840752
+ * @bug 6840752 8168078
* @summary Provide out-of-the-box support for ECC algorithms
* @library ../pkcs11
* @library ../pkcs11/ec
@@ -37,6 +37,7 @@
* @modules jdk.crypto.pkcs11/sun.security.pkcs11.wrapper
* @compile -XDignore.symbol.file TestEC.java
* @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
+ * @run main/othervm/java.security.policy=TestEC.policy -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
*/
import java.security.NoSuchProviderException;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ec/TestEC.policy Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,3 @@
+grant codebase "file:${test.classes}/*" {
+ permission java.security.AllPermission;
+};
--- a/jdk/test/sun/security/pkcs/pkcs7/PKCS7VerifyTest.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/sun/security/pkcs/pkcs7/PKCS7VerifyTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,8 +27,8 @@
* @summary Read signed data in one or more PKCS7 objects from individual files,
* verify SignerInfos and certificate chain.
* @modules java.base/sun.security.pkcs
- * @run main PKCS7VerifyTest PKCS7TEST.DSA.base64
- * @run main PKCS7VerifyTest PKCS7TEST.DSA.base64 PKCS7TEST.SF
+ * @run main/othervm PKCS7VerifyTest PKCS7TEST.DSA.base64
+ * @run main/othervm PKCS7VerifyTest PKCS7TEST.DSA.base64 PKCS7TEST.SF
*/
import java.io.ByteArrayInputStream;
import java.io.File;
@@ -36,6 +36,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.HashMap;
@@ -55,6 +56,8 @@
throw new RuntimeException("usage: java JarVerify <file1> <file2>");
}
+ Security.setProperty("jdk.jar.disabledAlgorithms", "");
+
// The command " java PKCS7VerifyTest file1 [file2] "
// treats file1 as containing the DER encoding of a PKCS7 signed data
// object. If file2 is absent, the program verifies that some signature
--- a/jdk/test/sun/security/pkcs11/PKCS11Test.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/sun/security/pkcs11/PKCS11Test.java Wed Jul 05 22:22:15 2017 +0200
@@ -47,6 +47,7 @@
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
@@ -112,7 +113,7 @@
found = true;
break;
}
- } catch (Exception e) {
+ } catch (Exception | ServiceConfigurationError e) {
// ignore and move on to the next one
}
}
--- a/jdk/test/sun/security/tools/jarsigner/JarSigningNonAscii.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/JarSigningNonAscii.java Wed Jul 05 22:22:15 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,12 @@
* @bug 4924188
* @summary sign a JAR file that has entry names with non-ASCII characters.
* @modules jdk.jartool/sun.security.tools.jarsigner
+ * @run main/othervm JarSigningNonAscii
*/
import sun.security.tools.*;
import java.io.*;
+import java.security.Security;
import java.util.*;
import java.util.jar.*;
import java.security.cert.Certificate;
@@ -40,6 +42,7 @@
private static String keystore;
public static void main(String[] args) throws Exception {
+ Security.setProperty("jdk.jar.disabledAlgorithms", "");
String srcDir = System.getProperty("test.src", ".");
String destDir = System.getProperty("test.classes", ".");
--- a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Wed Jul 05 22:22:15 2017 +0200
@@ -22,25 +22,29 @@
*/
import com.sun.net.httpserver.*;
-import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
-import java.io.FileInputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.InetSocketAddress;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Calendar;
+import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
-import java.util.Locale;
+import jdk.testlibrary.*;
+import jdk.testlibrary.JarUtils;
import sun.security.pkcs.ContentInfo;
import sun.security.pkcs.PKCS7;
import sun.security.pkcs.PKCS9Attribute;
@@ -52,11 +56,22 @@
import sun.security.x509.AlgorithmId;
import sun.security.x509.X500Name;
+/*
+ * @test
+ * @bug 6543842 6543440 6939248 8009636 8024302 8163304
+ * @summary checking response of timestamp
+ * @modules java.base/sun.security.pkcs
+ * java.base/sun.security.timestamp
+ * java.base/sun.security.x509
+ * java.base/sun.security.util
+ * java.base/sun.security.tools.keytool
+ * @library /lib/testlibrary
+ * @run main/timeout=600 TimestampCheck
+ */
public class TimestampCheck {
- static final String TSKS = "tsks";
- static final String JAR = "old.jar";
- static final String defaultPolicyId = "2.3.4.5";
+ static final String defaultPolicyId = "2.3.4";
+ static String host = null;
static class Handler implements HttpHandler, AutoCloseable {
@@ -75,11 +90,7 @@
t.getRequestBody().read(input);
try {
- int path = 0;
- if (t.getRequestURI().getPath().length() > 1) {
- path = Integer.parseInt(
- t.getRequestURI().getPath().substring(1));
- }
+ String path = t.getRequestURI().getPath().substring(1);
byte[] output = sign(input, path);
Headers out = t.getResponseHeaders();
out.set("Content-Type", "application/timestamp-reply");
@@ -97,24 +108,10 @@
/**
* @param input The data to sign
* @param path different cases to simulate, impl on URL path
- * 0: normal
- * 1: Missing nonce
- * 2: Different nonce
- * 3: Bad digets octets in messageImprint
- * 4: Different algorithmId in messageImprint
- * 5: whole chain in cert set
- * 6: extension is missing
- * 7: extension is non-critical
- * 8: extension does not have timestamping
- * 9: no cert in response
- * 10: normal
- * 11: always return default policy id
- * 12: normal
- * otherwise: normal
* @returns the signed
*/
- byte[] sign(byte[] input, int path) throws Exception {
- // Read TSRequest
+ byte[] sign(byte[] input, String path) throws Exception {
+
DerValue value = new DerValue(input);
System.err.println("\nIncoming Request\n===================");
System.err.println("Version: " + value.data.getInteger());
@@ -138,36 +135,33 @@
}
}
- // Write TSResponse
System.err.println("\nResponse\n===================");
- KeyStore ks = KeyStore.getInstance("JKS");
- try (FileInputStream fis = new FileInputStream(keystore)) {
- ks.load(fis, "changeit".toCharArray());
+ KeyStore ks = KeyStore.getInstance(
+ new File(keystore), "changeit".toCharArray());
+
+ String alias = "ts";
+ if (path.startsWith("bad") || path.equals("weak")) {
+ alias = "ts" + path;
}
- String alias = "ts";
- if (path == 6) alias = "tsbad1";
- if (path == 7) alias = "tsbad2";
- if (path == 8) alias = "tsbad3";
-
- if (path == 11) {
+ if (path.equals("diffpolicy")) {
policyId = new ObjectIdentifier(defaultPolicyId);
}
DerOutputStream statusInfo = new DerOutputStream();
statusInfo.putInteger(0);
- DerOutputStream token = new DerOutputStream();
AlgorithmId[] algorithms = {aid};
Certificate[] chain = ks.getCertificateChain(alias);
- X509Certificate[] signerCertificateChain = null;
+ X509Certificate[] signerCertificateChain;
X509Certificate signer = (X509Certificate)chain[0];
- if (path == 5) { // Only case 5 uses full chain
+
+ if (path.equals("fullchain")) { // Only case 5 uses full chain
signerCertificateChain = new X509Certificate[chain.length];
for (int i=0; i<chain.length; i++) {
signerCertificateChain[i] = (X509Certificate)chain[i];
}
- } else if (path == 9) {
+ } else if (path.equals("nocert")) {
signerCertificateChain = new X509Certificate[0];
} else {
signerCertificateChain = new X509Certificate[1];
@@ -179,11 +173,11 @@
tst.putInteger(1);
tst.putOID(policyId);
- if (path != 3 && path != 4) {
+ if (!path.equals("baddigest") && !path.equals("diffalg")) {
tst.putDerValue(messageImprint);
} else {
byte[] data = messageImprint.toByteArray();
- if (path == 4) {
+ if (path.equals("diffalg")) {
data[6] = (byte)0x01;
} else {
data[data.length-1] = (byte)0x01;
@@ -198,10 +192,10 @@
Calendar cal = Calendar.getInstance();
tst.putGeneralizedTime(cal.getTime());
- if (path == 2) {
+ if (path.equals("diffnonce")) {
tst.putInteger(1234);
- } else if (path == 1) {
- // do nothing
+ } else if (path.equals("nononce")) {
+ // no noce
} else {
tst.putInteger(nonce);
}
@@ -212,6 +206,8 @@
DerOutputStream tstInfo2 = new DerOutputStream();
tstInfo2.putOctetString(tstInfo.toByteArray());
+ // Always use the same algorithm at timestamp signing
+ // so it is different from the hash algorithm.
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initSign((PrivateKey)(ks.getKey(
alias, "changeit".toCharArray())));
@@ -229,12 +225,11 @@
SignerInfo signerInfo = new SignerInfo(
new X500Name(signer.getIssuerX500Principal().getName()),
signer.getSerialNumber(),
- aid, AlgorithmId.get("RSA"), sig.sign());
+ AlgorithmId.get("SHA-1"), AlgorithmId.get("RSA"), sig.sign());
SignerInfo[] signerInfos = {signerInfo};
- PKCS7 p7 =
- new PKCS7(algorithms, contentInfo, signerCertificateChain,
- signerInfos);
+ PKCS7 p7 = new PKCS7(algorithms, contentInfo,
+ signerCertificateChain, signerInfos);
ByteArrayOutputStream p7out = new ByteArrayOutputStream();
p7.encodeSignedData(p7out);
@@ -294,44 +289,68 @@
}
}
- public static void main(String[] args) throws Exception {
- try (Handler tsa = Handler.init(0, TSKS);) {
+ public static void main(String[] args) throws Throwable {
+
+ prepare();
+
+ try (Handler tsa = Handler.init(0, "tsks");) {
tsa.start();
int port = tsa.getPort();
-
- String cmd;
- // Use -J-Djava.security.egd=file:/dev/./urandom to speed up
- // nonce generation in timestamping request. Not avaibale on
- // Windows and defaults to thread seed generator, not too bad.
- if (System.getProperty("java.home").endsWith("jre")) {
- cmd = System.getProperty("java.home") + "/../bin/jarsigner";
- } else {
- cmd = System.getProperty("java.home") + "/bin/jarsigner";
- }
-
- cmd += " " + System.getProperty("test.tool.vm.opts")
- + " -J-Djava.security.egd=file:/dev/./urandom"
- + " -J-Duser.language=en -J-Duser.country=US"
- + " -debug -keystore " + TSKS + " -storepass changeit"
- + " -tsa http://localhost:" + port + "/%d"
- + " -signedjar new_%d.jar " + JAR + " old";
+ host = "http://localhost:" + port + "/";
if (args.length == 0) { // Run this test
- jarsigner(cmd, 0, true); // Success, normal call
- jarsigner(cmd, 1, false); // These 4 should fail
- jarsigner(cmd, 2, false);
- jarsigner(cmd, 3, false);
- jarsigner(cmd, 4, false);
- jarsigner(cmd, 5, true); // Success, 6543440 solved.
- jarsigner(cmd, 6, false); // tsbad1
- jarsigner(cmd, 7, false); // tsbad2
- jarsigner(cmd, 8, false); // tsbad3
- jarsigner(cmd, 9, false); // no cert in timestamp
- jarsigner(cmd + " -tsapolicyid 1.2.3.4", 10, true);
- checkTimestamp("new_10.jar", "1.2.3.4", "SHA-256");
- jarsigner(cmd + " -tsapolicyid 1.2.3.5", 11, false);
- jarsigner(cmd + " -tsadigestalg SHA", 12, true);
- checkTimestamp("new_12.jar", defaultPolicyId, "SHA-1");
+ sign("none")
+ .shouldContain("is not timestamped")
+ .shouldHaveExitValue(0);
+
+ sign("badku")
+ .shouldHaveExitValue(0);
+ checkBadKU("badku.jar");
+
+ sign("normal")
+ .shouldNotContain("is not timestamped")
+ .shouldHaveExitValue(0);
+
+ sign("nononce")
+ .shouldHaveExitValue(1);
+ sign("diffnonce")
+ .shouldHaveExitValue(1);
+ sign("baddigest")
+ .shouldHaveExitValue(1);
+ sign("diffalg")
+ .shouldHaveExitValue(1);
+ sign("fullchain")
+ .shouldHaveExitValue(0); // Success, 6543440 solved.
+ sign("bad1")
+ .shouldHaveExitValue(1);
+ sign("bad2")
+ .shouldHaveExitValue(1);
+ sign("bad3")
+ .shouldHaveExitValue(1);
+ sign("nocert")
+ .shouldHaveExitValue(1);
+
+ sign("policy", "-tsapolicyid", "1.2.3")
+ .shouldHaveExitValue(0);
+ checkTimestamp("policy.jar", "1.2.3", "SHA-256");
+
+ sign("diffpolicy", "-tsapolicyid", "1.2.3")
+ .shouldHaveExitValue(1);
+
+ sign("tsaalg", "-tsadigestalg", "SHA")
+ .shouldHaveExitValue(0);
+ checkTimestamp("tsaalg.jar", defaultPolicyId, "SHA-1");
+
+ sign("weak", "-digestalg", "MD5",
+ "-sigalg", "MD5withRSA", "-tsadigestalg", "MD5")
+ .shouldHaveExitValue(0)
+ .shouldMatch("MD5.*-digestalg.*risk")
+ .shouldMatch("MD5.*-tsadigestalg.*risk")
+ .shouldMatch("MD5withRSA.*-sigalg.*risk");
+ checkWeak("weak.jar");
+
+ // When .SF or .RSA is missing or invalid
+ checkMissingOrInvalidFiles("normal.jar");
} else { // Run as a standalone server
System.err.println("Press Enter to quit server");
System.in.read();
@@ -339,6 +358,95 @@
}
}
+ private static void checkMissingOrInvalidFiles(String s)
+ throws Throwable {
+ JarUtils.updateJar(s, "1.jar", "-", "META-INF/OLD.SF");
+ verify("1.jar", "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("Missing signature-related file META-INF/OLD.SF");
+ JarUtils.updateJar(s, "2.jar", "-", "META-INF/OLD.RSA");
+ verify("2.jar", "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("Missing block file for signature-related file META-INF/OLD.SF");
+ JarUtils.updateJar(s, "3.jar", "META-INF/OLD.SF");
+ verify("3.jar", "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("Unparsable signature-related file META-INF/OLD.SF");
+ JarUtils.updateJar(s, "4.jar", "META-INF/OLD.RSA");
+ verify("4.jar", "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("Unparsable signature-related file META-INF/OLD.RSA");
+ }
+
+ static OutputAnalyzer jarsigner(List<String> extra)
+ throws Throwable {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jarsigner")
+ .addVMArg("-Duser.language=en")
+ .addVMArg("-Duser.country=US")
+ .addToolArg("-keystore")
+ .addToolArg("tsks")
+ .addToolArg("-storepass")
+ .addToolArg("changeit");
+ for (String s : extra) {
+ if (s.startsWith("-J")) {
+ launcher.addVMArg(s.substring(2));
+ } else {
+ launcher.addToolArg(s);
+ }
+ }
+ return ProcessTools.executeCommand(launcher.getCommand());
+ }
+
+ static OutputAnalyzer verify(String file, String... extra)
+ throws Throwable {
+ List<String> args = new ArrayList<>();
+ args.add("-verify");
+ args.add(file);
+ args.addAll(Arrays.asList(extra));
+ return jarsigner(args);
+ }
+
+ static void checkBadKU(String file) throws Throwable {
+ verify(file)
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldContain("re-run jarsigner with debug enabled");
+ verify(file, "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("Signed by")
+ .shouldContain("treated as unsigned")
+ .shouldContain("re-run jarsigner with debug enabled");
+ verify(file, "-J-Djava.security.debug=jar")
+ .shouldHaveExitValue(0)
+ .shouldContain("SignatureException: Key usage restricted")
+ .shouldContain("treated as unsigned")
+ .shouldContain("re-run jarsigner with debug enabled");
+ }
+
+ static void checkWeak(String file) throws Throwable {
+ verify(file)
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldMatch("weak algorithm that is now disabled.")
+ .shouldMatch("Re-run jarsigner with the -verbose option for more details");
+ verify(file, "-verbose")
+ .shouldHaveExitValue(0)
+ .shouldContain("treated as unsigned")
+ .shouldMatch("weak algorithm that is now disabled by")
+ .shouldMatch("Digest algorithm: .*weak")
+ .shouldMatch("Signature algorithm: .*weak")
+ .shouldMatch("Timestamp digest algorithm: .*weak")
+ .shouldNotMatch("Timestamp signature algorithm: .*weak.*weak")
+ .shouldMatch("Timestamp signature algorithm: .*key.*weak");
+ verify(file, "-J-Djava.security.debug=jar")
+ .shouldHaveExitValue(0)
+ .shouldMatch("SignatureException:.*Disabled");
+ }
+
static void checkTimestamp(String file, String policyId, String digestAlg)
throws Exception {
try (JarFile jf = new JarFile(file)) {
@@ -365,41 +473,62 @@
}
}
+ static int which = 0;
+
/**
- * @param cmd the command line (with a hole to plug in)
- * @param path the path in the URL, i.e, http://localhost/path
- * @param expected if this command should succeed
+ * @param extra more args given to jarsigner
*/
- static void jarsigner(String cmd, int path, boolean expected)
- throws Exception {
- System.err.println("Test " + path);
- Process p = Runtime.getRuntime().exec(String.format(Locale.ROOT,cmd, path, path));
- BufferedReader reader = new BufferedReader(
- new InputStreamReader(p.getErrorStream()));
- while (true) {
- String s = reader.readLine();
- if (s == null) break;
- System.err.println(s);
+ static OutputAnalyzer sign(String path, String... extra)
+ throws Throwable {
+ which++;
+ System.err.println("\n>> Test #" + which + ": " + Arrays.toString(extra));
+ List<String> args = List.of("-J-Djava.security.egd=file:/dev/./urandom",
+ "-debug", "-signedjar", path + ".jar", "old.jar",
+ path.equals("badku") ? "badku" : "old");
+ args = new ArrayList<>(args);
+ if (!path.equals("none") && !path.equals("badku")) {
+ args.add("-tsa");
+ args.add(host + path);
}
+ args.addAll(Arrays.asList(extra));
+ return jarsigner(args);
+ }
- // Will not see noTimestamp warning
- boolean seeWarning = false;
- reader = new BufferedReader(
- new InputStreamReader(p.getInputStream()));
- while (true) {
- String s = reader.readLine();
- if (s == null) break;
- System.err.println(s);
- if (s.indexOf("Warning:") >= 0) {
- seeWarning = true;
- }
+ static void prepare() throws Exception {
+ jdk.testlibrary.JarUtils.createJar("old.jar", "A");
+ Files.deleteIfExists(Paths.get("tsks"));
+ keytool("-alias ca -genkeypair -ext bc -dname CN=CA");
+ keytool("-alias old -genkeypair -dname CN=old");
+ keytool("-alias badku -genkeypair -dname CN=badku");
+ keytool("-alias ts -genkeypair -dname CN=ts");
+ keytool("-alias tsweak -genkeypair -keysize 512 -dname CN=tsbad1");
+ keytool("-alias tsbad1 -genkeypair -dname CN=tsbad1");
+ keytool("-alias tsbad2 -genkeypair -dname CN=tsbad2");
+ keytool("-alias tsbad3 -genkeypair -dname CN=tsbad3");
+
+ gencert("old");
+ gencert("badku", "-ext ku:critical=keyAgreement");
+ gencert("ts", "-ext eku:critical=ts");
+ gencert("tsweak", "-ext eku:critical=ts");
+ gencert("tsbad1");
+ gencert("tsbad2", "-ext eku=ts");
+ gencert("tsbad3", "-ext eku:critical=cs");
+ }
+
+ static void gencert(String alias, String... extra) throws Exception {
+ keytool("-alias " + alias + " -certreq -file " + alias + ".req");
+ String genCmd = "-gencert -alias ca -infile " +
+ alias + ".req -outfile " + alias + ".cert";
+ for (String s : extra) {
+ genCmd += " " + s;
}
- int result = p.waitFor();
- if (expected && result != 0 || !expected && result == 0) {
- throw new Exception("Failed");
- }
- if (seeWarning) {
- throw new Exception("See warning");
- }
+ keytool(genCmd);
+ keytool("-alias " + alias + " -importcert -file " + alias + ".cert");
+ }
+
+ static void keytool(String cmd) throws Exception {
+ cmd = "-keystore tsks -storepass changeit -keypass changeit " +
+ "-keyalg rsa -validity 200 " + cmd;
+ sun.security.tools.keytool.Main.main(cmd.split(" "));
}
}
--- a/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/TsacertOptionTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -31,6 +31,7 @@
* @library /lib/testlibrary warnings
* @modules java.base/sun.security.pkcs
* java.base/sun.security.timestamp
+ * java.base/sun.security.tools.keytool
* java.base/sun.security.util
* java.base/sun.security.x509
* java.management
--- a/jdk/test/sun/security/tools/jarsigner/ts.sh Thu Oct 20 18:38:09 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-#
-# Copyright (c) 2007, 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
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 6543842 6543440 6939248 8009636 8024302
-# @summary checking response of timestamp
-# @modules java.base/sun.security.pkcs
-# java.base/sun.security.timestamp
-# java.base/sun.security.x509
-# java.base/sun.security.util
-#
-# @run shell/timeout=600 ts.sh
-
-# Run for a long time because jarsigner with timestamp needs to create a
-# 64-bit random number and it might be extremely slow on a machine with
-# not enough entropy pool
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
- Windows_* )
- FS="\\"
- ;;
- * )
- FS="/"
- ;;
-esac
-
-if [ "${TESTSRC}" = "" ] ; then
- TESTSRC="."
-fi
-if [ "${TESTJAVA}" = "" ] ; then
- JAVAC_CMD=`which javac`
- TESTJAVA=`dirname $JAVAC_CMD`/..
-fi
-
-JAR="${TESTJAVA}${FS}bin${FS}jar ${TESTTOOLVMOPTS}"
-JAVA="${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS}"
-JAVAC="${TESTJAVA}${FS}bin${FS}javac ${TESTTOOLVMOPTS} ${TESTJAVACOPTS}"
-KT="${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -keystore tsks -storepass changeit -keypass changeit -keyalg rsa -validity 200"
-
-rm tsks
-echo Nothing > A
-rm old.jar
-$JAR cvf old.jar A
-
-# ca is CA
-# old is signer for code
-# ts is signer for timestamp
-# tsbad1 has no extendedKeyUsage
-# tsbad2's extendedKeyUsage is non-critical
-# tsbad3's extendedKeyUsage has no timestamping
-
-$KT -alias ca -genkeypair -ext bc -dname CN=CA
-$KT -alias old -genkeypair -dname CN=old
-$KT -alias ts -genkeypair -dname CN=ts
-$KT -alias tsbad1 -genkeypair -dname CN=tsbad1
-$KT -alias tsbad2 -genkeypair -dname CN=tsbad2
-$KT -alias tsbad3 -genkeypair -dname CN=tsbad3
-
-$KT -alias old -certreq | \
- $KT -alias ca -gencert | \
- $KT -alias old -importcert
-$KT -alias ts -certreq | \
- $KT -alias ca -gencert -ext eku:critical=ts | \
- $KT -alias ts -importcert
-$KT -alias tsbad1 -certreq | \
- $KT -alias ca -gencert | \
- $KT -alias tsbad1 -importcert
-$KT -alias tsbad2 -certreq | \
- $KT -alias ca -gencert -ext eku=ts | \
- $KT -alias tsbad2 -importcert
-$KT -alias tsbad3 -certreq | \
- $KT -alias ca -gencert -ext eku:critical=cs | \
- $KT -alias tsbad3 -importcert
-
-EXTRAOPTS="--add-exports java.base/sun.security.pkcs=ALL-UNNAMED \
- --add-exports java.base/sun.security.timestamp=ALL-UNNAMED \
- --add-exports java.base/sun.security.x509=ALL-UNNAMED \
- --add-exports java.base/sun.security.util=ALL-UNNAMED"
-$JAVAC ${EXTRAOPTS} -d . ${TESTSRC}/TimestampCheck.java
-$JAVA ${TESTVMOPTS} ${EXTRAOPTS} "-Dtest.tool.vm.opts=${TESTTOOLVMOPTS}" TimestampCheck
-
--- a/jdk/test/tools/jlink/IntegrationTest.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/tools/jlink/IntegrationTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -37,14 +37,14 @@
import java.util.Properties;
import java.util.Set;
import java.util.function.Function;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.JlinkConfiguration;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
+import jdk.tools.jlink.internal.Jlink;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.internal.ExecutableImage;
+import jdk.tools.jlink.internal.Jlink.JlinkConfiguration;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.PostProcessor;
import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin;
import jdk.tools.jlink.internal.plugins.StripDebugPlugin;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/JLinkToolProviderTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, 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.io.PrintWriter;
+import java.io.StringWriter;
+import java.security.AccessControlException;
+import java.util.spi.ToolProvider;
+
+/*
+ * @test
+ * @build JLinkToolProviderTest
+ * @run main/othervm/java.security.policy=toolprovider.policy JLinkToolProviderTest
+ */
+public class JLinkToolProviderTest {
+ static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
+ .orElseThrow(() ->
+ new RuntimeException("jlink tool not found")
+ );
+
+ private static void checkJlinkOptions(String... options) {
+ StringWriter writer = new StringWriter();
+ PrintWriter pw = new PrintWriter(writer);
+
+ try {
+ JLINK_TOOL.run(pw, pw, options);
+ throw new AssertionError("SecurityException should have been thrown!");
+ } catch (AccessControlException ace) {
+ if (! ace.getPermission().getClass().getName().contains("JlinkPermission")) {
+ throw new AssertionError("expected JlinkPermission check failure");
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ checkJlinkOptions("--help");
+ checkJlinkOptions("--list-plugins");
+ }
+}
--- a/jdk/test/tools/jlink/SecurityTest.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/tools/jlink/SecurityTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -25,12 +25,12 @@
* @test
* @summary Test JlinkPermission
* @author Jean-Francois Denise
- * @modules jdk.jlink/jdk.tools.jlink
+ * @modules jdk.jlink/jdk.tools.jlink.internal
* @run main/othervm SecurityTest
*/
import java.security.AccessControlException;
-import jdk.tools.jlink.Jlink;
+import jdk.tools.jlink.internal.Jlink;
public class SecurityTest {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/plugins/ExcludeJmodSectionPluginTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,340 @@
+/**
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test --no-man-pages and --no-header-files
+ * @library /lib/testlibrary
+ * @modules jdk.compiler
+ * jdk.jlink
+ * @build CompilerUtils
+ * @run testng ExcludeJmodSectionPluginTest
+ */
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.spi.ToolProvider;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+public class ExcludeJmodSectionPluginTest {
+ static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
+ .orElseThrow(() ->
+ new RuntimeException("jmod tool not found")
+ );
+
+ static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
+ .orElseThrow(() ->
+ new RuntimeException("jlink tool not found")
+ );
+
+ static final Path MODULE_PATH = Paths.get(System.getProperty("java.home"), "jmods");
+ static final Path SRC_DIR = Paths.get("src");
+ static final Path MODS_DIR = Paths.get("mods");
+ static final Path JMODS_DIR = Paths.get("jmods");
+ static final Path MAN_DIR = Paths.get("man");
+ static final Path INCLUDE_DIR = Paths.get("include");
+ static final Path IMAGES_DIR = Paths.get("images");
+
+ @BeforeTest
+ private void setup() throws Exception {
+ // build jmod files
+ JmodFileBuilder m1 = new JmodFileBuilder("m1");
+ m1.headerFile("m1a.h");
+ m1.headerFile("m1b.h");
+ m1.build();
+
+ JmodFileBuilder m2 = new JmodFileBuilder("m2");
+ m2.headerFile("m2.h");
+ m2.manPage("tool2.1");
+ m2.build();
+
+ JmodFileBuilder m3 = new JmodFileBuilder("m3");
+ m3.manPage("tool3.1");
+ m3.build();
+ }
+
+ private String imageDir(String dir) {
+ return IMAGES_DIR.resolve(dir).toString();
+ }
+
+
+ @DataProvider(name = "jlinkoptions")
+ public Object[][] jlinkoptions() {
+ // options and expected header files & man pages
+ return new Object[][] {
+ { new String [] {
+ "test1",
+ "--exclude-files=/java.base/include/**,/java.base/man/**",
+ },
+ List.of("include/m1a.h",
+ "include/m1b.h",
+ "include/m2.h",
+ "man/tool2.1",
+ "man/tool3.1")
+ },
+
+ { new String [] {
+ "test2",
+ "--no-man-pages",
+ "--no-header-files",
+ },
+ List.of()
+ },
+
+ { new String[] {
+ "test3",
+ "--no-header-files",
+ "--exclude-files=/java.base/man/**"
+ },
+ List.of("man/tool2.1",
+ "man/tool3.1") },
+
+ { new String [] {
+ "test4",
+ "--no-man-pages",
+ "--exclude-files=/java.base/include/**,/m2/include/**",
+ },
+ List.of("include/m1a.h",
+ "include/m1b.h")
+ },
+
+ { new String [] {
+ "test5",
+ "--no-header-files",
+ "--exclude-files=/java.base/man/**,/m2/man/**"
+ },
+ List.of("man/tool3.1")
+ },
+ };
+ }
+
+ @Test(dataProvider = "jlinkoptions")
+ public void test(String[] opts, List<String> expectedFiles) throws Exception {
+ if (Files.notExists(MODULE_PATH)) {
+ // exploded image
+ return;
+ }
+
+ String dir = opts[0];
+ List<String> options = new ArrayList<>();
+ for (int i = 1; i < opts.length; i++) {
+ options.add(opts[i]);
+ }
+
+ String mpath = MODULE_PATH.toString() + File.pathSeparator +
+ JMODS_DIR.toString();
+ Stream.of("--module-path", mpath,
+ "--add-modules", "m1,m2,m3",
+ "--output", imageDir(dir))
+ .forEach(options::add);
+
+ Path image = createImage(dir, options, expectedFiles);
+
+ // check if any unexpected header file or man page
+ Set<Path> extraFiles = Files.walk(image, Integer.MAX_VALUE)
+ .filter(p -> Files.isRegularFile(p))
+ .filter(p -> p.getParent().endsWith("include") ||
+ p.getParent().endsWith("man"))
+ .filter(p -> {
+ String fn = String.format("%s/%s",
+ p.getParent().getFileName().toString(),
+ p.getFileName().toString());
+ return !expectedFiles.contains(fn);
+ })
+ .collect(Collectors.toSet());
+
+ if (extraFiles.size() > 0) {
+ System.out.println("Unexpected files: " + extraFiles.toString());
+ assertTrue(extraFiles.isEmpty());
+ }
+ }
+
+ /**
+ * Test java.base's include header files
+ */
+ @Test
+ public void testJavaBase() {
+ if (Files.notExists(MODULE_PATH)) {
+ // exploded image
+ return;
+ }
+ List<String> options = List.of("--module-path",
+ MODULE_PATH.toString(),
+ "--add-modules", "java.base",
+ "--output", imageDir("base"));
+ createImage("base", options,
+ List.of("include/jni.h", "include/jvmti.h"));
+
+ }
+
+ private Path createImage(String outputDir, List<String> options,
+ List<String> expectedFiles) {
+ System.out.println("jlink " + options.toString());
+ int rc = JLINK_TOOL.run(System.out, System.out,
+ options.toArray(new String[0]));
+ assertTrue(rc == 0);
+
+ Path d = IMAGES_DIR.resolve(outputDir);
+ for (String fn : expectedFiles) {
+ Path path = d.resolve(fn);
+ if (Files.notExists(path)) {
+ throw new RuntimeException(path + " not found");
+ }
+ }
+ return d;
+ }
+
+ private void deleteDirectory(Path dir) throws IOException {
+ Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ throws IOException
+ {
+ Files.delete(file);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc)
+ throws IOException
+ {
+ Files.delete(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+
+ /**
+ * Builder to create JMOD file
+ */
+ class JmodFileBuilder {
+
+ final String name;
+ final Set<String> manPages = new HashSet<>();
+ final Set<String> headerFiles = new HashSet<>();
+
+ JmodFileBuilder(String name) throws IOException {
+ this.name = name;
+
+ Path msrc = SRC_DIR.resolve(name);
+ if (Files.exists(msrc)) {
+ deleteDirectory(msrc);
+ }
+ }
+
+ JmodFileBuilder manPage(String filename) {
+ manPages.add(filename);
+ return this;
+ }
+
+ JmodFileBuilder headerFile(String filename) {
+ headerFiles.add(filename);
+ return this;
+ }
+
+ Path build() throws IOException {
+ compileModule();
+ // create man pages
+ Path mdir = MAN_DIR.resolve(name);
+ for (String filename : manPages) {
+ Files.createDirectories(mdir);
+ Files.createFile(mdir.resolve(filename));
+ }
+ // create header files
+ mdir = INCLUDE_DIR.resolve(name);
+ for (String filename : headerFiles) {
+ Files.createDirectories(mdir);
+ Files.createFile(mdir.resolve(filename));
+ }
+ return createJmodFile();
+ }
+
+ void compileModule() throws IOException {
+ Path msrc = SRC_DIR.resolve(name);
+ Files.createDirectories(msrc);
+ Path minfo = msrc.resolve("module-info.java");
+ try (BufferedWriter bw = Files.newBufferedWriter(minfo);
+ PrintWriter writer = new PrintWriter(bw)) {
+ writer.format("module %s { }%n", name);
+ }
+
+ assertTrue(CompilerUtils.compile(msrc, MODS_DIR,
+ "--module-source-path",
+ SRC_DIR.toString()));
+ }
+
+ Path createJmodFile() throws IOException {
+ Path mclasses = MODS_DIR.resolve(name);
+ Files.createDirectories(JMODS_DIR);
+ Path outfile = JMODS_DIR.resolve(name + ".jmod");
+ List<String> args = new ArrayList<>();
+ args.add("create");
+ // add classes
+ args.add("--class-path");
+ args.add(mclasses.toString());
+ // man pages
+ if (manPages.size() > 0) {
+ args.add("--man-pages");
+ args.add(MAN_DIR.resolve(name).toString());
+ }
+ // header files
+ if (headerFiles.size() > 0) {
+ args.add("--header-files");
+ args.add(INCLUDE_DIR.resolve(name).toString());
+ }
+ args.add(outfile.toString());
+
+ if (Files.exists(outfile))
+ Files.delete(outfile);
+
+ System.out.println("jmod " +
+ args.stream().collect(Collectors.joining(" ")));
+
+ int rc = JMOD_TOOL.run(System.out, System.out,
+ args.toArray(new String[args.size()]));
+ if (rc != 0) {
+ throw new AssertionError("jmod failed: rc = " + rc);
+ }
+ return outfile;
+ }
+ }
+}
--- a/jdk/test/tools/jlink/plugins/LastSorterTest.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/tools/jlink/plugins/LastSorterTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -37,11 +37,11 @@
import java.util.Map;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
+import jdk.tools.jlink.internal.ImagePluginStack;
+import jdk.tools.jlink.internal.Jlink;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
-import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePoolManager;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
--- a/jdk/test/tools/jlink/plugins/PluginsNegativeTest.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/tools/jlink/plugins/PluginsNegativeTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -36,11 +36,11 @@
import java.util.Map;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
+import jdk.tools.jlink.internal.Jlink;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePoolManager;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
--- a/jdk/test/tools/jlink/plugins/PrevisitorTest.java Thu Oct 20 18:38:09 2016 +0000
+++ b/jdk/test/tools/jlink/plugins/PrevisitorTest.java Wed Jul 05 22:22:15 2017 +0200
@@ -40,13 +40,13 @@
import java.util.stream.Collectors;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
+import jdk.tools.jlink.internal.Jlink;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
import jdk.tools.jlink.internal.ResourcePrevisitor;
import jdk.tools.jlink.internal.StringTable;
-import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/toolprovider.policy Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,2 @@
+grant {
+};
--- a/make/CreateJmods.gmk Thu Oct 20 18:38:09 2016 +0000
+++ b/make/CreateJmods.gmk Wed Jul 05 22:22:15 2017 +0200
@@ -44,6 +44,10 @@
CONF_DIR := $(firstword $(wildcard $(addsuffix /$(MODULE), \
$(SUPPORT_OUTPUTDIR)/modules_conf $(IMPORT_MODULES_CONF))))
CLASSES_DIR := $(wildcard $(JDK_OUTPUTDIR)/modules/$(MODULE))
+INCLUDE_HEADERS_DIR := $(firstword $(wildcard $(addsuffix /$(MODULE), \
+ $(SUPPORT_OUTPUTDIR)/modules_include $(IMPORT_MODULES_INCLUDE_HEADERS))))
+MAN_DIR := $(firstword $(wildcard $(addsuffix /$(MODULE), \
+ $(SUPPORT_OUTPUTDIR)/modules_man $(IMPORT_MODULES_MAN))))
$(eval $(call FillCacheFind, \
$(LIBS_DIR) $(CMDS_DIR) $(CONF_DIR) $(CLASSES_DIR) \
@@ -65,6 +69,14 @@
JMOD_FLAGS += --class-path $(CLASSES_DIR)
DEPS += $(call CacheFind, $(CLASSES_DIR))
endif
+ifneq ($(INCLUDE_HEADERS_DIR), )
+ JMOD_FLAGS += --header-files $(INCLUDE_HEADERS_DIR)
+ DEPS += $(call CacheFind, $(INCLUDE_HEADERS_DIR))
+endif
+ifneq ($(MAN_DIR), )
+ JMOD_FLAGS += --man-pages $(MAN_DIR)
+ DEPS += $(call CacheFind, $(MAN_DIR))
+endif
# Add dependencies on other jmod files. Only java.base needs access to other
# jmods.
@@ -103,7 +115,7 @@
--os-arch $(OPENJDK_TARGET_CPU_LEGACY) \
--os-version $(REQUIRED_OS_VERSION) \
--module-path $(JMODS_DIR) \
- --exclude '**{_the.*,*.diz,*.debuginfo,*.dSYM/**,*.dSYM,*.pdb,*.map}' \
+ --exclude '**{_the.*,*.diz,*.debuginfo,*.dSYM/**,*.dSYM,*.pdb,*.map}' \
$(JMOD_FLAGS) $(SUPPORT_OUTPUTDIR)/jmods/$(notdir $@)
$(MV) $(SUPPORT_OUTPUTDIR)/jmods/$(notdir $@) $@
--- a/make/Images.gmk Thu Oct 20 18:38:09 2016 +0000
+++ b/make/Images.gmk Wed Jul 05 22:22:15 2017 +0200
@@ -131,35 +131,41 @@
$(JLINK_JLI_CLASSES) \
#
+JLINK_JRE_EXTRA_OPTS := --no-man-pages --no-header-files
+
ifeq ($(JLINK_KEEP_PACKAGED_MODULES), true)
- JLINK_EXTRA_OPTS := --keep-packaged-modules $(JDK_IMAGE_DIR)/jmods
+ JLINK_JDK_EXTRA_OPTS := --keep-packaged-modules $(JDK_IMAGE_DIR)/jmods
endif
$(JDK_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
$(call DependOnVariable, JDK_MODULES_LIST) $(BASE_RELEASE_FILE)
$(ECHO) Creating jdk jimage
$(RM) -r $(JDK_IMAGE_DIR)
- $(JLINK_TOOL) --output $(JDK_IMAGE_DIR) \
- --add-modules $(JDK_MODULES_LIST) $(JLINK_EXTRA_OPTS)
+ $(JLINK_TOOL) --add-modules $(JDK_MODULES_LIST) \
+ $(JLINK_JDK_EXTRA_OPTS) \
+ --output $(JDK_IMAGE_DIR)
$(TOUCH) $@
$(JRE_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
$(call DependOnVariable, JRE_MODULES_LIST) $(BASE_RELEASE_FILE)
$(ECHO) Creating jre jimage
$(RM) -r $(JRE_IMAGE_DIR)
- $(JLINK_TOOL) --output $(JRE_IMAGE_DIR) \
- --add-modules $(JRE_MODULES_LIST)
+ $(JLINK_TOOL) --add-modules $(JRE_MODULES_LIST) \
+ $(JLINK_JRE_EXTRA_OPTS) \
+ --output $(JRE_IMAGE_DIR)
$(TOUCH) $@
JRE_COMPACT1_IMAGE_DIR := $(JRE_IMAGE_DIR)-compact1
JRE_COMPACT2_IMAGE_DIR := $(JRE_IMAGE_DIR)-compact2
JRE_COMPACT3_IMAGE_DIR := $(JRE_IMAGE_DIR)-compact3
+
$(JRE_COMPACT1_IMAGE_DIR)/$(JIMAGE_TARGET_FILE): $(JMODS) \
$(call DependOnVariable, JRE_COMPACT1_MODULES_LIST) $(BASE_RELEASE_FILE)
$(ECHO) Creating jre compact1 jimage
$(RM) -r $(JRE_COMPACT1_IMAGE_DIR)
$(JLINK_TOOL) --add-modules $(JRE_COMPACT1_MODULES_LIST) \
+ $(JLINK_JRE_EXTRA_OPTS) \
--output $(JRE_COMPACT1_IMAGE_DIR)
$(TOUCH) $@
@@ -168,6 +174,7 @@
$(ECHO) Creating jre compact2 jimage
$(RM) -r $(JRE_COMPACT2_IMAGE_DIR)
$(JLINK_TOOL) --add-modules $(JRE_COMPACT2_MODULES_LIST) \
+ $(JLINK_JRE_EXTRA_OPTS) \
--output $(JRE_COMPACT2_IMAGE_DIR)
$(TOUCH) $@
@@ -176,6 +183,7 @@
$(ECHO) Creating jre compact3 jimage
$(RM) -r $(JRE_COMPACT3_IMAGE_DIR)
$(JLINK_TOOL) --add-modules $(JRE_COMPACT3_MODULES_LIST) \
+ $(JLINK_JRE_EXTRA_OPTS) \
--output $(JRE_COMPACT3_IMAGE_DIR)
$(TOUCH) $@
@@ -313,16 +321,6 @@
endif # Windows
################################################################################
-# /include dir
-
-$(eval $(call SetupCopyFiles,COPY_INCLUDES, \
- SRC := $(JDK_OUTPUTDIR)/include, \
- DEST := $(JDK_IMAGE_DIR)/include, \
- FILES := $(call CacheFind,$(JDK_OUTPUTDIR)/include)))
-
-JDK_TARGETS += $(COPY_INCLUDES)
-
-################################################################################
# doc files
JRE_DOC_FILES ?= LICENSE ASSEMBLY_EXCEPTION THIRD_PARTY_README
--- a/make/common/SetupJavaCompilers.gmk Thu Oct 20 18:38:09 2016 +0000
+++ b/make/common/SetupJavaCompilers.gmk Wed Jul 05 22:22:15 2017 +0200
@@ -28,11 +28,11 @@
include JavaCompilation.gmk
-DISABLE_WARNINGS := -Xlint:all,-deprecation,-unchecked,-rawtypes,-cast,-serial,-dep-ann,-static,-fallthrough,-try,-varargs,-empty,-finally
+DISABLE_WARNINGS := -Xlint:all,-deprecation,-removal,-unchecked,-rawtypes,-cast,-serial,-dep-ann,-static,-fallthrough,-try,-varargs,-empty,-finally
# If warnings needs to be non-fatal for testing purposes use a command like:
# make JAVAC_WARNINGS="-Xlint:all -Xmaxwarns 10000"
-JAVAC_WARNINGS := -Xlint:all -Werror
+JAVAC_WARNINGS := -Xlint:all,-removal -Werror
# The BOOT_JAVAC setup uses the boot jdk compiler to compile the tools
# and the interim javac, to be run by the boot jdk.
--- a/nashorn/.hgtags Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/.hgtags Wed Jul 05 22:22:15 2017 +0200
@@ -374,3 +374,4 @@
4a6ee1185fc821df063e4d1537fa7ad2ebe9eb02 jdk-9+138
e3b11296395b39bfeb3364f26c2ef77fa652e300 jdk-9+139
785843878cf78d50cc2959ea2c5a4202bbe885b4 jdk-9+140
+a46b7d3867957a868a6cc8ee66c05079b883733a jdk-9+141
--- a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/jdk/nashorn/tools/jjs/Console.java Wed Jul 05 22:22:15 2017 +0200
@@ -42,6 +42,8 @@
import jdk.internal.jline.console.ConsoleReader;
import jdk.internal.jline.console.KeyMap;
import jdk.internal.jline.extra.EditingHistory;
+import jdk.internal.misc.Signal;
+import jdk.internal.misc.Signal.Handler;
class Console implements AutoCloseable {
private static final String DOCUMENTATION_SHORTCUT = "\033\133\132"; //Shift-TAB
@@ -68,6 +70,21 @@
in.addCompleter(completer);
Runtime.getRuntime().addShutdownHook(new Thread((Runnable)this::saveHistory));
bind(DOCUMENTATION_SHORTCUT, (ActionListener)evt -> showDocumentation(docHelper));
+ try {
+ Signal.handle(new Signal("CONT"), new Handler() {
+ @Override public void handle(Signal sig) {
+ try {
+ in.getTerminal().reset();
+ in.redrawLine();
+ in.flush();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ });
+ } catch (IllegalArgumentException ignored) {
+ //the CONT signal does not exist on this platform
+ }
}
String readLine(final String prompt) throws IOException {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Wed Jul 05 22:22:15 2017 +0200
@@ -129,10 +129,11 @@
@Override
public String getProgram(final String... statements) {
+ Objects.requireNonNull(statements);
final StringBuilder sb = new StringBuilder();
for (final String statement : statements) {
- sb.append(statement).append(';');
+ sb.append(Objects.requireNonNull(statement)).append(';');
}
return sb.toString();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayIterator.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/ArrayIterator.java Wed Jul 05 22:22:15 2017 +0200
@@ -47,13 +47,25 @@
private final Global global;
- ArrayIterator(final Object iteratedObject, final IterationKind iterationKind, final Global global) {
+ private ArrayIterator(final Object iteratedObject, final IterationKind iterationKind, final Global global) {
super(global.getArrayIteratorPrototype(), $nasgenmap$);
this.iteratedObject = iteratedObject instanceof ScriptObject ? (ScriptObject) iteratedObject : null;
this.iterationKind = iterationKind;
this.global = global;
}
+ static ArrayIterator newArrayValueIterator(final Object iteratedObject) {
+ return new ArrayIterator(Global.toObject(iteratedObject), IterationKind.VALUE, Global.instance());
+ }
+
+ static ArrayIterator newArrayKeyIterator(final Object iteratedObject) {
+ return new ArrayIterator(Global.toObject(iteratedObject), IterationKind.KEY, Global.instance());
+ }
+
+ static ArrayIterator newArrayKeyValueIterator(final Object iteratedObject) {
+ return new ArrayIterator(Global.toObject(iteratedObject), IterationKind.KEY_VALUE, Global.instance());
+ }
+
/**
* 22.1.5.2.1 %ArrayIteratorPrototype%.next()
*
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeArray.java Wed Jul 05 22:22:15 2017 +0200
@@ -1726,7 +1726,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object entries(final Object self) {
- return new ArrayIterator(Global.toObject(self), AbstractIterator.IterationKind.KEY_VALUE, Global.instance());
+ return ArrayIterator.newArrayKeyValueIterator(self);
}
/**
@@ -1737,7 +1737,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object keys(final Object self) {
- return new ArrayIterator(Global.toObject(self), AbstractIterator.IterationKind.KEY, Global.instance());
+ return ArrayIterator.newArrayKeyIterator(self);
}
/**
@@ -1748,7 +1748,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object values(final Object self) {
- return new ArrayIterator(Global.toObject(self), AbstractIterator.IterationKind.VALUE, Global.instance());
+ return ArrayIterator.newArrayValueIterator(self);
}
/**
@@ -1759,7 +1759,7 @@
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
public static Object getIterator(final Object self) {
- return new ArrayIterator(Global.toObject(self), AbstractIterator.IterationKind.VALUE, Global.instance());
+ return ArrayIterator.newArrayValueIterator(self);
}
/**
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java Wed Jul 05 22:22:15 2017 +0200
@@ -232,6 +232,17 @@
return (NativeFloat32Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getFloat32ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java Wed Jul 05 22:22:15 2017 +0200
@@ -232,6 +232,17 @@
return (NativeFloat64Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getFloat64ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java Wed Jul 05 22:22:15 2017 +0200
@@ -225,6 +225,17 @@
return (NativeInt16Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getInt16ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java Wed Jul 05 22:22:15 2017 +0200
@@ -224,6 +224,17 @@
return (NativeInt32Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getInt32ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt8Array.java Wed Jul 05 22:22:15 2017 +0200
@@ -224,6 +224,17 @@
return (NativeInt8Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getInt8ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExp.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeRegExp.java Wed Jul 05 22:22:15 2017 +0200
@@ -701,13 +701,9 @@
}
thisIndex = matcher.end();
- if (thisIndex == string.length() && matcher.start() == matcher.end()) {
- // Avoid getting empty match at end of string twice
- break;
- }
- // ECMA 15.5.4.10 String.prototype.match(regexp)
- if (thisIndex == previousLastIndex) {
+ // ECMA6 21.2.5.6 step 8.g.iv.5: If matchStr is empty advance index by one
+ if (matcher.start() == matcher.end()) {
setLastIndex(thisIndex + 1);
previousLastIndex = thisIndex + 1;
} else {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java Wed Jul 05 22:22:15 2017 +0200
@@ -229,6 +229,17 @@
return (NativeUint16Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getUint16ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java Wed Jul 05 22:22:15 2017 +0200
@@ -244,6 +244,17 @@
return (NativeUint32Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getUint32ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java Wed Jul 05 22:22:15 2017 +0200
@@ -230,6 +230,17 @@
return (NativeUint8Array)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getUint8ArrayPrototype();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Thu Oct 20 18:38:09 2016 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java Wed Jul 05 22:22:15 2017 +0200
@@ -82,7 +82,6 @@
private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
private static final MethodHandle RINT_D = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "rint", double.class, double.class).methodHandle();
private static final MethodHandle RINT_O = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "rint", Object.class, Object.class).methodHandle();
- private static final MethodHandle CLAMP_LONG = staticCall(MethodHandles.lookup(), Uint8ClampedArrayData.class, "clampLong", long.class, long.class).methodHandle();
private Uint8ClampedArrayData(final ByteBuffer nb, final int start, final int end) {
super((nb.position(start).limit(end)).slice(), end - start);
@@ -124,8 +123,6 @@
return MH.filterArguments(setter, 2, RINT_O);
} else if (elementType == double.class) {
return MH.filterArguments(setter, 2, RINT_D);
- } else if (elementType == long.class) {
- return MH.filterArguments(setter, 2, CLAMP_LONG);
}
}
return setter;
@@ -195,7 +192,7 @@
@Override
public ArrayData set(final int index, final double value, final boolean strict) {
- return set(index, rint(value), strict);
+ return set(index, (int) rint(value), strict);
}
private static double rint(final double rint) {
@@ -207,15 +204,6 @@
return rint(JSType.toNumber(rint));
}
- @SuppressWarnings("unused")
- private static long clampLong(final long l) {
- if(l < 0L) {
- return 0L;
- } else if(l > 0xffL) {
- return 0xffL;
- }
- return l;
- }
}
/**
@@ -278,6 +266,17 @@
return (NativeUint8ClampedArray)ArrayBufferView.subarrayImpl(self, begin, end);
}
+ /**
+ * ECMA 6 22.2.3.30 %TypedArray%.prototype [ @@iterator ] ( )
+ *
+ * @param self the self reference
+ * @return an iterator over the array's values
+ */
+ @Function(attributes = Attribute.NOT_ENUMERABLE, name = "@@iterator")
+ public static Object getIterator(final Object self) {
+ return ArrayIterator.newArrayValueIterator(self);
+ }
+
@Override
protected ScriptObject getPrototype(final Global global) {
return global.getUint8ClampedArrayPrototype();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8164708.js Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+/**
+ * JDK-8164708: String.prototype.replace replaces empty match twice
+ *
+ * @test
+ * @run
+ */
+
+Assert.assertEquals("4005".replace(/\B(?=(\d{3})+(?!\d))/g, ","), "4,005");
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8168146.js Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+/**
+ * JDK-8168146: Infinite recursion in Uint8ClampedArray.set
+ *
+ * @test
+ * @run
+ */
+
+
+var a = new Uint8ClampedArray(10);
+
+for (var i = 0; i < 10; i++) {
+ a[i] = i;
+ Assert.assertTrue(a[i] === i);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/es6/JDK-8168140.js Wed Jul 05 22:22:15 2017 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+/**
+ * JDK-8168140: TypedArrays should implement ES6 iterator protocol
+ *
+ * @test
+ * @run
+ * @option --language=es6
+ */
+
+let TypedArrayTypes = [
+ Int8Array,
+ Uint8Array,
+ Uint8ClampedArray,
+ Int16Array,
+ Uint16Array,
+ Int32Array,
+ Uint32Array,
+ Float32Array,
+ Float64Array
+];
+
+let arrays = [];
+let sum = 0;
+
+TypedArrayTypes.forEach(function(ArrayType) {
+ var a = new ArrayType(10);
+ for (let i = 0; i < a.length; i++) {
+ a[i] = i;
+ }
+ arrays.push(a);
+});
+
+Assert.assertTrue(arrays.length === 9);
+
+for (let array of arrays) {
+
+ Assert.assertTrue(array.length === 10);
+ let count = 0;
+
+ for (let value of array) {
+ Assert.assertTrue(value === count++);
+ sum += value;
+ }
+}
+
+Assert.assertTrue(sum === 405);
--- a/test/failure_handler/src/share/conf/common.properties Thu Oct 20 18:38:09 2016 +0000
+++ b/test/failure_handler/src/share/conf/common.properties Wed Jul 05 22:22:15 2017 +0200
@@ -34,9 +34,8 @@
jcmd.vm.classloader_stats jcmd.vm.stringtable \
jcmd.vm.symboltable jcmd.vm.uptime jcmd.vm.dynlibs \
jcmd.vm.system_properties \
- jcmd.gc.class_stats jcmd.gc.class_histogram \
- jstack \
- jmap.heap jmap.histo jmap.clstats jmap.finalizerinfo
+ jcmd.gc.heap_info jcmd.gc.class_stats jcmd.gc.class_histogram jcmd.gc.finalizer_info \
+ jstack
jinfo.app=jinfo
@@ -55,16 +54,12 @@
jcmd.gc.class_stats.args=%p GC.class_stats
jcmd.gc.class_histogram.args=%p GC.class_histogram
+jcmd.gc.finalizer_info.args=%p GC.finalizer_info
+jcmd.gc.heap_info.args=%p GC.heap_info
jstack.app=jstack
jstack.params.repeat=6
-jmap.app=jmap
-jmap.heap.args=-heap %p
-jmap.histo.args=-histo %p
-jmap.clstats.args=-clstats %p
-jmap.finalizerinfo.args=-finalizerinfo %p
-
################################################################################
# environment info to gather
################################################################################
--- a/test/lib/jdk/test/lib/cli/predicate/NotPredicate.java Thu Oct 20 18:38:09 2016 +0000
+++ b/test/lib/jdk/test/lib/cli/predicate/NotPredicate.java Wed Jul 05 22:22:15 2017 +0200
@@ -19,7 +19,6 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
- *
*/
package jdk.test.lib.cli.predicate;
--- a/test/lib/jdk/test/lib/cli/predicate/OrPredicate.java Thu Oct 20 18:38:09 2016 +0000
+++ b/test/lib/jdk/test/lib/cli/predicate/OrPredicate.java Wed Jul 05 22:22:15 2017 +0200
@@ -19,7 +19,6 @@
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
- *
*/
package jdk.test.lib.cli.predicate;
--- a/test/lib/sun/hotspot/WhiteBox.java Thu Oct 20 18:38:09 2016 +0000
+++ b/test/lib/sun/hotspot/WhiteBox.java Wed Jul 05 22:22:15 2017 +0200
@@ -19,7 +19,6 @@
* 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.hotspot;
--- a/test/lib/sun/hotspot/code/BlobType.java Thu Oct 20 18:38:09 2016 +0000
+++ b/test/lib/sun/hotspot/code/BlobType.java Wed Jul 05 22:22:15 2017 +0200
@@ -19,7 +19,6 @@
* 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.hotspot.code;
--- a/test/lib/sun/hotspot/code/CodeBlob.java Thu Oct 20 18:38:09 2016 +0000
+++ b/test/lib/sun/hotspot/code/CodeBlob.java Wed Jul 05 22:22:15 2017 +0200
@@ -19,7 +19,6 @@
* 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.hotspot.code;
--- a/test/lib/sun/hotspot/code/NMethod.java Thu Oct 20 18:38:09 2016 +0000
+++ b/test/lib/sun/hotspot/code/NMethod.java Wed Jul 05 22:22:15 2017 +0200
@@ -19,7 +19,6 @@
* 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.hotspot.code;
--- a/test/lib/sun/hotspot/cpuinfo/CPUInfo.java Thu Oct 20 18:38:09 2016 +0000
+++ b/test/lib/sun/hotspot/cpuinfo/CPUInfo.java Wed Jul 05 22:22:15 2017 +0200
@@ -19,7 +19,6 @@
* 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.hotspot.cpuinfo;
--- a/test/lib/sun/hotspot/gc/GC.java Thu Oct 20 18:38:09 2016 +0000
+++ b/test/lib/sun/hotspot/gc/GC.java Wed Jul 05 22:22:15 2017 +0200
@@ -19,7 +19,6 @@
* 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.hotspot.gc;