From 98e64cffff24ec8b8abeb7afd121e58bc53ed034 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Tue, 26 Aug 2025 05:29:16 +0000 Subject: [PATCH] 8159055: Clarify handling of null and invalid image data for ImageIcon constructors and setImage method Reviewed-by: aivanov, prr, abhiscxk, kizune, serb --- .../share/classes/javax/swing/ImageIcon.java | 15 ++ .../javax/swing/ImageIcon/ImageIconTest.java | 150 ++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 test/jdk/javax/swing/ImageIcon/ImageIconTest.java diff --git a/src/java.desktop/share/classes/javax/swing/ImageIcon.java b/src/java.desktop/share/classes/javax/swing/ImageIcon.java index f53a02a405f..aaaa2dfd4a4 100644 --- a/src/java.desktop/share/classes/javax/swing/ImageIcon.java +++ b/src/java.desktop/share/classes/javax/swing/ImageIcon.java @@ -63,6 +63,14 @@ import sun.awt.AppContext; * of the image. * *

+ * If the image source parameter to a constructor or method is non-null, + * but does not reference valid accessible image data, + * no exceptions will be thrown but no image will be rendered + * even though {@link #getImage()} will return a non-null value, + * as the image will have no dimensions + * and {@link #getImageLoadStatus()} will report {@code MediaTracker.ERRORED}. + * + *

* For further information and examples of using image icons, see * How to Use Icons * in The Java Tutorial. @@ -178,6 +186,7 @@ public class ImageIcon implements Icon, Serializable, Accessible { * of the image. * @param location the URL for the image * @param description a brief textual description of the image + * @throws NullPointerException if {@code location} is {@code null} * @see #ImageIcon(String) */ public ImageIcon(URL location, String description) { @@ -197,6 +206,7 @@ public class ImageIcon implements Icon, Serializable, Accessible { * The icon's description is initialized to be * a string representation of the URL. * @param location the URL for the image + * @throws NullPointerException if {@code location} is {@code null} * @see #getDescription */ public ImageIcon (URL location) { @@ -207,6 +217,7 @@ public class ImageIcon implements Icon, Serializable, Accessible { * Creates an ImageIcon from the image. * @param image the image * @param description a brief textual description of the image + * @throws NullPointerException if {@code image} is {@code null} */ public ImageIcon(Image image, String description) { this.image = image; @@ -220,6 +231,7 @@ public class ImageIcon implements Icon, Serializable, Accessible { * If the image has a "comment" property that is a string, * then the string is used as the description of this icon. * @param image the image + * @throws NullPointerException if {@code image} is {@code null} * @see #getDescription * @see java.awt.Image#getProperty */ @@ -248,6 +260,7 @@ public class ImageIcon implements Icon, Serializable, Accessible { * @param imageData an array of pixels in an image format supported * by the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG * @param description a brief textual description of the image + * @throws NullPointerException if {@code imageData} is {@code null} * @see java.awt.Toolkit#createImage */ public ImageIcon (byte[] imageData, String description) { @@ -271,6 +284,7 @@ public class ImageIcon implements Icon, Serializable, Accessible { * * @param imageData an array of pixels in an image format supported by * the AWT Toolkit, such as GIF, JPEG, or (as of 1.3) PNG + * @throws NullPointerException if {@code imageData} is {@code null} * @see java.awt.Toolkit#createImage * @see #getDescription * @see java.awt.Image#getProperty @@ -375,6 +389,7 @@ public class ImageIcon implements Icon, Serializable, Accessible { /** * Sets the image displayed by this icon. * @param image the image + * @throws NullPointerException if {@code image} is {@code null} */ public void setImage(Image image) { this.image = image; diff --git a/test/jdk/javax/swing/ImageIcon/ImageIconTest.java b/test/jdk/javax/swing/ImageIcon/ImageIconTest.java new file mode 100644 index 00000000000..ac9b2b7da67 --- /dev/null +++ b/test/jdk/javax/swing/ImageIcon/ImageIconTest.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2025, 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 8159055 + * @summary Verifies null parameter and invalid data handling of + * ImageIcon constructors and setImage method + * @run main ImageIconTest + */ + +import java.io.File; +import java.io.FileOutputStream; +import java.net.URI; +import java.net.URL; +import java.util.Random; +import java.awt.Image; +import java.awt.Toolkit; +import javax.swing.ImageIcon; + +public class ImageIconTest { + + static enum ArgType { FILE, URL, BYTE_ARRAY, IMAGE, SET_IMAGE }; + static enum ArgVal { NULL, INVALID_DATA }; + + public static void main(String[] args) throws Exception { + + String imgName = "invalid.gif"; + byte[] invalidData = new byte[100]; + new Random().nextBytes(invalidData); + try (FileOutputStream fos = new FileOutputStream(imgName)) { + fos.write(invalidData); + } + File file = new File(imgName); + file.deleteOnExit(); + + for (ArgType a : ArgType.values()) { + for (final ArgVal v : ArgVal.values()) { + System.out.println("Testing for ArgType " + a + " for case " + v); + boolean expected = true; + boolean passed = false; + try { + switch (a) { + + case FILE : + + expected = false; + String s = (v == ArgVal.NULL) ? null : imgName; + new ImageIcon(s); + passed = true; // no exception expected for this case + break; + + case URL : + + if (v == ArgVal.NULL) { + + new ImageIcon((URL)null); + + } else if (v == ArgVal.INVALID_DATA) { + expected = false; + new ImageIcon(new URI("file://" + imgName).toURL()); + passed = true; // no exception expected for this case + + } + break; + + case BYTE_ARRAY : + + if (v == ArgVal.NULL) { + + byte[] bytes = null; + new ImageIcon(bytes); + + } else if (v == ArgVal.INVALID_DATA) { + expected = false; + + new ImageIcon(invalidData); + + passed = true; // no exception expected for this case + } + break; + + case IMAGE : + + if (v == ArgVal.NULL) { + + new ImageIcon((Image)null); + + } else if (v == ArgVal.INVALID_DATA) { + expected = false; + + new ImageIcon((Image)Toolkit.getDefaultToolkit().createImage(imgName)); + + passed = true; // no exception expected for this case + } + break; + + case SET_IMAGE : + + ImageIcon ii = new ImageIcon(); + + if (v == ArgVal.NULL) { + + ii.setImage((Image) null); + + } else if (v == ArgVal.INVALID_DATA) { + expected = false; + + ii.setImage((Image)Toolkit.getDefaultToolkit().createImage(imgName)); + + passed = true; // no exception expected for this case + } + break; + } + } catch (NullPointerException e) { + if (expected) { + passed = true; + } + } + if (expected && !passed) { + throw new RuntimeException("Did not receive expected exception for : " + a); + } + if (!expected && !passed) { + throw new RuntimeException("Received unexpected exception for : " + a); + } + } + } + + } +}