View Javadoc

    1   /*
    2    * Created on Jan 17, 2005
    3    *
    4    * $Id: MethodReturnsInternalArray.java,v 1.14 2006/10/17 00:48:10 hooperbloob Exp $
    5    */
    6   package net.sourceforge.pmd.rules.sunsecure;
    7
    8   import net.sourceforge.pmd.ast.ASTAllocationExpression;
    9   import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
    10  import net.sourceforge.pmd.ast.ASTMethodDeclaration;
    11  import net.sourceforge.pmd.ast.ASTPrimaryPrefix;
    12  import net.sourceforge.pmd.ast.ASTPrimarySuffix;
    13  import net.sourceforge.pmd.ast.ASTReturnStatement;
    14  import net.sourceforge.pmd.ast.ASTTypeDeclaration;
    15
    16  import java.util.Iterator;
    17  import java.util.List;
    18
    19  /***
    20   * Implementation note: this rule currently ignores return types of y.x.z,
    21   * currently it handles only local type fields.
    22   *
    23   * @author mgriffa
    24   */
    25  public class MethodReturnsInternalArray extends AbstractSunSecureRule {
    26
    27      public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
    28          if (node.isInterface()) {
    29              return data;
    30          }
    31          return super.visit(node, data);
    32      }
    33
    34      public Object visit(ASTMethodDeclaration method, Object data) {
    35          if (!method.getResultType().returnsArray()) {
    36              return data;
    37          }
    38          List returns = method.findChildrenOfType(ASTReturnStatement.class);
    39          ASTTypeDeclaration td = (ASTTypeDeclaration) method.getFirstParentOfType(ASTTypeDeclaration.class);
    40          for (Iterator it = returns.iterator(); it.hasNext();) {
    41              final ASTReturnStatement ret = (ASTReturnStatement) it.next();
    42              final String vn = getReturnedVariableName(ret);
    43              if (!isField(vn, td)) {
    44                  continue;
    45              }
    46              if (ret.findChildrenOfType(ASTPrimarySuffix.class).size() > 2) {
    47                  continue;
    48              }
    49              if (!ret.findChildrenOfType(ASTAllocationExpression.class).isEmpty()) {
    50                  continue;
    51              }
    52              if (!isLocalVariable(vn, method)) {
    53                  addViolation(data, ret, vn);
    54              } else {
    55                  // This is to handle field hiding
    56                  final ASTPrimaryPrefix pp = (ASTPrimaryPrefix) ret.getFirstChildOfType(ASTPrimaryPrefix.class);
    57                  if (pp != null && pp.usesThisModifier()) {
    58                      final ASTPrimarySuffix ps = (ASTPrimarySuffix) ret.getFirstChildOfType(ASTPrimarySuffix.class);
    59                      if (ps.hasImageEqualTo(vn)) {
    60                          addViolation(data, ret, vn);
    61                      }
    62                  }
    63              }
    64          }
    65          return data;
    66      }
    67
    68
    69  }