New XBM images parser regression: only the first line of the bitmap array is parsed

XMLWordPrintable

    • Type: Bug
    • Resolution: Unresolved
    • Priority: P4
    • 27
    • 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
    • 2d
    • 26
    • generic
    • generic

      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 };

            Assignee:
            Harshitha Onkar
            Reporter:
            Francisco Ferrari Bihurriet
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: