Skip to content

Commit 74274e8

Browse files
committed
Swift: Add the four complete examples from the doc pages to the examples directory.
1 parent e2e8e5d commit 74274e8

File tree

4 files changed

+91
-0
lines changed

4 files changed

+91
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/**
2+
* @name Empty 'if' statement
3+
* @description Finds 'if' statements where the "then" branch is empty and no
4+
* "else" branch exists.
5+
* @id swift/examples/empty-if
6+
* @tags example
7+
*/
8+
9+
import swift
10+
11+
from IfStmt ifStmt
12+
where
13+
ifStmt.getThen().(BraceStmt).getNumberOfElements() = 0 and
14+
not exists(ifStmt.getElse())
15+
select ifStmt, "This 'if' statement is redundant."
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @name Constant password
3+
* @description Finds places where a string literal is used in a function call
4+
* argument named "password".
5+
* @id swift/examples/simple-constant-password
6+
* @tags example
7+
*/
8+
9+
import swift
10+
import codeql.swift.dataflow.DataFlow
11+
import codeql.swift.dataflow.TaintTracking
12+
13+
module ConstantPasswordConfig implements DataFlow::ConfigSig {
14+
predicate isSource(DataFlow::Node node) { node.asExpr() instanceof StringLiteralExpr }
15+
16+
predicate isSink(DataFlow::Node node) {
17+
// any argument called `password`
18+
exists(CallExpr call | call.getArgumentWithLabel("password").getExpr() = node.asExpr())
19+
}
20+
}
21+
22+
module ConstantPasswordFlow = TaintTracking::Global<ConstantPasswordConfig>;
23+
24+
from DataFlow::Node sourceNode, DataFlow::Node sinkNode
25+
where ConstantPasswordFlow::flow(sourceNode, sinkNode)
26+
select sinkNode, "The value '" + sourceNode.toString() + "' is used as a constant password."
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* @name Database query built from user-controlled sources
3+
* @description Finds places where a value from a remote or local user input
4+
* is used as an argument to the SQLite ``Connection.execute(_:)``
5+
* function.
6+
* @id swift/examples/simple-sql-injection
7+
* @tags example
8+
*/
9+
10+
import swift
11+
import codeql.swift.dataflow.DataFlow
12+
import codeql.swift.dataflow.TaintTracking
13+
import codeql.swift.dataflow.FlowSources
14+
15+
module SqlInjectionConfig implements DataFlow::ConfigSig {
16+
predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
17+
18+
predicate isSink(DataFlow::Node node) {
19+
exists(CallExpr call |
20+
call.getStaticTarget().(MethodDecl).hasQualifiedName("Connection", ["execute(_:)"]) and
21+
call.getArgument(0).getExpr() = node.asExpr()
22+
)
23+
}
24+
}
25+
26+
module SqlInjectionFlow = TaintTracking::Global<SqlInjectionConfig>;
27+
28+
from DataFlow::Node sourceNode, DataFlow::Node sinkNode
29+
where SqlInjectionFlow::flow(sourceNode, sinkNode)
30+
select sinkNode, "This query depends on a $@.", sourceNode, "user-provided value"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* @name Uncontrolled format string
3+
* @description Finds calls to ``String.init(format:_:)`` where the format
4+
* string is not a hard-coded string literal.
5+
* @id swift/examples/simple-uncontrolled-format-string
6+
* @tags example
7+
*/
8+
9+
import swift
10+
import codeql.swift.dataflow.DataFlow
11+
12+
from CallExpr call, MethodDecl method, Expr sinkExpr
13+
where
14+
call.getStaticTarget() = method and
15+
method.hasQualifiedName("String", "init(format:_:)") and
16+
sinkExpr = call.getArgument(0).getExpr() and
17+
not exists(StringLiteralExpr sourceLiteral |
18+
DataFlow::localFlow(DataFlow::exprNode(sourceLiteral), DataFlow::exprNode(sinkExpr))
19+
)
20+
select call, "Format argument to " + method.getName() + " isn't hard-coded."

0 commit comments

Comments
 (0)