From 55d0611bc3fce7352d934f4c9f4494e6a39edfb6 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Wed, 30 May 2018 19:59:56 -0700 Subject: [PATCH] Guard against JarURLConnection with wrong JAR Update `JarURLConnection.get()` to guard against the wrong nested JAR being used as context. Closes gh-11367 --- .../boot/loader/jar/JarURLConnection.java | 10 +++++++--- .../boot/loader/jar/JarURLConnectionTests.java | 10 ++++++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java index 59ee3f8f1e0..4a81ed10bc8 100644 --- a/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java +++ b/spring-boot-tools/spring-boot-loader/src/main/java/org/springframework/boot/loader/jar/JarURLConnection.java @@ -255,6 +255,10 @@ final class JarURLConnection extends java.net.JarURLConnection { static JarURLConnection get(URL url, JarFile jarFile) throws IOException { String spec = extractFullSpec(url, jarFile.getPathFromRoot()); + if (spec == null) { + return (Boolean.TRUE.equals(useFastExceptions.get()) ? NOT_FOUND_CONNECTION + : new JarURLConnection(url, null, EMPTY_JAR_ENTRY_NAME)); + } int separator; int index = 0; while ((separator = spec.indexOf(SEPARATOR, index)) > 0) { @@ -264,7 +268,7 @@ final class JarURLConnection extends java.net.JarURLConnection { return JarURLConnection.notFound(jarFile, entryName); } jarFile = jarFile.getNestedJarFile(jarEntry); - index += separator + SEPARATOR.length(); + index = separator + SEPARATOR.length(); } JarEntryName jarEntryName = JarEntryName.get(spec, index); if (Boolean.TRUE.equals(useFastExceptions.get())) { @@ -279,8 +283,8 @@ final class JarURLConnection extends java.net.JarURLConnection { private static String extractFullSpec(URL url, String pathFromRoot) { String file = url.getFile(); int separatorIndex = file.indexOf(SEPARATOR); - if (separatorIndex < 0) { - return ""; + if (separatorIndex < 0 || !file.startsWith(pathFromRoot, separatorIndex)) { + return null; } int specIndex = separatorIndex + SEPARATOR.length() + pathFromRoot.length(); return file.substring(specIndex); diff --git a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarURLConnectionTests.java b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarURLConnectionTests.java index 28d8dae188d..d35faac08eb 100644 --- a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarURLConnectionTests.java +++ b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarURLConnectionTests.java @@ -18,6 +18,7 @@ package org.springframework.boot.loader.jar; import java.io.ByteArrayInputStream; import java.io.File; +import java.io.FileNotFoundException; import java.net.URL; import org.junit.Before; @@ -152,6 +153,15 @@ public class JarURLConnectionTests { .hasSameContentAs(new ByteArrayInputStream(new byte[] { 3 })); } + @Test(expected = FileNotFoundException.class) + public void connectionToEntryUsingWrongAbsoluteUrlForEntryFromNestedJarFile() + throws Exception { + URL url = new URL("jar:file:" + getAbsolutePath() + "!/w.jar!/3.dat"); + JarFile nested = this.jarFile + .getNestedJarFile(this.jarFile.getEntry("nested.jar")); + JarURLConnection.get(url, nested).getInputStream(); + } + @Test public void getContentLengthReturnsLengthOfUnderlyingEntry() throws Exception { URL url = new URL(new URL("jar", null, -1,