Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Mar 2013 01:01:30 +0000 (UTC)
From:      Jung-uk Kim <jkim@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r313493 - in head/java/openjdk6: . files/icedtea/security/20130304
Message-ID:  <201303060101.r2611UZe001711@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jkim
Date: Wed Mar  6 01:01:29 2013
New Revision: 313493
URL: http://svnweb.freebsd.org/changeset/ports/313493

Log:
  Add multiple security patches from IcedTea6 1.12.4.
  
  http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2013-March/022145.html
  
  Obtained from:	IcedTea Project

Added:
  head/java/openjdk6/files/icedtea/security/20130304/
  head/java/openjdk6/files/icedtea/security/20130304/8007014.patch   (contents, props changed)
  head/java/openjdk6/files/icedtea/security/20130304/8007675.patch   (contents, props changed)
Modified:
  head/java/openjdk6/Makefile

Modified: head/java/openjdk6/Makefile
==============================================================================
--- head/java/openjdk6/Makefile	Wed Mar  6 00:56:02 2013	(r313492)
+++ head/java/openjdk6/Makefile	Wed Mar  6 01:01:29 2013	(r313493)
@@ -71,7 +71,9 @@ EXTRA_PATCHES=	${FILESDIR}/icedtea/secur
 		${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

Added: head/java/openjdk6/files/icedtea/security/20130304/8007014.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/java/openjdk6/files/icedtea/security/20130304/8007014.patch	Wed Mar  6 01:01:29 2013	(r313493)
@@ -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__
+

Added: head/java/openjdk6/files/icedtea/security/20130304/8007675.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/java/openjdk6/files/icedtea/security/20130304/8007675.patch	Wed Mar  6 01:01:29 2013	(r313493)
@@ -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;
+     }
+ }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201303060101.r2611UZe001711>