@@ -54,7 +54,7 @@ abstract private class SimpleFluentLambdaMethod extends FluentLambdaMethod {
5454private class RatpackPromiseMapMethod extends SimpleFluentLambdaMethod {
5555 RatpackPromiseMapMethod ( ) {
5656 getDeclaringType ( ) instanceof RatpackPromise and
57- hasName ( [ "map" , "flatMap" , "blockingMap" , "apply" ] )
57+ hasName ( [ "map" , "blockingMap" ] ) // "flatMap" & "apply" cause false positives. Wait for fluent lambda support.
5858 }
5959
6060 override predicate consumesTaint ( int lambdaArg ) { lambdaArg = 0 }
@@ -63,15 +63,14 @@ private class RatpackPromiseMapMethod extends SimpleFluentLambdaMethod {
6363}
6464
6565/**
66- * Represents the `mapIf` and `flatMapIf` method.
66+ * Represents the `mapIf` method.
6767 *
6868 * `<O> Promise<O> mapIf(Predicate<T> predicate, Function<T, O> onTrue, Function<T, O> onFalse)`
69- * `<O> Promise<O> flatMapIf(Predicate<T> predicate, Function<T, Promise<O>> onTrue, Function<T, Promise<O>> onFalse)`
7069 */
7170private class RatpackPromiseMapIfMethod extends FluentLambdaMethod {
7271 RatpackPromiseMapIfMethod ( ) {
7372 getDeclaringType ( ) instanceof RatpackPromise and
74- hasName ( [ "mapIf" , "flatMapIf" ] ) and
73+ hasName ( [ "mapIf" ] ) and // "flatMapIf" causes false positives. Wait for fluent lambda support.
7574 getNumberOfParameters ( ) = 3
7675 }
7776
@@ -85,7 +84,7 @@ private class RatpackPromiseMapIfMethod extends FluentLambdaMethod {
8584private class RatpackPromiseMapErrorMethod extends FluentLambdaMethod {
8685 RatpackPromiseMapErrorMethod ( ) {
8786 getDeclaringType ( ) instanceof RatpackPromise and
88- hasName ( [ "mapError" , "flatMapError" ] )
87+ hasName ( [ "mapError" ] ) // "flatMapError" causes false positives. Wait for fluent lambda support.
8988 }
9089
9190 override predicate consumesTaint ( int methodArg , int lambdaArg ) { none ( ) }
@@ -121,41 +120,41 @@ private class RatpackPromiseFluentMethod extends FluentMethod, FluentLambdaMetho
121120 hasName ( [ "route" ] ) and methodArg = [ 0 , 1 ] and lambdaArg = 0
122121 }
123122
124- override predicate doesReturnTaint ( int arg ) { hasName ( [ "flatMapIf" ] ) and arg = 1 }
123+ override predicate doesReturnTaint ( int arg ) { none ( ) } // "flatMapIf" causes false positives. Wait for fluent lambda support.
124+ }
125+
126+ /**
127+ * Holds if the method access qualifier `node1` has dataflow to the functional expression parameter `node2`.
128+ */
129+ private predicate stepIntoLambda ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
130+ exists ( MethodAccess ma , FluentLambdaMethod flm , int methodArg , int lambdaArg |
131+ flm .consumesTaint ( methodArg , lambdaArg )
132+ |
133+ ma .getMethod ( ) = flm and
134+ node1 .asExpr ( ) = ma .getQualifier ( ) and
135+ ma .getArgument ( methodArg ) .( FunctionalExpr ) .asMethod ( ) .getParameter ( lambdaArg ) =
136+ node2 .asParameter ( )
137+ )
138+ }
139+
140+ /**
141+ * Holds if the return statement result of the functional expression `node1` has dataflow to the
142+ * method access result `node2`.
143+ */
144+ private predicate stepOutOfLambda ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
145+ exists ( FluentLambdaMethod flm , MethodAccess ma , FunctionalExpr fe , int arg |
146+ flm .doesReturnTaint ( arg )
147+ |
148+ fe .asMethod ( ) .getBody ( ) .getAStmt ( ) .( ReturnStmt ) .getResult ( ) = node1 .asExpr ( ) and
149+ ma .getMethod ( ) = flm and
150+ node2 .asExpr ( ) = ma and
151+ ma .getArgument ( arg ) = fe
152+ )
125153}
126154
127155private class RatpackPromiseTaintPreservingStep extends AdditionalTaintStep {
128156 override predicate step ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
129157 stepIntoLambda ( node1 , node2 ) or
130158 stepOutOfLambda ( node1 , node2 )
131159 }
132-
133- /**
134- * Holds if the method access qualifier `node1` has dataflow to the functional expression parameter `node2`.
135- */
136- predicate stepIntoLambda ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
137- exists ( MethodAccess ma , FluentLambdaMethod flm , int methodArg , int lambdaArg |
138- flm .consumesTaint ( methodArg , lambdaArg )
139- |
140- ma .getMethod ( ) = flm and
141- node1 .asExpr ( ) = ma .getQualifier ( ) and
142- ma .getArgument ( methodArg ) .( FunctionalExpr ) .asMethod ( ) .getParameter ( lambdaArg ) =
143- node2 .asParameter ( )
144- )
145- }
146-
147- /**
148- * Holds if the return statement result of the functional expression `node1` has dataflow to the
149- * method access result `node2`.
150- */
151- predicate stepOutOfLambda ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
152- exists ( FluentLambdaMethod flm , MethodAccess ma , FunctionalExpr fe , int arg |
153- flm .doesReturnTaint ( arg )
154- |
155- fe .asMethod ( ) .getBody ( ) .getAStmt ( ) .( ReturnStmt ) .getResult ( ) = node1 .asExpr ( ) and
156- ma .getMethod ( ) = flm and
157- node2 .asExpr ( ) = ma and
158- ma .getArgument ( arg ) = fe
159- )
160- }
161160}
0 commit comments