--- old/src/java.desktop/share/classes/javax/imageio/ImageIO.java 2016-03-22 14:40:34.581798756 +0530 +++ new/src/java.desktop/share/classes/javax/imageio/ImageIO.java 2016-03-22 14:40:34.109798756 +0530 @@ -1290,7 +1290,8 @@ * @param input a File to read from. * * @return a BufferedImage containing the decoded - * contents of the input, or null. + * contents of the input, or null when we are not + * able to decode the input or cannot create required ImageInputStream. * * @exception IllegalArgumentException if input is * null. @@ -1305,9 +1306,8 @@ } ImageInputStream stream = createImageInputStream(input); - if (stream == null) { - throw new IIOException("Can't create an ImageInputStream!"); - } + if (stream == null) + return null; BufferedImage bi = read(stream); if (bi == null) { stream.close(); @@ -1340,7 +1340,8 @@ * @param input an InputStream to read from. * * @return a BufferedImage containing the decoded - * contents of the input, or null. + * contents of the input, or null when we are not + * able to decode the input or cannot create required ImageInputStream. * * @exception IllegalArgumentException if input is * null. @@ -1352,6 +1353,8 @@ } ImageInputStream stream = createImageInputStream(input); + if (stream == null) + return null; BufferedImage bi = read(stream); if (bi == null) { stream.close(); @@ -1380,7 +1383,8 @@ * @param input a URL to read from. * * @return a BufferedImage containing the decoded - * contents of the input, or null. + * contents of the input, or null when we are not + * able to decode the input or cannot create required ImageInputStream. * * @exception IllegalArgumentException if input is * null. @@ -1398,6 +1402,15 @@ throw new IIOException("Can't get input stream from URL!", e); } ImageInputStream stream = createImageInputStream(istream); + if (stream == null) { + /* We have to close istream when we are not able to create + * ImageInputStream otherwise it will cause memory leak, also if + * user has referenced the URL from a File then user will not be + * able to delete it as it will be alive with istream reference. + */ + istream.close(); + return null; + } BufferedImage bi; try { bi = read(stream); @@ -1506,7 +1519,8 @@ * name of the format. * @param output a File to be written to. * - * @return false if no appropriate writer is found. + * @return false if no appropriate writer is found or + * not able to create required ImageOutputStream. * * @exception IllegalArgumentException if any parameter is * null. @@ -1538,7 +1552,8 @@ try { return doWrite(im, writer, stream); } finally { - stream.close(); + if (stream != null) + stream.close(); } } @@ -1558,7 +1573,8 @@ * name of the format. * @param output an OutputStream to be written to. * - * @return false if no appropriate writer is found. + * @return false if no appropriate writer is found or + * not able to create required ImageOutputStream. * * @exception IllegalArgumentException if any parameter is * null. @@ -1580,7 +1596,8 @@ try { return doWrite(im, getWriter(im, formatName), stream); } finally { - stream.close(); + if (stream != null) + stream.close(); } } @@ -1610,6 +1627,9 @@ if (writer == null) { return false; } + if (output == null) { + return false; + } writer.setOutput(output); try { writer.write(im); --- /dev/null 2016-03-21 12:07:26.538306000 +0530 +++ new/test/javax/imageio/stream/NullStreamCheckTest.java 2016-03-22 14:40:35.397798756 +0530 @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2016, 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 8044289 + * @summary Test verifies that when createImageInputStream() or + * createImageOutputStream() returns null while read or write, + * does read() returns null and write() returns false. + * @run main NullStreamCheckTest + */ + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URL; +import javax.imageio.ImageIO; +import javax.imageio.spi.IIORegistry; +import javax.imageio.spi.ImageInputStreamSpi; +import javax.imageio.spi.ImageOutputStreamSpi; + +public class NullStreamCheckTest { + + // get ImageIORegistry default instance. + private static final IIORegistry localRegistry = IIORegistry. + getDefaultInstance(); + // stream variables needed for input and output. + static LocalOutputStream outputStream = new LocalOutputStream(); + static LocalInputStream inputStream = new LocalInputStream(); + + static final int width = 50, height = 50; + + // input and output BufferedImage needed while read and write. + static BufferedImage inputImage = new BufferedImage(width, height, + BufferedImage.TYPE_INT_ARGB); + static BufferedImage outputImage = new BufferedImage(width, height, + BufferedImage.TYPE_INT_ARGB); + + // creates test file needed for read and write in local directory. + private static File createTestFile(String name) throws IOException { + String sep = System.getProperty("file.separator"); + String dir = System.getProperty("test.src", "."); + String filePath = dir+sep; + File directory = new File(filePath); + File tmpTestFile = File.createTempFile(name, ".png", directory); + directory.delete(); + return tmpTestFile; + } + + private static void verifyFileWrite() throws IOException { + File outputTestFile = createTestFile("outputTestFile"); + Boolean verify; + try { + verify = ImageIO.write(inputImage, "png", outputTestFile); + if (verify != false) { + throw new RuntimeException("ImageIO.write() is not following" + + " the specification"); + } + } catch (IOException ex) { + throw ex; + } finally { + outputTestFile.delete(); + } + } + + private static void verifyStreamWrite() throws IOException { + Boolean verify; + try { + verify = ImageIO.write(inputImage, "png", outputStream); + if (verify != false) { + throw new RuntimeException("ImageIO.write() is not following" + + " the specification"); + } + } catch (IOException ex) { + throw ex; + } finally { + try { + outputStream.close(); + } catch (IOException ex) { + throw ex; + } + } + } + + private static void verifyFileRead() throws IOException { + File inputTestFile = createTestFile("inputTestFile"); + try { + outputImage = ImageIO.read(inputTestFile); + if (outputImage != null) { + throw new RuntimeException("ImageIO.read() is not following" + + " the specification"); + } + } catch (IOException ex) { + throw ex; + } finally { + inputTestFile.delete(); + } + } + + private static void verifyStreamRead() throws IOException { + try { + outputImage = ImageIO.read(inputStream); + if (outputImage != null) { + throw new RuntimeException("ImageIO.read() is not following" + + " the specification"); + } + } catch (IOException ex) { + throw ex; + } finally { + try { + inputStream.close(); + } catch (IOException ex) { + throw ex; + } + } + } + + private static void verifyUrlRead() throws IOException { + URL url; + File inputTestUrlFile = createTestFile("inputTestFile"); + try { + try { + url = inputTestUrlFile.toURI().toURL(); + } catch (MalformedURLException ex) { + throw ex; + } + + try { + outputImage = ImageIO.read(url); + if (outputImage != null) { + throw new RuntimeException("ImageIO.read() is not" + + " following the specification"); + } + } catch (IOException ex) { + throw ex; + } + } finally { + inputTestUrlFile.delete(); + } + } + + public static void main(String[] args) throws IOException, + MalformedURLException { + + /* deregister ImageOutputStreamSpi so that we creatImageOutputStream + * returns null while writing. + */ + localRegistry.deregisterAll(ImageOutputStreamSpi.class); + /* verify possible ImageIO.write() scenario's for null stream output + * from createImageOutputStream() API in ImageIO class. + */ + verifyFileWrite(); + verifyStreamWrite(); + + /* deregister ImageInputStreamSpi so that we creatImageInputStream + * returns null while reading. + */ + localRegistry.deregisterAll(ImageInputStreamSpi.class); + /* verify possible ImageIO.read() scenario's for null stream output + * from createImageInputStream API in ImageIO class. + */ + verifyFileRead(); + verifyStreamRead(); + verifyUrlRead(); + } + + static class LocalOutputStream extends OutputStream { + + @Override + public void write(int i) throws IOException { + } + } + + static class LocalInputStream extends InputStream { + + @Override + public int read() throws IOException { + return 0; + } + } +}