diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java index 56c21e18548b5..cd48d6422f5d4 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2022, 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 @@ -324,8 +324,11 @@ public void write(IIOMetadata streamMetadata, } if (!canEncodeImage(compressionType, colorModel, sampleModel)) { - throw new IOException("Image can not be encoded with compression type " - + BMPCompressionTypes.getName(compressionType)); + throw new + IOException("Image can not be encoded with compression type " + + BMPCompressionTypes.getName(compressionType) + + " and " + colorModel.getPixelSize() + + " bits per pixel"); } byte[] r = null, g = null, b = null, a = null; @@ -1452,8 +1455,11 @@ protected boolean canEncodeImage(int compression, ImageTypeSpecifier imgType) { if (!spi.canEncodeImage(imgType)) { return false; } - int biType = imgType.getBufferedImageType(); int bpp = imgType.getColorModel().getPixelSize(); + if (bpp != 0 && bpp != 1 && bpp != 4 && bpp != 8 && + bpp != 15 && bpp != 16 && bpp != 24 && bpp != 32) { + return false; + } if (compressionType == BI_RLE4 && bpp != 4) { // only 4bpp images can be encoded as BI_RLE4 return false; diff --git a/test/jdk/javax/imageio/plugins/bmp/BMPBitsPerPixelTest.java b/test/jdk/javax/imageio/plugins/bmp/BMPBitsPerPixelTest.java new file mode 100644 index 0000000000000..12d2052f80c73 --- /dev/null +++ b/test/jdk/javax/imageio/plugins/bmp/BMPBitsPerPixelTest.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022, 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. + * + * 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. + */ + +/* + * @test + * @bug 8278086 + * @summary Tests that writing invalid bits per pixel image in BMP + throws IOException + */ + +import java.awt.image.BufferedImage; +import java.awt.image.IndexColorModel; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +public class BMPBitsPerPixelTest { + + public static void main(String[] args) { + test(1, false); + test(2, true); + test(3, true); + test(4, false); + test(5, true); + test(6, true); + test(7, true); + test(8, false); + } + + public static void test(int bpp, boolean shouldThrowException) { + int palettes = (int)Math.pow(2, bpp); + byte[] r = new byte[palettes]; + byte[] g = new byte[palettes]; + byte[] b = new byte[palettes]; + boolean exceptionThrown = false; + try { + IndexColorModel cm = new IndexColorModel(bpp, palettes, r, g, b); + int imageType = BufferedImage.TYPE_BYTE_BINARY; + if (bpp > 4) { + imageType = BufferedImage.TYPE_BYTE_INDEXED; + } + BufferedImage img = new + BufferedImage(10, 10, imageType, (IndexColorModel)cm); + File file = File.createTempFile("test", ".bmp", new File(".")); + file.deleteOnExit(); + ImageIO.write(img, "BMP", file); + } catch (IOException e) { + exceptionThrown = true; + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Unexpected exception: " + e); + } + + if (shouldThrowException && !exceptionThrown) { + throw new RuntimeException("IOException was not caught."); + } else if (!shouldThrowException && exceptionThrown) { + throw new RuntimeException("IOException should not be thrown."); + } else { + System.out.println("Test PASSED."); + } + } +}