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
pull/18464/head
Andy Wilkinson 5 years ago
parent 5d346410fa
commit 795c2f225f

@ -123,4 +123,10 @@ class CentralDirectoryEndRecord {
return (int) numberOfRecords; 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();
}
} }

@ -80,6 +80,8 @@ public class JarFile extends java.util.jar.JarFile {
private boolean signed; private boolean signed;
private String comment;
/** /**
* Create a new {@link JarFile} backed by the specified file. * Create a new {@link JarFile} backed by the specified file.
* @param file the root jar file * @param file the root jar file
@ -146,6 +148,7 @@ public class JarFile extends java.util.jar.JarFile {
@Override @Override
public void visitStart(CentralDirectoryEndRecord endRecord, RandomAccessData centralDirectoryData) { public void visitStart(CentralDirectoryEndRecord endRecord, RandomAccessData centralDirectoryData) {
JarFile.this.comment = endRecord.getComment();
} }
@Override @Override
@ -290,6 +293,11 @@ public class JarFile extends java.util.jar.JarFile {
JarFileType.NESTED_JAR); JarFileType.NESTED_JAR);
} }
@Override
public String getComment() {
return this.comment;
}
@Override @Override
public int size() { public int size() {
return this.entries.getSize(); return this.entries.getSize();

@ -41,6 +41,7 @@ public abstract class TestJarCreator {
public static void createTestJar(File file, boolean unpackNested) throws Exception { public static void createTestJar(File file, boolean unpackNested) throws Exception {
FileOutputStream fileOutputStream = new FileOutputStream(file); FileOutputStream fileOutputStream = new FileOutputStream(file);
try (JarOutputStream jarOutputStream = new JarOutputStream(fileOutputStream)) { try (JarOutputStream jarOutputStream = new JarOutputStream(fileOutputStream)) {
jarOutputStream.setComment("outer");
writeManifest(jarOutputStream, "j1"); writeManifest(jarOutputStream, "j1");
writeEntry(jarOutputStream, "1.dat", 1); writeEntry(jarOutputStream, "1.dat", 1);
writeEntry(jarOutputStream, "2.dat", 2); writeEntry(jarOutputStream, "2.dat", 2);
@ -88,6 +89,7 @@ public abstract class TestJarCreator {
private static byte[] getNestedJarData(boolean multiRelease) throws Exception { private static byte[] getNestedJarData(boolean multiRelease) throws Exception {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
JarOutputStream jarOutputStream = new JarOutputStream(byteArrayOutputStream); JarOutputStream jarOutputStream = new JarOutputStream(byteArrayOutputStream);
jarOutputStream.setComment("nested");
writeManifest(jarOutputStream, "j2", multiRelease); writeManifest(jarOutputStream, "j2", multiRelease);
if (multiRelease) { if (multiRelease) {
writeEntry(jarOutputStream, "multi-release.dat", 8); writeEntry(jarOutputStream, "multi-release.dat", 8);

@ -79,6 +79,7 @@ public class JarFileTests {
public void jdkJarFile() throws Exception { public void jdkJarFile() throws Exception {
// Sanity checks to see how the default jar file operates // Sanity checks to see how the default jar file operates
java.util.jar.JarFile jarFile = new java.util.jar.JarFile(this.rootJarFile); java.util.jar.JarFile jarFile = new java.util.jar.JarFile(this.rootJarFile);
assertThat(jarFile.getComment()).isEqualTo("outer");
Enumeration<java.util.jar.JarEntry> entries = jarFile.entries(); Enumeration<java.util.jar.JarEntry> entries = jarFile.entries();
assertThat(entries.nextElement().getName()).isEqualTo("META-INF/"); assertThat(entries.nextElement().getName()).isEqualTo("META-INF/");
assertThat(entries.nextElement().getName()).isEqualTo("META-INF/MANIFEST.MF"); assertThat(entries.nextElement().getName()).isEqualTo("META-INF/MANIFEST.MF");
@ -152,6 +153,11 @@ public class JarFileTests {
assertThat(entry.getName()).isEqualTo("1.dat"); assertThat(entry.getName()).isEqualTo("1.dat");
} }
@Test
public void getComment() {
assertThat(this.jarFile.getComment()).isEqualTo("outer");
}
@Test @Test
public void getInputStream() throws Exception { public void getInputStream() throws Exception {
InputStream inputStream = this.jarFile.getInputStream(this.jarFile.getEntry("1.dat")); InputStream inputStream = this.jarFile.getInputStream(this.jarFile.getEntry("1.dat"));
@ -245,6 +251,7 @@ public class JarFileTests {
@Test @Test
public void getNestedJarFile() throws Exception { public void getNestedJarFile() throws Exception {
JarFile nestedJarFile = this.jarFile.getNestedJarFile(this.jarFile.getEntry("nested.jar")); JarFile nestedJarFile = this.jarFile.getNestedJarFile(this.jarFile.getEntry("nested.jar"));
assertThat(nestedJarFile.getComment()).isEqualTo("nested");
Enumeration<java.util.jar.JarEntry> entries = nestedJarFile.entries(); Enumeration<java.util.jar.JarEntry> entries = nestedJarFile.entries();
assertThat(entries.nextElement().getName()).isEqualTo("META-INF/"); assertThat(entries.nextElement().getName()).isEqualTo("META-INF/");

Loading…
Cancel
Save