View Javadoc

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