@@ -45,6 +45,11 @@ public class SpringRequestMappingMethodCheck extends IssuableSubscriptionVisitor
4545 private static final String REQUEST_METHOD = "method" ;
4646 public static final String MESSAGE = "Make sure allowing safe and unsafe HTTP methods is safe here." ;
4747
48+ private boolean classHasSafeMethods ;
49+ private boolean classHasUnsafeMethods ;
50+ private boolean methodHasSafeMethods ;
51+ private boolean methodHasUnsafeMethods ;
52+
4853 @ Override
4954 public List <Tree .Kind > nodesToVisit () {
5055 return Collections .singletonList (Tree .Kind .CLASS );
@@ -53,11 +58,11 @@ public List<Tree.Kind> nodesToVisit() {
5358 @ Override
5459 public void visitNode (Tree tree ) {
5560 ClassTree classTree = (ClassTree ) tree ;
61+ resetFlags ();
5662 findRequestMappingAnnotation (classTree .modifiers ())
5763 .flatMap (SpringRequestMappingMethodCheck ::findRequestMethods )
58- .filter (SpringRequestMappingMethodCheck :: mixSafeAndUnsafeMethods )
64+ .filter (this :: mixesSafeAndUnsafeMethodsOnClass )
5965 .ifPresent (methods -> reportIssue (methods , MESSAGE ));
60-
6166 classTree .members ().stream ()
6267 .filter (member -> member .is (Tree .Kind .METHOD ))
6368 .forEach (member -> checkMethod ((MethodTree ) member , classTree .symbol ()));
@@ -69,9 +74,15 @@ private void checkMethod(MethodTree method, Symbol.TypeSymbol classSymbol) {
6974 .flatMap (SpringRequestMappingMethodCheck ::findRequestMethods );
7075
7176 if (requestMethods .isPresent ()) {
72- requestMethods
73- .filter (SpringRequestMappingMethodCheck ::mixSafeAndUnsafeMethods )
74- .ifPresent (methods -> reportIssue (methods , MESSAGE ));
77+ Optional <ExpressionTree > expressionTree = requestMethods
78+ .filter (this ::mixesSafeAndUnsafeMethodsOnMethod );
79+ if (expressionTree .isPresent ()) {
80+ reportIssue (expressionTree .get (), MESSAGE );
81+ } else {
82+ if ((classHasSafeMethods && methodHasUnsafeMethods ) || (classHasUnsafeMethods && methodHasSafeMethods )) {
83+ reportIssue (requestMethods .get (), MESSAGE );
84+ }
85+ }
7586 } else if (requestMappingAnnotation .isPresent () && !inheritRequestMethod (classSymbol )) {
7687 reportIssue (requestMappingAnnotation .get ().annotationType (), MESSAGE );
7788 }
@@ -109,12 +120,29 @@ private static boolean inheritRequestMethod(Symbol.TypeSymbol symbol) {
109120 return false ;
110121 }
111122
112- private static boolean mixSafeAndUnsafeMethods (ExpressionTree requestMethodsAssignment ) {
123+ private boolean mixesSafeAndUnsafeMethodsOnClass (ExpressionTree requestMethodsAssignment ) {
124+ HttpMethodVisitor visitor = new HttpMethodVisitor ();
125+ requestMethodsAssignment .accept (visitor );
126+ classHasSafeMethods = visitor .hasSafeMethods ;
127+ classHasUnsafeMethods = visitor .hasUnsafeMethods ;
128+ return visitor .hasSafeMethods && visitor .hasUnsafeMethods ;
129+ }
130+
131+ private boolean mixesSafeAndUnsafeMethodsOnMethod (ExpressionTree requestMethodsAssignment ) {
113132 HttpMethodVisitor visitor = new HttpMethodVisitor ();
114133 requestMethodsAssignment .accept (visitor );
134+ methodHasSafeMethods = visitor .hasSafeMethods ;
135+ methodHasUnsafeMethods = visitor .hasUnsafeMethods ;
115136 return visitor .hasSafeMethods && visitor .hasUnsafeMethods ;
116137 }
117138
139+ private void resetFlags () {
140+ classHasSafeMethods = false ;
141+ classHasUnsafeMethods = false ;
142+ methodHasSafeMethods = false ;
143+ methodHasUnsafeMethods = false ;
144+ }
145+
118146 private static class HttpMethodVisitor extends BaseTreeVisitor {
119147 private static final Set <String > SAFE_METHODS = new HashSet <>(Arrays .asList ("GET" , "HEAD" , "OPTIONS" , "TRACE" ));
120148 private static final Set <String > UNSAFE_METHODS = new HashSet <>(Arrays .asList ("DELETE" , "PATCH" , "POST" , "PUT" ));
0 commit comments