diff --git a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReader.java b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReader.java index c40070fd..d78e5d9e 100755 --- a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReader.java +++ b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReader.java @@ -30,22 +30,6 @@ package com.twelvemonkeys.imageio.plugins.bmp; -import com.twelvemonkeys.imageio.ImageReaderBase; -import com.twelvemonkeys.imageio.stream.SubImageInputStream; -import com.twelvemonkeys.imageio.util.IIOUtil; -import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers; -import com.twelvemonkeys.imageio.util.ProgressListenerBase; -import com.twelvemonkeys.io.LittleEndianDataInputStream; -import com.twelvemonkeys.io.enc.DecoderStream; -import com.twelvemonkeys.xml.XMLSerializer; - -import javax.imageio.*; -import javax.imageio.event.IIOReadUpdateListener; -import javax.imageio.event.IIOReadWarningListener; -import javax.imageio.metadata.IIOMetadata; -import javax.imageio.metadata.IIOMetadataFormatImpl; -import javax.imageio.spi.ImageReaderSpi; -import javax.imageio.stream.ImageInputStream; import java.awt.*; import java.awt.color.ColorSpace; import java.awt.image.*; @@ -56,6 +40,27 @@ import java.nio.ByteOrder; import java.util.Arrays; import java.util.Iterator; +import javax.imageio.IIOException; +import javax.imageio.ImageIO; +import javax.imageio.ImageReadParam; +import javax.imageio.ImageReader; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.event.IIOReadUpdateListener; +import javax.imageio.event.IIOReadWarningListener; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.metadata.IIOMetadataFormatImpl; +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.stream.ImageInputStream; + +import com.twelvemonkeys.imageio.ImageReaderBase; +import com.twelvemonkeys.imageio.stream.SubImageInputStream; +import com.twelvemonkeys.imageio.util.IIOUtil; +import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers; +import com.twelvemonkeys.imageio.util.ProgressListenerBase; +import com.twelvemonkeys.io.LittleEndianDataInputStream; +import com.twelvemonkeys.io.enc.DecoderStream; +import com.twelvemonkeys.xml.XMLSerializer; + /** * ImageReader for Microsoft Windows Bitmap (BMP) format. * @@ -125,6 +130,10 @@ public final class BMPImageReader extends ImageReaderBase { // Read DIB header header = DIBHeader.read(imageInput); + + if (pixelOffset < header.size + DIB.BMP_FILE_HEADER_SIZE) { + throw new IIOException("Invalid pixel offset: " + pixelOffset); + } } } diff --git a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapDescriptor.java b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapDescriptor.java index 82c09384..ff8e80b7 100755 --- a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapDescriptor.java +++ b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapDescriptor.java @@ -29,9 +29,10 @@ */ package com.twelvemonkeys.imageio.plugins.bmp; -import com.twelvemonkeys.lang.Validate; +import static com.twelvemonkeys.lang.Validate.notNull; import java.awt.image.BufferedImage; +import java.io.IOException; /** * Describes a bitmap structure. @@ -47,14 +48,11 @@ abstract class BitmapDescriptor { protected BitmapMask mask; public BitmapDescriptor(final DirectoryEntry pEntry, final DIBHeader pHeader) { - Validate.notNull(pEntry, "entry"); - Validate.notNull(pHeader, "header"); - - entry = pEntry; - header = pHeader; + entry = notNull(pEntry, "entry");; + header = notNull(pHeader, "header"); } - abstract public BufferedImage getImage(); + abstract public BufferedImage getImage() throws IOException; public final int getWidth() { return entry.getWidth(); diff --git a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapIndexed.java b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapIndexed.java index 44e34d15..0d6417af 100755 --- a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapIndexed.java +++ b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapIndexed.java @@ -163,6 +163,7 @@ class BitmapIndexed extends BitmapDescriptor { return transparent; } + @Override public BufferedImage getImage() { if (image == null) { image = createImageIndexed(); diff --git a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapRGB.java b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapRGB.java index dfe6f55b..d3f74d7c 100755 --- a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapRGB.java +++ b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapRGB.java @@ -46,6 +46,7 @@ class BitmapRGB extends BitmapDescriptor { super(pEntry, pHeader); } + @Override public BufferedImage getImage() { // Test is mask != null rather than hasMask(), as 32 bit (w/alpha) // might still have bitmask, but we don't read or use it. diff --git a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapUnsupported.java b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapUnsupported.java index 6db18431..2c070378 100755 --- a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapUnsupported.java +++ b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/BitmapUnsupported.java @@ -31,6 +31,9 @@ package com.twelvemonkeys.imageio.plugins.bmp; import java.awt.image.BufferedImage; +import java.io.IOException; + +import javax.imageio.IIOException; /** * Represents bitmap structures we can't read. @@ -42,13 +45,14 @@ import java.awt.image.BufferedImage; class BitmapUnsupported extends BitmapDescriptor { private String message; - public BitmapUnsupported(final DirectoryEntry pEntry, final String pMessage) { - super(pEntry, null); + public BitmapUnsupported(final DirectoryEntry pEntry, DIBHeader header, final String pMessage) { + super(pEntry, header); message = pMessage; } - public BufferedImage getImage() { - throw new IllegalStateException(message); + @Override + public BufferedImage getImage() throws IOException { + throw new IIOException(message); } } diff --git a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/DIBHeader.java b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/DIBHeader.java index d58586bd..f4505426 100755 --- a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/DIBHeader.java +++ b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/DIBHeader.java @@ -30,11 +30,12 @@ package com.twelvemonkeys.imageio.plugins.bmp; -import javax.imageio.IIOException; import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; +import javax.imageio.IIOException; + /** * Represents the DIB (Device Independent Bitmap) Information header structure. * @@ -213,7 +214,7 @@ abstract class DIBHeader { // NOTE: Unlike all other headers, width and height are unsigned SHORT values (16 bit)! width = pStream.readUnsignedShort(); - height = pStream.readUnsignedShort(); + height = pStream.readShort(); if (height < 0) { height = -height; @@ -240,6 +241,7 @@ abstract class DIBHeader { * @see OS/2 Bitmap File Format Summary */ static final class BitmapCoreHeaderV2 extends DIBHeader { + @SuppressWarnings("unused") protected void read(final int pSize, final DataInput pStream) throws IOException { if (pSize != DIB.OS2_V2_HEADER_SIZE && pSize != DIB.OS2_V2_HEADER_16_SIZE) { throw new IIOException(String.format("Size: %s !=: %s", pSize, DIB.OS2_V2_HEADER_SIZE)); diff --git a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/DIBImageReader.java b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/DIBImageReader.java index 7a678731..ed6c1542 100644 --- a/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/DIBImageReader.java +++ b/imageio/imageio-bmp/src/main/java/com/twelvemonkeys/imageio/plugins/bmp/DIBImageReader.java @@ -30,16 +30,6 @@ package com.twelvemonkeys.imageio.plugins.bmp; -import com.twelvemonkeys.image.ImageUtil; -import com.twelvemonkeys.imageio.ImageReaderBase; -import com.twelvemonkeys.imageio.stream.SubImageInputStream; -import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers; -import com.twelvemonkeys.util.WeakWeakMap; - -import javax.imageio.*; -import javax.imageio.spi.ImageReaderSpi; -import javax.imageio.stream.ImageInputStream; -import javax.swing.*; import java.awt.*; import java.awt.color.ColorSpace; import java.awt.event.WindowAdapter; @@ -48,8 +38,26 @@ import java.awt.image.*; import java.io.File; import java.io.IOException; import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.Iterator; import java.util.List; -import java.util.*; +import java.util.Map; +import java.util.WeakHashMap; + +import javax.imageio.IIOException; +import javax.imageio.ImageIO; +import javax.imageio.ImageReadParam; +import javax.imageio.ImageReader; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.stream.ImageInputStream; +import javax.swing.*; + +import com.twelvemonkeys.image.ImageUtil; +import com.twelvemonkeys.imageio.ImageReaderBase; +import com.twelvemonkeys.imageio.stream.SubImageInputStream; +import com.twelvemonkeys.imageio.util.ImageTypeSpecifiers; +import com.twelvemonkeys.util.WeakWeakMap; /** * ImageReader for Microsoft Windows ICO (icon) format. @@ -287,7 +295,7 @@ abstract class DIBImageReader extends ImageReaderBase { // TODO: Support this, it's already in the BMP reader, spec allows RLE4 and RLE8 if (header.getCompression() != DIB.COMPRESSION_RGB) { - descriptor = new BitmapUnsupported(pEntry, String.format("Unsupported compression: %d", header.getCompression())); + descriptor = new BitmapUnsupported(pEntry, header, String.format("Unsupported compression: %d", header.getCompression())); } else { int bitCount = header.getBitCount(); @@ -315,7 +323,7 @@ abstract class DIBImageReader extends ImageReaderBase { break; default: - descriptor = new BitmapUnsupported(pEntry, String.format("Unsupported bit count %d", bitCount)); + descriptor = new BitmapUnsupported(pEntry, header, String.format("Unsupported bit count %d", bitCount)); } } diff --git a/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReaderTest.java b/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReaderTest.java index ccb4c5b7..1e244f99 100755 --- a/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReaderTest.java +++ b/imageio/imageio-bmp/src/test/java/com/twelvemonkeys/imageio/plugins/bmp/BMPImageReaderTest.java @@ -30,20 +30,14 @@ package com.twelvemonkeys.imageio.plugins.bmp; -import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest; -import com.twelvemonkeys.xml.XMLSerializer; +import static org.junit.Assert.*; +import static org.junit.Assume.assumeNoException; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.inOrder; +import static org.mockito.Mockito.mock; -import org.junit.Ignore; -import org.junit.Test; -import org.mockito.InOrder; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; - -import javax.imageio.*; -import javax.imageio.event.IIOReadProgressListener; -import javax.imageio.metadata.IIOMetadata; -import javax.imageio.metadata.IIOMetadataNode; -import javax.imageio.spi.ImageReaderSpi; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; @@ -55,11 +49,24 @@ import java.util.Collections; import java.util.Iterator; import java.util.List; -import static org.junit.Assert.*; -import static org.junit.Assume.assumeNoException; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.*; +import javax.imageio.IIOException; +import javax.imageio.ImageIO; +import javax.imageio.ImageReadParam; +import javax.imageio.ImageReader; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.event.IIOReadProgressListener; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.metadata.IIOMetadataNode; +import javax.imageio.spi.ImageReaderSpi; + +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.InOrder; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.twelvemonkeys.imageio.util.ImageReaderAbstractTest; +import com.twelvemonkeys.xml.XMLSerializer; /** * BMPImageReaderTest @@ -175,7 +182,7 @@ public class BMPImageReaderTest extends ImageReaderAbstractTest ImageTypeSpecifier rawType = reader.getRawImageType(0); - // As the JPEGImageReader we delegate to returns null for YCbCr, we'll have to do the same + // As the JPEGImageReader we delegate to may return null for YCbCr, we'll have to do the same if (rawType == null && data.getInput().toString().contains("jpeg")) { continue; }