8211422: Reading PNG with corrupt CRC for IEND chunk throws IIOException
Reviewed-by: serb, kaddepalli
--- a/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java Tue Nov 20 14:37:24 2018 +0530
+++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java Tue Nov 20 15:53:54 2018 +0530
@@ -749,7 +749,8 @@
loop: while (true) {
int chunkLength = stream.readInt();
int chunkType = stream.readInt();
- int chunkCRC;
+ // Initialize chunkCRC, value assigned has no significance
+ int chunkCRC = -1;
// verify the chunk length
if (chunkLength < 0) {
@@ -757,10 +758,20 @@
};
try {
- stream.mark();
- stream.seek(stream.getStreamPosition() + chunkLength);
- chunkCRC = stream.readInt();
- stream.reset();
+ /*
+ * As per PNG specification all chunks should have
+ * 4 byte CRC. But there are some images where
+ * CRC is not present/corrupt for IEND chunk.
+ * And these type of images are supported by other
+ * decoders. So as soon as we hit chunk type
+ * for IEND chunk stop reading metadata.
+ */
+ if (chunkType != IEND_TYPE) {
+ stream.mark();
+ stream.seek(stream.getStreamPosition() + chunkLength);
+ chunkCRC = stream.readInt();
+ stream.reset();
+ }
} catch (IOException e) {
throw new IIOException("Invalid chunk length " + chunkLength);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/imageio/plugins/png/PNGCorruptCRCForIENDChunkTest.java Tue Nov 20 15:53:54 2018 +0530
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2018, 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 8211422
+ * @summary Test verifies that PNGImageReader does not throw
+ * IIOException when IEND chunk has corrupt CRC chunk.
+ * @run main PNGCorruptCRCForIENDChunkTest
+ */
+
+import java.io.ByteArrayInputStream;
+import java.util.Base64;
+import javax.imageio.ImageIO;
+import java.util.Iterator;
+import javax.imageio.ImageReader;
+import javax.imageio.stream.ImageInputStream;
+import java.awt.image.BufferedImage;
+
+public class PNGCorruptCRCForIENDChunkTest {
+
+ // PNG image stream having corrupt CRC for IEND chunk
+ private static String inputImageBase64 = "iVBORw0KGgoAAAANSUhEUgAAAA" +
+ "8AAAAQCAYAAADJViUEAAAAIElEQVR4XmNQllf4Ty5mABHkgFHNJIJRzSSCo" +
+ "a6ZXAwA26ElUIYphtYAAAAASUVORK5C";
+
+ public static void main(String[] args) throws Exception {
+
+ byte[] inputBytes = Base64.getDecoder().decode(inputImageBase64);
+ ByteArrayInputStream bais = new ByteArrayInputStream(inputBytes);
+ ImageInputStream input = ImageIO.createImageInputStream(bais);
+ Iterator iter = ImageIO.getImageReaders(input);
+ ImageReader reader = (ImageReader) iter.next();
+ reader.setInput(input, false, false);
+ BufferedImage image = reader.read(0, reader.getDefaultReadParam());
+ }
+}