diff --git a/swift/ql/lib/change-notes/2023-08-10-numeric-models.md b/swift/ql/lib/change-notes/2023-08-10-numeric-models.md new file mode 100644 index 000000000000..85812d99c103 --- /dev/null +++ b/swift/ql/lib/change-notes/2023-08-10-numeric-models.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- + +* Added taint models for `Numeric` conversions. diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll index f9f56ae70625..2295c6d4f68c 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowPrivate.qll @@ -213,6 +213,11 @@ private module Cached { // retaining this case increases robustness of flow). nodeFrom.asExpr() = nodeTo.asExpr().(ForceValueExpr).getSubExpr() or + // read of an optional .some member via `let x: T = y: T?` pattern matching + // note: similar to `ForceValueExpr` this is ideally a content `readStep` but + // in practice we sometimes have taint on the optional itself. + nodeTo.asPattern() = nodeFrom.asPattern().(OptionalSomePattern).getSubPattern() + or // flow through `?` and `?.` nodeFrom.asExpr() = nodeTo.asExpr().(BindOptionalExpr).getSubExpr() or diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll index 26ded1c5b569..007647bf01ec 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Array.qll @@ -19,6 +19,10 @@ private class ArraySummaries extends SummaryModelCsv { override predicate row(string row) { row = [ + ";Array;true;init(_:);;;Argument[0];ReturnValue.CollectionElement;value", + ";Array;true;init(_:);;;Argument[0].CollectionElement;ReturnValue.CollectionElement;value", + ";Array;true;init(repeating:count:);;;Argument[0];ReturnValue.CollectionElement;value", + ";Array;true;init(arrayLiteral:);;;Argument[0].CollectionElement;ReturnValue.CollectionElement;value", ";Array;true;insert(_:at:);;;Argument[0];Argument[-1].CollectionElement;value", ";Array;true;insert(_:at:);;;Argument[1];Argument[-1];taint", ";Array;true;withUnsafeBufferPointer(_:);;;Argument[-1];Argument[0].Parameter[0].CollectionElement;taint", diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/CInterop.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/CInterop.qll index ac7d5c5b67e5..35a7cafe1e94 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/CInterop.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/CInterop.qll @@ -7,6 +7,6 @@ private import codeql.swift.dataflow.ExternalFlow private class CInteropSummaries extends SummaryModelCsv { override predicate row(string row) { - row = ";;false;getVaList(_:);;;Argument[0].ArrayElement;ReturnValue;value" + row = ";;false;getVaList(_:);;;Argument[0].CollectionElement;ReturnValue;value" } } diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Numeric.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Numeric.qll new file mode 100644 index 000000000000..904982846c03 --- /dev/null +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/Numeric.qll @@ -0,0 +1,53 @@ +/** + * Provides models for `Numeric` and related Swift classes (such as `Int` and `Float`). + */ + +import swift +private import codeql.swift.dataflow.DataFlow +private import codeql.swift.dataflow.ExternalFlow +private import codeql.swift.dataflow.FlowSteps + +/** + * A model for `Numeric` and related class members and functions that permit taint flow. + */ +private class NumericSummaries extends SummaryModelCsv { + override predicate row(string row) { + row = + [ + ";;false;numericCast(_:);;;Argument[0];ReturnValue;taint", + ";;false;unsafeDowncast(_:to:);;;Argument[0];ReturnValue;taint", + ";;false;unsafeBitCast(_:to:);;;Argument[0];ReturnValue;taint", + ";Numeric;true;init(exactly:);;;Argument[0];ReturnValue.OptionalSome;value", + ";Numeric;true;init(bitPattern:);;;Argument[0];ReturnValue;taint", + ";BinaryInteger;true;init(_:);;;Argument[0];ReturnValue;taint", + ";BinaryInteger;true;init(clamping:);;;Argument[0];ReturnValue;taint", + ";BinaryInteger;true;init(truncatingIfNeeded:);;;Argument[0];ReturnValue;taint", + ";BinaryInteger;true;init(_:format:lenient:);;;Argument[0];ReturnValue;taint", + ";BinaryInteger;true;init(_:strategy:);;;Argument[0];ReturnValue;taint", + ";BinaryInteger;true;formatted();;;Argument[-1];ReturnValue;taint", + ";BinaryInteger;true;formatted(_:);;;Argument[-1];ReturnValue;taint", + ";FixedWidthInteger;true;init(_:radix:);;;Argument[0];ReturnValue;taint", + ";FixedWidthInteger;true;init(littleEndian:);;;Argument[0];ReturnValue;taint", + ";FixedWidthInteger;true;init(bigEndian:);;;Argument[0];ReturnValue;taint", + ";FloatingPoint;true;init(_:);;;Argument[0];ReturnValue;taint", + ";FloatingPoint;true;init(sign:exponent:significand:);;;Argument[1..2];ReturnValue;taint", + ";FloatingPoint;true;init(signOf:magnitudeOf:);;;Argument[1];ReturnValue;taint", + ] + } +} + +/** + * A content implying that, if a `Numeric` is tainted, then some of its fields are + * tainted. + */ +private class NumericFieldsInheritTaint extends TaintInheritingContent, + DataFlow::Content::FieldContent +{ + NumericFieldsInheritTaint() { + this.getField().hasQualifiedName("FixedWidthInteger", ["littleEndian", "bigEndian"]) + or + this.getField() + .hasQualifiedName(["Double", "Float", "Float80", "FloatingPoint"], + ["exponent", "significand"]) + } +} diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/StandardLibrary.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/StandardLibrary.qll index e3bbd0dc1b8f..a96160922ae9 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/StandardLibrary.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/StandardLibrary.qll @@ -15,6 +15,7 @@ private import NsData private import NsObject private import NsString private import NsUrl +private import Numeric private import PointerTypes private import Sequence private import Set diff --git a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll index 4102940580ad..612ddc82ac2d 100644 --- a/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll +++ b/swift/ql/lib/codeql/swift/frameworks/StandardLibrary/String.qll @@ -27,7 +27,7 @@ private class StringSource extends SourceModelCsv { } /** - * A model for `String` and `StringProtocol` members that permit taint flow. + * A model for members of `String`, `StringProtocol` and similar classes that permit taint flow. */ private class StringSummaries extends SummaryModelCsv { override predicate row(string row) { @@ -124,7 +124,8 @@ private class StringSummaries extends SummaryModelCsv { ";String;true;randomElement();;;Argument[-1];ReturnValue;taint", ";String;true;randomElement(using:);;;Argument[-1];ReturnValue;taint", ";String;true;enumerated();;;Argument[-1];ReturnValue;taint", - ";String;true;encode(to:);;;Argument[-1];Argument[0];taint" + ";String;true;encode(to:);;;Argument[-1];Argument[0];taint", + ";LosslessStringConvertible;true;init(_:);;;Argument[0];ReturnValue;taint", ] } } diff --git a/swift/ql/lib/codeql/swift/security/CommandInjectionExtensions.qll b/swift/ql/lib/codeql/swift/security/CommandInjectionExtensions.qll index 5b1cc065ec28..5d78e82e76d6 100644 --- a/swift/ql/lib/codeql/swift/security/CommandInjectionExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/CommandInjectionExtensions.qll @@ -69,3 +69,13 @@ private class CommandInjectionSinks extends SinkModelCsv { ] } } + +/** + * A barrier for command injection vulnerabilities. + */ +private class CommandInjectionDefaultBarrier extends CommandInjectionBarrier { + CommandInjectionDefaultBarrier() { + // any numeric type + this.asExpr().getType().getUnderlyingType().getABaseType*().getName() = "Numeric" + } +} diff --git a/swift/ql/lib/codeql/swift/security/PredicateInjectionExtensions.qll b/swift/ql/lib/codeql/swift/security/PredicateInjectionExtensions.qll index e703d1d21e83..9e5a8a8e57b8 100644 --- a/swift/ql/lib/codeql/swift/security/PredicateInjectionExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/PredicateInjectionExtensions.qll @@ -39,3 +39,13 @@ private class PredicateInjectionSinkCsv extends SinkModelCsv { ] } } + +/** + * A barrier for predicate injection vulnerabilities vulnerabilities. + */ +private class PredicateInjectionDefaultBarrier extends PredicateInjectionBarrier { + PredicateInjectionDefaultBarrier() { + // any numeric type + this.asExpr().getType().getUnderlyingType().getABaseType*().getName() = "Numeric" + } +} diff --git a/swift/ql/lib/codeql/swift/security/SqlInjectionExtensions.qll b/swift/ql/lib/codeql/swift/security/SqlInjectionExtensions.qll index 1aac3571f538..48b2cadb3a8f 100644 --- a/swift/ql/lib/codeql/swift/security/SqlInjectionExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/SqlInjectionExtensions.qll @@ -153,3 +153,13 @@ private class GrdbDefaultSqlInjectionSink extends SqlInjectionSink { private class DefaultSqlInjectionSink extends SqlInjectionSink { DefaultSqlInjectionSink() { sinkNode(this, "sql-injection") } } + +/** + * A barrier for SQL injection. + */ +private class SqlInjectionDefaultBarrier extends SqlInjectionBarrier { + SqlInjectionDefaultBarrier() { + // any numeric type + this.asExpr().getType().getUnderlyingType().getABaseType*().getName() = "Numeric" + } +} diff --git a/swift/ql/lib/codeql/swift/security/UncontrolledFormatStringExtensions.qll b/swift/ql/lib/codeql/swift/security/UncontrolledFormatStringExtensions.qll index c2d587a35c24..835d4b1e65c3 100644 --- a/swift/ql/lib/codeql/swift/security/UncontrolledFormatStringExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/UncontrolledFormatStringExtensions.qll @@ -42,3 +42,13 @@ private class DefaultUncontrolledFormatStringSink extends UncontrolledFormatStri sinkNode(this, "format-string") } } + +/** + * A barrier for uncontrolled format string vulnerabilities. + */ +private class UncontrolledFormatStringDefaultBarrier extends UncontrolledFormatStringBarrier { + UncontrolledFormatStringDefaultBarrier() { + // any numeric type + this.asExpr().getType().getUnderlyingType().getABaseType*().getName() = "Numeric" + } +} diff --git a/swift/ql/lib/codeql/swift/security/UnsafeJsEvalExtensions.qll b/swift/ql/lib/codeql/swift/security/UnsafeJsEvalExtensions.qll index b1c353aff3c8..3eb65e6460f4 100644 --- a/swift/ql/lib/codeql/swift/security/UnsafeJsEvalExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/UnsafeJsEvalExtensions.qll @@ -30,7 +30,7 @@ class UnsafeJsEvalAdditionalFlowStep extends Unit { } /** - * A default SQL injection sink for the `WKWebView` interface. + * A default javascript evaluation sink for the `WKWebView` interface. */ private class WKWebViewDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { WKWebViewDefaultUnsafeJsEvalSink() { @@ -50,7 +50,7 @@ private class WKWebViewDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { } /** - * A default SQL injection sink for the `WKUserContentController` interface. + * A default javascript evaluation sink for the `WKUserContentController` interface. */ private class WKUserContentControllerDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { WKUserContentControllerDefaultUnsafeJsEvalSink() { @@ -61,7 +61,7 @@ private class WKUserContentControllerDefaultUnsafeJsEvalSink extends UnsafeJsEva } /** - * A default SQL injection sink for the `UIWebView` and `WebView` interfaces. + * A default javascript evaluation sink for the `UIWebView` and `WebView` interfaces. */ private class UIWebViewDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { UIWebViewDefaultUnsafeJsEvalSink() { @@ -74,7 +74,7 @@ private class UIWebViewDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { } /** - * A default SQL injection sink for the `JSContext` interface. + * A default javascript evaluation sink for the `JSContext` interface. */ private class JSContextDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { JSContextDefaultUnsafeJsEvalSink() { @@ -87,7 +87,7 @@ private class JSContextDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { } /** - * A default SQL injection sink for the `JSEvaluateScript` function. + * A default javascript evaluation sink for the `JSEvaluateScript` function. */ private class JSEvaluateScriptDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { JSEvaluateScriptDefaultUnsafeJsEvalSink() { @@ -98,7 +98,7 @@ private class JSEvaluateScriptDefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { } /** - * A default SQL injection additional taint step. + * A default javascript evaluation additional taint step. */ private class DefaultUnsafeJsEvalAdditionalFlowStep extends UnsafeJsEvalAdditionalFlowStep { override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { @@ -120,3 +120,13 @@ private class DefaultUnsafeJsEvalAdditionalFlowStep extends UnsafeJsEvalAddition private class DefaultUnsafeJsEvalSink extends UnsafeJsEvalSink { DefaultUnsafeJsEvalSink() { sinkNode(this, "code-injection") } } + +/** + * A barrier for javascript evaluation. + */ +private class UnsafeJsEvalDefaultBarrier extends UnsafeJsEvalBarrier { + UnsafeJsEvalDefaultBarrier() { + // any numeric type + this.asExpr().getType().getUnderlyingType().getABaseType*().getName() = "Numeric" + } +} diff --git a/swift/ql/lib/codeql/swift/security/regex/RegexInjectionExtensions.qll b/swift/ql/lib/codeql/swift/security/regex/RegexInjectionExtensions.qll index 3c6003b8bc80..75cf303ed620 100644 --- a/swift/ql/lib/codeql/swift/security/regex/RegexInjectionExtensions.qll +++ b/swift/ql/lib/codeql/swift/security/regex/RegexInjectionExtensions.qll @@ -57,3 +57,13 @@ private class RegexInjectionSinks extends SinkModelCsv { ] } } + +/** + * A barrier for regular expression injection vulnerabilities. + */ +private class RegexInjectionDefaultBarrier extends RegexInjectionBarrier { + RegexInjectionDefaultBarrier() { + // any numeric type + this.asExpr().getType().getUnderlyingType().getABaseType*().getName() = "Numeric" + } +} diff --git a/swift/ql/src/change-notes/2023-09-19-numeric-barriers.md b/swift/ql/src/change-notes/2023-09-19-numeric-barriers.md new file mode 100644 index 000000000000..0fd9989afe13 --- /dev/null +++ b/swift/ql/src/change-notes/2023-09-19-numeric-barriers.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Adder barriers for numeric type values to the injection-like queries, to reduce false positive results where the user input that can be injected is constrainted to a numerical value. The queries updated by this change are: "Predicate built from user-controlled sources" (`swift/predicate-injection`), "Database query built from user-controlled sources" (`swift/sql-injection`), "Uncontrolled format string" (`swift/uncontrolled-format-string`), "JavaScript Injection" (`swift/unsafe-js-eval`) and "Regular expression injection" (`swift/regex-injection`). diff --git a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected index 8efe10c62b66..a8b2848a287c 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/DataFlow.expected @@ -10,10 +10,12 @@ edges | file://:0:0:0:0 | self [x, some:0] | file://:0:0:0:0 | .x [some:0] | | 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 | self [x] | file://:0:0:0:0 | .x | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [v2] | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [v3] | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [v] | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [x] | +| file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [x] | | file://:0:0:0:0 | value [some:0] | file://:0:0:0:0 | [post] self [v2, some:0] | | file://:0:0:0:0 | value [some:0] | file://:0:0:0:0 | [post] self [x, some:0] | | test.swift:6:19:6:26 | call to source() | test.swift:7:15:7:15 | t1 | @@ -114,6 +116,8 @@ edges | test.swift:225:14:225:21 | call to source() | test.swift:238:13:238:15 | .source_value | | test.swift:259:12:259:19 | call to source() | test.swift:259:12:259:19 | call to source() [some:0] | | test.swift:259:12:259:19 | call to source() | test.swift:263:13:263:28 | call to optionalSource() | +| test.swift:259:12:259:19 | call to source() | test.swift:536:13:536:28 | call to optionalSource() | +| test.swift:259:12:259:19 | call to source() | test.swift:563:13:563:28 | call to optionalSource() | | test.swift:259:12:259:19 | call to source() [some:0] | test.swift:263:13:263:28 | call to optionalSource() [some:0] | | test.swift:259:12:259:19 | call to source() [some:0] | test.swift:536:13:536:28 | call to optionalSource() [some:0] | | test.swift:259:12:259:19 | call to source() [some:0] | test.swift:563:13:563:28 | call to optionalSource() [some:0] | @@ -124,7 +128,9 @@ edges | test.swift:263:13:263:28 | call to optionalSource() | test.swift:275:15:275:27 | ... ??(_:_:) ... | | test.swift:263:13:263:28 | call to optionalSource() | test.swift:279:15:279:31 | ... ? ... : ... | | test.swift:263:13:263:28 | call to optionalSource() | test.swift:280:15:280:38 | ... ? ... : ... | +| test.swift:263:13:263:28 | call to optionalSource() | test.swift:285:19:285:19 | z | | test.swift:263:13:263:28 | call to optionalSource() | test.swift:291:16:291:17 | ...? | +| test.swift:263:13:263:28 | call to optionalSource() | test.swift:300:15:300:15 | z1 | | test.swift:263:13:263:28 | call to optionalSource() | test.swift:303:15:303:16 | ...! | | test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:267:15:267:15 | x [some:0] | | test.swift:263:13:263:28 | call to optionalSource() [some:0] | test.swift:279:26:279:26 | x [some:0] | @@ -152,6 +158,7 @@ edges | test.swift:291:16:291:17 | ...? | test.swift:291:16:291:26 | call to signum() | | test.swift:291:16:291:17 | ...? [some:0] | test.swift:291:16:291:26 | call to signum() [some:0] | | test.swift:291:16:291:26 | call to signum() | test.swift:291:16:291:26 | call to signum() [some:0] | +| test.swift:291:16:291:26 | call to signum() | test.swift:292:19:292:19 | z | | test.swift:291:16:291:26 | call to signum() [some:0] | test.swift:291:8:291:12 | let ...? [some:0] | | test.swift:298:11:298:15 | let ...? [some:0] | test.swift:298:15:298:15 | z1 | | test.swift:298:15:298:15 | z1 | test.swift:300:15:300:15 | z1 | @@ -266,6 +273,7 @@ edges | test.swift:526:15:526:15 | e2 [some:0] | test.swift:526:15:526:17 | ...! | | test.swift:528:15:528:15 | e4 [some:0] | test.swift:528:15:528:17 | ...! | | test.swift:530:15:530:15 | e6 [some:0] | test.swift:530:15:530:17 | ...! | +| test.swift:536:13:536:28 | call to optionalSource() | test.swift:539:19:539:19 | a | | test.swift:536:13:536:28 | call to optionalSource() [some:0] | test.swift:538:8:538:12 | let ...? [some:0] | | test.swift:536:13:536:28 | call to optionalSource() [some:0] | test.swift:543:19:543:19 | x [some:0] | | test.swift:538:8:538:12 | let ...? [some:0] | test.swift:538:12:538:12 | a | @@ -276,15 +284,24 @@ edges | test.swift:545:11:545:22 | .some(...) [some:0] | test.swift:545:21:545:21 | a | | test.swift:545:21:545:21 | a | test.swift:546:19:546:19 | a | | test.swift:559:9:559:9 | self [x, some:0] | file://:0:0:0:0 | self [x, some:0] | +| test.swift:559:9:559:9 | self [x] | file://:0:0:0:0 | self [x] | +| test.swift:559:9:559:9 | value | file://:0:0:0:0 | value | | test.swift:559:9:559:9 | value [some:0] | file://:0:0:0:0 | value [some:0] | +| test.swift:563:13:563:28 | call to optionalSource() | test.swift:565:12:565:12 | x | | test.swift:563:13:563:28 | call to optionalSource() [some:0] | test.swift:565:12:565:12 | x [some:0] | | test.swift:565:5:565:5 | [post] cx [x, some:0] | test.swift:569:20:569:20 | cx [x, some:0] | +| test.swift:565:5:565:5 | [post] cx [x] | test.swift:569:20:569:20 | cx [x] | +| test.swift:565:12:565:12 | x | test.swift:559:9:559:9 | value | +| test.swift:565:12:565:12 | x | test.swift:565:5:565:5 | [post] cx [x] | | test.swift:565:12:565:12 | x [some:0] | test.swift:559:9:559:9 | value [some:0] | | test.swift:565:12:565:12 | x [some:0] | test.swift:565:5:565:5 | [post] cx [x, some:0] | | test.swift:569:11:569:15 | let ...? [some:0] | test.swift:569:15:569:15 | z1 | | test.swift:569:15:569:15 | z1 | test.swift:570:15:570:15 | z1 | | test.swift:569:20:569:20 | cx [x, some:0] | test.swift:559:9:559:9 | self [x, some:0] | | test.swift:569:20:569:20 | cx [x, some:0] | test.swift:569:20:569:23 | .x [some:0] | +| test.swift:569:20:569:20 | cx [x] | test.swift:559:9:559:9 | self [x] | +| test.swift:569:20:569:20 | cx [x] | test.swift:569:20:569:23 | .x | +| test.swift:569:20:569:23 | .x | test.swift:570:15:570:15 | z1 | | test.swift:569:20:569:23 | .x [some:0] | test.swift:569:11:569:15 | let ...? [some:0] | | test.swift:576:14:576:21 | call to source() | test.swift:576:13:576:21 | call to +(_:) | | test.swift:585:9:585:9 | self [str] | file://:0:0:0:0 | self [str] | @@ -378,6 +395,9 @@ edges | test.swift:700:21:700:28 | call to source() | test.swift:700:5:700:14 | [post] getter for ...[...] [Collection element] | | test.swift:701:15:701:15 | matrix2 [Collection element, Collection element] | test.swift:701:15:701:24 | ...[...] [Collection element] | | test.swift:701:15:701:24 | ...[...] [Collection element] | test.swift:701:15:701:27 | ...[...] | +| test.swift:708:16:708:51 | call to Array.init(repeating:count:) [Collection element] | test.swift:709:15:709:15 | arr5 [Collection element] | +| test.swift:708:33:708:40 | call to source() | test.swift:708:16:708:51 | call to Array.init(repeating:count:) [Collection element] | +| test.swift:709:15:709:15 | arr5 [Collection element] | test.swift:709:15:709:21 | ...[...] | | test.swift:712:5:712:5 | [post] arr6 [Collection element] | test.swift:713:15:713:15 | arr6 [Collection element] | | test.swift:712:17:712:24 | call to source() | test.swift:712:5:712:5 | [post] arr6 [Collection element] | | test.swift:713:15:713:15 | arr6 [Collection element] | test.swift:713:15:713:21 | ...[...] | @@ -548,6 +568,7 @@ nodes | file://:0:0:0:0 | .v3 | semmle.label | .v3 | | file://:0:0:0:0 | .x | semmle.label | .x | | file://:0:0:0:0 | .x | semmle.label | .x | +| file://:0:0:0:0 | .x | semmle.label | .x | | file://:0:0:0:0 | .x [some:0] | semmle.label | .x [some:0] | | file://:0:0:0:0 | KeyPathComponent | semmle.label | KeyPathComponent | | file://:0:0:0:0 | [post] self [v2, some:0] | semmle.label | [post] self [v2, some:0] | @@ -556,6 +577,7 @@ nodes | file://:0:0:0:0 | [post] self [v] | semmle.label | [post] self [v] | | file://:0:0:0:0 | [post] self [x, some:0] | semmle.label | [post] self [x, some:0] | | file://:0:0:0:0 | [post] self [x] | semmle.label | [post] self [x] | +| file://:0:0:0:0 | [post] self [x] | semmle.label | [post] self [x] | | file://:0:0:0:0 | self [a, x] | semmle.label | self [a, x] | | file://:0:0:0:0 | self [s, x] | semmle.label | self [s, x] | | file://:0:0:0:0 | self [str] | semmle.label | self [str] | @@ -566,6 +588,8 @@ nodes | file://:0:0:0:0 | self [x, some:0] | semmle.label | self [x, some:0] | | 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 | self [x] | semmle.label | self [x] | +| file://:0:0:0:0 | value | semmle.label | value | | file://:0:0:0:0 | value | semmle.label | value | | file://:0:0:0:0 | value | semmle.label | value | | file://:0:0:0:0 | value | semmle.label | value | @@ -839,6 +863,7 @@ nodes | test.swift:528:15:528:17 | ...! | semmle.label | ...! | | test.swift:530:15:530:15 | e6 [some:0] | semmle.label | e6 [some:0] | | test.swift:530:15:530:17 | ...! | semmle.label | ...! | +| test.swift:536:13:536:28 | call to optionalSource() | semmle.label | call to optionalSource() | | test.swift:536:13:536:28 | call to optionalSource() [some:0] | semmle.label | call to optionalSource() [some:0] | | test.swift:538:8:538:12 | let ...? [some:0] | semmle.label | let ...? [some:0] | | test.swift:538:12:538:12 | a | semmle.label | a | @@ -850,13 +875,20 @@ nodes | test.swift:545:21:545:21 | a | semmle.label | a | | test.swift:546:19:546:19 | a | semmle.label | a | | test.swift:559:9:559:9 | self [x, some:0] | semmle.label | self [x, some:0] | +| test.swift:559:9:559:9 | self [x] | semmle.label | self [x] | +| test.swift:559:9:559:9 | value | semmle.label | value | | test.swift:559:9:559:9 | value [some:0] | semmle.label | value [some:0] | +| test.swift:563:13:563:28 | call to optionalSource() | semmle.label | call to optionalSource() | | test.swift:563:13:563:28 | call to optionalSource() [some:0] | semmle.label | call to optionalSource() [some:0] | | test.swift:565:5:565:5 | [post] cx [x, some:0] | semmle.label | [post] cx [x, some:0] | +| test.swift:565:5:565:5 | [post] cx [x] | semmle.label | [post] cx [x] | +| test.swift:565:12:565:12 | x | semmle.label | x | | test.swift:565:12:565:12 | x [some:0] | semmle.label | x [some:0] | | test.swift:569:11:569:15 | let ...? [some:0] | semmle.label | let ...? [some:0] | | test.swift:569:15:569:15 | z1 | semmle.label | z1 | | test.swift:569:20:569:20 | cx [x, some:0] | semmle.label | cx [x, some:0] | +| test.swift:569:20:569:20 | cx [x] | semmle.label | cx [x] | +| test.swift:569:20:569:23 | .x | semmle.label | .x | | test.swift:569:20:569:23 | .x [some:0] | semmle.label | .x [some:0] | | test.swift:570:15:570:15 | z1 | semmle.label | z1 | | test.swift:576:13:576:21 | call to +(_:) | semmle.label | call to +(_:) | @@ -960,6 +992,10 @@ nodes | test.swift:701:15:701:15 | matrix2 [Collection element, Collection element] | semmle.label | matrix2 [Collection element, Collection element] | | test.swift:701:15:701:24 | ...[...] [Collection element] | semmle.label | ...[...] [Collection element] | | test.swift:701:15:701:27 | ...[...] | semmle.label | ...[...] | +| test.swift:708:16:708:51 | call to Array.init(repeating:count:) [Collection element] | semmle.label | call to Array.init(repeating:count:) [Collection element] | +| test.swift:708:33:708:40 | call to source() | semmle.label | call to source() | +| test.swift:709:15:709:15 | arr5 [Collection element] | semmle.label | arr5 [Collection element] | +| test.swift:709:15:709:21 | ...[...] | semmle.label | ...[...] | | test.swift:712:5:712:5 | [post] arr6 [Collection element] | semmle.label | [post] arr6 [Collection element] | | test.swift:712:17:712:24 | call to source() | semmle.label | call to source() | | test.swift:713:15:713:15 | arr6 [Collection element] | semmle.label | arr6 [Collection element] | @@ -1152,8 +1188,10 @@ subpaths | test.swift:376:30:376:30 | t1 [Tuple element at index 1] | test.swift:368:22:368:36 | t [Tuple element at index 1] | test.swift:369:12:369:19 | (...) [Tuple element at index 0] | test.swift:376:14:376:32 | call to tupleShiftLeft1(_:) [Tuple element at index 0] | | test.swift:509:24:509:31 | call to source() | test.swift:394:16:394:21 | v | test.swift:394:45:394:62 | call to ... [mySingle:0] | test.swift:509:14:509:32 | call to mkMyEnum1(_:) [mySingle:0] | | test.swift:522:26:522:33 | call to source() | test.swift:396:18:396:23 | v | test.swift:396:45:396:60 | call to ... [some:0] | test.swift:522:14:522:34 | call to mkOptional1(_:) [some:0] | +| test.swift:565:12:565:12 | x | test.swift:559:9:559:9 | value | file://:0:0:0:0 | [post] self [x] | test.swift:565:5:565:5 | [post] cx [x] | | test.swift:565:12:565:12 | x [some:0] | test.swift:559:9:559:9 | value [some:0] | file://:0:0:0:0 | [post] self [x, some:0] | test.swift:565:5:565:5 | [post] cx [x, some:0] | | test.swift:569:20:569:20 | cx [x, some:0] | test.swift:559:9:559:9 | self [x, some:0] | file://:0:0:0:0 | .x [some:0] | test.swift:569:20:569:23 | .x [some:0] | +| test.swift:569:20:569:20 | cx [x] | test.swift:559:9:559:9 | self [x] | file://:0:0:0:0 | .x | test.swift:569:20:569:23 | .x | | test.swift:593:20:593:28 | call to source3() | test.swift:586:10:586:13 | s | test.swift:587:7:587:7 | [post] self [str] | test.swift:593:7:593:7 | [post] self [str] | | test.swift:599:13:599:33 | call to MyClass.init(s:) [str] | test.swift:585:9:585:9 | self [str] | file://:0:0:0:0 | .str | test.swift:599:13:599:35 | .str | | test.swift:599:24:599:32 | call to source3() | test.swift:586:10:586:13 | s | test.swift:586:5:588:5 | self[return] [str] | test.swift:599:13:599:33 | call to MyClass.init(s:) [str] | @@ -1280,6 +1318,7 @@ subpaths | test.swift:693:15:693:21 | ...[...] | test.swift:692:17:692:24 | call to source() | test.swift:693:15:693:21 | ...[...] | result | | test.swift:697:15:697:26 | ...[...] | test.swift:695:20:695:27 | call to source() | test.swift:697:15:697:26 | ...[...] | result | | test.swift:701:15:701:27 | ...[...] | test.swift:700:21:700:28 | call to source() | test.swift:701:15:701:27 | ...[...] | result | +| test.swift:709:15:709:21 | ...[...] | test.swift:708:33:708:40 | call to source() | test.swift:709:15:709:21 | ...[...] | result | | test.swift:713:15:713:21 | ...[...] | test.swift:712:17:712:24 | call to source() | test.swift:713:15:713:21 | ...[...] | result | | test.swift:716:15:716:35 | ...! | test.swift:715:17:715:24 | call to source() | test.swift:716:15:716:35 | ...! | result | | test.swift:723:15:723:35 | ...! | test.swift:722:17:722:24 | call to source() | test.swift:723:15:723:35 | ...! | result | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected index 3e197c43e418..bc0fa7242063 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected +++ b/swift/ql/test/library-tests/dataflow/dataflow/LocalFlow.expected @@ -281,30 +281,36 @@ | test.swift:282:26:282:26 | y | test.swift:287:16:287:16 | y | | test.swift:282:26:282:27 | ...! | test.swift:282:15:282:38 | ... ? ... : ... | | test.swift:282:31:282:38 | call to source() | test.swift:282:15:282:38 | ... ? ... : ... | +| test.swift:284:8:284:12 | let ...? | test.swift:284:12:284:12 | z | | test.swift:284:12:284:12 | SSA def(z) | test.swift:285:19:285:19 | z | | test.swift:284:12:284:12 | z | test.swift:284:12:284:12 | SSA def(z) | | test.swift:284:16:284:16 | x | test.swift:284:8:284:12 | let ...? | | test.swift:284:16:284:16 | x | test.swift:291:16:291:16 | x | +| test.swift:287:8:287:12 | let ...? | test.swift:287:12:287:12 | z | | test.swift:287:12:287:12 | SSA def(z) | test.swift:288:19:288:19 | z | | test.swift:287:12:287:12 | z | test.swift:287:12:287:12 | SSA def(z) | | test.swift:287:16:287:16 | y | test.swift:287:8:287:12 | let ...? | | test.swift:287:16:287:16 | y | test.swift:294:16:294:16 | y | +| test.swift:291:8:291:12 | let ...? | test.swift:291:12:291:12 | z | | test.swift:291:12:291:12 | SSA def(z) | test.swift:292:19:292:19 | z | | test.swift:291:12:291:12 | z | test.swift:291:12:291:12 | SSA def(z) | | test.swift:291:16:291:16 | x | test.swift:291:16:291:17 | ...? | | test.swift:291:16:291:16 | x | test.swift:298:20:298:20 | x | | test.swift:291:16:291:26 | OptionalEvaluationExpr | test.swift:291:8:291:12 | let ...? | | test.swift:291:16:291:26 | call to signum() | test.swift:291:16:291:26 | OptionalEvaluationExpr | +| test.swift:294:8:294:12 | let ...? | test.swift:294:12:294:12 | z | | test.swift:294:12:294:12 | SSA def(z) | test.swift:295:19:295:19 | z | | test.swift:294:12:294:12 | z | test.swift:294:12:294:12 | SSA def(z) | | test.swift:294:16:294:16 | y | test.swift:294:16:294:17 | ...? | | test.swift:294:16:294:16 | y | test.swift:299:20:299:20 | y | | test.swift:294:16:294:26 | OptionalEvaluationExpr | test.swift:294:8:294:12 | let ...? | | test.swift:294:16:294:26 | call to signum() | test.swift:294:16:294:26 | OptionalEvaluationExpr | +| test.swift:298:11:298:15 | let ...? | test.swift:298:15:298:15 | z1 | | test.swift:298:15:298:15 | SSA def(z1) | test.swift:300:15:300:15 | z1 | | test.swift:298:15:298:15 | z1 | test.swift:298:15:298:15 | SSA def(z1) | | test.swift:298:20:298:20 | x | test.swift:298:11:298:15 | let ...? | | test.swift:298:20:298:20 | x | test.swift:303:15:303:15 | x | +| test.swift:299:11:299:15 | let ...? | test.swift:299:15:299:15 | z2 | | test.swift:299:15:299:15 | SSA def(z2) | test.swift:301:15:301:15 | z2 | | test.swift:299:15:299:15 | z2 | test.swift:299:15:299:15 | SSA def(z2) | | test.swift:299:20:299:20 | y | test.swift:299:11:299:15 | let ...? | @@ -601,10 +607,12 @@ | test.swift:536:9:536:9 | SSA def(x) | test.swift:538:16:538:16 | x | | test.swift:536:9:536:9 | x | test.swift:536:9:536:9 | SSA def(x) | | test.swift:536:13:536:28 | call to optionalSource() | test.swift:536:9:536:9 | x | +| test.swift:538:8:538:12 | let ...? | test.swift:538:12:538:12 | a | | test.swift:538:12:538:12 | SSA def(a) | test.swift:538:27:538:27 | SSA phi(a) | | test.swift:538:12:538:12 | a | test.swift:538:12:538:12 | SSA def(a) | | test.swift:538:16:538:16 | x | test.swift:538:8:538:12 | let ...? | | test.swift:538:16:538:16 | x | test.swift:543:19:543:19 | x | +| test.swift:538:19:538:23 | let ...? | test.swift:538:23:538:23 | b | | test.swift:538:23:538:23 | SSA def(b) | test.swift:540:19:540:19 | b | | test.swift:538:23:538:23 | b | test.swift:538:23:538:23 | SSA def(b) | | test.swift:538:27:538:27 | SSA phi(a) | test.swift:539:19:539:19 | a | @@ -619,6 +627,7 @@ | test.swift:545:21:545:21 | a | test.swift:545:21:545:21 | SSA def(a) | | test.swift:545:35:545:35 | SSA def(b) | test.swift:547:19:547:19 | b | | test.swift:545:35:545:35 | b | test.swift:545:35:545:35 | SSA def(b) | +| test.swift:552:8:552:17 | let ...? | test.swift:552:12:552:17 | (...) | | test.swift:552:13:552:13 | SSA def(x) | test.swift:553:19:553:19 | x | | test.swift:552:13:552:13 | x | test.swift:552:13:552:13 | SSA def(x) | | test.swift:552:16:552:16 | SSA def(y) | test.swift:554:19:554:19 | y | @@ -647,9 +656,11 @@ | test.swift:566:14:566:16 | call to C.init() | test.swift:566:9:566:9 | cy | | test.swift:567:5:567:5 | [post] cy | test.swift:571:20:571:20 | cy | | test.swift:567:5:567:5 | cy | test.swift:571:20:571:20 | cy | +| test.swift:569:11:569:15 | let ...? | test.swift:569:15:569:15 | z1 | | test.swift:569:15:569:15 | SSA def(z1) | test.swift:570:15:570:15 | z1 | | test.swift:569:15:569:15 | z1 | test.swift:569:15:569:15 | SSA def(z1) | | test.swift:569:20:569:23 | .x | test.swift:569:11:569:15 | let ...? | +| test.swift:571:11:571:15 | let ...? | test.swift:571:15:571:15 | z2 | | test.swift:571:15:571:15 | SSA def(z2) | test.swift:572:15:572:15 | z2 | | test.swift:571:15:571:15 | z2 | test.swift:571:15:571:15 | SSA def(z2) | | test.swift:571:20:571:23 | .x | test.swift:571:11:571:15 | let ...? | diff --git a/swift/ql/test/library-tests/dataflow/dataflow/test.swift b/swift/ql/test/library-tests/dataflow/dataflow/test.swift index d3dc57f8ef1c..a4bed4bcf7e8 100644 --- a/swift/ql/test/library-tests/dataflow/dataflow/test.swift +++ b/swift/ql/test/library-tests/dataflow/dataflow/test.swift @@ -706,7 +706,7 @@ func testArray() { sink(arg: arr4[0]) // $ MISSING: flow=692 var arr5 = Array(repeating: source(), count: 2) - sink(arg: arr5[0]) // $ MISSING: flow=708 + sink(arg: arr5[0]) // $ flow=708 var arr6 = [1,2,3] arr6.insert(source(), at: 2) diff --git a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected index b7408d1f57e0..5953d76c22d5 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/LocalTaint.expected @@ -1,3 +1,125 @@ +| conversions.swift:9:7:9:7 | SSA def(self) | conversions.swift:9:7:9:7 | self[return] | +| conversions.swift:9:7:9:7 | SSA def(self) | conversions.swift:9:7:9:7 | self[return] | +| conversions.swift:9:7:9:7 | self | conversions.swift:9:7:9:7 | SSA def(self) | +| conversions.swift:9:7:9:7 | self | conversions.swift:9:7:9:7 | SSA def(self) | +| conversions.swift:12:7:12:7 | SSA def(self) | conversions.swift:12:7:12:7 | self[return] | +| conversions.swift:12:7:12:7 | self | conversions.swift:12:7:12:7 | SSA def(self) | +| conversions.swift:12:36:12:36 | SSA def(self) | conversions.swift:12:36:12:36 | self[return] | +| conversions.swift:12:36:12:36 | self | conversions.swift:12:36:12:36 | SSA def(self) | +| conversions.swift:15:7:15:7 | SSA def(self) | conversions.swift:15:7:15:7 | self[return] | +| conversions.swift:15:7:15:7 | self | conversions.swift:15:7:15:7 | SSA def(self) | +| conversions.swift:16:11:16:11 | SSA def(self) | conversions.swift:16:11:16:42 | self[return] | +| conversions.swift:16:11:16:11 | self | conversions.swift:16:11:16:11 | SSA def(self) | +| conversions.swift:16:11:16:42 | [summary param] 0 in MyString.init(_:) | conversions.swift:16:11:16:42 | [summary] to write: ReturnValue in MyString.init(_:) | +| conversions.swift:18:28:18:28 | SSA def(self) | conversions.swift:18:28:18:44 | self[return] | +| conversions.swift:18:28:18:28 | self | conversions.swift:18:28:18:28 | SSA def(self) | +| conversions.swift:19:33:19:33 | SSA def(self) | conversions.swift:19:33:19:49 | self[return] | +| conversions.swift:19:33:19:33 | self | conversions.swift:19:33:19:33 | SSA def(self) | +| conversions.swift:20:22:20:22 | SSA def(self) | conversions.swift:20:22:20:38 | self[return] | +| conversions.swift:20:22:20:22 | self | conversions.swift:20:22:20:22 | SSA def(self) | +| conversions.swift:27:16:27:26 | call to sourceInt() | conversions.swift:27:12:27:27 | call to Self.init(_:) | +| conversions.swift:28:18:28:28 | call to sourceInt() | conversions.swift:28:12:28:29 | call to Self.init(_:) | +| conversions.swift:29:18:29:28 | call to sourceInt() | conversions.swift:29:12:29:29 | call to Float.init(_:) | +| conversions.swift:30:19:30:29 | call to sourceInt() | conversions.swift:30:12:30:30 | call to String.init(_:) | +| conversions.swift:31:12:31:30 | call to String.init(_:) | conversions.swift:31:12:31:32 | .utf8 | +| conversions.swift:31:19:31:29 | call to sourceInt() | conversions.swift:31:12:31:30 | call to String.init(_:) | +| conversions.swift:33:6:33:6 | SSA def(arr) | conversions.swift:34:12:34:12 | arr | +| conversions.swift:33:6:33:6 | arr | conversions.swift:33:6:33:6 | SSA def(arr) | +| conversions.swift:33:12:33:30 | [...] | conversions.swift:33:6:33:6 | arr | +| conversions.swift:34:12:34:12 | arr | conversions.swift:35:12:35:12 | arr | +| conversions.swift:35:12:35:12 | [post] arr | conversions.swift:36:20:36:20 | arr | +| conversions.swift:35:12:35:12 | arr | conversions.swift:35:12:35:17 | ...[...] | +| conversions.swift:35:12:35:12 | arr | conversions.swift:36:20:36:20 | arr | +| conversions.swift:36:20:36:20 | arr | conversions.swift:37:20:37:20 | arr | +| conversions.swift:37:12:37:23 | call to Array.init(_:) | conversions.swift:37:12:37:26 | ...[...] | +| conversions.swift:38:20:38:33 | call to sourceString() | conversions.swift:38:20:38:35 | .utf8 | +| conversions.swift:39:12:39:39 | call to Array.init(_:) | conversions.swift:39:12:39:42 | ...[...] | +| conversions.swift:39:20:39:33 | call to sourceString() | conversions.swift:39:20:39:35 | .utf8 | +| conversions.swift:41:5:41:9 | let ...? | conversions.swift:41:9:41:9 | v | +| conversions.swift:41:9:41:9 | SSA def(v) | conversions.swift:42:13:42:13 | v | +| conversions.swift:41:9:41:9 | v | conversions.swift:41:9:41:9 | SSA def(v) | +| conversions.swift:41:13:41:23 | call to sourceInt() | conversions.swift:41:5:41:9 | let ...? | +| conversions.swift:45:6:45:6 | SSA def(v2) | conversions.swift:46:12:46:12 | v2 | +| conversions.swift:45:6:45:6 | v2 | conversions.swift:45:6:45:6 | SSA def(v2) | +| conversions.swift:45:6:45:10 | ... as ... | conversions.swift:45:6:45:6 | v2 | +| conversions.swift:45:18:45:41 | call to numericCast(_:) | conversions.swift:45:6:45:10 | ... as ... | +| conversions.swift:45:30:45:40 | call to sourceInt() | conversions.swift:45:18:45:41 | call to numericCast(_:) | +| conversions.swift:48:6:48:6 | SSA def(v4) | conversions.swift:49:12:49:12 | v4 | +| conversions.swift:48:6:48:6 | v4 | conversions.swift:48:6:48:6 | SSA def(v4) | +| conversions.swift:48:6:48:10 | ... as ... | conversions.swift:48:6:48:6 | v4 | +| conversions.swift:48:17:48:57 | call to unsafeBitCast(_:to:) | conversions.swift:48:6:48:10 | ... as ... | +| conversions.swift:48:31:48:41 | call to sourceInt() | conversions.swift:48:17:48:57 | call to unsafeBitCast(_:to:) | +| conversions.swift:51:6:51:6 | SSA def(v5) | conversions.swift:52:12:52:12 | v5 | +| conversions.swift:51:6:51:6 | v5 | conversions.swift:51:6:51:6 | SSA def(v5) | +| conversions.swift:51:11:51:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:51:6:51:6 | v5 | +| conversions.swift:51:36:51:46 | call to sourceInt() | conversions.swift:51:11:51:47 | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:54:6:54:6 | SSA def(v6) | conversions.swift:55:12:55:12 | v6 | +| conversions.swift:54:6:54:6 | v6 | conversions.swift:54:6:54:6 | SSA def(v6) | +| conversions.swift:54:11:54:39 | call to UInt.init(bitPattern:) | conversions.swift:54:6:54:6 | v6 | +| conversions.swift:54:28:54:38 | call to sourceInt() | conversions.swift:54:11:54:39 | call to UInt.init(bitPattern:) | +| conversions.swift:57:12:57:36 | call to Self.init(exactly:) | conversions.swift:57:12:57:37 | ...! | +| conversions.swift:58:26:58:36 | call to sourceInt() | conversions.swift:58:12:58:37 | call to Self.init(clamping:) | +| conversions.swift:59:36:59:46 | call to sourceInt() | conversions.swift:59:12:59:47 | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:60:12:60:41 | call to Self.init(_:radix:) | conversions.swift:60:12:60:42 | ...! | +| conversions.swift:60:16:60:29 | call to sourceString() | conversions.swift:60:12:60:41 | call to Self.init(_:radix:) | +| conversions.swift:62:30:62:40 | call to sourceInt() | conversions.swift:62:12:62:41 | call to Self.init(littleEndian:) | +| conversions.swift:63:27:63:37 | call to sourceInt() | conversions.swift:63:12:63:38 | call to Self.init(bigEndian:) | +| conversions.swift:64:12:64:22 | call to sourceInt() | conversions.swift:64:12:64:24 | .littleEndian | +| conversions.swift:65:12:65:22 | call to sourceInt() | conversions.swift:65:12:65:24 | .bigEndian | +| conversions.swift:70:18:70:30 | call to sourceFloat() | conversions.swift:70:12:70:31 | call to Float.init(_:) | +| conversions.swift:71:18:71:30 | call to sourceFloat() | conversions.swift:71:12:71:31 | call to UInt8.init(_:) | +| conversions.swift:72:19:72:31 | call to sourceFloat() | conversions.swift:72:12:72:32 | call to String.init(_:) | +| conversions.swift:73:12:73:32 | call to String.init(_:) | conversions.swift:73:12:73:34 | .utf8 | +| conversions.swift:73:19:73:31 | call to sourceFloat() | conversions.swift:73:12:73:32 | call to String.init(_:) | +| conversions.swift:75:18:75:30 | call to sourceFloat() | conversions.swift:75:12:75:31 | call to Float.init(_:) | +| conversions.swift:76:41:76:51 | call to sourceInt() | conversions.swift:76:12:76:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:76:67:76:67 | 0.0 | conversions.swift:76:12:76:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:77:41:77:41 | 0 | conversions.swift:77:12:77:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:77:57:77:69 | call to sourceFloat() | conversions.swift:77:12:77:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:78:54:78:54 | 0.0 | conversions.swift:78:12:78:57 | call to Float.init(signOf:magnitudeOf:) | +| conversions.swift:79:44:79:56 | call to sourceFloat() | conversions.swift:79:12:79:57 | call to Float.init(signOf:magnitudeOf:) | +| conversions.swift:81:12:81:24 | call to sourceFloat() | conversions.swift:81:12:81:26 | .exponent | +| conversions.swift:82:12:82:24 | call to sourceFloat() | conversions.swift:82:12:82:26 | .significand | +| conversions.swift:87:19:87:32 | call to sourceString() | conversions.swift:87:12:87:33 | call to String.init(_:) | +| conversions.swift:89:6:89:6 | SSA def(ms1) | conversions.swift:90:12:90:12 | ms1 | +| conversions.swift:89:6:89:6 | ms1 | conversions.swift:89:6:89:6 | SSA def(ms1) | +| conversions.swift:89:12:89:26 | call to MyString.init(_:) | conversions.swift:89:12:89:27 | ...! | +| conversions.swift:89:12:89:27 | ...! | conversions.swift:89:6:89:6 | ms1 | +| conversions.swift:89:21:89:21 | abc | conversions.swift:89:12:89:26 | call to MyString.init(_:) | +| conversions.swift:90:12:90:12 | [post] ms1 | conversions.swift:91:12:91:12 | ms1 | +| conversions.swift:90:12:90:12 | ms1 | conversions.swift:91:12:91:12 | ms1 | +| conversions.swift:91:12:91:12 | [post] ms1 | conversions.swift:92:12:92:12 | ms1 | +| conversions.swift:91:12:91:12 | ms1 | conversions.swift:92:12:92:12 | ms1 | +| conversions.swift:92:12:92:12 | [post] ms1 | conversions.swift:93:12:93:12 | ms1 | +| conversions.swift:92:12:92:12 | ms1 | conversions.swift:93:12:93:12 | ms1 | +| conversions.swift:95:6:95:6 | SSA def(ms2) | conversions.swift:96:12:96:12 | ms2 | +| conversions.swift:95:6:95:6 | ms2 | conversions.swift:95:6:95:6 | SSA def(ms2) | +| conversions.swift:95:12:95:35 | call to MyString.init(_:) | conversions.swift:95:12:95:36 | ...! | +| conversions.swift:95:12:95:36 | ...! | conversions.swift:95:6:95:6 | ms2 | +| conversions.swift:95:21:95:34 | call to sourceString() | conversions.swift:95:12:95:35 | call to MyString.init(_:) | +| conversions.swift:96:12:96:12 | [post] ms2 | conversions.swift:97:12:97:12 | ms2 | +| conversions.swift:96:12:96:12 | ms2 | conversions.swift:97:12:97:12 | ms2 | +| conversions.swift:97:12:97:12 | [post] ms2 | conversions.swift:98:12:98:12 | ms2 | +| conversions.swift:97:12:97:12 | ms2 | conversions.swift:98:12:98:12 | ms2 | +| conversions.swift:98:12:98:12 | [post] ms2 | conversions.swift:99:12:99:12 | ms2 | +| conversions.swift:98:12:98:12 | ms2 | conversions.swift:99:12:99:12 | ms2 | +| conversions.swift:103:6:103:6 | SSA def(parent) | conversions.swift:104:12:104:12 | parent | +| conversions.swift:103:6:103:6 | parent | conversions.swift:103:6:103:6 | SSA def(parent) | +| conversions.swift:103:6:103:15 | ... as ... | conversions.swift:103:6:103:6 | parent | +| conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:103:6:103:15 | ... as ... | +| conversions.swift:104:12:104:12 | [post] parent | conversions.swift:105:12:105:12 | parent | +| conversions.swift:104:12:104:12 | parent | conversions.swift:105:12:105:12 | parent | +| conversions.swift:105:12:105:12 | [post] parent | conversions.swift:107:40:107:40 | parent | +| conversions.swift:105:12:105:12 | parent | conversions.swift:107:40:107:40 | parent | +| conversions.swift:107:6:107:6 | SSA def(v3) | conversions.swift:108:12:108:12 | v3 | +| conversions.swift:107:6:107:6 | v3 | conversions.swift:107:6:107:6 | SSA def(v3) | +| conversions.swift:107:6:107:10 | ... as ... | conversions.swift:107:6:107:6 | v3 | +| conversions.swift:107:25:107:69 | call to unsafeDowncast(_:to:) | conversions.swift:107:6:107:10 | ... as ... | +| conversions.swift:107:40:107:40 | parent | conversions.swift:107:25:107:69 | call to unsafeDowncast(_:to:) | +| conversions.swift:108:12:108:12 | [post] v3 | conversions.swift:109:12:109:12 | v3 | +| conversions.swift:108:12:108:12 | v3 | conversions.swift:109:12:109:12 | v3 | +| conversions.swift:116:24:116:24 | myCEnumConst | conversions.swift:116:12:116:36 | call to Self.init(_:) | +| conversions.swift:117:24:117:34 | call to sourceInt() | conversions.swift:117:12:117:35 | call to Self.init(_:) | | simple.swift:12:13:12:13 | 1 | simple.swift:12:13:12:24 | ... .+(_:_:) ... | | simple.swift:12:17:12:24 | call to source() | simple.swift:12:13:12:24 | ... .+(_:_:) ... | | simple.swift:13:13:13:20 | call to source() | simple.swift:13:13:13:24 | ... .+(_:_:) ... | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected index 3438ed3afebd..2fcfd5c16eb4 100644 --- a/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected +++ b/swift/ql/test/library-tests/dataflow/taint/core/Taint.expected @@ -1,4 +1,62 @@ edges +| conversions.swift:27:16:27:26 | call to sourceInt() | conversions.swift:27:12:27:27 | call to Self.init(_:) | +| conversions.swift:28:18:28:28 | call to sourceInt() | conversions.swift:28:12:28:29 | call to Self.init(_:) | +| conversions.swift:29:18:29:28 | call to sourceInt() | conversions.swift:29:12:29:29 | call to Float.init(_:) | +| conversions.swift:30:19:30:29 | call to sourceInt() | conversions.swift:30:12:30:30 | call to String.init(_:) | +| conversions.swift:31:12:31:30 | call to String.init(_:) | conversions.swift:31:12:31:32 | .utf8 | +| conversions.swift:31:19:31:29 | call to sourceInt() | conversions.swift:31:12:31:30 | call to String.init(_:) | +| conversions.swift:33:12:33:30 | [...] [Collection element] | conversions.swift:35:12:35:12 | arr [Collection element] | +| conversions.swift:33:12:33:30 | [...] [Collection element] | conversions.swift:37:20:37:20 | arr [Collection element] | +| conversions.swift:33:19:33:29 | call to sourceInt() | conversions.swift:33:12:33:30 | [...] [Collection element] | +| conversions.swift:35:12:35:12 | arr [Collection element] | conversions.swift:35:12:35:17 | ...[...] | +| conversions.swift:37:12:37:23 | call to Array.init(_:) [Collection element] | conversions.swift:37:12:37:26 | ...[...] | +| conversions.swift:37:20:37:20 | arr [Collection element] | conversions.swift:37:12:37:23 | call to Array.init(_:) [Collection element] | +| conversions.swift:39:12:39:39 | call to Array.init(_:) [Collection element] | conversions.swift:39:12:39:42 | ...[...] | +| conversions.swift:39:20:39:33 | call to sourceString() | conversions.swift:39:20:39:35 | .utf8 | +| conversions.swift:39:20:39:35 | .utf8 | conversions.swift:39:12:39:39 | call to Array.init(_:) [Collection element] | +| conversions.swift:41:13:41:23 | call to sourceInt() | conversions.swift:42:13:42:13 | v | +| conversions.swift:45:18:45:41 | call to numericCast(_:) | conversions.swift:46:12:46:12 | v2 | +| conversions.swift:45:30:45:40 | call to sourceInt() | conversions.swift:45:18:45:41 | call to numericCast(_:) | +| conversions.swift:48:17:48:57 | call to unsafeBitCast(_:to:) | conversions.swift:49:12:49:12 | v4 | +| conversions.swift:48:31:48:41 | call to sourceInt() | conversions.swift:48:17:48:57 | call to unsafeBitCast(_:to:) | +| conversions.swift:51:11:51:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:52:12:52:12 | v5 | +| conversions.swift:51:36:51:46 | call to sourceInt() | conversions.swift:51:11:51:47 | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:54:11:54:39 | call to UInt.init(bitPattern:) | conversions.swift:55:12:55:12 | v6 | +| conversions.swift:54:28:54:38 | call to sourceInt() | conversions.swift:54:11:54:39 | call to UInt.init(bitPattern:) | +| conversions.swift:57:12:57:36 | call to Self.init(exactly:) [some:0] | conversions.swift:57:12:57:37 | ...! | +| conversions.swift:57:25:57:35 | call to sourceInt() | conversions.swift:57:12:57:36 | call to Self.init(exactly:) [some:0] | +| conversions.swift:58:26:58:36 | call to sourceInt() | conversions.swift:58:12:58:37 | call to Self.init(clamping:) | +| conversions.swift:59:36:59:46 | call to sourceInt() | conversions.swift:59:12:59:47 | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:60:12:60:41 | call to Self.init(_:radix:) | conversions.swift:60:12:60:42 | ...! | +| conversions.swift:60:16:60:29 | call to sourceString() | conversions.swift:60:12:60:41 | call to Self.init(_:radix:) | +| conversions.swift:62:30:62:40 | call to sourceInt() | conversions.swift:62:12:62:41 | call to Self.init(littleEndian:) | +| conversions.swift:63:27:63:37 | call to sourceInt() | conversions.swift:63:12:63:38 | call to Self.init(bigEndian:) | +| conversions.swift:64:12:64:22 | call to sourceInt() | conversions.swift:64:12:64:24 | .littleEndian | +| conversions.swift:65:12:65:22 | call to sourceInt() | conversions.swift:65:12:65:24 | .bigEndian | +| conversions.swift:70:18:70:30 | call to sourceFloat() | conversions.swift:70:12:70:31 | call to Float.init(_:) | +| conversions.swift:71:18:71:30 | call to sourceFloat() | conversions.swift:71:12:71:31 | call to UInt8.init(_:) | +| conversions.swift:72:19:72:31 | call to sourceFloat() | conversions.swift:72:12:72:32 | call to String.init(_:) | +| conversions.swift:73:12:73:32 | call to String.init(_:) | conversions.swift:73:12:73:34 | .utf8 | +| conversions.swift:73:19:73:31 | call to sourceFloat() | conversions.swift:73:12:73:32 | call to String.init(_:) | +| conversions.swift:75:18:75:30 | call to sourceFloat() | conversions.swift:75:12:75:31 | call to Float.init(_:) | +| conversions.swift:76:41:76:51 | call to sourceInt() | conversions.swift:76:12:76:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:77:57:77:69 | call to sourceFloat() | conversions.swift:77:12:77:70 | call to Float.init(sign:exponent:significand:) | +| conversions.swift:79:44:79:56 | call to sourceFloat() | conversions.swift:79:12:79:57 | call to Float.init(signOf:magnitudeOf:) | +| conversions.swift:81:12:81:24 | call to sourceFloat() | conversions.swift:81:12:81:26 | .exponent | +| conversions.swift:82:12:82:24 | call to sourceFloat() | conversions.swift:82:12:82:26 | .significand | +| conversions.swift:87:19:87:32 | call to sourceString() | conversions.swift:87:12:87:33 | call to String.init(_:) | +| conversions.swift:95:12:95:35 | call to MyString.init(_:) | conversions.swift:95:12:95:35 | call to MyString.init(_:) [some:0] | +| conversions.swift:95:12:95:35 | call to MyString.init(_:) | conversions.swift:96:12:96:12 | ms2 | +| conversions.swift:95:12:95:35 | call to MyString.init(_:) [some:0] | conversions.swift:95:12:95:36 | ...! | +| conversions.swift:95:12:95:36 | ...! | conversions.swift:96:12:96:12 | ms2 | +| conversions.swift:95:21:95:34 | call to sourceString() | conversions.swift:95:12:95:35 | call to MyString.init(_:) | +| conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:104:12:104:12 | parent | +| conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:105:12:105:12 | parent | +| conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:107:40:107:40 | parent | +| conversions.swift:107:25:107:69 | call to unsafeDowncast(_:to:) | conversions.swift:108:12:108:12 | v3 | +| conversions.swift:107:25:107:69 | call to unsafeDowncast(_:to:) | conversions.swift:109:12:109:12 | v3 | +| conversions.swift:107:40:107:40 | parent | conversions.swift:107:25:107:69 | call to unsafeDowncast(_:to:) | +| conversions.swift:117:24:117:34 | call to sourceInt() | conversions.swift:117:12:117:35 | call to Self.init(_:) | | file://:0:0:0:0 | self [first] | file://:0:0:0:0 | .first | | file://:0:0:0:0 | self [second] | file://:0:0:0:0 | .second | | file://:0:0:0:0 | value | file://:0:0:0:0 | [post] self [first] | @@ -77,6 +135,100 @@ edges | try.swift:18:18:18:25 | call to source() | try.swift:18:18:18:25 | call to source() [some:0] | | try.swift:18:18:18:25 | call to source() [some:0] | try.swift:18:13:18:25 | try? ... [some:0] | nodes +| conversions.swift:26:12:26:22 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:27:12:27:27 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| conversions.swift:27:16:27:26 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:28:12:28:29 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| conversions.swift:28:18:28:28 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:29:12:29:29 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | +| conversions.swift:29:18:29:28 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:30:12:30:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:30:19:30:29 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:31:12:31:30 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:31:12:31:32 | .utf8 | semmle.label | .utf8 | +| conversions.swift:31:19:31:29 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:33:12:33:30 | [...] [Collection element] | semmle.label | [...] [Collection element] | +| conversions.swift:33:19:33:29 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:35:12:35:12 | arr [Collection element] | semmle.label | arr [Collection element] | +| conversions.swift:35:12:35:17 | ...[...] | semmle.label | ...[...] | +| conversions.swift:37:12:37:23 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | +| conversions.swift:37:12:37:26 | ...[...] | semmle.label | ...[...] | +| conversions.swift:37:20:37:20 | arr [Collection element] | semmle.label | arr [Collection element] | +| conversions.swift:39:12:39:39 | call to Array.init(_:) [Collection element] | semmle.label | call to Array.init(_:) [Collection element] | +| conversions.swift:39:12:39:42 | ...[...] | semmle.label | ...[...] | +| conversions.swift:39:20:39:33 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:39:20:39:35 | .utf8 | semmle.label | .utf8 | +| conversions.swift:41:13:41:23 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:42:13:42:13 | v | semmle.label | v | +| conversions.swift:45:18:45:41 | call to numericCast(_:) | semmle.label | call to numericCast(_:) | +| conversions.swift:45:30:45:40 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:46:12:46:12 | v2 | semmle.label | v2 | +| conversions.swift:48:17:48:57 | call to unsafeBitCast(_:to:) | semmle.label | call to unsafeBitCast(_:to:) | +| conversions.swift:48:31:48:41 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:49:12:49:12 | v4 | semmle.label | v4 | +| conversions.swift:51:11:51:47 | call to Self.init(truncatingIfNeeded:) | semmle.label | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:51:36:51:46 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:52:12:52:12 | v5 | semmle.label | v5 | +| conversions.swift:54:11:54:39 | call to UInt.init(bitPattern:) | semmle.label | call to UInt.init(bitPattern:) | +| conversions.swift:54:28:54:38 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:55:12:55:12 | v6 | semmle.label | v6 | +| conversions.swift:57:12:57:36 | call to Self.init(exactly:) [some:0] | semmle.label | call to Self.init(exactly:) [some:0] | +| conversions.swift:57:12:57:37 | ...! | semmle.label | ...! | +| conversions.swift:57:25:57:35 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:58:12:58:37 | call to Self.init(clamping:) | semmle.label | call to Self.init(clamping:) | +| conversions.swift:58:26:58:36 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:59:12:59:47 | call to Self.init(truncatingIfNeeded:) | semmle.label | call to Self.init(truncatingIfNeeded:) | +| conversions.swift:59:36:59:46 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:60:12:60:41 | call to Self.init(_:radix:) | semmle.label | call to Self.init(_:radix:) | +| conversions.swift:60:12:60:42 | ...! | semmle.label | ...! | +| conversions.swift:60:16:60:29 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:62:12:62:41 | call to Self.init(littleEndian:) | semmle.label | call to Self.init(littleEndian:) | +| conversions.swift:62:30:62:40 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:63:12:63:38 | call to Self.init(bigEndian:) | semmle.label | call to Self.init(bigEndian:) | +| conversions.swift:63:27:63:37 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:64:12:64:22 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:64:12:64:24 | .littleEndian | semmle.label | .littleEndian | +| conversions.swift:65:12:65:22 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:65:12:65:24 | .bigEndian | semmle.label | .bigEndian | +| conversions.swift:69:12:69:24 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:70:12:70:31 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | +| conversions.swift:70:18:70:30 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:71:12:71:31 | call to UInt8.init(_:) | semmle.label | call to UInt8.init(_:) | +| conversions.swift:71:18:71:30 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:72:12:72:32 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:72:19:72:31 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:73:12:73:32 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:73:12:73:34 | .utf8 | semmle.label | .utf8 | +| conversions.swift:73:19:73:31 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:75:12:75:31 | call to Float.init(_:) | semmle.label | call to Float.init(_:) | +| conversions.swift:75:18:75:30 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:76:12:76:70 | call to Float.init(sign:exponent:significand:) | semmle.label | call to Float.init(sign:exponent:significand:) | +| conversions.swift:76:41:76:51 | call to sourceInt() | semmle.label | call to sourceInt() | +| conversions.swift:77:12:77:70 | call to Float.init(sign:exponent:significand:) | semmle.label | call to Float.init(sign:exponent:significand:) | +| conversions.swift:77:57:77:69 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:79:12:79:57 | call to Float.init(signOf:magnitudeOf:) | semmle.label | call to Float.init(signOf:magnitudeOf:) | +| conversions.swift:79:44:79:56 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:81:12:81:24 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:81:12:81:26 | .exponent | semmle.label | .exponent | +| conversions.swift:82:12:82:24 | call to sourceFloat() | semmle.label | call to sourceFloat() | +| conversions.swift:82:12:82:26 | .significand | semmle.label | .significand | +| conversions.swift:86:12:86:25 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:87:12:87:33 | call to String.init(_:) | semmle.label | call to String.init(_:) | +| conversions.swift:87:19:87:32 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:95:12:95:35 | call to MyString.init(_:) | semmle.label | call to MyString.init(_:) | +| conversions.swift:95:12:95:35 | call to MyString.init(_:) [some:0] | semmle.label | call to MyString.init(_:) [some:0] | +| conversions.swift:95:12:95:36 | ...! | semmle.label | ...! | +| conversions.swift:95:21:95:34 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:96:12:96:12 | ms2 | semmle.label | ms2 | +| conversions.swift:103:31:103:44 | call to sourceString() | semmle.label | call to sourceString() | +| conversions.swift:104:12:104:12 | parent | semmle.label | parent | +| conversions.swift:105:12:105:12 | parent | semmle.label | parent | +| conversions.swift:107:25:107:69 | call to unsafeDowncast(_:to:) | semmle.label | call to unsafeDowncast(_:to:) | +| conversions.swift:107:40:107:40 | parent | semmle.label | parent | +| conversions.swift:108:12:108:12 | v3 | semmle.label | v3 | +| conversions.swift:109:12:109:12 | v3 | semmle.label | v3 | +| conversions.swift:117:12:117:35 | call to Self.init(_:) | semmle.label | call to Self.init(_:) | +| conversions.swift:117:24:117:34 | call to sourceInt() | semmle.label | call to sourceInt() | | file://:0:0:0:0 | .first | semmle.label | .first | | file://:0:0:0:0 | .second | semmle.label | .second | | file://:0:0:0:0 | [post] self [first] | semmle.label | [post] self [first] | @@ -200,6 +352,47 @@ subpaths | stringinterpolation.swift:28:14:28:21 | call to source() | stringinterpolation.swift:7:6:7:6 | value | file://:0:0:0:0 | [post] self [second] | stringinterpolation.swift:28:2:28:2 | [post] p2 [second] | | stringinterpolation.swift:31:21:31:21 | p2 [second] | stringinterpolation.swift:7:6:7:6 | self [second] | file://:0:0:0:0 | .second | stringinterpolation.swift:31:21:31:24 | .second | #select +| conversions.swift:26:12:26:22 | call to sourceInt() | conversions.swift:26:12:26:22 | call to sourceInt() | conversions.swift:26:12:26:22 | call to sourceInt() | result | +| conversions.swift:27:12:27:27 | call to Self.init(_:) | conversions.swift:27:16:27:26 | call to sourceInt() | conversions.swift:27:12:27:27 | call to Self.init(_:) | result | +| conversions.swift:28:12:28:29 | call to Self.init(_:) | conversions.swift:28:18:28:28 | call to sourceInt() | conversions.swift:28:12:28:29 | call to Self.init(_:) | result | +| conversions.swift:29:12:29:29 | call to Float.init(_:) | conversions.swift:29:18:29:28 | call to sourceInt() | conversions.swift:29:12:29:29 | call to Float.init(_:) | result | +| conversions.swift:30:12:30:30 | call to String.init(_:) | conversions.swift:30:19:30:29 | call to sourceInt() | conversions.swift:30:12:30:30 | call to String.init(_:) | result | +| conversions.swift:31:12:31:32 | .utf8 | conversions.swift:31:19:31:29 | call to sourceInt() | conversions.swift:31:12:31:32 | .utf8 | result | +| conversions.swift:35:12:35:17 | ...[...] | conversions.swift:33:19:33:29 | call to sourceInt() | conversions.swift:35:12:35:17 | ...[...] | result | +| conversions.swift:37:12:37:26 | ...[...] | conversions.swift:33:19:33:29 | call to sourceInt() | conversions.swift:37:12:37:26 | ...[...] | result | +| conversions.swift:39:12:39:42 | ...[...] | conversions.swift:39:20:39:33 | call to sourceString() | conversions.swift:39:12:39:42 | ...[...] | result | +| conversions.swift:42:13:42:13 | v | conversions.swift:41:13:41:23 | call to sourceInt() | conversions.swift:42:13:42:13 | v | result | +| conversions.swift:46:12:46:12 | v2 | conversions.swift:45:30:45:40 | call to sourceInt() | conversions.swift:46:12:46:12 | v2 | result | +| conversions.swift:49:12:49:12 | v4 | conversions.swift:48:31:48:41 | call to sourceInt() | conversions.swift:49:12:49:12 | v4 | result | +| conversions.swift:52:12:52:12 | v5 | conversions.swift:51:36:51:46 | call to sourceInt() | conversions.swift:52:12:52:12 | v5 | result | +| conversions.swift:55:12:55:12 | v6 | conversions.swift:54:28:54:38 | call to sourceInt() | conversions.swift:55:12:55:12 | v6 | result | +| conversions.swift:57:12:57:37 | ...! | conversions.swift:57:25:57:35 | call to sourceInt() | conversions.swift:57:12:57:37 | ...! | result | +| conversions.swift:58:12:58:37 | call to Self.init(clamping:) | conversions.swift:58:26:58:36 | call to sourceInt() | conversions.swift:58:12:58:37 | call to Self.init(clamping:) | result | +| conversions.swift:59:12:59:47 | call to Self.init(truncatingIfNeeded:) | conversions.swift:59:36:59:46 | call to sourceInt() | conversions.swift:59:12:59:47 | call to Self.init(truncatingIfNeeded:) | result | +| conversions.swift:60:12:60:42 | ...! | conversions.swift:60:16:60:29 | call to sourceString() | conversions.swift:60:12:60:42 | ...! | result | +| conversions.swift:62:12:62:41 | call to Self.init(littleEndian:) | conversions.swift:62:30:62:40 | call to sourceInt() | conversions.swift:62:12:62:41 | call to Self.init(littleEndian:) | result | +| conversions.swift:63:12:63:38 | call to Self.init(bigEndian:) | conversions.swift:63:27:63:37 | call to sourceInt() | conversions.swift:63:12:63:38 | call to Self.init(bigEndian:) | result | +| conversions.swift:64:12:64:24 | .littleEndian | conversions.swift:64:12:64:22 | call to sourceInt() | conversions.swift:64:12:64:24 | .littleEndian | result | +| conversions.swift:65:12:65:24 | .bigEndian | conversions.swift:65:12:65:22 | call to sourceInt() | conversions.swift:65:12:65:24 | .bigEndian | result | +| conversions.swift:69:12:69:24 | call to sourceFloat() | conversions.swift:69:12:69:24 | call to sourceFloat() | conversions.swift:69:12:69:24 | call to sourceFloat() | result | +| conversions.swift:70:12:70:31 | call to Float.init(_:) | conversions.swift:70:18:70:30 | call to sourceFloat() | conversions.swift:70:12:70:31 | call to Float.init(_:) | result | +| conversions.swift:71:12:71:31 | call to UInt8.init(_:) | conversions.swift:71:18:71:30 | call to sourceFloat() | conversions.swift:71:12:71:31 | call to UInt8.init(_:) | result | +| conversions.swift:72:12:72:32 | call to String.init(_:) | conversions.swift:72:19:72:31 | call to sourceFloat() | conversions.swift:72:12:72:32 | call to String.init(_:) | result | +| conversions.swift:73:12:73:34 | .utf8 | conversions.swift:73:19:73:31 | call to sourceFloat() | conversions.swift:73:12:73:34 | .utf8 | result | +| conversions.swift:75:12:75:31 | call to Float.init(_:) | conversions.swift:75:18:75:30 | call to sourceFloat() | conversions.swift:75:12:75:31 | call to Float.init(_:) | result | +| conversions.swift:76:12:76:70 | call to Float.init(sign:exponent:significand:) | conversions.swift:76:41:76:51 | call to sourceInt() | conversions.swift:76:12:76:70 | call to Float.init(sign:exponent:significand:) | result | +| conversions.swift:77:12:77:70 | call to Float.init(sign:exponent:significand:) | conversions.swift:77:57:77:69 | call to sourceFloat() | conversions.swift:77:12:77:70 | call to Float.init(sign:exponent:significand:) | result | +| conversions.swift:79:12:79:57 | call to Float.init(signOf:magnitudeOf:) | conversions.swift:79:44:79:56 | call to sourceFloat() | conversions.swift:79:12:79:57 | call to Float.init(signOf:magnitudeOf:) | result | +| conversions.swift:81:12:81:26 | .exponent | conversions.swift:81:12:81:24 | call to sourceFloat() | conversions.swift:81:12:81:26 | .exponent | result | +| conversions.swift:82:12:82:26 | .significand | conversions.swift:82:12:82:24 | call to sourceFloat() | conversions.swift:82:12:82:26 | .significand | result | +| conversions.swift:86:12:86:25 | call to sourceString() | conversions.swift:86:12:86:25 | call to sourceString() | conversions.swift:86:12:86:25 | call to sourceString() | result | +| conversions.swift:87:12:87:33 | call to String.init(_:) | conversions.swift:87:19:87:32 | call to sourceString() | conversions.swift:87:12:87:33 | call to String.init(_:) | result | +| conversions.swift:96:12:96:12 | ms2 | conversions.swift:95:21:95:34 | call to sourceString() | conversions.swift:96:12:96:12 | ms2 | result | +| conversions.swift:104:12:104:12 | parent | conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:104:12:104:12 | parent | result | +| conversions.swift:105:12:105:12 | parent | conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:105:12:105:12 | parent | result | +| conversions.swift:108:12:108:12 | v3 | conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:108:12:108:12 | v3 | result | +| conversions.swift:109:12:109:12 | v3 | conversions.swift:103:31:103:44 | call to sourceString() | conversions.swift:109:12:109:12 | v3 | result | +| conversions.swift:117:12:117:35 | call to Self.init(_:) | conversions.swift:117:24:117:34 | call to sourceInt() | conversions.swift:117:12:117:35 | call to Self.init(_:) | 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 | | simple.swift:14:13:14:24 | ... .-(_:_:) ... | simple.swift:14:17:14:24 | call to source() | simple.swift:14:13:14:24 | ... .-(_:_:) ... | result | diff --git a/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift new file mode 100644 index 000000000000..e24c8347251a --- /dev/null +++ b/swift/ql/test/library-tests/dataflow/taint/core/conversions.swift @@ -0,0 +1,118 @@ + +func sourceInt() -> Int { 0 } +func sourceFloat() -> Float { 0.0 } +func sourceString() -> String { "" } +func sink(arg: Any) { } + +// --- + +class MyParentClass { +} + +class MyChildClass : MyParentClass { +} + +class MyString : LosslessStringConvertible, CustomStringConvertible, CustomDebugStringConvertible { + required init?(_ description: String) { } + + var description: String { get { return "" } } + var debugDescription: String { get { return "" } } + var clean: String { get { return "" } } +} + +typealias MyInt = Int + +func testConversions() { + sink(arg: sourceInt()) // $ tainted=26 + sink(arg: Int(sourceInt())) // $ tainted=27 + sink(arg: UInt8(sourceInt())) // $ tainted=28 + sink(arg: Float(sourceInt())) // $ tainted=29 + sink(arg: String(sourceInt())) // $ tainted=30 + sink(arg: String(sourceInt()).utf8) // $ tainted=31 + + let arr = [1, 2, sourceInt()] + sink(arg: arr) + sink(arg: arr[0]) // $ tainted=33 + sink(arg: [MyInt](arr)) + sink(arg: [MyInt](arr)[0]) // $ tainted=33 + sink(arg: [UInt8](sourceString().utf8)) + sink(arg: [UInt8](sourceString().utf8)[0]) // $ tainted=39 + + if let v = sourceInt() as? UInt { + sink(arg: v) // $ tainted=41 + } + + let v2: UInt8 = numericCast(sourceInt()) + sink(arg: v2) // $ tainted=45 + + let v4: UInt = unsafeBitCast(sourceInt(), to: UInt.self) + sink(arg: v4) // $ tainted=48 + + let v5 = UInt(truncatingIfNeeded: sourceInt()) + sink(arg: v5) // $ tainted=51 + + let v6 = UInt(bitPattern: sourceInt()) + sink(arg: v6) // $ tainted=54 + + sink(arg: Int(exactly: sourceInt())!) // $ tainted=57 + sink(arg: Int(clamping: sourceInt())) // $ tainted=58 + sink(arg: Int(truncatingIfNeeded: sourceInt())) // $ tainted=59 + sink(arg: Int(sourceString(), radix: 10)!) // $ tainted=60 + + sink(arg: Int(littleEndian: sourceInt())) // $ tainted=62 + sink(arg: Int(bigEndian: sourceInt())) // $ tainted=63 + sink(arg: sourceInt().littleEndian) // $ tainted=64 + sink(arg: sourceInt().bigEndian) // $ tainted=65 + + // --- + + sink(arg: sourceFloat()) // $ tainted=69 + sink(arg: Float(sourceFloat())) // $ tainted=70 + sink(arg: UInt8(sourceFloat())) // $ tainted=71 + sink(arg: String(sourceFloat())) // $ tainted=72 + sink(arg: String(sourceFloat()).utf8) // $ tainted=73 + + sink(arg: Float(sourceFloat())) // $ tainted=75 + sink(arg: Float(sign: .plus, exponent: sourceInt(), significand: 0.0)) // $ tainted=76 + sink(arg: Float(sign: .plus, exponent: 0, significand: sourceFloat())) // $ tainted=77 + sink(arg: Float(signOf: sourceFloat(), magnitudeOf: 0.0)) // (good) + sink(arg: Float(signOf: 0.0, magnitudeOf: sourceFloat())) // $ tainted=79 + + sink(arg: sourceFloat().exponent) // $ tainted=81 + sink(arg: sourceFloat().significand) // $ tainted=82 + + // --- + + sink(arg: sourceString()) // $ tainted=86 + sink(arg: String(sourceString())) // $ tainted=87 + + let ms1 = MyString("abc")! + sink(arg: ms1) + sink(arg: ms1.description) + sink(arg: ms1.debugDescription) + sink(arg: ms1.clean) + + let ms2 = MyString(sourceString())! + sink(arg: ms2) // $ tainted=95 + sink(arg: ms2.description) // $ MISSING: tainted= + sink(arg: ms2.debugDescription) // $ MISSING: tainted= + sink(arg: ms2.clean) + + // --- + + let parent : MyParentClass = sourceString() as! MyChildClass + sink(arg: parent) // $ tainted=103 + sink(arg: parent as! MyChildClass) // $ tainted=103 + + let v3: MyChildClass = unsafeDowncast(parent, to: MyChildClass.self) + sink(arg: v3) // $ tainted=103 + sink(arg: v3 as! MyParentClass) // $ tainted=103 +} + +var myCEnumConst : Int = 0 +typealias MyCEnumType = UInt32 + +func testCEnum() { + sink(arg: MyCEnumType(myCEnumConst)) + sink(arg: MyCEnumType(sourceInt())) // $ tainted=117 +} diff --git a/swift/ql/test/library-tests/dataflow/taint/libraries/string.swift b/swift/ql/test/library-tests/dataflow/taint/libraries/string.swift index 2544512646f9..120e8b3f41d1 100644 --- a/swift/ql/test/library-tests/dataflow/taint/libraries/string.swift +++ b/swift/ql/test/library-tests/dataflow/taint/libraries/string.swift @@ -589,7 +589,7 @@ func taintedThroughConversion() { sink(arg: String(describing: source())) // $ tainted=589 sink(arg: Int("123")!) - sink(arg: Int(source2())!) // $ MISSING: tainted=592 + sink(arg: Int(source2())!) // $ tainted=592 } func untaintedFields() { diff --git a/swift/ql/test/query-tests/Security/CWE-078/CommandInjection.expected b/swift/ql/test/query-tests/Security/CWE-078/CommandInjection.expected index a015cb69b644..5d4c4a63b587 100644 --- a/swift/ql/test/query-tests/Security/CWE-078/CommandInjection.expected +++ b/swift/ql/test/query-tests/Security/CWE-078/CommandInjection.expected @@ -7,9 +7,11 @@ edges | CommandInjection.swift:69:12:69:12 | userControlledString | CommandInjection.swift:75:27:75:27 | userControlledString | | CommandInjection.swift:69:12:69:12 | userControlledString [some:0] | CommandInjection.swift:75:27:75:27 | userControlledString [some:0] | | CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) | CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) [some:0] | +| CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) | CommandInjection.swift:75:27:75:27 | userControlledString | | CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) [some:0, some:0] | CommandInjection.swift:69:8:69:12 | let ...? [some:0, some:0] | | CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) [some:0] | CommandInjection.swift:69:8:69:12 | let ...? [some:0] | | CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) [some:0] | CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) [some:0, some:0] | +| CommandInjection.swift:69:40:69:94 | call to String.init(contentsOf:) [some:0] | CommandInjection.swift:75:27:75:27 | userControlledString [some:0] | | CommandInjection.swift:75:2:75:2 | [post] task1 [arguments] | CommandInjection.swift:75:2:75:2 | [post] task1 | | CommandInjection.swift:75:20:75:47 | [...] | CommandInjection.swift:75:2:75:2 | [post] task1 [arguments] | | CommandInjection.swift:75:27:75:27 | userControlledString | CommandInjection.swift:75:20:75:47 | [...] | @@ -17,8 +19,10 @@ edges | CommandInjection.swift:75:27:75:27 | userControlledString [some:0] | CommandInjection.swift:78:43:78:43 | userControlledString [some:0] | | CommandInjection.swift:78:5:78:9 | let ...? [some:0] | CommandInjection.swift:78:9:78:9 | validatedString | | CommandInjection.swift:78:9:78:9 | validatedString | CommandInjection.swift:81:31:81:31 | validatedString | +| CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) | CommandInjection.swift:81:31:81:31 | validatedString | | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] | CommandInjection.swift:78:5:78:9 | let ...? [some:0] | | CommandInjection.swift:78:43:78:43 | userControlledString | CommandInjection.swift:58:22:58:33 | command | +| CommandInjection.swift:78:43:78:43 | userControlledString | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) | | CommandInjection.swift:78:43:78:43 | userControlledString | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] | | CommandInjection.swift:78:43:78:43 | userControlledString [some:0] | CommandInjection.swift:58:22:58:33 | command [some:0] | | CommandInjection.swift:78:43:78:43 | userControlledString [some:0] | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] | @@ -29,6 +33,8 @@ edges | CommandInjection.swift:99:12:99:12 | userControlledString | CommandInjection.swift:114:36:114:36 | userControlledString | | CommandInjection.swift:99:12:99:12 | userControlledString | CommandInjection.swift:115:28:115:28 | userControlledString | | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) [some:0] | +| CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | CommandInjection.swift:114:36:114:36 | userControlledString | +| CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) | CommandInjection.swift:115:28:115:28 | userControlledString | | CommandInjection.swift:99:40:99:94 | call to String.init(contentsOf:) [some:0] | CommandInjection.swift:99:8:99:12 | let ...? [some:0] | | CommandInjection.swift:114:2:114:2 | [post] task3 [executableURL] | CommandInjection.swift:114:2:114:2 | [post] task3 | | CommandInjection.swift:114:24:114:56 | call to URL.init(string:) [some:0] | CommandInjection.swift:114:24:114:57 | ...! | @@ -90,6 +96,7 @@ edges | CommandInjection.swift:180:9:180:13 | let ...? [some:0] | CommandInjection.swift:180:13:180:13 | userControlledString | | CommandInjection.swift:180:13:180:13 | userControlledString | CommandInjection.swift:184:19:184:19 | userControlledString | | CommandInjection.swift:180:41:180:95 | call to String.init(contentsOf:) | CommandInjection.swift:180:41:180:95 | call to String.init(contentsOf:) [some:0] | +| CommandInjection.swift:180:41:180:95 | call to String.init(contentsOf:) | CommandInjection.swift:184:19:184:19 | userControlledString | | CommandInjection.swift:180:41:180:95 | call to String.init(contentsOf:) [some:0] | CommandInjection.swift:180:9:180:13 | let ...? [some:0] | | CommandInjection.swift:184:18:184:39 | [...] | CommandInjection.swift:186:18:186:18 | tainted1 | | CommandInjection.swift:184:18:184:39 | [...] | CommandInjection.swift:187:19:187:19 | tainted1 | @@ -139,6 +146,7 @@ nodes | CommandInjection.swift:75:27:75:27 | userControlledString [some:0] | semmle.label | userControlledString [some:0] | | CommandInjection.swift:78:5:78:9 | let ...? [some:0] | semmle.label | let ...? [some:0] | | CommandInjection.swift:78:9:78:9 | validatedString | semmle.label | validatedString | +| CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) | semmle.label | call to validateCommand(_:) | | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] | semmle.label | call to validateCommand(_:) [some:0] | | CommandInjection.swift:78:43:78:43 | userControlledString | semmle.label | userControlledString | | CommandInjection.swift:78:43:78:43 | userControlledString [some:0] | semmle.label | userControlledString [some:0] | @@ -240,6 +248,7 @@ nodes | file://:0:0:0:0 | url | semmle.label | url | | file://:0:0:0:0 | url | semmle.label | url | subpaths +| CommandInjection.swift:78:43:78:43 | userControlledString | CommandInjection.swift:58:22:58:33 | command | CommandInjection.swift:62:16:62:16 | command | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) | | CommandInjection.swift:78:43:78:43 | userControlledString | CommandInjection.swift:58:22:58:33 | command | CommandInjection.swift:62:16:62:16 | command [some:0] | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] | | CommandInjection.swift:78:43:78:43 | userControlledString [some:0] | CommandInjection.swift:58:22:58:33 | command [some:0] | CommandInjection.swift:62:16:62:16 | command [some:0] | CommandInjection.swift:78:27:78:63 | call to validateCommand(_:) [some:0] | #select