Skip to content

Commit de0ec3e

Browse files
committed
Swift: WIP SetContent for dataflow
1 parent abe3a81 commit de0ec3e

File tree

7 files changed

+42
-2
lines changed

7 files changed

+42
-2
lines changed

swift/ql/lib/codeql/swift/dataflow/ExternalFlow.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,9 @@ predicate parseContent(AccessPathToken component, Content content) {
492492
or
493493
component.getName() = "ArrayElement" and
494494
content instanceof Content::ArrayContent
495+
or
496+
component.getName() = "SetElement" and
497+
content instanceof Content::SetContent
495498
}
496499

497500
cached

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,8 @@ private module Cached {
256256
TFieldContent(FieldDecl f) or
257257
TTupleContent(int index) { exists(any(TupleExpr te).getElement(index)) } or
258258
TEnumContent(ParamDecl f) { exists(EnumElementDecl d | d.getAParam() = f) } or
259-
TArrayContent()
259+
TArrayContent() or
260+
TSetContent()
260261
}
261262

262263
/**
@@ -898,7 +899,7 @@ class DataFlowExpr = Expr;
898899
* Holds if access paths with `c` at their head always should be tracked at high
899900
* precision. This disables adaptive access path precision for such access paths.
900901
*/
901-
predicate forceHighPrecision(Content c) { c instanceof Content::ArrayContent }
902+
predicate forceHighPrecision(Content c) { c instanceof Content::ArrayContent or c instanceof Content::SetContent }
902903

903904
/**
904905
* Holds if the node `n` is unreachable when the call context is `call`.

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,11 @@ module Content {
224224
class ArrayContent extends Content, TArrayContent {
225225
override string toString() { result = "Array element" }
226226
}
227+
228+
/** An element of a set */
229+
class SetContent extends Content, TSetContent {
230+
override string toString() { result = "Set element" }
231+
}
227232
}
228233

229234
/**

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ private string getContentSpecific(ContentSet cs) {
114114
cs.isSingleton(c) and
115115
result = "ArrayElement"
116116
)
117+
or
118+
exists(Content::SetContent c |
119+
cs.isSingleton(c) and
120+
result = "SetElement"
121+
)
117122
}
118123

119124
/** Gets the textual representation of a summary component in the format used for MaD models. */
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
private import codeql.swift.dataflow.ExternalFlow
2+
3+
/**
4+
* A model for `Set` and related class members that permit data flow.
5+
*/
6+
private class SetSummaries extends SummaryModelCsv {
7+
override predicate row(string row) {
8+
row =
9+
[
10+
";Set;true;insert(_:);;;Argument[-1].SetElement;ReturnValue.TupleElement[1];value",
11+
";Set;true;insert(_:);;;Argument[0];Argument[-1].SetElement;value",
12+
";Set;true;randomElement();;;Argument[-1].SetElement;ReturnValue;value"
13+
]
14+
}
15+
}

swift/ql/lib/codeql/swift/frameworks/StandardLibrary/StandardLibrary.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ private import NsObject
1515
private import NsString
1616
private import NsUrl
1717
private import Sequence
18+
private import Set
1819
private import String
1920
private import Url
2021
private import UrlSession

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,3 +693,13 @@ func testArray() {
693693
arr6.insert(source(), at: 2)
694694
sink(arg: arr6[0]) // $ flow=693
695695
}
696+
697+
func testSetCollections() {
698+
var set1: Set = [1,2,3]
699+
sink(arg: set1.randomElement()!)
700+
set1.insert(source())
701+
sink(arg: set1.randomElement()!) // $ MISSING: flow=700
702+
703+
let set2 = Set([source()])
704+
sink(arg: set2.randomElement()!) // $ MISSING: flow=703
705+
}

0 commit comments

Comments
 (0)