8022632: Reading a PNG file fails because of WBMPImageReaderSpi.canDecodeInput()
Reviewed-by: prr, jgodinez
--- a/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java Wed Oct 02 11:22:07 2013 -0700
+++ b/jdk/src/share/classes/com/sun/imageio/plugins/wbmp/WBMPImageReaderSpi.java Thu Oct 03 11:28:37 2013 +0400
@@ -85,42 +85,42 @@
ImageInputStream stream = (ImageInputStream)source;
stream.mark();
- int type = stream.readByte(); // TypeField
- int fixHeaderField = stream.readByte();
- // check WBMP "header"
- if (type != 0 || fixHeaderField != 0) {
- // while WBMP reader does not support ext WBMP headers
- stream.reset();
- return false;
- }
+ try {
+ int type = stream.readByte(); // TypeField
+ int fixHeaderField = stream.readByte();
+ // check WBMP "header"
+ if (type != 0 || fixHeaderField != 0) {
+ // while WBMP reader does not support ext WBMP headers
+ return false;
+ }
- int width = ReaderUtil.readMultiByteInteger(stream);
- int height = ReaderUtil.readMultiByteInteger(stream);
- // check image dimension
- if (width <= 0 || height <= 0) {
- stream.reset();
- return false;
- }
+ int width = ReaderUtil.readMultiByteInteger(stream);
+ int height = ReaderUtil.readMultiByteInteger(stream);
+ // check image dimension
+ if (width <= 0 || height <= 0) {
+ return false;
+ }
- long dataLength = stream.length();
- if (dataLength == -1) {
- // We can't verify that amount of data in the stream
- // corresponds to image dimension because we do not know
- // the length of the data stream.
- // Assuming that wbmp image are used for mobile devices,
- // let's introduce an upper limit for image dimension.
- // In case if exact amount of raster data is unknown,
- // let's reject images with dimension above the limit.
+ long dataLength = stream.length();
+ if (dataLength == -1) {
+ // We can't verify that amount of data in the stream
+ // corresponds to image dimension because we do not know
+ // the length of the data stream.
+ // Assuming that wbmp image are used for mobile devices,
+ // let's introduce an upper limit for image dimension.
+ // In case if exact amount of raster data is unknown,
+ // let's reject images with dimension above the limit.
+ return (width < MAX_WBMP_WIDTH) && (height < MAX_WBMP_HEIGHT);
+ }
+
+ dataLength -= stream.getStreamPosition();
+
+ long scanSize = (width / 8) + ((width % 8) == 0 ? 0 : 1);
+
+ return (dataLength == scanSize * height);
+ } finally {
stream.reset();
- return (width < MAX_WBMP_WIDTH) && (height < MAX_WBMP_HEIGHT);
}
-
- dataLength -= stream.getStreamPosition();
- stream.reset();
-
- long scanSize = (width / 8) + ((width % 8) == 0 ? 0 : 1);
-
- return (dataLength == scanSize * height);
}
public ImageReader createReaderInstance(Object extension)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/imageio/plugins/wbmp/StreamResetTest.java Thu Oct 03 11:28:37 2013 +0400
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2013, 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 8022632
+ * @summary Test verifies that SPI of WBMP image reader
+ * restores the stream position if an IOException
+ * occurs during processing of image header.
+ * @run main StreamResetTest
+ */
+
+
+import java.io.IOException;
+import javax.imageio.ImageIO;
+import javax.imageio.ImageReader;
+import javax.imageio.spi.ImageReaderSpi;
+import javax.imageio.stream.ImageInputStreamImpl;
+
+public class StreamResetTest {
+
+ public static void main(String[] args) {
+ IOException expectedException = null;
+ TestStream iis = new TestStream();
+
+ ImageReader wbmp = ImageIO.getImageReadersByFormatName("WBMP").next();
+ if (wbmp == null) {
+ System.out.println("No WBMP reader: skip the test");
+ return;
+ }
+
+ ImageReaderSpi spi = wbmp.getOriginatingProvider();
+
+ iis.checkPosition();
+
+ try {
+ spi.canDecodeInput(iis);
+ } catch (IOException e) {
+ expectedException = e;
+ }
+
+ if (expectedException == null) {
+ throw new RuntimeException("Test FAILED: stream was not used");
+ }
+
+ iis.checkPosition();
+
+ System.out.println("Test PASSED");
+
+ }
+
+ private static class TestStream extends ImageInputStreamImpl {
+ private final int errorPos = 1;
+
+ @Override
+ public int read() throws IOException {
+ if (streamPos == errorPos) {
+ throw new IOException("Test exception");
+ }
+ streamPos++;
+
+ return 0x03;
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ streamPos += len;
+ return len;
+ }
+
+ public void checkPosition() {
+ if (streamPos != 0) {
+ throw new RuntimeException("Test FAILED");
+ }
+ }
+ }
+}