From 3772d9f937a2097bba75a227db0ac86611da5ef5 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 1 Jun 2016 15:33:36 +0100 Subject: [PATCH] Update JarURLConnection to only require file read permission Previously, JarURLConnection didn't override getPermission(). This meant that it required all permissions. This was at odds with the Oracle JVM's concrete sun.net.www.protocol.jar.JarURLConnection which overrides getPermission to return a FilePermission with the read action for the path of the underlying jar. This commit updates our JarURLConnection to align its behaviour with sun.net.www.protocol.jar.JarURLConnection. Closes gh-5411 --- .../boot/loader/jar/JarURLConnection.java | 14 ++++++++++++++ .../boot/loader/jar/JarFileTests.java | 14 +++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) 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 dd7d88b9c13..720808c1234 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 @@ -18,12 +18,14 @@ package org.springframework.boot.loader.jar; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; +import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.net.URLStreamHandler; +import java.security.Permission; import java.util.jar.Manifest; import org.springframework.boot.loader.util.AsciiBytes; @@ -32,6 +34,7 @@ import org.springframework.boot.loader.util.AsciiBytes; * {@link java.net.JarURLConnection} used to support {@link JarFile#getUrl()}. * * @author Phillip Webb + * @author Andy Wilkinson */ class JarURLConnection extends java.net.JarURLConnection { @@ -61,10 +64,14 @@ class JarURLConnection extends java.net.JarURLConnection { private static final String FILE_COLON_DOUBLE_SLASH = "file://"; + private static final String READ_ACTION = "read"; + private static ThreadLocal useFastExceptions = new ThreadLocal(); private final JarFile jarFile; + private final Permission permission; + private JarEntryData jarEntryData; private URL jarFileUrl; @@ -84,6 +91,8 @@ class JarURLConnection extends java.net.JarURLConnection { } this.jarFile = jarFile; this.jarEntryName = getJarEntryName(spec); + this.permission = new FilePermission(jarFile.getRootJarFile().getFile().getPath(), + READ_ACTION); } private String getNormalizedFile(URL url) { @@ -214,6 +223,11 @@ class JarURLConnection extends java.net.JarURLConnection { return this.jarEntryName.getContentType(); } + @Override + public Permission getPermission() throws IOException { + return this.permission; + } + static void setUseFastExceptions(boolean useFastExceptions) { JarURLConnection.useFastExceptions.set(useFastExceptions); } diff --git a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java index 0dcee736adc..f0d61ab3988 100644 --- a/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java +++ b/spring-boot-tools/spring-boot-loader/src/test/java/org/springframework/boot/loader/jar/JarFileTests.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; +import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.net.URL; @@ -45,6 +46,7 @@ import org.springframework.util.StreamUtils; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.sameInstance; @@ -58,6 +60,7 @@ import static org.mockito.Mockito.verify; * * @author Phillip Webb * @author Martin Lau + * @author Andy Wilkinson */ public class JarFileTests { @@ -216,6 +219,11 @@ public class JarFileTests { assertThat(jarURLConnection.getContentLength(), equalTo(1)); assertThat(jarURLConnection.getContent(), instanceOf(InputStream.class)); assertThat(jarURLConnection.getContentType(), equalTo("content/unknown")); + assertThat(jarURLConnection.getPermission(), + is(instanceOf(FilePermission.class))); + FilePermission permission = (FilePermission) jarURLConnection.getPermission(); + assertThat(permission.getActions(), equalTo("read")); + assertThat(permission.getName(), equalTo(this.rootJarFile.getPath())); } @Test @@ -269,6 +277,10 @@ public class JarFileTests { assertThat(conn.getJarFile(), sameInstance(nestedJarFile)); assertThat(conn.getJarFileURL().toString(), equalTo("jar:" + this.rootJarFile.toURI() + "!/nested.jar")); + assertThat(conn.getPermission(), is(instanceOf(FilePermission.class))); + FilePermission permission = (FilePermission) conn.getPermission(); + assertThat(permission.getActions(), equalTo("read")); + assertThat(permission.getName(), equalTo(this.rootJarFile.getPath())); } @Test @@ -292,7 +304,7 @@ public class JarFileTests { } @Test - public void getNestJarEntryUrl() throws Exception { + public void getNestedJarEntryUrl() throws Exception { JarFile nestedJarFile = this.jarFile .getNestedJarFile(this.jarFile.getEntry("nested.jar")); URL url = nestedJarFile.getJarEntry("3.dat").getUrl();