Skip to content

Commit f28caee

Browse files
committed
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
1 parent d390471 commit f28caee

File tree

2 files changed

+51
-6
lines changed

2 files changed

+51
-6
lines changed

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,7 @@ private class JarEntryInputStream extends InputStream {
706706
JarEntryInputStream(ZipContent.Entry entry) throws IOException {
707707
this.uncompressedSize = entry.getUncompressedSize();
708708
this.content = entry.openContent();
709+
this.remaining = this.uncompressedSize;
709710
}
710711

711712
@Override
@@ -727,9 +728,6 @@ public int read(byte[] b, int off, int len) throws IOException {
727728
}
728729
result = count;
729730
}
730-
if (this.remaining == 0) {
731-
close();
732-
}
733731
return result;
734732
}
735733

@@ -741,9 +739,6 @@ public long skip(long n) throws IOException {
741739
this.pos += result;
742740
this.remaining -= result;
743741
}
744-
if (this.remaining == 0) {
745-
close();
746-
}
747742
return result;
748743
}
749744

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,56 @@ void mismatchedStreamEntriesThrowsException() throws IOException {
431431
.hasMessage("Content mismatch when reading security info for entry 'content' (content check)");
432432
}
433433

434+
@Test
435+
void readingToEndOfStoredContentCausesAvailableToReachZero() throws IOException {
436+
try (NestedJarFile jar = new NestedJarFile(this.file)) {
437+
JarEntry entry = jar.getEntry("nested.jar");
438+
try (InputStream input = jar.getInputStream(entry)) {
439+
assertThat(input.available()).isGreaterThan(0);
440+
StreamUtils.copyToByteArray(input);
441+
assertThat(input.available()).isZero();
442+
}
443+
}
444+
}
445+
446+
@Test
447+
void readingToEndOfDeflatedContentCausesAvailableToReachZero() throws IOException {
448+
try (NestedJarFile jar = new NestedJarFile(this.file)) {
449+
JarEntry entry = jar.getEntry("d/9.dat");
450+
try (InputStream input = jar.getInputStream(entry)) {
451+
assertThat(input.available()).isGreaterThan(0);
452+
StreamUtils.copyToByteArray(input);
453+
assertThat(input.available()).isZero();
454+
}
455+
}
456+
}
457+
458+
@Test
459+
void skippingBeyondEndOfStoredContentCausesAvailableToReachZero() throws IOException {
460+
try (NestedJarFile jar = new NestedJarFile(this.file)) {
461+
JarEntry entry = jar.getEntry("nested.jar");
462+
try (InputStream input = jar.getInputStream(entry)) {
463+
assertThat(input.available()).isGreaterThan(0);
464+
long skipped = input.skip(1000);
465+
assertThat(skipped).isLessThan(1000);
466+
assertThat(input.available()).isZero();
467+
}
468+
}
469+
}
470+
471+
@Test
472+
void skippingBeyondEndOfDeflatedContentCausesAvailableToReachZero() throws IOException {
473+
try (NestedJarFile jar = new NestedJarFile(this.file)) {
474+
JarEntry entry = jar.getEntry("d/9.dat");
475+
try (InputStream input = jar.getInputStream(entry)) {
476+
assertThat(input.available()).isGreaterThan(0);
477+
long skipped = input.skip(1000);
478+
assertThat(skipped).isLessThan(1000);
479+
assertThat(input.available()).isZero();
480+
}
481+
}
482+
}
483+
434484
private List<String> collectComments(JarFile jarFile) throws IOException {
435485
try (jarFile) {
436486
List<String> comments = new ArrayList<>();

0 commit comments

Comments
 (0)