private static boolean isValueOfInvocation(ExpressionTree abstractTypedTree) {
   if (!abstractTypedTree.is(Kind.METHOD_INVOCATION)) {
     return false;
   }
   Type type = abstractTypedTree.symbolType();
   MethodMatcher valueOfMatcher =
       MethodMatcher.create()
           .typeDefinition(type.fullyQualifiedName())
           .name("valueOf")
           .addParameter(((JavaType) type).primitiveType().fullyQualifiedName());
   return valueOfMatcher.matches((MethodInvocationTree) abstractTypedTree);
 }
 @Override
 public void visitMethodInvocation(MethodInvocationTree syntaxNode) {
   final ExpressionTree methodSelect = syntaxNode.methodSelect();
   if (isClosingResource(syntaxNode.symbol())) {
     if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
       final ExpressionTree targetExpression =
           ((MemberSelectExpressionTree) methodSelect).expression();
       if (targetExpression.is(Tree.Kind.IDENTIFIER)) {
         final IdentifierTree identifier = (IdentifierTree) targetExpression;
         programState = closeResource(programState, programState.getValue(identifier.symbol()));
       } else {
         programState = closeResource(programState, programState.peekValue());
       }
     }
   } else if (syntaxNode.methodSelect().is(Tree.Kind.MEMBER_SELECT)
       && isOpeningResultSet(syntaxNode.symbol())) {
     final SymbolicValue value = getTargetValue(syntaxNode);
     constraintManager.setValueFactory(new WrappedValueFactory(value));
   } else if (isClosingResultSets(syntaxNode.symbol())) {
     if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
       final SymbolicValue value = getTargetValue(syntaxNode);
       closeResultSetsRelatedTo(value);
     }
   } else {
     closeArguments(syntaxNode.arguments(), 1);
   }
 }
 private static ExpressionTree removeParenthesis(ExpressionTree tree) {
   ExpressionTree result = tree;
   while (result.is(Tree.Kind.PARENTHESIZED_EXPRESSION)) {
     result = ((ParenthesizedTree) result).expression();
   }
   return result;
 }
 private void addAssignment(ExpressionTree tree) {
   ExpressionTree variable = ExpressionsHelper.skipParentheses(tree);
   if (variable.is(Tree.Kind.IDENTIFIER)) {
     addAssignment((IdentifierTree) variable);
   } else if (variable.is(Tree.Kind.MEMBER_SELECT)) {
     addAssignment(((MemberSelectExpressionTree) variable).identifier());
   }
 }
 @Override
 public void visitAssignmentExpression(AssignmentExpressionTree syntaxNode) {
   final ExpressionTree variable = syntaxNode.variable();
   if (variable.is(Tree.Kind.ARRAY_ACCESS_EXPRESSION)) {
     List<SymbolicValue> stackedValues = programState.peekValues(2);
     SymbolicValue value = stackedValues.get(1);
     programState = closeResource(programState, value);
   }
 }
 private void addUnboxingIssue(ExpressionTree expressionTree, ExpressionTree expression) {
   if (expression.is(Tree.Kind.IDENTIFIER)) {
     IdentifierTree identifier = (IdentifierTree) expression;
     reportIssue(expressionTree, "Remove the unboxing of \"" + identifier.name() + "\".");
   } else {
     String name = expression.symbolType().name();
     reportIssue(expressionTree, "Remove the unboxing from \"" + name + "\".");
   }
 }
 @Override
 public void visitAssignmentExpression(AssignmentExpressionTree tree) {
   super.visitAssignmentExpression(tree);
   if (isFileCreateTempFile(tree.expression())) {
     ExpressionTree variable = tree.variable();
     if (variable.is(Tree.Kind.IDENTIFIER) && !symbolStack.isEmpty()) {
       symbolStack.peek().put(((IdentifierTree) variable).symbol(), State.CREATE_TMP_FILE);
     }
   }
 }
Example #8
0
 private static List<String> getValueFromExpression(ExpressionTree expression) {
   List<String> args = Lists.newArrayList();
   if (expression.is(Tree.Kind.STRING_LITERAL)) {
     args.add(LiteralUtils.trimQuotes(((LiteralTree) expression).value()));
   } else if (expression.is(Tree.Kind.NEW_ARRAY)) {
     for (ExpressionTree initializer : ((NewArrayTree) expression).initializers()) {
       args.addAll(getValueFromExpression(initializer));
     }
   }
   return args;
 }
 private void checkConcatenation(
     Tree tree, ExpressionTree leftOperand, ExpressionTree rightOperand) {
   Type wrapper = null;
   if (isEmptyString(leftOperand)) {
     wrapper = ((JavaType) rightOperand.symbolType()).primitiveWrapperType();
   } else if (isEmptyString(rightOperand)) {
     wrapper = ((JavaType) leftOperand.symbolType()).primitiveWrapperType();
   }
   if (wrapper != null) {
     createIssue(tree, wrapper.name());
   }
 }
 @Override
 public void visitMethodInvocation(MethodInvocationTree tree) {
   if (TO_STRING_MATCHERS.anyMatch(tree)) {
     ExpressionTree abstractTypedTree =
         ((MemberSelectExpressionTree) tree.methodSelect()).expression();
     if (abstractTypedTree.is(Kind.NEW_CLASS) || isValueOfInvocation(abstractTypedTree)) {
       String typeName = abstractTypedTree.symbolType().toString();
       createIssue(tree, typeName);
     }
   }
   super.visitMethodInvocation(tree);
 }
 private SymbolicValue getTargetValue(MethodInvocationTree syntaxNode) {
   final ExpressionTree targetExpression =
       ((MemberSelectExpressionTree) syntaxNode.methodSelect()).expression();
   final SymbolicValue value;
   if (targetExpression.is(Tree.Kind.IDENTIFIER)) {
     final IdentifierTree identifier = (IdentifierTree) targetExpression;
     value = programState.getValue(identifier.symbol());
   } else {
     value = programState.peekValue();
   }
   return value;
 }
 @CheckForNull
 private static Tree getAssignedVariable(ExpressionTree expression) {
   if (expression.is(Tree.Kind.ARRAY_ACCESS_EXPRESSION)) {
     return getAssignedVariable(((ArrayAccessExpressionTree) expression).expression());
   }
   IdentifierTree identifier;
   if (expression.is(Tree.Kind.IDENTIFIER)) {
     identifier = (IdentifierTree) expression;
   } else {
     identifier = ((MemberSelectExpressionTree) expression).identifier();
   }
   return identifier.symbol().declaration();
 }
 private static boolean isEqualsMethod(MethodInvocationTree syntaxNode) {
   if (syntaxNode.arguments().size() == 1) {
     ExpressionTree methodSelect = syntaxNode.methodSelect();
     if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
       MemberSelectExpressionTree expression = (MemberSelectExpressionTree) methodSelect;
       if ("equals".equals(expression.identifier().name())
           && syntaxNode.symbol().isMethodSymbol()) {
         Symbol.MethodSymbol symbol = (Symbol.MethodSymbol) syntaxNode.symbol();
         return symbol.parameterTypes().get(0).is("java.lang.Object");
       }
     }
   }
   return false;
 }
 @Override
 public void visitMethodInvocation(MethodInvocationTree syntaxNode) {
   if (syntaxNode.methodSelect().is(Tree.Kind.MEMBER_SELECT)
       && needsClosing(syntaxNode.symbolType())) {
     final ExpressionTree targetExpression =
         ((MemberSelectExpressionTree) syntaxNode.methodSelect()).expression();
     if (targetExpression.is(Tree.Kind.IDENTIFIER)
         && !isWithinTryHeader(syntaxNode)
         && (syntaxNode.symbol().isStatic() || isJdbcResourceCreation(targetExpression))) {
       programState =
           programState.addConstraint(
               programState.peekValue(),
               new ObjectConstraint(false, false, syntaxNode, Status.OPENED));
     }
   }
 }
 @Override
 public void visitReturnStatement(ReturnStatementTree syntaxNode) {
   SymbolicValue currentVal = programState.peekValue();
   if (currentVal != null) {
     final ExpressionTree expression = syntaxNode.expression();
     if (expression != null) {
       if (expression.is(Tree.Kind.IDENTIFIER)) {
         final IdentifierTree identifier = (IdentifierTree) expression;
         currentVal = programState.getValue(identifier.symbol());
       } else {
         currentVal = programState.peekValue();
       }
       programState = closeResource(programState, currentVal);
     }
   }
 }
 private void checkShiftWithoutByteSecuring(ExpressionTree shiftExpr, ExpressionTree byteExpr) {
   if (shifts.contains(shiftExpr)
       && !byteContainments.contains(byteExpr)
       && byteExpr.symbolType().isPrimitive(Primitives.BYTE)) {
     context.reportIssue(
         this, byteExpr, "Prevent \"int\" promotion by adding \"& 0xff\" to this expression.");
   }
 }
 private static boolean isJdbcResourceCreation(ExpressionTree targetExpression) {
   for (String creator : JDBC_RESOURCE_CREATIONS) {
     if (targetExpression.symbolType().is(creator)) {
       return true;
     }
   }
   return false;
 }
 private void checkForBoxing(ExpressionTree expression) {
   if (expression.is(Tree.Kind.NEW_CLASS)) {
     NewClassTree newClassTree = (NewClassTree) expression;
     Symbol.TypeSymbol classSymbol = wrapperClassSymbol(newClassTree);
     if (classSymbol != null) {
       ExpressionTree boxingArg = newClassTree.arguments().get(0);
       if (boxingArg.symbolType().isPrimitive()) {
         addBoxingIssue(newClassTree, classSymbol, boxingArg);
       }
     }
   } else if (expression.is(Tree.Kind.METHOD_INVOCATION)) {
     MethodInvocationTree methodInvocationTree = (MethodInvocationTree) expression;
     if (isValueOfInvocation(methodInvocationTree)) {
       ExpressionTree boxingArg = methodInvocationTree.arguments().get(0);
       addBoxingIssue(expression, methodInvocationTree.symbol().owner(), boxingArg);
     }
   }
 }
 @Override
 public void visitMemberSelectExpression(MemberSelectExpressionTree tree) {
   IdentifierTree identifier = null;
   ExpressionTree expression = tree.expression();
   if (expression.is(Kind.IDENTIFIER)) {
     identifier = (IdentifierTree) expression;
   } else if (expression.is(Kind.PARENTHESIZED_EXPRESSION)
       && ((ParenthesizedTree) expression).expression().is(Kind.IDENTIFIER)) {
     identifier = (IdentifierTree) ((ParenthesizedTree) expression).expression();
   }
   if (!validUsagesStack.isEmpty() && identifier != null) {
     Iterator<Collection<IdentifierTree>> iterator = validUsagesStack.iterator();
     while (iterator.hasNext()) {
       iterator.next().remove(identifier);
     }
   }
   super.visitMemberSelectExpression(tree);
 }
  @Override
  public void visitNewClass(NewClassTree tree) {
    if (TARGETED_CLASS.contains(getclassName(tree)) && tree.arguments().size() == 1) {
      ExpressionTree argument = tree.arguments().get(0);

      if (argument.is(Tree.Kind.CHAR_LITERAL)) {
        String character = ((LiteralTree) argument).value();
        context.reportIssue(
            this,
            argument,
            "Replace the constructor character parameter "
                + character
                + " with string parameter "
                + character.replace("'", "\"")
                + ".");
      }
    }
  }
 private void visitMethodInvocationTree(MethodInvocationTree methodInvocationTree) {
   if (isValueOfInvocation(methodInvocationTree)) {
     checkForUnboxing(methodInvocationTree.arguments().get(0));
   } else if (isUnboxingMethodInvocation(methodInvocationTree)) {
     ExpressionTree methodSelect = methodInvocationTree.methodSelect();
     if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
       MemberSelectExpressionTree memberSelectExpressionTree =
           (MemberSelectExpressionTree) methodSelect;
       checkForBoxing(memberSelectExpressionTree.expression());
     }
   } else {
     Symbol symbol = methodInvocationTree.symbol();
     if (symbol.isMethodSymbol()) {
       List<Type> parametersTypes = ((Symbol.MethodSymbol) symbol).parameterTypes();
       checkMethodInvocationArguments(methodInvocationTree, parametersTypes);
     }
   }
 }
 @Nullable
 private State checkAndAdvanceState(
     MethodInvocationTree mit, State requiredState, State nextState) {
   ExpressionTree methodSelect = mit.methodSelect();
   if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
     ExpressionTree expressionTree = ((MemberSelectExpressionTree) methodSelect).expression();
     if (expressionTree.is(Tree.Kind.IDENTIFIER)) {
       Symbol symbol = ((IdentifierTree) expressionTree).symbol();
       Map<Symbol, State> symbolStateMap = symbolStack.peek();
       if (symbolStateMap != null
           && symbolStateMap.containsKey(symbol)
           && requiredState.equals(symbolStateMap.get(symbol))) {
         symbolStateMap.put(symbol, nextState);
         return nextState;
       }
     }
   }
   return null;
 }
 private void checkForUnboxing(ExpressionTree expressionTree) {
   if (!expressionTree.is(Tree.Kind.METHOD_INVOCATION)) {
     return;
   }
   MethodInvocationTree methodInvocationTree = (MethodInvocationTree) expressionTree;
   if (isUnboxingMethodInvocation(methodInvocationTree)) {
     ExpressionTree methodSelect = methodInvocationTree.methodSelect();
     if (methodSelect.is(Tree.Kind.MEMBER_SELECT)) {
       MemberSelectExpressionTree memberSelectExpressionTree =
           (MemberSelectExpressionTree) methodSelect;
       ExpressionTree unboxedExpression = memberSelectExpressionTree.expression();
       String unboxingResultTypeName = methodInvocationTree.symbolType().fullyQualifiedName();
       if (unboxingResultTypeName.equals(
           PRIMITIVE_TYPES_BY_WRAPPER.get(unboxedExpression.symbolType().fullyQualifiedName()))) {
         addUnboxingIssue(expressionTree, unboxedExpression);
       }
     }
   }
 }
 @Override
 public void leaveNode(Tree tree) {
   if (hasSemantic()) {
     if (tree.is(Tree.Kind.METHOD)) {
       MethodTree method = (MethodTree) tree;
       if (ModifiersUtils.hasModifier(method.modifiers(), Modifier.NATIVE)) {
         hasNativeMethod = true;
       }
     } else if (tree.is(Tree.Kind.CLASS)) {
       classes.add((ClassTree) tree);
     } else if (tree.is(Tree.Kind.EXPRESSION_STATEMENT)) {
       ExpressionTree expression = ((ExpressionStatementTree) tree).expression();
       if (expression.is(ASSIGNMENT_KINDS)) {
         addAssignment(((AssignmentExpressionTree) expression).variable());
       }
     } else {
       leaveCompilationUnit();
     }
   }
 }
  private static String concatenate(ExpressionTree tree) {
    Deque<String> pieces = new LinkedList<>();
    ExpressionTree expr = tree;
    while (expr.is(Tree.Kind.MEMBER_SELECT)) {
      MemberSelectExpressionTree mse = (MemberSelectExpressionTree) expr;
      pieces.push(mse.identifier().name());
      pieces.push(".");
      expr = mse.expression();
    }
    if (expr.is(Tree.Kind.IDENTIFIER)) {
      IdentifierTree idt = (IdentifierTree) expr;
      pieces.push(idt.name());
    }

    StringBuilder sb = new StringBuilder();
    for (String piece : pieces) {
      sb.append(piece);
    }
    return sb.toString();
  }
 @Override
 public void visitNewClass(NewClassTree syntaxNode) {
   final List<SymbolicValue> arguments = programState.peekValues(syntaxNode.arguments().size());
   if (isOpeningResource(syntaxNode)) {
     Iterator<SymbolicValue> iterator = arguments.iterator();
     for (ExpressionTree argument : syntaxNode.arguments()) {
       if (!iterator.hasNext()) {
         throw new IllegalStateException(
             "Mismatch between declared constructor arguments and argument values!");
       }
       final Type type = argument.symbolType();
       final SymbolicValue value = iterator.next();
       if (isCloseable(type)) {
         constraintManager.setValueFactory(new WrappedValueFactory(value));
         break;
       }
     }
   } else {
     closeArguments(syntaxNode.arguments(), 0);
   }
 }
 public static boolean areOperandEquivalent(
     ExpressionTree left, ExpressionTree right, Tree.Kind binaryKind) {
   if (SyntacticEquivalence.areEquivalent(left, right)) {
     return true;
   }
   // Check other operands if operator is symetric.
   if (SYMETRIC_OPERATORS.contains(binaryKind) && left.is(binaryKind)) {
     return areOperandEquivalent(((BinaryExpressionTree) left).leftOperand(), right, binaryKind)
         || areOperandEquivalent(((BinaryExpressionTree) left).rightOperand(), right, binaryKind);
   }
   return false;
 }
  private boolean isQualifiedExcludedType(Tree tree) {
    if (!tree.is(Kind.MEMBER_SELECT)) {
      return false;
    }
    Deque<String> pieces = new LinkedList<>();
    ExpressionTree expr = (MemberSelectExpressionTree) tree;
    while (expr.is(Tree.Kind.MEMBER_SELECT)) {
      MemberSelectExpressionTree mse = (MemberSelectExpressionTree) expr;
      pieces.push(mse.identifier().name());
      pieces.push(".");
      expr = mse.expression();
    }
    if (expr.is(Tree.Kind.IDENTIFIER)) {
      IdentifierTree idt = (IdentifierTree) expr;
      pieces.push(idt.name());
    }

    StringBuilder sb = new StringBuilder();
    for (String piece : pieces) {
      sb.append(piece);
    }
    return Iterables.contains(exceptions, sb.toString());
  }
 private static boolean isFileCreateTempFile(ExpressionTree givenExpression) {
   ExpressionTree expressionTree = removeParenthesis(givenExpression);
   return expressionTree.is(Tree.Kind.METHOD_INVOCATION)
       && FILE_CREATE_TEMP_FILE.matches((MethodInvocationTree) expressionTree);
 }
 private static boolean isEmptyString(ExpressionTree expressionTree) {
   return expressionTree.is(Kind.STRING_LITERAL)
       && LiteralUtils.trimQuotes(((LiteralTree) expressionTree).value()).isEmpty();
 }