From 5d5279dc240e7758e9667bda5151a5d2b4cd6c9d Mon Sep 17 00:00:00 2001 From: LexManos Date: Mon, 8 Jan 2024 13:13:05 -0800 Subject: [PATCH] Bypass ZipFileSystem's production of invalid URIs when zip filenames are not properly url encoded. --- .../java/cpw/mods/jarhandling/impl/Jar.java | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/main/java/cpw/mods/jarhandling/impl/Jar.java b/src/main/java/cpw/mods/jarhandling/impl/Jar.java index af72711..539efb6 100644 --- a/src/main/java/cpw/mods/jarhandling/impl/Jar.java +++ b/src/main/java/cpw/mods/jarhandling/impl/Jar.java @@ -197,11 +197,11 @@ private Path newFileSystem(BiPredicate filter, Path[] paths) { fs = FileSystems.getFileSystem(uri); } } else { - // JarInJar is fucking stupid and breaks horribly if it knows about files directly. - // So because I don't want to go into the rabbit hole that is digging into that - // Any non-standard file system will be wrapped in a Union File System - // This still gets the performance benefit of having 90% of everything bypass the UFS - // TODO: [SM] Remove JarInJar file system in favor of a simpler dependency management system. + // JarInJar is fucking stupid and breaks horribly if it knows about files directly. + // So because I don't want to go into the rabbit hole that is digging into that + // Any non-standard file system will be wrapped in a Union File System + // This still gets the performance benefit of having 90% of everything bypass the UFS + // TODO: [SM] Remove JarInJar file system in favor of a simpler dependency management system. fs = UFSP.newFileSystem(paths[0], Map.of("filter", (BiPredicate)(a, b) -> true)); } } else { @@ -412,8 +412,20 @@ public Optional findFile(final String name) { } @Override - public Optional open(final String name) { - return jar.findFile(name).map(Paths::get).map(LambdaExceptionUtils.rethrowFunction(Files::newInputStream)); + public Optional open(String name) { + // Path.toURI() can sometimes return URIs that are invalid syntax/can't be passed to Paths.get + // Specifically ZipPath and jars with []'s. https://github.com/MinecraftForge/MinecraftForge/issues/9842 + // So bypass all of that and get the InputStream from the path itself. + name = jar.nameOverrides.getOrDefault(name, name); + var resolved = jar.filesystemRoot.resolve(name); + if (Files.exists(resolved)) { + try { + return Optional.of(Files.newInputStream(resolved)); + } catch (IOException e) { + return sneak(e); + } + } + return Optional.empty(); } @Override