Skip to content

Commit fdbdbe2

Browse files
committed
derive JarFile from URI in a safer way
It is possible to quite heavily customize URL handling by extension points like the system property `java.protocol.handler.pkgs`. Thus, it's safer to try to limit manual URI manipulations and file creations as much as possible and derive it from objects that participate in this customization. E.g. use the (possibly customized) `JarURLConnection` obtained from the URL to retrieve the `JarFile` instead of creating a new `File` from the URL and converting this to a `JarFile` again. Signed-off-by: Peter Gafert <peter.gafert@tngtech.com>
1 parent f364fa9 commit fdbdbe2

1 file changed

Lines changed: 16 additions & 16 deletions

File tree

  • archunit/src/main/java/com/tngtech/archunit/core/importer

archunit/src/main/java/com/tngtech/archunit/core/importer/Location.java

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import java.io.File;
1919
import java.io.IOException;
20+
import java.net.JarURLConnection;
2021
import java.net.URI;
2122
import java.net.URISyntaxException;
2223
import java.net.URL;
@@ -31,6 +32,7 @@
3132
import java.util.Enumeration;
3233
import java.util.List;
3334
import java.util.Objects;
35+
import java.util.Optional;
3436
import java.util.Set;
3537
import java.util.concurrent.ExecutionException;
3638
import java.util.jar.JarEntry;
@@ -288,28 +290,26 @@ public boolean isArchive() {
288290

289291
@Override
290292
Collection<NormalizedResourceName> readResourceEntries() {
291-
File file = getFileOfJar();
292-
if (!file.exists()) {
293-
return emptySet();
294-
}
295-
296-
return readJarFileContent(file);
293+
return getJarFile().map(this::readJarFileContent).orElse(emptySet());
297294
}
298295

299-
private File getFileOfJar() {
300-
return new File(URI.create(uri.toString()
301-
.replaceAll("^" + SCHEME + ":", "")
302-
.replaceAll("!/.*", "")));
296+
private Optional<JarFile> getJarFile() {
297+
try {
298+
// Note: We can't use a composed JAR URL like `jar:file:/path/to/file.jar!/com/example`, because opening the connection
299+
// fails with an exception if the directory entry for this path is missing (which is possible, even if there is
300+
// a class `com.example.SomeClass` in the JAR file).
301+
String baseUri = uri.toString().replaceAll("!/.*", "!/");
302+
JarURLConnection jarUrlConnection = (JarURLConnection) new URL(baseUri).openConnection();
303+
return Optional.of(jarUrlConnection.getJarFile());
304+
} catch (IOException e) {
305+
return Optional.empty();
306+
}
303307
}
304308

305-
private Collection<NormalizedResourceName> readJarFileContent(File fileOfJar) {
309+
private Collection<NormalizedResourceName> readJarFileContent(JarFile jarFile) {
306310
ImmutableList.Builder<NormalizedResourceName> result = ImmutableList.builder();
307311
String prefix = uri.toString().replaceAll(".*!/", "");
308-
try (JarFile jarFile = new JarFile(fileOfJar)) {
309-
result.addAll(readEntries(prefix, jarFile));
310-
} catch (IOException e) {
311-
throw new LocationException(e);
312-
}
312+
result.addAll(readEntries(prefix, jarFile));
313313
return result.build();
314314
}
315315

0 commit comments

Comments
 (0)