Mercurial > hg > icedtea8-forest > jdk
changeset 13433:9c9ff65b03b6 icedtea-3.8.0 icedtea-3.9.0pre00
Merge jdk8u171-b11
line wrap: on
line diff
--- a/.hgtags Mon Apr 30 19:04:05 2018 +0100 +++ b/.hgtags Fri May 25 01:50:25 2018 +0100 @@ -820,6 +820,11 @@ bfd67d7c7d41b320225d5502cec55c6b38cdaa6d jdk8u152-b15 e4ff08f9c787cdd45568926b13eded32b4672242 icedtea-3.7.0pre01 1cb70967c4d78a45a60d0d6eb64cb7fbe89ad005 jdk8u152-b16 +9dce8b2a03e056c54789c555176bd2c8a48b844f jdk8u152-b31 +5f0349b6341cf96a478ea14ee820af26fe190e36 jdk8u152-b32 +4c18aa8f0bc0eb78ed02863e465867804415a931 jdk8u152-b33 +dcd2081a3118944dc2bd8e00f92dead20ade495f jdk8u152-b34 +9828d410e76ece84f81f3290b421b0f2877e45f9 jdk8u152-b35 072e084bceeedeb75467e40ca77786ac9ef5227a jdk8u151-b00 5b0fa6e004312a5910a6a70e4fbc0f00a678e650 jdk8u151-b01 bd40efd56b4544ff9048d2f7be4cf108b281a6f3 jdk8u151-b02 @@ -902,3 +907,16 @@ 1d2ee5e60df1c3bc889c92154d839bfe73077f66 jdk8u162-b10 95df717479b19f5ea244afc67434827f2f851287 jdk8u162-b11 0a89388f0b97a8f924ebc7b7bf4ca2b1b67161eb icedtea-3.8.0pre01 +ddae5cb11d6c04130b8002b852bc7f80e0c8bcd2 jdk8u162-b12 +8e40acfcc41a631f5922824712d4336742652eac jdk8u162-b31 +b6195815c4bbbf275f1aefd337d805eb66f2b5b8 jdk8u171-b00 +f1792a59f1fa20e47fe5d4561754012440564bec jdk8u171-b01 +cac020298633fc736f5e21afddf00145665ef0a7 jdk8u171-b02 +c260afc0c5a13407aad4f066f81fba814bb0cbae jdk8u171-b03 +ac700f67341a20ddae093c319da1c65e41edcacd jdk8u171-b04 +863ef3413aa42c15fbdc14fef6732f2741f97046 jdk8u171-b05 +6cbe2e5989a85f82833191be05ccb531f685d171 jdk8u171-b06 +9cf14f22734a057adceff1764b4bb6c71329088b jdk8u171-b07 +9a59252d179a2a488e094cd28b58d86edbf454a0 jdk8u171-b08 +4617f1da787289f41d2a7e50d6859d85c005c857 jdk8u171-b09 +2212d32912153d4a963cc8d782163ea30d34d1f6 jdk8u171-b10
--- a/make/mapfiles/libjava/mapfile-vers Mon Apr 30 19:04:05 2018 +0100 +++ b/make/mapfiles/libjava/mapfile-vers Fri May 25 01:50:25 2018 +0100 @@ -272,7 +272,7 @@ Java_sun_misc_Version_getJvmVersionInfo; Java_sun_misc_Version_getJvmSpecialVersion; Java_sun_misc_VM_getThreadStateValues; - Java_sun_misc_VM_latestUserDefinedLoader; + Java_sun_misc_VM_latestUserDefinedLoader0; Java_sun_misc_VM_initialize; Java_sun_misc_VMSupport_initAgentProperties; Java_sun_misc_VMSupport_getVMTemporaryDirectory;
--- a/src/macosx/native/apple/security/KeystoreImpl.m Mon Apr 30 19:04:05 2018 +0100 +++ b/src/macosx/native/apple/security/KeystoreImpl.m Fri May 25 01:50:25 2018 +0100 @@ -431,12 +431,11 @@ if (passwordChars == NULL) { goto errOut; } - passwordStrRef = CFStringCreateWithCharacters(kCFAllocatorDefault, passwordChars, passwordLen); - // clear the password and release - memset(passwordChars, 0, passwordLen); - (*env)->ReleaseCharArrayElements(env, passwordObj, passwordChars, - JNI_ABORT); + passwordStrRef = CFStringCreateWithCharactersNoCopy(NULL, passwordChars, passwordLen, kCFAllocatorNull); + if (passwordStrRef == NULL) { + goto errOut; + } } } @@ -464,7 +463,12 @@ errOut: if (exportedData) CFRelease(exportedData); if (passwordStrRef) CFRelease(passwordStrRef); - + if (passwordChars) { + // clear the password and release + memset(passwordChars, 0, passwordLen); + (*env)->ReleaseCharArrayElements(env, passwordObj, passwordChars, + JNI_ABORT); + } return returnValue; } @@ -529,12 +533,11 @@ if (passwordChars == NULL) { goto errOut; } - passwordStrRef = CFStringCreateWithCharacters(kCFAllocatorDefault, passwordChars, passwordLen); - // clear the password and release - memset(passwordChars, 0, passwordLen); - (*env)->ReleaseCharArrayElements(env, passwordObj, passwordChars, - JNI_ABORT); + passwordStrRef = CFStringCreateWithCharactersNoCopy(NULL, passwordChars, passwordLen, kCFAllocatorNull); + if (passwordStrRef == NULL) { + goto errOut; + } } } @@ -572,7 +575,14 @@ CFRelease(createdItems); } -errOut: ; +errOut: + if (passwordStrRef) CFRelease(passwordStrRef); + if (passwordChars) { + // clear the password and release + memset(passwordChars, 0, passwordLen); + (*env)->ReleaseCharArrayElements(env, passwordObj, passwordChars, + JNI_ABORT); + } JNF_COCOA_EXIT(env);
--- a/src/share/classes/com/sun/crypto/provider/CipherCore.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/com/sun/crypto/provider/CipherCore.java Fri May 25 01:50:25 2018 +0100 @@ -988,8 +988,9 @@ if (padding != null) { int padStart = padding.unpad(outWithPadding, 0, outLen); if (padStart < 0) { - throw new BadPaddingException("Given final block not " - + "properly padded"); + throw new BadPaddingException("Given final block not " + + "properly padded. Such issues can arise if a bad key " + + "is used during decryption."); } outLen = padStart; }
--- a/src/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/com/sun/crypto/provider/DESedeWrapCipher.java Fri May 25 01:50:25 2018 +0100 @@ -473,6 +473,9 @@ } catch (InvalidKeyException ike) { // should never happen throw new RuntimeException("Internal cipher key is corrupted"); + } catch (InvalidAlgorithmParameterException iape) { + // should never happen + throw new RuntimeException("Internal cipher IV is invalid"); } byte[] out2 = new byte[out.length]; cipher.encrypt(out, 0, out.length, out2, 0); @@ -484,6 +487,9 @@ } catch (InvalidKeyException ike) { // should never happen throw new RuntimeException("Internal cipher key is corrupted"); + } catch (InvalidAlgorithmParameterException iape) { + // should never happen + throw new RuntimeException("Internal cipher IV is invalid"); } return out2; } @@ -527,8 +533,12 @@ } iv = new byte[IV_LEN]; System.arraycopy(buffer, 0, iv, 0, iv.length); - cipher.init(true, cipherKey.getAlgorithm(), cipherKey.getEncoded(), + try { + cipher.init(true, cipherKey.getAlgorithm(), cipherKey.getEncoded(), iv); + } catch (InvalidAlgorithmParameterException iape) { + throw new InvalidKeyException("IV in wrapped key is invalid"); + } byte[] buffer2 = new byte[buffer.length - iv.length]; cipher.decrypt(buffer, iv.length, buffer2.length, buffer2, 0); @@ -541,8 +551,12 @@ } } // restore cipher state to prior to this call - cipher.init(decrypting, cipherKey.getAlgorithm(), + try { + cipher.init(decrypting, cipherKey.getAlgorithm(), cipherKey.getEncoded(), IV2); + } catch (InvalidAlgorithmParameterException iape) { + throw new InvalidKeyException("IV in wrapped key is invalid"); + } byte[] out = new byte[keyValLen]; System.arraycopy(buffer2, 0, out, 0, keyValLen); return ConstructKeys.constructKey(out, wrappedKeyAlgorithm,
--- a/src/share/classes/com/sun/crypto/provider/FeedbackCipher.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/com/sun/crypto/provider/FeedbackCipher.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package com.sun.crypto.provider; import java.security.InvalidKeyException; +import java.security.InvalidAlgorithmParameterException; import javax.crypto.*; /** @@ -99,7 +100,8 @@ * initializing this cipher */ abstract void init(boolean decrypting, String algorithm, byte[] key, - byte[] iv) throws InvalidKeyException; + byte[] iv) throws InvalidKeyException, + InvalidAlgorithmParameterException; /** * Gets the initialization vector.
--- a/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/com/sun/crypto/provider/GaloisCounterMode.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, 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 @@ -262,8 +262,9 @@ * @exception InvalidKeyException if the given key is inappropriate for * initializing this cipher */ + @Override void init(boolean decrypting, String algorithm, byte[] key, byte[] iv) - throws InvalidKeyException { + throws InvalidKeyException, InvalidAlgorithmParameterException { init(decrypting, algorithm, key, iv, DEFAULT_TAG_LEN); } @@ -282,10 +283,16 @@ */ void init(boolean decrypting, String algorithm, byte[] keyValue, byte[] ivValue, int tagLenBytes) - throws InvalidKeyException { - if (keyValue == null || ivValue == null) { + throws InvalidKeyException, InvalidAlgorithmParameterException { + if (keyValue == null) { throw new InvalidKeyException("Internal error"); } + if (ivValue == null) { + throw new InvalidAlgorithmParameterException("Internal error"); + } + if (ivValue.length == 0) { + throw new InvalidAlgorithmParameterException("IV is empty"); + } // always encrypt mode for embedded cipher this.embeddedCipher.init(false, algorithm, keyValue);
--- a/src/share/classes/com/sun/crypto/provider/JceKeyStore.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/com/sun/crypto/provider/JceKeyStore.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -929,8 +929,10 @@ // First run a custom filter long nestedDepth = info.depth(); if ((nestedDepth == 1 && - info.serialClass() != SealedObjectForKeyProtector.class) || - nestedDepth > MAX_NESTED_DEPTH) { + info.serialClass() != SealedObjectForKeyProtector.class) || + (nestedDepth > MAX_NESTED_DEPTH && + info.serialClass() != null && + info.serialClass() != Object.class)) { return Status.REJECTED; }
--- a/src/share/classes/com/sun/crypto/provider/KeyProtector.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/com/sun/crypto/provider/KeyProtector.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,6 @@ package com.sun.crypto.provider; import java.io.IOException; -import java.io.Serializable; -import java.security.Security; import java.security.Key; import java.security.PrivateKey; import java.security.Provider; @@ -35,7 +33,6 @@ import java.security.MessageDigest; import java.security.GeneralSecurityException; import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; import java.security.UnrecoverableKeyException; import java.security.AlgorithmParameters; import java.security.spec.InvalidParameterSpecException; @@ -44,7 +41,6 @@ import javax.crypto.Cipher; import javax.crypto.CipherSpi; import javax.crypto.SecretKey; -import javax.crypto.IllegalBlockSizeException; import javax.crypto.SealedObject; import javax.crypto.spec.*; import sun.security.x509.AlgorithmId; @@ -347,7 +343,7 @@ SunJCE.getInstance(), "PBEWithMD5AndTripleDES"); cipher.init(Cipher.DECRYPT_MODE, skey, params); - return (Key)soForKeyProtector.getObject(cipher); + return soForKeyProtector.getKey(cipher); } catch (NoSuchAlgorithmException ex) { // Note: this catch needed to be here because of the // later catch of GeneralSecurityException
--- a/src/share/classes/com/sun/crypto/provider/SealedObjectForKeyProtector.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/com/sun/crypto/provider/SealedObjectForKeyProtector.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,9 @@ package com.sun.crypto.provider; +import sun.misc.ObjectInputFilter; +import sun.misc.SharedSecrets; + import java.io.*; import java.security.*; import javax.crypto.*; @@ -33,6 +36,16 @@ static final long serialVersionUID = -3650226485480866989L; + /** + * The InputStreamFilter for a Key object inside this SealedObject. It can + * be either provided as a {@link Security} property or a system property + * (when provided as latter, it shadows the former). If the result of this + * filter is {@link sun.misc.ObjectInputFilter.Status.UNDECIDED}, the system + * level filter defined by jdk.serialFilter will be consulted. The value + * of this property uses the same format of jdk.serialFilter. + */ + private static final String KEY_SERIAL_FILTER = "jceks.key.serialFilter"; + SealedObjectForKeyProtector(Serializable object, Cipher c) throws IOException, IllegalBlockSizeException { super(object, c); @@ -59,4 +72,88 @@ } return params; } + + final Key getKey(Cipher c) + throws IOException, ClassNotFoundException, IllegalBlockSizeException, + BadPaddingException { + + try (ObjectInputStream ois = SharedSecrets.getJavaxCryptoSealedObjectAccess() + .getExtObjectInputStream(this, c)) { + AccessController.doPrivileged( + (PrivilegedAction<Void>) () -> { + ObjectInputFilter.Config.setObjectInputFilter(ois, + DeserializationChecker.ONE_FILTER); + return null; + }); + try { + @SuppressWarnings("unchecked") + Key t = (Key) ois.readObject(); + return t; + } catch (InvalidClassException ice) { + String msg = ice.getMessage(); + if (msg.contains("REJECTED")) { + throw new IOException("Rejected by the" + + " jceks.key.serialFilter or jdk.serialFilter" + + " property", ice); + } else { + throw ice; + } + } + } + } + + /** + * The filter for the content of a SealedObjectForKeyProtector. + * + * First, the jceks.key.serialFilter will be consulted. If the result + * is UNDECIDED, the system level jdk.serialFilter will be consulted. + */ + private static class DeserializationChecker implements ObjectInputFilter { + + private static final ObjectInputFilter ONE_FILTER; + + static { + String prop = AccessController.doPrivileged( + (PrivilegedAction<String>) () -> { + String tmp = System.getProperty(KEY_SERIAL_FILTER); + if (tmp != null) { + return tmp; + } else { + return Security.getProperty(KEY_SERIAL_FILTER); + } + }); + ONE_FILTER = new DeserializationChecker(prop == null ? null + : ObjectInputFilter.Config.createFilter(prop)); + } + + private final ObjectInputFilter base; + + private DeserializationChecker(ObjectInputFilter base) { + this.base = base; + } + + @Override + public ObjectInputFilter.Status checkInput( + ObjectInputFilter.FilterInfo info) { + + if (info.serialClass() == Object.class) { + return Status.UNDECIDED; + } + + if (base != null) { + Status result = base.checkInput(info); + if (result != Status.UNDECIDED) { + return result; + } + } + + ObjectInputFilter defaultFilter = + ObjectInputFilter.Config.getSerialFilter(); + if (defaultFilter != null) { + return defaultFilter.checkInput(info); + } + + return Status.UNDECIDED; + } + } }
--- a/src/share/classes/com/sun/crypto/provider/ai.java Mon Apr 30 19:04:05 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2001, 2007, 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.crypto.provider; - -import java.io.IOException; -import java.io.Serializable; -import java.io.ObjectStreamException; -import java.security.AlgorithmParameters; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.SealedObject; -import javax.crypto.spec.*; - -/** - * This class is introduced to workaround a problem in - * the SunJCE provider shipped in JCE 1.2.1: the class - * SealedObjectForKeyProtector was obfuscated due to a mistake. - * - * In order to retrieve secret keys in a JCEKS KeyStore written - * by the SunJCE provider in JCE 1.2.1, this class will be used. - * - * @author Valerie Peng - * - * - * @see JceKeyStore - */ - -final class ai extends javax.crypto.SealedObject { - - static final long serialVersionUID = -7051502576727967444L; - - ai(SealedObject so) { - super(so); - } - - Object readResolve() throws ObjectStreamException { - return new SealedObjectForKeyProtector(this); - } -}
--- a/src/share/classes/com/sun/jmx/remote/internal/RMIExporter.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/com/sun/jmx/remote/internal/RMIExporter.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -25,7 +25,6 @@ package com.sun.jmx.remote.internal; -import sun.misc.ObjectInputFilter; import java.rmi.NoSuchObjectException; import java.rmi.Remote; import java.rmi.RemoteException; @@ -52,8 +51,7 @@ public Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, - RMIServerSocketFactory ssf, - ObjectInputFilter filter) + RMIServerSocketFactory ssf) throws RemoteException; public boolean unexportObject(Remote obj, boolean force)
--- a/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/com/sun/jmx/remote/util/EnvHelp.java Fri May 25 01:50:25 2018 +0100 @@ -1,6 +1,6 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,61 +70,6 @@ "jmx.remote.rmi.server.credential.types"; /** - * Name of the attribute that specifies an - * {@link ObjectInputFilter} pattern string to filter classes acceptable - * for {@link RMIServer#newClient(java.lang.Object) RMIServer.newClient()} - * remote method call. - * <p> - * The filter pattern must be in same format as used in - * {@link java.io.ObjectInputFilter.Config.createFilter} - * <p> - * This list of classes allowed by filter should correspond to the - * transitive closure of the credentials class (or classes) used by the - * installed {@linkplain JMXAuthenticator} associated with the - * {@linkplain RMIServer} implementation. - * If the attribute is not set then any class is deemed acceptable. - * @see ObjectInputFilter - */ - public static final String CREDENTIALS_FILTER_PATTERN = - "jmx.remote.rmi.server.credentials.filter.pattern"; - - /** - * This attribute defines a pattern from which to create a - * {@link java.io.ObjectInputFilter} that will be used when deserializing - * objects sent to the {@code JMXConnectorServer} by any client. - * <p> - * The filter will be called for any class found in the serialized - * stream sent to server by client, including all JMX defined classes - * (such as {@link javax.management.ObjectName}), all method parameters, - * and, if present in the stream, all classes transitively referred by - * the serial form of any deserialized object. - * The pattern must be in same format as used in - * {@link java.io.ObjectInputFilter.Config.createFilter}. - * It may define a white list of permitted classes, a black list of - * rejected classes, a maximum depth for the deserialized objects, - * etc. - * <p> - * To be functional, the filter should allow at least all the - * concrete types in the transitive closure of all objects that - * might get serialized when serializing all JMX classes referred - * as parameters in the {@link - * javax.management.remote.rmi.RMIConnection} interface, - * plus all classes that a {@link javax.management.remote.rmi.RMIConnectorClient} - * might need to transmit wrapped in {@linkplain java.rmi.MarshalledObject - * marshalled objects} in order to interoperate with the MBeans registered - * in the {@code MBeanServer}. That would potentially include all the - * concrete {@linkplain javax.management.openmbean JMX OpenTypes} and the - * classes they use in their serial form. - * <p> - * Care must be taken when defining such a filter, as defining - * a white list too restrictive or a too wide a black list may - * prevent legitimate clients from interoperating with the - * {@code JMXConnectorServer}. - */ - public static final String SERIAL_FILTER_PATTERN = - "jmx.remote.rmi.server.serial.filter.pattern"; - - /** * <p>Name of the attribute that specifies a default class loader * object. * The value associated with this attribute is a ClassLoader object</p>
--- a/src/share/classes/com/sun/rowset/RowSetResourceBundle_sv.properties Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/com/sun/rowset/RowSetResourceBundle_sv.properties Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -122,7 +122,7 @@ crsreader.caldetected = En kalender har identifierats #CachedRowSetWriter exceptions -crswriter.connect = Kan inte uppr\u00E4tta n\u00E5gon anslutning +crswriter.connect = Kan inte uppr\u00E4tta anslutning crswriter.tname = writeData kan inte fastst\u00E4lla tabellnamnet crswriter.params1 = Parameterv\u00E4rde1: {0} crswriter.params2 = Parameterv\u00E4rde2: {0}
--- a/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties Fri May 25 01:50:25 2018 +0100 @@ -66,7 +66,7 @@ FileChooser.cancelButtonToolTip.textAndMnemonic=Avbryt dialogrutan f\u00F6r filval FileChooser.saveButtonToolTip.textAndMnemonic=Spara vald fil FileChooser.openButtonToolTip.textAndMnemonic=\u00D6ppna vald fil -FileChooser.updateButtonToolTip.textAndMnemonic=Uppdatera kataloglistan +FileChooser.updateButtonToolTip.textAndMnemonic=Uppdatera kataloglista FileChooser.helpButtonToolTip.textAndMnemonic=Hj\u00E4lp f\u00F6r val av fil FileChooser.directoryOpenButtonToolTip.textAndMnemonic=\u00D6ppna vald katalog
--- a/src/share/classes/java/awt/Container.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/java/awt/Container.java Fri May 25 01:50:25 2018 +0100 @@ -35,6 +35,7 @@ import java.beans.PropertyChangeListener; import java.io.IOException; +import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.ObjectStreamField; @@ -3717,8 +3718,15 @@ throws ClassNotFoundException, IOException { ObjectInputStream.GetField f = s.readFields(); - Component [] tmpComponent = (Component[])f.get("component", EMPTY_ARRAY); + // array of components may not be present in the stream or may be null + Component [] tmpComponent = (Component[])f.get("component", null); + if (tmpComponent == null) { + tmpComponent = EMPTY_ARRAY; + } int ncomponents = (Integer) f.get("ncomponents", 0); + if (ncomponents < 0 || ncomponents > tmpComponent.length) { + throw new InvalidObjectException("Incorrect number of components"); + } component = new java.util.ArrayList<Component>(ncomponents); for (int i = 0; i < ncomponents; ++i) { component.add(tmpComponent[i]);
--- a/src/share/classes/java/io/FilePermission.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/java/io/FilePermission.java Fri May 25 01:50:25 2018 +0100 @@ -833,6 +833,8 @@ @SuppressWarnings("unchecked") Vector<Permission> permissions = (Vector<Permission>)gfields.get("permissions", null); perms = new ArrayList<>(permissions.size()); - perms.addAll(permissions); + for (Permission perm : permissions) { + perms.add(perm); + } } }
--- a/src/share/classes/java/io/ObjectInputStream.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/java/io/ObjectInputStream.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,8 @@ import sun.misc.SharedSecrets; import sun.misc.ObjectInputFilter; +import sun.misc.ObjectStreamClassValidator; +import sun.misc.SharedSecrets; import sun.reflect.misc.ReflectUtil; import sun.misc.JavaOISAccess; import sun.util.logging.PlatformLogger; @@ -245,7 +247,7 @@ static { /* Setup access so sun.misc can invoke package private functions. */ - sun.misc.SharedSecrets.setJavaOISAccess(new JavaOISAccess() { + JavaOISAccess javaOISAccess = new JavaOISAccess() { public void setObjectInputFilter(ObjectInputStream stream, ObjectInputFilter filter) { stream.setInternalObjectInputFilter(filter); } @@ -259,7 +261,9 @@ { stream.checkArray(arrayType, arrayLength); } - }); + }; + + sun.misc.SharedSecrets.setJavaOISAccess(javaOISAccess); } /* @@ -1748,6 +1752,9 @@ throw new StreamCorruptedException( String.format("invalid type code: %02X", tc)); } + if (descriptor != null) { + validateDescriptor(descriptor); + } return descriptor; } @@ -2329,10 +2336,11 @@ int ndoubles); /** - * Returns the first non-null class loader (not counting class loaders of - * generated reflection implementation classes) up the execution stack, or - * null if only code from the null class loader is on the stack. This - * method is also called via reflection by the following RMI-IIOP class: + * Returns first non-privileged class loader on the stack (excluding + * reflection generated frames) or the extension class loader if only + * class loaded by the boot class loader and extension class loader are + * found on the stack. This method is also called via reflection by the + * following RMI-IIOP class: * * com.sun.corba.se.internal.util.JDKClassLoader * @@ -3892,4 +3900,21 @@ throw new AssertionError(); } } + + private void validateDescriptor(ObjectStreamClass descriptor) { + ObjectStreamClassValidator validating = validator; + if (validating != null) { + validating.validateDescriptor(descriptor); + } + } + + // controlled access to ObjectStreamClassValidator + private volatile ObjectStreamClassValidator validator; + + private static void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator) { + ois.validator = validator; + } + static { + SharedSecrets.setJavaObjectInputStreamAccess(ObjectInputStream::setValidator); + } }
--- a/src/share/classes/java/lang/invoke/MethodType.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/java/lang/invoke/MethodType.java Fri May 25 01:50:25 2018 +0100 @@ -1140,33 +1140,24 @@ * @param s the stream to read the object from * @throws java.io.IOException if there is a problem reading the object * @throws ClassNotFoundException if one of the component classes cannot be resolved - * @see #MethodType() * @see #readResolve * @see #writeObject */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { + // Assign temporary defaults in case this object escapes + MethodType_init(void.class, NO_PTYPES); + s.defaultReadObject(); // requires serialPersistentFields to be an empty array Class<?> returnType = (Class<?>) s.readObject(); Class<?>[] parameterArray = (Class<?>[]) s.readObject(); + parameterArray = parameterArray.clone(); // make sure it is unshared - // Probably this object will never escape, but let's check - // the field values now, just to be sure. - checkRtype(returnType); - checkPtypes(parameterArray); - - parameterArray = parameterArray.clone(); // make sure it is unshared + // Assign deserialized values MethodType_init(returnType, parameterArray); } - /** - * For serialization only. - * Sets the final fields to null, pending {@code Unsafe.putObject}. - */ - private MethodType() { - this.rtype = null; - this.ptypes = null; - } + // Initialization of state for deserialization only private void MethodType_init(Class<?> rtype, Class<?>[] ptypes) { // In order to communicate these values to readResolve, we must // store them into the implementation-specific final fields. @@ -1196,9 +1187,14 @@ */ private Object readResolve() { // Do not use a trusted path for deserialization: - //return makeImpl(rtype, ptypes, true); + // return makeImpl(rtype, ptypes, true); // Verify all operands, and make sure ptypes is unshared: - return methodType(rtype, ptypes); + try { + return methodType(rtype, ptypes); + } finally { + // Re-assign defaults in case this object escapes + MethodType_init(void.class, NO_PTYPES); + } } /**
--- a/src/share/classes/java/security/MessageDigest.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/java/security/MessageDigest.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2017, 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 @@ -59,7 +59,7 @@ * and catching the CloneNotSupportedException: * * <pre>{@code - * MessageDigest md = MessageDigest.getInstance("SHA"); + * MessageDigest md = MessageDigest.getInstance("SHA-256"); * * try { * md.update(toChapter1); @@ -467,7 +467,7 @@ /** * Returns a string that identifies the algorithm, independent of * implementation details. The name should be a standard - * Java Security name (such as "SHA", "MD5", and so on). + * Java Security name (such as "SHA-256"). * See the MessageDigest section in the <a href= * "{@docRoot}/../technotes/guides/security/StandardNames.html#MessageDigest"> * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
--- a/src/share/classes/java/security/Signature.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/java/security/Signature.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2017, 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 @@ -52,11 +52,10 @@ * authentication and integrity assurance of digital data. * * <p> The signature algorithm can be, among others, the NIST standard - * DSA, using DSA and SHA-1. The DSA algorithm using the - * SHA-1 message digest algorithm can be specified as {@code SHA1withDSA}. - * In the case of RSA, there are multiple choices for the message digest - * algorithm, so the signing algorithm could be specified as, for example, - * {@code MD2withRSA}, {@code MD5withRSA}, or {@code SHA1withRSA}. + * DSA, using DSA and SHA-256. The DSA algorithm using the + * SHA-256 message digest algorithm can be specified as {@code SHA256withDSA}. + * In the case of RSA the signing algorithm could be specified as, for example, + * {@code SHA256withRSA}. * The algorithm name must be specified, as there is no default. * * <p> A Signature object can be used to generate and verify digital
--- a/src/share/classes/java/security/SignedObject.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/java/security/SignedObject.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -81,13 +81,12 @@ * verification in an attempt to bypass a security check. * * <p> The signature algorithm can be, among others, the NIST standard - * DSA, using DSA and SHA-1. The algorithm is specified using the + * DSA, using DSA and SHA-256. The algorithm is specified using the * same convention as that for signatures. The DSA algorithm using the - * SHA-1 message digest algorithm can be specified, for example, as - * "SHA/DSA" or "SHA-1/DSA" (they are equivalent). In the case of - * RSA, there are multiple choices for the message digest algorithm, - * so the signing algorithm could be specified as, for example, - * "MD2/RSA", "MD5/RSA" or "SHA-1/RSA". The algorithm name must be + * SHA-256 message digest algorithm can be specified, for example, as + * "SHA256withDSA". In the case of + * RSA the signing algorithm could be specified as, for example, + * "SHA256withRSA". The algorithm name must be * specified, as there is no default. * * <p> The name of the Cryptography Package Provider is designated
--- a/src/share/classes/java/util/Hashtable.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/java/util/Hashtable.java Fri May 25 01:50:25 2018 +0100 @@ -1194,6 +1194,10 @@ length--; length = Math.min(length, origlength); + if (length < 0) { // overflow + length = origlength; + } + // Check Map.Entry[].class since it's the nearest public type to // what we're actually creating. SharedSecrets.getJavaOISAccess().checkArray(s, Map.Entry[].class, length);
--- a/src/share/classes/java/util/Vector.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/java/util/Vector.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,9 @@ package java.util; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.StreamCorruptedException; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.UnaryOperator; @@ -1059,6 +1062,29 @@ } /** + * Loads a {@code Vector} instance from a stream + * (that is, deserializes it). + * This method performs checks to ensure the consistency + * of the fields. + * + * @param in the stream + * @throws java.io.IOException if an I/O error occurs + * @throws ClassNotFoundException if the stream contains data + * of a non-existing class + */ + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + ObjectInputStream.GetField gfields = in.readFields(); + int count = gfields.get("elementCount", 0); + Object[] data = (Object[])gfields.get("elementData", null); + if (count < 0 || data == null || count > data.length) { + throw new StreamCorruptedException("Inconsistent vector internals"); + } + elementCount = count; + elementData = data.clone(); + } + + /** * Save the state of the {@code Vector} instance to a stream (that * is, serialize it). * This method performs synchronization to ensure the consistency
--- a/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java Fri May 25 01:50:25 2018 +0100 @@ -48,6 +48,7 @@ import java.util.SortedSet; import java.util.Spliterator; import java.util.function.Consumer; +import sun.misc.SharedSecrets; /** * An unbounded {@linkplain BlockingQueue blocking queue} that uses @@ -940,7 +941,9 @@ throws java.io.IOException, ClassNotFoundException { try { s.defaultReadObject(); - this.queue = new Object[q.size()]; + int sz = q.size(); + SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, sz); + this.queue = new Object[sz]; comparator = q.comparator(); addAll(q); } finally {
--- a/src/share/classes/java/util/logging/FileHandler.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/java/util/logging/FileHandler.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2017, 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 @@ -156,9 +156,27 @@ private String lockFileName; private FileChannel lockFileChannel; private File files[]; - private static final int MAX_LOCKS = 100; + private static final int DEFAULT_MAX_LOCKS = 100; + private static int maxLocks; private static final Set<String> locks = new HashSet<>(); + /* + * Initialize maxLocks from the System property if set. + * If invalid/no property is provided 100 will be used as a default value. + */ + static { + maxLocks = java.security.AccessController.doPrivileged( + (PrivilegedAction<Integer>) () -> + Integer.getInteger( + "jdk.internal.FileHandlerLogging.maxLocks", + DEFAULT_MAX_LOCKS) + ); + + if (maxLocks <= 0) { + maxLocks = DEFAULT_MAX_LOCKS; + } + } + /** * A metered stream is a subclass of OutputStream that * (a) forwards all its output to a target stream @@ -434,8 +452,9 @@ int unique = -1; for (;;) { unique++; - if (unique > MAX_LOCKS) { - throw new IOException("Couldn't get lock for " + pattern); + if (unique > maxLocks) { + throw new IOException("Couldn't get lock for " + pattern + + ", maxLocks: " + maxLocks); } // Generate a lock file name from the "unique" int. lockFileName = generate(pattern, 0, unique).toString() + ".lck";
--- a/src/share/classes/javax/crypto/Cipher.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/javax/crypto/Cipher.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -59,7 +59,7 @@ * <p>A <i>transformation</i> is a string that describes the operation (or * set of operations) to be performed on the given input, to produce some * output. A transformation always includes the name of a cryptographic - * algorithm (e.g., <i>DES</i>), and may be followed by a feedback mode and + * algorithm (e.g., <i>AES</i>), and may be followed by a feedback mode and * padding scheme. * * <p> A transformation is of the form: @@ -75,17 +75,16 @@ * For example, the following is a valid transformation: * * <pre> - * Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>"); + * Cipher c = Cipher.getInstance("<i>AES/CBC/PKCS5Padding</i>"); * </pre> * * Using modes such as <code>CFB</code> and <code>OFB</code>, block * ciphers can encrypt data in units smaller than the cipher's actual * block size. When requesting such a mode, you may optionally specify * the number of bits to be processed at a time by appending this number - * to the mode name as shown in the "<code>DES/CFB8/NoPadding</code>" and - * "<code>DES/OFB32/PKCS5Padding</code>" transformations. If no such - * number is specified, a provider-specific default is used. (For - * example, the SunJCE provider uses a default of 64 bits for DES.) + * to the mode name as shown in the "{@code AES/CFB8/NoPadding}" and + * "{@code AES/OFB32/PKCS5Padding}" transformations. If no such + * number is specified, a provider-specific default is used. * Thus, block ciphers can be turned into byte-oriented stream ciphers by * using an 8 bit mode such as CFB8 or OFB8. * <p> @@ -307,7 +306,7 @@ /* * array containing the components of a Cipher transformation: * - * index 0: algorithm component (e.g., DES) + * index 0: algorithm component (e.g., AES) * index 1: feedback component (e.g., CFB) * index 2: padding component (e.g., PKCS5Padding) */ @@ -353,8 +352,8 @@ // transform string to lookup in the provider final String transform; // the mode/padding suffix in upper case. for example, if the algorithm - // to lookup is "DES/CBC/PKCS5Padding" suffix is "/CBC/PKCS5PADDING" - // if loopup is "DES", suffix is the empty string + // to lookup is "AES/CBC/PKCS5Padding" suffix is "/CBC/PKCS5PADDING" + // if lookup is "AES", suffix is the empty string // needed because aliases prevent straight transform.equals() final String suffix; // value to pass to setMode() or null if no such call required @@ -439,11 +438,11 @@ } if ((mode == null) && (pad == null)) { - // DES + // AES Transform tr = new Transform(alg, "", null, null); return Collections.singletonList(tr); } else { // if ((mode != null) && (pad != null)) { - // DES/CBC/PKCS5Padding + // AES/CBC/PKCS5Padding List<Transform> list = new ArrayList<>(4); list.add(new Transform(alg, "/" + mode + "/" + pad, null, null)); list.add(new Transform(alg, "/" + mode, null, pad)); @@ -479,7 +478,7 @@ * the {@link Security#getProviders() Security.getProviders()} method. * * @param transformation the name of the transformation, e.g., - * <i>DES/CBC/PKCS5Padding</i>. + * <i>AES/CBC/PKCS5Padding</i>. * See the Cipher section in the <a href= * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher"> * Java Cryptography Architecture Standard Algorithm Name Documentation</a> @@ -554,7 +553,7 @@ * the {@link Security#getProviders() Security.getProviders()} method. * * @param transformation the name of the transformation, - * e.g., <i>DES/CBC/PKCS5Padding</i>. + * e.g., <i>AES/CBC/PKCS5Padding</i>. * See the Cipher section in the <a href= * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher"> * Java Cryptography Architecture Standard Algorithm Name Documentation</a> @@ -606,7 +605,7 @@ * does not have to be registered in the provider list. * * @param transformation the name of the transformation, - * e.g., <i>DES/CBC/PKCS5Padding</i>. + * e.g., <i>AES/CBC/PKCS5Padding</i>. * See the Cipher section in the <a href= * "{@docRoot}/../technotes/guides/security/StandardNames.html#Cipher"> * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
--- a/src/share/classes/javax/crypto/CipherOutputStream.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/javax/crypto/CipherOutputStream.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,15 @@ * java.io.OutputStream and java.io.FilterOutputStream. This class * has exactly those methods specified in its ancestor classes, and * overrides them all. Moreover, this class catches all exceptions - * that are not thrown by its ancestor classes. + * that are not thrown by its ancestor classes. In particular, this + * class catches BadPaddingException and other exceptions thrown by + * failed integrity checks during decryption. These exceptions are not + * re-thrown, so the client will not be informed that integrity checks + * failed. Because of this behavior, this class may not be suitable + * for use with decryption in an authenticated mode of operation (e.g. GCM) + * if the application requires explicit notification when authentication + * fails. Such an application can use the Cipher API directly as an + * alternative to using this class. * * <p> It is crucial for a programmer using this class not to use * methods that are not defined or overriden in this class (such as a
--- a/src/share/classes/javax/crypto/CipherSpi.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/javax/crypto/CipherSpi.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -59,7 +59,7 @@ * <p>A <i>transformation</i> is a string that describes the operation (or * set of operations) to be performed on the given input, to produce some * output. A transformation always includes the name of a cryptographic - * algorithm (e.g., <i>DES</i>), and may be followed by a feedback mode and + * algorithm (e.g., <i>AES</i>), and may be followed by a feedback mode and * padding scheme. * * <p> A transformation is of the form: @@ -75,7 +75,7 @@ * For example, the following is a valid transformation: * * <pre> - * Cipher c = Cipher.getInstance("<i>DES/CBC/PKCS5Padding</i>"); + * Cipher c = Cipher.getInstance("<i>AES/CBC/PKCS5Padding</i>"); * </pre> * * <p>A provider may supply a separate class for each combination @@ -125,32 +125,32 @@ * </ul> * * <p>For example, a provider may supply a subclass of <code>CipherSpi</code> - * that implements <i>DES/ECB/PKCS5Padding</i>, one that implements - * <i>DES/CBC/PKCS5Padding</i>, one that implements - * <i>DES/CFB/PKCS5Padding</i>, and yet another one that implements - * <i>DES/OFB/PKCS5Padding</i>. That provider would have the following + * that implements <i>AES/ECB/PKCS5Padding</i>, one that implements + * <i>AES/CBC/PKCS5Padding</i>, one that implements + * <i>AES/CFB/PKCS5Padding</i>, and yet another one that implements + * <i>AES/OFB/PKCS5Padding</i>. That provider would have the following * <code>Cipher</code> properties in its master class: * * <ul> * * <li> * <pre> - * <code>Cipher.</code><i>DES/ECB/PKCS5Padding</i> + * <code>Cipher.</code><i>AES/ECB/PKCS5Padding</i> * </pre> * * <li> * <pre> - * <code>Cipher.</code><i>DES/CBC/PKCS5Padding</i> + * <code>Cipher.</code><i>AES/CBC/PKCS5Padding</i> * </pre> * * <li> * <pre> - * <code>Cipher.</code><i>DES/CFB/PKCS5Padding</i> + * <code>Cipher.</code><i>AES/CFB/PKCS5Padding</i> * </pre> * * <li> * <pre> - * <code>Cipher.</code><i>DES/OFB/PKCS5Padding</i> + * <code>Cipher.</code><i>AES/OFB/PKCS5Padding</i> * </pre> * * </ul> @@ -158,7 +158,7 @@ * <p>Another provider may implement a class for each of the above modes * (i.e., one class for <i>ECB</i>, one for <i>CBC</i>, one for <i>CFB</i>, * and one for <i>OFB</i>), one class for <i>PKCS5Padding</i>, - * and a generic <i>DES</i> class that subclasses from <code>CipherSpi</code>. + * and a generic <i>AES</i> class that subclasses from <code>CipherSpi</code>. * That provider would have the following * <code>Cipher</code> properties in its master class: * @@ -166,7 +166,7 @@ * * <li> * <pre> - * <code>Cipher.</code><i>DES</i> + * <code>Cipher.</code><i>AES</i> * </pre> * * </ul>
--- a/src/share/classes/javax/crypto/Mac.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/javax/crypto/Mac.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2017, 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,7 +50,7 @@ * * <p> A MAC mechanism that is based on cryptographic hash functions is * referred to as HMAC. HMAC can be used with any cryptographic hash function, - * e.g., MD5 or SHA-1, in combination with a secret shared key. HMAC is + * e.g., SHA256 or SHA384, in combination with a secret shared key. HMAC is * specified in RFC 2104. * * <p> Every implementation of the Java platform is required to support
--- a/src/share/classes/javax/crypto/SealedObject.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/javax/crypto/SealedObject.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,8 @@ package javax.crypto; +import sun.misc.SharedSecrets; + import java.io.*; import java.security.AlgorithmParameters; import java.security.Key; @@ -40,7 +42,7 @@ * <p> Given any Serializable object, one can create a SealedObject * that encapsulates the original object, in serialized * format (i.e., a "deep copy"), and seals (encrypts) its serialized contents, - * using a cryptographic algorithm such as DES, to protect its + * using a cryptographic algorithm such as AES, to protect its * confidentiality. The encrypted content can later be decrypted (with * the corresponding algorithm using the correct decryption key) and * de-serialized, yielding the original object. @@ -287,17 +289,7 @@ throws IOException, ClassNotFoundException, IllegalBlockSizeException, BadPaddingException { - /* - * Unseal the object - */ - byte[] content = c.doFinal(this.encryptedContent); - - /* - * De-serialize it - */ - // creating a stream pipe-line, from b to a - ByteArrayInputStream b = new ByteArrayInputStream(content); - ObjectInput a = new extObjectInputStream(b); + ObjectInput a = getExtObjectInputStream(c); try { Object obj = a.readObject(); return obj; @@ -417,17 +409,7 @@ throw new RuntimeException(iape.getMessage()); } - /* - * Unseal the object - */ - byte[] content = c.doFinal(this.encryptedContent); - - /* - * De-serialize it - */ - // creating a stream pipe-line, from b to a - ByteArrayInputStream b = new ByteArrayInputStream(content); - ObjectInput a = new extObjectInputStream(b); + ObjectInput a = getExtObjectInputStream(c); try { Object obj = a.readObject(); return obj; @@ -450,6 +432,19 @@ if (encodedParams != null) encodedParams = encodedParams.clone(); } + + // This method is also called inside SealedObjectForKeyProtector.java. + private ObjectInputStream getExtObjectInputStream(Cipher c) + throws BadPaddingException, IllegalBlockSizeException, IOException { + + byte[] content = c.doFinal(this.encryptedContent); + ByteArrayInputStream b = new ByteArrayInputStream(content); + return new extObjectInputStream(b); + } + + static { + SharedSecrets.setJavaxCryptoSealedObjectAccess((obj,c) -> obj.getExtObjectInputStream(c)); + } } final class extObjectInputStream extends ObjectInputStream {
--- a/src/share/classes/javax/management/openmbean/TabularDataSupport.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/javax/management/openmbean/TabularDataSupport.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import sun.misc.SharedSecrets; // jmx import // @@ -911,6 +912,8 @@ throws IOException, ClassNotFoundException { in.defaultReadObject(); List<String> tmpNames = tabularType.getIndexNames(); - indexNamesArray = tmpNames.toArray(new String[tmpNames.size()]); + int size = tmpNames.size(); + SharedSecrets.getJavaOISAccess().checkArray(in, String[].class, size); + indexNamesArray = tmpNames.toArray(new String[size]); } }
--- a/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/javax/management/remote/rmi/RMIConnectorServer.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; -import sun.misc.ObjectInputFilter; import java.io.ObjectOutputStream; import java.net.MalformedURLException; import java.rmi.server.RMIClientSocketFactory;
--- a/src/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ package javax.management.remote.rmi; import java.io.IOException; -import sun.misc.ObjectInputFilter; import java.rmi.NoSuchObjectException; import java.rmi.Remote; import java.rmi.RemoteException; @@ -48,11 +47,6 @@ import sun.rmi.server.DeserializationChecker; import sun.rmi.server.UnicastServerRef; import sun.rmi.server.UnicastServerRef2; -import java.util.Arrays; -import java.util.Set; -import java.util.stream.Collectors; -import sun.rmi.transport.LiveRef; - /** * <p>An {@link RMIServer} object that is exported through JRMP and that @@ -65,6 +59,8 @@ */ public class RMIJRMPServerImpl extends RMIServerImpl { + private final ExportedWrapper exportedWrapper; + /** * <p>Creates a new {@link RMIServer} object that will be exported * on the given port using the given socket factories.</p> @@ -105,37 +101,31 @@ String[] credentialsTypes = (String[]) this.env.get(EnvHelp.CREDENTIAL_TYPES); - - String credentialsFilter - = (String) this.env.get(EnvHelp.CREDENTIALS_FILTER_PATTERN); - - if(credentialsFilter != null){ - cFilter = ObjectInputFilter.Config.createFilter(credentialsFilter); - allowedTypes = null; + List<String> types = null; + if (credentialsTypes != null) { + types = new ArrayList<>(); + for (String type : credentialsTypes) { + if (type == null) { + throw new IllegalArgumentException("A credential type is null."); + } + ReflectUtil.checkPackageAccess(type); + types.add(type); + } } - else if (credentialsTypes != null) { - allowedTypes = Arrays.stream(credentialsTypes).filter( - s -> s!= null).collect(Collectors.toSet()); - allowedTypes.stream().forEach(ReflectUtil::checkPackageAccess); - cFilter = this::newClientCheckInput; - } else { - allowedTypes = null; - cFilter = null; - } - - String userJmxFilter = - (String) this.env.get(EnvHelp.SERIAL_FILTER_PATTERN); - if(userJmxFilter != null && !userJmxFilter.isEmpty()) - jmxRmiFilter = ObjectInputFilter.Config.createFilter(userJmxFilter); - else - jmxRmiFilter = null; + exportedWrapper = types != null ? + new ExportedWrapper(this, types) : + null; } protected void export() throws IOException { - export(this, cFilter); + if (exportedWrapper != null) { + export(exportedWrapper); + } else { + export(this); + } } - private void export(Remote obj, ObjectInputFilter typeFilter) throws RemoteException { + private void export(Remote obj) throws RemoteException { final RMIExporter exporter = (RMIExporter) env.get(RMIExporter.EXPORTER_ATTRIBUTE); final boolean daemon = EnvHelp.isServerDaemon(env); @@ -146,14 +136,16 @@ " cannot be used to specify an exporter!"); } - if (exporter != null) { - exporter.exportObject(obj, port, csf, ssf, typeFilter); - } else { + if (daemon) { if (csf == null && ssf == null) { - new UnicastServerRef(new LiveRef(port), typeFilter).exportObject(obj, null, daemon); + new UnicastServerRef(port).exportObject(obj, null, true); } else { - new UnicastServerRef2(port, csf, ssf, typeFilter).exportObject(obj, null, daemon); + new UnicastServerRef2(port, csf, ssf).exportObject(obj, null, true); } + } else if (exporter != null) { + exporter.exportObject(obj, port, csf, ssf); + } else { + UnicastRemoteObject.exportObject(obj, port, csf, ssf); } } @@ -180,7 +172,11 @@ * RMIJRMPServerImpl has not been exported yet. */ public Remote toStub() throws IOException { - return RemoteObject.toStub(this); + if (exportedWrapper != null) { + return RemoteObject.toStub(exportedWrapper); + } else { + return RemoteObject.toStub(this); + } } /** @@ -210,7 +206,7 @@ RMIConnection client = new RMIConnectionImpl(this, connectionId, getDefaultClassLoader(), subject, env); - export(client, jmxRmiFilter); + export(client); return client; } @@ -227,38 +223,56 @@ * server failed. */ protected void closeServer() throws IOException { - unexport(this, true); + if (exportedWrapper != null) { + unexport(exportedWrapper, true); + } else { + unexport(this, true); + } } - /** - * Check that a type in the remote invocation of {@link RMIServerImpl#newClient} - * is one of the {@code allowedTypes}. - * - * @param clazz the class; may be null - * @param size the size for arrays, otherwise is 0 - * @param nObjectRefs the current number of object references - * @param depth the current depth - * @param streamBytes the current number of bytes consumed - * @return {@code ObjectInputFilter.Status.ALLOWED} if the class is allowed, - * otherwise {@code ObjectInputFilter.Status.REJECTED} - */ - ObjectInputFilter.Status newClientCheckInput(ObjectInputFilter.FilterInfo filterInfo) { - ObjectInputFilter.Status status = ObjectInputFilter.Status.UNDECIDED; - if (allowedTypes != null && filterInfo.serialClass() != null) { - // If enabled, check type - String type = filterInfo.serialClass().getName(); - if (allowedTypes.contains(type)) - status = ObjectInputFilter.Status.ALLOWED; - else - status = ObjectInputFilter.Status.REJECTED; - } - return status; - } private final int port; private final RMIClientSocketFactory csf; private final RMIServerSocketFactory ssf; private final Map<String, ?> env; - private final Set<String> allowedTypes; - private final ObjectInputFilter jmxRmiFilter; - private final ObjectInputFilter cFilter; + + private static class ExportedWrapper implements RMIServer, DeserializationChecker { + private final RMIServer impl; + private final List<String> allowedTypes; + private ExportedWrapper(RMIServer impl, List<String> credentialsTypes) { + this.impl = impl; + allowedTypes = credentialsTypes; + } + + @Override + public String getVersion() throws RemoteException { + return impl.getVersion(); + } + + @Override + public RMIConnection newClient(Object credentials) throws IOException { + return impl.newClient(credentials); + } + + @Override + public void check(Method method, ObjectStreamClass descriptor, + int paramIndex, int callID) { + + String type = descriptor.getName(); + if (!allowedTypes.contains(type)) { + throw new ClassCastException("Unsupported type: " + type); + } + } + + @Override + public void checkProxyClass(Method method, String[] ifaces, + int paramIndex, int callID) { + if (ifaces != null && ifaces.length > 0) { + for (String iface : ifaces) { + if (!allowedTypes.contains(iface)) { + throw new ClassCastException("Unsupported type: " + iface); + } + } + } + } + } }
--- a/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/management/jmxremote/ConnectorBootstrap.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import sun.misc.ObjectInputFilter; +import java.io.Serializable; import java.lang.management.ManagementFactory; import java.net.InetAddress; import java.net.MalformedURLException; @@ -43,6 +43,7 @@ import java.rmi.registry.Registry; import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; +import java.rmi.server.RMISocketFactory; import java.rmi.server.RemoteObject; import java.rmi.server.UnicastRemoteObject; import java.security.KeyStore; @@ -82,7 +83,6 @@ import sun.rmi.server.UnicastRef; import sun.rmi.server.UnicastServerRef; import sun.rmi.server.UnicastServerRef2; -import sun.rmi.transport.LiveRef; /** * This class initializes and starts the RMIConnectorServer for JSR 163 @@ -141,8 +141,6 @@ "com.sun.management.jmxremote.ssl.need.client.auth"; public static final String SSL_CONFIG_FILE_NAME = "com.sun.management.jmxremote.ssl.config.file"; - public static final String SERIAL_FILTER_PATTERN = - "com.sun.management.jmxremote.serial.filter.pattern"; } /** @@ -183,8 +181,7 @@ public Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, - RMIServerSocketFactory ssf, - ObjectInputFilter filter) + RMIServerSocketFactory ssf) throws RemoteException { synchronized (this) { @@ -195,9 +192,9 @@ final UnicastServerRef ref; if (csf == null && ssf == null) { - ref = new UnicastServerRef(new LiveRef(port), filter); + ref = new UnicastServerRef(port); } else { - ref = new UnicastServerRef2(port, csf, ssf, filter); + ref = new UnicastServerRef2(port, csf, ssf); } return ref.exportObject(obj, null, true); } @@ -437,7 +434,6 @@ final String bindAddress = props.getProperty(PropertyNames.HOST); - final String jmxRmiFilter = props.getProperty(PropertyNames.SERIAL_FILTER_PATTERN); if (log.debugOn()) { log.debug("startRemoteConnectorServer", @@ -474,7 +470,7 @@ sslConfigFileName, enabledCipherSuitesList, enabledProtocolsList, sslNeedClientAuth, useAuthentication, loginConfigName, - passwordFileName, accessFileName, bindAddress, jmxRmiFilter); + passwordFileName, accessFileName, bindAddress); cs = data.jmxConnectorServer; url = data.jmxRemoteURL; log.config("startRemoteConnectorServer", @@ -514,7 +510,9 @@ // This RMI server should not keep the VM alive Map<String, Object> env = new HashMap<>(); env.put(RMIExporter.EXPORTER_ATTRIBUTE, new PermanentExporter()); - env.put(EnvHelp.CREDENTIALS_FILTER_PATTERN, String.class.getName() + ";!*"); + env.put(EnvHelp.CREDENTIAL_TYPES, new String[]{ + String[].class.getName(), String.class.getName() + }); // The local connector server need only be available via the // loopback connection. @@ -730,8 +728,7 @@ String loginConfigName, String passwordFileName, String accessFileName, - String bindAddress, - String jmxRmiFilter) + String bindAddress) throws IOException, MalformedURLException { /* Make sure we use non-guessable RMI object IDs. Otherwise @@ -746,11 +743,9 @@ PermanentExporter exporter = new PermanentExporter(); env.put(RMIExporter.EXPORTER_ATTRIBUTE, exporter); - env.put(EnvHelp.CREDENTIALS_FILTER_PATTERN, String.class.getName() + ";!*"); - - if(jmxRmiFilter != null && !jmxRmiFilter.isEmpty()) { - env.put(EnvHelp.SERIAL_FILTER_PATTERN, jmxRmiFilter); - } + env.put(EnvHelp.CREDENTIAL_TYPES, new String[]{ + String[].class.getName(), String.class.getName() + }); boolean useSocketFactory = bindAddress != null && !useSsl;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/misc/JavaObjectInputStreamAccess.java Fri May 25 01:50:25 2018 +0100 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.misc; + +import java.io.ObjectInputStream; + +/** + * The interface to specify methods for accessing {@code ObjectInputStream} + * @author sjiang + */ +public interface JavaObjectInputStreamAccess { + /** + * Sets a descriptor validating. + * @param ois stream to have the descriptors validated + * @param validator validator used to validate a descriptor. + */ + public void setValidator(ObjectInputStream ois, ObjectStreamClassValidator validator); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/misc/JavaxCryptoSealedObjectAccess.java Fri May 25 01:50:25 2018 +0100 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package sun.misc; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.SealedObject; +import java.io.IOException; +import java.io.ObjectInputStream; + +public interface JavaxCryptoSealedObjectAccess { + ObjectInputStream getExtObjectInputStream( + SealedObject sealed, Cipher cipher) + throws BadPaddingException, IllegalBlockSizeException, IOException; +}
--- a/src/share/classes/sun/misc/Launcher.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/misc/Launcher.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ /** * This class is used by the system to launch the main application. -Launcher */ + */ public class Launcher { private static URLStreamHandlerFactory factory = new Factory(); private static Launcher launcher = new Launcher(); @@ -121,6 +121,7 @@ static { ClassLoader.registerAsParallelCapable(); } + private static volatile ExtClassLoader instance = null; /** * create an ExtClassLoader. The ExtClassLoader is created @@ -128,8 +129,17 @@ */ public static ExtClassLoader getExtClassLoader() throws IOException { - final File[] dirs = getExtDirs(); + if (instance == null) { + synchronized(ExtClassLoader.class) { + if (instance == null) { + instance = createExtClassLoader(); + } + } + } + return instance; + } + private static ExtClassLoader createExtClassLoader() throws IOException { try { // Prior implementations of this doPrivileged() block supplied // aa synthesized ACC via a call to the private method @@ -138,6 +148,7 @@ return AccessController.doPrivileged( new PrivilegedExceptionAction<ExtClassLoader>() { public ExtClassLoader run() throws IOException { + final File[] dirs = getExtDirs(); int len = dirs.length; for (int i = 0; i < len; i++) { MetaIndex.registerDirectory(dirs[i]);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/classes/sun/misc/ObjectStreamClassValidator.java Fri May 25 01:50:25 2018 +0100 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.misc; + +import java.io.ObjectStreamClass; + +/** + * A callback used by {@code ObjectInputStream} to do descriptor validation. + * + * @author sjiang + */ +public interface ObjectStreamClassValidator { + /** + * This method will be called by ObjectInputStream to + * check a descriptor just before creating an object described by this descriptor. + * The object will not be created if this method throws a {@code RuntimeException}. + * @param descriptor descriptor to be checked. + */ + public void validateDescriptor(ObjectStreamClass descriptor); +}
--- a/src/share/classes/sun/misc/SharedSecrets.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/misc/SharedSecrets.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ package sun.misc; -import java.io.ObjectInputStream; +import javax.crypto.SealedObject; import java.util.jar.JarFile; import java.io.Console; import java.io.FileDescriptor; @@ -58,6 +58,8 @@ private static JavaUtilZipFileAccess javaUtilZipFileAccess; private static JavaAWTAccess javaAWTAccess; private static JavaOISAccess javaOISAccess; + private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess; + private static JavaObjectInputStreamAccess javaObjectInputStreamAccess; public static JavaUtilJarAccess javaUtilJarAccess() { if (javaUtilJarAccess == null) { @@ -199,4 +201,27 @@ } return javaAWTAccess; } + + + public static JavaObjectInputStreamAccess getJavaObjectInputStreamAccess() { + if (javaObjectInputStreamAccess == null) { + unsafe.ensureClassInitialized(ObjectInputStream.class); + } + return javaObjectInputStreamAccess; + } + + public static void setJavaObjectInputStreamAccess(JavaObjectInputStreamAccess access) { + javaObjectInputStreamAccess = access; + } + + public static void setJavaxCryptoSealedObjectAccess(JavaxCryptoSealedObjectAccess jcsoa) { + javaxCryptoSealedObjectAccess = jcsoa; + } + + public static JavaxCryptoSealedObjectAccess getJavaxCryptoSealedObjectAccess() { + if (javaxCryptoSealedObjectAccess == null) { + unsafe.ensureClassInitialized(SealedObject.class); + } + return javaxCryptoSealedObjectAccess; + } }
--- a/src/share/classes/sun/misc/VM.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/misc/VM.java Fri May 25 01:50:25 2018 +0100 @@ -26,6 +26,8 @@ package sun.misc; import static java.lang.Thread.State.*; +import java.io.IOException; +import java.security.AccessControlException; import java.util.Properties; import java.util.HashMap; import java.util.Map; @@ -399,10 +401,23 @@ private final static int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020; /* - * Returns the first non-null class loader up the execution stack, - * or null if only code from the null class loader is on the stack. + * Returns first non-privileged class loader on the stack (excluding + * reflection generated frames) or the extension class loader if only + * class loaded by the boot class loader and extension class loader are + * found on the stack. */ - public static native ClassLoader latestUserDefinedLoader(); + public static native ClassLoader latestUserDefinedLoader0(); + public static ClassLoader latestUserDefinedLoader() { + ClassLoader loader = latestUserDefinedLoader0(); + if (loader != null) { + return loader; + } + try { + return Launcher.ExtClassLoader.getExtClassLoader(); + } catch (IOException e) { + return null; + } + } static { initialize();
--- a/src/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl.java Fri May 25 01:50:25 2018 +0100 @@ -212,7 +212,7 @@ else sb.append(ownerType.toString()); - sb.append("."); + sb.append("$"); if (ownerType instanceof ParameterizedTypeImpl) { // Find simple name of nested type by removing the @@ -220,7 +220,7 @@ sb.append(rawType.getName().replace( ((ParameterizedTypeImpl)ownerType).rawType.getName() + "$", "")); } else - sb.append(rawType.getName()); + sb.append(rawType.getSimpleName()); } else sb.append(rawType.getName());
--- a/src/share/classes/sun/rmi/server/MarshalInputStream.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/rmi/server/MarshalInputStream.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,8 @@ import java.security.AccessControlException; import java.security.Permission; import java.rmi.server.RMIClassLoader; +import sun.misc.ObjectStreamClassValidator; +import sun.misc.SharedSecrets; /** * MarshalInputStream is an extension of ObjectInputStream. When resolving @@ -51,6 +53,11 @@ * @author Peter Jones */ public class MarshalInputStream extends ObjectInputStream { + interface StreamChecker extends ObjectStreamClassValidator { + void checkProxyInterfaceNames(String[] ifaces); + } + + private volatile StreamChecker streamChecker = null; /** * Value of "java.rmi.server.useCodebaseOnly" property, @@ -237,6 +244,11 @@ protected Class<?> resolveProxyClass(String[] interfaces) throws IOException, ClassNotFoundException { + StreamChecker checker = streamChecker; + if (checker != null) { + checker.checkProxyInterfaceNames(interfaces); + } + /* * Always read annotation written by MarshalOutputStream. */ @@ -255,8 +267,10 @@ } /* - * Returns the first non-null class loader up the execution stack, or null - * if only code from the null class loader is on the stack. + * Returns first non-privileged class loader on the stack (excluding + * reflection generated frames) or the extension class loader if only + * class loaded by the boot class loader and extension class loader are + * found on the stack. */ private static ClassLoader latestUserDefinedLoader() { return sun.misc.VM.latestUserDefinedLoader(); @@ -316,4 +330,28 @@ void useCodebaseOnly() { useCodebaseOnly = true; } + + synchronized void setStreamChecker(StreamChecker checker) { + streamChecker = checker; + SharedSecrets.getJavaObjectInputStreamAccess().setValidator(this, checker); + } + @Override + protected ObjectStreamClass readClassDescriptor() throws IOException, + ClassNotFoundException { + ObjectStreamClass descriptor = super.readClassDescriptor(); + + validateDesc(descriptor); + + return descriptor; + } + + private void validateDesc(ObjectStreamClass descriptor) { + StreamChecker checker; + synchronized (this) { + checker = streamChecker; + } + if (checker != null) { + checker.validateDescriptor(descriptor); + } + } }
--- a/src/share/classes/sun/rmi/server/UnicastServerRef.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/rmi/server/UnicastServerRef.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import java.io.ObjectInput; import java.io.ObjectInputStream; import java.io.ObjectOutput; +import java.io.ObjectStreamClass; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.rmi.AccessException; @@ -331,15 +332,10 @@ logCall(obj, method); // unmarshal parameters - Class<?>[] types = method.getParameterTypes(); - Object[] params = new Object[types.length]; - + Object[] params = null; try { unmarshalCustomCallData(in); - // Unmarshal the parameters - for (int i = 0; i < types.length; i++) { - params[i] = unmarshalValue(types[i], in); - } + params = unmarshalParameters(obj, method, marshalStream); } catch (AccessException aex) { // For compatibility, AccessException is not wrapped in UnmarshalException @@ -609,4 +605,84 @@ } } + /** + * Unmarshal parameters for the given method of the given instance over + * the given marshalinputstream. Perform any necessary checks. + */ + private Object[] unmarshalParameters(Object obj, Method method, MarshalInputStream in) + throws IOException, ClassNotFoundException { + return (obj instanceof DeserializationChecker) ? + unmarshalParametersChecked((DeserializationChecker)obj, method, in) : + unmarshalParametersUnchecked(method, in); + } + + /** + * Unmarshal parameters for the given method of the given instance over + * the given marshalinputstream. Do not perform any additional checks. + */ + private Object[] unmarshalParametersUnchecked(Method method, ObjectInput in) + throws IOException, ClassNotFoundException { + Class<?>[] types = method.getParameterTypes(); + Object[] params = new Object[types.length]; + for (int i = 0; i < types.length; i++) { + params[i] = unmarshalValue(types[i], in); + } + return params; + } + + /** + * Unmarshal parameters for the given method of the given instance over + * the given marshalinputstream. Do perform all additional checks. + */ + private Object[] unmarshalParametersChecked( + DeserializationChecker checker, + Method method, MarshalInputStream in) + throws IOException, ClassNotFoundException { + int callID = methodCallIDCount.getAndIncrement(); + MyChecker myChecker = new MyChecker(checker, method, callID); + in.setStreamChecker(myChecker); + try { + Class<?>[] types = method.getParameterTypes(); + Object[] values = new Object[types.length]; + for (int i = 0; i < types.length; i++) { + myChecker.setIndex(i); + values[i] = unmarshalValue(types[i], in); + } + myChecker.end(callID); + return values; + } finally { + in.setStreamChecker(null); + } + } + + private static class MyChecker implements MarshalInputStream.StreamChecker { + private final DeserializationChecker descriptorCheck; + private final Method method; + private final int callID; + private int parameterIndex; + + MyChecker(DeserializationChecker descriptorCheck, Method method, int callID) { + this.descriptorCheck = descriptorCheck; + this.method = method; + this.callID = callID; + } + + @Override + public void validateDescriptor(ObjectStreamClass descriptor) { + descriptorCheck.check(method, descriptor, parameterIndex, callID); + } + + @Override + public void checkProxyInterfaceNames(String[] ifaces) { + descriptorCheck.checkProxyClass(method, ifaces, parameterIndex, callID); + } + + void setIndex(int parameterIndex) { + this.parameterIndex = parameterIndex; + } + + void end(int callId) { + descriptorCheck.end(callId); + } + } }
--- a/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java Fri May 25 01:50:25 2018 +0100 @@ -119,6 +119,11 @@ } }); + private static final boolean disableIncomingHttp = + java.security.AccessController.doPrivileged( + new GetPropertyAction("sun.rmi.server.disableIncomingHttp", "true")) + .equalsIgnoreCase("true"); + /** total connections handled */ private static final AtomicInteger connectionCount = new AtomicInteger(0); @@ -722,6 +727,10 @@ int magic = in.readInt(); if (magic == POST) { + System.err.println("DISABLED: " + disableIncomingHttp); + if (disableIncomingHttp) { + throw new RemoteException("RMI over HTTP is disabled"); + } tcpLog.log(Log.BRIEF, "decoding HTTP-wrapped call"); // It's really a HTTP-wrapped request. Repackage
--- a/src/share/classes/sun/security/pkcs11/P11RSACipher.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/security/pkcs11/P11RSACipher.java Fri May 25 01:50:25 2018 +0100 @@ -357,7 +357,9 @@ System.arraycopy(buffer, 0, tmpBuffer, 0, bufOfs); tmpBuffer = p11.C_Sign(session.id(), tmpBuffer); if (tmpBuffer.length > outLen) { - throw new BadPaddingException("Output buffer too small"); + throw new BadPaddingException( + "Output buffer (" + outLen + ") is too small to " + + "hold the produced data (" + tmpBuffer.length + ")"); } System.arraycopy(tmpBuffer, 0, out, outOfs, tmpBuffer.length); n = tmpBuffer.length;
--- a/src/share/classes/sun/security/provider/PolicyFile.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/security/provider/PolicyFile.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,6 @@ import java.io.FilePermission; import java.net.SocketPermission; import java.net.NetPermission; -import java.util.concurrent.atomic.AtomicReference; import sun.misc.JavaSecurityProtectionDomainAccess; import static sun.misc.JavaSecurityProtectionDomainAccess.ProtectionDomainCache; import sun.misc.SharedSecrets; @@ -274,7 +273,8 @@ private static final int DEFAULT_CACHE_SIZE = 1; // contains the policy grant entries, PD cache, and alias mapping - private AtomicReference<PolicyInfo> policyInfo = new AtomicReference<>(); + // can be updated if refresh() is called + private volatile PolicyInfo policyInfo; private boolean constructed = false; private boolean expandProperties = true; @@ -437,7 +437,7 @@ // System.out.println("number caches=" + numCaches); PolicyInfo newInfo = new PolicyInfo(numCaches); initPolicyFile(newInfo, url); - policyInfo.set(newInfo); + policyInfo = newInfo; } private void initPolicyFile(final PolicyInfo newInfo, final URL url) { @@ -1074,9 +1074,7 @@ */ @Override public boolean implies(ProtectionDomain pd, Permission p) { - PolicyInfo pi = policyInfo.get(); - ProtectionDomainCache pdMap = pi.getPdMapping(); - + ProtectionDomainCache pdMap = policyInfo.getPdMapping(); PermissionCollection pc = pdMap.get(pd); if (pc != null) { @@ -1222,7 +1220,7 @@ private Permissions getPermissions(Permissions perms, final CodeSource cs, Principal[] principals) { - PolicyInfo pi = policyInfo.get(); + PolicyInfo pi = policyInfo; for (PolicyEntry entry : pi.policyEntries) { addPermissions(perms, cs, principals, entry);
--- a/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Fri May 25 01:50:25 2018 +0100 @@ -31,6 +31,7 @@ import java.util.*; import sun.security.provider.certpath.PKIX.ValidatorParams; +import sun.security.validator.Validator; import sun.security.x509.X509CertImpl; import sun.security.util.Debug; @@ -189,12 +190,21 @@ params.policyQualifiersRejected(), rootNode); certPathCheckers.add(pc); - // default value for date is current time - BasicChecker bc; - bc = new BasicChecker(anchor, - (params.timestamp() == null ? params.date() : - params.timestamp().getTimestamp()), - params.sigProvider(), false); + + // the time that the certificate validity period should be + // checked against + Date timeToCheck = null; + // use timestamp if checking signed code that is timestamped, otherwise + // use date parameter from PKIXParameters + if ((params.variant() == Validator.VAR_CODE_SIGNING || + params.variant() == Validator.VAR_PLUGIN_CODE_SIGNING) && + params.timestamp() != null) { + timeToCheck = params.timestamp().getTimestamp(); + } else { + timeToCheck = params.date(); + } + BasicChecker bc = new BasicChecker(anchor, timeToCheck, + params.sigProvider(), false); certPathCheckers.add(bc); boolean revCheckerAdded = false;
--- a/src/share/classes/sun/security/rsa/RSAPadding.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/security/rsa/RSAPadding.java Fri May 25 01:50:25 2018 +0100 @@ -253,7 +253,8 @@ public byte[] pad(byte[] data) throws BadPaddingException { if (data.length > maxDataSize) { throw new BadPaddingException("Data must be shorter than " - + (maxDataSize + 1) + " bytes"); + + (maxDataSize + 1) + " bytes but received " + + data.length + " bytes."); } switch (type) { case PAD_NONE: @@ -281,7 +282,9 @@ */ public byte[] unpad(byte[] padded) throws BadPaddingException { if (padded.length != paddedSize) { - throw new BadPaddingException("Decryption error"); + throw new BadPaddingException("Decryption error." + + "The padded array length (" + padded.length + + ") is not the specified padded size (" + paddedSize + ")"); } switch (type) { case PAD_NONE:
--- a/src/share/classes/sun/security/ssl/CipherBox.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/security/ssl/CipherBox.java Fri May 25 01:50:25 2018 +0100 @@ -493,7 +493,9 @@ if (protocolVersion.v >= ProtocolVersion.TLS11.v) { if (newLen < blockSize) { - throw new BadPaddingException("invalid explicit IV"); + throw new BadPaddingException("The length after " + + "padding removal (" + newLen + ") should be larger " + + "than <" + blockSize + "> since explicit IV used"); } } } @@ -504,7 +506,6 @@ } } - /* * Decrypts a block of data, returning the size of the * resulting block if padding was required. position and limit @@ -575,7 +576,9 @@ // check the explicit IV of TLS v1.1 or later if (protocolVersion.v >= ProtocolVersion.TLS11.v) { if (newLen < blockSize) { - throw new BadPaddingException("invalid explicit IV"); + throw new BadPaddingException("The length after " + + "padding removal (" + newLen + ") should be larger " + + "than <" + blockSize + "> since explicit IV used"); } // reset the position to the end of the decrypted data @@ -756,7 +759,9 @@ // so accept that as well // v3 does not require any particular value for the other bytes if (padLen > blockSize) { - throw new BadPaddingException("Invalid SSLv3 padding"); + throw new BadPaddingException("Padding length (" + + padLen + ") of SSLv3 message should not be bigger " + + "than the block size (" + blockSize + ")"); } } return newLen; @@ -802,7 +807,9 @@ // so accept that as well // v3 does not require any particular value for the other bytes if (padLen > blockSize) { - throw new BadPaddingException("Invalid SSLv3 padding"); + throw new BadPaddingException("Padding length (" + + padLen + ") of SSLv3 message should not be bigger " + + "than the block size (" + blockSize + ")"); } } @@ -925,7 +932,10 @@ case AEAD_CIPHER: if (bb.remaining() < (recordIvSize + tagSize)) { throw new BadPaddingException( - "invalid AEAD cipher fragment"); + "Insufficient buffer remaining for AEAD cipher " + + "fragment (" + bb.remaining() + "). Needs to be " + + "more than or equal to IV size (" + recordIvSize + + ") + tag size (" + tagSize + ")"); } // initialize the AEAD cipher for the unique IV
--- a/src/share/classes/sun/security/tools/keytool/Resources_de.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/security/tools/keytool/Resources_de.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -425,11 +425,11 @@ // 8171319: keytool should print out warnings when reading or // generating cert/cert req using weak algorithms - {"the.certificate.request", "Die Zertifikatsanforderung"}, + {"the.certificate.request", "Die Zertifikatanforderung"}, {"the.issuer", "Der Aussteller"}, {"the.generated.certificate", "Das generierte Zertifikat"}, {"the.generated.crl", "Die generierte CRL"}, - {"the.generated.certificate.request", "Die generierte Zertifikatsanforderung"}, + {"the.generated.certificate.request", "Die generierte Zertifikatanforderung"}, {"the.certificate", "Das Zertifikat"}, {"the.crl", "Die CRL"}, {"the.tsa.certificate", "Das TSA-Zertifikat"}, @@ -444,7 +444,7 @@ {".PATTERN.printX509Cert.with.weak", "Eigent\u00FCmer: {0}\nAussteller: {1}\nSeriennummer: {2}\nG\u00FCltig von: {3} bis: {4}\nZertifikatfingerprints:\n\t MD5: {5}\n\t SHA1: {6}\n\t SHA256: {7}\nSignaturalgorithmusname: {8}\nAlgorithmus des Public Key von Betreff: {9}\nVersion: {10}"}, {"PKCS.10.with.weak", - "PKCS #10-Zertifikatsanforderung (Version 1.0)\nSubject: %1$s\nFormat: %2$s\nPublic Key: %3$s\nSignaturalgorithmus: %4$s\n"}, + "PKCS #10-Zertifikatanforderung (Version 1.0)\nSubject: %1$s\nFormat: %2$s\nPublic Key: %3$s\nSignaturalgorithmus: %4$s\n"}, {"verified.by.s.in.s.weak", "Von %1$s in %2$s mit %3$s verifiziert"}, {"whose.sigalg.risk", "%1$s verwendet den Signaturalgorithmus %2$s. Dies gilt als Sicherheitsrisiko."}, {"whose.key.risk", "%1$s verwendet %2$s. Dies gilt als Sicherheitsrisiko."},
--- a/src/share/classes/sun/security/tools/policytool/Resources_sv.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/security/tools/policytool/Resources_sv.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,7 +111,7 @@ "Kan inte specificera identitetshavare utan namn"}, {"Permission.and.Target.Name.must.have.a.value", "Beh\u00F6righet och m\u00E5lnamn m\u00E5ste ha ett v\u00E4rde"}, - {"Remove.this.Policy.Entry.", "Vill du ta bort den h\u00E4r policyposten?"}, + {"Remove.this.Policy.Entry.", "Vill du ta bort policyposten?"}, {"Overwrite.File", "Skriv \u00F6ver fil"}, {"Policy.successfully.written.to.filename", "Policy har skrivits till {0}"},
--- a/src/share/classes/sun/security/util/ManifestDigester.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/security/util/ManifestDigester.java Fri May 25 01:50:25 2018 +0100 @@ -26,8 +26,10 @@ package sun.security.util; import java.security.*; +import java.util.ArrayList; import java.util.HashMap; import java.io.ByteArrayOutputStream; +import java.util.List; /** * This class is used to compute digests on sections of the Manifest. @@ -39,7 +41,7 @@ /** the raw bytes of the manifest */ private byte rawBytes[]; - /** the offset/length pair for a section */ + /** the entries grouped by names */ private HashMap<String, Entry> entries; // key is a UTF-8 string /** state returned by findSection */ @@ -120,8 +122,8 @@ return; // XXX: exception? // create an entry for main attributes - entries.put(MF_MAIN_ATTRS, - new Entry(0, pos.endOfSection + 1, pos.startOfNext, rawBytes)); + entries.put(MF_MAIN_ATTRS, new Entry().addSection( + new Section(0, pos.endOfSection + 1, pos.startOfNext, rawBytes))); int start = pos.startOfNext; while(findSection(start, pos)) { @@ -167,9 +169,15 @@ } } - entries.put(nameBuf.toString(), - new Entry(start, sectionLen, sectionLenWithBlank, - rawBytes)); + Entry e = entries.get(nameBuf.toString()); + if (e == null) { + entries.put(nameBuf.toString(), new Entry() + .addSection(new Section(start, sectionLen, + sectionLenWithBlank, rawBytes))); + } else { + e.addSection(new Section(start, sectionLen, + sectionLenWithBlank, rawBytes)); + } } catch (java.io.UnsupportedEncodingException uee) { throw new IllegalStateException( @@ -192,13 +200,52 @@ } public static class Entry { + + // One Entry for one name, and one name can have multiple sections. + // According to the JAR File Specification: "If there are multiple + // individual sections for the same file entry, the attributes in + // these sections are merged." + private List<Section> sections = new ArrayList<>(); + boolean oldStyle; + + private Entry addSection(Section sec) + { + sections.add(sec); + return this; + } + + public byte[] digest(MessageDigest md) + { + md.reset(); + for (Section sec : sections) { + if (oldStyle) { + Section.doOldStyle(md, sec.rawBytes, sec.offset, sec.lengthWithBlankLine); + } else { + md.update(sec.rawBytes, sec.offset, sec.lengthWithBlankLine); + } + } + return md.digest(); + } + + /** Netscape doesn't include the new line. Intel and JavaSoft do */ + + public byte[] digestWorkaround(MessageDigest md) + { + md.reset(); + for (Section sec : sections) { + md.update(sec.rawBytes, sec.offset, sec.length); + } + return md.digest(); + } + } + + private static class Section { int offset; int length; int lengthWithBlankLine; byte[] rawBytes; - boolean oldStyle; - public Entry(int offset, int length, + public Section(int offset, int length, int lengthWithBlankLine, byte[] rawBytes) { this.offset = offset; @@ -207,18 +254,7 @@ this.rawBytes = rawBytes; } - public byte[] digest(MessageDigest md) - { - md.reset(); - if (oldStyle) { - doOldStyle(md,rawBytes, offset, lengthWithBlankLine); - } else { - md.update(rawBytes, offset, lengthWithBlankLine); - } - return md.digest(); - } - - private void doOldStyle(MessageDigest md, + private static void doOldStyle(MessageDigest md, byte[] bytes, int offset, int length) @@ -242,16 +278,6 @@ } md.update(bytes, start, i-start); } - - - /** Netscape doesn't include the new line. Intel and JavaSoft do */ - - public byte[] digestWorkaround(MessageDigest md) - { - md.reset(); - md.update(rawBytes, offset, length); - return md.digest(); - } } public Entry get(String name, boolean oldStyle) {
--- a/src/share/classes/sun/security/util/Resources_sv.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/classes/sun/security/util/Resources_sv.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ // javax.security.auth.PrivateCredentialPermission {"invalid.null.input.s.", "ogiltiga null-indata"}, - {"actions.can.only.be.read.", "funktioner kan endast 'l\u00E4sas'"}, + {"actions.can.only.be.read.", "\u00E5tg\u00E4rder kan endast 'l\u00E4sas'"}, {"permission.name.name.syntax.invalid.", "syntaxen f\u00F6r beh\u00F6righetsnamnet [{0}] \u00E4r ogiltig: "}, {"Credential.Class.not.followed.by.a.Principal.Class.and.Name",
--- a/src/share/lib/management/management.properties Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/lib/management/management.properties Fri May 25 01:50:25 2018 +0100 @@ -329,38 +329,3 @@ # The format of the value for that property is any string accepted # by java.net.InetAddress.getByName(String). # - -# ################ Filter for ObjectInputStream ############################# -# com.sun.management.jmxremote.serial.filter.pattern=<filter-string> -# A filter, if configured, is used by java.io.ObjectInputStream during -# deserialization of parameters sent to the JMX default agent to validate the -# contents of the stream. -# A filter is configured as a sequence of patterns, each pattern is either -# matched against the name of a class in the stream or defines a limit. -# Patterns are separated by ";" (semicolon). -# Whitespace is significant and is considered part of the pattern. -# -# If a pattern includes a "=", it sets a limit. -# If a limit appears more than once the last value is used. -# Limits are checked before classes regardless of the order in the sequence of patterns. -# If any of the limits are exceeded, the filter status is REJECTED. -# -# maxdepth=value - the maximum depth of a graph -# maxrefs=value - the maximum number of internal references -# maxbytes=value - the maximum number of bytes in the input stream -# maxarray=value - the maximum array length allowed -# -# Other patterns, from left to right, match the class or package name as -# returned from Class.getName. -# If the class is an array type, the class or package to be matched is the element type. -# Arrays of any number of dimensions are treated the same as the element type. -# For example, a pattern of "!example.Foo", rejects creation of any instance or -# array of example.Foo. -# -# If the pattern starts with "!", the status is REJECTED if the remaining pattern -# is matched; otherwise the status is ALLOWED if the pattern matches. -# If the pattern ends with ".**" it matches any class in the package and all subpackages. -# If the pattern ends with ".*" it matches any class in the package. -# If the pattern ends with "*", it matches any class with the pattern as a prefix. -# If the pattern is equal to the class name, it matches. -# Otherwise, the status is UNDECIDED.
--- a/src/share/lib/security/java.security-aix Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/lib/security/java.security-aix Fri May 25 01:50:25 2018 +0100 @@ -627,7 +627,7 @@ # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 1024, \ - EC keySize < 224, DES40_CBC, RC4_40 + EC keySize < 224, DES40_CBC, RC4_40, 3DES_EDE_CBC # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -853,6 +853,7 @@ disallowReferenceUriSchemes file http https,\ minKeySize RSA 1024,\ minKeySize DSA 1024,\ + minKeySize EC 224,\ noDuplicateIds,\ noRetrievalMethodLoops @@ -866,6 +867,9 @@ # Patterns are separated by ";" (semicolon). # Whitespace is significant and is considered part of the pattern. # +# If the system property jdk.serialFilter is also specified, it supersedes +# the security property value defined here. +# # If a pattern includes a "=", it sets a limit. # If a limit appears more than once the last value is used. # Limits are checked before classes regardless of the order in the sequence of patterns. @@ -961,3 +965,20 @@ # It is not guaranteed to be examined and used by other implementations. # #com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name + +# +# JCEKS Encrypted Key Serial Filter +# +# This filter, if configured, is used by the JCEKS KeyStore during the +# deserialization of the encrypted Key object stored inside a key entry. +# If not configured or the filter result is UNDECIDED (i.e. none of the patterns +# matches), the filter configured by jdk.serialFilter will be consulted. +# +# If the system property jceks.key.serialFilter is also specified, it supersedes +# the security property value defined here. +# +# The filter pattern uses the same format as jdk.serialFilter. The default +# pattern allows java.lang.Enum, java.security.KeyRep, java.security.KeyRep$Type, +# and javax.crypto.spec.SecretKeySpec and rejects all the others. +jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;\ + java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;!*
--- a/src/share/lib/security/java.security-linux Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/lib/security/java.security-linux Fri May 25 01:50:25 2018 +0100 @@ -627,7 +627,7 @@ # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 1024, \ - EC keySize < 224, DES40_CBC, RC4_40 + EC keySize < 224, DES40_CBC, RC4_40, 3DES_EDE_CBC # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -854,6 +854,7 @@ disallowReferenceUriSchemes file http https,\ minKeySize RSA 1024,\ minKeySize DSA 1024,\ + minKeySize EC 224,\ noDuplicateIds,\ noRetrievalMethodLoops @@ -867,6 +868,9 @@ # Patterns are separated by ";" (semicolon). # Whitespace is significant and is considered part of the pattern. # +# If the system property jdk.serialFilter is also specified, it supersedes +# the security property value defined here. +# # If a pattern includes a "=", it sets a limit. # If a limit appears more than once the last value is used. # Limits are checked before classes regardless of the order in the sequence of patterns. @@ -967,3 +971,20 @@ # It is not guaranteed to be examined and used by other implementations. # #com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name + +# +# JCEKS Encrypted Key Serial Filter +# +# This filter, if configured, is used by the JCEKS KeyStore during the +# deserialization of the encrypted Key object stored inside a key entry. +# If not configured or the filter result is UNDECIDED (i.e. none of the patterns +# matches), the filter configured by jdk.serialFilter will be consulted. +# +# If the system property jceks.key.serialFilter is also specified, it supersedes +# the security property value defined here. +# +# The filter pattern uses the same format as jdk.serialFilter. The default +# pattern allows java.lang.Enum, java.security.KeyRep, java.security.KeyRep$Type, +# and javax.crypto.spec.SecretKeySpec and rejects all the others. +jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;\ + java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;!*
--- a/src/share/lib/security/java.security-macosx Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/lib/security/java.security-macosx Fri May 25 01:50:25 2018 +0100 @@ -630,7 +630,7 @@ # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 1024, \ - EC keySize < 224, DES40_CBC, RC4_40 + EC keySize < 224, DES40_CBC, RC4_40, 3DES_EDE_CBC # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -857,6 +857,7 @@ disallowReferenceUriSchemes file http https,\ minKeySize RSA 1024,\ minKeySize DSA 1024,\ + minKeySize EC 224,\ noDuplicateIds,\ noRetrievalMethodLoops @@ -870,6 +871,9 @@ # Patterns are separated by ";" (semicolon). # Whitespace is significant and is considered part of the pattern. # +# If the system property jdk.serialFilter is also specified, it supersedes +# the security property value defined here. +# # If a pattern includes a "=", it sets a limit. # If a limit appears more than once the last value is used. # Limits are checked before classes regardless of the order in the sequence of patterns. @@ -965,3 +969,20 @@ # It is not guaranteed to be examined and used by other implementations. # #com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name + +# +# JCEKS Encrypted Key Serial Filter +# +# This filter, if configured, is used by the JCEKS KeyStore during the +# deserialization of the encrypted Key object stored inside a key entry. +# If not configured or the filter result is UNDECIDED (i.e. none of the patterns +# matches), the filter configured by jdk.serialFilter will be consulted. +# +# If the system property jceks.key.serialFilter is also specified, it supersedes +# the security property value defined here. +# +# The filter pattern uses the same format as jdk.serialFilter. The default +# pattern allows java.lang.Enum, java.security.KeyRep, java.security.KeyRep$Type, +# and javax.crypto.spec.SecretKeySpec and rejects all the others. +jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;\ + java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;!*
--- a/src/share/lib/security/java.security-solaris Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/lib/security/java.security-solaris Fri May 25 01:50:25 2018 +0100 @@ -629,7 +629,7 @@ # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 1024, \ - EC keySize < 224, DES40_CBC, RC4_40 + EC keySize < 224, DES40_CBC, RC4_40, 3DES_EDE_CBC # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -856,6 +856,7 @@ disallowReferenceUriSchemes file http https,\ minKeySize RSA 1024,\ minKeySize DSA 1024,\ + minKeySize EC 224,\ noDuplicateIds,\ noRetrievalMethodLoops @@ -869,6 +870,9 @@ # Patterns are separated by ";" (semicolon). # Whitespace is significant and is considered part of the pattern. # +# If the system property jdk.serialFilter is also specified, it supersedes +# the security property value defined here. +# # If a pattern includes a "=", it sets a limit. # If a limit appears more than once the last value is used. # Limits are checked before classes regardless of the order in the sequence of patterns. @@ -964,3 +968,20 @@ # It is not guaranteed to be examined and used by other implementations. # #com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name + +# +# JCEKS Encrypted Key Serial Filter +# +# This filter, if configured, is used by the JCEKS KeyStore during the +# deserialization of the encrypted Key object stored inside a key entry. +# If not configured or the filter result is UNDECIDED (i.e. none of the patterns +# matches), the filter configured by jdk.serialFilter will be consulted. +# +# If the system property jceks.key.serialFilter is also specified, it supersedes +# the security property value defined here. +# +# The filter pattern uses the same format as jdk.serialFilter. The default +# pattern allows java.lang.Enum, java.security.KeyRep, java.security.KeyRep$Type, +# and javax.crypto.spec.SecretKeySpec and rejects all the others. +jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;\ + java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;!*
--- a/src/share/lib/security/java.security-windows Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/lib/security/java.security-windows Fri May 25 01:50:25 2018 +0100 @@ -630,7 +630,7 @@ # Example: # jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048 jdk.tls.disabledAlgorithms=SSLv3, RC4, MD5withRSA, DH keySize < 1024, \ - EC keySize < 224, DES40_CBC, RC4_40 + EC keySize < 224, DES40_CBC, RC4_40, 3DES_EDE_CBC # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) # processing in JSSE implementation. @@ -857,6 +857,7 @@ disallowReferenceUriSchemes file http https,\ minKeySize RSA 1024,\ minKeySize DSA 1024,\ + minKeySize EC 224,\ noDuplicateIds,\ noRetrievalMethodLoops @@ -870,6 +871,9 @@ # Patterns are separated by ";" (semicolon). # Whitespace is significant and is considered part of the pattern. # +# If the system property jdk.serialFilter is also specified, it supersedes +# the security property value defined here. +# # If a pattern includes a "=", it sets a limit. # If a limit appears more than once the last value is used. # Limits are checked before classes regardless of the order in the sequence of patterns. @@ -965,3 +969,20 @@ # It is not guaranteed to be examined and used by other implementations. # #com.sun.CORBA.ORBIorTypeCheckRegistryFilter=binary_class_name;binary_class_name + +# +# JCEKS Encrypted Key Serial Filter +# +# This filter, if configured, is used by the JCEKS KeyStore during the +# deserialization of the encrypted Key object stored inside a key entry. +# If not configured or the filter result is UNDECIDED (i.e. none of the patterns +# matches), the filter configured by jdk.serialFilter will be consulted. +# +# If the system property jceks.key.serialFilter is also specified, it supersedes +# the security property value defined here. +# +# The filter pattern uses the same format as jdk.serialFilter. The default +# pattern allows java.lang.Enum, java.security.KeyRep, java.security.KeyRep$Type, +# and javax.crypto.spec.SecretKeySpec and rejects all the others. +jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;\ + java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;!*
--- a/src/share/native/sun/java2d/cmm/lcms/LCMS.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/LCMS.c Fri May 25 01:50:25 2018 +0100 @@ -391,12 +391,12 @@ { lcmsProfile_p sProf = (lcmsProfile_p)jlong_to_ptr(id); TagSignature_t sig; - cmsInt32Number tagSize; + cmsUInt32Number tagSize; jbyte* dataArray = NULL; jbyteArray data = NULL; - jint bufSize; + cmsUInt32Number bufSize; sig.j = tagSig; @@ -839,7 +839,7 @@ for (i = 0; i < tagCount; i++) { cmsBool isTagReady = FALSE; const cmsTagSignature s = cmsGetTagSignature(pfTarget, i); - const cmsInt32Number tagSize = cmsReadRawTag(pfTarget, s, NULL, 0); + const cmsUInt32Number tagSize = cmsReadRawTag(pfTarget, s, NULL, 0); if (s == sig) { // skip the user supplied tag
--- a/src/share/native/sun/java2d/cmm/lcms/cmsalpha.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsalpha.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -55,7 +55,6 @@ #include "lcms2_internal.h" - // Alpha copy ------------------------------------------------------------------------------------------------------------------ // Floor to byte, taking care of saturation @@ -71,16 +70,16 @@ // Return the size in bytes of a given formatter static -int trueBytesSize(cmsUInt32Number Format) +cmsUInt32Number trueBytesSize(cmsUInt32Number Format) { - int fmt_bytes = T_BYTES(Format); + cmsUInt32Number fmt_bytes = T_BYTES(Format); - // For double, the T_BYTES field returns zero - if (fmt_bytes == 0) - return sizeof(double); + // For double, the T_BYTES field returns zero + if (fmt_bytes == 0) + return sizeof(double); - // Otherwise, it is already correct for all formats - return fmt_bytes; + // Otherwise, it is already correct for all formats + return fmt_bytes; } @@ -119,8 +118,13 @@ static void from8toHLF(void* dst, const void* src) { +#ifndef CMS_NO_HALF_SUPPORT cmsFloat32Number n = (*(cmsUInt8Number*)src) / 255.0f; *(cmsUInt16Number*)dst = _cmsFloat2Half(n); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif } // From 16 @@ -151,8 +155,13 @@ static void from16toHLF(void* dst, const void* src) { +#ifndef CMS_NO_HALF_SUPPORT cmsFloat32Number n = (*(cmsUInt16Number*)src) / 65535.0f; *(cmsUInt16Number*)dst = _cmsFloat2Half(n); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif } // From Float @@ -187,8 +196,13 @@ static void fromFLTtoHLF(void* dst, const void* src) { +#ifndef CMS_NO_HALF_SUPPORT cmsFloat32Number n = *(cmsFloat32Number*)src; *(cmsUInt16Number*)dst = _cmsFloat2Half(n); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif } @@ -197,27 +211,48 @@ static void fromHLFto8(void* dst, const void* src) { +#ifndef CMS_NO_HALF_SUPPORT cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src); *(cmsUInt8Number*)dst = _cmsQuickSaturateByte(n * 255.0f); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif + } static void fromHLFto16(void* dst, const void* src) { +#ifndef CMS_NO_HALF_SUPPORT cmsFloat32Number n = _cmsHalf2Float(*(cmsUInt16Number*)src); *(cmsUInt16Number*)dst = _cmsQuickSaturateWord(n * 65535.0f); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif } static void fromHLFtoFLT(void* dst, const void* src) { +#ifndef CMS_NO_HALF_SUPPORT *(cmsFloat32Number*)dst = _cmsHalf2Float(*(cmsUInt16Number*)src); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif } static void fromHLFtoDBL(void* dst, const void* src) { +#ifndef CMS_NO_HALF_SUPPORT *(cmsFloat64Number*)dst = (cmsFloat64Number)_cmsHalf2Float(*(cmsUInt16Number*)src); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif } // From double @@ -245,8 +280,13 @@ static void fromDBLtoHLF(void* dst, const void* src) { +#ifndef CMS_NO_HALF_SUPPORT cmsFloat32Number n = (cmsFloat32Number) *(cmsFloat64Number*)src; *(cmsUInt16Number*)dst = _cmsFloat2Half(n); +#else + cmsUNUSED_PARAMETER(dst); + cmsUNUSED_PARAMETER(src); +#endif } static @@ -260,21 +300,22 @@ static int FormatterPos(cmsUInt32Number frm) { - int b = T_BYTES(frm); + cmsUInt32Number b = T_BYTES(frm); - if (b == 0 && T_FLOAT(frm)) - return 4; // DBL - if (b == 2 && T_FLOAT(frm)) - return 2; // HLF - if (b == 4 && T_FLOAT(frm)) - return 3; // FLT - if (b == 2 && !T_FLOAT(frm)) - return 1; // 16 - if (b == 1 && !T_FLOAT(frm)) - return 0; // 8 + if (b == 0 && T_FLOAT(frm)) + return 4; // DBL +#ifndef CMS_NO_HALF_SUPPORT + if (b == 2 && T_FLOAT(frm)) + return 2; // HLF +#endif + if (b == 4 && T_FLOAT(frm)) + return 3; // FLT + if (b == 2 && !T_FLOAT(frm)) + return 1; // 16 + if (b == 1 && !T_FLOAT(frm)) + return 0; // 8 - return -1; // not recognized - + return -1; // not recognized } // Obtains a alpha-to-alpha funmction formatter @@ -310,12 +351,12 @@ cmsUInt32Number ComponentPointerIncrements[]) { cmsUInt32Number channels[cmsMAXCHANNELS]; - int extra = T_EXTRA(Format); - int nchannels = T_CHANNELS(Format); - int total_chans = nchannels + extra; - int i; - int channelSize = trueBytesSize(Format); - int pixelSize = channelSize * total_chans; + cmsUInt32Number extra = T_EXTRA(Format); + cmsUInt32Number nchannels = T_CHANNELS(Format); + cmsUInt32Number total_chans = nchannels + extra; + cmsUInt32Number i; + cmsUInt32Number channelSize = trueBytesSize(Format); + cmsUInt32Number pixelSize = channelSize * total_chans; // Sanity check if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS) @@ -368,11 +409,11 @@ cmsUInt32Number ComponentPointerIncrements[]) { cmsUInt32Number channels[cmsMAXCHANNELS]; - int extra = T_EXTRA(Format); - int nchannels = T_CHANNELS(Format); - int total_chans = nchannels + extra; - int i; - int channelSize = trueBytesSize(Format); + cmsUInt32Number extra = T_EXTRA(Format); + cmsUInt32Number nchannels = T_CHANNELS(Format); + cmsUInt32Number total_chans = nchannels + extra; + cmsUInt32Number i; + cmsUInt32Number channelSize = trueBytesSize(Format); // Sanity check if (total_chans <= 0 || total_chans >= cmsMAXCHANNELS)
--- a/src/share/native/sun/java2d/cmm/lcms/cmscam02.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmscam02.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"),
--- a/src/share/native/sun/java2d/cmm/lcms/cmscgats.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmscgats.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -176,23 +176,24 @@ SUBALLOCATOR Allocator; // String suballocator -- just to keep it fast // Parser state machine - SYMBOL sy; // Current symbol - int ch; // Current character - - int inum; // integer value - cmsFloat64Number dnum; // real value + SYMBOL sy; // Current symbol + int ch; // Current character + + cmsInt32Number inum; // integer value + cmsFloat64Number dnum; // real value + char id[MAXID]; // identifier char str[MAXSTR]; // string // Allowed keywords & datasets. They have visibility on whole stream - KEYVALUE* ValidKeywords; - KEYVALUE* ValidSampleID; + KEYVALUE* ValidKeywords; + KEYVALUE* ValidSampleID; char* Source; // Points to loc. being parsed - int lineno; // line counter for error reporting + cmsInt32Number lineno; // line counter for error reporting FILECTX* FileStack[MAXINCLUDE]; // Stack of files being parsed - int IncludeSP; // Include Stack Pointer + cmsInt32Number IncludeSP; // Include Stack Pointer char* MemoryBlock; // The stream if holded in memory @@ -265,65 +266,64 @@ {"PROD_DATE", WRITE_STRINGIFY}, // Identifies year and month of production of the target in the form yyyy:mm. {"SERIAL", WRITE_STRINGIFY}, // Uniquely identifies individual physical target. - {"MATERIAL", WRITE_STRINGIFY}, // Identifies the material on which the target was produced using a code - // uniquely identifying th e material. This is intend ed to be used for IT8.7 - // physical targets only (i.e . IT8.7/1 a nd IT8.7/2). - - {"INSTRUMENTATION", WRITE_STRINGIFY}, // Used to report the specific instrumentation used (manufacturer and - // model number) to generate the data reported. This data will often - // provide more information about the particular data collected than an - // extensive list of specific details. This is particularly important for - // spectral data or data derived from spectrophotometry. - - {"MEASUREMENT_SOURCE", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide - // a guide to the potential for issues of paper fluorescence, etc. - - {"PRINT_CONDITIONS", WRITE_STRINGIFY}, // Used to define the characteristics of the printed sheet being reported. - // Where standard conditions have been defined (e.g., SWOP at nominal) - // named conditions may suffice. Otherwise, detailed information is - // needed. - - {"SAMPLE_BACKING", WRITE_STRINGIFY}, // Identifies the backing material used behind the sample during - // measurement. Allowed values are “black”, “white”, or {"na". - - {"CHISQ_DOF", WRITE_STRINGIFY}, // Degrees of freedom associated with the Chi squared statistic - - // below properties are new in recent specs: + {"MATERIAL", WRITE_STRINGIFY}, // Identifies the material on which the target was produced using a code + // uniquely identifying th e material. This is intend ed to be used for IT8.7 + // physical targets only (i.e . IT8.7/1 a nd IT8.7/2). + + {"INSTRUMENTATION", WRITE_STRINGIFY}, // Used to report the specific instrumentation used (manufacturer and + // model number) to generate the data reported. This data will often + // provide more information about the particular data collected than an + // extensive list of specific details. This is particularly important for + // spectral data or data derived from spectrophotometry. + + {"MEASUREMENT_SOURCE", WRITE_STRINGIFY}, // Illumination used for spectral measurements. This data helps provide + // a guide to the potential for issues of paper fluorescence, etc. + + {"PRINT_CONDITIONS", WRITE_STRINGIFY}, // Used to define the characteristics of the printed sheet being reported. + // Where standard conditions have been defined (e.g., SWOP at nominal) + // named conditions may suffice. Otherwise, detailed information is + // needed. + + {"SAMPLE_BACKING", WRITE_STRINGIFY}, // Identifies the backing material used behind the sample during + // measurement. Allowed values are “black”, “white”, or {"na". + + {"CHISQ_DOF", WRITE_STRINGIFY}, // Degrees of freedom associated with the Chi squared statistic + // below properties are new in recent specs: {"MEASUREMENT_GEOMETRY", WRITE_STRINGIFY}, // The type of measurement, either reflection or transmission, should be indicated - // along with details of the geometry and the aperture size and shape. For example, - // for transmission measurements it is important to identify 0/diffuse, diffuse/0, - // opal or integrating sphere, etc. For reflection it is important to identify 0/45, - // 45/0, sphere (specular included or excluded), etc. - - {"FILTER", WRITE_STRINGIFY}, // Identifies the use of physical filter(s) during measurement. Typically used to - // denote the use of filters such as none, D65, Red, Green or Blue. - - {"POLARIZATION", WRITE_STRINGIFY}, // Identifies the use of a physical polarization filter during measurement. Allowed - // values are {"yes”, “white”, “none” or “na”. - - {"WEIGHTING_FUNCTION", WRITE_PAIR}, // Indicates such functions as: the CIE standard observer functions used in the - // calculation of various data parameters (2 degree and 10 degree), CIE standard - // illuminant functions used in the calculation of various data parameters (e.g., D50, - // D65, etc.), density status response, etc. If used there shall be at least one - // name-value pair following the WEIGHTING_FUNCTION tag/keyword. The first attribute - // in the set shall be {"name" and shall identify the particular parameter used. - // The second shall be {"value" and shall provide the value associated with that name. - // For ASCII data, a string containing the Name and Value attribute pairs shall follow - // the weighting function keyword. A semi-colon separates attribute pairs from each - // other and within the attribute the name and value are separated by a comma. - - {"COMPUTATIONAL_PARAMETER", WRITE_PAIR}, // Parameter that is used in computing a value from measured data. Name is the name - // of the calculation, parameter is the name of the parameter used in the calculation - // and value is the value of the parameter. - - {"TARGET_TYPE", WRITE_STRINGIFY}, // The type of target being measured, e.g. IT8.7/1, IT8.7/3, user defined, etc. - - {"COLORANT", WRITE_STRINGIFY}, // Identifies the colorant(s) used in creating the target. - - {"TABLE_DESCRIPTOR", WRITE_STRINGIFY}, // Describes the purpose or contents of a data table. - - {"TABLE_NAME", WRITE_STRINGIFY} // Provides a short name for a data table. + // along with details of the geometry and the aperture size and shape. For example, + // for transmission measurements it is important to identify 0/diffuse, diffuse/0, + // opal or integrating sphere, etc. For reflection it is important to identify 0/45, + // 45/0, sphere (specular included or excluded), etc. + + {"FILTER", WRITE_STRINGIFY}, // Identifies the use of physical filter(s) during measurement. Typically used to + // denote the use of filters such as none, D65, Red, Green or Blue. + + {"POLARIZATION", WRITE_STRINGIFY}, // Identifies the use of a physical polarization filter during measurement. Allowed + // values are {"yes”, “white”, “none” or “na”. + + {"WEIGHTING_FUNCTION", WRITE_PAIR}, // Indicates such functions as: the CIE standard observer functions used in the + // calculation of various data parameters (2 degree and 10 degree), CIE standard + // illuminant functions used in the calculation of various data parameters (e.g., D50, + // D65, etc.), density status response, etc. If used there shall be at least one + // name-value pair following the WEIGHTING_FUNCTION tag/keyword. The first attribute + // in the set shall be {"name" and shall identify the particular parameter used. + // The second shall be {"value" and shall provide the value associated with that name. + // For ASCII data, a string containing the Name and Value attribute pairs shall follow + // the weighting function keyword. A semi-colon separates attribute pairs from each + // other and within the attribute the name and value are separated by a comma. + + {"COMPUTATIONAL_PARAMETER", WRITE_PAIR}, // Parameter that is used in computing a value from measured data. Name is the name + // of the calculation, parameter is the name of the parameter used in the calculation + // and value is the value of the parameter. + + {"TARGET_TYPE", WRITE_STRINGIFY}, // The type of target being measured, e.g. IT8.7/1, IT8.7/3, user defined, etc. + + {"COLORANT", WRITE_STRINGIFY}, // Identifies the colorant(s) used in creating the target. + + {"TABLE_DESCRIPTOR", WRITE_STRINGIFY}, // Describes the purpose or contents of a data table. + + {"TABLE_NAME", WRITE_STRINGIFY} // Provides a short name for a data table. }; #define NUMPREDEFINEDPROPS (sizeof(PredefinedProperties)/sizeof(PROPERTY)) @@ -564,13 +564,13 @@ // Reads a Real number, tries to follow from integer number static -void ReadReal(cmsIT8* it8, int inum) +void ReadReal(cmsIT8* it8, cmsInt32Number inum) { - it8->dnum = (cmsFloat64Number) inum; + it8->dnum = (cmsFloat64Number)inum; while (isdigit(it8->ch)) { - it8->dnum = it8->dnum * 10.0 + (it8->ch - '0'); + it8->dnum = (cmsFloat64Number)it8->dnum * 10.0 + (cmsFloat64Number)(it8->ch - '0'); NextCh(it8); } @@ -583,7 +583,7 @@ while (isdigit(it8->ch)) { - frac = frac * 10.0 + (it8->ch - '0'); + frac = frac * 10.0 + (cmsFloat64Number)(it8->ch - '0'); prec++; NextCh(it8); } @@ -594,8 +594,8 @@ // Exponent, example 34.00E+20 if (toupper(it8->ch) == 'E') { - int e; - int sgn; + cmsInt32Number e; + cmsInt32Number sgn; NextCh(it8); sgn = 1; @@ -610,17 +610,19 @@ NextCh(it8); } - e = 0; - while (isdigit(it8->ch)) { - - if ((cmsFloat64Number) e * 10L < INT_MAX) - e = e * 10 + (it8->ch - '0'); - - NextCh(it8); - } - - e = sgn*e; - it8 -> dnum = it8 -> dnum * xpow10(e); + e = 0; + while (isdigit(it8->ch)) { + + cmsInt32Number digit = (it8->ch - '0'); + + if ((cmsFloat64Number)e * 10.0 + (cmsFloat64Number)digit < (cmsFloat64Number)+2147483647.0) + e = e * 10 + digit; + + NextCh(it8); + } + + e = sgn*e; + it8->dnum = it8->dnum * xpow10(e); } } @@ -638,12 +640,12 @@ if (*Buffer == '-' || *Buffer == '+') { - sign = (*Buffer == '-') ? -1 : 1; - Buffer++; + sign = (*Buffer == '-') ? -1 : 1; + Buffer++; } - while (*Buffer && isdigit((int) *Buffer)) { + while (*Buffer && isdigit((int)*Buffer)) { dnum = dnum * 10.0 + (*Buffer - '0'); if (*Buffer) Buffer++; @@ -652,11 +654,11 @@ if (*Buffer == '.') { cmsFloat64Number frac = 0.0; // fraction - int prec = 0; // precission + int prec = 0; // precision if (*Buffer) Buffer++; - while (*Buffer && isdigit((int) *Buffer)) { + while (*Buffer && isdigit((int)*Buffer)) { frac = frac * 10.0 + (*Buffer - '0'); prec++; @@ -687,17 +689,19 @@ if (*Buffer) Buffer++; } - e = 0; - while (*Buffer && isdigit((int) *Buffer)) { - - if ((cmsFloat64Number) e * 10L < INT_MAX) - e = e * 10 + (*Buffer - '0'); - - if (*Buffer) Buffer++; - } - - e = sgn*e; - dnum = dnum * xpow10(e); + e = 0; + while (*Buffer && isdigit((int)*Buffer)) { + + cmsInt32Number digit = (*Buffer - '0'); + + if ((cmsFloat64Number)e * 10.0 + digit < (cmsFloat64Number)+2147483647.0) + e = e * 10 + digit; + + if (*Buffer) Buffer++; + } + + e = sgn*e; + dnum = dnum * xpow10(e); } return sign * dnum; @@ -766,7 +770,7 @@ if (it8->ch >= 'A' && it8->ch <= 'F') j = it8->ch -'A'+10; else j = it8->ch - '0'; - if ((long) it8->inum * 16L > (long) INT_MAX) + if ((cmsFloat64Number) it8->inum * 16.0 + (cmsFloat64Number) j > (cmsFloat64Number)+2147483647.0) { SynError(it8, "Invalid hexadecimal number"); return; @@ -787,7 +791,7 @@ { j = it8->ch - '0'; - if ((long) it8->inum * 2L > (long) INT_MAX) + if ((cmsFloat64Number) it8->inum * 2.0 + j > (cmsFloat64Number)+2147483647.0) { SynError(it8, "Invalid binary number"); return; @@ -803,14 +807,16 @@ while (isdigit(it8->ch)) { - if ((long) it8->inum * 10L > (long) INT_MAX) { + cmsInt32Number digit = (it8->ch - '0'); + + if ((cmsFloat64Number) it8->inum * 10.0 + (cmsFloat64Number) digit > (cmsFloat64Number) +2147483647.0) { ReadReal(it8, it8->inum); it8->sy = SDNUM; it8->dnum *= sign; return; } - it8->inum = it8->inum * 10 + (it8->ch - '0'); + it8->inum = it8->inum * 10 + digit; NextCh(it8); } @@ -1515,8 +1521,8 @@ cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE h, int n, const char *Sample) { - cmsIT8* it8 = (cmsIT8*) h; - return SetDataFormat(it8, n, Sample); + cmsIT8* it8 = (cmsIT8*)h; + return SetDataFormat(it8, n, Sample); } static @@ -1541,8 +1547,8 @@ char* GetData(cmsIT8* it8, int nSet, int nField) { TABLE* t = GetTable(it8); - int nSamples = t -> nSamples; - int nPatches = t -> nPatches; + int nSamples = t -> nSamples; + int nPatches = t -> nPatches; if (nSet >= nPatches || nField >= nSamples) return NULL; @@ -1973,67 +1979,67 @@ case SIDENT: - strncpy(VarName, it8->id, MAXID-1); - VarName[MAXID-1] = 0; - - if (!IsAvailableOnList(it8-> ValidKeywords, VarName, NULL, &Key)) { + strncpy(VarName, it8->id, MAXID - 1); + VarName[MAXID - 1] = 0; + + if (!IsAvailableOnList(it8->ValidKeywords, VarName, NULL, &Key)) { #ifdef CMS_STRICT_CGATS - return SynError(it8, "Undefined keyword '%s'", VarName); + return SynError(it8, "Undefined keyword '%s'", VarName); #else - Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED); - if (Key == NULL) return FALSE; + Key = AddAvailableProperty(it8, VarName, WRITE_UNCOOKED); + if (Key == NULL) return FALSE; #endif - } - - InSymbol(it8); - if (!GetVal(it8, Buffer, MAXSTR-1, "Property data expected")) return FALSE; - - if(Key->WriteAs != WRITE_PAIR) { - AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer, - (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED); + } + + InSymbol(it8); + if (!GetVal(it8, Buffer, MAXSTR - 1, "Property data expected")) return FALSE; + + if (Key->WriteAs != WRITE_PAIR) { + AddToList(it8, &GetTable(it8)->HeaderList, VarName, NULL, Buffer, + (it8->sy == SSTRING) ? WRITE_STRINGIFY : WRITE_UNCOOKED); + } + else { + const char *Subkey; + char *Nextkey; + if (it8->sy != SSTRING) + return SynError(it8, "Invalid value '%s' for property '%s'.", Buffer, VarName); + + // chop the string as a list of "subkey, value" pairs, using ';' as a separator + for (Subkey = Buffer; Subkey != NULL; Subkey = Nextkey) + { + char *Value, *temp; + + // identify token pair boundary + Nextkey = (char*)strchr(Subkey, ';'); + if (Nextkey) + *Nextkey++ = '\0'; + + // for each pair, split the subkey and the value + Value = (char*)strrchr(Subkey, ','); + if (Value == NULL) + return SynError(it8, "Invalid value for property '%s'.", VarName); + + // gobble the spaces before the coma, and the coma itself + temp = Value++; + do *temp-- = '\0'; while (temp >= Subkey && *temp == ' '); + + // gobble any space at the right + temp = Value + strlen(Value) - 1; + while (*temp == ' ') *temp-- = '\0'; + + // trim the strings from the left + Subkey += strspn(Subkey, " "); + Value += strspn(Value, " "); + + if (Subkey[0] == 0 || Value[0] == 0) + return SynError(it8, "Invalid value for property '%s'.", VarName); + AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR); } - else { - const char *Subkey; - char *Nextkey; - if (it8->sy != SSTRING) - return SynError(it8, "Invalid value '%s' for property '%s'.", Buffer, VarName); - - // chop the string as a list of "subkey, value" pairs, using ';' as a separator - for (Subkey = Buffer; Subkey != NULL; Subkey = Nextkey) - { - char *Value, *temp; - - // identify token pair boundary - Nextkey = (char*) strchr(Subkey, ';'); - if(Nextkey) - *Nextkey++ = '\0'; - - // for each pair, split the subkey and the value - Value = (char*) strrchr(Subkey, ','); - if(Value == NULL) - return SynError(it8, "Invalid value for property '%s'.", VarName); - - // gobble the spaces before the coma, and the coma itself - temp = Value++; - do *temp-- = '\0'; while(temp >= Subkey && *temp == ' '); - - // gobble any space at the right - temp = Value + strlen(Value) - 1; - while(*temp == ' ') *temp-- = '\0'; - - // trim the strings from the left - Subkey += strspn(Subkey, " "); - Value += strspn(Value, " "); - - if(Subkey[0] == 0 || Value[0] == 0) - return SynError(it8, "Invalid value for property '%s'.", VarName); - AddToList(it8, &GetTable(it8)->HeaderList, VarName, Subkey, Value, WRITE_PAIR); - } - } - - InSymbol(it8); - break; + } + + InSymbol(it8); + break; case SEOLN: break; @@ -2062,7 +2068,6 @@ while (it8->ch != '\r' && it8 ->ch != '\n' && it8->ch != '\t' && it8 -> ch != 0) { - *SheetTypePtr++= (char) it8 ->ch; if (cnt++ < MAXSTR) *SheetTypePtr++= (char) it8 ->ch; NextCh(it8); @@ -2257,10 +2262,10 @@ // that should be something like some printable characters plus a \n // returns 0 if this is not like a CGATS, or an integer otherwise. This integer is the number of words in first line? static -int IsMyBlock(const cmsUInt8Number* Buffer, int n) +int IsMyBlock(const cmsUInt8Number* Buffer, cmsUInt32Number n) { int words = 1, space = 0, quot = 0; - int i; + cmsUInt32Number i; if (n < 10) return 0; // Too small @@ -2748,7 +2753,7 @@ { const char* cLabelFld; char Type[256], Label[256]; - int nTable; + cmsUInt32Number nTable; _cmsAssert(hIT8 != NULL); @@ -2761,7 +2766,7 @@ cLabelFld = cmsIT8GetData(hIT8, cSet, cField); if (!cLabelFld) return -1; - if (sscanf(cLabelFld, "%255s %d %255s", Label, &nTable, Type) != 3) + if (sscanf(cLabelFld, "%255s %u %255s", Label, &nTable, Type) != 3) return -1; if (ExpectedType != NULL && *ExpectedType == 0)
--- a/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmscnvrt.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -392,11 +392,12 @@ // Compute the conversion layer static -cmsBool ComputeConversion(int i, cmsHPROFILE hProfiles[], - cmsUInt32Number Intent, - cmsBool BPC, - cmsFloat64Number AdaptationState, - cmsMAT3* m, cmsVEC3* off) +cmsBool ComputeConversion(cmsUInt32Number i, + cmsHPROFILE hProfiles[], + cmsUInt32Number Intent, + cmsBool BPC, + cmsFloat64Number AdaptationState, + cmsMAT3* m, cmsVEC3* off) { int k; @@ -708,7 +709,7 @@ // Translate black-preserving intents to ICC ones static -int TranslateNonICCIntents(int Intent) +cmsUInt32Number TranslateNonICCIntents(cmsUInt32Number Intent) { switch (Intent) { case INTENT_PRESERVE_K_ONLY_PERCEPTUAL:
--- a/src/share/native/sun/java2d/cmm/lcms/cmserr.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmserr.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -83,9 +83,11 @@ long int p , n; p = ftell(f); // register current file position + if (p == -1L) + return -1L; if (fseek(f, 0, SEEK_END) != 0) { - return -1; + return -1L; } n = ftell(f); @@ -115,7 +117,7 @@ // ********************************************************************************* // This is the default memory allocation function. It does a very coarse -// check of amout of memory, just to prevent exploits +// check of amount of memory, just to prevent exploits static void* _cmsMallocDefaultFn(cmsContext ContextID, cmsUInt32Number size) { @@ -222,7 +224,7 @@ } else { - // To reset it, we use the default allocators, which cannot be overriden + // To reset it, we use the default allocators, which cannot be overridden ctx ->chunks[MemPlugin] = &ctx ->DefaultMemoryManager; } }
--- a/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c Fri May 25 01:50:25 2018 +0100 @@ -73,10 +73,11 @@ // The list of supported parametric curves typedef struct _cmsParametricCurvesCollection_st { - int nFunctions; // Number of supported functions in this chunk - int FunctionTypes[MAX_TYPES_IN_LCMS_PLUGIN]; // The identification types - int ParameterCount[MAX_TYPES_IN_LCMS_PLUGIN]; // Number of parameters for each function - cmsParametricCurveEvaluator Evaluator; // The evaluator + cmsUInt32Number nFunctions; // Number of supported functions in this chunk + cmsInt32Number FunctionTypes[MAX_TYPES_IN_LCMS_PLUGIN]; // The identification types + cmsUInt32Number ParameterCount[MAX_TYPES_IN_LCMS_PLUGIN]; // Number of parameters for each function + + cmsParametricCurveEvaluator Evaluator; // The evaluator struct _cmsParametricCurvesCollection_st* Next; // Next in list @@ -194,7 +195,7 @@ { int i; - for (i=0; i < c ->nFunctions; i++) + for (i=0; i < (int) c ->nFunctions; i++) if (abs(Type) == c ->FunctionTypes[i]) return i; return -1; @@ -238,20 +239,20 @@ // no optimation curve is computed. nSegments may also be zero in the inverse case, where only the // optimization curve is given. Both features simultaneously is an error static -cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsInt32Number nEntries, - cmsInt32Number nSegments, const cmsCurveSegment* Segments, +cmsToneCurve* AllocateToneCurveStruct(cmsContext ContextID, cmsUInt32Number nEntries, + cmsUInt32Number nSegments, const cmsCurveSegment* Segments, const cmsUInt16Number* Values) { cmsToneCurve* p; - int i; + cmsUInt32Number i; // We allow huge tables, which are then restricted for smoothing operations - if (nEntries > 65530 || nEntries < 0) { + if (nEntries > 65530) { cmsSignalError(ContextID, cmsERROR_RANGE, "Couldn't create tone curve of more than 65530 entries"); return NULL; } - if (nEntries <= 0 && nSegments <= 0) { + if (nEntries == 0 && nSegments == 0) { cmsSignalError(ContextID, cmsERROR_RANGE, "Couldn't create tone curve with zero segments and no table"); return NULL; } @@ -261,7 +262,7 @@ if (!p) return NULL; // In this case, there are no segments - if (nSegments <= 0) { + if (nSegments == 0) { p ->Segments = NULL; p ->Evals = NULL; } @@ -277,7 +278,7 @@ // This 16-bit table contains a limited precision representation of the whole curve and is kept for // increasing xput on certain operations. - if (nEntries <= 0) { + if (nEntries == 0) { p ->Table16 = NULL; } else { @@ -303,7 +304,7 @@ p ->SegInterp = (cmsInterpParams**) _cmsCalloc(ContextID, nSegments, sizeof(cmsInterpParams*)); if (p ->SegInterp == NULL) goto Error; - for (i=0; i< nSegments; i++) { + for (i=0; i < nSegments; i++) { // Type 0 is a special marker for table-based curves if (Segments[i].Type == 0) @@ -359,7 +360,7 @@ // Type 1 Reversed: X = Y ^1/gamma case -1: - if (R < 0) { + if (R < 0) { if (fabs(Params[0] - 1.0) < MATRIX_DET_TOLERANCE) Val = R; @@ -367,80 +368,123 @@ Val = 0; } else - Val = pow(R, 1/Params[0]); + { + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE) + Val = PLUS_INF; + else + Val = pow(R, 1 / Params[0]); + } break; // CIE 122-1966 // Y = (aX + b)^Gamma | X >= -b/a // Y = 0 | else case 2: - disc = -Params[2] / Params[1]; + { - if (R >= disc ) { + if (fabs(Params[1]) < MATRIX_DET_TOLERANCE) + { + Val = 0; + } + else + { + disc = -Params[2] / Params[1]; - e = Params[1]*R + Params[2]; + if (R >= disc) { + + e = Params[1] * R + Params[2]; - if (e > 0) - Val = pow(e, Params[0]); + if (e > 0) + Val = pow(e, Params[0]); + else + Val = 0; + } else Val = 0; } - else - Val = 0; - break; + } + break; // Type 2 Reversed // X = (Y ^1/g - b) / a case -2: - if (R < 0) + { + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE || + fabs(Params[1]) < MATRIX_DET_TOLERANCE) + { Val = 0; + } else - Val = (pow(R, 1.0/Params[0]) - Params[2]) / Params[1]; + { + if (R < 0) + Val = 0; + else + Val = (pow(R, 1.0 / Params[0]) - Params[2]) / Params[1]; - if (Val < 0) - Val = 0; - break; + if (Val < 0) + Val = 0; + } + } + break; // IEC 61966-3 // Y = (aX + b)^Gamma | X <= -b/a // Y = c | else case 3: - disc = -Params[2] / Params[1]; - if (disc < 0) - disc = 0; - - if (R >= disc) { - - e = Params[1]*R + Params[2]; - - if (e > 0) - Val = pow(e, Params[0]) + Params[3]; - else - Val = 0; + { + if (fabs(Params[1]) < MATRIX_DET_TOLERANCE) + { + Val = 0; } else - Val = Params[3]; - break; + { + disc = -Params[2] / Params[1]; + if (disc < 0) + disc = 0; + + if (R >= disc) { + + e = Params[1] * R + Params[2]; + + if (e > 0) + Val = pow(e, Params[0]) + Params[3]; + else + Val = 0; + } + else + Val = Params[3]; + } + } + break; // Type 3 reversed // X=((Y-c)^1/g - b)/a | (Y>=c) // X=-b/a | (Y<c) case -3: - if (R >= Params[3]) { + { + if (fabs(Params[1]) < MATRIX_DET_TOLERANCE) + { + Val = 0; + } + else + { + if (R >= Params[3]) { - e = R - Params[3]; + e = R - Params[3]; - if (e > 0) - Val = (pow(e, 1/Params[0]) - Params[2]) / Params[1]; - else - Val = 0; + if (e > 0) + Val = (pow(e, 1 / Params[0]) - Params[2]) / Params[1]; + else + Val = 0; + } + else { + Val = -Params[2] / Params[1]; + } } - else { - Val = -Params[2] / Params[1]; - } - break; + } + break; // IEC 61966-2.1 (sRGB) @@ -464,20 +508,31 @@ // X=((Y^1/g-b)/a) | Y >= (ad+b)^g // X=Y/c | Y< (ad+b)^g case -4: - e = Params[1] * Params[4] + Params[2]; - if (e < 0) - disc = 0; + { + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE || + fabs(Params[1]) < MATRIX_DET_TOLERANCE || + fabs(Params[3]) < MATRIX_DET_TOLERANCE) + { + Val = 0; + } else - disc = pow(e, Params[0]); + { + e = Params[1] * Params[4] + Params[2]; + if (e < 0) + disc = 0; + else + disc = pow(e, Params[0]); - if (R >= disc) { + if (R >= disc) { - Val = (pow(R, 1.0/Params[0]) - Params[2]) / Params[1]; + Val = (pow(R, 1.0 / Params[0]) - Params[2]) / Params[1]; + } + else { + Val = R / Params[3]; + } } - else { - Val = R / Params[3]; - } - break; + } + break; // Y = (aX + b)^Gamma + e | X >= d @@ -501,20 +556,29 @@ // X=((Y-e)1/g-b)/a | Y >=(ad+b)^g+e), cd+f // X=(Y-f)/c | else case -5: - - disc = Params[3] * Params[4] + Params[6]; - if (R >= disc) { + { + if (fabs(Params[1]) < MATRIX_DET_TOLERANCE || + fabs(Params[3]) < MATRIX_DET_TOLERANCE) + { + Val = 0; + } + else + { + disc = Params[3] * Params[4] + Params[6]; + if (R >= disc) { - e = R - Params[5]; - if (e < 0) - Val = 0; - else - Val = (pow(e, 1.0/Params[0]) - Params[2]) / Params[1]; + e = R - Params[5]; + if (e < 0) + Val = 0; + else + Val = (pow(e, 1.0 / Params[0]) - Params[2]) / Params[1]; + } + else { + Val = (R - Params[6]) / Params[3]; + } } - else { - Val = (R - Params[6]) / Params[3]; - } - break; + } + break; // Types 6,7,8 comes from segmented curves as described in ICCSpecRevision_02_11_06_Float.pdf @@ -532,12 +596,21 @@ // ((Y - c) ^1/Gamma - b) / a case -6: - e = R - Params[3]; - if (e < 0) + { + if (fabs(Params[1]) < MATRIX_DET_TOLERANCE) + { Val = 0; + } else - Val = (pow(e, 1.0/Params[0]) - Params[2]) / Params[1]; - break; + { + e = R - Params[3]; + if (e < 0) + Val = 0; + else + Val = (pow(e, 1.0 / Params[0]) - Params[2]) / Params[1]; + } + } + break; // Y = a * log (b * X^Gamma + c) + d @@ -554,8 +627,19 @@ // pow(10, (Y-d) / a) = b * X ^Gamma + c // pow((pow(10, (Y-d) / a) - c) / b, 1/g) = X case -7: - Val = pow((pow(10.0, (R-Params[4]) / Params[1]) - Params[3]) / Params[2], 1.0 / Params[0]); - break; + { + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE || + fabs(Params[1]) < MATRIX_DET_TOLERANCE || + fabs(Params[2]) < MATRIX_DET_TOLERANCE) + { + Val = 0; + } + else + { + Val = pow((pow(10.0, (R - Params[4]) / Params[1]) - Params[3]) / Params[2], 1.0 / Params[0]); + } + } + break; //Y = a * b^(c*X+d) + e @@ -571,12 +655,25 @@ disc = R - Params[4]; if (disc < 0) Val = 0; else - Val = (log(disc / Params[0]) / log(Params[1]) - Params[3]) / Params[2]; + { + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE || + fabs(Params[2]) < MATRIX_DET_TOLERANCE) + { + Val = 0; + } + else + { + Val = (log(disc / Params[0]) / log(Params[1]) - Params[3]) / Params[2]; + } + } break; // S-Shaped: (1 - (1-x)^1/g)^1/g case 108: - Val = pow(1.0 - pow(1 - R, 1/Params[0]), 1/Params[0]); + if (fabs(Params[0]) < MATRIX_DET_TOLERANCE) + Val = 0; + else + Val = pow(1.0 - pow(1 - R, 1/Params[0]), 1/Params[0]); break; // y = (1 - (1-x)^1/g)^1/g @@ -596,33 +693,45 @@ return Val; } -// Evaluate a segmented function for a single value. Return -1 if no valid segment found . +// Evaluate a segmented function for a single value. Return -Inf if no valid segment found . // If fn type is 0, perform an interpolation on the table static cmsFloat64Number EvalSegmentedFn(const cmsToneCurve *g, cmsFloat64Number R) { int i; + cmsFloat32Number Out32; + cmsFloat64Number Out; - for (i = g ->nSegments-1; i >= 0 ; --i) { + for (i = (int) g->nSegments - 1; i >= 0; --i) { // Check for domain - if ((R > g ->Segments[i].x0) && (R <= g ->Segments[i].x1)) { + if ((R > g->Segments[i].x0) && (R <= g->Segments[i].x1)) { // Type == 0 means segment is sampled - if (g ->Segments[i].Type == 0) { + if (g->Segments[i].Type == 0) { - cmsFloat32Number R1 = (cmsFloat32Number) (R - g ->Segments[i].x0) / (g ->Segments[i].x1 - g ->Segments[i].x0); - cmsFloat32Number Out; + cmsFloat32Number R1 = (cmsFloat32Number)(R - g->Segments[i].x0) / (g->Segments[i].x1 - g->Segments[i].x0); // Setup the table (TODO: clean that) - g ->SegInterp[i]-> Table = g ->Segments[i].SampledPoints; + g->SegInterp[i]->Table = g->Segments[i].SampledPoints; + + g->SegInterp[i]->Interpolation.LerpFloat(&R1, &Out32, g->SegInterp[i]); + Out = (cmsFloat64Number) Out32; - g ->SegInterp[i] -> Interpolation.LerpFloat(&R1, &Out, g ->SegInterp[i]); + } + else { + Out = g->Evals[i](g->Segments[i].Type, g->Segments[i].Params, R); + } - return Out; + if (isinf(Out)) + return PLUS_INF; + else + { + if (isinf(-Out)) + return MINUS_INF; } - else - return g ->Evals[i](g->Segments[i].Type, g ->Segments[i].Params, R); + + return Out; } } @@ -645,13 +754,13 @@ // Create an empty gamma curve, by using tables. This specifies only the limited-precision part, and leaves the // floating point description empty. -cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurve16(cmsContext ContextID, cmsInt32Number nEntries, const cmsUInt16Number Values[]) +cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurve16(cmsContext ContextID, cmsUInt32Number nEntries, const cmsUInt16Number Values[]) { return AllocateToneCurveStruct(ContextID, nEntries, 0, NULL, Values); } static -int EntriesByGamma(cmsFloat64Number Gamma) +cmsUInt32Number EntriesByGamma(cmsFloat64Number Gamma) { if (fabs(Gamma - 1.0) < 0.001) return 2; return 4096; @@ -660,12 +769,12 @@ // Create a segmented gamma, fill the table cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID, - cmsInt32Number nSegments, const cmsCurveSegment Segments[]) + cmsUInt32Number nSegments, const cmsCurveSegment Segments[]) { - int i; + cmsUInt32Number i; cmsFloat64Number R, Val; cmsToneCurve* g; - int nGridPoints = 4096; + cmsUInt32Number nGridPoints = 4096; _cmsAssert(Segments != NULL); @@ -680,7 +789,7 @@ // Once we have the floating point version, we can approximate a 16 bit table of 4096 entries // for performance reasons. This table would normally not be used except on 8/16 bits transforms. - for (i=0; i < nGridPoints; i++) { + for (i = 0; i < nGridPoints; i++) { R = (cmsFloat64Number) i / (nGridPoints-1); @@ -893,7 +1002,7 @@ if (LutTable[0] < LutTable[p ->Domain[0]]) { // Table is overall ascending - for (i=p->Domain[0]-1; i >=0; --i) { + for (i = (int) p->Domain[0] - 1; i >= 0; --i) { y0 = LutTable[i]; y1 = LutTable[i+1]; @@ -928,7 +1037,7 @@ } // Reverse a gamma table -cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, const cmsToneCurve* InCurve) +cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsUInt32Number nResultSamples, const cmsToneCurve* InCurve) { cmsToneCurve *out; cmsFloat64Number a = 0, b = 0, y, x1, y1, x2, y2; @@ -957,7 +1066,7 @@ Ascending = !cmsIsToneCurveDescending(InCurve); // Iterate across Y axis - for (i=0; i < nResultSamples; i++) { + for (i=0; i < (int) nResultSamples; i++) { y = (cmsFloat64Number) i * 65535.0 / (nResultSamples - 1); @@ -1012,7 +1121,8 @@ // Output: smoothed vector (z): vector from 1 to m. static -cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[], cmsFloat32Number z[], cmsFloat32Number lambda, int m) +cmsBool smooth2(cmsContext ContextID, cmsFloat32Number w[], cmsFloat32Number y[], + cmsFloat32Number z[], cmsFloat32Number lambda, int m) { int i, i1, i2; cmsFloat32Number *c, *d, *e; @@ -1071,73 +1181,121 @@ // Smooths a curve sampled at regular intervals. cmsBool CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda) { - cmsFloat32Number w[MAX_NODES_IN_CURVE], y[MAX_NODES_IN_CURVE], z[MAX_NODES_IN_CURVE]; - int i, nItems, Zeros, Poles; + cmsBool SuccessStatus = TRUE; + cmsFloat32Number *w, *y, *z; + cmsUInt32Number i, nItems, Zeros, Poles; + + if (Tab != NULL && Tab->InterpParams != NULL) + { + cmsContext ContextID = Tab->InterpParams->ContextID; + + if (!cmsIsToneCurveLinear(Tab)) // Only non-linear curves need smoothing + { + nItems = Tab->nEntries; + if (nItems < MAX_NODES_IN_CURVE) + { + // Allocate one more item than needed + w = (cmsFloat32Number *)_cmsCalloc(ContextID, nItems + 1, sizeof(cmsFloat32Number)); + y = (cmsFloat32Number *)_cmsCalloc(ContextID, nItems + 1, sizeof(cmsFloat32Number)); + z = (cmsFloat32Number *)_cmsCalloc(ContextID, nItems + 1, sizeof(cmsFloat32Number)); - if (Tab == NULL) return FALSE; + if (w != NULL && y != NULL && z != NULL) // Ensure no memory allocation failure + { + memset(w, 0, (nItems + 1) * sizeof(cmsFloat32Number)); + memset(y, 0, (nItems + 1) * sizeof(cmsFloat32Number)); + memset(z, 0, (nItems + 1) * sizeof(cmsFloat32Number)); + + for (i = 0; i < nItems; i++) + { + y[i + 1] = (cmsFloat32Number)Tab->Table16[i]; + w[i + 1] = 1.0; + } - if (cmsIsToneCurveLinear(Tab)) return TRUE; // Nothing to do + if (smooth2(ContextID, w, y, z, (cmsFloat32Number)lambda, (int)nItems)) + { + // Do some reality - checking... - nItems = Tab -> nEntries; + Zeros = Poles = 0; + for (i = nItems; i > 1; --i) + { + if (z[i] == 0.) Zeros++; + if (z[i] >= 65535.) Poles++; + if (z[i] < z[i - 1]) + { + cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic."); + SuccessStatus = FALSE; + break; + } + } - if (nItems >= MAX_NODES_IN_CURVE) { - cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: too many points."); - return FALSE; - } + if (SuccessStatus && Zeros > (nItems / 3)) + { + cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly zeros."); + SuccessStatus = FALSE; + } + + if (SuccessStatus && Poles > (nItems / 3)) + { + cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly poles."); + SuccessStatus = FALSE; + } - memset(w, 0, nItems * sizeof(cmsFloat32Number)); - memset(y, 0, nItems * sizeof(cmsFloat32Number)); - memset(z, 0, nItems * sizeof(cmsFloat32Number)); + if (SuccessStatus) // Seems ok + { + for (i = 0; i < nItems; i++) + { + // Clamp to cmsUInt16Number + Tab->Table16[i] = _cmsQuickSaturateWord(z[i + 1]); + } + } + } + else // Could not smooth + { + cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Function smooth2 failed."); + SuccessStatus = FALSE; + } + } + else // One or more buffers could not be allocated + { + cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Could not allocate memory."); + SuccessStatus = FALSE; + } - for (i=0; i < nItems; i++) + if (z != NULL) + _cmsFree(ContextID, z); + + if (y != NULL) + _cmsFree(ContextID, y); + + if (w != NULL) + _cmsFree(ContextID, w); + } + else // too many items in the table + { + cmsSignalError(ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Too many points."); + SuccessStatus = FALSE; + } + } + } + else // Tab parameter or Tab->InterpParams is NULL { - y[i+1] = (cmsFloat32Number) Tab -> Table16[i]; - w[i+1] = 1.0; + // Can't signal an error here since the ContextID is not known at this point + SuccessStatus = FALSE; } - if (!smooth2(Tab ->InterpParams->ContextID, w, y, z, (cmsFloat32Number) lambda, nItems)) return FALSE; - - // Do some reality - checking... - Zeros = Poles = 0; - for (i=nItems; i > 1; --i) { - - if (z[i] == 0.) Zeros++; - if (z[i] >= 65535.) Poles++; - if (z[i] < z[i-1]) { - cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Non-Monotonic."); - return FALSE; - } - } - - if (Zeros > (nItems / 3)) { - cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly zeros."); - return FALSE; - } - if (Poles > (nItems / 3)) { - cmsSignalError(Tab ->InterpParams->ContextID, cmsERROR_RANGE, "cmsSmoothToneCurve: Degenerated, mostly poles."); - return FALSE; - } - - // Seems ok - for (i=0; i < nItems; i++) { - - // Clamp to cmsUInt16Number - Tab -> Table16[i] = _cmsQuickSaturateWord(z[i+1]); - } - - return TRUE; + return SuccessStatus; } // Is a table linear? Do not use parametric since we cannot guarantee some weird parameters resulting // in a linear table. This way assures it is linear in 12 bits, which should be enought in most cases. cmsBool CMSEXPORT cmsIsToneCurveLinear(const cmsToneCurve* Curve) { - cmsUInt32Number i; + int i; int diff; _cmsAssert(Curve != NULL); - for (i=0; i < Curve ->nEntries; i++) { + for (i=0; i < (int) Curve ->nEntries; i++) { diff = abs((int) Curve->Table16[i] - (int) _cmsQuantizeVal(i, Curve ->nEntries)); if (diff > 0x0f) @@ -1150,7 +1308,7 @@ // Same, but for monotonicity cmsBool CMSEXPORT cmsIsToneCurveMonotonic(const cmsToneCurve* t) { - int n; + cmsUInt32Number n; int i, last; cmsBool lDescending; @@ -1167,7 +1325,7 @@ last = t ->Table16[0]; - for (i = 1; i < n; i++) { + for (i = 1; i < (int) n; i++) { if (t ->Table16[i] - last > 2) // We allow some ripple return FALSE; @@ -1180,7 +1338,7 @@ last = t ->Table16[n-1]; - for (i = n-2; i >= 0; --i) { + for (i = (int) n - 2; i >= 0; --i) { if (t ->Table16[i] - last > 2) return FALSE;
--- a/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsgmt.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -326,7 +326,7 @@ cmsStage* CLUT; cmsUInt32Number dwFormat; GAMUTCHAIN Chain; - int nChannels, nGridpoints; + cmsUInt32Number nChannels, nGridpoints; cmsColorSpaceSignature ColorSpace; cmsUInt32Number i; cmsHPROFILE ProfileList[256];
--- a/src/share/native/sun/java2d/cmm/lcms/cmshalf.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmshalf.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -532,7 +532,7 @@ 0x18, 0x18, 0x18, 0x18, 0x0d }; -cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h) +cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h) { union { cmsFloat32Number flt; @@ -545,7 +545,7 @@ return out.flt; } -cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt) +cmsUInt16Number CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt) { union { cmsFloat32Number flt;
--- a/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsintrp.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -58,6 +58,13 @@ // This module incorporates several interpolation routines, for 1 to 8 channels on input and // up to 65535 channels on output. The user may change those by using the interpolation plug-in +// Some people may want to compile as C++ with all warnings on, in this case make compiler silent +#ifdef _MSC_VER +# if (_MSC_VER >= 1400) +# pragma warning( disable : 4365 ) +# endif +#endif + // Interpolation routines by default static cmsInterpFunction DefaultInterpolatorsFactory(cmsUInt32Number nInputChannels, cmsUInt32Number nOutputChannels, cmsUInt32Number dwFlags); @@ -131,12 +138,12 @@ // This function precalculates as many parameters as possible to speed up the interpolation. cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], - int InputChan, int OutputChan, + cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void *Table, cmsUInt32Number dwFlags) { cmsInterpParams* p; - int i; + cmsUInt32Number i; // Check for maximum inputs if (InputChan > MAX_INPUT_DIMENSIONS) { @@ -180,7 +187,8 @@ // This one is a wrapper on the anterior, but assuming all directions have same number of nodes -cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags) +cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, + cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags) { int i; cmsUInt32Number Samples[MAX_INPUT_DIMENSIONS]; @@ -195,7 +203,7 @@ // Free all associated memory -void _cmsFreeInterpParams(cmsInterpParams* p) +void CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p) { if (p != NULL) _cmsFree(p ->ContextID, p); } @@ -244,7 +252,7 @@ // To prevent out of bounds indexing cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v) { - return v < 0.0f || v != v ? 0.0f : (v > 1.0f ? 1.0f : v); + return ((v < 1.0e-9f) || isnan(v)) ? 0.0f : (v > 1.0f ? 1.0f : v); } // Floating-point version of 1D interpolation @@ -381,10 +389,10 @@ y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0; X0 = p -> opta[1] * x0; - X1 = X0 + (Input[0] >= 1.0 ? 0 : p->opta[1]); + X1 = X0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[1]); Y0 = p -> opta[0] * y0; - Y1 = Y0 + (Input[1] >= 1.0 ? 0 : p->opta[0]); + Y1 = Y0 + (fclamp(Input[1]) >= 1.0 ? 0 : p->opta[0]); for (OutChan = 0; OutChan < TotalOut; OutChan++) { @@ -493,18 +501,18 @@ py = fclamp(Input[1]) * p->Domain[1]; pz = fclamp(Input[2]) * p->Domain[2]; - x0 = (int) _cmsQuickFloor(px); fx = px - (cmsFloat32Number) x0; - y0 = (int) _cmsQuickFloor(py); fy = py - (cmsFloat32Number) y0; - z0 = (int) _cmsQuickFloor(pz); fz = pz - (cmsFloat32Number) z0; + x0 = (int) floor(px); fx = px - (cmsFloat32Number) x0; // We need full floor funcionality here + y0 = (int) floor(py); fy = py - (cmsFloat32Number) y0; + z0 = (int) floor(pz); fz = pz - (cmsFloat32Number) z0; X0 = p -> opta[2] * x0; - X1 = X0 + (Input[0] >= 1.0 ? 0 : p->opta[2]); + X1 = X0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[2]); Y0 = p -> opta[1] * y0; - Y1 = Y0 + (Input[1] >= 1.0 ? 0 : p->opta[1]); + Y1 = Y0 + (fclamp(Input[1]) >= 1.0 ? 0 : p->opta[1]); Z0 = p -> opta[0] * z0; - Z1 = Z0 + (Input[2] >= 1.0 ? 0 : p->opta[0]); + Z1 = Z0 + (fclamp(Input[2]) >= 1.0 ? 0 : p->opta[0]); for (OutChan = 0; OutChan < TotalOut; OutChan++) { @@ -637,19 +645,19 @@ py = fclamp(Input[1]) * p->Domain[1]; pz = fclamp(Input[2]) * p->Domain[2]; - x0 = (int) _cmsQuickFloor(px); rx = (px - (cmsFloat32Number) x0); - y0 = (int) _cmsQuickFloor(py); ry = (py - (cmsFloat32Number) y0); - z0 = (int) _cmsQuickFloor(pz); rz = (pz - (cmsFloat32Number) z0); + x0 = (int) floor(px); rx = (px - (cmsFloat32Number) x0); // We need full floor functionality here + y0 = (int) floor(py); ry = (py - (cmsFloat32Number) y0); + z0 = (int) floor(pz); rz = (pz - (cmsFloat32Number) z0); X0 = p -> opta[2] * x0; - X1 = X0 + (Input[0] >= 1.0 ? 0 : p->opta[2]); + X1 = X0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[2]); Y0 = p -> opta[1] * y0; - Y1 = Y0 + (Input[1] >= 1.0 ? 0 : p->opta[1]); + Y1 = Y0 + (fclamp(Input[1]) >= 1.0 ? 0 : p->opta[1]); Z0 = p -> opta[0] * z0; - Z1 = Z0 + (Input[2] >= 1.0 ? 0 : p->opta[0]); + Z1 = Z0 + (fclamp(Input[2]) >= 1.0 ? 0 : p->opta[0]); for (OutChan=0; OutChan < TotalOut; OutChan++) { @@ -952,13 +960,13 @@ c3 = DENS(X0, Y0, Z1) - c0; } - else { + else { c1 = c2 = c3 = 0; } Rest = c1 * rx + c2 * ry + c3 * rz; - Tmp1[OutChan] = (cmsUInt16Number) ( c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest))); + Tmp1[OutChan] = (cmsUInt16Number)(c0 + ROUND_FIXED_TO_INT(_cmsToFixedDomain(Rest))); } @@ -1057,7 +1065,7 @@ rest = pk - (cmsFloat32Number) k0; K0 = p -> opta[3] * k0; - K1 = K0 + (Input[0] >= 1.0 ? 0 : p->opta[3]); + K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[3]); p1 = *p; memmove(&p1.Domain[0], &p ->Domain[1], 3*sizeof(cmsUInt32Number)); @@ -1144,7 +1152,7 @@ rest = pk - (cmsFloat32Number) k0; K0 = p -> opta[4] * k0; - K1 = K0 + (Input[0] >= 1.0 ? 0 : p->opta[4]); + K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[4]); p1 = *p; memmove(&p1.Domain[0], &p ->Domain[1], 4*sizeof(cmsUInt32Number)); @@ -1231,7 +1239,7 @@ rest = pk - (cmsFloat32Number) k0; K0 = p -> opta[5] * k0; - K1 = K0 + (Input[0] >= 1.0 ? 0 : p->opta[5]); + K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[5]); p1 = *p; memmove(&p1.Domain[0], &p ->Domain[1], 5*sizeof(cmsUInt32Number)); @@ -1316,7 +1324,7 @@ rest = pk - (cmsFloat32Number) k0; K0 = p -> opta[6] * k0; - K1 = K0 + (Input[0] >= 1.0 ? 0 : p->opta[6]); + K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[6]); p1 = *p; memmove(&p1.Domain[0], &p ->Domain[1], 6*sizeof(cmsUInt32Number)); @@ -1401,7 +1409,7 @@ rest = pk - (cmsFloat32Number) k0; K0 = p -> opta[7] * k0; - K1 = K0 + (Input[0] >= 1.0 ? 0 : p->opta[7]); + K1 = K0 + (fclamp(Input[0]) >= 1.0 ? 0 : p->opta[7]); p1 = *p; memmove(&p1.Domain[0], &p ->Domain[1], 7*sizeof(cmsUInt32Number));
--- a/src/share/native/sun/java2d/cmm/lcms/cmsio0.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsio0.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -366,21 +366,27 @@ return TRUE; } -// Returns file pointer position +// Returns file pointer position or 0 on error, which is also a valid position. static cmsUInt32Number FileTell(cmsIOHANDLER* iohandler) { - return (cmsUInt32Number) ftell((FILE*)iohandler ->stream); + long t = ftell((FILE*)iohandler ->stream); + if (t == -1L) { + cmsSignalError(iohandler->ContextID, cmsERROR_FILE, "Tell error; probably corrupted file"); + return 0; + } + + return (cmsUInt32Number)t; } // Writes data to stream, also keeps used space for further reference. Returns TRUE on success, FALSE on error static cmsBool FileWrite(cmsIOHANDLER* iohandler, cmsUInt32Number size, const void* Buffer) { - if (size == 0) return TRUE; // We allow to write 0 bytes, but nothing is written + if (size == 0) return TRUE; // We allow to write 0 bytes, but nothing is written - iohandler->UsedSpace += size; - return (fwrite(Buffer, size, 1, (FILE*) iohandler->stream) == 1); + iohandler->UsedSpace += size; + return (fwrite(Buffer, size, 1, (FILE*)iohandler->stream) == 1); } // Closes the file @@ -548,7 +554,7 @@ _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; if (Icc == NULL) return -1; - return Icc->TagCount; + return (cmsInt32Number) Icc->TagCount; } // Return the tag signature of a given tag number @@ -566,9 +572,9 @@ static int SearchOneTag(_cmsICCPROFILE* Profile, cmsTagSignature sig) { - cmsUInt32Number i; + int i; - for (i=0; i < Profile -> TagCount; i++) { + for (i=0; i < (int) Profile -> TagCount; i++) { if (sig == Profile -> TagNames[i]) return i; @@ -662,7 +668,7 @@ return FALSE; } - *NewPos = Icc ->TagCount; + *NewPos = (int) Icc ->TagCount; Icc -> TagCount++; } @@ -693,10 +699,10 @@ cmsUInt8Number temp2; if (*pByte > 0x09) *pByte = (cmsUInt8Number) 0x09; - temp1 = *(pByte+1) & 0xf0; - temp2 = *(pByte+1) & 0x0f; - if (temp1 > 0x90) temp1 = 0x90; - if (temp2 > 0x09) temp2 = 0x09; + temp1 = (cmsUInt8Number) (*(pByte+1) & 0xf0); + temp2 = (cmsUInt8Number) (*(pByte+1) & 0x0f); + if (temp1 > 0x90U) temp1 = 0x90U; + if (temp2 > 0x09U) temp2 = 0x09U; *(pByte+1) = (cmsUInt8Number)(temp1 | temp2); *(pByte+2) = (cmsUInt8Number)0; *(pByte+3) = (cmsUInt8Number)0; @@ -804,7 +810,7 @@ cmsICCHeader Header; cmsUInt32Number i; cmsTagEntry Tag; - cmsInt32Number Count = 0; + cmsUInt32Number Count; Header.size = _cmsAdjustEndianess32(UsedSpace); Header.cmmId = _cmsAdjustEndianess32(lcmsSignature); @@ -835,9 +841,9 @@ Header.renderingIntent = _cmsAdjustEndianess32(Icc -> RenderingIntent); // Illuminant is always D50 - Header.illuminant.X = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(cmsD50_XYZ()->X)); - Header.illuminant.Y = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(cmsD50_XYZ()->Y)); - Header.illuminant.Z = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(cmsD50_XYZ()->Z)); + Header.illuminant.X = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->X)); + Header.illuminant.Y = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->Y)); + Header.illuminant.Z = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(cmsD50_XYZ()->Z)); // Created by LittleCMS (that's me!) Header.creator = _cmsAdjustEndianess32(lcmsSignature); @@ -853,6 +859,7 @@ // Saves Tag directory // Get true count + Count = 0; for (i=0; i < Icc -> TagCount; i++) { if (Icc ->TagNames[i] != (cmsTagSignature) 0) Count++; @@ -865,9 +872,9 @@ if (Icc ->TagNames[i] == (cmsTagSignature) 0) continue; // It is just a placeholder - Tag.sig = (cmsTagSignature) _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagNames[i]); - Tag.offset = _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagOffsets[i]); - Tag.size = _cmsAdjustEndianess32((cmsInt32Number) Icc -> TagSizes[i]); + Tag.sig = (cmsTagSignature) _cmsAdjustEndianess32((cmsUInt32Number) Icc -> TagNames[i]); + Tag.offset = _cmsAdjustEndianess32((cmsUInt32Number) Icc -> TagOffsets[i]); + Tag.size = _cmsAdjustEndianess32((cmsUInt32Number) Icc -> TagSizes[i]); if (!Icc ->IOhandler -> Write(Icc-> IOhandler, sizeof(cmsTagEntry), &Tag)) return FALSE; } @@ -1176,7 +1183,7 @@ NewIcc = (_cmsICCPROFILE*) hEmpty; // Ok, in this case const void* is casted to void* just because open IO handler - // shares read and writting modes. Don't abuse this feature! + // shares read and writing modes. Don't abuse this feature! NewIcc ->IOhandler = cmsOpenIOhandlerFromMem(ContextID, (void*) MemPtr, dwSize, "r"); if (NewIcc ->IOhandler == NULL) goto Error; @@ -1466,7 +1473,7 @@ // Was open in write mode? if (Icc ->IsWrite) { - Icc ->IsWrite = FALSE; // Assure no further writting + Icc ->IsWrite = FALSE; // Assure no further writing rc &= cmsSaveProfileToFile(hProfile, Icc ->IOhandler->PhysicalFile); } @@ -1543,11 +1550,15 @@ // If the element is already in memory, return the pointer if (Icc -> TagPtrs[n]) { - if (Icc -> TagTypeHandlers[n] == NULL) goto Error; - BaseType = Icc -> TagTypeHandlers[n]->Signature; + if (Icc->TagTypeHandlers[n] == NULL) goto Error; + + // Sanity check + BaseType = Icc->TagTypeHandlers[n]->Signature; if (BaseType == 0) goto Error; - TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig); + + TagDescriptor = _cmsGetTagDescriptor(Icc->ContextID, sig); if (TagDescriptor == NULL) goto Error; + if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error; if (Icc ->TagSaveAsRaw[n]) goto Error; // We don't support read raw tags as cooked @@ -1560,6 +1571,8 @@ Offset = Icc -> TagOffsets[n]; TagSize = Icc -> TagSizes[n]; + if (TagSize < 8) goto Error; + // Seek to its location if (!io -> Seek(io, Offset)) goto Error; @@ -1583,7 +1596,7 @@ if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error; - TagSize -= 8; // Alredy read by the type base logic + TagSize -= 8; // Alredy read by the type base logic // Get type handler TypeHandler = _cmsGetTagTypeHandler(Icc ->ContextID, BaseType); @@ -1772,7 +1785,7 @@ // raw data written does not exactly correspond with the raw data proposed to cmsWriteRaw data, but this approach allows // to write a tag as raw data and the read it as handled. -cmsInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* data, cmsUInt32Number BufferSize) +cmsUInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* data, cmsUInt32Number BufferSize) { _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile; void *Object; @@ -1890,7 +1903,7 @@ } // Similar to the anterior. This function allows to write directly to the ICC profile any data, without -// checking anything. As a rule, mixing Raw with cooked doesn't work, so writting a tag as raw and then reading +// checking anything. As a rule, mixing Raw with cooked doesn't work, so writing a tag as raw and then reading // it as cooked without serializing does result into an error. If that is what you want, you will need to dump // the profile to memry or disk and then reopen it. cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size)
--- a/src/share/native/sun/java2d/cmm/lcms/cmsio1.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsio1.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -335,8 +335,8 @@ // Read and create a BRAND NEW MPE LUT from a given profile. All stuff dependent of version, etc // is adjusted here in order to create a LUT that takes care of all those details. -// We add intent = -1 as a way to read matrix shaper always, no matter of other LUT -cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent) +// We add intent = 0xffffffff as a way to read matrix shaper always, no matter of other LUT +cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent) { cmsTagTypeSignature OriginalType; cmsTagSignature tag16; @@ -366,8 +366,8 @@ } // This is an attempt to reuse this function to retrieve the matrix-shaper as pipeline no - // matter other LUT are present and have precedence. Intent = -1 means just this. - if (Intent >= INTENT_PERCEPTUAL && Intent <= INTENT_ABSOLUTE_COLORIMETRIC) { + // matter other LUT are present and have precedence. Intent = 0xffffffff can be used for that. + if (Intent <= INTENT_ABSOLUTE_COLORIMETRIC) { tag16 = Device2PCS16[Intent]; tagFloat = Device2PCSFloat[Intent]; @@ -611,7 +611,7 @@ } // Create an output MPE LUT from agiven profile. Version mismatches are handled here -cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent) +cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent) { cmsTagTypeSignature OriginalType; cmsTagSignature tag16; @@ -619,7 +619,7 @@ cmsContext ContextID = cmsGetProfileContextID(hProfile); - if (Intent >= INTENT_PERCEPTUAL && Intent <= INTENT_ABSOLUTE_COLORIMETRIC) { + if (Intent <= INTENT_ABSOLUTE_COLORIMETRIC) { tag16 = PCS2Device16[Intent]; tagFloat = PCS2DeviceFloat[Intent]; @@ -695,8 +695,8 @@ static cmsPipeline* _cmsReadFloatDevicelinkTag(cmsHPROFILE hProfile, cmsTagSignature tagFloat) { - cmsContext ContextID = cmsGetProfileContextID(hProfile); - cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*) cmsReadTag(hProfile, tagFloat)); + cmsContext ContextID = cmsGetProfileContextID(hProfile); + cmsPipeline* Lut = cmsPipelineDup((cmsPipeline*)cmsReadTag(hProfile, tagFloat)); cmsColorSpaceSignature PCS = cmsGetPCS(hProfile); cmsColorSpaceSignature spc = cmsGetColorSpace(hProfile); @@ -714,17 +714,17 @@ goto Error; } - if (PCS == cmsSigLabData) + if (PCS == cmsSigLabData) + { + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID))) + goto Error; + } + else + if (PCS == cmsSigXYZData) { - if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromLabFloat(ContextID))) + if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID))) goto Error; } - else - if (PCS == cmsSigXYZData) - { - if (!cmsPipelineInsertStage(Lut, cmsAT_END, _cmsStageNormalizeFromXyzFloat(ContextID))) - goto Error; - } return Lut; Error: @@ -734,7 +734,7 @@ // This one includes abstract profiles as well. Matrix-shaper cannot be obtained on that device class. The // tag name here may default to AToB0 -cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent) +cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent) { cmsPipeline* Lut; cmsTagTypeSignature OriginalType; @@ -743,7 +743,7 @@ cmsContext ContextID = cmsGetProfileContextID(hProfile); - if (Intent < INTENT_PERCEPTUAL || Intent > INTENT_ABSOLUTE_COLORIMETRIC) + if (Intent > INTENT_ABSOLUTE_COLORIMETRIC) return NULL; tag16 = Device2PCS16[Intent];
--- a/src/share/native/sun/java2d/cmm/lcms/cmslut.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmslut.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -153,8 +153,8 @@ mpe = Lut ->Elements; for (i=0; i < n; i++) { - // Get asked type - Type = (cmsStageSignature)va_arg(args, cmsStageSignature); + // Get asked type. cmsStageSignature is promoted to int by compiler + Type = (cmsStageSignature)va_arg(args, int); if (mpe ->Type != Type) { va_end(args); // Mismatch. We are done. @@ -321,7 +321,7 @@ // Create a bunch of identity curves -cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels) +cmsStage* CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels) { cmsStage* mpe = cmsStageAllocToneCurves(ContextID, nChannels, NULL); @@ -443,13 +443,13 @@ if (Offset != NULL) { - NewElem ->Offset = (cmsFloat64Number*) _cmsCalloc(ContextID, Cols, sizeof(cmsFloat64Number)); + NewElem ->Offset = (cmsFloat64Number*) _cmsCalloc(ContextID, Rows, sizeof(cmsFloat64Number)); if (NewElem->Offset == NULL) { MatrixElemTypeFree(NewMPE); return NULL; } - for (i=0; i < Cols; i++) { + for (i=0; i < Rows; i++) { NewElem ->Offset[i] = Offset[i]; } @@ -741,7 +741,7 @@ } // Creates an MPE that just copies input to output -cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan) +cmsStage* CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan) { cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS]; cmsStage* mpe ; @@ -765,7 +765,7 @@ // Quantize a value 0 <= i < MaxSamples to 0..0xffff -cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples) +cmsUInt16Number CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples) { cmsFloat64Number x; @@ -778,8 +778,9 @@ // function on knots. returns TRUE if all ok, FALSE otherwise. cmsBool CMSEXPORT cmsStageSampleCLut16bit(cmsStage* mpe, cmsSAMPLER16 Sampler, void * Cargo, cmsUInt32Number dwFlags) { - int i, t, nTotalPoints, index, rest; - int nInputs, nOutputs; + int i, t, index, rest; + cmsUInt32Number nTotalPoints; + cmsUInt32Number nInputs, nOutputs; cmsUInt32Number* nSamples; cmsUInt16Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS]; _cmsStageCLutData* clut; @@ -799,14 +800,17 @@ if (nInputs > MAX_INPUT_DIMENSIONS) return FALSE; if (nOutputs >= MAX_STAGE_CHANNELS) return FALSE; + memset(In, 0, sizeof(In)); + memset(Out, 0, sizeof(Out)); + nTotalPoints = CubeSize(nSamples, nInputs); if (nTotalPoints == 0) return FALSE; index = 0; - for (i = 0; i < nTotalPoints; i++) { + for (i = 0; i < (int) nTotalPoints; i++) { rest = i; - for (t = nInputs-1; t >=0; --t) { + for (t = (int)nInputs - 1; t >= 0; --t) { cmsUInt32Number Colorant = rest % nSamples[t]; @@ -816,7 +820,7 @@ } if (clut ->Tab.T != NULL) { - for (t=0; t < nOutputs; t++) + for (t = 0; t < (int)nOutputs; t++) Out[t] = clut->Tab.T[index + t]; } @@ -826,7 +830,7 @@ if (!(dwFlags & SAMPLER_INSPECT)) { if (clut ->Tab.T != NULL) { - for (t=0; t < nOutputs; t++) + for (t=0; t < (int) nOutputs; t++) clut->Tab.T[index + t] = Out[t]; } } @@ -837,11 +841,12 @@ return TRUE; } -// Same as anterior, but for floting point +// Same as anterior, but for floating point cmsBool CMSEXPORT cmsStageSampleCLutFloat(cmsStage* mpe, cmsSAMPLERFLOAT Sampler, void * Cargo, cmsUInt32Number dwFlags) { - int i, t, nTotalPoints, index, rest; - int nInputs, nOutputs; + int i, t, index, rest; + cmsUInt32Number nTotalPoints; + cmsUInt32Number nInputs, nOutputs; cmsUInt32Number* nSamples; cmsFloat32Number In[MAX_INPUT_DIMENSIONS+1], Out[MAX_STAGE_CHANNELS]; _cmsStageCLutData* clut = (_cmsStageCLutData*) mpe->Data; @@ -859,10 +864,10 @@ if (nTotalPoints == 0) return FALSE; index = 0; - for (i = 0; i < nTotalPoints; i++) { + for (i = 0; i < (int)nTotalPoints; i++) { rest = i; - for (t = nInputs-1; t >=0; --t) { + for (t = (int) nInputs-1; t >=0; --t) { cmsUInt32Number Colorant = rest % nSamples[t]; @@ -872,7 +877,7 @@ } if (clut ->Tab.TFloat != NULL) { - for (t=0; t < nOutputs; t++) + for (t=0; t < (int) nOutputs; t++) Out[t] = clut->Tab.TFloat[index + t]; } @@ -882,7 +887,7 @@ if (!(dwFlags & SAMPLER_INSPECT)) { if (clut ->Tab.TFloat != NULL) { - for (t=0; t < nOutputs; t++) + for (t=0; t < (int) nOutputs; t++) clut->Tab.TFloat[index + t] = Out[t]; } } @@ -900,7 +905,8 @@ cmsBool CMSEXPORT cmsSliceSpace16(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[], cmsSAMPLER16 Sampler, void * Cargo) { - int i, t, nTotalPoints, rest; + int i, t, rest; + cmsUInt32Number nTotalPoints; cmsUInt16Number In[cmsMAXCHANNELS]; if (nInputs >= cmsMAXCHANNELS) return FALSE; @@ -908,10 +914,10 @@ nTotalPoints = CubeSize(clutPoints, nInputs); if (nTotalPoints == 0) return FALSE; - for (i = 0; i < nTotalPoints; i++) { + for (i = 0; i < (int) nTotalPoints; i++) { rest = i; - for (t = nInputs-1; t >=0; --t) { + for (t = (int) nInputs-1; t >=0; --t) { cmsUInt32Number Colorant = rest % clutPoints[t]; @@ -930,7 +936,8 @@ cmsInt32Number CMSEXPORT cmsSliceSpaceFloat(cmsUInt32Number nInputs, const cmsUInt32Number clutPoints[], cmsSAMPLERFLOAT Sampler, void * Cargo) { - int i, t, nTotalPoints, rest; + int i, t, rest; + cmsUInt32Number nTotalPoints; cmsFloat32Number In[cmsMAXCHANNELS]; if (nInputs >= cmsMAXCHANNELS) return FALSE; @@ -938,10 +945,10 @@ nTotalPoints = CubeSize(clutPoints, nInputs); if (nTotalPoints == 0) return FALSE; - for (i = 0; i < nTotalPoints; i++) { + for (i = 0; i < (int) nTotalPoints; i++) { rest = i; - for (t = nInputs-1; t >=0; --t) { + for (t = (int) nInputs-1; t >=0; --t) { cmsUInt32Number Colorant = rest % clutPoints[t]; @@ -991,7 +998,7 @@ // No dup or free routines needed, as the structure has no pointers in it. -cmsStage* _cmsStageAllocLab2XYZ(cmsContext ContextID) +cmsStage* CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID) { return _cmsStageAllocPlaceholder(ContextID, cmsSigLab2XYZElemType, 3, 3, EvaluateLab2XYZ, NULL, NULL, NULL); } @@ -1021,7 +1028,7 @@ return NULL; } - // We need to map * (0xffff / 0xff00), thats same as (257 / 256) + // We need to map * (0xffff / 0xff00), that's same as (257 / 256) // So we can use 258-entry tables to do the trick (i / 257) * (255 * 257) * (257 / 256); for (i=0; i < 257; i++) { @@ -1042,7 +1049,7 @@ // ******************************************************************************** // Matrix-based conversion, which is more accurate, but slower and cannot properly be saved in devicelink profiles -cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID) +cmsStage* CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID) { static const cmsFloat64Number V2ToV4[] = { 65535.0/65280.0, 0, 0, 0, 65535.0/65280.0, 0, @@ -1058,7 +1065,7 @@ // Reverse direction -cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID) +cmsStage* CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID) { static const cmsFloat64Number V4ToV2[] = { 65280.0/65535.0, 0, 0, 0, 65280.0/65535.0, 0, @@ -1166,7 +1173,7 @@ } } -cmsStage* _cmsStageClipNegatives(cmsContext ContextID, int nChannels) +cmsStage* _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels) { return _cmsStageAllocPlaceholder(ContextID, cmsSigClipNegativesElemType, nChannels, nChannels, Clipper, NULL, NULL, NULL); @@ -1201,7 +1208,7 @@ cmsUNUSED_PARAMETER(mpe); } -cmsStage* _cmsStageAllocXYZ2Lab(cmsContext ContextID) +cmsStage* CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID) { return _cmsStageAllocPlaceholder(ContextID, cmsSigXYZ2LabElemType, 3, 3, EvaluateXYZ2Lab, NULL, NULL, NULL); @@ -1300,23 +1307,42 @@ // *********************************************************************************************************** // This function sets up the channel count - static -void BlessLUT(cmsPipeline* lut) +cmsBool BlessLUT(cmsPipeline* lut) { - // We can set the input/ouput channels only if we have elements. + // We can set the input/output channels only if we have elements. if (lut ->Elements != NULL) { - cmsStage *First, *Last; + cmsStage* prev; + cmsStage* next; + cmsStage* First; + cmsStage* Last; First = cmsPipelineGetPtrToFirstStage(lut); Last = cmsPipelineGetPtrToLastStage(lut); - if (First != NULL)lut ->InputChannels = First ->InputChannels; - if (Last != NULL) lut ->OutputChannels = Last ->OutputChannels; + if (First == NULL || Last == NULL) return FALSE; + + lut->InputChannels = First->InputChannels; + lut->OutputChannels = Last->OutputChannels; + + // Check chain consistency + prev = First; + next = prev->Next; + + while (next != NULL) + { + if (next->InputChannels != prev->OutputChannels) + return FALSE; + + next = next->Next; + prev = prev->Next; } } + return TRUE; +} + // Default to evaluate the LUT on 16 bit-basis. Precision is retained. static @@ -1368,21 +1394,18 @@ } - - // LUT Creation & Destruction - cmsPipeline* CMSEXPORT cmsPipelineAlloc(cmsContext ContextID, cmsUInt32Number InputChannels, cmsUInt32Number OutputChannels) { cmsPipeline* NewLUT; + // A value of zero in channels is allowed as placeholder if (InputChannels >= cmsMAXCHANNELS || OutputChannels >= cmsMAXCHANNELS) return NULL; NewLUT = (cmsPipeline*) _cmsMallocZero(ContextID, sizeof(cmsPipeline)); if (NewLUT == NULL) return NULL; - NewLUT -> InputChannels = InputChannels; NewLUT -> OutputChannels = OutputChannels; @@ -1393,7 +1416,11 @@ NewLUT ->Data = NewLUT; NewLUT ->ContextID = ContextID; - BlessLUT(NewLUT); + if (!BlessLUT(NewLUT)) + { + _cmsFree(ContextID, NewLUT); + return NULL; + } return NewLUT; } @@ -1500,7 +1527,12 @@ NewLUT ->SaveAs8Bits = lut ->SaveAs8Bits; - BlessLUT(NewLUT); + if (!BlessLUT(NewLUT)) + { + _cmsFree(lut->ContextID, NewLUT); + return NULL; + } + return NewLUT; } @@ -1537,8 +1569,7 @@ return FALSE; } - BlessLUT(lut); - return TRUE; + return BlessLUT(lut); } // Unlink an element and return the pointer to it @@ -1593,6 +1624,7 @@ else cmsStageFree(Unlinked); + // May fail, but we ignore it BlessLUT(lut); } @@ -1619,8 +1651,7 @@ return FALSE; } - BlessLUT(l1); - return TRUE; + return BlessLUT(l1); }
--- a/src/share/native/sun/java2d/cmm/lcms/cmsmd5.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsmd5.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"),
--- a/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsmtrx.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"),
--- a/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsnamed.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -156,7 +156,7 @@ for (i=0; i < mlu ->UsedEntries; i++) { if (mlu ->Entries[i].Country == CountryCode && - mlu ->Entries[i].Language == LanguageCode) return i; + mlu ->Entries[i].Language == LanguageCode) return (int) i; } // Not found @@ -207,31 +207,24 @@ return TRUE; } -// Convert from a 3-char code to a cmsUInt16Number. It is done inthis way because some +// Convert from a 3-char code to a cmsUInt16Number. It is done in this way because some // compilers don't properly align beginning of strings static cmsUInt16Number strTo16(const char str[3]) { - cmsUInt16Number n = ((cmsUInt16Number) str[0] << 8) | str[1]; + const cmsUInt8Number* ptr8 = (const cmsUInt8Number*)str; + cmsUInt16Number n = (cmsUInt16Number)(((cmsUInt16Number)ptr8[0] << 8) | ptr8[1]); - return n; // Always big endian in this case + return n; } static void strFrom16(char str[3], cmsUInt16Number n) { - // Assiming this would be aligned - union { - - cmsUInt16Number n; - char str[2]; - - } c; - - c.n = n; // Always big endian in this case - - str[0] = c.str[0]; str[1] = c.str[1]; str[2] = 0; + str[0] = (char)(n >> 8); + str[1] = (char)n; + str[2] = (char)0; } @@ -354,7 +347,7 @@ cmsUInt16Number* UsedLanguageCode, cmsUInt16Number* UsedCountryCode) { cmsUInt32Number i; - cmsInt32Number Best = -1; + int Best = -1; _cmsMLUentry* v; if (mlu == NULL) return NULL; @@ -367,7 +360,7 @@ if (v -> Language == LanguageCode) { - if (Best == -1) Best = i; + if (Best == -1) Best = (int) i; if (v -> Country == CountryCode) { @@ -633,10 +626,10 @@ } for (i=0; i < NamedColorList ->ColorantCount; i++) - NamedColorList ->List[NamedColorList ->nColors].DeviceColorant[i] = Colorant == NULL? 0 : Colorant[i]; + NamedColorList ->List[NamedColorList ->nColors].DeviceColorant[i] = Colorant == NULL ? (cmsUInt16Number)0 : Colorant[i]; for (i=0; i < 3; i++) - NamedColorList ->List[NamedColorList ->nColors].PCS[i] = PCS == NULL ? 0 : PCS[i]; + NamedColorList ->List[NamedColorList ->nColors].PCS[i] = PCS == NULL ? (cmsUInt16Number) 0 : PCS[i]; if (Name != NULL) { @@ -671,6 +664,7 @@ if (nColor >= cmsNamedColorCount(NamedColorList)) return FALSE; + // strcpy instead of strncpy because many apps are using small buffers if (Name) strcpy(Name, NamedColorList->List[nColor].Name); if (Prefix) strcpy(Prefix, NamedColorList->Prefix); if (Suffix) strcpy(Suffix, NamedColorList->Suffix); @@ -688,13 +682,14 @@ // Search for a given color name (no prefix or suffix) cmsInt32Number CMSEXPORT cmsNamedColorIndex(const cmsNAMEDCOLORLIST* NamedColorList, const char* Name) { - int i, n; + cmsUInt32Number i; + cmsUInt32Number n; if (NamedColorList == NULL) return -1; n = cmsNamedColorCount(NamedColorList); for (i=0; i < n; i++) { if (cmsstrcasecmp(Name, NamedColorList->List[i].Name) == 0) - return i; + return (cmsInt32Number) i; } return -1; @@ -723,7 +718,8 @@ cmsUInt16Number index = (cmsUInt16Number) _cmsQuickSaturateWord(In[0] * 65535.0); if (index >= NamedColorList-> nColors) { - cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range; ignored", index); + cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range", index); + Out[0] = Out[1] = Out[2] = 0.0f; } else { @@ -742,7 +738,10 @@ cmsUInt32Number j; if (index >= NamedColorList-> nColors) { - cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range; ignored", index); + cmsSignalError(NamedColorList ->ContextID, cmsERROR_RANGE, "Color %d out of range", index); + for (j = 0; j < NamedColorList->ColorantCount; j++) + Out[j] = 0.0f; + } else { for (j=0; j < NamedColorList ->ColorantCount; j++) @@ -752,7 +751,7 @@ // Named color lookup element -cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS) +cmsStage* CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS) { return _cmsStageAllocPlaceholder(NamedColorList ->ContextID, cmsSigNamedColorElemType,
--- a/src/share/native/sun/java2d/cmm/lcms/cmsopt.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsopt.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -78,8 +78,8 @@ cmsContext ContextID; // Number of channels - int nInputs; - int nOutputs; + cmsUInt32Number nInputs; + cmsUInt32Number nOutputs; _cmsInterpFn16 EvalCurveIn16[MAX_INPUT_DIMENSIONS]; // The maximum number of input channels is known in advance cmsInterpParams* ParamsCurveIn16[MAX_INPUT_DIMENSIONS]; @@ -123,8 +123,8 @@ cmsContext ContextID; - int nCurves; // Number of curves - int nElements; // Elements in curves + cmsUInt32Number nCurves; // Number of curves + cmsUInt32Number nElements; // Elements in curves cmsUInt16Number** Curves; // Points to a dynamically allocated array } Curves16Data; @@ -245,7 +245,7 @@ // Multiply both matrices to get the result _cmsMAT3per(&res, (cmsMAT3*)m2->Double, (cmsMAT3*)m1->Double); - // Get the next in chain afer the matrices + // Get the next in chain after the matrices chain = (*pt2)->Next; // Remove both matrices @@ -334,7 +334,7 @@ Prelin16Data* p16 = (Prelin16Data*) D; cmsUInt16Number StageABC[MAX_INPUT_DIMENSIONS]; cmsUInt16Number StageDEF[cmsMAXCHANNELS]; - int i; + cmsUInt32Number i; for (i=0; i < p16 ->nInputs; i++) { @@ -379,15 +379,15 @@ static Prelin16Data* PrelinOpt16alloc(cmsContext ContextID, const cmsInterpParams* ColorMap, - int nInputs, cmsToneCurve** In, - int nOutputs, cmsToneCurve** Out ) + cmsUInt32Number nInputs, cmsToneCurve** In, + cmsUInt32Number nOutputs, cmsToneCurve** Out ) { - int i; + cmsUInt32Number i; Prelin16Data* p16 = (Prelin16Data*)_cmsMallocZero(ContextID, sizeof(Prelin16Data)); if (p16 == NULL) return NULL; p16 ->nInputs = nInputs; - p16 -> nOutputs = nOutputs; + p16 ->nOutputs = nOutputs; for (i=0; i < nInputs; i++) { @@ -435,7 +435,7 @@ // Sampler implemented by another LUT. This is a clean way to precalculate the devicelink 3D CLUT for // almost any transform. We use floating point precision and then convert from floating point to 16 bits. static -int XFormSampler16(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo) +cmsInt32Number XFormSampler16(register const cmsUInt16Number In[], register cmsUInt16Number Out[], register void* Cargo) { cmsPipeline* Lut = (cmsPipeline*) Cargo; cmsFloat32Number InFloat[cmsMAXCHANNELS], OutFloat[cmsMAXCHANNELS]; @@ -482,7 +482,7 @@ // is to fix scum dot on broken profiles/transforms. Works on 1, 3 and 4 channels static cmsBool PatchLUT(cmsStage* CLUT, cmsUInt16Number At[], cmsUInt16Number Value[], - int nChannelsOut, int nChannelsIn) + cmsUInt32Number nChannelsOut, cmsUInt32Number nChannelsIn) { _cmsStageCLutData* Grid = (_cmsStageCLutData*) CLUT ->Data; cmsInterpParams* p16 = Grid ->Params; @@ -512,10 +512,10 @@ ((pz - z0) != 0) || ((pw - w0) != 0)) return FALSE; // Not on exact node - index = p16 -> opta[3] * x0 + - p16 -> opta[2] * y0 + - p16 -> opta[1] * z0 + - p16 -> opta[0] * w0; + index = (int) p16 -> opta[3] * x0 + + (int) p16 -> opta[2] * y0 + + (int) p16 -> opta[1] * z0 + + (int) p16 -> opta[0] * w0; } else if (nChannelsIn == 3) { @@ -532,9 +532,9 @@ ((py - y0) != 0) || ((pz - z0) != 0)) return FALSE; // Not on exact node - index = p16 -> opta[2] * x0 + - p16 -> opta[1] * y0 + - p16 -> opta[0] * z0; + index = (int) p16 -> opta[2] * x0 + + (int) p16 -> opta[1] * y0 + + (int) p16 -> opta[0] * z0; } else if (nChannelsIn == 1) { @@ -545,24 +545,24 @@ if (((px - x0) != 0)) return FALSE; // Not on exact node - index = p16 -> opta[0] * x0; + index = (int) p16 -> opta[0] * x0; } else { cmsSignalError(CLUT->ContextID, cmsERROR_INTERNAL, "(internal) %d Channels are not supported on PatchLUT", nChannelsIn); return FALSE; } - for (i=0; i < nChannelsOut; i++) - Grid -> Tab.T[index + i] = Value[i]; + for (i = 0; i < (int) nChannelsOut; i++) + Grid->Tab.T[index + i] = Value[i]; return TRUE; } // Auxiliary, to see if two values are equal or very different static -cmsBool WhitesAreEqual(int n, cmsUInt16Number White1[], cmsUInt16Number White2[] ) +cmsBool WhitesAreEqual(cmsUInt32Number n, cmsUInt16Number White1[], cmsUInt16Number White2[] ) { - int i; + cmsUInt32Number i; for (i=0; i < n; i++) { @@ -664,7 +664,7 @@ cmsStage* mpe; cmsStage* CLUT; cmsStage *KeepPreLin = NULL, *KeepPostLin = NULL; - int nGridPoints; + cmsUInt32Number nGridPoints; cmsColorSpaceSignature ColorSpace, OutputColorSpace; cmsStage *NewPreLin = NULL; cmsStage *NewPostLin = NULL; @@ -676,8 +676,13 @@ // This is a loosy optimization! does not apply in floating-point cases if (_cmsFormatterIsFloat(*InputFormat) || _cmsFormatterIsFloat(*OutputFormat)) return FALSE; - ColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*InputFormat)); - OutputColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*OutputFormat)); + ColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*InputFormat)); + OutputColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*OutputFormat)); + + // Color space must be specified + if (ColorSpace == (cmsColorSpaceSignature)0 || + OutputColorSpace == (cmsColorSpaceSignature)0) return FALSE; + nGridPoints = _cmsReasonableGridpointsByColorspace(ColorSpace, *dwFlags); // For empty LUTs, 2 points are enough @@ -715,7 +720,7 @@ goto Error; // Remove prelinearization. Since we have duplicated the curve - // in destination LUT, the sampling shoud be applied after this stage. + // in destination LUT, the sampling should be applied after this stage. cmsPipelineUnlinkStage(Src, cmsAT_BEGIN, &KeepPreLin); } } @@ -723,7 +728,7 @@ // Allocate the CLUT CLUT = cmsStageAllocCLut16bit(Src ->ContextID, nGridPoints, Src ->InputChannels, Src->OutputChannels, NULL); - if (CLUT == NULL) return FALSE; + if (CLUT == NULL) goto Error; // Add the CLUT to the destination LUT if (!cmsPipelineInsertStage(Dest, cmsAT_END, CLUT)) { @@ -747,14 +752,14 @@ if (!cmsPipelineInsertStage(Dest, cmsAT_END, NewPostLin)) goto Error; - // In destination LUT, the sampling shoud be applied after this stage. + // In destination LUT, the sampling should be applied after this stage. cmsPipelineUnlinkStage(Src, cmsAT_END, &KeepPostLin); } } } // Now its time to do the sampling. We have to ignore pre/post linearization - // The source LUT whithout pre/post curves is passed as parameter. + // The source LUT without pre/post curves is passed as parameter. if (!cmsStageSampleCLut16bit(CLUT, XFormSampler16, (void*) Src, 0)) { Error: // Ops, something went wrong, Restore stages @@ -834,7 +839,7 @@ { int BeginVal, EndVal; int AtBegin = (int) floor((cmsFloat64Number) g ->nEntries * 0.02 + 0.5); // Cutoff at 2% - int AtEnd = g ->nEntries - AtBegin - 1; // And 98% + int AtEnd = (int) g ->nEntries - AtBegin - 1; // And 98% cmsFloat64Number Val, Slope, beta; int i; @@ -895,9 +900,9 @@ // Move to 0..1.0 in fixed domain - v1 = _cmsToFixedDomain(Input[0] * p -> Domain[0]); - v2 = _cmsToFixedDomain(Input[1] * p -> Domain[1]); - v3 = _cmsToFixedDomain(Input[2] * p -> Domain[2]); + v1 = _cmsToFixedDomain((int) (Input[0] * p -> Domain[0])); + v2 = _cmsToFixedDomain((int) (Input[1] * p -> Domain[1])); + v3 = _cmsToFixedDomain((int) (Input[2] * p -> Domain[2])); // Store the precalculated table of nodes p8 ->X0[i] = (p->opta[2] * FIXED_TO_INT(v1)); @@ -942,27 +947,27 @@ cmsS15Fixed16Number rx, ry, rz; cmsS15Fixed16Number c0, c1, c2, c3, Rest; int OutChan; - register cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1; + register cmsS15Fixed16Number X0, X1, Y0, Y1, Z0, Z1; Prelin8Data* p8 = (Prelin8Data*) D; register const cmsInterpParams* p = p8 ->p; - int TotalOut = p -> nOutputs; + int TotalOut = (int) p -> nOutputs; const cmsUInt16Number* LutTable = (const cmsUInt16Number*) p->Table; - r = Input[0] >> 8; - g = Input[1] >> 8; - b = Input[2] >> 8; + r = (cmsUInt8Number) (Input[0] >> 8); + g = (cmsUInt8Number) (Input[1] >> 8); + b = (cmsUInt8Number) (Input[2] >> 8); - X0 = X1 = p8->X0[r]; - Y0 = Y1 = p8->Y0[g]; - Z0 = Z1 = p8->Z0[b]; + X0 = X1 = (cmsS15Fixed16Number) p8->X0[r]; + Y0 = Y1 = (cmsS15Fixed16Number) p8->Y0[g]; + Z0 = Z1 = (cmsS15Fixed16Number) p8->Z0[b]; rx = p8 ->rx[r]; ry = p8 ->ry[g]; rz = p8 ->rz[b]; - X1 = X0 + ((rx == 0) ? 0 : p ->opta[2]); - Y1 = Y0 + ((ry == 0) ? 0 : p ->opta[1]); - Z1 = Z0 + ((rz == 0) ? 0 : p ->opta[0]); + X1 = X0 + (cmsS15Fixed16Number)((rx == 0) ? 0 : p ->opta[2]); + Y1 = Y0 + (cmsS15Fixed16Number)((ry == 0) ? 0 : p ->opta[1]); + Z1 = Z0 + (cmsS15Fixed16Number)((rz == 0) ? 0 : p ->opta[0]); // These are the 6 Tetrahedral @@ -1015,9 +1020,8 @@ c1 = c2 = c3 = 0; } - Rest = c1 * rx + c2 * ry + c3 * rz + 0x8001; - Output[OutChan] = (cmsUInt16Number)c0 + ((Rest + (Rest>>16))>>16); + Output[OutChan] = (cmsUInt16Number) (c0 + ((Rest + (Rest >> 16)) >> 16)); } } @@ -1029,8 +1033,8 @@ static cmsBool IsDegenerated(const cmsToneCurve* g) { - int i, Zeros = 0, Poles = 0; - int nEntries = g ->nEntries; + cmsUInt32Number i, Zeros = 0, Poles = 0; + cmsUInt32Number nEntries = g ->nEntries; for (i=0; i < nEntries; i++) { @@ -1052,7 +1056,7 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags) { cmsPipeline* OriginalLut; - int nGridPoints; + cmsUInt32Number nGridPoints; cmsToneCurve *Trans[cmsMAXCHANNELS], *TransReverse[cmsMAXCHANNELS]; cmsUInt32Number t, i; cmsFloat32Number v, In[cmsMAXCHANNELS], Out[cmsMAXCHANNELS]; @@ -1090,8 +1094,13 @@ if (cmsStageType(mpe) == cmsSigNamedColorElemType) return FALSE; } - ColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*InputFormat)); - OutputColorSpace = _cmsICCcolorSpace(T_COLORSPACE(*OutputFormat)); + ColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*InputFormat)); + OutputColorSpace = _cmsICCcolorSpace((int) T_COLORSPACE(*OutputFormat)); + + // Color space must be specified + if (ColorSpace == (cmsColorSpaceSignature)0 || + OutputColorSpace == (cmsColorSpaceSignature)0) return FALSE; + nGridPoints = _cmsReasonableGridpointsByColorspace(ColorSpace, *dwFlags); // Empty gamma containers @@ -1212,7 +1221,10 @@ Prelin8Data* p8 = PrelinOpt8alloc(OptimizedLUT ->ContextID, OptimizedPrelinCLUT ->Params, OptimizedPrelinCurves); - if (p8 == NULL) return FALSE; + if (p8 == NULL) { + cmsPipelineFree(OptimizedLUT); + return FALSE; + } _cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval8, (void*) p8, Prelin8free, Prelin8dup); @@ -1222,7 +1234,10 @@ Prelin16Data* p16 = PrelinOpt16alloc(OptimizedLUT ->ContextID, OptimizedPrelinCLUT ->Params, 3, OptimizedPrelinCurves, 3, NULL); - if (p16 == NULL) return FALSE; + if (p16 == NULL) { + cmsPipelineFree(OptimizedLUT); + return FALSE; + } _cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval16, (void*) p16, PrelinOpt16free, Prelin16dup); @@ -1260,6 +1275,7 @@ return FALSE; cmsUNUSED_PARAMETER(Intent); + cmsUNUSED_PARAMETER(lIsLinear); } @@ -1269,7 +1285,7 @@ void CurvesFree(cmsContext ContextID, void* ptr) { Curves16Data* Data = (Curves16Data*) ptr; - int i; + cmsUInt32Number i; for (i=0; i < Data -> nCurves; i++) { @@ -1284,7 +1300,7 @@ void* CurvesDup(cmsContext ContextID, const void* ptr) { Curves16Data* Data = (Curves16Data*)_cmsDupMem(ContextID, ptr, sizeof(Curves16Data)); - int i; + cmsUInt32Number i; if (Data == NULL) return NULL; @@ -1299,9 +1315,9 @@ // Precomputes tables for 8-bit on input devicelink. static -Curves16Data* CurvesAlloc(cmsContext ContextID, int nCurves, int nElements, cmsToneCurve** G) +Curves16Data* CurvesAlloc(cmsContext ContextID, cmsUInt32Number nCurves, cmsUInt32Number nElements, cmsToneCurve** G) { - int i, j; + cmsUInt32Number i, j; Curves16Data* c16; c16 = (Curves16Data*)_cmsMallocZero(ContextID, sizeof(Curves16Data)); @@ -1311,7 +1327,10 @@ c16 ->nElements = nElements; c16->Curves = (cmsUInt16Number**) _cmsCalloc(ContextID, nCurves, sizeof(cmsUInt16Number*)); - if (c16 ->Curves == NULL) return NULL; + if (c16->Curves == NULL) { + _cmsFree(ContextID, c16); + return NULL; + } for (i=0; i < nCurves; i++) { @@ -1327,7 +1346,7 @@ return NULL; } - if (nElements == 256) { + if (nElements == 256U) { for (j=0; j < nElements; j++) { @@ -1351,8 +1370,8 @@ register const void* D) { Curves16Data* Data = (Curves16Data*) D; - cmsUInt8Number x; - int i; + int x; + cmsUInt32Number i; for (i=0; i < Data ->nCurves; i++) { @@ -1368,7 +1387,7 @@ register const void* D) { Curves16Data* Data = (Curves16Data*) D; - int i; + cmsUInt32Number i; for (i=0; i < Data ->nCurves; i++) { Out[i] = Data -> Curves[i][In[i]]; @@ -1548,9 +1567,9 @@ // In this case (and only in this case!) we can use this simplification since // In[] is assured to come from a 8 bit number. (a << 8 | a) - ri = In[0] & 0xFF; - gi = In[1] & 0xFF; - bi = In[2] & 0xFF; + ri = In[0] & 0xFFU; + gi = In[1] & 0xFFU; + bi = In[2] & 0xFFU; // Across first shaper, which also converts to 1.14 fixed point r = p->Shaper1R[ri]; @@ -1563,9 +1582,9 @@ l3 = (p->Mat[2][0] * r + p->Mat[2][1] * g + p->Mat[2][2] * b + p->Off[2] + 0x2000) >> 14; // Now we have to clip to 0..1.0 range - ri = (l1 < 0) ? 0 : ((l1 > 16384) ? 16384 : l1); - gi = (l2 < 0) ? 0 : ((l2 > 16384) ? 16384 : l2); - bi = (l3 < 0) ? 0 : ((l3 > 16384) ? 16384 : l3); + ri = (l1 < 0) ? 0 : ((l1 > 16384) ? 16384U : (cmsUInt32Number) l1); + gi = (l2 < 0) ? 0 : ((l2 > 16384) ? 16384U : (cmsUInt32Number) l2); + bi = (l3 < 0) ? 0 : ((l3 > 16384) ? 16384U : (cmsUInt32Number) l3); // And across second shaper, Out[0] = p->Shaper2R[ri]; @@ -1586,7 +1605,10 @@ R = (cmsFloat32Number) (i / 255.0); y = cmsEvalToneCurveFloat(Curve, R); - Table[i] = DOUBLE_TO_1FIXED14(y); + if (y < 131072.0) + Table[i] = DOUBLE_TO_1FIXED14(y); + else + Table[i] = 0x7fffffff; } } @@ -1602,6 +1624,12 @@ R = (cmsFloat32Number) (i / 16384.0); Val = cmsEvalToneCurveFloat(Curve, R); // Val comes 0..1.0 + if (Val < 0) + Val = 0; + + if (Val > 1.0) + Val = 1.0; + if (Is8BitsOutput) { // If 8 bits output, we can optimize further by computing the / 257 part. @@ -1640,7 +1668,7 @@ FillSecondShaper(p ->Shaper2G, Curve2[1], Is8Bits); FillSecondShaper(p ->Shaper2B, Curve2[2], Is8Bits); - // Convert matrix to nFixed14. Note that those values may take more than 16 bits as + // Convert matrix to nFixed14. Note that those values may take more than 16 bits for (i=0; i < 3; i++) { for (j=0; j < 3; j++) { p ->Mat[i][j] = DOUBLE_TO_1FIXED14(Mat->v[i].n[j]); @@ -1902,7 +1930,7 @@ // The entry point for LUT optimization cmsBool _cmsOptimizePipeline(cmsContext ContextID, cmsPipeline** PtrLut, - int Intent, + cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags)
--- a/src/share/native/sun/java2d/cmm/lcms/cmspack.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmspack.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -126,21 +126,21 @@ register cmsUInt8Number* accum, register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> InputFormat); - int DoSwap = T_DOSWAP(info ->InputFormat); - int Reverse = T_FLAVOR(info ->InputFormat); - int SwapFirst = T_SWAPFIRST(info -> InputFormat); - int Extra = T_EXTRA(info -> InputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; cmsUInt16Number v; - int i; + cmsUInt32Number i; if (ExtraFirst) { accum += Extra; } for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; v = FROM_8_TO_16(*accum); v = Reverse ? REVERSE_FLAVOR_16(v) : v; @@ -173,11 +173,11 @@ register cmsUInt8Number* accum, register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> InputFormat); - int DoSwap = T_DOSWAP(info ->InputFormat); - int SwapFirst = T_SWAPFIRST(info ->InputFormat); - int Reverse = T_FLAVOR(info ->InputFormat); - int i; + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number i; cmsUInt8Number* Init = accum; if (DoSwap ^ SwapFirst) { @@ -186,7 +186,7 @@ for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; cmsUInt16Number v = FROM_8_TO_16(*accum); wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v; @@ -503,14 +503,14 @@ register cmsUInt8Number* accum, register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> InputFormat); - int SwapEndian = T_ENDIAN16(info -> InputFormat); - int DoSwap = T_DOSWAP(info ->InputFormat); - int Reverse = T_FLAVOR(info ->InputFormat); - int SwapFirst = T_SWAPFIRST(info -> InputFormat); - int Extra = T_EXTRA(info -> InputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; - int i; + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number i; if (ExtraFirst) { accum += Extra * sizeof(cmsUInt16Number); @@ -518,7 +518,7 @@ for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; cmsUInt16Number v = *(cmsUInt16Number*) accum; if (SwapEndian) @@ -552,20 +552,20 @@ register cmsUInt8Number* accum, register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> InputFormat); - int DoSwap= T_DOSWAP(info ->InputFormat); - int Reverse= T_FLAVOR(info ->InputFormat); - int SwapEndian = T_ENDIAN16(info -> InputFormat); - int i; + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap= T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse= T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapEndian = T_ENDIAN16(info -> InputFormat); + cmsUInt32Number i; cmsUInt8Number* Init = accum; if (DoSwap) { - accum += T_EXTRA(info -> InputFormat) * Stride * sizeof(cmsUInt16Number); + accum += T_EXTRA(info -> InputFormat) * Stride; } for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; cmsUInt16Number v = *(cmsUInt16Number*) accum; if (SwapEndian) @@ -573,7 +573,7 @@ wIn[index] = Reverse ? REVERSE_FLAVOR_16(v) : v; - accum += Stride * sizeof(cmsUInt16Number); + accum += Stride; } return (Init + sizeof(cmsUInt16Number)); @@ -801,13 +801,18 @@ { if (T_PLANAR(info -> InputFormat)) { - cmsFloat64Number* Pt = (cmsFloat64Number*) accum; - cmsCIELab Lab; - - Lab.L = Pt[0]; - Lab.a = Pt[Stride]; - Lab.b = Pt[Stride*2]; + cmsUInt8Number* pos_L; + cmsUInt8Number* pos_a; + cmsUInt8Number* pos_b; + + pos_L = accum; + pos_a = accum + Stride; + pos_b = accum + Stride * 2; + + Lab.L = *(cmsFloat64Number*) pos_L; + Lab.a = *(cmsFloat64Number*) pos_a; + Lab.b = *(cmsFloat64Number*) pos_b; cmsFloat2LabEncoded(wIn, &Lab); return accum + sizeof(cmsFloat64Number); @@ -832,12 +837,17 @@ if (T_PLANAR(info -> InputFormat)) { - cmsFloat32Number* Pt = (cmsFloat32Number*) accum; - - - Lab.L = Pt[0]; - Lab.a = Pt[Stride]; - Lab.b = Pt[Stride*2]; + cmsUInt8Number* pos_L; + cmsUInt8Number* pos_a; + cmsUInt8Number* pos_b; + + pos_L = accum; + pos_a = accum + Stride; + pos_b = accum + Stride * 2; + + Lab.L = *(cmsFloat32Number*)pos_L; + Lab.a = *(cmsFloat32Number*)pos_a; + Lab.b = *(cmsFloat32Number*)pos_b; cmsFloat2LabEncoded(wIn, &Lab); return accum + sizeof(cmsFloat32Number); @@ -863,12 +873,19 @@ { if (T_PLANAR(info -> InputFormat)) { - cmsFloat64Number* Pt = (cmsFloat64Number*) accum; cmsCIEXYZ XYZ; - - XYZ.X = Pt[0]; - XYZ.Y = Pt[Stride]; - XYZ.Z = Pt[Stride*2]; + cmsUInt8Number* pos_X; + cmsUInt8Number* pos_Y; + cmsUInt8Number* pos_Z; + + pos_X = accum; + pos_Y = accum + Stride; + pos_Z = accum + Stride * 2; + + XYZ.X = *(cmsFloat64Number*)pos_X; + XYZ.Y = *(cmsFloat64Number*)pos_Y; + XYZ.Z = *(cmsFloat64Number*)pos_Z; + cmsFloat2XYZEncoded(wIn, &XYZ); return accum + sizeof(cmsFloat64Number); @@ -892,12 +909,19 @@ { if (T_PLANAR(info -> InputFormat)) { - cmsFloat32Number* Pt = (cmsFloat32Number*) accum; cmsCIEXYZ XYZ; - - XYZ.X = Pt[0]; - XYZ.Y = Pt[Stride]; - XYZ.Z = Pt[Stride*2]; + cmsUInt8Number* pos_X; + cmsUInt8Number* pos_Y; + cmsUInt8Number* pos_Z; + + pos_X = accum; + pos_Y = accum + Stride; + pos_Z = accum + Stride * 2; + + XYZ.X = *(cmsFloat32Number*)pos_X; + XYZ.Y = *(cmsFloat32Number*)pos_Y; + XYZ.Z = *(cmsFloat32Number*)pos_Z; + cmsFloat2XYZEncoded(wIn, &XYZ); return accum + sizeof(cmsFloat32Number); @@ -942,6 +966,20 @@ } } +// Return the size in bytes of a given formatter +static +cmsUInt32Number PixelSize(cmsUInt32Number Format) +{ + cmsUInt32Number fmt_bytes = T_BYTES(Format); + + // For double, the T_BYTES field is zero + if (fmt_bytes == 0) + return sizeof(cmsUInt64Number); + + // Otherwise, it is already correct for all formats + return fmt_bytes; +} + // Inks does come in percentage, remaining cases are between 0..1.0, again to 16 bits static cmsUInt8Number* UnrollDoubleTo16(register _cmsTRANSFORM* info, @@ -950,25 +988,27 @@ register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> InputFormat); - int DoSwap = T_DOSWAP(info ->InputFormat); - int Reverse = T_FLAVOR(info ->InputFormat); - int SwapFirst = T_SWAPFIRST(info -> InputFormat); - int Extra = T_EXTRA(info -> InputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; - int Planar = T_PLANAR(info -> InputFormat); + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info -> InputFormat); cmsFloat64Number v; cmsUInt16Number vi; - int i, start = 0; - cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0; - + cmsUInt32Number i, start = 0; + cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0; + + + Stride /= PixelSize(info->InputFormat); if (ExtraFirst) start = Extra; for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; if (Planar) v = (cmsFloat32Number) ((cmsFloat64Number*) accum)[(i + start) * Stride]; @@ -1006,25 +1046,26 @@ register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> InputFormat); - int DoSwap = T_DOSWAP(info ->InputFormat); - int Reverse = T_FLAVOR(info ->InputFormat); - int SwapFirst = T_SWAPFIRST(info -> InputFormat); - int Extra = T_EXTRA(info -> InputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; - int Planar = T_PLANAR(info -> InputFormat); + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info -> InputFormat); cmsFloat32Number v; cmsUInt16Number vi; - int i, start = 0; - cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0; - + cmsUInt32Number i, start = 0; + cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 655.35 : 65535.0; + + Stride /= PixelSize(info->InputFormat); if (ExtraFirst) start = Extra; for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; if (Planar) v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride]; @@ -1083,24 +1124,25 @@ cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> InputFormat); - int DoSwap = T_DOSWAP(info ->InputFormat); - int Reverse = T_FLAVOR(info ->InputFormat); - int SwapFirst = T_SWAPFIRST(info -> InputFormat); - int Extra = T_EXTRA(info -> InputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; - int Planar = T_PLANAR(info -> InputFormat); + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info -> InputFormat); cmsFloat32Number v; - int i, start = 0; + cmsUInt32Number i, start = 0; cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F; + Stride /= PixelSize(info->InputFormat); if (ExtraFirst) start = Extra; for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; if (Planar) v = (cmsFloat32Number) ((cmsFloat32Number*) accum)[(i + start) * Stride]; @@ -1135,24 +1177,25 @@ cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> InputFormat); - int DoSwap = T_DOSWAP(info ->InputFormat); - int Reverse = T_FLAVOR(info ->InputFormat); - int SwapFirst = T_SWAPFIRST(info -> InputFormat); - int Extra = T_EXTRA(info -> InputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; - int Planar = T_PLANAR(info -> InputFormat); + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info -> InputFormat); cmsFloat64Number v; - int i, start = 0; + cmsUInt32Number i, start = 0; cmsFloat64Number maximum = IsInkSpace(info ->InputFormat) ? 100.0 : 1.0; + Stride /= PixelSize(info->InputFormat); if (ExtraFirst) start = Extra; for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; if (Planar) v = (cmsFloat64Number) ((cmsFloat64Number*) accum)[(i + start) * Stride]; @@ -1191,7 +1234,9 @@ if (T_PLANAR(info -> InputFormat)) { - wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1 + Stride /= PixelSize(info->InputFormat); + + wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0); @@ -1219,6 +1264,8 @@ if (T_PLANAR(info -> InputFormat)) { + Stride /= PixelSize(info->InputFormat); + wIn[0] = (cmsFloat32Number) (Pt[0] / 100.0); // from 0..100 to 0..1 wIn[1] = (cmsFloat32Number) ((Pt[Stride] + 128) / 255.0); // form -128..+127 to 0..1 wIn[2] = (cmsFloat32Number) ((Pt[Stride*2] + 128) / 255.0); @@ -1249,6 +1296,8 @@ if (T_PLANAR(info -> InputFormat)) { + Stride /= PixelSize(info->InputFormat); + wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ); wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ); wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ); @@ -1276,6 +1325,8 @@ if (T_PLANAR(info -> InputFormat)) { + Stride /= PixelSize(info->InputFormat); + wIn[0] = (cmsFloat32Number) (Pt[0] / MAX_ENCODEABLE_XYZ); wIn[1] = (cmsFloat32Number) (Pt[Stride] / MAX_ENCODEABLE_XYZ); wIn[2] = (cmsFloat32Number) (Pt[Stride*2] / MAX_ENCODEABLE_XYZ); @@ -1306,15 +1357,15 @@ register cmsUInt8Number* output, register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> OutputFormat); - int DoSwap = T_DOSWAP(info ->OutputFormat); - int Reverse = T_FLAVOR(info ->OutputFormat); - int Extra = T_EXTRA(info -> OutputFormat); - int SwapFirst = T_SWAPFIRST(info -> OutputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number nChan = T_CHANNELS(info -> OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; cmsUInt8Number* swap1; cmsUInt8Number v = 0; - int i; + cmsUInt32Number i; swap1 = output; @@ -1324,7 +1375,7 @@ for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; v = FROM_16_TO_8(wOut[index]); @@ -1358,16 +1409,16 @@ register cmsUInt8Number* output, register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> OutputFormat); - int SwapEndian = T_ENDIAN16(info -> InputFormat); - int DoSwap = T_DOSWAP(info ->OutputFormat); - int Reverse = T_FLAVOR(info ->OutputFormat); - int Extra = T_EXTRA(info -> OutputFormat); - int SwapFirst = T_SWAPFIRST(info -> OutputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number nChan = T_CHANNELS(info -> OutputFormat); + cmsUInt32Number SwapEndian = T_ENDIAN16(info -> OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; cmsUInt16Number* swap1; cmsUInt16Number v = 0; - int i; + cmsUInt32Number i; swap1 = (cmsUInt16Number*) output; @@ -1377,7 +1428,7 @@ for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; v = wOut[index]; @@ -1415,11 +1466,11 @@ register cmsUInt8Number* output, register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> OutputFormat); - int DoSwap = T_DOSWAP(info ->OutputFormat); - int SwapFirst = T_SWAPFIRST(info ->OutputFormat); - int Reverse = T_FLAVOR(info ->OutputFormat); - int i; + cmsUInt32Number nChan = T_CHANNELS(info -> OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info ->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->OutputFormat); + cmsUInt32Number i; cmsUInt8Number* Init = output; @@ -1430,7 +1481,7 @@ for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; cmsUInt8Number v = FROM_16_TO_8(wOut[index]); *(cmsUInt8Number*) output = (cmsUInt8Number) (Reverse ? REVERSE_FLAVOR_8(v) : v); @@ -1449,21 +1500,21 @@ register cmsUInt8Number* output, register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> OutputFormat); - int DoSwap = T_DOSWAP(info ->OutputFormat); - int Reverse= T_FLAVOR(info ->OutputFormat); - int SwapEndian = T_ENDIAN16(info -> OutputFormat); - int i; + cmsUInt32Number nChan = T_CHANNELS(info -> OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->OutputFormat); + cmsUInt32Number SwapEndian = T_ENDIAN16(info -> OutputFormat); + cmsUInt32Number i; cmsUInt8Number* Init = output; cmsUInt16Number v; if (DoSwap) { - output += T_EXTRA(info -> OutputFormat) * Stride * sizeof(cmsUInt16Number); + output += T_EXTRA(info -> OutputFormat) * Stride; } for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; v = wOut[index]; @@ -1474,7 +1525,7 @@ v = REVERSE_FLAVOR_16(v); *(cmsUInt16Number*) output = v; - output += (Stride * sizeof(cmsUInt16Number)); + output += Stride; } return (Init + sizeof(cmsUInt16Number)); @@ -1823,9 +1874,9 @@ register cmsUInt8Number* output, register cmsUInt32Number Stride) { - *output++ = (wOut[0] & 0xFF); - *output++ = (wOut[1] & 0xFF); - *output++ = (wOut[2] & 0xFF); + *output++ = (wOut[0] & 0xFFU); + *output++ = (wOut[1] & 0xFFU); + *output++ = (wOut[2] & 0xFFU); return output; @@ -1855,9 +1906,9 @@ register cmsUInt8Number* output, register cmsUInt32Number Stride) { - *output++ = (wOut[2] & 0xFF); - *output++ = (wOut[1] & 0xFF); - *output++ = (wOut[0] & 0xFF); + *output++ = (wOut[2] & 0xFFU); + *output++ = (wOut[1] & 0xFFU); + *output++ = (wOut[0] & 0xFFU); return output; @@ -1946,9 +1997,9 @@ register cmsUInt8Number* output, register cmsUInt32Number Stride) { - *output++ = (wOut[0] & 0xFF); - *output++ = (wOut[1] & 0xFF); - *output++ = (wOut[2] & 0xFF); + *output++ = (wOut[0] & 0xFFU); + *output++ = (wOut[1] & 0xFFU); + *output++ = (wOut[2] & 0xFFU); output++; return output; @@ -1982,9 +2033,9 @@ register cmsUInt32Number Stride) { output++; - *output++ = (wOut[0] & 0xFF); - *output++ = (wOut[1] & 0xFF); - *output++ = (wOut[2] & 0xFF); + *output++ = (wOut[0] & 0xFFU); + *output++ = (wOut[1] & 0xFFU); + *output++ = (wOut[2] & 0xFFU); return output; @@ -2016,9 +2067,9 @@ register cmsUInt32Number Stride) { output++; - *output++ = (wOut[2] & 0xFF); - *output++ = (wOut[1] & 0xFF); - *output++ = (wOut[0] & 0xFF); + *output++ = (wOut[2] & 0xFFU); + *output++ = (wOut[1] & 0xFFU); + *output++ = (wOut[0] & 0xFFU); return output; @@ -2050,9 +2101,9 @@ register cmsUInt8Number* output, register cmsUInt32Number Stride) { - *output++ = (wOut[2] & 0xFF); - *output++ = (wOut[1] & 0xFF); - *output++ = (wOut[0] & 0xFF); + *output++ = (wOut[2] & 0xFFU); + *output++ = (wOut[1] & 0xFFU); + *output++ = (wOut[0] & 0xFFU); output++; return output; @@ -2326,6 +2377,8 @@ cmsFloat32Number* Out = (cmsFloat32Number*) output; + Stride /= PixelSize(info->OutputFormat); + Out[0] = (cmsFloat32Number)Lab.L; Out[Stride] = (cmsFloat32Number)Lab.a; Out[Stride*2] = (cmsFloat32Number)Lab.b; @@ -2354,6 +2407,8 @@ cmsFloat64Number* Out = (cmsFloat64Number*) output; cmsXYZEncoded2Float(&XYZ, wOut); + Stride /= PixelSize(Info->OutputFormat); + Out[0] = XYZ.X; Out[Stride] = XYZ.Y; Out[Stride*2] = XYZ.Z; @@ -2381,6 +2436,8 @@ cmsFloat32Number* Out = (cmsFloat32Number*) output; cmsXYZEncoded2Float(&XYZ, wOut); + Stride /= PixelSize(Info->OutputFormat); + Out[0] = (cmsFloat32Number) XYZ.X; Out[Stride] = (cmsFloat32Number) XYZ.Y; Out[Stride*2] = (cmsFloat32Number) XYZ.Z; @@ -2408,24 +2465,26 @@ register cmsUInt8Number* output, register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> OutputFormat); - int DoSwap = T_DOSWAP(info ->OutputFormat); - int Reverse = T_FLAVOR(info ->OutputFormat); - int Extra = T_EXTRA(info -> OutputFormat); - int SwapFirst = T_SWAPFIRST(info -> OutputFormat); - int Planar = T_PLANAR(info -> OutputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number nChan = T_CHANNELS(info -> OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> OutputFormat); + cmsUInt32Number Planar = T_PLANAR(info -> OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; cmsFloat64Number maximum = IsInkSpace(info ->OutputFormat) ? 655.35 : 65535.0; cmsFloat64Number v = 0; cmsFloat64Number* swap1 = (cmsFloat64Number*) output; - int i, start = 0; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->OutputFormat); if (ExtraFirst) start = Extra; for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; v = (cmsFloat64Number) wOut[index] / maximum; @@ -2459,24 +2518,26 @@ register cmsUInt8Number* output, register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info->OutputFormat); - int DoSwap = T_DOSWAP(info->OutputFormat); - int Reverse = T_FLAVOR(info->OutputFormat); - int Extra = T_EXTRA(info->OutputFormat); - int SwapFirst = T_SWAPFIRST(info->OutputFormat); - int Planar = T_PLANAR(info->OutputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Planar = T_PLANAR(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 655.35 : 65535.0; cmsFloat64Number v = 0; cmsFloat32Number* swap1 = (cmsFloat32Number*)output; - int i, start = 0; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->OutputFormat); if (ExtraFirst) start = Extra; for (i = 0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; v = (cmsFloat64Number)wOut[index] / maximum; @@ -2512,24 +2573,26 @@ cmsUInt8Number* output, cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info->OutputFormat); - int DoSwap = T_DOSWAP(info->OutputFormat); - int Reverse = T_FLAVOR(info->OutputFormat); - int Extra = T_EXTRA(info->OutputFormat); - int SwapFirst = T_SWAPFIRST(info->OutputFormat); - int Planar = T_PLANAR(info->OutputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Planar = T_PLANAR(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0; cmsFloat32Number* swap1 = (cmsFloat32Number*)output; cmsFloat64Number v = 0; - int i, start = 0; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->OutputFormat); if (ExtraFirst) start = Extra; for (i = 0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; v = wOut[index] * maximum; @@ -2561,24 +2624,26 @@ cmsUInt8Number* output, cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info->OutputFormat); - int DoSwap = T_DOSWAP(info->OutputFormat); - int Reverse = T_FLAVOR(info->OutputFormat); - int Extra = T_EXTRA(info->OutputFormat); - int SwapFirst = T_SWAPFIRST(info->OutputFormat); - int Planar = T_PLANAR(info->OutputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Planar = T_PLANAR(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; cmsFloat64Number maximum = IsInkSpace(info->OutputFormat) ? 100.0 : 1.0; cmsFloat64Number v = 0; cmsFloat64Number* swap1 = (cmsFloat64Number*)output; - int i, start = 0; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->OutputFormat); if (ExtraFirst) start = Extra; for (i = 0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; v = wOut[index] * maximum; @@ -2619,6 +2684,8 @@ if (T_PLANAR(Info -> OutputFormat)) { + Stride /= PixelSize(Info->OutputFormat); + Out[0] = (cmsFloat32Number) (wOut[0] * 100.0); Out[Stride] = (cmsFloat32Number) (wOut[1] * 255.0 - 128.0); Out[Stride*2] = (cmsFloat32Number) (wOut[2] * 255.0 - 128.0); @@ -2647,6 +2714,8 @@ if (T_PLANAR(Info -> OutputFormat)) { + Stride /= PixelSize(Info->OutputFormat); + Out[0] = (cmsFloat64Number) (wOut[0] * 100.0); Out[Stride] = (cmsFloat64Number) (wOut[1] * 255.0 - 128.0); Out[Stride*2] = (cmsFloat64Number) (wOut[2] * 255.0 - 128.0); @@ -2676,6 +2745,8 @@ if (T_PLANAR(Info -> OutputFormat)) { + Stride /= PixelSize(Info->OutputFormat); + Out[0] = (cmsFloat32Number) (wOut[0] * MAX_ENCODEABLE_XYZ); Out[Stride] = (cmsFloat32Number) (wOut[1] * MAX_ENCODEABLE_XYZ); Out[Stride*2] = (cmsFloat32Number) (wOut[2] * MAX_ENCODEABLE_XYZ); @@ -2704,6 +2775,8 @@ if (T_PLANAR(Info -> OutputFormat)) { + Stride /= PixelSize(Info->OutputFormat); + Out[0] = (cmsFloat64Number) (wOut[0] * MAX_ENCODEABLE_XYZ); Out[Stride] = (cmsFloat64Number) (wOut[1] * MAX_ENCODEABLE_XYZ); Out[Stride*2] = (cmsFloat64Number) (wOut[2] * MAX_ENCODEABLE_XYZ); @@ -2735,24 +2808,26 @@ register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> InputFormat); - int DoSwap = T_DOSWAP(info ->InputFormat); - int Reverse = T_FLAVOR(info ->InputFormat); - int SwapFirst = T_SWAPFIRST(info -> InputFormat); - int Extra = T_EXTRA(info -> InputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; - int Planar = T_PLANAR(info -> InputFormat); + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info -> InputFormat); cmsFloat32Number v; - int i, start = 0; + cmsUInt32Number i, start = 0; cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 655.35F : 65535.0F; + Stride /= PixelSize(info->OutputFormat); + if (ExtraFirst) start = Extra; for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; if (Planar) v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] ); @@ -2787,24 +2862,25 @@ cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info -> InputFormat); - int DoSwap = T_DOSWAP(info ->InputFormat); - int Reverse = T_FLAVOR(info ->InputFormat); - int SwapFirst = T_SWAPFIRST(info -> InputFormat); - int Extra = T_EXTRA(info -> InputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; - int Planar = T_PLANAR(info -> InputFormat); + cmsUInt32Number nChan = T_CHANNELS(info -> InputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info ->InputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info ->InputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info -> InputFormat); + cmsUInt32Number Extra = T_EXTRA(info -> InputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number Planar = T_PLANAR(info -> InputFormat); cmsFloat32Number v; - int i, start = 0; + cmsUInt32Number i, start = 0; cmsFloat32Number maximum = IsInkSpace(info ->InputFormat) ? 100.0F : 1.0F; + Stride /= PixelSize(info->OutputFormat); if (ExtraFirst) start = Extra; for (i=0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; if (Planar) v = _cmsHalf2Float ( ((cmsUInt16Number*) accum)[(i + start) * Stride] ); @@ -2837,24 +2913,26 @@ register cmsUInt8Number* output, register cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info->OutputFormat); - int DoSwap = T_DOSWAP(info->OutputFormat); - int Reverse = T_FLAVOR(info->OutputFormat); - int Extra = T_EXTRA(info->OutputFormat); - int SwapFirst = T_SWAPFIRST(info->OutputFormat); - int Planar = T_PLANAR(info->OutputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Planar = T_PLANAR(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 655.35F : 65535.0F; cmsFloat32Number v = 0; cmsUInt16Number* swap1 = (cmsUInt16Number*)output; - int i, start = 0; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->OutputFormat); if (ExtraFirst) start = Extra; for (i = 0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; v = (cmsFloat32Number)wOut[index] / maximum; @@ -2888,24 +2966,26 @@ cmsUInt8Number* output, cmsUInt32Number Stride) { - int nChan = T_CHANNELS(info->OutputFormat); - int DoSwap = T_DOSWAP(info->OutputFormat); - int Reverse = T_FLAVOR(info->OutputFormat); - int Extra = T_EXTRA(info->OutputFormat); - int SwapFirst = T_SWAPFIRST(info->OutputFormat); - int Planar = T_PLANAR(info->OutputFormat); - int ExtraFirst = DoSwap ^ SwapFirst; + cmsUInt32Number nChan = T_CHANNELS(info->OutputFormat); + cmsUInt32Number DoSwap = T_DOSWAP(info->OutputFormat); + cmsUInt32Number Reverse = T_FLAVOR(info->OutputFormat); + cmsUInt32Number Extra = T_EXTRA(info->OutputFormat); + cmsUInt32Number SwapFirst = T_SWAPFIRST(info->OutputFormat); + cmsUInt32Number Planar = T_PLANAR(info->OutputFormat); + cmsUInt32Number ExtraFirst = DoSwap ^ SwapFirst; cmsFloat32Number maximum = IsInkSpace(info->OutputFormat) ? 100.0F : 1.0F; cmsUInt16Number* swap1 = (cmsUInt16Number*)output; cmsFloat32Number v = 0; - int i, start = 0; + cmsUInt32Number i, start = 0; + + Stride /= PixelSize(info->OutputFormat); if (ExtraFirst) start = Extra; for (i = 0; i < nChan; i++) { - int index = DoSwap ? (nChan - i - 1) : i; + cmsUInt32Number index = DoSwap ? (nChan - i - 1) : i; v = wOut[index] * maximum; @@ -2936,7 +3016,7 @@ // ---------------------------------------------------------------------------------------------------------------- -static cmsFormatters16 InputFormatters16[] = { +static const cmsFormatters16 InputFormatters16[] = { // Type Mask Function // ---------------------------- ------------------------------------ ---------------------------- @@ -3007,7 +3087,7 @@ -static cmsFormattersFloat InputFormattersFloat[] = { +static const cmsFormattersFloat InputFormattersFloat[] = { // Type Mask Function // ---------------------------- ------------------------------------ ---------------------------- @@ -3040,7 +3120,7 @@ case CMS_PACK_FLAGS_16BITS: { for (i=0; i < sizeof(InputFormatters16) / sizeof(cmsFormatters16); i++) { - cmsFormatters16* f = InputFormatters16 + i; + const cmsFormatters16* f = InputFormatters16 + i; if ((dwInput & ~f ->Mask) == f ->Type) { fr.Fmt16 = f ->Frm; @@ -3052,7 +3132,7 @@ case CMS_PACK_FLAGS_FLOAT: { for (i=0; i < sizeof(InputFormattersFloat) / sizeof(cmsFormattersFloat); i++) { - cmsFormattersFloat* f = InputFormattersFloat + i; + const cmsFormattersFloat* f = InputFormattersFloat + i; if ((dwInput & ~f ->Mask) == f ->Type) { fr.FmtFloat = f ->Frm; @@ -3070,7 +3150,7 @@ return fr; } -static cmsFormatters16 OutputFormatters16[] = { +static const cmsFormatters16 OutputFormatters16[] = { // Type Mask Function // ---------------------------- ------------------------------------ ---------------------------- @@ -3158,7 +3238,7 @@ }; -static cmsFormattersFloat OutputFormattersFloat[] = { +static const cmsFormattersFloat OutputFormattersFloat[] = { // Type Mask Function // ---------------------------- --------------------------------------------------- ---------------------------- { TYPE_Lab_FLT, ANYPLANAR|ANYEXTRA, PackLabFloatFromFloat}, @@ -3176,8 +3256,6 @@ ANYFLAVOR|ANYSWAPFIRST|ANYSWAP|ANYEXTRA|ANYCHANNELS|ANYSPACE, PackHalfFromFloat }, #endif - - }; @@ -3197,7 +3275,7 @@ case CMS_PACK_FLAGS_16BITS: { for (i=0; i < sizeof(OutputFormatters16) / sizeof(cmsFormatters16); i++) { - cmsFormatters16* f = OutputFormatters16 + i; + const cmsFormatters16* f = OutputFormatters16 + i; if ((dwInput & ~f ->Mask) == f ->Type) { fr.Fmt16 = f ->Frm; @@ -3210,7 +3288,7 @@ case CMS_PACK_FLAGS_FLOAT: { for (i=0; i < sizeof(OutputFormattersFloat) / sizeof(cmsFormattersFloat); i++) { - cmsFormattersFloat* f = OutputFormattersFloat + i; + const cmsFormattersFloat* f = OutputFormattersFloat + i; if ((dwInput & ~f ->Mask) == f ->Type) { fr.FmtFloat = f ->Frm; @@ -3319,10 +3397,10 @@ return TRUE; } -cmsFormatter _cmsGetFormatter(cmsContext ContextID, - cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 - cmsFormatterDirection Dir, - cmsUInt32Number dwFlags) +cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID, + cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 + cmsFormatterDirection Dir, + cmsUInt32Number dwFlags) { _cmsFormattersPluginChunkType* ctx = ( _cmsFormattersPluginChunkType*) _cmsContextGetClientChunk(ContextID, FormattersPlugin); cmsFormattersFactoryList* f; @@ -3350,7 +3428,7 @@ // Return whatever given formatter refers to 8 bits cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type) { - int Bytes = T_BYTES(Type); + cmsUInt32Number Bytes = T_BYTES(Type); return (Bytes == 1); } @@ -3360,9 +3438,9 @@ { cmsColorSpaceSignature ColorSpace = cmsGetColorSpace(hProfile); - cmsUInt32Number ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace); + cmsUInt32Number ColorSpaceBits = (cmsUInt32Number) _cmsLCMScolorSpace(ColorSpace); cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace); - cmsUInt32Number Float = lIsFloat ? 1 : 0; + cmsUInt32Number Float = lIsFloat ? 1U : 0; // Create a fake formatter for result return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans); @@ -3372,10 +3450,11 @@ cmsUInt32Number CMSEXPORT cmsFormatterForPCSOfProfile(cmsHPROFILE hProfile, cmsUInt32Number nBytes, cmsBool lIsFloat) { - cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile); - int ColorSpaceBits = _cmsLCMScolorSpace(ColorSpace); - cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace); - cmsUInt32Number Float = lIsFloat ? 1 : 0; + cmsColorSpaceSignature ColorSpace = cmsGetPCS(hProfile); + + cmsUInt32Number ColorSpaceBits = (cmsUInt32Number) _cmsLCMScolorSpace(ColorSpace); + cmsUInt32Number nOutputChans = cmsChannelsOf(ColorSpace); + cmsUInt32Number Float = lIsFloat ? 1U : 0; // Create a fake formatter for result return FLOAT_SH(Float) | COLORSPACE_SH(ColorSpaceBits) | BYTES_SH(nBytes) | CHANNELS_SH(nOutputChans);
--- a/src/share/native/sun/java2d/cmm/lcms/cmspcs.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmspcs.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -685,9 +685,9 @@ // This function returns a number of gridpoints to be used as LUT table. It assumes same number // of gripdpoints in all dimensions. Flags may override the choice. -int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags) +cmsUInt32Number _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags) { - int nChannels; + cmsUInt32Number nChannels; // Already specified? if (dwFlags & 0x00FF0000) { @@ -831,7 +831,7 @@ case PT_MCH14: return cmsSigMCHEData; case PT_MCH15: return cmsSigMCHFData; - default: return (cmsColorSpaceSignature) (-1); + default: return (cmsColorSpaceSignature) 0; } } @@ -898,7 +898,7 @@ case cmsSigMCHFData: case cmsSig15colorData:return PT_MCH15; - default: return (cmsColorSpaceSignature) (-1); + default: return (cmsColorSpaceSignature) 0; } }
--- a/src/share/native/sun/java2d/cmm/lcms/cmsplugin.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsplugin.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -201,14 +201,28 @@ _cmsAssert(io != NULL); - if (io -> Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1) - return FALSE; + if (io->Read(io, &tmp, sizeof(cmsUInt32Number), 1) != 1) + return FALSE; if (n != NULL) { tmp = _cmsAdjustEndianess32(tmp); - *n = *(cmsFloat32Number*) (void*) &tmp; + *n = *(cmsFloat32Number*)(void*)&tmp; + + // Safeguard which covers against absurd values + if (*n > 1E+20 || *n < -1E+20) return FALSE; + + #if defined(_MSC_VER) && _MSC_VER < 1800 + return TRUE; + #elif defined (__BORLANDC__) + return TRUE; + #else + + // fpclassify() required by C99 (only provided by MSVC >= 1800, VS2013 onwards) + return ((fpclassify(*n) == FP_ZERO) || (fpclassify(*n) == FP_NORMAL)); + #endif } + return TRUE; } @@ -222,7 +236,11 @@ if (io -> Read(io, &tmp, sizeof(cmsUInt64Number), 1) != 1) return FALSE; - if (n != NULL) _cmsAdjustEndianess64(n, &tmp); + if (n != NULL) { + + _cmsAdjustEndianess64(n, &tmp); + } + return TRUE; } @@ -237,7 +255,7 @@ return FALSE; if (n != NULL) { - *n = _cms15Fixed16toDouble(_cmsAdjustEndianess32(tmp)); + *n = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32(tmp)); } return TRUE; @@ -254,9 +272,9 @@ if (XYZ != NULL) { - XYZ->X = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.X)); - XYZ->Y = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Y)); - XYZ->Z = _cms15Fixed16toDouble(_cmsAdjustEndianess32(xyz.Z)); + XYZ->X = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.X)); + XYZ->Y = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.Y)); + XYZ->Z = _cms15Fixed16toDouble((cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) xyz.Z)); } return TRUE; } @@ -345,7 +363,7 @@ _cmsAssert(io != NULL); - tmp = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(n)); + tmp = _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(n)); if (io -> Write(io, sizeof(cmsUInt32Number), &tmp) != 1) return FALSE; @@ -359,9 +377,9 @@ _cmsAssert(io != NULL); _cmsAssert(XYZ != NULL); - xyz.X = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->X)); - xyz.Y = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Y)); - xyz.Z = _cmsAdjustEndianess32(_cmsDoubleTo15Fixed16(XYZ->Z)); + xyz.X = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->X)); + xyz.Y = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->Y)); + xyz.Z = (cmsS15Fixed16Number) _cmsAdjustEndianess32((cmsUInt32Number) _cmsDoubleTo15Fixed16(XYZ->Z)); return io -> Write(io, sizeof(cmsEncodedXYZNumber), &xyz); } @@ -519,7 +537,7 @@ return FALSE; // Truncated, which is a fatal error for us } - rc = io ->Write(io, len, Buffer); + rc = io ->Write(io, (cmsUInt32Number) len, Buffer); va_end(args); @@ -779,6 +797,30 @@ struct _cmsContext_struct* ctx; struct _cmsContext_struct fakeContext; + // See the comments regarding locking in lcms2_internal.h + // for an explanation of why we need the following code. +#ifdef CMS_IS_WINDOWS_ +#ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT + { + static HANDLE _cmsWindowsInitMutex = NULL; + static volatile HANDLE* mutex = &_cmsWindowsInitMutex; + + if (*mutex == NULL) + { + HANDLE p = CreateMutex(NULL, FALSE, NULL); + if (p && InterlockedCompareExchangePointer((void **)mutex, (void*)p, NULL) != NULL) + CloseHandle(p); + } + if (*mutex == NULL || WaitForSingleObject(*mutex, INFINITE) == WAIT_FAILED) + return NULL; + if (((void **)&_cmsContextPoolHeadMutex)[0] == NULL) + InitializeCriticalSection(&_cmsContextPoolHeadMutex); + if (*mutex == NULL || !ReleaseMutex(*mutex)) + return NULL; + } +#endif +#endif + _cmsInstallAllocFunctions(_cmsFindMemoryPlugin(Plugin), &fakeContext.DefaultMemoryManager); fakeContext.chunks[UserPtr] = UserData; @@ -805,7 +847,7 @@ ctx ->chunks[MemPlugin] = &ctx->DefaultMemoryManager; // Now we can allocate the pool by using default memory manager - ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*)); // default size about 32 pointers + ctx ->MemPool = _cmsCreateSubAlloc(ctx, 22 * sizeof(void*)); // default size about 22 pointers if (ctx ->MemPool == NULL) { cmsDeleteContext(ctx);
--- a/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsps2.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -429,7 +429,7 @@ // Does write the intent static -void EmitIntent(cmsIOHANDLER* m, int RenderingIntent) +void EmitIntent(cmsIOHANDLER* m, cmsUInt32Number RenderingIntent) { const char *intent; @@ -563,7 +563,7 @@ // Compare gamma table static -cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, int nEntries) +cmsBool GammaTableEquals(cmsUInt16Number* g1, cmsUInt16Number* g2, cmsUInt32Number nEntries) { return memcmp(g1, g2, nEntries* sizeof(cmsUInt16Number)) == 0; } @@ -572,9 +572,9 @@ // Does write a set of gamma curves static -void EmitNGamma(cmsIOHANDLER* m, int n, cmsToneCurve* g[]) +void EmitNGamma(cmsIOHANDLER* m, cmsUInt32Number n, cmsToneCurve* g[]) { - int i; + cmsUInt32Number i; for( i=0; i < n; i++ ) { @@ -797,7 +797,7 @@ static -int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, int Intent, cmsCIEXYZ* BlackPoint) +int EmitCIEBasedDEF(cmsIOHANDLER* m, cmsPipeline* Pipeline, cmsUInt32Number Intent, cmsCIEXYZ* BlackPoint) { const char* PreMaj; const char* PostMaj; @@ -857,14 +857,14 @@ // Generates a curve from a gray profile static - cmsToneCurve* ExtractGray2Y(cmsContext ContextID, cmsHPROFILE hProfile, int Intent) +cmsToneCurve* ExtractGray2Y(cmsContext ContextID, cmsHPROFILE hProfile, cmsUInt32Number Intent) { cmsToneCurve* Out = cmsBuildTabulatedToneCurve16(ContextID, 256, NULL); cmsHPROFILE hXYZ = cmsCreateXYZProfile(); cmsHTRANSFORM xform = cmsCreateTransformTHR(ContextID, hProfile, TYPE_GRAY_8, hXYZ, TYPE_XYZ_DBL, Intent, cmsFLAGS_NOOPTIMIZE); int i; - if (Out != NULL) { + if (Out != NULL && xform != NULL) { for (i=0; i < 256; i++) { cmsUInt8Number Gray = (cmsUInt8Number) i; @@ -876,8 +876,8 @@ } } - cmsDeleteTransform(xform); - cmsCloseProfile(hXYZ); + if (xform) cmsDeleteTransform(xform); + if (hXYZ) cmsCloseProfile(hXYZ); return Out; } @@ -887,7 +887,7 @@ // a more perceptually uniform space... I do choose Lab. static -int WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, int Intent, cmsUInt32Number dwFlags) +int WriteInputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags) { cmsHPROFILE hLab; cmsHTRANSFORM xform; @@ -972,7 +972,6 @@ // Does create CSA based on matrix-shaper. Allowed types are gray and RGB based - static int WriteInputMatrixShaper(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsStage* Matrix, cmsStage* Shaper) { @@ -998,17 +997,17 @@ memmove(&Mat, GetPtrToMatrix(Matrix), sizeof(Mat)); - for (i=0; i < 3; i++) - for (j=0; j < 3; j++) + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) Mat.v[i].n[j] *= MAX_ENCODEABLE_XYZ; - rc = EmitCIEBasedABC(m, (cmsFloat64Number *) &Mat, - _cmsStageGetPtrToCurveSet(Shaper), - &BlackPointAdaptedToD50); + rc = EmitCIEBasedABC(m, (cmsFloat64Number *)&Mat, + _cmsStageGetPtrToCurveSet(Shaper), + &BlackPointAdaptedToD50); } - else { + else { - cmsSignalError(m ->ContextID, cmsERROR_COLORSPACE_CHECK, "Profile is not suitable for CSA. Unsupported colorspace."); + cmsSignalError(m->ContextID, cmsERROR_COLORSPACE_CHECK, "Profile is not suitable for CSA. Unsupported colorspace."); return 0; } @@ -1021,12 +1020,12 @@ // This is a HP extension, and it works in Lab instead of XYZ static -int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, int Intent) +int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number Intent) { cmsHTRANSFORM xform; cmsHPROFILE hLab; - int i, nColors; - char ColorName[32]; + cmsUInt32Number i, nColors; + char ColorName[cmsMAX_PATH]; cmsNAMEDCOLORLIST* NamedColorList; hLab = cmsCreateLab4ProfileTHR(m ->ContextID, NULL); @@ -1304,20 +1303,20 @@ // 8 bits. static -int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, int Intent, cmsUInt32Number dwFlags) +int WriteOutputLUT(cmsIOHANDLER* m, cmsHPROFILE hProfile, cmsUInt32Number Intent, cmsUInt32Number dwFlags) { cmsHPROFILE hLab; cmsHTRANSFORM xform; - int i, nChannels; + cmsUInt32Number i, nChannels; cmsUInt32Number OutputFormat; _cmsTRANSFORM* v; cmsPipeline* DeviceLink; cmsHPROFILE Profiles[3]; cmsCIEXYZ BlackPointAdaptedToD50; - cmsBool lDoBPC = (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION); - cmsBool lFixWhite = !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP); + cmsBool lDoBPC = (cmsBool) (dwFlags & cmsFLAGS_BLACKPOINTCOMPENSATION); + cmsBool lFixWhite = (cmsBool) !(dwFlags & cmsFLAGS_NOWHITEONWHITEFIXUP); cmsUInt32Number InFrm = TYPE_Lab_16; - int RelativeEncodingIntent; + cmsUInt32Number RelativeEncodingIntent; cmsColorSpaceSignature ColorSpace; @@ -1413,10 +1412,10 @@ // Builds a ASCII string containing colorant list in 0..1.0 range static -void BuildColorantList(char *Colorant, int nColorant, cmsUInt16Number Out[]) +void BuildColorantList(char *Colorant, cmsUInt32Number nColorant, cmsUInt16Number Out[]) { char Buff[32]; - int j; + cmsUInt32Number j; Colorant[0] = 0; if (nColorant > cmsMAXCHANNELS) @@ -1438,12 +1437,12 @@ // This is a HP extension. static -int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, int Intent, cmsUInt32Number dwFlags) +int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number Intent, cmsUInt32Number dwFlags) { cmsHTRANSFORM xform; - int i, nColors, nColorant; + cmsUInt32Number i, nColors, nColorant; cmsUInt32Number OutputFormat; - char ColorName[32]; + char ColorName[cmsMAX_PATH]; char Colorant[128]; cmsNAMEDCOLORLIST* NamedColorList;
--- a/src/share/native/sun/java2d/cmm/lcms/cmssamp.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmssamp.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"),
--- a/src/share/native/sun/java2d/cmm/lcms/cmssm.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmssm.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"),
--- a/src/share/native/sun/java2d/cmm/lcms/cmstypes.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmstypes.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -89,6 +89,11 @@ // Helper macro to define a MPE handler. Callbacks do have a fixed naming convention #define TYPE_MPE_HANDLER(t, x) { (t), READ_FN(x), WRITE_FN(x), GenericMPEdup, GenericMPEfree, NULL, 0 } +// Infinites +#define MINUS_INF (-1E22F) +#define PLUS_INF (+1E22F) + + // Register a new type handler. This routine is shared between normal types and MPE. LinkedList points to the optional list head static cmsBool RegisterTypesPlugin(cmsContext id, cmsPluginBase* Data, _cmsMemoryClient pos) @@ -202,6 +207,13 @@ { cmsUInt32Number i; cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL; + cmsUInt32Number currentPosition; + + currentPosition = io->Tell(io); + + // Verify there is enough space left to read at least two cmsUInt32Number items for Count items. + if (((io->ReportedSize - currentPosition) / (2 * sizeof(cmsUInt32Number))) < Count) + return FALSE; // Let's take the offsets to each element ElementOffsets = (cmsUInt32Number *) _cmsCalloc(io ->ContextID, Count, sizeof(cmsUInt32Number)); @@ -424,8 +436,8 @@ static cmsBool SaveOneChromaticity(cmsFloat64Number x, cmsFloat64Number y, cmsIOHANDLER* io) { - if (!_cmsWriteUInt32Number(io, _cmsDoubleTo15Fixed16(x))) return FALSE; - if (!_cmsWriteUInt32Number(io, _cmsDoubleTo15Fixed16(y))) return FALSE; + if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) _cmsDoubleTo15Fixed16(x))) return FALSE; + if (!_cmsWriteUInt32Number(io, (cmsUInt32Number) _cmsDoubleTo15Fixed16(y))) return FALSE; return TRUE; } @@ -984,7 +996,7 @@ cmsBool rc = FALSE; char Filler[68]; - // Used below for writting zeroes + // Used below for writing zeroes memset(Filler, 0, sizeof(Filler)); // Get the len of string @@ -1146,7 +1158,10 @@ NewGamma = cmsBuildTabulatedToneCurve16(self ->ContextID, Count, NULL); if (!NewGamma) return NULL; - if (!_cmsReadUInt16Array(io, Count, NewGamma -> Table16)) return NULL; + if (!_cmsReadUInt16Array(io, Count, NewGamma -> Table16)) { + cmsFreeToneCurve(NewGamma); + return NULL; + } *nItems = 1; return NewGamma; @@ -1206,7 +1221,7 @@ // ******************************************************************************** -// Decide which curve type to use on writting +// Decide which curve type to use on writing static cmsTagTypeSignature DecideCurveType(cmsFloat64Number ICCVersion, const void *Data) { @@ -1599,7 +1614,7 @@ // Type cmsSigLut8Type // ******************************************************************************** -// Decide which LUT type to use on writting +// Decide which LUT type to use on writing static cmsTagTypeSignature DecideLUTtypeA2B(cmsFloat64Number ICCVersion, const void *Data) { @@ -1648,10 +1663,10 @@ // Read 8 bit tables as gamma functions static -cmsBool Read8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, int nChannels) +cmsBool Read8bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, cmsUInt32Number nChannels) { cmsUInt8Number* Temp = NULL; - int i, j; + cmsUInt32Number i, j; cmsToneCurve* Tables[cmsMAXCHANNELS]; if (nChannels > cmsMAXCHANNELS) return FALSE; @@ -1784,8 +1799,8 @@ if (!_cmsReadUInt8Number(io, NULL)) goto Error; // Do some checking - if (InputChannels > cmsMAXCHANNELS) goto Error; - if (OutputChannels > cmsMAXCHANNELS) goto Error; + if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS) goto Error; + if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error; // Allocates an empty Pipeline NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels); @@ -1842,8 +1857,10 @@ _cmsFree(self ->ContextID, Temp); Temp = NULL; - if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T))) + if (!cmsPipelineInsertStage(NewLUT, cmsAT_END, cmsStageAllocCLut16bit(self ->ContextID, CLUTpoints, InputChannels, OutputChannels, T))) { + _cmsFree(self ->ContextID, T); goto Error; + } _cmsFree(self ->ContextID, T); } @@ -1872,7 +1889,7 @@ _cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL; _cmsStageMatrixData* MatMPE = NULL; _cmsStageCLutData* clut = NULL; - int clutPoints; + cmsUInt32Number clutPoints; // Disassemble the LUT into components. mpe = NewLUT -> Elements; @@ -1992,9 +2009,10 @@ // Read 16 bit tables as gamma functions static -cmsBool Read16bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, int nChannels, int nEntries) -{ - int i; +cmsBool Read16bitTables(cmsContext ContextID, cmsIOHANDLER* io, cmsPipeline* lut, + cmsUInt32Number nChannels, cmsUInt32Number nEntries) +{ + cmsUInt32Number i; cmsToneCurve* Tables[cmsMAXCHANNELS]; // Maybe an empty table? (this is a lcms extension) @@ -2036,10 +2054,10 @@ static cmsBool Write16bitTables(cmsContext ContextID, cmsIOHANDLER* io, _cmsStageToneCurvesData* Tables) { - int j; + cmsUInt32Number j; cmsUInt32Number i; cmsUInt16Number val; - int nEntries; + cmsUInt32Number nEntries; _cmsAssert(Tables != NULL); @@ -2077,8 +2095,8 @@ if (!_cmsReadUInt8Number(io, NULL)) return NULL; // Do some checking - if (InputChannels > cmsMAXCHANNELS) goto Error; - if (OutputChannels > cmsMAXCHANNELS) goto Error; + if (InputChannels == 0 || InputChannels > cmsMAXCHANNELS) goto Error; + if (OutputChannels == 0 || OutputChannels > cmsMAXCHANNELS) goto Error; // Allocates an empty LUT NewLUT = cmsPipelineAlloc(self ->ContextID, InputChannels, OutputChannels); @@ -2160,7 +2178,7 @@ _cmsStageToneCurvesData* PreMPE = NULL, *PostMPE = NULL; _cmsStageMatrixData* MatMPE = NULL; _cmsStageCLutData* clut = NULL; - int i, InputChannels, OutputChannels, clutPoints; + cmsUInt32Number i, InputChannels, OutputChannels, clutPoints; // Disassemble the LUT into components. mpe = NewLUT -> Elements; @@ -2346,7 +2364,8 @@ // V4 stuff. Read CLUT part for LutAtoB and LutBtoA static -cmsStage* ReadCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number Offset, int InputChannels, int OutputChannels) +cmsStage* ReadCLUT(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, + cmsUInt32Number Offset, cmsUInt32Number InputChannels, cmsUInt32Number OutputChannels) { cmsUInt8Number gridPoints8[cmsMAXCHANNELS]; // Number of grid points in each dimension. cmsUInt32Number GridPoints[cmsMAXCHANNELS], i; @@ -2382,7 +2401,10 @@ for (i=0; i < Data ->nEntries; i++) { - if (io ->Read(io, &v, sizeof(cmsUInt8Number), 1) != 1) return NULL; + if (io ->Read(io, &v, sizeof(cmsUInt8Number), 1) != 1) { + cmsStageFree(CLUT); + return NULL; + } Data ->Tab.T[i] = FROM_8_TO_16(v); } @@ -2512,7 +2534,10 @@ if (!_cmsReadUInt32Number(io, &offsetC)) return NULL; if (!_cmsReadUInt32Number(io, &offsetA)) return NULL; - // Allocates an empty LUT + if (inputChan == 0 || inputChan >= cmsMAXCHANNELS) return NULL; + if (outputChan == 0 || outputChan >= cmsMAXCHANNELS) return NULL; + + // Allocates an empty LUT NewLUT = cmsPipelineAlloc(self ->ContextID, inputChan, outputChan); if (NewLUT == NULL) return NULL; @@ -2694,7 +2719,7 @@ cmsBool Type_LUTA2B_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) { cmsPipeline* Lut = (cmsPipeline*) Ptr; - int inputChan, outputChan; + cmsUInt32Number inputChan, outputChan; cmsStage *A = NULL, *B = NULL, *M = NULL; cmsStage * Matrix = NULL; cmsStage * CLUT = NULL; @@ -2742,7 +2767,7 @@ if (CLUT != NULL) { offsetC = io ->Tell(io) - BaseOffset; - if (!WriteCLUT(self, io, Lut ->SaveAs8Bits ? 1 : 2, CLUT)) return FALSE; + if (!WriteCLUT(self, io, (Lut ->SaveAs8Bits ? 1U : 2U), CLUT)) return FALSE; } if (M != NULL) { @@ -2820,6 +2845,9 @@ if (!_cmsReadUInt8Number(io, &inputChan)) return NULL; if (!_cmsReadUInt8Number(io, &outputChan)) return NULL; + if (inputChan == 0 || inputChan >= cmsMAXCHANNELS) return NULL; + if (outputChan == 0 || outputChan >= cmsMAXCHANNELS) return NULL; + // Padding if (!_cmsReadUInt16Number(io, NULL)) return NULL; @@ -2879,7 +2907,7 @@ cmsBool Type_LUTB2A_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) { cmsPipeline* Lut = (cmsPipeline*) Ptr; - int inputChan, outputChan; + cmsUInt32Number inputChan, outputChan; cmsStage *A = NULL, *B = NULL, *M = NULL; cmsStage *Matrix = NULL; cmsStage *CLUT = NULL; @@ -2921,7 +2949,7 @@ if (CLUT != NULL) { offsetC = io ->Tell(io) - BaseOffset; - if (!WriteCLUT(self, io, Lut ->SaveAs8Bits ? 1 : 2, CLUT)) return FALSE; + if (!WriteCLUT(self, io, (Lut ->SaveAs8Bits ? 1U : 2U), CLUT)) return FALSE; } if (M != NULL) { @@ -3011,7 +3039,7 @@ for (i=0; i < Count; i++) { if (io ->Read(io, Name, 32, 1) != 1) goto Error; - Name[33] = 0; + Name[32] = 0; if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error; @@ -3037,7 +3065,7 @@ cmsBool Type_ColorantTable_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) { cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr; - int i, nColors; + cmsUInt32Number i, nColors; nColors = cmsNamedColorCount(NamedColorList); @@ -3045,9 +3073,11 @@ for (i=0; i < nColors; i++) { - char root[33]; + char root[cmsMAX_PATH]; cmsUInt16Number PCS[3]; + memset(root, 0, sizeof(root)); + if (!cmsNamedColorInfo(NamedColorList, i, root, NULL, NULL, PCS, NULL)) return 0; root[32] = 0; @@ -3107,8 +3137,8 @@ cmsUInt32Number nDeviceCoords; // Num of device coordinates char prefix[32]; // Prefix for each color name char suffix[32]; // Suffix for each color name - cmsNAMEDCOLORLIST* v; - cmsUInt32Number i; + cmsNAMEDCOLORLIST* v; + cmsUInt32Number i; *nItems = 0; @@ -3129,7 +3159,7 @@ if (nDeviceCoords > cmsMAXCHANNELS) { cmsSignalError(self->ContextID, cmsERROR_RANGE, "Too many device coordinates '%d'", nDeviceCoords); - return 0; + goto Error; } for (i=0; i < count; i++) { @@ -3138,7 +3168,7 @@ char Root[33]; memset(Colorant, 0, sizeof(Colorant)); - if (io -> Read(io, Root, 32, 1) != 1) return NULL; + if (io -> Read(io, Root, 32, 1) != 1) goto Error; Root[32] = 0; // To prevent exploits if (!_cmsReadUInt16Array(io, 3, PCS)) goto Error; @@ -3165,7 +3195,7 @@ cmsNAMEDCOLORLIST* NamedColorList = (cmsNAMEDCOLORLIST*) Ptr; char prefix[33]; // Prefix for each color name char suffix[33]; // Suffix for each color name - int i, nColors; + cmsUInt32Number i, nColors; nColors = cmsNamedColorCount(NamedColorList); @@ -3185,7 +3215,7 @@ cmsUInt16Number PCS[3]; cmsUInt16Number Colorant[cmsMAXCHANNELS]; - char Root[33]; + char Root[cmsMAX_PATH]; if (!cmsNamedColorInfo(NamedColorList, i, Root, NULL, NULL, PCS, Colorant)) return 0; Root[32] = 0; @@ -3939,7 +3969,7 @@ cmsUInt16Number nSegments; cmsCurveSegment* Segments; cmsToneCurve* Curve; - cmsFloat32Number PrevBreak = -1E22F; // - infinite + cmsFloat32Number PrevBreak = MINUS_INF; // - infinite // Take signature and channels for each element. if (!_cmsReadUInt32Number(io, (cmsUInt32Number*) &ElementSig)) return NULL; @@ -3964,7 +3994,7 @@ } Segments[nSegments-1].x0 = PrevBreak; - Segments[nSegments-1].x1 = 1E22F; // A big cmsFloat32Number number + Segments[nSegments-1].x1 = PLUS_INF; // A big cmsFloat32Number number // Read segments for (i=0; i < nSegments; i++) { @@ -3998,7 +4028,7 @@ case cmsSigSampledCurveSeg: { cmsUInt32Number Count; - if (!_cmsReadUInt32Number(io, &Count)) return NULL; + if (!_cmsReadUInt32Number(io, &Count)) goto Error; Segments[i].nGridPoints = Count; Segments[i].SampledPoints = (cmsFloat32Number*) _cmsCalloc(self ->ContextID, Count, sizeof(cmsFloat32Number)); @@ -4017,7 +4047,7 @@ _cmsTagSignature2String(String, (cmsTagSignature) ElementSig); cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown curve element type '%s' found.", String); } - return NULL; + goto Error; } } @@ -4031,7 +4061,12 @@ return Curve; Error: - if (Segments) _cmsFree(self ->ContextID, Segments); + if (Segments) { + for (i=0; i < nSegments; i++) { + if (Segments[i].SampledPoints) _cmsFree(self ->ContextID, Segments[i].SampledPoints); + } + _cmsFree(self ->ContextID, Segments); + } return NULL; } @@ -4085,7 +4120,7 @@ } _cmsFree(self ->ContextID, GammaTables); - *nItems = (mpe != NULL) ? 1 : 0; + *nItems = (mpe != NULL) ? 1U : 0; return mpe; cmsUNUSED_PARAMETER(SizeOfTag); @@ -4216,9 +4251,13 @@ if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; - nElems = InputChans * OutputChans; - - // Input and output chans may be ANY (up to 0xffff) + // Input and output chans may be ANY (up to 0xffff), + // but we choose to limit to 16 channels for now + if (InputChans >= cmsMAXCHANNELS) return NULL; + if (OutputChans >= cmsMAXCHANNELS) return NULL; + + nElems = (cmsUInt32Number) InputChans * OutputChans; + Matrix = (cmsFloat64Number*) _cmsCalloc(self ->ContextID, nElems, sizeof(cmsFloat64Number)); if (Matrix == NULL) return NULL; @@ -4233,7 +4272,11 @@ cmsFloat32Number v; - if (!_cmsReadFloat32Number(io, &v)) return NULL; + if (!_cmsReadFloat32Number(io, &v)) { + _cmsFree(self ->ContextID, Matrix); + _cmsFree(self ->ContextID, Offsets); + return NULL; + } Matrix[i] = v; } @@ -4242,7 +4285,11 @@ cmsFloat32Number v; - if (!_cmsReadFloat32Number(io, &v)) return NULL; + if (!_cmsReadFloat32Number(io, &v)) { + _cmsFree(self ->ContextID, Matrix); + _cmsFree(self ->ContextID, Offsets); + return NULL; + } Offsets[i] = v; } @@ -4313,8 +4360,9 @@ goto Error; // Copy MAX_INPUT_DIMENSIONS at most. Expand to cmsUInt32Number - nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? MAX_INPUT_DIMENSIONS : InputChans; - for (i=0; i < nMaxGrids; i++) { + nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? (cmsUInt32Number) MAX_INPUT_DIMENSIONS : InputChans; + + for (i = 0; i < nMaxGrids; i++) { if (Dimensions8[i] == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least GridPoints[i] = (cmsUInt32Number)Dimensions8[i]; } @@ -4323,11 +4371,11 @@ mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL); if (mpe == NULL) goto Error; - // Read the data + // Read and sanitize the data clut = (_cmsStageCLutData*) mpe ->Data; for (i=0; i < clut ->nEntries; i++) { - if (!_cmsReadFloat32Number(io, &clut ->Tab.TFloat[i])) goto Error; + if (!_cmsReadFloat32Number(io, &clut->Tab.TFloat[i])) goto Error; } *nItems = 1; @@ -4457,6 +4505,9 @@ if (!_cmsReadUInt16Number(io, &InputChans)) return NULL; if (!_cmsReadUInt16Number(io, &OutputChans)) return NULL; + if (InputChans == 0 || InputChans >= cmsMAXCHANNELS) return NULL; + if (OutputChans == 0 || OutputChans >= cmsMAXCHANNELS) return NULL; + // Allocates an empty LUT NewLUT = cmsPipelineAlloc(self ->ContextID, InputChans, OutputChans); if (NewLUT == NULL) return NULL; @@ -4464,6 +4515,10 @@ if (!_cmsReadUInt32Number(io, &ElementCount)) goto Error; if (!ReadPositionTable(self, io, ElementCount, BaseOffset, NewLUT, ReadMPEElem)) goto Error; + // Check channel count + if (InputChans != NewLUT->InputChannels || + OutputChans != NewLUT->OutputChannels) goto Error; + // Success *nItems = 1; return NewLUT; @@ -4484,7 +4539,7 @@ cmsBool Type_MPE_Write(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, void* Ptr, cmsUInt32Number nItems) { cmsUInt32Number i, BaseOffset, DirectoryPos, CurrentPos; - int inputChan, outputChan; + cmsUInt32Number inputChan, outputChan; cmsUInt32Number ElemCount; cmsUInt32Number *ElementOffsets = NULL, *ElementSizes = NULL, Before; cmsStageSignature ElementSig; @@ -4532,7 +4587,7 @@ _cmsTagSignature2String(String, (cmsTagSignature) ElementSig); - // An unknow element was found. + // An unknown element was found. cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Found unknown MPE type '%s'", String); goto Error; } @@ -5267,38 +5322,38 @@ // This is the list of built-in types -static _cmsTagTypeLinkedList SupportedTagTypes[] = { - -{TYPE_HANDLER(cmsSigChromaticityType, Chromaticity), &SupportedTagTypes[1] }, -{TYPE_HANDLER(cmsSigColorantOrderType, ColorantOrderType), &SupportedTagTypes[2] }, -{TYPE_HANDLER(cmsSigS15Fixed16ArrayType, S15Fixed16), &SupportedTagTypes[3] }, -{TYPE_HANDLER(cmsSigU16Fixed16ArrayType, U16Fixed16), &SupportedTagTypes[4] }, -{TYPE_HANDLER(cmsSigTextType, Text), &SupportedTagTypes[5] }, -{TYPE_HANDLER(cmsSigTextDescriptionType, Text_Description), &SupportedTagTypes[6] }, -{TYPE_HANDLER(cmsSigCurveType, Curve), &SupportedTagTypes[7] }, -{TYPE_HANDLER(cmsSigParametricCurveType, ParametricCurve), &SupportedTagTypes[8] }, -{TYPE_HANDLER(cmsSigDateTimeType, DateTime), &SupportedTagTypes[9] }, -{TYPE_HANDLER(cmsSigLut8Type, LUT8), &SupportedTagTypes[10] }, -{TYPE_HANDLER(cmsSigLut16Type, LUT16), &SupportedTagTypes[11] }, -{TYPE_HANDLER(cmsSigColorantTableType, ColorantTable), &SupportedTagTypes[12] }, -{TYPE_HANDLER(cmsSigNamedColor2Type, NamedColor), &SupportedTagTypes[13] }, -{TYPE_HANDLER(cmsSigMultiLocalizedUnicodeType, MLU), &SupportedTagTypes[14] }, -{TYPE_HANDLER(cmsSigProfileSequenceDescType, ProfileSequenceDesc), &SupportedTagTypes[15] }, -{TYPE_HANDLER(cmsSigSignatureType, Signature), &SupportedTagTypes[16] }, -{TYPE_HANDLER(cmsSigMeasurementType, Measurement), &SupportedTagTypes[17] }, -{TYPE_HANDLER(cmsSigDataType, Data), &SupportedTagTypes[18] }, -{TYPE_HANDLER(cmsSigLutAtoBType, LUTA2B), &SupportedTagTypes[19] }, -{TYPE_HANDLER(cmsSigLutBtoAType, LUTB2A), &SupportedTagTypes[20] }, -{TYPE_HANDLER(cmsSigUcrBgType, UcrBg), &SupportedTagTypes[21] }, -{TYPE_HANDLER(cmsSigCrdInfoType, CrdInfo), &SupportedTagTypes[22] }, -{TYPE_HANDLER(cmsSigMultiProcessElementType, MPE), &SupportedTagTypes[23] }, -{TYPE_HANDLER(cmsSigScreeningType, Screening), &SupportedTagTypes[24] }, -{TYPE_HANDLER(cmsSigViewingConditionsType, ViewingConditions), &SupportedTagTypes[25] }, -{TYPE_HANDLER(cmsSigXYZType, XYZ), &SupportedTagTypes[26] }, -{TYPE_HANDLER(cmsCorbisBrokenXYZtype, XYZ), &SupportedTagTypes[27] }, -{TYPE_HANDLER(cmsMonacoBrokenCurveType, Curve), &SupportedTagTypes[28] }, -{TYPE_HANDLER(cmsSigProfileSequenceIdType, ProfileSequenceId), &SupportedTagTypes[29] }, -{TYPE_HANDLER(cmsSigDictType, Dictionary), &SupportedTagTypes[30] }, +static const _cmsTagTypeLinkedList SupportedTagTypes[] = { + +{TYPE_HANDLER(cmsSigChromaticityType, Chromaticity), (_cmsTagTypeLinkedList*) &SupportedTagTypes[1] }, +{TYPE_HANDLER(cmsSigColorantOrderType, ColorantOrderType), (_cmsTagTypeLinkedList*) &SupportedTagTypes[2] }, +{TYPE_HANDLER(cmsSigS15Fixed16ArrayType, S15Fixed16), (_cmsTagTypeLinkedList*) &SupportedTagTypes[3] }, +{TYPE_HANDLER(cmsSigU16Fixed16ArrayType, U16Fixed16), (_cmsTagTypeLinkedList*) &SupportedTagTypes[4] }, +{TYPE_HANDLER(cmsSigTextType, Text), (_cmsTagTypeLinkedList*) &SupportedTagTypes[5] }, +{TYPE_HANDLER(cmsSigTextDescriptionType, Text_Description), (_cmsTagTypeLinkedList*) &SupportedTagTypes[6] }, +{TYPE_HANDLER(cmsSigCurveType, Curve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[7] }, +{TYPE_HANDLER(cmsSigParametricCurveType, ParametricCurve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[8] }, +{TYPE_HANDLER(cmsSigDateTimeType, DateTime), (_cmsTagTypeLinkedList*) &SupportedTagTypes[9] }, +{TYPE_HANDLER(cmsSigLut8Type, LUT8), (_cmsTagTypeLinkedList*) &SupportedTagTypes[10] }, +{TYPE_HANDLER(cmsSigLut16Type, LUT16), (_cmsTagTypeLinkedList*) &SupportedTagTypes[11] }, +{TYPE_HANDLER(cmsSigColorantTableType, ColorantTable), (_cmsTagTypeLinkedList*) &SupportedTagTypes[12] }, +{TYPE_HANDLER(cmsSigNamedColor2Type, NamedColor), (_cmsTagTypeLinkedList*) &SupportedTagTypes[13] }, +{TYPE_HANDLER(cmsSigMultiLocalizedUnicodeType, MLU), (_cmsTagTypeLinkedList*) &SupportedTagTypes[14] }, +{TYPE_HANDLER(cmsSigProfileSequenceDescType, ProfileSequenceDesc),(_cmsTagTypeLinkedList*) &SupportedTagTypes[15] }, +{TYPE_HANDLER(cmsSigSignatureType, Signature), (_cmsTagTypeLinkedList*) &SupportedTagTypes[16] }, +{TYPE_HANDLER(cmsSigMeasurementType, Measurement), (_cmsTagTypeLinkedList*) &SupportedTagTypes[17] }, +{TYPE_HANDLER(cmsSigDataType, Data), (_cmsTagTypeLinkedList*) &SupportedTagTypes[18] }, +{TYPE_HANDLER(cmsSigLutAtoBType, LUTA2B), (_cmsTagTypeLinkedList*) &SupportedTagTypes[19] }, +{TYPE_HANDLER(cmsSigLutBtoAType, LUTB2A), (_cmsTagTypeLinkedList*) &SupportedTagTypes[20] }, +{TYPE_HANDLER(cmsSigUcrBgType, UcrBg), (_cmsTagTypeLinkedList*) &SupportedTagTypes[21] }, +{TYPE_HANDLER(cmsSigCrdInfoType, CrdInfo), (_cmsTagTypeLinkedList*) &SupportedTagTypes[22] }, +{TYPE_HANDLER(cmsSigMultiProcessElementType, MPE), (_cmsTagTypeLinkedList*) &SupportedTagTypes[23] }, +{TYPE_HANDLER(cmsSigScreeningType, Screening), (_cmsTagTypeLinkedList*) &SupportedTagTypes[24] }, +{TYPE_HANDLER(cmsSigViewingConditionsType, ViewingConditions), (_cmsTagTypeLinkedList*) &SupportedTagTypes[25] }, +{TYPE_HANDLER(cmsSigXYZType, XYZ), (_cmsTagTypeLinkedList*) &SupportedTagTypes[26] }, +{TYPE_HANDLER(cmsCorbisBrokenXYZtype, XYZ), (_cmsTagTypeLinkedList*) &SupportedTagTypes[27] }, +{TYPE_HANDLER(cmsMonacoBrokenCurveType, Curve), (_cmsTagTypeLinkedList*) &SupportedTagTypes[28] }, +{TYPE_HANDLER(cmsSigProfileSequenceIdType, ProfileSequenceId), (_cmsTagTypeLinkedList*) &SupportedTagTypes[29] }, +{TYPE_HANDLER(cmsSigDictType, Dictionary), (_cmsTagTypeLinkedList*) &SupportedTagTypes[30] }, {TYPE_HANDLER(cmsSigVcgtType, vcgt), NULL } }; @@ -5390,7 +5445,7 @@ { _cmsTagTypePluginChunkType* ctx = ( _cmsTagTypePluginChunkType*) _cmsContextGetClientChunk(ContextID, TagTypePlugin); - return GetHandler(sig, ctx->TagTypes, SupportedTagTypes); + return GetHandler(sig, ctx->TagTypes, (_cmsTagTypeLinkedList*) SupportedTagTypes); } // ******************************************************************************** @@ -5405,7 +5460,7 @@ } _cmsTagLinkedList; -// This is the list of built-in tags +// This is the list of built-in tags. The data of this list can be modified by plug-ins static _cmsTagLinkedList SupportedTags[] = { { cmsSigAToB0Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutAtoBType, cmsSigLut8Type}, DecideLUTtypeA2B}, &SupportedTags[1]}, @@ -5454,7 +5509,7 @@ { cmsSigPreview2Tag, { 1, 3, { cmsSigLut16Type, cmsSigLutBtoAType, cmsSigLut8Type }, DecideLUTtypeB2A}, &SupportedTags[32]}, { cmsSigProfileDescriptionTag, { 1, 3, { cmsSigTextDescriptionType, cmsSigMultiLocalizedUnicodeType, cmsSigTextType}, DecideTextDescType}, &SupportedTags[33]}, - { cmsSigProfileSequenceDescTag, { 1, 1, { cmsSigProfileSequenceDescType }, NULL}, &SupportedTags[34]}, + { cmsSigProfileSequenceDescTag, { 1, 1, { cmsSigProfileSequenceDescType }, NULL}, &SupportedTags[34]}, { cmsSigTechnologyTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[35]}, { cmsSigColorimetricIntentImageStateTag, { 1, 1, { cmsSigSignatureType }, NULL}, &SupportedTags[36]}, @@ -5491,10 +5546,10 @@ { cmsSigVcgtTag, { 1, 1, { cmsSigVcgtType}, NULL }, &SupportedTags[60]}, { cmsSigMetaTag, { 1, 1, { cmsSigDictType}, NULL }, &SupportedTags[61]}, { cmsSigProfileSequenceIdTag, { 1, 1, { cmsSigProfileSequenceIdType}, NULL }, &SupportedTags[62]}, + { cmsSigProfileDescriptionMLTag,{ 1, 1, { cmsSigMultiLocalizedUnicodeType}, NULL}, &SupportedTags[63]}, { cmsSigArgyllArtsTag, { 9, 1, { cmsSigS15Fixed16ArrayType}, NULL}, NULL} - }; /*
--- a/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsvirt.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -320,7 +320,7 @@ { cmsHPROFILE hICC; cmsPipeline* Pipeline; - int nChannels; + cmsUInt32Number nChannels; hICC = cmsCreateProfilePlaceholder(ContextID); if (!hICC) @@ -426,7 +426,7 @@ cmsHPROFILE hICC; cmsPipeline* LUT; cmsStage* CLUT; - int nChannels; + cmsUInt32Number nChannels; if (ColorSpace != cmsSigCmykData) { cmsSignalError(ContextID, cmsERROR_COLORSPACE_CHECK, "InkLimiting: Only CMYK currently supported"); @@ -755,13 +755,13 @@ // contrast, Saturation and white point displacement cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID, - int nLUTPoints, - cmsFloat64Number Bright, - cmsFloat64Number Contrast, - cmsFloat64Number Hue, - cmsFloat64Number Saturation, - int TempSrc, - int TempDest) + cmsUInt32Number nLUTPoints, + cmsFloat64Number Bright, + cmsFloat64Number Contrast, + cmsFloat64Number Hue, + cmsFloat64Number Saturation, + cmsUInt32Number TempSrc, + cmsUInt32Number TempDest) { cmsHPROFILE hICC; cmsPipeline* Pipeline; @@ -769,7 +769,7 @@ cmsCIExyY WhitePnt; cmsStage* CLUT; cmsUInt32Number Dimensions[MAX_INPUT_DIMENSIONS]; - int i; + cmsUInt32Number i; bchsw.Brightness = Bright; bchsw.Contrast = Contrast; @@ -807,7 +807,7 @@ for (i=0; i < MAX_INPUT_DIMENSIONS; i++) Dimensions[i] = nLUTPoints; CLUT = cmsStageAllocCLut16bitGranular(ContextID, Dimensions, 3, 3, NULL); - if (CLUT == NULL) return NULL; + if (CLUT == NULL) goto Error; if (!cmsStageSampleCLut16bit(CLUT, bchswSampler, (void*) &bchsw, 0)) { @@ -840,13 +840,13 @@ } -CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(int nLUTPoints, +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(cmsUInt32Number nLUTPoints, cmsFloat64Number Bright, cmsFloat64Number Contrast, cmsFloat64Number Hue, cmsFloat64Number Saturation, - int TempSrc, - int TempDest) + cmsUInt32Number TempSrc, + cmsUInt32Number TempDest) { return cmsCreateBCHSWabstractProfileTHR(NULL, nLUTPoints, Bright, Contrast, Hue, Saturation, TempSrc, TempDest); } @@ -859,8 +859,10 @@ cmsHPROFILE hProfile; cmsPipeline* LUT = NULL; cmsStage* PostLin; - cmsToneCurve* EmptyTab; + cmsStage* OutLin; + cmsToneCurve* EmptyTab[3]; cmsUInt16Number Zero[2] = { 0, 0 }; + const cmsFloat64Number PickLstarMatrix[] = { 1, 0, 0 }; hProfile = cmsCreateProfilePlaceholder(ContextID); if (!hProfile) // can't allocate @@ -871,22 +873,28 @@ if (!SetTextTags(hProfile, L"NULL profile built-in")) goto Error; - cmsSetDeviceClass(hProfile, cmsSigOutputClass); cmsSetColorSpace(hProfile, cmsSigGrayData); cmsSetPCS(hProfile, cmsSigLabData); - // An empty LUTs is all we need - LUT = cmsPipelineAlloc(ContextID, 1, 1); + // Create a valid ICC 4 structure + LUT = cmsPipelineAlloc(ContextID, 3, 1); if (LUT == NULL) goto Error; - EmptyTab = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero); - PostLin = cmsStageAllocToneCurves(ContextID, 1, &EmptyTab); - cmsFreeToneCurve(EmptyTab); + EmptyTab[0] = EmptyTab[1] = EmptyTab[2] = cmsBuildTabulatedToneCurve16(ContextID, 2, Zero); + PostLin = cmsStageAllocToneCurves(ContextID, 3, EmptyTab); + OutLin = cmsStageAllocToneCurves(ContextID, 1, EmptyTab); + cmsFreeToneCurve(EmptyTab[0]); if (!cmsPipelineInsertStage(LUT, cmsAT_END, PostLin)) goto Error; + if (!cmsPipelineInsertStage(LUT, cmsAT_END, cmsStageAllocMatrix(ContextID, 1, 3, PickLstarMatrix, NULL))) + goto Error; + + if (!cmsPipelineInsertStage(LUT, cmsAT_END, OutLin)) + goto Error; + if (!cmsWriteTag(hProfile, cmsSigBToA0Tag, (void*) LUT)) goto Error; if (!cmsWriteTag(hProfile, cmsSigMediaWhitePointTag, cmsD50_XYZ())) goto Error; @@ -967,7 +975,7 @@ { _cmsTRANSFORM* v = (_cmsTRANSFORM*) xform; cmsHPROFILE hICC = NULL; - int i, nColors; + cmsUInt32Number i, nColors; cmsNAMEDCOLORLIST *nc2 = NULL, *Original = NULL; // Create an empty placeholder @@ -1084,7 +1092,7 @@ { cmsHPROFILE hProfile = NULL; cmsUInt32Number FrmIn, FrmOut, ChansIn, ChansOut; - cmsUInt32Number ColorSpaceBitsIn, ColorSpaceBitsOut; + int ColorSpaceBitsIn, ColorSpaceBitsOut; _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform; cmsPipeline* LUT = NULL; cmsStage* mpe;
--- a/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmswtpnt.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -105,7 +105,6 @@ } // Obtain y(x) - y = -3.000*(x*x) + 2.870*x - 0.275; // wave factors (not used, but here for futures extensions) @@ -131,7 +130,7 @@ } ISOTEMPERATURE; -static ISOTEMPERATURE isotempdata[] = { +static const ISOTEMPERATURE isotempdata[] = { // {Mirek, Ut, Vt, Tt } {0, 0.18006, 0.26352, -0.24341}, {10, 0.18066, 0.26589, -0.25479}, @@ -295,7 +294,7 @@ // Build a White point, primary chromas transfer matrix from RGB to CIE XYZ // This is just an approximation, I am not handling all the non-linear // aspects of the RGB to XYZ process, and assumming that the gamma correction -// has transitive property in the tranformation chain. +// has transitive property in the transformation chain. // // the alghoritm: //
--- a/src/share/native/sun/java2d/cmm/lcms/cmsxform.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/cmsxform.c Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -284,6 +284,8 @@ strideIn = 0; strideOut = 0; + memset(fIn, 0, sizeof(fIn)); + memset(fOut, 0, sizeof(fIn)); for (i = 0; i < LineCount; i++) { @@ -348,6 +350,7 @@ strideIn = 0; strideOut = 0; + memset(fIn, 0, sizeof(fIn)); for (i = 0; i < LineCount; i++) { @@ -385,6 +388,7 @@ strideIn = 0; strideOut = 0; + memset(wIn, 0, sizeof(wIn)); for (i = 0; i < LineCount; i++) { @@ -422,6 +426,8 @@ strideIn = 0; strideOut = 0; + memset(wIn, 0, sizeof(wIn)); + memset(wOut, 0, sizeof(wOut)); for (i = 0; i < LineCount; i++) { @@ -483,6 +489,8 @@ strideIn = 0; strideOut = 0; + memset(wIn, 0, sizeof(wIn)); + memset(wOut, 0, sizeof(wOut)); for (i = 0; i < LineCount; i++) { @@ -790,7 +798,10 @@ // Allocate needed memory _cmsTRANSFORM* p = (_cmsTRANSFORM*)_cmsMallocZero(ContextID, sizeof(_cmsTRANSFORM)); - if (!p) return NULL; + if (!p) { + cmsPipelineFree(lut); + return NULL; + } // Store the proposed pipeline p->Lut = lut; @@ -823,7 +834,7 @@ p->FromInputFloat = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_FLOAT).FmtFloat; p->ToOutputFloat = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_FLOAT).FmtFloat; - // Save the day? + // Save the day? (Ignore the warning) if (Plugin->OldXform) { p->OldXform = (_cmsTransformFn) p->xform; p->xform = _cmsTransform2toTransformAdaptor; @@ -848,7 +859,7 @@ if (p ->FromInputFloat == NULL || p ->ToOutputFloat == NULL) { cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format"); - _cmsFree(ContextID, p); + cmsDeleteTransform(p); return NULL; } @@ -870,7 +881,7 @@ } else { - int BytesPerPixelInput; + cmsUInt32Number BytesPerPixelInput; p ->FromInput = _cmsGetFormatter(ContextID, *InputFormat, cmsFormatterInput, CMS_PACK_FLAGS_16BITS).Fmt16; p ->ToOutput = _cmsGetFormatter(ContextID, *OutputFormat, cmsFormatterOutput, CMS_PACK_FLAGS_16BITS).Fmt16; @@ -878,7 +889,7 @@ if (p ->FromInput == NULL || p ->ToOutput == NULL) { cmsSignalError(ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unsupported raster format"); - _cmsFree(ContextID, p); + cmsDeleteTransform(p); return NULL; } @@ -920,13 +931,13 @@ } static -cmsBool GetXFormColorSpaces(int nProfiles, cmsHPROFILE hProfiles[], cmsColorSpaceSignature* Input, cmsColorSpaceSignature* Output) +cmsBool GetXFormColorSpaces(cmsUInt32Number nProfiles, cmsHPROFILE hProfiles[], cmsColorSpaceSignature* Input, cmsColorSpaceSignature* Output) { cmsColorSpaceSignature ColorSpaceIn, ColorSpaceOut; cmsColorSpaceSignature PostColorSpace; - int i; + cmsUInt32Number i; - if (nProfiles <= 0) return FALSE; + if (nProfiles == 0) return FALSE; if (hProfiles[0] == NULL) return FALSE; *Input = PostColorSpace = cmsGetColorSpace(hProfiles[0]); @@ -975,7 +986,7 @@ static cmsBool IsProperColorSpace(cmsColorSpaceSignature Check, cmsUInt32Number dwFormat) { - int Space1 = T_COLORSPACE(dwFormat); + int Space1 = (int) T_COLORSPACE(dwFormat); int Space2 = _cmsLCMScolorSpace(Check); if (Space1 == PT_ANY) return TRUE; @@ -1231,7 +1242,7 @@ hArray[0] = Input; hArray[1] = Output; - return cmsCreateMultiprofileTransformTHR(ContextID, hArray, Output == NULL ? 1 : 2, InputFormat, OutputFormat, Intent, dwFlags); + return cmsCreateMultiprofileTransformTHR(ContextID, hArray, Output == NULL ? 1U : 2U, InputFormat, OutputFormat, Intent, dwFlags); } CMSAPI cmsHTRANSFORM CMSEXPORT cmsCreateTransform(cmsHPROFILE Input,
--- a/src/share/native/sun/java2d/cmm/lcms/lcms2.h Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/lcms2.h Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -52,7 +52,7 @@ // //--------------------------------------------------------------------------------- // -// Version 2.8 +// Version 2.9rc3 // #ifndef _lcms2_H @@ -78,7 +78,7 @@ // #define CMS_USE_CPP_API // Uncomment this line if you need strict CGATS syntax. Makes CGATS files to -// require "KEYWORD" on undefined identifiers, keep it comented out unless needed +// require "KEYWORD" on undefined identifiers, keep it commented out unless needed // #define CMS_STRICT_CGATS 1 // Uncomment to get rid of the tables for "half" float support @@ -87,6 +87,9 @@ // Uncomment to get rid of pthreads/windows dependency // #define CMS_NO_PTHREADS 1 +// Uncomment this for special windows mutex initialization (see lcms2_internal.h) +// #define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT + // ********** End of configuration toggles ****************************** // Needed for streams @@ -104,7 +107,7 @@ #endif // Version/release -#define LCMS_VERSION 2080 +#define LCMS_VERSION 2090 // I will give the chance of redefining basic types for compilers that are not fully C99 compliant #ifndef CMS_BASIC_TYPES_ALREADY_DEFINED @@ -254,16 +257,21 @@ # define CMSAPI __declspec(dllexport) # else # define CMSAPI __declspec(dllimport) -# endif +# endif # endif # else -# define CMSEXPORT -# define CMSAPI +# define CMSEXPORT +# define CMSAPI # endif -#else -# define CMSEXPORT -# define CMSAPI -#endif +#else // not Windows +# ifdef HAVE_FUNC_ATTRIBUTE_VISIBILITY +# define CMSEXPORT +# define CMSAPI __attribute__((visibility("default"))) +# else +# define CMSEXPORT +# define CMSAPI +# endif +#endif // CMS_IS_WINDOWS_ #ifdef HasTHREADS # if HasTHREADS == 1 @@ -284,9 +292,9 @@ #endif // D50 XYZ normalized to Y=1.0 -#define cmsD50X 0.9642 -#define cmsD50Y 1.0 -#define cmsD50Z 0.8249 +#define cmsD50X 0.9642 +#define cmsD50Y 1.0 +#define cmsD50Z 0.8249 // V4 perceptual black #define cmsPERCEPTUAL_BLACK_X 0.00336 @@ -294,8 +302,8 @@ #define cmsPERCEPTUAL_BLACK_Z 0.00287 // Definitions in ICC spec -#define cmsMagicNumber 0x61637370 // 'acsp' -#define lcmsSignature 0x6c636d73 // 'lcms' +#define cmsMagicNumber 0x61637370 // 'acsp' +#define lcmsSignature 0x6c636d73 // 'lcms' // Base ICC type definitions @@ -1154,7 +1162,7 @@ cmsCIEXYZ whitePoint; cmsFloat64Number Yb; cmsFloat64Number La; - int surround; + cmsUInt32Number surround; cmsFloat64Number D_value; } cmsViewingConditions; @@ -1182,16 +1190,16 @@ // The internal representation is none of your business. typedef struct _cms_curve_struct cmsToneCurve; -CMSAPI cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID, cmsInt32Number nSegments, const cmsCurveSegment Segments[]); +CMSAPI cmsToneCurve* CMSEXPORT cmsBuildSegmentedToneCurve(cmsContext ContextID, cmsUInt32Number nSegments, const cmsCurveSegment Segments[]); CMSAPI cmsToneCurve* CMSEXPORT cmsBuildParametricToneCurve(cmsContext ContextID, cmsInt32Number Type, const cmsFloat64Number Params[]); CMSAPI cmsToneCurve* CMSEXPORT cmsBuildGamma(cmsContext ContextID, cmsFloat64Number Gamma); -CMSAPI cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurve16(cmsContext ContextID, cmsInt32Number nEntries, const cmsUInt16Number values[]); +CMSAPI cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurve16(cmsContext ContextID, cmsUInt32Number nEntries, const cmsUInt16Number values[]); CMSAPI cmsToneCurve* CMSEXPORT cmsBuildTabulatedToneCurveFloat(cmsContext ContextID, cmsUInt32Number nEntries, const cmsFloat32Number values[]); CMSAPI void CMSEXPORT cmsFreeToneCurve(cmsToneCurve* Curve); CMSAPI void CMSEXPORT cmsFreeToneCurveTriple(cmsToneCurve* Curve[3]); CMSAPI cmsToneCurve* CMSEXPORT cmsDupToneCurve(const cmsToneCurve* Src); CMSAPI cmsToneCurve* CMSEXPORT cmsReverseToneCurve(const cmsToneCurve* InGamma); -CMSAPI cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsInt32Number nResultSamples, const cmsToneCurve* InGamma); +CMSAPI cmsToneCurve* CMSEXPORT cmsReverseToneCurveEx(cmsUInt32Number nResultSamples, const cmsToneCurve* InGamma); CMSAPI cmsToneCurve* CMSEXPORT cmsJoinToneCurve(cmsContext ContextID, const cmsToneCurve* X, const cmsToneCurve* Y, cmsUInt32Number nPoints); CMSAPI cmsBool CMSEXPORT cmsSmoothToneCurve(cmsToneCurve* Tab, cmsFloat64Number lambda); CMSAPI cmsFloat32Number CMSEXPORT cmsEvalToneCurveFloat(const cmsToneCurve* Curve, cmsFloat32Number v); @@ -1236,7 +1244,7 @@ // Where to place/locate the stages in the pipeline chain typedef enum { cmsAT_BEGIN, cmsAT_END } cmsStageLoc; -CMSAPI int CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage* mpe); +CMSAPI cmsBool CMSEXPORT cmsPipelineInsertStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage* mpe); CMSAPI void CMSEXPORT cmsPipelineUnlinkStage(cmsPipeline* lut, cmsStageLoc loc, cmsStage** mpe); // This function is quite useful to analyze the structure of a Pipeline and retrieve the Stage elements @@ -1459,7 +1467,7 @@ CMSAPI cmsTagSignature CMSEXPORT cmsTagLinkedTo(cmsHPROFILE hProfile, cmsTagSignature sig); // Read and write raw data -CMSAPI cmsInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* Buffer, cmsUInt32Number BufferSize); +CMSAPI cmsUInt32Number CMSEXPORT cmsReadRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, void* Buffer, cmsUInt32Number BufferSize); CMSAPI cmsBool CMSEXPORT cmsWriteRawTag(cmsHPROFILE hProfile, cmsTagSignature sig, const void* data, cmsUInt32Number Size); // Access header data @@ -1550,7 +1558,7 @@ CMSAPI cmsBool CMSEXPORT cmsMD5computeID(cmsHPROFILE hProfile); -// Profile high level funtions ------------------------------------------------------------------------------------------ +// Profile high level functions ------------------------------------------------------------------------------------------ CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromFile(const char *ICCProfile, const char *sAccess); CMSAPI cmsHPROFILE CMSEXPORT cmsOpenProfileFromFileTHR(cmsContext ContextID, const char *ICCProfile, const char *sAccess); @@ -1610,21 +1618,21 @@ CMSAPI cmsHPROFILE CMSEXPORT cmsCreate_sRGBProfile(void); CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfileTHR(cmsContext ContextID, - int nLUTPoints, + cmsUInt32Number nLUTPoints, cmsFloat64Number Bright, cmsFloat64Number Contrast, cmsFloat64Number Hue, cmsFloat64Number Saturation, - int TempSrc, - int TempDest); + cmsUInt32Number TempSrc, + cmsUInt32Number TempDest); -CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(int nLUTPoints, +CMSAPI cmsHPROFILE CMSEXPORT cmsCreateBCHSWabstractProfile(cmsUInt32Number nLUTPoints, cmsFloat64Number Bright, cmsFloat64Number Contrast, cmsFloat64Number Hue, cmsFloat64Number Saturation, - int TempSrc, - int TempDest); + cmsUInt32Number TempSrc, + cmsUInt32Number TempDest); CMSAPI cmsHPROFILE CMSEXPORT cmsCreateNULLProfileTHR(cmsContext ContextID); CMSAPI cmsHPROFILE CMSEXPORT cmsCreateNULLProfile(void); @@ -1666,7 +1674,7 @@ #define cmsFLAGS_BLACKPOINTCOMPENSATION 0x2000 #define cmsFLAGS_NOWHITEONWHITEFIXUP 0x0004 // Don't fix scum dot #define cmsFLAGS_HIGHRESPRECALC 0x0400 // Use more memory to give better accurancy -#define cmsFLAGS_LOWRESPRECALC 0x0800 // Use less memory to minimize resouces +#define cmsFLAGS_LOWRESPRECALC 0x0800 // Use less memory to minimize resources // For devicelink creation #define cmsFLAGS_8BITS_DEVICELINK 0x0008 // Create 8 bits devicelinks
--- a/src/share/native/sun/java2d/cmm/lcms/lcms2_internal.h Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/lcms2_internal.h Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -106,7 +106,7 @@ // Maximum of channels for internal pipeline evaluation #define MAX_STAGE_CHANNELS 128 -// Unused parameter warning supression +// Unused parameter warning suppression #define cmsUNUSED_PARAMETER(x) ((void)x) // The specification for "inline" is section 6.7.4 of the C99 standard (ISO/IEC 9899:1999). @@ -125,9 +125,17 @@ # ifndef vsnprintf # define vsnprintf _vsnprintf # endif + +/// Properly define some macros to accommodate +/// older MSVC versions. +# if _MSC_VER <= 1700 + #include <float.h> + #define isnan _isnan + #define isinf(x) (!_finite((x))) +# endif + #endif - // A fast way to convert from/to 16 <-> 8 bits #define FROM_8_TO_16(rgb) (cmsUInt16Number) ((((cmsUInt16Number) (rgb)) << 8)|(rgb)) #define FROM_16_TO_8(rgb) (cmsUInt8Number) ((((cmsUInt32Number)(rgb) * 65281U + 8388608U) >> 24) & 0xFFU) @@ -201,19 +209,48 @@ return _cmsQuickFloorWord(d); } +// Test bed entry points--------------------------------------------------------------- +#define CMSCHECKPOINT CMSAPI // Pthread support -------------------------------------------------------------------- #ifndef CMS_NO_PTHREADS // This is the threading support. Unfortunately, it has to be platform-dependent because // windows does not support pthreads. - #ifdef CMS_IS_WINDOWS_ #define WIN32_LEAN_AND_MEAN 1 #include <windows.h> +// The locking scheme in LCMS requires a single 'top level' mutex +// to work. This is actually implemented on Windows as a +// CriticalSection, because they are lighter weight. With +// pthreads, this is statically inited. Unfortunately, windows +// can't officially statically init critical sections. +// +// We can work around this in 2 ways. +// +// 1) We can use a proper mutex purely to protect the init +// of the CriticalSection. This in turns requires us to protect +// the Mutex creation, which we can do using the snappily +// named InterlockedCompareExchangePointer API (present on +// windows XP and above). +// +// 2) In cases where we want to work on pre-Windows XP, we +// can use an even more horrible hack described below. +// +// So why wouldn't we always use 2)? Because not calling +// the init function for a critical section means it fails +// testing with ApplicationVerifier (and presumably similar +// tools). +// +// We therefore default to 1, and people who want to be able +// to run on pre-Windows XP boxes can build with: +// CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT +// defined. This is automatically set for builds using +// versions of MSVC that don't have this API available. +// // From: http://locklessinc.com/articles/pthreads_on_windows/ // The pthreads API has an initialization macro that has no correspondence to anything in // the windows API. By investigating the internal definition of the critical section type, @@ -235,14 +272,30 @@ typedef CRITICAL_SECTION _cmsMutex; -#define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0} - #ifdef _MSC_VER # if (_MSC_VER >= 1800) # pragma warning(disable : 26135) # endif #endif +#ifndef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT +// If we are building with a version of MSVC smaller +// than 1400 (i.e. before VS2005) then we don't have +// the InterlockedCompareExchangePointer API, so use +// the old version. +# ifdef _MSC_VER +# if _MSC_VER < 1400 +# define CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT +# endif +# endif +#endif + +#ifdef CMS_RELY_ON_WINDOWS_STATIC_MUTEX_INIT +# define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG) -1,-1,0,0,0,0} +#else +# define CMS_MUTEX_INITIALIZER {(PRTL_CRITICAL_SECTION_DEBUG)NULL,-1,0,0,0,0} +#endif + cmsINLINE int _cmsLockPrimitive(_cmsMutex *m) { EnterCriticalSection(m); @@ -478,7 +531,7 @@ void* chunks[MemoryClientMax]; // array of pointers to client chunks. Memory itself is hold in the suballocator. // If NULL, then it reverts to global Context0 - _cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overriden + _cmsMemPluginChunkType DefaultMemoryManager; // The allocators used for creating the context itself. Cannot be overridden }; // Returns a pointer to a valid context structure, including the global one if id is zero. @@ -800,10 +853,10 @@ // Interpolation --------------------------------------------------------------------------------------------------------- -cmsInterpParams* _cmsComputeInterpParams(cmsContext ContextID, int nSamples, int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags); -cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], int InputChan, int OutputChan, const void* Table, cmsUInt32Number dwFlags); -void _cmsFreeInterpParams(cmsInterpParams* p); -cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p); +CMSCHECKPOINT cmsInterpParams* CMSEXPORT _cmsComputeInterpParams(cmsContext ContextID, cmsUInt32Number nSamples, cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags); +cmsInterpParams* _cmsComputeInterpParamsEx(cmsContext ContextID, const cmsUInt32Number nSamples[], cmsUInt32Number InputChan, cmsUInt32Number OutputChan, const void* Table, cmsUInt32Number dwFlags); +CMSCHECKPOINT void CMSEXPORT _cmsFreeInterpParams(cmsInterpParams* p); +cmsBool _cmsSetInterpolationRoutine(cmsContext ContextID, cmsInterpParams* p); // Curves ---------------------------------------------------------------------------------------------------------------- @@ -853,20 +906,20 @@ // Special Stages (cannot be saved) -cmsStage* _cmsStageAllocLab2XYZ(cmsContext ContextID); -cmsStage* _cmsStageAllocXYZ2Lab(cmsContext ContextID); -cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID); -cmsStage* _cmsStageAllocLabV2ToV4(cmsContext ContextID); -cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID); -cmsStage* _cmsStageAllocLabV4ToV2(cmsContext ContextID); -cmsStage* _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS); -cmsStage* _cmsStageAllocIdentityCurves(cmsContext ContextID, int nChannels); -cmsStage* _cmsStageAllocIdentityCLut(cmsContext ContextID, int nChan); -cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID); -cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID); -cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID); -cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID); -cmsStage* _cmsStageClipNegatives(cmsContext ContextID, int nChannels); +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLab2XYZ(cmsContext ContextID); +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocXYZ2Lab(cmsContext ContextID); +cmsStage* _cmsStageAllocLabPrelin(cmsContext ContextID); +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV2ToV4(cmsContext ContextID); +cmsStage* _cmsStageAllocLabV2ToV4curves(cmsContext ContextID); +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocLabV4ToV2(cmsContext ContextID); +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocNamedColor(cmsNAMEDCOLORLIST* NamedColorList, cmsBool UsePCS); +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCurves(cmsContext ContextID, cmsUInt32Number nChannels); +CMSCHECKPOINT cmsStage* CMSEXPORT _cmsStageAllocIdentityCLut(cmsContext ContextID, cmsUInt32Number nChan); +cmsStage* _cmsStageNormalizeFromLabFloat(cmsContext ContextID); +cmsStage* _cmsStageNormalizeFromXyzFloat(cmsContext ContextID); +cmsStage* _cmsStageNormalizeToLabFloat(cmsContext ContextID); +cmsStage* _cmsStageNormalizeToXyzFloat(cmsContext ContextID); +cmsStage* _cmsStageClipNegatives(cmsContext ContextID, cmsUInt32Number nChannels); // For curve set only @@ -901,9 +954,9 @@ // Read tags using low-level function, provide necessary glue code to adapt versions, etc. All those return a brand new copy // of the LUTS, since ownership of original is up to the profile. The user should free allocated resources. -cmsPipeline* _cmsReadInputLUT(cmsHPROFILE hProfile, int Intent); -cmsPipeline* _cmsReadOutputLUT(cmsHPROFILE hProfile, int Intent); -cmsPipeline* _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, int Intent); +CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadInputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent); +CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadOutputLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent); +CMSCHECKPOINT cmsPipeline* CMSEXPORT _cmsReadDevicelinkLUT(cmsHPROFILE hProfile, cmsUInt32Number Intent); // Special values cmsBool _cmsReadMediaWhitePoint(cmsCIEXYZ* Dest, cmsHPROFILE hProfile); @@ -928,8 +981,9 @@ // LUT optimization ------------------------------------------------------------------------------------------------ -cmsUInt16Number _cmsQuantizeVal(cmsFloat64Number i, int MaxSamples); -int _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags); +CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsQuantizeVal(cmsFloat64Number i, cmsUInt32Number MaxSamples); + +cmsUInt32Number _cmsReasonableGridpointsByColorspace(cmsColorSpaceSignature Colorspace, cmsUInt32Number dwFlags); cmsBool _cmsEndPointsBySpace(cmsColorSpaceSignature Space, cmsUInt16Number **White, @@ -938,7 +992,7 @@ cmsBool _cmsOptimizePipeline(cmsContext ContextID, cmsPipeline** Lut, - int Intent, + cmsUInt32Number Intent, cmsUInt32Number* InputFormat, cmsUInt32Number* OutputFormat, cmsUInt32Number* dwFlags ); @@ -962,17 +1016,17 @@ cmsBool _cmsFormatterIsFloat(cmsUInt32Number Type); cmsBool _cmsFormatterIs8bit(cmsUInt32Number Type); -cmsFormatter _cmsGetFormatter(cmsContext ContextID, - cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 - cmsFormatterDirection Dir, - cmsUInt32Number dwFlags); +CMSCHECKPOINT cmsFormatter CMSEXPORT _cmsGetFormatter(cmsContext ContextID, + cmsUInt32Number Type, // Specific type, i.e. TYPE_RGB_8 + cmsFormatterDirection Dir, + cmsUInt32Number dwFlags); #ifndef CMS_NO_HALF_SUPPORT // Half float -cmsFloat32Number _cmsHalf2Float(cmsUInt16Number h); -cmsUInt16Number _cmsFloat2Half(cmsFloat32Number flt); +CMSCHECKPOINT cmsFloat32Number CMSEXPORT _cmsHalf2Float(cmsUInt16Number h); +CMSCHECKPOINT cmsUInt16Number CMSEXPORT _cmsFloat2Half(cmsFloat32Number flt); #endif
--- a/src/share/native/sun/java2d/cmm/lcms/lcms2_plugin.h Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/java2d/cmm/lcms/lcms2_plugin.h Fri May 25 01:50:25 2018 +0100 @@ -30,7 +30,7 @@ //--------------------------------------------------------------------------------- // // Little Color Management System -// Copyright (c) 1998-2016 Marti Maria Saguer +// Copyright (c) 1998-2017 Marti Maria Saguer // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the "Software"), @@ -347,7 +347,7 @@ // Parametric curves. A negative type means same function but analytically inverted. Max. number of params is 10 -// Evaluator callback for user-suplied parametric curves. May implement more than one type +// Evaluator callback for user-supplied parametric curves. May implement more than one type typedef cmsFloat64Number (* cmsParametricCurveEvaluator)(cmsInt32Number Type, const cmsFloat64Number Params[10], cmsFloat64Number R); // Plug-in may implement an arbitrary number of parametric curves @@ -457,7 +457,7 @@ cmsUInt32Number nSupportedTypes; // In how many types this tag can come (MAX_TYPES_IN_LCMS_PLUGIN maximum) cmsTagTypeSignature SupportedTypes[MAX_TYPES_IN_LCMS_PLUGIN]; - // For writting + // For writing cmsTagTypeSignature (* DecideType)(cmsFloat64Number ICCVersion, const void *Data); } cmsTagDescriptor;
--- a/src/share/native/sun/misc/VM.c Mon Apr 30 19:04:05 2018 +0100 +++ b/src/share/native/sun/misc/VM.c Fri May 25 01:50:25 2018 +0100 @@ -112,7 +112,7 @@ } JNIEXPORT jobject JNICALL -Java_sun_misc_VM_latestUserDefinedLoader(JNIEnv *env, jclass cls) { +Java_sun_misc_VM_latestUserDefinedLoader0(JNIEnv *env, jclass cls) { return JVM_LatestUserDefinedLoader(env); }
--- a/src/solaris/classes/sun/awt/X11/XMouseInfoPeer.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/solaris/classes/sun/awt/X11/XMouseInfoPeer.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,10 @@ package sun.awt.X11; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; import java.awt.Point; import java.awt.Window; -import java.awt.GraphicsEnvironment; -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; import java.awt.peer.MouseInfoPeer; import sun.awt.X11GraphicsDevice; @@ -83,14 +82,15 @@ } public boolean isWindowUnderMouse(Window w) { - + if (w == null) { + return false; + } + XWindow peer = (XWindow) w.getPeer(); + if (peer == null) { + return false; + } long display = XToolkit.getDisplay(); - - // java.awt.Component.findUnderMouseInWindow checks that - // the peer is non-null by checking that the component - // is showing. - - long contentWindow = ((XWindow)w.getPeer()).getContentWindow(); + long contentWindow = peer.getContentWindow(); long parent = XlibUtil.getParentWindow(contentWindow); XToolkit.awtLock();
--- a/src/windows/classes/sun/awt/windows/ThemeReader.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/windows/classes/sun/awt/windows/ThemeReader.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2017, 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 @@ -61,6 +61,7 @@ private static final Lock readLock = readWriteLock.readLock(); private static final Lock writeLock = readWriteLock.writeLock(); private static volatile boolean valid = false; + private static volatile boolean isThemed; static volatile boolean xpStyleEnabled; @@ -70,7 +71,17 @@ valid = false; } - public static native boolean isThemed(); + private static native boolean initThemes(); + + public static boolean isThemed() { + writeLock.lock(); + try { + isThemed = initThemes(); + return isThemed; + } finally { + writeLock.unlock(); + } + } public static boolean isXPStyleEnabled() { return xpStyleEnabled; @@ -98,6 +109,9 @@ // returns theme value // this method should be invoked with readLock locked private static Long getTheme(String widget) { + if (!isThemed) { + throw new IllegalStateException("Themes are not loaded"); + } if (!valid) { readLock.unlock(); writeLock.lock();
--- a/src/windows/classes/sun/awt/windows/WInputMethod.java Mon Apr 30 19:04:05 2018 +0100 +++ b/src/windows/classes/sun/awt/windows/WInputMethod.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, 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 @@ -584,6 +584,9 @@ Component client = getClientComponent(); if (client != null) { + if (!client.isShowing()) { + return; + } if (haveActiveClient()) { Rectangle rc = inputContext.getTextLocation(TextHitInfo.leading(0)); x = rc.x;
--- a/src/windows/native/sun/windows/MouseInfo.cpp Mon Apr 30 19:04:05 2018 +0100 +++ b/src/windows/native/sun/windows/MouseInfo.cpp Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, 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 @@ -48,6 +48,7 @@ } jobject winPeer = AwtObject::GetPeerForTarget(env, window); + CHECK_NULL_RETURN(winPeer, JNI_FALSE); PDATA pData; pData = JNI_GET_PDATA(winPeer); env->DeleteLocalRef(winPeer);
--- a/src/windows/native/sun/windows/ThemeReader.cpp Mon Apr 30 19:04:05 2018 +0100 +++ b/src/windows/native/sun/windows/ThemeReader.cpp Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2017, 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 @@ -225,7 +225,7 @@ return FALSE; } -JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_isThemed +JNIEXPORT jboolean JNICALL Java_sun_awt_windows_ThemeReader_initThemes (JNIEnv *env, jclass klass) { static BOOL TryLoadingThemeLib = FALSE; static BOOL Themed = FALSE;
--- a/src/windows/native/sun/windows/awt_Component.cpp Mon Apr 30 19:04:05 2018 +0100 +++ b/src/windows/native/sun/windows/awt_Component.cpp Fri May 25 01:50:25 2018 +0100 @@ -3788,6 +3788,9 @@ UINT bits = 1; POINT p = {0, 0}; // upper left corner of the client area HWND hWnd = GetHWnd(); + if (!::IsWindowVisible(hWnd)) { + return; + } HWND hTop = GetTopLevelParentForWindow(hWnd); ::ClientToScreen(hTop, &p); if (!m_bitsCandType) { @@ -4062,6 +4065,9 @@ // void AwtComponent::InquireCandidatePosition() { + if (!::IsWindowVisible(GetHWnd())) { + return; + } JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); // get global reference of WInputMethod class (run only once)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/lang/reflect/Generics/TestGenericReturnTypeToString.java Fri May 25 01:50:25 2018 +0100 @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8054213 + * @summary Check that toString method works properly for generic return type + * obtained via reflection + * @run main TestGenericReturnTypeToString + */ + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Method; +import java.util.List; + +public class TestGenericReturnTypeToString { + + public static void main(String[] args) { + boolean hasFailures = false; + for (Method method : TestGenericReturnTypeToString.class.getMethods()) { + if (method.isAnnotationPresent(ExpectedGenericString.class)) { + ExpectedGenericString es = method.getAnnotation + (ExpectedGenericString.class); + String result = method.getGenericReturnType().toString(); + if (!es.value().equals(result)) { + hasFailures = true; + System.err.println("Unexpected result of " + + "getGenericReturnType().toString() " + + " for " + method.getName() + + " expected: " + es.value() + " actual: " + result); + } + } + if (hasFailures) { + throw new RuntimeException("Test failed"); + } + } + } + + @ExpectedGenericString("TestGenericReturnTypeToString$" + + "FirstInnerClassGeneric<Dummy>$SecondInnerClassGeneric<Dummy>") + public FirstInnerClassGeneric<Dummy>.SecondInnerClassGeneric<Dummy> foo1() { + return null; + } + + @ExpectedGenericString("TestGenericReturnTypeToString$" + + "FirstInnerClassGeneric<Dummy>$SecondInnerClass") + public FirstInnerClassGeneric<Dummy>.SecondInnerClass foo2() { + return null; + } + + @ExpectedGenericString("TestGenericReturnTypeToString$" + + "FirstInnerClass$SecondInnerClassGeneric<Dummy>") + public FirstInnerClass.SecondInnerClassGeneric<Dummy> foo3() { + return null; + } + + @ExpectedGenericString("class TestGenericReturnTypeToString$" + + "FirstInnerClass$SecondInnerClass") + public FirstInnerClass.SecondInnerClass foo4() { + return null; + } + + @ExpectedGenericString( + "java.util.List<java.lang.String>") + public java.util.List<java.lang.String> foo5() { + return null; + } + + @ExpectedGenericString("interface TestGenericReturnTypeToString$" + + "FirstInnerClass$Interface") + public FirstInnerClass.Interface foo6() { + return null; + } + + @ExpectedGenericString("TestGenericReturnTypeToString$" + + "FirstInnerClass$InterfaceGeneric<Dummy>") + public FirstInnerClass.InterfaceGeneric<Dummy> foo7() { + return null; + } + + public static class FirstInnerClass { + + public class SecondInnerClassGeneric<T> { + } + + public class SecondInnerClass { + } + + interface Interface { + } + + interface InterfaceGeneric<T> { + } + } + + public class FirstInnerClassGeneric<T> { + + public class SecondInnerClassGeneric<T> { + } + + public class SecondInnerClass { + } + } +} + +@Retention(RetentionPolicy.RUNTIME) +@interface ExpectedGenericString { + String value(); +} + +class Dummy { +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/java/util/logging/FileHandlerMaxLocksTest.java Fri May 25 01:50:25 2018 +0100 @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2017, 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 8161266 + * @summary test the FileHandler's new System property + * "jdk.internal.FileHandlerLogging.maxLocks" with default value of 100. + * @library /lib/testlibrary + * @build jdk.testlibrary.FileUtils + * @author rpatil + * @run main/othervm -Djdk.internal.FileHandlerLogging.maxLocks=200 FileHandlerMaxLocksTest + * @run main/othervm -Djdk.internal.FileHandlerLogging.maxLocks=200ab FileHandlerMaxLocksTest + */ +import java.io.File; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.FileHandler; +import jdk.testlibrary.FileUtils; + +public class FileHandlerMaxLocksTest { + + private static final String LOGGER_DIR = "logger-dir"; + private static final String MX_LCK_SYS_PROPERTY = + "jdk.internal.FileHandlerLogging.maxLocks"; + + public static void main(String[] args) throws Exception { + String maxLocksSet = System.getProperty(MX_LCK_SYS_PROPERTY); + File loggerDir = createLoggerDir(); + List<FileHandler> fileHandlers = new ArrayList<>(); + try { + // 200 raises the default limit of 100, we try 102 times + for (int i = 0; i < 102; i++) { + fileHandlers.add(new FileHandler(loggerDir.getPath() + + File.separator + "test_%u.log")); + } + } catch (IOException ie) { + if (maxLocksSet.equals("200ab") + && ie.getMessage().contains("get lock for")) { + // Ignore: Expected exception while passing bad value- 200ab + } else { + throw new RuntimeException("Test Failed: " + ie.getMessage()); + } + } finally { + for (FileHandler fh : fileHandlers) { + fh.close(); + } + FileUtils.deleteFileTreeWithRetry(Paths.get(loggerDir.getPath())); + } + } + + /** + * Create a writable directory in user directory for the test + * + * @return writable directory created that needs to be deleted when done + * @throws RuntimeException + */ + private static File createLoggerDir() throws RuntimeException { + String userDir = System.getProperty("user.dir", "."); + File loggerDir = new File(userDir, LOGGER_DIR); + if (!createFile(loggerDir, true)) { + throw new RuntimeException("Test failed: unable to create" + + " writable working directory " + + loggerDir.getAbsolutePath()); + } + // System.out.println("Created Logger Directory: " + loggerDir.getPath()); + return loggerDir; + } + + /** + * @param newFile File to be created + * @param makeDirectory is File to be created is directory + * @return true if file already exists or creation succeeded + */ + private static boolean createFile(File newFile, boolean makeDirectory) { + if (newFile.exists()) { + return true; + } + if (makeDirectory) { + return newFile.mkdir(); + } else { + try { + return newFile.createNewFile(); + } catch (IOException ie) { + System.err.println("Not able to create file: " + newFile + + ", IOException: " + ie.getMessage()); + return false; + } + } + } +}
--- a/test/javax/management/remote/mandatory/connection/DefaultAgentFilterTest.java Mon Apr 30 19:04:05 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,327 +0,0 @@ -/* - * Copyright (c) 2017, 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 8159377 - * @library /lib/testlibrary - * @summary Tests ObjectFilter on default agent - * @author Harsha Wardhana B - * @build jdk.testlibrary.* DefaultAgentFilterTest - * @run main/othervm/timeout=600 -XX:+UsePerfData DefaultAgentFilterTest - */ -import java.io.EOFException; -import java.io.File; -import java.io.IOException; -import java.io.InvalidClassException; -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.net.BindException; -import java.rmi.UnmarshalException; -import java.rmi.registry.LocateRegistry; -import java.rmi.registry.Registry; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; -import javax.management.MBeanServerConnection; -import javax.management.ObjectName; -import javax.management.remote.JMXConnector; -import javax.management.remote.JMXConnectorFactory; -import javax.management.remote.JMXServiceURL; -import java.util.concurrent.TimeUnit; - -import jdk.testlibrary.ProcessTools; -import jdk.testlibrary.Utils; - -public class DefaultAgentFilterTest { - - public static class MyTestObject implements Serializable { - - String a; - int id; - } - - public interface TestMBean { - - public void op1(HashSet<Object> params); - - public void op2(String s, HashSet<String> params); - - public void op3(MyTestObject obj, String s, HashMap<String, String> param); - } - - public static class Test implements TestMBean { - - @Override - public void op1(HashSet<Object> params) { - System.out.println("Invoked op1"); - } - - @Override - public void op2(String s, HashSet<String> params) { - System.out.println("Invoked op2"); - } - - @Override - public void op3(MyTestObject obj, String s, HashMap<String, String> param) { - System.out.println("Invoked op3"); - } - } - - private static class TestAppRun implements AutoCloseable { - - private Process p; - private final ProcessBuilder pb; - private final String name; - private final AtomicBoolean started = new AtomicBoolean(false); - - public TestAppRun(ProcessBuilder pb, String name) { - this.pb = pb; - this.name = name; - } - - public synchronized void start() throws Exception { - if (started.compareAndSet(false, true)) { - try { - AtomicBoolean error = new AtomicBoolean(false); - AtomicBoolean bindError = new AtomicBoolean(false); - p = ProcessTools.startProcess( - TEST_APP_NAME + "{" + name + "}", - pb, - (line) -> { - if (line.toLowerCase().contains("exception") - || line.toLowerCase().contains("error")) { - error.set(true); - } - bindError.set(line.toLowerCase().contains("bindexception")); - return true; - }, 10, TimeUnit.SECONDS); - if (bindError.get()) { - throw new BindException("Process could not be started"); - } else if (error.get()) { - throw new RuntimeException(); - } - } catch (Exception ex) { - if (p != null) { - p.destroy(); - p.waitFor(); - } - throw ex; - } - } - } - - public synchronized void stop() - throws IOException, InterruptedException { - if (started.compareAndSet(true, false)) { - p.getOutputStream().write(0); - p.getOutputStream().flush(); - int ec = p.waitFor(); - if (ec != 0) { - StringBuilder msg = new StringBuilder(); - msg.append("Test application '").append(name); - msg.append("' failed with exit code: "); - msg.append(ec); - System.err.println(msg); - } - } - } - - @Override - public void close() throws Exception { - stop(); - } - } - - private static final String TEST_APP_NAME = "TestApp"; - - private static void testDefaultAgent(String propertyFile) throws Exception { - int port = Utils.getFreePort(); - String propFile = System.getProperty("test.src") + File.separator + propertyFile; - List<String> pbArgs = new ArrayList<>(Arrays.asList( - "-cp", - System.getProperty("test.class.path"), - "-XX:+UsePerfData" - )); - String[] args = new String[]{ - "-Dcom.sun.management.jmxremote.port=" + port, - "-Dcom.sun.management.jmxremote.authenticate=false", - "-Dcom.sun.management.jmxremote.ssl=false", - "-Dcom.sun.management.config.file=" + propFile - }; - pbArgs.addAll(Arrays.asList(args)); - pbArgs.add(TEST_APP_NAME); - - ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( - pbArgs.toArray(new String[pbArgs.size()]) - ); - - try (TestAppRun s = new TestAppRun(pb, DefaultAgentFilterTest.class.getSimpleName())) { - s.start(); - JMXServiceURL url = testConnect(port); - testMBeanOperations(url); - } - } - - private static JMXServiceURL testConnect(int port) throws Exception { - EOFException lastException = null; - JMXServiceURL url = null; - // factor adjusted timeout (5 seconds) for the RMI to become available - long timeout = System.currentTimeMillis() + Utils.adjustTimeout(5000); - do { - lastException = null; - try { - Registry registry = LocateRegistry.getRegistry(port); - String[] relist = registry.list(); - for (int i = 0; i < relist.length; ++i) { - System.out.println("Got registry: " + relist[i]); - } - String jmxUrlStr = String.format( - "service:jmx:rmi:///jndi/rmi://localhost:%d/jmxrmi", - port); - url = new JMXServiceURL(jmxUrlStr); - - try (JMXConnector c = JMXConnectorFactory.connect(url, null)) { - MBeanServerConnection conn = c.getMBeanServerConnection(); - ObjectName name = new ObjectName("jtreg:type=Test"); - conn.createMBean(Test.class.getName(), name); - } - } catch (Exception ex) { - if (ex instanceof EOFException) { - lastException = (EOFException) ex; - System.out.println("Error establishing RMI connection. Retrying in 500ms."); - Thread.sleep(500); - } else { - throw ex; - } - } - } while (lastException != null && System.currentTimeMillis() < timeout); - if (lastException != null) { - throw lastException; - } - return url; - } - - public static void main(String[] args) throws Exception { - System.out.println("---" + DefaultAgentFilterTest.class.getName() + "-main: starting ..."); - - boolean retry = false; - do { - try { - // blacklist String - testDefaultAgent("mgmt1.properties"); - System.out.println("----\tTest FAILED !!"); - throw new RuntimeException("---" + DefaultAgentFilterTest.class.getName() + " - No exception reported"); - } catch (Exception ex) { - if (ex instanceof InvocationTargetException) { - if (ex.getCause() instanceof BindException - || ex.getCause() instanceof java.rmi.ConnectException) { - System.out.println("Failed to allocate ports. Retrying ..."); - retry = true; - } - } else if (ex instanceof InvalidClassException) { - System.out.println("----\tTest PASSED !!"); - } else if (ex instanceof UnmarshalException - && ((UnmarshalException) ex).getCause() instanceof InvalidClassException) { - System.out.println("----\tTest PASSED !!"); - } else { - System.out.println(ex); - System.out.println("----\tTest FAILED !!"); - throw ex; - } - } - } while (retry); - retry = false; - do { - try { - // blacklist non-existent class - testDefaultAgent("mgmt2.properties"); - System.out.println("----\tTest PASSED !!"); - } catch (Exception ex) { - if (ex instanceof InvocationTargetException) { - if (ex.getCause() instanceof BindException - || ex.getCause() instanceof java.rmi.ConnectException) { - System.out.println("Failed to allocate ports. Retrying ..."); - retry = true; - } - } else { - System.out.println(ex); - System.out.println("----\tTest FAILED !!"); - throw ex; - } - } - } while (retry); - - System.out.println("---" + DefaultAgentFilterTest.class.getName() + "-main: finished ..."); - } - - private static void testMBeanOperations(JMXServiceURL serverUrl) throws Exception { - Map<String, Object> clientEnv = new HashMap<>(1); - ObjectName name = new ObjectName("jtreg:type=Test"); - try (JMXConnector client = JMXConnectorFactory.connect(serverUrl, clientEnv)) { - MBeanServerConnection conn = client.getMBeanServerConnection(); - - HashSet<String> set = new HashSet<>(); - set.add("test1"); - set.add("test2"); - - String a = "A"; - - Object[] params1 = {set}; - String[] sig1 = {HashSet.class.getName()}; - conn.invoke(name, "op1", params1, sig1); - - Object[] params2 = {a, set}; - String[] sig2 = {String.class.getName(), HashSet.class.getName()}; - conn.invoke(name, "op2", params2, sig2); - - HashMap<String, String> map = new HashMap<>(); - map.put("a", "A"); - map.put("b", "B"); - - Object[] params3 = {new MyTestObject(), a, map}; - String[] sig3 = {MyTestObject.class.getName(), String.class.getName(), - HashMap.class.getName()}; - conn.invoke(name, "op3", params3, sig3); - } - } -} - -class TestApp { - - private static void doSomething() throws IOException { - int r = System.in.read(); - System.out.println("read: " + r); - } - - public static void main(String args[]) throws Exception { - System.out.println("main enter"); - System.out.flush(); - doSomething(); - System.out.println("main exit"); - } -}
--- a/test/javax/management/remote/mandatory/connection/NewRMIClientFilterTest.java Mon Apr 30 19:04:05 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2017, 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 8159377 - * @summary Tests ObjectInputFilter on RMIServer.newClient - * @author Harsha Wardhana B - * @run clean NewRMIClientFilterTest - * @run build NewRMIClientFilterTest - * @run main NewRMIClientFilterTest - */ -import java.io.InvalidClassException; -import java.io.Serializable; -import java.lang.management.ManagementFactory; -import java.util.HashMap; -import java.util.Map; -import javax.management.remote.JMXConnector; -import javax.management.remote.JMXConnectorFactory; -import javax.management.remote.JMXConnectorServer; -import javax.management.remote.JMXConnectorServerFactory; -import javax.management.remote.JMXServiceURL; -import com.sun.jmx.remote.util.EnvHelp; - -public class NewRMIClientFilterTest { - - public static void main(String[] args) throws Exception { - System.out.println("---NewRMIClientFilterTest-main: starting ..."); - String filter1 = java.lang.String.class.getName() + ";!*"; - String filter2 = java.lang.String.class.getName() + ";" + MyCredentials.class.getName() + ";!*"; - - JMXServiceURL url = new JMXServiceURL("rmi", null, 0); - JMXServiceURL serverUrl = null; - Map<String, Object> env = new HashMap<>(1); - JMXConnectorServer server = null; - - System.out.println("\n---NewRMIClientFilterTest-main: testing types = null"); - server = newServer(url, null); - serverUrl = server.getAddress(); - doTest(serverUrl, null); - doTest(serverUrl, new String[]{"toto", "titi"}); - doTest(serverUrl, new Object[]{new MyCredentials(), "toto"}); - server.stop(); - - System.out.println("\n---NewRMIClientFilterTest-main: testing types = String[]"); - env.put(EnvHelp.CREDENTIALS_FILTER_PATTERN, - filter1); - server = newServer(url, env); - serverUrl = server.getAddress(); - doTest(serverUrl, null); - doTest(serverUrl, new String[]{"toto", "titi"}); - try { - doTest(serverUrl, new MyCredentials()); - throw new Error("Bad client is not refused!"); - } catch (Exception e) { - isInvalidClassEx(e); - } finally { - server.stop(); - } - - System.out.println("\n---NewRMIClientFilterTest-main: testing user specific types = String, MyCredentials"); - env.put(EnvHelp.CREDENTIALS_FILTER_PATTERN, - filter2); - server = newServer(url, env); - serverUrl = server.getAddress(); - doTest(serverUrl, null); - doTest(serverUrl, new String[]{"toto", "titi"}); - doTest(serverUrl, new MyCredentials[]{new MyCredentials(), (MyCredentials) null}); - try { - doTest(serverUrl, new Object[]{"toto", new byte[3]}); - throw new Error("Bad client is not refused!"); - } catch (Exception e) { - isInvalidClassEx(e); - } finally { - server.stop(); - } - - System.out.println("---NewRMIClientFilterTest-main PASSED!!!"); - } - - private static void doTest(JMXServiceURL serverAddr, Object credentials) throws Exception { - System.out.println("---NewRMIClientFilterTest-test:\n\tserver address: " - + serverAddr + "\n\tcredentials: " + credentials); - - Map<String, Object> env = new HashMap<>(1); - env.put("jmx.remote.credentials", credentials); - JMXConnector client = null; - try { - client = JMXConnectorFactory.connect(serverAddr, env); - client.getMBeanServerConnection().getDefaultDomain(); - } finally { - try { - client.close(); - } catch (Exception e) { - } - } - System.out.println("---NewRMIClientFilterTest-test: PASSED!"); - } - - private static JMXConnectorServer newServer(JMXServiceURL url, Map<String, Object> env) - throws Exception { - JMXConnectorServer server = JMXConnectorServerFactory.newJMXConnectorServer( - url, - env, - ManagementFactory.getPlatformMBeanServer()); - - server.start(); - return server; - } - - private static class MyCredentials implements Serializable { - } - - private static void isInvalidClassEx(Exception e) { - Throwable cause = e; - while (cause != null) { - if (cause instanceof InvalidClassException) { - System.out.println("---NewRMIClientFilterTest-InvalidClassException expected: " + cause); - return; - } - cause = cause.getCause(); - } - e.printStackTrace(); - throw new RuntimeException("Did not get expected InvalidClassException!"); - } -}
--- a/test/javax/management/remote/mandatory/connection/mgmt1.properties Mon Apr 30 19:04:05 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -# ################ Filter for ObjectInputStream ############################# -com.sun.management.jmxremote.serial.filter.pattern=!DefaultAgentFilterTest$MyTestObject -# A filter, if configured, is used by java.io.ObjectInputStream during -# deserialization of parameters sent to the JMX default agent to validate the -# contents of the stream. -# A filter is configured as a sequence of patterns, each pattern is either -# matched against the name of a class in the stream or defines a limit. -# Patterns are separated by ";" (semicolon). -# Whitespace is significant and is considered part of the pattern. -# -# If a pattern includes a "=", it sets a limit. -# If a limit appears more than once the last value is used. -# Limits are checked before classes regardless of the order in the sequence of patterns. -# If any of the limits are exceeded, the filter status is REJECTED. -# -# maxdepth=value - the maximum depth of a graph -# maxrefs=value - the maximum number of internal references -# maxbytes=value - the maximum number of bytes in the input stream -# maxarray=value - the maximum array length allowed -# -# Other patterns, from left to right, match the class or package name as -# returned from Class.getName. -# If the class is an array type, the class or package to be matched is the element type. -# Arrays of any number of dimensions are treated the same as the element type. -# For example, a pattern of "!example.Foo", rejects creation of any instance or -# array of example.Foo. -# -# If the pattern starts with "!", the status is REJECTED if the remaining pattern -# is matched; otherwise the status is ALLOWED if the pattern matches. -# If the pattern ends with ".**" it matches any class in the package and all subpackages. -# If the pattern ends with ".*" it matches any class in the package. -# If the pattern ends with "*", it matches any class with the pattern as a prefix. -# If the pattern is equal to the class name, it matches. -# Otherwise, the status is UNDECIDED.
--- a/test/javax/management/remote/mandatory/connection/mgmt2.properties Mon Apr 30 19:04:05 2018 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -# ################ Filter for ObjectInputStream ############################# -com.sun.management.jmxremote.serial.filter.pattern=!DefaultAgentFilterTest$ThisTypeIsNotUsed -# A filter, if configured, is used by java.io.ObjectInputStream during -# deserialization of parameters sent to the JMX default agent to validate the -# contents of the stream. -# A filter is configured as a sequence of patterns, each pattern is either -# matched against the name of a class in the stream or defines a limit. -# Patterns are separated by ";" (semicolon). -# Whitespace is significant and is considered part of the pattern. -# -# If a pattern includes a "=", it sets a limit. -# If a limit appears more than once the last value is used. -# Limits are checked before classes regardless of the order in the sequence of patterns. -# If any of the limits are exceeded, the filter status is REJECTED. -# -# maxdepth=value - the maximum depth of a graph -# maxrefs=value - the maximum number of internal references -# maxbytes=value - the maximum number of bytes in the input stream -# maxarray=value - the maximum array length allowed -# -# Other patterns, from left to right, match the class or package name as -# returned from Class.getName. -# If the class is an array type, the class or package to be matched is the element type. -# Arrays of any number of dimensions are treated the same as the element type. -# For example, a pattern of "!example.Foo", rejects creation of any instance or -# array of example.Foo. -# -# If the pattern starts with "!", the status is REJECTED if the remaining pattern -# is matched; otherwise the status is ALLOWED if the pattern matches. -# If the pattern ends with ".**" it matches any class in the package and all subpackages. -# If the pattern ends with ".*" it matches any class in the package. -# If the pattern ends with "*", it matches any class with the pattern as a prefix. -# If the pattern is equal to the class name, it matches. -# Otherwise, the status is UNDECIDED.
--- a/test/javax/management/remote/mandatory/connectorServer/RMIExporterTest.java Mon Apr 30 19:04:05 2018 +0100 +++ b/test/javax/management/remote/mandatory/connectorServer/RMIExporterTest.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 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 @@ -46,7 +46,6 @@ import javax.management.remote.JMXConnectorServerFactory; import javax.management.remote.JMXServiceURL; import com.sun.jmx.remote.internal.RMIExporter; -import sun.misc.ObjectInputFilter; public class RMIExporterTest { @@ -60,8 +59,7 @@ public Remote exportObject(Remote obj, int port, RMIClientSocketFactory csf, - RMIServerSocketFactory ssf, - ObjectInputFilter unused) + RMIServerSocketFactory ssf) throws RemoteException { System.out.println("CustomRMIExporter::exportObject():: " + "Remote = " + obj);
--- a/test/javax/security/auth/Subject/doAs/NestedActions.java Mon Apr 30 19:04:05 2018 +0100 +++ b/test/javax/security/auth/Subject/doAs/NestedActions.java Fri May 25 01:50:25 2018 +0100 @@ -23,7 +23,6 @@ */ import jdk.testlibrary.ProcessTools; -import jdk.testlibrary.JarUtils; import javax.security.auth.Subject; import javax.security.auth.x500.X500Principal; @@ -101,7 +100,7 @@ public static void main(String[] args) throws IOException { if (args.length > 0) { if ("jar".equals(args[0]) && args.length > 2) { - JarUtils.createJar(args[1], Paths.get(TEST_CLASSES + FS), + createJar(args[1], Arrays.copyOfRange(args, 2, args.length)); } else { runJava(args); @@ -111,6 +110,21 @@ } } + static void createJar(String dest, String... files) throws IOException { + System.out.println("Create " + dest + " with the following content:"); + try (JarOutputStream jos = new JarOutputStream( + new FileOutputStream(dest), new Manifest())) { + for (String file : files) { + System.out.println(" " + file); + jos.putNextEntry(new JarEntry(file)); + try (FileInputStream fis = new FileInputStream( + TEST_CLASSES + FS + file)) { + jdk.testlibrary.Utils.transferTo(fis, jos); + } + } + } + } + static void runJava(String[] args) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/javax/swing/JFrame/AlwaysOnTop/AlwaysOnTopImeTest.java Fri May 25 01:50:25 2018 +0100 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2017, 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 8179665 + * @summary [Windows] java.awt.IllegalComponentStateException: component must + * be showing on the screen to determine its location + * @run main AlwaysOnTopImeTest + */ + +import javax.swing.*; +import java.awt.*; + +public class AlwaysOnTopImeTest { + + private static JDialog d; + private static JFrame f; + + public static void main(String[] args) throws Exception { + SwingUtilities.invokeLater(() -> { + f = new JFrame(); + f.setVisible(true); + d = new JDialog(f); + d.add(new JTextField()); + d.pack(); + d.setModal(true); + f.setAlwaysOnTop(true); + d.setVisible(true); + f.setAlwaysOnTop(false); + }); + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(200); + SwingUtilities.invokeAndWait(() -> d.setVisible(false)); + robot.waitForIdle(); + robot.delay(200); + SwingUtilities.invokeLater(f::dispose); + } +}
--- a/test/javax/xml/ws/8159058/SaajEmptyNamespaceTest.java Mon Apr 30 19:04:05 2018 +0100 +++ b/test/javax/xml/ws/8159058/SaajEmptyNamespaceTest.java Fri May 25 01:50:25 2018 +0100 @@ -23,7 +23,7 @@ /* * @test - * @bug 8159058 + * @bug 8159058 8186441 * @summary Test that empty default namespace declaration clears the * default namespace value * @compile -XDignore.symbol.file SaajEmptyNamespaceTest.java @@ -59,6 +59,26 @@ public class SaajEmptyNamespaceTest { /* + * Test that SOAP reader doesn't move namespaces declarations to SOAP body element + * as reported in JDK-8186441 + */ + @Test + public void testPreserveNamespacesPosition() throws Exception { + // Create SOAP message from XML string and process it with SAAJ reader + XMLStreamReader envelope = XMLInputFactory.newFactory().createXMLStreamReader( + new StringReader(INPUT_SOAP_MESSAGE_2)); + StreamMessage streamMessage = new StreamMessage(SOAPVersion.SOAP_11, + envelope, null); + SAAJFactory saajFact = new SAAJFactory(); + SOAPMessage soapMessage = saajFact.readAsSOAPMessage(SOAPVersion.SOAP_11, streamMessage); + + //Get SOAP body and convert it to string representation + SOAPBody body = soapMessage.getSOAPBody(); + String bodyAsString = nodeToText(body); + Assert.assertEquals(bodyAsString, PRESERVE_NAMESPACES_EXPECTED_RESULT); + } + + /* * Test that SOAP message with default namespace declaration that contains empty * string is properly processed by SAAJ reader. */ @@ -273,10 +293,28 @@ // Expected body content after SAAJ processing private static String EXPECTED_RESULT = "<SampleServiceRequest" - +" xmlns=\"http://example.org/test\">" + + " xmlns=\"http://example.org/test\"" + + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + "<RequestParams xmlns=\"\">" + "<Param1>hogehoge</Param1>" + "<Param2>fugafuga</Param2>" + "</RequestParams>" + "</SampleServiceRequest>"; + + private static String PRESERVE_NAMESPACES_EXPECTED_RESULT = + "<s:Body xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">" + +"<Request xmlns=\"http://example.org/NS_1\">" + +"<Item><Contact xmlns=\"http://example.org/NS_2\">Test_Contact</Contact>" + +"</Item></Request></s:Body>"; + + private static String INPUT_SOAP_MESSAGE_2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">" + + "<s:Body>" + + "<Request xmlns=\"http://example.org/NS_1\">" + + "<Item>" + + "<Contact xmlns=\"http://example.org/NS_2\">Test_Contact</Contact>" + + "</Item>" + + "</Request>" + + "</s:Body>" + + "</s:Envelope>"; }
--- a/test/lib/testlibrary/jdk/testlibrary/JarUtils.java Mon Apr 30 19:04:05 2018 +0100 +++ b/test/lib/testlibrary/jdk/testlibrary/JarUtils.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,15 +23,17 @@ package jdk.testlibrary; -import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; import java.nio.file.Path; -import java.util.ArrayList; +import java.nio.file.Paths; import java.util.Enumeration; -import java.util.List; +import java.util.HashMap; +import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; @@ -42,31 +44,24 @@ */ public final class JarUtils { - /** * Create jar file with specified files. If a specified file does not exist, * a new jar entry will be created with the file name itself as the content. */ - public static void createJar(String dest, Path filesLocation, - String... fileNames) throws IOException { + public static void createJar(String dest, String... files) + throws IOException { try (JarOutputStream jos = new JarOutputStream( new FileOutputStream(dest), new Manifest())) { - for (String fileName : fileNames) { + for (String file : files) { System.out.println(String.format("Adding %s to %s", - fileName, dest)); + file, dest)); // add an archive entry, and write a file - jos.putNextEntry(new JarEntry(fileName)); - File file; - if (filesLocation != null) { - file = filesLocation.resolve(fileName).toFile(); - } else { - file = new File(fileName); - } + jos.putNextEntry(new JarEntry(file)); try (FileInputStream fis = new FileInputStream(file)) { - Utils.transferBetweenStreams(fis, jos); + Utils.transferTo(fis, jos); } catch (FileNotFoundException e) { - jos.write(fileName.getBytes()); + jos.write(file.getBytes()); } } } @@ -74,14 +69,6 @@ } /** - * Create jar file with specified files from current directory. - */ - public static void createJar(String dest, String... files) - throws IOException { - createJar(dest, null, files); - } - - /** * Add or remove specified files to existing jar file. If a specified file * to be updated or added does not exist, the jar entry will be created * with the file name itself as the content. @@ -96,70 +83,93 @@ */ public static void updateJar(String src, String dest, String... files) throws IOException { + Map<String,Object> changes = new HashMap<>(); + boolean update = true; + for (String file : files) { + if (file.equals("-")) { + update = false; + } else if (update) { + try { + Path p = Paths.get(file); + if (Files.exists(p)) { + changes.put(file, p); + } else { + changes.put(file, file); + } + } catch (InvalidPathException e) { + // Fallback if file not a valid Path. + changes.put(file, file); + } + } else { + changes.put(file, Boolean.FALSE); + } + } + updateJar(src, dest, changes); + } + + /** + * Update content of a jar file. + * + * @param src the original jar file name + * @param dest the new jar file name + * @param changes a map of changes, key is jar entry name, value is content. + * Value can be Path, byte[] or String. If key exists in + * src but value is Boolean FALSE. The entry is removed. + * Existing entries in src not a key is unmodified. + * @throws IOException + */ + public static void updateJar(String src, String dest, + Map<String,Object> changes) + throws IOException { + + // What if input changes is immutable? + changes = new HashMap<>(changes); + + System.out.printf("Creating %s from %s...\n", dest, src); try (JarOutputStream jos = new JarOutputStream( new FileOutputStream(dest))) { - // copy each old entry into destination unless the entry name - // is in the updated list - List<String> updatedFiles = new ArrayList<>(); try (JarFile srcJarFile = new JarFile(src)) { Enumeration<JarEntry> entries = srcJarFile.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String name = entry.getName(); - boolean found = false; - boolean update = true; - for (String file : files) { - if (file.equals("-")) { - update = false; - } else if (name.equals(file)) { - updatedFiles.add(file); - found = true; - break; - } - } - - if (found) { - if (update) { - System.out.println(String.format("Updating %s with %s", - dest, name)); - jos.putNextEntry(new JarEntry(name)); - try (FileInputStream fis = new FileInputStream(name)) { - Utils.transferBetweenStreams(fis, jos); - } catch (FileNotFoundException e) { - jos.write(name.getBytes()); - } - } else { - System.out.println(String.format("Removing %s from %s", - name, dest)); - } + if (changes.containsKey(name)) { + System.out.println(String.format("- Update %s", name)); + updateEntry(jos, name, changes.get(name)); + changes.remove(name); } else { - System.out.println(String.format("Copying %s to %s", - name, dest)); + System.out.println(String.format("- Copy %s", name)); jos.putNextEntry(entry); - Utils.transferBetweenStreams(srcJarFile. - getInputStream(entry), jos); + Utils.transferTo(srcJarFile.getInputStream(entry), jos); } } } - - // append new files - for (String file : files) { - if (file.equals("-")) { - break; - } - if (!updatedFiles.contains(file)) { - System.out.println(String.format("Adding %s with %s", - dest, file)); - jos.putNextEntry(new JarEntry(file)); - try (FileInputStream fis = new FileInputStream(file)) { - Utils.transferBetweenStreams(fis, jos); - } catch (FileNotFoundException e) { - jos.write(file.getBytes()); - } - } + for (Map.Entry<String, Object> e : changes.entrySet()) { + System.out.println(String.format("- Add %s", e.getKey())); + updateEntry(jos, e.getKey(), e.getValue()); } } System.out.println(); } -} \ No newline at end of file + + private static void updateEntry(JarOutputStream jos, String name, Object content) + throws IOException { + if (content instanceof Boolean) { + if (((Boolean) content).booleanValue()) { + throw new RuntimeException("Boolean value must be FALSE"); + } + } else { + jos.putNextEntry(new JarEntry(name)); + if (content instanceof Path) { + Utils.transferTo(Files.newInputStream((Path) content), jos); + } else if (content instanceof byte[]) { + jos.write((byte[]) content); + } else if (content instanceof String) { + jos.write(((String) content).getBytes()); + } else { + throw new RuntimeException("Unknown type " + content.getClass()); + } + } + } +}
--- a/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java Mon Apr 30 19:04:05 2018 +0100 +++ b/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java Fri May 25 01:50:25 2018 +0100 @@ -365,6 +365,21 @@ } /** + * Verify the exit value of the process + * + * @param notExpectedExitValue Unexpected exit value from process + * @throws RuntimeException If the exit value from the process did match the expected value + */ + public OutputAnalyzer shouldNotHaveExitValue(int notExpectedExitValue) { + if (getExitValue() == notExpectedExitValue) { + reportDiagnosticSummary(); + throw new RuntimeException("Unexpected to get exit value of [" + + notExpectedExitValue + "]\n"); + } + return this; + } + + /** * Report summary that will help to diagnose the problem Currently includes: * - standard input produced by the process under test - standard output - * exit code Note: the command line is printed by the ProcessTools
--- a/test/lib/testlibrary/jdk/testlibrary/Utils.java Mon Apr 30 19:04:05 2018 +0100 +++ b/test/lib/testlibrary/jdk/testlibrary/Utils.java Fri May 25 01:50:25 2018 +0100 @@ -38,6 +38,7 @@ import java.util.List; import java.util.Arrays; import java.util.Collections; +import java.util.Objects; import java.util.regex.Pattern; import java.util.regex.Matcher; import java.util.concurrent.TimeUnit; @@ -80,6 +81,9 @@ */ public static final long DEFAULT_TEST_TIMEOUT = TimeUnit.SECONDS.toMillis(120); + private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; + private static final int DEFAULT_BUFFER_SIZE = 8192; + private Utils() { // Private constructor to prevent class instantiation } @@ -292,6 +296,40 @@ } /** + * Helper method to read all bytes from InputStream + * + * @param is InputStream to read from + * @return array of bytes + * @throws IOException + */ + public static byte[] readAllBytes(InputStream is) throws IOException { + byte[] buf = new byte[DEFAULT_BUFFER_SIZE]; + int capacity = buf.length; + int nread = 0; + int n; + for (;;) { + // read to EOF which may read more or less than initial buffer size + while ((n = is.read(buf, nread, capacity - nread)) > 0) + nread += n; + + // if the last call to read returned -1, then we're done + if (n < 0) + break; + + // need to allocate a larger buffer + if (capacity <= MAX_BUFFER_SIZE - capacity) { + capacity = capacity << 1; + } else { + if (capacity == MAX_BUFFER_SIZE) + throw new OutOfMemoryError("Required array size too large"); + capacity = MAX_BUFFER_SIZE; + } + buf = Arrays.copyOf(buf, capacity); + } + return (capacity == nread) ? buf : Arrays.copyOf(buf, nread); + } + + /** * Adjusts the provided timeout value for the TIMEOUT_FACTOR * @param tOut the timeout value to be adjusted * @return The timeout value adjusted for the value of "test.timeout.factor" @@ -362,7 +400,7 @@ * @throws NullPointerException if {@code in} or {@code out} is {@code null} * */ - public static long transferBetweenStreams(InputStream in, OutputStream out) + public static long transferTo(InputStream in, OutputStream out) throws IOException { long transferred = 0; byte[] buffer = new byte[BUFFER_SIZE];
--- a/test/sun/rmi/transport/proxy/EagerHttpFallback.java Mon Apr 30 19:04:05 2018 +0100 +++ b/test/sun/rmi/transport/proxy/EagerHttpFallback.java Fri May 25 01:50:25 2018 +0100 @@ -28,7 +28,7 @@ * * @library ../../../../java/rmi/testlibrary * @build TestLibrary - * @run main/othervm EagerHttpFallback + * @run main/othervm -Dsun.rmi.server.disableIncomingHttp=false EagerHttpFallback */ import java.rmi.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/rmi/transport/tcp/DisableRMIOverHttp/DisableRMIOverHTTPTest.java Fri May 25 01:50:25 2018 +0100 @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * 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 8193833 + * + * @summary Disable RMI over HTTP by default + * + * @library ../../../../../java/rmi/testlibrary + * @build TestIface TestImpl + * @run main/othervm/timeout=60 DisableRMIOverHTTPTest + * @run main/othervm/timeout=60 -Dsun.rmi.server.disableIncomingHttp=false DisableRMIOverHTTPTest + */ + +/* + * This test is an adaptation of ../blockAccept/BlockAcceptTest.java + * + * This test: + * 1. Creates an object and exports it. + * 2. Makes a regular call, using HTTP tunnelling. + * 3. Either throws an exception if RMI over HTTP is disabled or completes + * execution if not. + */ + +import java.rmi.*; +import java.rmi.server.RMISocketFactory; +import java.io.*; +import java.net.*; + +import sun.rmi.transport.proxy.RMIMasterSocketFactory; +import sun.rmi.transport.proxy.RMIHttpToPortSocketFactory; + +public class DisableRMIOverHTTPTest +{ + public static void main(String[] args) + throws Exception + { + // HTTP direct to the server port + System.setProperty("http.proxyHost", "127.0.0.1"); + boolean incomingHttpDisabled = + Boolean.valueOf( + System.getProperty( + "sun.rmi.server.disableIncomingHttp", "true") + .equalsIgnoreCase("true")); + + // Set the socket factory. + System.err.println("(installing HTTP-out socket factory)"); + HttpOutFactory fac = new HttpOutFactory(); + RMISocketFactory.setSocketFactory(fac); + + // Create remote object + TestImpl impl = new TestImpl(); + + // Export and get which port. + System.err.println("(exporting remote object)"); + TestIface stub = impl.export(); + try { + int port = fac.whichPort(); + + // Sanity + if (port == 0) + throw new Error("TEST FAILED: export didn't reserve a port(?)"); + + // The test itself: make a remote call and see if it's blocked or + // if it works + //Thread.sleep(2000); + System.err.println("(making RMI-through-HTTP call)"); + String result = stub.testCall("dummy load"); + System.err.println(" => " + result); + + if ("OK".equals(result)) { + if (incomingHttpDisabled) { + throw new Error( + "TEST FAILED: should not receive result if incoming http is disabled"); + } + } else { + if (!incomingHttpDisabled) { + throw new Error("TEST FAILED: result not OK"); + } + } + System.err.println("Test passed."); + } catch (UnmarshalException e) { + if (!incomingHttpDisabled) { + throw e; + } else { + System.err.println("Test passed."); + } + } finally { + try { + impl.unexport(); + } catch (Throwable unmatter) { + } + } + + // Should exit here + } + + private static class HttpOutFactory + extends RMISocketFactory + { + private int servport = 0; + + public Socket createSocket(String h, int p) + throws IOException + { + return ((new RMIHttpToPortSocketFactory()).createSocket(h, p)); + } + + /** Create a server socket and remember which port it's on. + * Aborts if createServerSocket(0) is called twice, because then + * it doesn't know whether to remember the first or second port. + */ + public ServerSocket createServerSocket(int p) + throws IOException + { + ServerSocket ss; + ss = (new RMIMasterSocketFactory()).createServerSocket(p); + if (p == 0) { + if (servport != 0) { + System.err.println("TEST FAILED: " + + "Duplicate createServerSocket(0)"); + throw new Error("Test aborted (createServerSocket)"); + } + servport = ss.getLocalPort(); + } + return (ss); + } + + /** Return which port was reserved by createServerSocket(0). + * If the return value was 0, createServerSocket(0) wasn't called. + */ + public int whichPort() { + return (servport); + } + } // end class HttpOutFactory +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/rmi/transport/tcp/DisableRMIOverHttp/TestIface.java Fri May 25 01:50:25 2018 +0100 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.rmi.*; + +public interface TestIface + extends Remote +{ + public String testCall(String ign) + throws RemoteException; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/sun/rmi/transport/tcp/DisableRMIOverHttp/TestImpl.java Fri May 25 01:50:25 2018 +0100 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.rmi.*; +import java.rmi.server.*; + +public class TestImpl + extends Object + implements TestIface +{ + public TestImpl() { + } + + public TestIface export() + throws RemoteException + { + return (TestIface)UnicastRemoteObject.exportObject(this, 0); + } + + public void unexport() + throws NoSuchObjectException + { + UnicastRemoteObject.unexportObject(this, true); + } + + public String testCall(String ign) { + return ("OK"); + } +}
--- a/test/sun/rmi/transport/tcp/blockAccept/BlockAcceptTest.java Mon Apr 30 19:04:05 2018 +0100 +++ b/test/sun/rmi/transport/tcp/blockAccept/BlockAcceptTest.java Fri May 25 01:50:25 2018 +0100 @@ -29,7 +29,7 @@ * * @library ../../../../../java/rmi/testlibrary * @build TestIface TestImpl TestImpl_Stub - * @run main/othervm/policy=security.policy/timeout=60 BlockAcceptTest + * @run main/othervm/policy=security.policy/timeout=60 -Dsun.rmi.server.disableIncomingHttp=false BlockAcceptTest */ /* This test attempts to stymie the RMI accept loop. The accept loop in
--- a/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/ComHostnameVerifier.java Mon Apr 30 19:04:05 2018 +0100 +++ b/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/ComHostnameVerifier.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,21 +21,20 @@ * questions. */ +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. + /* * @test - * @bug 4474255 - * @test 1.1 01/06/27 - * @bug 4484246 + * @bug 4474255 4484246 * @summary When an application enables anonymous SSL cipher suite, * Hostname verification is not required * @run main/othervm ComHostnameVerifier - * - * SunJSSE does not support dynamic system properties, no way to re-use - * system properties in samevm/agentvm mode. */ import java.io.*; import java.net.*; +import java.security.Security; import javax.net.ssl.*; import javax.security.cert.*; import com.sun.net.ssl.HostnameVerifier; @@ -249,6 +248,8 @@ volatile Exception clientException = null; public static void main(String[] args) throws Exception { + // re-enable 3DES + Security.setProperty("jdk.tls.disabledAlgorithms", ""); if (debug) System.setProperty("javax.net.debug", "all");
--- a/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/JavaxHostnameVerifier.java Mon Apr 30 19:04:05 2018 +0100 +++ b/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/JavaxHostnameVerifier.java Fri May 25 01:50:25 2018 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,21 +21,20 @@ * questions. */ +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. + /* * @test - * @bug 4474255 - * @test 1.1 01/06/27 - * @bug 4484246 + * @bug 4474255 4484246 * @summary When an application enables anonymous SSL cipher suite, * Hostname verification is not required * @run main/othervm JavaxHostnameVerifier - * - * SunJSSE does not support dynamic system properties, no way to re-use - * system properties in samevm/agentvm mode. */ import java.io.*; import java.net.*; +import java.security.Security; import java.security.cert.*; import javax.net.ssl.*; @@ -244,6 +243,8 @@ volatile Exception clientException = null; public static void main(String[] args) throws Exception { + // re-enable 3DES + Security.setProperty("jdk.tls.disabledAlgorithms", ""); if (debug) System.setProperty("javax.net.debug", "all");