1
2
3
4
5
6 package net.sourceforge.pmd.rules.sunsecure;
7
8 import net.sourceforge.pmd.RuleContext;
9 import net.sourceforge.pmd.ast.ASTAssignmentOperator;
10 import net.sourceforge.pmd.ast.ASTBlockStatement;
11 import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
12 import net.sourceforge.pmd.ast.ASTConstructorDeclaration;
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
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Vector;
25
26 /***
27 *
28 * @author mgriffa
29 */
30 public class ArrayIsStoredDirectly extends AbstractSunSecureRule {
31
32 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
33 if (node.isInterface()) {
34 return data;
35 }
36 return super.visit(node, data);
37 }
38
39 /***
40 * Overriden method.
41 *
42 * @see net.sourceforge.pmd.ast.JavaParserVisitor#visit(net.sourceforge.pmd.ast.ASTConstructorDeclaration, java.lang.Object)
43 */
44 public Object visit(ASTConstructorDeclaration node, Object data) {
45 ASTFormalParameter[] arrs = getArrays((ASTFormalParameters) node.jjtGetChild(0));
46 if (arrs!=null) {
47
48 List bs = node.findChildrenOfType(ASTBlockStatement.class);
49 checkDirectlyAssigned((RuleContext)data, arrs, bs);
50 }
51 return data;
52 }
53
54 private void checkDirectlyAssigned(RuleContext context, ASTFormalParameter[] arrs, List bs) {
55 for (int i=0;i<arrs.length;i++) {
56 if (isDirectlyAssigned(arrs[i], bs)) {
57 addViolation(context, arrs[i]);
58 }
59 }
60 }
61
62 /***
63 * Checks if the variable designed in parameter is written to a field (not local variable) in the statements.
64 */
65 private boolean isDirectlyAssigned(final ASTFormalParameter parameter, final List bs) {
66 final ASTVariableDeclaratorId vid = (ASTVariableDeclaratorId) parameter.getFirstChildOfType(ASTVariableDeclaratorId.class);
67 final String varName = vid.getImage();
68 for (Iterator it = bs.iterator() ; it.hasNext() ; ) {
69 final ASTBlockStatement b = (ASTBlockStatement) it.next();
70 if (b.containsChildOfType(ASTAssignmentOperator.class)) {
71 final ASTStatementExpression se = (ASTStatementExpression) b.getFirstChildOfType(ASTStatementExpression.class);
72 if (se == null) {
73 continue;
74 }
75 if (!(se.jjtGetChild(0) instanceof ASTPrimaryExpression)) {
76 continue;
77 }
78 ASTPrimaryExpression pe = (ASTPrimaryExpression) se.jjtGetChild(0);
79 String assignedVar = getFirstNameImage(pe);
80 if (assignedVar==null) {
81 assignedVar = ((ASTPrimarySuffix)se.getFirstChildOfType(ASTPrimarySuffix.class)).getImage();
82 }
83
84 ASTMethodDeclaration n = (ASTMethodDeclaration) pe.getFirstParentOfType(ASTMethodDeclaration.class);
85 if (n == null) {
86 continue;
87 }
88 if (!isLocalVariable(assignedVar, n)) {
89 if (se.jjtGetNumChildren() < 3) {
90 continue;
91 }
92 ASTExpression e = (ASTExpression) se.jjtGetChild(2);
93 String val = getFirstNameImage(e);
94 if (val==null) {
95 ASTPrimarySuffix foo = (ASTPrimarySuffix)se.getFirstChildOfType(ASTPrimarySuffix.class);
96 if (foo == null) {
97 continue;
98 }
99 val = foo.getImage();
100 }
101 if (val == null) {
102 continue;
103 }
104
105 if (val.equals(varName)) {
106 ASTMethodDeclaration md = (ASTMethodDeclaration) parameter.getFirstParentOfType(ASTMethodDeclaration.class);
107 if (!isLocalVariable(varName, md)) {
108 return true;
109 }
110 }
111 }
112 }
113 }
114 return false;
115 }
116
117 public Object visit(ASTMethodDeclaration node, Object data) {
118 final ASTFormalParameters params = (ASTFormalParameters) node.getFirstChildOfType(ASTFormalParameters.class);
119 ASTFormalParameter[] arrs = getArrays(params);
120 if (arrs!=null) {
121 List bs = node.findChildrenOfType(ASTBlockStatement.class);
122 checkDirectlyAssigned((RuleContext)data, arrs, bs);
123 }
124 return data;
125 }
126
127 private final ASTFormalParameter[] getArrays(ASTFormalParameters params) {
128 final List l = params.findChildrenOfType(ASTFormalParameter.class);
129 if (l!=null && !l.isEmpty()) {
130 Vector v = new Vector();
131 for (Iterator it = l.iterator() ; it.hasNext() ; ) {
132 ASTFormalParameter fp = (ASTFormalParameter) it.next();
133 if (fp.isArray())
134 v.add(fp);
135 }
136 return (ASTFormalParameter[]) v.toArray(new ASTFormalParameter[v.size()]);
137 }
138 return null;
139 }
140
141 }