diff --git a/.hgtags b/.hgtags index e5dc359bc9d0134f3011539695e74d66e78fb05e..1969dad466dbdbcc0f39ab95af1c41fce46eb2e0 100644 --- a/.hgtags +++ b/.hgtags @@ -358,6 +358,7 @@ a21dd7999d1e4ba612c951c2c78504d23eb7243a jdk8u31-b11 ced84cf3eebc69f7e04b0098d85dcb3a6b872586 jdk8u31-b31 46338075c4262057099e57638e0758817052da0d jdk8u31-b32 a1c3099e1b90230435e890ca56adc8a5aa5149ff jdk8u31-b33 +35dfb86684554685d6efd2fc7fd5eb9b7d4545c5 jdk8u31-b34 e6ed015afbbf3459ba3297e270b4f3170e989c80 jdk8u40-b00 6e223d48080ef40f4ec11ecbcd19b4a20813b9eb jdk8u40-b01 4797cd0713b44b009525f1276d571ade7e24f3f5 jdk8u40-b02 @@ -429,6 +430,8 @@ b7403e15864dc0c1f9740d66af91bddb3e2215e8 jdk8u51-b14 192bda44c0c463104c96058bb815a546b282ca43 jdk8u51-b15 ee86422973691bb7efae58d201e5a382ea0bb150 jdk8u51-b16 f94ea276f608b22d78281d70361092ba4864038e jdk8u51-b31 +887dde3afb3bb233958775de22eafb3328af6437 jdk8u51-b32 +dc7b827522bc3a804f7e8951cc27414f19a7c427 jdk8u51-b33 5c31204d19e5976f025026db3d5c17331e8c44db jdk8u60-b00 c46daef6edb5385d11876ed40f292a4b62e96867 jdk8u60-b01 c10fd784956cc7099657181029ac3e790267b678 jdk8u60-b02 @@ -457,6 +460,8 @@ d433f5fd8910bee1f2c295b65cf03977034fe0ea jdk8u60-b24 c8cfbe57bcd5042d2fef42dcef14d73dd4bdc416 jdk8u60-b25 0d6a8a9b26a37678b420ff540b5a622c3f4fd44c jdk8u60-b26 afbc08ea922bf6e5e14d2eea24a2f94f37627ea7 jdk8u60-b27 +1450696a76c667e6f189d026408182a002b93fa7 jdk8u60-b31 +fe24fa1e6d995390df6491975352a15634981b35 jdk8u60-b32 286b9a885fcc6245fdf2b20697473ec3b35f2538 jdk8u65-b00 80a796d0db958f49a4b0713818227eda8e5efbb9 jdk8u65-b01 77d48e6d111faec236c8678997ae4311151cfee4 jdk8u65-b02 @@ -489,6 +494,14 @@ e951c898bb6ca7be2ce49ac23f8442c0bccad4e9 jdk8u66-b13 ea602badedd0cd0c352c072220a884e8f1335e33 jdk8u66-b15 5ceafca6a734e13d51319df6afd40678d68f9851 jdk8u66-b16 e6d562c0f079dfd1e21c3734b2dca16f4b2e2494 jdk8u66-b17 +f712dceafb546ea5833aeea507b5736e7e45f1ae jdk8u66-b31 +9a2747ef337bdee71bc8225dea77eb403cca1179 jdk8u71-b00 +e8b5e10a19d66a77d04f12d4677e6fec66f79651 jdk8u71-b01 +25d689a73bc037e1710f95f6d4acf0671d22047d jdk8u71-b02 +ab54163c8610f6238a1d5f1f67cbd19ba13d08a0 jdk8u71-b03 +5ea62bb625b6b8f828098884d13eb2e3114a7c97 jdk8u71-b04 +1a9ced1852957b65e0c156602c3101aff17274fb jdk8u71-b05 +be9d91d310a02c2974d2bdabc31d8a6df8ad596e jdk8u71-b06 be5faa9c77042f202106c18f4e8ea211137b4a3b jdk8u72-b00 5ad1e9e8e8417f80c91d7e0f1f44cdf89b34ead3 jdk8u72-b01 ab0c1040414d038ccbcfcc8ceb1ccf2f44ead8e4 jdk8u72-b02 diff --git a/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java b/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java index 4530fff6976beb9fe6443a83563ac5f7371889b1..4de4d57899dcf82a7ebc666a630dfd46f8e53cc0 100644 --- a/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java +++ b/src/macosx/classes/sun/lwawt/macosx/CPrinterJob.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -234,6 +234,11 @@ public final class CPrinterJob extends RasterPrinterJob { // this will not work if the user clicks on the "Preview" button // However if the printer is a StreamPrintService, its the right path. PrintService psvc = getPrintService(); + + if (psvc == null) { + throw new PrinterException("No print service found."); + } + if (psvc instanceof StreamPrintService) { spoolToService(psvc, attributes); return; @@ -775,4 +780,4 @@ public final class CPrinterJob extends RasterPrinterJob { (float) (paper.getImageableHeight() / dpi), MediaPrintableArea.INCH); } -} \ No newline at end of file +} diff --git a/src/share/classes/com/sun/crypto/provider/PBES2Core.java b/src/share/classes/com/sun/crypto/provider/PBES2Core.java index 51c49b500ab89390c703c6e22c8f91920339000e..37873666ebaad6cbd21c3e37b6009d5322f2605d 100644 --- a/src/share/classes/com/sun/crypto/provider/PBES2Core.java +++ b/src/share/classes/com/sun/crypto/provider/PBES2Core.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -263,7 +263,7 @@ abstract class PBES2Core extends CipherSpi { passwdChars[i] = (char) (passwdBytes[i] & 0x7f); PBEKeySpec pbeSpec = - new PBEKeySpec(passwdChars, salt, iCount, blkSize * 8); + new PBEKeySpec(passwdChars, salt, iCount, keyLength); // password char[] was cloned in PBEKeySpec constructor, // so we can zero it out here java.util.Arrays.fill(passwdChars, ' '); diff --git a/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java b/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java index 2a25cb64d5cbc279edfa038121a489086442ac38..66dd8620c438cf4c80bc5e7d536c965191363689 100644 --- a/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java +++ b/src/share/classes/com/sun/crypto/provider/TlsRsaPremasterSecretGenerator.java @@ -74,11 +74,14 @@ public final class TlsRsaPremasterSecretGenerator extends KeyGeneratorSpi { "TlsRsaPremasterSecretGenerator must be initialized"); } - if (random == null) { - random = new SecureRandom(); + byte[] b = spec.getEncodedSecret(); + if (b == null) { + if (random == null) { + random = new SecureRandom(); + } + b = new byte[48]; + random.nextBytes(b); } - byte[] b = new byte[48]; - random.nextBytes(b); b[0] = (byte)spec.getMajorVersion(); b[1] = (byte)spec.getMinorVersion(); diff --git a/src/share/classes/java/net/URL.java b/src/share/classes/java/net/URL.java index 1ff5d63a35a2e8d29ab8e2cf3cee1fda9049e54b..a6cbcbc4f9d9a0a3c2c90b545d77a211b674b624 100644 --- a/src/share/classes/java/net/URL.java +++ b/src/share/classes/java/net/URL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,10 @@ package java.net; import java.io.IOException; import java.io.InputStream; +import java.io.InvalidObjectException; +import java.io.ObjectStreamException; +import java.io.ObjectStreamField; +import java.io.ObjectInputStream.GetField; import java.util.Hashtable; import java.util.StringTokenizer; import sun.security.util.SecurityConstants; @@ -135,6 +139,7 @@ import sun.security.util.SecurityConstants; */ public final class URL implements java.io.Serializable { + static final String BUILTIN_HANDLERS_PREFIX = "sun.net.www.protocol"; static final long serialVersionUID = -7627629688361524110L; /** @@ -219,6 +224,8 @@ public final class URL implements java.io.Serializable { */ private int hashCode = -1; + private transient UrlDeserializedState tempState; + /** * Creates a {@code URL} object from the specified * {@code protocol}, {@code host}, {@code port} @@ -1219,6 +1226,31 @@ public final class URL implements java.io.Serializable { } + /** + * @serialField protocol String + * + * @serialField host String + * + * @serialField port int + * + * @serialField authority String + * + * @serialField file String + * + * @serialField ref String + * + * @serialField hashCode int + * + */ + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("protocol", String.class), + new ObjectStreamField("host", String.class), + new ObjectStreamField("port", int.class), + new ObjectStreamField("authority", String.class), + new ObjectStreamField("file", String.class), + new ObjectStreamField("ref", String.class), + new ObjectStreamField("hashCode", int.class), }; + /** * WriteObject is called to save the state of the URL to an * ObjectOutputStream. The handler is not saved since it is @@ -1241,16 +1273,67 @@ public final class URL implements java.io.Serializable { * stream handler. */ private synchronized void readObject(java.io.ObjectInputStream s) - throws IOException, ClassNotFoundException - { - s.defaultReadObject(); // read the fields - if ((handler = getURLStreamHandler(protocol)) == null) { + throws IOException, ClassNotFoundException { + GetField gf = s.readFields(); + String protocol = (String)gf.get("protocol", null); + if (getURLStreamHandler(protocol) == null) { throw new IOException("unknown protocol: " + protocol); } + String host = (String)gf.get("host", null); + int port = gf.get("port", -1); + String authority = (String)gf.get("authority", null); + String file = (String)gf.get("file", null); + String ref = (String)gf.get("ref", null); + int hashCode = gf.get("hashCode", -1); + if (authority == null + && ((host != null && host.length() > 0) || port != -1)) { + if (host == null) + host = ""; + authority = (port == -1) ? host : host + ":" + port; + } + tempState = new UrlDeserializedState(protocol, host, port, authority, + file, ref, hashCode); + } + + /** + * Replaces the de-serialized object with an URL object. + * + * @return a newly created object from the deserialzed state. + * + * @throws ObjectStreamException if a new object replacing this + * object could not be created + */ + + private Object readResolve() throws ObjectStreamException { + + URLStreamHandler handler = null; + // already been checked in readObject + handler = getURLStreamHandler(tempState.getProtocol()); + + URL replacementURL = null; + if (isBuiltinStreamHandler(handler.getClass().getName())) { + replacementURL = fabricateNewURL(); + } else { + replacementURL = setDeserializedFields(handler); + } + return replacementURL; + } + + private URL setDeserializedFields(URLStreamHandler handler) { + URL replacementURL; + String userInfo = null; + String protocol = tempState.getProtocol(); + String host = tempState.getHost(); + int port = tempState.getPort(); + String authority = tempState.getAuthority(); + String file = tempState.getFile(); + String ref = tempState.getRef(); + int hashCode = tempState.getHashCode(); + // Construct authority part - if (authority == null && - ((host != null && host.length() > 0) || port != -1)) { + if (authority == null + && ((host != null && host.length() > 0) || port != -1)) { if (host == null) host = ""; authority = (port == -1) ? host : host + ":" + port; @@ -1269,8 +1352,8 @@ public final class URL implements java.io.Serializable { } // Construct path and query part - path = null; - query = null; + String path = null; + String query = null; if (file != null) { // Fix: only do this if hierarchical? int q = file.lastIndexOf('?'); @@ -1280,6 +1363,67 @@ public final class URL implements java.io.Serializable { } else path = file; } + + if (port == -1) { + port = 0; + } + // Set the object fields. + this.protocol = protocol; + this.host = host; + this.port = port; + this.file = file; + this.authority = authority; + this.ref = ref; + this.hashCode = hashCode; + this.handler = handler; + this.query = query; + this.path = path; + this.userInfo = userInfo; + replacementURL = this; + return replacementURL; + } + + private URL fabricateNewURL() + throws InvalidObjectException { + // create URL string from deserialized object + URL replacementURL = null; + String urlString = tempState.reconstituteUrlString(); + + try { + replacementURL = new URL(urlString); + } catch (MalformedURLException mEx) { + resetState(); + InvalidObjectException invoEx = new InvalidObjectException( + "Malformed URL: " + urlString); + invoEx.initCause(mEx); + throw invoEx; + } + replacementURL.setSerializedHashCode(tempState.getHashCode()); + resetState(); + return replacementURL; + } + + private boolean isBuiltinStreamHandler(String handlerClassName) { + return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX)); + } + + private void resetState() { + this.protocol = null; + this.host = null; + this.port = -1; + this.file = null; + this.authority = null; + this.ref = null; + this.hashCode = -1; + this.handler = null; + this.query = null; + this.path = null; + this.userInfo = null; + this.tempState = null; + } + + private void setSerializedHashCode(int hc) { + this.hashCode = hc; } } @@ -1311,3 +1455,82 @@ class Parts { return ref; } } + +final class UrlDeserializedState { + private final String protocol; + private final String host; + private final int port; + private final String authority; + private final String file; + private final String ref; + private final int hashCode; + + public UrlDeserializedState(String protocol, + String host, int port, + String authority, String file, + String ref, int hashCode) { + this.protocol = protocol; + this.host = host; + this.port = port; + this.authority = authority; + this.file = file; + this.ref = ref; + this.hashCode = hashCode; + } + + String getProtocol() { + return protocol; + } + + String getHost() { + return host; + } + + String getAuthority () { + return authority; + } + + int getPort() { + return port; + } + + String getFile () { + return file; + } + + String getRef () { + return ref; + } + + int getHashCode () { + return hashCode; + } + + String reconstituteUrlString() { + + // pre-compute length of StringBuilder + int len = protocol.length() + 1; + if (authority != null && authority.length() > 0) + len += 2 + authority.length(); + if (file != null) { + len += file.length(); + } + if (ref != null) + len += 1 + ref.length(); + StringBuilder result = new StringBuilder(len); + result.append(protocol); + result.append(":"); + if (authority != null && authority.length() > 0) { + result.append("//"); + result.append(authority); + } + if (file != null) { + result.append(file); + } + if (ref != null) { + result.append("#"); + result.append(ref); + } + return result.toString(); + } +} diff --git a/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java b/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java index 33b765d9c47ea98e5f47f1aa11facd3871d6e348..d886cb6cf438f236b48d45f822b2b0480cdb77d6 100644 --- a/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +++ b/src/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java @@ -361,7 +361,6 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { "connectionId=" + connectionId +", className=" + className +", name=" + name - +", params=" + objects(values) +", signature=" + strings(signature)); return (ObjectInstance) @@ -427,7 +426,6 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { +", className=" + className +", name=" + name +", loaderName=" + loaderName - +", params=" + objects(values) +", signature=" + strings(signature)); return (ObjectInstance) @@ -719,7 +717,7 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { if (debug) logger.debug("setAttribute", "connectionId=" + connectionId +", name="+name - +", attribute="+attr); + +", attribute name="+attr.getName()); doPrivilegedOperation( SET_ATTRIBUTE, @@ -770,7 +768,7 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { if (debug) logger.debug("setAttributes", "connectionId=" + connectionId +", name="+name - +", attributes="+attrlist); + +", attribute names="+RMIConnector.getAttributesNames(attrlist)); return (AttributeList) doPrivilegedOperation( @@ -825,7 +823,6 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { "connectionId=" + connectionId +", name="+name +", operationName="+operationName - +", params="+objects(values) +", signature="+strings(signature)); return diff --git a/src/share/classes/javax/management/remote/rmi/RMIConnector.java b/src/share/classes/javax/management/remote/rmi/RMIConnector.java index d4928bd01a2e207a720cf77f6214886bcf11a7c7..71f1bc0f77f5944bcd33a2915129bcca722bfda2 100644 --- a/src/share/classes/javax/management/remote/rmi/RMIConnector.java +++ b/src/share/classes/javax/management/remote/rmi/RMIConnector.java @@ -41,7 +41,6 @@ import java.io.NotSerializableException; import java.io.ObjectInputStream; import java.io.ObjectStreamClass; import java.io.Serializable; -import java.io.WriteAbortedException; import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; @@ -70,6 +69,7 @@ import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.WeakHashMap; +import java.util.stream.Collectors; import javax.management.Attribute; import javax.management.AttributeList; import javax.management.AttributeNotFoundException; @@ -712,9 +712,7 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable if (logger.debugOn()) logger.debug("createMBean(String,ObjectName,Object[],String[])", "className=" + className + ", name=" - + name + ", params=" - + objects(params) + ", signature=" - + strings(signature)); + + name + ", signature=" + strings(signature)); final MarshalledObject sParams = new MarshalledObject(params); @@ -753,8 +751,7 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable if (logger.debugOn()) logger.debug( "createMBean(String,ObjectName,ObjectName,Object[],String[])", "className=" + className + ", name=" + name + ", loaderName=" - + loaderName + ", params=" + objects(params) - + ", signature=" + strings(signature)); + + loaderName + ", signature=" + strings(signature)); final MarshalledObject sParams = new MarshalledObject(params); @@ -954,8 +951,8 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable IOException { if (logger.debugOn()) logger.debug("setAttribute", - "name=" + name + ", attribute=" - + attribute); + "name=" + name + ", attribute name=" + + attribute.getName()); final MarshalledObject sAttribute = new MarshalledObject(attribute); @@ -977,9 +974,11 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable ReflectionException, IOException { - if (logger.debugOn()) logger.debug("setAttributes", - "name=" + name + ", attributes=" - + attributes); + if (logger.debugOn()) { + logger.debug("setAttributes", + "name=" + name + ", attribute names=" + + getAttributesNames(attributes)); + } final MarshalledObject sAttributes = new MarshalledObject(attributes); @@ -1012,7 +1011,6 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable if (logger.debugOn()) logger.debug("invoke", "name=" + name + ", operationName=" + operationName - + ", params=" + objects(params) + ", signature=" + strings(signature)); final MarshalledObject sParams = @@ -2636,4 +2634,12 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable private static String strings(final String[] strs) { return objects(strs); } + + static String getAttributesNames(AttributeList attributes) { + return attributes != null ? + attributes.asList().stream() + .map(Attribute::getName) + .collect(Collectors.joining("[", ", ", "]")) + : "[]"; + } } diff --git a/src/share/classes/sun/management/GarbageCollectorImpl.java b/src/share/classes/sun/management/GarbageCollectorImpl.java index 251dad43e043253d088bba5aee9b23cf46a5fd81..ca4b6cda80bbf3b75beec242fee54d664cfb1521 100644 --- a/src/share/classes/sun/management/GarbageCollectorImpl.java +++ b/src/share/classes/sun/management/GarbageCollectorImpl.java @@ -102,17 +102,13 @@ class GarbageCollectorImpl extends MemoryManagerImpl GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION }; - private MBeanNotificationInfo[] notifInfo = null; + @Override public MBeanNotificationInfo[] getNotificationInfo() { - synchronized (this) { - if (notifInfo == null) { - notifInfo = new MBeanNotificationInfo[1]; - notifInfo[0] = new MBeanNotificationInfo(gcNotifTypes, - notifName, - "GC Notification"); - } - } - return notifInfo; + return new MBeanNotificationInfo[]{ + new MBeanNotificationInfo(gcNotifTypes, + notifName, + "GC Notification") + }; } private static long seqNumber = 0; diff --git a/src/share/classes/sun/management/MemoryImpl.java b/src/share/classes/sun/management/MemoryImpl.java index f64a0a5bcf427f00cfba946fe7894a4a9ab42732..38a68262adee1401b96f6f6eaac00eb65976909c 100644 --- a/src/share/classes/sun/management/MemoryImpl.java +++ b/src/share/classes/sun/management/MemoryImpl.java @@ -115,17 +115,10 @@ class MemoryImpl extends NotificationEmitterSupport "Memory usage exceeds collection usage threshold" }; - private MBeanNotificationInfo[] notifInfo = null; public MBeanNotificationInfo[] getNotificationInfo() { - synchronized (this) { - if (notifInfo == null) { - notifInfo = new MBeanNotificationInfo[1]; - notifInfo[0] = new MBeanNotificationInfo(notifTypes, - notifName, - "Memory Notification"); - } - } - return notifInfo; + return new MBeanNotificationInfo[] { + new MBeanNotificationInfo(notifTypes, notifName, "Memory Notification") + }; } private static String getNotifMsg(String notifType) { diff --git a/src/share/classes/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java b/src/share/classes/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java index 0741499b9a78674e8c9a38e86fecceea3dbc2acc..9c020b3bbce0751404d66d52d370ec199fff92cd 100644 --- a/src/share/classes/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java +++ b/src/share/classes/sun/security/internal/spec/TlsRsaPremasterSecretParameterSpec.java @@ -43,6 +43,8 @@ import java.security.PrivilegedAction; public class TlsRsaPremasterSecretParameterSpec implements AlgorithmParameterSpec { + private final byte[] encodedSecret; + /* * The TLS spec says that the version in the RSA premaster secret must * be the maximum version supported by the client (i.e. the version it @@ -89,6 +91,33 @@ public class TlsRsaPremasterSecretParameterSpec this.clientVersion = checkVersion(clientVersion); this.serverVersion = checkVersion(serverVersion); + this.encodedSecret = null; + } + + /** + * Constructs a new TlsRsaPremasterSecretParameterSpec. + * + * @param clientVersion the version of the TLS protocol by which the + * client wishes to communicate during this session + * @param serverVersion the negotiated version of the TLS protocol which + * contains the lower of that suggested by the client in the client + * hello and the highest supported by the server. + * @param encodedSecret the encoded secret key + * + * @throws IllegalArgumentException if clientVersion or serverVersion are + * negative or larger than (2^16 - 1) or if encodedSecret is not + * exactly 48 bytes + */ + public TlsRsaPremasterSecretParameterSpec( + int clientVersion, int serverVersion, byte[] encodedSecret) { + + this.clientVersion = checkVersion(clientVersion); + this.serverVersion = checkVersion(serverVersion); + if (encodedSecret == null || encodedSecret.length != 48) { + throw new IllegalArgumentException( + "Encoded secret is not exactly 48 bytes"); + } + this.encodedSecret = encodedSecret.clone(); } /** @@ -147,4 +176,13 @@ public class TlsRsaPremasterSecretParameterSpec } return version; } + + /** + * Returns the encoded secret. + * + * @return the encoded secret, may be null if no encoded secret. + */ + public byte[] getEncodedSecret() { + return encodedSecret == null ? null : encodedSecret.clone(); + } } diff --git a/src/share/classes/sun/security/jca/JCAUtil.java b/src/share/classes/sun/security/jca/JCAUtil.java index b7bae41ea569b1cfe2fd82a87e3e3b822bf804a6..59e7cbf5730557b8b87c6fb2c453b80641c1f4cf 100644 --- a/src/share/classes/sun/security/jca/JCAUtil.java +++ b/src/share/classes/sun/security/jca/JCAUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,12 +41,6 @@ public final class JCAUtil { // no instantiation } - // lock to use for synchronization - private static final Object LOCK = JCAUtil.class; - - // cached SecureRandom instance - private static volatile SecureRandom secureRandom; - // size of the temporary arrays we use. Should fit into the CPU's 1st // level cache and could be adjusted based on the platform private final static int ARRAY_SIZE = 4096; @@ -60,26 +54,19 @@ public final class JCAUtil { return Math.min(ARRAY_SIZE, totalSize); } + // cached SecureRandom instance + private static class CachedSecureRandomHolder { + public static SecureRandom instance = new SecureRandom(); + } + /** - * Get a SecureRandom instance. This method should me used by JDK + * Get a SecureRandom instance. This method should be used by JDK * internal code in favor of calling "new SecureRandom()". That needs to * iterate through the provider table to find the default SecureRandom * implementation, which is fairly inefficient. */ public static SecureRandom getSecureRandom() { - // we use double checked locking to minimize synchronization - // works because we use a volatile reference - SecureRandom r = secureRandom; - if (r == null) { - synchronized (LOCK) { - r = secureRandom; - if (r == null) { - r = new SecureRandom(); - secureRandom = r; - } - } - } - return r; + return CachedSecureRandomHolder.instance; } } diff --git a/src/share/classes/sun/security/pkcs11/P11Cipher.java b/src/share/classes/sun/security/pkcs11/P11Cipher.java index 6fe59f8da8d1c79d4d7e63b529ccc83a2d2fdf84..3d3f5a17c6571d30e7c8927353545eda1df9a471 100644 --- a/src/share/classes/sun/security/pkcs11/P11Cipher.java +++ b/src/share/classes/sun/security/pkcs11/P11Cipher.java @@ -35,6 +35,7 @@ import javax.crypto.*; import javax.crypto.spec.*; import sun.nio.ch.DirectBuffer; +import sun.security.jca.JCAUtil; import sun.security.pkcs11.wrapper.*; import static sun.security.pkcs11.wrapper.PKCS11Constants.*; @@ -379,7 +380,7 @@ final class P11Cipher extends CipherSpi { } // generate random IV if (random == null) { - random = new SecureRandom(); + random = JCAUtil.getSecureRandom(); } iv = new byte[blockSize]; random.nextBytes(iv); diff --git a/src/share/classes/sun/security/pkcs11/P11RSACipher.java b/src/share/classes/sun/security/pkcs11/P11RSACipher.java index 253b8913a825416cab32ddf948f13dec0684c8b8..f3a16876a59dc0689eb7b4f7810ec894d107387f 100644 --- a/src/share/classes/sun/security/pkcs11/P11RSACipher.java +++ b/src/share/classes/sun/security/pkcs11/P11RSACipher.java @@ -468,49 +468,49 @@ final class P11RSACipher extends CipherSpi { algorithm.equals("TlsRsaPremasterSecret"); Exception failover = null; - SecureRandom secureRandom = random; - if (secureRandom == null && isTlsRsaPremasterSecret) { - secureRandom = new SecureRandom(); - } - // Should C_Unwrap be preferred for non-TLS RSA premaster secret? if (token.supportsRawSecretKeyImport()) { // XXX implement unwrap using C_Unwrap() for all keys implInit(Cipher.DECRYPT_MODE, p11Key); - if (wrappedKey.length > maxInputSize) { - throw new InvalidKeyException("Key is too long for unwrapping"); - } - - byte[] encoded = null; - implUpdate(wrappedKey, 0, wrappedKey.length); try { - encoded = doFinal(); - } catch (BadPaddingException e) { - if (isTlsRsaPremasterSecret) { - failover = e; - } else { + if (wrappedKey.length > maxInputSize) { + throw new InvalidKeyException("Key is too long for unwrapping"); + } + + byte[] encoded = null; + implUpdate(wrappedKey, 0, wrappedKey.length); + try { + encoded = doFinal(); + } catch (BadPaddingException e) { + if (isTlsRsaPremasterSecret) { + failover = e; + } else { + throw new InvalidKeyException("Unwrapping failed", e); + } + } catch (IllegalBlockSizeException e) { + // should not occur, handled with length check above throw new InvalidKeyException("Unwrapping failed", e); } - } catch (IllegalBlockSizeException e) { - // should not occur, handled with length check above - throw new InvalidKeyException("Unwrapping failed", e); - } - if (isTlsRsaPremasterSecret) { - if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) { - throw new IllegalStateException( - "No TlsRsaPremasterSecretParameterSpec specified"); + if (isTlsRsaPremasterSecret) { + if (!(spec instanceof TlsRsaPremasterSecretParameterSpec)) { + throw new IllegalStateException( + "No TlsRsaPremasterSecretParameterSpec specified"); + } + + // polish the TLS premaster secret + TlsRsaPremasterSecretParameterSpec psps = + (TlsRsaPremasterSecretParameterSpec)spec; + encoded = KeyUtil.checkTlsPreMasterSecretKey( + psps.getClientVersion(), psps.getServerVersion(), + random, encoded, (failover != null)); } - // polish the TLS premaster secret - TlsRsaPremasterSecretParameterSpec psps = - (TlsRsaPremasterSecretParameterSpec)spec; - encoded = KeyUtil.checkTlsPreMasterSecretKey( - psps.getClientVersion(), psps.getServerVersion(), - secureRandom, encoded, (failover != null)); + return ConstructKeys.constructKey(encoded, algorithm, type); + } finally { + // Restore original mode + implInit(Cipher.UNWRAP_MODE, p11Key); } - - return ConstructKeys.constructKey(encoded, algorithm, type); } else { Session s = null; SecretKey secretKey = null; @@ -538,20 +538,13 @@ final class P11RSACipher extends CipherSpi { } if (isTlsRsaPremasterSecret) { - byte[] replacer = new byte[48]; - if (failover == null) { - // Does smart compiler dispose this operation? - secureRandom.nextBytes(replacer); - } - TlsRsaPremasterSecretParameterSpec psps = (TlsRsaPremasterSecretParameterSpec)spec; - // Please use the tricky failover and replacer byte array - // as the parameters so that smart compiler won't dispose - // the unused variable . + // Please use the tricky failover as the parameter so that + // smart compiler won't dispose the unused variable. secretKey = polishPreMasterSecretKey(token, s, - failover, replacer, secretKey, + failover, secretKey, psps.getClientVersion(), psps.getServerVersion()); } @@ -570,29 +563,27 @@ final class P11RSACipher extends CipherSpi { private static SecretKey polishPreMasterSecretKey( Token token, Session session, - Exception failover, byte[] replacer, SecretKey secretKey, + Exception failover, SecretKey unwrappedKey, int clientVersion, int serverVersion) { - if (failover != null) { - CK_VERSION version = new CK_VERSION( - (clientVersion >>> 8) & 0xFF, clientVersion & 0xFF); - try { - CK_ATTRIBUTE[] attributes = token.getAttributes( - O_GENERATE, CKO_SECRET_KEY, - CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]); - long keyID = token.p11.C_GenerateKey(session.id(), - // new CK_MECHANISM(CKM_TLS_PRE_MASTER_KEY_GEN, version), - new CK_MECHANISM(CKM_SSL3_PRE_MASTER_KEY_GEN, version), - attributes); - return P11Key.secretKey(session, - keyID, "TlsRsaPremasterSecret", 48 << 3, attributes); - } catch (PKCS11Exception e) { - throw new ProviderException( - "Could not generate premaster secret", e); - } + SecretKey newKey; + CK_VERSION version = new CK_VERSION( + (clientVersion >>> 8) & 0xFF, clientVersion & 0xFF); + try { + CK_ATTRIBUTE[] attributes = token.getAttributes( + O_GENERATE, CKO_SECRET_KEY, + CKK_GENERIC_SECRET, new CK_ATTRIBUTE[0]); + long keyID = token.p11.C_GenerateKey(session.id(), + new CK_MECHANISM(CKM_SSL3_PRE_MASTER_KEY_GEN, version), + attributes); + newKey = P11Key.secretKey(session, + keyID, "TlsRsaPremasterSecret", 48 << 3, attributes); + } catch (PKCS11Exception e) { + throw new ProviderException( + "Could not generate premaster secret", e); } - return secretKey; + return (failover == null) ? unwrappedKey : newKey; } } diff --git a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java index 870d3ea3d5545655cc07373d8c8a299d8f8835eb..038cf2a46765a5be12ac3aec5b41a188458522b7 100644 --- a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java +++ b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java @@ -111,14 +111,34 @@ final class RSAClientKeyExchange extends HandshakeMessage { } } + byte[] encoded = null; try { Cipher cipher = JsseJce.getCipher(JsseJce.CIPHER_RSA_PKCS1); - cipher.init(Cipher.UNWRAP_MODE, privateKey, - new TlsRsaPremasterSecretParameterSpec( - maxVersion.v, currentVersion.v), - generator); - preMaster = (SecretKey)cipher.unwrap(encrypted, - "TlsRsaPremasterSecret", Cipher.SECRET_KEY); + boolean needFailover = !KeyUtil.isOracleJCEProvider( + cipher.getProvider().getName()); + if (needFailover) { + cipher.init(Cipher.DECRYPT_MODE, privateKey); + boolean failed = false; + try { + encoded = cipher.doFinal(encrypted); + } catch (BadPaddingException bpe) { + // Note: encoded == null + failed = true; + } + encoded = KeyUtil.checkTlsPreMasterSecretKey( + maxVersion.v, currentVersion.v, + generator, encoded, failed); + preMaster = generatePreMasterSecret( + maxVersion.v, currentVersion.v, + encoded, generator); + } else { + cipher.init(Cipher.UNWRAP_MODE, privateKey, + new TlsRsaPremasterSecretParameterSpec( + maxVersion.v, currentVersion.v), + generator); + preMaster = (SecretKey)cipher.unwrap(encrypted, + "TlsRsaPremasterSecret", Cipher.SECRET_KEY); + } } catch (InvalidKeyException ibk) { // the message is too big to process with RSA throw new SSLProtocolException( @@ -133,6 +153,35 @@ final class RSAClientKeyExchange extends HandshakeMessage { } } + // generate a premaster secret with the specified version number + @SuppressWarnings("deprecation") + private static SecretKey generatePreMasterSecret( + int clientVersion, int serverVersion, + byte[] encodedSecret, SecureRandom generator) { + + if (debug != null && Debug.isOn("handshake")) { + System.out.println("Generating a premaster secret"); + } + + try { + String s = ((clientVersion >= ProtocolVersion.TLS12.v) ? + "SunTls12RsaPremasterSecret" : "SunTlsRsaPremasterSecret"); + KeyGenerator kg = JsseJce.getKeyGenerator(s); + kg.init(new TlsRsaPremasterSecretParameterSpec( + clientVersion, serverVersion, encodedSecret), + generator); + return kg.generateKey(); + } catch (InvalidAlgorithmParameterException | + NoSuchAlgorithmException iae) { + // unlikely to happen, otherwise, must be a provider exception + if (debug != null && Debug.isOn("handshake")) { + System.out.println("RSA premaster secret generation error:"); + iae.printStackTrace(System.out); + } + throw new RuntimeException("Could not generate premaster secret", iae); + } + } + @Override int messageType() { return ht_client_key_exchange; diff --git a/src/share/classes/sun/security/util/KeyUtil.java b/src/share/classes/sun/security/util/KeyUtil.java index 661e3b973b937675636592be2596e49a5b2f3987..67a9e459506681c7c76e45b330a0523d7e985d8c 100644 --- a/src/share/classes/sun/security/util/KeyUtil.java +++ b/src/share/classes/sun/security/util/KeyUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,6 +41,8 @@ import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPublicKeySpec; import java.math.BigInteger; +import sun.security.jca.JCAUtil; + /** * A utility class to get key length, valiate keys, etc. */ @@ -144,8 +146,6 @@ public final class KeyUtil { /** * Returns whether the specified provider is Oracle provider or not. - *

- * Note that this method is only apply to SunJCE and SunPKCS11 at present. * * @param providerName * the provider name @@ -153,8 +153,11 @@ public final class KeyUtil { * {@code providerName} is Oracle provider */ public static final boolean isOracleJCEProvider(String providerName) { - return providerName != null && (providerName.equals("SunJCE") || - providerName.startsWith("SunPKCS11")); + return providerName != null && + (providerName.equals("SunJCE") || + providerName.equals("SunMSCAPI") || + providerName.equals("OracleUcrypto") || + providerName.startsWith("SunPKCS11")); } /** @@ -199,7 +202,7 @@ public final class KeyUtil { byte[] encoded, boolean isFailOver) { if (random == null) { - random = new SecureRandom(); + random = JCAUtil.getSecureRandom(); } byte[] replacer = new byte[48]; random.nextBytes(replacer); diff --git a/src/share/classes/sun/security/x509/AlgorithmId.java b/src/share/classes/sun/security/x509/AlgorithmId.java index f34d973fc73bc1e0daad1c2501847f6ce0ec9e0f..44eda75d1b302ed8404257d844090e7386a48a4b 100644 --- a/src/share/classes/sun/security/x509/AlgorithmId.java +++ b/src/share/classes/sun/security/x509/AlgorithmId.java @@ -588,7 +588,7 @@ public class AlgorithmId implements Serializable, DerEncoder { } if (oidTable == null) { - oidTable = new HashMap(1); + oidTable = Collections.emptyMap(); } initOidTable = true; } diff --git a/src/share/classes/sun/security/x509/CRLDistributionPointsExtension.java b/src/share/classes/sun/security/x509/CRLDistributionPointsExtension.java index c3814306978a008dfb002480c1d8e3348e3c8041..9062a53e132af508ea13f981f82147533f539b67 100644 --- a/src/share/classes/sun/security/x509/CRLDistributionPointsExtension.java +++ b/src/share/classes/sun/security/x509/CRLDistributionPointsExtension.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.io.OutputStream; import java.util.*; +import java.util.Collections; import sun.security.util.DerOutputStream; import sun.security.util.DerValue; @@ -255,11 +256,12 @@ public class CRLDistributionPointsExtension extends Extension */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(POINTS)) { - distributionPoints = new ArrayList(); + distributionPoints = + Collections.emptyList(); } else { throw new IOException("Attribute name [" + name + - "] not recognized by " + - "CertAttrSet:" + extensionName + "."); + "] not recognized by " + + "CertAttrSet:" + extensionName + '.'); } encodeThis(); } diff --git a/src/share/classes/sun/security/x509/CRLNumberExtension.java b/src/share/classes/sun/security/x509/CRLNumberExtension.java index 9649df6aa942b66bce861c559e7264e044ac030f..3abeb01cfffc20fd9eec0d65bb2439894d28e7a5 100644 --- a/src/share/classes/sun/security/x509/CRLNumberExtension.java +++ b/src/share/classes/sun/security/x509/CRLNumberExtension.java @@ -157,11 +157,10 @@ implements CertAttrSet { */ public BigInteger get(String name) throws IOException { if (name.equalsIgnoreCase(NUMBER)) { - if (crlNumber == null) return null; - else return crlNumber; + return crlNumber; } else { - throw new IOException("Attribute name not recognized by" - + " CertAttrSet:" + extensionName + "."); + throw new IOException("Attribute name not recognized by" + + " CertAttrSet:" + extensionName + '.'); } } diff --git a/src/share/classes/sun/security/x509/DNSName.java b/src/share/classes/sun/security/x509/DNSName.java index 2a35b86fb35f0d8219d7161be56911e3d52e820e..0946dd1b123dff5248fa9a414fa5693ae3ca1007 100644 --- a/src/share/classes/sun/security/x509/DNSName.java +++ b/src/share/classes/sun/security/x509/DNSName.java @@ -232,15 +232,15 @@ public class DNSName implements GeneralNameInterface { * @throws UnsupportedOperationException if not supported for this name type */ public int subtreeDepth() throws UnsupportedOperationException { - String subtree=name; - int i=1; + // subtree depth is always at least 1 + int sum = 1; - /* count dots */ - for (; subtree.lastIndexOf('.') >= 0; i++) { - subtree=subtree.substring(0,subtree.lastIndexOf('.')); + // count dots + for (int i = name.indexOf('.'); i >= 0; i = name.indexOf('.', i + 1)) { + ++sum; } - return i; + return sum; } } diff --git a/src/share/classes/sun/security/x509/EDIPartyName.java b/src/share/classes/sun/security/x509/EDIPartyName.java index feaf30bfd4ff7e83397980bfd92c758c8adedc15..513e3372b9d35490d7b3ffa9e88505078f7d0116 100644 --- a/src/share/classes/sun/security/x509/EDIPartyName.java +++ b/src/share/classes/sun/security/x509/EDIPartyName.java @@ -197,7 +197,7 @@ public class EDIPartyName implements GeneralNameInterface { */ public int hashCode() { if (myhash == -1) { - myhash = 37 + party.hashCode(); + myhash = 37 + (party == null ? 1 : party.hashCode()); if (assigner != null) { myhash = 37 * myhash + assigner.hashCode(); } diff --git a/src/share/classes/sun/security/x509/GeneralSubtrees.java b/src/share/classes/sun/security/x509/GeneralSubtrees.java index 9c5e6212c1af548395509890b43a6f4bdc40aa9e..e5c9e738041c4b0654e96deb3f2167f079e763f3 100644 --- a/src/share/classes/sun/security/x509/GeneralSubtrees.java +++ b/src/share/classes/sun/security/x509/GeneralSubtrees.java @@ -191,7 +191,7 @@ public class GeneralSubtrees implements Cloneable { // the list: if any subsequent entry matches or widens entry n, // remove entry n. If any subsequent entries narrow entry n, remove // the subsequent entries. - for (int i = 0; i < size(); i++) { + for (int i = 0; i < (size() - 1); i++) { GeneralNameInterface current = getGeneralNameInterface(i); boolean remove1 = false; diff --git a/src/share/classes/sun/security/x509/IPAddressName.java b/src/share/classes/sun/security/x509/IPAddressName.java index 084a6f3760a9ec18124bd2b893a7188515e43148..e558c9e3bdfb35a3bef77755ef0b33be386ee25f 100644 --- a/src/share/classes/sun/security/x509/IPAddressName.java +++ b/src/share/classes/sun/security/x509/IPAddressName.java @@ -197,8 +197,10 @@ public class IPAddressName implements GeneralNameInterface { // append a mask corresponding to the num of prefix bits specified int prefixLen = Integer.parseInt(name.substring(slashNdx+1)); - if (prefixLen > 128) - throw new IOException("IPv6Address prefix is longer than 128"); + if (prefixLen < 0 || prefixLen > 128) { + throw new IOException("IPv6Address prefix length (" + + prefixLen + ") in out of valid range [0,128]"); + } // create new bit array initialized to zeros BitArray bitArray = new BitArray(MASKSIZE * 8); @@ -317,7 +319,8 @@ public class IPAddressName implements GeneralNameInterface { if (!(obj instanceof IPAddressName)) return false; - byte[] other = ((IPAddressName)obj).getBytes(); + IPAddressName otherName = (IPAddressName)obj; + byte[] other = otherName.address; if (other.length != address.length) return false; @@ -326,12 +329,10 @@ public class IPAddressName implements GeneralNameInterface { // Two subnet addresses // Mask each and compare masked values int maskLen = address.length/2; - byte[] maskedThis = new byte[maskLen]; - byte[] maskedOther = new byte[maskLen]; for (int i=0; i < maskLen; i++) { - maskedThis[i] = (byte)(address[i] & address[i+maskLen]); - maskedOther[i] = (byte)(other[i] & other[i+maskLen]); - if (maskedThis[i] != maskedOther[i]) { + byte maskedThis = (byte)(address[i] & address[i+maskLen]); + byte maskedOther = (byte)(other[i] & other[i+maskLen]); + if (maskedThis != maskedOther) { return false; } } @@ -400,7 +401,8 @@ public class IPAddressName implements GeneralNameInterface { else if (((IPAddressName)inputName).equals(this)) constraintType = NAME_MATCH; else { - byte[] otherAddress = ((IPAddressName)inputName).getBytes(); + IPAddressName otherName = (IPAddressName)inputName; + byte[] otherAddress = otherName.address; if (otherAddress.length == 4 && address.length == 4) // Two host addresses constraintType = NAME_SAME_TYPE; diff --git a/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java b/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java index 6a932587c5f6fd61b3f24d0661917b254e68cab5..6fe8eb3b13c6f4185585f8451e8b7b1ac0852cb0 100644 --- a/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java +++ b/src/share/classes/sun/security/x509/IssuingDistributionPointExtension.java @@ -261,6 +261,7 @@ public class IssuingDistributionPointExtension extends Extension throw new IOException( "Attribute value should be of type ReasonFlags."); } + revocationReasons = (ReasonFlags)obj; } else if (name.equalsIgnoreCase(INDIRECT_CRL)) { if (!(obj instanceof Boolean)) { @@ -290,7 +291,6 @@ public class IssuingDistributionPointExtension extends Extension } hasOnlyAttributeCerts = ((Boolean)obj).booleanValue(); - } else { throw new IOException("Attribute name [" + name + "] not recognized by " + diff --git a/src/share/classes/sun/security/x509/KeyIdentifier.java b/src/share/classes/sun/security/x509/KeyIdentifier.java index 01d4803cecf25e828017ea1f0a3a45ab06340131..016fd4e952abd488720d7cc5b7393ecfa69272ab 100644 --- a/src/share/classes/sun/security/x509/KeyIdentifier.java +++ b/src/share/classes/sun/security/x509/KeyIdentifier.java @@ -148,7 +148,7 @@ public class KeyIdentifier { return true; if (!(other instanceof KeyIdentifier)) return false; - return java.util.Arrays.equals(octetString, - ((KeyIdentifier)other).getIdentifier()); + byte[] otherString = ((KeyIdentifier)other).octetString; + return java.util.Arrays.equals(octetString, otherString); } } diff --git a/src/share/classes/sun/security/x509/PolicyMappingsExtension.java b/src/share/classes/sun/security/x509/PolicyMappingsExtension.java index fba510469f5678d45d8acdb6319c1d86e1cf8203..e259826f1c2dba2799c714b10377759edb219efd 100644 --- a/src/share/classes/sun/security/x509/PolicyMappingsExtension.java +++ b/src/share/classes/sun/security/x509/PolicyMappingsExtension.java @@ -102,7 +102,7 @@ implements CertAttrSet { public PolicyMappingsExtension() { extensionId = PKIXExtensions.KeyUsage_Id; critical = false; - maps = new ArrayList(); + maps = Collections.emptyList(); } /** diff --git a/src/share/classes/sun/security/x509/PrivateKeyUsageExtension.java b/src/share/classes/sun/security/x509/PrivateKeyUsageExtension.java index c20d8557b0398645bbffde65a0b7f61a29aabfae..512880b563fff21b7a93ad5ba2e5d2169f13299b 100644 --- a/src/share/classes/sun/security/x509/PrivateKeyUsageExtension.java +++ b/src/share/classes/sun/security/x509/PrivateKeyUsageExtension.java @@ -33,6 +33,7 @@ import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateNotYetValidException; import java.util.Date; import java.util.Enumeration; +import java.util.Objects; import sun.security.util.*; @@ -206,16 +207,17 @@ implements CertAttrSet { */ public void valid(Date now) throws CertificateNotYetValidException, CertificateExpiredException { + Objects.requireNonNull(now); /* * we use the internal Dates rather than the passed in Date * because someone could override the Date methods after() * and before() to do something entirely different. */ - if (notBefore.after(now)) { + if (notBefore != null && notBefore.after(now)) { throw new CertificateNotYetValidException("NotBefore: " + notBefore.toString()); } - if (notAfter.before(now)) { + if (notAfter != null && notAfter.before(now)) { throw new CertificateExpiredException("NotAfter: " + notAfter.toString()); } diff --git a/src/share/classes/sun/security/x509/RDN.java b/src/share/classes/sun/security/x509/RDN.java index 05822590de8e59839e54663a2ef6d95f04432a18..e60e2e8435449ee5b2d5e9e636bfd3af5a5a18fc 100644 --- a/src/share/classes/sun/security/x509/RDN.java +++ b/src/share/classes/sun/security/x509/RDN.java @@ -27,6 +27,8 @@ package sun.security.x509; import java.io.IOException; import java.io.StringReader; +import java.util.Arrays; +import java.util.StringJoiner; import java.util.*; import sun.security.util.*; @@ -442,31 +444,19 @@ public class RDN { assertion[0].toRFC2253String(oidMap); } - StringBuilder relname = new StringBuilder(); - if (!canonical) { - for (int i = 0; i < assertion.length; i++) { - if (i > 0) { - relname.append('+'); - } - relname.append(assertion[i].toRFC2253String(oidMap)); - } - } else { + AVA[] toOutput = assertion; + if (canonical) { // order the string type AVA's alphabetically, // followed by the oid type AVA's numerically - List avaList = new ArrayList(assertion.length); - for (int i = 0; i < assertion.length; i++) { - avaList.add(assertion[i]); - } - java.util.Collections.sort(avaList, AVAComparator.getInstance()); - - for (int i = 0; i < avaList.size(); i++) { - if (i > 0) { - relname.append('+'); - } - relname.append(avaList.get(i).toRFC2253CanonicalString()); - } + toOutput = assertion.clone(); + Arrays.sort(toOutput, AVAComparator.getInstance()); + } + StringJoiner sj = new StringJoiner("+"); + for (AVA ava : toOutput) { + sj.add(canonical ? ava.toRFC2253CanonicalString() + : ava.toRFC2253String(oidMap)); } - return relname.toString(); + return sj.toString(); } } diff --git a/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java b/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java index 2f851f7dbec9fc32919a3c1959e3ef03f8e5f73d..e1a0bc2611468ef4b2b65b667219de99d99602dd 100644 --- a/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java +++ b/src/share/classes/sun/security/x509/SubjectInfoAccessExtension.java @@ -28,6 +28,7 @@ package sun.security.x509; import java.io.IOException; import java.io.OutputStream; +import java.util.Collections; import java.util.*; import sun.security.util.DerOutputStream; @@ -200,7 +201,8 @@ public class SubjectInfoAccessExtension extends Extension */ public void delete(String name) throws IOException { if (name.equalsIgnoreCase(DESCRIPTIONS)) { - accessDescriptions = new ArrayList(); + accessDescriptions = + Collections.emptyList(); } else { throw new IOException("Attribute name [" + name + "] not recognized by " + diff --git a/src/share/classes/sun/security/x509/URIName.java b/src/share/classes/sun/security/x509/URIName.java index 034117e2a05cb6623c1961e7d699ffb647231f5b..5f4021ef9385232d8c72fe27a6f05d46aa03d95d 100644 --- a/src/share/classes/sun/security/x509/URIName.java +++ b/src/share/classes/sun/security/x509/URIName.java @@ -165,7 +165,7 @@ public class URIName implements GeneralNameInterface { String host = uri.getSchemeSpecificPart(); try { DNSName hostDNS; - if (host.charAt(0) == '.') { + if (host.startsWith(".")) { hostDNS = new DNSName(host.substring(1)); } else { hostDNS = new DNSName(host); diff --git a/src/share/classes/sun/security/x509/X500Name.java b/src/share/classes/sun/security/x509/X500Name.java index 3cc7b93cf332a867bcc0cee502a949189d77e736..d82543c33cc2f9b1d7672bfbd77d6443cb317ff7 100644 --- a/src/share/classes/sun/security/x509/X500Name.java +++ b/src/share/classes/sun/security/x509/X500Name.java @@ -346,6 +346,8 @@ public class X500Name implements GeneralNameInterface, Principal { for (int i = 0; i < names.length; i++) { list.addAll(names[i].avas()); } + list = Collections.unmodifiableList(list); + allAvaList = list; } return list; } @@ -364,9 +366,6 @@ public class X500Name implements GeneralNameInterface, Principal { */ public boolean isEmpty() { int n = names.length; - if (n == 0) { - return true; - } for (int i = 0; i < n; i++) { if (names[i].assertion.length != 0) { return false; @@ -1109,12 +1108,8 @@ public class X500Name implements GeneralNameInterface, Principal { * and speed recognition of common X.500 attributes. */ static ObjectIdentifier intern(ObjectIdentifier oid) { - ObjectIdentifier interned = internedOIDs.get(oid); - if (interned != null) { - return interned; - } - internedOIDs.put(oid, oid); - return oid; + ObjectIdentifier interned = internedOIDs.putIfAbsent(oid, oid); + return (interned == null) ? oid : interned; } private static final Map internedOIDs diff --git a/src/share/classes/sun/security/x509/X509AttributeName.java b/src/share/classes/sun/security/x509/X509AttributeName.java index 090792aa2e9469de605e62e3cb7f0e5ee9f09eff..c60b6f46010e86bd46f093be5c7dfbdd3bae3f32 100644 --- a/src/share/classes/sun/security/x509/X509AttributeName.java +++ b/src/share/classes/sun/security/x509/X509AttributeName.java @@ -47,7 +47,7 @@ public class X509AttributeName { */ public X509AttributeName(String name) { int i = name.indexOf(SEPARATOR); - if (i == (-1)) { + if (i < 0) { prefix = name; } else { prefix = name.substring(0, i); diff --git a/src/share/classes/sun/security/x509/X509CRLImpl.java b/src/share/classes/sun/security/x509/X509CRLImpl.java index 21f39d0366b6b86c444b16d6eaee290cefd6a201..e19b298ad2368584ff058e32468fc5ad7cb85ac7 100644 --- a/src/share/classes/sun/security/x509/X509CRLImpl.java +++ b/src/share/classes/sun/security/x509/X509CRLImpl.java @@ -742,9 +742,7 @@ public class X509CRLImpl extends X509CRL implements DerEncoder { public byte[] getTBSCertList() throws CRLException { if (tbsCertList == null) throw new CRLException("Uninitialized CRL"); - byte[] dup = new byte[tbsCertList.length]; - System.arraycopy(tbsCertList, 0, dup, 0, dup.length); - return dup; + return tbsCertList.clone(); } /** @@ -755,9 +753,7 @@ public class X509CRLImpl extends X509CRL implements DerEncoder { public byte[] getSignature() { if (signature == null) return null; - byte[] dup = new byte[signature.length]; - System.arraycopy(signature, 0, dup, 0, dup.length); - return dup; + return signature.clone(); } /** diff --git a/src/share/classes/sun/security/x509/X509CertImpl.java b/src/share/classes/sun/security/x509/X509CertImpl.java index b3f448b09fdb5f6fc07d0431ee8a541b7ca854c6..b473ab840fc7cdad952ae8ea7b3c08d49472657e 100644 --- a/src/share/classes/sun/security/x509/X509CertImpl.java +++ b/src/share/classes/sun/security/x509/X509CertImpl.java @@ -1008,9 +1008,7 @@ public class X509CertImpl extends X509Certificate implements DerEncoder { public byte[] getSignature() { if (signature == null) return null; - byte[] dup = new byte[signature.length]; - System.arraycopy(signature, 0, dup, 0, dup.length); - return dup; + return signature.clone(); } /** diff --git a/src/share/native/sun/awt/image/jpeg/jpegdecoder.c b/src/share/native/sun/awt/image/jpeg/jpegdecoder.c index 37b743a03399dbc8392248ae77db4ba6f47a4976..43edba61f4a143f8f6ed84c91b057b51051eeeec 100644 --- a/src/share/native/sun/awt/image/jpeg/jpegdecoder.c +++ b/src/share/native/sun/awt/image/jpeg/jpegdecoder.c @@ -180,6 +180,7 @@ struct sun_jpeg_source_mgr { int *ip; unsigned char *bp; } outbuf; + size_t outbufSize; jobject hOutputBuffer; }; @@ -235,6 +236,7 @@ static int GET_ARRAYS(JNIEnv *env, sun_jpeg_source_ptr src) assert(src->outbuf.ip == 0); src->outbuf.ip = (int *)(*env)->GetPrimitiveArrayCritical (env, src->hOutputBuffer, 0); + src->outbufSize = (*env)->GetArrayLength(env, src->hOutputBuffer); if (src->outbuf.ip == 0) { RELEASE_ARRAYS(env, src); return 0; @@ -677,8 +679,8 @@ Java_sun_awt_image_JPEGImageDecoder_readImage(JNIEnv *env, cinfo.output_scanline - 1); } else { if (hasalpha) { - ip = jsrc.outbuf.ip + cinfo.image_width; - bp = jsrc.outbuf.bp + cinfo.image_width * 4; + ip = jsrc.outbuf.ip + jsrc.outbufSize; + bp = jsrc.outbuf.bp + jsrc.outbufSize * 4; while (ip > jsrc.outbuf.ip) { pixel = (*--bp) << 24; pixel |= (*--bp); @@ -687,8 +689,8 @@ Java_sun_awt_image_JPEGImageDecoder_readImage(JNIEnv *env, *--ip = pixel; } } else { - ip = jsrc.outbuf.ip + cinfo.image_width; - bp = jsrc.outbuf.bp + cinfo.image_width * 3; + ip = jsrc.outbuf.ip + jsrc.outbufSize; + bp = jsrc.outbuf.bp + jsrc.outbufSize * 3; while (ip > jsrc.outbuf.ip) { pixel = (*--bp); pixel |= (*--bp) << 8; diff --git a/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp b/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp index cbee0ba7097a2a3826cf5d44f032eb5cacd8038e..8beae2730aa7f80a18762b68231a4a1ded8b446c 100644 --- a/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp +++ b/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp @@ -243,14 +243,14 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LETableReference le_uint16 srSetCount = SWAPW(subRuleSetCount); if (coverageIndex < srSetCount) { - LEReferenceToArrayOf subRuleSetTableOffsetArrayRef(base, success, - &subRuleSetTableOffsetArray[coverageIndex], 1); + LEReferenceToArrayOf + subRuleSetTableOffsetArrayRef(base, success, subRuleSetTableOffsetArray, srSetCount); if (LE_FAILURE(success)) { return 0; } Offset subRuleSetTableOffset = SWAPW(subRuleSetTableOffsetArray[coverageIndex]); - LEReferenceTo - subRuleSetTable(base, success, (const SubRuleSetTable *) ((char *) this + subRuleSetTableOffset)); + LEReferenceTo subRuleSetTable(base, success, subRuleSetTableOffset); + if (LE_FAILURE(success)) { return 0; } le_uint16 subRuleCount = SWAPW(subRuleSetTable->subRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); @@ -264,6 +264,7 @@ le_uint32 ContextualSubstitutionFormat1Subtable::process(const LETableReference SWAPW(subRuleSetTable->subRuleTableOffsetArray[subRule]); LEReferenceTo subRuleTable(subRuleSetTable, success, subRuleTableOffset); + if (LE_FAILURE(success)) { return 0; } le_uint16 matchCount = SWAPW(subRuleTable->glyphCount) - 1; le_uint16 substCount = SWAPW(subRuleTable->substCount); LEReferenceToArrayOf inputGlyphArray(base, success, subRuleTable->inputGlyphArray, matchCount+2); @@ -304,8 +305,8 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LETableReference } if (coverageIndex >= 0) { - LEReferenceTo classDefinitionTable(base, success, - (const ClassDefinitionTable *) ((char *) this + SWAPW(classDefTableOffset))); + LEReferenceTo classDefinitionTable(base, success, SWAPW(classDefTableOffset)); + if (LE_FAILURE(success)) { return 0; } le_uint16 scSetCount = SWAPW(subClassSetCount); le_int32 setClass = classDefinitionTable->getGlyphClass(classDefinitionTable, glyphIterator->getCurrGlyphID(), @@ -313,44 +314,45 @@ le_uint32 ContextualSubstitutionFormat2Subtable::process(const LETableReference if (setClass < scSetCount) { LEReferenceToArrayOf - subClassSetTableOffsetArrayRef(base, success, subClassSetTableOffsetArray, setClass); + subClassSetTableOffsetArrayRef(base, success, subClassSetTableOffsetArray, scSetCount); if (LE_FAILURE(success)) { return 0; } if (subClassSetTableOffsetArray[setClass] != 0) { - Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]); - LEReferenceTo - subClassSetTable(base, success, (const SubClassSetTable *) ((char *) this + subClassSetTableOffset)); - le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount); - le_int32 position = glyphIterator->getCurrStreamPosition(); + Offset subClassSetTableOffset = SWAPW(subClassSetTableOffsetArray[setClass]); + LEReferenceTo subClassSetTable(base, success, subClassSetTableOffset); + if (LE_FAILURE(success)) { return 0; } + le_uint16 subClassRuleCount = SWAPW(subClassSetTable->subClassRuleCount); + le_int32 position = glyphIterator->getCurrStreamPosition(); LEReferenceToArrayOf subClassRuleTableOffsetArrayRef(base, success, subClassSetTable->subClassRuleTableOffsetArray, subClassRuleCount); if (LE_FAILURE(success)) { return 0; } - for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) { - Offset subClassRuleTableOffset = - SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]); - LEReferenceTo - subClassRuleTable(subClassSetTable, success, subClassRuleTableOffset); - le_uint16 matchCount = SWAPW(subClassRuleTable->glyphCount) - 1; - le_uint16 substCount = SWAPW(subClassRuleTable->substCount); + for (le_uint16 scRule = 0; scRule < subClassRuleCount; scRule += 1) { + Offset subClassRuleTableOffset = + SWAPW(subClassSetTable->subClassRuleTableOffsetArray[scRule]); + LEReferenceTo + subClassRuleTable(subClassSetTable, success, subClassRuleTableOffset); + if (LE_FAILURE(success)) { return 0; } + le_uint16 matchCount = SWAPW(subClassRuleTable->glyphCount) - 1; + le_uint16 substCount = SWAPW(subClassRuleTable->substCount); - LEReferenceToArrayOf classArray(base, success, subClassRuleTable->classArray, matchCount+1); + LEReferenceToArrayOf classArray(base, success, subClassRuleTable->classArray, matchCount+1); - if (LE_FAILURE(success)) { return 0; } - if (matchGlyphClasses(classArray, matchCount, glyphIterator, classDefinitionTable, success)) { - LEReferenceToArrayOf - substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount], substCount); + if (LE_FAILURE(success)) { return 0; } + if (matchGlyphClasses(classArray, matchCount, glyphIterator, classDefinitionTable, success)) { + LEReferenceToArrayOf + substLookupRecordArray(base, success, (const SubstitutionLookupRecord *) &subClassRuleTable->classArray[matchCount], substCount); - applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); + applySubstitutionLookups(lookupProcessor, substLookupRecordArray, substCount, glyphIterator, fontInstance, position, success); - return matchCount + 1; - } + return matchCount + 1; + } - glyphIterator->setCurrStreamPosition(position); + glyphIterator->setCurrStreamPosition(position); + } } } - } // XXX If we get here, the table is mal-formed... } @@ -463,13 +465,13 @@ le_uint32 ChainingContextualSubstitutionFormat1Subtable::process(const LETableRe if (coverageIndex < srSetCount) { LEReferenceToArrayOf - chainSubRuleSetTableOffsetArrayRef(base, success, chainSubRuleSetTableOffsetArray, coverageIndex); + chainSubRuleSetTableOffsetArrayRef(base, success, chainSubRuleSetTableOffsetArray, srSetCount); if (LE_FAILURE(success)) { return 0; } Offset chainSubRuleSetTableOffset = SWAPW(chainSubRuleSetTableOffsetArray[coverageIndex]); - LEReferenceTo - chainSubRuleSetTable(base, success, (const ChainSubRuleSetTable *) ((char *) this + chainSubRuleSetTableOffset)); + LEReferenceTo chainSubRuleSetTable(base, success, chainSubRuleSetTableOffset); + if (LE_FAILURE(success)) { return 0; } le_uint16 chainSubRuleCount = SWAPW(chainSubRuleSetTable->chainSubRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); @@ -550,17 +552,17 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LETableRe if (coverageIndex >= 0) { LEReferenceTo - backtrackClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(backtrackClassDefTableOffset))); + backtrackClassDefinitionTable(base, success, SWAPW(backtrackClassDefTableOffset)); LEReferenceTo - inputClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(inputClassDefTableOffset))); + inputClassDefinitionTable(base, success, SWAPW(inputClassDefTableOffset)); LEReferenceTo - lookaheadClassDefinitionTable(base, success, (const ClassDefinitionTable *) ((char *) this + SWAPW(lookaheadClassDefTableOffset))); + lookaheadClassDefinitionTable(base, success, SWAPW(lookaheadClassDefTableOffset)); le_uint16 scSetCount = SWAPW(chainSubClassSetCount); le_int32 setClass = inputClassDefinitionTable->getGlyphClass(inputClassDefinitionTable, glyphIterator->getCurrGlyphID(), success); LEReferenceToArrayOf - chainSubClassSetTableOffsetArrayRef(base, success, chainSubClassSetTableOffsetArray, setClass); + chainSubClassSetTableOffsetArrayRef(base, success, chainSubClassSetTableOffsetArray, scSetCount); if (LE_FAILURE(success)) { return 0; } @@ -568,7 +570,8 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LETableRe if (setClass < scSetCount && chainSubClassSetTableOffsetArray[setClass] != 0) { Offset chainSubClassSetTableOffset = SWAPW(chainSubClassSetTableOffsetArray[setClass]); LEReferenceTo - chainSubClassSetTable(base, success, (const ChainSubClassSetTable *) ((char *) this + chainSubClassSetTableOffset)); + chainSubClassSetTable(base, success, chainSubClassSetTableOffset); + if (LE_FAILURE(success)) { return 0; } le_uint16 chainSubClassRuleCount = SWAPW(chainSubClassSetTable->chainSubClassRuleCount); le_int32 position = glyphIterator->getCurrStreamPosition(); GlyphIterator tempIterator(*glyphIterator, emptyFeatureList); @@ -582,6 +585,7 @@ le_uint32 ChainingContextualSubstitutionFormat2Subtable::process(const LETableRe SWAPW(chainSubClassSetTable->chainSubClassRuleTableOffsetArray[scRule]); LEReferenceTo chainSubClassRuleTable(chainSubClassSetTable, success, chainSubClassRuleTableOffset); + if (LE_FAILURE(success)) { return 0; } le_uint16 backtrackGlyphCount = SWAPW(chainSubClassRuleTable->backtrackGlyphCount); LEReferenceToArrayOf backtrackClassArray(base, success, chainSubClassRuleTable->backtrackClassArray, backtrackGlyphCount); if( LE_FAILURE(success) ) { return 0; } diff --git a/src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp b/src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp index f2c9f95ac7065614e6d4d71cd59c0e942154b803..0f230f12e7d58def6d089152727d9d82ecf36d2c 100644 --- a/src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp +++ b/src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp @@ -46,7 +46,7 @@ le_uint32 CursiveAttachmentSubtable::process(const LEReferenceTo - entryExitRecordsArrayRef(base, success, entryExitRecords, coverageIndex); + entryExitRecordsArrayRef(base, success, entryExitRecords, eeCount); if (coverageIndex < 0 || coverageIndex >= eeCount || LE_FAILURE(success)) { glyphIterator->setCursiveGlyph(); diff --git a/src/share/native/sun/font/layout/Features.cpp b/src/share/native/sun/font/layout/Features.cpp index 02bb838d52f29ccb327df9ab87099e470147c69d..0621888504d407fc1b77e7ee80568b3640a7ae51 100644 --- a/src/share/native/sun/font/layout/Features.cpp +++ b/src/share/native/sun/font/layout/Features.cpp @@ -41,7 +41,7 @@ U_NAMESPACE_BEGIN LEReferenceTo FeatureListTable::getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const { LEReferenceToArrayOf - featureRecordArrayRef(base, success, featureRecordArray, featureIndex+1); + featureRecordArrayRef(base, success, featureRecordArray, SWAPW(featureCount)); if (featureIndex >= SWAPW(featureCount) || LE_FAILURE(success)) { return LEReferenceTo(); diff --git a/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp b/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp index ed1d11d40444c8c0f9d718c626ad5c92fe19d3e0..086da91629e583401f48c060f36e088b9a51fe53 100644 --- a/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp +++ b/src/share/native/sun/font/layout/MarkToBasePosnSubtables.cpp @@ -93,7 +93,7 @@ le_int32 MarkToBasePositioningSubtable::process(const LETableReference &base, Gl } LEReferenceTo baseRecord(base, success, &baseArray->baseRecordArray[baseCoverage * mcCount]); if( LE_FAILURE(success) ) { return 0; } - LEReferenceToArrayOf baseAnchorTableOffsetArray(base, success, &(baseRecord->baseAnchorTableOffsetArray[0]), markClass+1); + LEReferenceToArrayOf baseAnchorTableOffsetArray(base, success, &(baseRecord->baseAnchorTableOffsetArray[0]), mcCount); if( LE_FAILURE(success) ) { return 0; } Offset anchorTableOffset = SWAPW(baseRecord->baseAnchorTableOffsetArray[markClass]); diff --git a/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp b/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp index 55fadf3b5f0e12105fb89ab8ce255a6dd426bd3d..2515b8afb5afcabb2009d4cf490f7902db49c0f6 100644 --- a/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp +++ b/src/share/native/sun/font/layout/MarkToLigaturePosnSubtables.cpp @@ -83,6 +83,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base LEGlyphID ligatureGlyph = findLigatureGlyph(&ligatureIterator); le_int32 ligatureCoverage = getBaseCoverage(base, (LEGlyphID) ligatureGlyph, success); LEReferenceTo ligatureArray(base, success, SWAPW(baseArrayOffset)); + if (LE_FAILURE(success)) { return 0; } le_uint16 ligatureCount = SWAPW(ligatureArray->ligatureCount); if (ligatureCoverage < 0 || ligatureCoverage >= ligatureCount) { @@ -95,6 +96,7 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base le_int32 markPosition = glyphIterator->getCurrStreamPosition(); Offset ligatureAttachOffset = SWAPW(ligatureArray->ligatureAttachTableOffsetArray[ligatureCoverage]); LEReferenceTo ligatureAttachTable(ligatureArray, success, ligatureAttachOffset); + if (LE_FAILURE(success)) { return 0; } le_int32 componentCount = SWAPW(ligatureAttachTable->componentCount); le_int32 component = ligatureIterator.getMarkComponent(markPosition); @@ -104,10 +106,12 @@ le_int32 MarkToLigaturePositioningSubtable::process(const LETableReference &base } LEReferenceTo componentRecord(base, success, &ligatureAttachTable->componentRecordArray[component * mcCount]); - LEReferenceToArrayOf ligatureAnchorTableOffsetArray(base, success, &(componentRecord->ligatureAnchorTableOffsetArray[0]), markClass+1); + if (LE_FAILURE(success)) { return 0; } + LEReferenceToArrayOf ligatureAnchorTableOffsetArray(base, success, &(componentRecord->ligatureAnchorTableOffsetArray[0]), mcCount); if( LE_FAILURE(success) ) { return 0; } Offset anchorTableOffset = SWAPW(componentRecord->ligatureAnchorTableOffsetArray[markClass]); LEReferenceTo anchorTable(ligatureAttachTable, success, anchorTableOffset); + if (LE_FAILURE(success)) { return 0; } LEPoint ligatureAnchor, markAdvance, pixels; anchorTable->getAnchor(anchorTable, ligatureGlyph, fontInstance, ligatureAnchor, success);