Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8190332

PngReader throws NegativeArraySizeException/OOM error when IHDR width is very large

    XMLWordPrintable

    Details

    • Subcomponent:
    • Resolved In Build:
      b34
    • CPU:
      generic
    • OS:
      generic

      Description

      FULL PRODUCT VERSION :


      ADDITIONAL OS VERSION INFORMATION :
      Linux 4.4.0-97-generic Ubuntu SMP x86_64 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      The ImageReader com.sun.imageio.plugins.png.PNGImageReader throws a java.lang.NegativeArraySizeException when attempting to decode certain image files. This is not in the API spec for either ImageReader.read() or ImageIO.read().


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Construct a PNG with an IHDR section that specifies a very large width, such that WIDTH x BANDS (channels) x BIT_DEPTH is larger than Integer.MAX_VALUE (leading to integer overflow). The image need not actually be this large -- the example provided below is in fact only 209 bytes but has such a header (therefore, the image itself is malformed). Then attempt to decode this image using ImageIO via ImageIO.read() or ImageReader.read().

      A self-contained example is provided below. Simply compile and run the main class PngReaderNegativeArraySizeIssue.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      For the test case provided below, the expected behavior is a java.io.IOException since the image itself is malformed. However, if PngReader cannot handle such large images in general, an IllegalArgumentException should be thrown instead and such behavior should be documented in the API.
      ACTUAL -
      A java.lang.NegativeArraySizeException is thrown.

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Exception in thread "main" java.lang.NegativeArraySizeException
      at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.decodePass(PNGImageReader.java:1028)
      at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.decodeImage(PNGImageReader.java:1228)
      at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.readImage(PNGImageReader.java:1349)
      at java.desktop/com.sun.imageio.plugins.png.PNGImageReader.read(PNGImageReader.java:1627)
      at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1468)
      at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1363)
      at PngReaderNegativeArraySizeIssue.main(PngReaderNegativeArraySizeIssue.java:20)

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.io.ByteArrayInputStream;
      import java.io.InputStream;
      import java.util.Base64;
      import javax.imageio.ImageIO;

      public class PngReaderNegativeArraySizeIssue {

      // PNG image test case (encoded as base64 to avoid attaching files)
      private static String inputImageBase64 = "iVBORw0KGgoAAAANSUhEUn7///4" +
      "AAAABCAMAAABEpIrGAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAA" +
      "AAA9QTFRFZszM////AAAAM5lmmf/MPkyvFQAAAGFJREFUeNrckzEOwCAMA5OY/7+5NBQ" +
      "J1DphYaA3sPgkCwtEE0TVAm7BCkfMBaHgp4JvFwjPulSoITAabwHwk1a0PBB6TSBM+bc" +
      "w5ERIlkQiTEPuqTj2ydWbUWzl8yZcAgwA0mYDNbDXy5oAAAo=";

      public static void main(String[] args) throws java.io.IOException {
      // Convert test case into input stream
      byte[] inputBytes = Base64.getDecoder().decode(inputImageBase64);
      InputStream in = new ByteArrayInputStream(inputBytes);

      // Attempt to read PNG
      ImageIO.read(in); // Throws java.lang.NegativeArraySizeException!
      }
      }

      ---------- END SOURCE ----------

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                jdv Jayathirth D V
                Reporter:
                webbuggrp Webbug Group
              • Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: