View Javadoc

1   /*
2    * Created on Jan 17, 2005 
3    *
4    * $Id: MethodReturnsInternalArray.java,v 1.13 2006/03/29 13:58:51 tomcopeland Exp $
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.Iterator;
17  import java.util.List;
18  
19  /***
20   * Implementation note: this rule currently ignores return types of y.x.z,
21   * currently it handles only local type fields.
22   *
23   * @author mgriffa
24   */
25  public class MethodReturnsInternalArray extends AbstractSunSecureRule {
26  
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      public Object visit(ASTMethodDeclaration method, Object data) {
35          if (!method.getResultType().returnsArray()) {
36              return data;
37          }
38          List returns = method.findChildrenOfType(ASTReturnStatement.class);
39          ASTTypeDeclaration td = (ASTTypeDeclaration) method.getFirstParentOfType(ASTTypeDeclaration.class);
40          for (Iterator it = returns.iterator(); it.hasNext();) {
41              final ASTReturnStatement ret = (ASTReturnStatement) it.next();
42              final String vn = getReturnedVariableName(ret);
43              if (!isField(vn, td)) {
44                  continue;
45              }
46              if (ret.findChildrenOfType(ASTPrimarySuffix.class).size() > 2) {
47                  continue;
48              }
49              if (!ret.findChildrenOfType(ASTAllocationExpression.class).isEmpty()) {
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 = (ASTPrimaryPrefix) ret.getFirstChildOfType(ASTPrimaryPrefix.class);
57                  if (pp != null && pp.usesThisModifier()) {
58                      final ASTPrimarySuffix ps = (ASTPrimarySuffix) ret.getFirstChildOfType(ASTPrimarySuffix.class);
59                      if (ps.getImage().equals(vn)) {
60                          addViolation(data, ret, vn);
61                      }
62                  }
63              }
64          }
65          return data;
66      }
67  
68  
69  }