Guard against JarURLConnection with wrong JAR

Update `JarURLConnection.get()` to guard against the wrong nested JAR
being used as context.

Closes gh-11367
This commit is contained in:
Phillip Webb 2018-05-30 19:59:56 -07:00
parent 5243adce22
commit 55d0611bc3
2 changed files with 17 additions and 3 deletions

View File

@ -255,6 +255,10 @@ final class JarURLConnection extends java.net.JarURLConnection {
static JarURLConnection get(URL url, JarFile jarFile) throws IOException { static JarURLConnection get(URL url, JarFile jarFile) throws IOException {
String spec = extractFullSpec(url, jarFile.getPathFromRoot()); 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 separator;
int index = 0; int index = 0;
while ((separator = spec.indexOf(SEPARATOR, 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); return JarURLConnection.notFound(jarFile, entryName);
} }
jarFile = jarFile.getNestedJarFile(jarEntry); jarFile = jarFile.getNestedJarFile(jarEntry);
index += separator + SEPARATOR.length(); index = separator + SEPARATOR.length();
} }
JarEntryName jarEntryName = JarEntryName.get(spec, index); JarEntryName jarEntryName = JarEntryName.get(spec, index);
if (Boolean.TRUE.equals(useFastExceptions.get())) { 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) { private static String extractFullSpec(URL url, String pathFromRoot) {
String file = url.getFile(); String file = url.getFile();
int separatorIndex = file.indexOf(SEPARATOR); int separatorIndex = file.indexOf(SEPARATOR);
if (separatorIndex < 0) { if (separatorIndex < 0 || !file.startsWith(pathFromRoot, separatorIndex)) {
return ""; return null;
} }
int specIndex = separatorIndex + SEPARATOR.length() + pathFromRoot.length(); int specIndex = separatorIndex + SEPARATOR.length() + pathFromRoot.length();
return file.substring(specIndex); return file.substring(specIndex);

View File

@ -18,6 +18,7 @@ package org.springframework.boot.loader.jar;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.net.URL; import java.net.URL;
import org.junit.Before; import org.junit.Before;
@ -152,6 +153,15 @@ public class JarURLConnectionTests {
.hasSameContentAs(new ByteArrayInputStream(new byte[] { 3 })); .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 @Test
public void getContentLengthReturnsLengthOfUnderlyingEntry() throws Exception { public void getContentLengthReturnsLengthOfUnderlyingEntry() throws Exception {
URL url = new URL(new URL("jar", null, -1, URL url = new URL(new URL("jar", null, -1,