Skip to content

Commit 175a8a6

Browse files
authored
Merge pull request github#14865 from rdmarsh2/rdmarsh2/swift/correct-keypath-node-steps
Swift: move keypath dataflow writes to fix types
2 parents 971ced0 + 9ac46d4 commit 175a8a6

File tree

3 files changed

+72
-70
lines changed

3 files changed

+72
-70
lines changed

swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -278,13 +278,19 @@ private module Cached {
278278
nodeFrom.asPattern().(TypedPattern).getSubPattern()
279279
]
280280
or
281-
// Flow from the unique parameter of a key path expression to
282-
// the first component in the chain.
283-
nodeTo.(KeyPathComponentNodeImpl).getComponent() =
284-
nodeFrom.(KeyPathParameterNode).getComponent(0)
281+
// Flow from the last component in a key path chain to
282+
// the return node for the key path.
283+
exists(KeyPathExpr keyPath |
284+
nodeFrom.(KeyPathComponentNodeImpl).getComponent() =
285+
keyPath.getComponent(keyPath.getNumberOfComponents() - 1) and
286+
nodeTo.(KeyPathReturnNodeImpl).getKeyPathExpr() = keyPath
287+
)
285288
or
286-
nodeFrom.(KeyPathComponentPostUpdateNode).getComponent() =
287-
nodeTo.(KeyPathParameterPostUpdateNode).getComponent(0)
289+
exists(KeyPathExpr keyPath |
290+
nodeTo.(KeyPathComponentPostUpdateNode).getComponent() =
291+
keyPath.getComponent(keyPath.getNumberOfComponents() - 1) and
292+
nodeFrom.(KeyPathReturnPostUpdateNode).getKeyPathExpr() = keyPath
293+
)
288294
or
289295
// Flow to the result of a keypath assignment
290296
exists(KeyPathApplicationExpr apply, AssignExpr assign |
@@ -1085,8 +1091,8 @@ predicate storeStep(Node node1, ContentSet c, Node node2) {
10851091
// creation of an optional via implicit wrapping keypath component
10861092
exists(KeyPathComponent component |
10871093
component.isOptionalWrapping() and
1088-
node1.(KeyPathComponentNodeImpl).getComponent() = component and
1089-
node2.(KeyPathReturnNodeImpl).getKeyPathExpr() = component.getKeyPathExpr() and
1094+
node1.(KeyPathComponentNodeImpl).getComponent().getNextComponent() = component and
1095+
node2.(KeyPathComponentNodeImpl).getComponent() = component and
10901096
c instanceof OptionalSomeContentSet
10911097
)
10921098
or
@@ -1174,7 +1180,13 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
11741180
or
11751181
// read of a component in a key-path expression chain
11761182
exists(KeyPathComponent component |
1177-
component = node1.(KeyPathComponentNodeImpl).getComponent() and
1183+
// the first node is either the previous element in the chain
1184+
node1.(KeyPathComponentNodeImpl).getComponent().getNextComponent() = component
1185+
or
1186+
// or the start node, if this is the first component in the chain
1187+
component = node1.(KeyPathParameterNode).getComponent(0)
1188+
|
1189+
component = node2.(KeyPathComponentNodeImpl).getComponent() and
11781190
(
11791191
c.isSingleton(any(Content::FieldContent ct | ct.getField() = component.getDeclRef()))
11801192
or
@@ -1188,13 +1200,6 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
11881200
component.isOptionalChaining()
11891201
)
11901202
)
1191-
|
1192-
// the next node is either the next element in the chain
1193-
node2.(KeyPathComponentNodeImpl).getComponent() = component.getNextComponent()
1194-
or
1195-
// or the return node, if this is the last component in the chain
1196-
not exists(component.getNextComponent()) and
1197-
node2.(KeyPathReturnNodeImpl).getKeyPathExpr() = component.getKeyPathExpr()
11981203
)
11991204
or
12001205
// read of array or collection content via subscript operator

0 commit comments

Comments
 (0)