diff --git a/csharp/ql/test/library-tests/dataflow/reverse-flow/ReverseFlow.expected b/csharp/ql/test/library-tests/dataflow/reverse-flow/ReverseFlow.expected index 8dc3812f88a4..8196944216ee 100644 --- a/csharp/ql/test/library-tests/dataflow/reverse-flow/ReverseFlow.expected +++ b/csharp/ql/test/library-tests/dataflow/reverse-flow/ReverseFlow.expected @@ -44,12 +44,10 @@ edges | ReverseFlow.cs:39:9:39:12 | [post] this access : A [field Field] : String | ReverseFlow.cs:37:17:37:18 | this [Reverse] : A [field Field] : String | provenance | | | ReverseFlow.cs:39:22:39:38 | call to method Source : String | ReverseFlow.cs:39:9:39:12 | [post] this access : A [field Field] : String | provenance | | | ReverseFlow.cs:39:22:39:38 | call to method Source : String | ReverseFlow.cs:39:9:39:12 | [post] this access : A [field Field] : String | provenance | | -| ReverseFlow.cs:66:9:66:26 | [post] call to method GetNestedNested : A [field Field] : String | ReverseFlow.cs:66:9:66:26 | call to method GetNestedNested [Reverse] : A [field Field] : String | provenance | | -| ReverseFlow.cs:66:9:66:26 | [post] call to method GetNestedNested : A [field Field] : String | ReverseFlow.cs:66:9:66:26 | call to method GetNestedNested [Reverse] : A [field Field] : String | provenance | | -| ReverseFlow.cs:66:9:66:26 | call to method GetNestedNested [Reverse] : A [field Field] : String | ReverseFlow.cs:66:25:66:25 | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | provenance | | -| ReverseFlow.cs:66:9:66:26 | call to method GetNestedNested [Reverse] : A [field Field] : String | ReverseFlow.cs:66:25:66:25 | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | provenance | | -| ReverseFlow.cs:66:9:66:26 | call to method GetNestedNested [Reverse] : A [field Field] : String | ReverseFlow.cs:84:38:84:52 | access to field Nested [Reverse] : A [field Field] : String | provenance | | -| ReverseFlow.cs:66:9:66:26 | call to method GetNestedNested [Reverse] : A [field Field] : String | ReverseFlow.cs:84:38:84:52 | access to field Nested [Reverse] : A [field Field] : String | provenance | | +| ReverseFlow.cs:66:9:66:26 | [post] call to method GetNestedNested : A [field Field] : String | ReverseFlow.cs:66:25:66:25 | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | provenance | | +| ReverseFlow.cs:66:9:66:26 | [post] call to method GetNestedNested : A [field Field] : String | ReverseFlow.cs:66:25:66:25 | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | provenance | | +| ReverseFlow.cs:66:9:66:26 | [post] call to method GetNestedNested : A [field Field] : String | ReverseFlow.cs:84:38:84:52 | access to field Nested [Reverse] : A [field Field] : String | provenance | | +| ReverseFlow.cs:66:9:66:26 | [post] call to method GetNestedNested : A [field Field] : String | ReverseFlow.cs:84:38:84:52 | access to field Nested [Reverse] : A [field Field] : String | provenance | | | ReverseFlow.cs:66:25:66:25 | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | ReverseFlow.cs:67:14:67:14 | access to local variable a : A [field Nested, field Nested, field Field] : String | provenance | | | ReverseFlow.cs:66:25:66:25 | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | ReverseFlow.cs:67:14:67:14 | access to local variable a : A [field Nested, field Nested, field Field] : String | provenance | | | ReverseFlow.cs:66:36:66:52 | call to method Source : String | ReverseFlow.cs:66:9:66:26 | [post] call to method GetNestedNested : A [field Field] : String | provenance | | @@ -123,8 +121,6 @@ nodes | ReverseFlow.cs:39:22:39:38 | call to method Source : String | semmle.label | call to method Source : String | | ReverseFlow.cs:66:9:66:26 | [post] call to method GetNestedNested : A [field Field] : String | semmle.label | [post] call to method GetNestedNested : A [field Field] : String | | ReverseFlow.cs:66:9:66:26 | [post] call to method GetNestedNested : A [field Field] : String | semmle.label | [post] call to method GetNestedNested : A [field Field] : String | -| ReverseFlow.cs:66:9:66:26 | call to method GetNestedNested [Reverse] : A [field Field] : String | semmle.label | call to method GetNestedNested [Reverse] : A [field Field] : String | -| ReverseFlow.cs:66:9:66:26 | call to method GetNestedNested [Reverse] : A [field Field] : String | semmle.label | call to method GetNestedNested [Reverse] : A [field Field] : String | | ReverseFlow.cs:66:25:66:25 | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | semmle.label | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | | ReverseFlow.cs:66:25:66:25 | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | semmle.label | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | | ReverseFlow.cs:66:36:66:52 | call to method Source : String | semmle.label | call to method Source : String | @@ -154,8 +150,8 @@ nodes | ReverseFlow.cs:84:38:84:52 | access to field Nested [Reverse] : A [field Field] : String | semmle.label | access to field Nested [Reverse] : A [field Field] : String | | ReverseFlow.cs:84:38:84:52 | access to field Nested [Reverse] : A [field Field] : String | semmle.label | access to field Nested [Reverse] : A [field Field] : String | subpaths -| ReverseFlow.cs:66:9:66:26 | call to method GetNestedNested [Reverse] : A [field Field] : String | ReverseFlow.cs:84:38:84:52 | access to field Nested [Reverse] : A [field Field] : String | ReverseFlow.cs:84:32:84:32 | a [Reverse] : A [field Nested, field Nested, field Field] : String | ReverseFlow.cs:66:25:66:25 | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | -| ReverseFlow.cs:66:9:66:26 | call to method GetNestedNested [Reverse] : A [field Field] : String | ReverseFlow.cs:84:38:84:52 | access to field Nested [Reverse] : A [field Field] : String | ReverseFlow.cs:84:32:84:32 | a [Reverse] : A [field Nested, field Nested, field Field] : String | ReverseFlow.cs:66:25:66:25 | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | +| ReverseFlow.cs:66:9:66:26 | [post] call to method GetNestedNested : A [field Field] : String | ReverseFlow.cs:84:38:84:52 | access to field Nested [Reverse] : A [field Field] : String | ReverseFlow.cs:84:32:84:32 | a [Reverse] : A [field Nested, field Nested, field Field] : String | ReverseFlow.cs:66:25:66:25 | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | +| ReverseFlow.cs:66:9:66:26 | [post] call to method GetNestedNested : A [field Field] : String | ReverseFlow.cs:84:38:84:52 | access to field Nested [Reverse] : A [field Field] : String | ReverseFlow.cs:84:32:84:32 | a [Reverse] : A [field Nested, field Nested, field Field] : String | ReverseFlow.cs:66:25:66:25 | [post] access to local variable a : A [field Nested, field Nested, field Field] : String | testFailures #select | ReverseFlow.cs:11:14:11:27 | access to field Field | ReverseFlow.cs:22:19:22:35 | call to method Source : String | ReverseFlow.cs:11:14:11:27 | access to field Field | $@ | ReverseFlow.cs:22:19:22:35 | call to method Source : String | call to method Source : String | diff --git a/java/ql/test/library-tests/dataflow/fluent-methods/flow.expected b/java/ql/test/library-tests/dataflow/fluent-methods/flow.expected index c2428a8bb44a..afc5cf8106ba 100644 --- a/java/ql/test/library-tests/dataflow/fluent-methods/flow.expected +++ b/java/ql/test/library-tests/dataflow/fluent-methods/flow.expected @@ -1,11 +1,6 @@ models edges | Test.java:6:12:6:15 | this [Reverse] : Test [field] : String | Test.java:5:15:5:24 | parameter this [Reverse] : Test [field] : String | provenance | | -| Test.java:20:12:20:15 | this [Reverse] : Test [field] : String | Test.java:19:15:19:34 | parameter this [Reverse] : Test [field] : String | provenance | | -| Test.java:20:12:20:15 | this [Reverse] : Test [field] : String | Test.java:19:15:19:34 | parameter this [Reverse] : Test [field] : String | provenance | | -| Test.java:20:12:20:28 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:6:12:6:15 | this [Reverse] : Test [field] : String | provenance | | -| Test.java:20:12:20:28 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:20:12:20:15 | this [Reverse] : Test [field] : String | provenance | | -| Test.java:20:12:20:28 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:20:12:20:15 | this [Reverse] : Test [field] : String | provenance | | | Test.java:23:25:23:32 | x : String | Test.java:24:18:24:18 | x : String | provenance | | | Test.java:24:5:24:8 | this [post update] : Test [field] : String | Test.java:23:15:23:23 | parameter this [Reverse] : Test [field] : String | provenance | | | Test.java:24:18:24:18 | x : String | Test.java:24:5:24:8 | this [post update] : Test [field] : String | provenance | | @@ -13,55 +8,24 @@ edges | Test.java:32:17:32:19 | parameter this : Test [field] : String | Test.java:33:12:33:16 | this <.field> : Test [field] : String | provenance | | | Test.java:33:12:33:16 | this <.field> : Test [field] : String | Test.java:33:12:33:16 | field : String | provenance | | | Test.java:44:5:44:5 | t [post update] : Test [field] : String | Test.java:45:10:45:10 | t : Test [field] : String | provenance | | -| Test.java:44:5:44:18 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:6:12:6:15 | this [Reverse] : Test [field] : String | provenance | | -| Test.java:44:5:44:18 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:44:5:44:5 | t [post update] : Test [field] : String | provenance | | -| Test.java:44:5:44:18 | fluentNoop(...) [post update] : Test [field] : String | Test.java:44:5:44:18 | fluentNoop(...) [Reverse] : Test [field] : String | provenance | | +| Test.java:44:5:44:18 | fluentNoop(...) [post update] : Test [field] : String | Test.java:6:12:6:15 | this [Reverse] : Test [field] : String | provenance | | +| Test.java:44:5:44:18 | fluentNoop(...) [post update] : Test [field] : String | Test.java:44:5:44:5 | t [post update] : Test [field] : String | provenance | | | Test.java:44:30:44:37 | source(...) : String | Test.java:23:25:23:32 | x : String | provenance | | | Test.java:44:30:44:37 | source(...) : String | Test.java:44:5:44:18 | fluentNoop(...) [post update] : Test [field] : String | provenance | | | Test.java:45:10:45:10 | t : Test [field] : String | Test.java:32:17:32:19 | parameter this : Test [field] : String | provenance | | | Test.java:45:10:45:10 | t : Test [field] : String | Test.java:45:10:45:16 | get(...) | provenance | | -| Test.java:50:5:50:20 | identity(...) [Reverse] : Test [field] : String | Test.java:29:12:29:12 | t [Reverse] : Test [field] : String | provenance | | -| Test.java:50:5:50:20 | identity(...) [Reverse] : Test [field] : String | Test.java:50:19:50:19 | t [post update] : Test [field] : String | provenance | | -| Test.java:50:5:50:20 | identity(...) [post update] : Test [field] : String | Test.java:50:5:50:20 | identity(...) [Reverse] : Test [field] : String | provenance | | -| Test.java:50:5:50:33 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:6:12:6:15 | this [Reverse] : Test [field] : String | provenance | | -| Test.java:50:5:50:33 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:50:5:50:20 | identity(...) [post update] : Test [field] : String | provenance | | -| Test.java:50:5:50:33 | fluentNoop(...) [post update] : Test [field] : String | Test.java:50:5:50:33 | fluentNoop(...) [Reverse] : Test [field] : String | provenance | | +| Test.java:50:5:50:20 | identity(...) [post update] : Test [field] : String | Test.java:29:12:29:12 | t [Reverse] : Test [field] : String | provenance | | +| Test.java:50:5:50:20 | identity(...) [post update] : Test [field] : String | Test.java:50:19:50:19 | t [post update] : Test [field] : String | provenance | | +| Test.java:50:5:50:33 | fluentNoop(...) [post update] : Test [field] : String | Test.java:6:12:6:15 | this [Reverse] : Test [field] : String | provenance | | +| Test.java:50:5:50:33 | fluentNoop(...) [post update] : Test [field] : String | Test.java:50:5:50:20 | identity(...) [post update] : Test [field] : String | provenance | | | Test.java:50:19:50:19 | t [post update] : Test [field] : String | Test.java:51:10:51:10 | t : Test [field] : String | provenance | | | Test.java:50:45:50:52 | source(...) : String | Test.java:23:25:23:32 | x : String | provenance | | | Test.java:50:45:50:52 | source(...) : String | Test.java:50:5:50:33 | fluentNoop(...) [post update] : Test [field] : String | provenance | | | Test.java:51:10:51:10 | t : Test [field] : String | Test.java:32:17:32:19 | parameter this : Test [field] : String | provenance | | | Test.java:51:10:51:10 | t : Test [field] : String | Test.java:51:10:51:16 | get(...) | provenance | | -| Test.java:56:5:56:5 | t [post update] : Test [field] : String | Test.java:57:10:57:10 | t : Test [field] : String | provenance | | -| Test.java:56:5:56:28 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | Test.java:20:12:20:28 | fluentNoop(...) [Reverse] : Test [field] : String | provenance | | -| Test.java:56:5:56:28 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | Test.java:56:5:56:5 | t [post update] : Test [field] : String | provenance | | -| Test.java:56:5:56:28 | indirectlyFluentNoop(...) [post update] : Test [field] : String | Test.java:56:5:56:28 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | provenance | | -| Test.java:56:40:56:47 | source(...) : String | Test.java:23:25:23:32 | x : String | provenance | | -| Test.java:56:40:56:47 | source(...) : String | Test.java:56:5:56:28 | indirectlyFluentNoop(...) [post update] : Test [field] : String | provenance | | -| Test.java:57:10:57:10 | t : Test [field] : String | Test.java:32:17:32:19 | parameter this : Test [field] : String | provenance | | -| Test.java:57:10:57:10 | t : Test [field] : String | Test.java:57:10:57:16 | get(...) | provenance | | -| Test.java:62:5:62:5 | t [post update] : Test [field] : String | Test.java:63:10:63:10 | t : Test [field] : String | provenance | | -| Test.java:62:5:62:28 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | Test.java:20:12:20:28 | fluentNoop(...) [Reverse] : Test [field] : String | provenance | | -| Test.java:62:5:62:28 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | Test.java:62:5:62:5 | t [post update] : Test [field] : String | provenance | | -| Test.java:62:5:62:51 | modelledFluentMethod(...) [post update] : Test [field] : String | Test.java:62:5:62:28 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | provenance | ValuePreservingMethod | -| Test.java:62:63:62:70 | source(...) : String | Test.java:23:25:23:32 | x : String | provenance | | -| Test.java:62:63:62:70 | source(...) : String | Test.java:62:5:62:51 | modelledFluentMethod(...) [post update] : Test [field] : String | provenance | | -| Test.java:63:10:63:10 | t : Test [field] : String | Test.java:32:17:32:19 | parameter this : Test [field] : String | provenance | | -| Test.java:63:10:63:10 | t : Test [field] : String | Test.java:63:10:63:16 | get(...) | provenance | | -| Test.java:68:5:68:28 | modelledIdentity(...) [post update] : Test [field] : String | Test.java:69:10:69:10 | t : Test [field] : String | provenance | ValuePreservingMethod | -| Test.java:68:5:68:51 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | Test.java:20:12:20:28 | fluentNoop(...) [Reverse] : Test [field] : String | provenance | | -| Test.java:68:5:68:51 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | Test.java:68:5:68:28 | modelledIdentity(...) [post update] : Test [field] : String | provenance | | -| Test.java:68:5:68:74 | modelledFluentMethod(...) [post update] : Test [field] : String | Test.java:68:5:68:51 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | provenance | ValuePreservingMethod | -| Test.java:68:86:68:93 | source(...) : String | Test.java:23:25:23:32 | x : String | provenance | | -| Test.java:68:86:68:93 | source(...) : String | Test.java:68:5:68:74 | modelledFluentMethod(...) [post update] : Test [field] : String | provenance | | -| Test.java:69:10:69:10 | t : Test [field] : String | Test.java:32:17:32:19 | parameter this : Test [field] : String | provenance | | -| Test.java:69:10:69:10 | t : Test [field] : String | Test.java:69:10:69:16 | get(...) | provenance | | nodes | Test.java:5:15:5:24 | parameter this [Reverse] : Test [field] : String | semmle.label | parameter this [Reverse] : Test [field] : String | | Test.java:6:12:6:15 | this [Reverse] : Test [field] : String | semmle.label | this [Reverse] : Test [field] : String | -| Test.java:19:15:19:34 | parameter this [Reverse] : Test [field] : String | semmle.label | parameter this [Reverse] : Test [field] : String | -| Test.java:20:12:20:15 | this [Reverse] : Test [field] : String | semmle.label | this [Reverse] : Test [field] : String | -| Test.java:20:12:20:15 | this [Reverse] : Test [field] : String | semmle.label | this [Reverse] : Test [field] : String | -| Test.java:20:12:20:28 | fluentNoop(...) [Reverse] : Test [field] : String | semmle.label | fluentNoop(...) [Reverse] : Test [field] : String | | Test.java:23:15:23:23 | parameter this [Reverse] : Test [field] : String | semmle.label | parameter this [Reverse] : Test [field] : String | | Test.java:23:25:23:32 | x : String | semmle.label | x : String | | Test.java:24:5:24:8 | this [post update] : Test [field] : String | semmle.label | this [post update] : Test [field] : String | @@ -72,54 +36,25 @@ nodes | Test.java:33:12:33:16 | field : String | semmle.label | field : String | | Test.java:33:12:33:16 | this <.field> : Test [field] : String | semmle.label | this <.field> : Test [field] : String | | Test.java:44:5:44:5 | t [post update] : Test [field] : String | semmle.label | t [post update] : Test [field] : String | -| Test.java:44:5:44:18 | fluentNoop(...) [Reverse] : Test [field] : String | semmle.label | fluentNoop(...) [Reverse] : Test [field] : String | | Test.java:44:5:44:18 | fluentNoop(...) [post update] : Test [field] : String | semmle.label | fluentNoop(...) [post update] : Test [field] : String | | Test.java:44:30:44:37 | source(...) : String | semmle.label | source(...) : String | | Test.java:45:10:45:10 | t : Test [field] : String | semmle.label | t : Test [field] : String | | Test.java:45:10:45:16 | get(...) | semmle.label | get(...) | -| Test.java:50:5:50:20 | identity(...) [Reverse] : Test [field] : String | semmle.label | identity(...) [Reverse] : Test [field] : String | | Test.java:50:5:50:20 | identity(...) [post update] : Test [field] : String | semmle.label | identity(...) [post update] : Test [field] : String | -| Test.java:50:5:50:33 | fluentNoop(...) [Reverse] : Test [field] : String | semmle.label | fluentNoop(...) [Reverse] : Test [field] : String | | Test.java:50:5:50:33 | fluentNoop(...) [post update] : Test [field] : String | semmle.label | fluentNoop(...) [post update] : Test [field] : String | | Test.java:50:19:50:19 | t [post update] : Test [field] : String | semmle.label | t [post update] : Test [field] : String | | Test.java:50:45:50:52 | source(...) : String | semmle.label | source(...) : String | | Test.java:51:10:51:10 | t : Test [field] : String | semmle.label | t : Test [field] : String | | Test.java:51:10:51:16 | get(...) | semmle.label | get(...) | -| Test.java:56:5:56:5 | t [post update] : Test [field] : String | semmle.label | t [post update] : Test [field] : String | -| Test.java:56:5:56:28 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | semmle.label | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | -| Test.java:56:5:56:28 | indirectlyFluentNoop(...) [post update] : Test [field] : String | semmle.label | indirectlyFluentNoop(...) [post update] : Test [field] : String | -| Test.java:56:40:56:47 | source(...) : String | semmle.label | source(...) : String | -| Test.java:57:10:57:10 | t : Test [field] : String | semmle.label | t : Test [field] : String | -| Test.java:57:10:57:16 | get(...) | semmle.label | get(...) | -| Test.java:62:5:62:5 | t [post update] : Test [field] : String | semmle.label | t [post update] : Test [field] : String | -| Test.java:62:5:62:28 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | semmle.label | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | -| Test.java:62:5:62:51 | modelledFluentMethod(...) [post update] : Test [field] : String | semmle.label | modelledFluentMethod(...) [post update] : Test [field] : String | -| Test.java:62:63:62:70 | source(...) : String | semmle.label | source(...) : String | -| Test.java:63:10:63:10 | t : Test [field] : String | semmle.label | t : Test [field] : String | -| Test.java:63:10:63:16 | get(...) | semmle.label | get(...) | -| Test.java:68:5:68:28 | modelledIdentity(...) [post update] : Test [field] : String | semmle.label | modelledIdentity(...) [post update] : Test [field] : String | -| Test.java:68:5:68:51 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | semmle.label | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | -| Test.java:68:5:68:74 | modelledFluentMethod(...) [post update] : Test [field] : String | semmle.label | modelledFluentMethod(...) [post update] : Test [field] : String | -| Test.java:68:86:68:93 | source(...) : String | semmle.label | source(...) : String | -| Test.java:69:10:69:10 | t : Test [field] : String | semmle.label | t : Test [field] : String | -| Test.java:69:10:69:16 | get(...) | semmle.label | get(...) | subpaths -| Test.java:20:12:20:28 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:6:12:6:15 | this [Reverse] : Test [field] : String | Test.java:5:15:5:24 | parameter this [Reverse] : Test [field] : String | Test.java:20:12:20:15 | this [Reverse] : Test [field] : String | -| Test.java:20:12:20:28 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:6:12:6:15 | this [Reverse] : Test [field] : String | Test.java:5:15:5:24 | parameter this [Reverse] : Test [field] : String | Test.java:20:12:20:15 | this [Reverse] : Test [field] : String | -| Test.java:44:5:44:18 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:6:12:6:15 | this [Reverse] : Test [field] : String | Test.java:5:15:5:24 | parameter this [Reverse] : Test [field] : String | Test.java:44:5:44:5 | t [post update] : Test [field] : String | +| Test.java:44:5:44:18 | fluentNoop(...) [post update] : Test [field] : String | Test.java:6:12:6:15 | this [Reverse] : Test [field] : String | Test.java:5:15:5:24 | parameter this [Reverse] : Test [field] : String | Test.java:44:5:44:5 | t [post update] : Test [field] : String | | Test.java:44:30:44:37 | source(...) : String | Test.java:23:25:23:32 | x : String | Test.java:23:15:23:23 | parameter this [Reverse] : Test [field] : String | Test.java:44:5:44:18 | fluentNoop(...) [post update] : Test [field] : String | | Test.java:45:10:45:10 | t : Test [field] : String | Test.java:32:17:32:19 | parameter this : Test [field] : String | Test.java:33:12:33:16 | field : String | Test.java:45:10:45:16 | get(...) | -| Test.java:50:5:50:20 | identity(...) [Reverse] : Test [field] : String | Test.java:29:12:29:12 | t [Reverse] : Test [field] : String | Test.java:28:31:28:36 | t [Reverse] : Test [field] : String | Test.java:50:19:50:19 | t [post update] : Test [field] : String | -| Test.java:50:5:50:33 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:6:12:6:15 | this [Reverse] : Test [field] : String | Test.java:5:15:5:24 | parameter this [Reverse] : Test [field] : String | Test.java:50:5:50:20 | identity(...) [post update] : Test [field] : String | +| Test.java:50:5:50:20 | identity(...) [post update] : Test [field] : String | Test.java:29:12:29:12 | t [Reverse] : Test [field] : String | Test.java:28:31:28:36 | t [Reverse] : Test [field] : String | Test.java:50:19:50:19 | t [post update] : Test [field] : String | +| Test.java:50:5:50:33 | fluentNoop(...) [post update] : Test [field] : String | Test.java:6:12:6:15 | this [Reverse] : Test [field] : String | Test.java:5:15:5:24 | parameter this [Reverse] : Test [field] : String | Test.java:50:5:50:20 | identity(...) [post update] : Test [field] : String | | Test.java:50:45:50:52 | source(...) : String | Test.java:23:25:23:32 | x : String | Test.java:23:15:23:23 | parameter this [Reverse] : Test [field] : String | Test.java:50:5:50:33 | fluentNoop(...) [post update] : Test [field] : String | | Test.java:51:10:51:10 | t : Test [field] : String | Test.java:32:17:32:19 | parameter this : Test [field] : String | Test.java:33:12:33:16 | field : String | Test.java:51:10:51:16 | get(...) | -| Test.java:56:5:56:28 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | Test.java:20:12:20:28 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:19:15:19:34 | parameter this [Reverse] : Test [field] : String | Test.java:56:5:56:5 | t [post update] : Test [field] : String | -| Test.java:56:40:56:47 | source(...) : String | Test.java:23:25:23:32 | x : String | Test.java:23:15:23:23 | parameter this [Reverse] : Test [field] : String | Test.java:56:5:56:28 | indirectlyFluentNoop(...) [post update] : Test [field] : String | -| Test.java:57:10:57:10 | t : Test [field] : String | Test.java:32:17:32:19 | parameter this : Test [field] : String | Test.java:33:12:33:16 | field : String | Test.java:57:10:57:16 | get(...) | -| Test.java:62:5:62:28 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | Test.java:20:12:20:28 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:19:15:19:34 | parameter this [Reverse] : Test [field] : String | Test.java:62:5:62:5 | t [post update] : Test [field] : String | -| Test.java:62:63:62:70 | source(...) : String | Test.java:23:25:23:32 | x : String | Test.java:23:15:23:23 | parameter this [Reverse] : Test [field] : String | Test.java:62:5:62:51 | modelledFluentMethod(...) [post update] : Test [field] : String | -| Test.java:63:10:63:10 | t : Test [field] : String | Test.java:32:17:32:19 | parameter this : Test [field] : String | Test.java:33:12:33:16 | field : String | Test.java:63:10:63:16 | get(...) | -| Test.java:68:5:68:51 | indirectlyFluentNoop(...) [Reverse] : Test [field] : String | Test.java:20:12:20:28 | fluentNoop(...) [Reverse] : Test [field] : String | Test.java:19:15:19:34 | parameter this [Reverse] : Test [field] : String | Test.java:68:5:68:28 | modelledIdentity(...) [post update] : Test [field] : String | -| Test.java:68:86:68:93 | source(...) : String | Test.java:23:25:23:32 | x : String | Test.java:23:15:23:23 | parameter this [Reverse] : Test [field] : String | Test.java:68:5:68:74 | modelledFluentMethod(...) [post update] : Test [field] : String | -| Test.java:69:10:69:10 | t : Test [field] : String | Test.java:32:17:32:19 | parameter this : Test [field] : String | Test.java:33:12:33:16 | field : String | Test.java:69:10:69:16 | get(...) | testFailures +| Test.java:57:20:57:35 | // $hasValueFlow | Missing result: hasValueFlow | +| Test.java:63:20:63:35 | // $hasValueFlow | Missing result: hasValueFlow | +| Test.java:69:20:69:35 | // $hasValueFlow | Missing result: hasValueFlow | diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll index f043f86ed2b4..99fbe1cb2375 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImpl.qll @@ -337,7 +337,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate sinkNodeWithStateReverse(NodeEx node, FlowState state) { - Config::isSinkReverse(node.asNodeReverse(_), state) and + Config::isSinkReverse(node.asNodeReverse(), state) and not fullBarrier(node) and not stateBarrier(node, state) } @@ -582,11 +582,11 @@ module MakeImpl Lang> { cc = true or // flow out of a callable - fwdFlowOut(any(NormalDataFlowCall call), node, false) and + fwdFlowOut(_, node, false) and cc = false or // flow through a callable - exists(DataFlowCallEx call | + exists(DataFlowCall call | fwdFlowOutFromArg(call, node) and fwdFlowIsEntered(call, cc) ) @@ -594,8 +594,8 @@ module MakeImpl Lang> { // inline to reduce the number of iterations pragma[inline] - private predicate fwdFlowIn(DataFlowCallEx call, NodeEx arg, Cc cc, ParamNodeEx p) { - exists(DataFlowCall underlyingCall | underlyingCall = call.projectCall() | + private predicate fwdFlowIn(DataFlowCall call, NodeEx arg, Cc cc, ParamNodeEx p) { + exists(DataFlowCall underlyingCall | underlyingCall = call | // call context cannot help reduce virtual dispatch fwdFlow(arg, cc) and viableParamArgEx(call, p, arg) and @@ -620,15 +620,15 @@ module MakeImpl Lang> { * Holds if an argument to `call` is reached in the flow covered by `fwdFlow`. */ pragma[nomagic] - private predicate fwdFlowIsEntered(DataFlowCallEx call, Cc cc) { fwdFlowIn(call, _, cc, _) } + private predicate fwdFlowIsEntered(DataFlowCall call, Cc cc) { fwdFlowIn(call, _, cc, _) } pragma[nomagic] private predicate fwdFlowInReducedViableImplInSomeCallContext( - DataFlowCallEx call, NodeEx arg, ParamNodeEx p, DataFlowCallable target + DataFlowCall call, NodeEx arg, ParamNodeEx p, DataFlowCallable target ) { fwdFlow(arg, true) and viableParamArgEx(call, p, arg) and - CachedCallContextSensitivity::reducedViableImplInCallContext(call.projectCall(), _, _) and + CachedCallContextSensitivity::reducedViableImplInCallContext(call, _, _) and target = p.getEnclosingCallable() and not fullBarrier(p) } @@ -640,9 +640,9 @@ module MakeImpl Lang> { */ pragma[nomagic] private DataFlowCallable viableImplInSomeFwdFlowCallContextExt(DataFlowCall call) { - exists(DataFlowCallEx ctx | + exists(DataFlowCall ctx | fwdFlowIsEntered(ctx, _) and - result = viableImplInCallContextExt(call, ctx.projectCall()) + result = viableImplInCallContextExt(call, ctx) ) } @@ -689,7 +689,7 @@ module MakeImpl Lang> { // inline to reduce the number of iterations pragma[inline] - private predicate fwdFlowOut(DataFlowCallEx call, NodeEx out, Cc cc) { + private predicate fwdFlowOut(DataFlowCall call, NodeEx out, Cc cc) { exists(ReturnPosition pos | fwdFlowReturnPosition(pos, cc) and viableReturnPosOutEx(call, pos, out) and @@ -698,7 +698,7 @@ module MakeImpl Lang> { } pragma[nomagic] - private predicate fwdFlowOutFromArg(DataFlowCallEx call, NodeEx out) { + private predicate fwdFlowOutFromArg(DataFlowCall call, NodeEx out) { fwdFlowOut(call, out, true) } @@ -731,7 +731,7 @@ module MakeImpl Lang> { or fwdFlow(pragma[only_bind_into](node)) and fwdFlowState(state) and - Config::isSinkReverse(node.asNodeReverse(_)) + Config::isSinkReverse(node.asNodeReverse()) or fwdFlow(node) and fwdFlowState(state) and @@ -781,7 +781,7 @@ module MakeImpl Lang> { ) or // flow into a callable - revFlowIn(any(NormalDataFlowCall call), node, false) and + revFlowIn(_, node, false) and toReturn = false or // flow out of a callable @@ -792,7 +792,7 @@ module MakeImpl Lang> { ) or // flow through a callable - exists(DataFlowCallEx call | + exists(DataFlowCall call | revFlowInToReturn(call, node) and revFlowIsReturned(call, toReturn) ) @@ -832,7 +832,7 @@ module MakeImpl Lang> { pragma[nomagic] additional predicate viableReturnPosOutNodeCandFwd1( - DataFlowCallEx call, ReturnPosition pos, NodeEx out + DataFlowCall call, ReturnPosition pos, NodeEx out ) { fwdFlowReturnPosition(pos, _) and viableReturnPosOutEx(call, pos, out) @@ -848,14 +848,14 @@ module MakeImpl Lang> { pragma[nomagic] additional predicate viableParamArgNodeCandFwd1( - DataFlowCallEx call, ParamNodeEx p, ArgNodeEx arg + DataFlowCall call, ParamNodeEx p, ArgNodeEx arg ) { fwdFlowIn(call, arg, _, p) } // inline to reduce the number of iterations pragma[inline] - private predicate revFlowIn(DataFlowCallEx call, ArgNodeEx arg, boolean toReturn) { + private predicate revFlowIn(DataFlowCall call, ArgNodeEx arg, boolean toReturn) { exists(ParamNodeEx p | revFlow(p, toReturn) and viableParamArgNodeCandFwd1(call, p, arg) @@ -863,7 +863,7 @@ module MakeImpl Lang> { } pragma[nomagic] - private predicate revFlowInToReturn(DataFlowCallEx call, ArgNodeEx arg) { + private predicate revFlowInToReturn(DataFlowCall call, ArgNodeEx arg) { revFlowIn(call, arg, true) } @@ -873,7 +873,7 @@ module MakeImpl Lang> { * reaching an argument of `call`. */ pragma[nomagic] - private predicate revFlowIsReturned(DataFlowCallEx call, boolean toReturn) { + private predicate revFlowIsReturned(DataFlowCall call, boolean toReturn) { exists(NodeEx out | revFlow(out, toReturn) and fwdFlowOutFromArg(call, out) @@ -977,7 +977,7 @@ module MakeImpl Lang> { } pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCallEx call) { + predicate callMayFlowThroughRev(DataFlowCall call) { exists(ArgNodeEx arg, boolean toReturn | revFlow(arg, toReturn) and revFlowInToReturn(call, arg) and @@ -986,7 +986,7 @@ module MakeImpl Lang> { } predicate callEdgeArgParam( - DataFlowCallEx call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp ) { exists(boolean allowsFieldFlow | flowIntoCallNodeCand1(call, arg, p, allowsFieldFlow) and @@ -1000,18 +1000,18 @@ module MakeImpl Lang> { } predicate callEdgeReturn( - DataFlowCallEx call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow ) { flowOutOfCallNodeCand1(call, ret, kind, out, allowsFieldFlow) and c = ret.getEnclosingCallable() } - predicate relevantCallEdgeIn(DataFlowCallEx call, DataFlowCallable c) { + predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { callEdgeArgParam(call, c, _, _, _) } - predicate relevantCallEdgeOut(DataFlowCallEx call, DataFlowCallable c) { + predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { callEdgeReturn(call, c, _, _, _, _) } @@ -1033,7 +1033,7 @@ module MakeImpl Lang> { states = count(FlowState state | revFlowState(state)) and tuples = count(NodeEx n, boolean b | revFlow(n, b)) and calledges = - count(DataFlowCallEx call, DataFlowCallable c | + count(DataFlowCall call, DataFlowCallable c | callEdgeArgParam(call, c, _, _, _) or callEdgeReturn(call, c, _, _, _, _) ) @@ -1054,7 +1054,7 @@ module MakeImpl Lang> { private predicate sinkModel(NodeEx node, string model) { sinkNode(node, _) and - exists(Node n | n = [node.asNodeOrImplicitRead(), node.asNodeReverse(_)] | + exists(Node n | n = [node.asNodeOrImplicitRead(), node.asNodeReverse()] | knownSinkModel(n, model) or not knownSinkModel(n, _) and model = "" @@ -1111,9 +1111,7 @@ module MakeImpl Lang> { } pragma[nomagic] - private predicate viableReturnPosOutNodeCand1( - DataFlowCallEx call, ReturnPosition pos, NodeEx out - ) { + private predicate viableReturnPosOutNodeCand1(DataFlowCall call, ReturnPosition pos, NodeEx out) { Stage1::revFlow(out) and Stage1::viableReturnPosOutNodeCandFwd1(call, pos, out) } @@ -1125,7 +1123,7 @@ module MakeImpl Lang> { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCallEx call, RetNodeEx ret, ReturnKindExt kind, NodeEx out + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out ) { exists(ReturnPosition pos | viableReturnPosOutNodeCand1(call, pos, out) and @@ -1138,7 +1136,7 @@ module MakeImpl Lang> { } pragma[nomagic] - private predicate viableParamArgNodeCand1(DataFlowCallEx call, ParamNodeEx p, ArgNodeEx arg) { + private predicate viableParamArgNodeCand1(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg) { Stage1::viableParamArgNodeCandFwd1(call, p, arg) and Stage1::revFlow(arg) } @@ -1148,7 +1146,7 @@ module MakeImpl Lang> { * path from a source to a sink. */ pragma[nomagic] - private predicate flowIntoCallNodeCand1(DataFlowCallEx call, ArgNodeEx arg, ParamNodeEx p) { + private predicate flowIntoCallNodeCand1(DataFlowCall call, ArgNodeEx arg, ParamNodeEx p) { viableParamArgNodeCand1(call, p, arg) and Stage1::revFlow(p) and not outBarrier(arg) and @@ -1168,7 +1166,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate returnCallEdge1( - DataFlowCallable c, SndLevelScopeOption scope, DataFlowCallEx call, NodeEx out + DataFlowCallable c, SndLevelScopeOption scope, DataFlowCall call, NodeEx out ) { exists(RetNodeEx ret | flowOutOfCallNodeCand1(call, ret, _, out) and @@ -1177,7 +1175,7 @@ module MakeImpl Lang> { ) } - private int simpleDispatchFanoutOnReturn(DataFlowCallEx call, NodeEx out) { + private int simpleDispatchFanoutOnReturn(DataFlowCall call, NodeEx out) { result = strictcount(DataFlowCallable c, SndLevelScopeOption scope | returnCallEdge1(c, scope, call, out) @@ -1186,29 +1184,28 @@ module MakeImpl Lang> { pragma[nomagic] private predicate returnCallEdgeInCtx1( - DataFlowCallable c, SndLevelScopeOption scope, DataFlowCallEx call, NodeEx out, - DataFlowCall ctx + DataFlowCallable c, SndLevelScopeOption scope, DataFlowCall call, NodeEx out, DataFlowCall ctx ) { returnCallEdge1(c, scope, call, out) and - c = viableImplInCallContextExt(call.projectCall(), ctx) + c = viableImplInCallContextExt(call, ctx) } - private int ctxDispatchFanoutOnReturn(NodeEx out, DataFlowCallEx ctx) { - exists(DataFlowCallEx call, DataFlowCallable c | + private int ctxDispatchFanoutOnReturn(NodeEx out, DataFlowCall ctx) { + exists(DataFlowCall call, DataFlowCallable c | simpleDispatchFanoutOnReturn(call, out) > 1 and not Stage1::revFlow(out, false) and call.getEnclosingCallable() = c and returnCallEdge1(c, _, ctx, _) and - mayBenefitFromCallContextExt(call.projectCall(), _) and + mayBenefitFromCallContextExt(call, _) and result = count(DataFlowCallable tgt, SndLevelScopeOption scope | - returnCallEdgeInCtx1(tgt, scope, call, out, ctx.projectCall()) + returnCallEdgeInCtx1(tgt, scope, call, out, ctx) ) ) } private int ctxDispatchFanoutOnReturn(NodeEx out) { - result = max(DataFlowCallEx ctx | | ctxDispatchFanoutOnReturn(out, ctx)) + result = max(DataFlowCall ctx | | ctxDispatchFanoutOnReturn(out, ctx)) } private int dispatchFanoutOnReturn(NodeEx out) { @@ -1259,7 +1256,7 @@ module MakeImpl Lang> { */ pragma[nomagic] private predicate flowOutOfCallNodeCand1( - DataFlowCallEx call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow + DataFlowCall call, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow ) { flowOutOfCallNodeCand1(call, ret, kind, out) and exists(int j | @@ -1274,7 +1271,7 @@ module MakeImpl Lang> { } pragma[nomagic] - private predicate allowsFieldFlowThrough(DataFlowCallEx call, DataFlowCallable c) { + private predicate allowsFieldFlowThrough(DataFlowCall call, DataFlowCallable c) { exists(RetNodeEx ret | flowOutOfCallNodeCand1(call, ret, _, _, true) and c = ret.getEnclosingCallable() @@ -1288,7 +1285,7 @@ module MakeImpl Lang> { */ pragma[nomagic] private predicate flowIntoCallNodeCand1( - DataFlowCallEx call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, boolean allowsFieldFlow ) { flowIntoCallNodeCand1(call, arg, p) and exists(int b, int j | @@ -1314,7 +1311,7 @@ module MakeImpl Lang> { bindingset[node, state] predicate revFlow(NodeEx node, FlowState state, Ap ap); - predicate callMayFlowThroughRev(DataFlowCallEx call); + predicate callMayFlowThroughRev(DataFlowCall call); predicate parameterMayFlowThrough(ParamNodeEx p, boolean emptyAp); @@ -1327,17 +1324,17 @@ module MakeImpl Lang> { predicate readStepCand(NodeEx n1, Content c, NodeEx n2); predicate callEdgeArgParam( - DataFlowCallEx call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp ); predicate callEdgeReturn( - DataFlowCallEx call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow ); - predicate relevantCallEdgeIn(DataFlowCallEx call, DataFlowCallable c); + predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c); - predicate relevantCallEdgeOut(DataFlowCallEx call, DataFlowCallable c); + predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c); } private module MkStage { @@ -1414,14 +1411,14 @@ module MakeImpl Lang> { predicate viableImplNotCallContextReduced(DataFlowCall call, Cc ctx); bindingset[call, c] - CcCall getCallContextCall(DataFlowCallEx call, DataFlowCallable c); + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c); DataFlowCall viableImplCallContextReducedReverse(DataFlowCallable c, CcNoCall ctx); predicate viableImplNotCallContextReducedReverse(CcNoCall ctx); bindingset[call, c] - CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCallEx call); + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call); bindingset[cc] LocalCc getLocalCc(Cc cc); @@ -1471,7 +1468,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate flowThroughOutOfCall( - DataFlowCallEx call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow + DataFlowCall call, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow ) { exists(ReturnKindExt kind | PrevStage::callEdgeReturn(call, _, ret, kind, out, allowsFieldFlow) and @@ -1598,7 +1595,7 @@ module MakeImpl Lang> { apa = getApprox(ap) or // flow through a callable - exists(DataFlowCallEx call, RetNodeEx ret, boolean allowsFieldFlow | + exists(DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow | fwdFlowThrough(call, cc, state, summaryCtx, t, ap, stored, ret) and flowThroughOutOfCall(call, ret, node, allowsFieldFlow) and apa = getApprox(ap) and @@ -1773,7 +1770,7 @@ module MakeImpl Lang> { private module FwdFlowIn { pragma[nomagic] private predicate callEdgeArgParamRestricted( - DataFlowCallEx call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp ) { PrevStage::callEdgeArgParam(call, c, arg, p, emptyAp) and if @@ -1790,16 +1787,16 @@ module MakeImpl Lang> { pragma[nomagic] private DataFlowCallable viableImplCallContextReducedRestricted( - DataFlowCallEx call, CcCall ctx + DataFlowCall call, CcCall ctx ) { - result = viableImplCallContextReduced(call.projectCall(), ctx) and + result = viableImplCallContextReduced(call, ctx) and callEdgeArgParamRestricted(call, result, _, _, _) } bindingset[call, ctx] pragma[inline_late] private DataFlowCallable viableImplCallContextReducedInlineLate( - DataFlowCallEx call, CcCall ctx + DataFlowCall call, CcCall ctx ) { result = viableImplCallContextReducedRestricted(call, ctx) } @@ -1807,7 +1804,7 @@ module MakeImpl Lang> { bindingset[arg, ctx] pragma[inline_late] private DataFlowCallable viableImplCallContextReducedInlineLate( - DataFlowCallEx call, ArgNodeEx arg, CcCall ctx + DataFlowCall call, ArgNodeEx arg, CcCall ctx ) { callEdgeArgParamRestricted(call, _, arg, _, _) and instanceofCcCall(ctx) and @@ -1817,7 +1814,7 @@ module MakeImpl Lang> { bindingset[call] pragma[inline_late] private predicate callEdgeArgParamRestrictedInlineLate( - DataFlowCallEx call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp ) { callEdgeArgParamRestricted(call, c, arg, p, emptyAp) } @@ -1832,16 +1829,16 @@ module MakeImpl Lang> { bindingset[arg, outercc] pragma[inline_late] private predicate viableImplArgNotCallContextReduced( - DataFlowCallEx call, ArgNodeEx arg, Cc outercc + DataFlowCall call, ArgNodeEx arg, Cc outercc ) { callEdgeArgParamRestricted(call, _, arg, _, _) and instanceofCc(outercc) and - viableImplNotCallContextReducedInlineLate(call.projectCall(), outercc) + viableImplNotCallContextReducedInlineLate(call, outercc) } pragma[inline] private predicate fwdFlowInCand( - DataFlowCallEx call, ArgNodeEx arg, FlowState state, Cc outercc, DataFlowCallable inner, + DataFlowCall call, ArgNodeEx arg, FlowState state, Cc outercc, DataFlowCallable inner, ParamNodeEx p, SummaryCtx summaryCtx, Typ t, Ap ap, boolean emptyAp, TypOption stored, boolean cc ) { @@ -1858,7 +1855,7 @@ module MakeImpl Lang> { pragma[inline] private predicate fwdFlowInCandTypeFlowDisabled( - DataFlowCallEx call, ArgNodeEx arg, FlowState state, Cc outercc, DataFlowCallable inner, + DataFlowCall call, ArgNodeEx arg, FlowState state, Cc outercc, DataFlowCallable inner, ParamNodeEx p, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, boolean cc ) { not enableTypeFlow() and @@ -1867,7 +1864,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowInCandTypeFlowEnabled( - DataFlowCallEx call, ArgNodeEx arg, Cc outercc, DataFlowCallable inner, ParamNodeEx p, + DataFlowCall call, ArgNodeEx arg, Cc outercc, DataFlowCallable inner, ParamNodeEx p, boolean emptyAp, boolean cc ) { enableTypeFlow() and @@ -1876,26 +1873,26 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowInValidEdgeTypeFlowDisabled( - DataFlowCallEx call, DataFlowCallable inner, CcCall innercc, boolean cc + DataFlowCall call, DataFlowCallable inner, CcCall innercc, boolean cc ) { not enableTypeFlow() and - FwdTypeFlow::typeFlowValidEdgeIn(call.projectCall(), inner, cc) and + FwdTypeFlow::typeFlowValidEdgeIn(call, inner, cc) and innercc = getCallContextCall(call, inner) } pragma[nomagic] private predicate fwdFlowInValidEdgeTypeFlowEnabled( - DataFlowCallEx call, ArgNodeEx arg, Cc outercc, DataFlowCallable inner, ParamNodeEx p, + DataFlowCall call, ArgNodeEx arg, Cc outercc, DataFlowCallable inner, ParamNodeEx p, CcCall innercc, boolean emptyAp, boolean cc ) { fwdFlowInCandTypeFlowEnabled(call, arg, outercc, inner, p, emptyAp, cc) and - FwdTypeFlow::typeFlowValidEdgeIn(call.projectCall(), inner, cc) and + FwdTypeFlow::typeFlowValidEdgeIn(call, inner, cc) and innercc = getCallContextCall(call, inner) } pragma[inline] predicate fwdFlowIn( - DataFlowCallEx call, ArgNodeEx arg, DataFlowCallable inner, ParamNodeEx p, + DataFlowCall call, ArgNodeEx arg, DataFlowCallable inner, ParamNodeEx p, FlowState state, Cc outercc, CcCall innercc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, boolean cc ) { @@ -1918,10 +1915,9 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowInNoFlowThrough( - ParamNodeEx p, FlowState state, CcCall innercc, Typ t, Ap ap, TypOption stored + NormalParamNodeEx p, FlowState state, CcCall innercc, Typ t, Ap ap, TypOption stored ) { - FwdFlowInNoThrough::fwdFlowIn(any(NormalDataFlowCall call), _, _, p, state, _, innercc, _, - t, ap, stored, _) + FwdFlowInNoThrough::fwdFlowIn(_, _, _, p, state, _, innercc, _, t, ap, stored, _) } private predicate top() { any() } @@ -1936,16 +1932,16 @@ module MakeImpl Lang> { } pragma[nomagic] - private DataFlowCallEx viableImplCallContextReducedReverseRestricted( + private DataFlowCall viableImplCallContextReducedReverseRestricted( DataFlowCallable c, CcNoCall ctx ) { - result.projectCall() = viableImplCallContextReducedReverse(c, ctx) and + result = viableImplCallContextReducedReverse(c, ctx) and PrevStage::callEdgeReturn(result, c, _, _, _, _) } bindingset[c, ctx] pragma[inline_late] - private DataFlowCallEx viableImplCallContextReducedReverseInlineLate( + private DataFlowCall viableImplCallContextReducedReverseInlineLate( DataFlowCallable c, CcNoCall ctx ) { result = viableImplCallContextReducedReverseRestricted(c, ctx) @@ -1954,8 +1950,7 @@ module MakeImpl Lang> { bindingset[call] pragma[inline_late] private predicate flowOutOfCallInlineLate( - DataFlowCallEx call, DataFlowCallable c, RetNodeEx ret, NodeEx out, - boolean allowsFieldFlow + DataFlowCall call, DataFlowCallable c, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow ) { PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow) } @@ -1964,8 +1959,8 @@ module MakeImpl Lang> { pragma[inline_late] pragma[noopt] private predicate flowOutOfCallNotCallContextReduced( - DataFlowCallEx call, DataFlowCallable c, RetNodeEx ret, NodeEx out, - boolean allowsFieldFlow, CcNoCall innercc + DataFlowCall call, DataFlowCallable c, RetNodeEx ret, NodeEx out, boolean allowsFieldFlow, + CcNoCall innercc ) { viableImplNotCallContextReducedReverse(innercc) and PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow) @@ -1983,8 +1978,8 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowOutCand( - NormalDataFlowCall call, RetNodeEx ret, CcNoCall innercc, DataFlowCallable inner, - NodeEx out, boolean allowsFieldFlow + DataFlowCall call, RetNodeEx ret, CcNoCall innercc, DataFlowCallable inner, NodeEx out, + boolean allowsFieldFlow ) { fwdFlowIntoRet(ret, _, innercc, _, _, _, _) and inner = ret.getEnclosingCallable() and @@ -1998,18 +1993,18 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowOutValidEdge( - NormalDataFlowCall call, RetNodeEx ret, CcNoCall innercc, DataFlowCallable inner, - NodeEx out, CcNoCall outercc, boolean allowsFieldFlow + DataFlowCall call, RetNodeEx ret, CcNoCall innercc, DataFlowCallable inner, NodeEx out, + CcNoCall outercc, boolean allowsFieldFlow ) { fwdFlowOutCand(call, ret, innercc, inner, out, allowsFieldFlow) and - FwdTypeFlow::typeFlowValidEdgeOut(call.projectCall(), inner) and + FwdTypeFlow::typeFlowValidEdgeOut(call, inner) and outercc = getCallContextReturn(inner, call) } pragma[inline] private predicate fwdFlowOut( - NormalDataFlowCall call, DataFlowCallable inner, NodeEx out, FlowState state, - CcNoCall outercc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored + DataFlowCall call, DataFlowCallable inner, NodeEx out, FlowState state, CcNoCall outercc, + SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored ) { exists(RetNodeEx ret, CcNoCall innercc, boolean allowsFieldFlow | fwdFlowIntoRet(ret, state, innercc, summaryCtx, t, ap, stored) and @@ -2023,11 +2018,11 @@ module MakeImpl Lang> { predicate enableTypeFlow = Param::enableTypeFlow/0; predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { - PrevStage::relevantCallEdgeIn(injectCall(call), c) + PrevStage::relevantCallEdgeIn(call, c) } predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { - PrevStage::relevantCallEdgeOut(injectCall(call), c) + PrevStage::relevantCallEdgeOut(call, c) } pragma[nomagic] @@ -2035,11 +2030,9 @@ module MakeImpl Lang> { DataFlowCall call, DataFlowCallable c, ParamNodeEx p, FlowState state, CcCall innercc, Typ t, Ap ap, TypOption stored, boolean cc ) { - FwdFlowInNoThrough::fwdFlowIn(injectCall(call), _, c, p, state, _, innercc, _, t, ap, - stored, cc) + FwdFlowInNoThrough::fwdFlowIn(call, _, c, p, state, _, innercc, _, t, ap, stored, cc) or - FwdFlowInThrough::fwdFlowIn(injectCall(call), _, c, p, state, _, innercc, _, t, ap, - stored, cc) + FwdFlowInThrough::fwdFlowIn(call, _, c, p, state, _, innercc, _, t, ap, stored, cc) } pragma[nomagic] @@ -2063,7 +2056,7 @@ module MakeImpl Lang> { DataFlowCall call, DataFlowCallable c, NodeEx node, FlowState state, Cc cc, Typ t, Ap ap, TypOption stored ) { - fwdFlowOut(injectCall(call), c, node, state, cc, _, t, ap, stored) + fwdFlowOut(call, c, node, state, cc, _, t, ap, stored) } pragma[nomagic] @@ -2101,10 +2094,10 @@ module MakeImpl Lang> { private module FwdTypeFlow = TypeFlow; private predicate flowIntoCallTaken( - DataFlowCallEx call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp ) { PrevStage::callEdgeArgParam(call, c, arg, p, emptyAp) and - FwdTypeFlowInput::dataFlowTakenCallEdgeIn(call.projectCall(), c, _) + FwdTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _) } pragma[nomagic] @@ -2126,7 +2119,7 @@ module MakeImpl Lang> { pragma[inline] private predicate fwdFlowThrough0( - DataFlowCallEx call, ArgNodeEx arg, Cc cc, FlowState state, CcCall ccc, + DataFlowCall call, ArgNodeEx arg, Cc cc, FlowState state, CcCall ccc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, RetNodeEx ret, SummaryCtxSome innerSummaryCtx ) { @@ -2136,7 +2129,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowThrough( - DataFlowCallEx call, Cc cc, FlowState state, SummaryCtx summaryCtx, Typ t, Ap ap, + DataFlowCall call, Cc cc, FlowState state, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, RetNodeEx ret ) { fwdFlowThrough0(call, _, cc, state, _, summaryCtx, t, ap, stored, ret, _) @@ -2144,7 +2137,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowIsEntered0( - DataFlowCallEx call, ArgNodeEx arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, + DataFlowCall call, ArgNodeEx arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, ParamNodeEx p, FlowState state, Typ t, Ap ap, TypOption stored ) { FwdFlowInThrough::fwdFlowIn(call, arg, _, p, state, cc, innerCc, summaryCtx, t, ap, @@ -2157,7 +2150,7 @@ module MakeImpl Lang> { */ pragma[nomagic] private predicate fwdFlowIsEntered( - DataFlowCallEx call, ArgNodeEx arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, + DataFlowCall call, ArgNodeEx arg, Cc cc, CcCall innerCc, SummaryCtx summaryCtx, SummaryCtxSome innerSummaryCtx ) { exists(ParamNodeEx p, FlowState state, Typ t, Ap ap, TypOption stored | @@ -2180,7 +2173,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate returnFlowsThrough0( - DataFlowCallEx call, FlowState state, CcCall ccc, Ap ap, RetNodeEx ret, + DataFlowCall call, FlowState state, CcCall ccc, Ap ap, RetNodeEx ret, SummaryCtxSome innerSummaryCtx ) { fwdFlowThrough0(call, _, _, state, ccc, _, _, ap, _, ret, innerSummaryCtx) @@ -2191,7 +2184,7 @@ module MakeImpl Lang> { RetNodeEx ret, ReturnPosition pos, FlowState state, CcCall ccc, ParamNodeEx p, Typ argT, Ap argAp, TypOption argStored, Ap ap ) { - exists(DataFlowCallEx call, boolean allowsFieldFlow | + exists(DataFlowCall call, boolean allowsFieldFlow | returnFlowsThrough0(call, state, ccc, ap, ret, TSummaryCtxSome(p, _, argT, argAp, argStored)) and flowThroughOutOfCall(call, ret, _, allowsFieldFlow) and @@ -2202,7 +2195,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate flowThroughIntoCall( - DataFlowCallEx call, ArgNodeEx arg, ParamNodeEx p, Ap argAp, Ap ap + DataFlowCall call, ArgNodeEx arg, ParamNodeEx p, Ap argAp, Ap ap ) { exists(Typ argT, TypOption argStored | returnFlowsThrough(_, _, _, _, pragma[only_bind_into](p), pragma[only_bind_into](argT), @@ -2215,7 +2208,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate flowIntoCallAp( - DataFlowCallEx call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, Ap ap + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, Ap ap ) { flowIntoCallTaken(call, c, arg, p, isNil(ap)) and fwdFlow(arg, _, _, _, _, ap, _) @@ -2223,7 +2216,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate flowOutOfCallAp( - DataFlowCallEx call, DataFlowCallable c, RetNodeEx ret, ReturnPosition pos, NodeEx out, + DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnPosition pos, NodeEx out, Ap ap, boolean allowsFieldFlow ) { PrevStage::callEdgeReturn(call, c, ret, _, out, allowsFieldFlow) and @@ -2232,8 +2225,8 @@ module MakeImpl Lang> { (if allowsFieldFlow = false then ap instanceof ApNil else any()) and ( // both directions are needed for flow-through - FwdTypeFlowInput::dataFlowTakenCallEdgeIn(call.projectCall(), c, _) or - FwdTypeFlowInput::dataFlowTakenCallEdgeOut(call.projectCall(), c) + FwdTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _) or + FwdTypeFlowInput::dataFlowTakenCallEdgeOut(call, c) ) } @@ -2295,25 +2288,24 @@ module MakeImpl Lang> { ) or // flow into a callable - revFlowIn(any(NormalDataFlowCall call), _, node, state, ap) and + revFlowIn(_, _, node.(NormalArgNodeEx), state, ap) and returnCtx = TReturnCtxNone() and returnAp = apNone() or // flow through a callable - exists(DataFlowCallEx call, ParamNodeEx p, Ap innerReturnAp | + exists(DataFlowCall call, ParamNodeEx p, Ap innerReturnAp | revFlowThrough(call, returnCtx, p, state, _, returnAp, ap, innerReturnAp) and flowThroughIntoCall(call, node, p, ap, innerReturnAp) ) or // flow out of a callable - exists(DataFlowCallEx call, ReturnPosition pos | + exists(DataFlowCall call, ReturnPosition pos | revFlowOut(call, node, pos, state, _, _, _, ap) and if returnFlowsThrough(node, pos, state, _, _, _, _, _, ap) then ( returnCtx = TReturnCtxMaybeFlowThrough(pos) and returnAp = apSome(ap) ) else ( - call instanceof NormalDataFlowCall and returnCtx = TReturnCtxNoFlowThrough() and returnAp = apNone() ) @@ -2365,24 +2357,24 @@ module MakeImpl Lang> { predicate enableTypeFlow = Param::enableTypeFlow/0; predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { - flowOutOfCallAp(injectCall(call), c, _, _, _, _, _) + flowOutOfCallAp(call, c, _, _, _, _, _) } predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { - flowIntoCallAp(injectCall(call), c, _, _, _) + flowIntoCallAp(call, c, _, _, _) } pragma[nomagic] predicate dataFlowTakenCallEdgeIn(DataFlowCall call, DataFlowCallable c, boolean cc) { exists(RetNodeEx ret | - revFlowOut(injectCall(call), ret, _, _, _, cc, _, _) and + revFlowOut(call, ret, _, _, _, cc, _, _) and c = ret.getEnclosingCallable() ) } pragma[nomagic] predicate dataFlowTakenCallEdgeOut(DataFlowCall call, DataFlowCallable c) { - revFlowIn(injectCall(call), c, _, _, _) + revFlowIn(call, c, _, _, _) } predicate dataFlowNonCallEntry(DataFlowCallable c, boolean cc) { @@ -2405,24 +2397,24 @@ module MakeImpl Lang> { pragma[nomagic] private predicate flowIntoCallApValid( - DataFlowCallEx call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, Ap ap + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, Ap ap ) { flowIntoCallAp(call, c, arg, p, ap) and - RevTypeFlow::typeFlowValidEdgeOut(call.projectCall(), c) + RevTypeFlow::typeFlowValidEdgeOut(call, c) } pragma[nomagic] private predicate flowOutOfCallApValid( - DataFlowCallEx call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Ap ap, boolean cc + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, NodeEx out, Ap ap, boolean cc ) { exists(DataFlowCallable c | flowOutOfCallAp(call, c, ret, pos, out, ap, _) and - RevTypeFlow::typeFlowValidEdgeIn(call.projectCall(), c, cc) + RevTypeFlow::typeFlowValidEdgeIn(call, c, cc) ) } private predicate revFlowIn( - DataFlowCallEx call, DataFlowCallable c, ArgNodeEx arg, FlowState state, Ap ap + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, FlowState state, Ap ap ) { exists(ParamNodeEx p | revFlow(p, state, TReturnCtxNone(), _, ap) and @@ -2432,7 +2424,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate revFlowOut( - DataFlowCallEx call, RetNodeEx ret, ReturnPosition pos, FlowState state, + DataFlowCall call, RetNodeEx ret, ReturnPosition pos, FlowState state, ReturnCtx returnCtx, boolean cc, ApOption returnAp, Ap ap ) { exists(NodeEx out | @@ -2454,7 +2446,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate revFlowThrough( - DataFlowCallEx call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, + DataFlowCall call, ReturnCtx returnCtx, ParamNodeEx p, FlowState state, ReturnPosition pos, ApOption returnAp, Ap ap, Ap innerReturnAp ) { revFlowParamToReturn(p, state, pos, innerReturnAp, ap) and @@ -2468,12 +2460,12 @@ module MakeImpl Lang> { */ pragma[nomagic] private predicate revFlowIsReturned( - DataFlowCallEx call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap + DataFlowCall call, ReturnCtx returnCtx, ApOption returnAp, ReturnPosition pos, Ap ap ) { exists(RetNodeEx ret, FlowState state, CcCall ccc | revFlowOut(call, ret, pos, state, returnCtx, _, returnAp, ap) and returnFlowsThrough(ret, pos, state, ccc, _, _, _, _, ap) and - matchesCall(ccc, call.projectCall()) + matchesCall(ccc, call) ) } @@ -2586,8 +2578,8 @@ module MakeImpl Lang> { pragma[nomagic] private predicate revFlowThroughArg( - DataFlowCallEx call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, - ApOption returnAp, Ap ap + DataFlowCall call, ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, + Ap ap ) { exists(ParamNodeEx p, Ap innerReturnAp | revFlowThrough(call, returnCtx, p, state, _, returnAp, ap, innerReturnAp) and @@ -2596,7 +2588,7 @@ module MakeImpl Lang> { } pragma[nomagic] - predicate callMayFlowThroughRev(DataFlowCallEx call) { + predicate callMayFlowThroughRev(DataFlowCall call) { exists(ArgNodeEx arg, FlowState state, ReturnCtx returnCtx, ApOption returnAp, Ap ap | revFlow(arg, state, returnCtx, returnAp, ap) and revFlowThroughArg(call, arg, state, returnCtx, returnAp, ap) @@ -2604,7 +2596,7 @@ module MakeImpl Lang> { } predicate callEdgeArgParam( - DataFlowCallEx call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp + DataFlowCall call, DataFlowCallable c, ArgNodeEx arg, ParamNodeEx p, boolean emptyAp ) { exists(FlowState state, Ap ap | flowIntoCallAp(call, c, arg, p, ap) and @@ -2613,13 +2605,13 @@ module MakeImpl Lang> { emptyAp = isNil(ap) | // both directions are needed for flow-through - RevTypeFlowInput::dataFlowTakenCallEdgeIn(call.projectCall(), c, _) or - RevTypeFlowInput::dataFlowTakenCallEdgeOut(call.projectCall(), c) + RevTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _) or + RevTypeFlowInput::dataFlowTakenCallEdgeOut(call, c) ) } predicate callEdgeReturn( - DataFlowCallEx call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out, + DataFlowCall call, DataFlowCallable c, RetNodeEx ret, ReturnKindExt kind, NodeEx out, boolean allowsFieldFlow ) { exists(FlowState state, ReturnPosition pos, Ap ap | @@ -2627,15 +2619,15 @@ module MakeImpl Lang> { revFlow(ret, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and revFlow(out, pragma[only_bind_into](state), pragma[only_bind_into](ap)) and kind = pos.getKind() and - RevTypeFlowInput::dataFlowTakenCallEdgeIn(call.projectCall(), c, _) + RevTypeFlowInput::dataFlowTakenCallEdgeIn(call, c, _) ) } - predicate relevantCallEdgeIn(DataFlowCallEx call, DataFlowCallable c) { + predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { callEdgeArgParam(call, c, _, _, _) } - predicate relevantCallEdgeOut(DataFlowCallEx call, DataFlowCallable c) { + predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { callEdgeReturn(call, c, _, _, _, _) } @@ -3027,7 +3019,7 @@ module MakeImpl Lang> { ) or exists(Node n | - node.asNodeReverse(_) = n and + node.asNodeReverse() = n and result = node | Config::isSinkReverse(n) or Config::isSinkReverse(n, _) @@ -3174,7 +3166,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowThroughStep0( - DataFlowCallEx call, ArgNodeEx arg, Cc cc, FlowState state, CcCall ccc, + DataFlowCall call, ArgNodeEx arg, Cc cc, FlowState state, CcCall ccc, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, RetNodeEx ret, SummaryCtxSome innerSummaryCtx ) { @@ -3203,7 +3195,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate fwdFlowThroughStep1( - PathNodeImpl pn1, PathNodeImpl pn2, PathNodeImpl pn3, DataFlowCallEx call, Cc cc, + PathNodeImpl pn1, PathNodeImpl pn2, PathNodeImpl pn3, DataFlowCall call, Cc cc, FlowState state, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored, RetNodeEx ret ) { exists( @@ -3226,7 +3218,7 @@ module MakeImpl Lang> { PathNodeImpl pn1, PathNodeImpl pn2, PathNodeImpl pn3, NodeEx node, Cc cc, FlowState state, SummaryCtx summaryCtx, Typ t, Ap ap, TypOption stored ) { - exists(DataFlowCallEx call, RetNodeEx ret, boolean allowsFieldFlow | + exists(DataFlowCall call, RetNodeEx ret, boolean allowsFieldFlow | fwdFlowThroughStep1(pn1, pn2, pn3, call, cc, state, summaryCtx, t, ap, stored, ret) and flowThroughOutOfCall(call, ret, node, allowsFieldFlow) and not inBarrier(node, state) and @@ -3527,11 +3519,11 @@ module MakeImpl Lang> { final Node getNode() { super.getNodeEx().projectToNode() = result } /** Gets the underlying `Node`, but only when it represents a reverse-flow node. */ - final Node getNodeReverse() { super.getNodeEx().asNodeReverse(_) = result } + final Node getNodeReverse() { super.getNodeEx().asNodeReverse() = result } /** Gets the parameter node through which data is returned, if any. */ final ParameterNode asParameterReturnNode() { - result = super.getNodeEx().asNodeReverse(_) + result = super.getNodeEx().asNodeReverse() } /** Gets the `FlowState` of this node. */ @@ -3716,14 +3708,14 @@ module MakeImpl Lang> { predicate viableImplNotCallContextReduced(DataFlowCall call, Cc ctx) { any() } bindingset[call, c] - CcCall getCallContextCall(DataFlowCallEx call, DataFlowCallable c) { any() } + CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c) { any() } DataFlowCall viableImplCallContextReducedReverse(DataFlowCallable c, CcNoCall ctx) { none() } predicate viableImplNotCallContextReducedReverse(CcNoCall ctx) { any() } bindingset[call, c] - CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCallEx call) { any() } + CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() } } private module Stage2Param implements MkStage::StageParam { @@ -3847,11 +3839,11 @@ module MakeImpl Lang> { private module CallContextSensitivityInput implements CallContextSensitivityInputSig { predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { - PrevStage::relevantCallEdgeIn(injectCall(call), c) + PrevStage::relevantCallEdgeIn(call, c) } predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { - PrevStage::relevantCallEdgeOut(injectCall(call), c) + PrevStage::relevantCallEdgeOut(call, c) } predicate reducedViableImplInCallContextCand = @@ -4251,11 +4243,11 @@ module MakeImpl Lang> { private module CallContextSensitivityInput implements CallContextSensitivityInputSig { predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { - PrevStage::relevantCallEdgeIn(injectCall(call), c) + PrevStage::relevantCallEdgeIn(call, c) } predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { - PrevStage::relevantCallEdgeOut(injectCall(call), c) + PrevStage::relevantCallEdgeOut(call, c) } predicate reducedViableImplInCallContextCand = @@ -4451,11 +4443,11 @@ module MakeImpl Lang> { private module CallContextSensitivityInput implements CallContextSensitivityInputSig { predicate relevantCallEdgeIn(DataFlowCall call, DataFlowCallable c) { - PrevStage::relevantCallEdgeIn(injectCall(call), c) + PrevStage::relevantCallEdgeIn(call, c) } predicate relevantCallEdgeOut(DataFlowCall call, DataFlowCallable c) { - PrevStage::relevantCallEdgeOut(injectCall(call), c) + PrevStage::relevantCallEdgeOut(call, c) } predicate reducedViableImplInCallContextCand = @@ -4987,7 +4979,7 @@ module MakeImpl Lang> { not fullBarrier(node) and not stateBarrier(node, state) or - Config::isSinkReverse(node.asNodeReverse(_)) and + Config::isSinkReverse(node.asNodeReverse()) and relevantState(state) and not fullBarrier(node) and not stateBarrier(node, state) @@ -5461,14 +5453,14 @@ module MakeImpl Lang> { pragma[nomagic] private predicate partialPathOutOfCallable1( - PartialPathNodeFwd mid, DataFlowCallEx call, ReturnKindExt kind, FlowState state, + PartialPathNodeFwd mid, DataFlowCall call, ReturnKindExt kind, FlowState state, CallContext cc, DataFlowType t, PartialAccessPath ap ) { exists(ReturnPosition pos, DataFlowCallable c, CallContext innercc | partialPathOutOfCallable0(mid, pos, state, innercc, t, ap) and c = pos.getCallable() and kind = pos.getKind() and - CachedCallContextSensitivity::resolveReturn(innercc, c, call.projectCall()) and + CachedCallContextSensitivity::resolveReturn(innercc, c, call) and cc = CachedCallContextSensitivity::getCallContextReturn(c, call) ) } @@ -5477,7 +5469,7 @@ module MakeImpl Lang> { PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, DataFlowType t, PartialAccessPath ap ) { - exists(ReturnKindExt kind, DataFlowCallEx call | + exists(ReturnKindExt kind, DataFlowCall call | partialPathOutOfCallable1(mid, call, kind, state, cc, t, ap) and out = kind.getAnOutNodeEx(call) ) @@ -5486,7 +5478,7 @@ module MakeImpl Lang> { pragma[noinline] private predicate partialPathIntoArg( PartialPathNodeFwd mid, ParameterPositionEx ppos, FlowState state, CallContext cc, - DataFlowCallEx call, DataFlowType t, PartialAccessPath ap + DataFlowCall call, DataFlowType t, PartialAccessPath ap ) { exists(ArgNodeEx arg, ArgumentPositionEx apos | arg = mid.getNodeEx() and @@ -5502,16 +5494,16 @@ module MakeImpl Lang> { pragma[nomagic] private predicate partialPathIntoCallable0( PartialPathNodeFwd mid, DataFlowCallable callable, ParameterPositionEx pos, FlowState state, - CallContext outercc, DataFlowCallEx call, DataFlowType t, PartialAccessPath ap + CallContext outercc, DataFlowCall call, DataFlowType t, PartialAccessPath ap ) { partialPathIntoArg(mid, pos, state, outercc, call, t, ap) and - callable = CachedCallContextSensitivity::resolveCall(call.projectCall(), outercc) + callable = CachedCallContextSensitivity::resolveCall(call, outercc) } private predicate partialPathIntoCallable( PartialPathNodeFwd mid, ParamNodeEx p, FlowState state, CallContext outercc, CallContextCall innercc, TSummaryCtx1 sc1, TSummaryCtx2 sc2, TSummaryCtx3 sc3, - TSummaryCtx4 sc4, DataFlowCallEx call, DataFlowType t, PartialAccessPath ap + TSummaryCtx4 sc4, DataFlowCall call, DataFlowType t, PartialAccessPath ap ) { exists(ParameterPositionEx pos, DataFlowCallable callable | partialPathIntoCallable0(mid, callable, pos, state, outercc, call, t, ap) and @@ -5546,7 +5538,7 @@ module MakeImpl Lang> { pragma[noinline] private predicate partialPathThroughCallable0( - DataFlowCallEx call, PartialPathNodeFwd mid, ReturnKindExt kind, FlowState state, + DataFlowCall call, PartialPathNodeFwd mid, ReturnKindExt kind, FlowState state, CallContext cc, DataFlowType t, PartialAccessPath ap ) { exists( @@ -5562,7 +5554,7 @@ module MakeImpl Lang> { PartialPathNodeFwd mid, NodeEx out, FlowState state, CallContext cc, DataFlowType t, PartialAccessPath ap ) { - exists(DataFlowCallEx call, ReturnKindExt kind | + exists(DataFlowCall call, ReturnKindExt kind | partialPathThroughCallable0(call, mid, kind, state, cc, t, ap) and out = kind.getAnOutNodeEx(call) ) @@ -5733,7 +5725,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate revPartialPathIntoReturn( PartialPathNodeRev mid, ReturnPosition pos, FlowState state, TRevSummaryCtx1Some sc1, - TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3, DataFlowCallEx call, PartialAccessPath ap + TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3, DataFlowCall call, PartialAccessPath ap ) { exists(NodeEx out | mid.getNodeEx() = out and @@ -5765,7 +5757,7 @@ module MakeImpl Lang> { pragma[nomagic] private predicate revPartialPathThroughCallable0( - DataFlowCallEx call, PartialPathNodeRev mid, ArgumentPositionEx pos, FlowState state, + DataFlowCall call, PartialPathNodeRev mid, ArgumentPositionEx pos, FlowState state, PartialAccessPath ap ) { exists(TRevSummaryCtx1Some sc1, TRevSummaryCtx2Some sc2, TRevSummaryCtx3Some sc3 | @@ -5778,7 +5770,7 @@ module MakeImpl Lang> { private predicate revPartialPathThroughCallable( PartialPathNodeRev mid, ArgNodeEx node, FlowState state, PartialAccessPath ap ) { - exists(DataFlowCallEx call, ArgumentPositionEx pos | + exists(DataFlowCall call, ArgumentPositionEx pos | revPartialPathThroughCallable0(call, mid, pos, state, ap) and node.argumentOf(call, pos) ) diff --git a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll index 44b96b91f756..b0dc0bd2093f 100644 --- a/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll @@ -328,8 +328,7 @@ module MakeImplCommon Lang> { viableParamArg(call, param, arg) and parameterValueFlowReturn(param, kind, read, model, innerCtx) and callable = nodeGetEnclosingCallable(param) and - outerCtx = - CachedCallContextSensitivity::getCallContextReturn(callable, TNormalDataFlowCall(call)) + outerCtx = CachedCallContextSensitivity::getCallContextReturn(callable, call) | CachedCallContextSensitivity::viableImplNotCallContextReducedReverse(innerCtx) or @@ -555,7 +554,7 @@ module MakeImplCommon Lang> { * parameter position `ppos`. */ pragma[noinline] - predicate argumentPositionMatchEx(DataFlowCallEx call, ArgNodeEx arg, ParameterPositionEx ppos) { + predicate argumentPositionMatchEx(DataFlowCall call, ArgNodeEx arg, ParameterPositionEx ppos) { exists(ArgumentPositionEx apos | arg.argumentOf(call, apos) and parameterMatchEx(ppos, apos) @@ -1136,10 +1135,10 @@ module MakeImplCommon Lang> { /** Gets the call context when returning from `c` to `call`. */ bindingset[call, c] - CallContextNoCall getCallContextReturn(DataFlowCallable c, DataFlowCallEx call) { - result = Input2::getSpecificCallContextReturn(c, call.projectCall()) + CallContextNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { + result = Input2::getSpecificCallContextReturn(c, call) or - not exists(Input2::getSpecificCallContextReturn(c, call.projectCall())) and + not exists(Input2::getSpecificCallContextReturn(c, call)) and result = TAnyCallContext() } @@ -1167,9 +1166,9 @@ module MakeImplCommon Lang> { LocalCc getLocalCc(CallContext cc) { any() } bindingset[call, c] - CallContextCall getCallContextCall(DataFlowCallEx call, DataFlowCallable c) { - if recordDataFlowCallSiteDispatch(call.projectCall(), c) - then result = Input2::getSpecificCallContextCall(call.projectCall(), c) + CallContextCall getCallContextCall(DataFlowCall call, DataFlowCallable c) { + if recordDataFlowCallSiteDispatch(call, c) + then result = Input2::getSpecificCallContextCall(call, c) else result = TSomeCall() } } @@ -1195,9 +1194,9 @@ module MakeImplCommon Lang> { LocalCc getLocalCc(CallContext cc) { result = getLocalCallContext(cc) } bindingset[call, c] - CallContextCall getCallContextCall(DataFlowCallEx call, DataFlowCallable c) { - if recordDataFlowCallSite(call.projectCall(), c) - then result = Input2::getSpecificCallContextCall(call.projectCall(), c) + CallContextCall getCallContextCall(DataFlowCall call, DataFlowCallable c) { + if recordDataFlowCallSite(call, c) + then result = Input2::getSpecificCallContextCall(call, c) else result = TSomeCall() } } @@ -1238,14 +1237,14 @@ module MakeImplCommon Lang> { or exists(Node n | this.isImplicitReadNode(n) | result = n + " [Ext]") or - result = this.asNodeReverse(_) + " [Reverse]" + result = this.asNodeReverse() + " [Reverse]" } Node asNode() { this = TNodeNormal(result) } - Node asNodeReverse(boolean allowFwdFlowOut) { this = TNodeReverse(result, allowFwdFlowOut) } + Node asNodeReverse() { this = TNodeReverse(result) } - Node asNodeOrReverse() { result = [this.asNode(), this.asNodeReverse(_)] } + Node asNodeOrReverse() { result = [this.asNode(), this.asNodeReverse()] } /** Gets the corresponding Node if this is a normal node or its post-implicit read node. */ Node asNodeOrImplicitRead() { this = TNodeNormal(result) or this = TNodeImplicitRead(result) } @@ -1255,7 +1254,7 @@ module MakeImplCommon Lang> { Node projectToNode() { this = TNodeNormal(result) or this = TNodeImplicitRead(result) or - this = TNodeReverse(result, _) + this = TNodeReverse(result) } pragma[nomagic] @@ -1290,28 +1289,6 @@ module MakeImplCommon Lang> { CastingNodeEx() { castingNodeEx(this) } } - abstract class DataFlowCallEx extends TDataFlowCallEx { - abstract DataFlowCall projectCall(); - - DataFlowCallable getEnclosingCallable() { result = this.projectCall().getEnclosingCallable() } - - abstract string toString(); - - Location getLocation() { result = this.projectCall().getLocation() } - } - - DataFlowCallEx injectCall(DataFlowCall c) { result.projectCall() = c } - - final class NormalDataFlowCall extends DataFlowCallEx, TNormalDataFlowCall { - private DataFlowCall call; - - NormalDataFlowCall() { this = TNormalDataFlowCall(call) } - - override DataFlowCall projectCall() { result = call } - - override string toString() { result = call.toString() } - } - final class ArgumentPositionEx extends TArgumentPositionEx { ArgumentPosition asArgumentPosition() { this = TNormalArgumentPosition(result) } @@ -1337,20 +1314,18 @@ module MakeImplCommon Lang> { } abstract class ArgNodeEx extends NodeEx { - abstract predicate argumentOf(DataFlowCallEx call, ArgumentPositionEx pos); + abstract predicate argumentOf(DataFlowCall call, ArgumentPositionEx pos); - DataFlowCallEx getCall() { this.argumentOf(result, _) } + DataFlowCall getCall() { this.argumentOf(result, _) } } final class NormalArgNodeEx extends ArgNodeEx { - private NormalDataFlowCall call_; + private DataFlowCall call_; private ArgumentPositionEx pos_; - NormalArgNodeEx() { - this.asNode().(ArgNode).argumentOf(call_.projectCall(), pos_.asArgumentPosition()) - } + NormalArgNodeEx() { this.asNode().(ArgNode).argumentOf(call_, pos_.asArgumentPosition()) } - override predicate argumentOf(DataFlowCallEx call, ArgumentPositionEx pos) { + override predicate argumentOf(DataFlowCall call, ArgumentPositionEx pos) { call = call_ and pos = pos_ } @@ -1391,7 +1366,7 @@ module MakeImplCommon Lang> { OutNodeEx() { this.asNode() instanceof OutNodeExt or - this.asNodeReverse(_) instanceof ArgNode + this.asNodeReverse() instanceof ArgNode } } @@ -1406,49 +1381,54 @@ module MakeImplCommon Lang> { /** * todo */ - private module ReverseFlow { + module ReverseFlow { /** * Holds if `p` can flow to `node` in the same callable using only * value-preserving or read/store steps. */ pragma[nomagic] - predicate parameterValueFlow(ParamNode p, Node node) { - p = node + predicate parameterValueFlow(ParamNode p, Node node, boolean flowThrough) { + p = node and + flowThrough = false or // local flow exists(Node mid | - parameterValueFlow(p, mid) and + parameterValueFlow(p, mid, flowThrough) and simpleLocalFlowStep(mid, node, _) and - validParameterAliasStep(mid, node) + validParameterAliasStep(mid, node) and + flowThrough = false ) or // store none() and exists(Node mid | - parameterValueFlow(p, mid) and + parameterValueFlow(p, mid, flowThrough) and Lang::storeStep(mid, _, node) ) or // read exists(Node mid | - parameterValueFlow(p, mid) and + parameterValueFlow(p, mid, flowThrough) and Lang::readStep(mid, _, node) ) or // flow through exists(ArgNode arg | parameterValueFlowArg(p, arg) and - argumentValueFlowsThrough(arg, node) + argumentValueFlowsThrough(arg, node) and + flowThrough = true ) } pragma[nomagic] - private predicate parameterValueFlowArg(ParamNode p, ArgNode arg) { parameterValueFlow(p, arg) } + private predicate parameterValueFlowArg(ParamNode p, ArgNode arg) { + parameterValueFlow(p, arg, _) + } pragma[nomagic] private predicate parameterValueFlowReturn(ParamNode p, ReturnKind kind) { exists(ReturnNode ret | - parameterValueFlow(p, ret) and + parameterValueFlow(p, ret, _) and kind = ret.getKind() ) } @@ -1468,14 +1448,6 @@ module MakeImplCommon Lang> { ) } - // predicate cand(ParamNode p, Node n) { - // parameterValueFlowCand(p, n) and - // ( - // parameterValueFlowReturnCand(p, _) - // or - // parameterValueFlowsToPreUpdateCand(p, _) - // ) - // } /** * Holds if the local step from `arg` to `out` actually models a flow-through * step. @@ -1493,34 +1465,29 @@ module MakeImplCommon Lang> { // as soon as we take a reverse local step, forward out flow must be prohibited // in order to prevent time travelling exists(Node n1, Node n2 | - node1.asNodeReverse(_) = n1 and - node2.asNodeReverse(false) = n2 and + node1.asNodeReverse() = n1 and + node2.asNodeReverse() = n2 and simpleLocalFlowStep(pragma[only_bind_into](n2), pragma[only_bind_into](n1), model) and validParameterAliasStep(n2, n1) and not isFlowThroughLocalStep(n2, n1, model) ) or - exists(Node n1, Node n2, boolean allowFwdFlowOut | - node1.asNodeReverse(pragma[only_bind_into](allowFwdFlowOut)) = n1 and + exists(Node n1, Node n2 | + node1.asNode().(PostUpdateNode).getPreUpdateNode() = n1 and + node2.asNode().(PostUpdateNode).getPreUpdateNode() = n2 and isFlowThroughLocalStep(n2, n1, model) and validParameterAliasStep(n2, n1) - | - allowFwdFlowOut = false and - node2.asNodeReverse(pragma[only_bind_into](allowFwdFlowOut)) = n2 - or - allowFwdFlowOut = true and - node2.asNode().(PostUpdateNode).getPreUpdateNode() = n2 ) or - node1.asNode().(PostUpdateNode).getPreUpdateNode() = node2.asNodeReverse(true) and + node1.asNode().(PostUpdateNode).getPreUpdateNode() = node2.asNodeReverse() and model = "" } predicate storeStep(NodeEx node1, Content c, NodeEx node2) { exists(ContentSet cs | c = cs.getAStoreContent() | - exists(Node n1, Node n2, boolean allowFwdFlowOut | - n1 = pragma[only_bind_into](node1.asNodeReverse(allowFwdFlowOut)) and - n2 = pragma[only_bind_into](node2.asNodeReverse(allowFwdFlowOut)) and + exists(Node n1, Node n2 | + n1 = pragma[only_bind_into](node1.asNodeReverse()) and + n2 = pragma[only_bind_into](node2.asNodeReverse()) and Lang::readStep(n2, cs, n1) and // avoid overlap with `storeSet` not exists(PostUpdateNode pn1, PostUpdateNode pn2 | @@ -1533,55 +1500,36 @@ module MakeImplCommon Lang> { predicate readStep(NodeEx node1, ContentSet c, NodeEx node2) { none() and - exists(boolean allowFwdFlowOut | - Lang::storeStep(pragma[only_bind_into](node2.asNodeReverse(allowFwdFlowOut)), c, - pragma[only_bind_into](node1.asNodeReverse(allowFwdFlowOut))) - ) - } - - final class ReverseDataFlowCall extends DataFlowCallEx, TReverseDataFlowCall { - private DataFlowCall call; - private boolean allowFwdFlowOut; - - ReverseDataFlowCall() { this = TReverseDataFlowCall(call, allowFwdFlowOut) } - - override DataFlowCall projectCall() { result = call } - - override string toString() { - exists(string s | - s = call.toString() and - if allowFwdFlowOut = true - then result = s + " [Reverse]" - else result = s + " [Reverse, no out flow]" - ) - } + Lang::storeStep(pragma[only_bind_into](node2.asNodeReverse()), c, + pragma[only_bind_into](node1.asNodeReverse())) } final class ReverseArgNodeEx extends ArgNodeEx { - private ReverseFlow::ReverseDataFlowCall call_; + private DataFlowCall call_; private ArgumentPositionEx pos_; ReverseArgNodeEx() { - exists(DataFlowCall c, boolean allowFwdFlowOut | - call_ = TReverseDataFlowCall(c, allowFwdFlowOut) and - pragma[only_bind_into](this.asNodeReverse(allowFwdFlowOut)) = - getAnOutNode(c, pos_.asReturnKind().(ValueReturnKind).getKind()) - ) + this.asNode().(PostUpdateNode).getPreUpdateNode() = + getAnOutNode(call_, pos_.asReturnKind().(ValueReturnKind).getKind()) } - override predicate argumentOf(DataFlowCallEx call, ArgumentPositionEx pos) { + override predicate argumentOf(DataFlowCall call, ArgumentPositionEx pos) { call = call_ and pos = pos_ } } + final class ReverseNodeEx extends NodeEx, TNodeReverse { + ParameterNode getAParameterNode() { parameterValueFlow(result, this.asNodeReverse(), _) } + } + final class ReverseParamNodeEx extends ParamNodeEx, TNodeReverse { private DataFlowCallable c_; private ParameterPositionEx pos_; ReverseParamNodeEx() { exists(ReturnPosition pos | - pos = getValueReturnPosition(this.asNodeReverse(false)) and + pos = getValueReturnPosition(this.asNodeReverse()) and c_ = pos.getCallable() and pos_.asReturnKind() = pos.getKind() ) @@ -1590,6 +1538,8 @@ module MakeImplCommon Lang> { override predicate isParameterOf(DataFlowCallable c, ParameterPositionEx pos) { c = c_ and pos = pos_ } + + ParameterNode getAParameterNode() { parameterValueFlow(result, this.asNodeReverse(), _) } } } @@ -1603,11 +1553,6 @@ module MakeImplCommon Lang> { cached predicate forceCachingInSameStage() { any() } - cached - newtype TDataFlowCallEx = - TNormalDataFlowCall(DataFlowCall call) or - TReverseDataFlowCall(DataFlowCall call, Boolean allowFwdFlowOut) - cached newtype TArgumentPositionEx = TNormalArgumentPosition(ArgumentPosition pos) or @@ -1694,21 +1639,14 @@ module MakeImplCommon Lang> { } cached - OutNodeEx getAnOutNodeEx(DataFlowCallEx call, ReturnKindExt k) { + OutNodeEx getAnOutNodeEx(DataFlowCall call, ReturnKindExt k) { exists(DataFlowCall c | - c = call.(NormalDataFlowCall).projectCall() and + c = call.(DataFlowCall) and result.asNode() = getAnOutNode(c, k.(ValueReturnKind).getKind()) or exists(ArgNode arg | - arg.argumentOf(c, k.(ParamUpdateReturnKind).getAMatchingArgumentPosition()) - | - call = TReverseDataFlowCall(c, false) and - result.asNodeReverse(_) = arg - or - ( - call = TReverseDataFlowCall(c, true) or - c = call.(NormalDataFlowCall).projectCall() - ) and + arg.argumentOf(c, k.(ParamUpdateReturnKind).getAMatchingArgumentPosition()) and + c = call.(DataFlowCall) and result.asNode().(PostUpdateNode).getPreUpdateNode() = arg ) ) @@ -1934,11 +1872,11 @@ module MakeImplCommon Lang> { * dispatch into account. */ cached - predicate viableParamArgEx(DataFlowCallEx call, ParamNodeEx p, ArgNodeEx arg) { + predicate viableParamArgEx(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg) { // viableParamArg(call, p.asNode(), arg.asNode()) // or exists(ParameterPositionEx ppos, DataFlowCall underlyingCall | - underlyingCall = call.projectCall() and + underlyingCall = call and viableParamEx(underlyingCall, ppos, p) and argumentPositionMatchEx(call, arg, ppos) and compatibleTypesFilter(arg.getDataFlowType(), p.getDataFlowType()) and @@ -1969,9 +1907,9 @@ module MakeImplCommon Lang> { * taking virtual dispatch into account. */ cached - predicate viableReturnPosOutEx(DataFlowCallEx call, ReturnPosition pos, OutNodeEx out) { + predicate viableReturnPosOutEx(DataFlowCall call, ReturnPosition pos, OutNodeEx out) { exists(ReturnKindExt kind | - pos = viableReturnPos(call.projectCall(), kind) and + pos = viableReturnPos(call, kind) and out = kind.getAnOutNodeEx(call) //and // call.toString().matches("%GetBox1%") ) @@ -2026,9 +1964,7 @@ module MakeImplCommon Lang> { } cached - predicate allowParameterReturnInSelfEx(ParamNodeEx p) { - allowParameterReturnInSelf(p.asNodeOrReverse()) - } + predicate allowParameterReturnInSelfEx(ParamNodeEx p) { allowParameterReturnInSelf(p.asNode()) } cached predicate paramMustFlow(ParamNode p, ArgNode arg) { localMustFlowStep+(p, arg) } @@ -2161,15 +2097,7 @@ module MakeImplCommon Lang> { newtype TNodeEx = TNodeNormal(Node n) or TNodeImplicitRead(Node n) or // will be restricted to nodes with actual implicit reads in `DataFlowImpl.qll` - TNodeReverse(Node n, Boolean allowFwdFlowOut) { - ( - allowFwdFlowOut = false and - ReverseFlow::parameterValueFlow(_, n) - or - allowFwdFlowOut = true and - n = any(PostUpdateNode p).getPreUpdateNode() - ) - } + TNodeReverse(Node n) { ReverseFlow::parameterValueFlow(_, n, _) } /** * Holds if data can flow in one local step from `node1` to `node2`. @@ -2189,7 +2117,7 @@ module MakeImplCommon Lang> { ReturnPosition getReturnPositionEx(NodeEx ret) { result = getValueReturnPosition(ret.asNode()) or - result = getParamReturnPosition(ret.asNodeReverse(_)) + result = getParamReturnPosition(ret.asNodeReverse()) } } @@ -2723,7 +2651,7 @@ module MakeImplCommon Lang> { abstract string toString(); /** Gets a node corresponding to data flow out of `call`. */ - final OutNodeEx getAnOutNodeEx(DataFlowCallEx call) { result = getAnOutNodeEx(call, this) } + final OutNodeEx getAnOutNodeEx(DataFlowCall call) { result = getAnOutNodeEx(call, this) } } class ValueReturnKind extends ReturnKindExt, TValueReturn {