Merge remote-tracking branch 'upstream/main' into post-release-prep/codeql-cli-2.13.3

This commit is contained in:
Arthur Baars
2023-05-30 21:27:53 +02:00
360 changed files with 40677 additions and 18302 deletions

View File

@@ -26,6 +26,7 @@ runs:
--check-repeated-labels \
--check-redefined-labels \
--check-use-before-definition \
--consistency-queries "${{ github.workspace }}/swift/ql/consistency-queries" \
--compilation-cache "${{ steps.query-cache.outputs.cache-dir }}" \
${{ inputs.flags }} \
swift/ql/test

View File

@@ -380,10 +380,10 @@ lib/codeql/swift/generated/KeyPathComponent.qll c79c7bc04fc1426992ab472eedc1a20a
lib/codeql/swift/generated/Locatable.qll be20967d48a34cdba126fe298606e0adc11697831f097acba9c52a0b7ce9983e 8aa01bc376614abbc3209e25785c72f86c9b4e94bb5f471a4a0677fedaec4f61
lib/codeql/swift/generated/Location.qll c5793987e77812059a28254dadee29bfe9b38153c0399fbb1bf6a2f5c237fdab 6e6d8802b021e36bbaad81845657769dd48a798ea33080ada05e9818a20b38f7
lib/codeql/swift/generated/OtherAvailabilitySpec.qll 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5 0e26a203b26ff0581b7396b0c6d1606feec5cc32477f676585cdec4911af91c5
lib/codeql/swift/generated/ParentChild.qll b391a55feb3897dba372a0810e62ac4768531f44c227739b4f2811168c03d2b5 0a3ed301a05d51d19a122be68c691dfb0c736fffa5b51e00486f60a275cfe80c
lib/codeql/swift/generated/ParentChild.qll 5c5ff9812efbed0adf465d1c8b9108c893c77ff946f6feaaec7223ad38664079 94038dcd8a5e98b959ce9f09b7b54b745b0df49b91339b9396017a209abe8bb7
lib/codeql/swift/generated/PlatformVersionAvailabilitySpec.qll f82d9ca416fe8bd59b5531b65b1c74c9f317b3297a6101544a11339a1cffce38 7f5c6d3309e66c134107afe55bae76dfc9a72cb7cdd6d4c3706b6b34cee09fa0
lib/codeql/swift/generated/PureSynthConstructors.qll 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98 173c0dd59396a1de26fe870e3bc2766c46de689da2a4d8807cb62023bbce1a98
lib/codeql/swift/generated/Raw.qll 9dbf606ba1d2d3b3043c5d9c3f48cbcef053d3c5f1c92a095a654c6a022b703f c1fde9798e6ec3c74e79932a193420662e44e96966077567df7bce2276222cb4
lib/codeql/swift/generated/Raw.qll 87402f6b1a0173503a545b57b06c0e320459410834c9adc7a25b2ae53874075e 49e27ddf824decdf21c0531b1ebb3fa007a869ec63bde9f60d08a68fae12acc6
lib/codeql/swift/generated/Synth.qll 551fdf7e4b53f9ee1314d1bb42c2638cf82f45bfa1f40a635dfa7b6072e4418c 9ab178464700a19951fc5285acacda4913addee81515d8e072b3d7055935a814
lib/codeql/swift/generated/SynthConstructors.qll 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4 2f801bd8b0db829b0253cd459ed3253c1fdfc55dce68ebc53e7fec138ef0aca4
lib/codeql/swift/generated/UnknownFile.qll 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6 0fcf9beb8de79440bcdfff4bb6ab3dd139bd273e6c32754e05e6a632651e85f6
@@ -520,7 +520,7 @@ lib/codeql/swift/generated/expr/ObjCSelectorExpr.qll 94a8344bff75033a3aae101c103
lib/codeql/swift/generated/expr/ObjectLiteralExpr.qll f609e898670d4fc7937e9f5024dbf9d82c98bdfcef140cee6e13998046fbe044 cd8647e0b186ce74d27ac0fcfe037972f7e12a326a0ef53c51305cb7db783a0c
lib/codeql/swift/generated/expr/OneWayExpr.qll 8464649694b671a8462476fcd3827b07f8448069c7caa9e9efce44d7ce87aee0 c3e143ecd28238342a1d911a468087cc58a751106385f01cbe5a44e19c862d0e
lib/codeql/swift/generated/expr/OpaqueValueExpr.qll 354f23d00d5ea2e734fd192130620d26c76c14d5bb7b0a1aa69f17ffb5289793 354f23d00d5ea2e734fd192130620d26c76c14d5bb7b0a1aa69f17ffb5289793
lib/codeql/swift/generated/expr/OpenExistentialExpr.qll 55ff1b4fdf23b787538f8b8cdc5f382d874221cec230f8fa35189ebf6de09b58 8235fe3387753a0ac389e297bf67b416991117587a98a566620ac9b328887dd6
lib/codeql/swift/generated/expr/OpenExistentialExpr.qll dfa76a8ce3613f6beb15a1e1ef37588b3862b02044aedad39a70a72d53b0dd4b 0bb2c70df80bccac424e281c772d9cdeac184dabfdbacf609a5a8519e80e923e
lib/codeql/swift/generated/expr/OptionalEvaluationExpr.qll 76a3a789b3a4f17dd494f973f099766aa1db97c38cbbd93542e664a7cd7e1680 f56ce693b59cee6713a7cfdb2937a8a4e791d6e80c241ecd333ab197482a2d1b
lib/codeql/swift/generated/expr/OptionalTryExpr.qll f0c8dff90faee4fbf07772efda53afe1acc1fd148c16ee4d85a1502a36178e71 f0c8dff90faee4fbf07772efda53afe1acc1fd148c16ee4d85a1502a36178e71
lib/codeql/swift/generated/expr/OtherInitializerRefExpr.qll 94b793be9a37626fe0b1b7c93ac37b2a00e4fb93ab96e4a230aaba66ef1721de 136ac6a349db23144fc71f3aa1383fb68370b13a8615eb6ad398b29a55f2cae3
@@ -818,7 +818,8 @@ test/extractor-tests/generated/expr/ObjectLiteralExpr/ObjectLiteralExpr_getArgum
test/extractor-tests/generated/expr/ObjectLiteralExpr/ObjectLiteralExpr_getType.ql 07d59d9962f3705f8f32302c0d730c179ca980172dd000b724a72e768fbf39db cd146e19249590316bb83efec19dd41234723513025cf9df45313f78f2b364dd
test/extractor-tests/generated/expr/OneWayExpr/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/expr/OpaqueValueExpr/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/expr/OpenExistentialExpr/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/expr/OpenExistentialExpr/OpenExistentialExpr.ql 48da42e3a2d44f4ca6b159bc8ba273352984b34fd14a3d6ca15ec9d6c38a2608 ba6a769c8c3c8cea40d64e0339515f59aded493d2c8f9c2447b10bcc43bed5f7
test/extractor-tests/generated/expr/OpenExistentialExpr/OpenExistentialExpr_getType.ql f8d4ddc40e4bef7760446bfb90f3d2b7438fd5a0a2aa092efd59493fa8a98b23 e54f77a98a38c2c68414a5e6de8de18189ce7f0e68f9c945ab387e52d7e04a12
test/extractor-tests/generated/expr/OptionalEvaluationExpr/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/expr/OptionalTryExpr/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7
test/extractor-tests/generated/expr/OtherInitializerRefExpr/MISSING_SOURCE.txt 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7 66846d526b0bc4328735c3c4dd9c390a9325da5b5dfd42ec07622f9c7108a7d7

3
swift/ql/.gitattributes generated vendored
View File

@@ -820,7 +820,8 @@
/test/extractor-tests/generated/expr/ObjectLiteralExpr/ObjectLiteralExpr_getType.ql linguist-generated
/test/extractor-tests/generated/expr/OneWayExpr/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/expr/OpaqueValueExpr/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/expr/OpenExistentialExpr/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/expr/OpenExistentialExpr/OpenExistentialExpr.ql linguist-generated
/test/extractor-tests/generated/expr/OpenExistentialExpr/OpenExistentialExpr_getType.ql linguist-generated
/test/extractor-tests/generated/expr/OptionalEvaluationExpr/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/expr/OptionalTryExpr/MISSING_SOURCE.txt linguist-generated
/test/extractor-tests/generated/expr/OtherInitializerRefExpr/MISSING_SOURCE.txt linguist-generated

View File

@@ -0,0 +1 @@
import codeql.swift.printast.Consistency

View File

@@ -0,0 +1,4 @@
---
category: newQuery
---
* Added two consistency queries for checking control flow and AST printing internals.

View File

@@ -0,0 +1,4 @@
name: codeql/swift-consistency-queries
groups: [swift, test, consistency-queries]
dependencies:
codeql/swift-all: ${workspace}

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Some models for the `Data` class have been generalized to `DataProtocol` so that they apply more widely.

View File

@@ -0,0 +1,5 @@
---
category: fix
---
* Fixed a number of inconsistencies in the abstract syntax tree (AST) and in the control-flow graph (CFG). This may lead to more results in queries that use these libraries, or libraries that depend on them (such as dataflow).

View File

@@ -111,31 +111,21 @@ module Stmts {
override predicate propagatesAbnormal(ControlFlowElement node) { none() }
private predicate isBodyOfTapExpr() { any(TapExpr tap).getBody() = ast }
// Note: If the brace statement is the body of a `TapExpr`, the first element is the variable
// declaration (see https://github.com/apple/swift/blob/main/include/swift/AST/Expr.h#L848)
// that's initialized by the `TapExpr`. In `TapExprTree` we've already visited this declaration,
// along with its initializer. So we skip the first element here.
private AstNode getFirstElement() {
if this.isBodyOfTapExpr() then result = ast.getElement(1) else result = ast.getFirstElement()
}
override predicate first(ControlFlowElement first) {
this.firstInner(first)
or
not exists(this.getFirstElement()) and first.asAstNode() = ast
not exists(ast.getFirstElement()) and first.asAstNode() = ast
}
override predicate last(ControlFlowElement last, Completion c) {
this.lastInner(last, c)
or
not exists(this.getFirstElement()) and
not exists(ast.getFirstElement()) and
last.asAstNode() = ast and
c instanceof SimpleCompletion
}
predicate firstInner(ControlFlowElement first) { astFirst(this.getFirstElement(), first) }
predicate firstInner(ControlFlowElement first) { astFirst(ast.getFirstElement(), first) }
/** Gets the body of the i'th `defer` statement. */
private BraceStmt getDeferStmtBody(int i) {
@@ -969,6 +959,15 @@ module Decls {
result.asAstNode() = ast.getPattern(j).getFullyUnresolved()
)
or
// synthesized pattern bindings for property wrappers may be sharing the init with the backed
// variable declaration, so we need to skip those
not exists(VarDecl decl |
ast =
[
decl.getPropertyWrapperBackingVarBinding(),
decl.getPropertyWrapperProjectionVarBinding()
]
) and
exists(int j |
i = 2 * j + 1 and
result.asAstNode() = ast.getInit(j).getFullyConverted()
@@ -1397,20 +1396,12 @@ module Exprs {
override TapExpr ast;
final override ControlFlowElement getChildElement(int i) {
// We first visit the local variable declaration.
// We first visit the expression that gives the local variable its initial value.
i = 0 and
result.asAstNode() = ast.getVar()
or
// Then we visit the expression that gives the local variable its initial value.
i = 1 and
result.asAstNode() = ast.getSubExpr().getFullyConverted()
or
// And finally, we visit the body that potentially mutates the local variable.
// Note that the CFG for the body will skip the first element in the
// body because it's guaranteed to be the variable declaration
// that we've already visited at i = 0. See the explanation
// in `BraceStmtTree` for why this is necessary.
i = 2 and
// And then we visit the body that potentially mutates the local variable.
i = 1 and
result.asAstNode() = ast.getBody()
}
}

View File

@@ -26,9 +26,9 @@ private class DataSummaries extends SummaryModelCsv {
";Data;true;base64EncodedData(options:);;;Argument[-1];ReturnValue;taint",
";Data;true;base64EncodedString(options:);;;Argument[-1];ReturnValue;taint",
";Data;true;compactMap(_:);;;Argument[-1];ReturnValue;taint",
";Data;true;copyBytes(to:);;;Argument[-1];Argument[0];taint",
";Data;true;copyBytes(to:count:);;;Argument[-1];Argument[0];taint",
";Data;true;copyBytes(to:from:);;;Argument[-1];Argument[0];taint",
";DataProtocol;true;copyBytes(to:);;;Argument[-1];Argument[0];taint",
";DataProtocol;true;copyBytes(to:count:);;;Argument[-1];Argument[0];taint",
";DataProtocol;true;copyBytes(to:from:);;;Argument[-1];Argument[0];taint",
";Data;true;flatMap(_:);;;Argument[-1];ReturnValue;taint",
";Data;true;insert(contentsOf:at:);;;Argument[0];Argument[-1];taint",
";Data;true;map(_:);;;Argument[-1];ReturnValue;taint",

View File

@@ -1613,13 +1613,12 @@ private module Impl {
private Element getImmediateChildOfOpenExistentialExpr(
OpenExistentialExpr e, int index, string partialPredicateCall
) {
exists(int b, int bExpr, int n, int nSubExpr, int nExistential, int nOpaqueExpr |
exists(int b, int bExpr, int n, int nSubExpr, int nExistential |
b = 0 and
bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and
n = bExpr and
nSubExpr = n + 1 and
nExistential = nSubExpr + 1 and
nOpaqueExpr = nExistential + 1 and
(
none()
or
@@ -1630,10 +1629,6 @@ private module Impl {
index = nSubExpr and
result = e.getImmediateExistential() and
partialPredicateCall = "Existential()"
or
index = nExistential and
result = e.getImmediateOpaqueExpr() and
partialPredicateCall = "OpaqueExpr()"
)
)
}

View File

@@ -1438,22 +1438,35 @@ module Raw {
/**
* INTERNAL: Do not use.
* An implicit expression created by the compiler when a method is called on a protocol. For example in
* ```
* protocol P {
* func foo() -> Int
* }
* func bar(x: P) -> Int {
* return x.foo()
* }
* `x.foo()` is actually wrapped in an `OpenExistentialExpr` that "opens" `x` replacing it in its subexpression with
* an `OpaqueValueExpr`.
* ```
*/
class OpenExistentialExpr extends @open_existential_expr, Expr {
override string toString() { result = "OpenExistentialExpr" }
/**
* Gets the sub expression of this open existential expression.
*
* This wrapped subexpression is where the opaque value and the dynamic type under the protocol type may be used.
*/
Expr getSubExpr() { open_existential_exprs(this, result, _, _) }
/**
* Gets the existential of this open existential expression.
* Gets the protocol-typed expression opened by this expression.
*/
Expr getExistential() { open_existential_exprs(this, _, result, _) }
/**
* Gets the opaque expression of this open existential expression.
* Gets the opaque value expression embedded within `getSubExpr()`.
*/
OpaqueValueExpr getOpaqueExpr() { open_existential_exprs(this, _, _, result) }
}

View File

@@ -5,6 +5,19 @@ import codeql.swift.elements.expr.Expr
import codeql.swift.elements.expr.OpaqueValueExpr
module Generated {
/**
* An implicit expression created by the compiler when a method is called on a protocol. For example in
* ```
* protocol P {
* func foo() -> Int
* }
* func bar(x: P) -> Int {
* return x.foo()
* }
* `x.foo()` is actually wrapped in an `OpenExistentialExpr` that "opens" `x` replacing it in its subexpression with
* an `OpaqueValueExpr`.
* ```
*/
class OpenExistentialExpr extends Synth::TOpenExistentialExpr, Expr {
override string getAPrimaryQlClass() { result = "OpenExistentialExpr" }
@@ -23,6 +36,8 @@ module Generated {
/**
* Gets the sub expression of this open existential expression.
*
* This wrapped subexpression is where the opaque value and the dynamic type under the protocol type may be used.
*/
final Expr getSubExpr() {
exists(Expr immediate |
@@ -32,7 +47,7 @@ module Generated {
}
/**
* Gets the existential of this open existential expression.
* Gets the protocol-typed expression opened by this expression.
*
* This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the
* behavior of both the `Immediate` and non-`Immediate` versions.
@@ -45,7 +60,7 @@ module Generated {
}
/**
* Gets the existential of this open existential expression.
* Gets the protocol-typed expression opened by this expression.
*/
final Expr getExistential() {
exists(Expr immediate |
@@ -55,7 +70,7 @@ module Generated {
}
/**
* Gets the opaque expression of this open existential expression.
* Gets the opaque value expression embedded within `getSubExpr()`.
*
* This includes nodes from the "hidden" AST. It can be overridden in subclasses to change the
* behavior of both the `Immediate` and non-`Immediate` versions.
@@ -68,7 +83,7 @@ module Generated {
}
/**
* Gets the opaque expression of this open existential expression.
* Gets the opaque value expression embedded within `getSubExpr()`.
*/
final OpaqueValueExpr getOpaqueExpr() {
exists(OpaqueValueExpr immediate |

View File

@@ -0,0 +1,40 @@
/** Provides a set of checks that the AST is actually a tree. */
private import codeql.swift.printast.PrintAstNode
/** Checks that no child has more than one parent. */
query predicate doubleParents(
PrintAstNode parent1, string label1, PrintAstNode parent2, string label2, PrintAstNode child
) {
parent1 != parent2 and
parent1.hasChild(child, _, label1) and
parent2.hasChild(child, _, label2)
}
/** Checks that no two children share the same index. */
query predicate doubleChildren(
PrintAstNode parent, int index, string label1, PrintAstNode child1, string label2,
PrintAstNode child2
) {
child1 != child2 and
parent.hasChild(child1, index, label1) and
parent.hasChild(child2, index, label2)
}
/** Checks that no child is under different indexes. */
query predicate doubleIndexes(
PrintAstNode parent, int index1, string label1, int index2, string label2, PrintAstNode child
) {
index1 != index2 and
parent.hasChild(child, index1, label1) and
parent.hasChild(child, index2, label2)
}
private predicate isChildOf(PrintAstNode parent, PrintAstNode child) {
parent.hasChild(child, _, _)
}
/** Checks that there is no back edge. */
query predicate parentChildLoops(PrintAstNode parent, PrintAstNode child) {
isChildOf(parent, child) and isChildOf*(child, parent)
}

View File

@@ -28,7 +28,7 @@ private predicate shouldPrint(Locatable e) { any(PrintAstConfiguration config).s
/**
* An AST node that should be printed.
*/
private newtype TPrintAstNode = TLocatable(Locatable ast)
private newtype TPrintAstNode = TPrintLocatable(Locatable ast)
/**
* A node in the output tree.
@@ -60,6 +60,11 @@ class PrintAstNode extends TPrintAstNode {
* the property is `key`.
*/
string getProperty(string key) { none() }
/**
* Gets the underlying AST node, if any.
*/
abstract Locatable getAstNode();
}
private string prettyPrint(Locatable e) {
@@ -73,10 +78,10 @@ private class Unresolved extends Locatable {
/**
* A graph node representing a real Locatable node.
*/
class PrintLocatable extends PrintAstNode, TLocatable {
class PrintLocatable extends PrintAstNode, TPrintLocatable {
Locatable ast;
PrintLocatable() { this = TLocatable(ast) }
PrintLocatable() { this = TPrintLocatable(ast) }
override string toString() { result = prettyPrint(ast) }
@@ -87,9 +92,9 @@ class PrintLocatable extends PrintAstNode, TLocatable {
c = getChildAndAccessor(ast, i, accessor) and
(
// use even indexes for normal children, leaving odd slots for conversions if any
child = TLocatable(c) and index = 2 * i and label = accessor
child = TPrintLocatable(c) and index = 2 * i and label = accessor
or
child = TLocatable(c.getFullyUnresolved().(Unresolved)) and
child = TPrintLocatable(c.getFullyUnresolved().(Unresolved)) and
index = 2 * i + 1 and
(
if c instanceof Expr
@@ -100,6 +105,8 @@ class PrintLocatable extends PrintAstNode, TLocatable {
)
}
final override Locatable getAstNode() { result = ast }
final override Location getLocation() { result = ast.getLocation() }
}
@@ -112,17 +119,38 @@ class PrintUnresolved extends PrintLocatable {
override predicate hasChild(PrintAstNode child, int index, string label) {
// only print immediate unresolved children from the "parallel" AST
child = TLocatable(getImmediateChildAndAccessor(ast, index, label).(Unresolved))
child = TPrintLocatable(getImmediateChildAndAccessor(ast, index, label).(Unresolved))
}
}
private predicate hasPropertyWrapperElement(VarDecl d, Locatable a) {
a = [d.getPropertyWrapperBackingVar(), d.getPropertyWrapperProjectionVar()] or
a = [d.getPropertyWrapperBackingVarBinding(), d.getPropertyWrapperProjectionVarBinding()]
}
/**
* A specialization of graph node for `VarDecl`, to add typing information.
* A specialization of graph node for `VarDecl`, to add typing information and deal with ambiguity
* over property wrapper children.
*/
class PrintVarDecl extends PrintLocatable {
override VarDecl ast;
override string getProperty(string key) { key = "Type" and result = ast.getType().toString() }
override predicate hasChild(PrintAstNode child, int index, string label) {
PrintLocatable.super.hasChild(child, index, label) and
// exclude property wrapper related children when they are already listed in the enclosing
// nominal type declaration or for a wrapped parameter for which this is a virtual local variable copy
not exists(Locatable childAst |
childAst = child.getAstNode() and
hasPropertyWrapperElement(ast, childAst) and
(
childAst = ast.getDeclaringDecl().getAMember()
or
ast instanceof ConcreteVarDecl and hasPropertyWrapperElement(any(ParamDecl p), childAst)
)
)
}
}
/**
@@ -135,3 +163,23 @@ class PrintFunction extends PrintLocatable {
key = "InterfaceType" and result = ast.getInterfaceType().toString()
}
}
/**
* A specialization of graph node for `PatternBindingDecl`, to solve ambiguity on `getInit`.
* When a property wrapper is involved, `getInit` may become shared between the explicit binding and
* the implicit compiler synthesized one.
*/
class PrintPatternBindingDecl extends PrintLocatable {
override PatternBindingDecl ast;
override predicate hasChild(PrintAstNode child, int index, string label) {
PrintLocatable.super.hasChild(child, index, label) and
// exclude `getInit` that are already the initializer of a variable that has this as a property wrapper backer
not exists(Expr init, VarDecl var |
init = child.getAstNode() and
init = ast.getAnInit() and
var.getPropertyWrapperBackingVarBinding() = ast and
var.getParentInitializer() = init
)
}
}

View File

@@ -38,27 +38,34 @@ class StringType extends TStringType {
csvLabel = "nsstring-length"
or
this = TStringUtf8() and
name = "String.utf8" and
singular = "a String.utf8" and
name = "String.UTF8View" and
singular = "a String.UTF8View" and
equivClass = this and
csvLabel = "string-utf8-length"
or
this = TStringUtf16() and
name = "String.utf16" and
singular = "a String.utf16" and
name = "String.UTF16View" and
singular = "a String.UTF16View" and
equivClass = TNsString() and
csvLabel = "string-utf16-length"
or
this = TStringUnicodeScalars() and
name = "String.unicodeScalars" and
singular = "a String.unicodeScalars" and
name = "String.UnicodeScalarView" and
singular = "a String.UnicodeScalarView" and
equivClass = this and
csvLabel = "string-unicodescalars-length"
}
/** Gets a textual representation of this string type. */
/**
* Gets a textual representation of this string type.
*/
string toString() { result = name }
/**
* Gets the name of this string type.
*/
string getName() { result = name }
/**
* Gets the equivalence class for this string type. If these are equal,
* they should be treated as equivalent.
@@ -142,21 +149,16 @@ private class ExtraStringLengthConflationSource extends StringLengthConflationSo
StringType stringType;
ExtraStringLengthConflationSource() {
exists(MemberRefExpr memberRef, string typeName |
// source is the result of a call to `[stringType].count`.
exists(MemberRefExpr memberRef |
(
// result of a call to `String.utf8.count`
typeName = "String.UTF8View" and
stringType = TStringUtf8()
or
// result of a call to `String.utf16.count`
typeName = "String.UTF16View" and
stringType = TStringUtf16()
or
// result of a call to `String.unicodeScalars.count`
typeName = "String.UnicodeScalarView" and
stringType = TStringUnicodeScalars()
) and
memberRef.getBase().getType().(NominalType).getName() = typeName and
memberRef.getBase().getType().(NominalType).getName() = stringType.getName() and
memberRef.getMember().(VarDecl).getName() = "count" and
this.asExpr() = memberRef
)
@@ -180,14 +182,6 @@ private class StringLengthConflationSinks extends SinkModelCsv {
override predicate row(string row) {
row =
[
";Sequence;true;dropFirst(_:);;;Argument[0];string-length",
";Sequence;true;dropLast(_:);;;Argument[0];string-length",
";Sequence;true;prefix(_:);;;Argument[0];string-length",
";Sequence;true;suffix(_:);;;Argument[0];string-length",
";Collection;true;formIndex(_:offsetBy:);;;Argument[0..1];string-length",
";Collection;true;formIndex(_:offsetBy:limitBy:);;;Argument[0..1];string-length",
";Collection;true;removeFirst(_:);;;Argument[0];string-length",
";RangeReplaceableCollection;true;removeLast(_:);;;Argument[0];string-length",
";String;true;index(_:offsetBy:);;;Argument[0..1];string-length",
";String;true;index(_:offsetBy:limitBy:);;;Argument[0..1];string-length",
";String.Index;true;init(encodedOffset:);;;Argument[0];string-length",
@@ -203,3 +197,45 @@ private class StringLengthConflationSinks extends SinkModelCsv {
]
}
}
/**
* An extra sink that don't fit into the CSV scheme (because we care about the actual
* type the method is being called on, not just the type it's declared on).
*/
private class ExtraStringLengthConflationSink extends StringLengthConflationSink {
StringType stringType;
ExtraStringLengthConflationSink() {
// sink is a length or offset argument of a call to `[stringType].[method]`.
exists(CallExpr call |
(
stringType = TString()
or
stringType = TStringUtf8()
or
stringType = TStringUtf16()
or
stringType = TStringUnicodeScalars()
) and
(
call.getQualifier().getType().(NominalType).getName() = stringType.getName() or
call.getQualifier().getType().(InOutType).getObjectType().(NominalType).getName() =
stringType.getName()
) and
(
call.getStaticTarget().getName() =
[
"dropFirst(_:)", "dropLast(_:)", "prefix(_:)", "suffix(_:)", "removeFirst(_:)",
"removeLast(_:)"
] and
this.asExpr() = call.getArgument(0).getExpr()
or
call.getStaticTarget().getName() =
["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and
this.asExpr() = call.getArgument([0, 1]).getExpr()
)
)
}
override StringType getCorrectStringType() { result = stringType }
}

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Fixed some false positive results from the `swift/string-length-conflation` query, caused by imprecise sinks.

View File

@@ -0,0 +1,6 @@
deadEnd
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,5 @@
deadEnd
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| unspecified.swift:12:20:12:21 | (...) |
| unspecified.swift:25:9:28:9 | switch ErrorExpr { ... } |

View File

@@ -0,0 +1,2 @@
deadEnd
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,6 @@
deadEnd
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,14 @@
multipleSuccessors
| method_lookups.swift:42:9:42:19 | call to baz(_:) | successor | method_lookups.swift:42:3:42:19 | await ... |
| method_lookups.swift:42:9:42:19 | call to baz(_:) | successor | method_lookups.swift:44:7:44:7 | f |
| method_lookups.swift:48:9:48:19 | call to foo(_:_:) | successor | method_lookups.swift:48:3:48:19 | await ... |
| method_lookups.swift:48:9:48:19 | call to foo(_:_:) | successor | method_lookups.swift:49:9:49:11 | .bar() |
| method_lookups.swift:49:9:49:15 | call to bar() | successor | method_lookups.swift:49:3:49:15 | await ... |
| method_lookups.swift:49:9:49:15 | call to bar() | successor | method_lookups.swift:50:9:50:13 | .baz(_:) |
| method_lookups.swift:50:9:50:19 | call to baz(_:) | successor | method_lookups.swift:50:3:50:19 | await ... |
| method_lookups.swift:50:9:50:19 | call to baz(_:) | successor | method_lookups.swift:52:7:52:7 | f |
deadEnd
| method_lookups.swift:42:3:42:19 | await ... |
| method_lookups.swift:48:3:48:19 | await ... |
| method_lookups.swift:49:3:49:15 | await ... |
| method_lookups.swift:50:3:50:19 | await ... |

View File

@@ -0,0 +1,3 @@
doubleIndexes
| method_lookups.swift:44:13:44:13 | [AutoClosureExpr] { ... } | 2 | getParam(0) | 4 | getParam(1) | file://:0:0:0:0 | [ParamDecl] argument |
| method_lookups.swift:44:13:44:13 | [AutoClosureExpr] { ... } | 4 | getParam(1) | 2 | getParam(0) | file://:0:0:0:0 | [ParamDecl] argument |

View File

@@ -1,4 +0,0 @@
// generated by codegen/codegen.py
After a source file is added in this directory and codegen/codegen.py is run again, test queries
will appear and this file will be deleted

View File

@@ -0,0 +1 @@
| open_existentials.swift:14:5:14:19 | OpenExistentialExpr | hasType: | yes | getSubExpr: | open_existentials.swift:14:5:14:19 | call to foo() | getExistential: | open_existentials.swift:14:5:14:13 | call to createP() | getOpaqueExpr: | open_existentials.swift:14:5:14:13 | OpaqueValueExpr |

View File

@@ -0,0 +1,16 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from
OpenExistentialExpr x, string hasType, Expr getSubExpr, Expr getExistential,
OpaqueValueExpr getOpaqueExpr
where
toBeTested(x) and
not x.isUnknown() and
(if x.hasType() then hasType = "yes" else hasType = "no") and
getSubExpr = x.getSubExpr() and
getExistential = x.getExistential() and
getOpaqueExpr = x.getOpaqueExpr()
select x, "hasType:", hasType, "getSubExpr:", getSubExpr, "getExistential:", getExistential,
"getOpaqueExpr:", getOpaqueExpr

View File

@@ -0,0 +1 @@
| open_existentials.swift:14:5:14:19 | OpenExistentialExpr | () |

View File

@@ -0,0 +1,7 @@
// generated by codegen/codegen.py
import codeql.swift.elements
import TestUtils
from OpenExistentialExpr x
where toBeTested(x) and not x.isUnknown()
select x, x.getType()

View File

@@ -0,0 +1,15 @@
protocol P {
func foo() -> ()
}
class C : P {
func foo() {}
}
func createP() -> P {
return C()
}
func test() {
createP().foo()
}

View File

@@ -0,0 +1,2 @@
deadEnd
| patterns.swift:16:10:16:14 | =~ ... |

View File

@@ -0,0 +1,2 @@
deadEnd
| file://:0:0:0:0 | ... = ... |

View File

@@ -1,8 +1,3 @@
nonUniqueSetRepresentation
breakInvariant2
breakInvariant3
breakInvariant4
breakInvariant5
multipleSuccessors
| cfg.swift:33:28:33:28 | ... is ... | no-match | cfg.swift:33:49:33:60 | call to isZero(x:) |
| cfg.swift:33:28:33:28 | ... is ... | no-match | cfg.swift:35:5:37:3 | case ... |
@@ -10,15 +5,16 @@ multipleSuccessors
| cfg.swift:144:10:144:10 | =~ ... | no-match | cfg.swift:146:5:147:14 | case ... |
| cfg.swift:515:6:515:28 | #available | false | cfg.swift:515:42:515:46 | iOS 12 |
| cfg.swift:515:6:515:28 | #available | false | cfg.swift:519:10:519:10 | x |
| file://:0:0:0:0 | $interpolation | successor | cfg.swift:40:11:40:11 | OpaqueValueExpr |
| file://:0:0:0:0 | $interpolation | successor | cfg.swift:40:12:40:12 | .appendLiteral(_:) |
| file://:0:0:0:0 | $interpolation | successor | cfg.swift:263:10:263:10 | OpaqueValueExpr |
| file://:0:0:0:0 | $interpolation | successor | cfg.swift:263:11:263:11 | .appendLiteral(_:) |
simpleAndNormalSuccessors
deadEnd
| cfg.swift:33:49:33:60 | call to isZero(x:) |
| cfg.swift:144:18:144:34 | ... .&&(_:_:) ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
nonUniqueSplitKind
nonUniqueListOrder
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| patterns.swift:16:10:16:14 | =~ ... |

View File

@@ -1,8 +0,0 @@
private import codeql.swift.printast.PrintAstNode
from PrintAstNode parent, int index, PrintAstNode child1, PrintAstNode child2
where
child1 != child2 and
parent.hasChild(child1, index, _) and
parent.hasChild(child2, index, _)
select parent, index, child1, child2

View File

@@ -1,8 +0,0 @@
private import codeql.swift.printast.PrintAstNode
from PrintAstNode parent, int index1, int index2, PrintAstNode child
where
index1 != index2 and
parent.hasChild(child, index1, _) and
parent.hasChild(child, index2, _)
select parent, child, index1, index2

View File

@@ -1,8 +0,0 @@
private import codeql.swift.printast.PrintAstNode
from PrintAstNode parent1, PrintAstNode parent2, PrintAstNode child
where
parent1 != parent2 and
parent1.hasChild(child, _, _) and
parent2.hasChild(child, _, _)
select parent1, parent2, child

View File

@@ -1,7 +0,0 @@
private import codeql.swift.printast.PrintAstNode
predicate isChildOf(PrintAstNode parent, PrintAstNode child) { parent.hasChild(child, _, _) }
from PrintAstNode parent, PrintAstNode child
where isChildOf(parent, child) and isChildOf*(child, parent)
select parent, child

View File

@@ -0,0 +1,12 @@
multipleSuccessors
| cfg.swift:33:28:33:28 | ... is ... | no-match | cfg.swift:33:49:33:60 | call to isZero(x:) |
| cfg.swift:33:28:33:28 | ... is ... | no-match | cfg.swift:35:5:37:3 | case ... |
| cfg.swift:144:10:144:10 | =~ ... | no-match | cfg.swift:144:18:144:34 | ... .&&(_:_:) ... |
| cfg.swift:144:10:144:10 | =~ ... | no-match | cfg.swift:146:5:147:14 | case ... |
| cfg.swift:515:6:515:28 | #available | false | cfg.swift:515:42:515:46 | iOS 12 |
| cfg.swift:515:6:515:28 | #available | false | cfg.swift:519:10:519:10 | x |
deadEnd
| cfg.swift:33:49:33:60 | call to isZero(x:) |
| cfg.swift:144:18:144:34 | ... .&&(_:_:) ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |

View File

@@ -349,6 +349,7 @@ cfg.swift:
#-----| match -> print(_:separator:terminator:)
# 40| print(_:separator:terminator:)
#-----| -> OpaqueValueExpr
# 40| call to print(_:separator:terminator:)
#-----| -> 0
@@ -366,7 +367,6 @@ cfg.swift:
#-----| -> [...]
# 40| OpaqueValueExpr
#-----| -> .appendLiteral(_:)
# 40| TapExpr
#-----| -> "..."
@@ -2777,6 +2777,7 @@ cfg.swift:
#-----| -> y
# 262| y
#-----| -> OpaqueValueExpr
# 263| return ...
#-----| return -> exit interpolatedString(x:y:) (normal)
@@ -2788,7 +2789,6 @@ cfg.swift:
#-----| -> return ...
# 263| OpaqueValueExpr
#-----| -> .appendLiteral(_:)
# 263| TapExpr
#-----| -> "..."

View File

@@ -0,0 +1,3 @@
multipleSuccessors
| test.swift:488:8:488:12 | let ...? | no-match | test.swift:488:27:488:27 | y |
| test.swift:488:8:488:12 | let ...? | no-match | test.swift:493:9:493:9 | tuple1 |

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -2,12 +2,10 @@ import swift
import FlowConfig
import TestUtilities.InlineExpectationsTest
class TaintTest extends InlineExpectationsTest {
TaintTest() { this = "DataFlowTest" }
module TaintTest implements TestSig {
string getARelevantTag() { result = "flow" }
override string getARelevantTag() { result = "flow" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node source, DataFlow::Node sink, Expr sinkExpr |
TestFlow::flow(source, sink) and
sinkExpr = sink.asExpr() and
@@ -18,3 +16,5 @@ class TaintTest extends InlineExpectationsTest {
)
}
}
import MakeTest<TaintTest>

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -8,12 +8,10 @@ string describe(FlowSource source) {
source instanceof LocalFlowSource and result = "local"
}
class FlowSourcesTest extends InlineExpectationsTest {
FlowSourcesTest() { this = "FlowSourcesTest" }
module FlowSourcesTest implements TestSig {
string getARelevantTag() { result = "source" }
override string getARelevantTag() { result = "source" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(FlowSource source |
location = source.getLocation() and
location.getFile().getBaseName() != "" and
@@ -23,3 +21,5 @@ class FlowSourcesTest extends InlineExpectationsTest {
)
}
}
import MakeTest<FlowSourcesTest>

View File

@@ -150,7 +150,7 @@
| stringinterpolation.swift:13:3:13:3 | self | stringinterpolation.swift:13:3:13:3 | &... |
| stringinterpolation.swift:13:23:13:23 | "..." | stringinterpolation.swift:13:3:13:3 | [post] &... |
| stringinterpolation.swift:13:23:13:23 | "..." | stringinterpolation.swift:13:23:13:23 | [post] "..." |
| stringinterpolation.swift:13:23:13:23 | SSA def($interpolation) | stringinterpolation.swift:13:24:13:24 | SSA phi($interpolation) |
| stringinterpolation.swift:13:23:13:23 | SSA def($interpolation) | stringinterpolation.swift:13:24:13:24 | $interpolation |
| stringinterpolation.swift:13:23:13:23 | TapExpr | stringinterpolation.swift:13:23:13:23 | "..." |
| stringinterpolation.swift:13:23:13:23 | first is: | stringinterpolation.swift:13:23:13:23 | [post] first is: |
| stringinterpolation.swift:13:23:13:23 | first is: | stringinterpolation.swift:13:24:13:24 | [post] &... |
@@ -158,7 +158,6 @@
| stringinterpolation.swift:13:24:13:24 | &... | stringinterpolation.swift:13:23:13:23 | [post] first is: |
| stringinterpolation.swift:13:24:13:24 | &... | stringinterpolation.swift:13:24:13:24 | [post] &... |
| stringinterpolation.swift:13:24:13:24 | &... | stringinterpolation.swift:13:35:13:35 | $interpolation |
| stringinterpolation.swift:13:24:13:24 | SSA phi($interpolation) | stringinterpolation.swift:13:24:13:24 | $interpolation |
| stringinterpolation.swift:13:24:13:24 | [post] &... | stringinterpolation.swift:13:35:13:35 | $interpolation |
| stringinterpolation.swift:13:35:13:35 | $interpolation | stringinterpolation.swift:13:35:13:35 | &... |
| stringinterpolation.swift:13:35:13:35 | &... | stringinterpolation.swift:13:35:13:35 | [post] &... |
@@ -179,7 +178,7 @@
| stringinterpolation.swift:19:2:19:2 | p1 | stringinterpolation.swift:20:2:20:2 | p1 |
| stringinterpolation.swift:20:2:20:2 | [post] p1 | stringinterpolation.swift:22:21:22:21 | p1 |
| stringinterpolation.swift:20:2:20:2 | p1 | stringinterpolation.swift:22:21:22:21 | p1 |
| stringinterpolation.swift:22:12:22:12 | SSA def($interpolation) | stringinterpolation.swift:22:13:22:13 | SSA phi($interpolation) |
| stringinterpolation.swift:22:12:22:12 | SSA def($interpolation) | stringinterpolation.swift:22:13:22:13 | $interpolation |
| stringinterpolation.swift:22:12:22:12 | TapExpr | stringinterpolation.swift:22:12:22:12 | "..." |
| stringinterpolation.swift:22:12:22:12 | pair: | stringinterpolation.swift:22:12:22:12 | [post] pair: |
| stringinterpolation.swift:22:12:22:12 | pair: | stringinterpolation.swift:22:13:22:13 | [post] &... |
@@ -187,7 +186,6 @@
| stringinterpolation.swift:22:13:22:13 | &... | stringinterpolation.swift:22:12:22:12 | [post] pair: |
| stringinterpolation.swift:22:13:22:13 | &... | stringinterpolation.swift:22:13:22:13 | [post] &... |
| stringinterpolation.swift:22:13:22:13 | &... | stringinterpolation.swift:22:20:22:20 | $interpolation |
| stringinterpolation.swift:22:13:22:13 | SSA phi($interpolation) | stringinterpolation.swift:22:13:22:13 | $interpolation |
| stringinterpolation.swift:22:13:22:13 | [post] &... | stringinterpolation.swift:22:20:22:20 | $interpolation |
| stringinterpolation.swift:22:20:22:20 | $interpolation | stringinterpolation.swift:22:20:22:20 | &... |
| stringinterpolation.swift:22:20:22:20 | &... | stringinterpolation.swift:22:20:22:20 | [post] &... |
@@ -203,7 +201,7 @@
| stringinterpolation.swift:22:30:22:30 | &... | stringinterpolation.swift:22:30:22:30 | [post] |
| stringinterpolation.swift:22:30:22:30 | &... | stringinterpolation.swift:22:30:22:30 | [post] &... |
| stringinterpolation.swift:22:30:22:30 | [post] &... | stringinterpolation.swift:22:12:22:12 | TapExpr |
| stringinterpolation.swift:23:12:23:12 | SSA def($interpolation) | stringinterpolation.swift:23:13:23:13 | SSA phi($interpolation) |
| stringinterpolation.swift:23:12:23:12 | SSA def($interpolation) | stringinterpolation.swift:23:13:23:13 | $interpolation |
| stringinterpolation.swift:23:12:23:12 | TapExpr | stringinterpolation.swift:23:12:23:12 | "..." |
| stringinterpolation.swift:23:12:23:12 | pair: | stringinterpolation.swift:23:12:23:12 | [post] pair: |
| stringinterpolation.swift:23:12:23:12 | pair: | stringinterpolation.swift:23:13:23:13 | [post] &... |
@@ -211,7 +209,6 @@
| stringinterpolation.swift:23:13:23:13 | &... | stringinterpolation.swift:23:12:23:12 | [post] pair: |
| stringinterpolation.swift:23:13:23:13 | &... | stringinterpolation.swift:23:13:23:13 | [post] &... |
| stringinterpolation.swift:23:13:23:13 | &... | stringinterpolation.swift:23:20:23:20 | $interpolation |
| stringinterpolation.swift:23:13:23:13 | SSA phi($interpolation) | stringinterpolation.swift:23:13:23:13 | $interpolation |
| stringinterpolation.swift:23:13:23:13 | [post] &... | stringinterpolation.swift:23:20:23:20 | $interpolation |
| stringinterpolation.swift:23:20:23:20 | $interpolation | stringinterpolation.swift:23:20:23:20 | &... |
| stringinterpolation.swift:23:20:23:20 | &... | stringinterpolation.swift:23:20:23:20 | [post] &... |
@@ -227,7 +224,7 @@
| stringinterpolation.swift:23:31:23:31 | &... | stringinterpolation.swift:23:31:23:31 | [post] |
| stringinterpolation.swift:23:31:23:31 | &... | stringinterpolation.swift:23:31:23:31 | [post] &... |
| stringinterpolation.swift:23:31:23:31 | [post] &... | stringinterpolation.swift:23:12:23:12 | TapExpr |
| stringinterpolation.swift:24:12:24:12 | SSA def($interpolation) | stringinterpolation.swift:24:13:24:13 | SSA phi($interpolation) |
| stringinterpolation.swift:24:12:24:12 | SSA def($interpolation) | stringinterpolation.swift:24:13:24:13 | $interpolation |
| stringinterpolation.swift:24:12:24:12 | TapExpr | stringinterpolation.swift:24:12:24:12 | "..." |
| stringinterpolation.swift:24:12:24:12 | pair: | stringinterpolation.swift:24:12:24:12 | [post] pair: |
| stringinterpolation.swift:24:12:24:12 | pair: | stringinterpolation.swift:24:13:24:13 | [post] &... |
@@ -235,7 +232,6 @@
| stringinterpolation.swift:24:13:24:13 | &... | stringinterpolation.swift:24:12:24:12 | [post] pair: |
| stringinterpolation.swift:24:13:24:13 | &... | stringinterpolation.swift:24:13:24:13 | [post] &... |
| stringinterpolation.swift:24:13:24:13 | &... | stringinterpolation.swift:24:20:24:20 | $interpolation |
| stringinterpolation.swift:24:13:24:13 | SSA phi($interpolation) | stringinterpolation.swift:24:13:24:13 | $interpolation |
| stringinterpolation.swift:24:13:24:13 | [post] &... | stringinterpolation.swift:24:20:24:20 | $interpolation |
| stringinterpolation.swift:24:20:24:20 | $interpolation | stringinterpolation.swift:24:20:24:20 | &... |
| stringinterpolation.swift:24:20:24:20 | &... | stringinterpolation.swift:24:20:24:20 | [post] &... |
@@ -258,7 +254,7 @@
| stringinterpolation.swift:27:2:27:2 | p2 | stringinterpolation.swift:28:2:28:2 | p2 |
| stringinterpolation.swift:28:2:28:2 | [post] p2 | stringinterpolation.swift:30:21:30:21 | p2 |
| stringinterpolation.swift:28:2:28:2 | p2 | stringinterpolation.swift:30:21:30:21 | p2 |
| stringinterpolation.swift:30:12:30:12 | SSA def($interpolation) | stringinterpolation.swift:30:13:30:13 | SSA phi($interpolation) |
| stringinterpolation.swift:30:12:30:12 | SSA def($interpolation) | stringinterpolation.swift:30:13:30:13 | $interpolation |
| stringinterpolation.swift:30:12:30:12 | TapExpr | stringinterpolation.swift:30:12:30:12 | "..." |
| stringinterpolation.swift:30:12:30:12 | pair: | stringinterpolation.swift:30:12:30:12 | [post] pair: |
| stringinterpolation.swift:30:12:30:12 | pair: | stringinterpolation.swift:30:13:30:13 | [post] &... |
@@ -266,7 +262,6 @@
| stringinterpolation.swift:30:13:30:13 | &... | stringinterpolation.swift:30:12:30:12 | [post] pair: |
| stringinterpolation.swift:30:13:30:13 | &... | stringinterpolation.swift:30:13:30:13 | [post] &... |
| stringinterpolation.swift:30:13:30:13 | &... | stringinterpolation.swift:30:20:30:20 | $interpolation |
| stringinterpolation.swift:30:13:30:13 | SSA phi($interpolation) | stringinterpolation.swift:30:13:30:13 | $interpolation |
| stringinterpolation.swift:30:13:30:13 | [post] &... | stringinterpolation.swift:30:20:30:20 | $interpolation |
| stringinterpolation.swift:30:20:30:20 | $interpolation | stringinterpolation.swift:30:20:30:20 | &... |
| stringinterpolation.swift:30:20:30:20 | &... | stringinterpolation.swift:30:20:30:20 | [post] &... |
@@ -282,7 +277,7 @@
| stringinterpolation.swift:30:30:30:30 | &... | stringinterpolation.swift:30:30:30:30 | [post] |
| stringinterpolation.swift:30:30:30:30 | &... | stringinterpolation.swift:30:30:30:30 | [post] &... |
| stringinterpolation.swift:30:30:30:30 | [post] &... | stringinterpolation.swift:30:12:30:12 | TapExpr |
| stringinterpolation.swift:31:12:31:12 | SSA def($interpolation) | stringinterpolation.swift:31:13:31:13 | SSA phi($interpolation) |
| stringinterpolation.swift:31:12:31:12 | SSA def($interpolation) | stringinterpolation.swift:31:13:31:13 | $interpolation |
| stringinterpolation.swift:31:12:31:12 | TapExpr | stringinterpolation.swift:31:12:31:12 | "..." |
| stringinterpolation.swift:31:12:31:12 | pair: | stringinterpolation.swift:31:12:31:12 | [post] pair: |
| stringinterpolation.swift:31:12:31:12 | pair: | stringinterpolation.swift:31:13:31:13 | [post] &... |
@@ -290,7 +285,6 @@
| stringinterpolation.swift:31:13:31:13 | &... | stringinterpolation.swift:31:12:31:12 | [post] pair: |
| stringinterpolation.swift:31:13:31:13 | &... | stringinterpolation.swift:31:13:31:13 | [post] &... |
| stringinterpolation.swift:31:13:31:13 | &... | stringinterpolation.swift:31:20:31:20 | $interpolation |
| stringinterpolation.swift:31:13:31:13 | SSA phi($interpolation) | stringinterpolation.swift:31:13:31:13 | $interpolation |
| stringinterpolation.swift:31:13:31:13 | [post] &... | stringinterpolation.swift:31:20:31:20 | $interpolation |
| stringinterpolation.swift:31:20:31:20 | $interpolation | stringinterpolation.swift:31:20:31:20 | &... |
| stringinterpolation.swift:31:20:31:20 | &... | stringinterpolation.swift:31:20:31:20 | [post] &... |
@@ -306,7 +300,7 @@
| stringinterpolation.swift:31:31:31:31 | &... | stringinterpolation.swift:31:31:31:31 | [post] |
| stringinterpolation.swift:31:31:31:31 | &... | stringinterpolation.swift:31:31:31:31 | [post] &... |
| stringinterpolation.swift:31:31:31:31 | [post] &... | stringinterpolation.swift:31:12:31:12 | TapExpr |
| stringinterpolation.swift:32:12:32:12 | SSA def($interpolation) | stringinterpolation.swift:32:13:32:13 | SSA phi($interpolation) |
| stringinterpolation.swift:32:12:32:12 | SSA def($interpolation) | stringinterpolation.swift:32:13:32:13 | $interpolation |
| stringinterpolation.swift:32:12:32:12 | TapExpr | stringinterpolation.swift:32:12:32:12 | "..." |
| stringinterpolation.swift:32:12:32:12 | pair: | stringinterpolation.swift:32:12:32:12 | [post] pair: |
| stringinterpolation.swift:32:12:32:12 | pair: | stringinterpolation.swift:32:13:32:13 | [post] &... |
@@ -314,7 +308,6 @@
| stringinterpolation.swift:32:13:32:13 | &... | stringinterpolation.swift:32:12:32:12 | [post] pair: |
| stringinterpolation.swift:32:13:32:13 | &... | stringinterpolation.swift:32:13:32:13 | [post] &... |
| stringinterpolation.swift:32:13:32:13 | &... | stringinterpolation.swift:32:20:32:20 | $interpolation |
| stringinterpolation.swift:32:13:32:13 | SSA phi($interpolation) | stringinterpolation.swift:32:13:32:13 | $interpolation |
| stringinterpolation.swift:32:13:32:13 | [post] &... | stringinterpolation.swift:32:20:32:20 | $interpolation |
| stringinterpolation.swift:32:20:32:20 | $interpolation | stringinterpolation.swift:32:20:32:20 | &... |
| stringinterpolation.swift:32:20:32:20 | &... | stringinterpolation.swift:32:20:32:20 | [post] &... |

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -2,12 +2,10 @@ import swift
import Taint
import TestUtilities.InlineExpectationsTest
class TaintTest extends InlineExpectationsTest {
TaintTest() { this = "TaintTest" }
module TaintTest implements TestSig {
string getARelevantTag() { result = "tainted" }
override string getARelevantTag() { result = "tainted" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node source, DataFlow::Node sink, Expr sinkExpr |
TestFlow::flow(source, sink) and
sinkExpr = sink.asExpr() and
@@ -18,3 +16,5 @@ class TaintTest extends InlineExpectationsTest {
)
}
}
import MakeTest<TaintTest>

View File

@@ -0,0 +1,5 @@
deadEnd
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -2,12 +2,10 @@ import swift
import Taint
import TestUtilities.InlineExpectationsTest
class TaintTest extends InlineExpectationsTest {
TaintTest() { this = "TaintTest" }
module TaintTest implements TestSig {
string getARelevantTag() { result = "tainted" }
override string getARelevantTag() { result = "tainted" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node source, DataFlow::Node sink, Expr sinkExpr |
TestFlow::flow(source, sink) and
sinkExpr = sink.asExpr() and
@@ -18,3 +16,5 @@ class TaintTest extends InlineExpectationsTest {
)
}
}
import MakeTest<TaintTest>

View File

@@ -7,7 +7,19 @@ protocol SortComparator {
associatedtype Compared
}
struct Data : RangeReplaceableCollection
protocol DataProtocol {
}
extension DataProtocol {
func copyBytes(to: UnsafeMutableRawBufferPointer) {}
func copyBytes(to: UnsafeMutablePointer<UInt8>, count: Int) {}
func copyBytes(to: UnsafeMutablePointer<UInt8>, from: Range<Data.Index>) {}
}
extension UnsafeRawBufferPointer : DataProtocol { }
extension Array : DataProtocol where Element == UInt8 { }
protocol MutableDataProtocol : DataProtocol, RangeReplaceableCollection { }
struct Data : MutableDataProtocol
{
struct Base64EncodingOptions : OptionSet { let rawValue: Int }
struct Base64DecodingOptions : OptionSet { let rawValue: Int }
@@ -82,182 +94,193 @@ func taintThroughData() {
let dataTainted2 = Data(dataTainted)
sink(arg: dataClean)
sink(arg: dataTainted) // $ tainted=81
sink(arg: dataTainted2) // $ tainted=81
sink(arg: dataTainted) // $ tainted=93
sink(arg: dataTainted2) // $ tainted=93
// ";Data;true;init(base64Encoded:options:);;;Argument[0];ReturnValue;taint",
let dataTainted3 = Data(base64Encoded: source() as! Data, options: [])
sink(arg: dataTainted3) // $ tainted=89
sink(arg: dataTainted3) // $ tainted=101
// ";Data;true;init(buffer:);;;Argument[0];ReturnValue;taint",
let dataTainted4 = Data(buffer: source() as! UnsafeBufferPointer<UInt8>)
sink(arg: dataTainted4) // $ tainted=93
sink(arg: dataTainted4) // $ tainted=105
let dataTainted5 = Data(buffer: source() as! UnsafeMutablePointer<UInt8>)
sink(arg: dataTainted5) // $ tainted=95
sink(arg: dataTainted5) // $ tainted=107
// ";Data;true;init(bytes:count:);;;Argument[0];ReturnValue;taint",
let dataTainted6 = Data(bytes: source() as! UnsafeRawPointer, count: 0)
sink(arg: dataTainted6) // $ tainted=99
sink(arg: dataTainted6) // $ tainted=111
// ";Data;true;init(bytesNoCopy:count:deallocator:);;;Argument[0];ReturnValue;taint",
let dataTainted7 = Data(bytesNoCopy: source() as! UnsafeRawPointer, count: 0, deallocator: Data.Deallocator.none)
sink(arg: dataTainted7) // $ tainted=103
sink(arg: dataTainted7) // $ tainted=115
// ";Data;true;init(contentsOf:options:);;;Argument[0];ReturnValue;taint",
let urlTainted8 = source() as! URL
let dataTainted8 = Data(contentsOf: urlTainted8, options: [])
sink(arg: dataTainted8) // $ tainted=107
sink(arg: dataTainted8) // $ tainted=119
// ";Data;true;init(referencing:);;;Argument[0];ReturnValue;taint",
let dataTainted9 = Data(referencing: source() as! NSData)
sink(arg: dataTainted9) // $ tainted=112
sink(arg: dataTainted9) // $ tainted=124
// ";Data;true;append(_:);;;Argument[0];Argument[-1];taint",
let dataTainted10 = Data("")
dataTainted10.append(source() as! Data)
sink(arg: dataTainted10) // $ tainted=117
sink(arg: dataTainted10) // $ tainted=129
let dataTainted11 = Data("")
dataTainted11.append(source() as! UInt8)
sink(arg: dataTainted11) // $ tainted=121
sink(arg: dataTainted11) // $ tainted=133
let dataTainted12 = Data("")
dataTainted12.append(source() as! UnsafeBufferPointer<UInt8>)
sink(arg: dataTainted12) // $ tainted=125
sink(arg: dataTainted12) // $ tainted=137
// ";Data;true;append(_:count:);;;Argument[0];Argument[-1];taint",
let dataTainted13 = Data("")
dataTainted13.append(source() as! UnsafePointer<UInt8>, count: 0)
sink(arg: dataTainted13) // $ tainted=130
sink(arg: dataTainted13) // $ tainted=142
// ";Data;true;append(contentsOf:);;;Argument[0];Argument[-1];taint",
let dataTainted14 = Data("")
dataTainted14.append(contentsOf: source() as! [UInt8])
sink(arg: dataTainted14) // $ tainted=135
sink(arg: dataTainted14) // $ tainted=147
// ";Data;true;base64EncodedData(options:);;;Argument[-1];ReturnValue;taint",
let dataTainted15 = source() as! Data
sink(arg: dataTainted15.base64EncodedData(options: [])) // $ tainted=139
sink(arg: dataTainted15.base64EncodedData(options: [])) // $ tainted=151
// ";Data;true;base64EncodedString(options:);;;Argument[-1];ReturnValue;taint",
let dataTainted16 = source() as! Data
sink(arg: dataTainted16.base64EncodedString(options: [])) // $ tainted=143
sink(arg: dataTainted16.base64EncodedString(options: [])) // $ tainted=155
// ";Data;true;compactMap(_:);;;Argument[-1];ReturnValue;taint",
let dataTainted17 = source() as! Data
let compactMapped: [Int] = dataTainted17.compactMap { str in Int(str) }
sink(arg: compactMapped) // $ tainted=147
sink(arg: compactMapped) // $ tainted=159
// ";Data;true;copyBytes(to:);;;Argument[-1];Argument[0];taint",
let dataTainted18 = source() as! Data
let pointerTainted18 = UnsafeMutableRawBufferPointer.allocate(byteCount: 0, alignment: 0)
dataTainted18.copyBytes(to: pointerTainted18)
sink(arg: pointerTainted18) // $ tainted=152
sink(arg: pointerTainted18) // $ tainted=164
// ";Data;true;copyBytes(to:count:);;;Argument[-1];Argument[0];taint",
let dataTainted19 = source() as! Data
let pointerTainted19 = UnsafeMutablePointer<UInt8>.allocate(capacity: 0)
dataTainted19.copyBytes(to: pointerTainted19, count: 0)
sink(arg: pointerTainted19) // $ tainted=158
sink(arg: pointerTainted19) // $ tainted=170
// ";Data;true;copyBytes(to:from:);;;Argument[-1];Argument[0];taint",
let dataTainted20 = source() as! Data
let pointerTainted20 = UnsafeMutablePointer<UInt8>.allocate(capacity: 0)
dataTainted20.copyBytes(to: pointerTainted20, from: 0..<1)
sink(arg: pointerTainted20) // $ tainted=164
sink(arg: pointerTainted20) // $ tainted=176
// ";Data;true;flatMap(_:);;;Argument[-1];ReturnValue;taint",
let dataTainted21 = source() as! Data
let flatMapped = dataTainted21.flatMap { Array(repeating: $0, count: 0) }
sink(arg: flatMapped) // $ tainted=170
sink(arg: flatMapped) // $ tainted=182
let dataTainted22 = source() as! Data
let flatMapped2 = dataTainted22.flatMap { str in Int(str) }
sink(arg: flatMapped2) // $ tainted=174
sink(arg: flatMapped2) // $ tainted=186
// ";Data;true;insert(_:at:);;;Argument[0];Argument[-1];taint",
let dataTainted23 = Data("")
dataTainted23.insert(source() as! UInt8, at: 0)
sink(arg: dataTainted23) // $ tainted=180
sink(arg: dataTainted23) // $ tainted=192
// ";Data;true;insert(contentsOf:at:);;;Argument[0];Argument[-1];taint",
let dataTainted24 = Data("")
dataTainted24.insert(contentsOf: source() as! [UInt8], at: 0)
sink(arg: dataTainted24) // $ tainted=185
sink(arg: dataTainted24) // $ tainted=197
// ";Data;true;map(_:);;;Argument[-1];ReturnValue;taint",
let dataTainted25 = source() as! Data
let mapped = dataTainted25.map { $0 }
sink(arg: mapped) // $ tainted=189
sink(arg: mapped) // $ tainted=201
// ";Data;true;reduce(into:_:);;;Argument[-1];ReturnValue;taint",
let dataTainted26 = source() as! Data
let reduced = dataTainted26.reduce(into: [:]) { c, i in c[i, default: 0] += 1 }
sink(arg: reduced) // $ tainted=194
sink(arg: reduced) // $ tainted=206
// ";Data;true;replace(_:with:maxReplacements:);;;Argument[1];Argument[-1];taint",
let dataTainted27 = Data("")
dataTainted27.replace([0], with: source() as! [UInt8], maxReplacements: .max)
sink(arg: dataTainted27) // $ tainted=200
sink(arg: dataTainted27) // $ tainted=212
// ";Data;true;replaceSubrange(_:with:);;;Argument[1];Argument[-1];taint",
let dataTainted28 = Data("")
dataTainted28.replaceSubrange(1..<3, with: source() as! Data)
sink(arg: dataTainted28) // $ tainted=205
sink(arg: dataTainted28) // $ tainted=217
let dataTainted29 = Data("")
dataTainted29.replaceSubrange(1..<3, with: source() as! [UInt8])
sink(arg: dataTainted29) // $ tainted=209
sink(arg: dataTainted29) // $ tainted=221
let dataTainted30 = Data("")
dataTainted30.replaceSubrange(1..<3, with: source() as! UnsafeBufferPointer<UInt8>)
sink(arg: dataTainted30) // $ tainted=213
sink(arg: dataTainted30) // $ tainted=225
// ";Data;true;replaceSubrange(_:with:count:);;;Argument[1];Argument[-1];taint",
let dataTainted31 = Data("")
dataTainted31.replaceSubrange(1..<3, with: source() as! UnsafeRawPointer, count: 0)
sink(arg: dataTainted31) // $ tainted=218
sink(arg: dataTainted31) // $ tainted=230
// ";Data;true;replacing(_:with:maxReplacements:);;;Argument[1];Argument[-1];taint",
let dataTainted32 = Data("")
let _ = dataTainted32.replacing([0], with: source() as! [UInt8], maxReplacements: 0)
sink(arg: dataTainted32) // $ tainted=223
sink(arg: dataTainted32) // $ tainted=235
// ";Data;true;replacing(_:with:subrange:maxReplacements:);;;Argument[1];Argument[-1];taint",
let dataTainted33 = Data("")
let _ = dataTainted33.replacing([0], with: source() as! [UInt8], subrange: 1..<3, maxReplacements: 0)
sink(arg: dataTainted33) // $ tainted=228
sink(arg: dataTainted33) // $ tainted=240
// ";Data;true;reversed();;;Argument[-1];ReturnValue;taint",
let dataTainted34 = source() as! Data
sink(arg: dataTainted34.reversed()) // $ tainted=232
sink(arg: dataTainted34.reversed()) // $ tainted=244
// ";Data;true;sorted();;;Argument[-1];ReturnValue;taint",
let dataTainted35 = source() as! Data
sink(arg: dataTainted35.sorted()) // $ tainted=236
sink(arg: dataTainted35.sorted()) // $ tainted=248
// ";Data;true;sorted(by:);;;Argument[-1];ReturnValue;taint",
let dataTainted36 = source() as! Data
sink(arg: dataTainted36.sorted{ _,_ in return false }) // $ tainted=240
sink(arg: dataTainted36.sorted{ _,_ in return false }) // $ tainted=252
// ";Data;true;sorted(using:);;;Argument[-1];ReturnValue;taint",
let dataTainted37 = source() as! Data
sink(arg: dataTainted37.sorted(using: cmp()!)) // $ tainted=244
sink(arg: dataTainted37.sorted(using: cmp()!)) // $ tainted=256
// ";Data;true;shuffled();;;Argument[-1];ReturnValue;taint",
let dataTainted38 = source() as! Data
sink(arg: dataTainted38.shuffled()) // $ tainted=248
sink(arg: dataTainted38.shuffled()) // $ tainted=260
// ";Data;true;shuffled(using:);;;Argument[-1];ReturnValue;taint",
let dataTainted39 = source() as! Data
var rng = rng()!
sink(arg: dataTainted39.shuffled(using: &rng)) // $ tainted=252
var myRng = rng()!
sink(arg: dataTainted39.shuffled(using: &myRng)) // $ tainted=264
// ";Data;true;trimmingPrefix(_:);;;Argument[-1];ReturnValue;taint",
let dataTainted40 = source() as! Data
sink(arg: dataTainted40.trimmingPrefix([0])) // $ tainted=257
sink(arg: dataTainted40.trimmingPrefix([0])) // $ tainted=269
// ";Data;true;trimmingPrefix(while:);;;Argument[-1];ReturnValue;taint"
let dataTainted41 = source() as! Data
sink(arg: dataTainted41.trimmingPrefix { _ in false }) // $ tainted=261
sink(arg: dataTainted41.trimmingPrefix { _ in false }) // $ tainted=273
// ";DataProtocol;true;copyBytes(to:);;;Argument[-1];Argument[0];taint",
let dataTainted43 = source() as! UnsafeRawBufferPointer
let pointerTainted43 = UnsafeMutableRawBufferPointer.allocate(byteCount: 0, alignment: 0)
dataTainted43.copyBytes(to: pointerTainted43)
sink(arg: pointerTainted43) // $ tainted=277
let dataTainted44 = source() as! Array<UInt8>
let pointerTainted44 = UnsafeMutableRawBufferPointer.allocate(byteCount: 0, alignment: 0)
dataTainted44.copyBytes(to: pointerTainted44)
sink(arg: pointerTainted44) // $ tainted=282
}

View File

@@ -0,0 +1,3 @@
deadEnd
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,17 @@
multipleSuccessors
| methodlookup.swift:37:11:37:30 | call to instanceMethod() | successor | methodlookup.swift:37:5:37:30 | await ... |
| methodlookup.swift:37:11:37:30 | call to instanceMethod() | successor | methodlookup.swift:40:5:40:9 | .staticMethod() |
| methodlookup.swift:47:11:47:30 | call to instanceMethod() | successor | methodlookup.swift:47:5:47:30 | await ... |
| methodlookup.swift:47:11:47:30 | call to instanceMethod() | successor | methodlookup.swift:48:11:48:11 | Baz.Type |
| methodlookup.swift:48:11:48:35 | call to { ... } | successor | methodlookup.swift:48:5:48:35 | await ... |
| methodlookup.swift:48:11:48:35 | call to { ... } | successor | methodlookup.swift:50:11:50:15 | .classMethod() |
| methodlookup.swift:50:11:50:27 | call to classMethod() | successor | methodlookup.swift:50:5:50:27 | await ... |
| methodlookup.swift:50:11:50:27 | call to classMethod() | successor | methodlookup.swift:51:11:51:15 | .staticMethod() |
| methodlookup.swift:51:11:51:28 | call to staticMethod() | successor | methodlookup.swift:43:6:52:1 | exit { ... } (normal) |
| methodlookup.swift:51:11:51:28 | call to staticMethod() | successor | methodlookup.swift:51:5:51:28 | await ... |
deadEnd
| methodlookup.swift:37:5:37:30 | await ... |
| methodlookup.swift:47:5:47:30 | await ... |
| methodlookup.swift:48:5:48:35 | await ... |
| methodlookup.swift:50:5:50:27 | await ... |
| methodlookup.swift:51:5:51:28 | await ... |

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -4,12 +4,10 @@ import codeql.swift.dataflow.FlowSources
import codeql.swift.security.PathInjectionQuery
import TestUtilities.InlineExpectationsTest
class PathInjectionTest extends InlineExpectationsTest {
PathInjectionTest() { this = "PathInjectionTest" }
module PathInjectionTest implements TestSig {
string getARelevantTag() { result = "hasPathInjection" }
override string getARelevantTag() { result = "hasPathInjection" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node source, DataFlow::Node sink |
PathInjectionFlow::flow(source, sink) and
location = sink.getLocation() and
@@ -20,3 +18,5 @@ class PathInjectionTest extends InlineExpectationsTest {
)
}
}
import MakeTest<PathInjectionTest>

View File

@@ -0,0 +1,2 @@
deadEnd
| file://:0:0:0:0 | ... = ... |

View File

@@ -6,8 +6,8 @@ struct URL
init?(string: String) {}
init?(string: String, relativeTo: URL?) {}
}
struct Data {
protocol DataProtocol { }
struct Data : DataProtocol {
init<S>(_ elements: S) { count = 0 }
var count: Int

View File

@@ -0,0 +1,11 @@
deadEnd
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |

View File

@@ -18,6 +18,18 @@ edges
| StringLengthConflation.swift:137:34:137:36 | .count | StringLengthConflation.swift:137:34:137:44 | ... .-(_:_:) ... |
| StringLengthConflation.swift:138:36:138:38 | .count | StringLengthConflation.swift:138:36:138:46 | ... .-(_:_:) ... |
| StringLengthConflation.swift:144:28:144:30 | .count | StringLengthConflation.swift:144:28:144:38 | ... .-(_:_:) ... |
| StringLengthConflation.swift:168:29:168:36 | .count | StringLengthConflation.swift:168:29:168:44 | ... .-(_:_:) ... |
| StringLengthConflation.swift:169:29:169:37 | .count | StringLengthConflation.swift:169:29:169:45 | ... .-(_:_:) ... |
| StringLengthConflation.swift:170:29:170:46 | .count | StringLengthConflation.swift:170:29:170:54 | ... .-(_:_:) ... |
| StringLengthConflation.swift:171:29:171:32 | .length | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... |
| StringLengthConflation.swift:172:29:172:33 | .length | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... |
| StringLengthConflation.swift:173:35:173:37 | .count | StringLengthConflation.swift:173:35:173:45 | ... .-(_:_:) ... |
| StringLengthConflation.swift:174:35:174:42 | .count | StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... |
| StringLengthConflation.swift:175:35:175:43 | .count | StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... |
| StringLengthConflation.swift:177:35:177:38 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... |
| StringLengthConflation.swift:178:35:178:39 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... |
| StringLengthConflation.swift:179:37:179:39 | .count | StringLengthConflation.swift:179:37:179:47 | ... .-(_:_:) ... |
| StringLengthConflation.swift:181:37:181:39 | .count | StringLengthConflation.swift:181:37:181:47 | ... .-(_:_:) ... |
| file://:0:0:0:0 | .length | StringLengthConflation.swift:53:43:53:46 | .length |
| file://:0:0:0:0 | .length | StringLengthConflation.swift:60:47:60:50 | .length |
| file://:0:0:0:0 | .length | StringLengthConflation.swift:66:33:66:36 | .length |
@@ -27,6 +39,10 @@ edges
| file://:0:0:0:0 | .length | StringLengthConflation.swift:108:25:108:28 | .length |
| file://:0:0:0:0 | .length | StringLengthConflation.swift:114:23:114:26 | .length |
| file://:0:0:0:0 | .length | StringLengthConflation.swift:120:22:120:25 | .length |
| file://:0:0:0:0 | .length | StringLengthConflation.swift:171:29:171:32 | .length |
| file://:0:0:0:0 | .length | StringLengthConflation.swift:172:29:172:33 | .length |
| file://:0:0:0:0 | .length | StringLengthConflation.swift:177:35:177:38 | .length |
| file://:0:0:0:0 | .length | StringLengthConflation.swift:178:35:178:39 | .length |
nodes
| StringLengthConflation2.swift:35:36:35:38 | .count | semmle.label | .count |
| StringLengthConflation2.swift:35:36:35:46 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
@@ -76,6 +92,30 @@ nodes
| StringLengthConflation.swift:151:45:151:53 | .count | semmle.label | .count |
| StringLengthConflation.swift:156:45:156:52 | .count | semmle.label | .count |
| StringLengthConflation.swift:161:45:161:53 | .count | semmle.label | .count |
| StringLengthConflation.swift:168:29:168:36 | .count | semmle.label | .count |
| StringLengthConflation.swift:168:29:168:44 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
| StringLengthConflation.swift:169:29:169:37 | .count | semmle.label | .count |
| StringLengthConflation.swift:169:29:169:45 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
| StringLengthConflation.swift:170:29:170:46 | .count | semmle.label | .count |
| StringLengthConflation.swift:170:29:170:54 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
| StringLengthConflation.swift:171:29:171:32 | .length | semmle.label | .length |
| StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
| StringLengthConflation.swift:172:29:172:33 | .length | semmle.label | .length |
| StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
| StringLengthConflation.swift:173:35:173:37 | .count | semmle.label | .count |
| StringLengthConflation.swift:173:35:173:45 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
| StringLengthConflation.swift:174:35:174:42 | .count | semmle.label | .count |
| StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
| StringLengthConflation.swift:175:35:175:43 | .count | semmle.label | .count |
| StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
| StringLengthConflation.swift:177:35:177:38 | .length | semmle.label | .length |
| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
| StringLengthConflation.swift:178:35:178:39 | .length | semmle.label | .length |
| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
| StringLengthConflation.swift:179:37:179:39 | .count | semmle.label | .count |
| StringLengthConflation.swift:179:37:179:47 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
| StringLengthConflation.swift:181:37:181:39 | .count | semmle.label | .count |
| StringLengthConflation.swift:181:37:181:47 | ... .-(_:_:) ... | semmle.label | ... .-(_:_:) ... |
| file://:0:0:0:0 | .length | semmle.label | .length |
subpaths
#select
@@ -84,17 +124,17 @@ subpaths
| StringLengthConflation.swift:36:93:36:93 | len | StringLengthConflation.swift:72:33:72:35 | .count | StringLengthConflation.swift:36:93:36:93 | len | This String length is used in an NSString, but it may not be equivalent. |
| StringLengthConflation.swift:53:43:53:46 | .length | StringLengthConflation.swift:53:43:53:46 | .length | StringLengthConflation.swift:53:43:53:46 | .length | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:53:43:53:46 | .length | file://:0:0:0:0 | .length | StringLengthConflation.swift:53:43:53:46 | .length | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:54:43:54:50 | .count | StringLengthConflation.swift:54:43:54:50 | .count | StringLengthConflation.swift:54:43:54:50 | .count | This String.utf8 length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:55:43:55:51 | .count | StringLengthConflation.swift:55:43:55:51 | .count | StringLengthConflation.swift:55:43:55:51 | .count | This String.utf16 length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:56:43:56:60 | .count | StringLengthConflation.swift:56:43:56:60 | .count | StringLengthConflation.swift:56:43:56:60 | .count | This String.unicodeScalars length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:54:43:54:50 | .count | StringLengthConflation.swift:54:43:54:50 | .count | StringLengthConflation.swift:54:43:54:50 | .count | This String.UTF8View length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:55:43:55:51 | .count | StringLengthConflation.swift:55:43:55:51 | .count | StringLengthConflation.swift:55:43:55:51 | .count | This String.UTF16View length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:56:43:56:60 | .count | StringLengthConflation.swift:56:43:56:60 | .count | StringLengthConflation.swift:56:43:56:60 | .count | This String.UnicodeScalarView length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:60:47:60:59 | ... ./(_:_:) ... | StringLengthConflation.swift:60:47:60:50 | .length | StringLengthConflation.swift:60:47:60:59 | ... ./(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:60:47:60:59 | ... ./(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:60:47:60:59 | ... ./(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:66:33:66:45 | ... ./(_:_:) ... | StringLengthConflation.swift:66:33:66:36 | .length | StringLengthConflation.swift:66:33:66:45 | ... ./(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:66:33:66:45 | ... ./(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:66:33:66:45 | ... ./(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:72:33:72:35 | .count | StringLengthConflation.swift:72:33:72:35 | .count | StringLengthConflation.swift:72:33:72:35 | .count | This String length is used in an NSString, but it may not be equivalent. |
| StringLengthConflation.swift:78:47:78:49 | .count | StringLengthConflation.swift:78:47:78:49 | .count | StringLengthConflation.swift:78:47:78:49 | .count | This String length is used in an NSString, but it may not be equivalent. |
| StringLengthConflation.swift:79:47:79:54 | .count | StringLengthConflation.swift:79:47:79:54 | .count | StringLengthConflation.swift:79:47:79:54 | .count | This String.utf8 length is used in an NSString, but it may not be equivalent. |
| StringLengthConflation.swift:81:47:81:64 | .count | StringLengthConflation.swift:81:47:81:64 | .count | StringLengthConflation.swift:81:47:81:64 | .count | This String.unicodeScalars length is used in an NSString, but it may not be equivalent. |
| StringLengthConflation.swift:79:47:79:54 | .count | StringLengthConflation.swift:79:47:79:54 | .count | StringLengthConflation.swift:79:47:79:54 | .count | This String.UTF8View length is used in an NSString, but it may not be equivalent. |
| StringLengthConflation.swift:81:47:81:64 | .count | StringLengthConflation.swift:81:47:81:64 | .count | StringLengthConflation.swift:81:47:81:64 | .count | This String.UnicodeScalarView length is used in an NSString, but it may not be equivalent. |
| StringLengthConflation.swift:96:28:96:40 | ... .-(_:_:) ... | StringLengthConflation.swift:96:28:96:31 | .length | StringLengthConflation.swift:96:28:96:40 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:96:28:96:40 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:96:28:96:40 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:100:27:100:39 | ... .-(_:_:) ... | StringLengthConflation.swift:100:27:100:30 | .length | StringLengthConflation.swift:100:27:100:39 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
@@ -114,6 +154,22 @@ subpaths
| StringLengthConflation.swift:137:34:137:44 | ... .-(_:_:) ... | StringLengthConflation.swift:137:34:137:36 | .count | StringLengthConflation.swift:137:34:137:44 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. |
| StringLengthConflation.swift:138:36:138:46 | ... .-(_:_:) ... | StringLengthConflation.swift:138:36:138:38 | .count | StringLengthConflation.swift:138:36:138:46 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. |
| StringLengthConflation.swift:144:28:144:38 | ... .-(_:_:) ... | StringLengthConflation.swift:144:28:144:30 | .count | StringLengthConflation.swift:144:28:144:38 | ... .-(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. |
| StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | This String.unicodeScalars length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | This String.utf8 length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | This String.utf16 length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | StringLengthConflation.swift:151:45:151:53 | .count | This String.UnicodeScalarView length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | StringLengthConflation.swift:156:45:156:52 | .count | This String.UTF8View length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | StringLengthConflation.swift:161:45:161:53 | .count | This String.UTF16View length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:168:29:168:44 | ... .-(_:_:) ... | StringLengthConflation.swift:168:29:168:36 | .count | StringLengthConflation.swift:168:29:168:44 | ... .-(_:_:) ... | This String.UTF8View length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:169:29:169:45 | ... .-(_:_:) ... | StringLengthConflation.swift:169:29:169:37 | .count | StringLengthConflation.swift:169:29:169:45 | ... .-(_:_:) ... | This String.UTF16View length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:170:29:170:54 | ... .-(_:_:) ... | StringLengthConflation.swift:170:29:170:46 | .count | StringLengthConflation.swift:170:29:170:54 | ... .-(_:_:) ... | This String.UnicodeScalarView length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | StringLengthConflation.swift:171:29:171:32 | .length | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:171:29:171:41 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | StringLengthConflation.swift:172:29:172:33 | .length | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:172:29:172:42 | ... .-(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. |
| StringLengthConflation.swift:173:35:173:45 | ... .-(_:_:) ... | StringLengthConflation.swift:173:35:173:37 | .count | StringLengthConflation.swift:173:35:173:45 | ... .-(_:_:) ... | This String length is used in a String.UnicodeScalarView, but it may not be equivalent. |
| StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | StringLengthConflation.swift:174:35:174:42 | .count | StringLengthConflation.swift:174:35:174:50 | ... .-(_:_:) ... | This String.UTF8View length is used in a String.UnicodeScalarView, but it may not be equivalent. |
| StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | StringLengthConflation.swift:175:35:175:43 | .count | StringLengthConflation.swift:175:35:175:51 | ... .-(_:_:) ... | This String.UTF16View length is used in a String.UnicodeScalarView, but it may not be equivalent. |
| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | StringLengthConflation.swift:177:35:177:38 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | This NSString length is used in a String.UnicodeScalarView, but it may not be equivalent. |
| StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:177:35:177:47 | ... .-(_:_:) ... | This NSString length is used in a String.UnicodeScalarView, but it may not be equivalent. |
| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | StringLengthConflation.swift:178:35:178:39 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | This NSString length is used in a String.UnicodeScalarView, but it may not be equivalent. |
| StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | file://:0:0:0:0 | .length | StringLengthConflation.swift:178:35:178:48 | ... .-(_:_:) ... | This NSString length is used in a String.UnicodeScalarView, but it may not be equivalent. |
| StringLengthConflation.swift:179:37:179:47 | ... .-(_:_:) ... | StringLengthConflation.swift:179:37:179:39 | .count | StringLengthConflation.swift:179:37:179:47 | ... .-(_:_:) ... | This String length is used in a String.UTF8View, but it may not be equivalent. |
| StringLengthConflation.swift:181:37:181:47 | ... .-(_:_:) ... | StringLengthConflation.swift:181:37:181:39 | .count | StringLengthConflation.swift:181:37:181:47 | ... .-(_:_:) ... | This String length is used in a String.UTF16View, but it may not be equivalent. |

View File

@@ -161,6 +161,25 @@ func test(s: String) {
let _ = s.index(s.startIndex, offsetBy: s_utf16.count) // BAD
let _ = s_utf16.index(s_utf16.startIndex, offsetBy: scalars.count) // GOOD
let _ = s_utf16.index(s_utf16.startIndex, offsetBy: s.count) // BAD [NOT DETECTED]
// --- methods provided by Sequence, Collection etc ---
let _ = String(s.prefix(s.count - 10)) // GOOD
let _ = String(s.prefix(s.utf8.count - 10)) // BAD
let _ = String(s.prefix(s.utf16.count - 10)) // BAD
let _ = String(s.prefix(s.unicodeScalars.count - 10)) // BAD
let _ = String(s.prefix(ns.length - 10)) // BAD
let _ = String(s.prefix(nms.length - 10)) // BAD
let _ = String(scalars.prefix(s.count - 10)) // BAD
let _ = String(scalars.prefix(s.utf8.count - 10)) // BAD
let _ = String(scalars.prefix(s.utf16.count - 10)) // BAD
let _ = String(scalars.prefix(s.unicodeScalars.count - 10)) // GOOD
let _ = String(scalars.prefix(ns.length - 10)) // BAD
let _ = String(scalars.prefix(nms.length - 10)) // BAD
let _ = String(s.utf8.dropFirst(s.count - 10)) // BAD
let _ = String(s.utf8.dropFirst(s.utf8.count - 10)) // GOOD
let _ = String(s.utf16.dropLast(s.count - 10)) // BAD
let _ = String(s.utf16.dropLast(s.utf16.count - 10)) // GOOD
}
// `begin :thumbsup: end`, with thumbs up emoji and skin tone modifier

View File

@@ -0,0 +1,5 @@
deadEnd
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,2 @@
deadEnd
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,6 @@
deadEnd
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -3,12 +3,10 @@ import codeql.swift.dataflow.DataFlow
import codeql.swift.security.CleartextLoggingQuery
import TestUtilities.InlineExpectationsTest
class CleartextLogging extends InlineExpectationsTest {
CleartextLogging() { this = "CleartextLogging" }
module CleartextLogging implements TestSig {
string getARelevantTag() { result = "hasCleartextLogging" }
override string getARelevantTag() { result = "hasCleartextLogging" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node source, DataFlow::Node sink, Expr sinkExpr |
CleartextLoggingFlow::flow(source, sink) and
sinkExpr = sink.asExpr() and
@@ -19,3 +17,5 @@ class CleartextLogging extends InlineExpectationsTest {
)
}
}
import MakeTest<CleartextLogging>

View File

@@ -0,0 +1,13 @@
deadEnd
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,9 @@
deadEnd
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,2 @@
deadEnd
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,5 @@
deadEnd
| file://:0:0:0:0 | StmtCondition |
| file://:0:0:0:0 | StmtCondition |
| file://:0:0:0:0 | hasher |
| file://:0:0:0:0 | hasher |

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -9,12 +9,10 @@ class TestRemoteSource extends RemoteFlowSource {
override string getSourceType() { result = "Test source" }
}
class XxeTest extends InlineExpectationsTest {
XxeTest() { this = "XxeTest" }
module XxeTest implements TestSig {
string getARelevantTag() { result = "hasXXE" }
override string getARelevantTag() { result = "hasXXE" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node source, DataFlow::Node sink, Expr sinkExpr |
XxeFlow::flow(source, sink) and
sinkExpr = sink.asExpr() and
@@ -25,3 +23,5 @@ class XxeTest extends InlineExpectationsTest {
)
}
}
import MakeTest<XxeTest>

View File

@@ -0,0 +1,5 @@
deadEnd
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,5 @@
deadEnd
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,5 @@
deadEnd
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |
| file://:0:0:0:0 | ... = ... |

View File

@@ -0,0 +1,2 @@
failures
testFailures

View File

@@ -3,12 +3,10 @@ import codeql.swift.dataflow.DataFlow
import codeql.swift.security.PredicateInjectionQuery
import TestUtilities.InlineExpectationsTest
class PredicateInjectionTest extends InlineExpectationsTest {
PredicateInjectionTest() { this = "PredicateInjectionTest" }
module PredicateInjectionTest implements TestSig {
string getARelevantTag() { result = "hasPredicateInjection" }
override string getARelevantTag() { result = "hasPredicateInjection" }
override predicate hasActualResult(Location location, string element, string tag, string value) {
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node source, DataFlow::Node sink, Expr sinkExpr |
PredicateInjectionFlow::flow(source, sink) and
sinkExpr = sink.asExpr() and
@@ -19,3 +17,5 @@ class PredicateInjectionTest extends InlineExpectationsTest {
)
}
}
import MakeTest<PredicateInjectionTest>

View File

@@ -523,9 +523,22 @@ class OpaqueValueExpr(Expr):
pass
class OpenExistentialExpr(Expr):
sub_expr: Expr | child
existential: Expr | child
opaque_expr: OpaqueValueExpr | child
""" An implicit expression created by the compiler when a method is called on a protocol. For example in
```
protocol P {
func foo() -> Int
}
func bar(x: P) -> Int {
return x.foo()
}
`x.foo()` is actually wrapped in an `OpenExistentialExpr` that "opens" `x` replacing it in its subexpression with
an `OpaqueValueExpr`.
```
"""
sub_expr: Expr | child | desc("""
This wrapped subexpression is where the opaque value and the dynamic type under the protocol type may be used.""")
existential: Expr | child | doc("protocol-typed expression opened by this expression")
opaque_expr: OpaqueValueExpr | doc("opaque value expression embedded within `getSubExpr()`")
class OptionalEvaluationExpr(Expr):
sub_expr: Expr | child

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@@ -0,0 +1 @@
/usr/bin/xcodebuild build -project ./Foo.xcodeproj -target FooDemo CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO

View File

@@ -7,8 +7,9 @@
#include "swift/logging/SwiftLogging.h"
#include "swift/xcode-autobuilder/CustomizingBuildLink.h"
static const char* uiTest = "com.apple.product-type.bundle.ui-testing";
static const char* unitTest = "com.apple.product-type.bundle.unit-test";
static constexpr std::string_view uiTest = "com.apple.product-type.bundle.ui-testing";
static constexpr std::string_view unitTest = "com.apple.product-type.bundle.unit-test";
static constexpr std::string_view unknownType = "<unknown_target_type>";
const std::string_view codeql::programName = "autobuilder";
@@ -38,6 +39,16 @@ struct CLIArgs {
bool dryRun;
};
static bool endsWith(std::string_view s, std::string_view suffix) {
return s.size() >= suffix.size() && s.substr(s.size() - suffix.size()) == suffix;
}
static bool isNonSwiftOrTestTarget(const Target& t) {
return t.fileCount == 0 || t.type == uiTest || t.type == unitTest ||
// unknown target types can be legitimate, let's do a name-based heuristic then
(t.type == unknownType && (endsWith(t.name, "Tests") || endsWith(t.name, "Test")));
}
static void autobuild(const CLIArgs& args) {
auto collected = collectTargets(args.workingDir);
auto& targets = collected.targets;
@@ -45,10 +56,7 @@ static void autobuild(const CLIArgs& args) {
LOG_INFO("{}", t);
}
// Filter out targets that are tests or have no swift source files
targets.erase(std::remove_if(std::begin(targets), std::end(targets),
[&](Target& t) -> bool {
return t.fileCount == 0 || t.type == uiTest || t.type == unitTest;
}),
targets.erase(std::remove_if(std::begin(targets), std::end(targets), isNonSwiftOrTestTarget),
std::end(targets));
// Sort targets by the amount of files in each