Browse Source

Fix NestedJarFile.JarEntryInputStream's available() behavior

Previously, available() would return 0 initially and then negative
values once some data head been read. It should be a positive value
(for entries with content) initially a decrease as data is read
reaching zero once an entry's data has been read in its entirety.

This commit initialises the count of the remaining bytes to
be equal to the entry's uncompressed size. It also removes logic
that closes the stream when remaining equals zero upon read or skip.
This condition was not reached before as remaining would become
negative as soon as any data was read or skipped. With the correct
initialization of remaining, the condition is now reached and it
results in test failures due to premature closure. Furthermore, the
javadoc of read and skip do not require the stream to be closed
when the reach end of file.

Closes gh-47056
pull/47304/head
Andy Wilkinson 3 months ago
parent
commit
f28caee30d
  1. 7
      spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/NestedJarFile.java
  2. 50
      spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/NestedJarFileTests.java

7
spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/NestedJarFile.java

@ -706,6 +706,7 @@ public class NestedJarFile extends JarFile { @@ -706,6 +706,7 @@ public class NestedJarFile extends JarFile {
JarEntryInputStream(ZipContent.Entry entry) throws IOException {
this.uncompressedSize = entry.getUncompressedSize();
this.content = entry.openContent();
this.remaining = this.uncompressedSize;
}
@Override
@ -727,9 +728,6 @@ public class NestedJarFile extends JarFile { @@ -727,9 +728,6 @@ public class NestedJarFile extends JarFile {
}
result = count;
}
if (this.remaining == 0) {
close();
}
return result;
}
@ -741,9 +739,6 @@ public class NestedJarFile extends JarFile { @@ -741,9 +739,6 @@ public class NestedJarFile extends JarFile {
this.pos += result;
this.remaining -= result;
}
if (this.remaining == 0) {
close();
}
return result;
}

50
spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/NestedJarFileTests.java

@ -431,6 +431,56 @@ class NestedJarFileTests { @@ -431,6 +431,56 @@ class NestedJarFileTests {
.hasMessage("Content mismatch when reading security info for entry 'content' (content check)");
}
@Test
void readingToEndOfStoredContentCausesAvailableToReachZero() throws IOException {
try (NestedJarFile jar = new NestedJarFile(this.file)) {
JarEntry entry = jar.getEntry("nested.jar");
try (InputStream input = jar.getInputStream(entry)) {
assertThat(input.available()).isGreaterThan(0);
StreamUtils.copyToByteArray(input);
assertThat(input.available()).isZero();
}
}
}
@Test
void readingToEndOfDeflatedContentCausesAvailableToReachZero() throws IOException {
try (NestedJarFile jar = new NestedJarFile(this.file)) {
JarEntry entry = jar.getEntry("d/9.dat");
try (InputStream input = jar.getInputStream(entry)) {
assertThat(input.available()).isGreaterThan(0);
StreamUtils.copyToByteArray(input);
assertThat(input.available()).isZero();
}
}
}
@Test
void skippingBeyondEndOfStoredContentCausesAvailableToReachZero() throws IOException {
try (NestedJarFile jar = new NestedJarFile(this.file)) {
JarEntry entry = jar.getEntry("nested.jar");
try (InputStream input = jar.getInputStream(entry)) {
assertThat(input.available()).isGreaterThan(0);
long skipped = input.skip(1000);
assertThat(skipped).isLessThan(1000);
assertThat(input.available()).isZero();
}
}
}
@Test
void skippingBeyondEndOfDeflatedContentCausesAvailableToReachZero() throws IOException {
try (NestedJarFile jar = new NestedJarFile(this.file)) {
JarEntry entry = jar.getEntry("d/9.dat");
try (InputStream input = jar.getInputStream(entry)) {
assertThat(input.available()).isGreaterThan(0);
long skipped = input.skip(1000);
assertThat(skipped).isLessThan(1000);
assertThat(input.available()).isZero();
}
}
}
private List<String> collectComments(JarFile jarFile) throws IOException {
try (jarFile) {
List<String> comments = new ArrayList<>();

Loading…
Cancel
Save