File tree Expand file tree Collapse file tree
unified/ql/lib/codeql/unified/internal/dataflow Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -20,7 +20,8 @@ private newtype TDataFlowCall =
2020 isInAssignmentContext ( expr , _)
2121 or
2222 // Write back a value that was mutated in-place, such as `x.p` in `x.p.f = y`
23- isMutatedByCallOrAssign ( expr , _)
23+ isMutatedByCallOrAssign ( expr , _) and
24+ mayWriteBackViaSetterCall ( expr )
2425 ) and
2526 (
2627 N:: getStaticBindingTargetFromRef ( expr ) = any ( SetterDeclaration g ) .getNameNode ( )
Original file line number Diff line number Diff line change @@ -26,6 +26,15 @@ class DataFlowPlugin extends Unit {
2626 * This affects the steps generated by the language-agnostic code as well as steps from the plugin itself.
2727 */
2828 predicate bypassContentSet ( ContentSet contents ) { none ( ) }
29+
30+ /**
31+ * Holds if mutating the value of `expr` in-place, such as `expr.f = y` or `expr.mutate()`,
32+ * may cause the mutated value to be written back via a setter call.
33+ *
34+ * `expr` is an expression in getter position, such as a member access.
35+ */
36+ bindingset [ expr]
37+ predicate mayWriteBackViaSetterCall ( Expr expr ) { none ( ) }
2938}
3039
3140/**
@@ -40,3 +49,12 @@ predicate bypassContentSet(ContentSet contents) { any(DataFlowPlugin p).bypassCo
4049predicate exprStep ( Expr expr1 , Expr expr2 , boolean mustFlow ) {
4150 any ( DataFlowPlugin p ) .exprStep ( expr1 , expr2 , mustFlow )
4251}
52+
53+ /**
54+ * Holds if mutating the value of `expr` in-place, such as `expr.f = y` or `expr.mutate()`,
55+ * may cause the mutated value to be written back via a setter call.
56+ */
57+ bindingset [ expr]
58+ predicate mayWriteBackViaSetterCall ( Expr expr ) {
59+ any ( DataFlowPlugin p ) .mayWriteBackViaSetterCall ( expr )
60+ }
Original file line number Diff line number Diff line change @@ -11,6 +11,10 @@ private class SwiftDataFlowPlugin extends DataFlowPlugin {
1111 contents .asSingleton ( ) .asNamedMember ( ) = "some.0"
1212 }
1313
14+ // Swift writes back mutated values of computed properties via their setter
15+ bindingset [ expr]
16+ override predicate mayWriteBackViaSetterCall ( Expr expr ) { any ( ) }
17+
1418 override predicate exprStep ( Expr expr1 , Expr expr2 , boolean mustFlow ) {
1519 mustFlow = true and
1620 exists ( UnaryExpr expr |
You can’t perform that action at this time.
0 commit comments