View Javadoc

    1   /*
    2    * Created on Jan 17, 2005
    3    *
    4    * $Id: MethodReturnsInternalArray.java 5017 2007-01-31 00:53:53Z xlv $
    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.List;
    17
    18  /**
    19   * Implementation note: this rule currently ignores return types of y.x.z,
    20   * currently it handles only local type fields.
    21   *
    22   * @author mgriffa
    23   */
    24  public class MethodReturnsInternalArray extends AbstractSunSecureRule {
    25
    26      public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
    27          if (node.isInterface()) {
    28              return data;
    29          }
    30          return super.visit(node, data);
    31      }
    32
    33      public Object visit(ASTMethodDeclaration method, Object data) {
    34          if (!method.getResultType().returnsArray()) {
    35              return data;
    36          }
    37          List<ASTReturnStatement> returns = method.findChildrenOfType(ASTReturnStatement.class);
    38          ASTTypeDeclaration td = method.getFirstParentOfType(ASTTypeDeclaration.class);
    39          for (ASTReturnStatement ret: returns) {
    40              final String vn = getReturnedVariableName(ret);
    41              if (!isField(vn, td)) {
    42                  continue;
    43              }
    44              if (ret.findChildrenOfType(ASTPrimarySuffix.class).size() > 2) {
    45                  continue;
    46              }
    47              if (!ret.findChildrenOfType(ASTAllocationExpression.class).isEmpty()) {
    48                  continue;
    49              }
    50              if (!isLocalVariable(vn, method)) {
    51                  addViolation(data, ret, vn);
    52              } else {
    53                  // This is to handle field hiding
    54                  final ASTPrimaryPrefix pp = ret.getFirstChildOfType(ASTPrimaryPrefix.class);
    55                  if (pp != null && pp.usesThisModifier()) {
    56                      final ASTPrimarySuffix ps = ret.getFirstChildOfType(ASTPrimarySuffix.class);
    57                      if (ps.hasImageEqualTo(vn)) {
    58                          addViolation(data, ret, vn);
    59                      }
    60                  }
    61              }
    62          }
    63          return data;
    64      }
    65
    66
    67  }