Skip to content

Commit d9187c6

Browse files
committed
Swift: Parse MAD enum content.
1 parent 1cfb9bb commit d9187c6

File tree

4 files changed

+34
-3
lines changed

4 files changed

+34
-3
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,9 +476,15 @@ private predicate parseField(AccessPathToken c, Content::FieldContent f) {
476476
)
477477
}
478478

479+
private predicate parseEnum(AccessPathToken c, Content::EnumContent f) {
480+
c.getName() = "Enum" and
481+
c.getAnArgument() = f.getSignature()
482+
}
483+
479484
/** Holds if the specification component parses as a `Content`. */
480485
predicate parseContent(AccessPathToken component, Content content) {
481-
parseField(component, content)
486+
parseField(component, content) or
487+
parseEnum(component, content)
482488
}
483489

484490
cached

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,24 @@ module Content {
202202
/** Gets the declaration of the enum parameter. */
203203
ParamDecl getParam() { result = p }
204204

205-
override string toString() {
205+
/**
206+
* Gets a string describing this enum content, of the form: `EnumElementName:N` where `EnumElementName`
207+
* is the name of the enum element declaration within the enum, and `N` is the 0-based index of the
208+
* parameter that this content is for. For example in the following code there is only one `EnumContent`
209+
* and it's signature is `myValue:0`:
210+
* ```
211+
* enum MyEnum {
212+
* case myValue(Int)
213+
* }
214+
* ```
215+
*/
216+
string getSignature() {
206217
exists(EnumElementDecl d, int pos | d.getParam(pos) = p | result = d.toString() + ":" + pos)
207218
}
219+
220+
override string toString() {
221+
result = this.getSignature()
222+
}
208223
}
209224
}
210225

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,14 @@ edges
210210
| test.swift:490:14:490:32 | call to mkMyEnum1(_:) [mySingle:0] | test.swift:496:13:496:35 | .mySingle(...) [mySingle:0] |
211211
| test.swift:490:24:490:31 | call to source() | test.swift:375:16:375:21 | v |
212212
| test.swift:490:24:490:31 | call to source() | test.swift:490:14:490:32 | call to mkMyEnum1(_:) [mySingle:0] |
213+
| test.swift:492:14:492:32 | call to mkMyEnum2(_:) [mySingle:0] | test.swift:498:13:498:35 | .mySingle(...) [mySingle:0] |
214+
| test.swift:492:24:492:31 | call to source() | test.swift:492:14:492:32 | call to mkMyEnum2(_:) [mySingle:0] |
213215
| test.swift:494:13:494:35 | .mySingle(...) [mySingle:0] | test.swift:494:33:494:33 | d2 |
214216
| test.swift:494:33:494:33 | d2 | test.swift:494:54:494:54 | d2 |
215217
| test.swift:496:13:496:35 | .mySingle(...) [mySingle:0] | test.swift:496:33:496:33 | d4 |
216218
| test.swift:496:33:496:33 | d4 | test.swift:496:54:496:54 | d4 |
219+
| test.swift:498:13:498:35 | .mySingle(...) [mySingle:0] | test.swift:498:33:498:33 | d6 |
220+
| test.swift:498:33:498:33 | d6 | test.swift:498:54:498:54 | d6 |
217221
| test.swift:517:13:517:28 | call to optionalSource() [some:0] | test.swift:519:8:519:12 | let ...? [some:0] |
218222
| test.swift:517:13:517:28 | call to optionalSource() [some:0] | test.swift:524:19:524:19 | x [some:0] |
219223
| test.swift:519:8:519:12 | let ...? [some:0] | test.swift:519:12:519:12 | a |
@@ -517,12 +521,17 @@ nodes
517521
| test.swift:488:30:488:37 | call to source() | semmle.label | call to source() |
518522
| test.swift:490:14:490:32 | call to mkMyEnum1(_:) [mySingle:0] | semmle.label | call to mkMyEnum1(_:) [mySingle:0] |
519523
| test.swift:490:24:490:31 | call to source() | semmle.label | call to source() |
524+
| test.swift:492:14:492:32 | call to mkMyEnum2(_:) [mySingle:0] | semmle.label | call to mkMyEnum2(_:) [mySingle:0] |
525+
| test.swift:492:24:492:31 | call to source() | semmle.label | call to source() |
520526
| test.swift:494:13:494:35 | .mySingle(...) [mySingle:0] | semmle.label | .mySingle(...) [mySingle:0] |
521527
| test.swift:494:33:494:33 | d2 | semmle.label | d2 |
522528
| test.swift:494:54:494:54 | d2 | semmle.label | d2 |
523529
| test.swift:496:13:496:35 | .mySingle(...) [mySingle:0] | semmle.label | .mySingle(...) [mySingle:0] |
524530
| test.swift:496:33:496:33 | d4 | semmle.label | d4 |
525531
| test.swift:496:54:496:54 | d4 | semmle.label | d4 |
532+
| test.swift:498:13:498:35 | .mySingle(...) [mySingle:0] | semmle.label | .mySingle(...) [mySingle:0] |
533+
| test.swift:498:33:498:33 | d6 | semmle.label | d6 |
534+
| test.swift:498:54:498:54 | d6 | semmle.label | d6 |
526535
| test.swift:517:13:517:28 | call to optionalSource() [some:0] | semmle.label | call to optionalSource() [some:0] |
527536
| test.swift:519:8:519:12 | let ...? [some:0] | semmle.label | let ...? [some:0] |
528537
| test.swift:519:12:519:12 | a | semmle.label | a |
@@ -701,6 +710,7 @@ subpaths
701710
| test.swift:482:19:482:19 | e | test.swift:425:26:425:33 | call to source() | test.swift:482:19:482:19 | e | result |
702711
| test.swift:494:54:494:54 | d2 | test.swift:488:30:488:37 | call to source() | test.swift:494:54:494:54 | d2 | result |
703712
| test.swift:496:54:496:54 | d4 | test.swift:490:24:490:31 | call to source() | test.swift:496:54:496:54 | d4 | result |
713+
| test.swift:498:54:498:54 | d6 | test.swift:492:24:492:31 | call to source() | test.swift:498:54:498:54 | d6 | result |
704714
| test.swift:520:19:520:19 | a | test.swift:259:12:259:19 | call to source() | test.swift:520:19:520:19 | a | result |
705715
| test.swift:527:19:527:19 | a | test.swift:259:12:259:19 | call to source() | test.swift:527:19:527:19 | a | result |
706716
| test.swift:551:15:551:15 | z1 | test.swift:259:12:259:19 | call to source() | test.swift:551:15:551:15 | z1 | result |

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ func testEnums() {
495495
if case MyEnum.mySingle(let d3) = c3 { sink(arg: d3) }
496496
if case MyEnum.mySingle(let d4) = c4 { sink(arg: d4) } // $ flow=490
497497
if case MyEnum.mySingle(let d5) = c5 { sink(arg: d5) }
498-
if case MyEnum.mySingle(let d6) = c6 { sink(arg: d6) } // $ MISSING: flow=492
498+
if case MyEnum.mySingle(let d6) = c6 { sink(arg: d6) } // $ flow=492
499499

500500
let e1 = Optional.some(0)
501501
let e2 = Optional.some(source())

0 commit comments

Comments
 (0)