View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.lang.java.rule.sunsecure;
5   
6   import java.util.List;
7   
8   import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
9   import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
10  import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
11  import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix;
12  import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix;
13  import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement;
14  import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration;
15  
16  /**
17   * Implementation note: this rule currently ignores return types of y.x.z,
18   * currently it handles only local type fields.
19   * Created on Jan 17, 2005
20   *
21   * @author mgriffa
22   */
23  public class MethodReturnsInternalArrayRule extends AbstractSunSecureRule {
24  
25      @Override
26      public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
27          if (node.isInterface()) {
28              return data;
29          }
30          return super.visit(node, data);
31      }
32  
33      @Override
34      public Object visit(ASTMethodDeclaration method, Object data) {
35          if (!method.getResultType().returnsArray()) {
36              return data;
37          }
38          List<ASTReturnStatement> returns = method.findDescendantsOfType(ASTReturnStatement.class);
39          ASTTypeDeclaration td = method.getFirstParentOfType(ASTTypeDeclaration.class);
40          for (ASTReturnStatement ret: returns) {
41              final String vn = getReturnedVariableName(ret);
42              if (!isField(vn, td)) {
43                  continue;
44              }
45              if (ret.findDescendantsOfType(ASTPrimarySuffix.class).size() > 2) {
46                  continue;
47              }
48              if (ret.hasDescendantOfType(ASTAllocationExpression.class)) {
49                  continue;
50              }
51              if (!isLocalVariable(vn, method)) {
52                  addViolation(data, ret, vn);
53              } else {
54                  // This is to handle field hiding
55                  final ASTPrimaryPrefix pp = ret.getFirstDescendantOfType(ASTPrimaryPrefix.class);
56                  if (pp != null && pp.usesThisModifier()) {
57                      final ASTPrimarySuffix ps = ret.getFirstDescendantOfType(ASTPrimarySuffix.class);
58                      if (ps.hasImageEqualTo(vn)) {
59                          addViolation(data, ret, vn);
60                      }
61                  }
62              }
63          }
64          return data;
65      }
66  
67  
68  }