diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/Handler.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/Handler.java index 4852470c6a..4809cff762 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/Handler.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/Handler.java @@ -20,9 +20,9 @@ import java.io.File; import java.io.IOException; import java.lang.ref.SoftReference; import java.net.MalformedURLException; +import java.net.URI; import java.net.URL; import java.net.URLConnection; -import java.net.URLDecoder; import java.net.URLStreamHandler; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -302,8 +302,7 @@ public class Handler extends URLStreamHandler { if (!name.startsWith(FILE_PROTOCOL)) { throw new IllegalStateException("Not a file URL"); } - String path = name.substring(FILE_PROTOCOL.length()); - File file = new File(URLDecoder.decode(path, "UTF-8")); + File file = new File(URI.create(name)); Map cache = rootFileCache.get(); JarFile result = (cache != null) ? cache.get(file) : null; if (result == null) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/HandlerTests.java b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/HandlerTests.java index 3edb4627a9..9025382899 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/HandlerTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/HandlerTests.java @@ -165,6 +165,34 @@ class HandlerTests { assertThat(jdkConnection).isNotInstanceOf(JarURLConnection.class); } + @Test + public void whenJarHasAPlusInItsPathConnectionJarFileMatchesOriginalJarFile() throws Exception { + File testJar = this.temporaryFolder.newFile("t+e+s+t.jar"); + TestJarCreator.createTestJar(testJar); + URL url = new URL(null, "jar:" + testJar.toURI().toURL() + "!/nested.jar!/3.dat", this.handler); + JarURLConnection connection = (JarURLConnection) url.openConnection(); + try { + assertThat(connection.getJarFile().getRootJarFile().getFile()).isEqualTo(testJar); + } + finally { + connection.getJarFile().close(); + } + } + + @Test + public void whenJarHasASpaceInItsPathConnectionJarFileMatchesOriginalJarFile() throws Exception { + File testJar = this.temporaryFolder.newFile("t e s t.jar"); + TestJarCreator.createTestJar(testJar); + URL url = new URL(null, "jar:" + testJar.toURI().toURL() + "!/nested.jar!/3.dat", this.handler); + JarURLConnection connection = (JarURLConnection) url.openConnection(); + try { + assertThat(connection.getJarFile().getRootJarFile().getFile()).isEqualTo(testJar); + } + finally { + connection.getJarFile().close(); + } + } + private void assertStandardAndCustomHandlerUrlsAreEqual(String context, String spec) throws MalformedURLException { URL standardUrl = new URL(new URL("jar:" + context), spec); URL customHandlerUrl = new URL(new URL("jar", null, -1, context, this.handler), spec);