List of usage examples for org.objectweb.asm.tree AbstractInsnNode getOpcode
public int getOpcode()
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)); } } } }