From 735b6259e1d6bd188cc57500c11b3c98d95dd4c2 Mon Sep 17 00:00:00 2001 From: Technici4n <13494793+Technici4n@users.noreply.github.com> Date: Sat, 18 Nov 2023 10:30:19 +0100 Subject: [PATCH] SJH 3.0: Replace BiPredicate by UnionPathFilter in UnionFS and hide SecureJar impl details --- .../mods/jarhandling/JarContentsBuilder.java | 2 +- .../java/cpw/mods/jarhandling/SecureJar.java | 3 +- .../java/cpw/mods/jarhandling/impl/Jar.java | 2 +- .../jarhandling/impl/JarContentsImpl.java | 5 ++- .../cpw/mods/niofs/union/UnionFileSystem.java | 13 ++++-- .../niofs/union/UnionFileSystemProvider.java | 40 ++++++++----------- src/main/java/module-info.java | 1 - 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/main/java/cpw/mods/jarhandling/JarContentsBuilder.java b/src/main/java/cpw/mods/jarhandling/JarContentsBuilder.java index 3090066..cacd26e 100644 --- a/src/main/java/cpw/mods/jarhandling/JarContentsBuilder.java +++ b/src/main/java/cpw/mods/jarhandling/JarContentsBuilder.java @@ -53,6 +53,6 @@ public JarContentsBuilder pathFilter(@Nullable UnionPathFilter pathFilter) { * Builds the jar. */ public JarContents build() { - return new JarContentsImpl(paths, defaultManifest, pathFilter == null ? null : pathFilter::test); + return new JarContentsImpl(paths, defaultManifest, pathFilter); } } diff --git a/src/main/java/cpw/mods/jarhandling/SecureJar.java b/src/main/java/cpw/mods/jarhandling/SecureJar.java index 3b3b3f5..f5e03f8 100644 --- a/src/main/java/cpw/mods/jarhandling/SecureJar.java +++ b/src/main/java/cpw/mods/jarhandling/SecureJar.java @@ -2,6 +2,7 @@ import cpw.mods.jarhandling.impl.Jar; import cpw.mods.jarhandling.impl.JarContentsImpl; +import cpw.mods.niofs.union.UnionPathFilter; import org.jetbrains.annotations.Nullable; import java.io.IOException; @@ -103,7 +104,7 @@ record Provider(String serviceName, List providers) { /** * Helper method to parse service provider implementations from a {@link Path}. */ - public static Provider fromPath(final Path path, final BiPredicate pkgFilter) { + public static Provider fromPath(Path path, @Nullable UnionPathFilter pkgFilter) { final var sname = path.getFileName().toString(); try { var entries = Files.readAllLines(path).stream() diff --git a/src/main/java/cpw/mods/jarhandling/impl/Jar.java b/src/main/java/cpw/mods/jarhandling/impl/Jar.java index ee9c3e2..6d86970 100644 --- a/src/main/java/cpw/mods/jarhandling/impl/Jar.java +++ b/src/main/java/cpw/mods/jarhandling/impl/Jar.java @@ -32,7 +32,7 @@ public class Jar implements SecureJar { @Deprecated(forRemoval = true, since = "2.1.16") public Jar(final Supplier defaultManifest, final Function metadataFunction, final BiPredicate pathfilter, final Path... paths) { - this.contents = new JarContentsImpl(paths, defaultManifest, pathfilter); + this.contents = new JarContentsImpl(paths, defaultManifest, pathfilter == null ? null : pathfilter::test); this.manifest = contents.getManifest(); this.signingData = contents.signingData; this.filesystem = contents.filesystem; diff --git a/src/main/java/cpw/mods/jarhandling/impl/JarContentsImpl.java b/src/main/java/cpw/mods/jarhandling/impl/JarContentsImpl.java index a39807b..cc12075 100644 --- a/src/main/java/cpw/mods/jarhandling/impl/JarContentsImpl.java +++ b/src/main/java/cpw/mods/jarhandling/impl/JarContentsImpl.java @@ -4,6 +4,7 @@ import cpw.mods.jarhandling.SecureJar; import cpw.mods.niofs.union.UnionFileSystem; import cpw.mods.niofs.union.UnionFileSystemProvider; +import cpw.mods.niofs.union.UnionPathFilter; import org.jetbrains.annotations.Nullable; import java.io.IOException; @@ -48,7 +49,7 @@ public class JarContentsImpl implements JarContents { // Cache for repeated getMetaInfServices calls private List providers; - public JarContentsImpl(Path[] paths, Supplier defaultManifest, @Nullable BiPredicate pathFilter) { + public JarContentsImpl(Path[] paths, Supplier defaultManifest, @Nullable UnionPathFilter pathFilter) { var validPaths = Arrays.stream(paths).filter(Files::exists).toArray(Path[]::new); if (validPaths.length == 0) throw new UncheckedIOException(new IOException("Invalid paths argument, contained no existing paths: " + Arrays.toString(paths))); @@ -202,7 +203,7 @@ public List getMetaInfServices() { if (Files.exists(services)) { try (var walk = Files.walk(services)) { this.providers = walk.filter(path->!Files.isDirectory(path)) - .map((Path path1) -> SecureJar.Provider.fromPath(path1, filesystem.getFilesystemFilter())) + .map((Path path1) -> SecureJar.Provider.fromPath(path1, filesystem.getFileSystemFilter())) .toList(); } catch (IOException e) { throw new UncheckedIOException(e); diff --git a/src/main/java/cpw/mods/niofs/union/UnionFileSystem.java b/src/main/java/cpw/mods/niofs/union/UnionFileSystem.java index 1ae18b2..9a2ea42 100644 --- a/src/main/java/cpw/mods/niofs/union/UnionFileSystem.java +++ b/src/main/java/cpw/mods/niofs/union/UnionFileSystem.java @@ -34,13 +34,15 @@ import java.util.Set; import java.util.Spliterator; import java.util.Spliterators; -import java.util.function.BiPredicate; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; import java.util.stream.StreamSupport; +/** + * Can be instantiated using the public methods in {@link UnionFileSystemProvider}. + */ public class UnionFileSystem extends FileSystem { private static final MethodHandle ZIPFS_EXISTS; private static final MethodHandle ZIPFS_CH; @@ -104,15 +106,18 @@ public synchronized Throwable fillInStackTrace() { private final List basepaths; private final int lastElementIndex; @Nullable - private final BiPredicate pathFilter; + private final UnionPathFilter pathFilter; private final Map embeddedFileSystems; public Path getPrimaryPath() { return basepaths.get(basepaths.size() - 1); } + /** + * {@return the filter for this file system, or null if there is none} + */ @Nullable - public BiPredicate getFilesystemFilter() { + public UnionPathFilter getFileSystemFilter() { return pathFilter; } @@ -123,7 +128,7 @@ String getKey() { private record EmbeddedFileSystemMetadata(Path path, FileSystem fs, SeekableByteChannel fsCh) { } - public UnionFileSystem(final UnionFileSystemProvider provider, @Nullable BiPredicate pathFilter, final String key, final Path... basepaths) { + UnionFileSystem(UnionFileSystemProvider provider, @Nullable UnionPathFilter pathFilter, String key, Path... basepaths) { this.pathFilter = pathFilter; this.provider = provider; this.key = key; diff --git a/src/main/java/cpw/mods/niofs/union/UnionFileSystemProvider.java b/src/main/java/cpw/mods/niofs/union/UnionFileSystemProvider.java index ba0a689..c1114d5 100644 --- a/src/main/java/cpw/mods/niofs/union/UnionFileSystemProvider.java +++ b/src/main/java/cpw/mods/niofs/union/UnionFileSystemProvider.java @@ -11,7 +11,6 @@ import java.nio.file.attribute.*; import java.nio.file.spi.FileSystemProvider; import java.util.*; -import java.util.function.BiPredicate; import java.util.stream.Stream; public class UnionFileSystemProvider extends FileSystemProvider { @@ -55,24 +54,7 @@ protected Path uriToPath(URI uri) { */ @Override public FileSystem newFileSystem(final URI uri, final Map env) throws IOException { - @SuppressWarnings("unchecked") - var additional = ((Map>)env).getOrDefault("additional", List.of()); - @SuppressWarnings("unchecked") - var filter = ((Map>)env).getOrDefault("filter", null); - - if (filter == null && additional.isEmpty()) - throw new IllegalArgumentException("Missing additional and/or filter"); - - if (filter == null) - filter = (p, b) -> true; - - var path = uriToPath(uri); - var key = makeKey(path); - try { - return newFileSystemInternal(key, filter, Stream.concat(Stream.of(path), additional.stream()).toArray(Path[]::new)); - } catch (UncheckedIOException e) { - throw e.getCause(); - } + return newFileSystem(uriToPath(uri), env); } /** @@ -87,8 +69,7 @@ public FileSystem newFileSystem(final URI uri, final Map env) throws public FileSystem newFileSystem(final Path path, final Map env) throws IOException { @SuppressWarnings("unchecked") var additional = ((Map>)env).getOrDefault("additional", List.of()); - @SuppressWarnings("unchecked") - var filter = ((Map>)env).getOrDefault("filter", null); + var filter = readFilterFromEnv(env); if (filter == null && additional.isEmpty()) throw new UnsupportedOperationException("Missing additional and/or filter"); @@ -101,13 +82,26 @@ public FileSystem newFileSystem(final Path path, final Map env) throw } } - public UnionFileSystem newFileSystem(@Nullable BiPredicate pathfilter, final Path... paths) { + @Nullable + private static UnionPathFilter readFilterFromEnv(Map env) { + Object filter = env.get("filter"); + + if (filter == null) { + return null; + } else if (filter instanceof UnionPathFilter unionPathFilter) { + return unionPathFilter; + } else { + throw new IllegalArgumentException("Unknown type for \"filter\" UnionFileSystem env var: " + filter.getClass().getName()); + } + } + + public UnionFileSystem newFileSystem(@Nullable UnionPathFilter pathfilter, final Path... paths) { if (paths.length == 0) throw new IllegalArgumentException("Need at least one path"); var key = makeKey(paths[0]); return newFileSystemInternal(key, pathfilter, paths); } - private UnionFileSystem newFileSystemInternal(final String key, @Nullable BiPredicate pathfilter, final Path... paths) { + private UnionFileSystem newFileSystemInternal(final String key, @Nullable UnionPathFilter pathfilter, final Path... paths) { var normpaths = Arrays.stream(paths) .map(Path::toAbsolutePath) .map(Path::normalize) diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 6ad8598..82d0da2 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -4,7 +4,6 @@ module cpw.mods.securejarhandler { exports cpw.mods.jarhandling; - exports cpw.mods.jarhandling.impl; // TODO - Bump version, and remove this export, you don't need our implementation exports cpw.mods.cl; exports cpw.mods.niofs.union; requires jdk.unsupported;