Skip to content

Commit 686f7cc

Browse files
committed
Swift: add flow for self out of constructors
1 parent 9731989 commit 686f7cc

File tree

5 files changed

+74
-5
lines changed

5 files changed

+74
-5
lines changed

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,29 @@ private module ReturnNodes {
399399
override ReturnKind getKind() { result instanceof NormalReturnKind }
400400
}
401401

402+
class SelfReturnNode extends ReturnNode, TInoutReturnNode, NodeImpl {
403+
SelfParamDecl param;
404+
ControlFlowNode exit;
405+
SelfReturnNode() {
406+
this = TInoutReturnNode(param) and
407+
exit instanceof ExitNode and
408+
exit.getScope() = param.getDeclaringFunction() and
409+
param.getDeclaringFunction() instanceof ConstructorDecl
410+
}
411+
override ControlFlowNode getCfgNode() { result = exit }
412+
413+
override DataFlowCallable getEnclosingCallable() {
414+
result = TDataFlowFunc(param.getDeclaringFunction())
415+
}
416+
417+
ParamDecl getParameter() { result = param }
418+
419+
override Location getLocationImpl() { result = exit.getLocation() }
420+
421+
override string toStringImpl() { result = param.toString() + "[constructor return]" }
422+
override ReturnKind getKind() { result instanceof NormalReturnKind }
423+
}
424+
402425
class InoutReturnNodeImpl extends ReturnNode, TInoutReturnNode, NodeImpl {
403426
ParamDecl param;
404427
ControlFlowNode exit;

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

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
edges
22
| file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : |
33
| file://:0:0:0:0 | self [a, x] : | file://:0:0:0:0 | .a [x] : |
4+
| file://:0:0:0:0 | self [str] : | file://:0:0:0:0 | .str : |
45
| file://:0:0:0:0 | self [x] : | file://:0:0:0:0 | .x : |
56
| file://:0:0:0:0 | self [x] : | file://:0:0:0:0 | .x : |
67
| file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [x] : |
@@ -155,22 +156,36 @@ edges
155156
| test.swift:472:20:472:20 | cx [x] : | test.swift:472:20:472:23 | .x : |
156157
| test.swift:472:20:472:23 | .x : | test.swift:473:15:473:15 | z1 |
157158
| test.swift:479:14:479:21 | call to source() : | test.swift:479:13:479:21 | call to +(_:) |
159+
| test.swift:488:9:488:9 | self [str] : | file://:0:0:0:0 | self [str] : |
158160
| test.swift:489:10:489:13 | s : | test.swift:490:13:490:13 | s : |
161+
| test.swift:490:7:490:7 | [post] self [str] : | test.swift:489:5:491:5 | self[constructor return] [str] : |
159162
| test.swift:490:7:490:7 | [post] self [str] : | test.swift:489:5:491:5 | self[return] [str] : |
160163
| test.swift:490:13:490:13 | s : | test.swift:490:7:490:7 | [post] self [str] : |
164+
| test.swift:495:17:498:5 | self[constructor return] [str] : | test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : |
165+
| test.swift:495:17:498:5 | self[return] [str] : | test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : |
166+
| test.swift:496:7:496:7 | [post] self [str] : | test.swift:495:17:498:5 | self[constructor return] [str] : |
167+
| test.swift:496:7:496:7 | [post] self [str] : | test.swift:495:17:498:5 | self[return] [str] : |
161168
| test.swift:496:7:496:7 | [post] self [str] : | test.swift:497:17:497:17 | self [str] : |
162169
| test.swift:496:20:496:28 | call to source3() : | test.swift:489:10:489:13 | s : |
163170
| test.swift:496:20:496:28 | call to source3() : | test.swift:496:7:496:7 | [post] self [str] : |
164171
| test.swift:497:17:497:17 | self [str] : | test.swift:497:17:497:17 | .str |
172+
| test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | test.swift:488:9:488:9 | self [str] : |
173+
| test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | test.swift:502:13:502:35 | .str |
174+
| test.swift:502:24:502:32 | call to source3() : | test.swift:489:10:489:13 | s : |
175+
| test.swift:502:24:502:32 | call to source3() : | test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : |
176+
| test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | test.swift:488:9:488:9 | self [str] : |
177+
| test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | test.swift:503:13:503:43 | .str |
165178
nodes
166179
| file://:0:0:0:0 | .a [x] : | semmle.label | .a [x] : |
180+
| file://:0:0:0:0 | .str : | semmle.label | .str : |
167181
| file://:0:0:0:0 | .x : | semmle.label | .x : |
168182
| file://:0:0:0:0 | .x : | semmle.label | .x : |
169183
| file://:0:0:0:0 | [post] self [x] : | semmle.label | [post] self [x] : |
170184
| file://:0:0:0:0 | [post] self [x] : | semmle.label | [post] self [x] : |
171185
| file://:0:0:0:0 | [summary param] this in signum() : | semmle.label | [summary param] this in signum() : |
172186
| file://:0:0:0:0 | [summary] to write: return (return) in signum() : | semmle.label | [summary] to write: return (return) in signum() : |
173187
| file://:0:0:0:0 | self [a, x] : | semmle.label | self [a, x] : |
188+
| file://:0:0:0:0 | self [str] : | semmle.label | self [str] : |
174189
| file://:0:0:0:0 | self [x] : | semmle.label | self [x] : |
175190
| file://:0:0:0:0 | self [x] : | semmle.label | self [x] : |
176191
| file://:0:0:0:0 | value : | semmle.label | value : |
@@ -335,14 +350,27 @@ nodes
335350
| test.swift:479:13:479:21 | call to +(_:) | semmle.label | call to +(_:) |
336351
| test.swift:479:14:479:21 | call to source() : | semmle.label | call to source() : |
337352
| test.swift:480:14:480:21 | call to source() | semmle.label | call to source() |
353+
| test.swift:488:9:488:9 | self [str] : | semmle.label | self [str] : |
354+
| test.swift:489:5:491:5 | self[constructor return] [str] : | semmle.label | self[constructor return] [str] : |
355+
| test.swift:489:5:491:5 | self[constructor return] [str] : | semmle.label | self[return] [str] : |
356+
| test.swift:489:5:491:5 | self[return] [str] : | semmle.label | self[constructor return] [str] : |
338357
| test.swift:489:5:491:5 | self[return] [str] : | semmle.label | self[return] [str] : |
339358
| test.swift:489:10:489:13 | s : | semmle.label | s : |
340359
| test.swift:490:7:490:7 | [post] self [str] : | semmle.label | [post] self [str] : |
341360
| test.swift:490:13:490:13 | s : | semmle.label | s : |
361+
| test.swift:495:17:498:5 | self[constructor return] [str] : | semmle.label | self[constructor return] [str] : |
362+
| test.swift:495:17:498:5 | self[constructor return] [str] : | semmle.label | self[return] [str] : |
363+
| test.swift:495:17:498:5 | self[return] [str] : | semmle.label | self[constructor return] [str] : |
364+
| test.swift:495:17:498:5 | self[return] [str] : | semmle.label | self[return] [str] : |
342365
| test.swift:496:7:496:7 | [post] self [str] : | semmle.label | [post] self [str] : |
343366
| test.swift:496:20:496:28 | call to source3() : | semmle.label | call to source3() : |
344367
| test.swift:497:17:497:17 | .str | semmle.label | .str |
345368
| test.swift:497:17:497:17 | self [str] : | semmle.label | self [str] : |
369+
| test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | semmle.label | call to MyClass.init(s:) [str] : |
370+
| test.swift:502:13:502:35 | .str | semmle.label | .str |
371+
| test.swift:502:24:502:32 | call to source3() : | semmle.label | call to source3() : |
372+
| test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | semmle.label | call to Self.init(contentsOfFile:) [str] : |
373+
| test.swift:503:13:503:43 | .str | semmle.label | .str |
346374
subpaths
347375
| test.swift:75:21:75:22 | &... : | test.swift:65:16:65:28 | arg1 : | test.swift:65:1:70:1 | arg2[return] : | test.swift:75:31:75:32 | [post] &... : |
348376
| test.swift:114:19:114:19 | arg : | test.swift:109:9:109:14 | arg : | test.swift:110:12:110:12 | arg : | test.swift:114:12:114:22 | call to ... : |
@@ -375,8 +403,13 @@ subpaths
375403
| test.swift:303:15:303:16 | ...! : | file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | test.swift:303:15:303:25 | call to signum() |
376404
| test.swift:468:12:468:12 | x : | test.swift:462:9:462:9 | value : | file://:0:0:0:0 | [post] self [x] : | test.swift:468:5:468:5 | [post] cx [x] : |
377405
| test.swift:472:20:472:20 | cx [x] : | test.swift:462:9:462:9 | self [x] : | file://:0:0:0:0 | .x : | test.swift:472:20:472:23 | .x : |
406+
| test.swift:496:20:496:28 | call to source3() : | test.swift:489:10:489:13 | s : | test.swift:489:5:491:5 | self[constructor return] [str] : | test.swift:496:7:496:7 | [post] self [str] : |
378407
| test.swift:496:20:496:28 | call to source3() : | test.swift:489:10:489:13 | s : | test.swift:489:5:491:5 | self[return] [str] : | test.swift:496:7:496:7 | [post] self [str] : |
379408
| test.swift:496:20:496:28 | call to source3() : | test.swift:489:10:489:13 | s : | test.swift:490:7:490:7 | [post] self [str] : | test.swift:496:7:496:7 | [post] self [str] : |
409+
| test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | test.swift:488:9:488:9 | self [str] : | file://:0:0:0:0 | .str : | test.swift:502:13:502:35 | .str |
410+
| test.swift:502:24:502:32 | call to source3() : | test.swift:489:10:489:13 | s : | test.swift:489:5:491:5 | self[constructor return] [str] : | test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : |
411+
| test.swift:502:24:502:32 | call to source3() : | test.swift:489:10:489:13 | s : | test.swift:489:5:491:5 | self[return] [str] : | test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : |
412+
| test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | test.swift:488:9:488:9 | self [str] : | file://:0:0:0:0 | .str : | test.swift:503:13:503:43 | .str |
380413
#select
381414
| test.swift:7:15:7:15 | t1 | test.swift:6:19:6:26 | call to source() : | test.swift:7:15:7:15 | t1 | result |
382415
| test.swift:9:15:9:15 | t1 | test.swift:6:19:6:26 | call to source() : | test.swift:9:15:9:15 | t1 | result |
@@ -432,3 +465,5 @@ subpaths
432465
| test.swift:479:13:479:21 | call to +(_:) | test.swift:479:14:479:21 | call to source() : | test.swift:479:13:479:21 | call to +(_:) | result |
433466
| test.swift:480:14:480:21 | call to source() | test.swift:480:14:480:21 | call to source() | test.swift:480:14:480:21 | call to source() | result |
434467
| test.swift:497:17:497:17 | .str | test.swift:496:20:496:28 | call to source3() : | test.swift:497:17:497:17 | .str | result |
468+
| test.swift:502:13:502:35 | .str | test.swift:502:24:502:32 | call to source3() : | test.swift:502:13:502:35 | .str | result |
469+
| test.swift:503:13:503:43 | .str | test.swift:496:20:496:28 | call to source3() : | test.swift:503:13:503:43 | .str | result |
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +0,0 @@
1-
| test.swift:497:17:497:17 | .str | Unexpected result: flow=496 |

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@
115115
| test.swift:163:7:163:7 | value | test.swift:163:7:163:7 | SSA def(value) |
116116
| test.swift:165:3:165:3 | SSA def(self) | test.swift:166:5:166:5 | self |
117117
| test.swift:165:3:165:3 | self | test.swift:165:3:165:3 | SSA def(self) |
118+
| test.swift:166:5:166:5 | [post] self | test.swift:165:3:167:3 | self[constructor return] |
118119
| test.swift:166:5:166:5 | [post] self | test.swift:165:3:167:3 | self[return] |
120+
| test.swift:166:5:166:5 | self | test.swift:165:3:167:3 | self[constructor return] |
119121
| test.swift:166:5:166:5 | self | test.swift:165:3:167:3 | self[return] |
120122
| test.swift:169:8:169:8 | SSA def(self) | test.swift:170:5:170:5 | self |
121123
| test.swift:169:8:169:8 | self | test.swift:169:8:169:8 | SSA def(self) |
@@ -139,7 +141,9 @@
139141
| test.swift:185:7:185:7 | value | test.swift:185:7:185:7 | SSA def(value) |
140142
| test.swift:187:3:187:3 | SSA def(self) | test.swift:188:5:188:5 | self |
141143
| test.swift:187:3:187:3 | self | test.swift:187:3:187:3 | SSA def(self) |
144+
| test.swift:188:5:188:5 | [post] self | test.swift:187:3:189:3 | self[constructor return] |
142145
| test.swift:188:5:188:5 | [post] self | test.swift:187:3:189:3 | self[return] |
146+
| test.swift:188:5:188:5 | self | test.swift:187:3:189:3 | self[constructor return] |
143147
| test.swift:188:5:188:5 | self | test.swift:187:3:189:3 | self[return] |
144148
| test.swift:193:7:193:7 | SSA def(b) | test.swift:194:3:194:3 | b |
145149
| test.swift:193:11:193:13 | call to B.init() | test.swift:193:7:193:7 | SSA def(b) |
@@ -161,6 +165,7 @@
161165
| test.swift:217:11:217:13 | call to B.init() | test.swift:217:7:217:7 | SSA def(b) |
162166
| test.swift:218:3:218:3 | [post] b | test.swift:219:13:219:13 | b |
163167
| test.swift:218:3:218:3 | b | test.swift:219:13:219:13 | b |
168+
| test.swift:222:7:222:7 | SSA def(self) | test.swift:222:7:222:7 | self[constructor return] |
164169
| test.swift:222:7:222:7 | SSA def(self) | test.swift:222:7:222:7 | self[return] |
165170
| test.swift:222:7:222:7 | SSA def(self) | test.swift:222:7:222:7 | self[return] |
166171
| test.swift:222:7:222:7 | self | test.swift:222:7:222:7 | SSA def(self) |
@@ -186,7 +191,9 @@
186191
| test.swift:243:18:243:18 | self | test.swift:243:9:243:42 | self[return] |
187192
| test.swift:246:5:246:5 | SSA def(self) | test.swift:247:9:247:9 | self |
188193
| test.swift:246:5:246:5 | self | test.swift:246:5:246:5 | SSA def(self) |
194+
| test.swift:247:9:247:9 | [post] self | test.swift:246:5:248:5 | self[constructor return] |
189195
| test.swift:247:9:247:9 | [post] self | test.swift:246:5:248:5 | self[return] |
196+
| test.swift:247:9:247:9 | self | test.swift:246:5:248:5 | self[constructor return] |
190197
| test.swift:247:9:247:9 | self | test.swift:246:5:248:5 | self[return] |
191198
| test.swift:252:23:252:23 | value | test.swift:252:23:252:23 | SSA def(value) |
192199
| test.swift:262:21:262:27 | SSA def(y) | test.swift:266:15:266:15 | y |
@@ -366,6 +373,7 @@
366373
| test.swift:448:10:448:37 | SSA def(b) | test.swift:450:19:450:19 | b |
367374
| test.swift:455:8:455:17 | SSA def(x) | test.swift:456:19:456:19 | x |
368375
| test.swift:455:8:455:17 | SSA def(y) | test.swift:457:19:457:19 | y |
376+
| test.swift:461:7:461:7 | SSA def(self) | test.swift:461:7:461:7 | self[constructor return] |
369377
| test.swift:461:7:461:7 | SSA def(self) | test.swift:461:7:461:7 | self[return] |
370378
| test.swift:461:7:461:7 | SSA def(self) | test.swift:461:7:461:7 | self[return] |
371379
| test.swift:461:7:461:7 | self | test.swift:461:7:461:7 | SSA def(self) |
@@ -401,13 +409,17 @@
401409
| test.swift:489:5:489:5 | self | test.swift:489:5:489:5 | SSA def(self) |
402410
| test.swift:489:10:489:13 | SSA def(s) | test.swift:490:13:490:13 | s |
403411
| test.swift:489:10:489:13 | s | test.swift:489:10:489:13 | SSA def(s) |
412+
| test.swift:490:7:490:7 | [post] self | test.swift:489:5:491:5 | self[constructor return] |
404413
| test.swift:490:7:490:7 | [post] self | test.swift:489:5:491:5 | self[return] |
414+
| test.swift:490:7:490:7 | self | test.swift:489:5:491:5 | self[constructor return] |
405415
| test.swift:490:7:490:7 | self | test.swift:489:5:491:5 | self[return] |
406416
| test.swift:495:17:495:17 | SSA def(self) | test.swift:496:7:496:7 | self |
407417
| test.swift:495:17:495:17 | self | test.swift:495:17:495:17 | SSA def(self) |
408418
| test.swift:496:7:496:7 | [post] self | test.swift:497:17:497:17 | self |
409419
| test.swift:496:7:496:7 | self | test.swift:497:17:497:17 | self |
420+
| test.swift:497:17:497:17 | [post] self | test.swift:495:17:498:5 | self[constructor return] |
410421
| test.swift:497:17:497:17 | [post] self | test.swift:495:17:498:5 | self[return] |
422+
| test.swift:497:17:497:17 | self | test.swift:495:17:498:5 | self[constructor return] |
411423
| test.swift:497:17:497:17 | self | test.swift:495:17:498:5 | self[return] |
412424
| test.swift:501:21:501:27 | SSA def(path) | test.swift:503:37:503:37 | path |
413425
| test.swift:501:21:501:27 | path | test.swift:501:21:501:27 | SSA def(path) |

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -493,12 +493,12 @@ class MyClass {
493493

494494
extension MyClass {
495495
convenience init(contentsOfFile: String) {
496-
self.init(s: source3()) // taint should flow from the source String(contentsOfFile:) into MyClass
497-
sink(str: str)
496+
self.init(s: source3())
497+
sink(str: str) // $ flow=496
498498
}
499499
}
500500

501501
func extensionInits(path: String) {
502-
sink(str: MyClass(s: source3()).str)
503-
sink(str: MyClass(contentsOfFile: path).str)
502+
sink(str: MyClass(s: source3()).str) // $ flow=502
503+
sink(str: MyClass(contentsOfFile: path).str) // $ flow=496
504504
}

0 commit comments

Comments
 (0)