From c73319354399596ab2b9aab0a7f62e8fa0ab9365 Mon Sep 17 00:00:00 2001 From: Masanori Yano Date: Wed, 1 Dec 2021 06:18:44 +0000 Subject: [PATCH] 8262297: ImageIO.write() method will throw IndexOutOfBoundsException Reviewed-by: serb, jdv --- .../imageio/plugins/bmp/BMPImageWriter.java | 8 +- .../plugins/bmp/BMPBitsPerPixelTest.java | 80 +++++++++++++++++++ 2 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 test/jdk/javax/imageio/plugins/bmp/BMPBitsPerPixelTest.java 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 6a020ae9343..1773cf9ba98 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, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2021, 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 @@ -327,7 +327,8 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { if (!canEncodeImage(compressionType, colorModel, sampleModel)) { throw new IOException("Image can not be encoded with compression type " - + BMPCompressionTypes.getName(compressionType)); + + BMPCompressionTypes.getName(compressionType) + + " and " + colorModel.getPixelSize() + " bits per pixel"); } byte[] r = null, g = null, b = null, a = null; @@ -1456,6 +1457,9 @@ public class BMPImageWriter extends ImageWriter implements BMPConstants { } int biType = imgType.getBufferedImageType(); int bpp = imgType.getColorModel().getPixelSize(); + if (bpp != 0 && bpp != 1 && bpp != 4 && bpp != 8 && 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 00000000000..6708eb9f670 --- /dev/null +++ b/test/jdk/javax/imageio/plugins/bmp/BMPBitsPerPixelTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021, 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 8262297 + * @summary Test that writing invalid bit per pixel image 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."); + } + } +}