private Object sawInvokeSpecial(Object userObject) {
   Object returnValue = userObject;
   String methodName = getNameConstantOperand();
   if (Values.CONSTRUCTOR.equals(methodName)) {
     String clsName = getClassConstantOperand().replace('/', '.');
     if (doesObjectNeedToBeWatched(clsName)) {
       returnValue = Boolean.TRUE;
     }
   }
   processMethodParms();
   return returnValue;
 }
  /**
   * looks for methods that have it's parameters all follow the form arg0, arg1, arg2, or parm0,
   * parm1, parm2 etc, where the method actually has code in it
   *
   * @param cls the class to check
   */
  private void checkIDEGeneratedParmNames(JavaClass cls) {

    methods:
    for (Method m : cls.getMethods()) {
      if (!m.isPublic()) {
        continue;
      }

      String name = m.getName();
      if (Values.CONSTRUCTOR.equals(name) || Values.STATIC_INITIALIZER.equals(name)) {
        continue;
      }

      LocalVariableTable lvt = m.getLocalVariableTable();
      if (lvt == null) {
        continue;
      }

      if (m.getCode().getCode().length <= MAX_EMPTY_METHOD_SIZE) {
        continue;
      }

      int numArgs = m.getArgumentTypes().length;
      if (numArgs == 0) {
        continue;
      }

      int offset = m.isStatic() ? 0 : 1;

      for (int i = 0; i < numArgs; i++) {
        LocalVariable lv = lvt.getLocalVariable(offset + i, 0);
        if ((lv == null) || (lv.getName() == null)) {
          continue methods;
        }

        Matcher ma = ARG_PATTERN.matcher(lv.getName());
        if (!ma.matches()) {
          continue methods;
        }
      }

      bugReporter.reportBug(
          new BugInstance(
                  this,
                  BugType.IMC_IMMATURE_CLASS_IDE_GENERATED_PARAMETER_NAMES.name(),
                  NORMAL_PRIORITY)
              .addClass(cls)
              .addMethod(cls, m));
      return;
    }
  }
Beispiel #3
0
  @Override
  public void sawOpcode(int seen) {
    try {
      stack.precomputation(this);

      int pc = getPC();
      if ((loopEnd != -1) && (pc > loopEnd)) {
        loopStart = -1;
        loopEnd = -1;
        regValueType.clear();
      }

      if ((seen == ALOAD) || ((seen >= ALOAD_0) && (seen <= ALOAD_3))) {
        int reg = RegisterUtils.getALoadReg(this, seen);
        State type = regValueType.get(Integer.valueOf(reg));
        if (type != null) state = type;
        else state = State.SEEN_NOTHING;
        return;
      }
      if ((seen == ASTORE) || ((seen >= ASTORE_0) && (seen <= ASTORE_3))) {
        if (stack.getStackDepth() > 0) {
          OpcodeStack.Item item = stack.getStackItem(0);
          int reg = RegisterUtils.getAStoreReg(this, seen);
          regValueType.put(Integer.valueOf(reg), (State) item.getUserValue());
        }
        state = State.SEEN_NOTHING;
        return;
      }
      if ((seen == ILOAD) || ((seen >= ILOAD_0) && (seen <= ILOAD_3))) {
        int reg = RegisterUtils.getLoadReg(this, seen);
        State type = regValueType.get(Integer.valueOf(reg));
        if (type != null) state = type;
        else state = State.SEEN_NOTHING;
        return;
      }
      if ((seen == ISTORE) || ((seen >= ISTORE_0) && (seen <= ISTORE_3))) {
        if (stack.getStackDepth() > 0) {
          OpcodeStack.Item item = stack.getStackItem(0);
          int reg = RegisterUtils.getStoreReg(this, seen);
          regValueType.put(Integer.valueOf(reg), (State) item.getUserValue());
        }
        state = State.SEEN_NOTHING;
        return;
      }

      switch (state) {
        case SEEN_NOTHING:
          if (seen == INVOKESPECIAL) {
            if (("java/util/StringTokenizer".equals(getClassConstantOperand()))
                && (Values.CONSTRUCTOR.equals(getNameConstantOperand()))
                && ("(Ljava/lang/String;Ljava/lang/String;)V".equals(getSigConstantOperand())))
              state = State.SEEN_STRINGTOKENIZER;
          }
          break;

        case SEEN_STRINGTOKENIZER:
          if (seen == INVOKEVIRTUAL) {
            String methodName = getNameConstantOperand();
            String signature = getSigConstantOperand();
            if (("countTokens".equals(methodName)) && ("()I".equals(signature)))
              state = State.SEEN_COUNTTOKENS;
            else if ("hasMoreTokens".equals(methodName) || "hasMoreElements".equals(methodName))
              state = State.SEEN_HASMORE;
            else if ("nextToken".equals(methodName) || "nextElement".equals(methodName)) {
              if ((pc < loopStart) || (pc > loopEnd)) regValueType.clear();
              else state = State.SEEN_NEXT;
            }
          }
          break;

        case SEEN_COUNTTOKENS:
          if (seen == ANEWARRAY) state = State.SEEN_NEWARRAY;
          else if (seen == IF_ICMPGE) {
            int target = getBranchTarget() - 3; // sizeof goto
            byte[] code = getCode().getCode();
            if ((code[target] & 0x000000FF) == GOTO) {
              int offset = (code[target + 1] << 1) + code[target + 2];
              int gotoTarget = target + offset + 3;
              if (gotoTarget < getPC()) {
                loopStart = gotoTarget;
                loopEnd = target;
              }
            }
          }
          break;

        case SEEN_HASMORE:
          if (seen == IFEQ) {
            int target = getBranchTarget() - 3; // sizeof goto
            byte[] code = getCode().getCode();
            if ((code[target] & 0x000000FF) == GOTO) {
              int offset = (code[target + 1] << 1) + code[target + 2];
              int gotoTarget = target + offset + 3;
              if (gotoTarget < getPC()) {
                loopStart = gotoTarget;
                loopEnd = target;
              }
            }
          }
          state = State.SEEN_NOTHING;
          break;

        case SEEN_NEXT:
          if (seen == AASTORE) {
            if ((pc > loopStart) && (pc < loopEnd)) {
              if (stack.getStackDepth() > 2) {
                OpcodeStack.Item arrayItem = stack.getStackItem(2);
                State arrayType = (State) arrayItem.getUserValue();
                OpcodeStack.Item elemItem = stack.getStackItem(0);
                State elemType = (State) elemItem.getUserValue();
                if ((arrayType == State.SEEN_NEWARRAY) && (elemType == State.SEEN_NEXT)) {
                  bugReporter.reportBug(
                      new BugInstance(this, BugType.USS_USE_STRING_SPLIT.name(), NORMAL_PRIORITY)
                          .addClass(this)
                          .addMethod(this)
                          .addSourceLine(this));
                }
              }
            }
          }
          state = State.SEEN_NOTHING;
          break;

        case SEEN_ARRAYSTORE:
        case SEEN_NEWARRAY:
          break;
      }
    } finally {
      TernaryPatcher.pre(stack, seen);
      stack.sawOpcode(this, seen);
      TernaryPatcher.post(stack, seen);
      if (state != State.SEEN_NOTHING) {
        if (stack.getStackDepth() > 0) {
          OpcodeStack.Item item = stack.getStackItem(0);
          item.setUserValue(state);
        }
      }
    }
  }