Skip to content

Commit

Permalink
add validation for package overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
ix0rai committed Dec 29, 2024
1 parent 58cb956 commit 7e7b2b2
Show file tree
Hide file tree
Showing 9 changed files with 316 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,9 @@ public void proposeDynamicNames(EntryRemapper remapper, Entry<?> obfEntry, Entry

private void proposePackageName(ClassEntry entry, @Nullable EntryMapping newMapping, Map<Entry<?>, EntryMapping> mappings) {
if (entry.isInnerClass()) {
//throw new RuntimeException("cannot propose package name for an inner class: " + entry);
return;
}

// todo don't run through mojmaps here -- use whatever's passed?
EntryMapping mojmap = mojmaps.get(entry);
if (mojmap == null || mojmap.targetName() == null) {
Logger.error("no mojmap for outer class: " + entry);
Expand All @@ -125,7 +123,6 @@ private void proposePackageName(ClassEntry entry, @Nullable EntryMapping newMapp

if (!deobfPackageString.equals(obfPackageString)) {
String newTarget = target.replace(obfPackage + "/", deobfPackageString + "/");
// todo why is this stack overflowing
mappings.put(entry, new EntryMapping(newTarget));
}
});
Expand All @@ -146,8 +143,7 @@ public static PackageEntryList readPackageJson(Gson gson, String path) {
Reader jsonReader = new FileReader(path);
PackageEntryList entries = gson.fromJson(jsonReader, PackageEntryList.class);
for (PackageEntry entry : entries) {
// todo validate entry for invalid name
setupInheritance(entry);
setupInheritanceAndValidate(entry);
}

return entries;
Expand All @@ -159,10 +155,29 @@ public static PackageEntryList readPackageJson(Gson gson, String path) {
return null;
}

private static void setupInheritance(PackageEntry entry) {
private static void setupInheritanceAndValidate(PackageEntry entry) {
if (entry.deobf != null) {
String firstChar = String.valueOf(entry.deobf.charAt(0));
if (firstChar.matches("[0-9]")) {
throw new InvalidOverrideException(entry, "package name cannot begin with an integer");
}

if (entry.deobf.contains("/")) {
throw new InvalidOverrideException(entry, "package name cannot contain a slash");
} else if (entry.deobf.contains("-")) {
throw new InvalidOverrideException(entry, "package name cannot contain a dash");
} else if (entry.deobf.contains(" ")) {
throw new InvalidOverrideException(entry, "package name cannot contain a space");
} else if (!entry.deobf.toLowerCase().equals(entry.deobf)) {
throw new InvalidOverrideException(entry, "package name must be lowercase");
} else if (!entry.deobf.matches("[a-z0-9_]+")) {
throw new InvalidOverrideException(entry, "entry must match regex '[a-z0-9_]+'");
}
}

for (PackageEntry child : entry.children) {
child.parent = entry;
setupInheritance(child);
setupInheritanceAndValidate(child);
}
}

Expand Down Expand Up @@ -329,4 +344,10 @@ private boolean equals(String obfPackage) {
return this.toObfPackageString().equals(obfPackage);
}
}

public static class InvalidOverrideException extends RuntimeException {
public InvalidOverrideException(PackageEntry entry, String message) {
super("Invalid package override for " + entry.obf + " (" + entry.deobf + "): " + message);
}
}
}
48 changes: 43 additions & 5 deletions src/test/java/org/quiltmc/enigma_plugin/MojmapTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
import java.nio.file.Path;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;

// todo evaluate whether this obsoletes any proposers (non-hashed proposer is def on the chopping block)
// todo make sure of priority

Expand All @@ -46,11 +49,21 @@ public class MojmapTest {
private static final Path testResources = Path.of("./src/test/resources");
private static final Path mojmapTest = testResources.resolve("mojmap_test");
private static final Path emptyOverrides = mojmapTest.resolve("example_mappings_empty.json");

private static final Path overrideRenaming = mojmapTest.resolve("override_based_renaming");
private static final Path overrideRenamingOverrides = overrideRenaming.resolve("input_overrides.json");
private static final Path overrideRenamingJar = overrideRenaming.resolve("input.jar");
private static final Path overrideRenamingMappings = overrideRenaming.resolve("input.mapping");

private static final Path invalidOverrides = mojmapTest.resolve("invalid_overrides");
private static final Path beginWithInt = invalidOverrides.resolve("begin_with_int.json");
private static final Path hyphens = invalidOverrides.resolve("hyphens.json");
private static final Path multipleInvalidOverrides = invalidOverrides.resolve("multiple_invalid_overrides.json");
private static final Path spaces = invalidOverrides.resolve("spaces.json");
private static final Path slashes = invalidOverrides.resolve("slashes.json");
private static final Path uppercases = invalidOverrides.resolve("uppercases.json");
private static final Path validOverrides = invalidOverrides.resolve("valid_overrides.json");

private static EnigmaProject project;

@BeforeAll
Expand Down Expand Up @@ -224,21 +237,46 @@ void testOverrideRenaming() throws IOException, MappingParseException {
ClassEntry d = new ClassEntry("d");
ClassEntry e = new ClassEntry("e");
ClassEntry f = new ClassEntry("f");
ClassEntry g = new ClassEntry("g");

assertMapping(a, "a/Class1PackageA", TokenType.DEOBFUSCATED);
assertMapping(b, "a/b_/Class2PackageAB", TokenType.DEOBFUSCATED);
assertMapping(c, "b_/a/Class3PackageBA", TokenType.DEOBFUSCATED);
assertMapping(d, "c_/a_/Class4PackageCA", TokenType.DEOBFUSCATED);
assertMapping(e, "b_/b/Class5PackageBB", TokenType.DEOBFUSCATED);
assertMapping(f, "b_/b/c_/Class6PackageBBC", TokenType.DEOBFUSCATED);
// todo test for not proposing when no overrides are present on the class
// todo no mojmap found for g?
}

@Test
void testDynamicOverrideRenaming() {
// todo
void testDynamicOverrideRenaming() throws IOException, MappingParseException {
setupEnigma(overrideRenamingJar, overrideRenamingMappings, overrideRenamingOverrides);
project.setMappings(project.getEnigma().readMappings(overrideRenamingMappings).get(), ProgressListener.createEmpty());

ClassEntry a = new ClassEntry("a");
ClassEntry b = new ClassEntry("b");
ClassEntry c = new ClassEntry("c");

// assert normal proposed mappings
assertMapping(a, "a/Class1PackageA", TokenType.DEOBFUSCATED);
assertMapping(b, "a/b_/Class2PackageAB", TokenType.DEOBFUSCATED);
assertMapping(c, "b_/a/Class3PackageBA", TokenType.DEOBFUSCATED);

project.getRemapper().putMapping(new ValidationContext(PrintNotifier.INSTANCE), a, new EntryMapping("awesome/slay"));

assertMapping(a, "a/slay", TokenType.DEOBFUSCATED);

// todo more
}

@Test
void testInvalidOverrides() {
assertThrows(MojmapNameProposer.InvalidOverrideException.class, () -> setupEnigma(overrideRenamingJar, overrideRenamingMappings, beginWithInt));
assertThrows(MojmapNameProposer.InvalidOverrideException.class, () -> setupEnigma(overrideRenamingJar, overrideRenamingMappings, hyphens));
assertThrows(MojmapNameProposer.InvalidOverrideException.class, () -> setupEnigma(overrideRenamingJar, overrideRenamingMappings, multipleInvalidOverrides));
assertThrows(MojmapNameProposer.InvalidOverrideException.class, () -> setupEnigma(overrideRenamingJar, overrideRenamingMappings, slashes));
assertThrows(MojmapNameProposer.InvalidOverrideException.class, () -> setupEnigma(overrideRenamingJar, overrideRenamingMappings, spaces));
assertThrows(MojmapNameProposer.InvalidOverrideException.class, () -> setupEnigma(overrideRenamingJar, overrideRenamingMappings, uppercases));

assertDoesNotThrow(() -> setupEnigma(overrideRenamingJar, overrideRenamingMappings, validOverrides));
}

private void assertMapping(Entry<?> entry, String name, TokenType type) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[
{
"obf": "a",
"deobf": "a_valid",
"children": [
{
"obf": "b",
"deobf": "b_valid",
"children": []
}
]
},
{
"obf": "b",
"deobf": "b_valid",
"children": [
{
"obf": "a",
"deobf": "123invalid",
"children": []
},
{
"obf": "b",
"deobf": "valid123",
"children": [
{
"obf": "c",
"deobf": "c_valid",
"children": []
}
]
}
]
}
]
35 changes: 35 additions & 0 deletions src/test/resources/mojmap_test/invalid_overrides/hyphens.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[
{
"obf": "a",
"deobf": "a_valid",
"children": [
{
"obf": "b",
"deobf": "b_valid",
"children": []
}
]
},
{
"obf": "b",
"deobf": "b_valid",
"children": [
{
"obf": "a",
"deobf": "_123valid",
"children": []
},
{
"obf": "b",
"deobf": "valid123",
"children": [
{
"obf": "c",
"deobf": "c-invalid",
"children": []
}
]
}
]
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[
{
"obf": "a",
"deobf": "a a",
"children": [
{
"obf": "b",
"deobf": "b/b",
"children": []
}
]
},
{
"obf": "b",
"deobf": "b_b",
"children": [
{
"obf": "a",
"deobf": "123a",
"children": []
},
{
"obf": "b",
"deobf": "b123",
"children": [
{
"obf": "c",
"deobf": "c-c",
"children": []
}
]
}
]
}
]
35 changes: 35 additions & 0 deletions src/test/resources/mojmap_test/invalid_overrides/slashes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[
{
"obf": "a",
"deobf": "a_valid",
"children": [
{
"obf": "b",
"deobf": "b_valid",
"children": []
}
]
},
{
"obf": "b",
"deobf": "b/invalid",
"children": [
{
"obf": "a",
"deobf": "_123valid",
"children": []
},
{
"obf": "b",
"deobf": "valid123",
"children": [
{
"obf": "c",
"deobf": "c_valid",
"children": []
}
]
}
]
}
]
35 changes: 35 additions & 0 deletions src/test/resources/mojmap_test/invalid_overrides/spaces.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[
{
"obf": "a",
"deobf": "a_valid",
"children": [
{
"obf": "b",
"deobf": "b invalid",
"children": []
}
]
},
{
"obf": "b",
"deobf": "b_valid",
"children": [
{
"obf": "a",
"deobf": "_123valid",
"children": []
},
{
"obf": "b",
"deobf": "valid123",
"children": [
{
"obf": "c",
"deobf": "c_valid",
"children": []
}
]
}
]
}
]
35 changes: 35 additions & 0 deletions src/test/resources/mojmap_test/invalid_overrides/uppercases.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[
{
"obf": "a",
"deobf": "a_valid",
"children": [
{
"obf": "b",
"deobf": "b_INVALID",
"children": []
}
]
},
{
"obf": "b",
"deobf": "b_valid",
"children": [
{
"obf": "a",
"deobf": "_123valid",
"children": []
},
{
"obf": "b",
"deobf": "valid123",
"children": [
{
"obf": "c",
"deobf": "c_valid",
"children": []
}
]
}
]
}
]
Loading

0 comments on commit 7e7b2b2

Please sign in to comment.