8191431: Reading multiple PNG images with unique IDAT chunk positions will cause IIOException
authorjdv
Thu, 23 Nov 2017 10:44:29 +0530
changeset 47972 18dbd2ae7eca
parent 47971 75686e8da573
child 47973 d5774c36c605
8191431: Reading multiple PNG images with unique IDAT chunk positions will cause IIOException Reviewed-by: psadhukhan, pnarayanan
src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java
test/jdk/javax/imageio/plugins/png/PngMultipleImageReadTest.java
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java	Wed Nov 22 14:04:51 2017 -0800
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java	Thu Nov 23 10:44:29 2017 +0530
@@ -1698,5 +1698,6 @@
         gotMetadata = false;
         metadata = null;
         pixelStream = null;
+        imageStartPosition = -1L;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/imageio/plugins/png/PngMultipleImageReadTest.java	Thu Nov 23 10:44:29 2017 +0530
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017, 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     8191431
+ * @summary Test verifies that whether we can use same PNGImageReader instance
+ *          to read multiple images or not. It also verifies whether
+ *          imageStartPosition in PNGImageReader is updated properly when we
+ *          use same PNGImageReader instance to read multiple images.
+ * @run     main PngMultipleImageReadTest
+ */
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReadParam;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+
+public class PngMultipleImageReadTest {
+
+    private static final ImageReader PNG_READER =
+            ImageIO.getImageReadersByMIMEType("image/png").next();
+
+    public static void main(String[] args) throws IOException {
+
+        /*
+         * First we create a PNG image without palette so that the IDAT
+         * start position in the stream is at some position 'x'.
+         */
+        BufferedImage imageWithoutPalette =
+                new BufferedImage(20, 20, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D g1 = imageWithoutPalette.createGraphics();
+        g1.setColor(Color.WHITE);
+        g1.fillRect(0, 0, 20, 20);
+        g1.dispose();
+        // write and read the image without palette
+        writeAndReadImage(imageWithoutPalette);
+
+        /*
+         * We create another PNG image with PLTE(palette) chunk so that
+         * now the IDAT start position is at some 'x + y'.
+         */
+        IndexColorModel cm = new IndexColorModel(
+                3,
+                1,
+                new byte[]{10}, // r
+                new byte[]{10}, // g
+                new byte[]{10}); // b
+        BufferedImage imageWithPalette = new BufferedImage(
+                10, 10,
+                BufferedImage.TYPE_BYTE_INDEXED,
+                cm);
+        Graphics2D g2 = imageWithPalette.createGraphics();
+        g2.setColor(Color.BLACK);
+        g2.fillRect(0, 0, 10, 10);
+        g2.dispose();
+        // write and read the image with palette
+        writeAndReadImage(imageWithPalette);
+    }
+
+    private static void writeAndReadImage(BufferedImage image)
+            throws IOException {
+        File output = File.createTempFile("output", ".png");
+        ImageInputStream stream = null;
+        try {
+            ImageIO.write(image, "png", output);
+
+            stream = ImageIO.createImageInputStream(output);
+            ImageReadParam param = PNG_READER.getDefaultReadParam();
+            PNG_READER.setInput(stream, true, true);
+            PNG_READER.read(0, param);
+        } finally {
+            if (stream != null) {
+                stream.close();
+            }
+            Files.delete(output.toPath());
+        }
+    }
+}
+