[java] InvalidLogMessageFormat detection failing when String.format used
- Fixes #3146
This commit is contained in:
1 parent
5650b720b3
commit
954bcffb94
3 files changed
+63
-1
No files matched your search
@@ -16,6 +16,9 @@ This is a {{ site.pmd.release_type }} release.
|
||||
|
||||
### Fixed Issues
|
||||
|
||||
* java-errorprone
|
||||
* [#3146](https://github.com/pmd/pmd/issues/3146): \[java] InvalidLogMessageFormat detection failing when String.format used
|
||||
|
||||
### API Changes
|
||||
|
||||
### External Contributions
|
||||
|
||||
+40
-1
@@ -15,6 +15,7 @@ import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.sourceforge.pmd.RuleContext;
|
||||
import net.sourceforge.pmd.lang.ast.Node;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTArgumentList;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTArrayInitializer;
|
||||
@@ -23,6 +24,7 @@ import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTEnumBody;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTInitializer;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
|
||||
@@ -63,10 +65,31 @@ public class InvalidLogMessageFormatRule extends AbstractJavaRule {
|
||||
LOGGERS = loggersMap;
|
||||
}
|
||||
|
||||
private boolean formatIsStringFormat;
|
||||
|
||||
public InvalidLogMessageFormatRule() {
|
||||
addRuleChainVisit(ASTImportDeclaration.class);
|
||||
addRuleChainVisit(ASTName.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(RuleContext ctx) {
|
||||
formatIsStringFormat = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTImportDeclaration node, Object data) {
|
||||
if (node.isStatic()) {
|
||||
if ("java.lang.String.format".equals(node.getImportedName())) {
|
||||
formatIsStringFormat = true;
|
||||
}
|
||||
if ("java.lang.String".equals(node.getImportedName()) && node.isImportOnDemand()) {
|
||||
formatIsStringFormat = true;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(final ASTName node, final Object data) {
|
||||
final NameDeclaration nameDeclaration = node.getNameDeclaration();
|
||||
@@ -111,8 +134,13 @@ public class InvalidLogMessageFormatRule extends AbstractJavaRule {
|
||||
|
||||
// remove the message parameter
|
||||
final ASTExpression messageParam = argumentList.remove(0);
|
||||
final int expectedArguments = expectedArguments(messageParam);
|
||||
|
||||
// ignore if String.format
|
||||
if (isStringFormatCall(messageParam)) {
|
||||
return data;
|
||||
}
|
||||
|
||||
final int expectedArguments = expectedArguments(messageParam);
|
||||
if (expectedArguments == -1) {
|
||||
// ignore if we couldn't analyze the message parameter
|
||||
return data;
|
||||
@@ -213,6 +241,17 @@ public class InvalidLogMessageFormatRule extends AbstractJavaRule {
|
||||
+ params.size();
|
||||
}
|
||||
|
||||
private boolean isStringFormatCall(ASTExpression node) {
|
||||
if (node.getNumChildren() > 0 && node.getChild(0) instanceof ASTPrimaryExpression
|
||||
&& node.getChild(0).getNumChildren() > 0 && node.getChild(0).getChild(0) instanceof ASTPrimaryPrefix
|
||||
&& node.getChild(0).getChild(0).getNumChildren() > 0 && node.getChild(0).getChild(0).getChild(0) instanceof ASTName) {
|
||||
String name = node.getChild(0).getChild(0).getChild(0).getImage();
|
||||
|
||||
return "String.format".equals(name) || formatIsStringFormat && "format".equals(name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private int expectedArguments(final ASTExpression node) {
|
||||
int count = -1;
|
||||
// look if the logger has a literal message
|
||||
|
||||
+20
@@ -925,6 +925,26 @@ class TestInvalidLogMessageFormat {
|
||||
}
|
||||
|
||||
private String getBriefDescription() { return ""; }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>[java] InvalidLogMessageFormat detection failing when String.format used #3146</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import static java.lang.String.format;
|
||||
|
||||
class TestInvalidLogMessageFormat {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(TestInvalidLogMessageFormat.class);
|
||||
public void testPMD() {
|
||||
LOGGER.info(String.format("Skipping file %s because no parser could be found", getName()));
|
||||
LOGGER.info(format("Skipping file %s", getName()));
|
||||
}
|
||||
|
||||
private String getName() { return "the-name"; }
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
Reference in new issue
Block a user