Swift: support array keypath reads in dataflow

This commit is contained in:
Robert Marsh
2023-07-17 18:05:06 +00:00
parent 0b35be284e
commit 169326ffe5
3 changed files with 23 additions and 5 deletions

View File

@@ -757,10 +757,13 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
)
or
// read of a component in a key-path expression chain
exists(KeyPathComponent component, FieldDecl f |
exists(KeyPathComponent component|
component = node1.(KeyPathComponentNodeImpl).getComponent() and
f = component.getDeclRef() and
c.isSingleton(any(Content::FieldContent ct | ct.getField() = f))
(
c.isSingleton(any(Content::FieldContent ct | ct.getField() = component.getDeclRef()))
or
c.isSingleton(any(Content::ArrayContent ac))
)
|
// the next node is either the next element in the chain
node2.(KeyPathComponentNodeImpl).getComponent() = component.getNextComponent()

View File

@@ -269,6 +269,12 @@ edges
| test.swift:592:17:592:17 | KeyPathComponent [x] | test.swift:592:11:592:17 | exit #keyPath(...) |
| test.swift:593:13:593:13 | s2 [s, x] | test.swift:592:11:592:17 | enter #keyPath(...) [s, x] |
| test.swift:593:13:593:13 | s2 [s, x] | test.swift:593:13:593:26 | \\...[...] |
| test.swift:597:17:597:26 | [...] [Array element] | test.swift:599:15:599:15 | array [Array element] |
| test.swift:597:18:597:25 | call to source() | test.swift:597:17:597:26 | [...] [Array element] |
| test.swift:598:13:598:22 | enter #keyPath(...) [Array element] | test.swift:598:20:598:22 | KeyPathComponent [Array element] |
| test.swift:598:20:598:22 | KeyPathComponent [Array element] | test.swift:598:13:598:22 | exit #keyPath(...) |
| test.swift:599:15:599:15 | array [Array element] | test.swift:598:13:598:22 | enter #keyPath(...) [Array element] |
| test.swift:599:15:599:15 | array [Array element] | test.swift:599:15:599:31 | \\...[...] |
| test.swift:618:13:618:20 | call to source() | test.swift:626:15:626:15 | y |
| test.swift:628:9:628:16 | call to source() | test.swift:630:10:630:11 | &... |
| test.swift:628:9:628:16 | call to source() | test.swift:631:15:631:15 | x |
@@ -579,6 +585,13 @@ nodes
| test.swift:592:17:592:17 | KeyPathComponent [x] | semmle.label | KeyPathComponent [x] |
| test.swift:593:13:593:13 | s2 [s, x] | semmle.label | s2 [s, x] |
| test.swift:593:13:593:26 | \\...[...] | semmle.label | \\...[...] |
| test.swift:597:17:597:26 | [...] [Array element] | semmle.label | [...] [Array element] |
| test.swift:597:18:597:25 | call to source() | semmle.label | call to source() |
| test.swift:598:13:598:22 | enter #keyPath(...) [Array element] | semmle.label | enter #keyPath(...) [Array element] |
| test.swift:598:13:598:22 | exit #keyPath(...) | semmle.label | exit #keyPath(...) |
| test.swift:598:20:598:22 | KeyPathComponent [Array element] | semmle.label | KeyPathComponent [Array element] |
| test.swift:599:15:599:15 | array [Array element] | semmle.label | array [Array element] |
| test.swift:599:15:599:31 | \\...[...] | semmle.label | \\...[...] |
| test.swift:618:13:618:20 | call to source() | semmle.label | call to source() |
| test.swift:626:15:626:15 | y | semmle.label | y |
| test.swift:628:9:628:16 | call to source() | semmle.label | call to source() |
@@ -639,6 +652,7 @@ subpaths
| test.swift:590:16:590:23 | call to source() | test.swift:567:8:567:11 | x | test.swift:567:3:569:3 | self[return] [x] | test.swift:590:11:590:24 | call to S.init(x:) [x] |
| test.swift:591:18:591:18 | s [x] | test.swift:584:8:584:11 | s [x] | test.swift:584:3:586:3 | self[return] [s, x] | test.swift:591:12:591:19 | call to S2.init(s:) [s, x] |
| test.swift:593:13:593:13 | s2 [s, x] | test.swift:592:11:592:17 | enter #keyPath(...) [s, x] | test.swift:592:11:592:17 | exit #keyPath(...) | test.swift:593:13:593:26 | \\...[...] |
| test.swift:599:15:599:15 | array [Array element] | test.swift:598:13:598:22 | enter #keyPath(...) [Array element] | test.swift:598:13:598:22 | exit #keyPath(...) | test.swift:599:15:599:31 | \\...[...] |
#select
| test.swift:7:15:7:15 | t1 | test.swift:6:19:6:26 | call to source() | test.swift:7:15:7:15 | t1 | result |
| test.swift:9:15:9:15 | t1 | test.swift:6:19:6:26 | call to source() | test.swift:9:15:9:15 | t1 | result |
@@ -712,6 +726,7 @@ subpaths
| test.swift:575:13:575:25 | \\...[...] | test.swift:573:16:573:23 | call to source() | test.swift:575:13:575:25 | \\...[...] | result |
| test.swift:578:13:578:32 | \\...[...] | test.swift:573:16:573:23 | call to source() | test.swift:578:13:578:32 | \\...[...] | result |
| test.swift:593:13:593:26 | \\...[...] | test.swift:590:16:590:23 | call to source() | test.swift:593:13:593:26 | \\...[...] | result |
| test.swift:599:15:599:31 | \\...[...] | test.swift:597:18:597:25 | call to source() | test.swift:599:15:599:31 | \\...[...] | result |
| test.swift:626:15:626:15 | y | test.swift:618:13:618:20 | call to source() | test.swift:626:15:626:15 | y | result |
| test.swift:631:15:631:15 | x | test.swift:628:9:628:16 | call to source() | test.swift:631:15:631:15 | x | result |
| test.swift:632:15:632:15 | y | test.swift:628:9:628:16 | call to source() | test.swift:632:15:632:15 | y | result |

View File

@@ -596,7 +596,7 @@ func testNestedKeyPath() {
func testArrayKeyPath() {
let array = [source()]
let f = \[Int].[0]
sink(arg: array[keyPath: f]) // $ MISSING: flow=597
sink(arg: array[keyPath: f]) // $ flow=597
}
struct S2_Optional {
@@ -656,5 +656,5 @@ func testArray() {
var arr6 = [1,2,3]
arr6.insert(source(), at: 2)
sink(arg: arr6)
sink(arg: arr6) // $ MISSING: flow=658
}