Clover coverage report - PMD - 3.9
Coverage timestamp: Tue Dec 19 2006 09:38:44 EST
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%
coverage coverage
 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    }