View Javadoc

1   /*
2    * Created on Jan 17, 2005 
3    *
4    * $Id$
5    */
6   package net.sourceforge.pmd.rules.sunsecure;
7   
8   import net.sourceforge.pmd.ast.ASTAllocationExpression;
9   import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
10  import net.sourceforge.pmd.ast.ASTMethodDeclaration;
11  import net.sourceforge.pmd.ast.ASTPrimaryPrefix;
12  import net.sourceforge.pmd.ast.ASTPrimarySuffix;
13  import net.sourceforge.pmd.ast.ASTReturnStatement;
14  import net.sourceforge.pmd.ast.ASTTypeDeclaration;
15  
16  import java.util.List;
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 MethodReturnsInternalArray extends AbstractSunSecureRule {
25  
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      public Object visit(ASTMethodDeclaration method, Object data) {
34          if (!method.getResultType().returnsArray()) {
35              return data;
36          }
37          List<ASTReturnStatement> returns = method.findChildrenOfType(ASTReturnStatement.class);
38          ASTTypeDeclaration td = method.getFirstParentOfType(ASTTypeDeclaration.class);
39          for (ASTReturnStatement ret: returns) {
40              final String vn = getReturnedVariableName(ret);
41              if (!isField(vn, td)) {
42                  continue;
43              }
44              if (ret.findChildrenOfType(ASTPrimarySuffix.class).size() > 2) {
45                  continue;
46              }
47              if (!ret.findChildrenOfType(ASTAllocationExpression.class).isEmpty()) {
48                  continue;
49              }
50              if (!isLocalVariable(vn, method)) {
51                  addViolation(data, ret, vn);
52              } else {
53                  // This is to handle field hiding
54                  final ASTPrimaryPrefix pp = ret.getFirstChildOfType(ASTPrimaryPrefix.class);
55                  if (pp != null && pp.usesThisModifier()) {
56                      final ASTPrimarySuffix ps = ret.getFirstChildOfType(ASTPrimarySuffix.class);
57                      if (ps.hasImageEqualTo(vn)) {
58                          addViolation(data, ret, vn);
59                      }
60                  }
61              }
62          }
63          return data;
64      }
65  
66  
67  }