Skip to content

Commit e1cbde7

Browse files
committed
unified: Model ?? operator
1 parent b33ebeb commit e1cbde7

3 files changed

Lines changed: 28 additions & 0 deletions

File tree

‎unified/ql/lib/codeql/unified/internal/dataflow/DataFlowPluginSwift.qll‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,13 @@ private class SwiftDataFlowPlugin extends DataFlowPlugin {
5353
node2.isResultValue(expr)
5454
)
5555
or
56+
exists(NullCoalescingExpr expr |
57+
// We bypass Optional<T> content so we add value-flow out of both operands of "??"
58+
node1.isResultValue(expr.getAnOperand()) and
59+
step.value() and
60+
node2.isResultValue(expr)
61+
)
62+
or
5663
// Taint flow through URL(string: x). TODO: Model with MaD and flow summaries
5764
exists(CallExpr call |
5865
call.getCallee().(Identifier).getValue() = ["URL", "NSURL"] and

‎unified/ql/test/library-tests/dataflow/test.expected‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,11 @@ edges
284284
| test.swift:247:8:247:12 | ... .some(...) | test.swift:247:12:247:12 | x | provenance | |
285285
| test.swift:247:12:247:12 | x | test.swift:247:8:247:12 | ... .some(...) | provenance | |
286286
| test.swift:247:12:247:12 | x | test.swift:248:14:248:14 | x | provenance | |
287+
| test.swift:254:16:254:45 | ... .some(...) | test.swift:256:10:256:22 | getOptional(...) | provenance | |
288+
| test.swift:254:16:254:45 | ... .some(...) | test.swift:257:20:257:32 | getOptional(...) | provenance | |
289+
| test.swift:254:30:254:44 | source(...) | test.swift:254:16:254:45 | ... .some(...) | provenance | |
290+
| test.swift:256:10:256:22 | getOptional(...) | test.swift:256:10:256:35 | ... ?? ... | provenance | |
291+
| test.swift:257:20:257:32 | getOptional(...) | test.swift:257:10:257:32 | ... ?? ... | provenance | |
287292
nodes
288293
| calls.swift:7:19:7:19 | x | semmle.label | x |
289294
| calls.swift:8:14:8:14 | x | semmle.label | x |
@@ -634,6 +639,12 @@ nodes
634639
| test.swift:247:12:247:12 | x | semmle.label | x |
635640
| test.swift:247:12:247:12 | x | semmle.label | x |
636641
| test.swift:248:14:248:14 | x | semmle.label | x |
642+
| test.swift:254:16:254:45 | ... .some(...) | semmle.label | ... .some(...) |
643+
| test.swift:254:30:254:44 | source(...) | semmle.label | source(...) |
644+
| test.swift:256:10:256:22 | getOptional(...) | semmle.label | getOptional(...) |
645+
| test.swift:256:10:256:35 | ... ?? ... | semmle.label | ... ?? ... |
646+
| test.swift:257:10:257:32 | ... ?? ... | semmle.label | ... ?? ... |
647+
| test.swift:257:20:257:32 | getOptional(...) | semmle.label | getOptional(...) |
637648
subpaths
638649
| calls.swift:31:17:31:30 | source(...) | calls.swift:28:19:28:19 | x | calls.swift:29:16:29:24 | ... + ... | calls.swift:31:10:31:31 | target(...) |
639650
| calls.swift:32:17:32:30 | source(...) | calls.swift:28:19:28:19 | x | calls.swift:29:16:29:24 | ... + ... | calls.swift:32:10:32:31 | target(...) |
@@ -734,3 +745,5 @@ testFailures
734745
| test.swift:229:14:229:20 | element | test.swift:227:14:227:28 | source(...) | test.swift:229:14:229:20 | element | $@ | test.swift:227:14:227:28 | source(...) | source(...) |
735746
| test.swift:229:14:229:20 | element | test.swift:227:31:227:45 | source(...) | test.swift:229:14:229:20 | element | $@ | test.swift:227:31:227:45 | source(...) | source(...) |
736747
| test.swift:248:14:248:14 | x | test.swift:243:30:243:44 | source(...) | test.swift:248:14:248:14 | x | $@ | test.swift:243:30:243:44 | source(...) | source(...) |
748+
| test.swift:256:10:256:35 | ... ?? ... | test.swift:254:30:254:44 | source(...) | test.swift:256:10:256:35 | ... ?? ... | $@ | test.swift:254:30:254:44 | source(...) | source(...) |
749+
| test.swift:257:10:257:32 | ... ?? ... | test.swift:254:30:254:44 | source(...) | test.swift:257:10:257:32 | ... ?? ... | $@ | test.swift:254:30:254:44 | source(...) | source(...) |

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,11 @@ func t27() {
248248
sink(x) // $ hasValueFlow=t27.1
249249
}
250250
}
251+
252+
func t28() {
253+
func getOptional() -> String? {
254+
return Optional.some(source("t28.1"))
255+
}
256+
sink(getOptional() ?? "default") // $ hasValueFlow=t28.1
257+
sink("safe" ?? getOptional()) // $ hasValueFlow=t28.1
258+
}

0 commit comments

Comments
 (0)