KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > pmd > rules > sunsecure > ArrayIsStoredDirectly


1 /*
2  * Created on Jan 17, 2005
3  *
4  * $Id: ArrayIsStoredDirectly.java,v 1.17 2006/10/25 19:40:45 xlv Exp $
5  */

6 package net.sourceforge.pmd.rules.sunsecure;
7
8 import net.sourceforge.pmd.ast.ASTAssignmentOperator;
9 import net.sourceforge.pmd.ast.ASTBlockStatement;
10 import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
11 import net.sourceforge.pmd.ast.ASTConstructorDeclaration;
12 import net.sourceforge.pmd.ast.ASTEqualityExpression;
13 import net.sourceforge.pmd.ast.ASTExpression;
14 import net.sourceforge.pmd.ast.ASTFormalParameter;
15 import net.sourceforge.pmd.ast.ASTFormalParameters;
16 import net.sourceforge.pmd.ast.ASTMethodDeclaration;
17 import net.sourceforge.pmd.ast.ASTPrimaryExpression;
18 import net.sourceforge.pmd.ast.ASTPrimarySuffix;
19 import net.sourceforge.pmd.ast.ASTStatementExpression;
20 import net.sourceforge.pmd.ast.ASTVariableDeclaratorId;
21 import net.sourceforge.pmd.ast.SimpleNode;
22
23 import java.util.Iterator JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Vector JavaDoc;
26
27 /**
28  * @author mgriffa
29  */

30 public class ArrayIsStoredDirectly extends AbstractSunSecureRule {
31
32     public Object JavaDoc visit(ASTClassOrInterfaceDeclaration node, Object JavaDoc data) {
33         if (node.isInterface()) {
34             return data;
35         }
36         return super.visit(node, data);
37     }
38
39     public Object JavaDoc visit(ASTConstructorDeclaration node, Object JavaDoc data) {
40         ASTFormalParameter[] arrs = getArrays(node.getParameters());
41         if (arrs != null) {
42             //TODO check if one of these arrays is stored in a non local variable
43
List JavaDoc bs = node.findChildrenOfType(ASTBlockStatement.class);
44             checkAll(data, arrs, bs);
45         }
46         return data;
47     }
48
49     public Object JavaDoc visit(ASTMethodDeclaration node, Object JavaDoc data) {
50         final ASTFormalParameters params = (ASTFormalParameters) node.getFirstChildOfType(ASTFormalParameters.class);
51         ASTFormalParameter[] arrs = getArrays(params);
52         if (arrs != null) {
53             checkAll(data, arrs, node.findChildrenOfType(ASTBlockStatement.class));
54         }
55         return data;
56     }
57
58     private void checkAll(Object JavaDoc context, ASTFormalParameter[] arrs, List JavaDoc bs) {
59         for (int i = 0; i < arrs.length; i++) {
60             checkForDirectAssignment(context, arrs[i], bs);
61         }
62     }
63
64     /**
65      * Checks if the variable designed in parameter is written to a field (not local variable) in the statements.
66      */

67     private boolean checkForDirectAssignment(Object JavaDoc ctx, final ASTFormalParameter parameter, final List JavaDoc bs) {
68         final ASTVariableDeclaratorId vid = (ASTVariableDeclaratorId) parameter.getFirstChildOfType(ASTVariableDeclaratorId.class);
69         final String JavaDoc varName = vid.getImage();
70         for (Iterator JavaDoc it = bs.iterator(); it.hasNext();) {
71             final ASTBlockStatement b = (ASTBlockStatement) it.next();
72             if (b.containsChildOfType(ASTAssignmentOperator.class)) {
73                 final ASTStatementExpression se = (ASTStatementExpression) b.getFirstChildOfType(ASTStatementExpression.class);
74                 if (se == null || !(se.jjtGetChild(0) instanceof ASTPrimaryExpression)) {
75                     continue;
76                 }
77                 ASTPrimaryExpression pe = (ASTPrimaryExpression) se.jjtGetChild(0);
78                 String JavaDoc assignedVar = getFirstNameImage(pe);
79                 if (assignedVar == null) {
80                     ASTPrimarySuffix suffix = (ASTPrimarySuffix) se.getFirstChildOfType(ASTPrimarySuffix.class);
81                     if (suffix == null) {
82                         continue;
83                     }
84                     assignedVar = suffix.getImage();
85                 }
86
87                 SimpleNode n = (ASTMethodDeclaration) pe.getFirstParentOfType(ASTMethodDeclaration.class);
88                 if (n == null) {
89                     n = (ASTConstructorDeclaration) pe.getFirstParentOfType(ASTConstructorDeclaration.class);
90                     if (n == null) {
91                         continue;
92                     }
93                 }
94                 if (!isLocalVariable(assignedVar, n)) {
95                     // TODO could this be more clumsy? We really
96
// need to build out the PMD internal framework more
97
// to support simply queries like "isAssignedTo()" or something
98
if (se.jjtGetNumChildren() < 3) {
99                         continue;
100                     }
101                     ASTExpression e = (ASTExpression) se.jjtGetChild(2);
102                     if (e.findChildrenOfType(ASTEqualityExpression.class).size() > 0) {
103                         continue;
104                     }
105                     String JavaDoc val = getFirstNameImage(e);
106                     if (val == null) {
107                         ASTPrimarySuffix foo = (ASTPrimarySuffix) se.getFirstChildOfType(ASTPrimarySuffix.class);
108                         if (foo == null) {
109                             continue;
110                         }
111                         val = foo.getImage();
112                     }
113                     if (val == null) {
114                         continue;
115                     }
116                     ASTPrimarySuffix foo = (ASTPrimarySuffix) se.getFirstChildOfType(ASTPrimarySuffix.class);
117                     if (foo != null && foo.isArrayDereference()) {
118                         continue;
119                     }
120
121                     if (val.equals(varName)) {
122                         SimpleNode md = (ASTMethodDeclaration) parameter.getFirstParentOfType(ASTMethodDeclaration.class);
123                         if (md == null) {
124                             md = (ASTConstructorDeclaration) pe.getFirstParentOfType(ASTConstructorDeclaration.class);
125                         }
126                         if (!isLocalVariable(varName, md)) {
127                             addViolation(ctx, parameter, varName);
128                         }
129                     }
130                 }
131             }
132         }
133         return false;
134     }
135
136     private final ASTFormalParameter[] getArrays(ASTFormalParameters params) {
137         final List JavaDoc l = params.findChildrenOfType(ASTFormalParameter.class);
138         if (l != null && !l.isEmpty()) {
139             Vector JavaDoc v = new Vector JavaDoc();
140             for (Iterator JavaDoc it = l.iterator(); it.hasNext();) {
141                 ASTFormalParameter fp = (ASTFormalParameter) it.next();
142                 if (fp.isArray())
143                     v.add(fp);
144             }
145             return (ASTFormalParameter[]) v.toArray(new ASTFormalParameter[v.size()]);
146         }
147         return null;
148     }
149
150 }
151
Popular Tags