--- a/jdk/src/java.base/share/classes/java/lang/System.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/System.java Thu Jun 09 19:07:27 2016 +0000
@@ -1942,6 +1942,10 @@
* the application classpath or modulepath.
*/
private static void initPhase3() {
+ // Initialize publicLookup early, to avoid bootstrapping circularities
+ // with security manager using java.lang.invoke infrastructure.
+ java.lang.invoke.MethodHandles.publicLookup();
+
// set security manager
String cn = System.getProperty("java.security.manager");
if (cn != null) {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Jun 09 19:07:27 2016 +0000
@@ -2204,15 +2204,7 @@
}
}
- private static final Class<?> PUBLIC_LOOKUP_CLASS;
- static {
- PrivilegedAction<Class<?>> pa = new PrivilegedAction<Class<?>>() {
- public Class<?> run() {
- return createClass();
- }
- };
- PUBLIC_LOOKUP_CLASS = AccessController.doPrivileged(pa);
- }
+ private static final Class<?> PUBLIC_LOOKUP_CLASS = createClass();
/**
* Lookup that is trusted minimally. It can only be used to create
--- a/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java Thu Jun 09 19:07:27 2016 +0000
@@ -1733,41 +1733,32 @@
// no instantiation
}
- // This one is deliberately non-lambdified to optimize startup time:
- private static final Function<Class<?>, MethodHandle> MOST = new Function<Class<?>, MethodHandle>() {
+ private static class StringifierMost extends ClassValue<MethodHandle> {
@Override
- public MethodHandle apply(Class<?> cl) {
- MethodHandle mhObject = lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, Object.class);
-
- // We need the additional conversion here, because String.valueOf(Object) may return null.
- // String conversion rules in Java state we need to produce "null" String in this case.
- // It can be easily done with applying valueOf the second time.
- MethodHandle mhObjectNoNulls = MethodHandles.filterReturnValue(mhObject,
- mhObject.asType(MethodType.methodType(String.class, String.class)));
-
+ protected MethodHandle computeValue(Class<?> cl) {
if (cl == String.class) {
- return mhObject;
+ return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, Object.class);
} else if (cl == float.class) {
return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, float.class);
} else if (cl == double.class) {
return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, double.class);
} else if (!cl.isPrimitive()) {
- return mhObjectNoNulls;
+ MethodHandle mhObject = lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, Object.class);
+
+ // We need the additional conversion here, because String.valueOf(Object) may return null.
+ // String conversion rules in Java state we need to produce "null" String in this case.
+ // It can be easily done with applying valueOf the second time.
+ return MethodHandles.filterReturnValue(mhObject,
+ mhObject.asType(MethodType.methodType(String.class, String.class)));
}
return null;
}
- };
+ }
- // This one is deliberately non-lambdified to optimize startup time:
- private static final Function<Class<?>, MethodHandle> ANY = new Function<Class<?>, MethodHandle>() {
+ private static class StringifierAny extends ClassValue<MethodHandle> {
@Override
- public MethodHandle apply(Class<?> cl) {
- MethodHandle mh = MOST.apply(cl);
- if (mh != null) {
- return mh;
- }
-
+ protected MethodHandle computeValue(Class<?> cl) {
if (cl == byte.class || cl == short.class || cl == int.class) {
return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, int.class);
} else if (cl == boolean.class) {
@@ -1777,13 +1768,18 @@
} else if (cl == long.class) {
return lookupStatic(MethodHandles.publicLookup(), String.class, "valueOf", String.class, long.class);
} else {
- throw new IllegalStateException("Unknown class: " + cl);
+ MethodHandle mh = STRINGIFIERS_MOST.get(cl);
+ if (mh != null) {
+ return mh;
+ } else {
+ throw new IllegalStateException("Unknown class: " + cl);
+ }
}
}
- };
+ }
- private static final ConcurrentMap<Class<?>, MethodHandle> STRINGIFIERS_MOST = new ConcurrentHashMap<>();
- private static final ConcurrentMap<Class<?>, MethodHandle> STRINGIFIERS_ANY = new ConcurrentHashMap<>();
+ private static final ClassValue<MethodHandle> STRINGIFIERS_MOST = new StringifierMost();
+ private static final ClassValue<MethodHandle> STRINGIFIERS_ANY = new StringifierAny();
/**
* Returns a stringifier for references and floats/doubles only.
@@ -1793,7 +1789,7 @@
* @return stringifier; null, if not available
*/
static MethodHandle forMost(Class<?> t) {
- return STRINGIFIERS_MOST.computeIfAbsent(t, MOST);
+ return STRINGIFIERS_MOST.get(t);
}
/**
@@ -1803,7 +1799,7 @@
* @return stringifier
*/
static MethodHandle forAny(Class<?> t) {
- return STRINGIFIERS_ANY.computeIfAbsent(t, ANY);
+ return STRINGIFIERS_ANY.get(t);
}
}
--- a/jdk/src/java.base/share/classes/java/net/URI.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/net/URI.java Thu Jun 09 19:07:27 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2014, 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
@@ -92,9 +92,9 @@
* URIs are:
*
* <blockquote>
- * {@code http://java.sun.com/j2se/1.3/}<br>
- * {@code docs/guide/collections/designfaq.html#28}<br>
- * {@code ../../../demo/jfc/SwingSet2/src/SwingSet2.java}<br>
+ * {@code http://example.com/languages/java/}<br>
+ * {@code sample/a/index.html#28}<br>
+ * {@code ../../demo/b/index.html}<br>
* {@code file:///~/calendar}
* </blockquote>
*
@@ -178,28 +178,28 @@
* normalized. The result, for example, of resolving
*
* <blockquote>
- * {@code docs/guide/collections/designfaq.html#28}
+ * {@code sample/a/index.html#28}
*
* (1)
* </blockquote>
*
- * against the base URI {@code http://java.sun.com/j2se/1.3/} is the result
+ * against the base URI {@code http://example.com/languages/java/} is the result
* URI
*
* <blockquote>
- * {@code http://docs.oracle.com/javase/1.3/docs/guide/collections/designfaq.html#28}
+ * {@code http://example.com/languages/java/sample/a/index.html#28}
* </blockquote>
*
* Resolving the relative URI
*
* <blockquote>
- * {@code ../../../demo/jfc/SwingSet2/src/SwingSet2.java} (2)
+ * {@code ../../demo/b/index.html} (2)
* </blockquote>
*
* against this result yields, in turn,
*
* <blockquote>
- * {@code http://java.sun.com/j2se/1.3/demo/jfc/SwingSet2/src/SwingSet2.java}
+ * {@code http://example.com/languages/java/demo/b/index.html}
* </blockquote>
*
* Resolution of both absolute and relative URIs, and of both absolute and
@@ -210,7 +210,7 @@
* URI
*
* <blockquote>
- * {@code demo/jfc/SwingSet2/src/SwingSet2.java}
+ * {@code demo/b/index.html}
* </blockquote>
*
* <p> <i>Relativization</i>, finally, is the inverse of resolution: For any
@@ -226,16 +226,16 @@
* possible. For example, relativizing the URI
*
* <blockquote>
- * {@code http://docs.oracle.com/javase/1.3/docs/guide/index.html}
+ * {@code http://example.com/languages/java/sample/a/index.html#28}
* </blockquote>
*
* against the base URI
*
* <blockquote>
- * {@code http://java.sun.com/j2se/1.3}
+ * {@code http://example.com/languages/java/}
* </blockquote>
*
- * yields the relative URI {@code docs/guide/index.html}.
+ * yields the relative URI {@code sample/a/index.html#28}.
*
*
* <h4> Character categories </h4>
--- a/jdk/src/java.base/share/classes/java/security/SecureRandomParameters.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/security/SecureRandomParameters.java Thu Jun 09 19:07:27 2016 +0000
@@ -33,6 +33,7 @@
* can be passed to those implementations that support them.
*
* @see DrbgParameters
+ * @since 9
*/
public interface SecureRandomParameters {
}
--- a/jdk/src/java.base/share/classes/java/util/Locale.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/util/Locale.java Thu Jun 09 19:07:27 2016 +0000
@@ -2858,6 +2858,8 @@
* @param range a language range
* @throws NullPointerException if the given {@code range} is
* {@code null}
+ * @throws IllegalArgumentException if the given {@code range} does not
+ * comply with the syntax of the language range mentioned in RFC 4647
*/
public LanguageRange(String range) {
this(range, MAX_WEIGHT);
@@ -2873,8 +2875,10 @@
* {@code MAX_WEIGHT}
* @throws NullPointerException if the given {@code range} is
* {@code null}
- * @throws IllegalArgumentException if the given {@code weight} is less
- * than {@code MIN_WEIGHT} or greater than {@code MAX_WEIGHT}
+ * @throws IllegalArgumentException if the given {@code range} does not
+ * comply with the syntax of the language range mentioned in RFC 4647
+ * or if the given {@code weight} is less than {@code MIN_WEIGHT}
+ * or greater than {@code MAX_WEIGHT}
*/
public LanguageRange(String range, double weight) {
if (range == null) {
--- a/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java Thu Jun 09 19:07:27 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2013, 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
@@ -118,16 +118,22 @@
members = new HashMap<>(methods.length+1, 1.0f);
for (Method method : methods) {
- if (method.getParameterTypes().length != 0)
- throw new IllegalArgumentException(method + " has params");
- String name = method.getName();
- Class<?> type = method.getReturnType();
- memberTypes.put(name, invocationHandlerReturnType(type));
- members.put(name, method);
+ if (Modifier.isPublic(method.getModifiers()) &&
+ Modifier.isAbstract(method.getModifiers()) &&
+ !method.isSynthetic()) {
+ if (method.getParameterTypes().length != 0) {
+ throw new IllegalArgumentException(method + " has params");
+ }
+ String name = method.getName();
+ Class<?> type = method.getReturnType();
+ memberTypes.put(name, invocationHandlerReturnType(type));
+ members.put(name, method);
- Object defaultValue = method.getDefaultValue();
- if (defaultValue != null)
- memberDefaults.put(name, defaultValue);
+ Object defaultValue = method.getDefaultValue();
+ if (defaultValue != null) {
+ memberDefaults.put(name, defaultValue);
+ }
+ }
}
// Initialize retention, & inherited fields. Special treatment
--- a/jdk/src/java.base/share/classes/sun/security/provider/AbstractDrbg.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/AbstractDrbg.java Thu Jun 09 19:07:27 2016 +0000
@@ -33,12 +33,13 @@
import static java.security.DrbgParameters.Capability.*;
/**
- * The abstract base class for all DRBGs.
+ * The abstract base class for all DRBGs. It is used as {@link DRBG#impl}.
* <p>
- * This class creates 5 new abstract methods. 3 are defined by the SP800-90A:
+ * This class has 5 abstract methods. 3 are defined by SP800-90A:
* <ol>
* <li>{@link #generateAlgorithm(byte[], byte[])}
- * <li>{@link #reseedAlgorithm(byte[], byte[])} (might not be supported)
+ * <li>{@link #reseedAlgorithm(byte[], byte[])} (In fact this is not an
+ * abstract method, but any DRBG supporting reseeding must override it.)
* <li>{@link #instantiateAlgorithm(byte[])}
* </ol>
* and 2 for implementation purpose:
@@ -46,18 +47,19 @@
* <li>{@link #initEngine()}
* <li>{@link #chooseAlgorithmAndStrength}
* </ol>
- * All existing {@link SecureRandomSpi} methods are implemented based on the
- * methods above as final. The initialization process is divided into 2 phases:
- * configuration is eagerly called to set up parameters, and instantiation
- * is lazily called only when nextBytes or reseed is called.
+ * Although this class is not a child class of {@link SecureRandomSpi}, it
+ * implements all abstract methods there as final.
+ * <p>
+ * The initialization process of a DRBG is divided into 2 phases:
+ * {@link #configure configuration} is eagerly called to set up parameters,
+ * and {@link #instantiateIfNecessary instantiation} is lazily called only
+ * when nextBytes or reseed is called.
* <p>
* SecureRandom methods like reseed and nextBytes are not thread-safe.
* An implementation is required to protect shared access to instantiate states
- * (instantiated, nonce) and DRBG states (v, c, key, reseedCounter).
+ * (instantiated, nonce) and DRBG states (v, c, key, reseedCounter, etc).
*/
-public abstract class AbstractDrbg extends SecureRandomSpi {
-
- private static final long serialVersionUID = 9L;
+public abstract class AbstractDrbg {
/**
* This field is not null if {@code -Djava.security.debug=securerandom} is
@@ -69,7 +71,7 @@
// Common working status
- private transient boolean instantiated = false;
+ private boolean instantiated = false;
/**
* Reseed counter of a DRBG instance. A mechanism should increment it
@@ -78,7 +80,7 @@
*
* Volatile, will be used in a double checked locking.
*/
- protected transient volatile int reseedCounter = 0;
+ protected volatile int reseedCounter = 0;
// Mech features. If not same as below, must be redefined in constructor.
@@ -170,7 +172,7 @@
/**
* Algorithm used by this instance (SHA-512 or AES-256). Must be assigned
* in {@link #chooseAlgorithmAndStrength}. This field is used in
- * {@link #toString()} and {@link DRBG#algorithmName}.
+ * {@link #toString()}.
*/
protected String algorithm;
@@ -217,7 +219,7 @@
* After instantiation, this field is not null. Do not modify it
* in a mechanism.
*/
- protected transient byte[] nonce;
+ protected byte[] nonce;
/**
* Requested nonce in {@link MoreDrbgParameters}. If set to null,
@@ -237,7 +239,7 @@
* {@link #configure(SecureRandomParameters)}. This field
* can be null. {@link #getEntropyInput} will take care of null check.
*/
- private transient EntropySource es;
+ private EntropySource es;
// Five abstract methods for SP 800-90A DRBG
@@ -286,10 +288,7 @@
/**
* Initiates security engines ({@code MessageDigest}, {@code Mac},
- * or {@code Cipher}). Must be called in deserialization. Please note
- * that before instantiation the algorithm might not be available yet.
- * In this case, just return and this method will be called
- * automatically at instantiation.
+ * or {@code Cipher}). This method is called during instantiation.
*/
protected abstract void initEngine();
@@ -331,13 +330,11 @@
// SecureRandomSpi methods taken care of here. All final.
- @Override
protected final void engineNextBytes(byte[] result) {
engineNextBytes(result, DrbgParameters.nextBytes(
-1, predictionResistanceFlag, null));
}
- @Override
protected final void engineNextBytes(
byte[] result, SecureRandomParameters params) {
@@ -402,7 +399,6 @@
}
}
- @Override
public final void engineReseed(SecureRandomParameters params) {
if (debug != null) {
debug.println(this, "reseed with params");
@@ -454,7 +450,6 @@
* @param numBytes the number of seed bytes to generate.
* @return the seed bytes.
*/
- @Override
public final byte[] engineGenerateSeed(int numBytes) {
byte[] b = new byte[numBytes];
SeedGenerator.generateSeed(b);
@@ -469,7 +464,6 @@
*
* @param input the seed
*/
- @Override
public final synchronized void engineSetSeed(byte[] input) {
if (debug != null) {
debug.println(this, "setSeed");
@@ -598,7 +592,6 @@
*
* @return the curent configuration
*/
- @Override
protected SecureRandomParameters engineGetParameters() {
// Or read from variable.
return DrbgParameters.instantiation(
@@ -631,7 +624,8 @@
this.es = m.es;
this.requestedAlgorithm = m.algorithm;
this.usedf = m.usedf;
- params = m.config;
+ params = DrbgParameters.instantiation(m.strength,
+ m.capability, m.personalizationString);
}
if (params != null) {
if (params instanceof DrbgParameters.Instantiation) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/AbstractHashDrbg.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/AbstractHashDrbg.java Thu Jun 09 19:07:27 2016 +0000
@@ -32,8 +32,6 @@
public abstract class AbstractHashDrbg extends AbstractDrbg {
- private static final long serialVersionUID = 9L;
-
protected int outLen;
protected int seedLen;
--- a/jdk/src/java.base/share/classes/sun/security/provider/CtrDrbg.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/CtrDrbg.java Thu Jun 09 19:07:27 2016 +0000
@@ -28,14 +28,12 @@
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
-import java.io.IOException;
import java.security.*;
import java.util.Arrays;
import java.util.Locale;
public class CtrDrbg extends AbstractDrbg {
- private static final long serialVersionUID = 9L;
private static final int AES_LIMIT;
static {
@@ -47,7 +45,7 @@
}
}
- private transient Cipher cipher;
+ private Cipher cipher;
private String cipherAlg;
private String keyAlg;
@@ -57,8 +55,8 @@
private int keyLen;
private int seedLen;
- private transient byte[] v;
- private transient byte[] k;
+ private byte[] v;
+ private byte[] k;
public CtrDrbg(SecureRandomParameters params) {
mechName = "CTR_DRBG";
@@ -165,7 +163,7 @@
protected void initEngine() {
try {
/*
- * Use the local SUN implementation to avoid native
+ * Use the local SunJCE implementation to avoid native
* performance overhead.
*/
cipher = Cipher.getInstance(cipherAlg, "SunJCE");
@@ -463,12 +461,6 @@
// Step 8. Return
}
- private void readObject(java.io.ObjectInputStream s)
- throws IOException, ClassNotFoundException {
- s.defaultReadObject ();
- initEngine();
- }
-
@Override
public String toString() {
return super.toString() + ","
--- a/jdk/src/java.base/share/classes/sun/security/provider/DRBG.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/DRBG.java Thu Jun 09 19:07:27 2016 +0000
@@ -25,6 +25,7 @@
package sun.security.provider;
+import java.io.IOException;
import java.security.AccessController;
import java.security.DrbgParameters;
import java.security.PrivilegedAction;
@@ -61,11 +62,12 @@
private static final long serialVersionUID = 9L;
- private final AbstractDrbg impl;
+ private transient AbstractDrbg impl;
- private final String mechName;
-
- private final String algorithmName;
+ /**
+ * @serial
+ */
+ private final MoreDrbgParameters mdp;
public DRBG(SecureRandomParameters params) {
@@ -91,7 +93,7 @@
// Can be configured with a security property
String config = AccessController.doPrivileged((PrivilegedAction<String>)
- () -> Security.getProperty(PROP_NAME));
+ () -> Security.getProperty(PROP_NAME));
if (config != null && !config.isEmpty()) {
for (String part : config.split(",")) {
@@ -151,8 +153,9 @@
if (params != null) {
// MoreDrbgParameters is used for testing.
if (params instanceof MoreDrbgParameters) {
- MoreDrbgParameters m = (MoreDrbgParameters)params;
- params = m.config;
+ MoreDrbgParameters m = (MoreDrbgParameters) params;
+ params = DrbgParameters.instantiation(m.strength,
+ m.capability, m.personalizationString);
// No need to check null for es and nonce, they are still null
es = m.es;
@@ -197,26 +200,27 @@
usedf = true;
}
- MoreDrbgParameters m = new MoreDrbgParameters(
+ mdp = new MoreDrbgParameters(
es, mech, algorithm, nonce, usedf,
DrbgParameters.instantiation(strength, cap, ps));
- switch (mech.toLowerCase(Locale.ROOT)) {
+ createImpl();
+ }
+
+ private void createImpl() {
+ switch (mdp.mech.toLowerCase(Locale.ROOT)) {
case "hash_drbg":
- impl = new HashDrbg(m);
+ impl = new HashDrbg(mdp);
break;
case "hmac_drbg":
- impl = new HmacDrbg(m);
+ impl = new HmacDrbg(mdp);
break;
case "ctr_drbg":
- impl = new CtrDrbg(m);
+ impl = new CtrDrbg(mdp);
break;
default:
- throw new IllegalArgumentException("Unsupported mech: " + mech);
+ throw new IllegalArgumentException("Unsupported mech: " + mdp.mech);
}
-
- mechName = mech;
- algorithmName = impl.algorithm;
}
@Override
@@ -268,4 +272,13 @@
+ " cannot be provided more than once in " + PROP_NAME);
}
}
+
+ private void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ if (mdp.mech == null) {
+ throw new IllegalArgumentException("Input data is corrupted");
+ }
+ createImpl();
+ }
}
--- a/jdk/src/java.base/share/classes/sun/security/provider/HashDrbg.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/HashDrbg.java Thu Jun 09 19:07:27 2016 +0000
@@ -25,7 +25,6 @@
package sun.security.provider;
-import java.io.IOException;
import java.math.BigInteger;
import java.security.DigestException;
import java.security.MessageDigest;
@@ -36,15 +35,13 @@
public class HashDrbg extends AbstractHashDrbg {
- private static final long serialVersionUID = 9L;
-
private static final byte[] ZERO = new byte[1];
private static final byte[] ONE = new byte[]{1};
- private transient MessageDigest digest;
+ private MessageDigest digest;
- private transient byte[] v;
- private transient byte[] c;
+ private byte[] v;
+ private byte[] c;
public HashDrbg(SecureRandomParameters params) {
mechName = "Hash_DRBG";
@@ -267,10 +264,4 @@
// Step 5: No need to truncate
// Step 6: Return
}
-
- private void readObject(java.io.ObjectInputStream s)
- throws IOException, ClassNotFoundException {
- s.defaultReadObject ();
- initEngine();
- }
}
--- a/jdk/src/java.base/share/classes/sun/security/provider/HmacDrbg.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/HmacDrbg.java Thu Jun 09 19:07:27 2016 +0000
@@ -27,7 +27,6 @@
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
-import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
@@ -36,14 +35,12 @@
public class HmacDrbg extends AbstractHashDrbg {
- private static final long serialVersionUID = 9L;
-
- private transient Mac mac;
+ private Mac mac;
private String macAlg;
- private transient byte[] v;
- private transient byte[] k;
+ private byte[] v;
+ private byte[] k;
public HmacDrbg(SecureRandomParameters params) {
mechName = "HMAC_DRBG";
@@ -101,6 +98,10 @@
protected void initEngine() {
macAlg = "HmacSHA" + algorithm.substring(4);
try {
+ /*
+ * Use the local SunJCE implementation to avoid native
+ * performance overhead.
+ */
mac = Mac.getInstance(macAlg, "SunJCE");
} catch (NoSuchProviderException | NoSuchAlgorithmException e) {
// Fallback to any available.
@@ -194,10 +195,4 @@
// Step 8. Return
}
-
- private void readObject(java.io.ObjectInputStream s)
- throws IOException, ClassNotFoundException {
- s.defaultReadObject ();
- initEngine();
- }
}
--- a/jdk/src/java.base/share/classes/sun/security/provider/MoreDrbgParameters.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/MoreDrbgParameters.java Thu Jun 09 19:07:27 2016 +0000
@@ -25,20 +25,30 @@
package sun.security.provider;
+import java.io.IOException;
+import java.io.Serializable;
import java.security.DrbgParameters;
import java.security.SecureRandomParameters;
/**
- * Extra non-standard parameters that can be used by DRBGs.
+ * Exported and non-exported parameters that can be used by DRBGs.
*/
-public class MoreDrbgParameters implements SecureRandomParameters {
+public class MoreDrbgParameters implements SecureRandomParameters, Serializable {
+
+ private static final long serialVersionUID = 9L;
+
+ final transient EntropySource es;
final String mech;
final String algorithm;
- final EntropySource es;
- final byte[] nonce;
final boolean usedf;
- final DrbgParameters.Instantiation config;
+ final int strength;
+ final DrbgParameters.Capability capability;
+
+ // The following 2 fields will be reassigned in readObject and
+ // thus cannot be final
+ byte[] nonce;
+ byte[] personalizationString;
/**
* Creates a new {@code MoreDrbgParameters} object.
@@ -61,13 +71,31 @@
this.mech = mech;
this.algorithm = algorithm;
this.es = es;
- this.nonce = nonce;
+ this.nonce = (nonce == null) ? null : nonce.clone();
this.usedf = usedf;
- this.config = config;
+
+ this.strength = config.getStrength();
+ this.capability = config.getCapability();
+ this.personalizationString = config.getPersonalizationString();
}
@Override
public String toString() {
- return mech + "," + algorithm + "," + usedf + "," + config;
+ return mech + "," + algorithm + "," + usedf + "," + strength
+ + "," + capability + "," + personalizationString;
+ }
+
+ private void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ if (nonce != null) {
+ nonce = nonce.clone();
+ }
+ if (personalizationString != null) {
+ personalizationString = personalizationString.clone();
+ }
+ if (capability == null) {
+ throw new IllegalArgumentException("Input data is corrupted");
+ }
}
}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLServerSocketImpl.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLServerSocketImpl.java Thu Jun 09 19:07:27 2016 +0000
@@ -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
@@ -347,7 +347,7 @@
SSLSocketImpl s = new SSLSocketImpl(sslContext, useServerMode,
enabledCipherSuites, clientAuthType, enableSessionCreation,
enabledProtocols, identificationProtocol, algorithmConstraints,
- sniMatchers, preferLocalCipherSuites);
+ sniMatchers, preferLocalCipherSuites, applicationProtocols);
implAccept(s);
s.doneConnect();
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLSocketImpl.java Thu Jun 09 19:07:27 2016 +0000
@@ -497,7 +497,8 @@
String identificationProtocol,
AlgorithmConstraints algorithmConstraints,
Collection<SNIMatcher> sniMatchers,
- boolean preferLocalCipherSuites) throws IOException {
+ boolean preferLocalCipherSuites,
+ String[] applicationProtocols) throws IOException {
super();
doClientAuth = clientAuth;
@@ -506,6 +507,7 @@
this.algorithmConstraints = algorithmConstraints;
this.sniMatchers = sniMatchers;
this.preferLocalCipherSuites = preferLocalCipherSuites;
+ this.applicationProtocols = applicationProtocols;
init(context, serverMode);
/*
--- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Thu Jun 09 19:07:27 2016 +0000
@@ -206,7 +206,7 @@
IMPORTKEYSTORE("Imports.one.or.all.entries.from.another.keystore",
SRCKEYSTORE, DESTKEYSTORE, SRCSTORETYPE,
DESTSTORETYPE, SRCSTOREPASS, DESTSTOREPASS,
- SRCPROTECTED, SRCPROVIDERNAME, DESTPROVIDERNAME,
+ SRCPROTECTED, DESTPROTECTED, SRCPROVIDERNAME, DESTPROVIDERNAME,
SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS,
NOPROMPT, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH,
V),
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WS.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WS.java Thu Jun 09 19:07:27 2016 +0000
@@ -86,7 +86,7 @@
}
}
};
- transmitter = new WSTransmitter(executor, channel, errorHandler);
+ transmitter = new WSTransmitter(this, executor, channel, errorHandler);
receiver = new WSReceiver(this.listener, this, executor, channel);
}
@@ -95,12 +95,7 @@
}
@Override
- public CompletableFuture<Void> sendText(ByteBuffer message, boolean isLast) {
- throw new UnsupportedOperationException("Not implemented");
- }
-
- @Override
- public CompletableFuture<Void> sendText(CharSequence message, boolean isLast) {
+ public CompletableFuture<WebSocket> sendText(CharSequence message, boolean isLast) {
requireNonNull(message, "message");
synchronized (stateLock) {
checkState();
@@ -109,7 +104,7 @@
}
@Override
- public CompletableFuture<Void> sendText(Stream<? extends CharSequence> message) {
+ public CompletableFuture<WebSocket> sendText(Stream<? extends CharSequence> message) {
requireNonNull(message, "message");
synchronized (stateLock) {
checkState();
@@ -118,7 +113,7 @@
}
@Override
- public CompletableFuture<Void> sendBinary(ByteBuffer message, boolean isLast) {
+ public CompletableFuture<WebSocket> sendBinary(ByteBuffer message, boolean isLast) {
requireNonNull(message, "message");
synchronized (stateLock) {
checkState();
@@ -127,7 +122,7 @@
}
@Override
- public CompletableFuture<Void> sendPing(ByteBuffer message) {
+ public CompletableFuture<WebSocket> sendPing(ByteBuffer message) {
requireNonNull(message, "message");
synchronized (stateLock) {
checkState();
@@ -136,7 +131,7 @@
}
@Override
- public CompletableFuture<Void> sendPong(ByteBuffer message) {
+ public CompletableFuture<WebSocket> sendPong(ByteBuffer message) {
requireNonNull(message, "message");
synchronized (stateLock) {
checkState();
@@ -145,7 +140,7 @@
}
@Override
- public CompletableFuture<Void> sendClose(CloseCode code, CharSequence reason) {
+ public CompletableFuture<WebSocket> sendClose(CloseCode code, CharSequence reason) {
requireNonNull(code, "code");
requireNonNull(reason, "reason");
synchronized (stateLock) {
@@ -154,13 +149,13 @@
}
@Override
- public CompletableFuture<Void> sendClose() {
+ public CompletableFuture<WebSocket> sendClose() {
synchronized (stateLock) {
return doSendClose(() -> transmitter.sendClose());
}
}
- private CompletableFuture<Void> doSendClose(Supplier<CompletableFuture<Void>> s) {
+ private CompletableFuture<WebSocket> doSendClose(Supplier<CompletableFuture<WebSocket>> s) {
checkState();
boolean closeChannel = false;
synchronized (stateLock) {
@@ -170,7 +165,7 @@
tryChangeState(State.CLOSED_LOCALLY);
}
}
- CompletableFuture<Void> sent = s.get();
+ CompletableFuture<WebSocket> sent = s.get();
if (closeChannel) {
sent.whenComplete((v, t) -> {
try {
@@ -239,7 +234,7 @@
}
@Override
- public CompletionStage<?> onText(WebSocket webSocket, Text message,
+ public CompletionStage<?> onText(WebSocket webSocket, CharSequence message,
MessagePart part) {
synchronized (visibilityLock) {
return listener.onText(webSocket, message, part);
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSDisposableText.java Thu Jun 09 17:28:37 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +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 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 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 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 java.net.http;
-
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-
-final class WSDisposableText implements WebSocket.Text, WSDisposable {
-
- private final WSShared<CharBuffer> text;
-
- WSDisposableText(WSShared<CharBuffer> text) {
- this.text = text;
- }
-
- @Override
- public int length() {
- return text.buffer().length();
- }
-
- @Override
- public char charAt(int index) {
- return text.buffer().charAt(index);
- }
-
- @Override
- public CharSequence subSequence(int start, int end) {
- return text.buffer().subSequence(start, end);
- }
-
- @Override
- public ByteBuffer asByteBuffer() {
- throw new UnsupportedOperationException("To be removed from the API");
- }
-
- @Override
- public String toString() {
- return text.buffer().toString();
- }
-
- @Override
- public void dispose() {
- text.dispose();
- }
-}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSFrameConsumer.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSFrameConsumer.java Thu Jun 09 19:07:27 2016 +0000
@@ -214,7 +214,7 @@
if (!(binaryNonEmpty && !textData.hasRemaining())) {
// If there's a binary data, that result in no text, then we
// don't deliver anything
- output.onText(part, new WSDisposableText(textData));
+ output.onText(part, textData);
}
}
}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSMessageConsumer.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSMessageConsumer.java Thu Jun 09 19:07:27 2016 +0000
@@ -27,10 +27,11 @@
import java.net.http.WebSocket.CloseCode;
import java.net.http.WebSocket.MessagePart;
import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
interface WSMessageConsumer {
- void onText(MessagePart part, WSDisposableText data);
+ void onText(MessagePart part, WSShared<CharBuffer> data);
void onBinary(MessagePart part, WSShared<ByteBuffer> data);
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSReceiver.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSReceiver.java Thu Jun 09 19:07:27 2016 +0000
@@ -29,6 +29,7 @@
import java.net.ProtocolException;
import java.net.http.WebSocket.Listener;
import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.util.Optional;
import java.util.concurrent.CompletionStage;
@@ -169,11 +170,11 @@
private final class MessageConsumer implements WSMessageConsumer {
@Override
- public void onText(WebSocket.MessagePart part, WSDisposableText data) {
+ public void onText(WebSocket.MessagePart part, WSShared<CharBuffer> data) {
decrementDemand();
CompletionStage<?> cs;
try {
- cs = listener.onText(webSocket, data, part);
+ cs = listener.onText(webSocket, data.buffer(), part);
} catch (Exception e) {
closeExceptionally(new RuntimeException("onText threw an exception", e));
return;
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WSTransmitter.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSTransmitter.java Thu Jun 09 19:07:27 2016 +0000
@@ -51,15 +51,17 @@
*/
final class WSTransmitter {
- private final BlockingQueue<Pair<WSOutgoingMessage, CompletableFuture<Void>>>
+ private final BlockingQueue<Pair<WSOutgoingMessage, CompletableFuture<WebSocket>>>
backlog = new LinkedBlockingQueue<>();
private final WSMessageSender sender;
private final WSSignalHandler handler;
+ private final WebSocket webSocket;
private boolean previousMessageSent = true;
private boolean canSendBinary = true;
private boolean canSendText = true;
- WSTransmitter(Executor executor, RawChannel channel, Consumer<Throwable> errorHandler) {
+ WSTransmitter(WebSocket ws, Executor executor, RawChannel channel, Consumer<Throwable> errorHandler) {
+ this.webSocket = ws;
this.handler = new WSSignalHandler(executor, this::handleSignal);
Consumer<Throwable> sendCompletion = (error) -> {
synchronized (this) {
@@ -76,41 +78,41 @@
this.sender = new WSMessageSender(channel, sendCompletion);
}
- CompletableFuture<Void> sendText(CharSequence message, boolean isLast) {
+ CompletableFuture<WebSocket> sendText(CharSequence message, boolean isLast) {
checkAndUpdateText(isLast);
return acceptMessage(new Text(isLast, message));
}
- CompletableFuture<Void> sendText(Stream<? extends CharSequence> message) {
+ CompletableFuture<WebSocket> sendText(Stream<? extends CharSequence> message) {
checkAndUpdateText(true);
return acceptMessage(new StreamedText(message));
}
- CompletableFuture<Void> sendBinary(ByteBuffer message, boolean isLast) {
+ CompletableFuture<WebSocket> sendBinary(ByteBuffer message, boolean isLast) {
checkAndUpdateBinary(isLast);
return acceptMessage(new Binary(isLast, message));
}
- CompletableFuture<Void> sendPing(ByteBuffer message) {
+ CompletableFuture<WebSocket> sendPing(ByteBuffer message) {
checkSize(message.remaining(), 125);
return acceptMessage(new Ping(message));
}
- CompletableFuture<Void> sendPong(ByteBuffer message) {
+ CompletableFuture<WebSocket> sendPong(ByteBuffer message) {
checkSize(message.remaining(), 125);
return acceptMessage(new Pong(message));
}
- CompletableFuture<Void> sendClose(WebSocket.CloseCode code, CharSequence reason) {
+ CompletableFuture<WebSocket> sendClose(WebSocket.CloseCode code, CharSequence reason) {
return acceptMessage(createCloseMessage(code, reason));
}
- CompletableFuture<Void> sendClose() {
+ CompletableFuture<WebSocket> sendClose() {
return acceptMessage(new Close(ByteBuffer.allocate(0)));
}
- private CompletableFuture<Void> acceptMessage(WSOutgoingMessage m) {
- CompletableFuture<Void> cf = new CompletableFuture<>();
+ private CompletableFuture<WebSocket> acceptMessage(WSOutgoingMessage m) {
+ CompletableFuture<WebSocket> cf = new CompletableFuture<>();
synchronized (this) {
backlog.offer(pair(m, cf));
}
@@ -123,11 +125,11 @@
synchronized (this) {
while (!backlog.isEmpty() && previousMessageSent) {
previousMessageSent = false;
- Pair<WSOutgoingMessage, CompletableFuture<Void>> p = backlog.peek();
+ Pair<WSOutgoingMessage, CompletableFuture<WebSocket>> p = backlog.peek();
boolean sent = sender.trySendFully(p.first);
if (sent) {
backlog.remove();
- p.second.complete(null);
+ p.second.complete(webSocket);
previousMessageSent = true;
}
}
--- a/jdk/src/java.httpclient/share/classes/java/net/http/WebSocket.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.httpclient/share/classes/java/net/http/WebSocket.java Thu Jun 09 19:07:27 2016 +0000
@@ -52,8 +52,8 @@
*
* <p> Messages of type {@code X} are sent through the {@code WebSocket.sendX}
* methods and received through {@link WebSocket.Listener}{@code .onX} methods
- * asynchronously. Each of the methods begins the operation and returns a {@link
- * CompletionStage} which completes when the operation has completed.
+ * asynchronously. Each of the methods returns a {@link CompletionStage} which
+ * completes when the operation has completed.
*
* <p> Messages are received only if {@linkplain #request(long) requested}.
*
@@ -79,6 +79,9 @@
* or method of this type will cause a {@link NullPointerException
* NullPointerException} to be thrown.
*
+ * @implNote The default implementation's methods do not block before returning
+ * a {@code CompletableFuture}.
+ *
* @since 9
*/
public interface WebSocket {
@@ -234,9 +237,9 @@
/**
* Builds a {@code WebSocket}.
*
- * <p> Returns immediately with a {@code CompletableFuture<WebSocket>}
- * which completes with the {@code WebSocket} when it is connected, or
- * completes exceptionally if an error occurs.
+ * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+ * normally with the {@code WebSocket} when it is connected or completes
+ * exceptionally if an error occurs.
*
* <p> {@code CompletableFuture} may complete exceptionally with the
* following errors:
@@ -252,7 +255,7 @@
* if the opening handshake fails
* </ul>
*
- * @return a {@code CompletableFuture} of {@code WebSocket}
+ * @return a {@code CompletableFuture} with the {@code WebSocket}
*/
CompletableFuture<WebSocket> buildAsync();
}
@@ -264,7 +267,7 @@
* <ul>
* <li> {@link #onOpen onOpen} <br>
* This method is always the first to be invoked.
- * <li> {@link #onText(WebSocket, WebSocket.Text, WebSocket.MessagePart)
+ * <li> {@link #onText(WebSocket, CharSequence, WebSocket.MessagePart)
* onText}, {@link #onBinary(WebSocket, ByteBuffer, WebSocket.MessagePart)
* onBinary}, {@link #onPing(WebSocket, ByteBuffer) onPing} and {@link
* #onPong(WebSocket, ByteBuffer) onPong} <br>
@@ -375,6 +378,9 @@
* @implSpec The default implementation {@linkplain WebSocket#request(long)
* requests one more message}.
*
+ * @implNote This implementation passes only complete UTF-16 sequences
+ * to the {@code onText} method.
+ *
* @param webSocket
* the WebSocket
* @param message
@@ -386,7 +392,7 @@
* is done; or {@code null} if already done
*/
default CompletionStage<?> onText(WebSocket webSocket,
- Text message,
+ CharSequence message,
MessagePart part) {
webSocket.request(1);
return null;
@@ -596,59 +602,11 @@
}
/**
- * Sends a Text message with bytes from the given {@code ByteBuffer}.
- *
- * <p> Returns immediately with a {@code CompletableFuture<Void>} which
- * completes normally when the message has been sent, or completes
- * exceptionally if an error occurs.
- *
- * <p> This message may be a partial UTF-8 sequence. However, the
- * concatenation of all messages through the last must be a whole UTF-8
- * sequence.
- *
- * <p> The {@code ByteBuffer} should not be modified until the returned
- * {@code CompletableFuture} completes (either normally or exceptionally).
- *
- * <p> The returned {@code CompletableFuture} can complete exceptionally
- * with:
- * <ul>
- * <li> {@link IOException}
- * if an I/O error occurs during this operation; or the
- * {@code WebSocket} closes while this operation is in progress;
- * or the {@code message} is a malformed UTF-8 sequence
- * </ul>
+ * Sends a Text message with characters from the given {@code CharSequence}.
*
- * @param message
- * the message
- * @param isLast
- * {@code true} if this is the final part of the message,
- * {@code false} otherwise
- *
- * @return a CompletableFuture of Void
- *
- * @throws IllegalStateException
- * if the WebSocket is closed
- * @throws IllegalStateException
- * if a Close message has been sent already
- * @throws IllegalStateException
- * if there is an outstanding send operation
- * @throws IllegalStateException
- * if a previous Binary message
- * was not sent with {@code isLast == true}
- */
- CompletableFuture<Void> sendText(ByteBuffer message, boolean isLast);
-
- /**
- * Sends a Text message with characters from the given {@code
- * CharSequence}.
- *
- * <p> Returns immediately with a {@code CompletableFuture<Void>} which
- * completes normally when the message has been sent, or completes
- * exceptionally if an error occurs.
- *
- * <p> This message may be a partial UTF-16 sequence. However, the
- * concatenation of all messages through the last must be a whole UTF-16
- * sequence.
+ * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+ * normally when the message has been sent or completes exceptionally if an
+ * error occurs.
*
* <p> The {@code CharSequence} should not be modified until the returned
* {@code CompletableFuture} completes (either normally or exceptionally).
@@ -657,30 +615,30 @@
* with:
* <ul>
* <li> {@link IOException}
- * if an I/O error occurs during this operation; or the
- * {@code WebSocket} closes while this operation is in progress;
- * or the {@code message} is a malformed UTF-16 sequence
+ * if an I/O error occurs during this operation
+ * <li> {@link IllegalStateException}
+ * if the {@code WebSocket} closes while this operation is in progress;
+ * or if a Close message has been sent already;
+ * or if there is an outstanding send operation;
+ * or if a previous Binary message was not sent with {@code isLast == true}
* </ul>
*
+ * @implNote This implementation does not accept partial UTF-16
+ * sequences. In case such a sequence is passed, a returned {@code
+ * CompletableFuture} completes exceptionally.
+ *
* @param message
* the message
* @param isLast
- * {@code true} if this is the final part of the message
+ * {@code true} if this is the final part of the message,
* {@code false} otherwise
*
- * @return a CompletableFuture of Void
+ * @return a CompletableFuture with this WebSocket
*
- * @throws IllegalStateException
- * if the WebSocket is closed
- * @throws IllegalStateException
- * if a Close message has been already sent
- * @throws IllegalStateException
- * if there is an outstanding send operation
- * @throws IllegalStateException
- * if a previous Binary message was not sent
- * with {@code isLast == true}
+ * @throws IllegalArgumentException
+ * if {@code message} is a malformed (or an incomplete) UTF-16 sequence
*/
- CompletableFuture<Void> sendText(CharSequence message, boolean isLast);
+ CompletableFuture<WebSocket> sendText(CharSequence message, boolean isLast);
/**
* Sends a whole Text message with characters from the given {@code
@@ -689,9 +647,9 @@
* <p> This is a convenience method. For the general case, use {@link
* #sendText(CharSequence, boolean)}.
*
- * <p> Returns immediately with a {@code CompletableFuture<Void>} which
- * completes normally when the message has been sent, or completes
- * exceptionally if an error occurs.
+ * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+ * normally when the message has been sent or completes exceptionally if an
+ * error occurs.
*
* <p> The {@code CharSequence} should not be modified until the returned
* {@code CompletableFuture} completes (either normally or exceptionally).
@@ -700,27 +658,23 @@
* with:
* <ul>
* <li> {@link IOException}
- * if an I/O error occurs during this operation; or the
- * {@code WebSocket} closes while this operation is in progress;
- * or the message is a malformed UTF-16 sequence
+ * if an I/O error occurs during this operation
+ * <li> {@link IllegalStateException}
+ * if the {@code WebSocket} closes while this operation is in progress;
+ * or if a Close message has been sent already;
+ * or if there is an outstanding send operation;
+ * or if a previous Binary message was not sent with {@code isLast == true}
* </ul>
*
* @param message
* the message
*
- * @return a CompletableFuture of Void
+ * @return a CompletableFuture with this WebSocket
*
- * @throws IllegalStateException
- * if the WebSocket is closed
- * @throws IllegalStateException
- * if a Close message has been already sent
- * @throws IllegalStateException
- * if there is an outstanding send operation
- * @throws IllegalStateException
- * if a previous Binary message was not sent
- * with {@code isLast == true}
+ * @throws IllegalArgumentException
+ * if {@code message} is a malformed (or an incomplete) UTF-16 sequence
*/
- default CompletableFuture<Void> sendText(CharSequence message) {
+ default CompletableFuture<WebSocket> sendText(CharSequence message) {
return sendText(message, true);
}
@@ -731,9 +685,9 @@
* <p> This is a convenience method. For the general case use {@link
* #sendText(CharSequence, boolean)}.
*
- * <p> Returns immediately with a {@code CompletableFuture<Void>} which
- * completes normally when the message has been sent, or completes
- * exceptionally if an error occurs.
+ * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+ * normally when the message has been sent or completes exceptionally if an
+ * error occurs.
*
* <p> Streamed character sequences should not be modified until the
* returned {@code CompletableFuture} completes (either normally or
@@ -743,41 +697,41 @@
* with:
* <ul>
* <li> {@link IOException}
- * if an I/O error occurs during this operation; or the
- * {@code WebSocket} closes while this operation is in progress;
- * or the message is a malformed UTF-16 sequence
+ * if an I/O error occurs during this operation
+ * <li> {@link IllegalStateException}
+ * if the {@code WebSocket} closes while this operation is in progress;
+ * or if a Close message has been sent already;
+ * or if there is an outstanding send operation;
+ * or if a previous Binary message was not sent with {@code isLast == true}
* </ul>
*
* @param message
* the message
*
- * @return a CompletableFuture of Void
+ * @return a CompletableFuture with this WebSocket
*
- * @throws IllegalStateException
- * if the WebSocket is closed
- * @throws IllegalStateException
- * if a Close message has been already sent
- * @throws IllegalStateException
- * if there is an outstanding send operation
- * @throws IllegalStateException
- * if a previous Binary message was not sent
- * with {@code isLast == true}
+ * @throws IllegalArgumentException
+ * if {@code message} is a malformed (or an incomplete) UTF-16 sequence
*/
- CompletableFuture<Void> sendText(Stream<? extends CharSequence> message);
+ CompletableFuture<WebSocket> sendText(Stream<? extends CharSequence> message);
/**
* Sends a Binary message with bytes from the given {@code ByteBuffer}.
*
- * <p> Returns immediately with a {@code CompletableFuture<Void>} which
- * completes normally when the message has been sent, or completes
- * exceptionally if an error occurs.
+ * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+ * normally when the message has been sent or completes exceptionally if an
+ * error occurs.
*
* <p> The returned {@code CompletableFuture} can complete exceptionally
* with:
* <ul>
* <li> {@link IOException}
- * if an I/O error occurs during this operation or the
- * {@code WebSocket} closes while this operation is in progress
+ * if an I/O error occurs during this operation
+ * <li> {@link IllegalStateException}
+ * if the {@code WebSocket} closes while this operation is in progress;
+ * or if a Close message has been sent already;
+ * or if there is an outstanding send operation;
+ * or if a previous Text message was not sent with {@code isLast == true}
* </ul>
*
* @param message
@@ -786,33 +740,27 @@
* {@code true} if this is the final part of the message,
* {@code false} otherwise
*
- * @return a CompletableFuture of Void
- *
- * @throws IllegalStateException
- * if the WebSocket is closed
- * @throws IllegalStateException
- * if a Close message has been already sent
- * @throws IllegalStateException
- * if there is an outstanding send operation
- * @throws IllegalStateException
- * if a previous Text message was not sent
- * with {@code isLast == true}
+ * @return a CompletableFuture with this WebSocket
*/
- CompletableFuture<Void> sendBinary(ByteBuffer message, boolean isLast);
+ CompletableFuture<WebSocket> sendBinary(ByteBuffer message, boolean isLast);
/**
* Sends a Binary message with bytes from the given {@code byte[]}.
*
- * <p> Returns immediately with a {@code CompletableFuture<Void>} which
- * completes normally when the message has been sent, or completes
- * exceptionally if an error occurs.
+ * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+ * normally when the message has been sent or completes exceptionally if an
+ * error occurs.
*
* <p> The returned {@code CompletableFuture} can complete exceptionally
* with:
* <ul>
* <li> {@link IOException}
- * if an I/O error occurs during this operation or the
- * {@code WebSocket} closes while this operation is in progress
+ * if an I/O error occurs during this operation
+ * <li> {@link IllegalStateException}
+ * if the {@code WebSocket} closes while this operation is in progress;
+ * or if a Close message has been sent already;
+ * or if there is an outstanding send operation;
+ * or if a previous Text message was not sent with {@code isLast == true}
* </ul>
*
* @implSpec This is equivalent to:
@@ -826,19 +774,9 @@
* {@code true} if this is the final part of the message,
* {@code false} otherwise
*
- * @return a CompletableFuture of Void
- *
- * @throws IllegalStateException
- * if the WebSocket is closed
- * @throws IllegalStateException
- * if a Close message has been already sent
- * @throws IllegalStateException
- * if there is an outstanding send operation
- * @throws IllegalStateException
- * if a previous Text message was not sent
- * with {@code isLast == true}
+ * @return a CompletableFuture with this WebSocket
*/
- default CompletableFuture<Void> sendBinary(byte[] message, boolean isLast) {
+ default CompletableFuture<WebSocket> sendBinary(byte[] message, boolean isLast) {
Objects.requireNonNull(message, "message");
return sendBinary(ByteBuffer.wrap(message), isLast);
}
@@ -846,9 +784,9 @@
/**
* Sends a Ping message.
*
- * <p> Returns immediately with a {@code CompletableFuture<Void>} which
- * completes normally when the message has been sent, or completes
- * exceptionally if an error occurs.
+ * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+ * normally when the message has been sent or completes exceptionally if an
+ * error occurs.
*
* <p> A Ping message may be sent or received by either client or server.
* It may serve either as a keepalive or as a means to verify that the
@@ -861,32 +799,29 @@
* with:
* <ul>
* <li> {@link IOException}
- * if an I/O error occurs during this operation or the
- * {@code WebSocket} closes while this operation is in progress
+ * if an I/O error occurs during this operation
+ * <li> {@link IllegalStateException}
+ * if the {@code WebSocket} closes while this operation is in progress;
+ * or if a Close message has been sent already;
+ * or if there is an outstanding send operation
* </ul>
*
* @param message
* the message
*
- * @return a CompletableFuture of Void
+ * @return a CompletableFuture with this WebSocket
*
- * @throws IllegalStateException
- * if the WebSocket is closed
- * @throws IllegalStateException
- * if a Close message has been already sent
- * @throws IllegalStateException
- * if there is an outstanding send operation
* @throws IllegalArgumentException
* if {@code message.remaining() > 125}
*/
- CompletableFuture<Void> sendPing(ByteBuffer message);
+ CompletableFuture<WebSocket> sendPing(ByteBuffer message);
/**
* Sends a Pong message.
*
- * <p> Returns immediately with a {@code CompletableFuture<Void>} which
- * completes normally when the message has been sent, or completes
- * exceptionally if an error occurs.
+ * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+ * normally when the message has been sent or completes exceptionally if an
+ * error occurs.
*
* <p> A Pong message may be unsolicited or may be sent in response to a
* previously received Ping. In latter case the contents of the Pong is
@@ -899,32 +834,29 @@
* with:
* <ul>
* <li> {@link IOException}
- * if an I/O error occurs during this operation or the
- * {@code WebSocket} closes while this operation is in progress
+ * if an I/O error occurs during this operation
+ * <li> {@link IllegalStateException}
+ * if the {@code WebSocket} closes while this operation is in progress;
+ * or if a Close message has been sent already;
+ * or if there is an outstanding send operation
* </ul>
*
* @param message
* the message
*
- * @return a CompletableFuture of Void
+ * @return a CompletableFuture with this WebSocket
*
- * @throws IllegalStateException
- * if the WebSocket is closed
- * @throws IllegalStateException
- * if a Close message has been already sent
- * @throws IllegalStateException
- * if there is an outstanding send operation
* @throws IllegalArgumentException
* if {@code message.remaining() > 125}
*/
- CompletableFuture<Void> sendPong(ByteBuffer message);
+ CompletableFuture<WebSocket> sendPong(ByteBuffer message);
/**
* Sends a Close message with the given close code and the reason.
*
- * <p> Returns immediately with a {@code CompletableFuture<Void>} which
- * completes normally when the message has been sent, or completes
- * exceptionally if an error occurs.
+ * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+ * normally when the message has been sent or completes exceptionally if an
+ * error occurs.
*
* <p> A Close message may consist of a close code and a reason for closing.
* The reason must have a valid UTF-8 representation not longer than {@code
@@ -935,8 +867,11 @@
* with:
* <ul>
* <li> {@link IOException}
- * if an I/O error occurs during this operation or the
- * {@code WebSocket} closes while this operation is in progress
+ * if an I/O error occurs during this operation
+ * <li> {@link IllegalStateException}
+ * if the {@code WebSocket} closes while this operation is in progress;
+ * or if a Close message has been sent already;
+ * or if there is an outstanding send operation
* </ul>
*
* @param code
@@ -944,45 +879,35 @@
* @param reason
* the reason; can be empty
*
- * @return a CompletableFuture of Void
+ * @return a CompletableFuture with this WebSocket
*
- * @throws IllegalStateException
- * if the WebSocket is closed
- * @throws IllegalStateException
- * if a Close message has been already sent
- * @throws IllegalStateException
- * if there is an outstanding send operation
* @throws IllegalArgumentException
- * if the {@code reason} doesn't have a valid UTF-8
- * representation not longer than {@code 123} bytes
+ * if {@code reason} doesn't have an UTF-8 representation not longer
+ * than {@code 123} bytes
*/
- CompletableFuture<Void> sendClose(CloseCode code, CharSequence reason);
+ CompletableFuture<WebSocket> sendClose(CloseCode code, CharSequence reason);
/**
* Sends an empty Close message.
*
- * <p> Returns immediately with a {@code CompletableFuture<Void>} which
- * completes normally when the message has been sent, or completes
- * exceptionally if an error occurs.
+ * <p> Returns a {@code CompletableFuture<WebSocket>} which completes
+ * normally when the message has been sent or completes exceptionally if an
+ * error occurs.
*
* <p> The returned {@code CompletableFuture} can complete exceptionally
* with:
* <ul>
* <li> {@link IOException}
- * if an I/O error occurs during this operation or the
- * {@code WebSocket} closes while this operation is in progress
+ * if an I/O error occurs during this operation
+ * <li> {@link IllegalStateException}
+ * if the {@code WebSocket} closes while this operation is in progress;
+ * or if a Close message has been sent already;
+ * or if there is an outstanding send operation
* </ul>
*
- * @return a CompletableFuture of Void
- *
- * @throws IllegalStateException
- * if the WebSocket is closed
- * @throws IllegalStateException
- * if a Close message has been already sent
- * @throws IllegalStateException
- * if there is an outstanding send operation
+ * @return a CompletableFuture with this WebSocket
*/
- CompletableFuture<Void> sendClose();
+ CompletableFuture<WebSocket> sendClose();
/**
* Requests {@code n} more messages to be received by the {@link Listener
@@ -1001,6 +926,7 @@
* @implNote This implementation does not distinguish between partial and
* whole messages, because it's not known beforehand how a message will be
* received.
+ *
* <p> If a server sends more messages than requested, the implementation
* queues up these messages on the TCP connection and may eventually force
* the sender to stop sending through TCP flow control.
@@ -1242,47 +1168,4 @@
return Map.entry(cc.getCode(), cc);
}
}
-
- /**
- * A character sequence that provides access to the characters UTF-8 decoded
- * from a message in a {@code ByteBuffer}.
- *
- * @since 9
- */
- interface Text extends CharSequence {
-
- // Methods from the CharSequence below are mentioned explicitly for the
- // purpose of documentation, so when looking at javadoc it immediately
- // obvious what methods Text has
-
- @Override
- int length();
-
- @Override
- char charAt(int index);
-
- @Override
- CharSequence subSequence(int start, int end);
-
- /**
- * Returns a string containing the characters in this sequence in the
- * same order as this sequence. The length of the string will be the
- * length of this sequence.
- *
- * @return a string consisting of exactly this sequence of characters
- */
- @Override
- // TODO: remove the explicit javadoc above when:
- // (JDK-8144034 has been resolved) AND (the comment is still identical
- // to CharSequence#toString)
- String toString();
-
- /**
- * Returns a read-only {@code ByteBuffer} containing the message encoded
- * in UTF-8.
- *
- * @return a read-only ByteBuffer
- */
- ByteBuffer asByteBuffer();
- }
}
--- a/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Thu Jun 09 19:07:27 2016 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -128,7 +128,7 @@
* of "MULTITHREADED", and also, the engine maintains independent values
* for symbols in scripts executing on different threads.
* <li><code>"STATELESS"</code> - The implementation satisfies the requirements of
- * <li><code>"THREAD-ISOLATED"</code>. In addition, script executions do not alter the
+ * <code>"THREAD-ISOLATED"</code>. In addition, script executions do not alter the
* mappings in the <code>Bindings</code> which is the engine scope of the
* <code>ScriptEngine</code>. In particular, the keys in the <code>Bindings</code>
* and their associated values are the same before and after the execution of the script.
--- a/jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/extra/EditingHistory.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.internal.le/share/classes/jdk/internal/jline/extra/EditingHistory.java Thu Jun 09 19:07:27 2016 +0000
@@ -54,7 +54,9 @@
(Runnable) () -> moveHistoryToSnippet(in, ((EditingHistory) in.getHistory())::previousSnippet));
bind(in, CTRL_DOWN,
(Runnable) () -> moveHistoryToSnippet(in, ((EditingHistory) in.getHistory())::nextSnippet));
- load(originalHistory);
+ if (originalHistory != null) {
+ load(originalHistory);
+ }
}
private void moveHistoryToSnippet(ConsoleReader in, Supplier<Boolean> action) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/JImageTask.java Thu Jun 09 19:07:27 2016 +0000
@@ -28,19 +28,16 @@
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.FileChannel;
+import java.nio.file.FileSystem;
import java.nio.file.Files;
-import static java.nio.file.StandardOpenOption.READ;
-import static java.nio.file.StandardOpenOption.WRITE;
+import java.nio.file.PathMatcher;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
+import java.util.MissingResourceException;
+import java.util.function.Predicate;
import jdk.internal.jimage.BasicImageReader;
import jdk.internal.jimage.ImageHeader;
-import static jdk.internal.jimage.ImageHeader.MAGIC;
-import static jdk.internal.jimage.ImageHeader.MAJOR_VERSION;
-import static jdk.internal.jimage.ImageHeader.MINOR_VERSION;
import jdk.internal.jimage.ImageLocation;
import jdk.tools.jlink.internal.ImageResourcesTree;
import jdk.tools.jlink.internal.TaskHelper;
@@ -48,53 +45,71 @@
import static jdk.tools.jlink.internal.TaskHelper.JIMAGE_BUNDLE;
import jdk.tools.jlink.internal.TaskHelper.Option;
import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
+import jdk.tools.jlink.internal.Utils;
class JImageTask {
-
- static final Option<?>[] recognizedOptions = {
- new Option<JImageTask>(true, (task, opt, arg) -> {
+ private static final Option<?>[] RECOGNIZED_OPTIONS = {
+ new Option<JImageTask>(true, (task, option, arg) -> {
task.options.directory = arg;
}, "--dir"),
- new Option<JImageTask>(false, (task, opt, arg) -> {
+
+ new Option<JImageTask>(true, (task, option, arg) -> {
+ task.options.filters = arg;
+ }, "--filter"),
+
+ new Option<JImageTask>(false, (task, option, arg) -> {
task.options.fullVersion = true;
}, true, "--fullversion"),
- new Option<JImageTask>(false, (task, opt, arg) -> {
+
+ new Option<JImageTask>(false, (task, option, arg) -> {
task.options.help = true;
}, "--help"),
- new Option<JImageTask>(true, (task, opt, arg) -> {
- task.options.flags = arg;
- }, "--flags"),
- new Option<JImageTask>(false, (task, opt, arg) -> {
+
+ new Option<JImageTask>(false, (task, option, arg) -> {
task.options.verbose = true;
}, "--verbose"),
- new Option<JImageTask>(false, (task, opt, arg) -> {
+
+ new Option<JImageTask>(false, (task, option, arg) -> {
task.options.version = true;
}, "--version")
};
- private static final TaskHelper taskHelper
+ private static final TaskHelper TASK_HELPER
= new TaskHelper(JIMAGE_BUNDLE);
- private static final OptionsHelper<JImageTask> optionsHelper
- = taskHelper.newOptionsHelper(JImageTask.class, recognizedOptions);
+ private static final OptionsHelper<JImageTask> OPTION_HELPER
+ = TASK_HELPER.newOptionsHelper(JImageTask.class, RECOGNIZED_OPTIONS);
+ private static final String PROGNAME = "jimage";
+ private static final FileSystem JRT_FILE_SYSTEM = Utils.jrtFileSystem();
+
+ private final OptionsValues options;
+ private final List<Predicate<String>> filterPredicates;
+ private PrintWriter log;
+
+ JImageTask() {
+ this.options = new OptionsValues();
+ this.filterPredicates = new ArrayList<>();
+ log = null;
+ }
+
+ void setLog(PrintWriter out) {
+ log = out;
+ TASK_HELPER.setLog(log);
+ }
static class OptionsValues {
Task task = Task.LIST;
String directory = ".";
+ String filters = "";
boolean fullVersion;
boolean help;
- String flags;
boolean verbose;
boolean version;
List<File> jimages = new LinkedList<>();
}
- private static final String PROGNAME = "jimage";
- private final OptionsValues options = new OptionsValues();
-
enum Task {
EXTRACT,
INFO,
LIST,
- SET,
VERIFY
};
@@ -145,50 +160,97 @@
int run(String[] args) {
if (log == null) {
- setLog(new PrintWriter(System.out));
+ setLog(new PrintWriter(System.out, true));
}
if (args.length == 0) {
- log.println(taskHelper.getMessage("main.usage.summary", PROGNAME));
+ log.println(TASK_HELPER.getMessage("main.usage.summary", PROGNAME));
return EXIT_ABNORMAL;
}
try {
- List<String> unhandled = optionsHelper.handleOptions(this, args);
+ List<String> unhandled = OPTION_HELPER.handleOptions(this, args);
+
if(!unhandled.isEmpty()) {
try {
options.task = Enum.valueOf(Task.class, unhandled.get(0).toUpperCase());
} catch (IllegalArgumentException ex) {
- throw taskHelper.newBadArgs("err.not.a.task", unhandled.get(0));
+ throw TASK_HELPER.newBadArgs("err.not.a.task", unhandled.get(0));
}
+
for(int i = 1; i < unhandled.size(); i++) {
options.jimages.add(new File(unhandled.get(i)));
}
- } else {
- throw taskHelper.newBadArgs("err.not.a.task", "<unspecified>");
+ } else if (!options.help && !options.version && !options.fullVersion) {
+ throw TASK_HELPER.newBadArgs("err.invalid.task", "<unspecified>");
}
+
if (options.help) {
- optionsHelper.showHelp(PROGNAME);
+ if (unhandled.isEmpty()) {
+ log.println(TASK_HELPER.getMessage("main.usage", PROGNAME));
+
+ for (Option<?> o : RECOGNIZED_OPTIONS) {
+ String name = o.aliases()[0];
+
+ if (name.startsWith("--")) {
+ name = name.substring(2);
+ } else if (name.startsWith("-")) {
+ name = name.substring(1);
+ }
+
+ log.println(TASK_HELPER.getMessage("main.opt." + name));
+ }
+ } else {
+ try {
+ log.println(TASK_HELPER.getMessage("main.usage." +
+ options.task.toString().toLowerCase()));
+ } catch (MissingResourceException ex) {
+ throw TASK_HELPER.newBadArgs("err.not.a.task", unhandled.get(0));
+ }
+ }
+ return EXIT_OK;
}
+
if (options.version || options.fullVersion) {
- taskHelper.showVersion(options.fullVersion);
+ TASK_HELPER.showVersion(options.fullVersion);
+
+ if (unhandled.isEmpty()) {
+ return EXIT_OK;
+ }
}
- boolean ok = run();
- return ok ? EXIT_OK : EXIT_ERROR;
+
+ processFilter(options.filters);
+
+ return run() ? EXIT_OK : EXIT_ERROR;
} catch (BadArgs e) {
- taskHelper.reportError(e.key, e.args);
+ TASK_HELPER.reportError(e.key, e.args);
+
if (e.showUsage) {
- log.println(taskHelper.getMessage("main.usage.summary", PROGNAME));
+ log.println(TASK_HELPER.getMessage("main.usage.summary", PROGNAME));
}
+
return EXIT_CMDERR;
} catch (Exception x) {
x.printStackTrace();
+
return EXIT_ABNORMAL;
} finally {
log.flush();
}
}
+ private void processFilter(String filters) {
+ if (filters.isEmpty()) {
+ return;
+ }
+
+ for (String filter : filters.split(",")) {
+ final PathMatcher matcher = Utils.getPathMatcher(JRT_FILE_SYSTEM, filter);
+ Predicate<String> predicate = (path) -> matcher.matches(JRT_FILE_SYSTEM.getPath(path));
+ filterPredicates.add(predicate);
+ }
+ }
+
private void listTitle(File file, BasicImageReader reader) {
log.println("jimage: " + file);
}
@@ -216,10 +278,12 @@
if (parent.exists()) {
if (!parent.isDirectory()) {
- throw taskHelper.newBadArgs("err.cannot.create.dir", parent.getAbsolutePath());
+ throw TASK_HELPER.newBadArgs("err.cannot.create.dir",
+ parent.getAbsolutePath());
}
} else if (!parent.mkdirs()) {
- throw taskHelper.newBadArgs("err.cannot.create.dir", parent.getAbsolutePath());
+ throw TASK_HELPER.newBadArgs("err.cannot.create.dir",
+ parent.getAbsolutePath());
}
if (!ImageResourcesTree.isTreeInfoResource(name)) {
@@ -261,7 +325,7 @@
log.println(" Major Version: " + header.getMajorVersion());
log.println(" Minor Version: " + header.getMinorVersion());
- log.println(" Flags: " + Integer.toHexString(header.getMinorVersion()));
+ log.println(" Flags: " + Integer.toHexString(header.getFlags()));
log.println(" Resource Count: " + header.getResourceCount());
log.println(" Table Length: " + header.getTableLength());
log.println(" Offsets Size: " + header.getOffsetsSize());
@@ -287,36 +351,7 @@
print(reader, name);
}
- void set(File file, BasicImageReader reader) throws BadArgs {
- try {
- ImageHeader oldHeader = reader.getHeader();
-
- int value = 0;
- try {
- value = Integer.valueOf(options.flags);
- } catch (NumberFormatException ex) {
- throw taskHelper.newBadArgs("err.flags.not.int", options.flags);
- }
-
- ImageHeader newHeader = new ImageHeader(MAGIC, MAJOR_VERSION, MINOR_VERSION,
- value,
- oldHeader.getResourceCount(), oldHeader.getTableLength(),
- oldHeader.getLocationsSize(), oldHeader.getStringsSize());
-
- ByteBuffer buffer = ByteBuffer.allocate(ImageHeader.getHeaderSize());
- buffer.order(ByteOrder.nativeOrder());
- newHeader.writeTo(buffer);
- buffer.rewind();
-
- try (FileChannel channel = FileChannel.open(file.toPath(), READ, WRITE)) {
- channel.write(buffer, 0);
- }
- } catch (IOException ex) {
- throw taskHelper.newBadArgs("err.cannot.update.file", file.getName());
- }
- }
-
- void verify(BasicImageReader reader, String name, ImageLocation location) {
+ void verify(BasicImageReader reader, String name, ImageLocation location) {
if (name.endsWith(".class")) {
byte[] bytes = reader.getResource(location);
@@ -335,12 +370,12 @@
ModuleAction moduleAction,
ResourceAction resourceAction) throws IOException, BadArgs {
if (options.jimages.isEmpty()) {
- throw taskHelper.newBadArgs("err.no.jimage");
+ throw TASK_HELPER.newBadArgs("err.no.jimage");
}
for (File file : options.jimages) {
if (!file.exists() || !file.isFile()) {
- throw taskHelper.newBadArgs("err.not.a.jimage", file.getName());
+ throw TASK_HELPER.newBadArgs("err.not.a.jimage", file.getName());
}
try (BasicImageReader reader = BasicImageReader.open(file.toPath())) {
@@ -353,6 +388,19 @@
String oldModule = "";
for (String name : entryNames) {
+ boolean match = filterPredicates.isEmpty();
+
+ for (Predicate<String> predicate : filterPredicates) {
+ if (predicate.test(name)) {
+ match = true;
+ break;
+ }
+ }
+
+ if (!match) {
+ continue;
+ }
+
if (!ImageResourcesTree.isTreeInfoResource(name)) {
if (moduleAction != null) {
int offset = name.indexOf('/', 1);
@@ -387,21 +435,13 @@
case LIST:
iterate(this::listTitle, this::listModule, this::list);
break;
- case SET:
- iterate(this::set, null, null);
- break;
case VERIFY:
iterate(this::listTitle, null, this::verify);
break;
default:
- throw taskHelper.newBadArgs("err.invalid.task", options.task.name()).showUsage(true);
+ throw TASK_HELPER.newBadArgs("err.invalid.task",
+ options.task.name()).showUsage(true);
}
return true;
}
-
- private PrintWriter log;
- void setLog(PrintWriter out) {
- log = out;
- taskHelper.setLog(log);
- }
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties Thu Jun 09 19:07:27 2016 +0000
@@ -24,54 +24,67 @@
#
main.usage.summary=\
-Usage: {0} <extract|info|list|set|verify> <options> jimage...\n\
-use --help for a list of possible options
+Usage: {0} <extract | info | list | verify> <options> jimage...\n\
+use --help for a list of possible options.
main.usage=\
-Usage: {0} <extract|info|list|set|verify> <options> jimage...\n\
+Usage: {0} <extract | info | list | verify> <options> jimage...\n\
+\n\
+\ extract - Extract all jimage entries and place in a directory specified\n\
+\ by the --dir=<directory> (default='.') option.\n\
\n\
-\ extract - Extract all jimage entries into separate files into the directory\n\
-\ specified by --dir=<directory> (default='.')\n\
-\ info - Prints information specified in the jimage header.\n\
+\ info - Prints detailed information contained in the jimage header.\n\
+\n\
\ list - Prints the names of all the entries in the jimage. When used with\n\
-\ --verbose will also print entry attributes ex. size and offset.\n\
-\ set - sets the value of specific jimage header entries\n\
-\ verify - Reports errors on any .class entries that don't verify as classes.\n\
+\ --verbose, list will also print entry size and offset attributes.\n\
+\n\
+\ verify - Reports on any .class entries that don't verify as classes.\n\
\n\
Possible options include:
+main.usage.extract=\
+\ extract - Extract all jimage entries and place in a directory specified\n\
+\ by the --dir=<directory> (default='.') option.
+
+main.usage.info=\
+\ info - Prints detailed information contained in the jimage header.
+
+main.usage.list=\
+\ list - Prints the names of all the entries in the jimage. When used with\n\
+\ --verbose, list will also print entry size and offset attributes.
+
+main.usage.verify=\
+\ verify - Reports errors on any .class entries that don't verify as classes.
+
error.prefix=Error:
warn.prefix=Warning:
main.opt.dir=\
-\ --dir Target directory for extract
+\ --dir Target directory for extract directive
-main.opt.flags=\
-\ --flags=value Set the jimage flags to value
+main.opt.filter=\
+\ --filter Filter entries for list or extract\n\
+\ Ex. /java.base/*, */module-info.class
+
+main.opt.fullversion=\
+\ --fullversion Print full version information
main.opt.help=\
-\ --help Print this usage message
+\ --help Print usage message
main.opt.verbose=\
-\ --verbose Verbose listing
+\ --verbose Listing prints entry size and offset attributes
main.opt.version=\
-\ --version Version information
+\ --version Print version information
main.command.files=\
-\ @<filename> Read options from file
-err.cannot.read.file=cannot read file: {0}
-err.cannot.update.file=cannot update file: {0}
-err.file.not.found=cannot find file: {0}
-err.file.error=cannot access file: {0}
-err.flags.not.int=--flags value not integer: {0}
-err.internal.error=internal error: {0} {1} {2}
-err.invalid.arg.for.option=invalid argument for option: {0}
-err.invalid.task=task must be extract|info|list|verify: {0}
+\ @<filename> Read options from file
+
+err.not.a.task=task must be one of <extract | info | list | verify>: {0}
err.missing.arg=no value given for {0}
err.not.a.dir=not a directory: {0}
err.not.a.jimage=not a jimage file: {0}
err.no.jimage=no jimage provided
-err.not.a.task=not a valid task: {0}
err.option.unsupported={0} not supported: {1}
err.unknown.option=unknown option: {0}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Thu Jun 09 19:07:27 2016 +0000
@@ -186,7 +186,7 @@
int run(String[] args) {
if (log == null) {
- setLog(new PrintWriter(System.err));
+ setLog(new PrintWriter(System.err, true));
}
try {
optionsHelper.handleOptions(this, args);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Thu Jun 09 19:07:27 2016 +0000
@@ -136,6 +136,10 @@
void process(T task, String opt, String arg) throws BadArgs {
processing.process(task, opt, arg);
}
+
+ public String[] aliases() {
+ return aliases;
+ }
}
private static class PlugOption extends Option<PluginsOptions> {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java Thu Jun 09 19:07:27 2016 +0000
@@ -25,6 +25,10 @@
package jdk.tools.jlink.internal;
import java.lang.reflect.Module;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.PathMatcher;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@@ -155,4 +159,20 @@
public static boolean isBuiltin(Plugin prov) {
return THIS_MODULE.equals(prov.getClass().getModule());
}
+
+ public static FileSystem jrtFileSystem() {
+ return FileSystems.getFileSystem(URI.create("jrt:/"));
+ }
+
+ public static PathMatcher getPathMatcher(FileSystem fs, String pattern) {
+ if (!pattern.startsWith("glob:") && !pattern.startsWith("regex:")) {
+ pattern = "glob:" + pattern;
+ }
+
+ return fs.getPathMatcher(pattern);
+ }
+
+ public static PathMatcher getPathMatcher(String pattern) {
+ return getPathMatcher(jrtFileSystem(), pattern);
+ }
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java Thu Jun 09 19:07:27 2016 +0000
@@ -26,7 +26,9 @@
import java.io.File;
import java.io.IOException;
+import java.nio.file.FileSystem;
import java.nio.file.Files;
+import java.nio.file.PathMatcher;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -47,6 +49,8 @@
*/
public final class OrderResourcesPlugin implements TransformerPlugin {
public static final String NAME = "order-resources";
+ private static final FileSystem JRT_FILE_SYSTEM = Utils.jrtFileSystem();
+
private final List<ToIntFunction<String>> filters;
private final Map<String, Integer> orderedPaths;
@@ -187,27 +191,11 @@
}
}
} else {
- boolean endsWith = pattern.startsWith("*");
- boolean startsWith = pattern.endsWith("*");
- ToIntFunction<String> function;
final int result = ordinal++;
-
- if (startsWith && endsWith) {
- final String string = pattern.substring(1, pattern.length() - 1);
- function = (path)-> path.contains(string) ? result : Integer.MAX_VALUE;
- } else if (startsWith) {
- final String string = pattern.substring(0, pattern.length() - 1);
- function = (path)-> path.startsWith(string) ? result : Integer.MAX_VALUE;
- } else if (endsWith) {
- final String string = pattern.substring(1);
- function = (path)-> path.endsWith(string) ? result : Integer.MAX_VALUE;
- } else {
- final String string = pattern;
- function = (path)-> path.equals(string) ? result : Integer.MAX_VALUE;
- }
-
+ final PathMatcher matcher = Utils.getPathMatcher(JRT_FILE_SYSTEM, pattern);
+ ToIntFunction<String> function = (path)-> matcher.matches(JRT_FILE_SYSTEM.getPath(path)) ? result : Integer.MAX_VALUE;
filters.add(function);
- }
+ }
}
}
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ResourceFilter.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ResourceFilter.java Thu Jun 09 19:07:27 2016 +0000
@@ -24,113 +24,71 @@
*/
package jdk.tools.jlink.internal.plugins;
-import java.io.BufferedReader;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
-import java.io.InputStreamReader;
-import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.PathMatcher;
+import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
+import jdk.tools.jlink.internal.Utils;
+import jdk.tools.jlink.plugin.PluginException;
/**
*
- * Filter in or out a resource
+ * Filter resource resources using path matcher.
*/
public class ResourceFilter implements Predicate<String> {
+ private static final FileSystem JRT_FILE_SYSTEM = Utils.jrtFileSystem();
- private final Pattern inPatterns;
- private final Pattern outPatterns;
-
- static final String NEG = "^";
+ final boolean negate;
+ final List<PathMatcher> matchers;
public ResourceFilter(String[] patterns) throws IOException {
this(patterns, false);
}
- public ResourceFilter(String[] patterns, boolean negateAll) throws IOException {
+ public ResourceFilter(String[] patterns, boolean negate) throws IOException {
+ this.negate = negate;
+ this.matchers = new ArrayList<>();
+
+ for (String pattern : patterns) {
+ if (pattern.startsWith("@")) {
+ File file = new File(pattern.substring(1));
+
+ if (file.exists()) {
+ List<String> lines;
+
+ try {
+ lines = Files.readAllLines(file.toPath());
+ } catch (IOException ex) {
+ throw new PluginException(ex);
+ }
- // Get the patterns from a file
- if (patterns != null && patterns.length == 1) {
- String filePath = patterns[0];
- File f = new File(filePath);
- if (f.exists()) {
- List<String> pats;
- try (FileInputStream fis = new FileInputStream(f);
- InputStreamReader ins = new InputStreamReader(fis,
- StandardCharsets.UTF_8);
- BufferedReader reader = new BufferedReader(ins)) {
- pats = reader.lines().collect(Collectors.toList());
+ for (String line : lines) {
+ PathMatcher matcher = Utils.getPathMatcher(JRT_FILE_SYSTEM, line);
+ matchers.add(matcher);
+ }
}
- patterns = new String[pats.size()];
- pats.toArray(patterns);
+ } else {
+ PathMatcher matcher = Utils.getPathMatcher(JRT_FILE_SYSTEM, pattern);
+ matchers.add(matcher);
+ }
+ }
+ }
+
+ @Override
+ public boolean test(String name) {
+ Path path = JRT_FILE_SYSTEM.getPath(name);
+
+ for (PathMatcher matcher : matchers) {
+ if (matcher.matches(path)) {
+ return !negate;
}
}
- if (patterns != null && negateAll) {
- String[] excluded = new String[patterns.length];
- for (int i = 0; i < patterns.length; i++) {
- excluded[i] = ResourceFilter.NEG + patterns[i];
- }
- patterns = excluded;
- }
-
- StringBuilder inPatternsBuilder = new StringBuilder();
- StringBuilder outPatternsBuilder = new StringBuilder();
- if (patterns != null) {
- for (int i = 0; i < patterns.length; i++) {
- String p = patterns[i];
- p = p.replaceAll(" ", "");
- StringBuilder builder = p.startsWith(NEG)
- ? outPatternsBuilder : inPatternsBuilder;
- String pat = p.startsWith(NEG) ? p.substring(NEG.length()) : p;
- builder.append(escape(pat));
- if (i < patterns.length - 1) {
- builder.append("|");
- }
- }
- }
- this.inPatterns = inPatternsBuilder.length() == 0 ? null
- : Pattern.compile(inPatternsBuilder.toString());
- this.outPatterns = outPatternsBuilder.length() == 0 ? null
- : Pattern.compile(outPatternsBuilder.toString());
- }
-
- public static String escape(String s) {
- s = s.replaceAll(" ", "");
- s = s.replaceAll("\\$", Matcher.quoteReplacement("\\$"));
- s = s.replaceAll("\\.", Matcher.quoteReplacement("\\."));
- s = s.replaceAll("\\*", ".+");
- return s;
- }
-
- private boolean accept(String path) {
- if (outPatterns != null) {
- Matcher mout = outPatterns.matcher(path);
- if (mout.matches()) {
- //System.out.println("Excluding file " + resource.getPath());
- return false;
- }
- }
- boolean accepted = false;
- // If the inPatterns is null, means that all resources are accepted.
- if (inPatterns == null) {
- accepted = true;
- } else {
- Matcher m = inPatterns.matcher(path);
- if (m.matches()) {
- //System.out.println("Including file " + resource.getPath());
- accepted = true;
- }
- }
- return accepted;
- }
-
- @Override
- public boolean test(String path) {
- return accept(path);
+ return negate;
}
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Thu Jun 09 19:07:27 2016 +0000
@@ -1072,6 +1072,10 @@
@Override
public Pattern convert(String value) {
try {
+ if (value.startsWith("regex:")) {
+ value = value.substring("regex:".length()).trim();
+ }
+
return Pattern.compile(value);
} catch (PatternSyntaxException e) {
throw new CommandException("err.bad.pattern", value);
@@ -1083,10 +1087,15 @@
@Override public String valuePattern() { return "pattern"; }
}
- static class GlobConverter implements ValueConverter<PathMatcher> {
+ static class PathMatcherConverter implements ValueConverter<PathMatcher> {
@Override
public PathMatcher convert(String pattern) {
try {
+ if (!pattern.startsWith("glob:") &&
+ !pattern.startsWith("regex:")) {
+ pattern = "glob:" + pattern;
+ }
+
return FileSystems.getDefault()
.getPathMatcher("glob:" + pattern);
} catch (PatternSyntaxException e) {
@@ -1194,7 +1203,7 @@
OptionSpec<PathMatcher> excludes
= parser.accepts("exclude", getMessage("main.opt.exclude"))
.withRequiredArg()
- .withValuesConvertedBy(new GlobConverter());
+ .withValuesConvertedBy(new PathMatcherConverter());
OptionSpec<Pattern> hashModules
= parser.accepts("hash-modules", getMessage("main.opt.hash-modules"))
--- a/jdk/test/ProblemList.txt Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/test/ProblemList.txt Thu Jun 09 19:07:27 2016 +0000
@@ -167,6 +167,8 @@
java/net/DatagramSocket/SendDatagramToBadAddress.java 7143960 macosx-all
+sun/net/www/http/ChunkedOutputStream/checkError.java 8041924 linux-all
+
############################################################################
# jdk_nio
@@ -199,6 +201,8 @@
sun/rmi/rmic/newrmic/equivalence/run.sh 8145980 generic-all
+java/rmi/transport/dgcDeadLock/DGCDeadLock.java 8029360 macosx-all
+
############################################################################
# jdk_security
--- a/jdk/test/com/sun/crypto/provider/Cipher/TestCipher.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/test/com/sun/crypto/provider/Cipher/TestCipher.java Thu Jun 09 19:07:27 2016 +0000
@@ -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
@@ -150,11 +150,6 @@
}
// Encryption
- int PAD_LEN = 0;
- if (pad.equalsIgnoreCase("PKCS5Padding")) {
- // Need to consider pad bytes
- PAD_LEN = 8;
- }
byte[] plainText = INPUT_TEXT.clone();
@@ -162,12 +157,13 @@
byte[] cipherText = ci.doFinal(INPUT_TEXT, ENC_OFFSET, TEXT_LEN);
// Generate cipher and save to same buffer
- int offset = ci.update(
+ int enc_bytes = ci.update(
INPUT_TEXT, ENC_OFFSET, TEXT_LEN, INPUT_TEXT, STORAGE_OFFSET);
- ci.doFinal(INPUT_TEXT, offset + STORAGE_OFFSET);
+ enc_bytes += ci.doFinal(INPUT_TEXT, enc_bytes + STORAGE_OFFSET);
if (!equalsBlock(
- INPUT_TEXT, STORAGE_OFFSET, cipherText, 0, cipherText.length)) {
+ INPUT_TEXT, STORAGE_OFFSET, enc_bytes,
+ cipherText, 0, cipherText.length)) {
throw new RuntimeException(
"Different ciphers generated with same buffer");
}
@@ -183,8 +179,8 @@
byte[] recoveredText = ci.doFinal(cipherText, 0, cipherText.length);
if (!equalsBlock(
- plainText, ENC_OFFSET, recoveredText, 0,
- recoveredText.length)) {
+ plainText, ENC_OFFSET, TEXT_LEN,
+ recoveredText, 0, recoveredText.length)) {
throw new RuntimeException(
"Recovered text not same as plain text");
} else {
@@ -192,13 +188,13 @@
}
// Recover text from cipher and save to same buffer
- ci.update(INPUT_TEXT, STORAGE_OFFSET, TEXT_LEN + PAD_LEN, INPUT_TEXT,
- ENC_OFFSET);
- ci.doFinal(INPUT_TEXT, ENC_OFFSET);
+ int dec_bytes = ci.update(
+ INPUT_TEXT, STORAGE_OFFSET, enc_bytes, INPUT_TEXT, ENC_OFFSET);
+ dec_bytes += ci.doFinal(INPUT_TEXT, dec_bytes + ENC_OFFSET);
if (!equalsBlock(
- plainText, ENC_OFFSET, recoveredText, 0,
- recoveredText.length)) {
+ plainText, ENC_OFFSET, TEXT_LEN,
+ INPUT_TEXT, ENC_OFFSET, dec_bytes)) {
throw new RuntimeException(
"Recovered text not same as plain text with same buffer");
} else {
@@ -208,9 +204,12 @@
out.println("Test Passed.");
}
- private static boolean equalsBlock(byte[] b1, int off1, byte[] b2, int off2,
- int len) {
- for (int i = off1, j = off2, k = 0; k < len; i++, j++, k++) {
+ private static boolean equalsBlock(byte[] b1, int off1, int len1,
+ byte[] b2, int off2, int len2) {
+ if (len1 != len2) {
+ return false;
+ }
+ for (int i = off1, j = off2, k = 0; k < len1; i++, j++, k++) {
if (b1[i] != b2[j]) {
return false;
}
--- a/jdk/test/java/lang/String/concat/WithSecurityManager.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/test/java/lang/String/concat/WithSecurityManager.java Thu Jun 09 19:07:27 2016 +0000
@@ -26,7 +26,7 @@
/**
* @test
* @summary String concatenation fails with a custom SecurityManager that uses concatenation
- * @bug 8155090
+ * @bug 8155090 8158851
*
* @compile WithSecurityManager.java
*
@@ -37,17 +37,43 @@
* @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT WithSecurityManager
* @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT WithSecurityManager
* @run main/othervm -Xverify:all -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT WithSecurityManager
+ *
+ * @run main/othervm -Xverify:all -limitmods java.base WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=BC_SB WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=BC_SB_SIZED WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=MH_SB_SIZED WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT WithSecurityManager
+ * @run main/othervm -Xverify:all -limitmods java.base -Djava.lang.invoke.stringConcat=MH_INLINE_SIZED_EXACT WithSecurityManager
*/
public class WithSecurityManager {
public static void main(String[] args) throws Throwable {
- SecurityManager sm = new SecurityManager() {
- @Override
- public void checkPermission(Permission perm) {
- String abc = "abc";
- String full = abc + "def";
- }
- };
- System.setSecurityManager(sm);
- ClassLoader cl = new ClassLoader() {};
+ // First time should succeed to bootstrap everything
+ {
+ SecurityManager sm = new SecurityManager() {
+ @Override
+ public void checkPermission(Permission perm) {
+ String abc = "abc";
+ String full = abc + "def";
+ }
+ };
+ System.setSecurityManager(sm);
+ ClassLoader cl = new ClassLoader() {
+ };
+ }
+
+ // Second time should succeed to run after bootstrapping
+ {
+ SecurityManager sm = new SecurityManager() {
+ @Override
+ public void checkPermission(Permission perm) {
+ String abc = "abc";
+ String full = abc + "def";
+ }
+ };
+ System.setSecurityManager(sm);
+ ClassLoader cl = new ClassLoader() {
+ };
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/annotation/AnnotationWithLambda.java Thu Jun 09 19:07:27 2016 +0000
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8147585
+ * @summary Check Annotation with Lambda, with or without parameter
+ * @run testng AnnotationWithLambda
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Method;
+import java.util.function.Consumer;
+
+import org.testng.annotations.*;
+import static org.testng.Assert.*;
+
+public class AnnotationWithLambda {
+
+ @Test
+ void testAnnotationWithLambda() {
+ Method[] methods = AnnotationWithLambda.MethodsWithAnnotations.class.getDeclaredMethods();
+ for (Method method : methods) {
+ assertTrue((method.isAnnotationPresent(LambdaWithParameter.class)) &&
+ (method.isAnnotationPresent(LambdaWithoutParameter.class)));
+
+ }
+ }
+
+ static class MethodsWithAnnotations {
+
+ @LambdaWithParameter
+ @LambdaWithoutParameter
+ public void testAnnotationLambda() {
+ }
+ }
+}
+
+@Target(value = ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@interface LambdaWithParameter {
+ Consumer<Integer> f1 = a -> {
+ System.out.println("lambda has parameter");
+ };
+}
+
+@Target(value = ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@interface LambdaWithoutParameter {
+ Runnable r = () -> System.out.println("lambda without parameter");
+}
+
--- a/jdk/test/java/net/httpclient/BasicWebSocketAPITest.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/test/java/net/httpclient/BasicWebSocketAPITest.java Thu Jun 09 19:07:27 2016 +0000
@@ -30,6 +30,7 @@
import java.net.http.WebSocket;
import java.net.http.WebSocket.CloseCode;
import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
import java.nio.channels.SocketChannel;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
@@ -92,12 +93,24 @@
);
checkAndClose(
(ws) ->
+ TestKit.assertThrows(IllegalArgumentException.class,
+ ".*message.*",
+ () -> ws.sendPing(ByteBuffer.allocate(126)))
+ );
+ checkAndClose(
+ (ws) ->
TestKit.assertThrows(NullPointerException.class,
"message",
() -> ws.sendPing(null))
);
checkAndClose(
(ws) ->
+ TestKit.assertThrows(IllegalArgumentException.class,
+ ".*message.*",
+ () -> ws.sendPong(ByteBuffer.allocate(126)))
+ );
+ checkAndClose(
+ (ws) ->
TestKit.assertThrows(NullPointerException.class,
"message",
() -> ws.sendPong(null))
@@ -106,7 +119,7 @@
(ws) ->
TestKit.assertThrows(NullPointerException.class,
"message",
- () -> ws.sendText((CharSequence) null, true))
+ () -> ws.sendText(null, true))
);
checkAndClose(
(ws) ->
@@ -122,6 +135,12 @@
);
checkAndClose(
(ws) ->
+ TestKit.assertThrows(IllegalArgumentException.class,
+ "(?i).*reason.*",
+ () -> ws.sendClose(CloseCode.NORMAL_CLOSURE, CharBuffer.allocate(124)))
+ );
+ checkAndClose(
+ (ws) ->
TestKit.assertThrows(NullPointerException.class,
"code",
() -> ws.sendClose(null, ""))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/net/ssl/ALPN/SSLServerSocketAlpnTest.java Thu Jun 09 19:07:27 2016 +0000
@@ -0,0 +1,494 @@
+/*
+ * 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
+ * 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.
+ */
+
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
+/*
+ * @test
+ * @bug 8051498 8145849 8158978
+ * @summary JEP 244: TLS Application-Layer Protocol Negotiation Extension
+ * @compile MyX509ExtendedKeyManager.java
+ * @run main/othervm SSLServerSocketAlpnTest h2 h2 h2
+ * @run main/othervm SSLServerSocketAlpnTest h2 h2,http/1.1 h2
+ * @run main/othervm SSLServerSocketAlpnTest h2,http/1.1 h2,http/1.1 h2
+ * @run main/othervm SSLServerSocketAlpnTest http/1.1,h2 h2,http/1.1 http/1.1
+ * @run main/othervm SSLServerSocketAlpnTest h4,h3,h2 h1,h2 h2
+ * @run main/othervm SSLServerSocketAlpnTest EMPTY h2,http/1.1 NONE
+ * @run main/othervm SSLServerSocketAlpnTest h2 EMPTY NONE
+ * @run main/othervm SSLServerSocketAlpnTest H2 h2 ERROR
+ * @run main/othervm SSLServerSocketAlpnTest h2 http/1.1 ERROR
+ * @author Brad Wetmore
+ */
+import java.io.*;
+import java.security.KeyStore;
+
+import javax.net.ssl.*;
+
+public class SSLServerSocketAlpnTest {
+
+ /*
+ * =============================================================
+ * Set the various variables needed for the tests, then
+ * specify what tests to run on each side.
+ */
+
+ /*
+ * Should we run the client or server in a separate thread?
+ * Both sides can throw exceptions, but do you have a preference
+ * as to which side should be the main thread.
+ */
+ static boolean separateServerThread = false;
+
+ /*
+ * Where do we find the keystores?
+ */
+ static String pathToStores = "../etc";
+ static String keyStoreFile = "keystore";
+ static String trustStoreFile = "truststore";
+ static String passwd = "passphrase";
+
+ static String keyFilename = System.getProperty("test.src", ".") + "/"
+ + pathToStores + "/" + keyStoreFile;
+ static String trustFilename = System.getProperty("test.src", ".") + "/"
+ + pathToStores + "/" + trustStoreFile;
+
+ /*
+ * SSLContext
+ */
+ SSLContext mySSLContext = null;
+
+ /*
+ * Is the server ready to serve?
+ */
+ volatile static boolean serverReady = false;
+
+ /*
+ * Turn on SSL debugging?
+ */
+ static boolean debug = false;
+
+ static String[] serverAPs;
+ static String[] clientAPs;
+ static String expectedAP;
+
+ /*
+ * If the client or server is doing some kind of object creation
+ * that the other side depends on, and that thread prematurely
+ * exits, you may experience a hang. The test harness will
+ * terminate all hung threads after its timeout has expired,
+ * currently 3 minutes by default, but you might try to be
+ * smart about it....
+ */
+
+ /*
+ * Define the server side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doServerSide() throws Exception {
+ SSLServerSocketFactory sslssf = mySSLContext.getServerSocketFactory();
+ SSLServerSocket sslServerSocket
+ = (SSLServerSocket) sslssf.createServerSocket(serverPort);
+ sslServerSocket.setNeedClientAuth(true);
+
+ SSLParameters sslp = sslServerSocket.getSSLParameters();
+
+ // for both client/server to call into X509KM
+ sslp.setNeedClientAuth(true);
+
+ /*
+ * The default ciphersuite ordering from the SSLContext may not
+ * reflect "h2" ciphersuites as being preferred, additionally the
+ * client may not send them in an appropriate order. We could resort
+ * the suite list if so desired.
+ */
+ String[] suites = sslp.getCipherSuites();
+ sslp.setCipherSuites(suites);
+ sslp.setUseCipherSuitesOrder(true); // Set server side order
+
+ // Set the ALPN selection.
+ sslp.setApplicationProtocols(serverAPs);
+ sslServerSocket.setSSLParameters(sslp);
+
+ serverPort = sslServerSocket.getLocalPort();
+
+ /*
+ * Signal Client, we're ready for his connect.
+ */
+ serverReady = true;
+
+ SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
+
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null before the handshake starts");
+ }
+
+ sslSocket.startHandshake();
+
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null after the handshake is completed");
+ }
+
+ String ap = sslSocket.getApplicationProtocol();
+ System.out.println("Application Protocol: \"" + ap + "\"");
+
+ if (ap == null) {
+ throw new Exception(
+ "Handshake was completed but null was received");
+ }
+ if (expectedAP.equals("NONE")) {
+ if (!ap.isEmpty()) {
+ throw new Exception("Expected no ALPN value");
+ } else {
+ System.out.println("No ALPN value negotiated, as expected");
+ }
+ } else if (!expectedAP.equals(ap)) {
+ throw new Exception(expectedAP
+ + " ALPN value not available on negotiated connection");
+ }
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslIS.read();
+ sslOS.write(85);
+ sslOS.flush();
+
+ sslSocket.close();
+ }
+
+ /*
+ * Define the client side of the test.
+ *
+ * If the server prematurely exits, serverReady will be set to true
+ * to avoid infinite hangs.
+ */
+ void doClientSide() throws Exception {
+
+ /*
+ * Wait for server to get started.
+ */
+ while (!serverReady) {
+ Thread.sleep(50);
+ }
+
+ SSLSocketFactory sslsf = mySSLContext.getSocketFactory();
+ SSLSocket sslSocket
+ = (SSLSocket) sslsf.createSocket("localhost", serverPort);
+
+ SSLParameters sslp = sslSocket.getSSLParameters();
+
+ /*
+ * The default ciphersuite ordering from the SSLContext may not
+ * reflect "h2" ciphersuites as being preferred, additionally the
+ * client may not send them in an appropriate order. We could resort
+ * the suite list if so desired.
+ */
+ String[] suites = sslp.getCipherSuites();
+ sslp.setCipherSuites(suites);
+ sslp.setUseCipherSuitesOrder(true); // Set server side order
+
+ // Set the ALPN selection.
+ sslp.setApplicationProtocols(clientAPs);
+ sslSocket.setSSLParameters(sslp);
+
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null before the handshake starts");
+ }
+
+ sslSocket.startHandshake();
+
+ if (sslSocket.getHandshakeApplicationProtocol() != null) {
+ throw new Exception ("getHandshakeApplicationProtocol() should "
+ + "return null after the handshake is completed");
+ }
+
+ /*
+ * Check that the resulting connection meets our defined ALPN
+ * criteria. If we were connecting to a non-JSSE implementation,
+ * the server might have negotiated something we shouldn't accept.
+ */
+ String ap = sslSocket.getApplicationProtocol();
+ System.out.println("Application Protocol: \"" + ap + "\"");
+
+ if (ap == null) {
+ throw new Exception(
+ "Handshake was completed but null was received");
+ }
+ if (expectedAP.equals("NONE")) {
+ if (!ap.isEmpty()) {
+ throw new Exception("Expected no ALPN value");
+ } else {
+ System.out.println("No ALPN value negotiated, as expected");
+ }
+ } else if (!expectedAP.equals(ap)) {
+ throw new Exception(expectedAP
+ + " ALPN value not available on negotiated connection");
+ }
+
+ InputStream sslIS = sslSocket.getInputStream();
+ OutputStream sslOS = sslSocket.getOutputStream();
+
+ sslOS.write(280);
+ sslOS.flush();
+ sslIS.read();
+
+ sslSocket.close();
+ }
+
+ /*
+ * =============================================================
+ * The remainder is just support stuff
+ */
+ // use any free port by default
+ volatile int serverPort = 0;
+
+ volatile Exception serverException = null;
+ volatile Exception clientException = null;
+
+ public static void main(String[] args) throws Exception {
+
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+
+ // Validate parameters
+ if (args.length != 3) {
+ throw new Exception("Invalid number of test parameters");
+ }
+ serverAPs = convert(args[0]);
+ clientAPs = convert(args[1]);
+ expectedAP = args[2];
+
+ /*
+ * Start the tests.
+ */
+ try {
+ new SSLServerSocketAlpnTest();
+ } catch (SSLHandshakeException she) {
+ if (args[2].equals("ERROR")) {
+ System.out.println("Caught the expected exception: " + she);
+ } else {
+ throw she;
+ }
+ }
+
+ System.out.println("Test Passed.");
+ }
+
+ SSLContext getSSLContext(String keyFilename, String trustFilename)
+ throws Exception {
+ SSLContext ctx = SSLContext.getInstance("TLS");
+
+ // Keystores
+ KeyStore keyKS = KeyStore.getInstance("JKS");
+ keyKS.load(new FileInputStream(keyFilename), passwd.toCharArray());
+
+ KeyStore trustKS = KeyStore.getInstance("JKS");
+ trustKS.load(new FileInputStream(trustFilename), passwd.toCharArray());
+
+ // Generate KeyManager and TrustManager
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(keyKS, passwd.toCharArray());
+
+ KeyManager[] kms = kmf.getKeyManagers();
+ if (!(kms[0] instanceof X509ExtendedKeyManager)) {
+ throw new Exception("kms[0] not X509ExtendedKeyManager");
+ }
+
+ kms = new KeyManager[] { new MyX509ExtendedKeyManager(
+ (X509ExtendedKeyManager) kms[0], expectedAP) };
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(trustKS);
+ TrustManager[] tms = tmf.getTrustManagers();
+
+ // initial SSLContext
+ ctx.init(kms, tms, null);
+
+ return ctx;
+ }
+
+ /*
+ * Convert a comma-separated list into an array of strings.
+ */
+ private static String[] convert(String list) {
+ String[] strings;
+
+ if (list.equals("EMPTY")) {
+ return new String[0];
+ }
+
+ if (list.indexOf(',') > 0) {
+ strings = list.split(",");
+ } else {
+ strings = new String[]{ list };
+ }
+
+ return strings;
+ }
+
+ Thread clientThread = null;
+ Thread serverThread = null;
+
+ /*
+ * Primary constructor, used to drive remainder of the test.
+ *
+ * Fork off the other side, then do your work.
+ */
+ SSLServerSocketAlpnTest() throws Exception {
+ Exception startException = null;
+ mySSLContext = getSSLContext(keyFilename, trustFilename);
+ try {
+ if (separateServerThread) {
+ startServer(true);
+ startClient(false);
+ } else {
+ startClient(true);
+ startServer(false);
+ }
+ } catch (Exception e) {
+ startException = e;
+ }
+
+ /*
+ * Wait for other side to close down.
+ */
+ if (separateServerThread) {
+ if (serverThread != null) {
+ serverThread.join();
+ }
+ } else {
+ if (clientThread != null) {
+ clientThread.join();
+ }
+ }
+
+ /*
+ * When we get here, the test is pretty much over.
+ * Which side threw the error?
+ */
+ Exception local;
+ Exception remote;
+
+ if (separateServerThread) {
+ remote = serverException;
+ local = clientException;
+ } else {
+ remote = clientException;
+ local = serverException;
+ }
+
+ Exception exception = null;
+
+ /*
+ * Check various exception conditions.
+ */
+ if ((local != null) && (remote != null)) {
+ // If both failed, return the curthread's exception.
+ local.initCause(remote);
+ exception = local;
+ } else if (local != null) {
+ exception = local;
+ } else if (remote != null) {
+ exception = remote;
+ } else if (startException != null) {
+ exception = startException;
+ }
+
+ /*
+ * If there was an exception *AND* a startException,
+ * output it.
+ */
+ if (exception != null) {
+ if (exception != startException && startException != null) {
+ exception.addSuppressed(startException);
+ }
+ throw exception;
+ }
+
+ // Fall-through: no exception to throw!
+ }
+
+ void startServer(boolean newThread) throws Exception {
+ if (newThread) {
+ serverThread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ /*
+ * Our server thread just died.
+ *
+ * Release the client, if not active already...
+ */
+ System.err.println("Server died...");
+ serverReady = true;
+ serverException = e;
+ }
+ }
+ };
+ serverThread.start();
+ } else {
+ try {
+ doServerSide();
+ } catch (Exception e) {
+ serverException = e;
+ } finally {
+ serverReady = true;
+ }
+ }
+ }
+
+ void startClient(boolean newThread) throws Exception {
+ if (newThread) {
+ clientThread = new Thread() {
+ @Override
+ public void run() {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ /*
+ * Our client thread just died.
+ */
+ System.err.println("Client died...");
+ clientException = e;
+ }
+ }
+ };
+ clientThread.start();
+ } else {
+ try {
+ doClientSide();
+ } catch (Exception e) {
+ clientException = e;
+ }
+ }
+ }
+}
--- a/jdk/test/sun/security/provider/DSA/SupportedDSAParamGen.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/test/sun/security/provider/DSA/SupportedDSAParamGen.java Thu Jun 09 19:07:27 2016 +0000
@@ -28,7 +28,7 @@
* @run main/timeout=300 SupportedDSAParamGen 1024 160
* @run main/timeout=300 SupportedDSAParamGen 2048 224
* @run main/timeout=300 SupportedDSAParamGen 2048 256
- * @run main/timeout=450 SupportedDSAParamGen 3072 256
+ * @run main/timeout=700 SupportedDSAParamGen 3072 256
*/
import java.security.*;
import java.security.spec.*;
--- a/jdk/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java Thu Jun 09 17:28:37 2016 +0000
+++ b/jdk/test/sun/security/provider/NSASuiteB/TestDSAGenParameterSpec.java Thu Jun 09 19:07:27 2016 +0000
@@ -31,9 +31,6 @@
import java.security.spec.DSAGenParameterSpec;
import java.security.spec.DSAParameterSpec;
import java.security.spec.InvalidParameterSpecException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.stream.Collectors;
/*
* @test
@@ -43,8 +40,15 @@
* DSA within some certain range of key sizes as described in the class
* specification (L, N) as (1024, 160), (2048, 224), (2048, 256) and
* (3072, 256) should be OK for DSAGenParameterSpec.
- * @run main TestDSAGenParameterSpec 2048,256,true 2048,224,true 1024,160,true 4096,256 3072,224 2048,160 1024,224 512,160
- * @run main TestDSAGenParameterSpec 3072,256,true
+ * @run main TestDSAGenParameterSpec 512 160
+ * @run main TestDSAGenParameterSpec 1024 160 true
+ * @run main TestDSAGenParameterSpec 1024 224
+ * @run main TestDSAGenParameterSpec 2048 160
+ * @run main/timeout=300 TestDSAGenParameterSpec 2048 224 true
+ * @run main/timeout=300 TestDSAGenParameterSpec 2048 256 true
+ * @run main TestDSAGenParameterSpec 3072 224
+ * @run main/timeout=700 TestDSAGenParameterSpec 3072 256 true
+ * @run main TestDSAGenParameterSpec 4096 256
*/
public class TestDSAGenParameterSpec {
@@ -57,8 +61,8 @@
System.out.printf("Test case: primePLen=%d, " + "subprimeQLen=%d%n",
dataTuple.primePLen, dataTuple.subprimeQLen);
- AlgorithmParameterGenerator apg =
- AlgorithmParameterGenerator.getInstance(ALGORITHM_NAME,
+ AlgorithmParameterGenerator apg
+ = AlgorithmParameterGenerator.getInstance(ALGORITHM_NAME,
PROVIDER_NAME);
DSAGenParameterSpec genParamSpec = createGenParameterSpec(dataTuple);
@@ -80,8 +84,8 @@
private static void checkParam(AlgorithmParameters param,
DSAGenParameterSpec genParam) throws InvalidParameterSpecException,
- NoSuchAlgorithmException, NoSuchProviderException,
- InvalidAlgorithmParameterException {
+ NoSuchAlgorithmException, NoSuchProviderException,
+ InvalidAlgorithmParameterException {
String algorithm = param.getAlgorithm();
if (!algorithm.equalsIgnoreCase(ALGORITHM_NAME)) {
throw new RuntimeException(
@@ -139,21 +143,25 @@
}
public static void main(String[] args) throws Exception {
- List<DataTuple> dataTuples = Arrays.stream(args)
- .map(arg -> arg.split(",")).map(params -> {
- int primePLen = Integer.valueOf(params[0]);
- int subprimeQLen = Integer.valueOf(params[1]);
- boolean isDSASpecSupported = false;
- if (params.length == 3) {
- isDSASpecSupported = Boolean.valueOf(params[2]);
- }
- return new DataTuple(primePLen, subprimeQLen,
- isDSASpecSupported);
- }).collect(Collectors.toList());
+ if (args == null || args.length < 2) {
+ throw new RuntimeException("Invalid number of arguments to generate"
+ + " DSA parameter.");
+ }
+ DataTuple dataTuple = null;
+ switch (args.length) {
+ case 3:
+ dataTuple = new DataTuple(Integer.valueOf(args[0]),
+ Integer.valueOf(args[1]), Boolean.valueOf(args[2]));
+ break;
+ case 2:
+ dataTuple = new DataTuple(Integer.valueOf(args[0]),
+ Integer.valueOf(args[1]), false);
+ break;
+ default:
+ throw new RuntimeException("Unsupported arguments found.");
+ }
+ testDSAGenParameterSpec(dataTuple);
- for (DataTuple dataTuple : dataTuples) {
- testDSAGenParameterSpec(dataTuple);
- }
}
private static class DataTuple {
@@ -170,4 +178,3 @@
}
}
}
-
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/SecureRandom/AbstractDrbg/SpecTest.java Thu Jun 09 19:07:27 2016 +0000
@@ -0,0 +1,244 @@
+/*
+ * 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 8051408 8157308
+ * @modules java.base/sun.security.provider
+ * @build java.base/sun.security.provider.S
+ * @run main SpecTest
+ * @summary check the AbstractDrbg API etc
+ */
+
+import java.security.*;
+import sun.security.provider.S;
+import static java.security.DrbgParameters.Capability.*;
+
+/**
+ * This test makes sure the AbstractDrbg API works as specified. It also
+ * checks the SecureRandom API.
+ *
+ * The implementations must be patched into java.base/sun.security.provider
+ * because AbstractDrbg is not a public interface.
+ */
+public class SpecTest {
+
+ public static void main(String args[]) throws Exception {
+
+ // getInstance from a provider.
+
+ Provider p = new All("A", 0, "");
+ byte[] bytes = new byte[100];
+
+ // A non-DRBG
+ iae(() -> SecureRandom.getInstance("S1", null, p));
+ nsae(() -> SecureRandom.getInstance("S1",
+ new SecureRandomParameters() {}, p));
+
+ SecureRandom s1 = SecureRandom.getInstance("S1", p);
+ if (s1.getParameters() != null) {
+ throw new Exception();
+ }
+
+ iae(() -> s1.nextBytes(bytes, null));
+ uoe(() -> s1.nextBytes(bytes, new SecureRandomParameters() {}));
+ uoe(() -> s1.reseed());
+ iae(() -> s1.reseed(null));
+ uoe(() -> s1.reseed(new SecureRandomParameters() {}));
+
+ // A weak DRBG
+ iae(() -> SecureRandom.getInstance("S2", null, p));
+ nsae(() -> SecureRandom.getInstance("S2",
+ new SecureRandomParameters() {}, p));
+ nsae(() -> SecureRandom.getInstance("S2",
+ DrbgParameters.instantiation(256, NONE, null), p));
+ nsae(() -> SecureRandom.getInstance("S2",
+ DrbgParameters.instantiation(-1, PR_AND_RESEED, null), p));
+ nsae(() -> SecureRandom.getInstance("S2",
+ DrbgParameters.instantiation(-1, RESEED_ONLY, null), p));
+
+ SecureRandom s2 = SecureRandom.getInstance("S2",
+ DrbgParameters.instantiation(-1, NONE, null), p);
+ equals(s2, "S2,SQUEEZE,128,none");
+ equals(s2.getParameters(), "128,none,null");
+
+ npe(() -> s2.nextBytes(null));
+ iae(() -> s2.nextBytes(bytes, null));
+ iae(() -> s2.nextBytes(bytes, new SecureRandomParameters() {}));
+ uoe(() -> s2.reseed());
+ iae(() -> s2.reseed(null));
+
+ iae(() -> s2.nextBytes(bytes,
+ DrbgParameters.nextBytes(-1, false, new byte[101])));
+ s2.nextBytes(new byte[101],
+ DrbgParameters.nextBytes(-1, false, new byte[100]));
+ s2.nextBytes(bytes,
+ DrbgParameters.nextBytes(-1, false, new byte[100]));
+
+ // A strong DRBG
+ iae(() -> SecureRandom.getInstance("S3", null, p));
+ nsae(() -> SecureRandom.getInstance("S3",
+ new SecureRandomParameters() {}, p));
+ SecureRandom.getInstance("S3",
+ DrbgParameters.instantiation(192, PR_AND_RESEED, null), p);
+
+ SecureRandom s3 = SecureRandom.getInstance("S3", p);
+ equals(s3, "S3,SQUEEZE,128,reseed_only");
+ equals(s3.getParameters(), "128,reseed_only,null");
+
+ iae(() -> s3.nextBytes(bytes,
+ DrbgParameters.nextBytes(192, false, null)));
+ iae(() -> s3.nextBytes(bytes,
+ DrbgParameters.nextBytes(112, true, null)));
+ iae(() -> s3.reseed(new SecureRandomParameters() {}));
+
+ SecureRandom s32 = SecureRandom.getInstance(
+ "S3", DrbgParameters.instantiation(192, PR_AND_RESEED, null), p);
+ equals(s32, "S3,SQUEEZE,192,pr_and_reseed");
+ equals(s32.getParameters(), "192,pr_and_reseed,null");
+
+ s32.nextBytes(bytes, DrbgParameters.nextBytes(192, false, null));
+ s32.nextBytes(bytes, DrbgParameters.nextBytes(112, true, null));
+ s32.reseed();
+ s32.reseed(DrbgParameters.reseed(true, new byte[100]));
+
+ // getInstance from competitive providers.
+
+ Provider l = new Legacy("L", 0, "");
+ Provider w = new Weak("W", 0, "");
+ Provider s = new Strong("S", 0, "");
+
+ Security.addProvider(l);
+ Security.addProvider(w);
+ Security.addProvider(s);
+
+ SecureRandom s4;
+
+ try {
+ s4 = SecureRandom.getInstance("S");
+ if (s4.getProvider() != l) {
+ throw new Exception();
+ }
+
+ nsae(() -> SecureRandom.getInstance(
+ "S", DrbgParameters.instantiation(256, NONE, null)));
+
+ s4 = SecureRandom.getInstance(
+ "S", DrbgParameters.instantiation(192, NONE, null));
+ if (s4.getProvider() != s) {
+ throw new Exception();
+ }
+
+ s4 = SecureRandom.getInstance(
+ "S", DrbgParameters.instantiation(128, PR_AND_RESEED, null));
+ if (s4.getProvider() != s) {
+ throw new Exception();
+ }
+
+ s4 = SecureRandom.getInstance(
+ "S", DrbgParameters.instantiation(128, RESEED_ONLY, null));
+ if (s4.getProvider() != s) {
+ throw new Exception();
+ }
+
+ s4 = SecureRandom.getInstance(
+ "S", DrbgParameters.instantiation(128, NONE, null));
+ if (s4.getProvider() != w) {
+ throw new Exception();
+ }
+ } finally {
+ Security.removeProvider("L");
+ Security.removeProvider("W");
+ Security.removeProvider("S");
+ }
+ }
+
+ public static class All extends Provider {
+ protected All(String name, double version, String info) {
+ super(name, version, info);
+ put("SecureRandom.S1", S.S1.class.getName());
+ put("SecureRandom.S2", S.S2.class.getName());
+ put("SecureRandom.S3", S.S3.class.getName());
+ }
+ }
+
+ // Providing S with no params support
+ public static class Legacy extends Provider {
+ protected Legacy(String name, double version, String info) {
+ super(name, version, info);
+ put("SecureRandom.S", S.S1.class.getName());
+ }
+ }
+
+ public static class Weak extends Provider {
+ protected Weak(String name, double version, String info) {
+ super(name, version, info);
+ put("SecureRandom.S", S.S2.class.getName());
+ }
+ }
+
+ public static class Strong extends Provider {
+ protected Strong(String name, double version, String info) {
+ super(name, version, info);
+ put("SecureRandom.S", S.S3.class.getName());
+ }
+ }
+
+ static void nsae(RunnableWithException r) throws Exception {
+ checkException(r, NoSuchAlgorithmException.class);
+ }
+
+ static void iae(RunnableWithException r) throws Exception {
+ checkException(r, IllegalArgumentException.class);
+ }
+
+ static void uoe(RunnableWithException r) throws Exception {
+ checkException(r, UnsupportedOperationException.class);
+ }
+
+ static void npe(RunnableWithException r) throws Exception {
+ checkException(r, NullPointerException.class);
+ }
+
+ interface RunnableWithException {
+ void run() throws Exception;
+ }
+
+ static void checkException(RunnableWithException r, Class ex)
+ throws Exception {
+ try {
+ r.run();
+ } catch (Exception e) {
+ if (ex.isAssignableFrom(e.getClass())) {
+ return;
+ }
+ throw e;
+ }
+ throw new Exception("No exception thrown");
+ }
+
+ static void equals(Object o, String s) throws Exception {
+ if (!o.toString().equals(s)) {
+ throw new Exception(o.toString() + " is not " + s);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/SecureRandom/AbstractDrbg/java.base/sun/security/provider/S.java Thu Jun 09 19:07:27 2016 +0000
@@ -0,0 +1,155 @@
+/*
+ * 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 sun.security.provider;
+
+import java.security.SecureRandomParameters;
+import java.security.SecureRandomSpi;
+
+/**
+ * Read ../../../../SpecTest.java for details.
+ */
+public class S extends SecureRandomSpi {
+
+ protected AbstractDrbg impl;
+
+ // This is not a DRBG.
+ public static class S1 extends SecureRandomSpi {
+ @Override
+ protected void engineSetSeed(byte[] seed) {
+ }
+
+ @Override
+ protected void engineNextBytes(byte[] bytes) {
+ }
+
+ @Override
+ protected byte[] engineGenerateSeed(int numBytes) {
+ return new byte[numBytes];
+ }
+ }
+
+ // This is a weak DRBG. maximum strength is 128 and does
+ // not support prediction resistance or reseed.
+ public static class S2 extends S {
+ public S2(SecureRandomParameters params) {
+ impl = new Impl2(params);
+ }
+ }
+
+ // This is a strong DRBG.
+ public static class S3 extends S {
+ public S3(SecureRandomParameters params) {
+ impl = new Impl3(params);
+ }
+ }
+
+ // AbstractDrbg Implementations
+
+ static class Impl3 extends AbstractDrbg {
+
+ public Impl3(SecureRandomParameters params) {
+ supportPredictionResistance = true;
+ supportReseeding = true;
+ highestSupportedSecurityStrength = 192;
+ mechName = "S3";
+ algorithm = "SQUEEZE";
+ configure(params);
+ }
+
+ protected void chooseAlgorithmAndStrength() {
+ if (requestedInstantiationSecurityStrength < 0) {
+ securityStrength = DEFAULT_STRENGTH;
+ } else {
+ securityStrength = requestedInstantiationSecurityStrength;
+ }
+ minLength = securityStrength / 8;
+ maxAdditionalInputLength = maxPersonalizationStringLength = 100;
+ }
+
+ @Override
+ protected void initEngine() {
+ }
+
+ @Override
+ protected void instantiateAlgorithm(byte[] ei) {
+ }
+
+ @Override
+ protected void generateAlgorithm(byte[] result, byte[] additionalInput) {
+ }
+
+ @Override
+ protected void reseedAlgorithm(byte[] ei, byte[] additionalInput) {
+ }
+ }
+
+ static class Impl2 extends Impl3 {
+ public Impl2(SecureRandomParameters params) {
+ super(null);
+ mechName = "S2";
+ highestSupportedSecurityStrength = 128;
+ supportPredictionResistance = false;
+ supportReseeding = false;
+ configure(params);
+ }
+ }
+
+ // Overridden SecureRandomSpi methods
+
+ @Override
+ protected void engineSetSeed(byte[] seed) {
+ impl.engineSetSeed(seed);
+ }
+
+ @Override
+ protected void engineNextBytes(byte[] bytes) {
+ impl.engineNextBytes(bytes);
+ }
+
+ @Override
+ protected byte[] engineGenerateSeed(int numBytes) {
+ return impl.engineGenerateSeed(numBytes);
+ }
+
+ @Override
+ protected void engineNextBytes(
+ byte[] bytes, SecureRandomParameters params) {
+ impl.engineNextBytes(bytes, params);
+ }
+
+ @Override
+ protected void engineReseed(SecureRandomParameters params) {
+ impl.engineReseed(params);
+ }
+
+ @Override
+ protected SecureRandomParameters engineGetParameters() {
+ return impl.engineGetParameters();
+ }
+
+ @Override
+ public String toString() {
+ return impl.toString();
+ }
+}
--- a/jdk/test/sun/security/provider/SecureRandom/AbstractDrbgSpec.java Thu Jun 09 17:28:37 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +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 8051408
- * @modules java.base/sun.security.provider
- * @summary check the AbstractDrbg API etc
- */
-
-import java.security.*;
-import sun.security.provider.AbstractDrbg;
-import static java.security.DrbgParameters.Capability.*;
-
-/**
- * This test makes sure the AbstractDrbg API works as specified. It also
- * checks the SecureRandom API.
- */
-public class AbstractDrbgSpec {
-
- public static void main(String args[]) throws Exception {
-
- // getInstance from a provider.
-
- Provider p = new All("A", 0, "");
- byte[] bytes = new byte[100];
-
- // A non-DRBG
- iae(() -> SecureRandom.getInstance("S1", null, p));
- nsae(() -> SecureRandom.getInstance("S1",
- new SecureRandomParameters() {}, p));
-
- SecureRandom s1 = SecureRandom.getInstance("S1", p);
- if (s1.getParameters() != null) {
- throw new Exception();
- }
-
- iae(() -> s1.nextBytes(bytes, null));
- uoe(() -> s1.nextBytes(bytes, new SecureRandomParameters() {}));
- uoe(() -> s1.reseed());
- iae(() -> s1.reseed(null));
- uoe(() -> s1.reseed(new SecureRandomParameters() {}));
-
- // A weak DRBG
- iae(() -> SecureRandom.getInstance("S2", null, p));
- nsae(() -> SecureRandom.getInstance("S2",
- new SecureRandomParameters() {}, p));
- nsae(() -> SecureRandom.getInstance("S2",
- DrbgParameters.instantiation(256, NONE, null), p));
- nsae(() -> SecureRandom.getInstance("S2",
- DrbgParameters.instantiation(-1, PR_AND_RESEED, null), p));
- nsae(() -> SecureRandom.getInstance("S2",
- DrbgParameters.instantiation(-1, RESEED_ONLY, null), p));
-
- SecureRandom s2 = SecureRandom.getInstance("S2",
- DrbgParameters.instantiation(-1, NONE, null), p);
- equals(s2, "S2,SQUEEZE,128,none");
- equals(s2.getParameters(), "128,none,null");
-
- npe(() -> s2.nextBytes(null));
- iae(() -> s2.nextBytes(bytes, null));
- iae(() -> s2.nextBytes(bytes, new SecureRandomParameters() {}));
- uoe(() -> s2.reseed());
- iae(() -> s2.reseed(null));
-
- iae(() -> s2.nextBytes(bytes,
- DrbgParameters.nextBytes(-1, false, new byte[101])));
- s2.nextBytes(new byte[101],
- DrbgParameters.nextBytes(-1, false, new byte[100]));
- s2.nextBytes(bytes,
- DrbgParameters.nextBytes(-1, false, new byte[100]));
-
- // A strong DRBG
- iae(() -> SecureRandom.getInstance("S3", null, p));
- nsae(() -> SecureRandom.getInstance("S3",
- new SecureRandomParameters() {}, p));
- SecureRandom.getInstance("S3",
- DrbgParameters.instantiation(192, PR_AND_RESEED, null), p);
-
- SecureRandom s3 = SecureRandom.getInstance("S3", p);
- equals(s3, "S3,SQUEEZE,128,reseed_only");
- equals(s3.getParameters(), "128,reseed_only,null");
-
- iae(() -> s3.nextBytes(bytes,
- DrbgParameters.nextBytes(192, false, null)));
- iae(() -> s3.nextBytes(bytes,
- DrbgParameters.nextBytes(112, true, null)));
- iae(() -> s3.reseed(new SecureRandomParameters() {}));
-
- SecureRandom s32 = SecureRandom.getInstance(
- "S3", DrbgParameters.instantiation(192, PR_AND_RESEED, null), p);
- equals(s32, "S3,SQUEEZE,192,pr_and_reseed");
- equals(s32.getParameters(), "192,pr_and_reseed,null");
-
- s32.nextBytes(bytes, DrbgParameters.nextBytes(192, false, null));
- s32.nextBytes(bytes, DrbgParameters.nextBytes(112, true, null));
- s32.reseed();
- s32.reseed(DrbgParameters.reseed(true, new byte[100]));
-
- // getInstance from competitive providers.
-
- Provider l = new Legacy("L", 0, "");
- Provider w = new Weak("W", 0, "");
- Provider s = new Strong("S", 0, "");
-
- Security.addProvider(l);
- Security.addProvider(w);
- Security.addProvider(s);
-
- SecureRandom s4;
-
- try {
- s4 = SecureRandom.getInstance("S");
- if (s4.getProvider() != l) {
- throw new Exception();
- }
-
- nsae(() -> SecureRandom.getInstance(
- "S", DrbgParameters.instantiation(256, NONE, null)));
-
- s4 = SecureRandom.getInstance(
- "S", DrbgParameters.instantiation(192, NONE, null));
- if (s4.getProvider() != s) {
- throw new Exception();
- }
-
- s4 = SecureRandom.getInstance(
- "S", DrbgParameters.instantiation(128, PR_AND_RESEED, null));
- if (s4.getProvider() != s) {
- throw new Exception();
- }
-
- s4 = SecureRandom.getInstance(
- "S", DrbgParameters.instantiation(128, RESEED_ONLY, null));
- if (s4.getProvider() != s) {
- throw new Exception();
- }
-
- s4 = SecureRandom.getInstance(
- "S", DrbgParameters.instantiation(128, NONE, null));
- if (s4.getProvider() != w) {
- throw new Exception();
- }
- } finally {
- Security.removeProvider("L");
- Security.removeProvider("W");
- Security.removeProvider("S");
- }
- }
-
- public static class All extends Provider {
- protected All(String name, double version, String info) {
- super(name, version, info);
- put("SecureRandom.S1", S1.class.getName());
- put("SecureRandom.S2", S2.class.getName());
- put("SecureRandom.S3", S3.class.getName());
- }
- }
-
- // Providing S with no params support
- public static class Legacy extends Provider {
- protected Legacy(String name, double version, String info) {
- super(name, version, info);
- put("SecureRandom.S", S1.class.getName());
- }
- }
-
- public static class Weak extends Provider {
- protected Weak(String name, double version, String info) {
- super(name, version, info);
- put("SecureRandom.S", S2.class.getName());
- }
- }
-
- public static class Strong extends Provider {
- protected Strong(String name, double version, String info) {
- super(name, version, info);
- put("SecureRandom.S", S3.class.getName());
- }
- }
-
- // This is not a DRBG.
- public static class S1 extends SecureRandomSpi {
- @Override
- protected void engineSetSeed(byte[] seed) {
- }
-
- @Override
- protected void engineNextBytes(byte[] bytes) {
- }
-
- @Override
- protected byte[] engineGenerateSeed(int numBytes) {
- return new byte[numBytes];
- }
- }
-
- // This is a strong DRBG.
- public static class S3 extends AbstractDrbg {
-
- public S3(SecureRandomParameters params) {
- supportPredictionResistance = true;
- supportReseeding = true;
- highestSupportedSecurityStrength = 192;
- mechName = "S3";
- algorithm = "SQUEEZE";
- configure(params);
- }
- protected void chooseAlgorithmAndStrength() {
- if (requestedInstantiationSecurityStrength < 0) {
- securityStrength = DEFAULT_STRENGTH;
- } else {
- securityStrength = requestedInstantiationSecurityStrength;
- }
- minLength = securityStrength / 8;
- maxAdditionalInputLength = maxPersonalizationStringLength = 100;
- }
-
- @Override
- protected void initEngine() {
-
- }
-
- @Override
- protected void instantiateAlgorithm(byte[] ei) {
-
- }
-
- @Override
- protected void generateAlgorithm(byte[] result, byte[] additionalInput) {
-
- }
-
- @Override
- protected void reseedAlgorithm(byte[] ei, byte[] additionalInput) {
-
- }
- }
-
- // This is a weak DRBG. maximum strength is 128 and does
- // not support prediction resistance or reseed.
- public static class S2 extends S3 {
- public S2(SecureRandomParameters params) {
- super(null);
- mechName = "S2";
- highestSupportedSecurityStrength = 128;
- supportPredictionResistance = false;
- supportReseeding = false;
- configure(params);
- }
- }
-
- static void nsae(RunnableWithException r) throws Exception {
- checkException(r, NoSuchAlgorithmException.class);
- }
-
- static void iae(RunnableWithException r) throws Exception {
- checkException(r, IllegalArgumentException.class);
- }
-
- static void uoe(RunnableWithException r) throws Exception {
- checkException(r, UnsupportedOperationException.class);
- }
-
- static void npe(RunnableWithException r) throws Exception {
- checkException(r, NullPointerException.class);
- }
-
- interface RunnableWithException {
- void run() throws Exception;
- }
-
- static void checkException(RunnableWithException r, Class ex)
- throws Exception {
- try {
- r.run();
- } catch (Exception e) {
- if (ex.isAssignableFrom(e.getClass())) {
- return;
- }
- throw e;
- }
- throw new Exception("No exception thrown");
- }
-
- static void equals(Object o, String s) throws Exception {
- if (!o.toString().equals(s)) {
- throw new Exception(o.toString() + " is not " + s);
- }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/provider/SecureRandom/DRBGS11n.java Thu Jun 09 19:07:27 2016 +0000
@@ -0,0 +1,70 @@
+/*
+ * 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 sun.security.provider.DRBG;
+import sun.security.provider.MoreDrbgParameters;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.lang.reflect.Field;
+
+/**
+ * @test
+ * @bug 8157308
+ * @modules java.base/sun.security.provider
+ * @summary Make AbstractDrbg non-Serializable
+ * @run main DRBGS11n mech
+ * @run main DRBGS11n capability
+ */
+public class DRBGS11n {
+
+ public static void main(String[] args) throws Exception {
+
+ DRBG d = new DRBG(null);
+ Field f = DRBG.class.getDeclaredField("mdp");
+ f.setAccessible(true);
+ MoreDrbgParameters mdp = (MoreDrbgParameters)f.get(d);
+
+ // Corrupt the mech or capability fields inside DRBG#mdp.
+ f = MoreDrbgParameters.class.getDeclaredField(args[0]);
+ f.setAccessible(true);
+ f.set(mdp, null);
+
+ try {
+ revive(d);
+ } catch (IllegalArgumentException iae) {
+ // Expected
+ return;
+ }
+
+ throw new Exception("revive should fail");
+ }
+
+ static <T> T revive(T in) throws Exception {
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ new ObjectOutputStream(bout).writeObject(in);
+ return (T) new ObjectInputStream(
+ new ByteArrayInputStream(bout.toByteArray())).readObject();
+ }
+}