mirror of
https://github.com/github/codeql.git
synced 2026-03-06 15:49:08 +01:00
Merge pull request #14761 from geoffw0/moderntest
Swift: Update the inline dataflow tests
This commit is contained in:
@@ -16,15 +16,15 @@
|
||||
* To declare expectations, you can use the $hasTaintFlow or $hasValueFlow comments within the test source files.
|
||||
* Example of the corresponding test file, e.g. Test.java
|
||||
* ```swift
|
||||
* func source() -> Any { return nil }
|
||||
* func taint() -> Any { return nil }
|
||||
* func source(_ label: String) -> Any { return nil }
|
||||
* func taint(_ label: String) -> Any { return nil }
|
||||
* func sink(_ o: Any) { }
|
||||
*
|
||||
* func test() {
|
||||
* let s = source()
|
||||
* sink(s) // $ hasValueFlow
|
||||
* let t = "foo" + taint()
|
||||
* sink(t); // $ hasTaintFlow
|
||||
* let s = source("mySource")
|
||||
* sink(s) // $ hasValueFlow=mySource
|
||||
* let t = "foo" + taint("myTaint")
|
||||
* sink(t); // $ hasTaintFlow=myTaint
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
@@ -42,11 +42,17 @@ import codeql.swift.dataflow.TaintTracking
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
private predicate defaultSource(DataFlow::Node source) {
|
||||
source.asExpr().(CallExpr).getStaticTarget().(Function).getShortName() = ["source", "taint"]
|
||||
source
|
||||
.asExpr()
|
||||
.(CallExpr)
|
||||
.getStaticTarget()
|
||||
.(Function)
|
||||
.getShortName()
|
||||
.matches(["source%", "taint"])
|
||||
}
|
||||
|
||||
private predicate defaultSink(DataFlow::Node sink) {
|
||||
exists(CallExpr ca | ca.getStaticTarget().(Function).getShortName() = "sink" |
|
||||
exists(CallExpr ca | ca.getStaticTarget().(Function).getShortName().matches("sink%") |
|
||||
sink.asExpr() = ca.getAnArgument().getExpr()
|
||||
)
|
||||
}
|
||||
@@ -59,40 +65,55 @@ module DefaultFlowConfig implements DataFlow::ConfigSig {
|
||||
int fieldFlowBranchLimit() { result = 1000 }
|
||||
}
|
||||
|
||||
private module NoFlowConfig implements DataFlow::ConfigSig {
|
||||
module NoFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { none() }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
private signature string valueFlowTagSig();
|
||||
|
||||
private signature string taintFlowTagSig();
|
||||
|
||||
string defaultValueFlowTag() { result = "hasValueFlow" }
|
||||
|
||||
string defaultTaintFlowTag() { result = "hasTaintFlow" }
|
||||
|
||||
private string getSourceArgString(DataFlow::Node src) {
|
||||
defaultSource(src) and
|
||||
src.asExpr().(CallExpr).getAnArgument().getExpr().(StringLiteralExpr).getValue() = result
|
||||
}
|
||||
|
||||
module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFlowConfig> {
|
||||
module FlowTest<
|
||||
DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFlowConfig,
|
||||
valueFlowTagSig/0 valueFlowTag, taintFlowTagSig/0 taintFlowTag>
|
||||
{
|
||||
module ValueFlow = DataFlow::Global<ValueFlowConfig>;
|
||||
|
||||
module TaintFlow = TaintTracking::Global<TaintFlowConfig>;
|
||||
|
||||
private module InlineTest implements TestSig {
|
||||
string getARelevantTag() { result = ["hasValueFlow", "hasTaintFlow"] }
|
||||
string getARelevantTag() { result = [valueFlowTag(), taintFlowTag()] }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "hasValueFlow" and
|
||||
tag = valueFlowTag() and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink | ValueFlow::flow(src, sink) |
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
|
||||
if exists(getSourceArgString(src))
|
||||
then value = getSourceArgString(src)
|
||||
else value = src.getLocation().getStartLine().toString()
|
||||
)
|
||||
or
|
||||
tag = "hasTaintFlow" and
|
||||
tag = taintFlowTag() and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
TaintFlow::flow(src, sink) and not ValueFlow::flow(src, sink)
|
||||
|
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
if exists(getSourceArgString(src)) then value = getSourceArgString(src) else value = ""
|
||||
if exists(getSourceArgString(src))
|
||||
then value = getSourceArgString(src)
|
||||
else value = src.getLocation().getStartLine().toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -106,12 +127,13 @@ module FlowTest<DataFlow::ConfigSig ValueFlowConfig, DataFlow::ConfigSig TaintFl
|
||||
}
|
||||
}
|
||||
|
||||
module DefaultFlowTest = FlowTest<DefaultFlowConfig, DefaultFlowConfig>;
|
||||
module DefaultFlowTest =
|
||||
FlowTest<DefaultFlowConfig, DefaultFlowConfig, defaultValueFlowTag/0, defaultTaintFlowTag/0>;
|
||||
|
||||
module ValueFlowTest<DataFlow::ConfigSig ValueFlowConfig> {
|
||||
import FlowTest<ValueFlowConfig, NoFlowConfig>
|
||||
import FlowTest<ValueFlowConfig, NoFlowConfig, defaultValueFlowTag/0, defaultTaintFlowTag/0>
|
||||
}
|
||||
|
||||
module TaintFlowTest<DataFlow::ConfigSig TaintFlowConfig> {
|
||||
import FlowTest<NoFlowConfig, TaintFlowConfig>
|
||||
import FlowTest<NoFlowConfig, TaintFlowConfig, defaultValueFlowTag/0, defaultTaintFlowTag/0>
|
||||
}
|
||||
|
||||
@@ -604,8 +604,8 @@ edges
|
||||
| test.swift:884:15:884:15 | generator [Collection element] | test.swift:884:15:884:30 | call to next() [some:0] |
|
||||
| test.swift:884:15:884:30 | call to next() [some:0] | test.swift:884:15:884:31 | ...! |
|
||||
| test.swift:908:19:908:26 | call to source() | test.swift:904:13:904:18 | call to ... |
|
||||
| test.swift:927:12:927:21 | call to source() | test.swift:927:12:927:21 | OpenExistentialExpr |
|
||||
| test.swift:929:12:929:35 | call to source() | test.swift:929:12:929:35 | OpenExistentialExpr |
|
||||
| test.swift:927:12:927:31 | call to source(_:) | test.swift:927:12:927:31 | OpenExistentialExpr |
|
||||
| test.swift:929:12:929:57 | call to source(_:) | test.swift:929:12:929:57 | OpenExistentialExpr |
|
||||
nodes
|
||||
| file://:0:0:0:0 | .a [x] | semmle.label | .a [x] |
|
||||
| file://:0:0:0:0 | .s [x] | semmle.label | .s [x] |
|
||||
@@ -1256,12 +1256,12 @@ nodes
|
||||
| test.swift:884:15:884:31 | ...! | semmle.label | ...! |
|
||||
| test.swift:904:13:904:18 | call to ... | semmle.label | call to ... |
|
||||
| test.swift:908:19:908:26 | call to source() | semmle.label | call to source() |
|
||||
| test.swift:927:12:927:21 | OpenExistentialExpr | semmle.label | OpenExistentialExpr |
|
||||
| test.swift:927:12:927:21 | call to source() | semmle.label | call to source() |
|
||||
| test.swift:928:12:928:21 | call to source() | semmle.label | call to source() |
|
||||
| test.swift:929:12:929:35 | OpenExistentialExpr | semmle.label | OpenExistentialExpr |
|
||||
| test.swift:929:12:929:35 | call to source() | semmle.label | call to source() |
|
||||
| test.swift:930:12:930:39 | call to source() | semmle.label | call to source() |
|
||||
| test.swift:927:12:927:31 | OpenExistentialExpr | semmle.label | OpenExistentialExpr |
|
||||
| test.swift:927:12:927:31 | call to source(_:) | semmle.label | call to source(_:) |
|
||||
| test.swift:928:12:928:31 | call to source(_:) | semmle.label | call to source(_:) |
|
||||
| test.swift:929:12:929:57 | OpenExistentialExpr | semmle.label | OpenExistentialExpr |
|
||||
| test.swift:929:12:929:57 | call to source(_:) | semmle.label | call to source(_:) |
|
||||
| test.swift:930:12:930:65 | call to source(_:) | semmle.label | call to source(_:) |
|
||||
subpaths
|
||||
| test.swift:75:22:75:22 | x | test.swift:65:16:65:28 | arg1 | test.swift:65:1:70:1 | arg2[return] | test.swift:75:32:75:32 | [post] y |
|
||||
| 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 ... |
|
||||
@@ -1460,7 +1460,7 @@ subpaths
|
||||
| test.swift:880:19:880:19 | elem | test.swift:877:21:877:28 | call to source() | test.swift:880:19:880:19 | elem | result |
|
||||
| test.swift:884:15:884:31 | ...! | test.swift:877:21:877:28 | call to source() | test.swift:884:15:884:31 | ...! | result |
|
||||
| test.swift:904:13:904:18 | call to ... | test.swift:908:19:908:26 | call to source() | test.swift:904:13:904:18 | call to ... | result |
|
||||
| test.swift:927:12:927:21 | OpenExistentialExpr | test.swift:927:12:927:21 | call to source() | test.swift:927:12:927:21 | OpenExistentialExpr | result |
|
||||
| test.swift:928:12:928:21 | call to source() | test.swift:928:12:928:21 | call to source() | test.swift:928:12:928:21 | call to source() | result |
|
||||
| test.swift:929:12:929:35 | OpenExistentialExpr | test.swift:929:12:929:35 | call to source() | test.swift:929:12:929:35 | OpenExistentialExpr | result |
|
||||
| test.swift:930:12:930:39 | call to source() | test.swift:930:12:930:39 | call to source() | test.swift:930:12:930:39 | call to source() | result |
|
||||
| test.swift:927:12:927:31 | OpenExistentialExpr | test.swift:927:12:927:31 | call to source(_:) | test.swift:927:12:927:31 | OpenExistentialExpr | result |
|
||||
| test.swift:928:12:928:31 | call to source(_:) | test.swift:928:12:928:31 | call to source(_:) | test.swift:928:12:928:31 | call to source(_:) | result |
|
||||
| test.swift:929:12:929:57 | OpenExistentialExpr | test.swift:929:12:929:57 | call to source(_:) | test.swift:929:12:929:57 | OpenExistentialExpr | result |
|
||||
| test.swift:930:12:930:65 | call to source(_:) | test.swift:930:12:930:65 | call to source(_:) | test.swift:930:12:930:65 | call to source(_:) | result |
|
||||
|
||||
@@ -1,20 +1,6 @@
|
||||
import swift
|
||||
import TestUtilities.InlineFlowTest
|
||||
import FlowConfig
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
module TaintTest implements TestSig {
|
||||
string getARelevantTag() { result = "flow" }
|
||||
string customTaintFlowTag() { result = "flow" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(DataFlow::Node source, DataFlow::Node sink, Expr sinkExpr |
|
||||
TestFlow::flow(source, sink) and
|
||||
sinkExpr = sink.asExpr() and
|
||||
location = sinkExpr.getLocation() and
|
||||
element = sinkExpr.toString() and
|
||||
tag = "flow" and
|
||||
value = source.asExpr().getLocation().getStartLine().toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<TaintTest>
|
||||
import FlowTest<DefaultFlowConfig, NoFlowConfig, customTaintFlowTag/0, defaultTaintFlowTag/0>
|
||||
|
||||
@@ -9,7 +9,7 @@ import codeql.swift.frameworks.Frameworks
|
||||
|
||||
module TestConfiguration implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) {
|
||||
src.asExpr().(CallExpr).getStaticTarget().getName().matches("source%()")
|
||||
src.asExpr().(CallExpr).getStaticTarget().getName().matches("source%")
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
|
||||
@@ -1159,11 +1159,11 @@
|
||||
| test.swift:917:7:917:7 | SSA def(self) | test.swift:917:7:917:7 | self[return] |
|
||||
| test.swift:917:7:917:7 | self | test.swift:917:7:917:7 | SSA def(self) |
|
||||
| test.swift:917:7:917:7 | self | test.swift:917:7:917:7 | SSA def(self) |
|
||||
| test.swift:918:7:918:7 | SSA def(self) | test.swift:918:2:918:34 | self[return] |
|
||||
| test.swift:918:7:918:7 | SSA def(self) | test.swift:918:2:918:49 | self[return] |
|
||||
| test.swift:918:7:918:7 | self | test.swift:918:7:918:7 | SSA def(self) |
|
||||
| test.swift:926:30:926:33 | SSA def(x) | test.swift:927:12:927:12 | x |
|
||||
| test.swift:926:30:926:33 | x | test.swift:926:30:926:33 | SSA def(x) |
|
||||
| test.swift:926:45:926:48 | SSA def(y) | test.swift:928:12:928:12 | y |
|
||||
| test.swift:926:45:926:48 | y | test.swift:926:45:926:48 | SSA def(y) |
|
||||
| test.swift:927:12:927:21 | call to source() | test.swift:927:12:927:21 | OpenExistentialExpr |
|
||||
| test.swift:929:12:929:35 | call to source() | test.swift:929:12:929:35 | OpenExistentialExpr |
|
||||
| test.swift:927:12:927:31 | call to source(_:) | test.swift:927:12:927:31 | OpenExistentialExpr |
|
||||
| test.swift:929:12:929:57 | call to source(_:) | test.swift:929:12:929:57 | OpenExistentialExpr |
|
||||
|
||||
@@ -911,11 +911,11 @@ func autoclosureTest() {
|
||||
// ---
|
||||
|
||||
protocol MyProtocol {
|
||||
func source() -> Int
|
||||
func source(_ label: String) -> Int
|
||||
}
|
||||
|
||||
class MyProcotolImpl : MyProtocol {
|
||||
func source() -> Int { return 0 }
|
||||
func source(_ label: String) -> Int { return 0 }
|
||||
}
|
||||
|
||||
func getMyProtocol() -> MyProtocol { return MyProcotolImpl() }
|
||||
@@ -924,10 +924,10 @@ func getMyProtocolImpl() -> MyProcotolImpl { return MyProcotolImpl() }
|
||||
func sink(arg: Int) { }
|
||||
|
||||
func testOpenExistentialExpr(x: MyProtocol, y: MyProcotolImpl) {
|
||||
sink(arg: x.source()) // $ flow=927
|
||||
sink(arg: y.source()) // $ flow=928
|
||||
sink(arg: getMyProtocol().source()) // $ flow=929
|
||||
sink(arg: getMyProtocolImpl().source()) // $ flow=930
|
||||
sink(arg: x.source("x.source")) // $ flow=x.source
|
||||
sink(arg: y.source("y.source")) // $ flow=y.source
|
||||
sink(arg: getMyProtocol().source("getMyProtocol.source")) // $ flow=getMyProtocol.source
|
||||
sink(arg: getMyProtocolImpl().source("getMyProtocolImpl.source")) // $ flow=getMyProtocolImpl.source
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
@@ -187,7 +187,7 @@
|
||||
| conversions.swift:170:2:170:2 | self | conversions.swift:170:2:170:2 | SSA def(self) |
|
||||
| conversions.swift:171:7:171:7 | SSA def(arr1) | conversions.swift:173:13:173:13 | arr1 |
|
||||
| conversions.swift:171:7:171:7 | arr1 | conversions.swift:171:7:171:7 | SSA def(arr1) |
|
||||
| conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:171:7:171:7 | arr1 |
|
||||
| conversions.swift:171:14:171:33 | call to sourceArray(_:) | conversions.swift:171:7:171:7 | arr1 |
|
||||
| conversions.swift:172:7:172:7 | SSA def(arr2) | conversions.swift:174:13:174:13 | arr2 |
|
||||
| conversions.swift:172:7:172:7 | arr2 | conversions.swift:172:7:172:7 | SSA def(arr2) |
|
||||
| conversions.swift:172:14:172:26 | [...] | conversions.swift:172:7:172:7 | arr2 |
|
||||
|
||||
@@ -100,10 +100,10 @@ edges
|
||||
| conversions.swift:156:25:156:69 | call to unsafeDowncast(_:to:) | conversions.swift:158:12:158:12 | v3 |
|
||||
| conversions.swift:156:40:156:40 | parent | conversions.swift:156:25:156:69 | call to unsafeDowncast(_:to:) |
|
||||
| conversions.swift:166:24:166:34 | call to sourceInt() | conversions.swift:166:12:166:35 | call to Self.init(_:) |
|
||||
| conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:173:13:173:13 | arr1 |
|
||||
| conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:175:13:175:19 | ...[...] |
|
||||
| conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:178:25:178:25 | arr1 |
|
||||
| conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:185:31:185:31 | arr1 |
|
||||
| conversions.swift:171:14:171:33 | call to sourceArray(_:) | conversions.swift:173:13:173:13 | arr1 |
|
||||
| conversions.swift:171:14:171:33 | call to sourceArray(_:) | conversions.swift:175:13:175:19 | ...[...] |
|
||||
| conversions.swift:171:14:171:33 | call to sourceArray(_:) | conversions.swift:178:25:178:25 | arr1 |
|
||||
| conversions.swift:171:14:171:33 | call to sourceArray(_:) | conversions.swift:185:31:185:31 | arr1 |
|
||||
| conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:174:13:174:13 | arr2 |
|
||||
| conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:176:13:176:13 | arr2 [Collection element] |
|
||||
| conversions.swift:172:14:172:26 | [...] [Collection element] | conversions.swift:176:13:176:19 | ...[...] |
|
||||
@@ -357,7 +357,7 @@ nodes
|
||||
| conversions.swift:158:12:158:12 | v3 | semmle.label | v3 |
|
||||
| conversions.swift:166:12:166:35 | call to Self.init(_:) | semmle.label | call to Self.init(_:) |
|
||||
| conversions.swift:166:24:166:34 | call to sourceInt() | semmle.label | call to sourceInt() |
|
||||
| conversions.swift:171:14:171:26 | call to sourceArray() | semmle.label | call to sourceArray() |
|
||||
| conversions.swift:171:14:171:33 | call to sourceArray(_:) | semmle.label | call to sourceArray(_:) |
|
||||
| conversions.swift:172:14:172:26 | [...] [Collection element] | semmle.label | [...] [Collection element] |
|
||||
| conversions.swift:172:15:172:25 | call to sourceInt() | semmle.label | call to sourceInt() |
|
||||
| conversions.swift:173:13:173:13 | arr1 | semmle.label | arr1 |
|
||||
@@ -573,17 +573,17 @@ subpaths
|
||||
| conversions.swift:157:12:157:12 | v3 | conversions.swift:152:31:152:44 | call to sourceString() | conversions.swift:157:12:157:12 | v3 | result |
|
||||
| conversions.swift:158:12:158:12 | v3 | conversions.swift:152:31:152:44 | call to sourceString() | conversions.swift:158:12:158:12 | v3 | result |
|
||||
| conversions.swift:166:12:166:35 | call to Self.init(_:) | conversions.swift:166:24:166:34 | call to sourceInt() | conversions.swift:166:12:166:35 | call to Self.init(_:) | result |
|
||||
| conversions.swift:173:13:173:13 | arr1 | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:173:13:173:13 | arr1 | result |
|
||||
| conversions.swift:173:13:173:13 | arr1 | conversions.swift:171:14:171:33 | call to sourceArray(_:) | conversions.swift:173:13:173:13 | arr1 | result |
|
||||
| conversions.swift:174:13:174:13 | arr2 | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:174:13:174:13 | arr2 | result |
|
||||
| conversions.swift:175:13:175:19 | ...[...] | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:175:13:175:19 | ...[...] | result |
|
||||
| conversions.swift:175:13:175:19 | ...[...] | conversions.swift:171:14:171:33 | call to sourceArray(_:) | conversions.swift:175:13:175:19 | ...[...] | result |
|
||||
| conversions.swift:176:13:176:19 | ...[...] | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:176:13:176:19 | ...[...] | result |
|
||||
| conversions.swift:180:13:180:13 | arr1b | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:180:13:180:13 | arr1b | result |
|
||||
| conversions.swift:180:13:180:13 | arr1b | conversions.swift:171:14:171:33 | call to sourceArray(_:) | conversions.swift:180:13:180:13 | arr1b | result |
|
||||
| conversions.swift:181:13:181:13 | arr2b | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:181:13:181:13 | arr2b | result |
|
||||
| conversions.swift:182:13:182:20 | ...[...] | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:182:13:182:20 | ...[...] | result |
|
||||
| conversions.swift:182:13:182:20 | ...[...] | conversions.swift:171:14:171:33 | call to sourceArray(_:) | conversions.swift:182:13:182:20 | ...[...] | result |
|
||||
| conversions.swift:183:13:183:20 | ...[...] | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:183:13:183:20 | ...[...] | result |
|
||||
| conversions.swift:187:13:187:13 | arr1c | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:187:13:187:13 | arr1c | result |
|
||||
| conversions.swift:187:13:187:13 | arr1c | conversions.swift:171:14:171:33 | call to sourceArray(_:) | conversions.swift:187:13:187:13 | arr1c | result |
|
||||
| conversions.swift:188:13:188:13 | arr2c | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:188:13:188:13 | arr2c | result |
|
||||
| conversions.swift:189:13:189:20 | ...[...] | conversions.swift:171:14:171:26 | call to sourceArray() | conversions.swift:189:13:189:20 | ...[...] | result |
|
||||
| conversions.swift:189:13:189:20 | ...[...] | conversions.swift:171:14:171:33 | call to sourceArray(_:) | conversions.swift:189:13:189:20 | ...[...] | result |
|
||||
| conversions.swift:190:13:190:20 | ...[...] | conversions.swift:172:15:172:25 | call to sourceInt() | conversions.swift:190:13:190:20 | ...[...] | result |
|
||||
| simple.swift:12:13:12:24 | ... .+(_:_:) ... | simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... | result |
|
||||
| simple.swift:13:13:13:24 | ... .+(_:_:) ... | simple.swift:13:13:13:20 | call to source() | simple.swift:13:13:13:24 | ... .+(_:_:) ... | result |
|
||||
|
||||
@@ -1,20 +1,6 @@
|
||||
import swift
|
||||
import TestUtilities.InlineFlowTest
|
||||
import Taint
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
module TaintTest implements TestSig {
|
||||
string getARelevantTag() { result = "tainted" }
|
||||
string customTaintFlowTag() { result = "tainted" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(DataFlow::Node source, DataFlow::Node sink, Expr sinkExpr |
|
||||
TestFlow::flow(source, sink) and
|
||||
sinkExpr = sink.asExpr() and
|
||||
location = sinkExpr.getLocation() and
|
||||
element = sinkExpr.toString() and
|
||||
tag = "tainted" and
|
||||
value = source.asExpr().getLocation().getStartLine().toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<TaintTest>
|
||||
import FlowTest<NoFlowConfig, DefaultFlowConfig, defaultValueFlowTag/0, customTaintFlowTag/0>
|
||||
|
||||
@@ -6,7 +6,7 @@ func sourceFloat() -> Float { 0.0 }
|
||||
func sourceFloat80() -> Float80 { 0.0 }
|
||||
func sourceDouble() -> Double { 0.0 }
|
||||
func sourceString() -> String { "" }
|
||||
func sourceArray() -> [Int] { [] }
|
||||
func sourceArray(_ label: String) -> [Int] { [] }
|
||||
|
||||
func sink(arg: Any) { }
|
||||
|
||||
@@ -168,25 +168,25 @@ func testCEnum() {
|
||||
|
||||
class TestArrayConversion {
|
||||
init() {
|
||||
let arr1 = sourceArray()
|
||||
let arr1 = sourceArray("init1")
|
||||
let arr2 = [sourceInt()]
|
||||
sink(arg: arr1) // $ tainted=171
|
||||
sink(arg: arr1) // $ tainted=init1
|
||||
sink(arg: arr2) // $ tainted=172
|
||||
sink(arg: arr1[0]) // $ tainted=171
|
||||
sink(arg: arr1[0]) // $ tainted=init1
|
||||
sink(arg: arr2[0]) // $ tainted=172
|
||||
|
||||
let arr1b = try Array(arr1)
|
||||
let arr2b = try Array(arr2)
|
||||
sink(arg: arr1b) // $ tainted=171
|
||||
sink(arg: arr1b) // $ tainted=init1
|
||||
sink(arg: arr2b) // $ tainted=172
|
||||
sink(arg: arr1b[0]) // $ tainted=171
|
||||
sink(arg: arr1b[0]) // $ tainted=init1
|
||||
sink(arg: arr2b[0]) // $ tainted=172
|
||||
|
||||
let arr1c = ContiguousArray(arr1)
|
||||
let arr2c = ContiguousArray(arr2)
|
||||
sink(arg: arr1c) // $ tainted=171
|
||||
sink(arg: arr1c) // $ tainted=init1
|
||||
sink(arg: arr2c) // $ tainted=172
|
||||
sink(arg: arr1c[0]) // $ tainted=171
|
||||
sink(arg: arr1c[0]) // $ tainted=init1
|
||||
sink(arg: arr2c[0]) // $ tainted=172
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import swift
|
||||
import codeql.swift.dataflow.TaintTracking
|
||||
import codeql.swift.dataflow.DataFlow
|
||||
|
||||
module TestConfiguration implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node src) {
|
||||
src.asExpr().(CallExpr).getStaticTarget().getName().matches("source%")
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(CallExpr sinkCall |
|
||||
sinkCall.getStaticTarget().getName().matches("sink%") and
|
||||
sinkCall.getAnArgument().getExpr() = sink.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module TestFlow = TaintTracking::Global<TestConfiguration>;
|
||||
@@ -1,20 +1,5 @@
|
||||
import swift
|
||||
import Taint
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
import TestUtilities.InlineFlowTest
|
||||
|
||||
module TaintTest implements TestSig {
|
||||
string getARelevantTag() { result = "tainted" }
|
||||
string customTaintFlowTag() { result = "tainted" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
exists(DataFlow::Node source, DataFlow::Node sink, Expr sinkExpr |
|
||||
TestFlow::flow(source, sink) and
|
||||
sinkExpr = sink.asExpr() and
|
||||
location = sinkExpr.getLocation() and
|
||||
element = sinkExpr.toString() and
|
||||
tag = "tainted" and
|
||||
value = source.asExpr().getLocation().getStartLine().toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
import MakeTest<TaintTest>
|
||||
import FlowTest<NoFlowConfig, DefaultFlowConfig, defaultValueFlowTag/0, customTaintFlowTag/0>
|
||||
|
||||
@@ -3,38 +3,38 @@
|
||||
|
||||
// --- tests ---
|
||||
|
||||
func source() -> UInt8 { return 0; }
|
||||
func source(_ label: String) -> UInt8 { return 0; }
|
||||
func source2() -> Int { return 0; }
|
||||
func sink(arg: Any) {}
|
||||
|
||||
func taintThroughClosurePointer() {
|
||||
var myArray1: [UInt8] = [1, 2, 3, 4]
|
||||
|
||||
myArray1[0] = source()
|
||||
sink(arg: myArray1) // $ tainted=13
|
||||
sink(arg: myArray1[0]) // $ tainted=13
|
||||
myArray1[0] = source("myArray1")
|
||||
sink(arg: myArray1) // $ tainted=myArray1
|
||||
sink(arg: myArray1[0]) // $ tainted=myArray1
|
||||
let return1 = myArray1.withUnsafeBytes({
|
||||
ptr1 in
|
||||
sink(arg: ptr1) // $ tainted=13
|
||||
sink(arg: ptr1[0]) // $ tainted=13
|
||||
return source()
|
||||
sink(arg: ptr1) // $ tainted=myArray1
|
||||
sink(arg: ptr1[0]) // $ tainted=myArray1
|
||||
return source("return1")
|
||||
})
|
||||
sink(arg: return1) // $ tainted=20
|
||||
sink(arg: return1) // $ tainted=return1
|
||||
|
||||
// ---
|
||||
|
||||
var myArray2: [UInt8] = [1, 2, 3, 4]
|
||||
|
||||
myArray2[0] = source()
|
||||
sink(arg: myArray2) // $ tainted=28
|
||||
sink(arg: myArray2[0]) // $ tainted=28
|
||||
myArray2[0] = source("myArray2")
|
||||
sink(arg: myArray2) // $ tainted=myArray2
|
||||
sink(arg: myArray2[0]) // $ tainted=myArray2
|
||||
let return2 = myArray2.withUnsafeBufferPointer({
|
||||
ptr2 in
|
||||
sink(arg: ptr2) // $ tainted=28
|
||||
sink(arg: ptr2[0]) // $ tainted=28
|
||||
return source()
|
||||
sink(arg: ptr2) // $ tainted=myArray2
|
||||
sink(arg: ptr2[0]) // $ tainted=myArray2
|
||||
return source("return2")
|
||||
})
|
||||
sink(arg: return2) // $ tainted=35
|
||||
sink(arg: return2) // $ tainted=return2
|
||||
}
|
||||
|
||||
func taintThroughMutablePointer() {
|
||||
@@ -44,15 +44,15 @@ func taintThroughMutablePointer() {
|
||||
sink(arg: myArray1[0])
|
||||
let return1 = myArray1.withUnsafeMutableBufferPointer({
|
||||
buffer in
|
||||
buffer.update(repeating: source())
|
||||
sink(arg: buffer) // $ tainted=47
|
||||
sink(arg: buffer[0]) // $ tainted=47
|
||||
sink(arg: buffer.baseAddress!.pointee) // $ MISSING: tainted=47
|
||||
return source()
|
||||
buffer.update(repeating: source("array1write"))
|
||||
sink(arg: buffer) // $ tainted=array1write
|
||||
sink(arg: buffer[0]) // $ tainted=array1write
|
||||
sink(arg: buffer.baseAddress!.pointee) // $ MISSING: tainted=array1write
|
||||
return source("return1")
|
||||
})
|
||||
sink(arg: return1) // $ tainted=51
|
||||
sink(arg: myArray1) // $ tainted=47
|
||||
sink(arg: myArray1[0]) // $ tainted=47
|
||||
sink(arg: return1) // $ tainted=return1
|
||||
sink(arg: myArray1) // $ tainted=array1write
|
||||
sink(arg: myArray1[0]) // $ tainted=array1write
|
||||
|
||||
// ---
|
||||
|
||||
@@ -62,15 +62,15 @@ func taintThroughMutablePointer() {
|
||||
sink(arg: myArray2[0])
|
||||
let return2 = myArray2.withUnsafeMutableBufferPointer({
|
||||
buffer in
|
||||
buffer.baseAddress!.pointee = source()
|
||||
buffer.baseAddress!.pointee = source("array2write")
|
||||
sink(arg: buffer)
|
||||
sink(arg: buffer[0]) // $ MISSING: tainted=65
|
||||
sink(arg: buffer.baseAddress!.pointee) // $ MISSING: tainted=65
|
||||
return source()
|
||||
sink(arg: buffer[0]) // $ MISSING: tainted=array2write
|
||||
sink(arg: buffer.baseAddress!.pointee) // $ MISSING: tainted=array2write
|
||||
return source("return2")
|
||||
})
|
||||
sink(arg: return2) // $ tainted=69
|
||||
sink(arg: return2) // $ tainted=return2
|
||||
sink(arg: myArray2)
|
||||
sink(arg: myArray2[0]) // $ MISSING: tainted=65
|
||||
sink(arg: myArray2[0]) // $ MISSING: tainted=array2write
|
||||
|
||||
// ---
|
||||
|
||||
@@ -80,44 +80,44 @@ func taintThroughMutablePointer() {
|
||||
sink(arg: myArray3[0])
|
||||
let return3 = myArray3.withContiguousMutableStorageIfAvailable({
|
||||
ptr in
|
||||
ptr.update(repeating: source())
|
||||
sink(arg: ptr) // $ tainted=83
|
||||
sink(arg: ptr[0]) // $ tainted=83
|
||||
return source()
|
||||
ptr.update(repeating: source("array3write"))
|
||||
sink(arg: ptr) // $ tainted=array3write
|
||||
sink(arg: ptr[0]) // $ tainted=array3write
|
||||
return source("return3")
|
||||
})
|
||||
sink(arg: return3!) // $ tainted=86
|
||||
sink(arg: myArray3) // $ tainted=83
|
||||
sink(arg: myArray3[0]) // $ tainted=83
|
||||
sink(arg: return3!) // $ tainted=return3
|
||||
sink(arg: myArray3) // $ tainted=array3write
|
||||
sink(arg: myArray3[0]) // $ tainted=array3write
|
||||
|
||||
// ---
|
||||
|
||||
var myArray4: [UInt8] = [1, 2, 3, 4]
|
||||
var myArray5: [UInt8] = [5, 6, 7, 8]
|
||||
|
||||
myArray5[0] = source()
|
||||
myArray5[0] = source("array5write")
|
||||
sink(arg: myArray4)
|
||||
sink(arg: myArray4[0])
|
||||
sink(arg: myArray5) // $ tainted=97
|
||||
sink(arg: myArray5[0]) // $ tainted=97
|
||||
sink(arg: myArray5) // $ tainted=array5write
|
||||
sink(arg: myArray5[0]) // $ tainted=array5write
|
||||
let return4 = myArray4.withUnsafeMutableBytes({
|
||||
ptr4 in
|
||||
let return5 = myArray5.withUnsafeBytes({
|
||||
ptr5 in
|
||||
sink(arg: ptr5) // $ tainted=97
|
||||
sink(arg: ptr5[0]) // $ tainted=97
|
||||
sink(arg: ptr5) // $ tainted=array5write
|
||||
sink(arg: ptr5[0]) // $ tainted=array5write
|
||||
ptr4.copyBytes(from: ptr5)
|
||||
sink(arg: ptr4)
|
||||
sink(arg: ptr4[0]) // $ MISSING: tainted=97
|
||||
return source()
|
||||
sink(arg: ptr4[0]) // $ MISSING: tainted=array5write
|
||||
return source("return5")
|
||||
})
|
||||
sink(arg: return5) // $ tainted=111
|
||||
return source()
|
||||
sink(arg: return5) // $ tainted=return5
|
||||
return source("return4")
|
||||
})
|
||||
sink(arg: return4) // $ tainted=114
|
||||
sink(arg: return4) // $ tainted=return4
|
||||
sink(arg: myArray4)
|
||||
sink(arg: myArray4[0]) // $ MISSING: tainted=97
|
||||
sink(arg: myArray5) // $ tainted=97
|
||||
sink(arg: myArray5[0]) // $ tainted=97
|
||||
sink(arg: myArray4[0]) // $ MISSING: tainted=array5write
|
||||
sink(arg: myArray5) // $ tainted=array5write
|
||||
sink(arg: myArray5[0]) // $ tainted=array5write
|
||||
|
||||
// ---
|
||||
|
||||
@@ -131,9 +131,9 @@ func taintThroughMutablePointer() {
|
||||
ptr.update(repeating: source2())
|
||||
sink(arg: ptr) // $ tainted=131
|
||||
sink(arg: ptr[0]) // $ tainted=131
|
||||
return source()
|
||||
return source("return6")
|
||||
})
|
||||
sink(arg: return6!) // $ tainted=134
|
||||
sink(arg: return6!) // $ tainted=return6
|
||||
sink(arg: myMutableBuffer) // $ tainted=131
|
||||
sink(arg: myMutableBuffer[0]) // $ tainted=131
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user