1 /* 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /** 25 * @test 26 * @bug 6945174 27 * @summary Test verifies that PNG image readr throw correct exception if image contains 28 * a chunk with incorrect length. 29 * @run main ReadMalformedPngTest 30 */ 31 32 import java.awt.Color; 33 import java.awt.GradientPaint; 34 import java.awt.Graphics2D; 35 import java.awt.image.BufferedImage; 36 import java.io.ByteArrayInputStream; 37 import java.io.ByteArrayOutputStream; 38 import java.io.IOException; 39 import javax.imageio.IIOException; 40 import javax.imageio.IIOImage; 41 import javax.imageio.ImageIO; 42 import javax.imageio.ImageTypeSpecifier; 43 import javax.imageio.ImageWriteParam; 44 import javax.imageio.ImageWriter; 45 import javax.imageio.metadata.IIOMetadata; 46 import javax.imageio.metadata.IIOMetadataNode; 47 import javax.imageio.stream.ImageOutputStream; 48 import org.w3c.dom.Node; 49 50 public class ReadMalformedPngTest { 51 52 public static void main(String[] args) throws IOException { 53 ByteArrayInputStream bais = new ByteArrayInputStream(createTestPng()); 54 55 IIOException expected = null; 56 try { 57 ImageIO.read(bais); 58 } catch (IIOException e) { 59 expected = e; 60 } catch (Throwable e) { 61 throw new RuntimeException("Test failed!", e); 62 } 63 64 if (expected == null) { 65 throw new RuntimeException("Test failed."); 66 } 67 68 System.out.println("Test passed."); 69 } 70 71 private static byte[] createTestPng() throws IOException { 72 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 73 74 BufferedImage img = createTestImage(); 75 76 try { 77 ImageOutputStream ios = ImageIO.createImageOutputStream(baos); 78 79 ImageWriter w = ImageIO.getImageWritersByFormatName("PNG").next(); 80 81 w.setOutput(ios); 82 83 ImageWriteParam p = w.getDefaultWriteParam(); 84 85 ImageTypeSpecifier t = ImageTypeSpecifier.createFromRenderedImage(img); 86 87 IIOMetadata m = w.getDefaultImageMetadata(t, p); 88 89 String nativeMetadataFormat = m.getNativeMetadataFormatName(); 90 91 Node root = m.getAsTree(nativeMetadataFormat); 92 93 IIOMetadataNode textEntry = new IIOMetadataNode("tEXtEntry"); 94 textEntry.setAttribute("keyword", "comment"); 95 textEntry.setAttribute("value", "This is a test image for JDK-6945174"); 96 97 IIOMetadataNode text = new IIOMetadataNode("tEXt"); 98 text.appendChild(textEntry); 99 100 root.appendChild(text); 101 102 m.mergeTree(nativeMetadataFormat, root); 103 104 IIOImage iio_img = new IIOImage(img, null, m); 105 106 w.write(iio_img); 107 108 w.dispose(); 109 ios.flush(); 110 ios.close(); 111 } catch (IOException e) { 112 throw new RuntimeException("Test failed.", e); 113 } 114 115 baos.flush(); 116 117 byte[] data = baos.toByteArray(); 118 119 adjustCommentLength(Integer.MAX_VALUE + 0x1000, data); 120 121 return data; 122 } 123 124 private static void adjustCommentLength(int v, byte[] data) { 125 final int pos = getCommentPos(data); 126 data[pos + 3] = (byte) (v & 0xFF); 127 v = v >> 8; 128 data[pos + 2] = (byte) (v & 0xFF); 129 v = v >> 8; 130 data[pos + 1] = (byte) (v & 0xFF); 131 v = v >> 8; 132 data[pos + 0] = (byte) (v & 0xFF); 133 } 134 135 private static int getCommentPos(byte[] d) { 136 int p = 8; 137 while (p + 8 < d.length) { 138 if (d[p + 4] == (byte) 0x74 && d[p + 5] == (byte) 0x45 && 139 d[p + 6] == (byte) 0x58 && d[p + 7] == (byte) 0x74) 140 { 141 return p; 142 } 143 p++; 144 } 145 throw new RuntimeException("Test chunk was not found!"); 146 } 147 148 private static BufferedImage createTestImage() { 149 final int w = 128; 150 final int h = 128; 151 152 BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); 153 Graphics2D g = img.createGraphics(); 154 g.setPaint(new GradientPaint(0, 0, Color.blue, 155 w, h, Color.red)); 156 g.fillRect(0, 0, w, h); 157 g.dispose(); 158 return img; 159 } 160 }