Polish "Support zip64 jars"

See gh-16091
This commit is contained in:
Andy Wilkinson
2019-09-20 12:42:30 +01:00
parent 1917e1eac5
commit 02ac089767
4 changed files with 115 additions and 54 deletions

View File

@@ -143,14 +143,15 @@ class JarFileArchiveTests {
}
@Test
void filesInzip64ArchivesAreAllListed() throws IOException {
void filesInZip64ArchivesAreAllListed() throws IOException {
File file = new File(this.tempDir, "test.jar");
FileCopyUtils.copy(writeZip64Jar(), file);
JarFileArchive zip64Archive = new JarFileArchive(file);
Iterator<Entry> it = zip64Archive.iterator();
for (int i = 0; i < 65537; i++) {
assertThat(it.hasNext()).as(i + "nth file is present").isTrue();
it.next();
try (JarFileArchive zip64Archive = new JarFileArchive(file)) {
Iterator<Entry> entries = zip64Archive.iterator();
for (int i = 0; i < 65537; i++) {
assertThat(entries.hasNext()).as(i + "nth file is present").isTrue();
entries.next();
}
}
}

View File

@@ -16,19 +16,26 @@
package org.springframework.boot.loader.jar;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -512,6 +519,65 @@ class JarFileTests {
}
}
@Test
void zip64JarCanBeRead() throws Exception {
File zip64Jar = new File(this.tempDir, "zip64.jar");
FileCopyUtils.copy(zip64Jar(), zip64Jar);
try (JarFile zip64JarFile = new JarFile(zip64Jar)) {
List<JarEntry> entries = Collections.list(zip64JarFile.entries());
assertThat(entries).hasSize(65537);
for (int i = 0; i < entries.size(); i++) {
JarEntry entry = entries.get(i);
InputStream entryInput = zip64JarFile.getInputStream(entry);
String contents = StreamUtils.copyToString(entryInput, StandardCharsets.UTF_8);
assertThat(contents).isEqualTo("Entry " + (i + 1));
}
}
}
@Test
void nestedZip64JarCanBeRead() throws Exception {
File outer = new File(this.tempDir, "outer.jar");
try (JarOutputStream jarOutput = new JarOutputStream(new FileOutputStream(outer))) {
JarEntry nestedEntry = new JarEntry("nested-zip64.jar");
byte[] contents = zip64Jar();
nestedEntry.setSize(contents.length);
nestedEntry.setCompressedSize(contents.length);
CRC32 crc32 = new CRC32();
crc32.update(contents);
nestedEntry.setCrc(crc32.getValue());
nestedEntry.setMethod(ZipEntry.STORED);
jarOutput.putNextEntry(nestedEntry);
jarOutput.write(contents);
jarOutput.closeEntry();
}
try (JarFile outerJarFile = new JarFile(outer)) {
try (JarFile nestedZip64JarFile = outerJarFile
.getNestedJarFile(outerJarFile.getJarEntry("nested-zip64.jar"))) {
List<JarEntry> entries = Collections.list(nestedZip64JarFile.entries());
assertThat(entries).hasSize(65537);
for (int i = 0; i < entries.size(); i++) {
JarEntry entry = entries.get(i);
InputStream entryInput = nestedZip64JarFile.getInputStream(entry);
String contents = StreamUtils.copyToString(entryInput, StandardCharsets.UTF_8);
assertThat(contents).isEqualTo("Entry " + (i + 1));
}
}
}
}
private byte[] zip64Jar() throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
JarOutputStream jarOutput = new JarOutputStream(bytes);
for (int i = 0; i < 65537; i++) {
jarOutput.putNextEntry(new JarEntry(i + ".dat"));
jarOutput.write(("Entry " + (i + 1)).getBytes(StandardCharsets.UTF_8));
jarOutput.closeEntry();
}
jarOutput.close();
return bytes.toByteArray();
}
private int getJavaVersion() {
try {
Object runtimeVersion = Runtime.class.getMethod("version").invoke(null);