Beispiel #1
0
  /** Loads the code of the method. */
  protected Instruction[] loadCode(Method m) {
    Code c = m.getCode();

    if (c == null) {
      return null;
    }

    InstructionList il = new InstructionList(c.getCode());
    InstructionHandle[] hs = il.getInstructionHandles();
    int length = hs.length;
    Instruction[] is = new Instruction[length];

    for (int i = 0; i < length; i++) {
      is[i] = insnFactory.createAndInitialize(this, hs[i], i, m.getConstantPool());

      if (c.getLineNumberTable() != null) {
        // annoying bug when BCEL don't seem to find linenumber - pos match
        // also sometimes linenumber tables are not available
        is[i].setContext(
            ci.getName(),
            name,
            c.getLineNumberTable().getSourceLine(is[i].getPosition()),
            is[i].getPosition());
      }
    }

    return is;
  }
Beispiel #2
0
  /** Returns the exceptions of the method. */
  protected ExceptionHandler[] loadExceptions(Method m) {
    Code c = m.getCode();

    if (c == null) {
      return null;
    }

    CodeException[] ce = c.getExceptionTable();

    if (ce.length == 0) {
      return null;
    }

    int length = ce.length;
    ExceptionHandler[] eh = new ExceptionHandler[length];

    ConstantPool cp = m.getConstantPool();

    for (int i = 0; i < length; i++) {
      int ct = ce[i].getCatchType();
      eh[i] =
          new ExceptionHandler(
              ((ct == 0)
                  ? null
                  : cp.getConstantString(ct, Constants.CONSTANT_Class).replace('/', '.')),
              ce[i].getStartPC(),
              ce[i].getEndPC(),
              ce[i].getHandlerPC());
    }

    return eh;
  }
Beispiel #3
0
  /** Loads the line numbers for the method. */
  protected int[] loadLineNumbers(Method m) {
    Code c = m.getCode();

    if (c == null) {
      return null;
    }

    LineNumberTable lnt = c.getLineNumberTable();

    int length = code.length;
    int[] ln = new int[length];

    if (lnt == null) {
      // no line information
      return null;
    } else {
      for (int i = 0; i < length; i++) {
        try { // annoying bug when BCEL don't seem to find linenumber - pos match
          ln[i] = lnt.getSourceLine(code[i].getPosition());
        } catch (RuntimeException e) {
          System.out.print("^");
        }
      }
    }

    return ln;
  }
 @Override
 public void visit(Code obj) {
   sawSuperFinalize = false;
   super.visit(obj);
   bugAccumulator.reportAccumulatedBugs();
   if (!getMethodName().equals("finalize") || !getMethodSig().equals("()V")) return;
   String overridesFinalizeIn =
       Lookup.findSuperImplementor(getDottedClassName(), "finalize", "()V", bugReporter);
   boolean superHasNoFinalizer = overridesFinalizeIn.equals("java.lang.Object");
   // System.out.println("superclass: " + superclassName);
   if (obj.getCode().length == 1) {
     if (superHasNoFinalizer) {
       if (!getMethod().isFinal())
         bugReporter.reportBug(
             new BugInstance(this, "FI_EMPTY", NORMAL_PRIORITY).addClassAndMethod(this));
     } else
       bugReporter.reportBug(
           new BugInstance(this, "FI_NULLIFY_SUPER", NORMAL_PRIORITY)
               .addClassAndMethod(this)
               .addClass(overridesFinalizeIn));
   } else if (obj.getCode().length == 5 && sawSuperFinalize)
     bugReporter.reportBug(
         new BugInstance(this, "FI_USELESS", NORMAL_PRIORITY).addClassAndMethod(this));
   else if (!sawSuperFinalize && !superHasNoFinalizer)
     bugReporter.reportBug(
         new BugInstance(this, "FI_MISSING_SUPER_CALL", NORMAL_PRIORITY)
             .addClassAndMethod(this)
             .addClass(overridesFinalizeIn));
 }
  /**
   * overrides the visitor to find abstract methods that override concrete ones
   *
   * @param obj the context object of the currently parsed method
   */
  @Override
  public void visitMethod(Method obj) {
    if (!obj.isAbstract()) return;

    String methodName = obj.getName();
    String methodSig = obj.getSignature();
    outer:
    for (JavaClass cls : superClasses) {
      Method[] methods = cls.getMethods();
      for (Method m : methods) {
        if (m.isPrivate() || m.isAbstract()) continue;
        if (methodName.equals(m.getName()) && methodSig.equals(m.getSignature())) {
          BugInstance bug =
              new BugInstance(this, BugType.AOM_ABSTRACT_OVERRIDDEN_METHOD.name(), NORMAL_PRIORITY)
                  .addClass(this)
                  .addMethod(this);

          Code code = obj.getCode();
          if (code != null) bug.addSourceLineRange(clsContext, this, 0, code.getLength() - 1);
          bugReporter.reportBug(bug);

          break outer;
        }
      }
    }
  }
Beispiel #6
0
  public static int getMaxStack(Method m) {
    Code c = m.getCode();

    if (c == null) {
      return 0;
    }

    return c.getMaxStack();
  }
  @Override
  public void visitCode(Code obj) {
    Method m = getMethod();
    if (m.getReturnType() == Type.VOID) {
      return;
    }

    stack.resetForMethodEntry(this);
    ifBlocks.clear();
    activeUnconditional = null;

    CodeException[] ces = obj.getExceptionTable();
    if (CollectionUtils.isEmpty(ces)) {
      catchPCs = null;
    } else {
      catchPCs = new BitSet();
      for (CodeException ce : ces) {
        catchPCs.set(ce.getHandlerPC());
      }
    }
    gotoBranchPCs.clear();
    casePositions.clear();
    lookingForResetOp = false;

    try {
      super.visitCode(obj);
    } catch (StopOpcodeParsingException e) {
      // reported an issue, so get out
    }
  }
  /**
   * Dumps the contents of the specified class to the specified directory. The file is named
   * dump_dir/[class].bcel. It contains a synopsis of the fields and methods followed by the jvm
   * code for each method.
   *
   * @param jc javaclass to dump
   * @param dump_dir directory in which to write the file
   */
  public static void dump(JavaClass jc, File dump_dir) {

    try {
      dump_dir.mkdir();
      File path = new File(dump_dir, jc.getClassName() + ".bcel");
      PrintStream p = new PrintStream(path);

      // Print the class, super class and interfaces
      p.printf("class %s extends %s\n", jc.getClassName(), jc.getSuperclassName());
      String[] inames = jc.getInterfaceNames();
      if ((inames != null) && (inames.length > 0)) {
        p.printf("   ");
        for (String iname : inames) p.printf("implements %s ", iname);
        p.printf("\n");
      }

      // Print each field
      p.printf("\nFields\n");
      for (Field f : jc.getFields()) p.printf("  %s\n", f);

      // Print the signature of each method
      p.printf("\nMethods\n");
      for (Method m : jc.getMethods()) p.printf("  %s\n", m);

      // If this is not an interface, print the code for each method
      if (!jc.isInterface()) {
        for (Method m : jc.getMethods()) {
          p.printf("\nMethod %s\n", m);
          Code code = m.getCode();
          if (code != null) p.printf("  %s\n", code.toString().replace("\n", "\n  "));
        }
      }

      // Print the details of the constant pool.
      p.printf("Constant Pool:\n");
      ConstantPool cp = jc.getConstantPool();
      Constant[] constants = cp.getConstantPool();
      for (int ii = 0; ii < constants.length; ii++) {
        p.printf("  %d %s\n", ii, constants[ii]);
      }

      p.close();

    } catch (Exception e) {
      throw new Error("Unexpected error dumping javaclass", e);
    }
  }
Beispiel #9
0
  /**
   * Loads the names of the local variables.
   *
   * <p>NOTE: BCEL only gives us a list of all *named* locals, which might not include all local
   * vars (temporaries, like StringBuilder). Note that we have to fill this with "?" in order to
   * make the returned array correspond with slot numbers
   */
  protected String[] loadLocalVariableNames(Method m) {
    Code c = m.getCode();

    if (c == null) {
      return null;
    }

    LocalVariableTable lvt = c.getLocalVariableTable();

    if (lvt == null) {
      if (!warnedLocalInfo && !ci.isSystemClass()) {
        Debug.println(Debug.WARNING);
        Debug.println(Debug.WARNING, "No local variable information available");
        Debug.println(Debug.WARNING, "for " + getCompleteName());
        Debug.println(Debug.WARNING, "Recompile with -g to include this information");
        Debug.println(Debug.WARNING);
        warnedLocalInfo = true;
      }

      return null;
    }

    LocalVariable[] lv = lvt.getLocalVariableTable();
    int length = lv.length;
    String[] v = new String[c.getMaxLocals()];

    for (int i = 0; i < length; i++) {
      v[lv[i].getIndex()] = lv[i].getName();
    }

    for (int i = 0; i < v.length; i++) {
      if (v[i] == null) {
        v[i] = "?";
      }
    }

    return v;
  }
Beispiel #10
0
 @Override
 public void visit(Code obj) {
   if (!directChildOfTestCase
       && (getMethodName().equals("setUp") || getMethodName().equals("tearDown"))
       && !getMethod().isPrivate()
       && getMethodSig().equals("()V")) {
     sawSuperCall = false;
     super.visit(obj);
     if (sawSuperCall) {
       return;
     }
     JavaClass we =
         Lookup.findSuperImplementor(getThisClass(), getMethodName(), "()V", bugReporter);
     if (we != null && !we.getClassName().equals("junit.framework.TestCase")) {
       // OK, got a bug
       int offset = 0;
       if (getMethodName().equals("tearDown")) {
         offset = obj.getCode().length - 1;
       }
       Method superMethod = Lookup.findImplementation(we, getMethodName(), "()V");
       Code superCode = superMethod.getCode();
       if (superCode != null && superCode.getCode().length > 3) {
         bugReporter.reportBug(
             new BugInstance(
                     this,
                     getMethodName().equals("setUp")
                         ? "IJU_SETUP_NO_SUPER"
                         : "IJU_TEARDOWN_NO_SUPER",
                     NORMAL_PRIORITY)
                 .addClassAndMethod(this)
                 .addMethod(we, superMethod)
                 .describe(MethodAnnotation.METHOD_OVERRIDDEN)
                 .addSourceLine(this, offset));
       }
     }
   }
 }