Exemple #1
0
  @Override
  public void transferInstruction(InstructionHandle handle, BasicBlock basicBlock, LockSet fact)
      throws DataflowAnalysisException {

    Instruction ins = handle.getInstruction();
    short opcode = ins.getOpcode();
    if (opcode == Constants.MONITORENTER || opcode == Constants.MONITOREXIT) {
      ValueNumberFrame frame = vnaDataflow.getFactAtLocation(new Location(handle, basicBlock));

      modifyLock(frame, fact, opcode == Constants.MONITORENTER ? 1 : -1);

    } else if (opcode == Constants.INVOKEVIRTUAL || opcode == Constants.INVOKEINTERFACE) {

      InvokeInstruction inv = (InvokeInstruction) ins;
      String name = inv.getMethodName(methodGen.getConstantPool());
      String sig = inv.getSignature(methodGen.getConstantPool());
      ValueNumberFrame frame = vnaDataflow.getFactAtLocation(new Location(handle, basicBlock));

      if ("()V".equals(sig) && ("lock".equals(name) || "lockInterruptibly".equals(name))) {
        modifyLock(frame, fact, 1);
      } else if ("()V".equals(sig) && ("unlock".equals(name))) {
        modifyLock(frame, fact, -1);
      }

    } else if ((ins instanceof ReturnInstruction) && isSynchronized && !isStatic) {

      lockOp(fact, vna.getThisValue().getNumber(), -1);
    }
  }
  /**
   * @param classContext
   * @param method
   */
  private void analyzeMethod(ClassContext classContext, Method method)
      throws MethodUnprofitableException, CFGBuilderException, DataflowAnalysisException {
    if (method.isSynthetic()
        || (method.getAccessFlags() & Constants.ACC_BRIDGE) == Constants.ACC_BRIDGE) return;
    CFG cfg = classContext.getCFG(method);
    TypeDataflow typeDataflow = classContext.getTypeDataflow(method);
    ConstantPoolGen constantPoolGen = classContext.getConstantPoolGen();

    locationLoop:
    for (Iterator<Location> iter = cfg.locationIterator(); iter.hasNext(); ) {
      Location location = iter.next();
      InstructionHandle handle = location.getHandle();
      Instruction ins = handle.getInstruction();

      // Only consider invoke instructions
      if (!(ins instanceof InvokeInstruction)) continue;
      if (ins instanceof INVOKEINTERFACE) continue;

      InvokeInstruction inv = (InvokeInstruction) ins;
      TypeFrame frame = typeDataflow.getFactAtLocation(location);

      String methodName = inv.getMethodName(constantPoolGen);
      if (methodName.toLowerCase().indexOf("unsupported") >= 0) continue;
      String methodSig = inv.getSignature(constantPoolGen);
      if (methodSig.equals("()Ljava/lang/UnsupportedOperationException;")) continue;

      Set<XMethod> targets;
      try {

        targets = Hierarchy2.resolveMethodCallTargets(inv, frame, constantPoolGen);
      } catch (ClassNotFoundException e) {
        AnalysisContext.reportMissingClass(e);
        continue locationLoop;
      }
      if (targets.isEmpty()) continue locationLoop;
      int priority = targets.size() == 1 ? Priorities.HIGH_PRIORITY : Priorities.NORMAL_PRIORITY;
      for (XMethod m : targets) {
        if (!m.isUnsupported()) continue locationLoop;
        XClass xc = AnalysisContext.currentXFactory().getXClass(m.getClassDescriptor());
        if (!(inv instanceof INVOKESTATIC) && !(m.isFinal() || xc.isFinal()))
          priority = Priorities.NORMAL_PRIORITY;
        if (xc == null || xc.isAbstract()) {
          try {
            if (!AnalysisContext.currentAnalysisContext()
                .getSubtypes2()
                .hasSubtypes(m.getClassDescriptor())) continue locationLoop;
          } catch (ClassNotFoundException e) {
            AnalysisContext.reportMissingClass(e);
            continue locationLoop;
          }
        }
      }
      BugInstance bug =
          new BugInstance(this, "DMI_UNSUPPORTED_METHOD", priority)
              .addClassAndMethod(classContext.getJavaClass(), method)
              .addCalledMethod(constantPoolGen, inv)
              .addSourceLine(classContext, method, location);
      bugReporter.reportBug(bug);
    }
  }
Exemple #3
0
 /** Method invocation. */
 public void visitInvokeInstruction(InvokeInstruction i) {
   Type[] argTypes = i.getArgumentTypes(cp);
   for (int j = 0; j < argTypes.length; j++) cv.registerCoupling(argTypes[j]);
   cv.registerCoupling(i.getReturnType(cp));
   /* Measuring decision: measure overloaded methods separately */
   cv.registerMethodInvocation(i.getClassName(cp), i.getMethodName(cp), argTypes);
 }
 private TaintMethodSummary getMethodSummary(InvokeInstruction obj) {
   String methodNameWithSig = obj.getMethodName(cpg) + obj.getSignature(cpg);
   String fullMethodName = getSlashedClassName(obj) + "." + methodNameWithSig;
   TaintMethodSummary methodSummary = methodSummaries.get(fullMethodName);
   if (methodSummary == null && TO_STRING_METHOD.equals(methodNameWithSig)) {
     methodSummary = TaintMethodSummary.getDefaultToStringSummary();
   }
   return methodSummary;
 }
  /**
   * Determine if given Instruction is a monitor wait.
   *
   * @param ins the Instruction
   * @param cpg the ConstantPoolGen for the Instruction
   * @return true if the instruction is a monitor wait, false if not
   */
  public static boolean isMonitorNotify(Instruction ins, ConstantPoolGen cpg) {
    if (!(ins instanceof InvokeInstruction)) return false;
    if (ins.getOpcode() == Constants.INVOKESTATIC) return false;

    InvokeInstruction inv = (InvokeInstruction) ins;
    String methodName = inv.getMethodName(cpg);
    String methodSig = inv.getSignature(cpg);

    return isMonitorNotify(methodName, methodSig);
  }
Exemple #6
0
  /**
   * Get a MethodDescriptor describing the method called by given InvokeInstruction.
   *
   * @param inv the InvokeInstruction
   * @param cpg ConstantPoolGen of class containing instruction
   * @return MethodDescriptor describing the called method
   */
  public static MethodDescriptor getCalledMethodDescriptor(
      InvokeInstruction inv, ConstantPoolGen cpg) {
    String calledClassName = inv.getClassName(cpg).replace('.', '/');
    String calledMethodName = inv.getMethodName(cpg);
    String calledMethodSig = inv.getSignature(cpg);
    boolean isStatic = inv.getOpcode() == Constants.INVOKESTATIC;

    return DescriptorFactory.instance()
        .getMethodDescriptor(calledClassName, calledMethodName, calledMethodSig, isStatic);
  }
 private static String getFullMethodName(ConstantPoolGen cpg, InvokeInstruction invoke) {
   String dottedClassName = invoke.getReferenceType(cpg).toString();
   StringBuilder builder = new StringBuilder(ClassName.toSlashedClassName(dottedClassName));
   builder.append(".").append(invoke.getMethodName(cpg)).append(invoke.getSignature(cpg));
   return builder.toString();
 }
      private void checkForPossibleObligationTransfer(
          InvokeInstruction inv, InstructionHandle handle) throws ClassNotFoundException {
        //
        // We will assume that a method invocation might transfer
        // an obligation from one type to another if
        // 1. either
        // - it's a constructor where the constructed
        // type and exactly one param type
        // are obligation types, or
        // - it's a method where the return type and
        // exactly one param type are obligation types
        // 2. at least one instance of the resource "consumed"
        // by the transfer exists at the point of the transfer.
        // E.g., if we see a transfer of InputStream->Reader,
        // there must be an instance of InputStream at
        // the transfer point.
        //

        if (DEBUG_FP) {
          System.out.println("Checking " + handle + " as possible obligation transfer...:");
        }

        // Find the State which is a prefix of the error state
        // at the location of this (possible) transfer.
        State transferState = getTransferState(handle);
        if (transferState == null) {
          if (DEBUG_FP) {
            System.out.println("No transfer state???");
          }
          return;
        }

        String methodName = inv.getMethodName(cpg);
        Type producedType =
            methodName.equals("<init>") ? inv.getReferenceType(cpg) : inv.getReturnType(cpg);

        if (DEBUG_FP && !(producedType instanceof ObjectType)) {
          System.out.println("Produced type " + producedType + " not an ObjectType");
        }

        if (producedType instanceof ObjectType) {
          Obligation produced =
              database.getFactory().getObligationByType((ObjectType) producedType);

          if (DEBUG_FP && produced == null) {
            System.out.println("Produced type  " + producedType + " not an obligation type");
          }

          if (produced != null) {
            XMethod calledMethod = XFactory.createXMethod(inv, cpg);
            Obligation[] params = database.getFactory().getParameterObligationTypes(calledMethod);

            for (int i = 0; i < params.length; i++) {
              Obligation consumed = params[i];

              if (DEBUG_FP && consumed == null) {
                System.out.println("Param " + i + " not an obligation type");
              }

              if (DEBUG_FP && consumed != null && consumed.equals(produced)) {
                System.out.println("Consumed type is the same as produced type");
              }

              if (consumed != null && !consumed.equals(produced)) {
                // See if an instance of the consumed obligation
                // type
                // exists here.
                if (transferState.getObligationSet().getCount(consumed.getId()) > 0) {
                  transferList.add(new PossibleObligationTransfer(consumed, produced));
                  if (DEBUG_FP) {
                    System.out.println(
                        "===> Possible transfer of "
                            + consumed
                            + " to "
                            + produced
                            + " at "
                            + handle);
                  }
                } else if (DEBUG_FP) {
                  System.out.println(
                      handle
                          + " not a transfer "
                          + "of "
                          + consumed
                          + "->"
                          + produced
                          + " because no instances of "
                          + consumed);
                  System.out.println("I see " + transferState.getObligationSet());
                }
              }
            }
          }
        }
      }