Clover coverage report - PMD - 3.7 Coverage timestamp: Wed May 31 2006 09:25:59 EDT FRAMES NO FRAMES |
file stats: | LOC: | 139 |  | Methods: | 6
| NCLOC: | 112 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
ArrayIsStoredDirectly.java | 66.7% | 77% | 83.3% | 73.4% |

1 |  | /*
2 |  | * Created on Jan 17, 2005
3 |  | *
4 |  | * $Id: ArrayIsStoredDirectly.java,v 1.14 2006/02/23 15:34:06 tomcopeland 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 |  |
22 |  | import java.util.Iterator;
23 |  | import java.util.List;
24 |  | import java.util.Vector;
25 |  |
26 |  | /**
27 |  | * @author mgriffa
28 |  | */
29 |  | public class ArrayIsStoredDirectly extends AbstractSunSecureRule {
30 |  |
31 | 8 | public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
32 | 8 | if (node.isInterface()) {
33 | 1 | return data;
34 |  | }
35 | 7 | return super.visit(node, data);
36 |  | }
37 |  |
38 | 0 | public Object visit(ASTConstructorDeclaration node, Object data) {
39 | 0 | ASTFormalParameter[] arrs = getArrays((ASTFormalParameters) node.jjtGetChild(0));
40 | 0 | if (arrs != null) {
41 |  | //TODO check if one of these arrays is stored in a non local variable
42 | 0 | List bs = node.findChildrenOfType(ASTBlockStatement.class);
43 | 0 | checkAll(data, arrs, bs);
44 |  | }
45 | 0 | return data;
46 |  | }
47 |  |
48 | 8 | public Object visit(ASTMethodDeclaration node, Object data) {
49 | 8 | final ASTFormalParameters params = (ASTFormalParameters) node.getFirstChildOfType(ASTFormalParameters.class);
50 | 8 | ASTFormalParameter[] arrs = getArrays(params);
51 | 8 | if (arrs != null) {
52 | 8 | checkAll(data, arrs, node.findChildrenOfType(ASTBlockStatement.class));
53 |  | }
54 | 8 | return data;
55 |  | }
56 |  |
57 | 8 | private void checkAll(Object context, ASTFormalParameter[] arrs, List bs) {
58 | 8 | for (int i = 0; i < arrs.length; i++) {
59 | 8 | checkForDirectAssignment(context, arrs[i], bs);
60 |  | }
61 |  | }
62 |  |
63 |  | /**
64 |  | * Checks if the variable designed in parameter is written to a field (not local variable) in the statements.
65 |  | */
66 | 8 | private boolean checkForDirectAssignment(Object ctx, final ASTFormalParameter parameter, final List bs) {
67 | 8 | final ASTVariableDeclaratorId vid = (ASTVariableDeclaratorId) parameter.getFirstChildOfType(ASTVariableDeclaratorId.class);
68 | 8 | final String varName = vid.getImage();
69 | 8 | for (Iterator it = bs.iterator(); it.hasNext();) {
70 | 7 | final ASTBlockStatement b = (ASTBlockStatement) it.next();
71 | 7 | if (b.containsChildOfType(ASTAssignmentOperator.class)) {
72 | 6 | final ASTStatementExpression se = (ASTStatementExpression) b.getFirstChildOfType(ASTStatementExpression.class);
73 | 6 | if (se == null || !(se.jjtGetChild(0) instanceof ASTPrimaryExpression)) {
74 | 0 | continue;
75 |  | }
76 | 6 | ASTPrimaryExpression pe = (ASTPrimaryExpression) se.jjtGetChild(0);
77 | 6 | String assignedVar = getFirstNameImage(pe);
78 | 6 | if (assignedVar == null) {
79 | 2 | assignedVar = ((ASTPrimarySuffix) se.getFirstChildOfType(ASTPrimarySuffix.class)).getImage();
80 |  | }
81 |  |
82 | 6 | ASTMethodDeclaration n = (ASTMethodDeclaration) pe.getFirstParentOfType(ASTMethodDeclaration.class);
83 | 6 | if (n == null) {
84 | 0 | continue;
85 |  | }
86 | 6 | if (!isLocalVariable(assignedVar, n)) {
87 |  | // TODO could this be more clumsy? We really
88 |  | // need to build out the PMD internal framework more
89 |  | // to support simply queries like "isAssignedTo()" or something
90 | 5 | if (se.jjtGetNumChildren() < 3) {
91 | 0 | continue;
92 |  | }
93 | 5 | ASTExpression e = (ASTExpression) se.jjtGetChild(2);
94 | 5 | if (e.findChildrenOfType(ASTEqualityExpression.class).size() > 0) {
95 | 1 | continue;
96 |  | }
97 | 4 | String val = getFirstNameImage(e);
98 | 4 | if (val == null) {
99 | 0 | ASTPrimarySuffix foo = (ASTPrimarySuffix) se.getFirstChildOfType(ASTPrimarySuffix.class);
100 | 0 | if (foo == null) {
101 | 0 | continue;
102 |  | }
103 | 0 | val = foo.getImage();
104 |  | }
105 | 4 | if (val == null) {
106 | 0 | continue;
107 |  | }
108 | 4 | ASTPrimarySuffix foo = (ASTPrimarySuffix) se.getFirstChildOfType(ASTPrimarySuffix.class);
109 | 4 | if (foo != null && foo.isArrayDereference()) {
110 | 1 | continue;
111 |  | }
112 |  |
113 | 3 | if (val.equals(varName)) {
114 | 3 | ASTMethodDeclaration md = (ASTMethodDeclaration) parameter.getFirstParentOfType(ASTMethodDeclaration.class);
115 | 3 | if (!isLocalVariable(varName, md)) {
116 | 3 | addViolation(ctx, parameter, varName);
117 |  | }
118 |  | }
119 |  | }
120 |  | }
121 |  | }
122 | 8 | return false;
123 |  | }
124 |  |
125 | 8 | private final ASTFormalParameter[] getArrays(ASTFormalParameters params) {
126 | 8 | final List l = params.findChildrenOfType(ASTFormalParameter.class);
127 | 8 | if (l != null && !l.isEmpty()) {
128 | 8 | Vector v = new Vector();
129 | 8 | for (Iterator it = l.iterator(); it.hasNext();) {
130 | 8 | ASTFormalParameter fp = (ASTFormalParameter) it.next();
131 | 8 | if (fp.isArray())
132 | 8 | v.add(fp);
133 |  | }
134 | 8 | return (ASTFormalParameter[]) v.toArray(new ASTFormalParameter[v.size()]);
135 |  | }
136 | 0 | return null;
137 |  | }
138 |  |
139 |  | }