1 /*
   2  * Copyright (c) 2018, 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     8191023
  27  * @summary Test verifies that PNGImageReader doesn't throw any undocumented
  28  *          Exception when we try to create byte array of negative size because
  29  *          when keyword length is more than chunk size.
  30  * @run     main PngImproperChunkSizeTest
  31  */
  32 
  33 import java.io.ByteArrayInputStream;
  34 import java.io.IOException;
  35 import java.io.InputStream;
  36 import java.util.Base64;
  37 import javax.imageio.IIOException;
  38 import javax.imageio.ImageIO;
  39 import javax.imageio.ImageReader;
  40 
  41 public class PngImproperChunkSizeTest {
  42 
  43     private static ImageReader reader;
  44 
  45     private static String zTXTMalformedData = "iVBORw0KGgoAAAANSUhEUgAAAAEAAA" +
  46             "ABCAAAAAA6fptVAAAABHpUWHRhYWFhYWFhYQAAAApJREFUGFdj+A8AAQEBAFpNb" +
  47             "/EAAAAASUVORK5CYIIK";
  48 
  49     private static String tEXTMalformedData = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAAB"
  50             + "CAMAAAA6fptVAAAABHRFWHRhYWFhYWFhYQAAAApJREFUGFdj+A8AAQEBAFpNb"
  51             + "/EAAAAASUVORK5CYIIK";
  52 
  53     private static String iCCPMalformedData = "iVBORw0KGgoAAAANSUhEUgAAAAEAAA" +
  54             "ABCAAAAAA6fptVAAAABGlDQ1BhYWFhYWFhYQAAAApJREFUGFdj+A8AAQEBAFpNb" +
  55             "/EAAAAASUVORK5CYIIK";
  56 
  57     private static ByteArrayInputStream initializeInputStream(String input) {
  58         byte[] inputBytes = Base64.getDecoder().decode(input);
  59         return new ByteArrayInputStream(inputBytes);
  60     }
  61 
  62     private static Boolean readzTXTData(InputStream input) throws IOException {
  63         // Set input and mark ignoreMetadata = false
  64         reader.setInput(ImageIO.createImageInputStream(input), true, false);
  65         try {
  66             reader.read(0);
  67         } catch (IIOException e) {
  68             Throwable cause = e.getCause();
  69             if (cause == null ||
  70                 !cause.getMessage().
  71                         equals("zTXt chunk length is not proper"))
  72             {
  73                 return true;
  74             }
  75         }
  76         return false;
  77     }
  78 
  79     private static Boolean readtEXTData(InputStream input) throws IOException {
  80         // Set input and mark ignoreMetadata = false
  81         reader.setInput(ImageIO.createImageInputStream(input), true, false);
  82         try {
  83             reader.read(0);
  84         } catch (IIOException e) {
  85             Throwable cause = e.getCause();
  86             if (cause == null ||
  87                 !cause.getMessage().
  88                         equals("tEXt chunk length is not proper"))
  89             {
  90                 return true;
  91             }
  92         }
  93         return false;
  94     }
  95 
  96     private static Boolean readiCCPData(InputStream input) throws IOException {
  97         // Set input and mark ignoreMetadata = false
  98         reader.setInput(ImageIO.createImageInputStream(input), true, false);
  99         try {
 100             reader.read(0);
 101         } catch (IIOException e) {
 102             Throwable cause = e.getCause();
 103             if (cause == null ||
 104                 !cause.getMessage().
 105                         equals("iCCP chunk length is not proper"))
 106             {
 107                 return true;
 108             }
 109         }
 110         return false;
 111     }
 112 
 113     public static void main(String[] args) throws java.io.IOException {
 114         reader = ImageIO.getImageReadersByFormatName("png").next();
 115 
 116         InputStream in = initializeInputStream(zTXTMalformedData);
 117         Boolean zTXTFailed = readzTXTData(in);
 118 
 119         in = initializeInputStream(tEXTMalformedData);
 120         Boolean tEXTFailed = readtEXTData(in);
 121 
 122         in = initializeInputStream(iCCPMalformedData);
 123         Boolean iCCPFailed = readiCCPData(in);
 124 
 125         reader.dispose();
 126 
 127         if (zTXTFailed || tEXTFailed || iCCPFailed) {
 128             throw new RuntimeException("Test didn't throw the required" +
 129                     " Exception");
 130         }
 131     }
 132 }
 133