Example usage for org.objectweb.asm.tree AbstractInsnNode getOpcode

List of usage examples for org.objectweb.asm.tree AbstractInsnNode getOpcode

Introduction

In this page you can find the example usage for org.objectweb.asm.tree AbstractInsnNode getOpcode.

Prototype

public int getOpcode() 

Source Link

Document

Returns the opcode of this instruction.

Usage

From source file:com.android.ide.eclipse.apt.internal.analysis.StaticVirtualAnalyzer.java

License:Apache License

@Override
protected Collection<Problem> analyzeMethod(final MethodNode methodNode) {
    final Collection<Problem> problems = new LinkedList<Problem>();
    final int acc = methodNode.access;
    if ((acc & Opcodes.ACC_STATIC) == 0 && (acc & Opcodes.ACC_ABSTRACT) == 0) {
        final InsnList instructions = methodNode.instructions;
        //find if a method load this (ALOAD 0)
        boolean aload0 = false;
        for (int i = 0; i < instructions.size(); i++) {
            final AbstractInsnNode instruction = instructions.get(i);
            if (instruction.getOpcode() == Opcodes.ALOAD) {
                final VarInsnNode aload = (VarInsnNode) instruction;
                aload0 = aload.var == 0;
                if (aload0) {
                    break;
                }/*  ww  w.j av  a  2 s .  c  o m*/
            }
        }
        if (!aload0) {
            final Problem problem = new StaticVirtualProblem(instructions.get(1));
            problems.add(problem);
        }
    }
    return problems;
}

From source file:com.android.ide.eclipse.apt.internal.analysis.VirtualInterfaceAnalyzer.java

License:Apache License

@Override
protected Collection<Problem> analyzeMethod(final MethodNode methodNode) {
    final LinkedList<Problem> problems = new LinkedList<Problem>();
    final InsnList instructions = methodNode.instructions;
    for (int i = 0; i < instructions.size(); i++) {
        final AbstractInsnNode insnNode = instructions.get(i);
        if (insnNode.getOpcode() == Opcodes.INVOKEINTERFACE) {
            final Problem problem = new Problem(insnNode);
            problems.add(problem);//from  ww  w.ja v  a2s.  c  om
        }
    }
    return problems;
}

From source file:com.android.tools.klint.checks.ControlFlowGraph.java

License:Apache License

private static String dotDescribe(Node node) {
    AbstractInsnNode instruction = node.instruction;
    if (instruction instanceof LabelNode) {
        return "Label";
    } else if (instruction instanceof LineNumberNode) {
        LineNumberNode lineNode = (LineNumberNode) instruction;
        return "Line " + lineNode.line;
    } else if (instruction instanceof FrameNode) {
        return "Stack Frame";
    } else if (instruction instanceof MethodInsnNode) {
        MethodInsnNode method = (MethodInsnNode) instruction;
        String cls = method.owner.substring(method.owner.lastIndexOf('/') + 1);
        cls = cls.replace('$', '.');
        return "Call " + cls + "#" + method.name;
    } else if (instruction instanceof FieldInsnNode) {
        FieldInsnNode field = (FieldInsnNode) instruction;
        String cls = field.owner.substring(field.owner.lastIndexOf('/') + 1);
        cls = cls.replace('$', '.');
        return "Field " + cls + "#" + field.name;
    } else if (instruction instanceof TypeInsnNode && instruction.getOpcode() == Opcodes.NEW) {
        return "New " + ((TypeInsnNode) instruction).desc;
    }/*  www.j a va 2s.  co  m*/
    StringBuilder sb = new StringBuilder();
    String opcodeName = getOpcodeName(instruction.getOpcode());
    sb.append(opcodeName);

    if (instruction instanceof IntInsnNode) {
        IntInsnNode in = (IntInsnNode) instruction;
        sb.append(" ").append(Integer.toString(in.operand));
    } else if (instruction instanceof LdcInsnNode) {
        LdcInsnNode ldc = (LdcInsnNode) instruction;
        sb.append(" ");
        if (ldc.cst instanceof String) {
            sb.append("\\\"");
        }
        sb.append(ldc.cst);
        if (ldc.cst instanceof String) {
            sb.append("\\\"");
        }
    }
    return sb.toString();
}

From source file:com.android.tools.klint.client.api.LintDriver.java

License:Apache License

@Nullable
private static MethodInsnNode findConstructorInvocation(@NonNull MethodNode method, @NonNull String className) {
    InsnList nodes = method.instructions;
    for (int i = 0, n = nodes.size(); i < n; i++) {
        AbstractInsnNode instruction = nodes.get(i);
        if (instruction.getOpcode() == Opcodes.INVOKESPECIAL) {
            MethodInsnNode call = (MethodInsnNode) instruction;
            if (className.equals(call.owner)) {
                return call;
            }//  w  w  w .j a  v  a  2  s. c  om
        }
    }

    return null;
}

From source file:com.android.tools.klint.detector.api.LintUtils.java

License:Apache License

/**
 * Returns the previous opcode prior to the given node, ignoring label and
 * line number nodes//from www  .  ja v  a  2 s. c  o  m
 *
 * @param node the node to look up the previous opcode for
 * @return the previous opcode, or {@link Opcodes#NOP} if no previous node
 *         was found
 */
public static int getPrevOpcode(@NonNull AbstractInsnNode node) {
    AbstractInsnNode prev = getPrevInstruction(node);
    if (prev != null) {
        return prev.getOpcode();
    } else {
        return Opcodes.NOP;
    }
}

From source file:com.android.tools.klint.detector.api.LintUtils.java

License:Apache License

/**
 * Returns the next opcode after to the given node, ignoring label and line
 * number nodes/*from   w  w w . jav a 2  s. c  o m*/
 *
 * @param node the node to look up the next opcode for
 * @return the next opcode, or {@link Opcodes#NOP} if no next node was found
 */
public static int getNextOpcode(@NonNull AbstractInsnNode node) {
    AbstractInsnNode next = getNextInstruction(node);
    if (next != null) {
        return next.getOpcode();
    } else {
        return Opcodes.NOP;
    }
}

From source file:com.android.tools.lint.checks.AllowAllHostnameVerifierDetector.java

License:Apache License

@SuppressWarnings("rawtypes")
@Override// w  ww  . j  av  a  2s.  c  o  m
public void checkClass(@NonNull final ClassContext context, @NonNull ClassNode classNode) {
    if (!classNode.interfaces.contains("javax/net/ssl/HostnameVerifier")) {
        return;
    }
    List methodList = classNode.methods;
    for (Object m : methodList) {
        MethodNode method = (MethodNode) m;
        if ("verify".equals(method.name)) {
            InsnList nodes = method.instructions;
            boolean emptyMethod = true; // Stays true if method has no instructions
                                        // other than ICONST_1 or IRETURN.
            boolean containsIconst1 = false;

            for (int i = 0, n = nodes.size(); i < n; i++) {
                // Future work: Improve this check to be less sensitive to irrelevant
                // instructions/statements/invocations (e.g. System.out.println).
                AbstractInsnNode instruction = nodes.get(i);
                int type = instruction.getType();
                if (type != AbstractInsnNode.LABEL && type != AbstractInsnNode.LINE
                        && !(type == AbstractInsnNode.INSN && (instruction.getOpcode() == Opcodes.ICONST_1
                                || instruction.getOpcode() == Opcodes.IRETURN))) {
                    emptyMethod = false;
                    break;
                } else if (type == AbstractInsnNode.INSN && instruction.getOpcode() == Opcodes.ICONST_1) {
                    containsIconst1 = true;
                }
            }
            if (containsIconst1 && emptyMethod) {
                Location location = context.getLocation(method, classNode);
                context.report(ISSUE, location,
                        method.name + " always returns true, which "
                                + "could cause insecure network traffic due to trusting TLS/SSL "
                                + "server certificates for wrong hostnames");
            }
        }
    }
}

From source file:com.android.tools.lint.checks.ApiDetector.java

License:Apache License

private static void checkSimpleDateFormat(ClassContext context, MethodNode method, MethodInsnNode node,
        int minSdk) {
    if (minSdk >= 9) {
        // Already OK
        return;//www. j a va  2 s  . c o  m
    }
    if (node.name.equals(CONSTRUCTOR_NAME) && !node.desc.equals("()V")) { //$NON-NLS-1$
        // Check first argument
        AbstractInsnNode prev = LintUtils.getPrevInstruction(node);
        if (prev != null && !node.desc.equals("(Ljava/lang/String;)V")) { //$NON-NLS-1$
            prev = LintUtils.getPrevInstruction(prev);
        }
        if (prev != null && prev.getOpcode() == Opcodes.LDC) {
            LdcInsnNode ldc = (LdcInsnNode) prev;
            Object cst = ldc.cst;
            if (cst instanceof String) {
                String pattern = (String) cst;
                boolean isEscaped = false;
                for (int i = 0; i < pattern.length(); i++) {
                    char c = pattern.charAt(i);
                    if (c == '\'') {
                        isEscaped = !isEscaped;
                    } else if (!isEscaped && (c == 'L' || c == 'c')) {
                        String message = String
                                .format("The pattern character '%1$c' requires API level 9 (current "
                                        + "min is %2$d) : \"%3$s\"", c, minSdk, pattern);
                        report(context, message, node, method, pattern, null, SearchHints.create(FORWARD));
                        return;
                    }
                }
            }
        }
    }
}

From source file:com.android.tools.lint.checks.ApiDetector.java

License:Apache License

@SuppressWarnings("rawtypes") // ASM API
private static void checkSwitchBlock(ClassContext context, ClassNode classNode, FieldInsnNode field,
        MethodNode method, String name, String owner, int api, int minSdk) {
    // Switch statements on enums are tricky. The compiler will generate a method
    // which returns an array of the enum constants, indexed by their ordinal() values.
    // However, we only want to complain if the code is actually referencing one of
    // the non-available enum fields.
    ///*from   w w w  . jav  a2 s  .  co  m*/
    // For the android.graphics.PorterDuff.Mode enum for example, the first few items
    // in the array are populated like this:
    //
    //   L0
    //    ALOAD 0
    //    GETSTATIC android/graphics/PorterDuff$Mode.ADD : Landroid/graphics/PorterDuff$Mode;
    //    INVOKEVIRTUAL android/graphics/PorterDuff$Mode.ordinal ()I
    //    ICONST_1
    //    IASTORE
    //   L1
    //    GOTO L3
    //   L2
    //   FRAME FULL [[I] [java/lang/NoSuchFieldError]
    //    POP
    //   L3
    //   FRAME SAME
    //    ALOAD 0
    //    GETSTATIC android/graphics/PorterDuff$Mode.CLEAR : Landroid/graphics/PorterDuff$Mode;
    //    INVOKEVIRTUAL android/graphics/PorterDuff$Mode.ordinal ()I
    //    ICONST_2
    //    IASTORE
    //    ...
    // So if we for example find that the "ADD" field isn't accessible, since it requires
    // API 11, we need to
    //   (1) First find out what its ordinal number is. We can look at the following
    //       instructions to discover this; it's the "ICONST_1" and "IASTORE" instructions.
    //       (After ICONST_5 it moves on to BIPUSH 6, BIPUSH 7, etc.)
    //   (2) Find the corresponding *usage* of this switch method. For the above enum,
    //       the switch ordinal lookup method will be called
    //         "$SWITCH_TABLE$android$graphics$PorterDuff$Mode" with desc "()[I".
    //       This means we will be looking for an invocation in some other method which looks
    //       like this:
    //         INVOKESTATIC (current class).$SWITCH_TABLE$android$graphics$PorterDuff$Mode ()[I
    //       (obviously, it can be invoked more than once)
    //       Note that it can be used more than once in this class and all sites should be
    //       checked!
    //   (3) Look up the corresponding table switch, which should look something like this:
    //        INVOKESTATIC (current class).$SWITCH_TABLE$android$graphics$PorterDuff$Mode ()[I
    //        ALOAD 0
    //        INVOKEVIRTUAL android/graphics/PorterDuff$Mode.ordinal ()I
    //        IALOAD
    //        LOOKUPSWITCH
    //          2: L1
    //          11: L2
    //          default: L3
    //       Here we need to see if the LOOKUPSWITCH instruction is referencing our target
    //       case. Above we were looking for the "ADD" case which had ordinal 1. Since this
    //       isn't explicitly referenced, we can ignore this field reference.
    AbstractInsnNode next = field.getNext();
    if (next == null || next.getOpcode() != Opcodes.INVOKEVIRTUAL) {
        return;
    }
    next = next.getNext();
    if (next == null) {
        return;
    }
    int ordinal;
    switch (next.getOpcode()) {
    case Opcodes.ICONST_0:
        ordinal = 0;
        break;
    case Opcodes.ICONST_1:
        ordinal = 1;
        break;
    case Opcodes.ICONST_2:
        ordinal = 2;
        break;
    case Opcodes.ICONST_3:
        ordinal = 3;
        break;
    case Opcodes.ICONST_4:
        ordinal = 4;
        break;
    case Opcodes.ICONST_5:
        ordinal = 5;
        break;
    case Opcodes.BIPUSH: {
        IntInsnNode iin = (IntInsnNode) next;
        ordinal = iin.operand;
        break;
    }
    default:
        return;
    }

    // Find usages of this call site
    List methodList = classNode.methods;
    for (Object m : methodList) {
        InsnList nodes = ((MethodNode) m).instructions;
        for (int i = 0, n = nodes.size(); i < n; i++) {
            AbstractInsnNode instruction = nodes.get(i);
            if (instruction.getOpcode() != Opcodes.INVOKESTATIC) {
                continue;
            }
            MethodInsnNode node = (MethodInsnNode) instruction;
            if (node.name.equals(method.name) && node.desc.equals(method.desc)
                    && node.owner.equals(classNode.name)) {
                // Find lookup switch
                AbstractInsnNode target = getNextInstruction(node);
                while (target != null) {
                    if (target.getOpcode() == Opcodes.LOOKUPSWITCH) {
                        LookupSwitchInsnNode lookup = (LookupSwitchInsnNode) target;
                        @SuppressWarnings("unchecked") // ASM API
                        List<Integer> keys = lookup.keys;
                        if (keys != null && keys.contains(ordinal)) {
                            String fqcn = ClassContext.getFqcn(owner) + '#' + name;
                            String message = String.format(
                                    "Enum value requires API level %1$d " + "(current min is %2$d): %3$s", api,
                                    minSdk, fqcn);
                            report(context, message, lookup, (MethodNode) m, name, null,
                                    SearchHints.create(FORWARD).matchJavaSymbol());

                            // Break out of the inner target search only; the switch
                            // statement could be used in other places in this class as
                            // well and we want to report all problematic usages.
                            break;
                        }
                    }
                    target = getNextInstruction(target);
                }
            }
        }
    }
}

From source file:com.android.tools.lint.checks.CordovaVersionDetector.java

License:Apache License

private void checkInstructionInternal(ClassContext context, ClassNode classNode, AbstractInsnNode instruction) {

    FieldInsnNode node = (FieldInsnNode) instruction;
    if (node.getOpcode() == Opcodes.PUTSTATIC && node.owner.equals(FQN_CORDOVA_DEVICE)
            && node.name.equals(FIELD_NAME_CORDOVA_VERSION)) {
        AbstractInsnNode prevInstruction = LintUtils.getPrevInstruction(node);
        if (prevInstruction == null || prevInstruction.getOpcode() != Opcodes.LDC) {
            return;
        }/*  www. ja  v a2 s.c o  m*/
        LdcInsnNode ldcInsnNode = (LdcInsnNode) prevInstruction;
        if (ldcInsnNode.cst instanceof String) {
            mCordovaVersion = createVersion((String) ldcInsnNode.cst);
            if (mCordovaVersion != null) {
                validateCordovaVersion(context, mCordovaVersion, context.getLocation(classNode));
            }
        }
    }
}