diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index 059fd4ae26f..490887bf051 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -399,6 +399,29 @@ private module ReturnNodes { override ReturnKind getKind() { result instanceof NormalReturnKind } } + class SelfReturnNode extends ReturnNode, TInoutReturnNode, NodeImpl { + SelfParamDecl param; + ControlFlowNode exit; + SelfReturnNode() { + this = TInoutReturnNode(param) and + exit instanceof ExitNode and + exit.getScope() = param.getDeclaringFunction() and + param.getDeclaringFunction() instanceof ConstructorDecl + } + override ControlFlowNode getCfgNode() { result = exit } + + override DataFlowCallable getEnclosingCallable() { + result = TDataFlowFunc(param.getDeclaringFunction()) + } + + ParamDecl getParameter() { result = param } + + override Location getLocationImpl() { result = exit.getLocation() } + + override string toStringImpl() { result = param.toString() + "[constructor return]" } + override ReturnKind getKind() { result instanceof NormalReturnKind } + } + class InoutReturnNodeImpl extends ReturnNode, TInoutReturnNode, NodeImpl { ParamDecl param; ControlFlowNode exit; diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index de580e583a5..5fcac4bc9ce 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -1,6 +1,7 @@ edges | file://:0:0:0:0 | [summary param] this in signum() : | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | | file://:0:0:0:0 | self [a, x] : | file://:0:0:0:0 | .a [x] : | +| file://:0:0:0:0 | self [str] : | file://:0:0:0:0 | .str : | | file://:0:0:0:0 | self [x] : | file://:0:0:0:0 | .x : | | file://:0:0:0:0 | self [x] : | file://:0:0:0:0 | .x : | | file://:0:0:0:0 | value : | file://:0:0:0:0 | [post] self [x] : | @@ -155,15 +156,28 @@ edges | test.swift:472:20:472:20 | cx [x] : | test.swift:472:20:472:23 | .x : | | test.swift:472:20:472:23 | .x : | test.swift:473:15:473:15 | z1 | | test.swift:479:14:479:21 | call to source() : | test.swift:479:13:479:21 | call to +(_:) | +| test.swift:488:9:488:9 | self [str] : | file://:0:0:0:0 | self [str] : | | test.swift:489:10:489:13 | s : | test.swift:490:13:490:13 | s : | +| test.swift:490:7:490:7 | [post] self [str] : | test.swift:489:5:491:5 | self[constructor return] [str] : | | test.swift:490:7:490:7 | [post] self [str] : | test.swift:489:5:491:5 | self[return] [str] : | | test.swift:490:13:490:13 | s : | test.swift:490:7:490:7 | [post] self [str] : | +| test.swift:495:17:498:5 | self[constructor return] [str] : | test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | +| test.swift:495:17:498:5 | self[return] [str] : | test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | +| test.swift:496:7:496:7 | [post] self [str] : | test.swift:495:17:498:5 | self[constructor return] [str] : | +| test.swift:496:7:496:7 | [post] self [str] : | test.swift:495:17:498:5 | self[return] [str] : | | test.swift:496:7:496:7 | [post] self [str] : | test.swift:497:17:497:17 | self [str] : | | test.swift:496:20:496:28 | call to source3() : | test.swift:489:10:489:13 | s : | | test.swift:496:20:496:28 | call to source3() : | test.swift:496:7:496:7 | [post] self [str] : | | test.swift:497:17:497:17 | self [str] : | test.swift:497:17:497:17 | .str | +| test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | test.swift:488:9:488:9 | self [str] : | +| test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | test.swift:502:13:502:35 | .str | +| test.swift:502:24:502:32 | call to source3() : | test.swift:489:10:489:13 | s : | +| test.swift:502:24:502:32 | call to source3() : | test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | +| test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | test.swift:488:9:488:9 | self [str] : | +| test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | test.swift:503:13:503:43 | .str | nodes | file://:0:0:0:0 | .a [x] : | semmle.label | .a [x] : | +| file://:0:0:0:0 | .str : | semmle.label | .str : | | file://:0:0:0:0 | .x : | semmle.label | .x : | | file://:0:0:0:0 | .x : | semmle.label | .x : | | file://:0:0:0:0 | [post] self [x] : | semmle.label | [post] self [x] : | @@ -171,6 +185,7 @@ nodes | file://:0:0:0:0 | [summary param] this in signum() : | semmle.label | [summary param] this in signum() : | | file://:0:0:0:0 | [summary] to write: return (return) in signum() : | semmle.label | [summary] to write: return (return) in signum() : | | file://:0:0:0:0 | self [a, x] : | semmle.label | self [a, x] : | +| file://:0:0:0:0 | self [str] : | semmle.label | self [str] : | | file://:0:0:0:0 | self [x] : | semmle.label | self [x] : | | file://:0:0:0:0 | self [x] : | semmle.label | self [x] : | | file://:0:0:0:0 | value : | semmle.label | value : | @@ -335,14 +350,27 @@ nodes | test.swift:479:13:479:21 | call to +(_:) | semmle.label | call to +(_:) | | test.swift:479:14:479:21 | call to source() : | semmle.label | call to source() : | | test.swift:480:14:480:21 | call to source() | semmle.label | call to source() | +| test.swift:488:9:488:9 | self [str] : | semmle.label | self [str] : | +| test.swift:489:5:491:5 | self[constructor return] [str] : | semmle.label | self[constructor return] [str] : | +| test.swift:489:5:491:5 | self[constructor return] [str] : | semmle.label | self[return] [str] : | +| test.swift:489:5:491:5 | self[return] [str] : | semmle.label | self[constructor return] [str] : | | test.swift:489:5:491:5 | self[return] [str] : | semmle.label | self[return] [str] : | | test.swift:489:10:489:13 | s : | semmle.label | s : | | test.swift:490:7:490:7 | [post] self [str] : | semmle.label | [post] self [str] : | | test.swift:490:13:490:13 | s : | semmle.label | s : | +| test.swift:495:17:498:5 | self[constructor return] [str] : | semmle.label | self[constructor return] [str] : | +| test.swift:495:17:498:5 | self[constructor return] [str] : | semmle.label | self[return] [str] : | +| test.swift:495:17:498:5 | self[return] [str] : | semmle.label | self[constructor return] [str] : | +| test.swift:495:17:498:5 | self[return] [str] : | semmle.label | self[return] [str] : | | test.swift:496:7:496:7 | [post] self [str] : | semmle.label | [post] self [str] : | | test.swift:496:20:496:28 | call to source3() : | semmle.label | call to source3() : | | test.swift:497:17:497:17 | .str | semmle.label | .str | | test.swift:497:17:497:17 | self [str] : | semmle.label | self [str] : | +| test.swift:502:13:502:33 | call to MyClass.init(s:) [str] : | semmle.label | call to MyClass.init(s:) [str] : | +| test.swift:502:13:502:35 | .str | semmle.label | .str | +| test.swift:502:24:502:32 | call to source3() : | semmle.label | call to source3() : | +| test.swift:503:13:503:41 | call to Self.init(contentsOfFile:) [str] : | semmle.label | call to Self.init(contentsOfFile:) [str] : | +| test.swift:503:13:503:43 | .str | semmle.label | .str | subpaths | 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] &... : | | 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 | 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() | | 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] : | | 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 : | +| 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] : | | 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] : | | 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] : | +| 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 | +| 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] : | +| 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] : | +| 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 | #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 | @@ -432,3 +465,5 @@ subpaths | 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 | | 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 | | test.swift:497:17:497:17 | .str | test.swift:496:20:496:28 | call to source3() : | test.swift:497:17:497:17 | .str | result | +| test.swift:502:13:502:35 | .str | test.swift:502:24:502:32 | call to source3() : | test.swift:502:13:502:35 | .str | result | +| test.swift:503:13:503:43 | .str | test.swift:496:20:496:28 | call to source3() : | test.swift:503:13:503:43 | .str | result | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlowInline.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlowInline.expected index 31ccf792fd6..e69de29bb2d 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlowInline.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlowInline.expected @@ -1 +0,0 @@ -| test.swift:497:17:497:17 | .str | Unexpected result: flow=496 | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 2623819c0e8..302c8a32e85 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -115,7 +115,9 @@ | test.swift:163:7:163:7 | value | test.swift:163:7:163:7 | SSA def(value) | | test.swift:165:3:165:3 | SSA def(self) | test.swift:166:5:166:5 | self | | test.swift:165:3:165:3 | self | test.swift:165:3:165:3 | SSA def(self) | +| test.swift:166:5:166:5 | [post] self | test.swift:165:3:167:3 | self[constructor return] | | test.swift:166:5:166:5 | [post] self | test.swift:165:3:167:3 | self[return] | +| test.swift:166:5:166:5 | self | test.swift:165:3:167:3 | self[constructor return] | | test.swift:166:5:166:5 | self | test.swift:165:3:167:3 | self[return] | | test.swift:169:8:169:8 | SSA def(self) | test.swift:170:5:170:5 | self | | test.swift:169:8:169:8 | self | test.swift:169:8:169:8 | SSA def(self) | @@ -139,7 +141,9 @@ | test.swift:185:7:185:7 | value | test.swift:185:7:185:7 | SSA def(value) | | test.swift:187:3:187:3 | SSA def(self) | test.swift:188:5:188:5 | self | | test.swift:187:3:187:3 | self | test.swift:187:3:187:3 | SSA def(self) | +| test.swift:188:5:188:5 | [post] self | test.swift:187:3:189:3 | self[constructor return] | | test.swift:188:5:188:5 | [post] self | test.swift:187:3:189:3 | self[return] | +| test.swift:188:5:188:5 | self | test.swift:187:3:189:3 | self[constructor return] | | test.swift:188:5:188:5 | self | test.swift:187:3:189:3 | self[return] | | test.swift:193:7:193:7 | SSA def(b) | test.swift:194:3:194:3 | b | | test.swift:193:11:193:13 | call to B.init() | test.swift:193:7:193:7 | SSA def(b) | @@ -161,6 +165,7 @@ | test.swift:217:11:217:13 | call to B.init() | test.swift:217:7:217:7 | SSA def(b) | | test.swift:218:3:218:3 | [post] b | test.swift:219:13:219:13 | b | | test.swift:218:3:218:3 | b | test.swift:219:13:219:13 | b | +| test.swift:222:7:222:7 | SSA def(self) | test.swift:222:7:222:7 | self[constructor return] | | test.swift:222:7:222:7 | SSA def(self) | test.swift:222:7:222:7 | self[return] | | test.swift:222:7:222:7 | SSA def(self) | test.swift:222:7:222:7 | self[return] | | test.swift:222:7:222:7 | self | test.swift:222:7:222:7 | SSA def(self) | @@ -186,7 +191,9 @@ | test.swift:243:18:243:18 | self | test.swift:243:9:243:42 | self[return] | | test.swift:246:5:246:5 | SSA def(self) | test.swift:247:9:247:9 | self | | test.swift:246:5:246:5 | self | test.swift:246:5:246:5 | SSA def(self) | +| test.swift:247:9:247:9 | [post] self | test.swift:246:5:248:5 | self[constructor return] | | test.swift:247:9:247:9 | [post] self | test.swift:246:5:248:5 | self[return] | +| test.swift:247:9:247:9 | self | test.swift:246:5:248:5 | self[constructor return] | | test.swift:247:9:247:9 | self | test.swift:246:5:248:5 | self[return] | | test.swift:252:23:252:23 | value | test.swift:252:23:252:23 | SSA def(value) | | test.swift:262:21:262:27 | SSA def(y) | test.swift:266:15:266:15 | y | @@ -366,6 +373,7 @@ | test.swift:448:10:448:37 | SSA def(b) | test.swift:450:19:450:19 | b | | test.swift:455:8:455:17 | SSA def(x) | test.swift:456:19:456:19 | x | | test.swift:455:8:455:17 | SSA def(y) | test.swift:457:19:457:19 | y | +| test.swift:461:7:461:7 | SSA def(self) | test.swift:461:7:461:7 | self[constructor return] | | test.swift:461:7:461:7 | SSA def(self) | test.swift:461:7:461:7 | self[return] | | test.swift:461:7:461:7 | SSA def(self) | test.swift:461:7:461:7 | self[return] | | test.swift:461:7:461:7 | self | test.swift:461:7:461:7 | SSA def(self) | @@ -401,13 +409,17 @@ | test.swift:489:5:489:5 | self | test.swift:489:5:489:5 | SSA def(self) | | test.swift:489:10:489:13 | SSA def(s) | test.swift:490:13:490:13 | s | | test.swift:489:10:489:13 | s | test.swift:489:10:489:13 | SSA def(s) | +| test.swift:490:7:490:7 | [post] self | test.swift:489:5:491:5 | self[constructor return] | | test.swift:490:7:490:7 | [post] self | test.swift:489:5:491:5 | self[return] | +| test.swift:490:7:490:7 | self | test.swift:489:5:491:5 | self[constructor return] | | test.swift:490:7:490:7 | self | test.swift:489:5:491:5 | self[return] | | test.swift:495:17:495:17 | SSA def(self) | test.swift:496:7:496:7 | self | | test.swift:495:17:495:17 | self | test.swift:495:17:495:17 | SSA def(self) | | test.swift:496:7:496:7 | [post] self | test.swift:497:17:497:17 | self | | test.swift:496:7:496:7 | self | test.swift:497:17:497:17 | self | +| test.swift:497:17:497:17 | [post] self | test.swift:495:17:498:5 | self[constructor return] | | test.swift:497:17:497:17 | [post] self | test.swift:495:17:498:5 | self[return] | +| test.swift:497:17:497:17 | self | test.swift:495:17:498:5 | self[constructor return] | | test.swift:497:17:497:17 | self | test.swift:495:17:498:5 | self[return] | | test.swift:501:21:501:27 | SSA def(path) | test.swift:503:37:503:37 | path | | test.swift:501:21:501:27 | path | test.swift:501:21:501:27 | SSA def(path) | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/test.swift b/swift/ql/test/library-tests/dataflow/dataflow/test.swift index 5204d0ee287..03e5235f7b9 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/test.swift +++ b/swift/ql/test/library-tests/dataflow/dataflow/test.swift @@ -493,12 +493,12 @@ class MyClass { extension MyClass { convenience init(contentsOfFile: String) { - self.init(s: source3()) // taint should flow from the source String(contentsOfFile:) into MyClass - sink(str: str) + self.init(s: source3()) + sink(str: str) // $ flow=496 } } func extensionInits(path: String) { - sink(str: MyClass(s: source3()).str) - sink(str: MyClass(contentsOfFile: path).str) + sink(str: MyClass(s: source3()).str) // $ flow=502 + sink(str: MyClass(contentsOfFile: path).str) // $ flow=496 }