View Javadoc

1   /*
2    * Created on Jan 17, 2005 
3    *
4    * $Id: MethodReturnsInternalArray.java,v 1.5 2005/03/08 20:23:27 tomcopeland Exp $
5    */
6   package net.sourceforge.pmd.rules.sunsecure;
7   
8   import net.sourceforge.pmd.RuleContext;
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.ASTResultType;
14  import net.sourceforge.pmd.ast.ASTReturnStatement;
15  import net.sourceforge.pmd.ast.ASTTypeDeclaration;
16  
17  import java.util.Iterator;
18  import java.util.List;
19  
20  /***
21   * Implementation note: this rule currently ignores return types of y.x.z, 
22   * currently it handles only local type fields.
23   * 
24   * @author mgriffa
25   */
26  public class MethodReturnsInternalArray extends AbstractSunSecureRule {
27  
28      public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
29          if (node.isInterface()) {
30              return data;
31          }
32          return super.visit(node, data);
33      }
34  
35      public Object visit(ASTMethodDeclaration node, Object data) {
36          final ASTResultType rt = (ASTResultType) node.getFirstChildOfType(ASTResultType.class);
37  
38          if (rt.returnsArray()) {
39              final List returns = node.findChildrenOfType(ASTReturnStatement.class);
40              
41              if (returns!=null) {
42                  ASTTypeDeclaration td = (ASTTypeDeclaration) node.getFirstParentOfType(ASTTypeDeclaration.class);
43                  
44                  for (Iterator it = returns.iterator() ; it.hasNext() ; ) {
45                      final ASTReturnStatement ret = (ASTReturnStatement) it.next();
46                      final String vn = getReturnedVariableName(ret);
47                      if (isField(vn, td)) {
48                          if (!isLocalVariable(vn, node)) {  
49                              addViolation((RuleContext)data, ret);
50                          }  else {
51                              // This is to handle field hiding
52                              final ASTPrimaryPrefix pp = (ASTPrimaryPrefix) ret.getFirstChildOfType(ASTPrimaryPrefix.class);
53                              if (pp!=null && pp.usesThisModifier()) {
54                                  final ASTPrimarySuffix ps = (ASTPrimarySuffix) ret.getFirstChildOfType(ASTPrimarySuffix.class);
55                                  if (ps.getImage().equals(vn)) {
56                                      addViolation((RuleContext)data, ret);
57                                  }
58                              }
59                          }
60                      
61                      }
62                  }
63              }
64          }
65          return data;
66      }
67  
68  
69  }