/** * BSD-style license; for more info see http://pmd.sourceforge.net/license.html */ package net.sourceforge.pmd.lang.java.rule.sunsecure; import java.util.List; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression; import net.sourceforge.pmd.lang.java.ast.ASTEqualityExpression; import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTName; import net.sourceforge.pmd.lang.java.ast.ASTNullLiteral; import net.sourceforge.pmd.lang.java.ast.ASTPrimarySuffix; import net.sourceforge.pmd.lang.java.ast.ASTReturnStatement; import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTVariableDeclaratorId; import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule; /** * Utility methods for the package * * Created on Jan 17, 2005 * * @author mgriffa */ public abstract class AbstractSunSecureRule extends AbstractJavaRule { /** * Tells if the type declaration has a field with varName. * * @param varName * the name of the field to search * @param typeDeclaration * the type declaration * @return <code>true</code> if there is a field in the type declaration * named varName, <code>false</code> in other case */ protected final boolean isField(String varName, ASTTypeDeclaration typeDeclaration) { final List<ASTFieldDeclaration> fds = typeDeclaration.findDescendantsOfType(ASTFieldDeclaration.class); if (fds != null) { for (ASTFieldDeclaration fd : fds) { final ASTVariableDeclaratorId vid = fd.getFirstDescendantOfType(ASTVariableDeclaratorId.class); if (vid != null && vid.hasImageEqualTo(varName)) { return true; } } } return false; } /** * Gets the name of the variable returned. Some examples: <br> * for this.foo returns foo <br> * for foo returns foo <br> * for foo.bar returns foo.bar * * @param ret * a return statement to evaluate * @return the name of the variable associated or <code>null</code> if it * cannot be detected */ protected final String getReturnedVariableName(ASTReturnStatement ret) { if (hasTernaryCondition(ret) && hasTernaryNullCheck(ret)) { return ret.getFirstDescendantOfType(ASTConditionalExpression.class).jjtGetChild(0) .getFirstDescendantOfType(ASTName.class).getImage(); } final ASTName n = ret.getFirstDescendantOfType(ASTName.class); if (n != null) { return n.getImage(); } final ASTPrimarySuffix ps = ret.getFirstDescendantOfType(ASTPrimarySuffix.class); if (ps != null) { return ps.getImage(); } return null; } private boolean hasTernaryNullCheck(ASTReturnStatement ret) { ASTConditionalExpression condition = ret.getFirstDescendantOfType(ASTConditionalExpression.class); return condition.jjtGetChild(0) instanceof ASTEqualityExpression && condition.jjtGetChild(0).hasImageEqualTo("==") && condition.jjtGetChild(0).jjtGetChild(0).hasDescendantOfType(ASTName.class) && condition.jjtGetChild(0).jjtGetChild(1).hasDescendantOfType(ASTNullLiteral.class); } private boolean hasTernaryCondition(ASTReturnStatement ret) { ASTConditionalExpression condition = ret.getFirstDescendantOfType(ASTConditionalExpression.class); return condition != null && condition.isTernary(); } /** * TODO modify usages to use symbol table Tells if the variable name is a * local variable declared in the method. * * @param vn * the variable name * @param node * the ASTMethodDeclaration where the local variable name will be * searched * @return <code>true</code> if the method declaration contains any local * variable named vn and <code>false</code> in other case */ protected boolean isLocalVariable(String vn, Node node) { final List<ASTLocalVariableDeclaration> lvars = node.findDescendantsOfType(ASTLocalVariableDeclaration.class); if (lvars != null) { for (ASTLocalVariableDeclaration lvd : lvars) { final ASTVariableDeclaratorId vid = lvd.getFirstDescendantOfType(ASTVariableDeclaratorId.class); if (vid != null && vid.hasImageEqualTo(vn)) { return true; } } } return false; } /** * Gets the image of the ASTName node found by * {@link Node#getFirstDescendantOfType(Class)} if it is the greatgrandchild * of the given node. * * E.g. * * <pre> * n = Expression || StatementExpression * PrimaryExpression * PrimaryPrefix * Name * </pre> * * @param n * the node to search * @return the image of the first ASTName or <code>null</code> */ protected String getFirstNameImage(Node n) { ASTName name = n.getFirstDescendantOfType(ASTName.class); if (name != null && name.getNthParent(3) == n) { return name.getImage(); } return null; } }