Skip to content

Commit

Permalink
Pass basePath as Path during path filtering (#70)
Browse files Browse the repository at this point in the history
We're using the path filter mostly for filtering out resources / class
from Minecraft jars.
The basePath is important to unconditionally include certain resources
from specific basepaths of the union filesystem (client-extra jar). Not
having to do string matching on the basepath makes this more robust.

p.s.: This change is also motivated by SJH normalizing the base path
such that it becomes a relative path, but only on Linux.
So, `/tmp/blah.jar` becomes `tmp/blah.jar`.

Co-authored-by: Marc Hermans <[email protected]>
  • Loading branch information
shartte and marchermans authored Apr 25, 2024
1 parent 5daff13 commit 312eb11
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 18 deletions.
5 changes: 3 additions & 2 deletions src/main/java/cpw/mods/jarhandling/SecureJar.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -135,13 +136,13 @@ record Provider(String serviceName, List<String> providers) {
/**
* Helper method to parse service provider implementations from a {@link Path}.
*/
public static Provider fromPath(final Path path, final BiPredicate<String, String> pkgFilter) {
public static Provider fromPath(final Path path, final UnionPathFilter pkgFilter) {
final var sname = path.getFileName().toString();
try {
var entries = Files.readAllLines(path).stream()
.map(String::trim)
.filter(l-> !l.isEmpty() && !l.startsWith("#")) // We support comments :)
.filter(p-> pkgFilter == null || pkgFilter.test(p.replace('.','/'), ""))
.filter(p-> pkgFilter == null || pkgFilter.test(p.replace('.','/'), path.getRoot()))
.toList();
return new Provider(sname, entries);
} catch (IOException e) {
Expand Down
1 change: 1 addition & 0 deletions src/main/java/cpw/mods/jarhandling/impl/Jar.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import cpw.mods.jarhandling.JarMetadata;
import cpw.mods.jarhandling.SecureJar;
import cpw.mods.niofs.union.UnionFileSystem;
import cpw.mods.niofs.union.UnionPathFilter;
import cpw.mods.util.LambdaExceptionUtils;
import org.jetbrains.annotations.Nullable;

Expand Down
3 changes: 2 additions & 1 deletion src/main/java/cpw/mods/jarhandling/impl/JarContentsImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -49,7 +50,7 @@ public class JarContentsImpl implements JarContents {
// Cache for repeated getMetaInfServices calls
private List<SecureJar.Provider> providers;

public JarContentsImpl(Path[] paths, Supplier<Manifest> defaultManifest, @Nullable BiPredicate<String, String> pathFilter) {
public JarContentsImpl(Path[] paths, Supplier<Manifest> 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)));
Expand Down
12 changes: 4 additions & 8 deletions src/main/java/cpw/mods/niofs/union/UnionFileSystem.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
Expand Down Expand Up @@ -97,15 +96,15 @@ public synchronized Throwable fillInStackTrace() {
private final List<Path> basepaths;
private final int lastElementIndex;
@Nullable
private final BiPredicate<String, String> pathFilter;
private final UnionPathFilter pathFilter;
private final Map<Path, EmbeddedFileSystemMetadata> embeddedFileSystems;

public Path getPrimaryPath() {
return basepaths.get(basepaths.size() - 1);
}

@Nullable
public BiPredicate<String, String> getFilesystemFilter() {
public UnionPathFilter getFilesystemFilter() {
return pathFilter;
}

Expand All @@ -116,7 +115,7 @@ String getKey() {
private record EmbeddedFileSystemMetadata(Path path, FileSystem fs, SeekableByteChannel fsCh) {
}

public UnionFileSystem(final UnionFileSystemProvider provider, @Nullable BiPredicate<String, String> pathFilter, final String key, final Path... basepaths) {
public UnionFileSystem(final UnionFileSystemProvider provider, @Nullable UnionPathFilter pathFilter, final String key, final Path... basepaths) {
this.pathFilter = pathFilter;
this.provider = provider;
this.key = key;
Expand Down Expand Up @@ -454,9 +453,6 @@ private boolean testFilter(final Path path, final Path basePath, @Nullable Basic
sPath += '/';
if (sPath.length() > 1 && sPath.startsWith("/"))
sPath = sPath.substring(1);
String sBasePath = basePath.toString().replace('\\', '/');
if (sBasePath.length() > 1 && sBasePath.startsWith("/"))
sBasePath = sBasePath.substring(1);
return pathFilter.test(sPath, sBasePath);
return pathFilter.test(sPath, basePath);
}
}
12 changes: 6 additions & 6 deletions src/main/java/cpw/mods/niofs/union/UnionFileSystemProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ protected Path uriToPath(URI uri) {

/**
* Invoked by FileSystems.newFileSystem, Only returns a value if env contains one of more of:
* "filter": BiPredicate<String, String> - A filter to apply to the opened path
* "filter": UnionPathFilter - A filter to apply to the opened path
* "additional": List<Path> - Additional paths to join together
* If none specified, throws IllegalArgumentException
* If uri.getScheme() is not "union" throws IllegalArgumentException
Expand All @@ -76,7 +76,7 @@ public FileSystem newFileSystem(final URI uri, final Map<String, ?> env) throws
@SuppressWarnings("unchecked")
var additional = ((Map<String, List<Path>>)env).getOrDefault("additional", List.<Path>of());
@SuppressWarnings("unchecked")
var filter = ((Map<String, BiPredicate<String, String>>)env).getOrDefault("filter", null);
var filter = ((Map<String, UnionPathFilter>)env).getOrDefault("filter", null);

if (filter == null && additional.isEmpty())
throw new IllegalArgumentException("Missing additional and/or filter");
Expand All @@ -95,7 +95,7 @@ public FileSystem newFileSystem(final URI uri, final Map<String, ?> env) throws

/**
* Invoked by FileSystems.newFileSystem, Only returns a value if env contains one of more of:
* "filter": BiPredicate<String, String> - A filter to apply to the opened path
* "filter": UnionPathFilter - A filter to apply to the opened path
* "additional": List<Path> - Additional paths to join together
* If none specified, throws UnsupportedOperationException instead of IllegalArgumentException
* so that FileSystems.newFileSystem will search for the next provider.
Expand All @@ -106,7 +106,7 @@ public FileSystem newFileSystem(final Path path, final Map<String, ?> env) throw
@SuppressWarnings("unchecked")
var additional = ((Map<String, List<Path>>)env).getOrDefault("additional", List.<Path>of());
@SuppressWarnings("unchecked")
var filter = ((Map<String, BiPredicate<String, String>>)env).getOrDefault("filter", null);
var filter = ((Map<String, UnionPathFilter>)env).getOrDefault("filter", null);

if (filter == null && additional.isEmpty())
throw new UnsupportedOperationException("Missing additional and/or filter");
Expand All @@ -119,13 +119,13 @@ public FileSystem newFileSystem(final Path path, final Map<String, ?> env) throw
}
}

public UnionFileSystem newFileSystem(@Nullable BiPredicate<String, String> pathfilter, final Path... paths) {
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<String, String> 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)
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/cpw/mods/niofs/union/UnionPathFilter.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package cpw.mods.niofs.union;

import java.nio.file.Path;

/**
* Filter for paths in a {@link UnionFileSystem}.
*/
Expand All @@ -12,5 +14,5 @@ public interface UnionPathFilter {
* @param basePath the base path, i.e. one of the root paths the filesystem is built out of
* @return {@code true} to include the entry, {@code} false to exclude it
*/
boolean test(String entry, String basePath);
boolean test(String entry, Path basePath);
}

0 comments on commit 312eb11

Please sign in to comment.