Skip to content

Commit dfdc502

Browse files
authored
Merge pull request github#14908 from geoffw0/setmodels
Swift: Flow models for Set
2 parents 2e93c1d + 1638796 commit dfdc502

File tree

5 files changed

+160
-9
lines changed

5 files changed

+160
-9
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Expanded and improved flow models for `Set` and `Sequence`.

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

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,49 @@ private class SequenceSummaries extends SummaryModelCsv {
1414
override predicate row(string row) {
1515
row =
1616
[
17+
";Sequence;true;sorted();;;Argument[-1];ReturnValue;taint",
18+
";Sequence;true;sorted();;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
19+
";Sequence;true;sorted(by:);;;Argument[-1];ReturnValue;taint",
20+
";Sequence;true;sorted(by:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
1721
";Sequence;true;reversed();;;Argument[-1];ReturnValue;taint",
22+
";Sequence;true;reversed();;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
23+
";Sequence;true;shuffled();;;Argument[-1];ReturnValue;taint",
24+
";Sequence;true;shuffled();;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
25+
";Sequence;true;shuffled(using:);;;Argument[-1].CollectionElement;ReturnValue;taint",
26+
";Sequence;true;shuffled(using:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
1827
";Sequence;true;prefix(_:);;;Argument[-1];ReturnValue;taint",
28+
";Sequence;true;prefix(_:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
1929
";Sequence;true;prefix(while:);;;Argument[-1];ReturnValue;taint",
30+
";Sequence;true;prefix(while:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
2031
";Sequence;true;suffix(_:);;;Argument[-1];ReturnValue;taint",
32+
";Sequence;true;suffix(_:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
2133
";Sequence;true;dropFirst(_:);;;Argument[-1];ReturnValue;taint",
34+
";Sequence;true;dropFirst(_:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
2235
";Sequence;true;dropLast(_:);;;Argument[-1];ReturnValue;taint",
36+
";Sequence;true;dropLast(_:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
37+
";Sequence;true;drop(while:);;;Argument[-1];ReturnValue;taint",
38+
";Sequence;true;drop(while:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
2339
";Sequence;true;split(maxSplits:omittingEmptySubsequences:whereSeparator:);;;Argument[-1];ReturnValue;taint",
40+
";Sequence;true;split(maxSplits:omittingEmptySubsequences:whereSeparator:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
2441
";Sequence;true;split(separator:maxSplits:omittingEmptySubsequences:);;;Argument[-1];ReturnValue;taint",
42+
";Sequence;true;split(separator:maxSplits:omittingEmptySubsequences:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
2543
";Sequence;true;joined();;;Argument[-1];ReturnValue;taint",
26-
";Sequence;true;joined(separator:);;;Argument[-1..0];ReturnValue;taint",
27-
";Sequence;true;first(where:);;;Argument[-1];ReturnValue;taint",
44+
";Sequence;true;joined();;;Argument[-1].CollectionElement;ReturnValue;taint",
45+
";Sequence;true;joined();;;Argument[-1].CollectionElement.CollectionElement;ReturnValue.CollectionElement;value",
46+
";Sequence;true;joined(separator:);;;Argument[0..-1];ReturnValue;taint",
47+
";Sequence;true;joined(separator:);;;Argument[-1].CollectionElement;ReturnValue;taint",
48+
";Sequence;true;first(where:);;;Argument[-1].CollectionElement;ReturnValue;value",
2849
";Sequence;true;withContiguousStorageIfAvailable(_:);;;Argument[-1];Argument[0].Parameter[0].CollectionElement;taint",
2950
";Sequence;true;withContiguousStorageIfAvailable(_:);;;Argument[-1].CollectionElement;Argument[0].Parameter[0].CollectionElement;value",
3051
";Sequence;true;withContiguousStorageIfAvailable(_:);;;Argument[0].ReturnValue;ReturnValue.OptionalSome;value",
31-
";Sequence;true;makeIterator();;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value"
52+
";Sequence;true;forEach(_:);;;Argument[-1].CollectionElement;Argument[0].Parameter[0];value",
53+
";Sequence;true;enumerated();;;Argument[-1].CollectionElement;ReturnValue.CollectionElement.TupleElement[1];value",
54+
";Sequence;true;makeIterator();;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;value",
55+
";Sequence;true;min();;;Argument[-1].CollectionElement;ReturnValue.OptionalSome;taint",
56+
";Sequence;true;min(by:);;;Argument[-1].CollectionElement;ReturnValue.OptionalSome;taint",
57+
";Sequence;true;max();;;Argument[-1].CollectionElement;ReturnValue.OptionalSome;taint",
58+
";Sequence;true;max(by:);;;Argument[-1].CollectionElement;ReturnValue.OptionalSome;taint",
59+
";Sequence;true;formatted();;;Argument[-1].CollectionElement;ReturnValue;taint",
3260
]
3361
}
3462
}

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,22 @@ private class SetSummaries extends SummaryModelCsv {
1111
override predicate row(string row) {
1212
row =
1313
[
14-
";Set;true;insert(_:);;;Argument[-1].CollectionElement;ReturnValue.TupleElement[1];value",
14+
";Set;true;init(_:);;;Argument[0];ReturnValue;taint",
15+
";Set;true;init(_:);;;Argument[0].CollectionElement;ReturnValue.CollectionElement;value",
1516
";Set;true;insert(_:);;;Argument[0];Argument[-1].CollectionElement;value",
16-
";Set;true;insert(_:);;;Argument[0];ReturnValue.TupleElement[1];value",
17-
";Set;true;init(_:);;;Argument[0].CollectionElement;ReturnValue.CollectionElement;value"
17+
";Set;true;insert(_:);;;Argument[0];ReturnValue.TupleElement[1];taint",
18+
";Set;true;update(with:);;;Argument[0];Argument[-1].CollectionElement;value",
19+
";Set;true;update(with:);;;Argument[0];ReturnValue.OptionalSome;taint",
20+
";Set;true;remove(_:);;;Argument[0];ReturnValue.OptionalSome;taint",
21+
";Set;true;removeFirst();;;Argument[-1].CollectionElement;ReturnValue;value",
22+
";Set;true;remove(at:);;;Argument[-1].CollectionElement;ReturnValue;value",
23+
";Set;true;filter(_:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;taint",
24+
";Set;true;union(_:);;;Argument[-1..0].CollectionElement;ReturnValue.CollectionElement;value",
25+
";Set;true;formUnion(_:);;;Argument[0].CollectionElement;Argument[-1].CollectionElement;value",
26+
";Set;true;symmetricDifference(_:);;;Argument[-1..0].CollectionElement;ReturnValue.CollectionElement;taint",
27+
";Set;true;formSymmetricDifference(_:);;;Argument[0].CollectionElement;Argument[-1].CollectionElement;taint",
28+
";Set;true;intersection(_:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;taint",
29+
";Set;true;subtracting(_:);;;Argument[-1].CollectionElement;ReturnValue.CollectionElement;taint",
1830
]
1931
}
2032
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
2+
// --- stubs ---
3+
4+
// --- tests ---
5+
6+
func source(_ label: String) -> Int { return 0 }
7+
func sink(arg: Any) {}
8+
9+
// ---
10+
11+
func testSet(ix: Int) {
12+
let goodSet = Set([1, 2, 3])
13+
sink(arg: goodSet)
14+
sink(arg: goodSet.randomElement()!)
15+
sink(arg: goodSet.min()!)
16+
sink(arg: goodSet.max()!)
17+
sink(arg: goodSet.firstIndex(of: 1)!)
18+
sink(arg: goodSet[goodSet.firstIndex(of: 1)!])
19+
sink(arg: goodSet.first!)
20+
for elem in goodSet {
21+
sink(arg: elem)
22+
}
23+
24+
let taintedSet = Set([1, 2, source("t1")])
25+
sink(arg: taintedSet) // $ tainted=t1
26+
sink(arg: taintedSet.randomElement()!) // $ tainted=t1
27+
sink(arg: taintedSet.min()!) // $ tainted=t1
28+
sink(arg: taintedSet.max()!) // $ tainted=t1
29+
sink(arg: taintedSet.firstIndex(of: source("t2"))!)
30+
sink(arg: taintedSet[taintedSet.firstIndex(of: source("t3"))!]) // $ tainted=t1
31+
sink(arg: taintedSet.first!) // $ tainted=t1
32+
for elem in taintedSet {
33+
sink(arg: elem) // $ tainted=t1
34+
}
35+
for (ix, elem) in taintedSet.enumerated() {
36+
sink(arg: ix)
37+
sink(arg: elem) // $ tainted=t1
38+
}
39+
taintedSet.forEach {
40+
elem in
41+
sink(arg: elem) // $ tainted=t1
42+
}
43+
44+
var set1 = Set<Int>()
45+
set1.insert(1)
46+
sink(arg: set1.randomElement()!)
47+
set1.insert(source("t4"))
48+
sink(arg: set1.randomElement()!) // $ tainted=t4
49+
set1.insert(2)
50+
sink(arg: set1.randomElement()!) // $ tainted=t4
51+
set1.removeAll()
52+
sink(arg: set1.randomElement()!) // $ SPURIOUS: tainted=t4
53+
54+
var set2 = Set<Int>()
55+
set2.update(with: source("t5"))
56+
sink(arg: set2.randomElement()!) // $ tainted=t5
57+
58+
var set3 = Set([source("t6")])
59+
sink(arg: set3.randomElement()!) // $ tainted=t6
60+
let (inserted, previous) = set3.insert(source("t7"))
61+
sink(arg: inserted)
62+
sink(arg: previous) // $ tainted=t7
63+
let previous2 = set3.update(with: source("t8"))
64+
sink(arg: previous2!) // $ tainted=t8
65+
let previous3 = set3.remove(source("t9"))
66+
sink(arg: previous3!) // $ tainted=t9
67+
let previous4 = set3.removeFirst()
68+
sink(arg: previous4) // $ tainted=t6 tainted=t7 tainted=t8
69+
let previous5 = set3.remove(at: set3.firstIndex(of: source("t10"))!)
70+
sink(arg: previous5) // $ tainted=t6 tainted=t7 tainted=t8
71+
72+
sink(arg: goodSet.union(goodSet).randomElement()!)
73+
sink(arg: goodSet.union(taintedSet).randomElement()!) // $ tainted=t1
74+
sink(arg: taintedSet.union(goodSet).randomElement()!) // $ tainted=t1
75+
sink(arg: taintedSet.union(taintedSet).randomElement()!) // $ tainted=t1
76+
77+
var set4 = Set<Int>()
78+
set4.formUnion(goodSet)
79+
sink(arg: set4.randomElement()!)
80+
set4.formUnion(taintedSet)
81+
sink(arg: set4.randomElement()!) // $ tainted=t1
82+
set4.formUnion(goodSet)
83+
sink(arg: set4.randomElement()!) // $ tainted=t1
84+
85+
sink(arg: goodSet.intersection(goodSet).randomElement()!)
86+
sink(arg: goodSet.intersection(taintedSet).randomElement()!)
87+
sink(arg: taintedSet.intersection(goodSet).randomElement()!) // $ SPURIOUS: tainted=t1
88+
sink(arg: taintedSet.intersection(taintedSet).randomElement()!) // $ tainted=t1
89+
90+
sink(arg: goodSet.symmetricDifference(goodSet).randomElement()!)
91+
sink(arg: goodSet.symmetricDifference(taintedSet).randomElement()!) // $ tainted=t1
92+
sink(arg: taintedSet.symmetricDifference(goodSet).randomElement()!) // $ tainted=t1
93+
sink(arg: taintedSet.symmetricDifference(taintedSet).randomElement()!) // $ tainted=t1
94+
95+
sink(arg: goodSet.subtracting(goodSet).randomElement()!)
96+
sink(arg: goodSet.subtracting(taintedSet).randomElement()!)
97+
sink(arg: taintedSet.subtracting(goodSet).randomElement()!) // $ tainted=t1
98+
sink(arg: taintedSet.subtracting(taintedSet).randomElement()!) // $ tainted=t1
99+
100+
sink(arg: taintedSet.sorted().randomElement()!) // $ tainted=t1
101+
sink(arg: taintedSet.shuffled().randomElement()!) // $ tainted=t1
102+
103+
sink(arg: taintedSet.lazy[taintedSet.firstIndex(of: source("t11"))!]) // $ tainted=t1
104+
105+
var it = taintedSet.makeIterator()
106+
sink(arg: it.next()!) // $ tainted=t1
107+
}

swift/ql/test/library-tests/dataflow/taint/libraries/string.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,9 @@ func taintThroughSimpleStringOperations() {
267267
}))
268268

269269
sink(arg: [clean, clean].joined())
270-
sink(arg: [tainted, clean].joined()) // $ MISSING: tainted=217
271-
sink(arg: [clean, tainted].joined()) // $ MISSING: tainted=217
272-
sink(arg: [tainted, tainted].joined()) // $ MISSING: tainted=217
270+
sink(arg: [tainted, clean].joined()) // $ tainted=217
271+
sink(arg: [clean, tainted].joined()) // $ tainted=217
272+
sink(arg: [tainted, tainted].joined()) // $ tainted=217
273273

274274
sink(arg: clean.description)
275275
sink(arg: tainted.description) // $ tainted=217

0 commit comments

Comments
 (0)