Fix stack overflow error

This commit is contained in:
Andreas Dangel
2021-10-07 20:04:17 +02:00
parent 701938de1c
commit 202079eeca
2 changed files with 34 additions and 18 deletions

View File

@ -4,8 +4,11 @@
package net.sourceforge.pmd.lang.java.rule.security;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.sourceforge.pmd.RuleContext;
import net.sourceforge.pmd.lang.ast.Node;
import net.sourceforge.pmd.lang.java.ast.ASTAllocationExpression;
import net.sourceforge.pmd.lang.java.ast.ASTArgumentList;
@ -33,11 +36,17 @@ import net.sourceforge.pmd.lang.symboltable.NameOccurrence;
public class HardCodedCryptoKeyRule extends AbstractJavaRule {
private static final Class<?> SECRET_KEY_SPEC = javax.crypto.spec.SecretKeySpec.class;
private final Set<VariableNameDeclaration> checkedVars = new HashSet<>();
public HardCodedCryptoKeyRule() {
addRuleChainVisit(ASTAllocationExpression.class);
}
@Override
public void start(RuleContext ctx) {
checkedVars.clear();
}
@Override
public Object visit(ASTAllocationExpression node, Object data) {
if (TypeTestUtil.isA(SECRET_KEY_SPEC, node.getFirstChildOfType(ASTClassOrInterfaceType.class))) {
@ -72,21 +81,22 @@ public class HardCodedCryptoKeyRule extends AbstractJavaRule {
// named variable
ASTName namedVar = firstArgumentExpression.getFirstDescendantOfType(ASTName.class);
if (namedVar != null) {
// find where it's declared, if possible
if (namedVar != null && namedVar.getNameDeclaration() instanceof VariableNameDeclaration) {
VariableNameDeclaration varDecl = (VariableNameDeclaration) namedVar.getNameDeclaration();
ASTVariableInitializer initializer = varDecl.getAccessNodeParent().getFirstDescendantOfType(ASTVariableInitializer.class);
if (initializer != null) {
validateProperKeyArgument(data, initializer.getFirstDescendantOfType(ASTPrimaryPrefix.class));
}
List<NameOccurrence> usages = varDecl.getNode().getScope().getDeclarations().get(varDecl);
for (NameOccurrence occurrence : usages) {
ASTStatementExpression parentExpr = occurrence.getLocation().getFirstParentOfType(ASTStatementExpression.class);
if (isAssignment(parentExpr)) {
validateProperKeyArgument(data, parentExpr.getChild(2).getFirstDescendantOfType(ASTPrimaryPrefix.class));
}
// find where it's declared, if possible
if (namedVar != null && namedVar.getNameDeclaration() instanceof VariableNameDeclaration
&& !checkedVars.contains(namedVar.getNameDeclaration())) {
VariableNameDeclaration varDecl = (VariableNameDeclaration) namedVar.getNameDeclaration();
checkedVars.add(varDecl);
ASTVariableInitializer initializer = varDecl.getAccessNodeParent().getFirstDescendantOfType(ASTVariableInitializer.class);
if (initializer != null) {
validateProperKeyArgument(data, initializer.getFirstDescendantOfType(ASTPrimaryPrefix.class));
}
List<NameOccurrence> usages = varDecl.getNode().getScope().getDeclarations().get(varDecl);
for (NameOccurrence occurrence : usages) {
ASTStatementExpression parentExpr = occurrence.getLocation().getFirstParentOfType(ASTStatementExpression.class);
if (isAssignment(occurrence.getLocation(), parentExpr)) {
validateProperKeyArgument(data, parentExpr.getChild(2).getFirstDescendantOfType(ASTPrimaryPrefix.class));
}
}
}
@ -104,9 +114,9 @@ public class HardCodedCryptoKeyRule extends AbstractJavaRule {
}
}
private boolean isAssignment(ASTStatementExpression statement) {
return statement != null
&& statement.getNumChildren() >= 3
private boolean isAssignment(Node node, ASTStatementExpression statement) {
return statement != null && statement.getNumChildren() >= 3
&& node == statement.getChild(0).getFirstDescendantOfType(ASTName.class)
&& statement.getChild(1) instanceof ASTAssignmentOperator;
}
}

View File

@ -110,6 +110,12 @@ public class Foo {
var0 = "hard coded key here";
SecretKeySpec keySpec = new SecretKeySpec(var0.getBytes(), "AES");
}
void encrypt2(String prefix, String key) {
final String var0 = prefix;
var0 = var0 + key;
SecretKeySpec keySpec = new SecretKeySpec(var0.getBytes(), "AES");
}
}
]]></code>
</test-code>