From 795c2f225fdf0215dc7dbe1794c02baa0363ec8e Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Fri, 6 Sep 2019 14:29:48 +0100 Subject: [PATCH] Support getComment() on a nested JarFile Previously, calling getComment() on a nested jar file would result in the outer jar file's comment being returned. This commit updates the loader's JarFile to read the file's comment from the central directory end record and return it from getComment(). Fixes gh-18128 --- .../boot/loader/jar/CentralDirectoryEndRecord.java | 6 ++++++ .../java/org/springframework/boot/loader/jar/JarFile.java | 8 ++++++++ .../org/springframework/boot/loader/TestJarCreator.java | 2 ++ .../org/springframework/boot/loader/jar/JarFileTests.java | 7 +++++++ 4 files changed, 23 insertions(+) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/CentralDirectoryEndRecord.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/CentralDirectoryEndRecord.java index c3bfb8a399d..35ef5b20386 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/CentralDirectoryEndRecord.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/CentralDirectoryEndRecord.java @@ -123,4 +123,10 @@ class CentralDirectoryEndRecord { return (int) numberOfRecords; } + String getComment() { + int commentLength = (int) Bytes.littleEndianValue(this.block, this.offset + COMMENT_LENGTH_OFFSET, 2); + AsciiBytes comment = new AsciiBytes(this.block, this.offset + COMMENT_LENGTH_OFFSET + 2, commentLength); + return comment.toString(); + } + } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java index 07202b502c5..26d62978eb4 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarFile.java @@ -80,6 +80,8 @@ public class JarFile extends java.util.jar.JarFile { private boolean signed; + private String comment; + /** * Create a new {@link JarFile} backed by the specified file. * @param file the root jar file @@ -146,6 +148,7 @@ public class JarFile extends java.util.jar.JarFile { @Override public void visitStart(CentralDirectoryEndRecord endRecord, RandomAccessData centralDirectoryData) { + JarFile.this.comment = endRecord.getComment(); } @Override @@ -290,6 +293,11 @@ public class JarFile extends java.util.jar.JarFile { JarFileType.NESTED_JAR); } + @Override + public String getComment() { + return this.comment; + } + @Override public int size() { return this.entries.getSize(); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/TestJarCreator.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/TestJarCreator.java index 77efa2a9449..06976f0952a 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/TestJarCreator.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/TestJarCreator.java @@ -41,6 +41,7 @@ public abstract class TestJarCreator { public static void createTestJar(File file, boolean unpackNested) throws Exception { FileOutputStream fileOutputStream = new FileOutputStream(file); try (JarOutputStream jarOutputStream = new JarOutputStream(fileOutputStream)) { + jarOutputStream.setComment("outer"); writeManifest(jarOutputStream, "j1"); writeEntry(jarOutputStream, "1.dat", 1); writeEntry(jarOutputStream, "2.dat", 2); @@ -88,6 +89,7 @@ public abstract class TestJarCreator { private static byte[] getNestedJarData(boolean multiRelease) throws Exception { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); JarOutputStream jarOutputStream = new JarOutputStream(byteArrayOutputStream); + jarOutputStream.setComment("nested"); writeManifest(jarOutputStream, "j2", multiRelease); if (multiRelease) { writeEntry(jarOutputStream, "multi-release.dat", 8); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java index 1b0c4194f9d..416465c4733 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java @@ -79,6 +79,7 @@ public class JarFileTests { public void jdkJarFile() throws Exception { // Sanity checks to see how the default jar file operates java.util.jar.JarFile jarFile = new java.util.jar.JarFile(this.rootJarFile); + assertThat(jarFile.getComment()).isEqualTo("outer"); Enumeration entries = jarFile.entries(); assertThat(entries.nextElement().getName()).isEqualTo("META-INF/"); assertThat(entries.nextElement().getName()).isEqualTo("META-INF/MANIFEST.MF"); @@ -152,6 +153,11 @@ public class JarFileTests { assertThat(entry.getName()).isEqualTo("1.dat"); } + @Test + public void getComment() { + assertThat(this.jarFile.getComment()).isEqualTo("outer"); + } + @Test public void getInputStream() throws Exception { InputStream inputStream = this.jarFile.getInputStream(this.jarFile.getEntry("1.dat")); @@ -245,6 +251,7 @@ public class JarFileTests { @Test public void getNestedJarFile() throws Exception { JarFile nestedJarFile = this.jarFile.getNestedJarFile(this.jarFile.getEntry("nested.jar")); + assertThat(nestedJarFile.getComment()).isEqualTo("nested"); Enumeration entries = nestedJarFile.entries(); assertThat(entries.nextElement().getName()).isEqualTo("META-INF/");