mirror of
https://github.com/github/codeql.git
synced 2026-05-05 05:35:13 +02:00
Merge remote-tracking branch 'upstream/main' into post-release-prep/codeql-cli-2.13.3
This commit is contained in:
@@ -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
|
||||
|
||||
9
swift/ql/.generated.list
generated
9
swift/ql/.generated.list
generated
@@ -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
3
swift/ql/.gitattributes
generated
vendored
@@ -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
|
||||
|
||||
1
swift/ql/consistency-queries/PrintAstConsistency.ql
Normal file
1
swift/ql/consistency-queries/PrintAstConsistency.ql
Normal file
@@ -0,0 +1 @@
|
||||
import codeql.swift.printast.Consistency
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* Added two consistency queries for checking control flow and AST printing internals.
|
||||
4
swift/ql/consistency-queries/qlpack.yml
Normal file
4
swift/ql/consistency-queries/qlpack.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
name: codeql/swift-consistency-queries
|
||||
groups: [swift, test, consistency-queries]
|
||||
dependencies:
|
||||
codeql/swift-all: ${workspace}
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Some models for the `Data` class have been generalized to `DataProtocol` so that they apply more widely.
|
||||
@@ -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).
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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()"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
17
swift/ql/lib/codeql/swift/generated/Raw.qll
generated
17
swift/ql/lib/codeql/swift/generated/Raw.qll
generated
@@ -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) }
|
||||
}
|
||||
|
||||
@@ -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 |
|
||||
|
||||
40
swift/ql/lib/codeql/swift/printast/Consistency.qll
Normal file
40
swift/ql/lib/codeql/swift/printast/Consistency.qll
Normal 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)
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Fixed some false positive results from the `swift/string-length-conflation` query, caused by imprecise sinks.
|
||||
@@ -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 | ... = ... |
|
||||
@@ -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 { ... } |
|
||||
@@ -0,0 +1,2 @@
|
||||
deadEnd
|
||||
| file://:0:0:0:0 | ... = ... |
|
||||
@@ -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 | ... = ... |
|
||||
@@ -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 ... |
|
||||
@@ -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 |
|
||||
@@ -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
|
||||
@@ -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 |
|
||||
16
swift/ql/test/extractor-tests/generated/expr/OpenExistentialExpr/OpenExistentialExpr.ql
generated
Normal file
16
swift/ql/test/extractor-tests/generated/expr/OpenExistentialExpr/OpenExistentialExpr.ql
generated
Normal 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
|
||||
@@ -0,0 +1 @@
|
||||
| open_existentials.swift:14:5:14:19 | OpenExistentialExpr | () |
|
||||
7
swift/ql/test/extractor-tests/generated/expr/OpenExistentialExpr/OpenExistentialExpr_getType.ql
generated
Normal file
7
swift/ql/test/extractor-tests/generated/expr/OpenExistentialExpr/OpenExistentialExpr_getType.ql
generated
Normal 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()
|
||||
@@ -0,0 +1,15 @@
|
||||
protocol P {
|
||||
func foo() -> ()
|
||||
}
|
||||
|
||||
class C : P {
|
||||
func foo() {}
|
||||
}
|
||||
|
||||
func createP() -> P {
|
||||
return C()
|
||||
}
|
||||
|
||||
func test() {
|
||||
createP().foo()
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
deadEnd
|
||||
| patterns.swift:16:10:16:14 | =~ ... |
|
||||
@@ -0,0 +1,2 @@
|
||||
deadEnd
|
||||
| file://:0:0:0:0 | ... = ... |
|
||||
@@ -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 | =~ ... |
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 | ... = ... |
|
||||
@@ -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
|
||||
#-----| -> "..."
|
||||
|
||||
@@ -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 |
|
||||
@@ -0,0 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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] &... |
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 | ... = ... |
|
||||
@@ -0,0 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
deadEnd
|
||||
| file://:0:0:0:0 | ... = ... |
|
||||
| file://:0:0:0:0 | ... = ... |
|
||||
@@ -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 ... |
|
||||
@@ -0,0 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
deadEnd
|
||||
| file://:0:0:0:0 | ... = ... |
|
||||
@@ -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
|
||||
|
||||
@@ -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 | ... = ... |
|
||||
@@ -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. |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 | ... = ... |
|
||||
@@ -0,0 +1,2 @@
|
||||
deadEnd
|
||||
| file://:0:0:0:0 | ... = ... |
|
||||
@@ -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 | ... = ... |
|
||||
@@ -0,0 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 | ... = ... |
|
||||
@@ -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 | ... = ... |
|
||||
@@ -0,0 +1,2 @@
|
||||
deadEnd
|
||||
| file://:0:0:0:0 | ... = ... |
|
||||
@@ -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 |
|
||||
@@ -0,0 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 | ... = ... |
|
||||
@@ -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 | ... = ... |
|
||||
@@ -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 | ... = ... |
|
||||
@@ -0,0 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1 @@
|
||||
/usr/bin/xcodebuild build -project ./Foo.xcodeproj -target FooDemo CODE_SIGNING_REQUIRED=NO CODE_SIGNING_ALLOWED=NO
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user