Skip to content

Commit eca46bd

Browse files
SONARJAVA-4691 S6804 should not fail on named value annotation argument
Prevent crashes when processing a value annotation with a named argument
1 parent 5dda9f9 commit eca46bd

4 files changed

Lines changed: 36 additions & 10 deletions

File tree

its/ruling/src/test/resources/autoscan/autoscan-diff-by-rules.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2876,7 +2876,7 @@
28762876
{
28772877
"ruleKey": "S6804",
28782878
"hasTruePositives": false,
2879-
"falseNegatives": 7,
2879+
"falseNegatives": 9,
28802880
"falsePositives": 0
28812881
},
28822882
{

java-checks-test-sources/src/main/java/checks/spring/ValueAnnotationShouldInjectPropertyOrSpELCheckSample.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,28 @@
44
import org.springframework.beans.factory.annotation.Value;
55

66
class ValueAnnotationShouldInjectPropertyOrSpELCheckSample {
7+
private static final String COMPLIANT_CONSTANT = "${catalog.name}";
8+
private static final String NON_COMPLIANT_CONSTANT = "catalog.name";
79

810
@Value("catalog.name") // Noncompliant [[sc=3;ec=25]] {{Either replace the "@Value" annotation with a standard field initialization, use "${propertyName}" to inject a property or use "#{expression}" to evaluate a SpEL expression.}}
911
String catalogA;
1012

1113
@Value("${catalog.name}") // Compliant
1214
String catalogB;
1315

16+
@Value(value = "catalog.name") // Noncompliant [[sc=3;ec=33]] {{Either replace the "@Value" annotation with a standard field initialization, use "${propertyName}" to inject a property or use "#{expression}" to evaluate a SpEL expression.}}
17+
String catalogWithNamedArgumentA;
18+
19+
@Value(value = "${catalog.name}") // Compliant
20+
String catalogWithNamedArgumentB;
21+
22+
@Value(value = NON_COMPLIANT_CONSTANT) // Noncompliant [[sc=3;ec=41]]
23+
String catalogWithNamedArgumentC;
24+
25+
@Value(value = COMPLIANT_CONSTANT) // Compliant
26+
String catalogWithNamedArgumentD;
27+
28+
1429
@Value("book.topics[0]") // Noncompliant, this will not evaluate the expression
1530
String topicA;
1631

@@ -20,6 +35,7 @@ class ValueAnnotationShouldInjectPropertyOrSpELCheckSample {
2035
@Value("Hello, world!") // Noncompliant, this use of @Value is redundant
2136
String greetingA;
2237

38+
2339
String greetingB = "Hello, world!"; // Compliant
2440

2541
@Value("") // Noncompliant

java-checks/src/main/java/org/sonar/java/checks/spring/ValueAnnotationShouldInjectPropertyOrSpELCheck.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222
import java.util.List;
2323
import java.util.stream.Collectors;
2424
import java.util.stream.Stream;
25+
import javax.annotation.CheckForNull;
2526
import org.sonar.check.Rule;
27+
import org.sonar.java.checks.helpers.ExpressionsHelper;
2628
import org.sonar.plugins.java.api.IssuableSubscriptionVisitor;
2729
import org.sonar.plugins.java.api.tree.AnnotationTree;
30+
import org.sonar.plugins.java.api.tree.AssignmentExpressionTree;
2831
import org.sonar.plugins.java.api.tree.ClassTree;
29-
import org.sonar.plugins.java.api.tree.LiteralTree;
32+
import org.sonar.plugins.java.api.tree.ExpressionTree;
3033
import org.sonar.plugins.java.api.tree.Tree;
3134
import org.sonar.plugins.java.api.tree.VariableTree;
3235

@@ -61,21 +64,29 @@ public void visitNode(Tree tree) {
6164
"or use \"#{expression}\" to evaluate a SpEL expression."));
6265
}
6366

64-
private static boolean isSimpleSpringValue(AnnotationTree ann) {
65-
if (ann.symbolType().is(SPRING_VALUE)) {
66-
LiteralTree literal = (LiteralTree) ann.arguments().get(0);
67-
String value = literal.value();
68-
return !isPropertyName(value) && !isSpEL(value);
67+
private static boolean isSimpleSpringValue(AnnotationTree annotation) {
68+
if (annotation.symbolType().is(SPRING_VALUE)) {
69+
String value = extractArgumentValue(annotation.arguments().get(0));
70+
return value != null && !(isPropertyName(value) || isSpEL(value));
6971
}
7072
return false;
7173
}
7274

75+
@CheckForNull
76+
private static String extractArgumentValue(ExpressionTree annotationArgument) {
77+
if (annotationArgument.is(Tree.Kind.ASSIGNMENT)) {
78+
ExpressionTree expression = ((AssignmentExpressionTree) annotationArgument).expression();
79+
return ExpressionsHelper.getConstantValueAsString(expression).value();
80+
}
81+
return ExpressionsHelper.getConstantValueAsString(annotationArgument).value();
82+
}
83+
7384
private static boolean isPropertyName(String value) {
74-
return value.startsWith("\"${") && value.endsWith("}\"");
85+
return value.startsWith("${") && value.endsWith("}");
7586
}
7687

7788
private static boolean isSpEL(String value) {
78-
return value.startsWith("\"#{") && value.endsWith("}\"");
89+
return value.startsWith("#{") && value.endsWith("}");
7990
}
8091

8192
}

java-checks/src/test/java/org/sonar/java/checks/spring/ValueAnnotationShouldInjectPropertyOrSpELCheckTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,4 @@ void test() {
3333
.withCheck(new ValueAnnotationShouldInjectPropertyOrSpELCheck())
3434
.verifyIssues();
3535
}
36-
3736
}

0 commit comments

Comments
 (0)