-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
P4
-
Affects Version/s: 11.0.30-oracle, 17.0.18, 17.0.18-oracle, 21.0.10, 21.0.10-oracle, 25.0.2, 26
-
Component/s: client-libs
While evaluating JDK-8361748 for 11u and 8u backports, I found some problems with the logic of the original change.
#
# Main problem: multi-line bitmap arrays
#
All the bitmap bytes are parsed only if the line contains "[]":
https://github.com/openjdk/jdk/blob/jdk-26+11/src/java.desktop/share/classes/sun/awt/image/XbmImageDecoder.java#L154
So the following data lines are being ignored, which for valid.xbm, means the whole image data is ignored:
https://github.com/openjdk/jdk/blob/jdk-26+11/test/jdk/java/awt/image/XBMDecoder/valid.xbm#L6
https://github.com/openjdk/jdk/blob/jdk-26+11/test/jdk/java/awt/image/XBMDecoder/valid_hex.xbm#L4
Unfortunately, the test case isn't checking the parsed image data, so it isn't catching the issue. I suggest at least checking the image data isn't full of zeros (this would detect the problem for valid.xbm, see [1]).
Please note that matching "[]" might also be too restrictive, as whitespace should probably be allowed between the square brackets. But this is a minor issue, and perhaps acceptable for a minimalist parser.
#
# Additional problem: regexes
#
I've also spotted some regex mistakes where the intention was to define a group (should be enclosed between parenthesis), but the code defines a character set (is enclosed between square brackets):
• matchRegex = "(0[xX])?[0-9a-fA-F]+[\\s+]?[,|};]"
• Very likely intended to be matchRegex = "(0[xX])?[0-9a-fA-F]+(\\s+)?(,|\\};)"
• And can be simplified as matchRegex = "(0[xX])?[0-9a-fA-F]+\\s*(,|\\};)"
• replaceRegex = "(0[xX])|,|[\\s+]|[};]"
• Very likely intended to be replaceRegex = "(0[xX])|,|(\\s+)|(\\};)"
• And can be simplified as replaceRegex = "0[xX]|,|\\s+|\\};"
As a consequence, invalid files containing a plus sign are not rejected by the parser. I suggest adding an invalid_plus.xbm case for this (see [2]).
[1]
diff --git a/test/jdk/java/awt/image/XBMDecoder/XBMDecoderTest.java b/test/jdk/java/awt/image/XBMDecoder/XBMDecoderTest.java
index 19bc6d95c39..185e3dcc0fe 100644
--- a/test/jdk/java/awt/image/XBMDecoder/XBMDecoderTest.java
+++ b/test/jdk/java/awt/image/XBMDecoder/XBMDecoderTest.java
@@ -29,10 +29,14 @@
* @run main XBMDecoderTest
*/
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintStream;
+import java.util.Arrays;
import javax.swing.ImageIcon;
public class XBMDecoderTest {
@@ -68,10 +72,27 @@ public static void main(String[] args) throws Exception {
throw new RuntimeException("Test failed: ImageFormatException"
+ " expected but not thrown");
}
+ if (validCase) {
+ assertHasPixelData(icon.getImage());
+ }
System.out.println("PASSED\n");
} finally {
System.setErr(originalErr);
}
}
}
+
+ private static void assertHasPixelData(Image img) {
+ int w = img.getWidth(null);
+ int h = img.getHeight(null);
+ BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g = bi.createGraphics();
+ g.drawImage(img, 0, 0, null);
+ g.dispose();
+ int[] pixels = bi.getRGB(0, 0, w, h, null, 0, w);
+ if (Arrays.stream(pixels).allMatch(i -> i == 0)) {
+ throw new RuntimeException("Test failed: the parsed image does " +
+ "not contain any pixel data");
+ }
+ }
}
[2] test/jdk/java/awt/image/XBMDecoder/invalid_plus.xbm
#define test_width 16
#define test_height 2
static unsigned char test_bits[] = { 0x13, 0x11, 0xAB+, 0xff };
#
# Main problem: multi-line bitmap arrays
#
All the bitmap bytes are parsed only if the line contains "[]":
https://github.com/openjdk/jdk/blob/jdk-26+11/src/java.desktop/share/classes/sun/awt/image/XbmImageDecoder.java#L154
So the following data lines are being ignored, which for valid.xbm, means the whole image data is ignored:
https://github.com/openjdk/jdk/blob/jdk-26+11/test/jdk/java/awt/image/XBMDecoder/valid.xbm#L6
https://github.com/openjdk/jdk/blob/jdk-26+11/test/jdk/java/awt/image/XBMDecoder/valid_hex.xbm#L4
Unfortunately, the test case isn't checking the parsed image data, so it isn't catching the issue. I suggest at least checking the image data isn't full of zeros (this would detect the problem for valid.xbm, see [1]).
Please note that matching "[]" might also be too restrictive, as whitespace should probably be allowed between the square brackets. But this is a minor issue, and perhaps acceptable for a minimalist parser.
#
# Additional problem: regexes
#
I've also spotted some regex mistakes where the intention was to define a group (should be enclosed between parenthesis), but the code defines a character set (is enclosed between square brackets):
• matchRegex = "(0[xX])?[0-9a-fA-F]+[\\s+]?[,|};]"
• Very likely intended to be matchRegex = "(0[xX])?[0-9a-fA-F]+(\\s+)?(,|\\};)"
• And can be simplified as matchRegex = "(0[xX])?[0-9a-fA-F]+\\s*(,|\\};)"
• replaceRegex = "(0[xX])|,|[\\s+]|[};]"
• Very likely intended to be replaceRegex = "(0[xX])|,|(\\s+)|(\\};)"
• And can be simplified as replaceRegex = "0[xX]|,|\\s+|\\};"
As a consequence, invalid files containing a plus sign are not rejected by the parser. I suggest adding an invalid_plus.xbm case for this (see [2]).
[1]
diff --git a/test/jdk/java/awt/image/XBMDecoder/XBMDecoderTest.java b/test/jdk/java/awt/image/XBMDecoder/XBMDecoderTest.java
index 19bc6d95c39..185e3dcc0fe 100644
--- a/test/jdk/java/awt/image/XBMDecoder/XBMDecoderTest.java
+++ b/test/jdk/java/awt/image/XBMDecoder/XBMDecoderTest.java
@@ -29,10 +29,14 @@
* @run main XBMDecoderTest
*/
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.PrintStream;
+import java.util.Arrays;
import javax.swing.ImageIcon;
public class XBMDecoderTest {
@@ -68,10 +72,27 @@ public static void main(String[] args) throws Exception {
throw new RuntimeException("Test failed: ImageFormatException"
+ " expected but not thrown");
}
+ if (validCase) {
+ assertHasPixelData(icon.getImage());
+ }
System.out.println("PASSED\n");
} finally {
System.setErr(originalErr);
}
}
}
+
+ private static void assertHasPixelData(Image img) {
+ int w = img.getWidth(null);
+ int h = img.getHeight(null);
+ BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g = bi.createGraphics();
+ g.drawImage(img, 0, 0, null);
+ g.dispose();
+ int[] pixels = bi.getRGB(0, 0, w, h, null, 0, w);
+ if (Arrays.stream(pixels).allMatch(i -> i == 0)) {
+ throw new RuntimeException("Test failed: the parsed image does " +
+ "not contain any pixel data");
+ }
+ }
}
[2] test/jdk/java/awt/image/XBMDecoder/invalid_plus.xbm
#define test_width 16
#define test_height 2
static unsigned char test_bits[] = { 0x13, 0x11, 0xAB+, 0xff };
- caused by
-
JDK-8361748 Enforce limits on the size of an XBM image
-
- Resolved
-