Skip to content

Commit 8d3b608

Browse files
authored
Handle the case of a Multi-Release Jar not actually containing Multi-Release Classes (#42)
Seen a couple of people encounter this in mod dev (when adding dependencies): SJH considers a Jar to be `Multi-Release` based on the `Manifest` <https://github.com/McModLauncher/securejarhandler/blob/96a7b6a8fe1f1117e01dfd94c640757154372a68/src/main/java/cpw/mods/jarhandling/impl/Jar.java#L124> If it is then it resolves a path to `/META-INF/versions` <https://github.com/McModLauncher/securejarhandler/blob/96a7b6a8fe1f1117e01dfd94c640757154372a68/src/main/java/cpw/mods/jarhandling/impl/Jar.java#L126> And tries to walk it <https://github.com/McModLauncher/securejarhandler/blob/96a7b6a8fe1f1117e01dfd94c640757154372a68/src/main/java/cpw/mods/jarhandling/impl/Jar.java#L127> This works for most Jars, however it does not consider the case where a Jar is erroneously marked as `Multi-Release`, with `/META-INF/versions` **not** existing. If this is the case, `Files.walk` will throw a `UnionFileSystem$NoSuchFileException` which is then wrapped and rethrown as a `UncheckedIOException` <https://github.com/McModLauncher/securejarhandler/blob/96a7b6a8fe1f1117e01dfd94c640757154372a68/src/main/java/cpw/mods/jarhandling/impl/Jar.java#L138> Attached Example Stacktrace, <https://gist.github.com/AterAnimAvis/35ded98d52a78c2f257d59173c86366c> --- Current implementation of a fix is from a bit of spitballing [in Discord](https://discord.com/channels/313125603924639766/922237746460893234/1129415771567689738)
1 parent bbf1ff4 commit 8d3b608

File tree

3 files changed

+10
-0
lines changed

3 files changed

+10
-0
lines changed

src/main/java/cpw/mods/jarhandling/impl/JarContentsImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ private Map<Path, Integer> readMultiReleaseInfo() {
115115
}
116116

117117
var vers = filesystem.getRoot().resolve("META-INF/versions");
118+
if (!Files.isDirectory(vers)) return Map.of();
119+
118120
try (var walk = Files.walk(vers)) {
119121
Map<Path, Integer> pathToJavaVersion = new HashMap<>();
120122
walk

src/test/java/cpw/mods/jarhandling/impl/TestMultiRelease.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ public void testMultiRelease() {
2828
Assertions.assertNotEquals("too new", bContents.strip());
2929
}
3030

31+
@Test
32+
public void testMultiReleaseNoVersions() {
33+
Path rootDir = Paths.get("src", "test", "resources", "multirelease-noversions");
34+
// Jars marked with Multi-Release but don't actually have a versions folder should not throw
35+
Assertions.assertDoesNotThrow(() -> SecureJar.from(rootDir));
36+
}
37+
3138
private static String readString(SecureJar jar, String file) {
3239
// Note: we must read the jar through the module data provider for version-specific files to be used
3340
try (var is = jar.moduleDataProvider().open(file).get()) {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Multi-Release: true

0 commit comments

Comments
 (0)