# HG changeset patch
# User andrew
# Date 1374492919 -3600
# Node ID 6450b0e87f344ca80b7918a222ffce6f33ecd3c0
# Parent  c7c63559dc734238ae4b7856c4e9bad440902ae8
7042594: 3 testis api/java_awt/Color/ICC_ProfileRGB/index.html fail against RI  b138 OEL6x64.
Reviewed-by: prr

diff --git a/src/share/native/sun/java2d/cmm/lcms/LCMS.c b/src/share/native/sun/java2d/cmm/lcms/LCMS.c
--- openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c
+++ openjdk/jdk/src/share/native/sun/java2d/cmm/lcms/LCMS.c
@@ -232,9 +232,19 @@
     jint dataSize;
     storeID_t sProf;
 
+    if (JNU_IsNull(env, data)) {
+        JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
+        return 0L;
+    }
+
     dataArray = (*env)->GetByteArrayElements (env, data, 0);
     dataSize = (*env)->GetArrayLength (env, data);
 
+    if (dataArray == NULL) {
+        JNU_ThrowIllegalArgumentException(env, "Invalid profile data");
+        return 0L;
+    }
+
     sProf.pf = cmsOpenProfileFromMem((const void *)dataArray,
                                      (cmsUInt32Number) dataSize);
 
@@ -333,8 +343,9 @@
 }
 
 /* Get profile header info */
-cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
-cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
+static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
+static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize);
+static cmsBool _writeCookedTag(cmsHPROFILE pfTarget, cmsTagSignature sig, jbyte *pData, jint size);
 
 /*
  * Class:     sun_java2d_cmm_lcms_LCMS
@@ -355,7 +366,7 @@
         result = sizeof(cmsICCHeader);
     } else {
       if (cmsIsTag(sProf.pf, sig.cms)) {
-            result = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0);
+          result = cmsReadRawTag(sProf.pf, sig.cms, NULL, 0);
         } else {
             JNU_ThrowByName(env, "java/awt/color/CMMException",
                             "ICC profile tag not found");
@@ -467,22 +478,30 @@
     sProf.j = id;
     sig.j = tagSig;
 
+    if (JNU_IsNull(env, data)) {
+        JNU_ThrowIllegalArgumentException(env, "Can not write tag data.");
+        return;
+    }
 
     tagSize =(*env)->GetArrayLength(env, data);
 
     dataArray = (*env)->GetByteArrayElements(env, data, 0);
 
+    if (dataArray == NULL) {
+        JNU_ThrowIllegalArgumentException(env, "Can not write tag data.");
+        return;
+    }
+
     if (tagSig == SigHead) {
         status = _setHeaderInfo(sProf.pf, dataArray, tagSize);
     } else {
-        status = cmsWriteRawTag(sProf.pf, sig.cms, dataArray, tagSize);
+        status = _writeCookedTag(sProf.pf, sig.cms, dataArray, tagSize);
     }
 
     (*env)->ReleaseByteArrayElements(env, data, dataArray, 0);
 
     if (!status) {
-        JNU_ThrowByName(env, "java/awt/color/CMMException",
-                        "Can not write tag data.");
+        JNU_ThrowIllegalArgumentException(env, "Can not write tag data.");
     }
 }
 
@@ -644,7 +663,7 @@
     PF_ID_fID = (*env)->GetFieldID (env, Pf, "ID", "J");
 }
 
-cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
+static cmsBool _getHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
 {
   cmsUInt32Number pfSize = 0;
   cmsUInt8Number* pfBuffer = NULL;
@@ -671,7 +690,7 @@
   return status;
 }
 
-cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
+static cmsBool _setHeaderInfo(cmsHPROFILE pf, jbyte* pBuffer, jint bufferSize)
 {
   cmsICCHeader pfHeader = { 0 };
 
@@ -695,3 +714,77 @@
 
   return TRUE;
 }
+
+static cmsBool _writeCookedTag(cmsHPROFILE pfTarget,
+                               cmsTagSignature sig,
+                               jbyte *pData, jint size)
+{
+    cmsBool status;
+    cmsUInt32Number pfSize = 0;
+    cmsUInt8Number* pfBuffer = NULL;
+
+    cmsHPROFILE p = cmsCreateProfilePlaceholder(NULL);
+    if (NULL != p) {
+        cmsICCHeader hdr = { 0 };
+
+        /* Populate the placeholder's header according to target profile */
+        hdr.flags = cmsGetHeaderFlags(pfTarget);
+        hdr.renderingIntent = cmsGetHeaderRenderingIntent(pfTarget);
+        hdr.manufacturer = cmsGetHeaderManufacturer(pfTarget);
+        hdr.model = cmsGetHeaderModel(pfTarget);
+        hdr.pcs = cmsGetPCS(pfTarget);
+        hdr.colorSpace = cmsGetColorSpace(pfTarget);
+        hdr.deviceClass = cmsGetDeviceClass(pfTarget);
+        hdr.version = cmsGetEncodedICCversion(pfTarget);
+        cmsGetHeaderAttributes(pfTarget, &hdr.attributes);
+        cmsGetHeaderProfileID(pfTarget, (cmsUInt8Number*)&hdr.profileID);
+
+        cmsSetHeaderFlags(p, hdr.flags);
+        cmsSetHeaderManufacturer(p, hdr.manufacturer);
+        cmsSetHeaderModel(p, hdr.model);
+        cmsSetHeaderAttributes(p, hdr.attributes);
+        cmsSetHeaderProfileID(p, (cmsUInt8Number*)&(hdr.profileID));
+        cmsSetHeaderRenderingIntent(p, hdr.renderingIntent);
+        cmsSetPCS(p, hdr.pcs);
+        cmsSetColorSpace(p, hdr.colorSpace);
+        cmsSetDeviceClass(p, hdr.deviceClass);
+        cmsSetEncodedICCversion(p, hdr.version);
+
+
+        if (cmsWriteRawTag(p, sig, pData, size)) {
+            if (cmsSaveProfileToMem(p, NULL, &pfSize)) {
+                pfBuffer = malloc(pfSize);
+                if (pfBuffer != NULL) {
+                    /* load raw profile data into the buffer */
+                    if (!cmsSaveProfileToMem(p, pfBuffer, &pfSize)) {
+                        free(pfBuffer);
+                        pfBuffer = NULL;
+                    }
+                }
+            }
+        }
+        cmsCloseProfile(p);
+    }
+
+    if (pfBuffer == NULL) {
+        return FALSE;
+    }
+
+    /* re-open the placeholder profile */
+    p = cmsOpenProfileFromMem(pfBuffer, pfSize);
+    free(pfBuffer);
+    status = FALSE;
+
+    if (p != NULL) {
+        /* Note that pCookedTag points to internal structures of the placeholder,
+         * so this data is valid only while the placeholder is open.
+         */
+        void *pCookedTag = cmsReadTag(p, sig);
+        if (pCookedTag != NULL) {
+            status = cmsWriteTag(pfTarget, sig, pCookedTag);
+        }
+        pCookedTag = NULL;
+        cmsCloseProfile(p);
+    }
+    return status;
+}
diff --git a/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java b/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java
--- openjdk/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java
+++ openjdk/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 6476665 6523403 6733501
+ * @bug 6476665 6523403 6733501 7042594
  * @summary Verifies reading and writing profiles and tags of the standard color
  * spaces
  * @run main ReadWriteProfileTest
@@ -94,7 +94,16 @@
             for (int tagSig : tags[i].keySet()) {
                 byte [] tagData = pf.getData(tagSig);
                 byte [] empty = new byte[tagData.length];
-                pf.setData(tagSig, empty);
+                boolean emptyDataRejected = false;
+                try {
+                    pf.setData(tagSig, empty);
+                } catch (IllegalArgumentException e) {
+                    emptyDataRejected = true;
+                }
+                if (!emptyDataRejected) {
+                    throw new
+                        RuntimeException("Test failed: empty tag data was not rejected.");
+                }
                 pf.setData(tagSig, tagData);
 
                 byte [] tagData1 = pf.getData(tagSig);
diff --git a/test/sun/java2d/cmm/ProfileOp/SetDataTest.java b/test/sun/java2d/cmm/ProfileOp/SetDataTest.java
new file mode 100644
--- /dev/null
+++ openjdk/jdk/test/sun/java2d/cmm/ProfileOp/SetDataTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2011, 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     7042594
+ * @summary Test verifies that ICC_Profile.setData() conforms the spec.
+ *
+ * @run     main SetDataTest
+ */
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.awt.color.ICC_Profile;
+import static java.awt.color.ICC_ColorSpace.CS_GRAY;
+import static java.awt.color.ICC_Profile.icSigGrayTRCTag;
+import static java.awt.color.ICC_Profile.icSigRedTRCTag;
+import static java.awt.color.ICC_Profile.icSigGreenTRCTag;
+
+public class SetDataTest {
+
+    static class TestCase {
+
+        static ICC_Profile profile;
+        static byte[] validTRCdata;
+        static byte[] invalidTRCData;
+
+        static {
+            profile = ICC_Profile.getInstance(CS_GRAY);
+            validTRCdata = profile.getData(icSigGrayTRCTag);
+            invalidTRCData = new byte[]{0x42, 0x42, 0x42, 0x42, 1, 3, 4, 6,};
+        }
+        String desciption;
+        int signature;
+        boolean useValidData;
+        Throwable err;
+        boolean isIAEexpected;
+
+        public TestCase(String descr, int sig,
+                boolean useValidData,
+                boolean isIAEexpected) {
+            this.desciption = descr;
+            this.signature = sig;
+
+            this.useValidData = useValidData;
+            this.isIAEexpected = isIAEexpected;
+
+        }
+
+        public void doTest() {
+            System.out.println(desciption);
+            byte[] data = useValidData
+                    ? validTRCdata : invalidTRCData;
+            err = null;
+            try {
+                profile.setData(signature, data);
+            } catch (Throwable e) {
+                err = e;
+                System.out.println("Got exception: " +
+                        e.getClass().getName() + ": " +
+                        e.getMessage());
+            }
+
+            if (isIAEexpected) {
+                if (err == null) {
+                    throw new RuntimeException(
+                            "Test failed: expected exception was not thrown");
+                }
+                if (!(err instanceof IllegalArgumentException)) {
+                    throw new RuntimeException(
+                            "Unexpected exception was thrown: " +
+                            err.getMessage(), err);
+                }
+            } else {
+                if (err != null) {
+                    throw new RuntimeException(
+                            "Unexpected exception was thrown: " +
+                            err.getMessage(), err);
+                }
+            }
+            System.out.println("Testcase PASSED");
+        }
+    }
+
+    public static void main(String[] args) {
+        List<TestCase> tests = new ArrayList<TestCase>();
+
+        TestCase selfupdate = new TestCase(
+                "Selfupdate: update grayTRC with the same data.",
+                icSigGrayTRCTag, true, false);
+        tests.add(selfupdate);
+
+        TestCase newValdTag = new TestCase(
+                "Insert new valid tag",
+                icSigRedTRCTag,
+                true, false);
+        tests.add(newValdTag);
+
+        TestCase newInvalidTag = new TestCase(
+                "Insert new tag with invalid contet",
+                icSigGreenTRCTag,
+                false, true);
+        tests.add(newInvalidTag);
+
+        TestCase newUnknowInvalidTag = new TestCase(
+                "Insert new tag with invalid data and unknown signature",
+                0x41414141,
+                false, true);
+        tests.add(newUnknowInvalidTag);
+
+        TestCase newUnknownValidTag = new TestCase(
+                "Insert new tag with valid data and unknown signatiure",
+                0x41414141,
+                true, true);
+        tests.add(newUnknownValidTag);
+
+        for (TestCase t: tests) {
+            t.doTest();
+        }
+        System.out.println("Test passed!.");
+    }
+}
