From b103aaa1f612b866d62643907153b1881fb1e871 Mon Sep 17 00:00:00 2001 From: Ian Kettle <25729118+icikle@users.noreply.github.com> Date: Tue, 15 Sep 2026 09:03:31 +1200 Subject: [PATCH 1/2] Fix inflater cache race in NestedJarFileResources Update `NestedJarFileResources` to fix a race condition that could result in a `NullPointerException`. The methods `getOrCreateInflater` and `endOrCacheInflater` both synchronize on a local `inflaterCache` variable but attempted to use the `this.inflaterCache` instance which could be set to null. The `releaseInflators` method had a synchronized block for ending each inflater but the cache was being nulled out outside the block meaning that the other 2 methods mentioned could hit the race condition. Signed-off-by: Ian Kettle <25729118+icikle@users.noreply.github.com> See gh-51744 --- .../boot/loader/jar/NestedJarFileResources.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/loader/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/NestedJarFileResources.java b/loader/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/NestedJarFileResources.java index 41fc29b55ce..812c7d191fb 100644 --- a/loader/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/NestedJarFileResources.java +++ b/loader/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/NestedJarFileResources.java @@ -116,7 +116,7 @@ class NestedJarFileResources implements Runnable { Deque inflaterCache = this.inflaterCache; if (inflaterCache != null) { synchronized (inflaterCache) { - Inflater inflater = this.inflaterCache.poll(); + Inflater inflater = inflaterCache.poll(); if (inflater != null) { return inflater; } @@ -136,7 +136,7 @@ class NestedJarFileResources implements Runnable { synchronized (inflaterCache) { if (this.inflaterCache == inflaterCache && inflaterCache.size() < INFLATER_CACHE_LIMIT) { inflater.reset(); - this.inflaterCache.add(inflater); + inflaterCache.add(inflater); return; } } @@ -167,13 +167,13 @@ class NestedJarFileResources implements Runnable { private IOException releaseInflators(IOException exceptionChain) { Deque inflaterCache = this.inflaterCache; if (inflaterCache != null) { - try { - synchronized (inflaterCache) { + synchronized (inflaterCache) { + try { inflaterCache.forEach(Inflater::end); } - } - finally { - this.inflaterCache = null; + finally { + this.inflaterCache = null; + } } } return exceptionChain; From d6aac54e2e2bbb00b7ee60a0ad551a8d2d2b0730 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Mon, 14 Sep 2026 17:34:36 -0700 Subject: [PATCH 2/2] Polish 'Fix inflater cache race in NestedJarFileResources' See gh-51744 --- .../springframework/boot/loader/jar/NestedJarFileResources.java | 1 + 1 file changed, 1 insertion(+) diff --git a/loader/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/NestedJarFileResources.java b/loader/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/NestedJarFileResources.java index 812c7d191fb..bf4aa5eded4 100644 --- a/loader/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/NestedJarFileResources.java +++ b/loader/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/NestedJarFileResources.java @@ -37,6 +37,7 @@ import org.springframework.boot.loader.zip.ZipContent.Kind; * for registration with a {@link Cleaner}. * * @author Phillip Webb + * @author Ian Kettle */ class NestedJarFileResources implements Runnable {