Skip to content

Commit 0a95b32

Browse files
SONARJAVA-4901 S6856 does not raise when parent class defines model attribute (#5117)
1 parent 7024aab commit 0a95b32

4 files changed

Lines changed: 51 additions & 2 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"ruleKey": "S6856",
33
"hasTruePositives": false,
4-
"falseNegatives": 45,
4+
"falseNegatives": 46,
55
"falsePositives": 0
66
}

java-checks-test-sources/default/src/main/java/checks/spring/MissingPathVariableAnnotationCheckSample.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,26 @@
1313

1414
public class MissingPathVariableAnnotationCheckSample {
1515

16+
class ParentController {
17+
@ModelAttribute("viewCfg")
18+
public String getView(@PathVariable("view") final String view){
19+
return "";
20+
}
21+
}
22+
class ChildController extends ParentController {
23+
@GetMapping("/model/{view}") //Compliant, parent class defines 'view' path var in the model attribute
24+
public String list(@ModelAttribute("viewCfg") final String viewConfig){
25+
return "";
26+
}
27+
}
28+
class MissingParentChildController extends MissingPathVariableParentInDifferentSample {
29+
@GetMapping("/model/{view}") // Noncompliant
30+
// FP: parent class in different file, cannot collect the model attribute
31+
public String list(@ModelAttribute("parentView") final String viewConfig){
32+
return "";
33+
}
34+
}
35+
1636
@GetMapping("/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}") // Noncompliant
1737
public void handleWithoutExt(@PathVariable String name, @PathVariable String version) {}
1838

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package checks.spring;
2+
3+
import org.springframework.web.bind.annotation.ModelAttribute;
4+
import org.springframework.web.bind.annotation.PathVariable;
5+
6+
public class MissingPathVariableParentInDifferentSample {
7+
@ModelAttribute("parentView")
8+
public String getView(@PathVariable("view") final String view){
9+
return "";
10+
}
11+
}

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ public void visitNode(Tree tree) {
7777
}
7878

7979
Set<String> modelAttributeMethodParameter = extractModelAttributeMethodParameter(methods);
80+
modelAttributeMethodParameter.addAll(addInheritedModelAttributeMethodParameter(modelAttributeMethodParameter, clazzTree));
8081

8182
checkParametersAndPathTemplate(methods, modelAttributeMethodParameter, requestMappingTemplateVariables);
8283
}
8384

8485
private static Set<String> extractModelAttributeMethodParameter(List<MethodTree> methods){
85-
Set<java.lang.String> modelAttributeMethodParameter = new HashSet<>();
86+
Set<String> modelAttributeMethodParameter = new HashSet<>();
8687
for (var method : methods) {
8788
if (!method.symbol().metadata().isAnnotatedWith(MODEL_ATTRIBUTE_ANNOTATION)) {
8889
continue;
@@ -98,6 +99,23 @@ private static Set<String> extractModelAttributeMethodParameter(List<MethodTree>
9899
return modelAttributeMethodParameter;
99100
}
100101

102+
private static Set<String> addInheritedModelAttributeMethodParameter(Set<String> modelAttributeMethodParameters, ClassTree clazz){
103+
if(clazz.superClass() == null){
104+
return modelAttributeMethodParameters;
105+
}
106+
Type superClass = clazz.superClass().symbolType();
107+
ClassTree declaration = superClass.symbol().declaration();
108+
if(declaration != null){
109+
List<MethodTree> methods = declaration.members().stream()
110+
.filter(member -> member.is(Tree.Kind.METHOD))
111+
.map(MethodTree.class::cast)
112+
.toList();
113+
modelAttributeMethodParameters.addAll(extractModelAttributeMethodParameter(methods));
114+
modelAttributeMethodParameters.addAll(addInheritedModelAttributeMethodParameter(modelAttributeMethodParameters, declaration));
115+
}
116+
return modelAttributeMethodParameters;
117+
}
118+
101119
private void checkParametersAndPathTemplate(List<MethodTree> methods, Set<String> modelAttributeMethodParameter, Set<String> requestMappingTemplateVariables) {
102120
for (var method : methods) {
103121
if (!method.symbol().metadata().isAnnotatedWith(MODEL_ATTRIBUTE_ANNOTATION)) {

0 commit comments

Comments
 (0)