changeset 2966:1ecedefb66fa

Add 2013/03/04 security patches. 2013-03-07 Andrew John Hughes <gnu.andrew@redhat.com> * Makefile.am: (SECURITY_PATCHES): List new patches. * patches/security/20130304/8007014.patch, * patches/security/20130304/8007675.patch: Patches from upstream. * patches/security/20130304/declaration_correction.patch: Correct bad code added to LCMSTransform.java which fails with ecj.
author Andrew John Hughes <gnu.andrew@redhat.com>
date Thu, 07 Mar 2013 13:16:01 +0000
parents 076acbb953a5
children 7088315fb75f
files ChangeLog Makefile.am patches/security/20130304/8007014.patch patches/security/20130304/8007675.patch patches/security/20130304/declaration_correction.patch
diffstat 5 files changed, 954 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Mar 06 19:28:09 2013 +0000
+++ b/ChangeLog	Thu Mar 07 13:16:01 2013 +0000
@@ -1,3 +1,14 @@
+2013-03-07  Andrew John Hughes  <gnu.andrew@redhat.com>
+
+	* Makefile.am:
+	(SECURITY_PATCHES): List new patches.
+	* patches/security/20130304/8007014.patch,
+	* patches/security/20130304/8007675.patch:
+	Patches from upstream.
+	* patches/security/20130304/declaration_correction.patch:
+	Correct bad code added to LCMSTransform.java
+	which fails with ecj.
+
 2013-02-17  Andrew John Hughes  <gnu.andrew@redhat.com>
 
 	* Makefile.am:
--- a/Makefile.am	Wed Mar 06 19:28:09 2013 +0000
+++ b/Makefile.am	Thu Mar 07 13:16:01 2013 +0000
@@ -276,7 +276,10 @@
 	patches/security/20130201/8001235.patch \
 	patches/security/20130219/8006446.patch \
 	patches/security/20130219/8006777.patch \
-	patches/security/20130219/8007688.patch
+	patches/security/20130219/8007688.patch \
+	patches/security/20130304/8007014.patch \
+	patches/security/20130304/8007675.patch \
+	patches/security/20130304/declaration_correction.patch
 
 if !WITH_ALT_HSBUILD
 SECURITY_PATCHES += \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/20130304/8007014.patch	Thu Mar 07 13:16:01 2013 +0000
@@ -0,0 +1,477 @@
+# HG changeset patch
+# User bae
+# Date 1360857111 -14400
+# Node ID 44c99b68e36c57648829320843fbc77cf2d4c4d1
+# Parent  b8b3916e20ed651fa6ad9da6ae96b2548a13f96c
+8007014: Improve image handling
+Reviewed-by: prr, mschoene, jgodinez
+
+diff --git a/src/share/classes/sun/awt/image/ByteComponentRaster.java b/src/share/classes/sun/awt/image/ByteComponentRaster.java
+--- openjdk/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java
++++ openjdk/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java
+@@ -868,6 +868,15 @@
+      * 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,13 +914,14 @@
+         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;
+             }
+diff --git a/src/share/classes/sun/awt/image/BytePackedRaster.java b/src/share/classes/sun/awt/image/BytePackedRaster.java
+--- openjdk/jdk/src/share/classes/sun/awt/image/BytePackedRaster.java
++++ openjdk/jdk/src/share/classes/sun/awt/image/BytePackedRaster.java
+@@ -1368,11 +1368,35 @@
+             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");
+         }
+diff --git a/src/share/classes/sun/awt/image/IntegerComponentRaster.java b/src/share/classes/sun/awt/image/IntegerComponentRaster.java
+--- openjdk/jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java
++++ openjdk/jdk/src/share/classes/sun/awt/image/IntegerComponentRaster.java
+@@ -208,7 +208,7 @@
+                                             " SinglePixelPackedSampleModel");
+         }
+ 
+-        verify(false);
++        verify();
+     }
+ 
+ 
+@@ -629,16 +629,26 @@
+     }
+ 
+     /**
+-     * 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.
++     * 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.
+      */
+-    private void verify (boolean strictCheck) {
++    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 @@
+         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 + " )");
+         }
+     }
+ 
+diff --git a/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java b/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java
+--- openjdk/jdk/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java
++++ openjdk/jdk/src/share/classes/sun/awt/image/IntegerInterleavedRaster.java
+@@ -151,7 +151,7 @@
+             throw new RasterFormatException("IntegerInterleavedRasters must have"+
+                                             " SinglePixelPackedSampleModel");
+         }
+-        verify(false);
++        verify();
+     }
+ 
+ 
+@@ -540,31 +540,6 @@
+         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
+diff --git a/src/share/classes/sun/awt/image/ShortComponentRaster.java b/src/share/classes/sun/awt/image/ShortComponentRaster.java
+--- openjdk/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java
++++ openjdk/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java
+@@ -802,6 +802,15 @@
+      * 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,12 +848,13 @@
+         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;
+             }
+diff --git a/src/share/native/sun/awt/image/awt_parseImage.c b/src/share/native/sun/awt/image/awt_parseImage.c
+--- openjdk/jdk/src/share/native/sun/awt/image/awt_parseImage.c
++++ openjdk/jdk/src/share/native/sun/awt/image/awt_parseImage.c
+@@ -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);
+ 
+diff --git a/src/share/native/sun/awt/medialib/awt_ImagingLib.c b/src/share/native/sun/awt/medialib/awt_ImagingLib.c
+--- openjdk/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c
++++ openjdk/jdk/src/share/native/sun/awt/medialib/awt_ImagingLib.c
+@@ -42,6 +42,7 @@
+ #include "awt_Mlib.h"
+ #include "gdefs.h"
+ #include "safe_alloc.h"
++#include "safe_math.h"
+ 
+ /***************************************************************************
+  *                               Definitions                               *
+@@ -1970,13 +1971,23 @@
+     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,
+@@ -2106,8 +2117,14 @@
+     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) {
+@@ -2357,6 +2374,9 @@
+     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);
+@@ -2365,6 +2385,9 @@
+         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);
+@@ -2374,6 +2397,9 @@
+         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);
+diff --git a/src/share/native/sun/awt/medialib/mlib_ImageCreate.c b/src/share/native/sun/awt/medialib/mlib_ImageCreate.c
+--- openjdk/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c
++++ openjdk/jdk/src/share/native/sun/awt/medialib/mlib_ImageCreate.c
+@@ -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,28 +248,50 @@
+     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;
++  }
++
+   data = mlib_malloc(wb * height);
+   if (data == NULL) {
+     return NULL;
+diff --git a/src/share/native/sun/awt/medialib/safe_alloc.h b/src/share/native/sun/awt/medialib/safe_alloc.h
+--- openjdk/jdk/src/share/native/sun/awt/medialib/safe_alloc.h
++++ openjdk/jdk/src/share/native/sun/awt/medialib/safe_alloc.h
+@@ -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__
+diff --git a/src/share/native/sun/awt/medialib/safe_math.h b/src/share/native/sun/awt/medialib/safe_math.h
+new file mode 100644
+--- /dev/null
++++ openjdk/jdk/src/share/native/sun/awt/medialib/safe_math.h
+@@ -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__
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/20130304/8007675.patch	Thu Mar 07 13:16:01 2013 +0000
@@ -0,0 +1,416 @@
+# HG changeset patch
+# User bae
+# Date 1362257363 -10800
+# Node ID 9714f53ef17344fbcb6dc2249a7b238e6292f726
+# Parent  44c99b68e36c57648829320843fbc77cf2d4c4d1
+8007675: Improve color conversion
+Reviewed-by: prr, jgodinez
+
+diff --git a/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java b/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java
+--- openjdk/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java
++++ openjdk/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSImageLayout.java
+@@ -99,50 +99,75 @@
+     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;
++        dataArrayLength = data.length;
++
++        verify();
+     }
+ 
+-    public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize) {
++    public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize)
++            throws ImageLayoutException
++    {
+         this(np, pixelType, pixelSize);
+         dataType = DT_SHORT;
+         dataArray = data;
++        dataArrayLength = 2 * data.length;
++
++        verify();
+     }
+ 
+-    public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize) {
++    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;
++        dataArrayLength = 8 * data.length;
++
++        verify();
+     }
+ 
+-    public LCMSImageLayout(BufferedImage image) {
++    public LCMSImageLayout(BufferedImage image) throws ImageLayoutException {
+         ShortComponentRaster shortRaster;
+         IntegerComponentRaster intRaster;
+         ByteComponentRaster byteRaster;
+@@ -186,9 +211,13 @@
+             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 @@
+             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 @@
+                 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 @@
+         }
+         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);
++        }
++    }
+ }
+diff --git a/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java b/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java
+--- openjdk/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java
++++ openjdk/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java
+@@ -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 {
+@@ -116,8 +117,12 @@
+             LCMSImageLayout.isSupported(dst))
+         {
+             synchronized(this) {
+-                LCMS.colorConvert(this, new LCMSImageLayout(src),
+-                                  new LCMSImageLayout(dst));
++                try {
++                    LCMS.colorConvert(this, new LCMSImageLayout(src),
++                                      new LCMSImageLayout(dst));
++                } catch (ImageLayoutException e) {
++                    throw new CMMException("Unable to convert images");
++                }
+             }
+             return;
+         }
+@@ -177,14 +182,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
+@@ -234,16 +243,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
+@@ -353,16 +365,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
+@@ -447,15 +462,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
+@@ -489,16 +507,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
+@@ -540,15 +562,19 @@
+             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);
++        } catch (ImageLayoutException e) {
++            throw new CMMException("Unable to convert data");
++        }
+ 
+         synchronized(this) {
+             LCMS.colorConvert(this, srcIL, dstIL);
+@@ -562,15 +588,19 @@
+             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());
++        } catch (ImageLayoutException e) {
++            throw new CMMException("Unable to convert data");
++        }
+ 
+         synchronized(this) {
+             LCMS.colorConvert(this, srcIL, dstIL);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/security/20130304/declaration_correction.patch	Thu Mar 07 13:16:01 2013 +0000
@@ -0,0 +1,46 @@
+--- openjdk.orig/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java	2013-03-07 12:17:44.080685352 +0000
++++ openjdk/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMSTransform.java	2013-03-07 12:39:57.202035054 +0000
+@@ -557,18 +557,19 @@
+     /* the number of colors is (size of the array) / (number of input/output
+        components */
+     public short[] colorConvert(short[] src, short[] dst) {
++        LCMSImageLayout srcIL, dstIL;
+ 
+         if (dst == null) {
+             dst = new short [(src.length/getNumInComponents())*getNumOutComponents()];
+         }
+ 
+         try {
+-            LCMSImageLayout srcIL = new LCMSImageLayout(
++            srcIL = new LCMSImageLayout(
+                 src, src.length/getNumInComponents(),
+                 LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+                 LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
+ 
+-            LCMSImageLayout dstIL = new LCMSImageLayout(
++            dstIL = new LCMSImageLayout(
+                 dst, dst.length/getNumOutComponents(),
+                 LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+                 LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
+@@ -584,17 +585,19 @@
+     }
+ 
+     public byte[] colorConvert(byte[] src, byte[] dst) {
++        LCMSImageLayout srcIL, dstIL;
++
+         if (dst == null) {
+             dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()];
+         }
+ 
+         try {
+-            LCMSImageLayout srcIL = new LCMSImageLayout(
++            srcIL = new LCMSImageLayout(
+                 src, src.length/getNumInComponents(),
+                 LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
+                 LCMSImageLayout.BYTES_SH(1), getNumInComponents());
+ 
+-            LCMSImageLayout dstIL = new LCMSImageLayout(
++            dstIL = new LCMSImageLayout(
+                 dst, dst.length/getNumOutComponents(),
+                 LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
+                 LCMSImageLayout.BYTES_SH(1), getNumOutComponents());