Projects
Mega:24.03:SP1:Everything
openjdk-1.8.0
_service:tar_scm:Backport-7036144-GZIPInputStre...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:Backport-7036144-GZIPInputStream-readTrailer-uses-faulty-avai.patch of Package openjdk-1.8.0
From 8f3c271e9d34a1105f069fb9d3081c72e1c48180 Mon Sep 17 00:00:00 2001 Date: Tue, 28 May 2024 02:31:27 +0000 Subject: [PATCH] [Backport]7036144:GZIPInputStream readTrailer uses faulty available() test for end-of-stream --- .../java/util/zip/GZIPInputStream.java | 24 ++-- .../zip/GZIP/GZIPInputStreamAvailable.java | 112 ++++++++++++++++++ 2 files changed, 121 insertions(+), 15 deletions(-) create mode 100644 jdk/test/java/util/zip/GZIP/GZIPInputStreamAvailable.java diff --git a/jdk/src/share/classes/java/util/zip/GZIPInputStream.java b/jdk/src/share/classes/java/util/zip/GZIPInputStream.java index b3d9240ba..0d57e8ab3 100644 --- a/jdk/src/share/classes/java/util/zip/GZIPInputStream.java +++ b/jdk/src/share/classes/java/util/zip/GZIPInputStream.java @@ -224,23 +224,17 @@ class GZIPInputStream extends InflaterInputStream { (readUInt(in) != (inf.getBytesWritten() & 0xffffffffL))) throw new ZipException("Corrupt GZIP trailer"); - // If there are more bytes available in "in" or - // the leftover in the "inf" is > 26 bytes: - // this.trailer(8) + next.header.min(10) + next.trailer(8) // try concatenated case - if (this.in.available() > 0 || n > 26) { - int m = 8; // this.trailer - try { - m += readHeader(in); // next.header - } catch (IOException ze) { - return true; // ignore any malformed, do nothing - } - inf.reset(); - if (n > m) - inf.setInput(buf, len - n + m, n - m); - return false; + int m = 8; // this.trailer + try { + m += readHeader(in); // next.header + } catch (IOException ze) { + return true; // ignore any malformed, do nothing } - return true; + inf.reset(); + if (n > m) + inf.setInput(buf, len - n + m, n - m); + return false; } /* diff --git a/jdk/test/java/util/zip/GZIP/GZIPInputStreamAvailable.java b/jdk/test/java/util/zip/GZIP/GZIPInputStreamAvailable.java new file mode 100644 index 000000000..265050b17 --- /dev/null +++ b/jdk/test/java/util/zip/GZIP/GZIPInputStreamAvailable.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2023, 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 7036144 + * @summary Test concatenated gz streams when available() returns zero + */ + +import java.io.*; +import java.util.*; +import java.util.zip.*; + +public class GZIPInputStreamAvailable { + + public static final int NUM_COPIES = 100; + public static void main(String[] args) throws Throwable { + testZeroAvailable(); + } + + public static void testZeroAvailable() throws IOException { + + // Create some uncompressed data and then repeat it NUM_COPIES times + byte[] uncompressed1 = "this is a test".getBytes("ASCII"); + byte[] uncompressedN = repeat(uncompressed1, NUM_COPIES); + + // Compress the original data and then repeat that NUM_COPIES times + byte[] compressed1 = deflate(uncompressed1); + byte[] compressedN = repeat(compressed1, NUM_COPIES); + + // (a) Read back inflated data from a stream where available() is accurate and verify + byte[] readback1 = inflate(new ByteArrayInputStream(compressedN), uncompressedN.length); + assertArrayEquals(uncompressedN, readback1); + + // (b) Read back inflated data from a stream where available() always returns zero and verify + byte[] readback2 = inflate(new ZeroAvailableStream(new ByteArrayInputStream(compressedN)), uncompressedN.length); + assertArrayEquals(uncompressedN, readback2); + } + + public static byte[] repeat(byte[] data, int count) { + byte[] repeat = new byte[data.length * count]; + int off = 0; + for (int i = 0; i < count; i++) { + System.arraycopy(data, 0, repeat, off, data.length); + off += data.length; + } + return repeat; + } + + public static byte[] deflate(byte[] data) throws IOException { + ByteArrayOutputStream buf = new ByteArrayOutputStream(); + try (GZIPOutputStream out = new GZIPOutputStream(buf)) { + out.write(data); + } + return buf.toByteArray(); + } + + public static byte[] inflate(InputStream in, int bufferLen) throws IOException { + GZIPInputStream gzipInputStream = new GZIPInputStream(in); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] buffer = new byte[bufferLen]; + int len; + while ((len = gzipInputStream.read(buffer)) != -1) { + bos.write(buffer, 0, len); + } + gzipInputStream.close(); + bos.close(); + return bos.toByteArray(); + } + + public static class ZeroAvailableStream extends FilterInputStream { + public ZeroAvailableStream(InputStream in) { + super(in); + } + @Override + public int available() { + return 0; + } + } + + public static void assertArrayEquals(byte[] arr1, byte[] arr2) { + if (arr1 == null && arr2 == null) return; + if (arr1 != null && arr2 != null && arr1.length == arr2.length) { + for (int i = 0; i < arr1.length; i++) { + if (arr1[i] != arr2[i]) { + throw new AssertionError(Arrays.toString(arr1) + " != " + Arrays.toString(arr2)); + } + } + return; + } + throw new AssertionError(Arrays.toString(arr1) + " != " + Arrays.toString(arr2)); + } +} \ No newline at end of file -- 2.23.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2