diff --git a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/sunsecure/MethodReturnsInternalArrayRule.java b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/sunsecure/MethodReturnsInternalArrayRule.java index f1407206c1..9c67c4affe 100644 --- a/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/sunsecure/MethodReturnsInternalArrayRule.java +++ b/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/sunsecure/MethodReturnsInternalArrayRule.java @@ -5,8 +5,14 @@ package net.sourceforge.pmd.lang.java.rule.sunsecure; import java.util.List; +import org.jaxen.JaxenException; + +import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression; +import net.sourceforge.pmd.lang.java.ast.ASTArrayInitializer; import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration; +import net.sourceforge.pmd.lang.java.ast.ASTExpression; +import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration; import net.sourceforge.pmd.lang.java.ast.ASTName; import net.sourceforge.pmd.lang.java.ast.ASTPrimaryExpression; @@ -14,6 +20,8 @@ import net.sourceforge.pmd.lang.java.ast.ASTPrimaryPrefix; 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.ast.ASTVariableInitializer; /** * Implementation note: this rule currently ignores return types of y.x.z, @@ -56,6 +64,9 @@ public class MethodReturnsInternalArrayRule extends AbstractSunSecureRule { if (hasClone(ret, vn)) { continue; } + if (isEmptyArray(vn, td)) { + continue; + } if (!isLocalVariable(vn, method)) { addViolation(data, ret, vn); } else { @@ -100,4 +111,32 @@ public class MethodReturnsInternalArrayRule extends AbstractSunSecureRule { } return false; } + + private boolean isEmptyArray(String varName, ASTTypeDeclaration typeDeclaration) { + final List 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)) { + ASTVariableInitializer initializer = fd.getFirstDescendantOfType(ASTVariableInitializer.class); + if (initializer != null && initializer.jjtGetNumChildren() == 1) { + Node child = initializer.jjtGetChild(0); + if (child instanceof ASTArrayInitializer && child.jjtGetNumChildren() == 0) { + return true; + } else if (child instanceof ASTExpression) { + try { + List arrayAllocation = child.findChildNodesWithXPath("./PrimaryExpression/PrimaryPrefix/AllocationExpression/ArrayDimsAndInits/Expression/PrimaryExpression/PrimaryPrefix/Literal[@IntLiteral=\"true\"][@Image=\"0\"]"); + if (arrayAllocation != null && arrayAllocation.size() == 1) { + return true; + } + } catch (JaxenException e) { + return false; + } + } + } + } + } + } + return false; + } } diff --git a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/sunsecure/xml/MethodReturnsInternalArray.xml b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/sunsecure/xml/MethodReturnsInternalArray.xml index 8975818f7e..8a3af43a83 100644 --- a/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/sunsecure/xml/MethodReturnsInternalArray.xml +++ b/pmd-java/src/test/resources/net/sourceforge/pmd/lang/java/rule/sunsecure/xml/MethodReturnsInternalArray.xml @@ -184,6 +184,36 @@ public class A { private Object[] getContent() { return content; } +} + ]]> + + + + #1475 False positive of MethodReturnsInternalArray + 0 + + + + + #1475 False positive of MethodReturnsInternalArray - ArrayAllocation + 0 + diff --git a/src/site/markdown/overview/changelog.md b/src/site/markdown/overview/changelog.md index db43cd797b..57bfcc2576 100644 --- a/src/site/markdown/overview/changelog.md +++ b/src/site/markdown/overview/changelog.md @@ -49,6 +49,7 @@ * java-optimizations/UseStringBufferForStringAppends: * [#1340](https://sourceforge.net/p/pmd/bugs/1340/): UseStringBufferForStringAppends False Positive with ternary operator * java-sunsecure/ArrayIsStoredDirectly: + * [#1475](https://sourceforge.net/p/pmd/bugs/1475/): False positive of MethodReturnsInternalArray * [#1476](https://sourceforge.net/p/pmd/bugs/1476/): False positive of ArrayIsStoredDirectly * java-unnecessary/UnnecessaryFinalModifier: * [#1464](https://sourceforge.net/p/pmd/bugs/1464/): UnnecessaryFinalModifier false positive on a @SafeVarargs method