diff options
-rw-r--r-- | openjdk/java/awt/image/BufferedImage.java | 82 | ||||
-rw-r--r-- | openjdk/java/awt/image/IndexColorModel.java | 10 | ||||
-rw-r--r-- | openjdk/java/io/ObjectStreamField.java | 10 | ||||
-rw-r--r-- | openjdk/sun/awt/image/ByteComponentRaster.java | 91 | ||||
-rw-r--r-- | openjdk/sun/awt/image/BytePackedRaster.java | 27 | ||||
-rw-r--r-- | openjdk/sun/awt/image/IntegerComponentRaster.java | 82 | ||||
-rw-r--r-- | openjdk/sun/awt/image/ShortComponentRaster.java | 90 | ||||
-rw-r--r-- | runtime/DynamicTypeWrapper.cs | 4 |
8 files changed, 306 insertions, 90 deletions
diff --git a/openjdk/java/awt/image/BufferedImage.java b/openjdk/java/awt/image/BufferedImage.java index 33c9c270..ee00c6a8 100644 --- a/openjdk/java/awt/image/BufferedImage.java +++ b/openjdk/java/awt/image/BufferedImage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2008, 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 @@ -38,6 +38,8 @@ import java.awt.geom.Rectangle2D; import java.awt.geom.Point2D; import java.awt.Point; import java.awt.Rectangle; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.Hashtable; import java.util.Vector; @@ -425,6 +427,7 @@ public class BufferedImage extends java.awt.Image colorModel = cm; this.imageType = imageType; this.currentBuffer = BUFFER_RASTER; + raster.getDataBuffer().setImage( this ); } /** @@ -469,7 +472,7 @@ public class BufferedImage extends java.awt.Image WritableRaster raster, boolean isRasterPremultiplied, Hashtable<?,?> properties) { - + if (!cm.isCompatibleRaster(raster)) { throw new IllegalArgumentException("Raster "+raster+ @@ -486,10 +489,12 @@ public class BufferedImage extends java.awt.Image colorModel = cm; this.raster = raster; + raster.getDataBuffer().setImage( this ); this.currentBuffer = BUFFER_RASTER; this.properties = properties; int numBands = raster.getNumBands(); boolean isAlphaPre = cm.isAlphaPremultiplied(); + final boolean isStandard = isStandard(cm, raster); ColorSpace cs; // Force the raster data alpha state to match the premultiplied @@ -500,8 +505,9 @@ public class BufferedImage extends java.awt.Image cs = cm.getColorSpace(); int csType = cs.getType(); if (csType != ColorSpace.TYPE_RGB) { - if (csType == ColorSpace.TYPE_GRAY - && cm instanceof ComponentColorModel) { + if (csType == ColorSpace.TYPE_GRAY && + isStandard && + cm instanceof ComponentColorModel) { // Check if this might be a child raster (fix for bug 4240596) if (sm instanceof ComponentSampleModel && ((ComponentSampleModel)sm).getPixelStride() != numBands) { @@ -531,6 +537,7 @@ public class BufferedImage extends java.awt.Image // are correct int pixSize = cm.getPixelSize(); if (iraster.getPixelStride() == 1 && + isStandard && cm instanceof DirectColorModel && (pixSize == 32 || pixSize == 24)) { @@ -563,6 +570,7 @@ public class BufferedImage extends java.awt.Image } // if (iraster.getPixelStride() == 1 } // ((raster instanceof IntegerComponentRaster) && else if ((cm instanceof IndexColorModel) && (numBands == 1) && + isStandard && (!cm.hasAlpha() || !isAlphaPre)) { IndexColorModel icm = (IndexColorModel) cm; @@ -580,6 +588,7 @@ public class BufferedImage extends java.awt.Image } // else if (cm instanceof IndexColorModel) && (numBands == 1)) else if ((raster instanceof ShortComponentRaster) && (cm instanceof DirectColorModel) + && isStandard && (numBands == 3) && !cm.hasAlpha()) { @@ -599,6 +608,7 @@ public class BufferedImage extends java.awt.Image } // else if ((cm instanceof IndexColorModel) && (numBands == 1)) else if ((raster instanceof ByteComponentRaster) && (cm instanceof ComponentColorModel) + && isStandard && (raster.getSampleModel() instanceof PixelInterleavedSampleModel) && (numBands == 3 || numBands == 4)) { @@ -623,14 +633,15 @@ public class BufferedImage extends java.awt.Image } } if (is8bit && + braster.getPixelStride() == numBands && offs[0] == numBands-1 && offs[1] == numBands-2 && offs[2] == numBands-3) { - if (numBands == 3) { + if (numBands == 3 && !ccm.hasAlpha()) { imageType = TYPE_3BYTE_BGR; } - else if (offs[3] == 0) { + else if (offs[3] == 0 && ccm.hasAlpha()) { imageType = (isAlphaPre ? TYPE_4BYTE_ABGR_PRE : TYPE_4BYTE_ABGR); @@ -638,6 +649,27 @@ public class BufferedImage extends java.awt.Image } } // else if ((raster instanceof ByteComponentRaster) && } + + private static boolean isStandard(ColorModel cm, WritableRaster wr) { + final Class<? extends ColorModel> cmClass = cm.getClass(); + final Class<? extends WritableRaster> wrClass = wr.getClass(); + final Class<? extends SampleModel> smClass = wr.getSampleModel().getClass(); + + final PrivilegedAction<Boolean> checkClassLoadersAction = + new PrivilegedAction<Boolean>() + { + + @Override + public Boolean run() { + final ClassLoader std = System.class.getClassLoader(); + + return (cmClass.getClassLoader() == std) && + (smClass.getClassLoader() == std) && + (wrClass.getClassLoader() == std); + } + }; + return AccessController.doPrivileged(checkClassLoadersAction); + } /** * Get the .NET Bitmap object. @@ -649,6 +681,23 @@ public class BufferedImage extends java.awt.Image } /** + * Switch to the BITMAP buffer and invalidate the RASTER buffer before a graphics operation. + */ + final void toBitmap(){ + raster2Bitmap(); + currentBuffer = BUFFER_BITMAP; + } + + /** + * Switch to the RASTER buffer and invalidate the BITMAP buffer before a graphics operation. + */ + @cli.IKVM.Attributes.HideFromJavaAttribute.Annotation + final void toRaster() { + bitmap2Raster(); + currentBuffer = BUFFER_RASTER; + } + + /** * This Implementation of BufferedImage has 2 different Buffer, * a Java WritableRaster and a .NET Bitmap. * This method convert a Java WritableRaster to a .NET Bitmap if needed. @@ -714,21 +763,23 @@ public class BufferedImage extends java.awt.Image } if(raster == null){ raster = createRaster(width, height); + raster.getDataBuffer().setImage( this ); } + this.currentBuffer = BUFFER_BOTH; switch (getType()){ case TYPE_INT_ARGB: copyFromBitmap(bitmap, ((DataBufferInt)raster.getDataBuffer()).getData()); break; default: + Object pixel = colorModel.getDataElements( 0, null ); //allocate a buffer for the follow loop for( int y = 0; y<height; y++){ for(int x = 0; x<width; x++){ int rgb = bitmap.GetPixel(x, y).ToArgb(); - raster.setDataElements(x, y, colorModel.getDataElements(rgb, null)); + raster.setDataElements(x, y, colorModel.getDataElements(rgb, pixel)); } } } - this.currentBuffer = BUFFER_BOTH; } } @@ -1192,7 +1243,7 @@ public class BufferedImage extends java.awt.Image * pixels for this image. * @see ImageProducer */ - public ImageProducer getSource(){ + public ImageProducer getSource() { if(currentBuffer != BUFFER_RASTER){ synchronized( bitmap ) { int width = bitmap.get_Width(); @@ -1281,10 +1332,9 @@ public class BufferedImage extends java.awt.Image * image. */ public Graphics2D createGraphics() { - ikvm.awt.IkvmToolkit toolkit = ikvm.awt.IkvmToolkit.DefaultToolkit.get(); - raster2Bitmap(); - this.currentBuffer = BUFFER_BITMAP; - return toolkit.createGraphics( bitmap ); + GraphicsEnvironment env = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + return env.createGraphics(this); } /** @@ -1346,9 +1396,9 @@ public class BufferedImage extends java.awt.Image * <code>BufferedImage</code>. */ public String toString() { - return new String("BufferedImage@"+Integer.toHexString(hashCode()) - +": type = "+imageType - +" "+colorModel+" "+raster); + return "BufferedImage@"+Integer.toHexString(hashCode()) + +": type = "+imageType + +" "+colorModel+" "+raster; } /** diff --git a/openjdk/java/awt/image/IndexColorModel.java b/openjdk/java/awt/image/IndexColorModel.java index 34ab79d6..b76f924c 100644 --- a/openjdk/java/awt/image/IndexColorModel.java +++ b/openjdk/java/awt/image/IndexColorModel.java @@ -618,7 +618,7 @@ public class IndexColorModel extends ColorModel { } nBits[0] = nBits[1] = nBits[2] = 8; } - return nBits; + return nBits.clone(); } /** @@ -1501,6 +1501,14 @@ public class IndexColorModel extends ColorModel { } /** + * Disposes of system resources associated with this + * <code>ColorModel</code> once this <code>ColorModel</code> is no + * longer referenced. + */ + public void finalize() { + } + + /** * Returns the <code>String</code> representation of the contents of * this <code>ColorModel</code>object. * @return a <code>String</code> representing the contents of this diff --git a/openjdk/java/io/ObjectStreamField.java b/openjdk/java/io/ObjectStreamField.java index c2d1ffe1..1d7c2cdf 100644 --- a/openjdk/java/io/ObjectStreamField.java +++ b/openjdk/java/io/ObjectStreamField.java @@ -26,6 +26,9 @@ package java.io; import java.lang.reflect.Field; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; +import sun.reflect.misc.ReflectUtil; /** * A description of a Serializable field from a Serializable class. An array @@ -163,7 +166,14 @@ public class ObjectStreamField * @return a <code>Class</code> object representing the type of the * serializable field */ + @CallerSensitive public Class<?> getType() { + if (System.getSecurityManager() != null) { + Class<?> caller = Reflection.getCallerClass(); + if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), type.getClassLoader())) { + ReflectUtil.checkPackageAccess(type); + } + } return type; } diff --git a/openjdk/sun/awt/image/ByteComponentRaster.java b/openjdk/sun/awt/image/ByteComponentRaster.java index 912542a7..133a6d68 100644 --- a/openjdk/sun/awt/image/ByteComponentRaster.java +++ b/openjdk/sun/awt/image/ByteComponentRaster.java @@ -191,7 +191,7 @@ public class ByteComponentRaster extends SunWritableRaster { } this.bandOffset = this.dataOffsets[0]; - verify(false); + verify(); } /** @@ -850,38 +850,79 @@ public class ByteComponentRaster extends SunWritableRaster { } /** - * 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) { - // Make sure data for Raster is in a legal range - for (int i=0; i < dataOffsets.length; i++) { + 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+ - "("+dataOffsets[i]+ - ") must be >= 0"); + throw new RasterFormatException("Data offsets for band " + i + + "(" + dataOffsets[i] + + ") must be >= 0"); } } - int maxSize = 0; - int size; + // we can be sure that width and height are greater than 0 + if (scanlineStride < 0 || + scanlineStride > (Integer.MAX_VALUE / height) || + scanlineStride > data.length) + { + // integer overflow + throw new RasterFormatException("Incorrect scanline stride: " + + scanlineStride); + } + int lastScanOffset = (height - 1) * scanlineStride; + + if (pixelStride < 0 || + pixelStride > (Integer.MAX_VALUE / width) || + pixelStride > data.length) + { + // 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; + + int index; + int maxIndex = 0; + for (int i = 0; i < numDataElements; i++) { + if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) { + throw new RasterFormatException("Incorrect band offset: " + + dataOffsets[i]); + + } + + index = lastPixelOffset + dataOffsets[i]; - for (int i=0; i < numDataElements; i++) { - size = (height-1)*scanlineStride + (width-1)*pixelStride + - dataOffsets[i]; - if (size > maxSize) { - maxSize = size; + if (index > maxIndex) { + maxIndex = index; } } - if (data.length < maxSize) { - throw new RasterFormatException("Data array too small (should be "+ - maxSize+" )"); + if (data.length <= maxIndex) { + throw new RasterFormatException("Data array too small (should be > " + + maxIndex + " )"); } } diff --git a/openjdk/sun/awt/image/BytePackedRaster.java b/openjdk/sun/awt/image/BytePackedRaster.java index 25c84f42..e9999c4c 100644 --- a/openjdk/sun/awt/image/BytePackedRaster.java +++ b/openjdk/sun/awt/image/BytePackedRaster.java @@ -1361,11 +1361,36 @@ public class BytePackedRaster extends SunWritableRaster { 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) || + scanlineStride > data.length) + { + 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/openjdk/sun/awt/image/IntegerComponentRaster.java b/openjdk/sun/awt/image/IntegerComponentRaster.java index 7c44c6f9..48d6f920 100644 --- a/openjdk/sun/awt/image/IntegerComponentRaster.java +++ b/openjdk/sun/awt/image/IntegerComponentRaster.java @@ -201,7 +201,7 @@ public class IntegerComponentRaster extends SunWritableRaster { " SinglePixelPackedSampleModel"); } - verify(false); + verify(); } @@ -622,35 +622,75 @@ public class IntegerComponentRaster extends SunWritableRaster { } /** - * 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"); } - int maxSize = 0; - int size; + // we can be sure that width and height are greater than 0 + if (scanlineStride < 0 || + scanlineStride > (Integer.MAX_VALUE / height) || + scanlineStride > data.length) + { + // integer overflow + throw new RasterFormatException("Incorrect scanline stride: " + + scanlineStride); + } + int lastScanOffset = (height - 1) * scanlineStride; + + if (pixelStride < 0 || + pixelStride > (Integer.MAX_VALUE / width) || + pixelStride > data.length) + { + // 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; + + int index; + int maxIndex = 0; + for (int i = 0; i < numDataElements; i++) { + if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) { + throw new RasterFormatException("Incorrect band offset: " + + dataOffsets[i]); + } + + index = lastPixelOffset + dataOffsets[i]; - for (int i=0; i < numDataElements; i++) { - size = (height-1)*scanlineStride + (width-1)*pixelStride + - dataOffsets[i]; - if (size > maxSize) { - maxSize = size; + if (index > maxIndex) { + maxIndex = index; } } - if (data.length < maxSize) { - throw new RasterFormatException("Data array too small (should be "+ - maxSize - +" but is "+data.length+" )"); + if (data.length <= maxIndex) { + throw new RasterFormatException("Data array too small (should be > " + + maxIndex + " )"); } } diff --git a/openjdk/sun/awt/image/ShortComponentRaster.java b/openjdk/sun/awt/image/ShortComponentRaster.java index f353fa8c..8ec545c5 100644 --- a/openjdk/sun/awt/image/ShortComponentRaster.java +++ b/openjdk/sun/awt/image/ShortComponentRaster.java @@ -191,7 +191,7 @@ public class ShortComponentRaster extends SunWritableRaster { } this.bandOffset = this.dataOffsets[0]; - verify(false); + verify(); } /** @@ -784,38 +784,78 @@ public class ShortComponentRaster extends SunWritableRaster { } /** - * 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) { - // Make sure data for Raster is in a legal range - for (int i=0; i < dataOffsets.length; i++) { + 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+ - "("+dataOffsets[i]+ - ") must be >= 0"); + throw new RasterFormatException("Data offsets for band " + i + + "(" + dataOffsets[i] + + ") must be >= 0"); } } - int maxSize = 0; - int size; + // we can be sure that width and height are greater than 0 + if (scanlineStride < 0 || + scanlineStride > (Integer.MAX_VALUE / height) || + scanlineStride > data.length) + { + // integer overflow + throw new RasterFormatException("Incorrect scanline stride: " + + scanlineStride); + } + int lastScanOffset = (height - 1) * scanlineStride; + + if (pixelStride < 0 || + pixelStride > (Integer.MAX_VALUE / width) || + pixelStride > data.length) + { + // 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; + + int index; + int maxIndex = 0; + for (int i = 0; i < numDataElements; i++) { + if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) { + throw new RasterFormatException("Incorrect band offset: " + + dataOffsets[i]); + } + + index = lastPixelOffset + dataOffsets[i]; - for (int i=0; i < numDataElements; i++) { - size = (height-1)*scanlineStride + (width-1)*pixelStride + - dataOffsets[i]; - if (size > maxSize) { - maxSize = size; + if (index > maxIndex) { + maxIndex = index; } } - if (data.length < maxSize) { - throw new RasterFormatException("Data array too small (should be "+ - maxSize+" )"); + if (data.length <= maxIndex) { + throw new RasterFormatException("Data array too small (should be > " + + maxIndex + " )"); } } diff --git a/runtime/DynamicTypeWrapper.cs b/runtime/DynamicTypeWrapper.cs index 5861d0c0..04fa043f 100644 --- a/runtime/DynamicTypeWrapper.cs +++ b/runtime/DynamicTypeWrapper.cs @@ -6463,7 +6463,9 @@ namespace IKVM.Internal internal static bool RequiresDynamicReflectionCallerClass(string classFile, string method, string signature) { return (classFile == "java.lang.ClassLoader" && method == "getParent" && signature == "()Ljava.lang.ClassLoader;") - || (classFile == "java.lang.Thread" && method == "getContextClassLoader" && signature == "()Ljava.lang.ClassLoader;"); + || (classFile == "java.lang.Thread" && method == "getContextClassLoader" && signature == "()Ljava.lang.ClassLoader;") + || (classFile == "java.io.ObjectStreamField" && method == "getType" && signature == "()Ljava.lang.Class;") + ; } #endif } |