Clover coverage report - PMD - 3.9 Coverage timestamp: Tue Dec 19 2006 09:38:44 EST FRAMES NO FRAMES |
file stats: | LOC: | 150 |  | Methods: | 6
| NCLOC: | 123 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
ArrayIsStoredDirectly.java | 77.1% | 86.8% | 100% | 83.6% |

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;
24 |  | import java.util.List;
25 |  | import java.util.Vector;
26 |  |
27 |  | /**
28 |  | * @author mgriffa
29 |  | */
30 |  | public class ArrayIsStoredDirectly extends AbstractSunSecureRule {
31 |  |
32 | 11 | public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
33 | 11 | if (node.isInterface()) {
34 | 1 | return data;
35 |  | }
36 | 10 | return super.visit(node, data);
37 |  | }
38 |  |
39 | 2 | public Object visit(ASTConstructorDeclaration node, Object data) {
40 | 2 | ASTFormalParameter[] arrs = getArrays(node.getParameters());
41 | 2 | if (arrs != null) {
42 |  | //TODO check if one of these arrays is stored in a non local variable
43 | 2 | List bs = node.findChildrenOfType(ASTBlockStatement.class);
44 | 2 | checkAll(data, arrs, bs);
45 |  | }
46 | 2 | return data;
47 |  | }
48 |  |
49 | 9 | public Object visit(ASTMethodDeclaration node, Object data) {
50 | 9 | final ASTFormalParameters params = (ASTFormalParameters) node.getFirstChildOfType(ASTFormalParameters.class);
51 | 9 | ASTFormalParameter[] arrs = getArrays(params);
52 | 9 | if (arrs != null) {
53 | 8 | checkAll(data, arrs, node.findChildrenOfType(ASTBlockStatement.class));
54 |  | }
55 | 9 | return data;
56 |  | }
57 |  |
58 | 10 | private void checkAll(Object context, ASTFormalParameter[] arrs, List bs) {
59 | 10 | for (int i = 0; i < arrs.length; i++) {
60 | 10 | 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 | 10 | private boolean checkForDirectAssignment(Object ctx, final ASTFormalParameter parameter, final List bs) {
68 | 10 | final ASTVariableDeclaratorId vid = (ASTVariableDeclaratorId) parameter.getFirstChildOfType(ASTVariableDeclaratorId.class);
69 | 10 | final String varName = vid.getImage();
70 | 10 | for (Iterator it = bs.iterator(); it.hasNext();) {
71 | 9 | final ASTBlockStatement b = (ASTBlockStatement) it.next();
72 | 9 | if (b.containsChildOfType(ASTAssignmentOperator.class)) {
73 | 8 | final ASTStatementExpression se = (ASTStatementExpression) b.getFirstChildOfType(ASTStatementExpression.class);
74 | 8 | if (se == null || !(se.jjtGetChild(0) instanceof ASTPrimaryExpression)) {
75 | 0 | continue;
76 |  | }
77 | 8 | ASTPrimaryExpression pe = (ASTPrimaryExpression) se.jjtGetChild(0);
78 | 8 | String assignedVar = getFirstNameImage(pe);
79 | 8 | if (assignedVar == null) {
80 | 2 | ASTPrimarySuffix suffix = (ASTPrimarySuffix) se.getFirstChildOfType(ASTPrimarySuffix.class);
81 | 2 | if (suffix == null) {
82 | 0 | continue;
83 |  | }
84 | 2 | assignedVar = suffix.getImage();
85 |  | }
86 |  |
87 | 8 | SimpleNode n = (ASTMethodDeclaration) pe.getFirstParentOfType(ASTMethodDeclaration.class);
88 | 8 | if (n == null) {
89 | 2 | n = (ASTConstructorDeclaration) pe.getFirstParentOfType(ASTConstructorDeclaration.class);
90 | 2 | if (n == null) {
91 | 0 | continue;
92 |  | }
93 |  | }
94 | 8 | 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 | 7 | if (se.jjtGetNumChildren() < 3) {
99 | 0 | continue;
100 |  | }
101 | 7 | ASTExpression e = (ASTExpression) se.jjtGetChild(2);
102 | 7 | if (e.findChildrenOfType(ASTEqualityExpression.class).size() > 0) {
103 | 1 | continue;
104 |  | }
105 | 6 | String val = getFirstNameImage(e);
106 | 6 | if (val == null) {
107 | 0 | ASTPrimarySuffix foo = (ASTPrimarySuffix) se.getFirstChildOfType(ASTPrimarySuffix.class);
108 | 0 | if (foo == null) {
109 | 0 | continue;
110 |  | }
111 | 0 | val = foo.getImage();
112 |  | }
113 | 6 | if (val == null) {
114 | 0 | continue;
115 |  | }
116 | 6 | ASTPrimarySuffix foo = (ASTPrimarySuffix) se.getFirstChildOfType(ASTPrimarySuffix.class);
117 | 6 | if (foo != null && foo.isArrayDereference()) {
118 | 1 | continue;
119 |  | }
120 |  |
121 | 5 | if (val.equals(varName)) {
122 | 4 | SimpleNode md = (ASTMethodDeclaration) parameter.getFirstParentOfType(ASTMethodDeclaration.class);
123 | 4 | if (md == null) {
124 | 1 | md = (ASTConstructorDeclaration) pe.getFirstParentOfType(ASTConstructorDeclaration.class);
125 |  | }
126 | 4 | if (!isLocalVariable(varName, md)) {
127 | 4 | addViolation(ctx, parameter, varName);
128 |  | }
129 |  | }
130 |  | }
131 |  | }
132 |  | }
133 | 10 | return false;
134 |  | }
135 |  |
136 | 11 | private final ASTFormalParameter[] getArrays(ASTFormalParameters params) {
137 | 11 | final List l = params.findChildrenOfType(ASTFormalParameter.class);
138 | 11 | if (l != null && !l.isEmpty()) {
139 | 10 | Vector v = new Vector();
140 | 10 | for (Iterator it = l.iterator(); it.hasNext();) {
141 | 10 | ASTFormalParameter fp = (ASTFormalParameter) it.next();
142 | 10 | if (fp.isArray())
143 | 10 | v.add(fp);
144 |  | }
145 | 10 | return (ASTFormalParameter[]) v.toArray(new ASTFormalParameter[v.size()]);
146 |  | }
147 | 1 | return null;
148 |  | }
149 |  |
150 |  | }