aboutsummaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2013-03-06 01:01:29 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2013-03-06 01:01:29 +0000
commit2d1c28ddc6283c8defe29fa0a5616bc33f6c8bb5 (patch)
tree6f08dc3e4724c310c3cfaeee88a1a1b932e870fd /java
parent134c34afe7c332072b33a77d420d624f4a2775d9 (diff)
downloadports-2d1c28ddc6283c8defe29fa0a5616bc33f6c8bb5.tar.gz
ports-2d1c28ddc6283c8defe29fa0a5616bc33f6c8bb5.zip
Notes
Diffstat (limited to 'java')
-rw-r--r--java/openjdk6/Makefile4
-rw-r--r--java/openjdk6/files/icedtea/security/20130304/8007014.patch463
-rw-r--r--java/openjdk6/files/icedtea/security/20130304/8007675.patch509
3 files changed, 975 insertions, 1 deletions
diff --git a/java/openjdk6/Makefile b/java/openjdk6/Makefile
index 71ad10ae9922..038475b2ee7b 100644
--- a/java/openjdk6/Makefile
+++ b/java/openjdk6/Makefile
@@ -71,7 +71,9 @@ EXTRA_PATCHES= ${FILESDIR}/icedtea/security/20120830/7182135-impossible_to_use_s
${FILESDIR}/icedtea/security/20130201/8001235.patch \
${FILESDIR}/icedtea/security/20130219/8006446.patch \
${FILESDIR}/icedtea/security/20130219/8006777.patch \
- ${FILESDIR}/icedtea/security/20130219/8007688.patch
+ ${FILESDIR}/icedtea/security/20130219/8007688.patch \
+ ${FILESDIR}/icedtea/security/20130304/8007014.patch \
+ ${FILESDIR}/icedtea/security/20130304/8007675.patch
OPTIONS_DEFINE= ICEDTEA IPV6 POLICY SOUND TZUPDATE
OPTIONS_DEFAULT=ICEDTEA IPV6 TZUPDATE
diff --git a/java/openjdk6/files/icedtea/security/20130304/8007014.patch b/java/openjdk6/files/icedtea/security/20130304/8007014.patch
new file mode 100644
index 000000000000..85cdc4cd8adb
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130304/8007014.patch
@@ -0,0 +1,463 @@
+# HG changeset patch
+# User bae
+# Date 1360857111 -14400
+# Node ID 0dcf8ad3e63dfa4bb929bf2de99b95f18f5ea1c8
+# Parent 8a980f97e66a6433a1cdc946c90aff4433ea505c
+8007014: Improve image handling
+Reviewed-by: prr, mschoene, jgodinez
+
+--- jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java Tue Feb 26 12:42:17 2013 -0800
++++ jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java Thu Feb 14 19:51:51 2013 +0400
+@@ -868,6 +868,15 @@ public class ByteComponentRaster extends
+ * or if data buffer has not enough capacity.
+ */
+ protected final void verify() {
++ /* Need to re-verify the dimensions since a sample model may be
++ * specified to the constructor
++ */
++ if (width <= 0 || height <= 0 ||
++ height > (Integer.MAX_VALUE / width))
++ {
++ throw new RasterFormatException("Invalid raster dimension");
++ }
++
+ for (int i = 0; i < dataOffsets.length; i++) {
+ if (dataOffsets[i] < 0) {
+ throw new RasterFormatException("Data offsets for band " + i
+@@ -905,12 +914,13 @@ public class ByteComponentRaster extends
+ lastPixelOffset += lastScanOffset;
+
+ for (int i = 0; i < numDataElements; i++) {
+- size = lastPixelOffset + dataOffsets[i];
+ if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
+ throw new RasterFormatException("Incorrect band offset: "
+ + dataOffsets[i]);
+
+ }
++
++ size = lastPixelOffset + dataOffsets[i];
+
+ if (size > maxSize) {
+ maxSize = size;
+--- jdk/src/share/classes/sun/awt/image/BytePackedRaster.java Tue Feb 26 12:42:17 2013 -0800
++++ jdk/src/share/classes/sun/awt/image/BytePackedRaster.java Thu Feb 14 19:51:51 2013 +0400
+@@ -1368,11 +1368,35 @@ public class BytePackedRaster extends Su
+ throw new RasterFormatException("Data offsets must be >= 0");
+ }
+
++ /* Need to re-verify the dimensions since a sample model may be
++ * specified to the constructor
++ */
++ if (width <= 0 || height <= 0 ||
++ height > (Integer.MAX_VALUE / width))
++ {
++ throw new RasterFormatException("Invalid raster dimension");
++ }
++
++
++ /*
++ * pixelBitstride was verified in constructor, so just make
++ * sure that it is safe to multiply it by width.
++ */
++ if ((width - 1) > Integer.MAX_VALUE / pixelBitStride) {
++ throw new RasterFormatException("Invalid raster dimension");
++ }
++
++ if (scanlineStride < 0 ||
++ scanlineStride > (Integer.MAX_VALUE / height))
++ {
++ throw new RasterFormatException("Invalid scanline stride");
++ }
++
+ int lastbit = (dataBitOffset
+ + (height-1) * scanlineStride * 8
+ + (width-1) * pixelBitStride
+ + pixelBitStride - 1);
+- if (lastbit / 8 >= data.length) {
++ if (lastbit < 0 || lastbit / 8 >= data.length) {
+ throw new RasterFormatException("raster dimensions overflow " +
+ "array bounds");
+ }
+--- jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java Tue Feb 26 12:42:17 2013 -0800
++++ jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java Thu Feb 14 19:51:51 2013 +0400
+@@ -208,7 +208,7 @@ public class IntegerComponentRaster exte
+ " SinglePixelPackedSampleModel");
+ }
+
+- verify(false);
++ verify();
+ }
+
+
+@@ -629,16 +629,26 @@ public class IntegerComponentRaster exte
+ }
+
+ /**
+- * Verify that the layout parameters are consistent with
+- * the data. If strictCheck
+- * is false, this method will check for ArrayIndexOutOfBounds conditions. If
+- * strictCheck is true, this method will check for additional error
+- * conditions such as line wraparound (width of a line greater than
+- * the scanline stride).
+- * @return String Error string, if the layout is incompatible with
+- * the data. Otherwise returns null.
+- */
+- private void verify (boolean strictCheck) {
++ * Verify that the layout parameters are consistent with the data.
++ *
++ * The method verifies whether scanline stride and pixel stride do not
++ * cause an integer overflow during calculation of a position of the pixel
++ * in data buffer. It also verifies whether the data buffer has enough data
++ * to correspond the raster layout attributes.
++ *
++ * @throws RasterFormatException if an integer overflow is detected,
++ * or if data buffer has not enough capacity.
++ */
++ protected final void verify() {
++ /* Need to re-verify the dimensions since a sample model may be
++ * specified to the constructor
++ */
++ if (width <= 0 || height <= 0 ||
++ height > (Integer.MAX_VALUE / width))
++ {
++ throw new RasterFormatException("Invalid raster dimension");
++ }
++
+ if (dataOffsets[0] < 0) {
+ throw new RasterFormatException("Data offset ("+dataOffsets[0]+
+ ") must be >= 0");
+@@ -647,17 +657,46 @@ public class IntegerComponentRaster exte
+ int maxSize = 0;
+ int size;
+
+- for (int i=0; i < numDataElements; i++) {
+- size = (height-1)*scanlineStride + (width-1)*pixelStride +
+- dataOffsets[i];
++ // we can be sure that width and height are greater than 0
++ if (scanlineStride < 0 ||
++ scanlineStride > (Integer.MAX_VALUE / height))
++ {
++ // integer overflow
++ throw new RasterFormatException("Incorrect scanline stride: "
++ + scanlineStride);
++ }
++ int lastScanOffset = (height - 1) * scanlineStride;
++
++ if (pixelStride < 0 ||
++ pixelStride > (Integer.MAX_VALUE / width))
++ {
++ // integer overflow
++ throw new RasterFormatException("Incorrect pixel stride: "
++ + pixelStride);
++ }
++ int lastPixelOffset = (width - 1) * pixelStride;
++
++ if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) {
++ // integer overflow
++ throw new RasterFormatException("Incorrect raster attributes");
++ }
++ lastPixelOffset += lastScanOffset;
++
++ for (int i = 0; i < numDataElements; i++) {
++ if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
++ throw new RasterFormatException("Incorrect band offset: "
++ + dataOffsets[i]);
++ }
++
++ size = lastPixelOffset + dataOffsets[i];
++
+ if (size > maxSize) {
+ maxSize = size;
+ }
+ }
+ if (data.length < maxSize) {
+- throw new RasterFormatException("Data array too small (should be "+
+- maxSize
+- +" but is "+data.length+" )");
++ throw new RasterFormatException("Data array too small (should be "
++ + maxSize + " )");
+ }
+ }
+
+--- jdk/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java Tue Feb 26 12:42:17 2013 -0800
++++ jdk/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java Thu Feb 14 19:51:51 2013 +0400
+@@ -151,7 +151,7 @@ public class IntegerInterleavedRaster ex
+ throw new RasterFormatException("IntegerInterleavedRasters must have"+
+ " SinglePixelPackedSampleModel");
+ }
+- verify(false);
++ verify();
+ }
+
+
+@@ -540,31 +540,6 @@ public class IntegerInterleavedRaster ex
+ return createCompatibleWritableRaster(width,height);
+ }
+
+- /**
+- * Verify that the layout parameters are consistent with
+- * the data. If strictCheck
+- * is false, this method will check for ArrayIndexOutOfBounds conditions. If
+- * strictCheck is true, this method will check for additional error
+- * conditions such as line wraparound (width of a line greater than
+- * the scanline stride).
+- * @return String Error string, if the layout is incompatible with
+- * the data. Otherwise returns null.
+- */
+- private void verify (boolean strictCheck) {
+- int maxSize = 0;
+- int size;
+-
+- size = (height-1)*scanlineStride + (width-1) + dataOffsets[0];
+- if (size > maxSize) {
+- maxSize = size;
+- }
+- if (data.length < maxSize) {
+- throw new RasterFormatException("Data array too small (should be "+
+- maxSize
+- +" but is "+data.length+" )");
+- }
+- }
+-
+ public String toString() {
+ return new String ("IntegerInterleavedRaster: width = "+width
+ +" height = " + height
+--- jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java Tue Feb 26 12:42:17 2013 -0800
++++ jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java Thu Feb 14 19:51:51 2013 +0400
+@@ -802,6 +802,15 @@ public class ShortComponentRaster extend
+ * or if data buffer has not enough capacity.
+ */
+ protected final void verify() {
++ /* Need to re-verify the dimensions since a sample model may be
++ * specified to the constructor
++ */
++ if (width <= 0 || height <= 0 ||
++ height > (Integer.MAX_VALUE / width))
++ {
++ throw new RasterFormatException("Invalid raster dimension");
++ }
++
+ for (int i = 0; i < dataOffsets.length; i++) {
+ if (dataOffsets[i] < 0) {
+ throw new RasterFormatException("Data offsets for band " + i
+@@ -839,11 +848,12 @@ public class ShortComponentRaster extend
+ lastPixelOffset += lastScanOffset;
+
+ for (int i = 0; i < numDataElements; i++) {
+- size = lastPixelOffset + dataOffsets[i];
+ if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
+ throw new RasterFormatException("Incorrect band offset: "
+ + dataOffsets[i]);
+ }
++
++ size = lastPixelOffset + dataOffsets[i];
+
+ if (size > maxSize) {
+ maxSize = size;
+--- jdk/src/share/native/sun/awt/image/awt_parseImage.c Tue Feb 26 12:42:17 2013 -0800
++++ jdk/src/share/native/sun/awt/image/awt_parseImage.c Thu Feb 14 19:51:51 2013 +0400
+@@ -34,6 +34,7 @@
+ #include "java_awt_color_ColorSpace.h"
+ #include "awt_Mlib.h"
+ #include "safe_alloc.h"
++#include "safe_math.h"
+
+ static int setHints(JNIEnv *env, BufImageS_t *imageP);
+
+--- jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Tue Feb 26 12:42:17 2013 -0800
++++ jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c Thu Feb 14 19:51:51 2013 +0400
+@@ -42,6 +42,7 @@
+ #include "awt_Mlib.h"
+ #include "gdefs.h"
+ #include "safe_alloc.h"
++#include "safe_math.h"
+
+ /***************************************************************************
+ * Definitions *
+@@ -1993,13 +1994,23 @@ cvtCustomToDefault(JNIEnv *env, BufImage
+ unsigned char *dP = dataP;
+ #define NUM_LINES 10
+ int numLines = NUM_LINES;
+- int nbytes = rasterP->width*4*NUM_LINES;
++ /* it is safe to calculate the scan length, because width has been verified
++ * on creation of the mlib image
++ */
++ int scanLength = rasterP->width * 4;
++
++ int nbytes = 0;
++ if (!SAFE_TO_MULT(numLines, scanLength)) {
++ return -1;
++ }
++
++ nbytes = numLines * scanLength;
+
+ for (y=0; y < rasterP->height; y+=numLines) {
+ /* getData, one scanline at a time */
+ if (y+numLines > rasterP->height) {
+ numLines = rasterP->height - y;
+- nbytes = rasterP->width*4*numLines;
++ nbytes = numLines * scanLength;
+ }
+ jpixels = (*env)->CallObjectMethod(env, imageP->jimage,
+ g_BImgGetRGBMID, 0, y,
+@@ -2129,8 +2140,14 @@ allocateArray(JNIEnv *env, BufImageS_t *
+ if (cvtToDefault) {
+ int status = 0;
+ *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, 4, width, height);
++ if (*mlibImagePP == NULL) {
++ return -1;
++ }
+ cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
+- /* Make sure the image is cleared */
++ /* Make sure the image is cleared.
++ * NB: the image dimension is already verified, so we can
++ * safely calculate the length of the buffer.
++ */
+ memset(cDataP, 0, width*height*4);
+
+ if (!isSrc) {
+@@ -2380,6 +2397,9 @@ allocateRasterArray(JNIEnv *env, RasterS
+ case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_PACKED_SAMPLES:
+ *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
+ width, height);
++ if (*mlibImagePP == NULL) {
++ return -1;
++ }
+ if (!isSrc) return 0;
+ cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
+ return expandPackedBCR(env, rasterP, -1, cDataP);
+@@ -2388,6 +2408,9 @@ allocateRasterArray(JNIEnv *env, RasterS
+ if (rasterP->sppsm.maxBitSize <= 8) {
+ *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
+ width, height);
++ if (*mlibImagePP == NULL) {
++ return -1;
++ }
+ if (!isSrc) return 0;
+ cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
+ return expandPackedSCR(env, rasterP, -1, cDataP);
+@@ -2397,6 +2420,9 @@ allocateRasterArray(JNIEnv *env, RasterS
+ if (rasterP->sppsm.maxBitSize <= 8) {
+ *mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
+ width, height);
++ if (*mlibImagePP == NULL) {
++ return -1;
++ }
+ if (!isSrc) return 0;
+ cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
+ return expandPackedICR(env, rasterP, -1, cDataP);
+--- jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c Tue Feb 26 12:42:17 2013 -0800
++++ jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c Thu Feb 14 19:51:51 2013 +0400
+@@ -120,6 +120,7 @@
+ #include "mlib_image.h"
+ #include "mlib_ImageRowTable.h"
+ #include "mlib_ImageCreate.h"
++#include "safe_math.h"
+
+ /***************************************************************/
+ mlib_image* mlib_ImageSet(mlib_image *image,
+@@ -247,25 +248,47 @@ mlib_image *mlib_ImageCreate(mlib_type t
+ return NULL;
+ };
+
++ if (!SAFE_TO_MULT(width, channels)) {
++ return NULL;
++ }
++
++ wb = width * channels;
++
+ switch (type) {
+ case MLIB_DOUBLE:
+- wb = width * channels * 8;
++ if (!SAFE_TO_MULT(wb, 8)) {
++ return NULL;
++ }
++ wb *= 8;
+ break;
+ case MLIB_FLOAT:
+ case MLIB_INT:
+- wb = width * channels * 4;
++ if (!SAFE_TO_MULT(wb, 4)) {
++ return NULL;
++ }
++ wb *= 4;
+ break;
+ case MLIB_USHORT:
+ case MLIB_SHORT:
+- wb = width * channels * 2;
++ if (!SAFE_TO_MULT(wb, 4)) {
++ return NULL;
++ }
++ wb *= 2;
+ break;
+ case MLIB_BYTE:
+- wb = width * channels;
++ // wb is ready
+ break;
+ case MLIB_BIT:
+- wb = (width * channels + 7) / 8;
++ if (!SAFE_TO_ADD(7, wb)) {
++ return NULL;
++ }
++ wb = (wb + 7) / 8;
+ break;
+ default:
++ return NULL;
++ }
++
++ if (!SAFE_TO_MULT(wb, height)) {
+ return NULL;
+ }
+
+--- jdk/src/share/native/sun/awt/medialib/safe_alloc.h Tue Feb 26 12:42:17 2013 -0800
++++ jdk/src/share/native/sun/awt/medialib/safe_alloc.h Thu Feb 14 19:51:51 2013 +0400
+@@ -41,10 +41,4 @@
+ (((w) > 0) && ((h) > 0) && ((sz) > 0) && \
+ (((0xffffffffu / ((juint)(w))) / ((juint)(h))) > ((juint)(sz))))
+
+-#define SAFE_TO_MULT(a, b) \
+- (((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b)))
+-
+-#define SAFE_TO_ADD(a, b) \
+- (((a) >= 0) && ((b) >= 0) && ((0x7fffffff - (a)) > (b)))
+-
+ #endif // __SAFE_ALLOC_H__
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ jdk/src/share/native/sun/awt/medialib/safe_math.h Thu Feb 14 19:51:51 2013 +0400
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 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
++ * 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.
++ */
++
++#ifndef __SAFE_MATH_H__
++#define __SAFE_MATH_H__
++
++#define SAFE_TO_MULT(a, b) \
++ (((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b)))
++
++#define SAFE_TO_ADD(a, b) \
++ (((a) >= 0) && ((b) >= 0) && ((0x7fffffff - (a)) > (b)))
++
++#endif // __SAFE_MATH_H__
+
diff --git a/java/openjdk6/files/icedtea/security/20130304/8007675.patch b/java/openjdk6/files/icedtea/security/20130304/8007675.patch
new file mode 100644
index 000000000000..2e1be10f0614
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130304/8007675.patch
@@ -0,0 +1,509 @@
+# HG changeset patch
+# User bae
+# Date 1361431543 -14400
+# Node ID b130c8cfecfc552614047b3244d5d94439827fcd
+# Parent 0dcf8ad3e63dfa4bb929bf2de99b95f18f5ea1c8
+8007675: Improve color conversion
+Reviewed-by: prr, jgodinez
+
+--- jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java Thu Feb 14 19:51:51 2013 +0400
++++ jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java Thu Feb 21 11:25:43 2013 +0400
+@@ -99,50 +99,75 @@ class LCMSImageLayout {
+ int offset;
+
+ Object dataArray;
+- private LCMSImageLayout(int np, int pixelType, int pixelSize) {
++ private int dataArrayLength; /* in bytes */
++
++ private LCMSImageLayout(int np, int pixelType, int pixelSize)
++ throws ImageLayoutException
++ {
+ this.pixelType = pixelType;
+ width = np;
+ height = 1;
+- nextRowOffset = np*pixelSize;
++ nextRowOffset = safeMult(pixelSize, np);
+ offset = 0;
+ }
+
+ private LCMSImageLayout(int width, int height, int pixelType,
+- int pixelSize) {
++ int pixelSize)
++ throws ImageLayoutException
++ {
+ this.pixelType = pixelType;
+ this.width = width;
+ this.height = height;
+- nextRowOffset = width*pixelSize;
++ nextRowOffset = safeMult(pixelSize, width);
+ offset = 0;
+ }
+
+
+- public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize) {
++ public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize)
++ throws ImageLayoutException
++ {
+ this(np, pixelType, pixelSize);
+ dataType = DT_BYTE;
+ dataArray = data;
+- }
+-
+- public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize) {
++ dataArrayLength = data.length;
++
++ verify();
++ }
++
++ public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize)
++ throws ImageLayoutException
++ {
+ this(np, pixelType, pixelSize);
+ dataType = DT_SHORT;
+ dataArray = data;
+- }
+-
+- public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize) {
++ dataArrayLength = 2 * data.length;
++
++ verify();
++ }
++
++ public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize)
++ throws ImageLayoutException
++ {
+ this(np, pixelType, pixelSize);
+ dataType = DT_INT;
+ dataArray = data;
++ dataArrayLength = 4 * data.length;
++
++ verify();
+ }
+
+ public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize)
++ throws ImageLayoutException
+ {
+ this(np, pixelType, pixelSize);
+ dataType = DT_DOUBLE;
+ dataArray = data;
+- }
+-
+- public LCMSImageLayout(BufferedImage image) {
++ dataArrayLength = 8 * data.length;
++
++ verify();
++ }
++
++ public LCMSImageLayout(BufferedImage image) throws ImageLayoutException {
+ ShortComponentRaster shortRaster;
+ IntegerComponentRaster intRaster;
+ ByteComponentRaster byteRaster;
+@@ -186,9 +211,13 @@ class LCMSImageLayout {
+ case BufferedImage.TYPE_INT_ARGB:
+ case BufferedImage.TYPE_INT_BGR:
+ intRaster = (IntegerComponentRaster)image.getRaster();
+- nextRowOffset = intRaster.getScanlineStride()*4;
+- offset = intRaster.getDataOffset(0)*4;
++
++ nextRowOffset = safeMult(4, intRaster.getScanlineStride());
++
++ offset = safeMult(4, intRaster.getDataOffset(0));
++
+ dataArray = intRaster.getDataStorage();
++ dataArrayLength = 4 * intRaster.getDataStorage().length;
+ dataType = DT_INT;
+ break;
+
+@@ -196,8 +225,10 @@ class LCMSImageLayout {
+ case BufferedImage.TYPE_4BYTE_ABGR:
+ byteRaster = (ByteComponentRaster)image.getRaster();
+ nextRowOffset = byteRaster.getScanlineStride();
+- offset = byteRaster.getDataOffset(0);
++ int firstBand = image.getSampleModel().getNumBands() - 1;
++ offset = byteRaster.getDataOffset(firstBand);
+ dataArray = byteRaster.getDataStorage();
++ dataArrayLength = byteRaster.getDataStorage().length;
+ dataType = DT_BYTE;
+ break;
+
+@@ -206,17 +237,20 @@ class LCMSImageLayout {
+ nextRowOffset = byteRaster.getScanlineStride();
+ offset = byteRaster.getDataOffset(0);
+ dataArray = byteRaster.getDataStorage();
++ dataArrayLength = byteRaster.getDataStorage().length;
+ dataType = DT_BYTE;
+ break;
+
+ case BufferedImage.TYPE_USHORT_GRAY:
+ shortRaster = (ShortComponentRaster)image.getRaster();
+- nextRowOffset = shortRaster.getScanlineStride()*2;
+- offset = shortRaster.getDataOffset(0) * 2;
++ nextRowOffset = safeMult(2, shortRaster.getScanlineStride());
++ offset = safeMult(2, shortRaster.getDataOffset(0));
+ dataArray = shortRaster.getDataStorage();
++ dataArrayLength = 2 * shortRaster.getDataStorage().length;
+ dataType = DT_SHORT;
+ break;
+ }
++ verify();
+ }
+
+ public static boolean isSupported(BufferedImage image) {
+@@ -232,4 +266,45 @@ class LCMSImageLayout {
+ }
+ return false;
+ }
++
++ private void verify() throws ImageLayoutException {
++
++ if (offset < 0 || offset >= dataArrayLength) {
++ throw new ImageLayoutException("Invalid image layout");
++ }
++
++ int lastPixelOffset = safeMult(nextRowOffset, (height - 1));
++
++ lastPixelOffset = safeAdd(lastPixelOffset, (width - 1));
++
++ int off = safeAdd(offset, lastPixelOffset);
++
++ if (off < 0 || off >= dataArrayLength) {
++ throw new ImageLayoutException("Invalid image layout");
++ }
++ }
++
++ static int safeAdd(int a, int b) throws ImageLayoutException {
++ long res = a;
++ res += b;
++ if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
++ throw new ImageLayoutException("Invalid image layout");
++ }
++ return (int)res;
++ }
++
++ static int safeMult(int a, int b) throws ImageLayoutException {
++ long res = a;
++ res *= b;
++ if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
++ throw new ImageLayoutException("Invalid image layout");
++ }
++ return (int)res;
++ }
++
++ public static class ImageLayoutException extends Exception {
++ public ImageLayoutException(String message) {
++ super(message);
++ }
++ }
+ }
+--- jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java Fri Oct 26 14:32:40 2012 -0700
++++ jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java Mon Mar 04 19:22:10 2013 +0100
+@@ -51,6 +51,7 @@
+ import java.awt.image.ComponentSampleModel;
+ import sun.java2d.cmm.*;
+ import sun.java2d.cmm.lcms.*;
++import static sun.java2d.cmm.lcms.LCMSImageLayout.ImageLayoutException;
+
+
+ public class LCMSTransform implements ColorTransform {
+@@ -111,15 +112,26 @@
+ return profiles[profiles.length - 1].getNumComponents();
+ }
+
++ private synchronized void doTransform(LCMSImageLayout in,
++ LCMSImageLayout out) {
++ // update native transfrom if needed
++ if (ID == 0L) {
++ ID = LCMS.createNativeTransform(profileIDs, renderType,
++ disposerReferent);
++ }
++ LCMS.colorConvert(this, in, out);
++ }
++
+ public void colorConvert(BufferedImage src, BufferedImage dst) {
+ if (LCMSImageLayout.isSupported(src) &&
+ LCMSImageLayout.isSupported(dst))
+ {
+- synchronized(this) {
+- LCMS.colorConvert(this, new LCMSImageLayout(src),
+- new LCMSImageLayout(dst));
++ try {
++ doTransform(new LCMSImageLayout(src), new LCMSImageLayout(dst));
++ return;
++ } catch (ImageLayoutException e) {
++ throw new CMMException("Unable to convert images");
+ }
+- return;
+ }
+ LCMSImageLayout srcIL, dstIL;
+ Raster srcRas = src.getRaster();
+@@ -177,14 +189,18 @@
+ }
+ int idx;
+ // TODO check for src npixels = dst npixels
+- srcIL = new LCMSImageLayout(
+- srcLine, srcLine.length/getNumInComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+- LCMSImageLayout.BYTES_SH(1), getNumInComponents());
+- dstIL = new LCMSImageLayout(
+- dstLine, dstLine.length/getNumOutComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+- LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
++ try {
++ srcIL = new LCMSImageLayout(
++ srcLine, srcLine.length/getNumInComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
++ LCMSImageLayout.BYTES_SH(1), getNumInComponents());
++ dstIL = new LCMSImageLayout(
++ dstLine, dstLine.length/getNumOutComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
++ LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
++ } catch (ImageLayoutException e) {
++ throw new CMMException("Unable to convert images");
++ }
+ // process each scanline
+ for (int y = 0; y < h; y++) {
+ // convert src scanline
+@@ -204,9 +220,8 @@
+ }
+ }
+ // color convert srcLine to dstLine
+- synchronized (this) {
+- LCMS.colorConvert(this, srcIL, dstIL);
+- }
++ doTransform(srcIL, dstIL);
++
+ // convert dst scanline
+ pixel = null;
+ idx = 0;
+@@ -234,16 +249,19 @@
+ alpha = new float[w];
+ }
+ int idx;
+- srcIL = new LCMSImageLayout(
+- srcLine, srcLine.length/getNumInComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+- LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
++ try {
++ srcIL = new LCMSImageLayout(
++ srcLine, srcLine.length/getNumInComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
++ LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
+
+- dstIL = new LCMSImageLayout(
+- dstLine, dstLine.length/getNumOutComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+- LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
+-
++ dstIL = new LCMSImageLayout(
++ dstLine, dstLine.length/getNumOutComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
++ LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
++ } catch (ImageLayoutException e) {
++ throw new CMMException("Unable to convert images");
++ }
+ // process each scanline
+ for (int y = 0; y < h; y++) {
+ // convert src scanline
+@@ -263,9 +281,8 @@
+ }
+ }
+ // color convert srcLine to dstLine
+- synchronized(this) {
+- LCMS.colorConvert(this, srcIL, dstIL);
+- }
++ doTransform(srcIL, dstIL);
++
+ // convert dst scanline
+ pixel = null;
+ idx = 0;
+@@ -353,16 +370,19 @@
+ short[] srcLine = new short[w * srcNumBands];
+ short[] dstLine = new short[w * dstNumBands];
+ int idx;
+- srcIL = new LCMSImageLayout(
+- srcLine, srcLine.length/getNumInComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+- LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
++ try {
++ srcIL = new LCMSImageLayout(
++ srcLine, srcLine.length/getNumInComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
++ LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
+
+- dstIL = new LCMSImageLayout(
+- dstLine, dstLine.length/getNumOutComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+- LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
+-
++ dstIL = new LCMSImageLayout(
++ dstLine, dstLine.length/getNumOutComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
++ LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
++ } catch (ImageLayoutException e) {
++ throw new CMMException("Unable to convert rasters");
++ }
+ // process each scanline
+ for (int y = 0; y < h; y++, ys++, yd++) {
+ // get src scanline
+@@ -377,9 +397,7 @@
+ }
+
+ // color convert srcLine to dstLine
+- synchronized(this) {
+- LCMS.colorConvert(this, srcIL, dstIL);
+- }
++ doTransform(srcIL, dstIL);
+
+ // store dst scanline
+ xd = dst.getMinX();
+@@ -447,15 +465,18 @@
+ byte[] dstLine = new byte[w * dstNumBands];
+ int idx;
+ // TODO check for src npixels = dst npixels
+- srcIL = new LCMSImageLayout(
+- srcLine, srcLine.length/getNumInComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+- LCMSImageLayout.BYTES_SH(1), getNumInComponents());
+- dstIL = new LCMSImageLayout(
+- dstLine, dstLine.length/getNumOutComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+- LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
+-
++ try {
++ srcIL = new LCMSImageLayout(
++ srcLine, srcLine.length/getNumInComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
++ LCMSImageLayout.BYTES_SH(1), getNumInComponents());
++ dstIL = new LCMSImageLayout(
++ dstLine, dstLine.length/getNumOutComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
++ LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
++ } catch (ImageLayoutException e) {
++ throw new CMMException("Unable to convert rasters");
++ }
+ // process each scanline
+ for (int y = 0; y < h; y++, ys++, yd++) {
+ // get src scanline
+@@ -470,9 +491,7 @@
+ }
+
+ // color convert srcLine to dstLine
+- synchronized(this) {
+- LCMS.colorConvert(this, srcIL, dstIL);
+- }
++ doTransform(srcIL, dstIL);
+
+ // store dst scanline
+ xd = dst.getMinX();
+@@ -489,16 +508,20 @@
+ short[] srcLine = new short[w * srcNumBands];
+ short[] dstLine = new short[w * dstNumBands];
+ int idx;
+- srcIL = new LCMSImageLayout(
+- srcLine, srcLine.length/getNumInComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+- LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
+
+- dstIL = new LCMSImageLayout(
+- dstLine, dstLine.length/getNumOutComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+- LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
++ try {
++ srcIL = new LCMSImageLayout(
++ srcLine, srcLine.length/getNumInComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
++ LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
+
++ dstIL = new LCMSImageLayout(
++ dstLine, dstLine.length/getNumOutComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
++ LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
++ } catch (ImageLayoutException e) {
++ throw new CMMException("Unable to convert rasters");
++ }
+ // process each scanline
+ for (int y = 0; y < h; y++, ys++, yd++) {
+ // get src scanline
+@@ -513,9 +536,8 @@
+ }
+
+ // color convert srcLine to dstLine
+- synchronized(this) {
+- LCMS.colorConvert(this, srcIL, dstIL);
+- }
++ doTransform(srcIL, dstIL);
++
+ // store dst scanline
+ xd = dst.getMinX();
+ idx = 0;
+@@ -540,21 +562,23 @@
+ dst = new short [(src.length/getNumInComponents())*getNumOutComponents()];
+ }
+
+- LCMSImageLayout srcIL = new LCMSImageLayout(
+- src, src.length/getNumInComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+- LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
++ try {
++ LCMSImageLayout srcIL = new LCMSImageLayout(
++ src, src.length/getNumInComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
++ LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
+
+- LCMSImageLayout dstIL = new LCMSImageLayout(
+- dst, dst.length/getNumOutComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+- LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
++ LCMSImageLayout dstIL = new LCMSImageLayout(
++ dst, dst.length/getNumOutComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
++ LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
+
+- synchronized(this) {
+- LCMS.colorConvert(this, srcIL, dstIL);
++ doTransform(srcIL, dstIL);
++
++ return dst;
++ } catch (ImageLayoutException e) {
++ throw new CMMException("Unable to convert data");
+ }
+-
+- return dst;
+ }
+
+ public byte[] colorConvert(byte[] src, byte[] dst) {
+@@ -562,20 +586,22 @@
+ dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()];
+ }
+
+- LCMSImageLayout srcIL = new LCMSImageLayout(
+- src, src.length/getNumInComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+- LCMSImageLayout.BYTES_SH(1), getNumInComponents());
++ try {
++ LCMSImageLayout srcIL = new LCMSImageLayout(
++ src, src.length/getNumInComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
++ LCMSImageLayout.BYTES_SH(1), getNumInComponents());
+
+- LCMSImageLayout dstIL = new LCMSImageLayout(
+- dst, dst.length/getNumOutComponents(),
+- LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+- LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
++ LCMSImageLayout dstIL = new LCMSImageLayout(
++ dst, dst.length/getNumOutComponents(),
++ LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
++ LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
+
+- synchronized(this) {
+- LCMS.colorConvert(this, srcIL, dstIL);
++ doTransform(srcIL, dstIL);
++
++ return dst;
++ } catch (ImageLayoutException e) {
++ throw new CMMException("Unable to convert data");
+ }
+-
+- return dst;
+ }
+ }