Mercurial > hg > release > icedtea8-forest-3.0 > jdk
changeset 10007:be30cb2a3088 jdk8u20-b23
Merge
author | lana |
---|---|
date | Tue, 15 Jul 2014 14:08:27 -0700 |
parents | 125d545184fa (current diff) 35b34d6782b4 (diff) |
children | f0bd72b0f177 65b68b7458c7 b1725c165e29 |
files | src/share/classes/com/sun/jmx/remote/util/CacheMap.java test/javax/management/remote/mandatory/util/CacheMapTest.java |
diffstat | 33 files changed, 626 insertions(+), 567 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Tue Jul 15 02:00:52 2014 +0400 +++ b/.hgtags Tue Jul 15 14:08:27 2014 -0700 @@ -260,6 +260,7 @@ 343f4f8ba0982b3516e33c859b01634d919243c4 jdk8u5-b02 c35571198602a5856280d5c7c10bda4e7b769104 jdk8u5-b03 55e6175fb6904d771bfaec4ada4f5e20b54f4791 jdk8u5-b04 +911d590f34aaa7f7b9ef300d0c0a019e70a62d1d jdk8u11-b00 911d590f34aaa7f7b9ef300d0c0a019e70a62d1d jdk8u5-b05 94fe0ed14bfcca335ff72abd20cf871dab100e79 jdk8u5-b06 469c2c1a4885ddedc114e17902bb2f7f7326a4b7 jdk8u5-b07 @@ -269,6 +270,20 @@ f4f3b7ccd2801a0a87dd4677332f5b93191d08f2 jdk8u5-b11 9ff7f7909e122bb54f7df80efd0fc7a03ce7efff jdk8u5-b12 c6836440c427800a9f48168af29759b79857781d jdk8u5-b13 +8ba5281f1dce1122edac9e7d12b6c42e6da6297b jdk8u5-b31 +5eff6b1060758eae51125156a6f9c7725905e64e jdk8u11-b01 +cb1b9eca5890807476935051b8a5f13f4d3e5c63 jdk8u11-b02 +5efce41be1c8637b399980ea227f19e0f98341bc jdk8u11-b03 +4af24a3f52aeb07b51d3860049b0d1504e400feb jdk8u11-b04 +726370d73baebc513d0d83df71bb7629703ef7d0 jdk8u11-b05 +dc8eb8ba138a53df4cc80f6379ed25ef20644667 jdk8u11-b06 +69ea8bc3ce29eda152d9c2ebea91a9ce233bde9e jdk8u11-b07 +bec9dcd4c06358154cce431c4b70da56530827de jdk8u11-b08 +801e730c85eb822ac3b00466b32d42e089cb7233 jdk8u11-b09 +105753f0465e534e3664d0935016f5a0d061829d jdk8u11-b10 +bd5f7651116e2634c09adf073609811c60a4d5e7 jdk8u11-b11 +cbdfb9fdf1b3819f0299991a07e6ca72b3573625 jdk8u11-b12 +35329d502d6fb65e4f089fd338d4ee0757811b36 jdk8u11-b31 9543b632ab87368c887d8b29b21157ebb44228d0 jdk8u20-b02 5a9f04957f826ce23639479c9791c7d8fd282b01 jdk8u20-b03 c347889445c1153f11aaa56092d44a911e497454 jdk8u20-b04
--- a/make/mapfiles/libsunec/mapfile-vers Tue Jul 15 02:00:52 2014 +0400 +++ b/make/mapfiles/libsunec/mapfile-vers Tue Jul 15 14:08:27 2014 -0700 @@ -1,5 +1,5 @@ # -# Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -28,10 +28,9 @@ SUNWprivate_1.1 { global: Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair; - Java_sun_security_ec_ECKeyPairGenerator_getEncodedBytes; - Java_sun_security_ec_ECDSASignature_signDigest; - Java_sun_security_ec_ECDSASignature_verifySignedDigest; - Java_sun_security_ec_ECDHKeyAgreement_deriveKey; + Java_sun_security_ec_ECDSASignature_signDigest; + Java_sun_security_ec_ECDSASignature_verifySignedDigest; + Java_sun_security_ec_ECDHKeyAgreement_deriveKey; local: *; };
--- a/make/profile-includes.txt Tue Jul 15 02:00:52 2014 +0400 +++ b/make/profile-includes.txt Tue Jul 15 14:08:27 2014 -0700 @@ -73,6 +73,7 @@ rt.jar \ security/US_export_policy.jar \ security/blacklist \ + security/blacklisted.certs \ security/cacerts \ security/java.policy \ security/java.security \
--- a/src/share/classes/com/sun/jmx/remote/security/SubjectDelegator.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/classes/com/sun/jmx/remote/security/SubjectDelegator.java Tue Jul 15 14:08:27 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,22 +34,14 @@ import javax.management.remote.SubjectDelegationPermission; -import com.sun.jmx.remote.util.CacheMap; -import java.util.ArrayList; -import java.util.Collection; +import java.util.*; public class SubjectDelegator { - private static final int PRINCIPALS_CACHE_SIZE = 10; - private static final int ACC_CACHE_SIZE = 10; - - private CacheMap<Subject, Principal[]> principalsCache; - private CacheMap<Subject, AccessControlContext> accCache; - /* Return the AccessControlContext appropriate to execute an operation on behalf of the delegatedSubject. If the authenticatedAccessControlContext does not have permission to delegate to that subject, throw SecurityException. */ - public synchronized AccessControlContext + public AccessControlContext delegatedContext(AccessControlContext authenticatedACC, Subject delegatedSubject, boolean removeCallerContext) @@ -58,56 +50,14 @@ if (System.getSecurityManager() != null && authenticatedACC == null) { throw new SecurityException("Illegal AccessControlContext: null"); } - if (principalsCache == null || accCache == null) { - principalsCache = - new CacheMap<>(PRINCIPALS_CACHE_SIZE); - accCache = - new CacheMap<>(ACC_CACHE_SIZE); - } - - // Retrieve the principals for the given - // delegated subject from the cache - // - Principal[] delegatedPrincipals = principalsCache.get(delegatedSubject); - - // Convert the set of principals stored in the - // delegated subject into an array of principals - // and store it in the cache - // - if (delegatedPrincipals == null) { - delegatedPrincipals = - delegatedSubject.getPrincipals().toArray(new Principal[0]); - principalsCache.put(delegatedSubject, delegatedPrincipals); - } - - // Retrieve the access control context for the - // given delegated subject from the cache - // - AccessControlContext delegatedACC = accCache.get(delegatedSubject); - - // Build the access control context to be used - // when executing code as the delegated subject - // and store it in the cache - // - if (delegatedACC == null) { - if (removeCallerContext) { - delegatedACC = - JMXSubjectDomainCombiner.getDomainCombinerContext( - delegatedSubject); - } else { - delegatedACC = - JMXSubjectDomainCombiner.getContext(delegatedSubject); - } - accCache.put(delegatedSubject, delegatedACC); - } // Check if the subject delegation permission allows the // authenticated subject to assume the identity of each // principal in the delegated subject // - final Principal[] dp = delegatedPrincipals; - final Collection<Permission> permissions = new ArrayList<>(dp.length); - for(Principal p : dp) { + Collection<Principal> ps = getSubjectPrincipals(delegatedSubject); + final Collection<Permission> permissions = new ArrayList<>(ps.size()); + for(Principal p : ps) { final String pname = p.getClass().getName() + "." + p.getName(); permissions.add(new SubjectDelegationPermission(pname)); } @@ -122,7 +72,15 @@ }; AccessController.doPrivileged(action, authenticatedACC); - return delegatedACC; + return getDelegatedAcc(delegatedSubject, removeCallerContext); + } + + private AccessControlContext getDelegatedAcc(Subject delegatedSubject, boolean removeCallerContext) { + if (removeCallerContext) { + return JMXSubjectDomainCombiner.getDomainCombinerContext(delegatedSubject); + } else { + return JMXSubjectDomainCombiner.getContext(delegatedSubject); + } } /** @@ -137,11 +95,9 @@ public static synchronized boolean checkRemoveCallerContext(Subject subject) { try { - final Principal[] dp = - subject.getPrincipals().toArray(new Principal[0]); - for (int i = 0 ; i < dp.length ; i++) { + for (Principal p : getSubjectPrincipals(subject)) { final String pname = - dp[i].getClass().getName() + "." + dp[i].getName(); + p.getClass().getName() + "." + p.getName(); final Permission sdp = new SubjectDelegationPermission(pname); AccessController.checkPermission(sdp); @@ -151,4 +107,19 @@ } return true; } + + /** + * Retrieves the {@linkplain Subject} principals + * @param subject The subject + * @return If the {@code Subject} is immutable it will return the principals directly. + * If the {@code Subject} is mutable it will create an unmodifiable copy. + */ + private static Collection<Principal> getSubjectPrincipals(Subject subject) { + if (subject.isReadOnly()) { + return subject.getPrincipals(); + } + + List<Principal> principals = Arrays.asList(subject.getPrincipals().toArray(new Principal[0])); + return Collections.unmodifiableList(principals); + } }
--- a/src/share/classes/com/sun/jmx/remote/util/CacheMap.java Tue Jul 15 02:00:52 2014 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.jmx.remote.util; - -import java.lang.ref.SoftReference; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.WeakHashMap; - -import com.sun.jmx.mbeanserver.Util; - -/** - * <p>Like WeakHashMap, except that the keys of the <em>n</em> most - * recently-accessed entries are kept as {@link SoftReference soft - * references}. Accessing an element means creating it, or retrieving - * it with {@link #get(Object) get}. Because these entries are kept - * with soft references, they will tend to remain even if their keys - * are not referenced elsewhere. But if memory is short, they will - * be removed.</p> - */ -public class CacheMap<K, V> extends WeakHashMap<K, V> { - /** - * <p>Create a <code>CacheMap</code> that can keep up to - * <code>nSoftReferences</code> as soft references.</p> - * - * @param nSoftReferences Maximum number of keys to keep as soft - * references. Access times for {@link #get(Object) get} and - * {@link #put(Object, Object) put} have a component that scales - * linearly with <code>nSoftReferences</code>, so this value - * should not be too great. - * - * @throws IllegalArgumentException if - * <code>nSoftReferences</code> is negative. - */ - public CacheMap(int nSoftReferences) { - if (nSoftReferences < 0) { - throw new IllegalArgumentException("nSoftReferences = " + - nSoftReferences); - } - this.nSoftReferences = nSoftReferences; - } - - public V put(K key, V value) { - cache(key); - return super.put(key, value); - } - - public V get(Object key) { - cache(Util.<K>cast(key)); - return super.get(key); - } - - /* We don't override remove(Object) or try to do something with - the map's iterators to detect removal. So we may keep useless - entries in the soft reference list for keys that have since - been removed. The assumption is that entries are added to the - cache but never removed. But the behavior is not wrong if - they are in fact removed -- the caching is just less - performant. */ - - private void cache(K key) { - Iterator<SoftReference<K>> it = cache.iterator(); - while (it.hasNext()) { - SoftReference<K> sref = it.next(); - K key1 = sref.get(); - if (key1 == null) - it.remove(); - else if (key.equals(key1)) { - // Move this element to the head of the LRU list - it.remove(); - cache.add(0, sref); - return; - } - } - - int size = cache.size(); - if (size == nSoftReferences) { - if (size == 0) - return; // degenerate case, equivalent to WeakHashMap - it.remove(); - } - - cache.add(0, new SoftReference<K>(key)); - } - - /* List of soft references for the most-recently referenced keys. - The list is in most-recently-used order, i.e. the first element - is the most-recently referenced key. There are never more than - nSoftReferences elements of this list. - - If we didn't care about J2SE 1.3 compatibility, we could use - LinkedHashSet in conjunction with a subclass of SoftReference - whose equals and hashCode reflect the referent. */ - private final LinkedList<SoftReference<K>> cache = - new LinkedList<SoftReference<K>>(); - private final int nSoftReferences; -}
--- a/src/share/classes/com/sun/security/sasl/CramMD5Base.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/classes/com/sun/security/sasl/CramMD5Base.java Tue Jul 15 14:08:27 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ import java.security.NoSuchAlgorithmException; import java.security.MessageDigest; +import java.util.Arrays; import java.util.logging.Logger; /** @@ -159,7 +160,7 @@ MessageDigest md5 = MessageDigest.getInstance("MD5"); /* digest the key if longer than 64 bytes */ - if (key.length > 64) { + if (key.length > MD5_BLOCKSIZE) { key = md5.digest(key); } @@ -169,13 +170,9 @@ int i; /* store key in pads */ - for (i = 0; i < MD5_BLOCKSIZE; i++) { - for ( ; i < key.length; i++) { - ipad[i] = key[i]; - opad[i] = key[i]; - } - ipad[i] = 0x00; - opad[i] = 0x00; + for (i = 0; i < key.length; i++) { + ipad[i] = key[i]; + opad[i] = key[i]; } /* XOR key with pads */ @@ -207,6 +204,11 @@ } } + Arrays.fill(ipad, (byte)0); + Arrays.fill(opad, (byte)0); + ipad = null; + opad = null; + return (digestString.toString()); }
--- a/src/share/classes/java/lang/ProcessBuilder.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/classes/java/lang/ProcessBuilder.java Tue Jul 15 14:08:27 2014 -0700 @@ -1019,6 +1019,12 @@ String dir = directory == null ? null : directory.toString(); + for (int i = 1; i < cmdarray.length; i++) { + if (cmdarray[i].indexOf('\u0000') >= 0) { + throw new IOException("invalid null character in command"); + } + } + try { return ProcessImpl.start(cmdarray, environment,
--- a/src/share/classes/java/lang/invoke/MethodHandles.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/classes/java/lang/invoke/MethodHandles.java Tue Jul 15 14:08:27 2014 -0700 @@ -39,7 +39,9 @@ import sun.security.util.SecurityConstants; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; + import java.util.concurrent.ConcurrentHashMap; + import sun.security.util.SecurityConstants; /** @@ -1504,6 +1506,10 @@ // that is *not* the bytecode behavior. mods ^= Modifier.PROTECTED | Modifier.PUBLIC; } + if (Modifier.isProtected(mods) && refKind == REF_newInvokeSpecial) { + // cannot "new" a protected ctor in a different package + mods ^= Modifier.PROTECTED; + } if (Modifier.isFinal(mods) && MethodHandleNatives.refKindIsSetter(refKind)) throw m.makeAccessException("unexpected set of a final field", this);
--- a/src/share/classes/java/lang/reflect/Proxy.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/classes/java/lang/reflect/Proxy.java Tue Jul 15 14:08:27 2014 -0700 @@ -362,12 +362,13 @@ Class<?>... interfaces) throws IllegalArgumentException { - SecurityManager sm = System.getSecurityManager(); + final Class<?>[] intfs = interfaces.clone(); + final SecurityManager sm = System.getSecurityManager(); if (sm != null) { - checkProxyAccess(Reflection.getCallerClass(), loader, interfaces); + checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } - return getProxyClass0(loader, interfaces); + return getProxyClass0(loader, intfs); } /* @@ -706,15 +707,16 @@ { Objects.requireNonNull(h); + final Class<?>[] intfs = interfaces.clone(); final SecurityManager sm = System.getSecurityManager(); if (sm != null) { - checkProxyAccess(Reflection.getCallerClass(), loader, interfaces); + checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } /* * Look up or generate the designated proxy class. */ - Class<?> cl = getProxyClass0(loader, interfaces); + Class<?> cl = getProxyClass0(loader, intfs); /* * Invoke its constructor with the designated invocation handler.
--- a/src/share/classes/java/security/Provider.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/classes/java/security/Provider.java Tue Jul 15 14:08:27 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2014, 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 @@ -1372,7 +1372,7 @@ * <p>This class defines the methods {@link #supportsParameter * supportsParameter()} and {@link #newInstance newInstance()} * which are used by the Java security framework when it searches for - * suitable services and instantes them. The valid arguments to those + * suitable services and instantiates them. The valid arguments to those * methods depend on the type of service. For the service types defined * within Java SE, see the * <a href="../../../technotes/guides/security/crypto/CryptoSpec.html"> @@ -1562,7 +1562,7 @@ * * @throws InvalidParameterException if the value of * constructorParameter is invalid for this type of service. - * @throws NoSuchAlgorithmException if instantation failed for + * @throws NoSuchAlgorithmException if instantiation failed for * any other reason. */ public Object newInstance(Object constructorParameter) @@ -1590,7 +1590,9 @@ + " engines"); } Class<?> clazz = getImplClass(); - return clazz.newInstance(); + Class<?>[] empty = {}; + Constructor<?> con = clazz.getConstructor(empty); + return con.newInstance(); } else { Class<?> paramClass = cap.getConstructorParameterClass(); if (constructorParameter != null) { @@ -1633,13 +1635,18 @@ } else { clazz = cl.loadClass(className); } + if (!Modifier.isPublic(clazz.getModifiers())) { + throw new NoSuchAlgorithmException + ("class configured for " + type + " (provider: " + + provider.getName() + ") is not public."); + } classRef = new WeakReference<Class<?>>(clazz); } return clazz; } catch (ClassNotFoundException e) { throw new NoSuchAlgorithmException - ("class configured for " + type + "(provider: " + - provider.getName() + ")" + "cannot be found.", e); + ("class configured for " + type + " (provider: " + + provider.getName() + ") cannot be found.", e); } } @@ -1652,15 +1659,21 @@ throws Exception { Class<?> clazz = getImplClass(); if (constructorParameter == null) { - Object o = clazz.newInstance(); - return o; + // create instance with public no-arg constructor if it exists + try { + Class<?>[] empty = {}; + Constructor<?> con = clazz.getConstructor(empty); + return con.newInstance(); + } catch (NoSuchMethodException e) { + throw new NoSuchAlgorithmException("No public no-arg " + + "constructor found in class " + className); + } } Class<?> argClass = constructorParameter.getClass(); Constructor[] cons = clazz.getConstructors(); // find first public constructor that can take the // argument as parameter - for (int i = 0; i < cons.length; i++) { - Constructor<?> con = cons[i]; + for (Constructor<?> con : cons) { Class<?>[] paramTypes = con.getParameterTypes(); if (paramTypes.length != 1) { continue; @@ -1668,10 +1681,9 @@ if (paramTypes[0].isAssignableFrom(argClass) == false) { continue; } - Object o = con.newInstance(new Object[] {constructorParameter}); - return o; + return con.newInstance(constructorParameter); } - throw new NoSuchAlgorithmException("No constructor matching " + throw new NoSuchAlgorithmException("No public constructor matching " + argClass.getName() + " found in class " + className); }
--- a/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java Tue Jul 15 14:08:27 2014 -0700 @@ -334,6 +334,8 @@ if (vclass != fieldClass) throw new ClassCastException(); + if (vclass.isPrimitive()) + throw new IllegalArgumentException("Must be reference type"); if (!Modifier.isVolatile(modifiers)) throw new IllegalArgumentException("Must be volatile type");
--- a/src/share/classes/javax/swing/filechooser/FileSystemView.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/classes/javax/swing/filechooser/FileSystemView.java Tue Jul 15 14:08:27 2014 -0700 @@ -718,7 +718,8 @@ * @return the Desktop folder. */ public File getHomeDirectory() { - return getRoots()[0]; + File[] roots = getRoots(); + return (roots.length == 0) ? null : roots[0]; } /**
--- a/src/share/classes/sun/awt/AppContext.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/classes/sun/awt/AppContext.java Tue Jul 15 14:08:27 2014 -0700 @@ -331,6 +331,20 @@ while (context == null) { threadGroup = threadGroup.getParent(); if (threadGroup == null) { + // We've got up to the root thread group and did not find an AppContext + // Try to get it from the security manager + SecurityManager securityManager = System.getSecurityManager(); + if (securityManager != null) { + ThreadGroup smThreadGroup = securityManager.getThreadGroup(); + if (smThreadGroup != null) { + /* + * If we get this far then it's likely that + * the ThreadGroup does not actually belong + * to the applet, so do not cache it. + */ + return threadGroup2appContext.get(smThreadGroup); + } + } return null; } context = threadGroup2appContext.get(threadGroup);
--- a/src/share/classes/sun/security/ec/ECKeyPairGenerator.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/classes/sun/security/ec/ECKeyPairGenerator.java Tue Jul 15 14:08:27 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, 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 @@ -125,19 +125,18 @@ try { - long[] handles = generateECKeyPair(keySize, encodedParams, seed); + Object[] keyBytes = generateECKeyPair(keySize, encodedParams, seed); // The 'params' object supplied above is equivalent to the native // one so there is no need to fetch it. - - // handles[0] points to the native private key - BigInteger s = new BigInteger(1, getEncodedBytes(handles[0])); + // keyBytes[0] is the encoding of the native private key + BigInteger s = new BigInteger(1, (byte[])keyBytes[0]); PrivateKey privateKey = new ECPrivateKeyImpl(s, (ECParameterSpec)params); - // handles[1] points to the native public key - ECPoint w = ECUtil.decodePoint(getEncodedBytes(handles[1]), + // keyBytes[1] is the encoding of the native public key + ECPoint w = ECUtil.decodePoint((byte[])keyBytes[1], ((ECParameterSpec)params).getCurve()); PublicKey publicKey = new ECPublicKeyImpl(w, (ECParameterSpec)params); @@ -162,14 +161,9 @@ } /* - * Generates the keypair and returns a 2-element array of handles. - * The first handle points to the private key, the second to the public key. + * Generates the keypair and returns a 2-element array of encoding bytes. + * The first one is for the private key, the second for the public key. */ - private static native long[] generateECKeyPair(int keySize, + private static native Object[] generateECKeyPair(int keySize, byte[] encodedParams, byte[] seed) throws GeneralSecurityException; - - /* - * Extracts the encoded key data using the supplied handle. - */ - private static native byte[] getEncodedBytes(long handle); }
--- a/src/share/classes/sun/security/rsa/RSACore.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/classes/sun/security/rsa/RSACore.java Tue Jul 15 14:08:27 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, 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 @@ -50,6 +50,15 @@ */ public final class RSACore { + // globally enable/disable use of blinding + private final static boolean ENABLE_BLINDING = true; + + // cache for blinding parameters. Map<BigInteger, BlindingParameters> + // use a weak hashmap so that cached values are automatically cleared + // when the modulus is GC'ed + private final static Map<BigInteger, BlindingParameters> + blindingCache = new WeakHashMap<>(); + private RSACore() { // empty } @@ -100,12 +109,12 @@ if (key instanceof RSAPrivateCrtKey) { return crtCrypt(msg, (RSAPrivateCrtKey)key); } else { - return crypt(msg, key.getModulus(), key.getPrivateExponent()); + return priCrypt(msg, key.getModulus(), key.getPrivateExponent()); } } /** - * RSA public key ops and non-CRT private key ops. Simple modPow(). + * RSA public key ops. Simple modPow(). */ private static byte[] crypt(byte[] msg, BigInteger n, BigInteger exp) throws BadPaddingException { @@ -115,22 +124,29 @@ } /** + * RSA non-CRT private key operations. + */ + private static byte[] priCrypt(byte[] msg, BigInteger n, BigInteger exp) + throws BadPaddingException { + + BigInteger c = parseMsg(msg, n); + BlindingRandomPair brp = null; + BigInteger m; + if (ENABLE_BLINDING) { + brp = getBlindingRandomPair(null, exp, n); + c = c.multiply(brp.u).mod(n); + m = c.modPow(exp, n); + m = m.multiply(brp.v).mod(n); + } else { + m = c.modPow(exp, n); + } + + return toByteArray(m, getByteLength(n)); + } + + /** * RSA private key operations with CRT. Algorithm and variable naming * are taken from PKCS#1 v2.1, section 5.1.2. - * - * The only difference is the addition of blinding to twart timing attacks. - * This is described in the RSA Bulletin#2 (Jan 96) among other places. - * This means instead of implementing RSA as - * m = c ^ d mod n (or RSA in CRT variant) - * we do - * r = random(0, n-1) - * c' = c * r^e mod n - * m' = c' ^ d mod n (or RSA in CRT variant) - * m = m' * r^-1 mod n (where r^-1 is the modular inverse of r mod n) - * This works because r^(e*d) * r^-1 = r * r^-1 = 1 (all mod n) - * - * We do not generate new blinding parameters for each operation but reuse - * them BLINDING_MAX_REUSE times (see definition below). */ private static byte[] crtCrypt(byte[] msg, RSAPrivateCrtKey key) throws BadPaddingException { @@ -141,13 +157,13 @@ BigInteger dP = key.getPrimeExponentP(); BigInteger dQ = key.getPrimeExponentQ(); BigInteger qInv = key.getCrtCoefficient(); + BigInteger e = key.getPublicExponent(); + BigInteger d = key.getPrivateExponent(); - BlindingParameters params; + BlindingRandomPair brp; if (ENABLE_BLINDING) { - params = getBlindingParameters(key); - c = c.multiply(params.re).mod(n); - } else { - params = null; + brp = getBlindingRandomPair(e, d, n); + c = c.multiply(brp.u).mod(n); } // m1 = c ^ dP mod p @@ -165,8 +181,8 @@ // m = m2 + q * h BigInteger m = h.multiply(q).add(m2); - if (params != null) { - m = m.multiply(params.rInv).mod(n); + if (ENABLE_BLINDING) { + m = m.multiply(brp.v).mod(n); } return toByteArray(m, getByteLength(n)); @@ -208,82 +224,217 @@ return t; } - // globally enable/disable use of blinding - private final static boolean ENABLE_BLINDING = true; + /** + * Parameters (u,v) for RSA Blinding. This is described in the RSA + * Bulletin#2 (Jan 96) and other places: + * + * ftp://ftp.rsa.com/pub/pdfs/bull-2.pdf + * + * The standard RSA Blinding decryption requires the public key exponent + * (e) and modulus (n), and converts ciphertext (c) to plaintext (p). + * + * Before the modular exponentiation operation, the input message should + * be multiplied by (u (mod n)), and afterward the result is corrected + * by multiplying with (v (mod n)). The system should reject messages + * equal to (0 (mod n)). That is: + * + * 1. Generate r between 0 and n-1, relatively prime to n. + * 2. Compute x = (c*u) mod n + * 3. Compute y = (x^d) mod n + * 4. Compute p = (y*v) mod n + * + * The Java APIs allows for either standard RSAPrivateKey or + * RSAPrivateCrtKey RSA keys. + * + * If the public exponent is available to us (e.g. RSAPrivateCrtKey), + * choose a random r, then let (u, v): + * + * u = r ^ e mod n + * v = r ^ (-1) mod n + * + * The proof follows: + * + * p = (((c * u) ^ d mod n) * v) mod n + * = ((c ^ d) * (u ^ d) * v) mod n + * = ((c ^ d) * (r ^ e) ^ d) * (r ^ (-1))) mod n + * = ((c ^ d) * (r ^ (e * d)) * (r ^ (-1))) mod n + * = ((c ^ d) * (r ^ 1) * (r ^ (-1))) mod n (see below) + * = (c ^ d) mod n + * + * because in RSA cryptosystem, d is the multiplicative inverse of e: + * + * (r^(e * d)) mod n + * = (r ^ 1) mod n + * = r mod n + * + * However, if the public exponent is not available (e.g. RSAPrivateKey), + * we mitigate the timing issue by using a similar random number blinding + * approach using the private key: + * + * u = r + * v = ((r ^ (-1)) ^ d) mod n + * + * This returns the same plaintext because: + * + * p = (((c * u) ^ d mod n) * v) mod n + * = ((c ^ d) * (u ^ d) * v) mod n + * = ((c ^ d) * (u ^ d) * ((u ^ (-1)) ^d)) mod n + * = (c ^ d) mod n + * + * Computing inverses mod n and random number generation is slow, so + * it is often not practical to generate a new random (u, v) pair for + * each new exponentiation. The calculation of parameters might even be + * subject to timing attacks. However, (u, v) pairs should not be + * reused since they themselves might be compromised by timing attacks, + * leaving the private exponent vulnerable. An efficient solution to + * this problem is update u and v before each modular exponentiation + * step by computing: + * + * u = u ^ 2 + * v = v ^ 2 + * + * The total performance cost is small. + */ + private final static class BlindingRandomPair { + final BigInteger u; + final BigInteger v; - // maximum number of times that we will use a set of blinding parameters - // value suggested by Paul Kocher (quoted by NSS) - private final static int BLINDING_MAX_REUSE = 50; - - // cache for blinding parameters. Map<BigInteger, BlindingParameters> - // use a weak hashmap so that cached values are automatically cleared - // when the modulus is GC'ed - private final static Map<BigInteger, BlindingParameters> blindingCache = - new WeakHashMap<>(); + BlindingRandomPair(BigInteger u, BigInteger v) { + this.u = u; + this.v = v; + } + } /** * Set of blinding parameters for a given RSA key. * * The RSA modulus is usually unique, so we index by modulus in - * blindingCache. However, to protect against the unlikely case of two - * keys sharing the same modulus, we also store the public exponent. - * This means we cannot cache blinding parameters for multiple keys that - * share the same modulus, but since sharing moduli is fundamentally broken - * an insecure, this does not matter. + * {@code blindingCache}. However, to protect against the unlikely + * case of two keys sharing the same modulus, we also store the public + * or the private exponent. This means we cannot cache blinding + * parameters for multiple keys that share the same modulus, but + * since sharing moduli is fundamentally broken and insecure, this + * does not matter. */ - private static final class BlindingParameters { - // e (RSA public exponent) - final BigInteger e; - // r ^ e mod n - final BigInteger re; - // inverse of r mod n - final BigInteger rInv; - // how many more times this parameter object can be used - private volatile int remainingUses; - BlindingParameters(BigInteger e, BigInteger re, BigInteger rInv) { + private final static class BlindingParameters { + private final static BigInteger BIG_TWO = BigInteger.valueOf(2L); + + // RSA public exponent + private final BigInteger e; + + // hash code of RSA private exponent + private final BigInteger d; + + // r ^ e mod n (CRT), or r mod n (Non-CRT) + private BigInteger u; + + // r ^ (-1) mod n (CRT) , or ((r ^ (-1)) ^ d) mod n (Non-CRT) + private BigInteger v; + + // e: the public exponent + // d: the private exponent + // n: the modulus + BlindingParameters(BigInteger e, BigInteger d, BigInteger n) { + this.u = null; + this.v = null; this.e = e; - this.re = re; - this.rInv = rInv; - // initialize remaining uses, subtract current use now - remainingUses = BLINDING_MAX_REUSE - 1; + this.d = d; + + int len = n.bitLength(); + SecureRandom random = JCAUtil.getSecureRandom(); + u = new BigInteger(len, random).mod(n); + // Although the possibility is very much limited that u is zero + // or is not relatively prime to n, we still want to be careful + // about the special value. + // + // Secure random generation is expensive, try to use BigInteger.ONE + // this time if this new generated random number is zero or is not + // relatively prime to n. Next time, new generated secure random + // number will be used instead. + if (u.equals(BigInteger.ZERO)) { + u = BigInteger.ONE; // use 1 this time + } + + try { + // The call to BigInteger.modInverse() checks that u is + // relatively prime to n. Otherwise, ArithmeticException is + // thrown. + v = u.modInverse(n); + } catch (ArithmeticException ae) { + // if u is not relatively prime to n, use 1 this time + u = BigInteger.ONE; + v = BigInteger.ONE; + } + + if (e != null) { + u = u.modPow(e, n); // e: the public exponent + // u: random ^ e + // v: random ^ (-1) + } else { + v = v.modPow(d, n); // d: the private exponent + // u: random + // v: random ^ (-d) + } } - boolean valid(BigInteger e) { - int k = remainingUses--; - return (k > 0) && this.e.equals(e); + + // return null if need to reset the parameters + BlindingRandomPair getBlindingRandomPair( + BigInteger e, BigInteger d, BigInteger n) { + + if ((this.e != null && this.e.equals(e)) || + (this.d != null && this.d.equals(d))) { + + BlindingRandomPair brp = null; + synchronized (this) { + if (!u.equals(BigInteger.ZERO) && + !v.equals(BigInteger.ZERO)) { + + brp = new BlindingRandomPair(u, v); + if (u.compareTo(BigInteger.ONE) <= 0 || + v.compareTo(BigInteger.ONE) <= 0) { + + // need to reset the random pair next time + u = BigInteger.ZERO; + v = BigInteger.ZERO; + } else { + u = u.modPow(BIG_TWO, n); + v = v.modPow(BIG_TWO, n); + } + } // Otherwise, need to reset the random pair. + } + return brp; + } + + return null; } } - /** - * Return valid RSA blinding parameters for the given private key. - * Use cached parameters if available. If not, generate new parameters - * and cache. - */ - private static BlindingParameters getBlindingParameters - (RSAPrivateCrtKey key) { - BigInteger modulus = key.getModulus(); - BigInteger e = key.getPublicExponent(); - BlindingParameters params; - // we release the lock between get() and put() - // that means threads might concurrently generate new blinding - // parameters for the same modulus. this is only a slight waste - // of cycles and seems preferable in terms of scalability - // to locking out all threads while generating new parameters + private static BlindingRandomPair getBlindingRandomPair( + BigInteger e, BigInteger d, BigInteger n) { + + BlindingParameters bps = null; synchronized (blindingCache) { - params = blindingCache.get(modulus); + bps = blindingCache.get(n); } - if ((params != null) && params.valid(e)) { - return params; + + if (bps == null) { + bps = new BlindingParameters(e, d, n); + synchronized (blindingCache) { + blindingCache.putIfAbsent(n, bps); + } } - int len = modulus.bitLength(); - SecureRandom random = JCAUtil.getSecureRandom(); - BigInteger r = new BigInteger(len, random).mod(modulus); - BigInteger re = r.modPow(e, modulus); - BigInteger rInv = r.modInverse(modulus); - params = new BlindingParameters(e, re, rInv); - synchronized (blindingCache) { - blindingCache.put(modulus, params); + + BlindingRandomPair brp = bps.getBlindingRandomPair(e, d, n); + if (brp == null) { + // need to reset the blinding parameters + bps = new BlindingParameters(e, d, n); + synchronized (blindingCache) { + blindingCache.replace(n, bps); + } + brp = bps.getBlindingRandomPair(e, d, n); } - return params; + + return brp; } }
--- a/src/share/classes/sun/security/util/KeyUtil.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/classes/sun/security/util/KeyUtil.java Tue Jul 15 14:08:27 2014 -0700 @@ -272,7 +272,16 @@ "Diffie-Hellman public key is too large"); } - // Don't bother to check against the y^q mod p if safe primes are used. + // y^q mod p == 1? + // Unable to perform this check as q is unknown in this circumstance. + + // p is expected to be prime. However, it is too expensive to check + // that p is prime. Instead, in order to mitigate the impact of + // non-prime values, we check that y is not a factor of p. + BigInteger r = p.remainder(y); + if (r.equals(BigInteger.ZERO)) { + throw new InvalidKeyException("Invalid Diffie-Hellman parameters"); + } } /**
--- a/src/share/lib/security/java.security-linux Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/lib/security/java.security-linux Tue Jul 15 14:08:27 2014 -0700 @@ -210,8 +210,8 @@ org.jcp.xml.dsig.internal.,\ jdk.internal.,\ jdk.nashorn.internal.,\ - jdk.nashorn.tools. - + jdk.nashorn.tools.,\ + com.sun.activation.registries. # # List of comma-separated packages that start with or equal this string @@ -257,8 +257,8 @@ org.jcp.xml.dsig.internal.,\ jdk.internal.,\ jdk.nashorn.internal.,\ - jdk.nashorn.tools. - + jdk.nashorn.tools.,\ + com.sun.activation.registries. # # Determines whether this properties file can be appended to
--- a/src/share/lib/security/java.security-macosx Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/lib/security/java.security-macosx Tue Jul 15 14:08:27 2014 -0700 @@ -212,6 +212,7 @@ jdk.internal.,\ jdk.nashorn.internal.,\ jdk.nashorn.tools.,\ + com.sun.activation.registries.,\ apple. # @@ -259,6 +260,7 @@ jdk.internal.,\ jdk.nashorn.internal.,\ jdk.nashorn.tools.,\ + com.sun.activation.registries.,\ apple. #
--- a/src/share/lib/security/java.security-solaris Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/lib/security/java.security-solaris Tue Jul 15 14:08:27 2014 -0700 @@ -212,7 +212,8 @@ org.jcp.xml.dsig.internal.,\ jdk.internal.,\ jdk.nashorn.internal.,\ - jdk.nashorn.tools. + jdk.nashorn.tools.,\ + com.sun.activation.registries. # # List of comma-separated packages that start with or equal this string @@ -258,7 +259,8 @@ org.jcp.xml.dsig.internal.,\ jdk.internal.,\ jdk.nashorn.internal.,\ - jdk.nashorn.tools. + jdk.nashorn.tools.,\ + com.sun.activation.registries. # # Determines whether this properties file can be appended to
--- a/src/share/lib/security/java.security-windows Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/lib/security/java.security-windows Tue Jul 15 14:08:27 2014 -0700 @@ -212,6 +212,7 @@ jdk.internal.,\ jdk.nashorn.internal.,\ jdk.nashorn.tools.,\ + com.sun.activation.registries.,\ com.sun.java.accessibility. # @@ -259,6 +260,7 @@ jdk.internal.,\ jdk.nashorn.internal.,\ jdk.nashorn.tools.,\ + com.sun.activation.registries.,\ com.sun.java.accessibility. #
--- a/src/share/native/com/sun/java/util/jar/pack/defines.h Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/native/com/sun/java/util/jar/pack/defines.h Tue Jul 15 14:08:27 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, 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 @@ -79,6 +79,7 @@ #define ERROR_RESOURCE "Cannot extract resource file" #define ERROR_OVERFLOW "Internal buffer overflow" #define ERROR_INTERNAL "Internal error" +#define ERROR_INIT "cannot init class members" #define LOGFILE_STDOUT "-" #define LOGFILE_STDERR ""
--- a/src/share/native/com/sun/java/util/jar/pack/jni.cpp Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/native/com/sun/java/util/jar/pack/jni.cpp Tue Jul 15 14:08:27 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, 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 @@ -56,6 +56,45 @@ #define THROW_IOE(x) JNU_ThrowIOException(env,x) +#define CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(CERVTI_exception, CERVTI_message) \ + do { \ + if ((env)->ExceptionOccurred()) { \ + THROW_IOE(CERVTI_message); \ + return; \ + } \ + if ((CERVTI_exception) == NULL) { \ + THROW_IOE(CERVTI_message); \ + return; \ + } \ + } while (JNI_FALSE) + + +#define CHECK_EXCEPTION_RETURN_VALUE(CERL_exception, CERL_return_value) \ + do { \ + if ((env)->ExceptionOccurred()) { \ + return CERL_return_value; \ + } \ + if ((CERL_exception) == NULL) { \ + return CERL_return_value; \ + } \ + } while (JNI_FALSE) + + +// If these useful macros aren't defined in jni_util.h then define them here +#ifndef CHECK_NULL_RETURN +#define CHECK_NULL_RETURN(x, y) \ + do { \ + if ((x) == NULL) return (y); \ + } while (JNI_FALSE) +#endif + +#ifndef CHECK_EXCEPTION_RETURN +#define CHECK_EXCEPTION_RETURN(env, y) \ + do { \ + if ((*env)->ExceptionCheck(env)) return (y); \ + } while (JNI_FALSE) +#endif + static jlong read_input_via_jni(unpacker* self, void* buf, jlong minlen, jlong maxlen); @@ -92,9 +131,11 @@ vm->GetEnv(&envRaw, JNI_VERSION_1_1); JNIEnv* env = (JNIEnv*) envRaw; //fprintf(stderr, "get_unpacker() env=%p\n", env); - if (env == null) - return null; + CHECK_NULL_RETURN(env, NULL); jobject pObj = env->CallStaticObjectMethod(NIclazz, currentInstMID); + // We should check upon the known non-null variable because here we want to check + // only for pending exceptions. If pObj is null we'll deal with it later. + CHECK_EXCEPTION_RETURN_VALUE(env, NULL); //fprintf(stderr, "get_unpacker0() pObj=%p\n", pObj); if (pObj != null) { // Got pObj and env; now do it the easy way. @@ -137,20 +178,20 @@ while( dbg != null) { sleep(10); } #endif NIclazz = (jclass) env->NewGlobalRef(clazz); + unpackerPtrFID = env->GetFieldID(clazz, "unpackerPtr", "J"); + CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(unpackerPtrFID, ERROR_INIT); + currentInstMID = env->GetStaticMethodID(clazz, "currentInstance", "()Ljava/lang/Object;"); + CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(currentInstMID, ERROR_INIT); + readInputMID = env->GetMethodID(clazz, "readInputFn", "(Ljava/nio/ByteBuffer;J)J"); - getUnpackerPtrMID = env->GetMethodID(clazz, "getUnpackerPtr", "()J"); + CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(readInputMID, ERROR_INIT); - if (unpackerPtrFID == null || - currentInstMID == null || - readInputMID == null || - NIclazz == null || - getUnpackerPtrMID == null) { - THROW_IOE("cannot init class members"); - } + getUnpackerPtrMID = env->GetMethodID(clazz, "getUnpackerPtr", "()J"); + CHECK_EXCEPTION_RETURN_VOID_THROW_IOE(getUnpackerPtrMID, ERROR_INIT); } JNIEXPORT jlong JNICALL @@ -160,9 +201,7 @@ // valid object pointers and env is intact, if not now is good time to bail. unpacker* uPtr = get_unpacker(); //fprintf(stderr, "start(%p) uPtr=%p initializing\n", pObj, uPtr); - if (uPtr == null) { - return -1; - } + CHECK_EXCEPTION_RETURN_VALUE(uPtr, -1); // redirect our io to the default log file or whatever. uPtr->redirect_stdio(); @@ -200,6 +239,7 @@ jobjectArray pParts) { unpacker* uPtr = get_unpacker(env, pObj); + CHECK_EXCEPTION_RETURN_VALUE(uPtr, false); unpacker::file* filep = uPtr->get_next_file(); if (uPtr->aborting()) { @@ -207,32 +247,38 @@ return false; } - if (filep == null) { - return false; // end of the sequence - } + CHECK_NULL_RETURN(filep, false); assert(filep == &uPtr->cur_file); int pidx = 0, iidx = 0; jintArray pIntParts = (jintArray) env->GetObjectArrayElement(pParts, pidx++); + CHECK_EXCEPTION_RETURN_VALUE(pIntParts, false); jint* intParts = env->GetIntArrayElements(pIntParts, null); intParts[iidx++] = (jint)( (julong)filep->size >> 32 ); intParts[iidx++] = (jint)( (julong)filep->size >> 0 ); intParts[iidx++] = filep->modtime; intParts[iidx++] = filep->deflate_hint() ? 1 : 0; env->ReleaseIntArrayElements(pIntParts, intParts, JNI_COMMIT); - - env->SetObjectArrayElement(pParts, pidx++, env->NewStringUTF(filep->name)); - + jstring filename = env->NewStringUTF(filep->name); + CHECK_EXCEPTION_RETURN_VALUE(filename, false); + env->SetObjectArrayElement(pParts, pidx++, filename); + CHECK_EXCEPTION_RETURN_VALUE(uPtr, false); jobject pDataBuf = null; - if (filep->data[0].len > 0) + if (filep->data[0].len > 0) { pDataBuf = env->NewDirectByteBuffer(filep->data[0].ptr, filep->data[0].len); + CHECK_EXCEPTION_RETURN_VALUE(pDataBuf, false); + } env->SetObjectArrayElement(pParts, pidx++, pDataBuf); + CHECK_EXCEPTION_RETURN_VALUE(uPtr, false); pDataBuf = null; - if (filep->data[1].len > 0) + if (filep->data[1].len > 0) { pDataBuf = env->NewDirectByteBuffer(filep->data[1].ptr, filep->data[1].len); + CHECK_EXCEPTION_RETURN_VALUE(pDataBuf, false); + } env->SetObjectArrayElement(pParts, pidx++, pDataBuf); + CHECK_EXCEPTION_RETURN_VALUE(uPtr, false); return true; } @@ -241,6 +287,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_java_util_jar_pack_NativeUnpack_getUnusedInput(JNIEnv *env, jobject pObj) { unpacker* uPtr = get_unpacker(env, pObj); + CHECK_EXCEPTION_RETURN_VALUE(uPtr, NULL); unpacker::file* filep = &uPtr->cur_file; if (uPtr->aborting()) { @@ -263,7 +310,7 @@ JNIEXPORT jlong JNICALL Java_com_sun_java_util_jar_pack_NativeUnpack_finish(JNIEnv *env, jobject pObj) { unpacker* uPtr = get_unpacker(env, pObj, false); - if (uPtr == null) return 0; + CHECK_EXCEPTION_RETURN_VALUE(uPtr, NULL); size_t consumed = uPtr->input_consumed(); free_unpacker(env, pObj, uPtr); return consumed; @@ -274,7 +321,9 @@ jstring pProp, jstring pValue) { unpacker* uPtr = get_unpacker(env, pObj); const char* prop = env->GetStringUTFChars(pProp, JNI_FALSE); + CHECK_EXCEPTION_RETURN_VALUE(prop, false); const char* value = env->GetStringUTFChars(pValue, JNI_FALSE); + CHECK_EXCEPTION_RETURN_VALUE(value, false); jboolean retval = uPtr->set_option(prop, value); env->ReleaseStringUTFChars(pProp, prop); env->ReleaseStringUTFChars(pValue, value); @@ -286,9 +335,11 @@ jstring pProp) { unpacker* uPtr = get_unpacker(env, pObj); + CHECK_EXCEPTION_RETURN_VALUE(uPtr, NULL); const char* prop = env->GetStringUTFChars(pProp, JNI_FALSE); + CHECK_EXCEPTION_RETURN_VALUE(prop, NULL); const char* value = uPtr->get_option(prop); + CHECK_EXCEPTION_RETURN_VALUE(value, NULL); env->ReleaseStringUTFChars(pProp, prop); - if (value == null) return null; return env->NewStringUTF(value); }
--- a/src/share/native/sun/awt/medialib/awt_ImagingLib.c Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/native/sun/awt/medialib/awt_ImagingLib.c Tue Jul 15 14:08:27 2014 -0700 @@ -373,14 +373,14 @@ /* Parse the source image */ - if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) { + if (awt_parseImage(env, jsrc, &srcImageP, FALSE) <= 0) { /* Can't handle any custom images */ free(dkern); return 0; } /* Parse the destination image */ - if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) { + if (awt_parseImage(env, jdst, &dstImageP, FALSE) <= 0) { /* Can't handle any custom images */ awt_freeParsedImage(srcImageP, TRUE); free(dkern); @@ -627,7 +627,7 @@ } /* Parse the source raster */ - if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) { + if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) { /* Can't handle any custom rasters */ free(srcRasterP); free(dstRasterP); @@ -636,7 +636,7 @@ } /* Parse the destination raster */ - if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) { + if (awt_parseRaster(env, jdst, dstRasterP) <= 0) { /* Can't handle any custom images */ awt_freeParsedRaster(srcRasterP, TRUE); free(dstRasterP); @@ -839,13 +839,13 @@ (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT); /* Parse the source image */ - if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) { + if (awt_parseImage(env, jsrc, &srcImageP, FALSE) <= 0) { /* Can't handle any custom images */ return 0; } /* Parse the destination image */ - if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) { + if (awt_parseImage(env, jdst, &dstImageP, FALSE) <= 0) { /* Can't handle any custom images */ awt_freeParsedImage(srcImageP, TRUE); return 0; @@ -1059,7 +1059,7 @@ (*env)->ReleasePrimitiveArrayCritical(env, jmatrix, matrix, JNI_ABORT); /* Parse the source raster */ - if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) { + if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) { /* Can't handle any custom rasters */ free(srcRasterP); free(dstRasterP); @@ -1067,7 +1067,7 @@ } /* Parse the destination raster */ - if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) { + if (awt_parseRaster(env, jdst, dstRasterP) <= 0) { /* Can't handle any custom images */ awt_freeParsedRaster(srcRasterP, TRUE); free(dstRasterP); @@ -1306,13 +1306,13 @@ if (s_timeIt) (*start_timer)(3600); /* Parse the source image */ - if ((status = awt_parseImage(env, jsrc, &srcImageP, FALSE)) <= 0) { + if (awt_parseImage(env, jsrc, &srcImageP, FALSE) <= 0) { /* Can't handle any custom images */ return 0; } /* Parse the destination image */ - if ((status = awt_parseImage(env, jdst, &dstImageP, FALSE)) <= 0) { + if (awt_parseImage(env, jdst, &dstImageP, FALSE) <= 0) { /* Can't handle any custom images */ awt_freeParsedImage(srcImageP, TRUE); return 0; @@ -1554,14 +1554,14 @@ } /* Parse the source raster - reject custom images */ - if ((status = awt_parseRaster(env, jsrc, srcRasterP)) <= 0) { + if (awt_parseRaster(env, jsrc, srcRasterP) <= 0) { free(srcRasterP); free(dstRasterP); return 0; } /* Parse the destination image - reject custom images */ - if ((status = awt_parseRaster(env, jdst, dstRasterP)) <= 0) { + if (awt_parseRaster(env, jdst, dstRasterP) <= 0) { awt_freeParsedRaster(srcRasterP, TRUE); free(dstRasterP); return 0;
--- a/src/share/native/sun/font/freetypeScaler.c Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/native/sun/font/freetypeScaler.c Tue Jul 15 14:08:27 2014 -0700 @@ -177,18 +177,10 @@ if (numBytes > FILEDATACACHESIZE) { bBuffer = (*env)->NewDirectByteBuffer(env, destBuffer, numBytes); if (bBuffer != NULL) { - /* Loop until the read succeeds (or EOF). - * This should improve robustness in the event of a problem in - * the I/O system. If we find that we ever end up spinning here - * we are going to have to do some serious work to recover. - * Just returning without reading the data will cause a crash. - */ - while (bread == 0) { - bread = (*env)->CallIntMethod(env, - scalerInfo->font2D, - sunFontIDs.ttReadBlockMID, - bBuffer, offset, numBytes); - } + bread = (*env)->CallIntMethod(env, + scalerInfo->font2D, + sunFontIDs.ttReadBlockMID, + bBuffer, offset, numBytes); return bread; } else { /* We probably hit bug bug 4845371. For reasons that @@ -224,19 +216,10 @@ (offset + FILEDATACACHESIZE > scalerInfo->fileSize) ? scalerInfo->fileSize - offset : FILEDATACACHESIZE; bBuffer = scalerInfo->directBuffer; - /* Loop until all the read succeeds (or EOF). - * This should improve robustness in the event of a problem in - * the I/O system. If we find that we ever end up spinning here - * we are going to have to do some serious work to recover. - * Just returning without reading the data will cause a crash. - */ - while (bread == 0) { - bread = (*env)->CallIntMethod(env, scalerInfo->font2D, - sunFontIDs.ttReadBlockMID, - bBuffer, offset, - scalerInfo->fontDataLength); - } - + bread = (*env)->CallIntMethod(env, scalerInfo->font2D, + sunFontIDs.ttReadBlockMID, + bBuffer, offset, + scalerInfo->fontDataLength); memcpy(destBuffer, scalerInfo->fontData, numBytes); return numBytes; }
--- a/src/share/native/sun/management/GcInfoBuilder.c Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/native/sun/management/GcInfoBuilder.c Tue Jul 15 14:08:27 2014 -0700 @@ -190,7 +190,7 @@ if (ext_att_count <= 0) { JNU_ThrowIllegalArgumentException(env, "Invalid ext_att_count"); - return; + return 0; } gc_stat.usage_before_gc = usageBeforeGC;
--- a/src/share/native/sun/security/ec/ECC_JNI.cpp Tue Jul 15 02:00:52 2014 +0400 +++ b/src/share/native/sun/security/ec/ECC_JNI.cpp Tue Jul 15 14:08:27 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2014, 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 @@ -64,22 +64,40 @@ free(ecparams); } +jbyteArray getEncodedBytes(JNIEnv *env, SECItem *hSECItem) +{ + SECItem *s = (SECItem *)hSECItem; + + jbyteArray jEncodedBytes = env->NewByteArray(s->len); + if (jEncodedBytes == NULL) { + return NULL; + } + // Copy bytes from a native SECItem buffer to Java byte array + env->SetByteArrayRegion(jEncodedBytes, 0, s->len, (jbyte *)s->data); + if (env->ExceptionCheck()) { // should never happen + return NULL; + } + return jEncodedBytes; +} + + /* * Class: sun_security_ec_ECKeyPairGenerator * Method: generateECKeyPair - * Signature: (I[B[B)[J + * Signature: (I[B[B)[[B */ -JNIEXPORT jlongArray +JNIEXPORT jobjectArray JNICALL Java_sun_security_ec_ECKeyPairGenerator_generateECKeyPair (JNIEnv *env, jclass clazz, jint keySize, jbyteArray encodedParams, jbyteArray seed) { - ECPrivateKey *privKey; /* contains both public and private values */ + ECPrivateKey *privKey = NULL; // contains both public and private values ECParams *ecparams = NULL; SECKEYECParams params_item; jint jSeedLength; jbyte* pSeedBuffer = NULL; - jlongArray result = NULL; - jlong* resultElements = NULL; + jobjectArray result = NULL; + jclass baCls = NULL; + jbyteArray jba; // Initialize the ECParams struct params_item.len = env->GetArrayLength(encodedParams); @@ -106,61 +124,61 @@ } jboolean isCopy; - result = env->NewLongArray(2); - resultElements = env->GetLongArrayElements(result, &isCopy); + baCls = env->FindClass("[B"); + if (baCls == NULL) { + goto cleanup; + } + result = env->NewObjectArray(2, baCls, NULL); + if (result == NULL) { + goto cleanup; + } + jba = getEncodedBytes(env, &(privKey->privateValue)); + if (jba == NULL) { + result = NULL; + goto cleanup; + } + env->SetObjectArrayElement(result, 0, jba); // big integer + if (env->ExceptionCheck()) { // should never happen + result = NULL; + goto cleanup; + } - resultElements[0] = (jlong) &(privKey->privateValue); // private big integer - resultElements[1] = (jlong) &(privKey->publicValue); // encoded ec point - - // If the array is a copy then we must write back our changes - if (isCopy == JNI_TRUE) { - env->ReleaseLongArrayElements(result, resultElements, 0); + jba = getEncodedBytes(env, &(privKey->publicValue)); + if (jba == NULL) { + result = NULL; + goto cleanup; + } + env->SetObjectArrayElement(result, 1, jba); // encoded ec point + if (env->ExceptionCheck()) { // should never happen + result = NULL; + goto cleanup; } cleanup: { - if (params_item.data) + if (params_item.data) { env->ReleaseByteArrayElements(encodedParams, (jbyte *) params_item.data, JNI_ABORT); - - if (ecparams) + } + if (ecparams) { FreeECParams(ecparams, true); - + } if (privKey) { FreeECParams(&privKey->ecParams, false); SECITEM_FreeItem(&privKey->version, B_FALSE); - // Don't free privKey->privateValue and privKey->publicValue + SECITEM_FreeItem(&privKey->privateValue, B_FALSE); + SECITEM_FreeItem(&privKey->publicValue, B_FALSE); + free(privKey); } - - if (pSeedBuffer) + if (pSeedBuffer) { delete [] pSeedBuffer; + } } return result; } /* - * Class: sun_security_ec_ECKeyPairGenerator - * Method: getEncodedBytes - * Signature: (J)[B - */ -JNIEXPORT jbyteArray -JNICALL Java_sun_security_ec_ECKeyPairGenerator_getEncodedBytes - (JNIEnv *env, jclass clazz, jlong hSECItem) -{ - SECItem *s = (SECItem *)hSECItem; - jbyteArray jEncodedBytes = env->NewByteArray(s->len); - - // Copy bytes from a native SECItem buffer to Java byte array - env->SetByteArrayRegion(jEncodedBytes, 0, s->len, (jbyte *)s->data); - - // Use B_FALSE to free only the SECItem->data - SECITEM_FreeItem(s, B_FALSE); - - return jEncodedBytes; -} - -/* * Class: sun_security_ec_ECDSASignature * Method: signDigest * Signature: ([B[B[B[B)[B @@ -234,21 +252,26 @@ cleanup: { - if (params_item.data) + if (params_item.data) { env->ReleaseByteArrayElements(encodedParams, (jbyte *) params_item.data, JNI_ABORT); - - if (pDigestBuffer) + } + if (privKey.privateValue.data) { + env->ReleaseByteArrayElements(privateKey, + (jbyte *) privKey.privateValue.data, JNI_ABORT); + } + if (pDigestBuffer) { delete [] pDigestBuffer; - - if (pSignedDigestBuffer) + } + if (pSignedDigestBuffer) { delete [] pSignedDigestBuffer; - - if (pSeedBuffer) + } + if (pSeedBuffer) { delete [] pSeedBuffer; - - if (ecparams) + } + if (ecparams) { FreeECParams(ecparams, true); + } } return jSignedDigest;
--- a/src/windows/bin/java_md.c Tue Jul 15 02:00:52 2014 +0400 +++ b/src/windows/bin/java_md.c Tue Jul 15 14:08:27 2014 -0700 @@ -1306,6 +1306,14 @@ /* save path length */ jrePathLen = JLI_StrLen(libraryPath); + if (jrePathLen + JLI_StrLen("\\bin\\verify.dll") >= MAXPATHLEN) { + /* jre path is too long, the library path will not fit there; + * report and abort preloading + */ + JLI_ReportErrorMessage(JRE_ERROR11); + break; + } + /* load msvcrt 1st */ LoadMSVCRT();
--- a/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java Tue Jul 15 14:08:27 2014 -0700 @@ -583,11 +583,18 @@ // Needs to be accessible to Win32ShellFolderManager2 static String getFileSystemPath(final int csidl) throws IOException, InterruptedException { - return invoke(new Callable<String>() { + String path = invoke(new Callable<String>() { public String call() throws IOException { return getFileSystemPath0(csidl); } }, IOException.class); + if (path != null) { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkRead(path); + } + } + return path; } // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
--- a/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java Tue Jul 15 14:08:27 2014 -0700 @@ -136,6 +136,8 @@ if (desktop == null) { try { desktop = new Win32ShellFolder2(DESKTOP); + } catch (SecurityException e) { + // Ignore error } catch (IOException e) { // Ignore error } catch (InterruptedException e) { @@ -149,6 +151,8 @@ if (drives == null) { try { drives = new Win32ShellFolder2(DRIVES); + } catch (SecurityException e) { + // Ignore error } catch (IOException e) { // Ignore error } catch (InterruptedException e) { @@ -165,6 +169,8 @@ if (path != null) { recent = createShellFolder(getDesktop(), new File(path)); } + } catch (SecurityException e) { + // Ignore error } catch (InterruptedException e) { // Ignore error } catch (IOException e) { @@ -178,6 +184,8 @@ if (network == null) { try { network = new Win32ShellFolder2(NETWORK); + } catch (SecurityException e) { + // Ignore error } catch (IOException e) { // Ignore error } catch (InterruptedException e) { @@ -201,6 +209,8 @@ personal.setIsPersonal(); } } + } catch (SecurityException e) { + // Ignore error } catch (InterruptedException e) { // Ignore error } catch (IOException e) {
--- a/src/windows/classes/sun/awt/windows/ThemeReader.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/windows/classes/sun/awt/windows/ThemeReader.java Tue Jul 15 14:08:27 2014 -0700 @@ -60,18 +60,12 @@ new ReentrantReadWriteLock(); private static final Lock readLock = readWriteLock.readLock(); private static final Lock writeLock = readWriteLock.writeLock(); + private static volatile boolean valid = false; static void flush() { - writeLock.lock(); - try { - // Close old themes. - for (Long value : widgetToTheme.values()) { - closeTheme(value.longValue()); - } - widgetToTheme.clear(); - } finally { - writeLock.unlock(); - } + // Could be called on Toolkit thread, so do not try to aquire locks + // to avoid deadlock with theme initialization + valid = false; } public static native boolean isThemed(); @@ -98,6 +92,24 @@ // returns theme value // this method should be invoked with readLock locked private static Long getTheme(String widget) { + if (!valid) { + readLock.unlock(); + writeLock.lock(); + try { + if (!valid) { + // Close old themes. + for (Long value : widgetToTheme.values()) { + closeTheme(value); + } + widgetToTheme.clear(); + valid = true; + } + } finally { + readLock.lock(); + writeLock.unlock(); + } + } + // mostly copied from the javadoc for ReentrantReadWriteLock Long theme = widgetToTheme.get(widget); if (theme == null) {
--- a/src/windows/classes/sun/awt/windows/WToolkit.java Tue Jul 15 02:00:52 2014 +0400 +++ b/src/windows/classes/sun/awt/windows/WToolkit.java Tue Jul 15 14:08:27 2014 -0700 @@ -38,6 +38,7 @@ import java.security.PrivilegedAction; import sun.awt.AWTAutoShutdown; import sun.awt.LightweightFrame; +import sun.awt.AppContext; import sun.awt.SunToolkit; import sun.misc.ThreadGroupUtils; import sun.awt.Win32GraphicsDevice; @@ -579,7 +580,6 @@ /** * Returns <code>true</code> if this frame state is supported. */ - @Override public boolean isFrameStateSupported(int state) { switch (state) { case Frame.NORMAL: @@ -929,12 +929,16 @@ * Windows doesn't always send WM_SETTINGCHANGE when it should. */ private void windowsSettingChange() { - EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - updateProperties(); - } - }); + if (AppContext.getAppContext() == null) { + // We cannot post the update to any EventQueue. Listeners will + // be called on EDTs by DesktopPropertyChangeSupport + updateProperties(); + } else { + // Cannot update on Toolkit thread. + // DesktopPropertyChangeSupport will call listeners on Toolkit + // thread if it has AppContext (standalone mode) + EventQueue.invokeLater(this::updateProperties); + } } private synchronized void updateProperties() { @@ -974,7 +978,6 @@ * initialize only static props here and do not try to initialize props which depends on wprops, * this should be done in lazilyLoadDesktopProperty() only. */ - @Override protected synchronized void initializeDesktopProperties() { desktopProperties.put("DnD.Autoscroll.initialDelay", Integer.valueOf(50));
--- a/test/java/lang/SecurityManager/CheckPackageAccess.java Tue Jul 15 02:00:52 2014 +0400 +++ b/test/java/lang/SecurityManager/CheckPackageAccess.java Tue Jul 15 14:08:27 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 6741606 7146431 8000450 8019830 8022945 + * @bug 6741606 7146431 8000450 8019830 8022945 8027144 8041633 * @summary Make sure all restricted packages listed in the package.access * property in the java.security file are blocked * @run main/othervm CheckPackageAccess @@ -84,7 +84,8 @@ "org.jcp.xml.dsig.internal.", "jdk.internal.", "jdk.nashorn.internal.", - "jdk.nashorn.tools." + "jdk.nashorn.tools.", + "com.sun.activation.registries." }; public static void main(String[] args) throws Exception {
--- a/test/javax/management/remote/mandatory/util/CacheMapTest.java Tue Jul 15 02:00:52 2014 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2003, 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 7654321 - * @summary Tests the CacheMap class. - * @author Eamonn McManus - * @run clean CacheMapTest - * @run build CacheMapTest - * @run main CacheMapTest - */ - -import java.util.Iterator; -import java.util.Map; - -import com.sun.jmx.remote.util.CacheMap; - -public class CacheMapTest { - public static void main(String[] args) { - try { - boolean ok = test(5) && test(100); - if (ok) { - System.out.println("Test completed"); - return; - } else { - System.out.println("Test failed!"); - System.exit(1); - } - } catch (Exception e) { - System.err.println("Unexpected exception: " + e); - e.printStackTrace(); - System.exit(1); - } - } - - private static boolean test(int cacheSize) throws Exception { - System.out.println("CacheMap test with cache size " + cacheSize); - CacheMap map = new CacheMap(cacheSize); - int size = 0; - int maxIterations = cacheSize * 10; - while (map.size() == size && size < maxIterations) { - Integer key = new Integer(size); - Object x = map.put(key, "x"); - if (x != null) { - System.out.println("Map already had entry " + key + "!"); - return false; - } - x = map.get(key); - if (!"x".equals(x)) { - System.out.println("Got back surprising value: " + x); - return false; - } - size++; - } - System.out.println("Map size is " + map.size() + " after inserting " + - size + " elements"); - do { - System.gc(); - Thread.sleep(1); - System.out.println("Map size is " + map.size() + " after GC"); - } while (map.size() > cacheSize); - if (map.size() < cacheSize) { - System.out.println("Map shrank to less than cache size: " + - map.size() + " (surprising but not wrong)"); - } else - System.out.println("Map shrank to cache size as expected"); - int lowest = size - cacheSize; - // lowest value that can still be in cache if LRU is respected - for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) { - Map.Entry entry = (Map.Entry) it.next(); - Integer x = (Integer) entry.getKey(); - int xx = x.intValue(); - if (xx < lowest || xx >= size) { - System.out.println("Old value remained (" + x + "), " + - "expected none earlier than " + lowest); - return false; - } - Object xxx = entry.getValue(); - if (!"x".equals(xxx)) { - System.out.println("Got back surprising value: " + xxx); - return false; - } - } - if (map.size() > 0) - System.out.println("Remaining elements are the most recent ones"); - System.out.println("Test passed"); - return true; - } -}