Skip to content

Commit 89e7b75

Browse files
committed
Swift: Flow from optional content through "!".
1 parent d9187c6 commit 89e7b75

File tree

3 files changed

+58
-3
lines changed

3 files changed

+58
-3
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@ private module Cached {
170170
nodeFrom.asExpr() = nodeTo.asExpr().(AnyTryExpr).getSubExpr()
171171
or
172172
// flow through `!`
173+
// note: there's a case in `readStep` that handles when the source is the
174+
// `OptionalSomeContentSet` within the RHS. This case is for when the
175+
// `Optional` itself is tainted (which it usually shouldn't be, but
176+
// retaining this case increases robustness of flow).
173177
nodeFrom.asExpr() = nodeTo.asExpr().(ForceValueExpr).getSubExpr()
174178
or
175179
// flow through `?` and `?.`
@@ -725,6 +729,10 @@ predicate readStep(Node node1, ContentSet c, Node node2) {
725729
)
726730
)
727731
or
732+
// read of an enum (`Optional.Some`) member via `!`
733+
node1.asExpr() = node2.asExpr().(ForceValueExpr).getSubExpr() and
734+
c instanceof OptionalSomeContentSet
735+
or
728736
// read of a tuple member via `case let (v1, v2)` pattern matching
729737
exists(TuplePattern tupPat, int idx, Pattern subPat |
730738
node1.asPattern() = tupPat and

swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,23 @@ edges
115115
| test.swift:263:13:263:28 | call to optionalSource() | test.swift:280:15:280:38 | ... ? ... : ... |
116116
| test.swift:263:13:263:28 | call to optionalSource() | test.swift:291:16:291:17 | ...? |
117117
| test.swift:263:13:263:28 | call to optionalSource() | test.swift:303:15:303:16 | ...! |
118+
| test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:267:15:267:15 | x [some:0] |
119+
| test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:279:26:279:26 | x [some:0] |
120+
| test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:280:26:280:26 | x [some:0] |
118121
| test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:284:8:284:12 | let ...? [some:0] |
119122
| test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:291:16:291:17 | ...? [some:0] |
120123
| test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:298:11:298:15 | let ...? [some:0] |
124+
| test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:303:15:303:15 | x [some:0] |
121125
| test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:306:13:306:24 | .some(...) [some:0] |
122126
| test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:314:10:314:21 | .some(...) [some:0] |
127+
| test.swift:267:15:267:15 | x [some:0] | test.swift:267:15:267:16 | ...! |
123128
| test.swift:270:15:270:22 | call to source() | test.swift:270:15:270:31 | call to signum() |
124129
| test.swift:271:15:271:16 | ...? | test.swift:271:15:271:25 | call to signum() |
125130
| test.swift:271:15:271:25 | call to signum() | test.swift:271:15:271:25 | OptionalEvaluationExpr |
131+
| test.swift:279:26:279:26 | x [some:0] | test.swift:279:26:279:27 | ...! |
132+
| test.swift:279:26:279:27 | ...! | test.swift:279:15:279:31 | ... ? ... : ... |
133+
| test.swift:280:26:280:26 | x [some:0] | test.swift:280:26:280:27 | ...! |
134+
| test.swift:280:26:280:27 | ...! | test.swift:280:15:280:38 | ... ? ... : ... |
126135
| test.swift:280:31:280:38 | call to source() | test.swift:280:15:280:38 | ... ? ... : ... |
127136
| test.swift:282:31:282:38 | call to source() | test.swift:282:15:282:38 | ... ? ... : ... |
128137
| test.swift:284:8:284:12 | let ...? [some:0] | test.swift:284:12:284:12 | z |
@@ -135,6 +144,7 @@ edges
135144
| test.swift:291:16:291:26 | call to signum() [some:0] | test.swift:291:8:291:12 | let ...? [some:0] |
136145
| test.swift:298:11:298:15 | let ...? [some:0] | test.swift:298:15:298:15 | z1 |
137146
| test.swift:298:15:298:15 | z1 | test.swift:300:15:300:15 | z1 |
147+
| test.swift:303:15:303:15 | x [some:0] | test.swift:303:15:303:16 | ...! |
138148
| test.swift:303:15:303:16 | ...! | test.swift:303:15:303:25 | call to signum() |
139149
| test.swift:306:13:306:24 | .some(...) [some:0] | test.swift:306:23:306:23 | z |
140150
| test.swift:306:23:306:23 | z | test.swift:307:19:307:19 | z |
@@ -164,6 +174,8 @@ edges
164174
| test.swift:361:15:361:15 | t2 [Tuple element at index 1] | test.swift:361:15:361:18 | .1 |
165175
| test.swift:375:16:375:21 | v | test.swift:375:61:375:61 | v |
166176
| test.swift:375:61:375:61 | v | test.swift:375:45:375:62 | call to ... [mySingle:0] |
177+
| test.swift:377:18:377:23 | v | test.swift:377:59:377:59 | v |
178+
| test.swift:377:59:377:59 | v | test.swift:377:45:377:60 | call to ... [some:0] |
167179
| test.swift:403:9:403:27 | call to ... [mySingle:0] | test.swift:408:10:408:25 | .mySingle(...) [mySingle:0] |
168180
| test.swift:403:9:403:27 | call to ... [mySingle:0] | test.swift:417:13:417:28 | .mySingle(...) [mySingle:0] |
169181
| test.swift:403:19:403:26 | call to source() | test.swift:403:9:403:27 | call to ... [mySingle:0] |
@@ -218,6 +230,16 @@ edges
218230
| test.swift:496:33:496:33 | d4 | test.swift:496:54:496:54 | d4 |
219231
| test.swift:498:13:498:35 | .mySingle(...) [mySingle:0] | test.swift:498:33:498:33 | d6 |
220232
| test.swift:498:33:498:33 | d6 | test.swift:498:54:498:54 | d6 |
233+
| test.swift:501:14:501:36 | call to ... [some:0] | test.swift:507:15:507:15 | e2 [some:0] |
234+
| test.swift:501:28:501:35 | call to source() | test.swift:501:14:501:36 | call to ... [some:0] |
235+
| test.swift:503:14:503:34 | call to mkOptional1(_:) [some:0] | test.swift:509:15:509:15 | e4 [some:0] |
236+
| test.swift:503:26:503:33 | call to source() | test.swift:377:18:377:23 | v |
237+
| test.swift:503:26:503:33 | call to source() | test.swift:503:14:503:34 | call to mkOptional1(_:) [some:0] |
238+
| test.swift:505:14:505:34 | call to mkOptional2(_:) [some:0] | test.swift:511:15:511:15 | e6 [some:0] |
239+
| test.swift:505:26:505:33 | call to source() | test.swift:505:14:505:34 | call to mkOptional2(_:) [some:0] |
240+
| test.swift:507:15:507:15 | e2 [some:0] | test.swift:507:15:507:17 | ...! |
241+
| test.swift:509:15:509:15 | e4 [some:0] | test.swift:509:15:509:17 | ...! |
242+
| test.swift:511:15:511:15 | e6 [some:0] | test.swift:511:15:511:17 | ...! |
221243
| test.swift:517:13:517:28 | call to optionalSource() [some:0] | test.swift:519:8:519:12 | let ...? [some:0] |
222244
| test.swift:517:13:517:28 | call to optionalSource() [some:0] | test.swift:524:19:524:19 | x [some:0] |
223245
| test.swift:519:8:519:12 | let ...? [some:0] | test.swift:519:12:519:12 | a |
@@ -410,6 +432,7 @@ nodes
410432
| test.swift:263:13:263:28 | call to optionalSource() | semmle.label | call to optionalSource() |
411433
| test.swift:263:13:263:28 | call to optionalSource() [some:0] | semmle.label | call to optionalSource() [some:0] |
412434
| test.swift:265:15:265:15 | x | semmle.label | x |
435+
| test.swift:267:15:267:15 | x [some:0] | semmle.label | x [some:0] |
413436
| test.swift:267:15:267:16 | ...! | semmle.label | ...! |
414437
| test.swift:270:15:270:22 | call to source() | semmle.label | call to source() |
415438
| test.swift:270:15:270:31 | call to signum() | semmle.label | call to signum() |
@@ -419,7 +442,11 @@ nodes
419442
| test.swift:274:15:274:20 | ... ??(_:_:) ... | semmle.label | ... ??(_:_:) ... |
420443
| test.swift:275:15:275:27 | ... ??(_:_:) ... | semmle.label | ... ??(_:_:) ... |
421444
| test.swift:279:15:279:31 | ... ? ... : ... | semmle.label | ... ? ... : ... |
445+
| test.swift:279:26:279:26 | x [some:0] | semmle.label | x [some:0] |
446+
| test.swift:279:26:279:27 | ...! | semmle.label | ...! |
422447
| test.swift:280:15:280:38 | ... ? ... : ... | semmle.label | ... ? ... : ... |
448+
| test.swift:280:26:280:26 | x [some:0] | semmle.label | x [some:0] |
449+
| test.swift:280:26:280:27 | ...! | semmle.label | ...! |
423450
| test.swift:280:31:280:38 | call to source() | semmle.label | call to source() |
424451
| test.swift:282:15:282:38 | ... ? ... : ... | semmle.label | ... ? ... : ... |
425452
| test.swift:282:31:282:38 | call to source() | semmle.label | call to source() |
@@ -436,6 +463,7 @@ nodes
436463
| test.swift:298:11:298:15 | let ...? [some:0] | semmle.label | let ...? [some:0] |
437464
| test.swift:298:15:298:15 | z1 | semmle.label | z1 |
438465
| test.swift:300:15:300:15 | z1 | semmle.label | z1 |
466+
| test.swift:303:15:303:15 | x [some:0] | semmle.label | x [some:0] |
439467
| test.swift:303:15:303:16 | ...! | semmle.label | ...! |
440468
| test.swift:303:15:303:25 | call to signum() | semmle.label | call to signum() |
441469
| test.swift:306:13:306:24 | .some(...) [some:0] | semmle.label | .some(...) [some:0] |
@@ -473,6 +501,9 @@ nodes
473501
| test.swift:375:16:375:21 | v | semmle.label | v |
474502
| test.swift:375:45:375:62 | call to ... [mySingle:0] | semmle.label | call to ... [mySingle:0] |
475503
| test.swift:375:61:375:61 | v | semmle.label | v |
504+
| test.swift:377:18:377:23 | v | semmle.label | v |
505+
| test.swift:377:45:377:60 | call to ... [some:0] | semmle.label | call to ... [some:0] |
506+
| test.swift:377:59:377:59 | v | semmle.label | v |
476507
| test.swift:403:9:403:27 | call to ... [mySingle:0] | semmle.label | call to ... [mySingle:0] |
477508
| test.swift:403:19:403:26 | call to source() | semmle.label | call to source() |
478509
| test.swift:408:10:408:25 | .mySingle(...) [mySingle:0] | semmle.label | .mySingle(...) [mySingle:0] |
@@ -532,6 +563,18 @@ nodes
532563
| test.swift:498:13:498:35 | .mySingle(...) [mySingle:0] | semmle.label | .mySingle(...) [mySingle:0] |
533564
| test.swift:498:33:498:33 | d6 | semmle.label | d6 |
534565
| test.swift:498:54:498:54 | d6 | semmle.label | d6 |
566+
| test.swift:501:14:501:36 | call to ... [some:0] | semmle.label | call to ... [some:0] |
567+
| test.swift:501:28:501:35 | call to source() | semmle.label | call to source() |
568+
| test.swift:503:14:503:34 | call to mkOptional1(_:) [some:0] | semmle.label | call to mkOptional1(_:) [some:0] |
569+
| test.swift:503:26:503:33 | call to source() | semmle.label | call to source() |
570+
| test.swift:505:14:505:34 | call to mkOptional2(_:) [some:0] | semmle.label | call to mkOptional2(_:) [some:0] |
571+
| test.swift:505:26:505:33 | call to source() | semmle.label | call to source() |
572+
| test.swift:507:15:507:15 | e2 [some:0] | semmle.label | e2 [some:0] |
573+
| test.swift:507:15:507:17 | ...! | semmle.label | ...! |
574+
| test.swift:509:15:509:15 | e4 [some:0] | semmle.label | e4 [some:0] |
575+
| test.swift:509:15:509:17 | ...! | semmle.label | ...! |
576+
| test.swift:511:15:511:15 | e6 [some:0] | semmle.label | e6 [some:0] |
577+
| test.swift:511:15:511:17 | ...! | semmle.label | ...! |
535578
| test.swift:517:13:517:28 | call to optionalSource() [some:0] | semmle.label | call to optionalSource() [some:0] |
536579
| test.swift:519:8:519:12 | let ...? [some:0] | semmle.label | let ...? [some:0] |
537580
| test.swift:519:12:519:12 | a | semmle.label | a |
@@ -634,6 +677,7 @@ subpaths
634677
| test.swift:219:13:219:13 | b [a, x] | test.swift:185:7:185:7 | self [a, x] | file://:0:0:0:0 | .a [x] | test.swift:219:13:219:15 | .a [x] |
635678
| test.swift:219:13:219:15 | .a [x] | test.swift:163:7:163:7 | self [x] | file://:0:0:0:0 | .x | test.swift:219:13:219:17 | .x |
636679
| test.swift:490:24:490:31 | call to source() | test.swift:375:16:375:21 | v | test.swift:375:45:375:62 | call to ... [mySingle:0] | test.swift:490:14:490:32 | call to mkMyEnum1(_:) [mySingle:0] |
680+
| test.swift:503:26:503:33 | call to source() | test.swift:377:18:377:23 | v | test.swift:377:45:377:60 | call to ... [some:0] | test.swift:503:14:503:34 | call to mkOptional1(_:) [some:0] |
637681
| test.swift:546:12:546:12 | x [some:0] | test.swift:540:9:540:9 | value [some:0] | file://:0:0:0:0 | [post] self [x, some:0] | test.swift:546:5:546:5 | [post] cx [x, some:0] |
638682
| test.swift:550:20:550:20 | cx [x, some:0] | test.swift:540:9:540:9 | self [x, some:0] | file://:0:0:0:0 | .x [some:0] | test.swift:550:20:550:23 | .x [some:0] |
639683
| test.swift:574:20:574:28 | call to source3() | test.swift:567:10:567:13 | s | test.swift:568:7:568:7 | [post] self [str] | test.swift:574:7:574:7 | [post] self [str] |
@@ -711,6 +755,9 @@ subpaths
711755
| test.swift:494:54:494:54 | d2 | test.swift:488:30:488:37 | call to source() | test.swift:494:54:494:54 | d2 | result |
712756
| test.swift:496:54:496:54 | d4 | test.swift:490:24:490:31 | call to source() | test.swift:496:54:496:54 | d4 | result |
713757
| test.swift:498:54:498:54 | d6 | test.swift:492:24:492:31 | call to source() | test.swift:498:54:498:54 | d6 | result |
758+
| test.swift:507:15:507:17 | ...! | test.swift:501:28:501:35 | call to source() | test.swift:507:15:507:17 | ...! | result |
759+
| test.swift:509:15:509:17 | ...! | test.swift:503:26:503:33 | call to source() | test.swift:509:15:509:17 | ...! | result |
760+
| test.swift:511:15:511:17 | ...! | test.swift:505:26:505:33 | call to source() | test.swift:511:15:511:17 | ...! | result |
714761
| test.swift:520:19:520:19 | a | test.swift:259:12:259:19 | call to source() | test.swift:520:19:520:19 | a | result |
715762
| test.swift:527:19:527:19 | a | test.swift:259:12:259:19 | call to source() | test.swift:527:19:527:19 | a | result |
716763
| test.swift:551:15:551:15 | z1 | test.swift:259:12:259:19 | call to source() | test.swift:551:15:551:15 | z1 | result |

swift/ql/test/library-tests/dataflow/dataflow/test.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -504,11 +504,11 @@ func testEnums() {
504504
let e5 = mkOptional2(0)
505505
let e6 = mkOptional2(source())
506506
sink(arg: e1!)
507-
sink(arg: e2!) // $ MISSING: flow=501
507+
sink(arg: e2!) // $ flow=501
508508
sink(arg: e3!)
509-
sink(arg: e4!) // $ MISSING: flow=503
509+
sink(arg: e4!) // $ flow=503
510510
sink(arg: e5!)
511-
sink(arg: e6!) // $ MISSING: flow=505
511+
sink(arg: e6!) // $ flow=505
512512
}
513513

514514
func source2() -> (Int, Int)? { return nil }

0 commit comments

Comments
 (0)