From 967d099d813222545bd6b29b2d9c3df2aad99bc0 Mon Sep 17 00:00:00 2001 From: wea_ondara Date: Sat, 10 Sep 2022 11:11:58 +0200 Subject: [PATCH] fix asm parser for methods --- src/main/java/jef/asm/AsmParser.java | 2 +- src/main/java/jef/asm/FilterClassVisitor.java | 9 ++++++++- .../java/jef/asm/FilterMethodVisitor.java | 20 +++++++++++-------- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/main/java/jef/asm/AsmParser.java b/src/main/java/jef/asm/AsmParser.java index 516f2ab..5c485c3 100644 --- a/src/main/java/jef/asm/AsmParser.java +++ b/src/main/java/jef/asm/AsmParser.java @@ -69,7 +69,7 @@ public class AsmParser { } private AsmParseResult parseMethodExpression() throws Exception { - var cls = method.getClass(); + var cls = method.getDeclaringClass(); var loader = cls.getClassLoader(); InputStream is = loader.getResourceAsStream(cls.getName().replace(".", "/") + ".class"); Object[] args = new Object[0];//TODO capturing args here? or maybe not supported since this will only be user by getter evaluation diff --git a/src/main/java/jef/asm/FilterClassVisitor.java b/src/main/java/jef/asm/FilterClassVisitor.java index 71d935d..bc0aa70 100644 --- a/src/main/java/jef/asm/FilterClassVisitor.java +++ b/src/main/java/jef/asm/FilterClassVisitor.java @@ -10,6 +10,7 @@ class FilterClassVisitor extends ClassVisitor { private final String lambdaname; private final Object[] args; + private String className; private FilterMethodVisitor mv; protected FilterClassVisitor(int api, String lambdaname, Object[] args) { @@ -19,6 +20,12 @@ class FilterClassVisitor extends ClassVisitor { this.args = args; } + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + super.visit(version, access, name, signature, superName, interfaces); + this.className = name; + } + @Override public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { if (!name.equals(lambdaname)) { @@ -28,7 +35,7 @@ class FilterClassVisitor extends ClassVisitor { if (mv != null) { throw new IllegalStateException("multiple lambda with same name found: " + lambdaname); } - return mv = new FilterMethodVisitor(api, descriptor, args); + return mv = new FilterMethodVisitor(api, className, descriptor, args); } @Override diff --git a/src/main/java/jef/asm/FilterMethodVisitor.java b/src/main/java/jef/asm/FilterMethodVisitor.java index d37adee..a6140b5 100644 --- a/src/main/java/jef/asm/FilterMethodVisitor.java +++ b/src/main/java/jef/asm/FilterMethodVisitor.java @@ -30,7 +30,6 @@ import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.Stack; -import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -41,15 +40,20 @@ class FilterMethodVisitor extends MethodVisitor { private Expression lambdaExpr; private final Set accessedMembers = new HashSet<>(); - protected FilterMethodVisitor(int api, String descriptor, Object[] args) { + protected FilterMethodVisitor(int api, String className, String descriptor, Object[] args) { super(api); - this.args = args; //parameters var types = Type.getMethodType(descriptor).getArgumentTypes(); - parameterClasses = new String[types.length]; - for (int i = 0; i < types.length; i++) { - parameterClasses[i] = types[i].getClassName(); + if (types.length == 0) {// class method //TODO this is dirty, as only works for parameterless class methods + this.args = new Object[]{null}; + parameterClasses = new String[]{className}; + } else { + this.args = args; + parameterClasses = new String[types.length]; + for (int i = 0; i < types.length; i++) { + parameterClasses[i] = types[i].getClassName(); + } } } @@ -105,8 +109,8 @@ class FilterMethodVisitor extends MethodVisitor { } else if (opcode == Opcodes.INVOKEINTERFACE || opcode == Opcodes.INVOKEVIRTUAL) { try { if (name.equals("contains") - && owner.startsWith("java/util/") - && Collection.class.isAssignableFrom(Class.forName(owner.replace("/", ".")))) { + && owner.startsWith("java/util/") + && Collection.class.isAssignableFrom(Class.forName(owner.replace("/", ".")))) { var element = varStack.pop(); var collection = varStack.pop(); varStack.push(new BinaryExpression(element, collection, BinaryExpression.Operator.IN));