From fa6a326bf50ce4f78b650ed8eac5da00aaa4330f Mon Sep 17 00:00:00 2001 From: Adam Date: Sun, 17 Apr 2016 12:55:53 -0400 Subject: [PATCH] Fix getter return types again --- .../net/runelite/deob/injection/Inject.java | 64 +++++++++++++------ .../runelite/deob/injection/InjectTest.java | 14 +++- .../deob/injection/TestingClassLoader.java | 61 ++++++++++++++++++ 3 files changed, 118 insertions(+), 21 deletions(-) create mode 100644 src/test/java/net/runelite/deob/injection/TestingClassLoader.java diff --git a/src/main/java/net/runelite/deob/injection/Inject.java b/src/main/java/net/runelite/deob/injection/Inject.java index 57e502173e..32769403e5 100644 --- a/src/main/java/net/runelite/deob/injection/Inject.java +++ b/src/main/java/net/runelite/deob/injection/Inject.java @@ -96,29 +96,53 @@ public class Inject return sig; } - private Type toApiType(Type t) + private Type classToType(java.lang.Class c) { - // t = vanilla type - - if (t.isPrimitive()) - return t; - - String type = t.getType(); - type = type.substring(1, type.length() - 1); - - ClassFile cf = vanilla.findClass(type); - if (cf == null) - return t; - - for (Class c : cf.getInterfaces().getInterfaces()) + int dimms = 0; + while (c.isArray()) { - if (c.getName().startsWith(API_PACKAGE_BASE.replace('.', '/'))) - { - return new Type("L" + c.getName() + ";", t.getArrayDims()); - } + c = c.getComponentType(); + ++dimms; } - return t; + if (c.isPrimitive()) + { + String s; + + switch (c.getName()) + { + case "int": + s = "I"; + break; + case "long": + s = "J"; + break; + case "boolean": + s = "Z"; + break; + case "char": + s = "C"; + break; + case "short": + s = "S"; + break; + case "float": + s = "F"; + break; + case "double": + s = "D"; + break; + case "byte": + s = "B"; + break; + default: + throw new RuntimeException("unknown primitive type"); + } + + return new Type(s, dimms); + } + + return new Type("L" + c.getName().replace('.', '/') + ";", dimms); } public void run() @@ -300,7 +324,7 @@ public class Inject assert field.isStatic() || field.getFields().getClassFile() == clazz; Signature sig = new Signature(); - sig.setTypeOfReturnValue(toApiType(field.getType())); + sig.setTypeOfReturnValue(classToType(method.getReturnType())); Method getterMethod = new Method(clazz.getMethods(), method.getName(), sig); getterMethod.setAccessFlags(Method.ACC_PUBLIC); diff --git a/src/test/java/net/runelite/deob/injection/InjectTest.java b/src/test/java/net/runelite/deob/injection/InjectTest.java index 69b8862ff7..5e3e924ebb 100644 --- a/src/test/java/net/runelite/deob/injection/InjectTest.java +++ b/src/test/java/net/runelite/deob/injection/InjectTest.java @@ -2,6 +2,7 @@ package net.runelite.deob.injection; import java.io.File; import java.io.IOException; +import net.runelite.asm.ClassFile; import net.runelite.asm.ClassGroup; import net.runelite.deob.util.JarUtil; import org.junit.After; @@ -30,10 +31,21 @@ public class InjectTest } @Test - public void testRun() + public void testRun() throws IOException, ClassNotFoundException { Inject instance = new Inject(deob, vanilla); instance.run(); + + testLoading(vanilla); + } + + private void testLoading(ClassGroup group) throws ClassNotFoundException + { + TestingClassLoader loader = new TestingClassLoader(group); + for (ClassFile cf : group.getClasses()) + { + loader.findClass(cf.getName()); + } } } diff --git a/src/test/java/net/runelite/deob/injection/TestingClassLoader.java b/src/test/java/net/runelite/deob/injection/TestingClassLoader.java new file mode 100644 index 0000000000..52b6939b1f --- /dev/null +++ b/src/test/java/net/runelite/deob/injection/TestingClassLoader.java @@ -0,0 +1,61 @@ +package net.runelite.deob.injection; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.security.SecureClassLoader; +import java.util.HashMap; +import java.util.Map; +import net.runelite.asm.ClassFile; +import net.runelite.asm.ClassGroup; +import net.runelite.asm.objectwebasm.AsmUtils; + +public class TestingClassLoader extends SecureClassLoader +{ + private ClassGroup group; + private Map > classes = new HashMap<>(); + + public TestingClassLoader(ClassGroup group) + { + this.group = group; + } + + @Override + public Class findClass(String name) throws ClassNotFoundException + { + ClassFile cf = group.findClass(name); + if (cf == null) + return super.findClass(name); + + Class c = classes.get(name); + if (c != null) + return c; + + return defineClass(name, classToBytes(cf)); + } + + private Class defineClass(String name, byte[] b) + { + Class c = super.defineClass(name.replace('/', '.'), b, 0, b.length); + classes.put(name, c); + return c; + } + + private byte[] classToBytes(ClassFile cf) + { + try + { + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + cf.write(new DataOutputStream(bout)); + + // run through asm to generate stackmaps + return AsmUtils.rebuildWithStackmaps(group, new ByteArrayInputStream(bout.toByteArray())); + } + catch (IOException ex) + { + ex.printStackTrace(); + return null; + } + } +}