|  | 
|  | 1 | +/* | 
|  | 2 | + * Copyright (c) 2021, 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 8193682 | 
|  | 27 | + * @summary Test Infinite loop while writing on closed GZipOutputStream , ZipOutputStream and JarOutputStream. | 
|  | 28 | + * @run testng CloseDeflaterTest | 
|  | 29 | + */ | 
|  | 30 | +import java.io.*; | 
|  | 31 | +import java.util.Random; | 
|  | 32 | +import java.util.jar.JarOutputStream; | 
|  | 33 | +import java.util.zip.GZIPOutputStream; | 
|  | 34 | +import java.util.zip.ZipOutputStream; | 
|  | 35 | +import java.util.zip.ZipEntry; | 
|  | 36 | + | 
|  | 37 | +import org.testng.annotations.BeforeTest; | 
|  | 38 | +import org.testng.annotations.DataProvider; | 
|  | 39 | +import org.testng.annotations.Test; | 
|  | 40 | +import static org.testng.Assert.fail; | 
|  | 41 | + | 
|  | 42 | + | 
|  | 43 | +public class CloseDeflaterTest { | 
|  | 44 | + | 
|  | 45 | + //number of bytes to write | 
|  | 46 | + private static final int INPUT_LENGTH= 512; | 
|  | 47 | + //OutputStream that will throw an exception during a write operation | 
|  | 48 | + private static OutputStream outStream = new OutputStream() { | 
|  | 49 | + @Override | 
|  | 50 | + public void write(byte[] b, int off, int len) throws IOException { | 
|  | 51 | + //throw exception during write | 
|  | 52 | + throw new IOException(); | 
|  | 53 | + } | 
|  | 54 | + @Override | 
|  | 55 | + public void write(byte b[]) throws IOException {} | 
|  | 56 | + @Override | 
|  | 57 | + public void write(int b) throws IOException {} | 
|  | 58 | + }; | 
|  | 59 | + private static byte[] inputBytes = new byte[INPUT_LENGTH]; | 
|  | 60 | + private static Random rand = new Random(); | 
|  | 61 | + | 
|  | 62 | + @DataProvider(name = "testgzipinput") | 
|  | 63 | + public Object[][] testGZipInput() { | 
|  | 64 | + //testGZip will close the GZipOutputStream using close() method when the boolean | 
|  | 65 | + //useCloseMethod is set to true and finish() method if the value is set to false | 
|  | 66 | + return new Object[][] { | 
|  | 67 | + { GZIPOutputStream.class, true }, | 
|  | 68 | + { GZIPOutputStream.class, false }, | 
|  | 69 | + }; | 
|  | 70 | + } | 
|  | 71 | + | 
|  | 72 | + @DataProvider(name = "testzipjarinput") | 
|  | 73 | + public Object[][] testZipAndJarInput() { | 
|  | 74 | + //testZipAndJarInput will perfrom write/closeEntry operations on JarOutputStream when the boolean | 
|  | 75 | + //useJar is set to true and on ZipOutputStream if the value is set to false | 
|  | 76 | + return new Object[][] { | 
|  | 77 | + { JarOutputStream.class, true }, | 
|  | 78 | + { ZipOutputStream.class, false }, | 
|  | 79 | + }; | 
|  | 80 | + } | 
|  | 81 | + | 
|  | 82 | + @BeforeTest | 
|  | 83 | + public void before_test() | 
|  | 84 | + { | 
|  | 85 | + //add inputBytes array with random bytes to write into Zip | 
|  | 86 | + rand.nextBytes(inputBytes); | 
|  | 87 | + } | 
|  | 88 | + | 
|  | 89 | + //Test for infinite loop by writing bytes to closed GZIPOutputStream | 
|  | 90 | + @Test(dataProvider = "testgzipinput") | 
|  | 91 | + public void testGZip(Class<?> type, boolean useCloseMethod) throws IOException { | 
|  | 92 | + GZIPOutputStream zip = new GZIPOutputStream(outStream); | 
|  | 93 | + try { | 
|  | 94 | + zip.write(inputBytes, 0, INPUT_LENGTH); | 
|  | 95 | + //close zip | 
|  | 96 | + if(useCloseMethod) { | 
|  | 97 | + zip.close(); | 
|  | 98 | + } else { | 
|  | 99 | + zip.finish(); | 
|  | 100 | + } | 
|  | 101 | + } catch (IOException e) { | 
|  | 102 | + //expected | 
|  | 103 | + } | 
|  | 104 | + for (int i = 0; i < 3; i++) { | 
|  | 105 | + try { | 
|  | 106 | + //write on a closed GZIPOutputStream | 
|  | 107 | + zip.write(inputBytes, 0, INPUT_LENGTH); | 
|  | 108 | + fail("Deflater closed exception not thrown"); | 
|  | 109 | + } catch (NullPointerException e) { | 
|  | 110 | + //expected , Deflater has been closed exception | 
|  | 111 | + } | 
|  | 112 | + } | 
|  | 113 | + } | 
|  | 114 | + | 
|  | 115 | + //Test for infinite loop by writing bytes to closed ZipOutputStream/JarOutputStream | 
|  | 116 | + @Test(dataProvider = "testzipjarinput") | 
|  | 117 | + public void testZipCloseEntry(Class<?> type,boolean useJar) throws IOException { | 
|  | 118 | + ZipOutputStream zip = null; | 
|  | 119 | + if(useJar) { | 
|  | 120 | + zip = new JarOutputStream(outStream); | 
|  | 121 | + } else { | 
|  | 122 | + zip = new ZipOutputStream(outStream); | 
|  | 123 | + } | 
|  | 124 | + try { | 
|  | 125 | + zip.putNextEntry(new ZipEntry("")); | 
|  | 126 | + } catch (IOException e) { | 
|  | 127 | + //expected to throw IOException since putNextEntry calls write method | 
|  | 128 | + } | 
|  | 129 | + try { | 
|  | 130 | + zip.write(inputBytes, 0, INPUT_LENGTH); | 
|  | 131 | + //close zip entry | 
|  | 132 | + zip.closeEntry(); | 
|  | 133 | + } catch (IOException e) { | 
|  | 134 | + //expected | 
|  | 135 | + } | 
|  | 136 | + for (int i = 0; i < 3; i++) { | 
|  | 137 | + try { | 
|  | 138 | + //write on a closed ZipOutputStream | 
|  | 139 | + zip.write(inputBytes, 0, INPUT_LENGTH); | 
|  | 140 | + fail("Deflater closed exception not thrown"); | 
|  | 141 | + } catch (NullPointerException e) { | 
|  | 142 | + //expected , Deflater has been closed exception | 
|  | 143 | + } | 
|  | 144 | + } | 
|  | 145 | + } | 
|  | 146 | + | 
|  | 147 | +} | 
0 commit comments