8321616: Retire binary test vectors in test/jdk/java/util/zip/ZipFile
8322830: Add test case for ZipFile opening a ZIP with no entries Reviewed-by: lancea
This commit is contained in:
parent
b530c0281b
commit
26de9e247a
@ -23,99 +23,120 @@
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 8253952
|
||||
* @summary Test behaviour when copying ZipEntries between zip files.
|
||||
* @run main/othervm CopyZipFile
|
||||
* @run junit CopyZipFile
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Enumeration;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.CRC32;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
import java.util.zip.*;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class CopyZipFile {
|
||||
private static final String ZIP_FILE = "first.zip";
|
||||
private static final String TEST_STRING = "TestTestTest";
|
||||
// ZIP file created in this test
|
||||
private Path zip = Path.of("first.zip");
|
||||
// The content to put in each entry
|
||||
private static final byte[] TEST_STRING = "TestTestTest".getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
private static void createZip(String zipFile) throws Exception {
|
||||
File f = new File(zipFile);
|
||||
f.deleteOnExit();
|
||||
try (OutputStream os = new FileOutputStream(f);
|
||||
ZipOutputStream zos = new ZipOutputStream(os)) {
|
||||
// First file will be compressed with DEFAULT_COMPRESSION (i.e. -1 or 6)
|
||||
zos.putNextEntry(new ZipEntry("test1.txt"));
|
||||
zos.write(TEST_STRING.getBytes());
|
||||
zos.closeEntry();
|
||||
// Second file won't be compressed at all (i.e. STORED)
|
||||
zos.setMethod(ZipOutputStream.STORED);
|
||||
ZipEntry ze = new ZipEntry("test2.txt");
|
||||
int length = TEST_STRING.length();
|
||||
ze.setSize(length);
|
||||
ze.setCompressedSize(length);
|
||||
CRC32 crc = new CRC32();
|
||||
crc.update(TEST_STRING.getBytes("utf8"), 0, length);
|
||||
ze.setCrc(crc.getValue());
|
||||
zos.putNextEntry(ze);
|
||||
zos.write(TEST_STRING.getBytes());
|
||||
// Third file will be compressed with NO_COMPRESSION (i.e. 0)
|
||||
zos.setMethod(ZipOutputStream.DEFLATED);
|
||||
zos.setLevel(Deflater.NO_COMPRESSION);
|
||||
zos.putNextEntry(new ZipEntry("test3.txt"));
|
||||
zos.write(TEST_STRING.getBytes());
|
||||
// Fourth file will be compressed with BEST_SPEED (i.e. 1)
|
||||
zos.setLevel(Deflater.BEST_SPEED);
|
||||
zos.putNextEntry(new ZipEntry("test4.txt"));
|
||||
zos.write(TEST_STRING.getBytes());
|
||||
// Fifth file will be compressed with BEST_COMPRESSION (i.e. 9)
|
||||
zos.setLevel(Deflater.BEST_COMPRESSION);
|
||||
zos.putNextEntry(new ZipEntry("test5.txt"));
|
||||
zos.write(TEST_STRING.getBytes());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
/**
|
||||
* Create the sample ZIP file used in this test, including a STORED entry
|
||||
* and DEFLATE entries with various compression levels.
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@BeforeEach
|
||||
public void createZip() throws IOException {
|
||||
// By default, ZipOutputStream creates zip files with Local File Headers
|
||||
// without size, compressedSize and crc values and an extra Data
|
||||
// without size, compressed size and crc values and an extra Data
|
||||
// Descriptor (see https://en.wikipedia.org/wiki/Zip_(file_format)
|
||||
// after the data belonging to that entry with these values if in the
|
||||
// corresponding ZipEntry one of the size, compressedSize or crc fields is
|
||||
// equal to '-1' (which is the default for newly created ZipEntries).
|
||||
createZip(ZIP_FILE);
|
||||
|
||||
// Now read all the entries of the newly generated zip file with a ZipInputStream
|
||||
// and copy them to a new zip file with the help of a ZipOutputStream.
|
||||
// This only works reliably because the generated zip file has no values for the
|
||||
// size, compressedSize and crc values of a zip entry in the local file header and
|
||||
// therefore the ZipEntry objects created by ZipOutputStream.getNextEntry() will have
|
||||
// all these fields set to '-1'.
|
||||
ZipEntry entry;
|
||||
byte[] buf = new byte[512];
|
||||
try (InputStream is = new FileInputStream(ZIP_FILE);
|
||||
ZipInputStream zis = new ZipInputStream(is);
|
||||
OutputStream os = new ByteArrayOutputStream();
|
||||
try (OutputStream os = Files.newOutputStream(zip) ;
|
||||
ZipOutputStream zos = new ZipOutputStream(os)) {
|
||||
while((entry = zis.getNextEntry())!=null) {
|
||||
// First file will be compressed with DEFAULT_COMPRESSION (i.e. -1 or 6)
|
||||
zos.setLevel(Deflater.DEFAULT_COMPRESSION);
|
||||
zos.putNextEntry(new ZipEntry("DEFAULT_COMPRESSION.txt"));
|
||||
zos.write(TEST_STRING);
|
||||
|
||||
// Second file won't be compressed at all (i.e. STORED)
|
||||
zos.setMethod(ZipOutputStream.STORED);
|
||||
ZipEntry ze = new ZipEntry("STORED.txt");
|
||||
ze.setSize(TEST_STRING.length);
|
||||
ze.setCompressedSize(TEST_STRING.length);
|
||||
CRC32 crc = new CRC32();
|
||||
crc.update(TEST_STRING);
|
||||
ze.setCrc(crc.getValue());
|
||||
zos.putNextEntry(ze);
|
||||
zos.write(TEST_STRING);
|
||||
|
||||
// Third file will be compressed with NO_COMPRESSION (i.e. 0)
|
||||
zos.setMethod(ZipOutputStream.DEFLATED);
|
||||
zos.setLevel(Deflater.NO_COMPRESSION);
|
||||
zos.putNextEntry(new ZipEntry("NO_COMPRESSION.txt"));
|
||||
zos.write(TEST_STRING);
|
||||
|
||||
// Fourth file will be compressed with BEST_SPEED (i.e. 1)
|
||||
zos.setLevel(Deflater.BEST_SPEED);
|
||||
zos.putNextEntry(new ZipEntry("BEST_SPEED.txt"));
|
||||
zos.write(TEST_STRING);
|
||||
|
||||
// Fifth file will be compressed with BEST_COMPRESSION (i.e. 9)
|
||||
zos.setLevel(Deflater.BEST_COMPRESSION);
|
||||
zos.putNextEntry(new ZipEntry("BEST_COMPRESSION.txt"));
|
||||
zos.write(TEST_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the ZIP file produced by this test
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@AfterEach
|
||||
public void cleanup() throws IOException {
|
||||
Files.deleteIfExists(zip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all entries using ZipInputStream.getNextEntry and copy them
|
||||
* to a new zip file using ZipOutputStream.putNextEntry. This only works
|
||||
* reliably because the input zip file has no values for the size, compressedSize
|
||||
* and crc values of streamed zip entries in the local file header and
|
||||
* therefore the ZipEntry objects created by ZipOutputStream.getNextEntry
|
||||
* will have all these fields set to '-1'.
|
||||
*
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void copyFromZipInputStreamToZipOutputStream() throws IOException {
|
||||
|
||||
try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(zip));
|
||||
ZipOutputStream zos = new ZipOutputStream(OutputStream.nullOutputStream())) {
|
||||
ZipEntry entry;
|
||||
while ((entry = zis.getNextEntry()) != null) {
|
||||
// ZipInputStream.getNextEntry() only reads the Local File Header of a zip entry,
|
||||
// so for the zip file we've just generated the ZipEntry fields 'size', 'compressedSize`
|
||||
// and 'crc' for deflated entries should be uninitialized (i.e. '-1').
|
||||
System.out.println(
|
||||
String.format("name=%s, clen=%d, len=%d, crc=%d",
|
||||
entry.getName(), entry.getCompressedSize(), entry.getSize(), entry.getCrc()));
|
||||
if (entry.getMethod() == ZipEntry.DEFLATED &&
|
||||
(entry.getCompressedSize() != -1 || entry.getSize() != -1 || entry.getCrc() != -1)) {
|
||||
throw new Exception("'size', 'compressedSize' and 'crc' shouldn't be initialized at this point.");
|
||||
String.format("name=%s, clen=%d, len=%d, crc=%d",
|
||||
entry.getName(), entry.getCompressedSize(), entry.getSize(), entry.getCrc()));
|
||||
if (entry.getMethod() == ZipEntry.DEFLATED) {
|
||||
// Expect size, compressed size and crc to not be initialized at this point
|
||||
assertEquals(-1, entry.getCompressedSize());
|
||||
assertEquals(-1, entry.getSize());
|
||||
assertEquals(-1, entry.getCrc());
|
||||
}
|
||||
zos.putNextEntry(entry);
|
||||
zis.transferTo(zos);
|
||||
@ -124,29 +145,37 @@ public class CopyZipFile {
|
||||
// Descriptor (if any) after the data and will have updated the 'size', 'compressedSize' and 'crc'
|
||||
// fields of the ZipEntry object.
|
||||
System.out.println(
|
||||
String.format("name=%s, clen=%d, len=%d, crc=%d\n",
|
||||
entry.getName(), entry.getCompressedSize(), entry.getSize(), entry.getCrc()));
|
||||
if (entry.getCompressedSize() == -1 || entry.getSize() == -1) {
|
||||
throw new Exception("'size' and 'compressedSize' must be initialized at this point.");
|
||||
}
|
||||
String.format("name=%s, clen=%d, len=%d, crc=%d\n",
|
||||
entry.getName(), entry.getCompressedSize(), entry.getSize(), entry.getCrc()));
|
||||
// Expect size, compressed size and crc to be initialized at this point
|
||||
assertNotEquals(-1, entry.getCompressedSize());
|
||||
assertNotEquals(-1, entry.getSize());
|
||||
assertNotEquals(-1, entry.getCrc());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now we read all the entries of the initially generated zip file with the help
|
||||
// of the ZipFile class. The ZipFile class reads all the zip entries from the Central
|
||||
// Directory which must have accurate information for size, compressedSize and crc.
|
||||
// This means that all ZipEntry objects returned from ZipFile will have correct
|
||||
// settings for these fields.
|
||||
// If the compression level was different in the initial zip file (which we can't find
|
||||
// out any more now because the zip file format doesn't record this information) the
|
||||
// size of the re-compressed entry we are writing to the ZipOutputStream might differ
|
||||
// from the original compressed size recorded in the ZipEntry. This would result in an
|
||||
// "invalid entry compressed size" ZipException if ZipOutputStream wouldn't ignore
|
||||
// the implicitely set compressed size attribute of ZipEntries read from a ZipFile
|
||||
// or ZipInputStream.
|
||||
try (OutputStream os = new ByteArrayOutputStream();
|
||||
ZipOutputStream zos = new ZipOutputStream(os);
|
||||
ZipFile zf = new ZipFile(ZIP_FILE)) {
|
||||
/**
|
||||
* Read all entries using the ZipFile class and copy them to a new zip file
|
||||
* using ZipOutputStream.putNextEntry.
|
||||
* The ZipFile class reads all the zip entries from the Central
|
||||
* Directory, which has accurate information for size, compressedSize and crc.
|
||||
* This means that all ZipEntry objects returned from ZipFile will have correct
|
||||
* settings for these fields.
|
||||
* If the compression level was different in the input zip file (which we can't know
|
||||
* because the zip file format doesn't record this information), the
|
||||
* size of the re-compressed entry we are writing to the ZipOutputStream might differ
|
||||
* from the original compressed size recorded in the ZipEntry. This would result in an
|
||||
* "invalid entry compressed size" ZipException if ZipOutputStream wouldn't ignore
|
||||
* the implicitely set compressed size attribute of ZipEntries read from a ZipFile
|
||||
* or ZipInputStream.
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void copyFromZipFileToZipOutputStream() throws IOException {
|
||||
try (ZipOutputStream zos = new ZipOutputStream(OutputStream.nullOutputStream());
|
||||
ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
ZipEntry entry;
|
||||
Enumeration<? extends ZipEntry> entries = zf.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
entry = entries.nextElement();
|
||||
@ -154,48 +183,84 @@ public class CopyZipFile {
|
||||
String.format("name=%s, clen=%d, len=%d, crc=%d\n",
|
||||
entry.getName(), entry.getCompressedSize(),
|
||||
entry.getSize(), entry.getCrc()));
|
||||
if (entry.getCompressedSize() == -1 || entry.getSize() == -1) {
|
||||
throw new Exception("'size' and 'compressedSize' must be initialized at this point.");
|
||||
}
|
||||
InputStream is = zf.getInputStream(entry);
|
||||
// Expect size, compressed size and crc to be initialized at this point
|
||||
assertNotEquals(-1, entry.getCompressedSize());
|
||||
assertNotEquals(-1, entry.getSize());
|
||||
assertNotEquals(-1, entry.getCrc());
|
||||
|
||||
zos.putNextEntry(entry);
|
||||
is.transferTo(zos);
|
||||
try (InputStream is = zf.getInputStream(entry)) {
|
||||
is.transferTo(zos);
|
||||
}
|
||||
zos.closeEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If the compressed size is set explicitly using ZipEntry.setCompressedSize(),
|
||||
* then the entry will be restreamed with a data descriptor and the compressed size
|
||||
* recomputed. If the source compression level was different from the target compression
|
||||
* level, the compressed sizes may differ and a ZipException will be thrown
|
||||
* when the entry is closed in ZipOutputStream.closeEntry
|
||||
*
|
||||
* @throws IOException if an unexpected IOException is thrown
|
||||
*/
|
||||
@Test
|
||||
public void explicitCompressedSizeWithDifferentCompressionLevels() throws IOException {
|
||||
try (ZipOutputStream zos = new ZipOutputStream(OutputStream.nullOutputStream());
|
||||
ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
// Be explicit about the default compression level
|
||||
zos.setLevel(Deflater.DEFAULT_COMPRESSION);
|
||||
|
||||
// The compressed size attribute of a ZipEntry shouldn't be ignored if it was set
|
||||
// explicitely by calling ZipEntry.setCpompressedSize()
|
||||
try (OutputStream os = new ByteArrayOutputStream();
|
||||
ZipOutputStream zos = new ZipOutputStream(os);
|
||||
ZipFile zf = new ZipFile(ZIP_FILE)) {
|
||||
Enumeration<? extends ZipEntry> entries = zf.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
try {
|
||||
entry = entries.nextElement();
|
||||
entry.setCompressedSize(entry.getCompressedSize());
|
||||
InputStream is = zf.getInputStream(entry);
|
||||
ZipEntry entry = entries.nextElement();
|
||||
|
||||
// Explicitly setting the compressed size will disable data descriptors
|
||||
// and enable validation that the compressed size in the ZipEntry matches the
|
||||
// actual compressed size written by ZipOutputStream
|
||||
entry.setCompressedSize(entry.getCompressedSize());
|
||||
|
||||
try (InputStream is = zf.getInputStream(entry)) {
|
||||
zos.putNextEntry(entry);
|
||||
is.transferTo(zos);
|
||||
zos.closeEntry();
|
||||
if ("test3.txt".equals(entry.getName())) {
|
||||
throw new Exception(
|
||||
"Should throw a ZipException if ZipEntry.setCpompressedSize() was called.");
|
||||
// Some compression levels lead to unexpected recompressed sizes when closing the entry
|
||||
switch (entry.getName()) {
|
||||
case "DEFAULT_COMPRESSION.txt" -> {
|
||||
// DEFAULT_COMPRESSION matches expected size
|
||||
zos.closeEntry();
|
||||
}
|
||||
case "STORED.txt" -> {
|
||||
// STORED should not throw
|
||||
zos.closeEntry();
|
||||
}
|
||||
case "NO_COMPRESSION.txt", "BEST_SPEED.txt" -> {
|
||||
// NO_COMPRESSION and BEST_SPEED should lead to an unexpected recompressed size
|
||||
ZipException ze = assertThrows(ZipException.class, () -> {
|
||||
zos.closeEntry();
|
||||
});
|
||||
|
||||
// Hack to fix and close the offending zip entry with the correct recompressed size.
|
||||
// The exception message is something like:
|
||||
// "invalid entry compressed size (expected 12 but got 7 bytes)"
|
||||
// and we need to extract the second integer.
|
||||
Pattern cSize = Pattern.compile("\\d+");
|
||||
Matcher m = cSize.matcher(ze.getMessage());
|
||||
m.find();
|
||||
m.find();
|
||||
entry.setCompressedSize(Integer.parseInt(m.group()));
|
||||
zos.closeEntry();
|
||||
}
|
||||
case "BEST_COMPRESSION.txt" -> {
|
||||
// BEST_COMPRESSION produces the same compressed
|
||||
// size as DEFAULT_COMPRESSION for sample content
|
||||
zos.closeEntry();
|
||||
}
|
||||
default -> {
|
||||
throw new IllegalArgumentException("Unexpected entry " + entry.getName());
|
||||
}
|
||||
}
|
||||
} catch (ZipException ze) {
|
||||
if ("test1.txt".equals(entry.getName()) || "test2.txt".equals(entry.getName())) {
|
||||
throw new Exception(
|
||||
"Shouldn't throw a ZipExcpetion for STORED files or files compressed with DEFAULT_COMPRESSION");
|
||||
}
|
||||
// Hack to fix and close the offending zip entry with the correct compressed size.
|
||||
// The exception message is something like:
|
||||
// "invalid entry compressed size (expected 12 but got 7 bytes)"
|
||||
// and we need to extract the second integer.
|
||||
Pattern cSize = Pattern.compile("\\d+");
|
||||
Matcher m = cSize.matcher(ze.getMessage());
|
||||
m.find();
|
||||
m.find();
|
||||
entry.setCompressedSize(Integer.parseInt(m.group()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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.
|
||||
*/
|
||||
|
||||
import java.util.zip.*;
|
||||
import java.io.File;
|
||||
|
||||
public class Available
|
||||
{
|
||||
public static void main (String argv[]) throws Exception {
|
||||
ZipFile zf = new ZipFile(new File(System.getProperty("test.src"),
|
||||
"input.jar"));
|
||||
ZipEntry e = zf.getEntry("ReleaseInflater.java");
|
||||
if (e.getSize() != zf.getInputStream(e).available()) {
|
||||
throw new Exception("wrong return value of available");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, 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 1.1 99/06/01
|
||||
@bug 4239446
|
||||
@summary Make sure the ZipEntry fields are correct.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
public class CopyJar {
|
||||
public static void main(String args[]) throws Exception {
|
||||
try (ZipFile zf = new ZipFile(new File(System.getProperty("test.src", "."),
|
||||
"input.jar"))) {
|
||||
ZipEntry ze = zf.getEntry("ReleaseInflater.java");
|
||||
ZipOutputStream zos = new ZipOutputStream(new ByteArrayOutputStream());
|
||||
InputStream in = zf.getInputStream(ze);
|
||||
byte[] b = new byte[128];
|
||||
int n;
|
||||
zos.putNextEntry(ze);
|
||||
while((n = in.read(b)) != -1) {
|
||||
zos.write(b, 0, n);
|
||||
}
|
||||
zos.close();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, 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 4290060
|
||||
@summary Check if the zip file is closed before access any
|
||||
elements in the Enumeration.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.zip.*;
|
||||
import java.util.Enumeration;
|
||||
|
||||
public class EnumAfterClose {
|
||||
public static void main(String args[]) throws Exception {
|
||||
Enumeration e;
|
||||
try (ZipFile zf = new ZipFile(new File(System.getProperty("test.src", "."),
|
||||
"input.zip"))) {
|
||||
e = zf.entries();
|
||||
}
|
||||
// ensure that the ZipFile is closed before checking the Enumeration
|
||||
try {
|
||||
if (e.hasMoreElements()) {
|
||||
ZipEntry ze = (ZipEntry)e.nextElement();
|
||||
}
|
||||
} catch (IllegalStateException ie) {
|
||||
}
|
||||
}
|
||||
}
|
94
test/jdk/java/util/zip/ZipFile/EnumerateAfterClose.java
Normal file
94
test/jdk/java/util/zip/ZipFile/EnumerateAfterClose.java
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2024, 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 4290060
|
||||
@summary Check if the zip file is closed before access any
|
||||
elements in the Enumeration.
|
||||
@run junit EnumerateAfterClose
|
||||
*/
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
public class EnumerateAfterClose {
|
||||
|
||||
// ZIP file used in this test
|
||||
private Path zip = Path.of("enum-after-close.zip");
|
||||
|
||||
/**
|
||||
* Create a sample ZIP file for use by this test
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@BeforeEach
|
||||
public void setUp() throws IOException {
|
||||
try (OutputStream out = Files.newOutputStream(zip);
|
||||
ZipOutputStream zo = new ZipOutputStream(out)) {
|
||||
zo.putNextEntry(new ZipEntry("file.txt"));
|
||||
zo.write("hello".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the ZIP file produced by this test
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@AfterEach
|
||||
public void cleanup() throws IOException {
|
||||
Files.deleteIfExists(zip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempting to using a ZipEntry Enumeration after its backing
|
||||
* ZipFile is closed should throw IllegalStateException.
|
||||
*
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void enumeratingAfterCloseShouldThrowISE() throws IOException {
|
||||
// Retain a reference to an enumeration backed by a closed ZipFile
|
||||
Enumeration e;
|
||||
try (ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
e = zf.entries();
|
||||
}
|
||||
// Using the enumeration after the ZipFile is closed should throw ISE
|
||||
assertThrows(IllegalStateException.class, () -> {
|
||||
if (e.hasMoreElements()) {
|
||||
ZipEntry ze = (ZipEntry)e.nextElement();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2010, 2024, 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
|
||||
@ -24,20 +24,64 @@
|
||||
/* @test
|
||||
@bug 7003462
|
||||
@summary Make sure cached Inflater does not get finalized.
|
||||
@run junit FinalizeInflater
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
public class FinalizeInflater {
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
try (ZipFile zf = new ZipFile(new File(System.getProperty("test.src", "."), "input.zip")))
|
||||
{
|
||||
ZipEntry ze = zf.getEntry("ReadZip.java");
|
||||
// ZIP file produced by this test
|
||||
private Path zip = Path.of("finalize-inflater.zip");
|
||||
|
||||
/**
|
||||
* Create the sample ZIP used in this test
|
||||
*
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@BeforeEach
|
||||
public void setUp() throws IOException {
|
||||
try (OutputStream out = Files.newOutputStream(zip);
|
||||
ZipOutputStream zo = new ZipOutputStream(out)) {
|
||||
zo.putNextEntry(new ZipEntry("file.txt"));
|
||||
byte[] hello = "hello".getBytes(StandardCharsets.UTF_8);
|
||||
for (int i = 0; i < 100; i++) {
|
||||
zo.write(hello);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the ZIP file produced by this test
|
||||
*
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@AfterEach
|
||||
public void cleanup() throws IOException {
|
||||
Files.deleteIfExists(zip);
|
||||
}
|
||||
|
||||
/**
|
||||
* A cached Inflater should not be made invalid by finalization
|
||||
*
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void shouldNotFinalizeInflaterInPool() throws IOException {
|
||||
try (ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
ZipEntry ze = zf.getEntry("file.txt");
|
||||
read(zf.getInputStream(ze));
|
||||
System.gc();
|
||||
System.runFinalization();
|
||||
@ -51,15 +95,10 @@ public class FinalizeInflater {
|
||||
throws IOException
|
||||
{
|
||||
Wrapper wrapper = new Wrapper(is);
|
||||
byte[] buffer = new byte[32];
|
||||
try {
|
||||
while(is.read(buffer)>0){}
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
}
|
||||
is.readAllBytes();
|
||||
}
|
||||
|
||||
static class Wrapper{
|
||||
static class Wrapper {
|
||||
InputStream is;
|
||||
public Wrapper(InputStream is) {
|
||||
this.is = is;
|
||||
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, 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 4206838
|
||||
@summary getEntry() will search for a directory
|
||||
even without an ending '/'.
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
public class GetDirEntry {
|
||||
public static void main(String args[]) throws Exception {
|
||||
try (ZipFile zf = new ZipFile(new File(System.getProperty("test.src", "."),
|
||||
"input.jar"))) {
|
||||
ZipEntry ze = zf.getEntry("META-INF");
|
||||
if (ze == null) {
|
||||
throw new Exception("failed to find a directory entry");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2011, 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 4528128 6846616
|
||||
@summary Test if reading InputStream of a closed ZipFile crashes VM
|
||||
@author kladko
|
||||
*/
|
||||
|
||||
|
||||
import java.util.zip.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ReadAfterClose {
|
||||
public static void main(String[] argv) throws Exception {
|
||||
InputStream in;
|
||||
try (ZipFile zf = new ZipFile(
|
||||
new File(System.getProperty("test.src","."),"crash.jar"))) {
|
||||
ZipEntry zent = zf.getEntry("Test.java");
|
||||
in = zf.getInputStream(zent);
|
||||
}
|
||||
// ensure zf is closed at this point
|
||||
try {
|
||||
in.read();
|
||||
} catch (IOException e) {
|
||||
return;
|
||||
}
|
||||
throw new Exception("Test failed.");
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2024, 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
|
||||
@ -22,185 +22,359 @@
|
||||
*/
|
||||
|
||||
/* @test
|
||||
@bug 4241361 4842702 4985614 6646605 5032358 6923692 6233323 8144977 8186464
|
||||
@bug 4241361 4842702 4985614 6646605 5032358 6923692 6233323 8144977 8186464 4401122 8322830
|
||||
@summary Make sure we can read a zip file.
|
||||
@key randomness
|
||||
@modules jdk.zipfs
|
||||
@run junit ReadZip
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.List;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.*;
|
||||
import java.util.Collections;
|
||||
import java.util.HexFormat;
|
||||
import java.util.Map;
|
||||
import java.util.zip.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class ReadZip {
|
||||
private static void unreached (Object o)
|
||||
throws Exception
|
||||
{
|
||||
// Should never get here
|
||||
throw new Exception ("Expected exception was not thrown");
|
||||
|
||||
// ZIP file produced during tests
|
||||
private Path zip = Path.of("read-zip.zip");
|
||||
|
||||
/**
|
||||
* Create a sample ZIP file for use by tests
|
||||
* @param name name of the ZIP file to create
|
||||
* @return a sample ZIP file
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
private Path createZip(String name) throws IOException {
|
||||
Path zip = Path.of(name);
|
||||
|
||||
try (OutputStream out = Files.newOutputStream(zip);
|
||||
ZipOutputStream zo = new ZipOutputStream(out)) {
|
||||
zo.putNextEntry(new ZipEntry("file.txt"));
|
||||
zo.write("hello".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
return zip;
|
||||
}
|
||||
|
||||
public static void main(String args[]) throws Exception {
|
||||
try (ZipFile zf = new ZipFile(new File(System.getProperty("test.src", "."),
|
||||
"input.zip"))) {
|
||||
// Make sure we throw NPE on null objects
|
||||
try { unreached (zf.getEntry(null)); }
|
||||
catch (NullPointerException e) {}
|
||||
/**
|
||||
* Delete the ZIP file produced after each test method
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@AfterEach
|
||||
public void cleanup() throws IOException {
|
||||
Files.deleteIfExists(zip);
|
||||
}
|
||||
|
||||
try { unreached (zf.getInputStream(null)); }
|
||||
catch (NullPointerException e) {}
|
||||
/**
|
||||
* Make sure we throw NPE when calling getEntry or getInputStream with null params
|
||||
*
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void nullPointerExceptionOnNullParams() throws IOException {
|
||||
zip = createZip("null-params.zip");
|
||||
try (ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
|
||||
ZipEntry ze = zf.getEntry("ReadZip.java");
|
||||
if (ze == null) {
|
||||
throw new Exception("cannot read from zip file");
|
||||
}
|
||||
assertThrows(NullPointerException.class, () -> zf.getEntry(null));
|
||||
assertThrows(NullPointerException.class, () -> zf.getInputStream(null));
|
||||
|
||||
// Sanity check that we can still read an entry
|
||||
ZipEntry ze = zf.getEntry("file.txt");
|
||||
assertNotNull(ze, "cannot read from zip file");
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we can read the zip file that has some garbage
|
||||
// bytes padded at the end.
|
||||
File newZip = new File(System.getProperty("test.dir", "."), "input2.zip");
|
||||
Files.copy(Paths.get(System.getProperty("test.src", ""), "input.zip"),
|
||||
newZip.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
/**
|
||||
* Read the zip file that has some garbage bytes padded at the end
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void bytesPaddedAtEnd() throws IOException {
|
||||
|
||||
newZip.setWritable(true);
|
||||
zip = createZip("bytes-padded.zip");
|
||||
|
||||
// pad some bytes
|
||||
try (OutputStream os = Files.newOutputStream(newZip.toPath(),
|
||||
StandardOpenOption.APPEND)) {
|
||||
os.write(1); os.write(3); os.write(5); os.write(7);
|
||||
try (OutputStream os = Files.newOutputStream(zip,
|
||||
StandardOpenOption.APPEND)) {
|
||||
os.write(1);
|
||||
os.write(3);
|
||||
os.write(5);
|
||||
os.write(7);
|
||||
}
|
||||
|
||||
try (ZipFile zf = new ZipFile(newZip)) {
|
||||
ZipEntry ze = zf.getEntry("ReadZip.java");
|
||||
if (ze == null) {
|
||||
throw new Exception("cannot read from zip file");
|
||||
}
|
||||
} finally {
|
||||
newZip.delete();
|
||||
try (ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
ZipEntry ze = zf.getEntry("file.txt");
|
||||
assertNotNull(ze, "cannot read from zip file");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that we can read a comment from the ZIP
|
||||
* file's 'End of Central Directory' header
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void readZipFileComment() throws IOException {
|
||||
|
||||
// Create a zip file with a comment in the 'End of Central Directory' header
|
||||
try (OutputStream out = Files.newOutputStream(zip);
|
||||
ZipOutputStream zos = new ZipOutputStream(out)) {
|
||||
ZipEntry ze = new ZipEntry("ZipEntry");
|
||||
zos.putNextEntry(ze);
|
||||
zos.write(1);
|
||||
zos.write(2);
|
||||
zos.write(3);
|
||||
zos.write(4);
|
||||
zos.closeEntry();
|
||||
zos.setComment("This is the comment for testing");
|
||||
}
|
||||
|
||||
// Read zip file comment
|
||||
try {
|
||||
try (FileOutputStream fos = new FileOutputStream(newZip);
|
||||
ZipOutputStream zos = new ZipOutputStream(fos))
|
||||
{
|
||||
ZipEntry ze = new ZipEntry("ZipEntry");
|
||||
zos.putNextEntry(ze);
|
||||
zos.write(1); zos.write(2); zos.write(3); zos.write(4);
|
||||
zos.closeEntry();
|
||||
zos.setComment("This is the comment for testing");
|
||||
}
|
||||
|
||||
try (ZipFile zf = new ZipFile(newZip)) {
|
||||
ZipEntry ze = zf.getEntry("ZipEntry");
|
||||
if (ze == null)
|
||||
throw new Exception("cannot read entry from zip file");
|
||||
if (!"This is the comment for testing".equals(zf.getComment()))
|
||||
throw new Exception("cannot read comment from zip file");
|
||||
}
|
||||
} finally {
|
||||
newZip.delete();
|
||||
}
|
||||
|
||||
// Read directory entry
|
||||
try {
|
||||
try (FileOutputStream fos = new FileOutputStream(newZip);
|
||||
ZipOutputStream zos = new ZipOutputStream(fos))
|
||||
{
|
||||
ZipEntry ze = new ZipEntry("directory/");
|
||||
zos.putNextEntry(ze);
|
||||
zos.closeEntry();
|
||||
}
|
||||
try (ZipFile zf = new ZipFile(newZip)) {
|
||||
ZipEntry ze = zf.getEntry("directory/");
|
||||
if (ze == null || !ze.isDirectory())
|
||||
throw new RuntimeException("read entry \"directory/\" failed");
|
||||
try (InputStream is = zf.getInputStream(ze)) {
|
||||
is.available();
|
||||
} catch (Exception x) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
|
||||
ze = zf.getEntry("directory");
|
||||
if (ze == null || !ze.isDirectory())
|
||||
throw new RuntimeException("read entry \"directory\" failed");
|
||||
try (InputStream is = zf.getInputStream(ze)) {
|
||||
is.available();
|
||||
} catch (Exception x) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
newZip.delete();
|
||||
}
|
||||
|
||||
// Throw a FNF exception when read a non-existing zip file
|
||||
try { unreached (new ZipFile(
|
||||
new File(System.getProperty("test.src", "."),
|
||||
"input"
|
||||
+ String.valueOf(new java.util.Random().nextInt())
|
||||
+ ".zip")));
|
||||
} catch (NoSuchFileException nsfe) {}
|
||||
|
||||
// read a zip file with ZIP64 end
|
||||
Path path = Paths.get(System.getProperty("test.dir", ""), "end64.zip");
|
||||
try {
|
||||
URI uri = URI.create("jar:" + path.toUri());
|
||||
Map<String, Object> env = Map.of("create", "true", "forceZIP64End", "true");
|
||||
try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
|
||||
Files.write(fs.getPath("hello"), "hello".getBytes());
|
||||
}
|
||||
try (ZipFile zf = new ZipFile(path.toFile())) {
|
||||
if (!"hello".equals(new String(zf.getInputStream(new ZipEntry("hello"))
|
||||
.readAllBytes(),
|
||||
US_ASCII)))
|
||||
throw new RuntimeException("zipfile: read entry failed");
|
||||
} catch (IOException x) {
|
||||
throw new RuntimeException("zipfile: zip64 end failed");
|
||||
}
|
||||
try (FileSystem fs = FileSystems.newFileSystem(uri, Map.of())) {
|
||||
if (!"hello".equals(new String(Files.readAllBytes(fs.getPath("hello")))))
|
||||
throw new RuntimeException("zipfs: read entry failed");
|
||||
} catch (IOException x) {
|
||||
throw new RuntimeException("zipfile: zip64 end failed");
|
||||
}
|
||||
} finally {
|
||||
Files.deleteIfExists(path);
|
||||
}
|
||||
|
||||
// read a zip file created via "echo hello | zip dst.zip -", which uses
|
||||
// ZIP64 end record
|
||||
if (Files.notExists(Paths.get("/usr/bin/zip")))
|
||||
return;
|
||||
try {
|
||||
Process zip = new ProcessBuilder("zip", path.toString().toString(), "-").start();
|
||||
OutputStream os = zip.getOutputStream();
|
||||
os.write("hello".getBytes(US_ASCII));
|
||||
os.close();
|
||||
zip.waitFor();
|
||||
if (zip.exitValue() == 0 && Files.exists(path)) {
|
||||
try (ZipFile zf = new ZipFile(path.toFile())) {
|
||||
if (!"hello".equals(new String(zf.getInputStream(new ZipEntry("-"))
|
||||
.readAllBytes())))
|
||||
throw new RuntimeException("zipfile: read entry failed");
|
||||
} catch (IOException x) {
|
||||
throw new RuntimeException("zipfile: zip64 end failed");
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Files.deleteIfExists(path);
|
||||
try (ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
ZipEntry ze = zf.getEntry("ZipEntry");
|
||||
assertNotNull(ze, "cannot read entry from zip file");
|
||||
assertEquals("This is the comment for testing", zf.getComment());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that a directory entry can be found using the
|
||||
* name 'directory/' as well as 'directory/'
|
||||
*
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void readDirectoryEntries() throws IOException {
|
||||
|
||||
// Create a ZIP containing some directory entries
|
||||
try (OutputStream fos = Files.newOutputStream(zip);
|
||||
ZipOutputStream zos = new ZipOutputStream(fos)) {
|
||||
// Add a META-INF directory with STORED compression type
|
||||
ZipEntry metaInf = new ZipEntry("META-INF/");
|
||||
metaInf.setMethod(ZipEntry.STORED);
|
||||
metaInf.setSize(0);
|
||||
metaInf.setCrc(0);
|
||||
zos.putNextEntry(metaInf);
|
||||
|
||||
// Add a regular directory
|
||||
ZipEntry dir = new ZipEntry("directory/");
|
||||
zos.putNextEntry(dir);
|
||||
zos.closeEntry();
|
||||
}
|
||||
|
||||
// Verify directory lookups
|
||||
try (ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
// Look up 'directory/' using the full name
|
||||
ZipEntry ze = zf.getEntry("directory/");
|
||||
assertNotNull(ze, "read entry \"directory/\" failed");
|
||||
assertTrue(ze.isDirectory(), "read entry \"directory/\" failed");
|
||||
assertEquals("directory/", ze.getName());
|
||||
|
||||
try (InputStream is = zf.getInputStream(ze)) {
|
||||
is.available();
|
||||
} catch (Exception x) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
|
||||
// Look up 'directory/' without the trailing slash
|
||||
ze = zf.getEntry("directory");
|
||||
assertNotNull(ze, "read entry \"directory\" failed");
|
||||
assertTrue(ze.isDirectory(), "read entry \"directory\" failed");
|
||||
assertEquals("directory/", ze.getName());
|
||||
|
||||
try (InputStream is = zf.getInputStream(ze)) {
|
||||
is.available();
|
||||
} catch (Exception x) {
|
||||
x.printStackTrace();
|
||||
}
|
||||
// Sanity check that also META-INF/ can be looked up with or without the trailing slash
|
||||
assertNotNull(zf.getEntry("META-INF"));
|
||||
assertNotNull(zf.getEntry("META-INF/"));
|
||||
assertEquals(zf.getEntry("META-INF").getName(),
|
||||
zf.getEntry("META-INF/").getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw a NoSuchFileException exception when reading a non-existing zip file
|
||||
*/
|
||||
@Test
|
||||
public void nonExistingFile() {
|
||||
File nonExistingFile = new File("non-existing-file-f6804460f.zip");
|
||||
assertThrows(NoSuchFileException.class, () ->
|
||||
new ZipFile(nonExistingFile));
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a Zip file with a 'Zip64 End of Central Directory header' which was created
|
||||
* using ZipFileSystem with the 'forceZIP64End' option.
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void readZip64EndZipFs() throws IOException {
|
||||
|
||||
// Create zip file with Zip64 end
|
||||
Map<String, Object> env = Map.of("create", "true", "forceZIP64End", "true");
|
||||
try (FileSystem fs = FileSystems.newFileSystem(zip, env)) {
|
||||
Files.write(fs.getPath("hello"), "hello".getBytes());
|
||||
}
|
||||
// Read using ZipFile
|
||||
try (ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
try (InputStream in = zf.getInputStream(zf.getEntry("hello"))) {
|
||||
assertEquals("hello", new String(in.readAllBytes(), StandardCharsets.US_ASCII));
|
||||
}
|
||||
}
|
||||
// Read using ZipFileSystem
|
||||
try (FileSystem fs = FileSystems.newFileSystem(zip, Map.of())) {
|
||||
assertEquals("hello", new String(Files.readAllBytes(fs.getPath("hello"))));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a zip file created via Info-ZIP in streaming mode,
|
||||
* which includes a 'Zip64 End of Central Directory header'.
|
||||
*
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
* @throws InterruptedException if an unexpected InterruptedException occurs
|
||||
*/
|
||||
@Test
|
||||
public void readZip64EndInfoZIPStreaming() throws IOException, InterruptedException {
|
||||
// ZIP created using: "echo -n hello | zip zip64.zip -"
|
||||
// Hex encoded using: "cat zip64.zip | xxd -ps"
|
||||
byte[] zipBytes = HexFormat.of().parseHex("""
|
||||
504b03042d0000000000c441295886a61036ffffffffffffffff01001400
|
||||
2d010010000500000000000000050000000000000068656c6c6f504b0102
|
||||
1e032d0000000000c441295886a610360500000005000000010000000000
|
||||
000001000000b011000000002d504b06062c000000000000001e032d0000
|
||||
00000000000000010000000000000001000000000000002f000000000000
|
||||
003800000000000000504b06070000000067000000000000000100000050
|
||||
4b050600000000010001002f000000380000000000
|
||||
""".replaceAll("\n","")
|
||||
);
|
||||
|
||||
Files.write(zip, zipBytes);
|
||||
|
||||
try (ZipFile zf = new ZipFile(this.zip.toFile())) {
|
||||
try (InputStream in = zf.getInputStream(zf.getEntry("-"))) {
|
||||
String contents = new String(in.readAllBytes(), StandardCharsets.US_ASCII);
|
||||
assertEquals("hello", contents);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the available() method overriden by the input stream returned by
|
||||
* ZipFile.getInputStream correctly returns the number of remaining uncompressed bytes
|
||||
*
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void availableShouldReturnRemainingUncompressedBytes() throws IOException {
|
||||
// The number of uncompressed bytes to write to the sample ZIP entry
|
||||
final int expectedBytes = 512;
|
||||
|
||||
// Create a sample ZIP with deflated entry of a known uncompressed size
|
||||
try (ZipOutputStream zo = new ZipOutputStream(Files.newOutputStream(zip))) {
|
||||
zo.putNextEntry(new ZipEntry("file.txt"));
|
||||
zo.write(new byte[expectedBytes]);
|
||||
}
|
||||
|
||||
// Verify the behavior of ZipFileInflaterInputStream.available()
|
||||
try (ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
ZipEntry e = zf.getEntry("file.txt");
|
||||
try (InputStream in = zf.getInputStream(e)) {
|
||||
// Initially, available() should return the full uncompressed size of the entry
|
||||
assertEquals(expectedBytes, in.available(),
|
||||
"wrong initial return value of available");
|
||||
|
||||
// Reading a few bytes should reduce the number of available bytes accordingly
|
||||
int bytesToRead = 10;
|
||||
in.read(new byte[bytesToRead]);
|
||||
assertEquals(expectedBytes - bytesToRead, in.available());
|
||||
|
||||
// Reading all remaining bytes should reduce the number of available bytes to zero
|
||||
in.transferTo(OutputStream.nullOutputStream());
|
||||
assertEquals(0, in.available());
|
||||
|
||||
// available on a closed input stream should return zero
|
||||
in.close();
|
||||
assertEquals(0, in.available());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that reading an InputStream from a closed ZipFile
|
||||
* throws IOException as expected and does not crash the VM.
|
||||
* See bugs: 4528128 6846616
|
||||
*
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void readAfterClose() throws IOException {
|
||||
zip = createZip("read-after-close.zip");
|
||||
InputStream in;
|
||||
try (ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
ZipEntry zent = zf.getEntry("file.txt");
|
||||
in = zf.getInputStream(zent);
|
||||
}
|
||||
|
||||
// zf is closed at this point
|
||||
assertThrows(IOException.class, () -> {
|
||||
in.read();
|
||||
});
|
||||
assertThrows(IOException.class, () -> {
|
||||
in.read(new byte[10]);
|
||||
});
|
||||
assertThrows(IOException.class, () -> {
|
||||
byte[] buf = new byte[10];
|
||||
in.read(buf, 0, buf.length);
|
||||
});
|
||||
assertThrows(IOException.class, () -> {
|
||||
in.readAllBytes();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that ZipFile can open a ZIP file with zero entries
|
||||
*
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void noEntries() throws IOException {
|
||||
// Create a ZIP file with no entries
|
||||
try (ZipOutputStream zo = new ZipOutputStream(Files.newOutputStream(zip))) {
|
||||
}
|
||||
|
||||
// Open the "empty" ZIP file
|
||||
try (ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
// Verify size
|
||||
assertEquals(0, zf.size());
|
||||
|
||||
// Verify entry lookup using ZipFile.getEntry()
|
||||
assertNull(zf.getEntry("file.txt"));
|
||||
|
||||
// Verify iteration using ZipFile.entries()
|
||||
assertEquals(Collections.emptyList(), Collections.list(zf.entries()));
|
||||
|
||||
// Verify iteration using ZipFile.stream()
|
||||
assertEquals(Collections.emptyList(), zf.stream().toList());
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2024, 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
|
||||
@ -25,31 +25,74 @@
|
||||
* @bug 4214795
|
||||
* @summary Make sure the same inflater will only be recycled
|
||||
* once.
|
||||
* @run junit ReleaseInflater
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.zip.*;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class ReleaseInflater {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
ZipFile zf = new ZipFile(new File(System.getProperty("test.src"),
|
||||
"input.jar"));
|
||||
ZipEntry e = zf.getEntry("ReleaseInflater.java");
|
||||
// ZIP file produced in this test
|
||||
private Path zip = Path.of("release-inflater.zip");
|
||||
|
||||
InputStream in1 = zf.getInputStream(e);
|
||||
// close the stream, the inflater will be released
|
||||
in1.close();
|
||||
// close the stream again, should be no-op
|
||||
in1.close();
|
||||
/**
|
||||
* Create a sample ZIP file for use by tests
|
||||
* @param name name of the ZIP file to create
|
||||
* @return a sample ZIP file
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@BeforeEach
|
||||
public void setUp() throws IOException {
|
||||
try (ZipOutputStream zo = new ZipOutputStream(Files.newOutputStream(zip))) {
|
||||
zo.putNextEntry(new ZipEntry("file.txt"));
|
||||
zo.write("helloworld".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
// create two new streams, allocating inflaters
|
||||
InputStream in2 = zf.getInputStream(e);
|
||||
InputStream in3 = zf.getInputStream(e);
|
||||
/**
|
||||
* Delete the ZIP and JAR files produced after each test method
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
|
||||
// check to see if they influence each other
|
||||
if (in2.read() != in3.read()) {
|
||||
throw new Exception("Stream is corrupted!");
|
||||
@AfterEach
|
||||
public void cleanup() throws IOException {
|
||||
Files.deleteIfExists(zip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that the same Inflater is not recycled across input streams
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void recycleInflaterOnlyOnce() throws IOException {
|
||||
try (ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
ZipEntry e = zf.getEntry("file.txt");
|
||||
|
||||
InputStream in1 = zf.getInputStream(e);
|
||||
// close the stream, the inflater will be released
|
||||
in1.close();
|
||||
// close the stream again, should be no-op
|
||||
in1.close();
|
||||
|
||||
// create two new streams, allocating inflaters
|
||||
InputStream in2 = zf.getInputStream(e);
|
||||
InputStream in3 = zf.getInputStream(e);
|
||||
|
||||
// check to see if they influence each other
|
||||
assertEquals(in2.read(), in3.read(), "Stream is corrupted!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2024, 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
|
||||
@ -23,74 +23,169 @@
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @run testng StreamZipEntriesTest
|
||||
* @run junit StreamZipEntriesTest
|
||||
* @summary Make sure we can stream entries of a zip file.
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.Object;
|
||||
import java.lang.System;
|
||||
import java.util.jar.JarFile;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
public class StreamZipEntriesTest {
|
||||
|
||||
// ZIP file produced in this test
|
||||
private Path zip = Path.of("stream.zip");
|
||||
// JAR file produced in this test
|
||||
private Path jar = Path.of("stream.jar");
|
||||
|
||||
/**
|
||||
* Create sample ZIP and JAR files used in in this test
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@BeforeEach
|
||||
public void setUp() throws IOException {
|
||||
|
||||
try (OutputStream out = Files.newOutputStream(zip);
|
||||
ZipOutputStream zo = new ZipOutputStream(out)) {
|
||||
zo.putNextEntry(new ZipEntry("entry1.txt"));
|
||||
zo.write("hello".getBytes(StandardCharsets.UTF_8));
|
||||
zo.putNextEntry(new ZipEntry("entry2.txt"));
|
||||
zo.write("hello".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
try (OutputStream out = Files.newOutputStream(jar);
|
||||
ZipOutputStream zo = new ZipOutputStream(out)) {
|
||||
// A JAR file may start with a META-INF/ directory before the manifest
|
||||
zo.putNextEntry(new ZipEntry("META-INF/"));
|
||||
// Write the manifest
|
||||
zo.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
|
||||
new Manifest().write(zo);
|
||||
|
||||
// Write two regular entries
|
||||
zo.putNextEntry(new ZipEntry("entry1.txt"));
|
||||
zo.write("hello".getBytes(StandardCharsets.UTF_8));
|
||||
zo.putNextEntry(new ZipEntry("entry2.txt"));
|
||||
zo.write("hello".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the ZIP file produced after each test method
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@AfterEach
|
||||
public void cleanup() throws IOException {
|
||||
Files.deleteIfExists(zip);
|
||||
Files.deleteIfExists(jar);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that ZipFile.stream() produces the expected entries
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void testStreamZip() throws IOException {
|
||||
try (ZipFile zf = new ZipFile(new File(System.getProperty("test.src", "."), "input.zip"))) {
|
||||
zf.stream().forEach(e -> assertTrue(e instanceof ZipEntry));
|
||||
zf.stream().forEach(e -> assertEquals(e.toString(), "ReadZip.java"));
|
||||
Set<String> names = new HashSet<>(Set.of("entry1.txt", "entry2.txt"));
|
||||
|
||||
try (ZipFile zf = new ZipFile(zip.toFile())) {
|
||||
zf.stream().forEach(e -> {
|
||||
assertTrue(e instanceof ZipEntry);
|
||||
String name = e.getName();
|
||||
assertNotNull(names.remove(name));
|
||||
String toString = e.toString();
|
||||
assertEquals(name, toString);
|
||||
});
|
||||
|
||||
// Check that all expected names were processed
|
||||
assertTrue(names.isEmpty());
|
||||
|
||||
// Check that Stream.toArray produces the expected result
|
||||
Object elements[] = zf.stream().toArray();
|
||||
assertEquals(1, elements.length);
|
||||
assertEquals(elements[0].toString(), "ReadZip.java");
|
||||
assertEquals(2, elements.length);
|
||||
assertEquals(elements[0].toString(), "entry1.txt");
|
||||
assertEquals(elements[1].toString(), "entry2.txt");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that JarFile.stream() produces the expected entries
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void testStreamJar() throws IOException {
|
||||
try (JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"))) {
|
||||
jf.stream().forEach(e -> assertTrue(e instanceof JarEntry));
|
||||
try (JarFile jf = new JarFile(jar.toFile())) {
|
||||
Set<String> names = new HashSet<>(Set.of(
|
||||
"META-INF/",
|
||||
"META-INF/MANIFEST.MF",
|
||||
"entry1.txt",
|
||||
"entry2.txt"
|
||||
));
|
||||
|
||||
jf.stream().forEach(e -> {
|
||||
assertTrue(e instanceof JarEntry);
|
||||
String name = e.getName();
|
||||
assertNotNull(names.remove(name));
|
||||
String toString = e.toString();
|
||||
assertEquals(name, toString);
|
||||
}
|
||||
);
|
||||
|
||||
// Check that all expected names were processed
|
||||
assertTrue(names.isEmpty(), "Unprocessed entries: " + names);
|
||||
|
||||
|
||||
// Check that Stream.toArray produces the expected result
|
||||
Object elements[] = jf.stream().toArray();
|
||||
assertEquals(3, elements.length);
|
||||
assertEquals(4, elements.length);
|
||||
assertEquals(elements[0].toString(), "META-INF/");
|
||||
assertEquals(elements[1].toString(), "META-INF/MANIFEST.MF");
|
||||
assertEquals(elements[2].toString(), "ReleaseInflater.java");
|
||||
assertEquals(elements[2].toString(), "entry1.txt");
|
||||
assertEquals(elements[3].toString(), "entry2.txt");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calling ZipFile.stream() on a closed ZipFile should throw ISE
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void testClosedZipFile() throws IOException {
|
||||
ZipFile zf = new ZipFile(new File(System.getProperty("test.src", "."), "input.zip"));
|
||||
ZipFile zf = new ZipFile(zip.toFile());
|
||||
zf.close();
|
||||
try {
|
||||
assertThrows(IllegalStateException.class, () -> {
|
||||
Stream s = zf.stream();
|
||||
fail("Should have thrown IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
// expected;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Calling JarFile.stream() on a closed JarFile should throw ISE
|
||||
* @throws IOException if an unexpected IOException occurs
|
||||
*/
|
||||
@Test
|
||||
public void testClosedJarFile() throws IOException {
|
||||
JarFile jf = new JarFile(new File(System.getProperty("test.src", "."), "input.jar"));
|
||||
JarFile jf = new JarFile(jar.toFile());
|
||||
jf.close();
|
||||
try {
|
||||
assertThrows(IllegalStateException.class, () -> {
|
||||
Stream s = jf.stream();
|
||||
fail("Should have thrown IllegalStateException");
|
||||
} catch (IllegalStateException e) {
|
||||
// expected;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user