Clover coverage report - PMD - 3.7
Coverage timestamp: Wed May 31 2006 09:25:59 EDT
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%
coverage coverage
 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    }