From 8c6022b78ae1e376ce0db95e1d49738e8b1ee2dd Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 16 Mar 2022 22:37:34 +0100 Subject: [PATCH 001/465] QL: add query detecting inconsistent deprecations --- .../queries/bugs/InconsistentDeprecation.ql | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 ql/ql/src/queries/bugs/InconsistentDeprecation.ql diff --git a/ql/ql/src/queries/bugs/InconsistentDeprecation.ql b/ql/ql/src/queries/bugs/InconsistentDeprecation.ql new file mode 100644 index 00000000000..366d2daa4f5 --- /dev/null +++ b/ql/ql/src/queries/bugs/InconsistentDeprecation.ql @@ -0,0 +1,24 @@ +/** + * @name Inconsistent deprecation + * @description A deprecated predicate that overrides a non-deprecated predicate is an indication that the super-predicate should be deprecated. + * @kind problem + * @problem.severity warning + * @id ql/inconsistent-deprecation + * @tags correctness + * maintanability + * @precision very-high + */ + +import ql + +predicate overrides(ClassPredicate sub, ClassPredicate sup, string description, string overrides) { + sub.overrides(sup) and description = "predicate" and overrides = "predicate" +} + +from AstNode sub, AstNode sup, string description, string overrides +where + overrides(sub, sup, description, overrides) and + sub.hasAnnotation("deprecated") and + not sup.hasAnnotation("deprecated") +select sub, "This deprecated " + description + " overrides $@. Consider deprecating both.", sup, + "a non-deprecated " + overrides From af112a011a031a4d7be4cb3a30e5f62730e2409f Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 18 Dec 2021 14:35:38 +0100 Subject: [PATCH 002/465] QL: Add query detecting suspiciously missing parameters from the QLDoc of a predicate --- .../queries/style/MissingParameterInQlDoc.ql | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 ql/ql/src/queries/style/MissingParameterInQlDoc.ql diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql new file mode 100644 index 00000000000..1fe962154f8 --- /dev/null +++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql @@ -0,0 +1,83 @@ +/** + * @name Missing QLDoc for parameter + * @description It is suspicious when a predicate has a parameter that is + * unmentioned in the qldoc, and the qldoc contains a + * code-fragment mentioning a non-parameter. + * @kind problem + * @problem.severity warning + * @precision high + * @id ql/missing-parameter-qldoc + * @tags maintainability + */ + +import ql + +/** + * Gets a fragment enclosed in backticks (`) from a QLDoc of the predicate `p`. + * Skips code-blocks that are triple-quoted. + */ +private string getACodeFragment(Predicate p) { + result = p.getQLDoc().getContents().regexpFind("`([^`]*)`(?!`)", _, _) +} + +/** Gets a parameter name from `p`. */ +private string getAParameterName(Predicate p) { result = p.getParameter(_).getName() } + +/** + * Gets the name of a parameter of `p` that is mentioned in any way in the QLDoc of `p`. + * Also includes names that are mentioned in non-code fragments. + */ +private string getADocumentedParameter(Predicate p) { + result = p.getQLDoc().getContents().regexpFind("\\b\\w[\\w_]*\\b", _, _) and + result.toLowerCase() = getAParameterName(p).toLowerCase() +} + +/** + * Get something that looks like a parameter name from the QLDoc, + * but which is not a parameter of `p`. + */ +private string getAMentionedNonParameter(Predicate p) { + exists(string fragment | fragment = getACodeFragment(p) | + result = fragment.substring(1, fragment.length() - 1) + ) and + result.regexpMatch("^[a-z]\\w+$") and + not result.toLowerCase() = getAParameterName(p).toLowerCase() and + not result = ["true", "false", "NaN"] and // keywords + not result.regexpMatch("\\d+") and // numbers + // predicates get mentioned all the time, it's fine. + not result = + any(Predicate pred | pred.getLocation().getFile() = p.getLocation().getFile()).getName() and + // classes get mentioned all the time, it's fine. + not result = + any(TypeExpr t | t.getLocation().getFile() = p.getLocation().getFile()) + .getResolvedType() + .getName() +} + +/** Gets a parameter name from `p` that is not mentioned in the qldoc. */ +private string getAnUndocumentedParameter(Predicate p) { + result = getAParameterName(p) and + not result.toLowerCase() = getADocumentedParameter(p).toLowerCase() and + not result = ["config", "conf", "cfg"] // DataFlow configurations are often undocumented, and that's fine. +} + +/** Holds if `p` has documented parameters, but `param` is undocumented */ +private predicate missingDocumentation(Predicate p, string param) { + param = getAnUndocumentedParameter(p) and + exists(getADocumentedParameter(p)) +} + +/** Gets the one string containing the undocumented parameters from `p` */ +private string getUndocumentedParameters(Predicate p) { + result = strictconcat(string param | missingDocumentation(p, param) | param, ", or ") +} + +/** Gets the parameter-like names mentioned in the QLDoc of `p` that are not parameters. */ +private string getMentionedNonParameters(Predicate p) { + result = strictconcat(string param | param = getAMentionedNonParameter(p) | param, ", and ") +} + +from Predicate p +select p, + "The QLDoc has no documentation for " + getUndocumentedParameters(p) + ", but the QLDoc mentions " + + getMentionedNonParameters(p) From ecd3aceb078c15135e516b9856fde261251fae85 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 20 Dec 2021 09:43:22 +0100 Subject: [PATCH 003/465] QL: add test for ql/missing-parameter-qldoc --- .../queries/style/MissingParameterInQlDoc/Foo.qll | 14 ++++++++++++++ .../MissingParameterInQlDoc.expected | 2 ++ .../MissingParameterInQlDoc.qlref | 1 + 3 files changed, 17 insertions(+) create mode 100644 ql/ql/test/queries/style/MissingParameterInQlDoc/Foo.qll create mode 100644 ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected create mode 100644 ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.qlref diff --git a/ql/ql/test/queries/style/MissingParameterInQlDoc/Foo.qll b/ql/ql/test/queries/style/MissingParameterInQlDoc/Foo.qll new file mode 100644 index 00000000000..13509dbe521 --- /dev/null +++ b/ql/ql/test/queries/style/MissingParameterInQlDoc/Foo.qll @@ -0,0 +1,14 @@ +/** `param1`, `param2`, and `param3` are the parameters. */ +predicate test1(int param1, int param2, int param3) { none() } // OK + +/** `param1`, `par2` */ +predicate test2(int param1, int param2) { none() } // NOT OK - `par2` is not a parameter, and `param2` has no documentation + +/** `param1`, `par2 + par3` */ +predicate test3(int param1, int par2, int par3) { none() } // OK + +/** this mentions no parameters */ +predicate test4(int param1, int param2) { none() } // OK - the QLDoc mentions none of the parameters, that's OK + +/** the param1 parameter is mentioned in a non-code block, but the `par2` parameter is misspelled */ +predicate test5(int param1, int param2) { none() } // NOT OK - the `param1` parameter is "documented" in clear text, but `par2` is misspelled diff --git a/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected new file mode 100644 index 00000000000..cca5b457ec4 --- /dev/null +++ b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected @@ -0,0 +1,2 @@ +| Foo.qll:5:1:5:50 | ClasslessPredicate test2 | The QLDoc has no documentation for param2, but the QLDoc mentions par2 | +| Foo.qll:14:1:14:50 | ClasslessPredicate test5 | The QLDoc has no documentation for param2, but the QLDoc mentions par2 | diff --git a/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.qlref b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.qlref new file mode 100644 index 00000000000..0539e4f5de2 --- /dev/null +++ b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.qlref @@ -0,0 +1 @@ +queries/style/MissingParameterInQlDoc.ql \ No newline at end of file From efba220b45f42f6643fdc55b4714cbb269535ee2 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 19 Dec 2021 23:01:53 +0100 Subject: [PATCH 004/465] JS: fix most `ql/missing-parameter-qldoc` issues --- .../ql/lib/semmle/javascript/BasicBlocks.qll | 2 +- .../semmle/javascript/CharacterEscapes.qll | 2 +- .../lib/semmle/javascript/ES2015Modules.qll | 2 +- javascript/ql/lib/semmle/javascript/Paths.qll | 4 ++-- .../lib/semmle/javascript/RangeAnalysis.qll | 22 +++++++++---------- javascript/ql/lib/semmle/javascript/SSA.qll | 2 +- .../javascript/dataflow/Configuration.qll | 12 +++++----- .../semmle/javascript/dataflow/DataFlow.qll | 2 +- .../semmle/javascript/dataflow/Portals.qll | 2 +- .../javascript/dataflow/TaintTracking.qll | 2 +- .../AngularJS/AngularJSExpressions.qll | 6 ++--- .../AngularJS/ServiceDefinitions.qll | 4 ++-- .../semmle/javascript/frameworks/Fastify.qll | 2 +- .../javascript/frameworks/NodeJSLib.qll | 8 +++---- .../security/performance/ReDoSUtil.qll | 2 +- .../src/Declarations/DeadStoreOfProperty.ql | 4 ++-- .../TemplateSyntaxInStringLiteral.ql | 4 ++-- javascript/ql/src/Metrics/ES20xxFeatures.qll | 2 +- javascript/ql/src/NodeJS/InvalidExport.ql | 8 +++---- .../Security/CWE-020/HostnameRegexpShared.qll | 2 +- .../CWE-020/IncompleteUrlSchemeCheck.ql | 4 ++-- .../Security/CWE-020/IncorrectSuffixCheck.ql | 2 +- javascript/ql/src/definitions.qll | 2 +- javascript/ql/src/external/DefectFilter.qll | 4 ++-- javascript/ql/src/external/MetricFilter.qll | 4 ++-- 25 files changed, 55 insertions(+), 55 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll index 2b02b6b6486..6e6579d6f7e 100644 --- a/javascript/ql/lib/semmle/javascript/BasicBlocks.qll +++ b/javascript/ql/lib/semmle/javascript/BasicBlocks.qll @@ -146,7 +146,7 @@ class BasicBlock extends @cfg_node, NodeInStmtContainer { /** Holds if this basic block uses variable `v` in its `i`th node `u`. */ predicate useAt(int i, Variable v, VarUse u) { useAt(this, i, v, u) } - /** Holds if this basic block defines variable `v` in its `i`th node `u`. */ + /** Holds if this basic block defines variable `v` in its `i`th node `d`. */ predicate defAt(int i, Variable v, VarDef d) { defAt(this, i, v, d) } /** diff --git a/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll b/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll index 1a19112cee3..5c8dd2bdd06 100644 --- a/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll +++ b/javascript/ql/lib/semmle/javascript/CharacterEscapes.qll @@ -75,7 +75,7 @@ module CharacterEscapes { } /** - * Gets a character in `n` that is preceded by a single useless backslash, resulting in a likely regular expression mistake explained by `mistake`. + * Gets a character in `src` that is preceded by a single useless backslash, resulting in a likely regular expression mistake explained by `mistake`. * * The character is the `i`th character of the raw string value of `rawStringNode`. */ diff --git a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll index 7ee6311393b..e584167a73b 100644 --- a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll +++ b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll @@ -337,7 +337,7 @@ class BulkReExportDeclaration extends ReExportDeclaration, @export_all_declarati } /** - * Holds if the given bulk export should not re-export `name` because there is an explicit export + * Holds if the given bulk export `reExport` should not re-export `name` because there is an explicit export * of that name in the same module. * * At compile time, shadowing works across declaration spaces. diff --git a/javascript/ql/lib/semmle/javascript/Paths.qll b/javascript/ql/lib/semmle/javascript/Paths.qll index e22d5ad6132..7574fe1e301 100644 --- a/javascript/ql/lib/semmle/javascript/Paths.qll +++ b/javascript/ql/lib/semmle/javascript/Paths.qll @@ -180,7 +180,7 @@ private Path resolveUpTo(PathString p, int n, Folder root, boolean inTS) { } /** - * Gets the `i`th component of the path `str`, where `base` is the resolved path one level up. + * Gets the `n`th component of the path `str`, where `base` is the resolved path one level up. * Supports that the root directory might be compiled output from TypeScript. * `inTS` is true if the result is TypeScript that is compiled into the path specified by `str`. */ @@ -227,7 +227,7 @@ private module TypeScriptOutDir { } /** - * Gets the `outDir` option from a tsconfig file from the folder `parent`. + * Gets the "outDir" option from a `tsconfig` file from the folder `parent`. */ private string getOutDir(JsonObject tsconfig, Folder parent) { tsconfig.getFile().getBaseName().regexpMatch("tsconfig.*\\.json") and diff --git a/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll b/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll index 5c15ea3d3aa..9d8b3967b1c 100644 --- a/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll +++ b/javascript/ql/lib/semmle/javascript/RangeAnalysis.qll @@ -260,7 +260,7 @@ module RangeAnalysis { } /** - * Holds if the given comparison can be modeled as `A B + bias` where `` is the comparison operator, + * Holds if the given `comparison` can be modeled as `A B + bias` where `` is the comparison operator, * and `A` is `a * asign` and likewise `B` is `b * bsign`. */ predicate linearComparison( @@ -310,18 +310,18 @@ module RangeAnalysis { * Holds if `guard` asserts that the outcome of `A B + bias` is true, where `` is a comparison operator. */ predicate linearComparisonGuard( - ConditionGuardNode guard, DataFlow::Node a, int asign, string operator, DataFlow::Node b, - int bsign, Bias bias + ConditionGuardNode guard, DataFlow::Node a, int asign, string op, DataFlow::Node b, int bsign, + Bias bias ) { exists(Comparison compare | compare = guard.getTest().flow().getImmediatePredecessor*().asExpr() and linearComparison(compare, a, asign, b, bsign, bias) and ( - guard.getOutcome() = true and operator = compare.getOperator() + guard.getOutcome() = true and op = compare.getOperator() or not hasNaNIndicator(guard.getContainer()) and guard.getOutcome() = false and - operator = negateOperator(compare.getOperator()) + op = negateOperator(compare.getOperator()) ) ) } @@ -657,13 +657,13 @@ module RangeAnalysis { */ pragma[noopt] private predicate reachableByNegativeEdges( - DataFlow::Node a, int asign, DataFlow::Node b, int bsign, ControlFlowNode cfg + DataFlow::Node src, int asign, DataFlow::Node dst, int bsign, ControlFlowNode cfg ) { - negativeEdge(a, asign, b, bsign, cfg) + negativeEdge(src, asign, dst, bsign, cfg) or exists(DataFlow::Node mid, int midx, ControlFlowNode midcfg | - reachableByNegativeEdges(a, asign, mid, midx, cfg) and - negativeEdge(mid, midx, b, bsign, midcfg) and + reachableByNegativeEdges(src, asign, mid, midx, cfg) and + negativeEdge(mid, midx, dst, bsign, midcfg) and exists(BasicBlock bb, int i, int j | bb.getNode(i) = midcfg and bb.getNode(j) = cfg and @@ -676,8 +676,8 @@ module RangeAnalysis { DataFlow::Node mid, int midx, ControlFlowNode midcfg, BasicBlock midBB, ReachableBasicBlock midRBB, BasicBlock cfgBB | - reachableByNegativeEdges(a, asign, mid, midx, cfg) and - negativeEdge(mid, midx, b, bsign, midcfg) and + reachableByNegativeEdges(src, asign, mid, midx, cfg) and + negativeEdge(mid, midx, dst, bsign, midcfg) and midBB = midcfg.getBasicBlock() and midRBB = midBB.(ReachableBasicBlock) and cfgBB = cfg.getBasicBlock() and diff --git a/javascript/ql/lib/semmle/javascript/SSA.qll b/javascript/ql/lib/semmle/javascript/SSA.qll index 41831a282ac..8e60fb0c3e4 100644 --- a/javascript/ql/lib/semmle/javascript/SSA.qll +++ b/javascript/ql/lib/semmle/javascript/SSA.qll @@ -501,7 +501,7 @@ class SsaExplicitDefinition extends SsaDefinition, TExplicitDef { } /** This SSA definition corresponds to the definition of `v` at `def`. */ - predicate defines(VarDef d, SsaSourceVariable v) { this = TExplicitDef(_, _, d, v) } + predicate defines(VarDef def, SsaSourceVariable v) { this = TExplicitDef(_, _, def, v) } /** Gets the variable definition wrapped by this SSA definition. */ VarDef getDef() { this = TExplicitDef(_, _, result, _) } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll index 5a9b3de4a9b..48ebd583c83 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll @@ -353,7 +353,7 @@ abstract class BarrierGuardNode extends DataFlow::Node { } /** - * Holds if data flow node `nd` acts as a barrier for data flow. + * Holds if data flow node `guard` acts as a barrier for data flow. * * `label` is bound to the blocked label, or the empty string if all labels should be blocked. */ @@ -382,7 +382,7 @@ private predicate barrierGuardIsRelevant(BarrierGuardNode guard) { } /** - * Holds if data flow node `nd` acts as a barrier for data flow due to aliasing through + * Holds if data flow node `guard` acts as a barrier for data flow due to aliasing through * an access path. * * `label` is bound to the blocked label, or the empty string if all labels should be blocked. @@ -1155,7 +1155,7 @@ private predicate appendStep( } /** - * Holds if a function invoked at `invk` may return an expression into which `input`, + * Holds if a function invoked at `output` may return an expression into which `input`, * which is either an argument or a definition captured by the function, flows under * configuration `cfg`, possibly through callees. */ @@ -1391,7 +1391,7 @@ private predicate reachableFromStoreBase( } /** - * Holds if `base` is the base of a write to property `prop`, and `nd` is reachable + * Holds if `base` is the base of a write to property `endProp`, and `nd` is reachable * from `base` under configuration `cfg` (possibly through callees) along a path whose * last step is summarized by `newSummary`, and the previous steps are summarized * by `oldSummary`. @@ -1752,7 +1752,7 @@ class PathNode extends TPathNode { this = MkSinkNode(nd, cfg) } - /** Holds if this path node wraps data-flow node `nd` and configuration `c`. */ + /** Holds if this path node wraps data-flow node `n` and configuration `c`. */ predicate wraps(DataFlow::Node n, DataFlow::Configuration c) { nd = n and cfg = c } /** Gets the underlying configuration of this path node. */ @@ -1867,7 +1867,7 @@ class MidPathNode extends PathNode, MkMidNode { MidPathNode() { this = MkMidNode(nd, cfg, summary) } - /** Holds if this path node wraps data-flow node `nd`, configuration `c` and summary `s`. */ + /** Holds if this path node wraps data-flow node `n`, configuration `c` and summary `s`. */ predicate wraps(DataFlow::Node n, DataFlow::Configuration c, PathSummary s) { nd = n and cfg = c and summary = s } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll index 247c9dfd319..eda5c2ff54f 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll @@ -1613,7 +1613,7 @@ module DataFlow { } /** - * Holds if the flow information for this node is incomplete. + * Holds if the flow information for the node `nd`. * * This predicate holds if there may be a source flow node from which data flows into * this node, but that node is not a result of `getALocalSource()` due to analysis incompleteness. diff --git a/javascript/ql/lib/semmle/javascript/dataflow/Portals.qll b/javascript/ql/lib/semmle/javascript/dataflow/Portals.qll index 299819de4cd..3a8e0b477fb 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/Portals.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/Portals.qll @@ -498,7 +498,7 @@ private module ReturnPortal { invk = callee.getAnExitNode(isRemote).getAnInvocation() } - /** Holds if `ret` is a return node of a function flowing through `callee`. */ + /** Holds if `ret` is a return node of a function flowing through `base`. */ predicate returns(Portal base, DataFlow::Node ret, boolean escapes) { ret = base.getAnEntryNode(escapes).getALocalSource().(DataFlow::FunctionNode).getAReturn() } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 184e8a255a7..45a8920cfd8 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -831,7 +831,7 @@ module TaintTracking { } /** - * Holds if the property `loadStep` should be copied from the object `pred` to the property `storeStep` of object `succ`. + * Holds if the property `loadProp` should be copied from the object `pred` to the property `storeProp` of object `succ`. * * This step is used to copy the value of our pseudo-property that can later be accessed using a `get` or `getAll` call. * For an expression `url.searchParams`, the property `hiddenUrlPseudoProperty()` from the `url` object is stored in the property `getableUrlPseudoProperty()` on `url.searchParams`. diff --git a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSExpressions.qll b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSExpressions.qll index 56fca49cd10..050c123e30a 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSExpressions.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/AngularJSExpressions.qll @@ -15,11 +15,11 @@ import javascript abstract class NgSourceProvider extends Locatable { /** * Holds if this element provides the source as `src` for an AngularJS expression at the specified location. - * The location spans column `startcolumn` of line `startline` to - * column `endcolumn` of line `endline` in file `filepath`. + * The location spans column `startColumn` of line `startLine` to + * column `endColumn` of line `endLine` in file `filepath`. */ abstract predicate providesSourceAt( - string src, string path, int startLine, int startColumn, int endLine, int endColumn + string src, string filepath, int startLine, int startColumn, int endLine, int endColumn ); /** diff --git a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll index dcce784cd1a..6d421de851c 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/AngularJS/ServiceDefinitions.qll @@ -278,11 +278,11 @@ abstract private class CustomSpecialServiceDefinition extends CustomServiceDefin bindingset[moduleMethodName] private predicate isCustomServiceDefinitionOnModule( DataFlow::CallNode mce, string moduleMethodName, string serviceName, - DataFlow::Node factoryArgument + DataFlow::Node factoryFunction ) { mce = moduleRef(_).getAMethodCall(moduleMethodName) and mce.getArgument(0).asExpr().mayHaveStringValue(serviceName) and - factoryArgument = mce.getArgument(1) + factoryFunction = mce.getArgument(1) } pragma[inline] diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll b/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll index a0007de194d..3516935cf54 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Fastify.qll @@ -299,7 +299,7 @@ module Fastify { } /** - * Holds if `rh` uses `plugin`. + * Holds if `rh` uses `middleware`. */ private predicate usesMiddleware(RouteHandler rh, DataFlow::SourceNode middleware) { exists(RouteSetup setup | diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll index 8f2576d58d4..0c5b9bcdfa2 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NodeJSLib.qll @@ -474,17 +474,17 @@ module NodeJSLib { * that receives the data. * * We determine this by looking for an externs declaration for - * `fs.methodName` where the `i`th parameter's name is `data` or + * `fs.methodName` where the `i`th parameter's name (`paramName`) is `data` or * `buffer` or a `callback`. */ - private predicate fsDataParam(string methodName, int i, string n) { + private predicate fsDataParam(string methodName, int i, string paramName) { exists(ExternalMemberDecl decl, Function f, JSDocParamTag p | decl.hasQualifiedName("fs", methodName) and f = decl.getInit() and p.getDocumentedParameter() = f.getParameter(i).getAVariable() and - n = p.getName().toLowerCase() + paramName = p.getName().toLowerCase() | - n = "data" or n = "buffer" or n = "callback" + paramName = ["data", "buffer", "callback"] ) } diff --git a/javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll b/javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll index 91b2d1d0378..b05435cf1f4 100644 --- a/javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll +++ b/javascript/ql/lib/semmle/javascript/security/performance/ReDoSUtil.qll @@ -32,7 +32,7 @@ abstract class ReDoSConfiguration extends string { } /** - * Holds if repeating `pump' starting at `state` is a candidate for causing backtracking. + * Holds if repeating `pump` starting at `state` is a candidate for causing backtracking. * No check whether a rejected suffix exists has been made. */ private predicate isReDoSCandidate(State state, string pump) { diff --git a/javascript/ql/src/Declarations/DeadStoreOfProperty.ql b/javascript/ql/src/Declarations/DeadStoreOfProperty.ql index 48b574f8cd1..c8cb0d8536e 100644 --- a/javascript/ql/src/Declarations/DeadStoreOfProperty.ql +++ b/javascript/ql/src/Declarations/DeadStoreOfProperty.ql @@ -154,7 +154,7 @@ predicate maybeAssignsAccessedPropInBlock(DataFlow::PropWrite assign, boolean af */ private module PurityCheck { /** - * Holds if a ControlFlowNode `c` is before an impure expression inside `bb`. + * Holds if `write` is before an impure expression inside `bb`. */ predicate isBeforeImpure(DataFlow::PropWrite write, ReachableBasicBlock bb) { getANodeAfterWrite(write, bb).(Expr).isImpure() @@ -181,7 +181,7 @@ private module PurityCheck { } /** - * Holds if a ControlFlowNode `c` is after an impure expression inside `bb`. + * Holds if `write` is after an impure expression inside `bb`. */ predicate isAfterImpure(DataFlow::PropWrite write, ReachableBasicBlock bb) { getANodeBeforeWrite(write, bb).(Expr).isImpure() diff --git a/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql b/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql index daa34825939..f22b9779560 100644 --- a/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql +++ b/javascript/ql/src/LanguageFeatures/TemplateSyntaxInStringLiteral.ql @@ -84,10 +84,10 @@ predicate hasObjectProvidingTemplateVariables(CandidateStringLiteral lit) { * Gets a declaration of variable `v` in `tl`, where `v` has the given `name` and * belongs to `scope`. */ -VarDecl getDeclIn(Variable v, Scope s, string name, CandidateTopLevel tl) { +VarDecl getDeclIn(Variable v, Scope scope, string name, CandidateTopLevel tl) { v.getName() = name and v.getADeclaration() = result and - v.getScope() = s and + v.getScope() = scope and result.getTopLevel() = tl } diff --git a/javascript/ql/src/Metrics/ES20xxFeatures.qll b/javascript/ql/src/Metrics/ES20xxFeatures.qll index 8069ba5e50f..4aaed2d0fda 100644 --- a/javascript/ql/src/Metrics/ES20xxFeatures.qll +++ b/javascript/ql/src/Metrics/ES20xxFeatures.qll @@ -6,7 +6,7 @@ import javascript /** - * Holds if `nd` is a use of a feature introduced in ECMAScript version `ver` + * Holds if `nd` is a use of a feature introduced in ECMAScript `version` * from the given category. * * Categories are taken from Kangax' [ECMAScript 6 compatibility table] diff --git a/javascript/ql/src/NodeJS/InvalidExport.ql b/javascript/ql/src/NodeJS/InvalidExport.ql index 9daa363e888..e0b4a73fd69 100644 --- a/javascript/ql/src/NodeJS/InvalidExport.ql +++ b/javascript/ql/src/NodeJS/InvalidExport.ql @@ -16,14 +16,14 @@ import javascript /** * Holds if `assign` assigns the value of `nd` to `exportsVar`, which is an `exports` variable */ -predicate exportsAssign(Assignment assgn, Variable exportsVar, DataFlow::Node nd) { +predicate exportsAssign(Assignment assign, Variable exportsVar, DataFlow::Node nd) { exists(NodeModule m | exportsVar = m.getScope().getVariable("exports") and - assgn.getLhs() = exportsVar.getAnAccess() and - nd = assgn.getRhs().flow() + assign.getLhs() = exportsVar.getAnAccess() and + nd = assign.getRhs().flow() ) or - exportsAssign(assgn, exportsVar, nd.getASuccessor()) + exportsAssign(assign, exportsVar, nd.getASuccessor()) } /** diff --git a/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll b/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll index 97d75d4a524..428f8992bc7 100644 --- a/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll +++ b/javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll @@ -53,7 +53,7 @@ predicate matchesBeginningOfString(RegExpTerm term) { } /** - * Holds if the given sequence contains top-level domain preceded by a dot, such as `.com`, + * Holds if the given sequence `seq` contains top-level domain preceded by a dot, such as `.com`, * excluding cases where this is at the very beginning of the regexp. * * `i` is bound to the index of the last child in the top-level domain part. diff --git a/javascript/ql/src/Security/CWE-020/IncompleteUrlSchemeCheck.ql b/javascript/ql/src/Security/CWE-020/IncompleteUrlSchemeCheck.ql index c5fb503d176..b84e9730ed4 100644 --- a/javascript/ql/src/Security/CWE-020/IncompleteUrlSchemeCheck.ql +++ b/javascript/ql/src/Security/CWE-020/IncompleteUrlSchemeCheck.ql @@ -88,8 +88,8 @@ DataFlow::Node schemeCheck(DataFlow::Node nd, DangerousScheme scheme) { } /** Gets a data-flow node that checks an instance of `ap` against the given `scheme`. */ -DataFlow::Node schemeCheckOn(DataFlow::SourceNode root, string path, DangerousScheme scheme) { - result = schemeCheck(AccessPath::getAReferenceTo(root, path), scheme) +DataFlow::Node schemeCheckOn(DataFlow::SourceNode root, string ap, DangerousScheme scheme) { + result = schemeCheck(AccessPath::getAReferenceTo(root, ap), scheme) } from DataFlow::SourceNode root, string path, int n diff --git a/javascript/ql/src/Security/CWE-020/IncorrectSuffixCheck.ql b/javascript/ql/src/Security/CWE-020/IncorrectSuffixCheck.ql index 03a7a75828b..650b71dd62f 100644 --- a/javascript/ql/src/Security/CWE-020/IncorrectSuffixCheck.ql +++ b/javascript/ql/src/Security/CWE-020/IncorrectSuffixCheck.ql @@ -84,7 +84,7 @@ class LiteralLengthExpr extends DotExpr { } /** - * Holds if `length` is derived from the length of the given `indexOf`-operand. + * Holds if `length` is derived from the length of the given indexOf `operand`. */ predicate isDerivedFromLength(DataFlow::Node length, DataFlow::Node operand) { exists(IndexOfCall call | operand = call.getAnOperand() | diff --git a/javascript/ql/src/definitions.qll b/javascript/ql/src/definitions.qll index 4d0c0d50176..7b4806b1478 100644 --- a/javascript/ql/src/definitions.qll +++ b/javascript/ql/src/definitions.qll @@ -45,7 +45,7 @@ private predicate variableDefLookup(VarAccess va, AstNode def, string kind) { /** * Holds if variable access `va` is of kind `kind` and refers to the - * variable declaration. + * variable declaration `decl`. * * For example, in the statement `var x = 42, y = x;`, the initializing * expression of `y` is a variable access `x` of kind `"V"` that refers to diff --git a/javascript/ql/src/external/DefectFilter.qll b/javascript/ql/src/external/DefectFilter.qll index 40c9527e96d..558d5ef77b6 100644 --- a/javascript/ql/src/external/DefectFilter.qll +++ b/javascript/ql/src/external/DefectFilter.qll @@ -5,8 +5,8 @@ import semmle.javascript.Files /** * Holds if `id` in the opaque identifier of a result reported by query `queryPath`, * such that `message` is the associated message and the location of the result spans - * column `startcolumn` of line `startline` to column `endcolumn` of line `endline` - * in file `filepath`. + * column `startcol` of line `startline` to column `endcol` of line `endline` + * in `file`. * * For more information, see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ diff --git a/javascript/ql/src/external/MetricFilter.qll b/javascript/ql/src/external/MetricFilter.qll index a857a4fad3e..f195060b60c 100644 --- a/javascript/ql/src/external/MetricFilter.qll +++ b/javascript/ql/src/external/MetricFilter.qll @@ -5,8 +5,8 @@ import javascript /** * Holds if `id` in the opaque identifier of a result reported by query `queryPath`, * such that `value` is the reported metric value and the location of the result spans - * column `startcolumn` of line `startline` to column `endcolumn` of line `endline` - * in file `filepath`. + * column `startcol` of line `startline` to column `endcol` of line `endline` + * in `file`. * * For more information, see [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). */ From 53760799fc2c18cc929d7b359d54e2b570aa188b Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 19 Dec 2021 23:03:36 +0100 Subject: [PATCH 005/465] sync files --- python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll | 2 +- ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll b/python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll index 91b2d1d0378..b05435cf1f4 100644 --- a/python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll +++ b/python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll @@ -32,7 +32,7 @@ abstract class ReDoSConfiguration extends string { } /** - * Holds if repeating `pump' starting at `state` is a candidate for causing backtracking. + * Holds if repeating `pump` starting at `state` is a candidate for causing backtracking. * No check whether a rejected suffix exists has been made. */ private predicate isReDoSCandidate(State state, string pump) { diff --git a/ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll b/ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll index 91b2d1d0378..b05435cf1f4 100644 --- a/ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll +++ b/ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll @@ -32,7 +32,7 @@ abstract class ReDoSConfiguration extends string { } /** - * Holds if repeating `pump' starting at `state` is a candidate for causing backtracking. + * Holds if repeating `pump` starting at `state` is a candidate for causing backtracking. * No check whether a rejected suffix exists has been made. */ private predicate isReDoSCandidate(State state, string pump) { From f204a411220eecd6816d6e600951e73a4bdfe58d Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 20 Dec 2021 11:15:21 +0100 Subject: [PATCH 006/465] QL: fix ql/missing-parameter-qldoc error in QL-for-QL --- ql/ql/src/codeql_ql/ast/internal/Module.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/ql/src/codeql_ql/ast/internal/Module.qll b/ql/ql/src/codeql_ql/ast/internal/Module.qll index 50416337bf4..225fa4c4d3a 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Module.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Module.qll @@ -239,7 +239,7 @@ boolean getPublicBool(AstNode n) { /** * Holds if `container` defines module `m` with name `name`. * - * `m` may be defined either directly or through `import`s. + * `m` may be defined either directly or through imports. */ private predicate definesModule( ContainerOrModule container, string name, ContainerOrModule m, boolean public From 3762ce2c72c3c13cf5e2ef680f829d00f3c18279 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 20 Dec 2021 13:46:02 +0100 Subject: [PATCH 007/465] QL: also report missing QLDoc for parameters when no parameters are documented --- .../queries/style/MissingParameterInQlDoc.ql | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql index 1fe962154f8..1b9f82a566e 100644 --- a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql +++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql @@ -42,34 +42,35 @@ private string getAMentionedNonParameter(Predicate p) { ) and result.regexpMatch("^[a-z]\\w+$") and not result.toLowerCase() = getAParameterName(p).toLowerCase() and - not result = ["true", "false", "NaN"] and // keywords - not result.regexpMatch("\\d+") and // numbers + not result = ["true", "false", "NaN", "this"] and // keywords + not result = getMentionedPredicates(p.getLocation().getFile()) and + // variables inside the predicate are also fine + not result = any(VarDecl var | var.getEnclosingPredicate() = p).getName() +} + +/** Gets the names of all predicates that are mentioned in `file`. */ +pragma[noinline] +private string getMentionedPredicates(File file) { // predicates get mentioned all the time, it's fine. - not result = - any(Predicate pred | pred.getLocation().getFile() = p.getLocation().getFile()).getName() and - // classes get mentioned all the time, it's fine. - not result = - any(TypeExpr t | t.getLocation().getFile() = p.getLocation().getFile()) - .getResolvedType() - .getName() + result = any(Predicate pred | pred.getLocation().getFile() = file).getName() or + result = any(Call c | c.getLocation().getFile() = file).getTarget().getName() } /** Gets a parameter name from `p` that is not mentioned in the qldoc. */ private string getAnUndocumentedParameter(Predicate p) { result = getAParameterName(p) and not result.toLowerCase() = getADocumentedParameter(p).toLowerCase() and - not result = ["config", "conf", "cfg"] // DataFlow configurations are often undocumented, and that's fine. -} - -/** Holds if `p` has documented parameters, but `param` is undocumented */ -private predicate missingDocumentation(Predicate p, string param) { - param = getAnUndocumentedParameter(p) and - exists(getADocumentedParameter(p)) + not result = ["config", "conf", "cfg"] and // DataFlow configurations are often undocumented, and that's fine. + not ( + // "the given" often refers to the first parameter. + p.getQLDoc().getContents().regexpMatch("(?s).*\\bthe given\\b.*") and + result = p.getParameter(0).getName() + ) } /** Gets the one string containing the undocumented parameters from `p` */ private string getUndocumentedParameters(Predicate p) { - result = strictconcat(string param | missingDocumentation(p, param) | param, ", or ") + result = strictconcat(string param | param = getAnUndocumentedParameter(p) | param, ", or ") } /** Gets the parameter-like names mentioned in the QLDoc of `p` that are not parameters. */ @@ -78,6 +79,7 @@ private string getMentionedNonParameters(Predicate p) { } from Predicate p +where not p.getLocation().getFile().getBaseName() = "Aliases.qll" // these are OK select p, "The QLDoc has no documentation for " + getUndocumentedParameters(p) + ", but the QLDoc mentions " + getMentionedNonParameters(p) From daed33f5afe8d5c0a9ea835be1264c160f37fde1 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 20 Dec 2021 13:46:15 +0100 Subject: [PATCH 008/465] JS: fix more instances of `ql/missing-parameter-qldoc` --- .../dataflow/TemplateInjection/TemplateInjection.ql | 2 +- javascript/ql/lib/semmle/javascript/Classes.qll | 2 +- javascript/ql/lib/semmle/javascript/ES2015Modules.qll | 2 +- javascript/ql/lib/semmle/javascript/PrintAst.qll | 2 +- javascript/ql/lib/semmle/javascript/Routing.qll | 2 +- javascript/ql/lib/semmle/javascript/TypeScript.qll | 2 +- .../ql/lib/semmle/javascript/frameworks/Bundling.qll | 6 +++--- .../javascript/frameworks/ConnectExpressShared.qll | 2 +- .../ql/lib/semmle/javascript/frameworks/NoSQL.qll | 6 +++--- .../ql/lib/semmle/javascript/frameworks/SocketIO.qll | 4 ++-- .../ql/lib/semmle/javascript/frameworks/jQuery.qll | 11 ++++++----- javascript/ql/src/RegExp/RegExpAlwaysMatches.ql | 8 ++++---- .../ql/src/Security/CWE-200/PrivateFileExposure.ql | 10 +++++----- javascript/ql/src/Security/CWE-384/SessionFixation.ql | 2 +- 14 files changed, 31 insertions(+), 30 deletions(-) diff --git a/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql b/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql index 2286fdc2121..ea4a99c69d8 100644 --- a/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql +++ b/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql @@ -14,7 +14,7 @@ import DataFlow::PathGraph /** * Gets the name of an unescaped placeholder in a lodash template. * - * For example, the string `

<%= title %>

` contains the placeholder `title`. + * For example, the string "

<%= title %>

" contains the placeholder "title". */ bindingset[s] string getAPlaceholderInString(string s) { diff --git a/javascript/ql/lib/semmle/javascript/Classes.qll b/javascript/ql/lib/semmle/javascript/Classes.qll index 309e2aae615..2b39eac9f42 100644 --- a/javascript/ql/lib/semmle/javascript/Classes.qll +++ b/javascript/ql/lib/semmle/javascript/Classes.qll @@ -172,7 +172,7 @@ class ClassDefinition extends @class_definition, ClassOrInterface, AST::ValueNod /** Gets the expression denoting the super class of the defined class, if any. */ override Expr getSuperClass() { result = this.getChildExpr(1) } - /** Gets the `n`th type from the `implements` clause of this class, starting at 0. */ + /** Gets the `i`th type from the `implements` clause of this class, starting at 0. */ override TypeExpr getSuperInterface(int i) { // AST indices for super interfaces: -1, -4, -7, ... exists(int astIndex | typeexprs(result, _, this, astIndex, _) | diff --git a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll index e584167a73b..89e0f92a13d 100644 --- a/javascript/ql/lib/semmle/javascript/ES2015Modules.qll +++ b/javascript/ql/lib/semmle/javascript/ES2015Modules.qll @@ -54,7 +54,7 @@ private predicate hasNamedExports(ES2015Module mod) { } /** - * Holds if this module contains a `default` export. + * Holds if this module contains a default export. */ private predicate hasDefaultExport(ES2015Module mod) { // export default foo; diff --git a/javascript/ql/lib/semmle/javascript/PrintAst.qll b/javascript/ql/lib/semmle/javascript/PrintAst.qll index f60b19ccb4e..be762640327 100644 --- a/javascript/ql/lib/semmle/javascript/PrintAst.qll +++ b/javascript/ql/lib/semmle/javascript/PrintAst.qll @@ -195,7 +195,7 @@ private module PrintJavaScript { * Gets the `i`th child of `element`. * Can be overriden in subclasses to get more specific behavior for `getChild()`. */ - AstNode getChildNode(int childIndex) { result = getLocationSortedChild(element, childIndex) } + AstNode getChildNode(int i) { result = getLocationSortedChild(element, i) } } /** Provides predicates for pretty printing `AstNode`s. */ diff --git a/javascript/ql/lib/semmle/javascript/Routing.qll b/javascript/ql/lib/semmle/javascript/Routing.qll index ad75132f9f9..84c83956d07 100644 --- a/javascript/ql/lib/semmle/javascript/Routing.qll +++ b/javascript/ql/lib/semmle/javascript/Routing.qll @@ -229,7 +229,7 @@ module Routing { } /** - * Holds if `node` has processed the incoming request strictly prior to this node. + * Holds if `guard` has processed the incoming request strictly prior to this node. */ pragma[inline] private predicate isGuardedByNodeInternal(Node guard) { diff --git a/javascript/ql/lib/semmle/javascript/TypeScript.qll b/javascript/ql/lib/semmle/javascript/TypeScript.qll index 70a1ed98830..4f421eb5d4d 100644 --- a/javascript/ql/lib/semmle/javascript/TypeScript.qll +++ b/javascript/ql/lib/semmle/javascript/TypeScript.qll @@ -751,7 +751,7 @@ class TypeAccess extends @typeaccess, TypeExpr, TypeRef { } /** - * Gets a suitable name for the library imported by `import`. + * Gets a suitable name for the library imported by `imprt`. * * For relative imports, this is the snapshot-relative path to the imported module. * For non-relative imports, it is the import path itself. diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Bundling.qll b/javascript/ql/lib/semmle/javascript/frameworks/Bundling.qll index d7fd51c1b82..1315ac651d5 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Bundling.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Bundling.qll @@ -102,9 +102,9 @@ private predicate isBrowserifyDependencyMap(ObjectExpr deps) { * Holds if `m` is a function that looks like a bundled module created * by Webpack. * - * Parameters must be named either `module` or `exports`, - * or their name must contain the substring `webpack_require` - * or `webpack_module_template_argument`. + * Parameters must be named either "module" or "exports", + * or their name must contain the substring "webpack_require" + * or "webpack_module_template_argument". */ private predicate isWebpackModule(FunctionExpr m) { forex(Parameter parm | parm = m.getAParameter() | diff --git a/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll b/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll index 9da7c959cb0..489fcf550c4 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/ConnectExpressShared.qll @@ -50,7 +50,7 @@ module ConnectExpressShared { } /** - * Holds if `fun` appears to match the given signature based on parameter naming. + * Holds if `function` appears to match the given signature based on parameter naming. */ private predicate matchesSignature(Function function, RouteHandlerSignature sig) { function.getNumParameter() = sig.getArity() and diff --git a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll index 6889161696f..fb64d054ed7 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/NoSQL.qll @@ -584,11 +584,11 @@ private module Minimongo { */ module CollectionMethodSignatures { /** - * Holds if Collection method `name` interprets parameter `n` as a query. + * Holds if Collection method `name` interprets parameter `queryArgIdx` as a query. */ - predicate interpretsArgumentAsQuery(string m, int queryArgIdx) { + predicate interpretsArgumentAsQuery(string name, int queryArgIdx) { // implements most of the MongoDB interface - MongoDB::CollectionMethodSignatures::interpretsArgumentAsQuery(m, queryArgIdx) + MongoDB::CollectionMethodSignatures::interpretsArgumentAsQuery(name, queryArgIdx) } } diff --git a/javascript/ql/lib/semmle/javascript/frameworks/SocketIO.qll b/javascript/ql/lib/semmle/javascript/frameworks/SocketIO.qll index df761420e29..4ffdf1432ac 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/SocketIO.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/SocketIO.qll @@ -55,7 +55,7 @@ module SocketIO { /** Gets the namespace with the given path of this server. */ NamespaceObject getNamespace(string path) { result = MkNamespace(this, path) } - /** Gets a api node that may refer to the socket.io server created at `srv`. */ + /** Gets a api node that may refer to a socket.io server. */ private API::Node server() { result = node or @@ -144,7 +144,7 @@ module SocketIO { override NamespaceObject getNamespace() { result = ns } /** - * Gets a data flow node that may refer to the socket.io namespace created at `ns`. + * Gets a data flow node that may refer a the socket.io namespace. */ private API::Node namespace() { result = node diff --git a/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll b/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll index 28a01dba7ab..54833514e69 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/jQuery.qll @@ -309,12 +309,13 @@ private module JQueryClientRequest { /** * Gets a node refering to the response contained in an `jqXHR` object. */ - private DataFlow::SourceNode getAResponseNodeFromAnXHRObject(DataFlow::SourceNode obj) { + private DataFlow::SourceNode getAResponseNodeFromAnXHRObject(DataFlow::SourceNode jqXHR) { result = - obj.getAPropertyRead(any(string s | - s = "responseText" or - s = "responseXML" - )) + jqXHR + .getAPropertyRead(any(string s | + s = "responseText" or + s = "responseXML" + )) } /** diff --git a/javascript/ql/src/RegExp/RegExpAlwaysMatches.ql b/javascript/ql/src/RegExp/RegExpAlwaysMatches.ql index e352617337f..06e0a8146ef 100644 --- a/javascript/ql/src/RegExp/RegExpAlwaysMatches.ql +++ b/javascript/ql/src/RegExp/RegExpAlwaysMatches.ql @@ -39,10 +39,10 @@ RegExpTerm getEffectiveRoot(RegExpTerm actualRoot) { /** * Holds if `term` contains an anchor on both ends. */ -predicate isPossiblyAnchoredOnBothEnds(RegExpSequence node) { - node.getAChild*() instanceof RegExpCaret and - node.getAChild*() instanceof RegExpDollar and - node.getNumChild() >= 2 +predicate isPossiblyAnchoredOnBothEnds(RegExpSequence term) { + term.getAChild*() instanceof RegExpCaret and + term.getAChild*() instanceof RegExpDollar and + term.getNumChild() >= 2 } /** diff --git a/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql b/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql index 99ca8cba8a7..add8679dee7 100644 --- a/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql +++ b/javascript/ql/src/Security/CWE-200/PrivateFileExposure.ql @@ -72,11 +72,11 @@ pragma[noinline] Folder getAPackageJsonFolder() { result = any(PackageJson json).getFile().getParentContainer() } /** - * Gets a reference to `dirname`, the home folder, the current working folder, or the root folder. + * Gets a reference to a directory that has a `package.json` in the same folder, the home folder, + * the current working folder, or the root folder. * All of these might cause information to be leaked. * - * For `dirname` that can happen if there is a `package.json` file in the same folder. - * It is assumed that the presence of a `package.json` file means that a `node_modules` folder can also exist. + * For the first case it is assumed that the presence of a `package.json` file means that a `node_modules` folder can also exist. * * For the root/home/working folder, they contain so much information that they must leak information somehow (e.g. ssh keys in the `~/.ssh` folder). */ @@ -108,7 +108,7 @@ DataFlow::Node getALeakingFolder(string description) { } /** - * Gets a data-flow node that represents a path to the private folder `path`. + * Gets a data-flow node that represents the private folder descriped by `description`. */ DataFlow::Node getAPrivateFolderPath(string description) { exists(string path | @@ -119,7 +119,7 @@ DataFlow::Node getAPrivateFolderPath(string description) { } /** - * Gest a call that serves the folder `path` to the public. + * Gest a call that serves the folder descriped by `description` to the public. */ DataFlow::CallNode servesAPrivateFolder(string description) { result = DataFlow::moduleMember(["express", "connect"], "static").getACall() and diff --git a/javascript/ql/src/Security/CWE-384/SessionFixation.ql b/javascript/ql/src/Security/CWE-384/SessionFixation.ql index aec00f22d45..7fccf16b01b 100644 --- a/javascript/ql/src/Security/CWE-384/SessionFixation.ql +++ b/javascript/ql/src/Security/CWE-384/SessionFixation.ql @@ -36,7 +36,7 @@ predicate isLoginSetup(Express::RouteSetup setup) { } /** - * Holds if `handler` regenerates its session using `req.session.regenerate`. + * Holds if `setup` regenerates its session using `req.session.regenerate`. */ pragma[inline] predicate regeneratesSession(Express::RouteSetup setup) { From 35c3c62f9e7e5acea9441e5989961ded1a290fd1 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Tue, 4 Jan 2022 13:42:30 +0100 Subject: [PATCH 009/465] apply suggestions from code review --- .../queries/dataflow/TemplateInjection/TemplateInjection.ql | 2 +- ql/ql/src/queries/style/MissingParameterInQlDoc.ql | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql b/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql index ea4a99c69d8..b146b19e54d 100644 --- a/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql +++ b/javascript/ql/examples/queries/dataflow/TemplateInjection/TemplateInjection.ql @@ -14,7 +14,7 @@ import DataFlow::PathGraph /** * Gets the name of an unescaped placeholder in a lodash template. * - * For example, the string "

<%= title %>

" contains the placeholder "title". + * For example, the string `"

<%= title %>

"` contains the placeholder "title". */ bindingset[s] string getAPlaceholderInString(string s) { diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql index 1b9f82a566e..ccf587d9611 100644 --- a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql +++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql @@ -42,7 +42,8 @@ private string getAMentionedNonParameter(Predicate p) { ) and result.regexpMatch("^[a-z]\\w+$") and not result.toLowerCase() = getAParameterName(p).toLowerCase() and - not result = ["true", "false", "NaN", "this"] and // keywords + not result = ["true", "false", "NaN", "this", "forall", "exists", "null", "break", "return"] and // keywords + not result = any(Aggregate a).getKind() and // min, max, sum, count, etc. not result = getMentionedPredicates(p.getLocation().getFile()) and // variables inside the predicate are also fine not result = any(VarDecl var | var.getEnclosingPredicate() = p).getName() From 86c8737250596bc5988b033ce03339b2e0233639 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Tue, 4 Jan 2022 13:51:49 +0100 Subject: [PATCH 010/465] remove string constants from mentioned non-params --- ql/ql/src/queries/style/MissingParameterInQlDoc.ql | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql index ccf587d9611..d4acb329a23 100644 --- a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql +++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql @@ -44,17 +44,18 @@ private string getAMentionedNonParameter(Predicate p) { not result.toLowerCase() = getAParameterName(p).toLowerCase() and not result = ["true", "false", "NaN", "this", "forall", "exists", "null", "break", "return"] and // keywords not result = any(Aggregate a).getKind() and // min, max, sum, count, etc. - not result = getMentionedPredicates(p.getLocation().getFile()) and + not result = getMentionedThings(p.getLocation().getFile()) and // variables inside the predicate are also fine not result = any(VarDecl var | var.getEnclosingPredicate() = p).getName() } -/** Gets the names of all predicates that are mentioned in `file`. */ +/** Gets the names of all predicates and string constants that are mentioned in `file`. */ pragma[noinline] -private string getMentionedPredicates(File file) { +private string getMentionedThings(File file) { // predicates get mentioned all the time, it's fine. result = any(Predicate pred | pred.getLocation().getFile() = file).getName() or - result = any(Call c | c.getLocation().getFile() = file).getTarget().getName() + result = any(Call c | c.getLocation().getFile() = file).getTarget().getName() or + result = any(String s | s.getLocation().getFile() = file).getValue() } /** Gets a parameter name from `p` that is not mentioned in the qldoc. */ From 2a196611af2a199449eb26d9fb818e9e35d83e0c Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Tue, 4 Jan 2022 13:54:53 +0100 Subject: [PATCH 011/465] add `not` as a keyword --- ql/ql/src/queries/style/MissingParameterInQlDoc.ql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql index d4acb329a23..730b5a89a1f 100644 --- a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql +++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql @@ -42,7 +42,9 @@ private string getAMentionedNonParameter(Predicate p) { ) and result.regexpMatch("^[a-z]\\w+$") and not result.toLowerCase() = getAParameterName(p).toLowerCase() and - not result = ["true", "false", "NaN", "this", "forall", "exists", "null", "break", "return"] and // keywords + // keywords + not result = + ["true", "false", "NaN", "this", "forall", "exists", "null", "break", "return", "not"] and not result = any(Aggregate a).getKind() and // min, max, sum, count, etc. not result = getMentionedThings(p.getLocation().getFile()) and // variables inside the predicate are also fine From 4b50c68934df4faf20a3155e7c0d3dec9675e95f Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Tue, 4 Jan 2022 14:13:48 +0100 Subject: [PATCH 012/465] exclude annotation names --- ql/ql/src/queries/style/MissingParameterInQlDoc.ql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql index 730b5a89a1f..b378803822a 100644 --- a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql +++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql @@ -47,6 +47,8 @@ private string getAMentionedNonParameter(Predicate p) { ["true", "false", "NaN", "this", "forall", "exists", "null", "break", "return", "not"] and not result = any(Aggregate a).getKind() and // min, max, sum, count, etc. not result = getMentionedThings(p.getLocation().getFile()) and + not result = any(Annotation a).getName() and // private, final, etc. + not result = any(Annotation a).getArgs(_).getValue() and // noinline, etc. // variables inside the predicate are also fine not result = any(VarDecl var | var.getEnclosingPredicate() = p).getName() } From 85fab200867f1adf87f0102452be5bc96aa48774 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Thu, 12 May 2022 12:49:02 +0200 Subject: [PATCH 013/465] Add Expr::getUnderlyingExpr predicate --- .../change-notes/2022-05-12-get-underlying-expr.md | 4 ++++ java/ql/lib/semmle/code/java/Expr.qll | 12 ++++++++++++ .../security/CleartextStorageSharedPrefsQuery.qll | 4 ++-- .../code/java/security/UnsafeAndroidAccess.qll | 5 ++++- 4 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 java/ql/lib/change-notes/2022-05-12-get-underlying-expr.md diff --git a/java/ql/lib/change-notes/2022-05-12-get-underlying-expr.md b/java/ql/lib/change-notes/2022-05-12-get-underlying-expr.md new file mode 100644 index 00000000000..f24c9379abb --- /dev/null +++ b/java/ql/lib/change-notes/2022-05-12-get-underlying-expr.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* The QL predicate `Expr::getUnderlyingExpr` has been added. It can be used to look through casts and not-null expressions and obtain the underlying expression to which they apply. diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll index 48023e135af..2c969a8d442 100755 --- a/java/ql/lib/semmle/code/java/Expr.qll +++ b/java/ql/lib/semmle/code/java/Expr.qll @@ -100,6 +100,18 @@ class Expr extends ExprParent, @expr { /** Holds if this expression is parenthesized. */ predicate isParenthesized() { isParenthesized(this, _) } + + /** + * Gets the underlying expression looking through casts and not-nulls, if any. + * Otherwise just gets this expression. + */ + Expr getUnderlyingExpr() { + if this instanceof CastingExpr or this instanceof NotNullExpr + then + result = this.(CastingExpr).getExpr().getUnderlyingExpr() or + result = this.(NotNullExpr).getExpr().getUnderlyingExpr() + else result = this + } } /** diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll index 30a8ffc3a12..e67a2d1aa21 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll @@ -51,7 +51,7 @@ private predicate sharedPreferencesInput(DataFlow::Node editor, Expr input) { exists(MethodAccess m | m.getMethod() instanceof PutSharedPreferenceMethod and input = m.getArgument(1) and - editor.asExpr() = m.getQualifier() + editor.asExpr() = m.getQualifier().getUnderlyingExpr() ) } @@ -61,7 +61,7 @@ private predicate sharedPreferencesInput(DataFlow::Node editor, Expr input) { */ private predicate sharedPreferencesStore(DataFlow::Node editor, MethodAccess m) { m.getMethod() instanceof StoreSharedPreferenceMethod and - editor.asExpr() = m.getQualifier() + editor.asExpr() = m.getQualifier().getUnderlyingExpr() } /** Flow from `SharedPreferences.Editor` to either a setter or a store method. */ diff --git a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll index 176b093b68a..ba162ede986 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll @@ -75,6 +75,8 @@ private predicate webViewLoadUrl(Argument urlArg, WebViewRef webview) { loadUrl.getArgument(0) = urlArg and loadUrl.getMethod() instanceof WebViewLoadUrlMethod | + webview.getAnAccess() = DataFlow::exprNode(loadUrl.getQualifier().getUnderlyingExpr()) + or webview.getAnAccess() = DataFlow::getInstanceArgument(loadUrl) or // `webview` is received as a parameter of an event method in a custom `WebViewClient`, @@ -82,8 +84,9 @@ private predicate webViewLoadUrl(Argument urlArg, WebViewRef webview) { exists(WebViewClientEventMethod eventMethod, MethodAccess setWebClient | setWebClient.getMethod() instanceof WebViewSetWebViewClientMethod and setWebClient.getArgument(0).getType() = eventMethod.getDeclaringType() and - loadUrl.getQualifier() = eventMethod.getWebViewParameter().getAnAccess() + loadUrl.getQualifier().getUnderlyingExpr() = eventMethod.getWebViewParameter().getAnAccess() | + webview.getAnAccess() = DataFlow::exprNode(setWebClient.getQualifier().getUnderlyingExpr()) or webview.getAnAccess() = DataFlow::getInstanceArgument(setWebClient) ) ) From f0b90b391f2ed866cda8df311835b8a06051d869 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Fri, 13 May 2022 17:55:55 +0200 Subject: [PATCH 014/465] Add Kotlin test for CleartextStorageSharedPrefs --- .../CWE-312/CleartextStorageSharedPrefsTestKt.kt | 11 +++++++++++ java/ql/test/query-tests/security/CWE-312/options | 1 + 2 files changed, 12 insertions(+) create mode 100644 java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTestKt.kt diff --git a/java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTestKt.kt b/java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTestKt.kt new file mode 100644 index 00000000000..f2f18eaeb0a --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-312/CleartextStorageSharedPrefsTestKt.kt @@ -0,0 +1,11 @@ +import android.app.Activity +import android.content.Context +import android.content.SharedPreferences + +class CleartextStorageSharedPrefsTestKt : Activity() { + fun testSetSharedPrefs1(context: Context, name: String, password: String) { + val sharedPrefs = context.getSharedPreferences("user_prefs", Context.MODE_PRIVATE); + sharedPrefs.edit().putString("name", name).apply(); // Safe + sharedPrefs.edit().putString("password", password).apply(); // $ hasCleartextStorageSharedPrefs + } +} diff --git a/java/ql/test/query-tests/security/CWE-312/options b/java/ql/test/query-tests/security/CWE-312/options index f017f81ff2f..93845c4b2a8 100644 --- a/java/ql/test/query-tests/security/CWE-312/options +++ b/java/ql/test/query-tests/security/CWE-312/options @@ -1 +1,2 @@ // semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/google-android-9.0.0 +// codeql-extractor-kotlin-options: ${testdir}/../../../stubs/google-android-9.0.0 From 9c941dc7ab54249ca88cf66fdbdcf56daec3b0f6 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 24 May 2022 10:51:31 +0200 Subject: [PATCH 015/465] Add Kotlin test for UnsafeAndroidAccess --- .../security/CWE-749/AndroidManifest.xml | 1 + .../security/CWE-749/UnsafeActivityKt.kt | 20 +++++++++++++++++++ .../test/query-tests/security/CWE-749/options | 3 ++- 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 java/ql/test/query-tests/security/CWE-749/UnsafeActivityKt.kt diff --git a/java/ql/test/query-tests/security/CWE-749/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-749/AndroidManifest.xml index b215e4d3466..79d79d0cd10 100755 --- a/java/ql/test/query-tests/security/CWE-749/AndroidManifest.xml +++ b/java/ql/test/query-tests/security/CWE-749/AndroidManifest.xml @@ -44,6 +44,7 @@ + diff --git a/java/ql/test/query-tests/security/CWE-749/UnsafeActivityKt.kt b/java/ql/test/query-tests/security/CWE-749/UnsafeActivityKt.kt new file mode 100644 index 00000000000..d20845f5c77 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-749/UnsafeActivityKt.kt @@ -0,0 +1,20 @@ +package com.example.app + +import android.app.Activity +import android.os.Bundle +import android.webkit.WebSettings +import android.webkit.WebView +import android.webkit.WebViewClient + +class UnsafeActivityKt : Activity() { + override fun onCreate(savedInstanceState : Bundle) { + + val wv = findViewById(-1) + // Implicit not-nulls happening here + wv.settings.setJavaScriptEnabled(true) + wv.settings.setAllowFileAccessFromFileURLs(true) + + val thisUrl : String = intent.extras.getString("url") + wv.loadUrl(thisUrl) // $ hasUnsafeAndroidAccess + } +} diff --git a/java/ql/test/query-tests/security/CWE-749/options b/java/ql/test/query-tests/security/CWE-749/options index d6a9adcece3..49f527db1db 100644 --- a/java/ql/test/query-tests/security/CWE-749/options +++ b/java/ql/test/query-tests/security/CWE-749/options @@ -1 +1,2 @@ -//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/android +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/google-android-9.0.0 +//codeql-extractor-kotlin-options: ${testdir}/../../../stubs/google-android-9.0.0 From b715a6b63b31a6544870e62974fce9ac31444e4f Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 26 May 2022 09:06:13 +0100 Subject: [PATCH 016/465] Swift: Add test containing local declarations. --- .../controlflow/graph/Cfg.expected | 96 +++++++++++++++++++ .../library-tests/controlflow/graph/cfg.swift | 37 +++++++ 2 files changed, 133 insertions(+) diff --git a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected index 181ae94bf32..09a945976a0 100644 --- a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -4785,3 +4785,99 @@ cfg.swift: # 405| DeclRefExpr #-----| -> TupleExpr + +# 410| TBD (YieldStmt) +#-----| -> exit AccessorDecl (normal) + +# 410| enter AccessorDecl + +# 410| enter AccessorDecl + +# 410| enter AccessorDecl +#-----| -> TBD (YieldStmt) + +# 410| exit AccessorDecl + +# 410| exit AccessorDecl + +# 410| exit AccessorDecl + +# 410| exit AccessorDecl (normal) +#-----| -> exit AccessorDecl + +# 410| exit AccessorDecl (normal) +#-----| -> exit AccessorDecl + +# 410| exit AccessorDecl (normal) +#-----| -> exit AccessorDecl + +# 411| enter ConstructorDecl +#-----| -> DeclRefExpr + +# 411| exit ConstructorDecl + +# 411| exit ConstructorDecl (normal) +#-----| -> exit ConstructorDecl + +# 412| DeclRefExpr +#-----| -> MemberRefExpr + +# 412| MemberRefExpr +#-----| -> IntegerLiteralExpr + +# 412| AssignExpr +#-----| -> ReturnStmt + +# 412| IntegerLiteralExpr +#-----| -> AssignExpr + +# 413| ReturnStmt +#-----| return -> exit ConstructorDecl (normal) + +# 417| TBD (YieldStmt) +#-----| -> exit AccessorDecl (normal) + +# 417| enter AccessorDecl + +# 417| enter AccessorDecl + +# 417| enter AccessorDecl +#-----| -> TBD (YieldStmt) + +# 417| exit AccessorDecl + +# 417| exit AccessorDecl + +# 417| exit AccessorDecl + +# 417| exit AccessorDecl (normal) +#-----| -> exit AccessorDecl + +# 417| exit AccessorDecl (normal) +#-----| -> exit AccessorDecl + +# 417| exit AccessorDecl (normal) +#-----| -> exit AccessorDecl + +# 418| enter ConstructorDecl +#-----| -> DeclRefExpr + +# 418| exit ConstructorDecl + +# 418| exit ConstructorDecl (normal) +#-----| -> exit ConstructorDecl + +# 419| DeclRefExpr +#-----| -> MemberRefExpr + +# 419| MemberRefExpr +#-----| -> IntegerLiteralExpr + +# 419| AssignExpr +#-----| -> ReturnStmt + +# 419| IntegerLiteralExpr +#-----| -> AssignExpr + +# 420| ReturnStmt +#-----| return -> exit ConstructorDecl (normal) diff --git a/swift/ql/test/library-tests/controlflow/graph/cfg.swift b/swift/ql/test/library-tests/controlflow/graph/cfg.swift index ae07cd05b71..9af52fce6c1 100644 --- a/swift/ql/test/library-tests/controlflow/graph/cfg.swift +++ b/swift/ql/test/library-tests/controlflow/graph/cfg.swift @@ -403,4 +403,41 @@ class Structors { func dictionaryLiteral(x: Int, y: Int) -> [String: Int] { return ["x": x, "y": y] +} + +func localDeclarations() -> Int { + class MyLocalClass { + var x: Int + init() { + x = 10 + } + } + + struct MyLocalStruct { + var x: Int + init() { + x = 10 + } + } + + enum MyLocalEnum { + case A + case B + } + + var myLocalVar : Int; + + // Error: declaration is only valid at file scope + // extension Int { + // func myExtensionMethod() -> Int { + // return self + // } + // } + + // protocol 'MyProtocol' cannot be nested inside another declaration + // protocol MyProtocol { + // func myMethod() + // } + + return 0 } \ No newline at end of file From df2c1972e9f120c984dfa7c4fe13f630c99940b0 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Thu, 26 May 2022 09:09:17 +0100 Subject: [PATCH 017/465] Swift: Add CFG trees for local declarations and accept test changes. --- .../internal/ControlFlowGraphImpl.qll | 8 + .../controlflow/graph/Cfg.expected | 139 ++++++++++++++++++ 2 files changed, 147 insertions(+) diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll index cc89ab2f836..036e235c3d1 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll @@ -884,6 +884,14 @@ module Decls { ) } } + + private class AbstractFunctionDeclTree extends AstLeafTree { + override AbstractFunctionDecl ast; + } + + private class TypeDeclTree extends AstLeafTree { + override TypeDecl ast; + } } module Exprs { diff --git a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected index 09a945976a0..9de7bce1b0b 100644 --- a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -357,6 +357,17 @@ cfg.swift: # 46| ClosureExpr #-----| -> ReturnStmt +# 51| enter ConcreteFuncDecl +#-----| -> ConcreteFuncDecl + +# 51| exit ConcreteFuncDecl + +# 51| exit ConcreteFuncDecl (normal) +#-----| -> exit ConcreteFuncDecl + +# 52| ConcreteFuncDecl +#-----| -> DeclRefExpr + # 52| enter ConcreteFuncDecl #-----| -> DeclRefExpr @@ -387,6 +398,12 @@ cfg.swift: # 53| DeclRefExpr #-----| -> BinaryExpr +# 55| ReturnStmt +#-----| return -> exit ConcreteFuncDecl (normal) + +# 55| DeclRefExpr +#-----| -> ReturnStmt + # 58| enter ConcreteFuncDecl #-----| -> ClosureExpr @@ -611,10 +628,16 @@ cfg.swift: # 81| enter ConcreteFuncDecl #-----| -> NamedPattern +# 81| exit ConcreteFuncDecl + +# 81| exit ConcreteFuncDecl (normal) +#-----| -> exit ConcreteFuncDecl + # 82| PatternBindingDecl #-----| -> ConcreteVarDecl # 82| ConcreteVarDecl +#-----| -> ConcreteFuncDecl # 82| NamedPattern #-----| -> IntegerLiteralExpr @@ -622,6 +645,9 @@ cfg.swift: # 82| IntegerLiteralExpr #-----| -> PatternBindingDecl +# 84| ConcreteFuncDecl +#-----| -> ConcreteFuncDecl + # 84| enter ConcreteFuncDecl #-----| -> DeclRefExpr @@ -658,6 +684,9 @@ cfg.swift: # 85| IntegerLiteralExpr #-----| -> BinaryExpr +# 88| ConcreteFuncDecl +#-----| -> DeclRefExpr + # 88| enter ConcreteFuncDecl #-----| -> DeclRefExpr @@ -675,6 +704,81 @@ cfg.swift: # 89| NilLiteralExpr #-----| -> AssignExpr +# 92| DeclRefExpr +#-----| -> DeclRefExpr + +# 92| CallExpr +#-----| exception -> exit ConcreteFuncDecl (normal) +#-----| -> NamedPattern + +# 92| InOutExpr +#-----| -> CallExpr + +# 92| DeclRefExpr +#-----| -> InOutExpr + +# 93| PatternBindingDecl +#-----| -> ConcreteVarDecl + +# 93| ConcreteVarDecl +#-----| -> DeclRefExpr + +# 93| NamedPattern +#-----| -> TypedPattern + +# 93| TypedPattern +#-----| -> IntegerLiteralExpr + +# 93| InjectIntoOptionalExpr +#-----| -> PatternBindingDecl + +# 93| IntegerLiteralExpr +#-----| -> InjectIntoOptionalExpr + +# 94| DeclRefExpr +#-----| -> DeclRefExpr + +# 94| CallExpr +#-----| exception -> exit ConcreteFuncDecl (normal) +#-----| -> DeclRefExpr + +# 94| InOutExpr +#-----| -> CallExpr + +# 94| DeclRefExpr +#-----| -> InOutExpr + +# 95| ReturnStmt +#-----| return -> exit ConcreteFuncDecl (normal) + +# 95| DeclRefExpr +#-----| -> LoadExpr + +# 95| LoadExpr +#-----| -> DeclRefExpr + +# 95| BinaryExpr +#-----| -> ReturnStmt + +# 95| DeclRefExpr +#-----| -> TypeExpr + +# 95| DotSyntaxCallExpr +#-----| exception -> exit ConcreteFuncDecl (normal) +#-----| -> DeclRefExpr + +# 95| TypeExpr +#-----| -> DotSyntaxCallExpr + +# 95| DeclRefExpr +#-----| -> LoadExpr + +# 95| LoadExpr +#-----| -> ForceValueExpr + +# 95| ForceValueExpr +#-----| -> BinaryExpr + # 99| enter AccessorDecl # 99| exit AccessorDecl @@ -4786,6 +4890,17 @@ cfg.swift: # 405| DeclRefExpr #-----| -> TupleExpr +# 408| enter ConcreteFuncDecl +#-----| -> ClassDecl + +# 408| exit ConcreteFuncDecl + +# 408| exit ConcreteFuncDecl (normal) +#-----| -> exit ConcreteFuncDecl + +# 409| ClassDecl +#-----| -> StructDecl + # 410| TBD (YieldStmt) #-----| -> exit AccessorDecl (normal) @@ -4834,6 +4949,9 @@ cfg.swift: # 413| ReturnStmt #-----| return -> exit ConstructorDecl (normal) +# 416| StructDecl +#-----| -> EnumDecl + # 417| TBD (YieldStmt) #-----| -> exit AccessorDecl (normal) @@ -4881,3 +4999,24 @@ cfg.swift: # 420| ReturnStmt #-----| return -> exit ConstructorDecl (normal) + +# 423| EnumDecl +#-----| -> NamedPattern + +# 428| PatternBindingDecl +#-----| -> ConcreteVarDecl + +# 428| ConcreteVarDecl +#-----| -> IntegerLiteralExpr + +# 428| NamedPattern +#-----| -> TypedPattern + +# 428| TypedPattern +#-----| -> PatternBindingDecl + +# 442| ReturnStmt +#-----| return -> exit ConcreteFuncDecl (normal) + +# 442| IntegerLiteralExpr +#-----| -> ReturnStmt From c012c235c6efb1628ed75c7fb3d7594ddd51f544 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Tue, 14 Jun 2022 01:06:39 +0000 Subject: [PATCH 018/465] rough draft of check request verb query --- .../ManuallyCheckHttpVerb.ql | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql new file mode 100644 index 00000000000..ab71ba45d46 --- /dev/null +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -0,0 +1,78 @@ +/** + * @name Manually checking http verb instead of using built in rails routes and protections + * @description Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. + * @kind problem + * @problem.severity error + * @security-severity 7.0 + * @precision medium + * @id rb/manually-checking-http-verb + * @tags security + */ + +import ruby +import codeql.ruby.DataFlow + +class ManuallyCheckHttpVerb extends DataFlow::CallNode { + ManuallyCheckHttpVerb() { + this instanceof CheckGetRequest or + this instanceof CheckPostRequest or + this instanceof CheckPatchRequest or + this instanceof CheckPostRequest or + this instanceof CheckDeleteRequest or + this instanceof CheckHeadRequest or + this.asExpr().getExpr() instanceof CheckRequestMethodFromEnv + } +} + +class CheckRequestMethodFromEnv extends ComparisonOperation { + CheckRequestMethodFromEnv() { + this.getAnOperand() instanceof GetRequestMethodFromEnv + } +} + +class GetRequestMethodFromEnv extends ElementReference { + GetRequestMethodFromEnv() { + this.getAChild+().toString() = "REQUEST_METHOD" // and + // this.getReceiver().toString() = "env" + } +} + +class CheckGetRequest extends DataFlow::CallNode { + CheckGetRequest() { + this.getMethodName() = "get?" + } +} + +class CheckPostRequest extends DataFlow::CallNode { + CheckPostRequest() { + this.getMethodName() = "post?" + } +} + +class CheckPutRequest extends DataFlow::CallNode { + CheckPutRequest() { + this.getMethodName() = "put?" + } +} + +class CheckPatchRequest extends DataFlow::CallNode { + CheckPatchRequest() { + this.getMethodName() = "patch?" + } +} + +class CheckDeleteRequest extends DataFlow::CallNode { + CheckDeleteRequest() { + this.getMethodName() = "delete?" + } +} + +class CheckHeadRequest extends DataFlow::CallNode { + CheckHeadRequest() { + this.getMethodName() = "head?" + } +} + +from ManuallyCheckHttpVerb check +where check.asExpr().getExpr().getAControlFlowNode().isCondition() +select check, "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods." \ No newline at end of file From 7bdec98e6f73764028038476dc8c2c14d51e99f5 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Tue, 14 Jun 2022 02:13:15 +0000 Subject: [PATCH 019/465] draft tests --- .../ExampleController.rb | 51 +++++++++++++++++++ .../ManuallyCheckHttpVerb.qlref | 1 + .../manually-check-http-verb/NotController.rb | 28 ++++++++++ 3 files changed, 80 insertions(+) create mode 100644 ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb create mode 100644 ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.qlref create mode 100644 ruby/ql/test/query-tests/security/manually-check-http-verb/NotController.rb diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb b/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb new file mode 100644 index 00000000000..a67d4e5306a --- /dev/null +++ b/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb @@ -0,0 +1,51 @@ +class ExampleController < ActionController::Base + # This function should have 6 vulnerable lines + def example_action + if request.get? + Example.find(params[:example_id]) + elsif request.post? + Example.new(params[:example_name], params[:example_details]) + elsif request.delete? + example = Example.find(params[:example_id]) + example.delete + elsif request.put? + Example.upsert(params[:example_name], params[:example_details]) + elsif request.path? + Example.update(params[:example_name], params[:example_details]) + elsif request.head? + "This is the endpoint for the Example resource." + end + end +end + +class ResourceController < ActionController::Base + # This method should have 1 vulnerable line + def resource_action + case env['REQUEST_METHOD'] + when "GET" + Resource.find(params[:id]) + when "POST" + Resource.new(params[:id], params[:details]) + end + end +end + +class SafeController < ActionController::Base + # this method should have no hits because controllers rely on conventional Rails routes + def index + Safe.find(params[:id]) + end + + def create + Safe.new(params[:id], params[:details]) + end + + def update + Safe.update(params[:id], params[:details]) + end + + def delete + s = Safe.find(params[:id]) + s.delete + end +end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.qlref b/ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.qlref new file mode 100644 index 00000000000..463c21cd0f2 --- /dev/null +++ b/ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.qlref @@ -0,0 +1 @@ +experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/NotController.rb b/ruby/ql/test/query-tests/security/manually-check-http-verb/NotController.rb new file mode 100644 index 00000000000..81a73d72410 --- /dev/null +++ b/ruby/ql/test/query-tests/security/manually-check-http-verb/NotController.rb @@ -0,0 +1,28 @@ +# There should be no hits from this class because it does not inherit from ActionController +class NotAController + def example_action + if request.get? + Example.find(params[:example_id]) + elsif request.post? + Example.new(params[:example_name], params[:example_details]) + elsif request.delete? + example = Example.find(params[:example_id]) + example.delete + elsif request.put? + Example.upsert(params[:example_name], params[:example_details]) + elsif request.path? + Example.update(params[:example_name], params[:example_details]) + elsif request.head? + "This is the endpoint for the Example resource." + end + end + + def resource_action + case env['REQUEST_METHOD'] + when "GET" + Resource.find(params[:id]) + when "POST" + Resource.new(params[:id], params[:details]) + end + end +end \ No newline at end of file From 6bef71ea2ca8960082507da96b1967265fb3f943 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Tue, 14 Jun 2022 02:17:12 +0000 Subject: [PATCH 020/465] tweaks to tests --- .../manually-check-http-verb/ExampleController.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb b/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb index a67d4e5306a..c3e913367b8 100644 --- a/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb +++ b/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb @@ -18,8 +18,16 @@ class ExampleController < ActionController::Base end end +class OtherController < ActionController::Base + def other_action + if env['REQUEST_METHOD'] == "GET" + Other.find(params[:id]) + end + end +end + class ResourceController < ActionController::Base - # This method should have 1 vulnerable line + # This method should have 1 vulnerable line, but is currently failing because it's not a comparison node def resource_action case env['REQUEST_METHOD'] when "GET" From 7b5d9ec7df7129aeae2d0bc596b09baa5d157f72 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Tue, 14 Jun 2022 14:59:59 +0200 Subject: [PATCH 021/465] python: Straight port of tarslip --- .../python/security/dataflow/TarSlip.qll | 29 +++ .../dataflow/TarSlipCustomizations.qll | 145 +++++++++++++++ python/ql/src/Security/CWE-022/TarSlip.ql | 170 +----------------- .../Security/CWE-022-TarSlip/options | 1 - 4 files changed, 179 insertions(+), 166 deletions(-) create mode 100644 python/ql/lib/semmle/python/security/dataflow/TarSlip.qll create mode 100644 python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll delete mode 100644 python/ql/test/query-tests/Security/CWE-022-TarSlip/options diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlip.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlip.qll new file mode 100644 index 00000000000..90c79da1f04 --- /dev/null +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlip.qll @@ -0,0 +1,29 @@ +/** + * Provides a taint-tracking configuration for detecting "command injection" vulnerabilities. + * + * Note, for performance reasons: only import this file if + * `TarSlip::Configuration` is needed, otherwise + * `TarSlipCustomizations` should be imported instead. + */ + +private import python +import semmle.python.dataflow.new.DataFlow +import semmle.python.dataflow.new.TaintTracking +import TarSlipCustomizations::TarSlip + +/** + * A taint-tracking configuration for detecting "command injection" vulnerabilities. + */ +class Configuration extends TaintTracking::Configuration { + Configuration() { this = "TarSlip" } + + override predicate isSource(DataFlow::Node source) { source instanceof Source } + + override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } + + override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } + + override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { + guard instanceof SanitizerGuard + } +} diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll new file mode 100644 index 00000000000..7393b129f37 --- /dev/null +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll @@ -0,0 +1,145 @@ +/** + * Provides default sources, sinks and sanitizers for detecting + * "tar slip" + * vulnerabilities, as well as extension points for adding your own. + */ + +private import python +private import semmle.python.dataflow.new.DataFlow +private import semmle.python.Concepts +private import semmle.python.dataflow.new.BarrierGuards +private import semmle.python.ApiGraphs + +/** + * Provides default sources, sinks and sanitizers for detecting + * "tar slip" + * vulnerabilities, as well as extension points for adding your own. + */ +module TarSlip { + /** + * A data flow source for "tar slip" vulnerabilities. + */ + abstract class Source extends DataFlow::Node { } + + /** + * A data flow sink for "tar slip" vulnerabilities. + */ + abstract class Sink extends DataFlow::Node { } + + /** + * A sanitizer for "tar slip" vulnerabilities. + */ + abstract class Sanitizer extends DataFlow::Node { } + + /** + * A sanitizer guard for "tar slip" vulnerabilities. + */ + abstract class SanitizerGuard extends DataFlow::BarrierGuard { } + + /** + * A source of exception info, considered as a flow source. + */ + class TarfileOpen extends Source { + TarfileOpen() { + this = API::moduleImport("tarfile").getMember("open").getACall() and + // If argument refers to a string object, then it's a hardcoded path and + // this tarfile is safe. + not this.(DataFlow::CallCfgNode).getArg(0).getALocalSource().asExpr() instanceof StrConst and + /* Ignore opens within the tarfile module itself */ + not this.getLocation().getFile().getBaseName() = "tarfile.py" + } + } + + /** + * For efficiency we don't want to track the flow of taint + * around the tarfile module. + */ + class ExcludeTarFilePy extends Sanitizer { + ExcludeTarFilePy() { this.getLocation().getFile().getBaseName() = "tarfile.py" } + } + + /** + * For a call to `file.extractall` without arguments, `file` is considered a sink. + */ + class ExtractAllSink extends Sink { + ExtractAllSink() { + exists(DataFlow::CallCfgNode call | + call = + API::moduleImport("tarfile") + .getMember("open") + .getReturn() + .getMember("extractall") + .getACall() and + not exists(call.getArg(_)) and + not exists(call.getArgByName(_)) and + this = call.(DataFlow::MethodCallNode).getObject() + ) + } + } + + /** + * An argument to `extract` is considered a sink. + */ + class ExtractSink extends Sink { + ExtractSink() { + exists(DataFlow::CallCfgNode call | + call = + API::moduleImport("tarfile").getMember("open").getReturn().getMember("extract").getACall() and + this = call.getArg(0) + ) + } + } + + /* Members argument to extract method */ + class ExtractMembersSink extends Sink { + ExtractMembersSink() { + exists(DataFlow::CallCfgNode call | + call = + API::moduleImport("tarfile") + .getMember("open") + .getReturn() + .getMember("extractall") + .getACall() and + this in [call.getArg(0), call.getArgByName("members")] + ) + } + } + + class TarFileInfoSanitizer extends SanitizerGuard { + ControlFlowNode tarInfo; + + TarFileInfoSanitizer() { + exists(CallNode call, AttrNode attr | + this = call and + // We must test the name of the tar info object. + attr = call.getAnArg() and + attr.getName() = "name" and + attr.getObject() = tarInfo + | + // Assume that any test with "path" in it is a sanitizer + call.getAChild*().(AttrNode).getName().matches("%path") + or + call.getAChild*().(NameNode).getId().matches("%path") + ) + } + + override predicate checks(ControlFlowNode checked, boolean branch) { + checked = tarInfo and + branch in [true, false] + } + + DataFlow::ExprNode shouldGuard() { + tarInfo.dominates(result.asCfgNode()) and + // exists(EssaDefinition def | + // def.getAUse() = tarInfo and + // def.getAUse() = result.asCfgNode() + // ) and + exists(SsaSourceVariable v | + v.getAUse() = tarInfo and + v.getAUse() = result.asCfgNode() + ) + } + } + + DataFlow::ExprNode getAGuardedNode(TarFileInfoSanitizer tfis) { result = tfis.getAGuardedNode() } +} diff --git a/python/ql/src/Security/CWE-022/TarSlip.ql b/python/ql/src/Security/CWE-022/TarSlip.ql index 76d799a0aca..1528be7377d 100644 --- a/python/ql/src/Security/CWE-022/TarSlip.ql +++ b/python/ql/src/Security/CWE-022/TarSlip.ql @@ -13,170 +13,10 @@ */ import python -import semmle.python.security.Paths -import semmle.python.dataflow.TaintTracking -import semmle.python.security.strings.Basic +import semmle.python.security.dataflow.TarSlip +import DataFlow::PathGraph -/** A TaintKind to represent open tarfile objects. That is, the result of calling `tarfile.open(...)` */ -class OpenTarFile extends TaintKind { - OpenTarFile() { this = "tarfile.open" } - - override TaintKind getTaintOfMethodResult(string name) { - name = "getmember" and result instanceof TarFileInfo - or - name = "getmembers" and result.(SequenceKind).getItem() instanceof TarFileInfo - } - - override ClassValue getType() { result = Value::named("tarfile.TarFile") } - - override TaintKind getTaintForIteration() { result instanceof TarFileInfo } -} - -/** The source of open tarfile objects. That is, any call to `tarfile.open(...)` */ -class TarfileOpen extends TaintSource { - TarfileOpen() { - Value::named("tarfile.open").getACall() = this and - /* - * If argument refers to a string object, then it's a hardcoded path and - * this tarfile is safe. - */ - - not this.(CallNode).getAnArg().pointsTo(any(StringValue str)) and - /* Ignore opens within the tarfile module itself */ - not this.(ControlFlowNode).getLocation().getFile().getBaseName() = "tarfile.py" - } - - override predicate isSourceOf(TaintKind kind) { kind instanceof OpenTarFile } -} - -class TarFileInfo extends TaintKind { - TarFileInfo() { this = "tarfile.entry" } - - override TaintKind getTaintOfMethodResult(string name) { name = "next" and result = this } - - override TaintKind getTaintOfAttribute(string name) { - name = "name" and result instanceof TarFileInfo - } -} - -/* - * For efficiency we don't want to track the flow of taint - * around the tarfile module. - */ - -class ExcludeTarFilePy extends Sanitizer { - ExcludeTarFilePy() { this = "Tar sanitizer" } - - override predicate sanitizingNode(TaintKind taint, ControlFlowNode node) { - node.getLocation().getFile().getBaseName() = "tarfile.py" and - ( - taint instanceof OpenTarFile - or - taint instanceof TarFileInfo - or - taint.(SequenceKind).getItem() instanceof TarFileInfo - ) - } -} - -/* Any call to an extractall method */ -class ExtractAllSink extends TaintSink { - ExtractAllSink() { - exists(CallNode call | - this = call.getFunction().(AttrNode).getObject("extractall") and - not exists(call.getAnArg()) - ) - } - - override predicate sinks(TaintKind kind) { kind instanceof OpenTarFile } -} - -/* Argument to extract method */ -class ExtractSink extends TaintSink { - CallNode call; - - ExtractSink() { - call.getFunction().(AttrNode).getName() = "extract" and - this = call.getArg(0) - } - - override predicate sinks(TaintKind kind) { kind instanceof TarFileInfo } -} - -/* Members argument to extract method */ -class ExtractMembersSink extends TaintSink { - CallNode call; - - ExtractMembersSink() { - call.getFunction().(AttrNode).getName() = "extractall" and - (this = call.getArg(0) or this = call.getArgByName("members")) - } - - override predicate sinks(TaintKind kind) { - kind.(SequenceKind).getItem() instanceof TarFileInfo - or - kind instanceof OpenTarFile - } -} - -class TarFileInfoSanitizer extends Sanitizer { - TarFileInfoSanitizer() { this = "TarInfo sanitizer" } - - /* The test `if :` clears taint on its `false` edge. */ - override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) { - taint instanceof TarFileInfo and - clears_taint_on_false_edge(test.getTest(), test.getSense()) - } - - private predicate clears_taint_on_false_edge(ControlFlowNode test, boolean sense) { - path_sanitizing_test(test) and - sense = false - or - // handle `not` (also nested) - test.(UnaryExprNode).getNode().getOp() instanceof Not and - clears_taint_on_false_edge(test.(UnaryExprNode).getOperand(), sense.booleanNot()) - } -} - -private predicate path_sanitizing_test(ControlFlowNode test) { - /* Assume that any test with "path" in it is a sanitizer */ - test.getAChild+().(AttrNode).getName().matches("%path") - or - test.getAChild+().(NameNode).getId().matches("%path") -} - -class TarSlipConfiguration extends TaintTracking::Configuration { - TarSlipConfiguration() { this = "TarSlip configuration" } - - override predicate isSource(TaintTracking::Source source) { source instanceof TarfileOpen } - - override predicate isSink(TaintTracking::Sink sink) { - sink instanceof ExtractSink or - sink instanceof ExtractAllSink or - sink instanceof ExtractMembersSink - } - - override predicate isSanitizer(Sanitizer sanitizer) { - sanitizer instanceof TarFileInfoSanitizer - or - sanitizer instanceof ExcludeTarFilePy - } - - override predicate isBarrier(DataFlow::Node node) { - // Avoid flow into the tarfile module - exists(ParameterDefinition def | - node.asVariable().getDefinition() = def - or - node.asCfgNode() = def.getDefiningNode() - | - def.getScope() = Value::named("tarfile.open").(CallableValue).getScope() - or - def.isSelf() and def.getScope().getEnclosingModule().getName() = "tarfile" - ) - } -} - -from TarSlipConfiguration config, TaintedPathSource src, TaintedPathSink sink -where config.hasFlowPath(src, sink) -select sink.getSink(), src, sink, "Extraction of tarfile from $@", src.getSource(), +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode(), source, sink, "Extraction of tarfile from $@", source.getNode(), "a potentially untrusted source" diff --git a/python/ql/test/query-tests/Security/CWE-022-TarSlip/options b/python/ql/test/query-tests/Security/CWE-022-TarSlip/options deleted file mode 100644 index 492768b3481..00000000000 --- a/python/ql/test/query-tests/Security/CWE-022-TarSlip/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: -p ../lib/ --max-import-depth=3 From 304e2926c9ee67b2cff89152482e9ee28e2a4c0c Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Tue, 14 Jun 2022 10:56:15 +0100 Subject: [PATCH 022/465] Java: Fix RefType.getAStrictAncestor() in the presence of type hierarchy cycles --- java/ql/lib/semmle/code/java/Type.qll | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/java/ql/lib/semmle/code/java/Type.qll b/java/ql/lib/semmle/code/java/Type.qll index a37f9810c44..323513b6a44 100755 --- a/java/ql/lib/semmle/code/java/Type.qll +++ b/java/ql/lib/semmle/code/java/Type.qll @@ -413,8 +413,12 @@ class RefType extends Type, Annotatable, Modifiable, @reftype { /** Gets a direct or indirect supertype of this type, including itself. */ RefType getAnAncestor() { hasDescendant(result, this) } - /** Gets a direct or indirect supertype of this type, not including itself. */ - RefType getAStrictAncestor() { result = this.getAnAncestor() and result != this } + /** + * Gets a direct or indirect supertype of this type. + * This does not including itself, unless this type is part of a cycle + * in the type hierarchy. + */ + RefType getAStrictAncestor() { result = this.getASupertype().getAnAncestor() } /** * Gets the source declaration of a direct supertype of this type, excluding itself. From b524fb4f3ae369f67dfc91e51fff37f083224e77 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Tue, 14 Jun 2022 10:58:26 +0100 Subject: [PATCH 023/465] Java: Add a test for cycles in the type hierarchy --- java/ql/test/library-tests/types/cycles/Test.java | 2 ++ java/ql/test/library-tests/types/cycles/cycles.expected | 6 ++++++ java/ql/test/library-tests/types/cycles/cycles.ql | 5 +++++ 3 files changed, 13 insertions(+) create mode 100644 java/ql/test/library-tests/types/cycles/Test.java create mode 100644 java/ql/test/library-tests/types/cycles/cycles.expected create mode 100644 java/ql/test/library-tests/types/cycles/cycles.ql diff --git a/java/ql/test/library-tests/types/cycles/Test.java b/java/ql/test/library-tests/types/cycles/Test.java new file mode 100644 index 00000000000..a06540728b9 --- /dev/null +++ b/java/ql/test/library-tests/types/cycles/Test.java @@ -0,0 +1,2 @@ +public class Test { +} diff --git a/java/ql/test/library-tests/types/cycles/cycles.expected b/java/ql/test/library-tests/types/cycles/cycles.expected new file mode 100644 index 00000000000..7c0e79d7252 --- /dev/null +++ b/java/ql/test/library-tests/types/cycles/cycles.expected @@ -0,0 +1,6 @@ +| BiFunction | +| BiFunction | +| Function | +| Function | +| Map | +| Map | diff --git a/java/ql/test/library-tests/types/cycles/cycles.ql b/java/ql/test/library-tests/types/cycles/cycles.ql new file mode 100644 index 00000000000..dd4d6e1f757 --- /dev/null +++ b/java/ql/test/library-tests/types/cycles/cycles.ql @@ -0,0 +1,5 @@ +import java + +from RefType t +where t = t.getAStrictAncestor() +select t.toString() From 1959f491658d8ae892034d623ef1983042c35d10 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 29 Mar 2022 10:44:11 +0100 Subject: [PATCH 024/465] Add Improper Intent Verification query --- .../ImproperIntentVerificationQuery.qll | 154 ++++++++++++++++++ .../CWE/CWE-925/ImproperIntentVerification.ql | 18 ++ 2 files changed, 172 insertions(+) create mode 100644 java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll create mode 100644 java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll new file mode 100644 index 00000000000..f300697a6ed --- /dev/null +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -0,0 +1,154 @@ +/** Definitions for the improper intent verification query. */ + +import java +import semmle.code.java.dataflow.DataFlow + +/** An `onRecieve` method of a `BroadcastReciever` */ +private class OnReceiveMethod extends Method { + OnReceiveMethod() { + this.getASourceOverriddenMethod*() + .hasQualifiedName("android.content", "BroadcastReciever", "onReceeve") + } + + /** Gets the paramter of this method that holds the received `Intent`. */ + Parameter getIntentParameter() { result = this.getParameter(1) } +} + +/** A configuration to detect whether the `action` of an `Intent` is checked. */ +private class VerifiedIntentConfig extends DataFlow::Configuration { + VerifiedIntentConfig() { this = "VerifiedIntentConfig" } + + override predicate isSource(DataFlow::Node src) { + src.asParameter() = any(OnReceiveMethod orm).getIntentParameter() + } + + override predicate isSink(DataFlow::Node sink) { + exists(MethodAccess ma | + ma.getMethod().hasQualifiedName("android.content", "Intent", "getAction") and + sink.asExpr() = ma.getQualifier() + ) + } +} + +/** An `onRecieve` method that doesn't verify the action of the intent it recieves. */ +class UnverifiedOnReceiveMethod extends OnReceiveMethod { + UnverifiedOnReceiveMethod() { + not any(VerifiedIntentConfig c).hasFlow(DataFlow::parameterNode(this.getIntentParameter()), _) + } +} + +/** Gets the name of an intent action that can only be sent by the system. */ +string getASystemActionName() { + result = + [ + "AIRPLANE_MODE", "AIRPLANE_MODE_CHANGED", "APPLICATION_LOCALE_CHANGED", + "APPLICATION_RESTRICTIONS_CHANGED", "BATTERY_CHANGED", "BATTERY_LOW", "BATTERY_OKAY", + "BOOT_COMPLETED", "CONFIGURATION_CHANGED", "DEVICE_STORAGE_LOW", "DEVICE_STORAGE_OK", + "DREAMING_STARTED", "DREAMING_STOPPED", "EXTERNAL_APPLICATIONS_AVAILABLE", + "EXTERNAL_APPLICATIONS_UNAVAILABLE", "LOCALE_CHANGED", "LOCKED_BOOT_COMPLETED", + "MY_PACKAGE_REPLACED", "MY_PACKAGE_SUSPENDED", "MY_PACKAGE_UNSUSPENDED", "NEW_OUTGOING_CALL", + "PACKAGES_SUSPENDED", "PACKAGES_UNSUSPENDED", "PACKAGE_ADDED", "PACKAGE_CHANGED", + "PACKAGE_DATA_CLEARED", "PACKAGE_FIRST_LAUNCH", "PACKAGE_FULLY_REMOVED", "PACKAGE_INSTALL", + "PACKAGE_NEEDS_VERIFICATION", "PACKAGE_REMOVED", "PACKAGE_REPLACED", "PACKAGE_RESTARTED", + "PACKAGE_VERIFIED", "POWER_CONNECTED", "POWER_DISCONNECTED", "REBOOT", "SCREEN_OFF", + "SCREEN_ON", "SHUTDOWN", "TIMEZONE_CHANGED", "TIME_TICK", "UID_REMOVED", "USER_PRESENT" + ] +} + +/** An expression or XML attribute that contains the name of a system intent action. */ +class SystemActionName extends Top { + string name; + + SystemActionName() { + name = getASystemActionName() and + ( + this.(StringLiteral).getValue() = "android.intent.action." + name + or + this.(FieldRead).getField().hasQualifiedName("android.content", "Intent", "ACTION_" + name) + or + this.(XMLAttribute).getValue() = "android.intent.action." + name + ) + } + + /** Gets the name of the system intent that this expression or attriute represents. */ + string getName() { result = name } +} + +/** A call to `Context.registerReciever` */ +private class RegisterReceiverCall extends MethodAccess { + RegisterReceiverCall() { + this.getMethod() + .getASourceOverriddenMethod*() + .hasQualifiedName("android.content", "Context", "registerReceiver") + } + + /** Gets the `BroadcastReceiver` argument to this call. */ + Expr getReceiverArgument() { result = this.getArgument(0) } + + /** Gets the `IntentFilter` argument to this call. */ + Expr getFilterArgument() { result = this.getArgument(1) } +} + +/** A configuration to detect uses of `registerReciever` with system intent actions. */ +private class RegisterSystemActionConfig extends DataFlow::Configuration { + RegisterSystemActionConfig() { this = "RegisterSystemActionConfig" } + + override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SystemActionName } + + override predicate isSink(DataFlow::Node node) { + exists(RegisterReceiverCall ma | node.asExpr() = ma.getFilterArgument()) + } + + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + exists(ConstructorCall cc | + cc.getConstructedType().hasQualifiedName("android.content", "IntentFilter") and + node1.asExpr() = cc.getArgument(0) and + node2.asExpr() = cc + ) + or + exists(MethodAccess ma | + ma.getMethod().hasQualifiedName("android.content", "IntentFilter", "create") and + node1.asExpr() = ma.getArgument(0) and + node2.asExpr() = ma + ) + or + exists(MethodAccess ma | + ma.getMethod().hasQualifiedName("android.content", "IntentFilter", "addAction") and + node1.asExpr() = ma.getArgument(0) and + node2.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = ma.getQualifier() + ) + } +} + +/** Holds if `rrc` registers a reciever `orm` to recieve the system action `sa` that doesn't verifiy intents it recieves. */ +predicate registeredUnverifiedSystemReciever( + RegisterReceiverCall rrc, UnverifiedOnReceiveMethod orm, SystemActionName sa +) { + exists(RegisterSystemActionConfig conf, ConstructorCall cc | + conf.hasFlow(DataFlow::exprNode(sa), DataFlow::exprNode(rrc.getFilterArgument())) and + cc.getConstructedType() = orm.getDeclaringType() and + DataFlow::localExprFlow(cc, rrc.getReceiverArgument()) + ) +} + +/** Holds if the XML element `rec` declares a reciever `orm` to recieve the system action named `sa` that doesn't verifiy intents it recieves. */ +predicate xmlUnverifiedSystemReciever( + XMLElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa +) { + exists(XMLElement filter, XMLElement action, Class ormty | + rec.hasName("receiver") and + filter.hasName("intent-filter") and + action.hasName("action") and + filter = rec.getAChild() and + action = rec.getAChild() and + ormty = orm.getDeclaringType() and + rec.getAttribute("android:name").getValue() = ["." + ormty.getName(), ormty.getQualifiedName()] and + action.getAttribute("android:name") = sa + ) +} + +/** Holds if `reg` registers (either explicitly or through XML) a reciever `orm` to recieve the system action named `sa` that doesn't verify intents it recieves. */ +predicate unverifiedSystemReciever(Top reg, Method orm, SystemActionName sa) { + registeredUnverifiedSystemReciever(reg, orm, sa) or + xmlUnverifiedSystemReciever(reg, orm, sa) +} diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql new file mode 100644 index 00000000000..249da869250 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql @@ -0,0 +1,18 @@ +/** + * @name Improper Verification of Intent by Broadcast Reciever + * @description The Android application uses a Broadcast Receiver that receives an Intent but does not properly verify that the Intent came from an authorized source. + * @kind problem + * @problem.severity warning + * @precision high + * @id java/improper-intent-verification + * @tags security + * external/cwe/cwe-925 + */ + +import java +import semmle.code.java.security.ImproperIntentVerificationQuery + +from Top reg, Method orm, SystemActionName sa +where unverifiedSystemReciever(reg, orm, sa) +select orm, "This reciever doesn't verify intents it recieves, and is registered $@ to recieve $@.", + reg, "here", sa, "the system action " + sa.getName() From 87f26bf0337f5549c2486e3c64f20a0da03bec68 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 5 Apr 2022 12:32:31 +0100 Subject: [PATCH 025/465] Fix typos --- .../ImproperIntentVerificationQuery.qll | 20 +++++++++---------- .../CWE/CWE-925/ImproperIntentVerification.ql | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll index f300697a6ed..e8ed1f17b42 100644 --- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -3,11 +3,11 @@ import java import semmle.code.java.dataflow.DataFlow -/** An `onRecieve` method of a `BroadcastReciever` */ +/** An `onReceive` method of a `BroadcastReceiver` */ private class OnReceiveMethod extends Method { OnReceiveMethod() { this.getASourceOverriddenMethod*() - .hasQualifiedName("android.content", "BroadcastReciever", "onReceeve") + .hasQualifiedName("android.content", "BroadcastReceiver", "onReceive") } /** Gets the paramter of this method that holds the received `Intent`. */ @@ -30,7 +30,7 @@ private class VerifiedIntentConfig extends DataFlow::Configuration { } } -/** An `onRecieve` method that doesn't verify the action of the intent it recieves. */ +/** An `onReceive` method that doesn't verify the action of the intent it recieves. */ class UnverifiedOnReceiveMethod extends OnReceiveMethod { UnverifiedOnReceiveMethod() { not any(VerifiedIntentConfig c).hasFlow(DataFlow::parameterNode(this.getIntentParameter()), _) @@ -74,7 +74,7 @@ class SystemActionName extends Top { string getName() { result = name } } -/** A call to `Context.registerReciever` */ +/** A call to `Context.registerReceiver` */ private class RegisterReceiverCall extends MethodAccess { RegisterReceiverCall() { this.getMethod() @@ -89,7 +89,7 @@ private class RegisterReceiverCall extends MethodAccess { Expr getFilterArgument() { result = this.getArgument(1) } } -/** A configuration to detect uses of `registerReciever` with system intent actions. */ +/** A configuration to detect uses of `registerReceiver` with system intent actions. */ private class RegisterSystemActionConfig extends DataFlow::Configuration { RegisterSystemActionConfig() { this = "RegisterSystemActionConfig" } @@ -121,7 +121,7 @@ private class RegisterSystemActionConfig extends DataFlow::Configuration { } /** Holds if `rrc` registers a reciever `orm` to recieve the system action `sa` that doesn't verifiy intents it recieves. */ -predicate registeredUnverifiedSystemReciever( +predicate registeredUnverifiedSystemReceiver( RegisterReceiverCall rrc, UnverifiedOnReceiveMethod orm, SystemActionName sa ) { exists(RegisterSystemActionConfig conf, ConstructorCall cc | @@ -132,7 +132,7 @@ predicate registeredUnverifiedSystemReciever( } /** Holds if the XML element `rec` declares a reciever `orm` to recieve the system action named `sa` that doesn't verifiy intents it recieves. */ -predicate xmlUnverifiedSystemReciever( +predicate xmlUnverifiedSystemReceiver( XMLElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa ) { exists(XMLElement filter, XMLElement action, Class ormty | @@ -148,7 +148,7 @@ predicate xmlUnverifiedSystemReciever( } /** Holds if `reg` registers (either explicitly or through XML) a reciever `orm` to recieve the system action named `sa` that doesn't verify intents it recieves. */ -predicate unverifiedSystemReciever(Top reg, Method orm, SystemActionName sa) { - registeredUnverifiedSystemReciever(reg, orm, sa) or - xmlUnverifiedSystemReciever(reg, orm, sa) +predicate unverifiedSystemReceiver(Top reg, Method orm, SystemActionName sa) { + registeredUnverifiedSystemReceiver(reg, orm, sa) or + xmlUnverifiedSystemReceiver(reg, orm, sa) } diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql index 249da869250..867f2733954 100644 --- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql @@ -13,6 +13,6 @@ import java import semmle.code.java.security.ImproperIntentVerificationQuery from Top reg, Method orm, SystemActionName sa -where unverifiedSystemReciever(reg, orm, sa) +where unverifiedSystemReceiver(reg, orm, sa) select orm, "This reciever doesn't verify intents it recieves, and is registered $@ to recieve $@.", reg, "here", sa, "the system action " + sa.getName() From 4aed1a1e235c737a09ed87becef3ba9222412af3 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 22 Apr 2022 16:41:01 +0100 Subject: [PATCH 026/465] Add test cases; fix handling of recievers declared through xml --- .../ImproperIntentVerificationQuery.qll | 11 +++++-- .../security/CWE-925/AndroidManifest.xml | 9 ++++++ .../security/CWE-925/BootReceiverXml.java | 13 ++++++++ .../ImproperIntentVerification.expected | 0 .../CWE-925/ImproperIntentVerification.ql | 18 +++++++++++ .../ImproperIntentVerificationTest.java | 31 +++++++++++++++++++ .../test/query-tests/security/CWE-925/options | 1 + 7 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 java/ql/test/query-tests/security/CWE-925/AndroidManifest.xml create mode 100644 java/ql/test/query-tests/security/CWE-925/BootReceiverXml.java create mode 100644 java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected create mode 100644 java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql create mode 100644 java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java create mode 100644 java/ql/test/query-tests/security/CWE-925/options diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll index e8ed1f17b42..9004414664a 100644 --- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -72,6 +72,11 @@ class SystemActionName extends Top { /** Gets the name of the system intent that this expression or attriute represents. */ string getName() { result = name } + + override string toString() { + result = + [this.(StringLiteral).toString(), this.(FieldRead).toString(), this.(XMLAttribute).toString()] + } } /** A call to `Context.registerReceiver` */ @@ -140,10 +145,10 @@ predicate xmlUnverifiedSystemReceiver( filter.hasName("intent-filter") and action.hasName("action") and filter = rec.getAChild() and - action = rec.getAChild() and + action = filter.getAChild() and ormty = orm.getDeclaringType() and - rec.getAttribute("android:name").getValue() = ["." + ormty.getName(), ormty.getQualifiedName()] and - action.getAttribute("android:name") = sa + rec.getAttribute("name").getValue() = ["." + ormty.getName(), ormty.getQualifiedName()] and + action.getAttribute("name") = sa ) } diff --git a/java/ql/test/query-tests/security/CWE-925/AndroidManifest.xml b/java/ql/test/query-tests/security/CWE-925/AndroidManifest.xml new file mode 100644 index 00000000000..f9e11a1ee81 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-925/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-925/BootReceiverXml.java b/java/ql/test/query-tests/security/CWE-925/BootReceiverXml.java new file mode 100644 index 00000000000..3a9f8498396 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-925/BootReceiverXml.java @@ -0,0 +1,13 @@ +package test; +import android.content.Intent; +import android.content.Context; +import android.content.BroadcastReceiver; + +class BootReceiverXml extends BroadcastReceiver { + void doStuff(Intent intent) {} + + @Override + public void onReceive(Context ctx, Intent intent) { // $hasResult + doStuff(intent); + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql new file mode 100644 index 00000000000..30ced62b2ed --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerification.ql @@ -0,0 +1,18 @@ +import java +import semmle.code.java.security.ImproperIntentVerificationQuery +import TestUtilities.InlineExpectationsTest + +class HasFlowTest extends InlineExpectationsTest { + HasFlowTest() { this = "HasFlowTest" } + + override string getARelevantTag() { result = "hasResult" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasResult" and + exists(Method orm | unverifiedSystemReceiver(_, orm, _) | + orm.getLocation() = location and + element = orm.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java new file mode 100644 index 00000000000..736410eb9f0 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java @@ -0,0 +1,31 @@ +package test; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.Context; +import android.content.BroadcastReceiver; + +class ImproperIntentVerificationTest { + static void doStuff(Intent intent) {} + + class ShutdownBroadcastReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context ctx, Intent intent) { // $hasResult + doStuff(intent); + } + } + + class ShutdownBroadcastReceiverSafe extends BroadcastReceiver { + @Override + public void onReceive(Context ctx, Intent intent) { + if (!intent.getAction().equals(Intent.ACTION_SHUTDOWN)) { + return; + } + doStuff(intent); + } + } + + void test(Context c) { + c.registerReceiver(new ShutdownBroadcastReceiver(), new IntentFilter(Intent.ACTION_SHUTDOWN)); + c.registerReceiver(new ShutdownBroadcastReceiverSafe(), new IntentFilter(Intent.ACTION_SHUTDOWN)); + } +} \ No newline at end of file diff --git a/java/ql/test/query-tests/security/CWE-925/options b/java/ql/test/query-tests/security/CWE-925/options new file mode 100644 index 00000000000..5a47a1d8fd3 --- /dev/null +++ b/java/ql/test/query-tests/security/CWE-925/options @@ -0,0 +1 @@ +// semmle-extractor-options: --javac-args -cp ${testdir}/../../../stubs/google-android-9.0.0 \ No newline at end of file From 8e2e8cc77feba695d92465f64e1efcee2c94b698 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 27 Apr 2022 16:04:06 +0100 Subject: [PATCH 027/465] Add qhelp --- java/ql/src/Security/CWE/CWE-925/Bad.java | 13 +++++++ java/ql/src/Security/CWE/CWE-925/Good.java | 16 ++++++++ .../CWE-925/ImproperIntentVerification.qhelp | 39 +++++++++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 java/ql/src/Security/CWE/CWE-925/Bad.java create mode 100644 java/ql/src/Security/CWE/CWE-925/Good.java create mode 100644 java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp diff --git a/java/ql/src/Security/CWE/CWE-925/Bad.java b/java/ql/src/Security/CWE/CWE-925/Bad.java new file mode 100644 index 00000000000..a2703d83cf4 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-925/Bad.java @@ -0,0 +1,13 @@ +... +IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN); +BroadcastReceiver sReceiver = new ShutDownReceiver(); +context.registerReceiver(sReceiver, filter); +... + +public class ShutdownReceiver extends BroadcastReceiver { + @Override + public void onReceive(final Context context, final Intent intent) { + mainActivity.saveLocalData(); + mainActivity.stopActivity(); + } +} \ No newline at end of file diff --git a/java/ql/src/Security/CWE/CWE-925/Good.java b/java/ql/src/Security/CWE/CWE-925/Good.java new file mode 100644 index 00000000000..3830b8c4bc3 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-925/Good.java @@ -0,0 +1,16 @@ +... +IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN); +BroadcastReceiver sReceiver = new ShutDownReceiver(); +context.registerReceiver(sReceiver, filter); +... + +public class ShutdownReceiver extends BroadcastReceiver { + @Override + public void onReceive(final Context context, final Intent intent) { + if (!intent.getAction().equals(Intent.ACTION_SHUTDOWN)) { + return; + } + mainActivity.saveLocalData(); + mainActivity.stopActivity(); + } +} \ No newline at end of file diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp new file mode 100644 index 00000000000..d4218c228fb --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp @@ -0,0 +1,39 @@ + + + + + +

+When an android application uses a BroadcastReciever to receive Intents, +it is also able to receive explicit Intents that are sent drctly to it, egardless of its filter. + +Certain intent actions are only able to be sent by the operating system, not third-party applications. +However, a BroadcastReceiver that is registered to recieve system intents is still able to recieve +other intents from a third-party application, so it should check that the intent received has the expected action. +Otherwise, a third-party application could impersonate the system this way and cause unintended behaviour, such as a denial of service. +

+
+ + +

In the following code, the ShutdownReceiver initiates a shutdown procedure upon receiving an Intent, + without checking that the received action is indeed ACTION_SHUTDOWN. This allows third-party applications to + send explicit intents to this receiver to cause a denial of service.

+ +
+ + +

+In the onReceive method of a BroadcastReciever, the action of the received Intent should be checked. The following code demonstrates this. +

+ +
+ + + + + + + +
From 2fc142f41f38ece9f04109b530e309bc869b4ff0 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 27 Apr 2022 16:31:02 +0100 Subject: [PATCH 028/465] Add security severity --- java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql index 867f2733954..3790ce3bb4d 100644 --- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql @@ -3,6 +3,7 @@ * @description The Android application uses a Broadcast Receiver that receives an Intent but does not properly verify that the Intent came from an authorized source. * @kind problem * @problem.severity warning + * @security-severity 8.2 * @precision high * @id java/improper-intent-verification * @tags security From d88d216388c3d7c50ca15d75a3372c5e77bcff38 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 27 Apr 2022 16:37:58 +0100 Subject: [PATCH 029/465] Add change note --- .../src/Security/CWE/CWE-925/ImproperIntentVerification.ql | 2 +- java/ql/src/change-notes/2022-04-27-intent-verification.md | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 java/ql/src/change-notes/2022-04-27-intent-verification.md diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql index 3790ce3bb4d..222e8ada5be 100644 --- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql @@ -1,5 +1,5 @@ /** - * @name Improper Verification of Intent by Broadcast Reciever + * @name Improper Verification of Intent by Broadcast Receiver * @description The Android application uses a Broadcast Receiver that receives an Intent but does not properly verify that the Intent came from an authorized source. * @kind problem * @problem.severity warning diff --git a/java/ql/src/change-notes/2022-04-27-intent-verification.md b/java/ql/src/change-notes/2022-04-27-intent-verification.md new file mode 100644 index 00000000000..e0ed5f5ef27 --- /dev/null +++ b/java/ql/src/change-notes/2022-04-27-intent-verification.md @@ -0,0 +1,6 @@ +--- +category: newQuery +--- +* A new query "Improper Verification of Intent by Broadcast Receiver" (`java/improper-intent-verification`) has been added. +This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received Intents when registered +to receive system intents. \ No newline at end of file From 9d048e78af6cafc735cf3a6ef6c5a4b87a1d1237 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 28 Apr 2022 12:45:20 +0100 Subject: [PATCH 030/465] Apply suggestions from code review - fix typos/style, make things private Co-authored-by: Tony Torralba --- .../security/ImproperIntentVerificationQuery.qll | 16 ++++++++-------- java/ql/src/Security/CWE/CWE-925/Bad.java | 4 ++-- java/ql/src/Security/CWE/CWE-925/Good.java | 4 ++-- .../CWE/CWE-925/ImproperIntentVerification.qhelp | 10 +++++----- .../2022-04-27-intent-verification.md | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll index 9004414664a..82885a65807 100644 --- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -10,7 +10,7 @@ private class OnReceiveMethod extends Method { .hasQualifiedName("android.content", "BroadcastReceiver", "onReceive") } - /** Gets the paramter of this method that holds the received `Intent`. */ + /** Gets the parameter of this method that holds the received `Intent`. */ Parameter getIntentParameter() { result = this.getParameter(1) } } @@ -30,7 +30,7 @@ private class VerifiedIntentConfig extends DataFlow::Configuration { } } -/** An `onReceive` method that doesn't verify the action of the intent it recieves. */ +/** An `onReceive` method that doesn't verify the action of the intent it receives. */ class UnverifiedOnReceiveMethod extends OnReceiveMethod { UnverifiedOnReceiveMethod() { not any(VerifiedIntentConfig c).hasFlow(DataFlow::parameterNode(this.getIntentParameter()), _) @@ -70,7 +70,7 @@ class SystemActionName extends Top { ) } - /** Gets the name of the system intent that this expression or attriute represents. */ + /** Gets the name of the system intent that this expression or attribute represents. */ string getName() { result = name } override string toString() { @@ -125,8 +125,8 @@ private class RegisterSystemActionConfig extends DataFlow::Configuration { } } -/** Holds if `rrc` registers a reciever `orm` to recieve the system action `sa` that doesn't verifiy intents it recieves. */ -predicate registeredUnverifiedSystemReceiver( +/** Holds if `rrc` registers a receiver `orm` to receive the system action `sa` that doesn't verify the intents it receives. */ +private predicate registeredUnverifiedSystemReceiver( RegisterReceiverCall rrc, UnverifiedOnReceiveMethod orm, SystemActionName sa ) { exists(RegisterSystemActionConfig conf, ConstructorCall cc | @@ -136,8 +136,8 @@ predicate registeredUnverifiedSystemReceiver( ) } -/** Holds if the XML element `rec` declares a reciever `orm` to recieve the system action named `sa` that doesn't verifiy intents it recieves. */ -predicate xmlUnverifiedSystemReceiver( +/** Holds if the XML element `rec` declares a receiver `orm` to receive the system action named `sa` that doesn't verify intents it receives. */ +private predicate xmlUnverifiedSystemReceiver( XMLElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa ) { exists(XMLElement filter, XMLElement action, Class ormty | @@ -152,7 +152,7 @@ predicate xmlUnverifiedSystemReceiver( ) } -/** Holds if `reg` registers (either explicitly or through XML) a reciever `orm` to recieve the system action named `sa` that doesn't verify intents it recieves. */ +/** Holds if `reg` registers (either explicitly or through XML) a receiver `orm` to receive the system action named `sa` that doesn't verify the intents it receives. */ predicate unverifiedSystemReceiver(Top reg, Method orm, SystemActionName sa) { registeredUnverifiedSystemReceiver(reg, orm, sa) or xmlUnverifiedSystemReceiver(reg, orm, sa) diff --git a/java/ql/src/Security/CWE/CWE-925/Bad.java b/java/ql/src/Security/CWE/CWE-925/Bad.java index a2703d83cf4..52a5d0c29f8 100644 --- a/java/ql/src/Security/CWE/CWE-925/Bad.java +++ b/java/ql/src/Security/CWE/CWE-925/Bad.java @@ -1,8 +1,8 @@ -... +// ... IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN); BroadcastReceiver sReceiver = new ShutDownReceiver(); context.registerReceiver(sReceiver, filter); -... +// ... public class ShutdownReceiver extends BroadcastReceiver { @Override diff --git a/java/ql/src/Security/CWE/CWE-925/Good.java b/java/ql/src/Security/CWE/CWE-925/Good.java index 3830b8c4bc3..6f3a718487a 100644 --- a/java/ql/src/Security/CWE/CWE-925/Good.java +++ b/java/ql/src/Security/CWE/CWE-925/Good.java @@ -1,8 +1,8 @@ -... +// ... IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN); BroadcastReceiver sReceiver = new ShutDownReceiver(); context.registerReceiver(sReceiver, filter); -... +// ... public class ShutdownReceiver extends BroadcastReceiver { @Override diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp index d4218c228fb..2fd06e9817b 100644 --- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp @@ -6,18 +6,18 @@

-When an android application uses a BroadcastReciever to receive Intents, -it is also able to receive explicit Intents that are sent drctly to it, egardless of its filter. +When an android application uses a BroadcastReciever to receive intents, +it is also able to receive explicit intents that are sent directly to it, regardless of its filter. Certain intent actions are only able to be sent by the operating system, not third-party applications. -However, a BroadcastReceiver that is registered to recieve system intents is still able to recieve +However, a BroadcastReceiver that is registered to receive system intents is still able to receive other intents from a third-party application, so it should check that the intent received has the expected action. -Otherwise, a third-party application could impersonate the system this way and cause unintended behaviour, such as a denial of service. +Otherwise, a third-party application could impersonate the system this way and cause unintended behavior, such as a denial of service.

-

In the following code, the ShutdownReceiver initiates a shutdown procedure upon receiving an Intent, +

In the following code, the ShutdownReceiver initiates a shutdown procedure upon receiving an intent, without checking that the received action is indeed ACTION_SHUTDOWN. This allows third-party applications to send explicit intents to this receiver to cause a denial of service.

diff --git a/java/ql/src/change-notes/2022-04-27-intent-verification.md b/java/ql/src/change-notes/2022-04-27-intent-verification.md index e0ed5f5ef27..143b0bcd39b 100644 --- a/java/ql/src/change-notes/2022-04-27-intent-verification.md +++ b/java/ql/src/change-notes/2022-04-27-intent-verification.md @@ -2,5 +2,5 @@ category: newQuery --- * A new query "Improper Verification of Intent by Broadcast Receiver" (`java/improper-intent-verification`) has been added. -This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received Intents when registered +This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered to receive system intents. \ No newline at end of file From 320c671b73dcb6a30428e6292a925fa586464da8 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 28 Apr 2022 14:14:02 +0100 Subject: [PATCH 031/465] Adress reveiw comments - make use of existing ql libraries --- .../ImproperIntentVerificationQuery.qll | 31 +++++++------------ .../CWE/CWE-925/ImproperIntentVerification.ql | 2 +- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll index 82885a65807..f161c67cfbb 100644 --- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -2,13 +2,12 @@ import java import semmle.code.java.dataflow.DataFlow +import semmle.code.xml.AndroidManifest +import semmle.code.java.frameworks.android.Intent /** An `onReceive` method of a `BroadcastReceiver` */ private class OnReceiveMethod extends Method { - OnReceiveMethod() { - this.getASourceOverriddenMethod*() - .hasQualifiedName("android.content", "BroadcastReceiver", "onReceive") - } + OnReceiveMethod() { this.getASourceOverriddenMethod*() instanceof AndroidReceiveIntentMethod } /** Gets the parameter of this method that holds the received `Intent`. */ Parameter getIntentParameter() { result = this.getParameter(1) } @@ -31,7 +30,7 @@ private class VerifiedIntentConfig extends DataFlow::Configuration { } /** An `onReceive` method that doesn't verify the action of the intent it receives. */ -class UnverifiedOnReceiveMethod extends OnReceiveMethod { +private class UnverifiedOnReceiveMethod extends OnReceiveMethod { UnverifiedOnReceiveMethod() { not any(VerifiedIntentConfig c).hasFlow(DataFlow::parameterNode(this.getIntentParameter()), _) } @@ -62,21 +61,18 @@ class SystemActionName extends Top { SystemActionName() { name = getASystemActionName() and ( - this.(StringLiteral).getValue() = "android.intent.action." + name + this.(CompileTimeConstantExpr).getStringValue() = "android.intent.action." + name or this.(FieldRead).getField().hasQualifiedName("android.content", "Intent", "ACTION_" + name) or - this.(XMLAttribute).getValue() = "android.intent.action." + name + this.(AndroidActionXmlElement).getActionName() = "android.intent.action." + name ) } /** Gets the name of the system intent that this expression or attribute represents. */ string getName() { result = name } - override string toString() { - result = - [this.(StringLiteral).toString(), this.(FieldRead).toString(), this.(XMLAttribute).toString()] - } + override string toString() { result = [this.(Expr).toString(), this.(XMLAttribute).toString()] } } /** A call to `Context.registerReceiver` */ @@ -138,17 +134,12 @@ private predicate registeredUnverifiedSystemReceiver( /** Holds if the XML element `rec` declares a receiver `orm` to receive the system action named `sa` that doesn't verify intents it receives. */ private predicate xmlUnverifiedSystemReceiver( - XMLElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa + AndroidReceiverXmlElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa ) { - exists(XMLElement filter, XMLElement action, Class ormty | - rec.hasName("receiver") and - filter.hasName("intent-filter") and - action.hasName("action") and - filter = rec.getAChild() and - action = filter.getAChild() and + exists(Class ormty | ormty = orm.getDeclaringType() and - rec.getAttribute("name").getValue() = ["." + ormty.getName(), ormty.getQualifiedName()] and - action.getAttribute("name") = sa + rec.getComponentName() = ["." + ormty.getName(), ormty.getQualifiedName()] and + rec.getAnIntentFilterElement().getAnActionElement() = sa ) } diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql index 222e8ada5be..87fcf3c659b 100644 --- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql @@ -15,5 +15,5 @@ import semmle.code.java.security.ImproperIntentVerificationQuery from Top reg, Method orm, SystemActionName sa where unverifiedSystemReceiver(reg, orm, sa) -select orm, "This reciever doesn't verify intents it recieves, and is registered $@ to recieve $@.", +select orm, "This reciever doesn't verify intents it receives, and is registered $@ to receive $@.", reg, "here", sa, "the system action " + sa.getName() From c71586e1f8baa3e439fdf20acc763da701e9c7cc Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 31 May 2022 15:26:48 +0100 Subject: [PATCH 032/465] Remove checks for dynamically registered recievers --- .../ImproperIntentVerificationQuery.qll | 79 +------------------ .../Security/CWE/CWE-925/AndroidManifest.xml | 9 +++ java/ql/src/Security/CWE/CWE-925/Bad.java | 6 -- java/ql/src/Security/CWE/CWE-925/Good.java | 6 -- .../CWE-925/ImproperIntentVerification.qhelp | 1 + .../CWE/CWE-925/ImproperIntentVerification.ql | 2 +- .../ImproperIntentVerificationTest.java | 31 -------- 7 files changed, 15 insertions(+), 119 deletions(-) create mode 100644 java/ql/src/Security/CWE/CWE-925/AndroidManifest.xml delete mode 100644 java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll index f161c67cfbb..00a6dae69e9 100644 --- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -55,85 +55,20 @@ string getASystemActionName() { } /** An expression or XML attribute that contains the name of a system intent action. */ -class SystemActionName extends Top { +class SystemActionName extends AndroidActionXmlElement { string name; SystemActionName() { name = getASystemActionName() and - ( - this.(CompileTimeConstantExpr).getStringValue() = "android.intent.action." + name - or - this.(FieldRead).getField().hasQualifiedName("android.content", "Intent", "ACTION_" + name) - or - this.(AndroidActionXmlElement).getActionName() = "android.intent.action." + name - ) + this.getActionName() = "android.intent.action." + name } /** Gets the name of the system intent that this expression or attribute represents. */ - string getName() { result = name } - - override string toString() { result = [this.(Expr).toString(), this.(XMLAttribute).toString()] } -} - -/** A call to `Context.registerReceiver` */ -private class RegisterReceiverCall extends MethodAccess { - RegisterReceiverCall() { - this.getMethod() - .getASourceOverriddenMethod*() - .hasQualifiedName("android.content", "Context", "registerReceiver") - } - - /** Gets the `BroadcastReceiver` argument to this call. */ - Expr getReceiverArgument() { result = this.getArgument(0) } - - /** Gets the `IntentFilter` argument to this call. */ - Expr getFilterArgument() { result = this.getArgument(1) } -} - -/** A configuration to detect uses of `registerReceiver` with system intent actions. */ -private class RegisterSystemActionConfig extends DataFlow::Configuration { - RegisterSystemActionConfig() { this = "RegisterSystemActionConfig" } - - override predicate isSource(DataFlow::Node node) { node.asExpr() instanceof SystemActionName } - - override predicate isSink(DataFlow::Node node) { - exists(RegisterReceiverCall ma | node.asExpr() = ma.getFilterArgument()) - } - - override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(ConstructorCall cc | - cc.getConstructedType().hasQualifiedName("android.content", "IntentFilter") and - node1.asExpr() = cc.getArgument(0) and - node2.asExpr() = cc - ) - or - exists(MethodAccess ma | - ma.getMethod().hasQualifiedName("android.content", "IntentFilter", "create") and - node1.asExpr() = ma.getArgument(0) and - node2.asExpr() = ma - ) - or - exists(MethodAccess ma | - ma.getMethod().hasQualifiedName("android.content", "IntentFilter", "addAction") and - node1.asExpr() = ma.getArgument(0) and - node2.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = ma.getQualifier() - ) - } -} - -/** Holds if `rrc` registers a receiver `orm` to receive the system action `sa` that doesn't verify the intents it receives. */ -private predicate registeredUnverifiedSystemReceiver( - RegisterReceiverCall rrc, UnverifiedOnReceiveMethod orm, SystemActionName sa -) { - exists(RegisterSystemActionConfig conf, ConstructorCall cc | - conf.hasFlow(DataFlow::exprNode(sa), DataFlow::exprNode(rrc.getFilterArgument())) and - cc.getConstructedType() = orm.getDeclaringType() and - DataFlow::localExprFlow(cc, rrc.getReceiverArgument()) - ) + string getSystemActionName() { result = name } } /** Holds if the XML element `rec` declares a receiver `orm` to receive the system action named `sa` that doesn't verify intents it receives. */ -private predicate xmlUnverifiedSystemReceiver( +predicate unverifiedSystemReceiver( AndroidReceiverXmlElement rec, UnverifiedOnReceiveMethod orm, SystemActionName sa ) { exists(Class ormty | @@ -142,9 +77,3 @@ private predicate xmlUnverifiedSystemReceiver( rec.getAnIntentFilterElement().getAnActionElement() = sa ) } - -/** Holds if `reg` registers (either explicitly or through XML) a receiver `orm` to receive the system action named `sa` that doesn't verify the intents it receives. */ -predicate unverifiedSystemReceiver(Top reg, Method orm, SystemActionName sa) { - registeredUnverifiedSystemReceiver(reg, orm, sa) or - xmlUnverifiedSystemReceiver(reg, orm, sa) -} diff --git a/java/ql/src/Security/CWE/CWE-925/AndroidManifest.xml b/java/ql/src/Security/CWE/CWE-925/AndroidManifest.xml new file mode 100644 index 00000000000..f9e11a1ee81 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-925/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/java/ql/src/Security/CWE/CWE-925/Bad.java b/java/ql/src/Security/CWE/CWE-925/Bad.java index 52a5d0c29f8..376805f824e 100644 --- a/java/ql/src/Security/CWE/CWE-925/Bad.java +++ b/java/ql/src/Security/CWE/CWE-925/Bad.java @@ -1,9 +1,3 @@ -// ... -IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN); -BroadcastReceiver sReceiver = new ShutDownReceiver(); -context.registerReceiver(sReceiver, filter); -// ... - public class ShutdownReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, final Intent intent) { diff --git a/java/ql/src/Security/CWE/CWE-925/Good.java b/java/ql/src/Security/CWE/CWE-925/Good.java index 6f3a718487a..b6ad1c43193 100644 --- a/java/ql/src/Security/CWE/CWE-925/Good.java +++ b/java/ql/src/Security/CWE/CWE-925/Good.java @@ -1,9 +1,3 @@ -// ... -IntentFilter filter = new IntentFilter(Intent.ACTION_SHUTDOWN); -BroadcastReceiver sReceiver = new ShutDownReceiver(); -context.registerReceiver(sReceiver, filter); -// ... - public class ShutdownReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, final Intent intent) { diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp index 2fd06e9817b..edc9b6269f9 100644 --- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp @@ -21,6 +21,7 @@ Otherwise, a third-party application could impersonate the system this way and c without checking that the received action is indeed ACTION_SHUTDOWN. This allows third-party applications to send explicit intents to this receiver to cause a denial of service.

+
diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql index 87fcf3c659b..fb49d00cafa 100644 --- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql @@ -13,7 +13,7 @@ import java import semmle.code.java.security.ImproperIntentVerificationQuery -from Top reg, Method orm, SystemActionName sa +from AndroidReceiverXmlElement reg, Method orm, SystemActionName sa where unverifiedSystemReceiver(reg, orm, sa) select orm, "This reciever doesn't verify intents it receives, and is registered $@ to receive $@.", reg, "here", sa, "the system action " + sa.getName() diff --git a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java b/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java deleted file mode 100644 index 736410eb9f0..00000000000 --- a/java/ql/test/query-tests/security/CWE-925/ImproperIntentVerificationTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package test; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.Context; -import android.content.BroadcastReceiver; - -class ImproperIntentVerificationTest { - static void doStuff(Intent intent) {} - - class ShutdownBroadcastReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context ctx, Intent intent) { // $hasResult - doStuff(intent); - } - } - - class ShutdownBroadcastReceiverSafe extends BroadcastReceiver { - @Override - public void onReceive(Context ctx, Intent intent) { - if (!intent.getAction().equals(Intent.ACTION_SHUTDOWN)) { - return; - } - doStuff(intent); - } - } - - void test(Context c) { - c.registerReceiver(new ShutdownBroadcastReceiver(), new IntentFilter(Intent.ACTION_SHUTDOWN)); - c.registerReceiver(new ShutdownBroadcastReceiverSafe(), new IntentFilter(Intent.ACTION_SHUTDOWN)); - } -} \ No newline at end of file From a6736a99e4059df26f0be42fd5b700009c4058f8 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 14 Jun 2022 14:55:37 +0100 Subject: [PATCH 033/465] Apply doc review suggestions - fix typos and capitilisation; reword description. --- .../Security/CWE/CWE-925/ImproperIntentVerification.qhelp | 6 +++--- .../src/Security/CWE/CWE-925/ImproperIntentVerification.ql | 4 ++-- java/ql/src/change-notes/2022-04-27-intent-verification.md | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp index edc9b6269f9..e489e411379 100644 --- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.qhelp @@ -6,13 +6,13 @@

-When an android application uses a BroadcastReciever to receive intents, +When an Android application uses a BroadcastReceiver to receive intents, it is also able to receive explicit intents that are sent directly to it, regardless of its filter. Certain intent actions are only able to be sent by the operating system, not third-party applications. However, a BroadcastReceiver that is registered to receive system intents is still able to receive -other intents from a third-party application, so it should check that the intent received has the expected action. -Otherwise, a third-party application could impersonate the system this way and cause unintended behavior, such as a denial of service. +intents from a third-party application, so it should check that the intent received has the expected action. +Otherwise, a third-party application could impersonate the system this way to cause unintended behavior, such as a denial of service.

diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql index fb49d00cafa..1314f91a2bd 100644 --- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql @@ -1,6 +1,6 @@ /** - * @name Improper Verification of Intent by Broadcast Receiver - * @description The Android application uses a Broadcast Receiver that receives an Intent but does not properly verify that the Intent came from an authorized source. + * @name Improper verification of intent by broadcast receiver + * @description A broadcast reciever that does not verify intents it recieves may be susceptible to unintended behaviour by third party applications sending it explicit intents. * @kind problem * @problem.severity warning * @security-severity 8.2 diff --git a/java/ql/src/change-notes/2022-04-27-intent-verification.md b/java/ql/src/change-notes/2022-04-27-intent-verification.md index 143b0bcd39b..e5e0e287753 100644 --- a/java/ql/src/change-notes/2022-04-27-intent-verification.md +++ b/java/ql/src/change-notes/2022-04-27-intent-verification.md @@ -1,6 +1,6 @@ --- category: newQuery --- -* A new query "Improper Verification of Intent by Broadcast Receiver" (`java/improper-intent-verification`) has been added. +* A new query "Improper verification of intent by broadcast receiver" (`java/improper-intent-verification`) has been added. This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered to receive system intents. \ No newline at end of file From f46dd8cc85d5202527b3135b4437cbb7446f7319 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 14 Jun 2022 15:34:08 +0100 Subject: [PATCH 034/465] Fix misspellings --- java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql index 1314f91a2bd..51c54e288ac 100644 --- a/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql +++ b/java/ql/src/Security/CWE/CWE-925/ImproperIntentVerification.ql @@ -1,6 +1,6 @@ /** * @name Improper verification of intent by broadcast receiver - * @description A broadcast reciever that does not verify intents it recieves may be susceptible to unintended behaviour by third party applications sending it explicit intents. + * @description A broadcast receiver that does not verify intents it receives may be susceptible to unintended behavior by third party applications sending it explicit intents. * @kind problem * @problem.severity warning * @security-severity 8.2 From f4ce382b7da04c17a3215d95b8a2cc6d3403c42e Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Wed, 15 Jun 2022 12:40:14 +0200 Subject: [PATCH 035/465] python: update test expectations --- .../Security/CWE-022-TarSlip/TarSlip.expected | 61 +++++++++++-------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected b/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected index edcdaf88e48..2ddfe7143d0 100644 --- a/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected +++ b/python/ql/test/query-tests/Security/CWE-022-TarSlip/TarSlip.expected @@ -1,29 +1,36 @@ edges -| tarslip.py:12:7:12:39 | tarfile.open | tarslip.py:13:1:13:3 | tarfile.open | -| tarslip.py:12:7:12:39 | tarfile.open | tarslip.py:13:1:13:3 | tarfile.open | -| tarslip.py:16:7:16:39 | tarfile.open | tarslip.py:17:14:17:16 | tarfile.open | -| tarslip.py:16:7:16:39 | tarfile.open | tarslip.py:17:14:17:16 | tarfile.open | -| tarslip.py:17:1:17:17 | tarfile.entry | tarslip.py:18:17:18:21 | tarfile.entry | -| tarslip.py:17:1:17:17 | tarfile.entry | tarslip.py:18:17:18:21 | tarfile.entry | -| tarslip.py:17:14:17:16 | tarfile.open | tarslip.py:17:1:17:17 | tarfile.entry | -| tarslip.py:17:14:17:16 | tarfile.open | tarslip.py:17:1:17:17 | tarfile.entry | -| tarslip.py:33:7:33:39 | tarfile.open | tarslip.py:34:14:34:16 | tarfile.open | -| tarslip.py:33:7:33:39 | tarfile.open | tarslip.py:34:14:34:16 | tarfile.open | -| tarslip.py:34:1:34:17 | tarfile.entry | tarslip.py:37:17:37:21 | tarfile.entry | -| tarslip.py:34:1:34:17 | tarfile.entry | tarslip.py:37:17:37:21 | tarfile.entry | -| tarslip.py:34:14:34:16 | tarfile.open | tarslip.py:34:1:34:17 | tarfile.entry | -| tarslip.py:34:14:34:16 | tarfile.open | tarslip.py:34:1:34:17 | tarfile.entry | -| tarslip.py:40:7:40:39 | tarfile.open | tarslip.py:41:24:41:26 | tarfile.open | -| tarslip.py:40:7:40:39 | tarfile.open | tarslip.py:41:24:41:26 | tarfile.open | -| tarslip.py:56:7:56:39 | tarfile.open | tarslip.py:57:14:57:16 | tarfile.open | -| tarslip.py:56:7:56:39 | tarfile.open | tarslip.py:57:14:57:16 | tarfile.open | -| tarslip.py:57:1:57:17 | tarfile.entry | tarslip.py:59:21:59:25 | tarfile.entry | -| tarslip.py:57:1:57:17 | tarfile.entry | tarslip.py:59:21:59:25 | tarfile.entry | -| tarslip.py:57:14:57:16 | tarfile.open | tarslip.py:57:1:57:17 | tarfile.entry | -| tarslip.py:57:14:57:16 | tarfile.open | tarslip.py:57:1:57:17 | tarfile.entry | +| tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | tarslip.py:13:1:13:3 | ControlFlowNode for tar | +| tarslip.py:16:7:16:39 | ControlFlowNode for Attribute() | tarslip.py:17:5:17:9 | GSSA Variable entry | +| tarslip.py:17:5:17:9 | GSSA Variable entry | tarslip.py:18:17:18:21 | ControlFlowNode for entry | +| tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | tarslip.py:34:5:34:9 | GSSA Variable entry | +| tarslip.py:34:5:34:9 | GSSA Variable entry | tarslip.py:37:17:37:21 | ControlFlowNode for entry | +| tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | tarslip.py:41:24:41:26 | ControlFlowNode for tar | +| tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | tarslip.py:57:5:57:9 | GSSA Variable entry | +| tarslip.py:57:5:57:9 | GSSA Variable entry | tarslip.py:59:21:59:25 | ControlFlowNode for entry | +| tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | tarslip.py:80:5:80:9 | GSSA Variable entry | +| tarslip.py:80:5:80:9 | GSSA Variable entry | tarslip.py:82:21:82:25 | ControlFlowNode for entry | +nodes +| tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarslip.py:13:1:13:3 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| tarslip.py:16:7:16:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarslip.py:17:5:17:9 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| tarslip.py:18:17:18:21 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarslip.py:34:5:34:9 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| tarslip.py:37:17:37:21 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarslip.py:41:24:41:26 | ControlFlowNode for tar | semmle.label | ControlFlowNode for tar | +| tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarslip.py:57:5:57:9 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| tarslip.py:59:21:59:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +| tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | semmle.label | ControlFlowNode for Attribute() | +| tarslip.py:80:5:80:9 | GSSA Variable entry | semmle.label | GSSA Variable entry | +| tarslip.py:82:21:82:25 | ControlFlowNode for entry | semmle.label | ControlFlowNode for entry | +subpaths #select -| tarslip.py:13:1:13:3 | tar | tarslip.py:12:7:12:39 | tarfile.open | tarslip.py:13:1:13:3 | tarfile.open | Extraction of tarfile from $@ | tarslip.py:12:7:12:39 | Attribute() | a potentially untrusted source | -| tarslip.py:18:17:18:21 | entry | tarslip.py:16:7:16:39 | tarfile.open | tarslip.py:18:17:18:21 | tarfile.entry | Extraction of tarfile from $@ | tarslip.py:16:7:16:39 | Attribute() | a potentially untrusted source | -| tarslip.py:37:17:37:21 | entry | tarslip.py:33:7:33:39 | tarfile.open | tarslip.py:37:17:37:21 | tarfile.entry | Extraction of tarfile from $@ | tarslip.py:33:7:33:39 | Attribute() | a potentially untrusted source | -| tarslip.py:41:24:41:26 | tar | tarslip.py:40:7:40:39 | tarfile.open | tarslip.py:41:24:41:26 | tarfile.open | Extraction of tarfile from $@ | tarslip.py:40:7:40:39 | Attribute() | a potentially untrusted source | -| tarslip.py:59:21:59:25 | entry | tarslip.py:56:7:56:39 | tarfile.open | tarslip.py:59:21:59:25 | tarfile.entry | Extraction of tarfile from $@ | tarslip.py:56:7:56:39 | Attribute() | a potentially untrusted source | +| tarslip.py:13:1:13:3 | ControlFlowNode for tar | tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | tarslip.py:13:1:13:3 | ControlFlowNode for tar | Extraction of tarfile from $@ | tarslip.py:12:7:12:39 | ControlFlowNode for Attribute() | a potentially untrusted source | +| tarslip.py:18:17:18:21 | ControlFlowNode for entry | tarslip.py:16:7:16:39 | ControlFlowNode for Attribute() | tarslip.py:18:17:18:21 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:16:7:16:39 | ControlFlowNode for Attribute() | a potentially untrusted source | +| tarslip.py:37:17:37:21 | ControlFlowNode for entry | tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | tarslip.py:37:17:37:21 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:33:7:33:39 | ControlFlowNode for Attribute() | a potentially untrusted source | +| tarslip.py:41:24:41:26 | ControlFlowNode for tar | tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | tarslip.py:41:24:41:26 | ControlFlowNode for tar | Extraction of tarfile from $@ | tarslip.py:40:7:40:39 | ControlFlowNode for Attribute() | a potentially untrusted source | +| tarslip.py:59:21:59:25 | ControlFlowNode for entry | tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | tarslip.py:59:21:59:25 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:56:7:56:39 | ControlFlowNode for Attribute() | a potentially untrusted source | +| tarslip.py:82:21:82:25 | ControlFlowNode for entry | tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | tarslip.py:82:21:82:25 | ControlFlowNode for entry | Extraction of tarfile from $@ | tarslip.py:79:7:79:39 | ControlFlowNode for Attribute() | a potentially untrusted source | From 40b61fa85fef5e758cba013c68b756177b0af98c Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Wed, 15 Jun 2022 14:07:35 +0200 Subject: [PATCH 036/465] python: fix qldocs and clean-up dead code --- .../dataflow/TarSlipCustomizations.qll | 24 ++++++------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll index 7393b129f37..21d7cc03e74 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll @@ -90,7 +90,7 @@ module TarSlip { } } - /* Members argument to extract method */ + /** The `members` argument `extractall` is considered a sink. */ class ExtractMembersSink extends Sink { ExtractMembersSink() { exists(DataFlow::CallCfgNode call | @@ -105,6 +105,10 @@ module TarSlip { } } + /** + * For a "check-like function name" (matching `"%path"`), `checkPath`, + * and a call `checkPath(info.name)`, the variable `info` is considered checked. + */ class TarFileInfoSanitizer extends SanitizerGuard { ControlFlowNode tarInfo; @@ -117,9 +121,9 @@ module TarSlip { attr.getObject() = tarInfo | // Assume that any test with "path" in it is a sanitizer - call.getAChild*().(AttrNode).getName().matches("%path") + call.getAChild*().(AttrNode).getName().toLowerCase().matches("%path") or - call.getAChild*().(NameNode).getId().matches("%path") + call.getAChild*().(NameNode).getId().toLowerCase().matches("%path") ) } @@ -127,19 +131,5 @@ module TarSlip { checked = tarInfo and branch in [true, false] } - - DataFlow::ExprNode shouldGuard() { - tarInfo.dominates(result.asCfgNode()) and - // exists(EssaDefinition def | - // def.getAUse() = tarInfo and - // def.getAUse() = result.asCfgNode() - // ) and - exists(SsaSourceVariable v | - v.getAUse() = tarInfo and - v.getAUse() = result.asCfgNode() - ) - } } - - DataFlow::ExprNode getAGuardedNode(TarFileInfoSanitizer tfis) { result = tfis.getAGuardedNode() } } From 0608d4d2f991180cff54881d08296938eee9f907 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Wed, 15 Jun 2022 14:18:29 +0200 Subject: [PATCH 037/465] python: fix alerts Also, remove the `toLowerCase` again, as I do not know what effect it will have. --- .../security/dataflow/TarSlipCustomizations.qll | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll index 21d7cc03e74..d767f90c5c6 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll @@ -51,6 +51,8 @@ module TarSlip { } /** + * A sanitizer based on file name. This beacuse we extract the standard library. + * * For efficiency we don't want to track the flow of taint * around the tarfile module. */ @@ -59,6 +61,8 @@ module TarSlip { } /** + * A sink capturing method calls to `extractall`. + * * For a call to `file.extractall` without arguments, `file` is considered a sink. */ class ExtractAllSink extends Sink { @@ -106,7 +110,9 @@ module TarSlip { } /** - * For a "check-like function name" (matching `"%path"`), `checkPath`, + * A sanitizer guard heuristic. + * + * For a "check-like function-name" (matching `"%path"`), `checkPath`, * and a call `checkPath(info.name)`, the variable `info` is considered checked. */ class TarFileInfoSanitizer extends SanitizerGuard { @@ -121,9 +127,9 @@ module TarSlip { attr.getObject() = tarInfo | // Assume that any test with "path" in it is a sanitizer - call.getAChild*().(AttrNode).getName().toLowerCase().matches("%path") + call.getAChild*().(AttrNode).getName().matches("%path") or - call.getAChild*().(NameNode).getId().toLowerCase().matches("%path") + call.getAChild*().(NameNode).getId().matches("%path") ) } From b993558987e3e9286e83b397a0e3b6473b6953e1 Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Wed, 15 Jun 2022 10:14:51 -0700 Subject: [PATCH 038/465] Update docs to include how to run a pack with path `scope/name@range:path` is a valid way to specify a set of queries. --- ...nalyzing-databases-with-the-codeql-cli.rst | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst index d3b04a32a0b..cac63f6d01f 100644 --- a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst @@ -135,6 +135,60 @@ pack names and use the ``--download`` flag:: The ``analyze`` command above runs the default suite from ``microsoft/coding-standards v1.0.0`` and the latest version of ``github/security-queries`` on the specified database. For further information about default suites, see ":ref:`Publishing and using CodeQL packs `". +Running a subset of queries in a CodeQL pack +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Additionally, you can include a path at the end of a pack specification to run a subset of queries inside the pack. This applies to any command that locates or runs queries within a pack. + +The complete way to specify a set of queries is in the form ``scope/name@range:path``, where: + +- ``scope/name`` is the qualified name of a CodeQL pack. +- ``range`` is a `semver range `_. +- ``path`` is a file system path to a single query, a directory containing queries, or a query suite file. + +If a ``scope/name`` is specified, the ``range`` and ``path`` are +optional. A missing ``range`` implies the latest version of the +specified pack. A missing ``path`` implies the default query suite +of the specified pack. + +The ``path`` can be one of a ``*.ql`` query file, a directory +containing one or more queries, or a ``.qls`` query suite file. If +there is no pack name specified, then a ``path`` must be provided, +and will be interpreted relative to the current working directory +of the current process. + +If a ``scope/name`` and ``path`` are specified, then the ``path`` cannot +be absolute. It is considered relative to the root of the CodeQL +pack. + +The relevant commands are: + +* `codeql database analyze <../manual/database-analyze>`__. +* `codeql database run-queries <../manual/database-run-queries>`__. +* `codeql execute queries <../manual/execute-queries>`__. +* `codeql resolve queries <../manual/resolve-queries>`__. + +For example:: + + # Analyze a database using all queries in the experimental/Security folder within the codeql/cpp-queries + # CodeQL query pack. + codeql database analyze --format=sarif-latest --output=results \ + codeql/cpp-queries:experimental/Security + + # Analyse using only the RedundantNullCheckParam.ql query in the codeql/cpp-queries CodeQL query pack. + codeql database analyze --format=sarif-latest --output=results \ + 'codeql/cpp-queries:experimental/Likely Bugs/RedundantNullCheckParam.ql' + + # Analyse using the cpp-security-and-quality.qls query suite in the codeql/cpp-queries CodeQL query pack. + codeql database analyze --format=sarif-latest --output=results \ + 'codeql/cpp-queries:codeql-suites/cpp-security-and-quality.qls' + + # Analyse using the cpp-security-and-quality.qls query suite from a version of the codeql/cpp-queries pack + # that is >= 0.0.3 and < 0.1.0 (the highest compatible version will be chosen). + # All valid semver ranges are allowed. See https://docs.npmjs.com/cli/v6/using-npm/semver#ranges + codeql database analyze --format=sarif-latest --output=results \ + 'codeql/cpp-queries@~0.0.3:codeql-suites/cpp-security-and-quality.qls' + For more information about CodeQL packs, see :doc:`About CodeQL Packs `. Running query suites From 5931ea4ab80113b66dfa5bf26df30cd80aefe102 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Wed, 15 Jun 2022 16:42:32 -0700 Subject: [PATCH 039/465] Add section on managing packs on GHES --- .../publishing-and-using-codeql-packs.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst index d28e27e10d7..0a1affb782b 100644 --- a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst +++ b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst @@ -72,3 +72,21 @@ The ``analyze`` command will run the default suite of any specified CodeQL packs :: codeql analyze / / + +Managing packs on GitHub Enterprise Server +------------------------------------------ + +By default, CodeQL will download packs from and publish packs to the GitHub.com Container registry. +You can manage packs on GitHub Enterprise Server 3.6 and later by creating a ``qlconfig.yml`` file to tell CodeQL which Container registry to use for each pack. +Create the ``~/.codeql/qlconfig.yml`` file using your preferred text editor, and add entries to specify which registry to use for each pack name pattern. +For example, the following ``qlconfig.yml`` file associates all packs with the Container registry for the GitHub Enterprise Server at ``GHE_HOSTNAME``, except packs matching ``codeql/*``, which are associated with the GitHub.com Container registry: + +.. code-block:: yaml + + registries: + - packages: '*' + url: https://containers.GHE_HOSTNAME/v2/ + - packages: 'codeql/*' + url: https://ghcr.io/v2/ + +You can now use ``codeql pack publish``, ``codeql pack download``, and ``codeql database analyze`` to manage packs on GitHub Enterprise Server. From e4462b7aacd5ea62ea3676c2f7d8603a47c7b3aa Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Thu, 16 Jun 2022 14:35:55 -0700 Subject: [PATCH 040/465] Add a section on authenticating to Container registries --- .../publishing-and-using-codeql-packs.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst index 0a1affb782b..4e7b8d452ac 100644 --- a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst +++ b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst @@ -90,3 +90,21 @@ For example, the following ``qlconfig.yml`` file associates all packs with the C url: https://ghcr.io/v2/ You can now use ``codeql pack publish``, ``codeql pack download``, and ``codeql database analyze`` to manage packs on GitHub Enterprise Server. + +Authenticating to GitHub Container registries +--------------------------------------------- + +You can download a private pack or publish a pack by authenticating to the appropriate GitHub Container registry. + +You can authenticate to the GitHub.com Container registry in two ways: + +1. Pass the ``--github-auth-stdin`` option to the CodeQL CLI, then supply a GitHub Apps token or personal access token via standard input. +2. Set the ``GITHUB_TOKEN`` environment variable to a GitHub Apps token or personal access token. + +Similarly, you can authenticate to a GHES Container registry, or authenticate to multiple registries simultaneously (for example to download or analyze private packs from multiple registries) in two ways: + +1. Pass the ``--registries-auth-stdin`` option to the CodeQL CLI, then supply a registry authentication string via standard input. +2. Set the ``CODEQL_REGISTRIES_AUTH`` environment variable to a registry authentication string. + +A registry authentication string is a comma-separated list of ``=`` pairs, where ``registry-url`` is a GitHub Container registry URL, for example ``https://containers.GHE_HOSTNAME/v2/`` and ``token`` is a GitHub Apps token or personal access token for that GitHub Container registry. +This ensures that each token is only passed to the Container registry you specify. From 4733653939b7d895c0f624086e7c8ad5d1b36652 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Thu, 16 Jun 2022 15:08:16 -0700 Subject: [PATCH 041/465] Add a note on how to install dependencies from GHES --- .../codeql-cli/creating-and-working-with-codeql-packs.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst b/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst index 6373440bcbb..e6a679c89a9 100644 --- a/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst +++ b/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst @@ -68,3 +68,11 @@ This command downloads all dependencies to the shared cache on the local disk. Note Running the ``codeql pack add`` and ``codeql pack install`` commands will generate or update the ``qlpack.lock.yml`` file. This file should be checked-in to version control. The ``qlpack.lock.yml`` file contains the precise version numbers used by the pack. + +.. pull-quote:: + + Note + + By default ``codeql pack install`` will install dependencies from the GitHub.com Container registry. + You can install dependencies from a GitHub Enterprise Server Container registry by creating a ``qlconfig.yml`` file. + For more information, see ":doc:`Publishing and using CodeQL packs `." From 8aa2602d9e24a0e2b3ebae1836630c818116f376 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Sat, 18 Jun 2022 03:09:04 +0000 Subject: [PATCH 042/465] trying to hone in on eq comparison and include? --- .../ManuallyCheckHttpVerb.ql | 56 ++++++++++--------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql index ab71ba45d46..ac34ad34088 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -1,6 +1,6 @@ /** * @name Manually checking http verb instead of using built in rails routes and protections - * @description Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. + * @description Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. * @kind problem * @problem.severity error * @security-severity 7.0 @@ -20,59 +20,63 @@ class ManuallyCheckHttpVerb extends DataFlow::CallNode { this instanceof CheckPostRequest or this instanceof CheckDeleteRequest or this instanceof CheckHeadRequest or - this.asExpr().getExpr() instanceof CheckRequestMethodFromEnv + this instanceof CheckRequestMethodFromEnv } } -class CheckRequestMethodFromEnv extends ComparisonOperation { +class CheckRequestMethodFromEnv extends DataFlow::CallNode { CheckRequestMethodFromEnv() { - this.getAnOperand() instanceof GetRequestMethodFromEnv + // is this node an instance of `env["REQUEST_METHOD"] + this.getExprNode().getNode() instanceof GetRequestMethodFromEnv and + ( + // and is this node a param of a call to `.include?` + exists(MethodCall call | call.getAnArgument() = this.getExprNode().getNode() | + call.getMethodName() = "include?" + ) + or + exists(DataFlow::Node node | + node.asExpr().getExpr().(MethodCall).getMethodName() = "include?" + | + node.getALocalSource() = this + ) + or + // or is this node on either size of an equality comparison + exists(EqualityOperation eq | eq.getAChild() = this.getExprNode().getNode()) + ) } } class GetRequestMethodFromEnv extends ElementReference { GetRequestMethodFromEnv() { - this.getAChild+().toString() = "REQUEST_METHOD" // and - // this.getReceiver().toString() = "env" + this.getAChild+().toString() = "REQUEST_METHOD" and + this.getAChild+().toString() = "env" } } class CheckGetRequest extends DataFlow::CallNode { - CheckGetRequest() { - this.getMethodName() = "get?" - } + CheckGetRequest() { this.getMethodName() = "get?" } } class CheckPostRequest extends DataFlow::CallNode { - CheckPostRequest() { - this.getMethodName() = "post?" - } + CheckPostRequest() { this.getMethodName() = "post?" } } class CheckPutRequest extends DataFlow::CallNode { - CheckPutRequest() { - this.getMethodName() = "put?" - } + CheckPutRequest() { this.getMethodName() = "put?" } } class CheckPatchRequest extends DataFlow::CallNode { - CheckPatchRequest() { - this.getMethodName() = "patch?" - } + CheckPatchRequest() { this.getMethodName() = "patch?" } } class CheckDeleteRequest extends DataFlow::CallNode { - CheckDeleteRequest() { - this.getMethodName() = "delete?" - } + CheckDeleteRequest() { this.getMethodName() = "delete?" } } class CheckHeadRequest extends DataFlow::CallNode { - CheckHeadRequest() { - this.getMethodName() = "head?" - } + CheckHeadRequest() { this.getMethodName() = "head?" } } from ManuallyCheckHttpVerb check -where check.asExpr().getExpr().getAControlFlowNode().isCondition() -select check, "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods." \ No newline at end of file +select check, + "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods." From 059c4d38ad97b4972f0be1e4e878fbd32ad3b10c Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Sat, 18 Jun 2022 18:26:45 +0000 Subject: [PATCH 043/465] refine query to use appropriate types --- .../ManuallyCheckHttpVerb.ql | 26 ++++++++++--------- .../ManuallyCheckHttpVerb.expected | 0 2 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.expected diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql index ac34ad34088..7396e75b920 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -12,15 +12,14 @@ import ruby import codeql.ruby.DataFlow -class ManuallyCheckHttpVerb extends DataFlow::CallNode { - ManuallyCheckHttpVerb() { +class HttpVerbMethod extends MethodCall { + HttpVerbMethod() { this instanceof CheckGetRequest or this instanceof CheckPostRequest or this instanceof CheckPatchRequest or this instanceof CheckPostRequest or this instanceof CheckDeleteRequest or - this instanceof CheckHeadRequest or - this instanceof CheckRequestMethodFromEnv + this instanceof CheckHeadRequest } } @@ -53,30 +52,33 @@ class GetRequestMethodFromEnv extends ElementReference { } } -class CheckGetRequest extends DataFlow::CallNode { +class CheckGetRequest extends MethodCall { CheckGetRequest() { this.getMethodName() = "get?" } } -class CheckPostRequest extends DataFlow::CallNode { +class CheckPostRequest extends MethodCall { CheckPostRequest() { this.getMethodName() = "post?" } } -class CheckPutRequest extends DataFlow::CallNode { +class CheckPutRequest extends MethodCall { CheckPutRequest() { this.getMethodName() = "put?" } } -class CheckPatchRequest extends DataFlow::CallNode { +class CheckPatchRequest extends MethodCall { CheckPatchRequest() { this.getMethodName() = "patch?" } } -class CheckDeleteRequest extends DataFlow::CallNode { +class CheckDeleteRequest extends MethodCall { CheckDeleteRequest() { this.getMethodName() = "delete?" } } -class CheckHeadRequest extends DataFlow::CallNode { +class CheckHeadRequest extends MethodCall { CheckHeadRequest() { this.getMethodName() = "head?" } } -from ManuallyCheckHttpVerb check -select check, +from CheckRequestMethodFromEnv env, AstNode node +where + node instanceof HttpVerbMethod or + node = env.asExpr().getExpr() +select node, "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods." diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.expected b/ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.expected new file mode 100644 index 00000000000..e69de29bb2d From 8b3619102395283814944424ed142ee843a22a97 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Sat, 18 Jun 2022 18:38:58 +0000 Subject: [PATCH 044/465] drop precision to low for now --- .../manually-check-http-verb/ManuallyCheckHttpVerb.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql index 7396e75b920..5be00b48464 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -3,8 +3,8 @@ * @description Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. * @kind problem * @problem.severity error - * @security-severity 7.0 - * @precision medium + * @security-severity 5.0 + * @precision low * @id rb/manually-checking-http-verb * @tags security */ From ecb2114b7bb709a67160334db0234172caed31e3 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Sat, 18 Jun 2022 19:21:17 +0000 Subject: [PATCH 045/465] replace duplicate post with put --- .../manually-check-http-verb/ManuallyCheckHttpVerb.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql index 5be00b48464..6946d26a7e8 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -17,7 +17,7 @@ class HttpVerbMethod extends MethodCall { this instanceof CheckGetRequest or this instanceof CheckPostRequest or this instanceof CheckPatchRequest or - this instanceof CheckPostRequest or + this instanceof CheckPutRequest or this instanceof CheckDeleteRequest or this instanceof CheckHeadRequest } From 3478e7e9109fc216e741c42a999f56697c70bf1d Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Sat, 18 Jun 2022 20:43:58 +0000 Subject: [PATCH 046/465] first draft of weak params query --- .../experimental/weak-params/WeakParams.ql | 46 +++++++++++++++++++ .../security/weak-params/WeakParams.expected | 0 .../security/weak-params/WeakParams.qlref | 1 + .../security/weak-params/WeakParams.rb | 15 ++++++ 4 files changed, 62 insertions(+) create mode 100644 ruby/ql/src/experimental/weak-params/WeakParams.ql create mode 100644 ruby/ql/test/query-tests/security/weak-params/WeakParams.expected create mode 100644 ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref create mode 100644 ruby/ql/test/query-tests/security/weak-params/WeakParams.rb diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql new file mode 100644 index 00000000000..b756d6ed8b8 --- /dev/null +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -0,0 +1,46 @@ +/** + * @name Weak or direct parameter references are used + * @description Directly checking request parameters without following a strong params pattern can lead to unintentional avenues for injection attacks. + * @kind problem + * @problem.severity error + * @security-severity 5.0 + * @precision low + * @id rb/weak-params + * @tags security + */ + +import ruby + +class WeakParams extends AstNode { + WeakParams() { + this instanceof UnspecificParamsMethod or + this instanceof ParamsReference + } +} + +class StrongParamsMethod extends Method { + StrongParamsMethod() { this.getName().regexpMatch(".*_params") } +} + +class UnspecificParamsMethod extends MethodCall { + UnspecificParamsMethod() { + ( + this.getMethodName() = "expose_all" or + this.getMethodName() = "original_hash" or + this.getMethodName() = "path_parametes" or + this.getMethodName() = "query_parameters" or + this.getMethodName() = "request_parameters" or + this.getMethodName() = "GET" or + this.getMethodName() = "POST" + ) + } +} + +class ParamsReference extends ElementReference { + ParamsReference() { this.getAChild().toString() = "params" } +} + +from WeakParams params +where not params.getEnclosingMethod() instanceof StrongParamsMethod +select params, + "By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects." diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.expected b/ruby/ql/test/query-tests/security/weak-params/WeakParams.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref b/ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref new file mode 100644 index 00000000000..5350e4bf40a --- /dev/null +++ b/ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref @@ -0,0 +1 @@ +experimental/weak-params/WeakParams.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb b/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb new file mode 100644 index 00000000000..cc0dc80341f --- /dev/null +++ b/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb @@ -0,0 +1,15 @@ +class TestController < ActionController::Base + def create + TestObject.new(request.request_parameters) + end + + def create_query + TestObject.new(request.query_parameters) + end + + # + def object_params + p = params.query_parameters + params.require(:uuid).permit(:notes) + end +end \ No newline at end of file From 3a4f0299c728b9fc81f65405dd3ee68d606c9546 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Fri, 17 Jun 2022 15:15:25 +0200 Subject: [PATCH 047/465] fix typo --- javascript/ql/src/Expressions/TypoDatabase.qll | 2 ++ ql/ql/src/codeql_ql/ast/internal/Predicate.qll | 2 +- ql/ql/src/codeql_ql/style/TypoDatabase.qll | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/javascript/ql/src/Expressions/TypoDatabase.qll b/javascript/ql/src/Expressions/TypoDatabase.qll index aad43d9d0cc..fadc1b8af75 100644 --- a/javascript/ql/src/Expressions/TypoDatabase.qll +++ b/javascript/ql/src/Expressions/TypoDatabase.qll @@ -5793,6 +5793,8 @@ predicate typos(string wrong, string right) { or wrong = "paramters" and right = "parameters" or + wrong = "parametarized" and right = "parameterized" + or wrong = "paranthesis" and right = "parenthesis" or wrong = "paraphenalia" and right = "paraphernalia" diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll index eb7e298b7cd..0e614c23c25 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll @@ -176,7 +176,7 @@ module PredConsistency { c > 1 and resolvePredicateExpr(pe, p) } - // This can happen with parametarized modules + // This can happen with parameterized modules /* * query predicate multipleResolveCall(Call call, int c, PredicateOrBuiltin p) { * c = diff --git a/ql/ql/src/codeql_ql/style/TypoDatabase.qll b/ql/ql/src/codeql_ql/style/TypoDatabase.qll index aad43d9d0cc..fadc1b8af75 100644 --- a/ql/ql/src/codeql_ql/style/TypoDatabase.qll +++ b/ql/ql/src/codeql_ql/style/TypoDatabase.qll @@ -5793,6 +5793,8 @@ predicate typos(string wrong, string right) { or wrong = "paramters" and right = "parameters" or + wrong = "parametarized" and right = "parameterized" + or wrong = "paranthesis" and right = "parenthesis" or wrong = "paraphenalia" and right = "paraphernalia" From a59f0d36f55fac849e2fa97d7db40dbddd929c2e Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Fri, 17 Jun 2022 18:06:12 +0200 Subject: [PATCH 048/465] run the implicit-this patch on QL-for-QL --- ql/ql/src/codeql_ql/ast/Ast.qll | 2 +- ql/ql/src/codeql_ql/dataflow/DataFlow.qll | 16 +++++++++------- ql/ql/src/queries/reports/FrameworkCoverage.ql | 6 ++++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index fa551b0de83..ffd8d07cd2a 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -1167,7 +1167,7 @@ class Import extends TImport, ModuleMember, TypeRef { */ string getImportString() { exists(string selec | - not exists(getSelectionName(_)) and selec = "" + not exists(this.getSelectionName(_)) and selec = "" or selec = "::" + strictconcat(int i, string q | q = this.getSelectionName(i) | q, "::" order by i) diff --git a/ql/ql/src/codeql_ql/dataflow/DataFlow.qll b/ql/ql/src/codeql_ql/dataflow/DataFlow.qll index da8bc1da837..c9043416bae 100644 --- a/ql/ql/src/codeql_ql/dataflow/DataFlow.qll +++ b/ql/ql/src/codeql_ql/dataflow/DataFlow.qll @@ -204,7 +204,7 @@ class SuperNode extends LocalFlow::TSuperNode { Node getANode() { LocalFlow::getRepr(result) = repr } /** Gets an AST node from any of the nodes in this super node. */ - AstNode asAstNode() { result = getANode().asAstNode() } + AstNode asAstNode() { result = this.getANode().asAstNode() } /** * Gets a single node from this super node. @@ -214,23 +214,25 @@ class SuperNode extends LocalFlow::TSuperNode { * - An `AstNodeNode` is preferred over other nodes. * - A node occurring earlier is preferred over one occurring later. */ - Node getArbitraryRepr() { result = min(Node n | n = getANode() | n order by getInternalId(n)) } + Node getArbitraryRepr() { + result = min(Node n | n = this.getANode() | n order by getInternalId(n)) + } /** * Gets the predicate containing all nodes that are part of this super node. */ - Predicate getEnclosingPredicate() { result = getANode().getEnclosingPredicate() } + Predicate getEnclosingPredicate() { result = this.getANode().getEnclosingPredicate() } /** Gets a string representation of this super node. */ string toString() { exists(int c | - c = strictcount(getANode()) and - result = "Super node of " + c + " nodes in " + getEnclosingPredicate().getName() + c = strictcount(this.getANode()) and + result = "Super node of " + c + " nodes in " + this.getEnclosingPredicate().getName() ) } /** Gets the location of an arbitrary node in this super node. */ - Location getLocation() { result = getArbitraryRepr().getLocation() } + Location getLocation() { result = this.getArbitraryRepr().getLocation() } /** Gets any member call whose receiver is in the same super node. */ MemberCall getALocalMemberCall() { superNode(result.getBase()) = this } @@ -287,7 +289,7 @@ class SuperNode extends LocalFlow::TSuperNode { cached private string getAStringValue(Tracker t) { t.start() and - result = asAstNode().(String).getValue() + result = this.asAstNode().(String).getValue() or exists(SuperNode pred, Tracker t2 | this = pred.track(t2, t) and diff --git a/ql/ql/src/queries/reports/FrameworkCoverage.ql b/ql/ql/src/queries/reports/FrameworkCoverage.ql index 7f5eb7f5310..f394a5a0091 100644 --- a/ql/ql/src/queries/reports/FrameworkCoverage.ql +++ b/ql/ql/src/queries/reports/FrameworkCoverage.ql @@ -18,11 +18,13 @@ class PackageImportCall extends PredicateCall { PackageImportCall() { this.getQualifier().getName() = ["API", "DataFlow"] and this.getPredicateName() = ["moduleImport", "moduleMember"] and - not isExcludedFile(getLocation().getFile()) + not isExcludedFile(this.getLocation().getFile()) } /** Gets the name of a package referenced by this call */ - string getAPackageName() { result = DataFlow::superNode(getArgument(0)).getAStringValueNoCall() } + string getAPackageName() { + result = DataFlow::superNode(this.getArgument(0)).getAStringValueNoCall() + } } /** Gets a reference to `package` or any transitive member thereof. */ From 7e93416e9728ba24d2936027d033607c952621e1 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Fri, 17 Jun 2022 21:32:19 +0200 Subject: [PATCH 049/465] only resolve module types if we know that the TypeExpr could possibly resolve to a module --- ql/ql/src/codeql_ql/ast/Ast.qll | 13 +++++++++++-- ql/ql/test/queries/style/RedundantCast/Foo.qll | 11 +++++++++++ .../style/RedundantCast/RedundantCast.expected | 3 +++ .../queries/style/RedundantCast/RedundantCast.qlref | 1 + 4 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 ql/ql/test/queries/style/RedundantCast/Foo.qll create mode 100644 ql/ql/test/queries/style/RedundantCast/RedundantCast.expected create mode 100644 ql/ql/test/queries/style/RedundantCast/RedundantCast.qlref diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index ffd8d07cd2a..09f6e35171f 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -682,8 +682,17 @@ class TypeExpr extends TType, TypeRef { // resolve type resolveTypeExpr(this, result) or - // if it resolves to a module - exists(FileOrModule mod | resolveModuleRef(this, mod) | result = mod.toType()) + // if it resolves to a module, + exists(FileOrModule mod | resolveModuleRef(this, mod) | result = mod.toType()) and + result instanceof ModuleType and + // we can get spurious results in some cases, so we restrict to where it is possible to have a module. + ( + // only possible if this is inside a moduleInstantiation. + this = any(ModuleExpr mod).getArgument(_).asType() + or + // or if it's a parameter to a parameterized module + this = any(SignatureExpr sig, Module mod | mod.hasParameter(_, _, sig) | sig).asType() + ) } override AstNode getAChild(string pred) { diff --git a/ql/ql/test/queries/style/RedundantCast/Foo.qll b/ql/ql/test/queries/style/RedundantCast/Foo.qll new file mode 100644 index 00000000000..d993f654bc4 --- /dev/null +++ b/ql/ql/test/queries/style/RedundantCast/Foo.qll @@ -0,0 +1,11 @@ +class Foo extends string { + Foo() { this = "Foo" } +} + +predicate test(Foo f) { f.(Foo).toString() = "X" } + +predicate test2(Foo a, Foo b) { a.(Foo) = b } + +predicate called(Foo a) { a.toString() = "X" } + +predicate test3(string s) { called(s.(Foo)) } diff --git a/ql/ql/test/queries/style/RedundantCast/RedundantCast.expected b/ql/ql/test/queries/style/RedundantCast/RedundantCast.expected new file mode 100644 index 00000000000..e4e57083633 --- /dev/null +++ b/ql/ql/test/queries/style/RedundantCast/RedundantCast.expected @@ -0,0 +1,3 @@ +| Foo.qll:5:25:5:31 | InlineCast | Redundant cast to $@ | Foo.qll:5:28:5:30 | TypeExpr | Foo | +| Foo.qll:7:33:7:39 | InlineCast | Redundant cast to $@ | Foo.qll:7:36:7:38 | TypeExpr | Foo | +| Foo.qll:11:36:11:42 | InlineCast | Redundant cast to $@ | Foo.qll:11:39:11:41 | TypeExpr | Foo | diff --git a/ql/ql/test/queries/style/RedundantCast/RedundantCast.qlref b/ql/ql/test/queries/style/RedundantCast/RedundantCast.qlref new file mode 100644 index 00000000000..659062d3ae5 --- /dev/null +++ b/ql/ql/test/queries/style/RedundantCast/RedundantCast.qlref @@ -0,0 +1 @@ +queries/style/RedundantCast.ql From 0391db67876892ef943108e44d52725f9dbbcfb5 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Fri, 17 Jun 2022 22:52:17 +0200 Subject: [PATCH 050/465] simplify some code based on review --- ql/ql/src/codeql_ql/ast/Ast.qll | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index 09f6e35171f..a237e1f6b58 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -2226,9 +2226,7 @@ class ModuleExpr extends TModuleExpr, TypeRef { or not exists(me.getName()) and result = me.getChild().(QL::SimpleId).getValue() or - exists(QL::ModuleInstantiation instantiation | instantiation.getParent() = me | - result = instantiation.getName().getChild().getValue() - ) + result = me.getChild().(QL::ModuleInstantiation).getName().getChild().getValue() } /** @@ -2263,9 +2261,7 @@ class ModuleExpr extends TModuleExpr, TypeRef { * The result is either a `PredicateExpr` or a `TypeExpr`. */ SignatureExpr getArgument(int i) { - exists(QL::ModuleInstantiation instantiation | instantiation.getParent() = me | - result.toQL() = instantiation.getChild(i) - ) + result.toQL() = me.getChild().(QL::ModuleInstantiation).getChild(i) } } From 638a886dfef9d4601feca560df5225071a22e1a8 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 18 Jun 2022 16:43:56 +0200 Subject: [PATCH 051/465] move create-extractor-pack to a `scripts` folder --- .github/workflows/ql-for-ql-dataset_measure.yml | 2 +- .github/workflows/ql-for-ql-tests.yml | 2 +- ql/README.md | 4 ++-- ql/{ => scripts}/create-extractor-pack.ps1 | 0 ql/{ => scripts}/create-extractor-pack.sh | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename ql/{ => scripts}/create-extractor-pack.ps1 (100%) rename ql/{ => scripts}/create-extractor-pack.sh (100%) diff --git a/.github/workflows/ql-for-ql-dataset_measure.yml b/.github/workflows/ql-for-ql-dataset_measure.yml index cf3b696f3b8..a5ed2e9b266 100644 --- a/.github/workflows/ql-for-ql-dataset_measure.yml +++ b/.github/workflows/ql-for-ql-dataset_measure.yml @@ -36,7 +36,7 @@ jobs: ql/target key: ${{ runner.os }}-qltest-cargo-${{ hashFiles('ql/**/Cargo.lock') }} - name: Build Extractor - run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./create-extractor-pack.sh + run: cd ql; env "PATH=$PATH:`dirname ${CODEQL}`" ./scripts/create-extractor-pack.sh env: CODEQL: ${{ steps.find-codeql.outputs.codeql-path }} - name: Checkout ${{ matrix.repo }} diff --git a/.github/workflows/ql-for-ql-tests.yml b/.github/workflows/ql-for-ql-tests.yml index 3b0a4963b79..b016f21f2b9 100644 --- a/.github/workflows/ql-for-ql-tests.yml +++ b/.github/workflows/ql-for-ql-tests.yml @@ -36,7 +36,7 @@ jobs: run: | cd ql; codeqlpath=$(dirname ${{ steps.find-codeql.outputs.codeql-path }}); - env "PATH=$PATH:$codeqlpath" ./create-extractor-pack.sh + env "PATH=$PATH:$codeqlpath" ./scripts/create-extractor-pack.sh - name: Run QL tests run: | "${CODEQL}" test run --check-databases --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --search-path "${{ github.workspace }}/ql/extractor-pack" --consistency-queries ql/ql/consistency-queries ql/ql/test diff --git a/ql/README.md b/ql/README.md index 4bb5e30ba84..29b5aaef63c 100644 --- a/ql/README.md +++ b/ql/README.md @@ -21,14 +21,14 @@ cargo build --release The generated `ql/src/ql.dbscheme` and `ql/src/codeql_ql/ast/internal/TreeSitter.qll` files are included in the repository, but they can be re-generated as follows: ```bash -./create-extractor-pack.sh +./scripts/create-extractor-pack.sh ``` ## Building a CodeQL database for a QL program First, get an extractor pack: -Run `./create-extractor-pack.sh` (Linux/Mac) or `.\create-extractor-pack.ps1` (Windows PowerShell) and the pack will be created in the `extractor-pack` directory. +Run `./scripts/create-extractor-pack.sh` (Linux/Mac) or `.\scripts\create-extractor-pack.ps1` (Windows PowerShell) and the pack will be created in the `extractor-pack` directory. Then run diff --git a/ql/create-extractor-pack.ps1 b/ql/scripts/create-extractor-pack.ps1 similarity index 100% rename from ql/create-extractor-pack.ps1 rename to ql/scripts/create-extractor-pack.ps1 diff --git a/ql/create-extractor-pack.sh b/ql/scripts/create-extractor-pack.sh similarity index 100% rename from ql/create-extractor-pack.sh rename to ql/scripts/create-extractor-pack.sh From 6e2f3e2fcb8097e48195491326f96e975587504e Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sat, 18 Jun 2022 16:44:10 +0200 Subject: [PATCH 052/465] merge all .sarif files at the end of the QL-for-QL workflow --- .github/workflows/ql-for-ql-build.yml | 27 ++++++++++++++++++++++++--- ql/scripts/merge-sarif.js | 26 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) create mode 100644 ql/scripts/merge-sarif.js diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index 6b4f6a0abee..ffb4ad1cbc0 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -50,9 +50,6 @@ jobs: path: ${{ runner.temp }}/query-pack.zip extractors: - strategy: - fail-fast: false - runs-on: ubuntu-latest steps: @@ -201,3 +198,27 @@ jobs: name: ${{ matrix.folder }}.sarif path: ${{ matrix.folder }}.sarif + combine: + runs-on: ubuntu-latest + needs: + - analyze + + steps: + - uses: actions/checkout@v3 + - name: Make a folder for artifacts. + run: mkdir -p results + - name: Download all sarif files + uses: actions/download-artifact@v3 + with: + path: results + - uses: actions/setup-node@v3 + with: + node-version: 16 + - name: Combine all sarif files + run: | + node ./ql/scripts/merge-sarif.js results/**/*.sarif combined.sarif + - name: Upload combined sarif file + uses: actions/upload-artifact@v3 + with: + name: combined.sarif + path: combined.sarif diff --git a/ql/scripts/merge-sarif.js b/ql/scripts/merge-sarif.js new file mode 100644 index 00000000000..c7507986d5a --- /dev/null +++ b/ql/scripts/merge-sarif.js @@ -0,0 +1,26 @@ +var fs = require("fs"); + +// first a list of files to merge, and the last argument is the output file. +async function main(files) { + const inputs = files + .slice(0, -1) + .map((file) => fs.readFileSync(file)) + .map((data) => JSON.parse(data)); + const out = inputs[0]; // just arbitrarily take the first one + const outFile = files[files.length - 1]; + + const combinedResults = []; + + for (const sarif of inputs) { + combinedResults.push(...sarif.runs[0].results); + } + + out.runs[0].artifacts = []; // the indexes in these won't make sense, so I hope this works. + out.runs[0].results = combinedResults; + + // workaround until https://github.com/microsoft/sarif-vscode-extension/pull/436/ is part of a release + out["$schema"] = "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0"; + + fs.writeFileSync(outFile, JSON.stringify(out, null, 2)); +} +main(process.argv.splice(2)); From 1856e2b3891c6b2e534057bdd763332208729aa3 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 19 Jun 2022 13:12:38 +0200 Subject: [PATCH 053/465] fixup the $schema in all .sarif files --- .github/workflows/ql-for-ql-build.yml | 3 +++ ql/scripts/merge-sarif.js | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index ffb4ad1cbc0..95b93dd772c 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -192,6 +192,9 @@ jobs: category: "ql-for-ql-${{ matrix.folder }}" - name: Copy sarif file to CWD run: cp ../results/ql.sarif ./${{ matrix.folder }}.sarif + - name: Fixup the $scema in sarif # Until https://github.com/microsoft/sarif-vscode-extension/pull/436/ is part in a stable release + run: | + sed -i 's/\$schema.*/\$schema": "https:\/\/raw.githubusercontent.com\/oasis-tcs\/sarif-spec\/master\/Schemata\/sarif-schema-2.1.0",/' ${{ matrix.folder }}.sarif - name: Sarif as artifact uses: actions/upload-artifact@v3 with: diff --git a/ql/scripts/merge-sarif.js b/ql/scripts/merge-sarif.js index c7507986d5a..5c781f1b67d 100644 --- a/ql/scripts/merge-sarif.js +++ b/ql/scripts/merge-sarif.js @@ -18,9 +18,6 @@ async function main(files) { out.runs[0].artifacts = []; // the indexes in these won't make sense, so I hope this works. out.runs[0].results = combinedResults; - // workaround until https://github.com/microsoft/sarif-vscode-extension/pull/436/ is part of a release - out["$schema"] = "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0"; - fs.writeFileSync(outFile, JSON.stringify(out, null, 2)); } main(process.argv.splice(2)); From 26df367a8a9b6be00fcabed22e9f0c352e167cfe Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 19 Jun 2022 18:59:00 +0200 Subject: [PATCH 054/465] fix some instances of spuriously resolving to multiple predicates --- .../src/codeql_ql/ast/internal/Predicate.qll | 7 +++-- ql/ql/test/callgraph/MultiResolve.qll | 26 +++++++++++++++++++ ql/ql/test/callgraph/callgraph.expected | 5 ++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 ql/ql/test/callgraph/MultiResolve.qll diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll index 0e614c23c25..b4a5eaa6574 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll @@ -31,7 +31,8 @@ private predicate definesPredicate( name = alias.getName() and resolvePredicateExpr(alias.getAlias(), p) and public = getPublicBool(alias) and - arity = alias.getArity() + arity = alias.getArity() and + arity = p.getArity() ) ) } @@ -53,10 +54,12 @@ private module Cached { } private predicate resolvePredicateCall(PredicateCall pc, PredicateOrBuiltin p) { + // calls to class methods exists(Class c, ClassType t | c = pc.getParent*() and t = c.getType() and - p = t.getClassPredicate(pc.getPredicateName(), pc.getNumberOfArguments()) + p = t.getClassPredicate(pc.getPredicateName(), pc.getNumberOfArguments()) and + not exists(pc.getQualifier()) // no module qualifier, because then it's not a call to a class method. ) or exists(FileOrModule m, boolean public | diff --git a/ql/ql/test/callgraph/MultiResolve.qll b/ql/ql/test/callgraph/MultiResolve.qll new file mode 100644 index 00000000000..161d86077ad --- /dev/null +++ b/ql/ql/test/callgraph/MultiResolve.qll @@ -0,0 +1,26 @@ +predicate foo(int a, int b) { + a = 2 and + b = 2 +} + +predicate foo(int a, int b, int c) { + a = 2 and + b = 2 and + c = 2 +} + +predicate myFoo = foo/2; + +predicate test(int i) { myFoo(i, i) } // <- should only resolve to the `foo` with 2 arguments (and the `myFoo` alias). + +module MyMod { + predicate bar() { any() } + + class Bar extends int { + Bar() { this = 42 } + + predicate bar() { + MyMod::bar() // <- should resolve to the module's predicate. + } + } +} diff --git a/ql/ql/test/callgraph/callgraph.expected b/ql/ql/test/callgraph/callgraph.expected index 97c84034602..b640afaecc6 100644 --- a/ql/ql/test/callgraph/callgraph.expected +++ b/ql/ql/test/callgraph/callgraph.expected @@ -14,6 +14,9 @@ getTarget | Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:24:3:24:32 | ClasslessPredicate alias0 | | Foo.qll:36:36:36:65 | MemberCall | file://:0:0:0:0 | replaceAll | | Foo.qll:38:39:38:67 | MemberCall | file://:0:0:0:0 | regexpCapture | +| MultiResolve.qll:14:25:14:35 | PredicateCall | MultiResolve.qll:1:1:4:1 | ClasslessPredicate foo | +| MultiResolve.qll:14:25:14:35 | PredicateCall | MultiResolve.qll:12:1:12:24 | ClasslessPredicate myFoo | +| MultiResolve.qll:25:7:25:18 | PredicateCall | MultiResolve.qll:17:3:19:3 | ClasslessPredicate bar | | Overrides.qll:8:30:8:39 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | | Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | | Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:14:12:14:43 | ClassPredicate bar | @@ -43,5 +46,7 @@ exprPredicate | Foo.qll:26:22:26:31 | predicate | Foo.qll:20:3:20:54 | ClasslessPredicate myThing2 | | Foo.qll:47:55:47:62 | predicate | Foo.qll:42:20:42:27 | NewTypeBranch MkRoot | | Foo.qll:47:65:47:70 | predicate | Foo.qll:44:9:44:56 | ClasslessPredicate edge | +| MultiResolve.qll:12:19:12:23 | predicate | MultiResolve.qll:1:1:4:1 | ClasslessPredicate foo | +| MultiResolve.qll:12:19:12:23 | predicate | MultiResolve.qll:6:1:10:1 | ClasslessPredicate foo | | ParamModules.qll:4:18:4:25 | predicate | ParamModules.qll:2:13:2:36 | ClasslessPredicate fooSig | | ParamModules.qll:10:34:10:40 | predicate | ParamModules.qll:8:3:8:35 | ClasslessPredicate myFoo | From 115110475d3ba345a21b38c8b8891cba5835730d Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 19 Jun 2022 20:09:01 +0200 Subject: [PATCH 055/465] fix `getName()` on module instantiations --- ql/ql/src/codeql_ql/ast/Ast.qll | 4 ++-- ql/ql/src/codeql_ql/ast/internal/Module.qll | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index a237e1f6b58..3a0063aaa76 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -2226,7 +2226,7 @@ class ModuleExpr extends TModuleExpr, TypeRef { or not exists(me.getName()) and result = me.getChild().(QL::SimpleId).getValue() or - result = me.getChild().(QL::ModuleInstantiation).getName().getChild().getValue() + result = me.getAFieldOrChild().(QL::ModuleInstantiation).getName().getChild().getValue() } /** @@ -2261,7 +2261,7 @@ class ModuleExpr extends TModuleExpr, TypeRef { * The result is either a `PredicateExpr` or a `TypeExpr`. */ SignatureExpr getArgument(int i) { - result.toQL() = me.getChild().(QL::ModuleInstantiation).getChild(i) + result.toQL() = me.getAFieldOrChild().(QL::ModuleInstantiation).getChild(i) } } diff --git a/ql/ql/src/codeql_ql/ast/internal/Module.qll b/ql/ql/src/codeql_ql/ast/internal/Module.qll index b487c98cc7e..d84f0b8122e 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Module.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Module.qll @@ -332,7 +332,19 @@ module ModConsistency { * } */ - query predicate noName(Module mod) { not exists(mod.getName()) } + query predicate noName(AstNode mod) { + mod instanceof Module and + not exists(mod.(Module).getName()) + or + mod instanceof ModuleExpr and + not exists(mod.(ModuleExpr).getName()) + } - query predicate nonUniqueName(Module mod) { count(mod.getName()) >= 2 } + query predicate nonUniqueName(AstNode mod) { + mod instanceof Module and + count(mod.(Module).getName()) >= 2 + or + mod instanceof ModuleExpr and + count(mod.(ModuleExpr).getName()) >= 2 + } } From f08f02ed66724fe55482746e5ade7f826ad64ddd Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 19 Jun 2022 20:38:16 +0200 Subject: [PATCH 056/465] use the explicit super type to resolve calls --- ql/ql/src/codeql_ql/ast/internal/Predicate.qll | 17 +++++++++++++---- ql/ql/test/callgraph/MultiResolve.qll | 16 ++++++++++++++++ ql/ql/test/callgraph/callgraph.expected | 3 ++- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll index b4a5eaa6574..60b52c3241f 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll @@ -95,15 +95,24 @@ private module Cached { ) or // super calls - and `this.method()` calls in charpreds. (Basically: in charpreds there is no difference between super and this.) - exists(AstNode sup, ClassType type, Type supertype | + exists(AstNode sup, Type supertype | sup instanceof Super or sup.(ThisAccess).getEnclosingPredicate() instanceof CharPred | mc.getBase() = sup and - sup.getEnclosingPredicate().getParent().(Class).getType() = type and - supertype in [type.getASuperType(), type.getAnInstanceofType()] and - p = supertype.getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments()) + p = supertype.getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments()) and + ( + // super.method() + not exists(mc.getSuperType()) and + exists(ClassType type | + sup.getEnclosingPredicate().getParent().(Class).getType() = type and + supertype in [type.getASuperType(), type.getAnInstanceofType()] + ) + or + // Class.super.method() + supertype = mc.getSuperType().getResolvedType() + ) ) } diff --git a/ql/ql/test/callgraph/MultiResolve.qll b/ql/ql/test/callgraph/MultiResolve.qll index 161d86077ad..aabb680709d 100644 --- a/ql/ql/test/callgraph/MultiResolve.qll +++ b/ql/ql/test/callgraph/MultiResolve.qll @@ -24,3 +24,19 @@ module MyMod { } } } + +class Super1 extends int { + Super1() { this = 42 } + + predicate foo() { any() } +} + +class Super2 extends int { + Super2() { this = 42 } + + predicate foo() { none() } +} + +class Sub extends Super1, Super2 { + override predicate foo() { Super1.super.foo() } // <- should resolve to Super1::foo() +} diff --git a/ql/ql/test/callgraph/callgraph.expected b/ql/ql/test/callgraph/callgraph.expected index b640afaecc6..52cd12bcb53 100644 --- a/ql/ql/test/callgraph/callgraph.expected +++ b/ql/ql/test/callgraph/callgraph.expected @@ -16,7 +16,8 @@ getTarget | Foo.qll:38:39:38:67 | MemberCall | file://:0:0:0:0 | regexpCapture | | MultiResolve.qll:14:25:14:35 | PredicateCall | MultiResolve.qll:1:1:4:1 | ClasslessPredicate foo | | MultiResolve.qll:14:25:14:35 | PredicateCall | MultiResolve.qll:12:1:12:24 | ClasslessPredicate myFoo | -| MultiResolve.qll:25:7:25:18 | PredicateCall | MultiResolve.qll:17:3:19:3 | ClasslessPredicate bar | +| MultiResolve.qll:23:7:23:18 | PredicateCall | MultiResolve.qll:17:3:17:27 | ClasslessPredicate bar | +| MultiResolve.qll:41:30:41:47 | MemberCall | MultiResolve.qll:31:3:31:27 | ClassPredicate foo | | Overrides.qll:8:30:8:39 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | | Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | | Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:14:12:14:43 | ClassPredicate bar | From f8b451a514bcd55db4a5c3ae645171744fb64bdc Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 19 Jun 2022 22:38:09 +0200 Subject: [PATCH 057/465] get all calls to resolve to a unique predicate (within reason) --- ql/ql/src/codeql_ql/ast/internal/Module.qll | 3 +- .../src/codeql_ql/ast/internal/Predicate.qll | 46 +++++++++++++------ .../queries/diagnostics/EmptyConsistencies.ql | 2 + ql/ql/test/callgraph/MultiResolve.qll | 16 +++++++ ql/ql/test/callgraph/callgraph.expected | 5 +- 5 files changed, 54 insertions(+), 18 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/internal/Module.qll b/ql/ql/src/codeql_ql/ast/internal/Module.qll index d84f0b8122e..4b224ad4adf 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Module.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Module.qll @@ -229,7 +229,8 @@ private module Cached { pragma[noinline] private predicate resolveModuleRefHelper(TypeRef me, ContainerOrModule enclosing, string name) { enclosing = getEnclosingModule(me).getEnclosing*() and - name = [me.(ModuleExpr).getName(), me.(TypeExpr).getClassName()] + name = [me.(ModuleExpr).getName(), me.(TypeExpr).getClassName()] and + (not me instanceof ModuleExpr or not enclosing instanceof Folder_) // module expressions are not imports, so they can't resolve to a file (which is contained in a folder). } } diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll index 60b52c3241f..e2da87b1904 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll @@ -88,7 +88,23 @@ private module Cached { ) } + /** + * Holds if `mc` is a `this.method()` call to a predicate defined in the same class. + * helps avoid spuriously resolving to predicates in super-classes. + */ + private predicate resolveSelfClassCalls(MemberCall mc, PredicateOrBuiltin p) { + exists(Class c | + mc.getBase() instanceof ThisAccess and + c = mc.getEnclosingPredicate().getParent() and + p = c.getClassPredicate(mc.getMemberName()) and + p.getArity() = mc.getNumberOfArguments() + ) + } + private predicate resolveMemberCall(MemberCall mc, PredicateOrBuiltin p) { + resolveSelfClassCalls(mc, p) + or + not resolveSelfClassCalls(mc, _) and exists(Type t | t = mc.getBase().getType() and p = t.getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments()) @@ -188,20 +204,20 @@ module PredConsistency { c > 1 and resolvePredicateExpr(pe, p) } - // This can happen with parameterized modules - /* - * query predicate multipleResolveCall(Call call, int c, PredicateOrBuiltin p) { - * c = - * strictcount(PredicateOrBuiltin p0 | - * resolveCall(call, p0) and - * // aliases are expected to resolve to multiple. - * not exists(p0.(ClasslessPredicate).getAlias()) and - * // overridden predicates may have multiple targets - * not p0.(ClassPredicate).isOverride() - * ) and - * c > 1 and - * resolveCall(call, p) - * } - */ + query predicate multipleResolveCall(Call call, int c, PredicateOrBuiltin p) { + c = + strictcount(PredicateOrBuiltin p0 | + resolveCall(call, p0) and + // aliases are expected to resolve to multiple. + not exists(p0.(ClasslessPredicate).getAlias()) and + // overridden predicates may have multiple targets + not p0.(ClassPredicate).isOverride() and + not p0 instanceof Relation // <- DB relations resolve to both a relation and a predicate. + ) and + c > 1 and + resolveCall(call, p) and + // parameterized modules are expected to resolve to multiple. + not exists(Predicate sig | not exists(sig.getBody()) and resolveCall(call, sig)) } +} diff --git a/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql b/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql index 7f95fec935e..8cd89f7fd37 100644 --- a/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql +++ b/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql @@ -22,6 +22,8 @@ where or PredConsistency::noResolvePredicateExpr(node) and msg = "PredConsistency::noResolvePredicateExpr" or + PredConsistency::multipleResolveCall(node, _, _) and msg = "PredConsistency::multipleResolveCall" + or TypeConsistency::exprNoType(node) and msg = "TypeConsistency::exprNoType" or TypeConsistency::varDefNoType(node) and msg = "TypeConsistency::varDefNoType" diff --git a/ql/ql/test/callgraph/MultiResolve.qll b/ql/ql/test/callgraph/MultiResolve.qll index aabb680709d..dce88d01689 100644 --- a/ql/ql/test/callgraph/MultiResolve.qll +++ b/ql/ql/test/callgraph/MultiResolve.qll @@ -40,3 +40,19 @@ class Super2 extends int { class Sub extends Super1, Super2 { override predicate foo() { Super1.super.foo() } // <- should resolve to Super1::foo() } + +module Foo { + predicate foo() { any() } +} + +predicate test() { + Foo::foo() // <- should resolve to `foo` from the module above, and not from the `Foo.qll` file. +} + +class Sub2 extends Super1, Super2 { + override predicate foo() { Super2.super.foo() } // <- should resolve to Super2::foo() + + predicate test() { + this.foo() // <- should resolve to only the above `foo` predicate, but currently it resolves to that, and all the overrides [INCONSISTENCY] + } +} diff --git a/ql/ql/test/callgraph/callgraph.expected b/ql/ql/test/callgraph/callgraph.expected index 52cd12bcb53..4d7840383cf 100644 --- a/ql/ql/test/callgraph/callgraph.expected +++ b/ql/ql/test/callgraph/callgraph.expected @@ -18,10 +18,11 @@ getTarget | MultiResolve.qll:14:25:14:35 | PredicateCall | MultiResolve.qll:12:1:12:24 | ClasslessPredicate myFoo | | MultiResolve.qll:23:7:23:18 | PredicateCall | MultiResolve.qll:17:3:17:27 | ClasslessPredicate bar | | MultiResolve.qll:41:30:41:47 | MemberCall | MultiResolve.qll:31:3:31:27 | ClassPredicate foo | +| MultiResolve.qll:49:3:49:12 | PredicateCall | MultiResolve.qll:45:3:45:27 | ClasslessPredicate foo | +| MultiResolve.qll:53:30:53:47 | MemberCall | MultiResolve.qll:37:3:37:28 | ClassPredicate foo | +| MultiResolve.qll:56:5:56:14 | MemberCall | MultiResolve.qll:53:12:53:49 | ClassPredicate foo | | Overrides.qll:8:30:8:39 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | -| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | | Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:14:12:14:43 | ClassPredicate bar | -| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | | Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:22:12:22:44 | ClassPredicate bar | | Overrides.qll:28:3:28:9 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | | Overrides.qll:29:3:29:10 | MemberCall | Overrides.qll:8:3:8:41 | ClassPredicate baz | From 15f9e084d5962b1d3b5930d935574a8d2c8c7d77 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 19 Jun 2022 22:43:41 +0200 Subject: [PATCH 058/465] fix spurious resolved predicate expressions --- ql/ql/src/codeql_ql/ast/internal/Predicate.qll | 10 ++++++++-- ql/ql/src/queries/diagnostics/EmptyConsistencies.ql | 3 +++ ql/ql/test/callgraph/callgraph.expected | 1 - 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll index e2da87b1904..6b17216b9aa 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll @@ -49,7 +49,8 @@ private module Cached { m = pe.getQualifier().getResolvedModule() and public = true | - definesPredicate(m, pe.getName(), p.getArity(), p, public) + definesPredicate(m, pe.getName(), p.getArity(), p, public) and + p.getArity() = pe.getArity() ) } @@ -200,7 +201,12 @@ module PredConsistency { } query predicate multipleResolvePredicateExpr(PredicateExpr pe, int c, ClasslessPredicate p) { - c = strictcount(ClasslessPredicate p0 | resolvePredicateExpr(pe, p0)) and + c = + strictcount(ClasslessPredicate p0 | + resolvePredicateExpr(pe, p0) and + // aliases are expected to resolve to multiple. + not exists(p0.(ClasslessPredicate).getAlias()) + ) and c > 1 and resolvePredicateExpr(pe, p) } diff --git a/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql b/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql index 8cd89f7fd37..8691aa2168c 100644 --- a/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql +++ b/ql/ql/src/queries/diagnostics/EmptyConsistencies.ql @@ -24,6 +24,9 @@ where or PredConsistency::multipleResolveCall(node, _, _) and msg = "PredConsistency::multipleResolveCall" or + PredConsistency::multipleResolvePredicateExpr(node, _, _) and + msg = "PredConsistency::multipleResolvePredicateExpr" + or TypeConsistency::exprNoType(node) and msg = "TypeConsistency::exprNoType" or TypeConsistency::varDefNoType(node) and msg = "TypeConsistency::varDefNoType" diff --git a/ql/ql/test/callgraph/callgraph.expected b/ql/ql/test/callgraph/callgraph.expected index 4d7840383cf..de11b0d658c 100644 --- a/ql/ql/test/callgraph/callgraph.expected +++ b/ql/ql/test/callgraph/callgraph.expected @@ -49,6 +49,5 @@ exprPredicate | Foo.qll:47:55:47:62 | predicate | Foo.qll:42:20:42:27 | NewTypeBranch MkRoot | | Foo.qll:47:65:47:70 | predicate | Foo.qll:44:9:44:56 | ClasslessPredicate edge | | MultiResolve.qll:12:19:12:23 | predicate | MultiResolve.qll:1:1:4:1 | ClasslessPredicate foo | -| MultiResolve.qll:12:19:12:23 | predicate | MultiResolve.qll:6:1:10:1 | ClasslessPredicate foo | | ParamModules.qll:4:18:4:25 | predicate | ParamModules.qll:2:13:2:36 | ClasslessPredicate fooSig | | ParamModules.qll:10:34:10:40 | predicate | ParamModules.qll:8:3:8:35 | ClasslessPredicate myFoo | From 6d3808bd899210863868c42b4f41369481bbd73f Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Sun, 19 Jun 2022 23:19:01 +0200 Subject: [PATCH 059/465] remove redundant cast --- ql/ql/src/codeql_ql/ast/internal/Predicate.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll index 6b17216b9aa..d419534788b 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Predicate.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Predicate.qll @@ -205,7 +205,7 @@ module PredConsistency { strictcount(ClasslessPredicate p0 | resolvePredicateExpr(pe, p0) and // aliases are expected to resolve to multiple. - not exists(p0.(ClasslessPredicate).getAlias()) + not exists(p0.getAlias()) ) and c > 1 and resolvePredicateExpr(pe, p) From 94145e9e74bf91641d1dfeca221bb9201ad4d29f Mon Sep 17 00:00:00 2001 From: yoff Date: Mon, 20 Jun 2022 10:14:52 +0200 Subject: [PATCH 060/465] Update python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll --- .../semmle/python/security/dataflow/TarSlipCustomizations.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll index d767f90c5c6..8795bd31c27 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll @@ -51,7 +51,7 @@ module TarSlip { } /** - * A sanitizer based on file name. This beacuse we extract the standard library. + * A sanitizer based on file name. This because we extract the standard library. * * For efficiency we don't want to track the flow of taint * around the tarfile module. From 7d62b9e13179c8712ad9aa0994de24fd75442e94 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 20 Jun 2022 12:12:57 +0200 Subject: [PATCH 061/465] move the pruning for module resolution of TypeExprs --- ql/ql/src/codeql_ql/ast/Ast.qll | 11 +---------- ql/ql/src/codeql_ql/ast/internal/Module.qll | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index 3a0063aaa76..c411f287fbc 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -683,16 +683,7 @@ class TypeExpr extends TType, TypeRef { resolveTypeExpr(this, result) or // if it resolves to a module, - exists(FileOrModule mod | resolveModuleRef(this, mod) | result = mod.toType()) and - result instanceof ModuleType and - // we can get spurious results in some cases, so we restrict to where it is possible to have a module. - ( - // only possible if this is inside a moduleInstantiation. - this = any(ModuleExpr mod).getArgument(_).asType() - or - // or if it's a parameter to a parameterized module - this = any(SignatureExpr sig, Module mod | mod.hasParameter(_, _, sig) | sig).asType() - ) + exists(FileOrModule mod | resolveModuleRef(this, mod) | result = mod.toType()) } override AstNode getAChild(string pred) { diff --git a/ql/ql/src/codeql_ql/ast/internal/Module.qll b/ql/ql/src/codeql_ql/ast/internal/Module.qll index 4b224ad4adf..1ca459ac108 100644 --- a/ql/ql/src/codeql_ql/ast/internal/Module.qll +++ b/ql/ql/src/codeql_ql/ast/internal/Module.qll @@ -218,6 +218,20 @@ private module Cached { not exists(me.(ModuleExpr).getQualifier()) and exists(ContainerOrModule enclosing, string name | resolveModuleRefHelper(me, enclosing, name) | definesModule(enclosing, name, m, _) + ) and + ( + not me instanceof TypeExpr + or + // remove some spurious results that can happen with `TypeExpr` + me instanceof TypeExpr and + m instanceof Module_ and // TypeExpr can only resolve to a Module, and only in some scenarios + ( + // only possible if this is inside a moduleInstantiation. + me = any(ModuleExpr mod).getArgument(_).asType() + or + // or if it's a parameter to a parameterized module + me = any(SignatureExpr sig, Module mod | mod.hasParameter(_, _, sig) | sig).asType() + ) ) or exists(FileOrModule mid | From 9d6b1bf14255d07234924585eafbd4ff9a0ee672 Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Mon, 20 Jun 2022 10:24:56 -0700 Subject: [PATCH 062/465] Apply suggestions from code review Co-authored-by: James Fletcher <42464962+jf205@users.noreply.github.com> --- ...nalyzing-databases-with-the-codeql-cli.rst | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst index cac63f6d01f..e6ee13c7823 100644 --- a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst @@ -161,34 +161,22 @@ If a ``scope/name`` and ``path`` are specified, then the ``path`` cannot be absolute. It is considered relative to the root of the CodeQL pack. -The relevant commands are: - -* `codeql database analyze <../manual/database-analyze>`__. -* `codeql database run-queries <../manual/database-run-queries>`__. -* `codeql execute queries <../manual/execute-queries>`__. -* `codeql resolve queries <../manual/resolve-queries>`__. - For example:: - # Analyze a database using all queries in the experimental/Security folder within the codeql/cpp-queries - # CodeQL query pack. +To analyze a database using all queries in the `experimental/Security` folder within the `codeql/cpp-queries` CodeQL pack you can use:: + codeql database analyze --format=sarif-latest --output=results \ codeql/cpp-queries:experimental/Security - # Analyse using only the RedundantNullCheckParam.ql query in the codeql/cpp-queries CodeQL query pack. +To run the `RedundantNullCheckParam.ql` query in the `codeql/cpp-queries` CodeQL pack use:: + codeql database analyze --format=sarif-latest --output=results \ 'codeql/cpp-queries:experimental/Likely Bugs/RedundantNullCheckParam.ql' - # Analyse using the cpp-security-and-quality.qls query suite in the codeql/cpp-queries CodeQL query pack. - codeql database analyze --format=sarif-latest --output=results \ - 'codeql/cpp-queries:codeql-suites/cpp-security-and-quality.qls' +To analyze your database using the `cpp-security-and-quality.qls` query suite from a version of the `codeql/cpp-queries` CodeQL pack that is >= 0.0.3 and < 0.1.0 (the highest compatible version will be chosen) you can use:: - # Analyse using the cpp-security-and-quality.qls query suite from a version of the codeql/cpp-queries pack - # that is >= 0.0.3 and < 0.1.0 (the highest compatible version will be chosen). - # All valid semver ranges are allowed. See https://docs.npmjs.com/cli/v6/using-npm/semver#ranges codeql database analyze --format=sarif-latest --output=results \ 'codeql/cpp-queries@~0.0.3:codeql-suites/cpp-security-and-quality.qls' - For more information about CodeQL packs, see :doc:`About CodeQL Packs `. Running query suites From 3547c338ef95346b5561fd64ee77b5bbf1ca10fd Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Mon, 20 Jun 2022 12:00:43 -0700 Subject: [PATCH 063/465] Update docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst Co-authored-by: James Fletcher <42464962+jf205@users.noreply.github.com> --- .../codeql-cli/analyzing-databases-with-the-codeql-cli.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst index e6ee13c7823..84b76615520 100644 --- a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst @@ -160,9 +160,6 @@ of the current process. If a ``scope/name`` and ``path`` are specified, then the ``path`` cannot be absolute. It is considered relative to the root of the CodeQL pack. - -For example:: - To analyze a database using all queries in the `experimental/Security` folder within the `codeql/cpp-queries` CodeQL pack you can use:: codeql database analyze --format=sarif-latest --output=results \ From 73b657ce2595a0d52763b832febf06b173e225e5 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Tue, 21 Jun 2022 12:23:20 +0200 Subject: [PATCH 064/465] QL: focus alert locations --- ql/ql/src/codeql_ql/ast/Ast.qll | 22 ++++- .../performance/VarUnusedInDisjunct.ql | 20 ++--- ql/ql/src/queries/style/LibraryAnnotation.ql | 7 +- .../queries/style/UseInstanceofExtension.ql | 2 +- ql/ql/test/callgraph/callgraph.expected | 80 +++++++++---------- ql/ql/test/printAst/printAst.expected | 68 ++++++++-------- .../AcronymsShouldBeCamelCase.expected | 6 +- .../queries/style/DeadCode/DeadCode.expected | 4 +- .../MissingOverride/MissingOverride.expected | 2 +- .../style/Misspelling/Misspelling.expected | 6 +- ql/ql/test/type/type.expected | 36 ++++----- 11 files changed, 136 insertions(+), 117 deletions(-) diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index fa551b0de83..d12239de072 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -21,11 +21,13 @@ private string stringIndexedMember(string name, string index) { class AstNode extends TAstNode { string toString() { result = this.getAPrimaryQlClass() } - /** - * Gets the location of the AST node. - */ + /** Gets the location of the AST node. */ cached - Location getLocation() { + Location getLocation() { result = this.getFullLocation() } // overriden in some subclasses + + /** Gets the location that spans the entire AST node. */ + cached + final Location getFullLocation() { exists(QL::AstNode node | not node instanceof QL::ParExpr | node = toQL(this) and result = node.getLocation() @@ -434,6 +436,8 @@ class ClasslessPredicate extends TClasslessPredicate, Predicate, ModuleDeclarati ClasslessPredicate() { this = TClasslessPredicate(pred) } + override Location getLocation() { result = pred.getName().getLocation() } + /** * Gets the aliased value if this predicate is an alias * E.g. for `predicate foo = Module::bar/2;` gets `Module::bar/2`. @@ -484,6 +488,8 @@ class ClassPredicate extends TClassPredicate, Predicate { ClassPredicate() { this = TClassPredicate(pred) } + override Location getLocation() { result = pred.getName().getLocation() } + override string getName() { result = pred.getName().getValue() } override Formula getBody() { toQL(result) = pred.getChild(_).(QL::Body).getChild() } @@ -701,6 +707,8 @@ class Module extends TModule, ModuleDeclaration { Module() { this = TModule(mod) } + override Location getLocation() { result = mod.getName().getLocation() } + override string getAPrimaryQlClass() { result = "Module" } override string getName() { result = mod.getName().getChild().getValue() } @@ -784,6 +792,8 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration { Class() { this = TClass(cls) } + override Location getLocation() { result = cls.getName().getLocation() } + override string getAPrimaryQlClass() { result = "Class" } override string getName() { result = cls.getName().getValue() } @@ -871,6 +881,8 @@ class NewType extends TNewType, TypeDeclaration, ModuleDeclaration { NewType() { this = TNewType(type) } + override Location getLocation() { result = type.getName().getLocation() } + override string getName() { result = type.getName().getValue() } override string getAPrimaryQlClass() { result = "NewType" } @@ -896,6 +908,8 @@ class NewTypeBranch extends TNewTypeBranch, Predicate, TypeDeclaration { NewTypeBranch() { this = TNewTypeBranch(branch) } + override Location getLocation() { result = branch.getName().getLocation() } + override string getAPrimaryQlClass() { result = "NewTypeBranch" } override string getName() { result = branch.getName().getValue() } diff --git a/ql/ql/src/queries/performance/VarUnusedInDisjunct.ql b/ql/ql/src/queries/performance/VarUnusedInDisjunct.ql index 2317cdc80c4..c26b47554fe 100644 --- a/ql/ql/src/queries/performance/VarUnusedInDisjunct.ql +++ b/ql/ql/src/queries/performance/VarUnusedInDisjunct.ql @@ -119,12 +119,14 @@ class EffectiveDisjunction extends AstNode { * Holds if `disj` only uses `var` in one of its branches. */ pragma[noinline] -predicate onlyUseInOneBranch(EffectiveDisjunction disj, VarDef var) { +predicate onlyUseInOneBranch(EffectiveDisjunction disj, VarDef var, AstNode notBoundIn) { alwaysBindsVar(var, disj.getLeft()) and - not alwaysBindsVar(var, disj.getRight()) + not alwaysBindsVar(var, disj.getRight()) and + notBoundIn = disj.getRight() or not alwaysBindsVar(var, disj.getLeft()) and - alwaysBindsVar(var, disj.getRight()) + alwaysBindsVar(var, disj.getRight()) and + notBoundIn = disj.getLeft() } /** @@ -170,7 +172,7 @@ class EffectiveConjunction extends AstNode { predicate varIsAlwaysBound(VarDef var, AstNode node) { // base case alwaysBindsVar(var, node) and - onlyUseInOneBranch(_, var) // <- manual magic + onlyUseInOneBranch(_, var, _) // <- manual magic or // recursive cases exists(AstNode parent | node.getParent() = parent | varIsAlwaysBound(var, parent)) @@ -194,8 +196,8 @@ predicate varIsAlwaysBound(VarDef var, AstNode node) { * Holds if `disj` only uses `var` in one of its branches. * And we should report it as being a bad thing. */ -predicate badDisjunction(EffectiveDisjunction disj, VarDef var) { - onlyUseInOneBranch(disj, var) and +predicate badDisjunction(EffectiveDisjunction disj, VarDef var, AstNode notBoundIn) { + onlyUseInOneBranch(disj, var, notBoundIn) and // it's fine if it's always bound further up not varIsAlwaysBound(var, disj) and // none() on one side makes everything fine. (this happens, it's a type-system hack) @@ -213,9 +215,9 @@ predicate badDisjunction(EffectiveDisjunction disj, VarDef var) { not isTinyAssignment(disj.getAnOperand()) } -from EffectiveDisjunction disj, VarDef var, string type +from EffectiveDisjunction disj, VarDef var, AstNode notBoundIn, string type where - badDisjunction(disj, var) and - not badDisjunction(disj.getParent(), var) and // avoid duplicate reporting of the same error + badDisjunction(disj, var, notBoundIn) and + not badDisjunction(disj.getParent(), var, _) and // avoid duplicate reporting of the same error if var.getParent() instanceof FieldDecl then type = "field" else type = "variable" select disj, "The $@ is only used in one side of disjunct.", var, type + " " + var.getName() diff --git a/ql/ql/src/queries/style/LibraryAnnotation.ql b/ql/ql/src/queries/style/LibraryAnnotation.ql index cf4a4bc8232..99b80f97fb9 100644 --- a/ql/ql/src/queries/style/LibraryAnnotation.ql +++ b/ql/ql/src/queries/style/LibraryAnnotation.ql @@ -10,6 +10,9 @@ import ql -from AstNode n -where n.hasAnnotation("library") and not n.hasAnnotation("deprecated") +from AstNode n, Annotation library +where + library = n.getAnAnnotation() and + library.getName() = "library" and + not n.hasAnnotation("deprecated") select n, "Don't use the library annotation." diff --git a/ql/ql/src/queries/style/UseInstanceofExtension.ql b/ql/ql/src/queries/style/UseInstanceofExtension.ql index 2e7b8e3de80..da27e5cbb47 100644 --- a/ql/ql/src/queries/style/UseInstanceofExtension.ql +++ b/ql/ql/src/queries/style/UseInstanceofExtension.ql @@ -18,4 +18,4 @@ where usesFieldBasedInstanceof(c, any(TypeExpr te | te.getResolvedType() = type), _, _) ) and message = "consider defining $@ as non-extending subtype of $@" -select c, message, c, c.getName(), type, type.getName() +select c, message, c, c.getName(), type.getDeclaration(), type.getName() diff --git a/ql/ql/test/callgraph/callgraph.expected b/ql/ql/test/callgraph/callgraph.expected index 97c84034602..dae7a03b047 100644 --- a/ql/ql/test/callgraph/callgraph.expected +++ b/ql/ql/test/callgraph/callgraph.expected @@ -1,47 +1,47 @@ getTarget -| Bar.qll:5:38:5:47 | PredicateCall | Bar.qll:8:3:8:31 | ClasslessPredicate snapshot | -| Bar.qll:24:12:24:32 | MemberCall | Bar.qll:19:3:19:47 | ClassPredicate getParameter | -| Bar.qll:26:12:26:31 | MemberCall | Bar.qll:19:3:19:47 | ClassPredicate getParameter | -| Bar.qll:30:12:30:32 | MemberCall | Bar.qll:19:3:19:47 | ClassPredicate getParameter | -| Baz.qll:8:18:8:44 | MemberCall | Baz.qll:4:3:4:37 | ClassPredicate getImportedPath | -| Foo.qll:5:26:5:30 | PredicateCall | Foo.qll:3:1:3:26 | ClasslessPredicate foo | -| Foo.qll:10:21:10:25 | PredicateCall | Foo.qll:8:3:8:28 | ClassPredicate bar | -| Foo.qll:14:30:14:40 | MemberCall | Foo.qll:10:3:10:27 | ClassPredicate baz | -| Foo.qll:17:27:17:42 | MemberCall | Foo.qll:8:3:8:28 | ClassPredicate bar | -| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:20:3:20:54 | ClasslessPredicate myThing2 | -| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:26:3:26:32 | ClasslessPredicate alias2 | -| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:22:3:22:32 | ClasslessPredicate myThing0 | -| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:24:3:24:32 | ClasslessPredicate alias0 | +| Bar.qll:5:38:5:47 | PredicateCall | Bar.qll:8:7:8:14 | ClasslessPredicate snapshot | +| Bar.qll:24:12:24:32 | MemberCall | Bar.qll:19:7:19:18 | ClassPredicate getParameter | +| Bar.qll:26:12:26:31 | MemberCall | Bar.qll:19:7:19:18 | ClassPredicate getParameter | +| Bar.qll:30:12:30:32 | MemberCall | Bar.qll:19:7:19:18 | ClassPredicate getParameter | +| Baz.qll:8:18:8:44 | MemberCall | Baz.qll:4:10:4:24 | ClassPredicate getImportedPath | +| Foo.qll:5:26:5:30 | PredicateCall | Foo.qll:3:11:3:13 | ClasslessPredicate foo | +| Foo.qll:10:21:10:25 | PredicateCall | Foo.qll:8:13:8:15 | ClassPredicate bar | +| Foo.qll:14:30:14:40 | MemberCall | Foo.qll:10:13:10:15 | ClassPredicate baz | +| Foo.qll:17:27:17:42 | MemberCall | Foo.qll:8:13:8:15 | ClassPredicate bar | +| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:20:13:20:20 | ClasslessPredicate myThing2 | +| Foo.qll:29:5:29:16 | PredicateCall | Foo.qll:26:13:26:18 | ClasslessPredicate alias2 | +| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:22:13:22:20 | ClasslessPredicate myThing0 | +| Foo.qll:31:5:31:12 | PredicateCall | Foo.qll:24:13:24:18 | ClasslessPredicate alias0 | | Foo.qll:36:36:36:65 | MemberCall | file://:0:0:0:0 | replaceAll | | Foo.qll:38:39:38:67 | MemberCall | file://:0:0:0:0 | regexpCapture | -| Overrides.qll:8:30:8:39 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | -| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | -| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:14:12:14:43 | ClassPredicate bar | -| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | -| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:22:12:22:44 | ClassPredicate bar | -| Overrides.qll:28:3:28:9 | MemberCall | Overrides.qll:6:3:6:29 | ClassPredicate bar | -| Overrides.qll:29:3:29:10 | MemberCall | Overrides.qll:8:3:8:41 | ClassPredicate baz | -| ParamModules.qll:5:28:5:41 | PredicateCall | ParamModules.qll:2:13:2:36 | ClasslessPredicate fooSig | -| ParamModules.qll:5:28:5:41 | PredicateCall | ParamModules.qll:8:3:8:35 | ClasslessPredicate myFoo | -| ParamModules.qll:10:26:10:49 | PredicateCall | ParamModules.qll:5:5:5:43 | ClasslessPredicate bar | -| ParamModules.qll:26:27:26:53 | PredicateCall | ParamModules.qll:17:5:17:42 | ClasslessPredicate getAnEven | -| ParamModules.qll:26:27:26:61 | MemberCall | ParamModules.qll:23:5:23:39 | ClassPredicate myFoo | -| ParamModules.qll:37:29:37:47 | PredicateCall | ParamModules.qll:33:5:33:17 | ClasslessPredicate getThing | -| ParamModules.qll:37:29:37:47 | PredicateCall | ParamModules.qll:51:5:51:26 | ClasslessPredicate getThing | -| ParamModules.qll:59:30:59:45 | PredicateCall | ParamModules.qll:37:5:37:49 | ClasslessPredicate getThing | -| ParamModules.qll:59:30:59:53 | MemberCall | ParamModules.qll:46:7:46:41 | ClassPredicate myFoo | -| ParamModules.qll:61:39:61:47 | MemberCall | ParamModules.qll:46:7:46:41 | ClassPredicate myFoo | -| packs/other/OtherThing.qll:5:3:5:8 | PredicateCall | packs/lib/LibThing/Foo.qll:1:1:1:30 | ClasslessPredicate foo | -| packs/other/OtherThing.qll:6:3:6:8 | PredicateCall | packs/src/SrcThing.qll:8:1:8:30 | ClasslessPredicate bar | -| packs/src/SrcThing.qll:4:3:4:8 | PredicateCall | packs/lib/LibThing/Foo.qll:1:1:1:30 | ClasslessPredicate foo | -| packs/src/SrcThing.qll:5:3:5:8 | PredicateCall | packs/src/SrcThing.qll:8:1:8:30 | ClasslessPredicate bar | +| Overrides.qll:8:30:8:39 | MemberCall | Overrides.qll:6:7:6:9 | ClassPredicate bar | +| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:6:7:6:9 | ClassPredicate bar | +| Overrides.qll:16:39:16:48 | MemberCall | Overrides.qll:14:16:14:18 | ClassPredicate bar | +| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:6:7:6:9 | ClassPredicate bar | +| Overrides.qll:24:39:24:48 | MemberCall | Overrides.qll:22:16:22:18 | ClassPredicate bar | +| Overrides.qll:28:3:28:9 | MemberCall | Overrides.qll:6:7:6:9 | ClassPredicate bar | +| Overrides.qll:29:3:29:10 | MemberCall | Overrides.qll:8:13:8:15 | ClassPredicate baz | +| ParamModules.qll:5:28:5:41 | PredicateCall | ParamModules.qll:2:23:2:28 | ClasslessPredicate fooSig | +| ParamModules.qll:5:28:5:41 | PredicateCall | ParamModules.qll:8:13:8:17 | ClasslessPredicate myFoo | +| ParamModules.qll:10:26:10:49 | PredicateCall | ParamModules.qll:5:15:5:17 | ClasslessPredicate bar | +| ParamModules.qll:26:27:26:53 | PredicateCall | ParamModules.qll:17:13:17:21 | ClasslessPredicate getAnEven | +| ParamModules.qll:26:27:26:61 | MemberCall | ParamModules.qll:23:12:23:16 | ClassPredicate myFoo | +| ParamModules.qll:37:29:37:47 | PredicateCall | ParamModules.qll:33:7:33:14 | ClasslessPredicate getThing | +| ParamModules.qll:37:29:37:47 | PredicateCall | ParamModules.qll:51:7:51:14 | ClasslessPredicate getThing | +| ParamModules.qll:59:30:59:45 | PredicateCall | ParamModules.qll:37:7:37:14 | ClasslessPredicate getThing | +| ParamModules.qll:59:30:59:53 | MemberCall | ParamModules.qll:46:14:46:18 | ClassPredicate myFoo | +| ParamModules.qll:61:39:61:47 | MemberCall | ParamModules.qll:46:14:46:18 | ClassPredicate myFoo | +| packs/other/OtherThing.qll:5:3:5:8 | PredicateCall | packs/lib/LibThing/Foo.qll:1:11:1:13 | ClasslessPredicate foo | +| packs/other/OtherThing.qll:6:3:6:8 | PredicateCall | packs/src/SrcThing.qll:8:11:8:13 | ClasslessPredicate bar | +| packs/src/SrcThing.qll:4:3:4:8 | PredicateCall | packs/lib/LibThing/Foo.qll:1:11:1:13 | ClasslessPredicate foo | +| packs/src/SrcThing.qll:5:3:5:8 | PredicateCall | packs/src/SrcThing.qll:8:11:8:13 | ClasslessPredicate bar | dependsOn | packs/other/qlpack.yml:1:1:1:4 | ql-other-pack-thing | packs/src/qlpack.yml:1:1:1:4 | ql-testing-src-pack | | packs/src/qlpack.yml:1:1:1:4 | ql-testing-src-pack | packs/lib/qlpack.yml:1:1:1:4 | ql-testing-lib-pack | exprPredicate -| Foo.qll:24:22:24:31 | predicate | Foo.qll:22:3:22:32 | ClasslessPredicate myThing0 | -| Foo.qll:26:22:26:31 | predicate | Foo.qll:20:3:20:54 | ClasslessPredicate myThing2 | -| Foo.qll:47:55:47:62 | predicate | Foo.qll:42:20:42:27 | NewTypeBranch MkRoot | -| Foo.qll:47:65:47:70 | predicate | Foo.qll:44:9:44:56 | ClasslessPredicate edge | -| ParamModules.qll:4:18:4:25 | predicate | ParamModules.qll:2:13:2:36 | ClasslessPredicate fooSig | -| ParamModules.qll:10:34:10:40 | predicate | ParamModules.qll:8:3:8:35 | ClasslessPredicate myFoo | +| Foo.qll:24:22:24:31 | predicate | Foo.qll:22:13:22:20 | ClasslessPredicate myThing0 | +| Foo.qll:26:22:26:31 | predicate | Foo.qll:20:13:20:20 | ClasslessPredicate myThing2 | +| Foo.qll:47:55:47:62 | predicate | Foo.qll:42:20:42:25 | NewTypeBranch MkRoot | +| Foo.qll:47:65:47:70 | predicate | Foo.qll:44:19:44:22 | ClasslessPredicate edge | +| ParamModules.qll:4:18:4:25 | predicate | ParamModules.qll:2:23:2:28 | ClasslessPredicate fooSig | +| ParamModules.qll:10:34:10:40 | predicate | ParamModules.qll:8:13:8:17 | ClasslessPredicate myFoo | diff --git a/ql/ql/test/printAst/printAst.expected b/ql/ql/test/printAst/printAst.expected index 603608355d7..daa299215d3 100644 --- a/ql/ql/test/printAst/printAst.expected +++ b/ql/ql/test/printAst/printAst.expected @@ -3,8 +3,8 @@ nodes | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | | Foo.qll:1:1:27:2 | TopLevel | semmle.label | [TopLevel] TopLevel | | Foo.qll:1:1:27:2 | TopLevel | semmle.order | 1 | -| Foo.qll:3:1:7:1 | Class Foo | semmle.label | [Class] Class Foo | -| Foo.qll:3:1:7:1 | Class Foo | semmle.order | 3 | +| Foo.qll:3:7:3:9 | Class Foo | semmle.label | [Class] Class Foo | +| Foo.qll:3:7:3:9 | Class Foo | semmle.order | 3 | | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 | | Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | [CharPred] CharPred Foo | @@ -17,8 +17,8 @@ nodes | Foo.qll:4:15:4:15 | Integer | semmle.order | 8 | | Foo.qll:6:3:6:8 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | | Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 9 | -| Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.label | [ClassPredicate] ClassPredicate toString | -| Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.order | 9 | +| Foo.qll:6:10:6:17 | ClassPredicate toString | semmle.label | [ClassPredicate] ClassPredicate toString | +| Foo.qll:6:10:6:17 | ClassPredicate toString | semmle.order | 10 | | Foo.qll:6:23:6:28 | result | semmle.label | [ResultAccess] result | | Foo.qll:6:23:6:28 | result | semmle.order | 11 | | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | [ComparisonFormula] ComparisonFormula | @@ -27,8 +27,8 @@ nodes | Foo.qll:6:32:6:36 | String | semmle.order | 13 | | Foo.qll:9:1:9:5 | annotation | semmle.label | [Annotation] annotation | | Foo.qll:9:1:9:5 | annotation | semmle.order | 14 | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.label | [ClasslessPredicate] ClasslessPredicate foo | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.order | 15 | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.label | [ClasslessPredicate] ClasslessPredicate foo | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.order | 15 | | Foo.qll:9:21:9:23 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | | Foo.qll:9:21:9:23 | TypeExpr | semmle.order | 16 | | Foo.qll:9:21:9:25 | f | semmle.label | [VarDecl] f | @@ -59,8 +59,8 @@ nodes | Foo.qll:10:69:10:73 | inner | semmle.order | 29 | | Foo.qll:10:69:10:84 | MemberCall | semmle.label | [MemberCall] MemberCall | | Foo.qll:10:69:10:84 | MemberCall | semmle.order | 29 | -| Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.label | [ClasslessPredicate] ClasslessPredicate calls | -| Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.order | 31 | +| Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.label | [ClasslessPredicate] ClasslessPredicate calls | +| Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.order | 31 | | Foo.qll:13:17:13:19 | TypeExpr | semmle.label | [TypeExpr] TypeExpr | | Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 32 | | Foo.qll:13:17:13:21 | f | semmle.label | [VarDecl] f | @@ -239,38 +239,38 @@ nodes edges | Foo.qll:1:1:27:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.label | getAnImport() | | Foo.qll:1:1:27:2 | TopLevel | Foo.qll:1:1:1:17 | Import | semmle.order | 1 | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:1:7:1 | Class Foo | semmle.label | getAClass() | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:1:7:1 | Class Foo | semmle.order | 3 | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.label | getAPredicate() | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:7:11:1 | ClasslessPredicate foo | semmle.order | 15 | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.label | getAPredicate() | -| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:1:27:1 | ClasslessPredicate calls | semmle.order | 31 | -| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | getASuperType() | -| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 | -| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | getCharPred() | -| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.order | 5 | -| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.label | getClassPredicate(_) | -| Foo.qll:3:1:7:1 | Class Foo | Foo.qll:6:3:6:38 | ClassPredicate toString | semmle.order | 9 | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.label | getAClass() | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:3:7:3:9 | Class Foo | semmle.order | 3 | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.label | getAPredicate() | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:9:17:9:19 | ClasslessPredicate foo | semmle.order | 15 | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.label | getAPredicate() | +| Foo.qll:1:1:27:2 | TopLevel | Foo.qll:13:11:13:15 | ClasslessPredicate calls | semmle.order | 31 | +| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.label | getASuperType() | +| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:3:19:3:22 | TypeExpr | semmle.order | 4 | +| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.label | getCharPred() | +| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:4:3:4:17 | CharPred Foo | semmle.order | 5 | +| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:6:10:6:17 | ClassPredicate toString | semmle.label | getClassPredicate(_) | +| Foo.qll:3:7:3:9 | Class Foo | Foo.qll:6:10:6:17 | ClassPredicate toString | semmle.order | 10 | | Foo.qll:4:3:4:17 | CharPred Foo | Foo.qll:4:11:4:15 | ComparisonFormula | semmle.label | getBody() | | Foo.qll:4:3:4:17 | CharPred Foo | Foo.qll:4:11:4:15 | ComparisonFormula | semmle.order | 6 | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:11:4:11 | Integer | semmle.label | getLeftOperand() | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:11:4:11 | Integer | semmle.order | 6 | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:15:4:15 | Integer | semmle.label | getRightOperand() | | Foo.qll:4:11:4:15 | ComparisonFormula | Foo.qll:4:15:4:15 | Integer | semmle.order | 8 | -| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.label | getReturnTypeExpr() | -| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 9 | -| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | getBody() | -| Foo.qll:6:3:6:38 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.order | 11 | +| Foo.qll:6:10:6:17 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.label | getReturnTypeExpr() | +| Foo.qll:6:10:6:17 | ClassPredicate toString | Foo.qll:6:3:6:8 | TypeExpr | semmle.order | 9 | +| Foo.qll:6:10:6:17 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.label | getBody() | +| Foo.qll:6:10:6:17 | ClassPredicate toString | Foo.qll:6:23:6:36 | ComparisonFormula | semmle.order | 11 | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:23:6:28 | result | semmle.label | getLeftOperand() | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:23:6:28 | result | semmle.order | 11 | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:32:6:36 | String | semmle.label | getRightOperand() | | Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:32:6:36 | String | semmle.order | 13 | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.label | getAnAnnotation() | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.order | 14 | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.label | getParameter(_) | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.order | 16 | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.label | getBody() | -| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.order | 18 | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.label | getAnAnnotation() | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.order | 14 | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.label | getParameter(_) | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.order | 16 | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.label | getBody() | +| Foo.qll:9:17:9:19 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.order | 18 | | Foo.qll:9:21:9:25 | f | Foo.qll:9:21:9:23 | TypeExpr | semmle.label | getTypeExpr() | | Foo.qll:9:21:9:25 | f | Foo.qll:9:21:9:23 | TypeExpr | semmle.order | 16 | | Foo.qll:10:3:10:85 | ComparisonFormula | Foo.qll:10:3:10:3 | f | semmle.label | getLeftOperand() | @@ -297,10 +297,10 @@ edges | Foo.qll:10:27:10:50 | ComparisonFormula | Foo.qll:10:46:10:50 | String | semmle.order | 27 | | Foo.qll:10:69:10:84 | MemberCall | Foo.qll:10:69:10:73 | inner | semmle.label | getBase() | | Foo.qll:10:69:10:84 | MemberCall | Foo.qll:10:69:10:73 | inner | semmle.order | 29 | -| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.label | getParameter(_) | -| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.order | 32 | -| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.label | getBody() | -| Foo.qll:13:1:27:1 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.order | 34 | +| Foo.qll:13:11:13:15 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.label | getParameter(_) | +| Foo.qll:13:11:13:15 | ClasslessPredicate calls | Foo.qll:13:17:13:21 | f | semmle.order | 32 | +| Foo.qll:13:11:13:15 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.label | getBody() | +| Foo.qll:13:11:13:15 | ClasslessPredicate calls | Foo.qll:14:3:26:14 | Disjunction | semmle.order | 34 | | Foo.qll:13:17:13:21 | f | Foo.qll:13:17:13:19 | TypeExpr | semmle.label | getTypeExpr() | | Foo.qll:13:17:13:21 | f | Foo.qll:13:17:13:19 | TypeExpr | semmle.order | 32 | | Foo.qll:14:3:14:10 | PredicateCall | Foo.qll:14:9:14:9 | f | semmle.label | getArgument(_) | diff --git a/ql/ql/test/queries/style/AcronymsShouldBeCamelCase/AcronymsShouldBeCamelCase.expected b/ql/ql/test/queries/style/AcronymsShouldBeCamelCase/AcronymsShouldBeCamelCase.expected index bd6bc99489d..de23b92bafa 100644 --- a/ql/ql/test/queries/style/AcronymsShouldBeCamelCase/AcronymsShouldBeCamelCase.expected +++ b/ql/ql/test/queries/style/AcronymsShouldBeCamelCase/AcronymsShouldBeCamelCase.expected @@ -1,3 +1,3 @@ -| Test.qll:2:1:2:27 | ClasslessPredicate isXML | Acronyms in isXML should be PascalCase/camelCase | -| Test.qll:8:1:10:15 | NewType TXMLElements | Acronyms in TXMLElements should be PascalCase/camelCase | -| Test.qll:10:3:10:15 | NewTypeBranch TXMLElement | Acronyms in TXMLElement should be PascalCase/camelCase | +| Test.qll:2:11:2:15 | ClasslessPredicate isXML | Acronyms in isXML should be PascalCase/camelCase | +| Test.qll:8:9:8:20 | NewType TXMLElements | Acronyms in TXMLElements should be PascalCase/camelCase | +| Test.qll:10:3:10:13 | NewTypeBranch TXMLElement | Acronyms in TXMLElement should be PascalCase/camelCase | diff --git a/ql/ql/test/queries/style/DeadCode/DeadCode.expected b/ql/ql/test/queries/style/DeadCode/DeadCode.expected index d3b3115e729..39a2b034390 100644 --- a/ql/ql/test/queries/style/DeadCode/DeadCode.expected +++ b/ql/ql/test/queries/style/DeadCode/DeadCode.expected @@ -1,2 +1,2 @@ -| Foo.qll:2:11:2:38 | ClasslessPredicate dead1 | Code is dead | -| Foo.qll:6:3:6:30 | ClasslessPredicate dead2 | Code is dead | +| Foo.qll:2:21:2:25 | ClasslessPredicate dead1 | Code is dead | +| Foo.qll:6:13:6:17 | ClasslessPredicate dead2 | Code is dead | diff --git a/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected b/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected index f59b21d0d73..2ef0dd4b1ad 100644 --- a/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected +++ b/ql/ql/test/queries/style/MissingOverride/MissingOverride.expected @@ -1 +1 @@ -| Test.qll:12:3:12:33 | ClassPredicate test | Wrong.test overrides $@ but does not have an override annotation. | Test.qll:4:3:4:40 | ClassPredicate test | Super.test | +| Test.qll:12:13:12:16 | ClassPredicate test | Wrong.test overrides $@ but does not have an override annotation. | Test.qll:4:13:4:16 | ClassPredicate test | Super.test | diff --git a/ql/ql/test/queries/style/Misspelling/Misspelling.expected b/ql/ql/test/queries/style/Misspelling/Misspelling.expected index dc028c412d8..65f9f245d3b 100644 --- a/ql/ql/test/queries/style/Misspelling/Misspelling.expected +++ b/ql/ql/test/queries/style/Misspelling/Misspelling.expected @@ -1,6 +1,6 @@ | Test.qll:1:1:3:3 | QLDoc | This QLDoc comment contains the common misspelling 'mispelled', which should instead be 'misspelled'. | -| Test.qll:4:1:11:1 | Class PublicallyAccessible | This class name contains the common misspelling 'publically', which should instead be 'publicly'. | +| Test.qll:4:7:4:26 | Class PublicallyAccessible | This class name contains the common misspelling 'publically', which should instead be 'publicly'. | | Test.qll:5:3:5:20 | FieldDecl | This field name contains the common misspelling 'occurences', which should instead be 'occurrences'. | -| Test.qll:10:3:10:36 | ClassPredicate hasAgrument | This classPredicate name contains the common misspelling 'agrument', which should instead be 'argument'. | +| Test.qll:10:13:10:23 | ClassPredicate hasAgrument | This classPredicate name contains the common misspelling 'agrument', which should instead be 'argument'. | | Test.qll:13:1:16:3 | QLDoc | This QLDoc comment contains the non-US spelling 'colour', which should instead be 'color'. | -| Test.qll:17:1:22:1 | Class AnalysedInt | This class name contains the non-US spelling 'analysed', which should instead be 'analyzed'. | +| Test.qll:17:7:17:17 | Class AnalysedInt | This class name contains the non-US spelling 'analysed', which should instead be 'analyzed'. | diff --git a/ql/ql/test/type/type.expected b/ql/ql/test/type/type.expected index 773a9244a22..fd3a34c27f6 100644 --- a/ql/ql/test/type/type.expected +++ b/ql/ql/test/type/type.expected @@ -1,6 +1,6 @@ -| Test.qll:4:15:4:18 | this | Test.qll:3:1:5:1 | Strings | -| Test.qll:4:15:4:18 | this | Test.qll:3:1:5:1 | Strings.Strings | -| Test.qll:4:15:4:18 | this | Test.qll:3:1:5:1 | Strings.extends | +| Test.qll:4:15:4:18 | this | Test.qll:3:7:3:13 | Strings | +| Test.qll:4:15:4:18 | this | Test.qll:3:7:3:13 | Strings.Strings | +| Test.qll:4:15:4:18 | this | Test.qll:3:7:3:13 | Strings.extends | | Test.qll:4:22:4:76 | Set | file://:0:0:0:0 | string | | Test.qll:4:23:4:24 | String | file://:0:0:0:0 | string | | Test.qll:4:27:4:29 | String | file://:0:0:0:0 | string | @@ -12,9 +12,9 @@ | Test.qll:4:61:4:63 | String | file://:0:0:0:0 | string | | Test.qll:4:66:4:69 | String | file://:0:0:0:0 | string | | Test.qll:4:72:4:75 | String | file://:0:0:0:0 | string | -| Test.qll:8:14:8:17 | this | Test.qll:7:1:9:1 | Floats | -| Test.qll:8:14:8:17 | this | Test.qll:7:1:9:1 | Floats.Floats | -| Test.qll:8:14:8:17 | this | Test.qll:7:1:9:1 | Floats.extends | +| Test.qll:8:14:8:17 | this | Test.qll:7:7:7:12 | Floats | +| Test.qll:8:14:8:17 | this | Test.qll:7:7:7:12 | Floats.Floats | +| Test.qll:8:14:8:17 | this | Test.qll:7:7:7:12 | Floats.extends | | Test.qll:8:21:8:70 | Set | file://:0:0:0:0 | float | | Test.qll:8:22:8:24 | Float | file://:0:0:0:0 | float | | Test.qll:8:27:8:29 | Float | file://:0:0:0:0 | float | @@ -27,28 +27,28 @@ | Test.qll:8:62:8:64 | Float | file://:0:0:0:0 | float | | Test.qll:8:67:8:69 | Float | file://:0:0:0:0 | float | | Test.qll:11:37:11:42 | result | file://:0:0:0:0 | string | -| Test.qll:11:46:11:46 | a | Test.qll:3:1:5:1 | Strings | +| Test.qll:11:46:11:46 | a | Test.qll:3:7:3:13 | Strings | | Test.qll:11:46:11:50 | AddExpr | file://:0:0:0:0 | string | -| Test.qll:11:50:11:50 | b | Test.qll:3:1:5:1 | Strings | +| Test.qll:11:50:11:50 | b | Test.qll:3:7:3:13 | Strings | | Test.qll:13:36:13:41 | result | file://:0:0:0:0 | float | -| Test.qll:13:45:13:45 | a | Test.qll:7:1:9:1 | Floats | +| Test.qll:13:45:13:45 | a | Test.qll:7:7:7:12 | Floats | | Test.qll:13:45:13:49 | AddExpr | file://:0:0:0:0 | float | -| Test.qll:13:49:13:49 | b | Test.qll:7:1:9:1 | Floats | -| Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base | -| Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base.Base | -| Test.qll:16:12:16:15 | this | Test.qll:15:1:19:1 | Base.extends | +| Test.qll:13:49:13:49 | b | Test.qll:7:7:7:12 | Floats | +| Test.qll:16:12:16:15 | this | Test.qll:15:7:15:10 | Base | +| Test.qll:16:12:16:15 | this | Test.qll:15:7:15:10 | Base.Base | +| Test.qll:16:12:16:15 | this | Test.qll:15:7:15:10 | Base.extends | | Test.qll:16:19:16:23 | String | file://:0:0:0:0 | string | | Test.qll:18:15:18:20 | result | file://:0:0:0:0 | int | | Test.qll:18:24:18:24 | Integer | file://:0:0:0:0 | int | -| Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub | -| Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub.Sub | -| Test.qll:22:11:22:14 | this | Test.qll:21:1:27:1 | Sub.extends | +| Test.qll:22:11:22:14 | this | Test.qll:21:7:21:9 | Sub | +| Test.qll:22:11:22:14 | this | Test.qll:21:7:21:9 | Sub.Sub | +| Test.qll:22:11:22:14 | this | Test.qll:21:7:21:9 | Sub.extends | | Test.qll:22:18:22:22 | String | file://:0:0:0:0 | string | | Test.qll:24:15:24:20 | result | file://:0:0:0:0 | int | -| Test.qll:24:24:24:33 | Super | Test.qll:15:1:19:1 | Base | +| Test.qll:24:24:24:33 | Super | Test.qll:15:7:15:10 | Base | | Test.qll:24:24:24:39 | MemberCall | file://:0:0:0:0 | int | | Test.qll:26:16:26:21 | result | file://:0:0:0:0 | int | -| Test.qll:26:25:26:29 | Super | Test.qll:15:1:19:1 | Base | +| Test.qll:26:25:26:29 | Super | Test.qll:15:7:15:10 | Base | | Test.qll:26:25:26:35 | MemberCall | file://:0:0:0:0 | int | | Test.qll:30:32:30:37 | result | file://:0:0:0:0 | int | | Test.qll:30:41:30:41 | a | file://:0:0:0:0 | int | From 8f259d4bb6a774a088b7468493cfafd6660c41dc Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 30 May 2022 14:10:34 +0200 Subject: [PATCH 065/465] Python: port API graph doc comment --- python/ql/lib/semmle/python/ApiGraphs.qll | 77 ++++++++++++++++++++++- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index fcb89e5f866..16fa18adea0 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -12,12 +12,83 @@ import semmle.python.dataflow.new.DataFlow private import semmle.python.internal.CachedStages /** - * Provides classes and predicates for working with APIs used in a database. + * Provides classes and predicates for working with the API boundary between the current + * codebase and external libraries. + * + * See `API::Node` for more in-depth documentation. */ module API { /** - * An abstract representation of a definition or use of an API component such as a function - * exported by a Python package, or its result. + * A node in the API graph, representing a value that has crossed the boundary between this + * codebase and an external library (or in general, any external codebase). + * + * ### Basic usage + * + * API graphs are typically used to identify "API calls", that is, calls to an external function + * whose implementation is not necessarily part of the current codebase. + * + * The most basic use of API graphs is typically as follows: + * 1. Start with `API::moduleImport` for the relevant library. + * 2. Follow up with a chain of accessors such as `getMember` describing how to get to the relevant API function. + * 3. Map the resulting API graph nodes to data-flow nodes, using `asSource` or `asSink`. + * + * For example, a simplified way to get arguments to `json.dumps` would be + * ```ql + * API::moduleImport("json").getMember("dumps").getParameter(0).asSink() + * ``` + * + * The most commonly used accessors are `getMember`, `getParameter`, and `getReturn`. + * + * ### API graph nodes + * + * There are two kinds of nodes in the API graphs, distinguished by who is "holding" the value: + * - **Use-nodes** represent values held by the current codebase, which came from an external library. + * (The current codebase is "using" a value that came from the library). + * - **Def-nodes** represent values held by the external library, which came from this codebase. + * (The current codebase "defines" the value seen by the library). + * + * API graph nodes are associated with data-flow nodes in the current codebase. + * (Since external libraries are not part of the database, there is no way to associate with concrete + * data-flow nodes from the external library). + * - **Use-nodes** are associated with data-flow nodes where a value enters the current codebase, + * such as the return value of a call to an external function. + * - **Def-nodes** are associated with data-flow nodes where a value leaves the current codebase, + * such as an argument passed in a call to an external function. + * + * + * ### Access paths and edge labels + * + * Nodes in the API graph are associated with a set of access paths, describing a series of operations + * that may be performed to obtain that value. + * + * For example, the access path `API::moduleImport("json").getMember("dumps")` represents the action of + * importing `json` and then accessing the member `dumps` on the resulting object. + * + * Each edge in the graph is labelled by such an "operation". For an edge `A->B`, the type of the `A` node + * determines who is performing the operation, and the type of the `B` node determines who ends up holding + * the result: + * - An edge starting from a use-node describes what the current codebase is doing to a value that + * came from a library. + * - An edge starting from a def-node describes what the external library might do to a value that + * came from the current codebase. + * - An edge ending in a use-node means the result ends up in the current codebase (at its associated data-flow node). + * - An edge ending in a def-node means the result ends up in external code (its associated data-flow node is + * the place where it was "last seen" in the current codebase before flowing out) + * + * Because the implementation of the external library is not visible, it is not known exactly what operations + * it will perform on values that flow there. Instead, the edges starting from a def-node are operations that would + * lead to an observable effect within the current codebase; without knowing for certain if the library will actually perform + * those operations. (When constructing these edges, we assume the library is somewhat well-behaved). + * + * For example, given this snippet: + * ```python + * import foo + * foo.bar(lambda x: doSomething(x)) + * ``` + * A callback is passed to the external function `foo.bar`. We can't know if `foo.bar` will actually invoke this callback. + * But _if_ the library should decide to invoke the callback, then a value will flow into the current codebase via the `x` parameter. + * For that reason, an edge is generated representing the argument-passing operation that might be performed by `foo.bar`. + * This edge is going from the def-node associated with the callback to the use-node associated with the parameter `x`. */ class Node extends Impl::TApiNode { /** From 60fde3c031e4b3c2f1c92bd91c23a459daa1bab4 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 13 Jun 2022 09:56:10 +0200 Subject: [PATCH 066/465] Python: Rename getARhs -> asSink --- python/ql/lib/semmle/python/ApiGraphs.qll | 10 +++++----- python/ql/lib/semmle/python/frameworks/Aiomysql.qll | 4 ++-- python/ql/lib/semmle/python/frameworks/Aiopg.qll | 4 ++-- python/ql/lib/semmle/python/frameworks/Asyncpg.qll | 4 ++-- python/ql/lib/semmle/python/frameworks/Requests.qll | 2 +- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 12 ++++++------ .../semmle/python/frameworks/data/ModelsAsData.qll | 2 +- .../dataflow/PathInjectionCustomizations.qll | 2 +- .../security/dataflow/SqlInjectionCustomizations.qll | 2 +- python/ql/test/TestUtilities/VerifyApiGraphs.qll | 2 +- python/ql/test/experimental/meta/MaDTest.qll | 2 +- python/ql/test/library-tests/frameworks/data/test.ql | 4 ++-- 12 files changed, 25 insertions(+), 25 deletions(-) diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index 16fa18adea0..9be1419f230 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -128,13 +128,13 @@ module API { * ``` * `x` is the right-hand side of a definition of the first parameter of `bar` from the `mypkg.foo` module. */ - DataFlow::Node getARhs() { Impl::rhs(this, result) } + DataFlow::Node asSink() { Impl::rhs(this, result) } /** * Gets a data-flow node that may interprocedurally flow to the right-hand side of a definition * of the API component represented by this node. */ - DataFlow::Node getAValueReachingRhs() { result = Impl::trackDefNode(this.getARhs()) } + DataFlow::Node getAValueReachingRhs() { result = Impl::trackDefNode(this.asSink()) } /** * Gets an immediate use of the API component represented by this node. @@ -390,14 +390,14 @@ module API { * Gets an API node where a RHS of the node is the `i`th argument to this call. */ pragma[noinline] - private Node getAParameterCandidate(int i) { result.getARhs() = this.getArg(i) } + private Node getAParameterCandidate(int i) { result.asSink() = this.getArg(i) } /** Gets the API node for a parameter of this invocation. */ Node getAParameter() { result = this.getParameter(_) } /** Gets the object that this method-call is being called on, if this is a method-call */ Node getSelfParameter() { - result.getARhs() = this.(DataFlow::MethodCallNode).getObject() and + result.asSink() = this.(DataFlow::MethodCallNode).getObject() and result = callee.getSelfParameter() } @@ -417,7 +417,7 @@ module API { pragma[noinline] private Node getAKeywordParameterCandidate(string name) { - result.getARhs() = this.getArgByName(name) + result.asSink() = this.getArgByName(name) } /** Gets the API node for the return value of this call. */ diff --git a/python/ql/lib/semmle/python/frameworks/Aiomysql.qll b/python/ql/lib/semmle/python/frameworks/Aiomysql.qll index fdcf21afc34..aa676e8fe82 100644 --- a/python/ql/lib/semmle/python/frameworks/Aiomysql.qll +++ b/python/ql/lib/semmle/python/frameworks/Aiomysql.qll @@ -53,7 +53,7 @@ private module Aiomysql { class CursorExecuteCall extends SqlConstruction::Range, API::CallNode { CursorExecuteCall() { this = cursor().getMember("execute").getACall() } - override DataFlow::Node getSql() { result = this.getParameter(0, "operation").getARhs() } + override DataFlow::Node getSql() { result = this.getParameter(0, "operation").asSink() } } /** @@ -94,7 +94,7 @@ private module Aiomysql { class SAConnectionExecuteCall extends SqlConstruction::Range, API::CallNode { SAConnectionExecuteCall() { this = saConnection().getMember("execute").getACall() } - override DataFlow::Node getSql() { result = this.getParameter(0, "query").getARhs() } + override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() } } /** diff --git a/python/ql/lib/semmle/python/frameworks/Aiopg.qll b/python/ql/lib/semmle/python/frameworks/Aiopg.qll index afc553fe04b..27c754fb344 100644 --- a/python/ql/lib/semmle/python/frameworks/Aiopg.qll +++ b/python/ql/lib/semmle/python/frameworks/Aiopg.qll @@ -53,7 +53,7 @@ private module Aiopg { class CursorExecuteCall extends SqlConstruction::Range, API::CallNode { CursorExecuteCall() { this = cursor().getMember("execute").getACall() } - override DataFlow::Node getSql() { result = this.getParameter(0, "operation").getARhs() } + override DataFlow::Node getSql() { result = this.getParameter(0, "operation").asSink() } } /** @@ -90,7 +90,7 @@ private module Aiopg { class SAConnectionExecuteCall extends SqlConstruction::Range, API::CallNode { SAConnectionExecuteCall() { this = saConnection().getMember("execute").getACall() } - override DataFlow::Node getSql() { result = this.getParameter(0, "query").getARhs() } + override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() } } /** diff --git a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll index 81da12a015c..26361366022 100644 --- a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll +++ b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll @@ -61,7 +61,7 @@ private module Asyncpg { this = ModelOutput::getATypeNode("asyncpg", "Connection").getMember("cursor").getACall() } - override DataFlow::Node getSql() { result = this.getParameter(0, "query").getARhs() } + override DataFlow::Node getSql() { result = this.getParameter(0, "query").asSink() } } /** The creation of a `Cursor` executes the associated query. */ @@ -78,7 +78,7 @@ private module Asyncpg { prepareCall = ModelOutput::getATypeNode("asyncpg", "Connection").getMember("prepare").getACall() | - sql = prepareCall.getParameter(0, "query").getARhs() and + sql = prepareCall.getParameter(0, "query").asSink() and this = prepareCall .getReturn() diff --git a/python/ql/lib/semmle/python/frameworks/Requests.qll b/python/ql/lib/semmle/python/frameworks/Requests.qll index 6c9028d6135..05e08b45166 100644 --- a/python/ql/lib/semmle/python/frameworks/Requests.qll +++ b/python/ql/lib/semmle/python/frameworks/Requests.qll @@ -61,7 +61,7 @@ private module Requests { override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { - disablingNode = this.getKeywordParameter("verify").getARhs() and + disablingNode = this.getKeywordParameter("verify").asSink() and argumentOrigin = this.getKeywordParameter("verify").getAValueReachingRhs() and // requests treats `None` as the default and all other "falsey" values as `False`. argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false and diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index a273511979c..bb1b6073d16 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -2553,7 +2553,7 @@ private module StdlibPrivate { override DataFlow::Node getAPathArgument() { result = super.getAPathArgument() or - result = this.getParameter(0, "target").getARhs() + result = this.getParameter(0, "target").asSink() } } @@ -2570,7 +2570,7 @@ private module StdlibPrivate { override DataFlow::Node getAPathArgument() { result = super.getAPathArgument() or - result = this.getParameter(0, "target").getARhs() + result = this.getParameter(0, "target").asSink() } } @@ -2585,7 +2585,7 @@ private module StdlibPrivate { override DataFlow::Node getAPathArgument() { result = super.getAPathArgument() or - result = this.getParameter(0, "other_path").getARhs() + result = this.getParameter(0, "other_path").asSink() } } @@ -2670,7 +2670,7 @@ private module StdlibPrivate { override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) } - override DataFlow::Node getAnInput() { result = this.getParameter(1, "data").getARhs() } + override DataFlow::Node getAnInput() { result = this.getParameter(1, "data").asSink() } override Cryptography::BlockMode getBlockMode() { none() } } @@ -3433,7 +3433,7 @@ private module StdlibPrivate { private DataFlow::Node saxParserWithFeatureExternalGesTurnedOn(DataFlow::TypeTracker t) { t.start() and exists(SaxParserSetFeatureCall call | - call.getFeatureArg().getARhs() = + call.getFeatureArg().asSink() = API::moduleImport("xml") .getMember("sax") .getMember("handler") @@ -3449,7 +3449,7 @@ private module StdlibPrivate { // take account of that we can set the feature to False, which makes the parser safe again not exists(SaxParserSetFeatureCall call | call.getObject() = result and - call.getFeatureArg().getARhs() = + call.getFeatureArg().asSink() = API::moduleImport("xml") .getMember("sax") .getMember("handler") diff --git a/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll b/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll index 2af91a69432..e80e9f7ad0b 100644 --- a/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll +++ b/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll @@ -34,7 +34,7 @@ private class RemoteFlowSourceFromCsv extends RemoteFlowSource { private predicate summaryStepNodes(DataFlow::Node pred, DataFlow::Node succ, string kind) { exists(API::Node predNode, API::Node succNode | Specific::summaryStep(predNode, succNode, kind) and - pred = predNode.getARhs() and + pred = predNode.asSink() and succ = succNode.getAnImmediateUse() ) } diff --git a/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll index 5a033664823..fe7053ef4d2 100644 --- a/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/PathInjectionCustomizations.qll @@ -62,7 +62,7 @@ module PathInjection { private import semmle.python.frameworks.data.ModelsAsData private class DataAsFileSink extends Sink { - DataAsFileSink() { this = ModelOutput::getASinkNode("path-injection").getARhs() } + DataAsFileSink() { this = ModelOutput::getASinkNode("path-injection").asSink() } } /** diff --git a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll index cf21a5c0e94..ae011c00f11 100644 --- a/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/SqlInjectionCustomizations.qll @@ -65,6 +65,6 @@ module SqlInjection { /** A sink for sql-injection from model data. */ private class DataAsSqlSink extends Sink { - DataAsSqlSink() { this = ModelOutput::getASinkNode("sql-injection").getARhs() } + DataAsSqlSink() { this = ModelOutput::getASinkNode("sql-injection").asSink() } } } diff --git a/python/ql/test/TestUtilities/VerifyApiGraphs.qll b/python/ql/test/TestUtilities/VerifyApiGraphs.qll index 22d7ae365d4..03af20dbabe 100644 --- a/python/ql/test/TestUtilities/VerifyApiGraphs.qll +++ b/python/ql/test/TestUtilities/VerifyApiGraphs.qll @@ -21,7 +21,7 @@ import semmle.python.ApiGraphs private DataFlow::Node getNode(API::Node nd, string kind) { kind = "def" and - result = nd.getARhs() + result = nd.asSink() or kind = "use" and result = nd.getAUse() diff --git a/python/ql/test/experimental/meta/MaDTest.qll b/python/ql/test/experimental/meta/MaDTest.qll index 3d75ba0d2e7..92b8afef422 100644 --- a/python/ql/test/experimental/meta/MaDTest.qll +++ b/python/ql/test/experimental/meta/MaDTest.qll @@ -19,7 +19,7 @@ class MadSinkTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(DataFlow::Node sink, string kind | - sink = ModelOutput::getASinkNode(kind).getARhs() and + sink = ModelOutput::getASinkNode(kind).asSink() and location = sink.getLocation() and element = sink.toString() and value = prettyNodeForInlineTest(sink) and diff --git a/python/ql/test/library-tests/frameworks/data/test.ql b/python/ql/test/library-tests/frameworks/data/test.ql index 86f960b1adf..c1bc85eaf49 100644 --- a/python/ql/test/library-tests/frameworks/data/test.ql +++ b/python/ql/test/library-tests/frameworks/data/test.ql @@ -91,7 +91,7 @@ class BasicTaintTracking extends TaintTracking::Configuration { } override predicate isSink(DataFlow::Node sink) { - sink = ModelOutput::getASinkNode("test-sink").getARhs() + sink = ModelOutput::getASinkNode("test-sink").asSink() } } @@ -100,7 +100,7 @@ query predicate taintFlow(DataFlow::Node source, DataFlow::Node sink) { } query predicate isSink(DataFlow::Node node, string kind) { - node = ModelOutput::getASinkNode(kind).getARhs() + node = ModelOutput::getASinkNode(kind).asSink() } query predicate isSource(DataFlow::Node node, string kind) { From 181a53bd03837c620feb63aa68145fa0e58bbc9f Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 13 Jun 2022 09:59:24 +0200 Subject: [PATCH 067/465] Python: Rename getAnImmediateUse -> asSource --- python/ql/lib/semmle/python/ApiGraphs.qll | 8 ++++---- python/ql/lib/semmle/python/filters/Tests.qll | 2 +- python/ql/lib/semmle/python/frameworks/Aiohttp.qll | 4 +--- .../ql/lib/semmle/python/frameworks/Aiomysql.qll | 4 ++-- python/ql/lib/semmle/python/frameworks/Aiopg.qll | 4 ++-- python/ql/lib/semmle/python/frameworks/Asyncpg.qll | 4 ++-- .../lib/semmle/python/frameworks/Cryptography.qll | 4 +--- python/ql/lib/semmle/python/frameworks/Django.qll | 14 ++++++-------- python/ql/lib/semmle/python/frameworks/FastApi.qll | 2 +- python/ql/lib/semmle/python/frameworks/Flask.qll | 14 ++++++-------- .../semmle/python/frameworks/FlaskSqlAlchemy.qll | 4 ++-- .../lib/semmle/python/frameworks/RestFramework.qll | 2 +- python/ql/lib/semmle/python/frameworks/Stdlib.qll | 12 ++++++------ python/ql/lib/semmle/python/frameworks/Tornado.qll | 2 +- python/ql/lib/semmle/python/frameworks/Twisted.qll | 2 +- .../semmle/python/frameworks/data/ModelsAsData.qll | 4 ++-- .../python/frameworks/internal/SubclassFinder.qll | 2 +- python/ql/lib/semmle/python/regex.qll | 2 +- .../dataflow/typetracking/moduleattr.ql | 2 +- .../experimental/dataflow/typetracking/tracked.ql | 6 +++--- python/ql/test/experimental/meta/MaDTest.qll | 2 +- .../ql/test/library-tests/frameworks/data/test.ql | 4 ++-- 22 files changed, 48 insertions(+), 56 deletions(-) diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index 9be1419f230..61a42f812a7 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -147,12 +147,12 @@ module API { * to the `escape` member of `re`, neither `x` nor any node that `x` flows to is a reference to * this API component. */ - DataFlow::LocalSourceNode getAnImmediateUse() { Impl::use(this, result) } + DataFlow::LocalSourceNode asSource() { Impl::use(this, result) } /** * Gets a call to the function represented by this API component. */ - CallNode getACall() { result = this.getReturn().getAnImmediateUse() } + CallNode getACall() { result = this.getReturn().asSource() } /** * Gets a node representing member `m` of this API component. @@ -377,7 +377,7 @@ module API { class CallNode extends DataFlow::CallCfgNode { API::Node callee; - CallNode() { this = callee.getReturn().getAnImmediateUse() } + CallNode() { this = callee.getReturn().asSource() } /** Gets the API node for the `i`th parameter of this invocation. */ pragma[nomagic] @@ -423,7 +423,7 @@ module API { /** Gets the API node for the return value of this call. */ Node getReturn() { result = callee.getReturn() and - result.getAnImmediateUse() = this + result.asSource() = this } /** diff --git a/python/ql/lib/semmle/python/filters/Tests.qll b/python/ql/lib/semmle/python/filters/Tests.qll index 44ea2edebe4..20f6713a837 100644 --- a/python/ql/lib/semmle/python/filters/Tests.qll +++ b/python/ql/lib/semmle/python/filters/Tests.qll @@ -9,7 +9,7 @@ class UnitTestClass extends TestScope, Class { testCaseString.matches("%TestCase") and testCaseClass = any(API::Node mod).getMember(testCaseString) | - this.getParent() = testCaseClass.getASubclass*().getAnImmediateUse().asExpr() + this.getParent() = testCaseClass.getASubclass*().asSource().asExpr() ) } } diff --git a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll index 359c8c14159..733845de30b 100644 --- a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll @@ -243,9 +243,7 @@ module AiohttpWebModel { /** A class that has a super-type which is an aiohttp.web View class. */ class AiohttpViewClassFromSuperClass extends AiohttpViewClass { - AiohttpViewClassFromSuperClass() { - this.getParent() = View::subclassRef().getAnImmediateUse().asExpr() - } + AiohttpViewClassFromSuperClass() { this.getParent() = View::subclassRef().asSource().asExpr() } } /** A class that is used in a route-setup, therefore being considered an aiohttp.web View class. */ diff --git a/python/ql/lib/semmle/python/frameworks/Aiomysql.qll b/python/ql/lib/semmle/python/frameworks/Aiomysql.qll index aa676e8fe82..3d43c13b91a 100644 --- a/python/ql/lib/semmle/python/frameworks/Aiomysql.qll +++ b/python/ql/lib/semmle/python/frameworks/Aiomysql.qll @@ -63,7 +63,7 @@ private module Aiomysql { class AwaitedCursorExecuteCall extends SqlExecution::Range { CursorExecuteCall executeCall; - AwaitedCursorExecuteCall() { this = executeCall.getReturn().getAwaited().getAnImmediateUse() } + AwaitedCursorExecuteCall() { this = executeCall.getReturn().getAwaited().asSource() } override DataFlow::Node getSql() { result = executeCall.getSql() } } @@ -104,7 +104,7 @@ private module Aiomysql { class AwaitedSAConnectionExecuteCall extends SqlExecution::Range { SAConnectionExecuteCall execute; - AwaitedSAConnectionExecuteCall() { this = execute.getReturn().getAwaited().getAnImmediateUse() } + AwaitedSAConnectionExecuteCall() { this = execute.getReturn().getAwaited().asSource() } override DataFlow::Node getSql() { result = execute.getSql() } } diff --git a/python/ql/lib/semmle/python/frameworks/Aiopg.qll b/python/ql/lib/semmle/python/frameworks/Aiopg.qll index 27c754fb344..053d59df51a 100644 --- a/python/ql/lib/semmle/python/frameworks/Aiopg.qll +++ b/python/ql/lib/semmle/python/frameworks/Aiopg.qll @@ -63,7 +63,7 @@ private module Aiopg { class AwaitedCursorExecuteCall extends SqlExecution::Range { CursorExecuteCall execute; - AwaitedCursorExecuteCall() { this = execute.getReturn().getAwaited().getAnImmediateUse() } + AwaitedCursorExecuteCall() { this = execute.getReturn().getAwaited().asSource() } override DataFlow::Node getSql() { result = execute.getSql() } } @@ -100,7 +100,7 @@ private module Aiopg { class AwaitedSAConnectionExecuteCall extends SqlExecution::Range { SAConnectionExecuteCall excute; - AwaitedSAConnectionExecuteCall() { this = excute.getReturn().getAwaited().getAnImmediateUse() } + AwaitedSAConnectionExecuteCall() { this = excute.getReturn().getAwaited().asSource() } override DataFlow::Node getSql() { result = excute.getSql() } } diff --git a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll index 26361366022..ca28dca550f 100644 --- a/python/ql/lib/semmle/python/frameworks/Asyncpg.qll +++ b/python/ql/lib/semmle/python/frameworks/Asyncpg.qll @@ -71,7 +71,7 @@ private module Asyncpg { CursorCreation() { exists(CursorConstruction c | sql = c.getSql() and - this = c.getReturn().getAwaited().getAnImmediateUse() + this = c.getReturn().getAwaited().asSource() ) or exists(API::CallNode prepareCall | @@ -86,7 +86,7 @@ private module Asyncpg { .getMember("cursor") .getReturn() .getAwaited() - .getAnImmediateUse() + .asSource() ) } diff --git a/python/ql/lib/semmle/python/frameworks/Cryptography.qll b/python/ql/lib/semmle/python/frameworks/Cryptography.qll index 954def9e7da..1520f17e883 100644 --- a/python/ql/lib/semmle/python/frameworks/Cryptography.qll +++ b/python/ql/lib/semmle/python/frameworks/Cryptography.qll @@ -144,9 +144,7 @@ private module CryptographyModel { DataFlow::Node getCurveArg() { result in [this.getArg(0), this.getArgByName("curve")] } override int getKeySizeWithOrigin(DataFlow::Node origin) { - exists(API::Node n | - n = Ecc::predefinedCurveClass(result) and origin = n.getAnImmediateUse() - | + exists(API::Node n | n = Ecc::predefinedCurveClass(result) and origin = n.asSource() | this.getCurveArg() = n.getAUse() or this.getCurveArg() = n.getReturn().getAUse() diff --git a/python/ql/lib/semmle/python/frameworks/Django.qll b/python/ql/lib/semmle/python/frameworks/Django.qll index a22957d1fe0..a955de7a01a 100644 --- a/python/ql/lib/semmle/python/frameworks/Django.qll +++ b/python/ql/lib/semmle/python/frameworks/Django.qll @@ -562,7 +562,7 @@ module PrivateDjango { /** A `django.db.connection` is a PEP249 compliant DB connection. */ class DjangoDbConnection extends PEP249::Connection::InstanceSource { - DjangoDbConnection() { this = connection().getAnImmediateUse() } + DjangoDbConnection() { this = connection().asSource() } } // ------------------------------------------------------------------------- @@ -869,7 +869,7 @@ module PrivateDjango { /** Gets the (AST) class of the Django model class `modelClass`. */ Class getModelClassClass(API::Node modelClass) { - result.getParent() = modelClass.getAnImmediateUse().asExpr() and + result.getParent() = modelClass.asSource().asExpr() and modelClass = Model::subclassRef() } @@ -2202,9 +2202,7 @@ module PrivateDjango { * thereby handling user input. */ class DjangoFormClass extends Class, SelfRefMixin { - DjangoFormClass() { - this.getParent() = Django::Forms::Form::subclassRef().getAnImmediateUse().asExpr() - } + DjangoFormClass() { this.getParent() = Django::Forms::Form::subclassRef().asSource().asExpr() } } /** @@ -2237,7 +2235,7 @@ module PrivateDjango { */ class DjangoFormFieldClass extends Class { DjangoFormFieldClass() { - this.getParent() = Django::Forms::Field::subclassRef().getAnImmediateUse().asExpr() + this.getParent() = Django::Forms::Field::subclassRef().asSource().asExpr() } } @@ -2340,7 +2338,7 @@ module PrivateDjango { */ class DjangoViewClassFromSuperClass extends DjangoViewClass { DjangoViewClassFromSuperClass() { - this.getParent() = Django::Views::View::subclassRef().getAnImmediateUse().asExpr() + this.getParent() = Django::Views::View::subclassRef().asSource().asExpr() } } @@ -2743,7 +2741,7 @@ module PrivateDjango { .getMember("utils") .getMember("log") .getMember("request_logger") - .getAnImmediateUse() + .asSource() } } diff --git a/python/ql/lib/semmle/python/frameworks/FastApi.qll b/python/ql/lib/semmle/python/frameworks/FastApi.qll index 1c48562eb70..3a683108f4c 100644 --- a/python/ql/lib/semmle/python/frameworks/FastApi.qll +++ b/python/ql/lib/semmle/python/frameworks/FastApi.qll @@ -166,7 +166,7 @@ private module FastApi { exists(Class cls, API::Node base | base = getModeledResponseClass(_).getASubclass*() and cls.getABase() = base.getAUse().asExpr() and - responseClass.getAnImmediateUse().asExpr() = cls.getParent() + responseClass.asSource().asExpr() = cls.getParent() | exists(Assign assign | assign = cls.getAStmt() | assign.getATarget().(Name).getId() = "media_type" and diff --git a/python/ql/lib/semmle/python/frameworks/Flask.qll b/python/ql/lib/semmle/python/frameworks/Flask.qll index 02331ed316e..8df9295c285 100644 --- a/python/ql/lib/semmle/python/frameworks/Flask.qll +++ b/python/ql/lib/semmle/python/frameworks/Flask.qll @@ -195,7 +195,7 @@ module Flask { FlaskViewClass() { api_node = Views::View::subclassRef() and - this.getParent() = api_node.getAnImmediateUse().asExpr() + this.getParent() = api_node.asSource().asExpr() } /** Gets a function that could handle incoming requests, if any. */ @@ -220,7 +220,7 @@ module Flask { class FlaskMethodViewClass extends FlaskViewClass { FlaskMethodViewClass() { api_node = Views::MethodView::subclassRef() and - this.getParent() = api_node.getAnImmediateUse().asExpr() + this.getParent() = api_node.asSource().asExpr() } override Function getARequestHandler() { @@ -404,7 +404,7 @@ module Flask { private class RequestAttrMultiDict extends Werkzeug::MultiDict::InstanceSource { RequestAttrMultiDict() { - this = request().getMember(["args", "values", "form", "files"]).getAnImmediateUse() + this = request().getMember(["args", "values", "form", "files"]).asSource() } } @@ -427,14 +427,12 @@ module Flask { /** An `Headers` instance that originates from a flask request. */ private class FlaskRequestHeadersInstances extends Werkzeug::Headers::InstanceSource { - FlaskRequestHeadersInstances() { this = request().getMember("headers").getAnImmediateUse() } + FlaskRequestHeadersInstances() { this = request().getMember("headers").asSource() } } /** An `Authorization` instance that originates from a flask request. */ private class FlaskRequestAuthorizationInstances extends Werkzeug::Authorization::InstanceSource { - FlaskRequestAuthorizationInstances() { - this = request().getMember("authorization").getAnImmediateUse() - } + FlaskRequestAuthorizationInstances() { this = request().getMember("authorization").asSource() } } // --------------------------------------------------------------------------- @@ -574,6 +572,6 @@ module Flask { * - https://flask.palletsprojects.com/en/2.0.x/logging/ */ private class FlaskLogger extends Stdlib::Logger::InstanceSource { - FlaskLogger() { this = FlaskApp::instance().getMember("logger").getAnImmediateUse() } + FlaskLogger() { this = FlaskApp::instance().getMember("logger").asSource() } } } diff --git a/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll b/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll index 6269baee9d5..535e32426b2 100644 --- a/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll +++ b/python/ql/lib/semmle/python/frameworks/FlaskSqlAlchemy.qll @@ -35,7 +35,7 @@ private module FlaskSqlAlchemy { /** Access on a DB resulting in an Engine */ private class DbEngine extends SqlAlchemy::Engine::InstanceSource { DbEngine() { - this = dbInstance().getMember("engine").getAnImmediateUse() + this = dbInstance().getMember("engine").asSource() or this = dbInstance().getMember("get_engine").getACall() } @@ -44,7 +44,7 @@ private module FlaskSqlAlchemy { /** Access on a DB resulting in a Session */ private class DbSession extends SqlAlchemy::Session::InstanceSource { DbSession() { - this = dbInstance().getMember("session").getAnImmediateUse() + this = dbInstance().getMember("session").asSource() or this = dbInstance().getMember("create_session").getReturn().getACall() or diff --git a/python/ql/lib/semmle/python/frameworks/RestFramework.qll b/python/ql/lib/semmle/python/frameworks/RestFramework.qll index 61f031576de..c8f73f909c2 100644 --- a/python/ql/lib/semmle/python/frameworks/RestFramework.qll +++ b/python/ql/lib/semmle/python/frameworks/RestFramework.qll @@ -115,7 +115,7 @@ private module RestFramework { */ class RestFrameworkApiViewClass extends PrivateDjango::DjangoViewClassFromSuperClass { RestFrameworkApiViewClass() { - this.getParent() = any(ModeledApiViewClasses c).getASubclass*().getAnImmediateUse().asExpr() + this.getParent() = any(ModeledApiViewClasses c).getASubclass*().asSource().asExpr() } override Function getARequestHandler() { diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index bb1b6073d16..b0629d94b2c 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -274,7 +274,7 @@ module Stdlib { ClassInstantiation() { this = subclassRef().getACall() or - this = API::moduleImport("logging").getMember("root").getAnImmediateUse() + this = API::moduleImport("logging").getMember("root").asSource() or this = API::moduleImport("logging").getMember("getLogger").getACall() } @@ -1767,11 +1767,11 @@ private module StdlibPrivate { or nodeFrom.asCfgNode() = nodeTo.asCfgNode().(CallNode).getFunction() and ( - nodeFrom = getvalueRef().getAUse() and nodeTo = getvalueResult().getAnImmediateUse() + nodeFrom = getvalueRef().getAUse() and nodeTo = getvalueResult().asSource() or - nodeFrom = getfirstRef().getAUse() and nodeTo = getfirstResult().getAnImmediateUse() + nodeFrom = getfirstRef().getAUse() and nodeTo = getfirstResult().asSource() or - nodeFrom = getlistRef().getAUse() and nodeTo = getlistResult().getAnImmediateUse() + nodeFrom = getlistRef().getAUse() and nodeTo = getlistResult().asSource() ) or // Indexing @@ -1939,7 +1939,7 @@ private module StdlibPrivate { /** A HttpRequestHandler class definition (most likely in project code). */ class HttpRequestHandlerClassDef extends Class { - HttpRequestHandlerClassDef() { this.getParent() = subclassRef().getAnImmediateUse().asExpr() } + HttpRequestHandlerClassDef() { this.getParent() = subclassRef().asSource().asExpr() } } /** DEPRECATED: Alias for HttpRequestHandlerClassDef */ @@ -2037,7 +2037,7 @@ private module StdlibPrivate { .getMember("simple_server") .getMember("WSGIServer") .getASubclass*() - .getAnImmediateUse() + .asSource() .asExpr() } } diff --git a/python/ql/lib/semmle/python/frameworks/Tornado.qll b/python/ql/lib/semmle/python/frameworks/Tornado.qll index 9c604afc1ec..d66da17aa5d 100644 --- a/python/ql/lib/semmle/python/frameworks/Tornado.qll +++ b/python/ql/lib/semmle/python/frameworks/Tornado.qll @@ -92,7 +92,7 @@ private module Tornado { /** A RequestHandler class (most likely in project code). */ class RequestHandlerClass extends Class { - RequestHandlerClass() { this.getParent() = subclassRef().getAnImmediateUse().asExpr() } + RequestHandlerClass() { this.getParent() = subclassRef().asSource().asExpr() } /** Gets a function that could handle incoming requests, if any. */ Function getARequestHandler() { diff --git a/python/ql/lib/semmle/python/frameworks/Twisted.qll b/python/ql/lib/semmle/python/frameworks/Twisted.qll index 513f5c942d0..c316321555e 100644 --- a/python/ql/lib/semmle/python/frameworks/Twisted.qll +++ b/python/ql/lib/semmle/python/frameworks/Twisted.qll @@ -33,7 +33,7 @@ private module Twisted { .getMember("resource") .getMember("Resource") .getASubclass*() - .getAnImmediateUse() + .asSource() .asExpr() } diff --git a/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll b/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll index e80e9f7ad0b..f8d7ae75ad0 100644 --- a/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll +++ b/python/ql/lib/semmle/python/frameworks/data/ModelsAsData.qll @@ -23,7 +23,7 @@ private import semmle.python.dataflow.new.TaintTracking * A remote flow source originating from a CSV source row. */ private class RemoteFlowSourceFromCsv extends RemoteFlowSource { - RemoteFlowSourceFromCsv() { this = ModelOutput::getASourceNode("remote").getAnImmediateUse() } + RemoteFlowSourceFromCsv() { this = ModelOutput::getASourceNode("remote").asSource() } override string getSourceType() { result = "Remote flow (from model)" } } @@ -35,7 +35,7 @@ private predicate summaryStepNodes(DataFlow::Node pred, DataFlow::Node succ, str exists(API::Node predNode, API::Node succNode | Specific::summaryStep(predNode, succNode, kind) and pred = predNode.asSink() and - succ = succNode.getAnImmediateUse() + succ = succNode.asSource() ) } diff --git a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll index 8bef349f417..100d8165b51 100644 --- a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll +++ b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll @@ -204,7 +204,7 @@ private module NotExposed { FindSubclassesSpec spec, string newSubclassQualified, ClassExpr classExpr, Module mod, Location loc ) { - classExpr = newOrExistingModeling(spec).getASubclass*().getAnImmediateUse().asExpr() and + classExpr = newOrExistingModeling(spec).getASubclass*().asSource().asExpr() and classExpr.getScope() = mod and newSubclassQualified = mod.getName() + "." + classExpr.getName() and loc = classExpr.getLocation() and diff --git a/python/ql/lib/semmle/python/regex.qll b/python/ql/lib/semmle/python/regex.qll index b72adba1716..5431d5df320 100644 --- a/python/ql/lib/semmle/python/regex.qll +++ b/python/ql/lib/semmle/python/regex.qll @@ -75,7 +75,7 @@ private string canonical_name(API::Node flag) { */ private DataFlow::TypeTrackingNode re_flag_tracker(string flag_name, DataFlow::TypeTracker t) { t.start() and - exists(API::Node flag | flag_name = canonical_name(flag) and result = flag.getAnImmediateUse()) + exists(API::Node flag | flag_name = canonical_name(flag) and result = flag.asSource()) or exists(BinaryExprNode binop, DataFlow::Node operand | operand.getALocalSource() = re_flag_tracker(flag_name, t.continue()) and diff --git a/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql b/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql index 91375904043..74f5f259319 100644 --- a/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql +++ b/python/ql/test/experimental/dataflow/typetracking/moduleattr.ql @@ -5,7 +5,7 @@ import semmle.python.ApiGraphs private DataFlow::TypeTrackingNode module_tracker(TypeTracker t) { t.start() and - result = API::moduleImport("module").getAnImmediateUse() + result = API::moduleImport("module").asSource() or exists(TypeTracker t2 | result = module_tracker(t2).track(t2, t)) } diff --git a/python/ql/test/experimental/dataflow/typetracking/tracked.ql b/python/ql/test/experimental/dataflow/typetracking/tracked.ql index 142e5b11639..c35775d0046 100644 --- a/python/ql/test/experimental/dataflow/typetracking/tracked.ql +++ b/python/ql/test/experimental/dataflow/typetracking/tracked.ql @@ -120,7 +120,7 @@ class TrackedSelfTest extends InlineExpectationsTest { /** Gets a reference to `foo` (fictive module). */ private DataFlow::TypeTrackingNode foo(DataFlow::TypeTracker t) { t.start() and - result = API::moduleImport("foo").getAnImmediateUse() + result = API::moduleImport("foo").asSource() or exists(DataFlow::TypeTracker t2 | result = foo(t2).track(t2, t)) } @@ -131,7 +131,7 @@ DataFlow::Node foo() { foo(DataFlow::TypeTracker::end()).flowsTo(result) } /** Gets a reference to `foo.bar` (fictive module). */ private DataFlow::TypeTrackingNode foo_bar(DataFlow::TypeTracker t) { t.start() and - result = API::moduleImport("foo").getMember("bar").getAnImmediateUse() + result = API::moduleImport("foo").getMember("bar").asSource() or t.startInAttr("bar") and result = foo() @@ -145,7 +145,7 @@ DataFlow::Node foo_bar() { foo_bar(DataFlow::TypeTracker::end()).flowsTo(result) /** Gets a reference to `foo.bar.baz` (fictive attribute on `foo.bar` module). */ private DataFlow::TypeTrackingNode foo_bar_baz(DataFlow::TypeTracker t) { t.start() and - result = API::moduleImport("foo").getMember("bar").getMember("baz").getAnImmediateUse() + result = API::moduleImport("foo").getMember("bar").getMember("baz").asSource() or t.startInAttr("baz") and result = foo_bar() diff --git a/python/ql/test/experimental/meta/MaDTest.qll b/python/ql/test/experimental/meta/MaDTest.qll index 92b8afef422..a4b5877f5ea 100644 --- a/python/ql/test/experimental/meta/MaDTest.qll +++ b/python/ql/test/experimental/meta/MaDTest.qll @@ -38,7 +38,7 @@ class MadSourceTest extends InlineExpectationsTest { override predicate hasActualResult(Location location, string element, string tag, string value) { exists(location.getFile().getRelativePath()) and exists(DataFlow::Node source, string kind | - source = ModelOutput::getASourceNode(kind).getAnImmediateUse() and + source = ModelOutput::getASourceNode(kind).asSource() and location = source.getLocation() and element = source.toString() and value = prettyNodeForInlineTest(source) and diff --git a/python/ql/test/library-tests/frameworks/data/test.ql b/python/ql/test/library-tests/frameworks/data/test.ql index c1bc85eaf49..cdd1782052a 100644 --- a/python/ql/test/library-tests/frameworks/data/test.ql +++ b/python/ql/test/library-tests/frameworks/data/test.ql @@ -87,7 +87,7 @@ class BasicTaintTracking extends TaintTracking::Configuration { BasicTaintTracking() { this = "BasicTaintTracking" } override predicate isSource(DataFlow::Node source) { - source = ModelOutput::getASourceNode("test-source").getAnImmediateUse() + source = ModelOutput::getASourceNode("test-source").asSource() } override predicate isSink(DataFlow::Node sink) { @@ -104,7 +104,7 @@ query predicate isSink(DataFlow::Node node, string kind) { } query predicate isSource(DataFlow::Node node, string kind) { - node = ModelOutput::getASourceNode(kind).getAnImmediateUse() + node = ModelOutput::getASourceNode(kind).asSource() } class SyntaxErrorTest extends ModelInput::SinkModelCsv { From b096f9ec72064fd68a2f850b4d67737d5bc69145 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 13 Jun 2022 10:02:14 +0200 Subject: [PATCH 068/465] Python: Rename getAUse -> getAValueReachableFromSource --- python/ql/lib/semmle/python/ApiGraphs.qll | 2 +- .../lib/semmle/python/frameworks/Aiohttp.qll | 3 +- .../semmle/python/frameworks/Cryptodome.qll | 2 +- .../semmle/python/frameworks/Cryptography.qll | 12 +++---- .../lib/semmle/python/frameworks/Django.qll | 2 +- .../lib/semmle/python/frameworks/Fabric.qll | 2 +- .../lib/semmle/python/frameworks/FastApi.qll | 16 ++++++---- .../ql/lib/semmle/python/frameworks/Flask.qll | 11 ++++--- .../lib/semmle/python/frameworks/Invoke.qll | 3 +- .../semmle/python/frameworks/RuamelYaml.qll | 2 +- .../lib/semmle/python/frameworks/Stdlib.qll | 32 +++++++++++-------- .../lib/semmle/python/frameworks/Werkzeug.qll | 6 ++-- .../ql/lib/semmle/python/frameworks/Yaml.qll | 2 +- .../python/frameworks/internal/PEP249Impl.qll | 4 ++- .../frameworks/internal/SubclassFinder.qll | 4 +-- .../semmle/python/internal/CachedStages.qll | 2 +- .../CWE-295/MissingHostKeyValidation.ql | 4 +-- python/ql/src/Security/CWE-327/PyOpenSSL.qll | 10 +++--- python/ql/src/Security/CWE-327/Ssl.qll | 25 ++++++++++++--- .../semmle/python/frameworks/Django.qll | 6 ++-- .../semmle/python/frameworks/Flask.qll | 6 +++- .../semmle/python/frameworks/LDAP.qll | 4 ++- .../semmle/python/frameworks/NoSQL.qll | 4 +-- .../ql/test/TestUtilities/VerifyApiGraphs.qll | 2 +- .../test/library-tests/ApiGraphs/py2/use.ql | 2 +- 25 files changed, 103 insertions(+), 65 deletions(-) diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index 61a42f812a7..538d4fe8818 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -106,7 +106,7 @@ module API { * ``` * both `obj.foo` and `x` are uses of the `foo` member from `obj`. */ - DataFlow::Node getAUse() { + DataFlow::Node getAValueReachableFromSource() { exists(DataFlow::LocalSourceNode src | Impl::use(this, src) | Impl::trackUseNode(src).flowsTo(result) ) diff --git a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll index 733845de30b..b78feb217c6 100644 --- a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll @@ -626,7 +626,8 @@ module AiohttpWebModel { // and just go with the LHS this.asCfgNode() = subscript | - subscript.getObject() = aiohttpResponseInstance().getMember("cookies").getAUse().asCfgNode() and + subscript.getObject() = + aiohttpResponseInstance().getMember("cookies").getAValueReachableFromSource().asCfgNode() and value.asCfgNode() = subscript.(DefinitionNode).getValue() and index.asCfgNode() = subscript.getIndex() ) diff --git a/python/ql/lib/semmle/python/frameworks/Cryptodome.qll b/python/ql/lib/semmle/python/frameworks/Cryptodome.qll index 8d1e47d0ff3..0c3e8968c23 100644 --- a/python/ql/lib/semmle/python/frameworks/Cryptodome.qll +++ b/python/ql/lib/semmle/python/frameworks/Cryptodome.qll @@ -164,7 +164,7 @@ private module CryptodomeModel { .getMember("Cipher") .getMember(cipherName) .getMember(modeName) - .getAUse() + .getAValueReachableFromSource() | result = modeName.splitAt("_", 1) ) diff --git a/python/ql/lib/semmle/python/frameworks/Cryptography.qll b/python/ql/lib/semmle/python/frameworks/Cryptography.qll index 1520f17e883..021da3ef0a0 100644 --- a/python/ql/lib/semmle/python/frameworks/Cryptography.qll +++ b/python/ql/lib/semmle/python/frameworks/Cryptography.qll @@ -145,9 +145,9 @@ private module CryptographyModel { override int getKeySizeWithOrigin(DataFlow::Node origin) { exists(API::Node n | n = Ecc::predefinedCurveClass(result) and origin = n.asSource() | - this.getCurveArg() = n.getAUse() + this.getCurveArg() = n.getAValueReachableFromSource() or - this.getCurveArg() = n.getReturn().getAUse() + this.getCurveArg() = n.getReturn().getAValueReachableFromSource() ) } @@ -189,12 +189,12 @@ private module CryptographyModel { .getMember("ciphers") .getMember("Cipher") .getACall() and - algorithmClassRef(algorithmName).getReturn().getAUse() in [ + algorithmClassRef(algorithmName).getReturn().getAValueReachableFromSource() in [ call.getArg(0), call.getArgByName("algorithm") ] and exists(DataFlow::Node modeArg | modeArg in [call.getArg(1), call.getArgByName("mode")] | - if modeArg = modeClassRef(_).getReturn().getAUse() - then modeArg = modeClassRef(modeName).getReturn().getAUse() + if modeArg = modeClassRef(_).getReturn().getAValueReachableFromSource() + then modeArg = modeClassRef(modeName).getReturn().getAValueReachableFromSource() else modeName = "" ) ) @@ -252,7 +252,7 @@ private module CryptographyModel { .getMember("hashes") .getMember("Hash") .getACall() and - algorithmClassRef(algorithmName).getReturn().getAUse() in [ + algorithmClassRef(algorithmName).getReturn().getAValueReachableFromSource() in [ call.getArg(0), call.getArgByName("algorithm") ] ) diff --git a/python/ql/lib/semmle/python/frameworks/Django.qll b/python/ql/lib/semmle/python/frameworks/Django.qll index a955de7a01a..a430513cb62 100644 --- a/python/ql/lib/semmle/python/frameworks/Django.qll +++ b/python/ql/lib/semmle/python/frameworks/Django.qll @@ -2799,7 +2799,7 @@ module PrivateDjango { .getMember("decorators") .getMember("csrf") .getMember(decoratorName) - .getAUse() and + .getAValueReachableFromSource() and this.asExpr() = function.getADecorator() } diff --git a/python/ql/lib/semmle/python/frameworks/Fabric.qll b/python/ql/lib/semmle/python/frameworks/Fabric.qll index bb1500965f4..5fd9d2afe18 100644 --- a/python/ql/lib/semmle/python/frameworks/Fabric.qll +++ b/python/ql/lib/semmle/python/frameworks/Fabric.qll @@ -179,7 +179,7 @@ private module FabricV2 { DataFlow::ParameterNode { FabricTaskFirstParamConnectionInstance() { exists(Function func | - func.getADecorator() = Fabric::Tasks::task().getAUse().asExpr() and + func.getADecorator() = Fabric::Tasks::task().getAValueReachableFromSource().asExpr() and this.getParameter() = func.getArg(0) ) } diff --git a/python/ql/lib/semmle/python/frameworks/FastApi.qll b/python/ql/lib/semmle/python/frameworks/FastApi.qll index 3a683108f4c..f042dafea59 100644 --- a/python/ql/lib/semmle/python/frameworks/FastApi.qll +++ b/python/ql/lib/semmle/python/frameworks/FastApi.qll @@ -90,7 +90,8 @@ private module FastApi { private class PydanticModelRequestHandlerParam extends Pydantic::BaseModel::InstanceSource, DataFlow::ParameterNode { PydanticModelRequestHandlerParam() { - this.getParameter().getAnnotation() = Pydantic::BaseModel::subclassRef().getAUse().asExpr() and + this.getParameter().getAnnotation() = + Pydantic::BaseModel::subclassRef().getAValueReachableFromSource().asExpr() and any(FastApiRouteSetup rs).getARequestHandler().getArgByName(_) = this.getParameter() } } @@ -104,7 +105,8 @@ private module FastApi { private class WebSocketRequestHandlerParam extends Starlette::WebSocket::InstanceSource, DataFlow::ParameterNode { WebSocketRequestHandlerParam() { - this.getParameter().getAnnotation() = Starlette::WebSocket::classRef().getAUse().asExpr() and + this.getParameter().getAnnotation() = + Starlette::WebSocket::classRef().getAValueReachableFromSource().asExpr() and any(FastApiRouteSetup rs).getARequestHandler().getArgByName(_) = this.getParameter() } } @@ -165,7 +167,7 @@ private module FastApi { // user-defined subclasses exists(Class cls, API::Node base | base = getModeledResponseClass(_).getASubclass*() and - cls.getABase() = base.getAUse().asExpr() and + cls.getABase() = base.getAValueReachableFromSource().asExpr() and responseClass.asSource().asExpr() = cls.getParent() | exists(Assign assign | assign = cls.getAStmt() | @@ -257,7 +259,7 @@ private module FastApi { override string getMimetypeDefault() { exists(API::Node responseClass | - responseClass.getAUse() = routeSetup.getResponseClassArg() and + responseClass.getAValueReachableFromSource() = routeSetup.getResponseClassArg() and result = getDefaultMimeType(responseClass) ) or @@ -274,7 +276,7 @@ private module FastApi { FileSystemAccess::Range { FastApiRequestHandlerFileResponseReturn() { exists(API::Node responseClass | - responseClass.getAUse() = routeSetup.getResponseClassArg() and + responseClass.getAValueReachableFromSource() = routeSetup.getResponseClassArg() and responseClass = getModeledResponseClass("FileResponse").getASubclass*() ) } @@ -292,7 +294,7 @@ private module FastApi { HTTP::Server::HttpRedirectResponse::Range { FastApiRequestHandlerRedirectReturn() { exists(API::Node responseClass | - responseClass.getAUse() = routeSetup.getResponseClassArg() and + responseClass.getAValueReachableFromSource() = routeSetup.getResponseClassArg() and responseClass = getModeledResponseClass("RedirectResponse").getASubclass*() ) } @@ -311,7 +313,7 @@ private module FastApi { class RequestHandlerParam extends InstanceSource, DataFlow::ParameterNode { RequestHandlerParam() { this.getParameter().getAnnotation() = - getModeledResponseClass(_).getASubclass*().getAUse().asExpr() and + getModeledResponseClass(_).getASubclass*().getAValueReachableFromSource().asExpr() and any(FastApiRouteSetup rs).getARequestHandler().getArgByName(_) = this.getParameter() } } diff --git a/python/ql/lib/semmle/python/frameworks/Flask.qll b/python/ql/lib/semmle/python/frameworks/Flask.qll index 8df9295c285..8ee93fcec52 100644 --- a/python/ql/lib/semmle/python/frameworks/Flask.qll +++ b/python/ql/lib/semmle/python/frameworks/Flask.qll @@ -305,7 +305,7 @@ module Flask { ) or exists(FlaskViewClass vc | - this.getViewArg() = vc.asViewResult().getAUse() and + this.getViewArg() = vc.asViewResult().getAValueReachableFromSource() and result = vc.getARequestHandler() ) } @@ -339,7 +339,7 @@ module Flask { */ private class FlaskRequestSource extends RemoteFlowSource::Range { FlaskRequestSource() { - this = request().getAUse() and + this = request().getAValueReachableFromSource() and not any(Import imp).contains(this.asExpr()) and not exists(ControlFlowNode def | this.asVar().getSourceVariable().hasDefiningNode(def) | any(Import imp).contains(def.getNode()) @@ -357,7 +357,7 @@ module Flask { private class InstanceTaintSteps extends InstanceTaintStepsHelper { InstanceTaintSteps() { this = "flask.Request" } - override DataFlow::Node getInstance() { result = request().getAUse() } + override DataFlow::Node getInstance() { result = request().getAValueReachableFromSource() } override string getAttributeName() { result in [ @@ -415,12 +415,13 @@ module Flask { // be able to do something more structured for providing modeling of the members // of a container-object. exists(API::Node files | files = request().getMember("files") | - this.asCfgNode().(SubscriptNode).getObject() = files.getAUse().asCfgNode() + this.asCfgNode().(SubscriptNode).getObject() = + files.getAValueReachableFromSource().asCfgNode() or this = files.getMember("get").getACall() or this.asCfgNode().(SubscriptNode).getObject() = - files.getMember("getlist").getReturn().getAUse().asCfgNode() + files.getMember("getlist").getReturn().getAValueReachableFromSource().asCfgNode() ) } } diff --git a/python/ql/lib/semmle/python/frameworks/Invoke.qll b/python/ql/lib/semmle/python/frameworks/Invoke.qll index 435536dda9f..b1ceb078907 100644 --- a/python/ql/lib/semmle/python/frameworks/Invoke.qll +++ b/python/ql/lib/semmle/python/frameworks/Invoke.qll @@ -39,7 +39,8 @@ private module Invoke { result = InvokeModule::Context::ContextClass::classRef().getACall() or exists(Function func | - func.getADecorator() = invoke().getMember("task").getAUse().asExpr() and + func.getADecorator() = + invoke().getMember("task").getAValueReachableFromSource().asExpr() and result.(DataFlow::ParameterNode).getParameter() = func.getArg(0) ) ) diff --git a/python/ql/lib/semmle/python/frameworks/RuamelYaml.qll b/python/ql/lib/semmle/python/frameworks/RuamelYaml.qll index 2d553c409b0..d9ba39814eb 100644 --- a/python/ql/lib/semmle/python/frameworks/RuamelYaml.qll +++ b/python/ql/lib/semmle/python/frameworks/RuamelYaml.qll @@ -44,7 +44,7 @@ private module RuamelYaml { API::moduleImport("ruamel") .getMember("yaml") .getMember(["SafeLoader", "BaseLoader", "CSafeLoader", "CBaseLoader"]) - .getAUse() + .getAValueReachableFromSource() ) } diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index b0629d94b2c..74f80b1d478 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -1727,15 +1727,16 @@ private module StdlibPrivate { private DataFlow::TypeTrackingNode fieldList(DataFlow::TypeTracker t) { t.start() and // TODO: Should have better handling of subscripting - result.asCfgNode().(SubscriptNode).getObject() = instance().getAUse().asCfgNode() + result.asCfgNode().(SubscriptNode).getObject() = + instance().getAValueReachableFromSource().asCfgNode() or exists(DataFlow::TypeTracker t2 | result = fieldList(t2).track(t2, t)) } /** Gets a reference to a list of fields. */ DataFlow::Node fieldList() { - result = getlistResult().getAUse() or - result = getvalueResult().getAUse() or + result = getlistResult().getAValueReachableFromSource() or + result = getvalueResult().getAValueReachableFromSource() or fieldList(DataFlow::TypeTracker::end()).flowsTo(result) } @@ -1744,16 +1745,16 @@ private module StdlibPrivate { t.start() and // TODO: Should have better handling of subscripting result.asCfgNode().(SubscriptNode).getObject() = - [instance().getAUse(), fieldList()].asCfgNode() + [instance().getAValueReachableFromSource(), fieldList()].asCfgNode() or exists(DataFlow::TypeTracker t2 | result = field(t2).track(t2, t)) } /** Gets a reference to a field. */ DataFlow::Node field() { - result = getfirstResult().getAUse() + result = getfirstResult().getAValueReachableFromSource() or - result = getvalueResult().getAUse() + result = getvalueResult().getAValueReachableFromSource() or field(DataFlow::TypeTracker::end()).flowsTo(result) } @@ -1762,20 +1763,23 @@ private module StdlibPrivate { override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { // Methods nodeFrom = nodeTo.(DataFlow::AttrRead).getObject() and - nodeFrom = instance().getAUse() and - nodeTo = [getvalueRef(), getfirstRef(), getlistRef()].getAUse() + nodeFrom = instance().getAValueReachableFromSource() and + nodeTo = [getvalueRef(), getfirstRef(), getlistRef()].getAValueReachableFromSource() or nodeFrom.asCfgNode() = nodeTo.asCfgNode().(CallNode).getFunction() and ( - nodeFrom = getvalueRef().getAUse() and nodeTo = getvalueResult().asSource() + nodeFrom = getvalueRef().getAValueReachableFromSource() and + nodeTo = getvalueResult().asSource() or - nodeFrom = getfirstRef().getAUse() and nodeTo = getfirstResult().asSource() + nodeFrom = getfirstRef().getAValueReachableFromSource() and + nodeTo = getfirstResult().asSource() or - nodeFrom = getlistRef().getAUse() and nodeTo = getlistResult().asSource() + nodeFrom = getlistRef().getAValueReachableFromSource() and + nodeTo = getlistResult().asSource() ) or // Indexing - nodeFrom in [instance().getAUse(), fieldList()] and + nodeFrom in [instance().getAValueReachableFromSource(), fieldList()] and nodeTo.asCfgNode().(SubscriptNode).getObject() = nodeFrom.asCfgNode() or // Attributes on Field @@ -3438,7 +3442,7 @@ private module StdlibPrivate { .getMember("sax") .getMember("handler") .getMember("feature_external_ges") - .getAUse() and + .getAValueReachableFromSource() and call.getStateArg().getAValueReachingRhs().asExpr().(BooleanLiteral).booleanValue() = true and result = call.getObject() ) @@ -3454,7 +3458,7 @@ private module StdlibPrivate { .getMember("sax") .getMember("handler") .getMember("feature_external_ges") - .getAUse() and + .getAValueReachableFromSource() and call.getStateArg().getAValueReachingRhs().asExpr().(BooleanLiteral).booleanValue() = false ) } diff --git a/python/ql/lib/semmle/python/frameworks/Werkzeug.qll b/python/ql/lib/semmle/python/frameworks/Werkzeug.qll index e9e3f257871..5e318f59e73 100644 --- a/python/ql/lib/semmle/python/frameworks/Werkzeug.qll +++ b/python/ql/lib/semmle/python/frameworks/Werkzeug.qll @@ -285,7 +285,7 @@ private module WerkzeugOld { * See https://werkzeug.palletsprojects.com/en/1.0.x/datastructures/#werkzeug.datastructures.Headers.getlist */ deprecated DataFlow::Node getlist() { - result = any(InstanceSourceApiNode a).getMember("getlist").getAUse() + result = any(InstanceSourceApiNode a).getMember("getlist").getAValueReachableFromSource() } private class MultiDictAdditionalTaintStep extends TaintTracking::AdditionalTaintStep { @@ -331,7 +331,9 @@ private module WerkzeugOld { abstract deprecated class InstanceSourceApiNode extends API::Node { } /** Gets a reference to an instance of `werkzeug.datastructures.FileStorage`. */ - deprecated DataFlow::Node instance() { result = any(InstanceSourceApiNode a).getAUse() } + deprecated DataFlow::Node instance() { + result = any(InstanceSourceApiNode a).getAValueReachableFromSource() + } private class FileStorageAdditionalTaintStep extends TaintTracking::AdditionalTaintStep { override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { diff --git a/python/ql/lib/semmle/python/frameworks/Yaml.qll b/python/ql/lib/semmle/python/frameworks/Yaml.qll index 07a98ec2ba3..670fad75e6e 100644 --- a/python/ql/lib/semmle/python/frameworks/Yaml.qll +++ b/python/ql/lib/semmle/python/frameworks/Yaml.qll @@ -64,7 +64,7 @@ private module Yaml { loader_arg = API::moduleImport("yaml") .getMember(["SafeLoader", "BaseLoader", "CSafeLoader", "CBaseLoader"]) - .getAUse() + .getAValueReachableFromSource() ) } diff --git a/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll b/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll index 57e7131c2b7..5feaa7f61da 100644 --- a/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll +++ b/python/ql/lib/semmle/python/frameworks/internal/PEP249Impl.qll @@ -33,7 +33,9 @@ module PEP249 { } /** Gets a reference to the `connect` function of a module that implements PEP 249. */ - DataFlow::Node connect() { result = any(PEP249ModuleApiNode a).getMember("connect").getAUse() } + DataFlow::Node connect() { + result = any(PEP249ModuleApiNode a).getMember("connect").getAValueReachableFromSource() + } /** * Provides models for database connections (following PEP 249). diff --git a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll index 100d8165b51..47521ac0b31 100644 --- a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll +++ b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll @@ -152,7 +152,7 @@ private module NotExposed { FindSubclassesSpec spec, string newAliasFullyQualified, ImportMember importMember, Module mod, Location loc ) { - importMember = newOrExistingModeling(spec).getAUse().asExpr() and + importMember = newOrExistingModeling(spec).getAValueReachableFromSource().asExpr() and importMember.getScope() = mod and loc = importMember.getLocation() and ( @@ -182,7 +182,7 @@ private module NotExposed { // WHAT A HACK :D :D relevantClass.getPath() = relevantClass.getAPredecessor().getPath() + ".getMember(\"" + relevantName + "\")" and - relevantClass.getAPredecessor().getAUse().asExpr() = importStar.getModule() and + relevantClass.getAPredecessor().getAValueReachableFromSource().asExpr() = importStar.getModule() and ( mod.isPackageInit() and newAliasFullyQualified = mod.getPackageName() + "." + relevantName diff --git a/python/ql/lib/semmle/python/internal/CachedStages.qll b/python/ql/lib/semmle/python/internal/CachedStages.qll index ad4fe98ccee..290a90f5a73 100644 --- a/python/ql/lib/semmle/python/internal/CachedStages.qll +++ b/python/ql/lib/semmle/python/internal/CachedStages.qll @@ -121,7 +121,7 @@ module Stages { or exists(any(NewDataFlow::TypeTracker t).append(_)) or - exists(any(API::Node n).getAMember().getAUse()) + exists(any(API::Node n).getAMember().getAValueReachableFromSource()) } } diff --git a/python/ql/src/Security/CWE-295/MissingHostKeyValidation.ql b/python/ql/src/Security/CWE-295/MissingHostKeyValidation.ql index 89548d714ce..713354c84a0 100644 --- a/python/ql/src/Security/CWE-295/MissingHostKeyValidation.ql +++ b/python/ql/src/Security/CWE-295/MissingHostKeyValidation.ql @@ -29,7 +29,7 @@ where call = paramikoSSHClientInstance().getMember("set_missing_host_key_policy").getACall() and arg in [call.getArg(0), call.getArgByName("policy")] and ( - arg = unsafe_paramiko_policy(name).getAUse() or - arg = unsafe_paramiko_policy(name).getReturn().getAUse() + arg = unsafe_paramiko_policy(name).getAValueReachableFromSource() or + arg = unsafe_paramiko_policy(name).getReturn().getAValueReachableFromSource() ) select call, "Setting missing host key policy to " + name + " may be unsafe." diff --git a/python/ql/src/Security/CWE-327/PyOpenSSL.qll b/python/ql/src/Security/CWE-327/PyOpenSSL.qll index a0008cdc7c1..7f7b9184570 100644 --- a/python/ql/src/Security/CWE-327/PyOpenSSL.qll +++ b/python/ql/src/Security/CWE-327/PyOpenSSL.qll @@ -17,7 +17,8 @@ class PyOpenSSLContextCreation extends ContextCreation, DataFlow::CallCfgNode { protocolArg in [this.getArg(0), this.getArgByName("method")] | protocolArg in [ - pyo.specific_version(result).getAUse(), pyo.unspecific_version(result).getAUse() + pyo.specific_version(result).getAValueReachableFromSource(), + pyo.unspecific_version(result).getAValueReachableFromSource() ] ) } @@ -43,9 +44,10 @@ class SetOptionsCall extends ProtocolRestriction, DataFlow::CallCfgNode { } override ProtocolVersion getRestriction() { - API::moduleImport("OpenSSL").getMember("SSL").getMember("OP_NO_" + result).getAUse() in [ - this.getArg(0), this.getArgByName("options") - ] + API::moduleImport("OpenSSL") + .getMember("SSL") + .getMember("OP_NO_" + result) + .getAValueReachableFromSource() in [this.getArg(0), this.getArgByName("options")] } } diff --git a/python/ql/src/Security/CWE-327/Ssl.qll b/python/ql/src/Security/CWE-327/Ssl.qll index 80ef32c8de6..d1122f82ed9 100644 --- a/python/ql/src/Security/CWE-327/Ssl.qll +++ b/python/ql/src/Security/CWE-327/Ssl.qll @@ -15,7 +15,10 @@ class SSLContextCreation extends ContextCreation, DataFlow::CallCfgNode { protocolArg in [this.getArg(0), this.getArgByName("protocol")] | protocolArg = - [ssl.specific_version(result).getAUse(), ssl.unspecific_version(result).getAUse()] + [ + ssl.specific_version(result).getAValueReachableFromSource(), + ssl.unspecific_version(result).getAValueReachableFromSource() + ] ) or not exists(this.getArg(_)) and @@ -54,7 +57,11 @@ class OptionsAugOr extends ProtocolRestriction, DataFlow::CfgNode { aa.getTarget() = attr.getNode() and attr.getName() = "options" and attr.getObject() = node and - flag = API::moduleImport("ssl").getMember("OP_NO_" + restriction).getAUse().asExpr() and + flag = + API::moduleImport("ssl") + .getMember("OP_NO_" + restriction) + .getAValueReachableFromSource() + .asExpr() and ( aa.getValue() = flag or @@ -79,7 +86,11 @@ class OptionsAugAndNot extends ProtocolUnrestriction, DataFlow::CfgNode { attr.getObject() = node and notFlag.getOp() instanceof Invert and notFlag.getOperand() = flag and - flag = API::moduleImport("ssl").getMember("OP_NO_" + restriction).getAUse().asExpr() and + flag = + API::moduleImport("ssl") + .getMember("OP_NO_" + restriction) + .getAValueReachableFromSource() + .asExpr() and ( aa.getValue() = notFlag or @@ -134,7 +145,10 @@ class ContextSetVersion extends ProtocolRestriction, ProtocolUnrestriction, Data this = aw.getObject() and aw.getAttributeName() = "minimum_version" and aw.getValue() = - API::moduleImport("ssl").getMember("TLSVersion").getMember(restriction).getAUse() + API::moduleImport("ssl") + .getMember("TLSVersion") + .getMember(restriction) + .getAValueReachableFromSource() ) } @@ -188,7 +202,8 @@ class Ssl extends TlsLibrary { override DataFlow::CallCfgNode insecure_connection_creation(ProtocolVersion version) { result = API::moduleImport("ssl").getMember("wrap_socket").getACall() and - this.specific_version(version).getAUse() = result.getArgByName("ssl_version") and + this.specific_version(version).getAValueReachableFromSource() = + result.getArgByName("ssl_version") and version.isInsecure() } diff --git a/python/ql/src/experimental/semmle/python/frameworks/Django.qll b/python/ql/src/experimental/semmle/python/frameworks/Django.qll index 6853f9c3f6a..f1895af0ea9 100644 --- a/python/ql/src/experimental/semmle/python/frameworks/Django.qll +++ b/python/ql/src/experimental/semmle/python/frameworks/Django.qll @@ -86,11 +86,13 @@ private module ExperimentalPrivateDjango { t.start() and ( exists(SubscriptNode subscript | - subscript.getObject() = baseClassRef().getReturn().getAUse().asCfgNode() and + subscript.getObject() = + baseClassRef().getReturn().getAValueReachableFromSource().asCfgNode() and result.asCfgNode() = subscript ) or - result.(DataFlow::AttrRead).getObject() = baseClassRef().getReturn().getAUse() + result.(DataFlow::AttrRead).getObject() = + baseClassRef().getReturn().getAValueReachableFromSource() ) or exists(DataFlow::TypeTracker t2 | result = headerInstance(t2).track(t2, t)) diff --git a/python/ql/src/experimental/semmle/python/frameworks/Flask.qll b/python/ql/src/experimental/semmle/python/frameworks/Flask.qll index 5444a692b26..3252acf24fd 100644 --- a/python/ql/src/experimental/semmle/python/frameworks/Flask.qll +++ b/python/ql/src/experimental/semmle/python/frameworks/Flask.qll @@ -29,7 +29,11 @@ module ExperimentalFlask { /** Gets a reference to a header instance. */ private DataFlow::LocalSourceNode headerInstance() { - result = [Flask::Response::classRef(), flaskMakeResponse()].getReturn().getAMember().getAUse() + result = + [Flask::Response::classRef(), flaskMakeResponse()] + .getReturn() + .getAMember() + .getAValueReachableFromSource() } /** Gets a reference to a header instance call/subscript */ diff --git a/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll b/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll index 6085dddf5f8..871b47b48c9 100644 --- a/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll +++ b/python/ql/src/experimental/semmle/python/frameworks/LDAP.qll @@ -90,7 +90,9 @@ private module LDAP { /**List of SSL-demanding options */ private class LDAPSSLOptions extends DataFlow::Node { - LDAPSSLOptions() { this = ldap().getMember("OPT_X_TLS_" + ["DEMAND", "HARD"]).getAUse() } + LDAPSSLOptions() { + this = ldap().getMember("OPT_X_TLS_" + ["DEMAND", "HARD"]).getAValueReachableFromSource() + } } /** diff --git a/python/ql/src/experimental/semmle/python/frameworks/NoSQL.qll b/python/ql/src/experimental/semmle/python/frameworks/NoSQL.qll index c5efb3dd833..2d7c93c3029 100644 --- a/python/ql/src/experimental/semmle/python/frameworks/NoSQL.qll +++ b/python/ql/src/experimental/semmle/python/frameworks/NoSQL.qll @@ -50,11 +50,11 @@ private module NoSql { t.start() and ( exists(SubscriptNode subscript | - subscript.getObject() = mongoClientInstance().getAUse().asCfgNode() and + subscript.getObject() = mongoClientInstance().getAValueReachableFromSource().asCfgNode() and result.asCfgNode() = subscript ) or - result.(DataFlow::AttrRead).getObject() = mongoClientInstance().getAUse() + result.(DataFlow::AttrRead).getObject() = mongoClientInstance().getAValueReachableFromSource() or result = mongoEngine().getMember(["get_db", "connect"]).getACall() or diff --git a/python/ql/test/TestUtilities/VerifyApiGraphs.qll b/python/ql/test/TestUtilities/VerifyApiGraphs.qll index 03af20dbabe..f2d43a08867 100644 --- a/python/ql/test/TestUtilities/VerifyApiGraphs.qll +++ b/python/ql/test/TestUtilities/VerifyApiGraphs.qll @@ -24,7 +24,7 @@ private DataFlow::Node getNode(API::Node nd, string kind) { result = nd.asSink() or kind = "use" and - result = nd.getAUse() + result = nd.getAValueReachableFromSource() } private string getLocStr(Location loc) { diff --git a/python/ql/test/library-tests/ApiGraphs/py2/use.ql b/python/ql/test/library-tests/ApiGraphs/py2/use.ql index f02bb048c58..6b18b2c1dd7 100644 --- a/python/ql/test/library-tests/ApiGraphs/py2/use.ql +++ b/python/ql/test/library-tests/ApiGraphs/py2/use.ql @@ -9,7 +9,7 @@ class ApiUseTest extends InlineExpectationsTest { override string getARelevantTag() { result = "use" } private predicate relevant_node(API::Node a, DataFlow::Node n, Location l) { - n = a.getAUse() and l = n.getLocation() + n = a.getAValueReachableFromSource() and l = n.getLocation() } override predicate hasActualResult(Location location, string element, string tag, string value) { From 3a669a8d213e2e341d07b8b43cf30ef1a6aa6144 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 13 Jun 2022 10:03:32 +0200 Subject: [PATCH 069/465] Python: getAValueReachingRhs -> getAValueReachingSink --- python/ql/lib/semmle/python/ApiGraphs.qll | 2 +- .../ql/lib/semmle/python/frameworks/Aiohttp.qll | 4 ++-- .../ql/lib/semmle/python/frameworks/Httpx.qll | 8 ++++---- python/ql/lib/semmle/python/frameworks/Lxml.qll | 17 +++++++++-------- .../lib/semmle/python/frameworks/Requests.qll | 2 +- .../ql/lib/semmle/python/frameworks/Stdlib.qll | 6 +++--- .../ql/lib/semmle/python/frameworks/Urllib3.qll | 9 +++++---- .../lib/semmle/python/frameworks/Xmltodict.qll | 2 +- .../Security/CWE-079/Jinja2WithoutEscaping.ql | 2 +- .../ql/src/Security/CWE-285/PamAuthorization.ql | 4 ++-- .../src/Security/CWE-732/WeakFilePermissions.ql | 4 ++-- 11 files changed, 31 insertions(+), 29 deletions(-) diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index 538d4fe8818..72f49c859ef 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -134,7 +134,7 @@ module API { * Gets a data-flow node that may interprocedurally flow to the right-hand side of a definition * of the API component represented by this node. */ - DataFlow::Node getAValueReachingRhs() { result = Impl::trackDefNode(this.asSink()) } + DataFlow::Node getAValueReachingSink() { result = Impl::trackDefNode(this.asSink()) } /** * Gets an immediate use of the API component represented by this node. diff --git a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll index b78feb217c6..5f687a01b49 100644 --- a/python/ql/lib/semmle/python/frameworks/Aiohttp.qll +++ b/python/ql/lib/semmle/python/frameworks/Aiohttp.qll @@ -685,8 +685,8 @@ private module AiohttpClientModel { DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { exists(API::Node param | param = this.getKeywordParameter(["ssl", "verify_ssl"]) | - disablingNode = param.getARhs() and - argumentOrigin = param.getAValueReachingRhs() and + disablingNode = param.asSink() and + argumentOrigin = param.getAValueReachingSink() and // aiohttp.client treats `None` as the default and all other "falsey" values as `False`. argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false and not argumentOrigin.asExpr() instanceof None diff --git a/python/ql/lib/semmle/python/frameworks/Httpx.qll b/python/ql/lib/semmle/python/frameworks/Httpx.qll index 67dbbffbd9f..b746de6ee5e 100644 --- a/python/ql/lib/semmle/python/frameworks/Httpx.qll +++ b/python/ql/lib/semmle/python/frameworks/Httpx.qll @@ -44,8 +44,8 @@ private module HttpxModel { override predicate disablesCertificateValidation( DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { - disablingNode = this.getKeywordParameter("verify").getARhs() and - argumentOrigin = this.getKeywordParameter("verify").getAValueReachingRhs() and + disablingNode = this.getKeywordParameter("verify").asSink() and + argumentOrigin = this.getKeywordParameter("verify").getAValueReachingSink() and // unlike `requests`, httpx treats `None` as turning off verify (and not as the default) argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false // TODO: Handling of insecure SSLContext passed to verify argument @@ -89,8 +89,8 @@ private module HttpxModel { constructor = classRef().getACall() and this = constructor.getReturn().getMember(methodName).getACall() | - disablingNode = constructor.getKeywordParameter("verify").getARhs() and - argumentOrigin = constructor.getKeywordParameter("verify").getAValueReachingRhs() and + disablingNode = constructor.getKeywordParameter("verify").asSink() and + argumentOrigin = constructor.getKeywordParameter("verify").getAValueReachingSink() and // unlike `requests`, httpx treats `None` as turning off verify (and not as the default) argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false // TODO: Handling of insecure SSLContext passed to verify argument diff --git a/python/ql/lib/semmle/python/frameworks/Lxml.qll b/python/ql/lib/semmle/python/frameworks/Lxml.qll index 70e46a6d3b0..63c71a67110 100644 --- a/python/ql/lib/semmle/python/frameworks/Lxml.qll +++ b/python/ql/lib/semmle/python/frameworks/Lxml.qll @@ -141,17 +141,18 @@ private module Lxml { // resolve_entities has default True not exists(this.getArgByName("resolve_entities")) or - this.getKeywordParameter("resolve_entities").getAValueReachingRhs().asExpr() = any(True t) + this.getKeywordParameter("resolve_entities").getAValueReachingSink().asExpr() = + any(True t) ) or kind.isXmlBomb() and - this.getKeywordParameter("huge_tree").getAValueReachingRhs().asExpr() = any(True t) and - not this.getKeywordParameter("resolve_entities").getAValueReachingRhs().asExpr() = + this.getKeywordParameter("huge_tree").getAValueReachingSink().asExpr() = any(True t) and + not this.getKeywordParameter("resolve_entities").getAValueReachingSink().asExpr() = any(False t) or kind.isDtdRetrieval() and - this.getKeywordParameter("load_dtd").getAValueReachingRhs().asExpr() = any(True t) and - this.getKeywordParameter("no_network").getAValueReachingRhs().asExpr() = any(False t) + this.getKeywordParameter("load_dtd").getAValueReachingSink().asExpr() = any(True t) and + this.getKeywordParameter("no_network").getAValueReachingSink().asExpr() = any(False t) } } @@ -318,11 +319,11 @@ private module Lxml { kind.isXxe() or kind.isXmlBomb() and - this.getKeywordParameter("huge_tree").getAValueReachingRhs().asExpr() = any(True t) + this.getKeywordParameter("huge_tree").getAValueReachingSink().asExpr() = any(True t) or kind.isDtdRetrieval() and - this.getKeywordParameter("load_dtd").getAValueReachingRhs().asExpr() = any(True t) and - this.getKeywordParameter("no_network").getAValueReachingRhs().asExpr() = any(False t) + this.getKeywordParameter("load_dtd").getAValueReachingSink().asExpr() = any(True t) and + this.getKeywordParameter("no_network").getAValueReachingSink().asExpr() = any(False t) } override predicate mayExecuteInput() { none() } diff --git a/python/ql/lib/semmle/python/frameworks/Requests.qll b/python/ql/lib/semmle/python/frameworks/Requests.qll index 05e08b45166..0c944d889d2 100644 --- a/python/ql/lib/semmle/python/frameworks/Requests.qll +++ b/python/ql/lib/semmle/python/frameworks/Requests.qll @@ -62,7 +62,7 @@ private module Requests { DataFlow::Node disablingNode, DataFlow::Node argumentOrigin ) { disablingNode = this.getKeywordParameter("verify").asSink() and - argumentOrigin = this.getKeywordParameter("verify").getAValueReachingRhs() and + argumentOrigin = this.getKeywordParameter("verify").getAValueReachingSink() and // requests treats `None` as the default and all other "falsey" values as `False`. argumentOrigin.asExpr().(ImmutableLiteral).booleanValue() = false and not argumentOrigin.asExpr() instanceof None diff --git a/python/ql/lib/semmle/python/frameworks/Stdlib.qll b/python/ql/lib/semmle/python/frameworks/Stdlib.qll index 74f80b1d478..df9301a46c3 100644 --- a/python/ql/lib/semmle/python/frameworks/Stdlib.qll +++ b/python/ql/lib/semmle/python/frameworks/Stdlib.qll @@ -2657,7 +2657,7 @@ private module StdlibPrivate { /** Gets a call to `hashlib.new` with `algorithmName` as the first argument. */ private API::CallNode hashlibNewCall(string algorithmName) { algorithmName = - result.getParameter(0, "name").getAValueReachingRhs().asExpr().(StrConst).getText() and + result.getParameter(0, "name").getAValueReachingSink().asExpr().(StrConst).getText() and result = API::moduleImport("hashlib").getMember("new").getACall() } @@ -3443,7 +3443,7 @@ private module StdlibPrivate { .getMember("handler") .getMember("feature_external_ges") .getAValueReachableFromSource() and - call.getStateArg().getAValueReachingRhs().asExpr().(BooleanLiteral).booleanValue() = true and + call.getStateArg().getAValueReachingSink().asExpr().(BooleanLiteral).booleanValue() = true and result = call.getObject() ) or @@ -3459,7 +3459,7 @@ private module StdlibPrivate { .getMember("handler") .getMember("feature_external_ges") .getAValueReachableFromSource() and - call.getStateArg().getAValueReachingRhs().asExpr().(BooleanLiteral).booleanValue() = false + call.getStateArg().getAValueReachingSink().asExpr().(BooleanLiteral).booleanValue() = false ) } diff --git a/python/ql/lib/semmle/python/frameworks/Urllib3.qll b/python/ql/lib/semmle/python/frameworks/Urllib3.qll index 568591d64f9..418a135fbfc 100644 --- a/python/ql/lib/semmle/python/frameworks/Urllib3.qll +++ b/python/ql/lib/semmle/python/frameworks/Urllib3.qll @@ -71,14 +71,15 @@ private module Urllib3 { | // cert_reqs // see https://urllib3.readthedocs.io/en/stable/user-guide.html?highlight=cert_reqs#certificate-verification - disablingNode = constructor.getKeywordParameter("cert_reqs").getARhs() and - argumentOrigin = constructor.getKeywordParameter("cert_reqs").getAValueReachingRhs() and + disablingNode = constructor.getKeywordParameter("cert_reqs").asSink() and + argumentOrigin = constructor.getKeywordParameter("cert_reqs").getAValueReachingSink() and argumentOrigin.asExpr().(StrConst).getText() = "CERT_NONE" or // assert_hostname // see https://urllib3.readthedocs.io/en/stable/reference/urllib3.connectionpool.html?highlight=assert_hostname#urllib3.HTTPSConnectionPool - disablingNode = constructor.getKeywordParameter("assert_hostname").getARhs() and - argumentOrigin = constructor.getKeywordParameter("assert_hostname").getAValueReachingRhs() and + disablingNode = constructor.getKeywordParameter("assert_hostname").asSink() and + argumentOrigin = + constructor.getKeywordParameter("assert_hostname").getAValueReachingSink() and argumentOrigin.asExpr().(BooleanLiteral).booleanValue() = false ) } diff --git a/python/ql/lib/semmle/python/frameworks/Xmltodict.qll b/python/ql/lib/semmle/python/frameworks/Xmltodict.qll index f63fec7afe4..495725e9a76 100644 --- a/python/ql/lib/semmle/python/frameworks/Xmltodict.qll +++ b/python/ql/lib/semmle/python/frameworks/Xmltodict.qll @@ -29,7 +29,7 @@ private module Xmltodict { override predicate vulnerableTo(XML::XmlParsingVulnerabilityKind kind) { kind.isXmlBomb() and - this.getKeywordParameter("disable_entities").getAValueReachingRhs().asExpr() = any(False f) + this.getKeywordParameter("disable_entities").getAValueReachingSink().asExpr() = any(False f) } override predicate mayExecuteInput() { none() } diff --git a/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql b/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql index 820937f8649..97bbb72edec 100644 --- a/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql +++ b/python/ql/src/Security/CWE-079/Jinja2WithoutEscaping.ql @@ -42,7 +42,7 @@ where not exists(call.getArgByName("autoescape")) or call.getKeywordParameter("autoescape") - .getAValueReachingRhs() + .getAValueReachingSink() .asExpr() .(ImmutableLiteral) .booleanValue() = false diff --git a/python/ql/src/Security/CWE-285/PamAuthorization.ql b/python/ql/src/Security/CWE-285/PamAuthorization.ql index 233e42e6239..affb59ff7db 100644 --- a/python/ql/src/Security/CWE-285/PamAuthorization.ql +++ b/python/ql/src/Security/CWE-285/PamAuthorization.ql @@ -18,9 +18,9 @@ import semmle.python.dataflow.new.TaintTracking API::Node libPam() { exists(API::CallNode findLibCall, API::CallNode cdllCall | findLibCall = API::moduleImport("ctypes").getMember("util").getMember("find_library").getACall() and - findLibCall.getParameter(0).getAValueReachingRhs().asExpr().(StrConst).getText() = "pam" and + findLibCall.getParameter(0).getAValueReachingSink().asExpr().(StrConst).getText() = "pam" and cdllCall = API::moduleImport("ctypes").getMember("CDLL").getACall() and - cdllCall.getParameter(0).getAValueReachingRhs() = findLibCall + cdllCall.getParameter(0).getAValueReachingSink() = findLibCall | result = cdllCall.getReturn() ) diff --git a/python/ql/src/Security/CWE-732/WeakFilePermissions.ql b/python/ql/src/Security/CWE-732/WeakFilePermissions.ql index 393198cf72e..90921b99fb9 100644 --- a/python/ql/src/Security/CWE-732/WeakFilePermissions.ql +++ b/python/ql/src/Security/CWE-732/WeakFilePermissions.ql @@ -36,13 +36,13 @@ string permissive_permission(int p) { predicate chmod_call(API::CallNode call, string name, int mode) { call = API::moduleImport("os").getMember("chmod").getACall() and - mode = call.getParameter(1, "mode").getAValueReachingRhs().asExpr().(IntegerLiteral).getValue() and + mode = call.getParameter(1, "mode").getAValueReachingSink().asExpr().(IntegerLiteral).getValue() and name = "chmod" } predicate open_call(API::CallNode call, string name, int mode) { call = API::moduleImport("os").getMember("open").getACall() and - mode = call.getParameter(2, "mode").getAValueReachingRhs().asExpr().(IntegerLiteral).getValue() and + mode = call.getParameter(2, "mode").getAValueReachingSink().asExpr().(IntegerLiteral).getValue() and name = "open" } From fecbfa6ca37e70a308f5fdd8e8d07b1361798ebd Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 30 May 2022 14:15:48 +0200 Subject: [PATCH 070/465] Python: add deprecation --- python/ql/lib/semmle/python/ApiGraphs.qll | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index 72f49c859ef..7d59b14696f 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -149,6 +149,18 @@ module API { */ DataFlow::LocalSourceNode asSource() { Impl::use(this, result) } + /** DEPRECATED. This predicate has been renamed to `getAValueReachableFromSource()`. */ + deprecated DataFlow::Node getAUse() { result = this.getAValueReachableFromSource() } + + /** DEPRECATED. This predicate has been renamed to `asSource()`. */ + deprecated DataFlow::LocalSourceNode getAnImmediateUse() { result = this.asSource() } + + /** DEPRECATED. This predicate has been renamed to `asSink()`. */ + deprecated DataFlow::Node getARhs() { result = this.asSink() } + + /** DEPRECATED. This predicate has been renamed to `getAValueReachingSink()`. */ + deprecated DataFlow::Node getAValueReachingRhs() { result = this.getAValueReachingSink() } + /** * Gets a call to the function represented by this API component. */ From 092a6a01ac71d57baa80d0639907ccad8113eacb Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 14 Jun 2022 10:44:30 +0200 Subject: [PATCH 071/465] Python: Update member documentation --- python/ql/lib/semmle/python/ApiGraphs.qll | 60 +++++++++++------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index 7d59b14696f..65fffc9aee1 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -92,19 +92,10 @@ module API { */ class Node extends Impl::TApiNode { /** - * Gets a data-flow node corresponding to a use of the API component represented by this node. + * Gets a data-flow node where this value may flow after entering the current codebase. * - * For example, `import re; re.escape` is a use of the `escape` function from the - * `re` module, and `import re; re.escape("hello")` is a use of the return of that function. - * - * This includes indirect uses found via data flow, meaning that in - * ```python - * def f(x): - * pass - * - * f(obj.foo) - * ``` - * both `obj.foo` and `x` are uses of the `foo` member from `obj`. + * This is similar to `asSource()` but additionally includes nodes that are transitively reachable by data flow. + * See `asSource()` for examples. */ DataFlow::Node getAValueReachableFromSource() { exists(DataFlow::LocalSourceNode src | Impl::use(this, src) | @@ -113,39 +104,48 @@ module API { } /** - * Gets a data-flow node corresponding to the right-hand side of a definition of the API - * component represented by this node. + * Gets a data-flow node where this value leaves the current codebase and flows into an + * external library (or in general, any external codebase). * - * For example, in the property write `foo.bar = x`, variable `x` is the the right-hand side - * of a write to the `bar` property of `foo`. + * Concretely, this is either an argument passed to a call to external code, + * or the right-hand side of a property write on an object flowing into such a call. * - * Note that for parameters, it is the arguments flowing into that parameter that count as - * right-hand sides of the definition, not the declaration of the parameter itself. - * Consequently, in : + * For example: * ```python - * from mypkg import foo; + * import foo + * + * # 'x' is matched by API::moduleImport("foo").getMember("bar").getParameter(0).asSink() * foo.bar(x) + * + * # 'x' is matched by API::moduleImport("foo").getMember("bar").getParameter(0).getMember("prop").asSink() + * obj.prop = x + * foo.bar(obj); * ``` - * `x` is the right-hand side of a definition of the first parameter of `bar` from the `mypkg.foo` module. */ DataFlow::Node asSink() { Impl::rhs(this, result) } /** - * Gets a data-flow node that may interprocedurally flow to the right-hand side of a definition - * of the API component represented by this node. + * Gets a data-flow node that transitively flows to an external library (or in general, any external codebase). + * + * This is similar to `asSink()` but additionally includes nodes that transitively reach a sink by data flow. + * See `asSink()` for examples. */ DataFlow::Node getAValueReachingSink() { result = Impl::trackDefNode(this.asSink()) } /** - * Gets an immediate use of the API component represented by this node. + * Gets a data-flow node where this value enters the current codebase. * - * For example, `import re; re.escape` is a an immediate use of the `escape` member - * from the `re` module. + * For example: + * ```python + * # API::moduleImport("re").asSource() + * import re * - * Unlike `getAUse()`, this predicate only gets the immediate references, not the indirect uses - * found via data flow. This means that in `x = re.escape` only `re.escape` is a reference - * to the `escape` member of `re`, neither `x` nor any node that `x` flows to is a reference to - * this API component. + * # API::moduleImport("re").getMember("escape").asSource() + * re.escape + * + * # API::moduleImport("re").getMember("escape").getReturn().asSource() + * re.escape() + * ``` */ DataFlow::LocalSourceNode asSource() { Impl::use(this, result) } From 1ec838e671f1eeeb81ad1abfa3124f1bcdb2b863 Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Tue, 21 Jun 2022 09:14:23 -0700 Subject: [PATCH 072/465] Update docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst Co-authored-by: James Fletcher <42464962+jf205@users.noreply.github.com> --- .../codeql-cli/analyzing-databases-with-the-codeql-cli.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst index 84b76615520..6c7169634bb 100644 --- a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst @@ -174,6 +174,7 @@ To analyze your database using the `cpp-security-and-quality.qls` query suite fr codeql database analyze --format=sarif-latest --output=results \ 'codeql/cpp-queries@~0.0.3:codeql-suites/cpp-security-and-quality.qls' + For more information about CodeQL packs, see :doc:`About CodeQL Packs `. Running query suites From a2e2dcdfd5d743edd3eafd1bc34989f3332dcdb2 Mon Sep 17 00:00:00 2001 From: Brandon Stewart <20469703+boveus@users.noreply.github.com> Date: Tue, 21 Jun 2022 14:44:52 -0400 Subject: [PATCH 073/465] Make ActiveRecordInstanceMethodCall Public --- ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index 0846e30d047..5809b35baf4 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -331,7 +331,7 @@ class ActiveRecordInstance extends DataFlow::Node { } // A call whose receiver may be an active record model object -private class ActiveRecordInstanceMethodCall extends DataFlow::CallNode { +class ActiveRecordInstanceMethodCall extends DataFlow::CallNode { private ActiveRecordInstance instance; ActiveRecordInstanceMethodCall() { this.getReceiver() = instance } From 83b720d730c90f932b8fb1a2862645045233c804 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Sat, 18 Jun 2022 20:43:58 +0000 Subject: [PATCH 074/465] first draft of weak params query --- .../experimental/weak-params/WeakParams.ql | 46 +++++++++++++++++++ .../security/weak-params/WeakParams.expected | 0 .../security/weak-params/WeakParams.qlref | 1 + .../security/weak-params/WeakParams.rb | 15 ++++++ 4 files changed, 62 insertions(+) create mode 100644 ruby/ql/src/experimental/weak-params/WeakParams.ql create mode 100644 ruby/ql/test/query-tests/security/weak-params/WeakParams.expected create mode 100644 ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref create mode 100644 ruby/ql/test/query-tests/security/weak-params/WeakParams.rb diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql new file mode 100644 index 00000000000..b756d6ed8b8 --- /dev/null +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -0,0 +1,46 @@ +/** + * @name Weak or direct parameter references are used + * @description Directly checking request parameters without following a strong params pattern can lead to unintentional avenues for injection attacks. + * @kind problem + * @problem.severity error + * @security-severity 5.0 + * @precision low + * @id rb/weak-params + * @tags security + */ + +import ruby + +class WeakParams extends AstNode { + WeakParams() { + this instanceof UnspecificParamsMethod or + this instanceof ParamsReference + } +} + +class StrongParamsMethod extends Method { + StrongParamsMethod() { this.getName().regexpMatch(".*_params") } +} + +class UnspecificParamsMethod extends MethodCall { + UnspecificParamsMethod() { + ( + this.getMethodName() = "expose_all" or + this.getMethodName() = "original_hash" or + this.getMethodName() = "path_parametes" or + this.getMethodName() = "query_parameters" or + this.getMethodName() = "request_parameters" or + this.getMethodName() = "GET" or + this.getMethodName() = "POST" + ) + } +} + +class ParamsReference extends ElementReference { + ParamsReference() { this.getAChild().toString() = "params" } +} + +from WeakParams params +where not params.getEnclosingMethod() instanceof StrongParamsMethod +select params, + "By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects." diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.expected b/ruby/ql/test/query-tests/security/weak-params/WeakParams.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref b/ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref new file mode 100644 index 00000000000..5350e4bf40a --- /dev/null +++ b/ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref @@ -0,0 +1 @@ +experimental/weak-params/WeakParams.ql \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb b/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb new file mode 100644 index 00000000000..cc0dc80341f --- /dev/null +++ b/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb @@ -0,0 +1,15 @@ +class TestController < ActionController::Base + def create + TestObject.new(request.request_parameters) + end + + def create_query + TestObject.new(request.query_parameters) + end + + # + def object_params + p = params.query_parameters + params.require(:uuid).permit(:notes) + end +end \ No newline at end of file From 53729f99c5b0e5eb08903bd27797446b2f7ec23f Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Tue, 21 Jun 2022 20:28:29 +0000 Subject: [PATCH 075/465] restrict findings to just controller classes --- ruby/ql/src/experimental/weak-params/WeakParams.ql | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql index b756d6ed8b8..d7408f8bea7 100644 --- a/ruby/ql/src/experimental/weak-params/WeakParams.ql +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -18,6 +18,10 @@ class WeakParams extends AstNode { } } +class ControllerClass extends ModuleBase { + ControllerClass() { this.getModule().getSuperClass+().toString() = "ApplicationController" } +} + class StrongParamsMethod extends Method { StrongParamsMethod() { this.getName().regexpMatch(".*_params") } } @@ -41,6 +45,8 @@ class ParamsReference extends ElementReference { } from WeakParams params -where not params.getEnclosingMethod() instanceof StrongParamsMethod +where + not params.getEnclosingMethod() instanceof StrongParamsMethod and + params.getEnclosingModule() instanceof ControllerClass select params, "By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects." From 990747cd229b83f467c018d50ebd0ffdea93607d Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Tue, 21 Jun 2022 21:27:18 +0000 Subject: [PATCH 076/465] Limit findings to just those called in Controllers --- .../manually-check-http-verb/ManuallyCheckHttpVerb.ql | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql index 6946d26a7e8..98c2c266cab 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -23,6 +23,10 @@ class HttpVerbMethod extends MethodCall { } } +class ControllerClass extends ModuleBase { + ControllerClass() { this.getModule().getSuperClass+().toString() = "ApplicationController" } +} + class CheckRequestMethodFromEnv extends DataFlow::CallNode { CheckRequestMethodFromEnv() { // is this node an instance of `env["REQUEST_METHOD"] @@ -78,7 +82,10 @@ class CheckHeadRequest extends MethodCall { from CheckRequestMethodFromEnv env, AstNode node where - node instanceof HttpVerbMethod or - node = env.asExpr().getExpr() + ( + node instanceof HttpVerbMethod or + node = env.asExpr().getExpr() + ) and + node.getEnclosingModule() instanceof ControllerClass select node, "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods." From c767f241ad919d67b7a718207f669a457b464d53 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Wed, 22 Jun 2022 02:12:23 +0000 Subject: [PATCH 077/465] narrow query scope --- .../ManuallyCheckHttpVerb.ql | 65 +++++-------------- 1 file changed, 16 insertions(+), 49 deletions(-) diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql index 98c2c266cab..6e48255d4d6 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -12,39 +12,30 @@ import ruby import codeql.ruby.DataFlow -class HttpVerbMethod extends MethodCall { - HttpVerbMethod() { - this instanceof CheckGetRequest or - this instanceof CheckPostRequest or - this instanceof CheckPatchRequest or - this instanceof CheckPutRequest or - this instanceof CheckDeleteRequest or - this instanceof CheckHeadRequest - } +class CheckNotGetRequest extends ConditionalExpr { + CheckNotGetRequest() { this.getCondition() instanceof CheckGetRequest } +} + +class CheckGetRequest extends MethodCall { + CheckGetRequest() { this.getMethodName() = "get?" } } class ControllerClass extends ModuleBase { ControllerClass() { this.getModule().getSuperClass+().toString() = "ApplicationController" } } -class CheckRequestMethodFromEnv extends DataFlow::CallNode { - CheckRequestMethodFromEnv() { +class CheckGetFromEnv extends AstNode { + CheckGetFromEnv() { // is this node an instance of `env["REQUEST_METHOD"] - this.getExprNode().getNode() instanceof GetRequestMethodFromEnv and + this instanceof GetRequestMethodFromEnv and ( // and is this node a param of a call to `.include?` - exists(MethodCall call | call.getAnArgument() = this.getExprNode().getNode() | - call.getMethodName() = "include?" - ) + exists(MethodCall call | call.getAnArgument() = this | call.getMethodName() = "include?") or - exists(DataFlow::Node node | - node.asExpr().getExpr().(MethodCall).getMethodName() = "include?" - | - node.getALocalSource() = this + // check if env["REQUEST_METHOD"] is compared to GET + exists(EqualityOperation eq | eq.getAChild() = this | + eq.getAChild().(StringLiteral).toString() = "GET" ) - or - // or is this node on either size of an equality comparison - exists(EqualityOperation eq | eq.getAChild() = this.getExprNode().getNode()) ) } } @@ -56,35 +47,11 @@ class GetRequestMethodFromEnv extends ElementReference { } } -class CheckGetRequest extends MethodCall { - CheckGetRequest() { this.getMethodName() = "get?" } -} - -class CheckPostRequest extends MethodCall { - CheckPostRequest() { this.getMethodName() = "post?" } -} - -class CheckPutRequest extends MethodCall { - CheckPutRequest() { this.getMethodName() = "put?" } -} - -class CheckPatchRequest extends MethodCall { - CheckPatchRequest() { this.getMethodName() = "patch?" } -} - -class CheckDeleteRequest extends MethodCall { - CheckDeleteRequest() { this.getMethodName() = "delete?" } -} - -class CheckHeadRequest extends MethodCall { - CheckHeadRequest() { this.getMethodName() = "head?" } -} - -from CheckRequestMethodFromEnv env, AstNode node +from AstNode node where ( - node instanceof HttpVerbMethod or - node = env.asExpr().getExpr() + node instanceof CheckNotGetRequest or + node instanceof CheckGetFromEnv ) and node.getEnclosingModule() instanceof ControllerClass select node, From 995f36556847cb5997750f5d3d92600764b26d93 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Wed, 22 Jun 2022 02:17:01 +0000 Subject: [PATCH 078/465] just check string literal --- .../manually-check-http-verb/ManuallyCheckHttpVerb.ql | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql index 6e48255d4d6..a006587a13e 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -28,14 +28,9 @@ class CheckGetFromEnv extends AstNode { CheckGetFromEnv() { // is this node an instance of `env["REQUEST_METHOD"] this instanceof GetRequestMethodFromEnv and - ( - // and is this node a param of a call to `.include?` - exists(MethodCall call | call.getAnArgument() = this | call.getMethodName() = "include?") - or - // check if env["REQUEST_METHOD"] is compared to GET - exists(EqualityOperation eq | eq.getAChild() = this | - eq.getAChild().(StringLiteral).toString() = "GET" - ) + // check if env["REQUEST_METHOD"] is compared to GET + exists(EqualityOperation eq | eq.getAChild() = this | + eq.getAChild().(StringLiteral).toString() = "GET" ) } } From 0ef97b41c8fab10f56581f40f6f325cbcdae4594 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 22 Jun 2022 13:03:10 +0200 Subject: [PATCH 079/465] C#: Update .NET Runtime models and add sources and sinks. --- .../frameworks/generated/dotnet/Runtime.qll | 256 +----------------- 1 file changed, 13 insertions(+), 243 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll b/csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll index b3f247ede94..f4c5596c973 100644 --- a/csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll +++ b/csharp/ql/lib/semmle/code/csharp/frameworks/generated/dotnet/Runtime.qll @@ -1,11 +1,23 @@ /** * THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT. - * Definitions of taint steps in the dotnetruntime framework. + * Definitions of taint steps in the Runtime framework. */ import csharp private import semmle.code.csharp.dataflow.ExternalFlow +private class RuntimeSinksCsv extends SinkModelCsv { + override predicate row(string row) { + row = + [ + "System.Data.Odbc;OdbcDataAdapter;false;OdbcDataAdapter;(System.String,System.Data.Odbc.OdbcConnection);;Argument[0];sql;generated", + "System.Data.Odbc;OdbcDataAdapter;false;OdbcDataAdapter;(System.String,System.String);;Argument[0];sql;generated", + "System.Net.Http;StringContent;false;StringContent;(System.String);;Argument[0];xss;generated", + "System.Net.Http;StringContent;false;StringContent;(System.String,System.Text.Encoding);;Argument[0];xss;generated" + ] + } +} + private class RuntimeSummaryCsv extends SummaryModelCsv { override predicate row(string row) { row = @@ -529,11 +541,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.CodeDom.Compiler;GeneratedCodeAttribute;false;GeneratedCodeAttribute;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated", "System.CodeDom.Compiler;GeneratedCodeAttribute;false;get_Tool;();;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom.Compiler;GeneratedCodeAttribute;false;get_Version;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.CodeDom.Compiler;IndentedTextWriter;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom.Compiler;IndentedTextWriter;false;IndentedTextWriter;(System.IO.TextWriter,System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.CodeDom.Compiler;IndentedTextWriter;false;IndentedTextWriter;(System.IO.TextWriter,System.String);;Argument[1];Argument[Qualifier];taint;generated", - "System.CodeDom.Compiler;IndentedTextWriter;false;WriteLineNoTabsAsync;(System.String);;Argument[0];ReturnValue;taint;generated", - "System.CodeDom.Compiler;IndentedTextWriter;false;WriteLineNoTabsAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom.Compiler;IndentedTextWriter;false;get_Encoding;();;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom.Compiler;IndentedTextWriter;false;get_InnerWriter;();;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom.Compiler;IndentedTextWriter;false;get_NewLine;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -746,7 +755,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.CodeDom;CodeNamespaceImport;false;set_Namespace;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.CodeDom;CodeNamespaceImportCollection;false;Add;(System.CodeDom.CodeNamespaceImport);;Argument[0];Argument[Qualifier];taint;generated", "System.CodeDom;CodeNamespaceImportCollection;false;AddRange;(System.CodeDom.CodeNamespaceImport[]);;Argument[0].Element;Argument[Qualifier];taint;generated", - "System.CodeDom;CodeNamespaceImportCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom;CodeNamespaceImportCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.CodeDom;CodeNamespaceImportCollection;false;set_Item;(System.Int32,System.CodeDom.CodeNamespaceImport);;Argument[1];Argument[Qualifier];taint;generated", "System.CodeDom;CodeObject;false;get_UserData;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -919,7 +927,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Concurrent;ConcurrentBag<>;false;TryAdd;(T);;Argument[0];Argument[Qualifier];taint;generated", "System.Collections.Concurrent;ConcurrentBag<>;false;TryPeek;(T);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Concurrent;ConcurrentBag<>;false;TryTake;(T);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetOrAdd;(TKey,TValue);;Argument[1];ReturnValue;taint;generated", "System.Collections.Concurrent;ConcurrentDictionary<,>;false;get_Comparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Concurrent;ConcurrentStack<>;false;ConcurrentStack;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated", @@ -933,7 +940,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Concurrent;Partitioner;false;Create<>;(System.Collections.Generic.IEnumerable,System.Collections.Concurrent.EnumerablePartitionerOptions);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Concurrent;Partitioner;false;Create<>;(System.Collections.Generic.IList,System.Boolean);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Concurrent;Partitioner;false;Create<>;(TSource[],System.Boolean);;Argument[0].Element;ReturnValue;taint;generated", - "System.Collections.Generic;CollectionExtensions;false;AsReadOnly<,>;(System.Collections.Generic.IDictionary);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Generic;CollectionExtensions;false;AsReadOnly<>;(System.Collections.Generic.IList);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Generic;CollectionExtensions;false;GetDefaultAssets;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Generic;CollectionExtensions;false;GetDefaultGroup;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", @@ -945,9 +951,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[1];ReturnValue;taint;generated", "System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated", "System.Collections.Generic;CollectionExtensions;false;Remove<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;ReturnValue;taint;generated", - "System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;Argument[2];taint;generated", - "System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[1];Argument[0].Element;taint;generated", - "System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[2];Argument[0].Element;taint;generated", "System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Entry;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Key;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -967,8 +970,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Generic;HashSet<>;false;HashSet;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated", "System.Collections.Generic;HashSet<>;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Generic;HashSet<>;false;get_Comparer;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[1];ReturnValue;taint;generated", "System.Collections.Generic;KeyValuePair<,>;false;Deconstruct;(TKey,TValue);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Generic;KeyValuePair<,>;false;get_Key;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Generic;KeyValuePair<,>;false;get_Value;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -1120,12 +1121,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary;false;GetValueOrDefault<,>;(System.Collections.Immutable.IImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;taint;generated", @@ -1142,7 +1137,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableDictionary<,>+Builder;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary<,>+Builder;false;set_KeyComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated", "System.Collections.Immutable;ImmutableDictionary<,>+Builder;false;set_ValueComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated", - "System.Collections.Immutable;ImmutableDictionary<,>;false;Clear;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary<,>;false;Remove;(TKey);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary<,>;false;RemoveRange;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary<,>;false;SetItem;(TKey,TValue);;Argument[Qualifier];ReturnValue;taint;generated", @@ -1155,8 +1149,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableDictionary<,>;false;get_KeyComparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableDictionary<,>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Collections.Immutable;ImmutableDictionary<,>;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableHashSet;false;Create<>;(System.Collections.Generic.IEqualityComparer,T);;Argument[1];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableHashSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet;false;ToImmutableHashSet<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", @@ -1166,7 +1158,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableHashSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet<>+Builder;false;get_KeyComparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet<>+Builder;false;set_KeyComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated", - "System.Collections.Immutable;ImmutableHashSet<>;false;Clear;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet<>;false;Except;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet<>;false;Intersect;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet<>;false;Remove;(T);;Argument[Qualifier];ReturnValue;taint;generated", @@ -1179,9 +1170,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableHashSet<>;false;get_KeyComparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableHashSet<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Collections.Immutable;ImmutableInterlocked;false;GetOrAdd<,>;(System.Collections.Immutable.ImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableList;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableList;false;Create<>;(T[]);;Argument[0].Element;ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableList;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableList;false;Remove<>;(System.Collections.Immutable.IImmutableList,T);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableList;false;RemoveRange<>;(System.Collections.Immutable.IImmutableList,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableList;false;Replace<>;(System.Collections.Immutable.IImmutableList,T,T);;Argument[0].Element;ReturnValue;taint;generated", @@ -1240,12 +1228,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[1];ReturnValue;taint;generated", @@ -1262,8 +1244,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_KeyComparer;(System.Collections.Generic.IComparer);;Argument[0];Argument[Qualifier];taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_ValueComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Clear;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Remove;(TKey);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary<,>;false;RemoveRange;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedDictionary<,>;false;SetItem;(TKey,TValue);;Argument[0];ReturnValue;taint;generated", @@ -1281,10 +1261,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableSortedDictionary<,>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Collections.Immutable;ImmutableSortedDictionary<,>;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[1];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T[]);;Argument[0];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet;false;CreateBuilder<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated", @@ -1294,7 +1271,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableSortedSet;false;ToImmutableSortedSet<>;(System.Collections.Generic.IEnumerable,System.Collections.Generic.IComparer);;Argument[1];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet;false;ToImmutableSortedSet<>;(System.Collections.Immutable.ImmutableSortedSet+Builder);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;IntersectWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated", - "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;ToImmutable;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated", @@ -1305,13 +1281,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;set_KeyComparer;(System.Collections.Generic.IComparer);;Argument[0];Argument[Qualifier];taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet<>;false;Clear;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>;false;Except;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet<>;false;Intersect;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>;false;Remove;(T);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated", - "System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated", - "System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>;false;ToBuilder;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated", "System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated", @@ -1335,23 +1306,17 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections.Immutable;ImmutableStack<>;false;Push;(T);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;Collection<>;false;Collection;(System.Collections.Generic.IList);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated", - "System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated", "System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated", - "System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated", "System.Collections.ObjectModel;Collection<>;false;get_Items;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;Collection<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated", - "System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated", "System.Collections.ObjectModel;KeyedCollection<,>;false;KeyedCollection;(System.Collections.Generic.IEqualityComparer,System.Int32);;Argument[0];Argument[Qualifier];taint;generated", "System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated", - "System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated", "System.Collections.ObjectModel;KeyedCollection<,>;false;TryGetValue;(TKey,TItem);;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;KeyedCollection<,>;false;get_Comparer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;KeyedCollection<,>;false;get_Dictionary;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated", - "System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated", "System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated", - "System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated", "System.Collections.ObjectModel;ReadOnlyCollection<>;false;ReadOnlyCollection;(System.Collections.Generic.IList);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Collections.ObjectModel;ReadOnlyCollection<>;false;get_Items;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections.ObjectModel;ReadOnlyCollection<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -1430,7 +1395,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections;BitArray;false;Xor;(System.Collections.BitArray);;Argument[Qualifier];ReturnValue;value;generated", "System.Collections;BitArray;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[0];Argument[Qualifier];taint;generated", - "System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[Qualifier];Argument[0];taint;generated", "System.Collections;CollectionBase;false;get_InnerList;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections;CollectionBase;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections;CollectionBase;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -1480,7 +1444,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Collections;Stack;false;Synchronized;(System.Collections.Stack);;Argument[0].Element;ReturnValue;taint;generated", "System.Collections;Stack;false;ToArray;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Collections;Stack;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", - "System.ComponentModel.Composition.Hosting;AggregateCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;AggregateCatalog;false;get_Catalogs;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;AggregateExportProvider;false;AggregateExportProvider;(System.ComponentModel.Composition.Hosting.ExportProvider[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;AggregateExportProvider;false;GetExportsCore;(System.ComponentModel.Composition.Primitives.ImportDefinition,System.ComponentModel.Composition.Hosting.AtomicComposition);;Argument[Qualifier];ReturnValue;taint;generated", @@ -1489,7 +1452,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel.Composition.Hosting;ApplicationCatalog;false;ApplicationCatalog;(System.Reflection.ReflectionContext);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;ApplicationCatalog;false;ApplicationCatalog;(System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;ApplicationCatalog;false;ApplicationCatalog;(System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated", - "System.ComponentModel.Composition.Hosting;ApplicationCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.Reflection.Assembly);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.Reflection.Assembly,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.Reflection.Assembly,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated", @@ -1502,7 +1464,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.String,System.Reflection.ReflectionContext);;Argument[1];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;AssemblyCatalog;(System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[2];Argument[Qualifier];taint;generated", - "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;get_Assembly;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;AssemblyCatalog;false;get_DisplayName;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -1539,7 +1500,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;CompositionScopeDefinition;(System.ComponentModel.Composition.Primitives.ComposablePartCatalog,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;CompositionScopeDefinition;(System.ComponentModel.Composition.Primitives.ComposablePartCatalog,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[1].Element;Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;CompositionScopeDefinition;(System.ComponentModel.Composition.Primitives.ComposablePartCatalog,System.Collections.Generic.IEnumerable,System.Collections.Generic.IEnumerable);;Argument[2].Element;Argument[Qualifier];taint;generated", - "System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;get_Children;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;CompositionScopeDefinition;false;get_PublicSurface;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;DirectoryCatalog;(System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated", @@ -1554,7 +1514,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;DirectoryCatalog;(System.String,System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;DirectoryCatalog;(System.String,System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[2];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;DirectoryCatalog;(System.String,System.String,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[3];Argument[Qualifier];taint;generated", - "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;get_DisplayName;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;DirectoryCatalog;false;get_FullPath;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -1573,14 +1532,12 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel.Composition.Hosting;ExportsChangeEventArgs;false;get_AddedExports;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;ExportsChangeEventArgs;false;get_ChangedContractNames;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;ExportsChangeEventArgs;false;get_RemovedExports;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.ComponentModel.Composition.Hosting;FilteredCatalog;false;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;FilteredCatalog;false;get_Complement;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Hosting;ImportEngine;false;ImportEngine;(System.ComponentModel.Composition.Hosting.ExportProvider,System.ComponentModel.Composition.Hosting.CompositionOptions);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;TypeCatalog;false;TypeCatalog;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;TypeCatalog;false;TypeCatalog;(System.Collections.Generic.IEnumerable,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;TypeCatalog;false;TypeCatalog;(System.Collections.Generic.IEnumerable,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[1];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Hosting;TypeCatalog;false;TypeCatalog;(System.Collections.Generic.IEnumerable,System.Reflection.ReflectionContext,System.ComponentModel.Composition.Primitives.ICompositionElement);;Argument[2];Argument[Qualifier];taint;generated", - "System.ComponentModel.Composition.Primitives;ComposablePartCatalog;true;GetExports;(System.ComponentModel.Composition.Primitives.ImportDefinition);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Primitives;ComposablePartCatalog;true;get_Parts;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel.Composition.Primitives;ComposablePartException;false;ComposablePartException;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel.Composition.Primitives;ComposablePartException;false;ComposablePartException;(System.String,System.ComponentModel.Composition.Primitives.ICompositionElement,System.Exception);;Argument[1];Argument[Qualifier];taint;generated", @@ -1781,9 +1738,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel;BaseNumberConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[1];ReturnValue;taint;generated", "System.ComponentModel;BaseNumberConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated", "System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated", - "System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated", "System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated", - "System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated", "System.ComponentModel;CategoryAttribute;false;CategoryAttribute;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.ComponentModel;CategoryAttribute;false;get_Category;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel;CharConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated", @@ -1917,7 +1872,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.ComponentModel;ToolboxItemAttribute;false;get_ToolboxItemTypeName;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel;ToolboxItemFilterAttribute;false;get_TypeId;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel;TypeConverter+StandardValuesCollection;false;CopyTo;(System.Array,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;generated", - "System.ComponentModel;TypeConverter+StandardValuesCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel;TypeConverter+StandardValuesCollection;false;StandardValuesCollection;(System.Collections.ICollection);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.ComponentModel;TypeConverter+StandardValuesCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.ComponentModel;TypeConverter;false;ConvertFrom;(System.Object);;Argument[0];ReturnValue;taint;generated", @@ -2380,10 +2334,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data.Common;DataTableMappingCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Data.Common;DbCommand;false;ExecuteReader;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbCommand;false;ExecuteReader;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data.Common;DbCommand;false;ExecuteReaderAsync;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbCommand;false;get_Connection;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbCommand;false;get_Parameters;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbCommand;false;get_Transaction;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -2391,7 +2341,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data.Common;DbCommand;false;set_Connection;(System.Data.IDbConnection);;Argument[0];Argument[Qualifier];taint;generated", "System.Data.Common;DbCommand;false;set_Transaction;(System.Data.Common.DbTransaction);;Argument[0];Argument[Qualifier];taint;generated", "System.Data.Common;DbCommand;false;set_Transaction;(System.Data.IDbTransaction);;Argument[0];Argument[Qualifier];taint;generated", - "System.Data.Common;DbCommand;true;ExecuteDbDataReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbCommand;true;PrepareAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated", @@ -2418,7 +2367,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String);;Argument[2];Argument[0];taint;generated", "System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String,System.Boolean);;Argument[1];Argument[0];taint;generated", "System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String,System.Boolean);;Argument[2];Argument[0];taint;generated", - "System.Data.Common;DbConnectionStringBuilder;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbConnectionStringBuilder;false;GetProperties;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbConnectionStringBuilder;false;GetProperties;(System.Attribute[]);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbConnectionStringBuilder;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated", @@ -2445,12 +2393,9 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[0];ReturnValue;taint;generated", "System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[1];ReturnValue;taint;generated", "System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[3];ReturnValue;taint;generated", - "System.Data.Common;DbDataReader;false;GetFieldValueAsync<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbDataReader;true;GetFieldValue<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data.Common;DbDataReader;true;GetFieldValueAsync<>;(System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbDataReader;true;GetProviderSpecificValue;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbDataReader;true;GetProviderSpecificValues;(System.Object[]);;Argument[Qualifier];Argument[0].Element;taint;generated", - "System.Data.Common;DbDataReader;true;GetSchemaTableAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbDataReader;true;GetTextReader;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Common;DbDataRecord;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated", "System.Data.Common;DbEnumerator;false;DbEnumerator;(System.Data.IDataReader);;Argument[0];Argument[Qualifier];taint;generated", @@ -2595,7 +2540,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data.Odbc;OdbcParameter;false;set_Value;(System.Object);;Argument[0];Argument[Qualifier];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;Add;(System.Data.Odbc.OdbcParameter);;Argument[0];Argument[Qualifier];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;Add;(System.Data.Odbc.OdbcParameter);;Argument[0];ReturnValue;taint;generated", - "System.Data.Odbc;OdbcParameterCollection;false;Add;(System.Data.Odbc.OdbcParameter);;Argument[Qualifier];Argument[0];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;Add;(System.String,System.Data.Odbc.OdbcType);;Argument[0];Argument[Qualifier];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;Add;(System.String,System.Data.Odbc.OdbcType);;Argument[0];ReturnValue;taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;Add;(System.String,System.Data.Odbc.OdbcType,System.Int32);;Argument[0];Argument[Qualifier];taint;generated", @@ -2617,7 +2561,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data.Odbc;OdbcParameterCollection;false;GetParameter;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;GetParameter;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;Insert;(System.Int32,System.Data.Odbc.OdbcParameter);;Argument[1];Argument[Qualifier];taint;generated", - "System.Data.Odbc;OdbcParameterCollection;false;Insert;(System.Int32,System.Data.Odbc.OdbcParameter);;Argument[Qualifier];Argument[1];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;SetParameter;(System.Int32,System.Data.Common.DbParameter);;Argument[Qualifier];Argument[1];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;SetParameter;(System.String,System.Data.Common.DbParameter);;Argument[Qualifier];Argument[1];taint;generated", "System.Data.Odbc;OdbcParameterCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", @@ -2729,15 +2672,11 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data;DataColumn;false;set_Prefix;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Data;DataColumnChangeEventArgs;false;DataColumnChangeEventArgs;(System.Data.DataRow,System.Data.DataColumn,System.Object);;Argument[1];Argument[Qualifier];taint;generated", "System.Data;DataColumnChangeEventArgs;false;get_Column;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data;DataColumnCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data;DataColumnCollection;false;Add;(System.String,System.Type);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data;DataColumnCollection;false;Add;(System.String,System.Type,System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataColumnCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataColumnCollection;false;get_Item;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataColumnCollection;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataReaderExtensions;false;GetDateTime;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated", "System.Data;DataReaderExtensions;false;GetFieldValue<>;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated", - "System.Data;DataReaderExtensions;false;GetFieldValueAsync<>;(System.Data.Common.DbDataReader,System.String,System.Threading.CancellationToken);;Argument[0].Element;ReturnValue;taint;generated", "System.Data;DataReaderExtensions;false;GetGuid;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated", "System.Data;DataReaderExtensions;false;GetProviderSpecificValue;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated", "System.Data;DataReaderExtensions;false;GetString;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated", @@ -2767,16 +2706,10 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data;DataRelation;false;get_RelationName;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataRelation;false;set_RelationName;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Data;DataRelationCollection;false;Remove;(System.Data.DataRelation);;Argument[0];Argument[Qualifier];taint;generated", - "System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];ReturnValue;taint;generated", - "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];ReturnValue;taint;generated", - "System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataRow;false;DataRow;(System.Data.DataRowBuilder);;Argument[0];Argument[Qualifier];taint;generated", "System.Data;DataRow;false;GetChildRows;(System.Data.DataRelation);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataRow;false;GetChildRows;(System.Data.DataRelation,System.Data.DataRowVersion);;Argument[Qualifier];ReturnValue;taint;generated", @@ -2874,10 +2807,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Data;DataTable;false;set_PrimaryKey;(System.Data.DataColumn[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Data;DataTable;false;set_Site;(System.ComponentModel.ISite);;Argument[0];Argument[Qualifier];taint;generated", "System.Data;DataTable;false;set_TableName;(System.String);;Argument[0];Argument[Qualifier];taint;generated", - "System.Data;DataTableCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated", "System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];ReturnValue;taint;generated", - "System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataTableCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataTableCollection;false;get_Item;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.Data;DataTableCollection;false;get_Item;(System.String,System.String);;Argument[Qualifier];ReturnValue;taint;generated", @@ -3180,29 +3111,20 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.DirectoryServices.Protocols;DirSyncRequestControl;false;DirSyncRequestControl;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.DirectoryServices.Protocols;DirSyncRequestControl;false;set_Cookie;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.Byte[]);;Argument[Qualifier];Argument[0].Element;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.String);;Argument[0];Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.String);;Argument[Qualifier];Argument[0];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.Uri);;Argument[0];Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Add;(System.Uri);;Argument[Qualifier];Argument[0];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;AddRange;(System.Object[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;CopyTo;(System.Object[],System.Int32);;Argument[Qualifier];Argument[0].Element;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;DirectoryAttribute;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;DirectoryAttribute;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;DirectoryAttribute;(System.String,System.Object[]);;Argument[Qualifier];Argument[1].Element;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;GetValues;(System.Type);;Argument[Qualifier];ReturnValue;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.Byte[]);;Argument[1].Element;Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.Byte[]);;Argument[Qualifier];Argument[1].Element;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.String);;Argument[1];Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.String);;Argument[Qualifier];Argument[1];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.Uri);;Argument[1];Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Insert;(System.Int32,System.Uri);;Argument[Qualifier];Argument[1];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;Remove;(System.Object);;Argument[0];Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;Remove;(System.Object);;Argument[Qualifier];Argument[0];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;get_Name;();;Argument[Qualifier];ReturnValue;taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;set_Item;(System.Int32,System.Object);;Argument[1];Argument[Qualifier];taint;generated", - "System.DirectoryServices.Protocols;DirectoryAttribute;false;set_Item;(System.Int32,System.Object);;Argument[Qualifier];Argument[1];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttribute;false;set_Name;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttributeCollection;false;Add;(System.DirectoryServices.Protocols.DirectoryAttribute);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.DirectoryServices.Protocols;DirectoryAttributeCollection;false;AddRange;(System.DirectoryServices.Protocols.DirectoryAttributeCollection);;Argument[0].Element;Argument[Qualifier];taint;generated", @@ -3391,22 +3313,18 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Drawing.Printing;PrintPageEventArgs;false;get_PageBounds;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrintPageEventArgs;false;get_PageSettings;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;Add;(System.Drawing.Printing.PaperSize);;Argument[0];Argument[Qualifier];taint;generated", - "System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;PaperSizeCollection;(System.Drawing.Printing.PaperSize[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSizeCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;Add;(System.Drawing.Printing.PaperSource);;Argument[0];Argument[Qualifier];taint;generated", - "System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;PaperSourceCollection;(System.Drawing.Printing.PaperSource[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PaperSourceCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;Add;(System.Drawing.Printing.PrinterResolution);;Argument[0];Argument[Qualifier];taint;generated", - "System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;PrinterResolutionCollection;(System.Drawing.Printing.PrinterResolution[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+PrinterResolutionCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Drawing.Printing;PrinterSettings+StringCollection;false;Add;(System.String);;Argument[0];Argument[Qualifier];taint;generated", - "System.Drawing.Printing;PrinterSettings+StringCollection;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+StringCollection;false;StringCollection;(System.String[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Drawing.Printing;PrinterSettings+StringCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Drawing.Printing;PrinterSettings+StringCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", @@ -3663,14 +3581,10 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO.Compression;BrotliStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.IO.Compression;BrotliStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.Compression;DeflateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.IO.Compression;DeflateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO.Compression;DeflateStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.Compression;DeflateStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.Compression;GZipStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.IO.Compression;GZipStream;false;GZipStream;(System.IO.Stream,System.IO.Compression.CompressionLevel,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.IO.Compression;GZipStream;false;GZipStream;(System.IO.Stream,System.IO.Compression.CompressionMode,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", - "System.IO.Compression;GZipStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO.Compression;GZipStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.Compression;GZipStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.Compression;ZLibException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[Qualifier];Argument[0];taint;generated", "System.IO.Compression;ZLibException;false;ZLibException;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[0];Argument[Qualifier];taint;generated", @@ -3709,7 +3623,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO.IsolatedStorage;IsolatedStorage;false;get_AssemblyIdentity;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.IsolatedStorage;IsolatedStorage;false;get_DomainIdentity;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.IsolatedStorage;IsolatedStorageFileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.IO.IsolatedStorage;IsolatedStorageFileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO.IsolatedStorage;IsolatedStorageFileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", @@ -3830,7 +3743,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;BinaryReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated", - "System.IO;BinaryWriter;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;BinaryWriter;false;Write;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;BinaryWriter;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;BinaryWriter;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -3899,7 +3811,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;FileNotFoundException;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;FileNotFoundException;false;get_Message;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;FileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.IO;FileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;FileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.IO;FileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;FileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", @@ -3956,26 +3867,14 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;RenamedEventArgs;false;RenamedEventArgs;(System.IO.WatcherChangeTypes,System.String,System.String,System.String);;Argument[3];Argument[Qualifier];taint;generated", "System.IO;RenamedEventArgs;false;get_OldFullPath;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;RenamedEventArgs;false;get_OldName;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;Stream;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;Stream;false;Synchronized;(System.IO.Stream);;Argument[0];ReturnValue;taint;generated", - "System.IO;Stream;true;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;Stream;true;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;Stream;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StreamReader;false;StreamReader;(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StreamReader;false;StreamReader;(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated", "System.IO;StreamReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StreamReader;false;get_CurrentEncoding;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StreamWriter;false;StreamWriter;(System.IO.Stream,System.Text.Encoding,System.Int32,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StreamWriter;false;StreamWriter;(System.IO.Stream,System.Text.Encoding,System.Int32,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StreamWriter;false;WriteLine;(System.String,System.Object);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StreamWriter;false;WriteLine;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated", "System.IO;StreamWriter;false;WriteLine;(System.String,System.Object,System.Object);;Argument[0];Argument[Qualifier];taint;generated", @@ -3987,15 +3886,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;StreamWriter;false;WriteLine;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated", "System.IO;StreamWriter;false;WriteLine;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StreamWriter;false;WriteLine;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated", - "System.IO;StreamWriter;false;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StreamWriter;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StreamWriter;false;get_Encoding;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StringWriter;false;GetStringBuilder;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -4003,29 +3894,19 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;StringWriter;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;StringWriter;false;Write;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;Write;(System.String);;Argument[0];Argument[Qualifier];taint;generated", - "System.IO;StringWriter;false;Write;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.IO;StringWriter;false;WriteAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated", - "System.IO;StringWriter;false;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;StringWriter;false;WriteLine;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.IO;StringWriter;false;WriteLineAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated", - "System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextReader;false;Synchronized;(System.IO.TextReader);;Argument[0];ReturnValue;taint;generated", "System.IO;TextWriter;false;Synchronized;(System.IO.TextWriter);;Argument[0];ReturnValue;taint;generated", "System.IO;TextWriter;false;TextWriter;(System.IFormatProvider);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated", - "System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated", - "System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated", - "System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated", - "System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;true;Write;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;Write;(System.Object);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;Write;(System.String,System.Object);;Argument[0];Argument[Qualifier];taint;generated", @@ -4039,14 +3920,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;TextWriter;true;Write;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;true;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.IO;TextWriter;true;WriteLine;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;WriteLine;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated", @@ -4063,18 +3937,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.IO;TextWriter;true;WriteLine;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated", "System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated", - "System.IO;TextWriter;true;WriteLine;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", - "System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;true;get_FormatProvider;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;true;get_NewLine;();;Argument[Qualifier];ReturnValue;taint;generated", "System.IO;TextWriter;true;set_NewLine;(System.String);;Argument[0];Argument[Qualifier];taint;generated", @@ -4673,7 +4537,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Http.Headers;HeaderStringValues;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http.Headers;HttpHeaders;false;get_NonValidated;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http.Headers;HttpHeadersNonValidated+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http.Headers;HttpHeadersNonValidated;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http.Headers;HttpHeadersNonValidated;false;TryGetValue;(System.String,System.Net.Http.Headers.HeaderStringValues);;Argument[0];ReturnValue;taint;generated", "System.Net.Http.Headers;HttpHeadersNonValidated;false;TryGetValues;(System.String,System.Net.Http.Headers.HeaderStringValues);;Argument[0];ReturnValue;taint;generated", "System.Net.Http.Headers;HttpHeadersNonValidated;false;get_Item;(System.String);;Argument[0];ReturnValue;taint;generated", @@ -4774,23 +4637,14 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Net.Http;ByteArrayContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http;ByteArrayContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;ByteArrayContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated", "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;DelegatingHandler;false;DelegatingHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Http;DelegatingHandler;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Http;DelegatingHandler;false;get_InnerHandler;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;DelegatingHandler;false;set_InnerHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated", - "System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", "System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage);;Argument[Qualifier];Argument[0];taint;generated", "System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption);;Argument[Qualifier];Argument[0];taint;generated", "System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", @@ -4817,10 +4671,7 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Http;HttpContent;false;ReadAsStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;HttpContent;false;get_Headers;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;HttpContent;true;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http;HttpContent;true;CreateContentReadStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;HttpMessageInvoker;false;HttpMessageInvoker;(System.Net.Http.HttpMessageHandler,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Http;HttpMessageInvoker;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Http;HttpMethod;false;HttpMethod;(System.String);;Argument[0];Argument[Qualifier];taint;generated", @@ -4855,7 +4706,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent,System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Http;MultipartFormDataContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", "System.Net.Http;ReadOnlyMemoryContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http;ReadOnlyMemoryContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;ReadOnlyMemoryContent;false;ReadOnlyMemoryContent;(System.ReadOnlyMemory);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Http;SocketsHttpConnectionContext;false;get_DnsEndPoint;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;SocketsHttpConnectionContext;false;get_InitialRequestMessage;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -4894,19 +4744,11 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Http;SocketsHttpPlaintextStreamFilterContext;false;get_NegotiatedHttpVersion;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;SocketsHttpPlaintextStreamFilterContext;false;get_PlaintextStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;StreamContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated", "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream,System.Int32);;Argument[0];Argument[Qualifier];taint;generated", - "System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", "System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String);;Argument[0];ReturnValue;taint;generated", "System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[0];ReturnValue;taint;generated", "System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[1];ReturnValue;taint;generated", @@ -5039,7 +4881,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Quic;QuicListener;false;QuicListener;(System.Net.Quic.Implementations.QuicImplementationProvider,System.Net.Quic.QuicListenerOptions);;Argument[1];Argument[Qualifier];taint;generated", "System.Net.Quic;QuicListener;false;get_ListenEndPoint;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Security;AuthenticatedStream;false;AuthenticatedStream;(System.IO.Stream,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", - "System.Net.Security;AuthenticatedStream;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Security;AuthenticatedStream;false;get_InnerStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[1];Argument[Qualifier];taint;generated", "System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[2];Argument[Qualifier];taint;generated", @@ -5058,7 +4899,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Security;NegotiateStream;false;AuthenticateAsServerAsync;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ExtendedProtectionPolicy,System.Net.Security.ProtectionLevel,System.Security.Principal.TokenImpersonationLevel);;Argument[1];Argument[Qualifier];taint;generated", "System.Net.Security;NegotiateStream;false;AuthenticateAsServerAsync;(System.Security.Authentication.ExtendedProtection.ExtendedProtectionPolicy);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Security;NegotiateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Net.Security;NegotiateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", @@ -5071,7 +4911,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Security;SslCertificateTrust;false;CreateForX509Collection;(System.Security.Cryptography.X509Certificates.X509Certificate2Collection,System.Boolean);;Argument[0].Element;ReturnValue;taint;generated", "System.Net.Security;SslCertificateTrust;false;CreateForX509Store;(System.Security.Cryptography.X509Certificates.X509Store,System.Boolean);;Argument[0];ReturnValue;taint;generated", "System.Net.Security;SslStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Net.Security;SslStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Security;SslStream;false;Write;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Net.Security;SslStream;false;get_LocalCertificate;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Security;SslStream;false;get_NegotiatedApplicationProtocol;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -5102,7 +4941,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;NetworkStream;false;get_Socket;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Sockets;SafeSocketHandle;false;SafeSocketHandle;(System.IntPtr,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Sockets;Socket;false;Accept;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Sockets;Socket;false;AcceptAsync;(System.Net.Sockets.Socket);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;AcceptAsync;(System.Net.Sockets.Socket,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;AcceptAsync;(System.Net.Sockets.Socket,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;AcceptAsync;(System.Net.Sockets.Socket,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", @@ -5126,7 +4964,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;Socket;false;DisconnectAsync;(System.Boolean,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;DisconnectAsync;(System.Boolean,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;DisconnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated", - "System.Net.Sockets;Socket;false;EndAccept;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveAsync;(System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveAsync;(System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveAsync;(System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", @@ -5146,8 +4983,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;Socket;false;ReceiveFrom;(System.Span,System.Net.EndPoint);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveFrom;(System.Span,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[2];Argument[Qualifier];taint;generated", "System.Net.Sockets;Socket;false;ReceiveFrom;(System.Span,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[2];ReturnValue;taint;generated", - "System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.ArraySegment,System.Net.EndPoint);;Argument[1];ReturnValue;taint;generated", - "System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[2];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", @@ -5161,8 +4996,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;Socket;false;ReceiveMessageFrom;(System.Byte[],System.Int32,System.Int32,System.Net.Sockets.SocketFlags,System.Net.EndPoint,System.Net.Sockets.IPPacketInformation);;Argument[4];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveMessageFrom;(System.Span,System.Net.Sockets.SocketFlags,System.Net.EndPoint,System.Net.Sockets.IPPacketInformation);;Argument[2];Argument[Qualifier];taint;generated", "System.Net.Sockets;Socket;false;ReceiveMessageFrom;(System.Span,System.Net.Sockets.SocketFlags,System.Net.EndPoint,System.Net.Sockets.IPPacketInformation);;Argument[2];ReturnValue;taint;generated", - "System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.ArraySegment,System.Net.EndPoint);;Argument[1];ReturnValue;taint;generated", - "System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[2];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;Socket;false;ReceiveMessageFromAsync;(System.Memory,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated", @@ -5221,7 +5054,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;SocketAsyncEventArgs;false;set_SendPacketsElements;(System.Net.Sockets.SendPacketsElement[]);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Net.Sockets;SocketAsyncEventArgs;false;set_UserToken;(System.Object);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Sockets;SocketException;false;get_Message;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Sockets;SocketTaskExtensions;false;AcceptAsync;(System.Net.Sockets.Socket,System.Net.Sockets.Socket);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint);;Argument[1];Argument[0];taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[1];Argument[0];taint;generated", @@ -5233,8 +5065,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated", - "System.Net.Sockets;SocketTaskExtensions;false;ReceiveFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated", - "System.Net.Sockets;SocketTaskExtensions;false;ReceiveMessageFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated", "System.Net.Sockets;SocketTaskExtensions;false;SendToAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];Argument[0];taint;generated", @@ -5249,8 +5079,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net.Sockets;TcpListener;false;AcceptSocketAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;TcpListener;false;AcceptSocketAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net.Sockets;TcpListener;false;AcceptTcpClient;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net.Sockets;TcpListener;false;EndAcceptSocket;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net.Sockets;TcpListener;false;EndAcceptTcpClient;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", "System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPAddress,System.Int32);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPEndPoint);;Argument[0];Argument[Qualifier];taint;generated", "System.Net.Sockets;TcpListener;false;get_LocalEndpoint;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -5335,17 +5163,11 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net;CookieCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated", "System.Net;CookieException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[Qualifier];Argument[0];taint;generated", "System.Net;CredentialCache;false;GetCredential;(System.Uri,System.String);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net;Dns;false;EndGetHostAddresses;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net;Dns;false;EndGetHostByName;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net;Dns;false;EndGetHostEntry;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net;Dns;false;EndResolve;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", "System.Net;DnsEndPoint;false;DnsEndPoint;(System.String,System.Int32,System.Net.Sockets.AddressFamily);;Argument[0];Argument[Qualifier];taint;generated", "System.Net;DnsEndPoint;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;DnsEndPoint;false;get_Host;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;DownloadDataCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;DownloadStringCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net;FileWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net;FileWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", "System.Net;FileWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;FileWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;FileWebRequest;false;get_ContentType;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -5419,9 +5241,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net;HttpListenerTimeoutManager;false;get_IdleConnection;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;HttpListenerTimeoutManager;false;set_DrainEntityBody;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated", "System.Net;HttpListenerTimeoutManager;false;set_IdleConnection;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated", - "System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated", - "System.Net;HttpWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", "System.Net;HttpWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;HttpWebRequest;false;GetRequestStream;(System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;HttpWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -5478,7 +5297,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net;OpenWriteCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;PathList;false;get_Item;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;PathList;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Net;PathList;false;get_Values;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;ProtocolViolationException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[Qualifier];Argument[0];taint;generated", "System.Net;UploadDataCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Net;UploadFileCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -5508,8 +5326,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest);;Argument[0];ReturnValue;taint;generated", "System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];Argument[Qualifier];taint;generated", "System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];ReturnValue;taint;generated", - "System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];Argument[Qualifier];taint;generated", - "System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];ReturnValue;taint;generated", "System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];ReturnValue;taint;generated", "System.Net;WebClient;false;OpenRead;(System.String);;Argument[Qualifier];ReturnValue;taint;generated", @@ -6425,7 +6241,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Resources;ResourceReader;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Resources;ResourceReader;false;GetResourceData;(System.String,System.String,System.Byte[]);;Argument[Qualifier];ReturnValue;taint;generated", "System.Resources;ResourceReader;false;ResourceReader;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated", - "System.Resources;ResourceSet;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Resources;ResourceSet;false;ResourceSet;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated", "System.Resources;ResourceSet;false;ResourceSet;(System.Resources.IResourceReader);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Resources;ResourceWriter;false;ResourceWriter;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated", @@ -6836,7 +6651,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Security.Cryptography.Pkcs;Pkcs12SafeBag;false;set_Attributes;(System.Security.Cryptography.CryptographicAttributeObjectCollection);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Security.Cryptography.Pkcs;Pkcs12SafeContents;false;AddSafeBag;(System.Security.Cryptography.Pkcs.Pkcs12SafeBag);;Argument[0];Argument[Qualifier];taint;generated", "System.Security.Cryptography.Pkcs;Pkcs12SafeContents;false;AddSecret;(System.Security.Cryptography.Oid,System.ReadOnlyMemory);;Argument[0];ReturnValue;taint;generated", - "System.Security.Cryptography.Pkcs;Pkcs12SafeContents;false;GetBags;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Pkcs;Pkcs12SecretBag;false;GetSecretType;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Pkcs;Pkcs12SecretBag;false;get_SecretValue;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Pkcs;Pkcs9AttributeObject;false;CopyFrom;(System.Security.Cryptography.AsnEncodedData);;Argument[0];Argument[Qualifier];taint;generated", @@ -6923,7 +6737,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Security.Cryptography.X509Certificates;X509Certificate;false;ToString;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Issuer;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Subject;();;Argument[Qualifier];ReturnValue;taint;generated", - "System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;X509CertificateEnumerator;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;Remove;(System.Security.Cryptography.X509Certificates.X509Certificate);;Argument[0];Argument[Qualifier];taint;generated", "System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;X509CertificateCollection;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier];taint;generated", @@ -7044,7 +6857,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Security.Cryptography.Xml;EncryptionPropertyCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Xml;EncryptionPropertyCollection;false;set_ItemOf;(System.Int32,System.Security.Cryptography.Xml.EncryptionProperty);;Argument[1];Argument[Qualifier];taint;generated", "System.Security.Cryptography.Xml;KeyInfo;false;AddClause;(System.Security.Cryptography.Xml.KeyInfoClause);;Argument[0];Argument[Qualifier];taint;generated", - "System.Security.Cryptography.Xml;KeyInfo;false;GetEnumerator;(System.Type);;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Xml;KeyInfo;false;LoadXml;(System.Xml.XmlElement);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Security.Cryptography.Xml;KeyInfo;false;get_Id;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Xml;KeyInfo;false;set_Id;(System.String);;Argument[0];Argument[Qualifier];taint;generated", @@ -7157,7 +6969,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Security.Cryptography.Xml;Transform;false;set_Context;(System.Xml.XmlElement);;Argument[0].Element;Argument[Qualifier];taint;generated", "System.Security.Cryptography.Xml;Transform;false;set_Resolver;(System.Xml.XmlResolver);;Argument[0];Argument[Qualifier];taint;generated", "System.Security.Cryptography.Xml;TransformChain;false;Add;(System.Security.Cryptography.Xml.Transform);;Argument[0];Argument[Qualifier];taint;generated", - "System.Security.Cryptography.Xml;TransformChain;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Xml;TransformChain;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography.Xml;XmlDecryptionTransform;false;AddExceptUri;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Security.Cryptography.Xml;XmlDecryptionTransform;false;GetOutput;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -7223,7 +7034,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Security.Cryptography;CryptoStream;false;CryptoStream;(System.IO.Stream,System.Security.Cryptography.ICryptoTransform,System.Security.Cryptography.CryptoStreamMode,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", "System.Security.Cryptography;CryptoStream;false;CryptoStream;(System.IO.Stream,System.Security.Cryptography.ICryptoTransform,System.Security.Cryptography.CryptoStreamMode,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated", "System.Security.Cryptography;CryptoStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Security.Cryptography;CryptoStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography;CryptographicAttributeObject;false;CryptographicAttributeObject;(System.Security.Cryptography.Oid,System.Security.Cryptography.AsnEncodedDataCollection);;Argument[0];Argument[Qualifier];taint;generated", "System.Security.Cryptography;CryptographicAttributeObject;false;get_Oid;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Security.Cryptography;CryptographicAttributeObjectCollection;false;Add;(System.Security.Cryptography.CryptographicAttributeObject);;Argument[0];Argument[Qualifier];taint;generated", @@ -7488,7 +7298,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Text.Encodings.Web;TextEncoder;true;Encode;(System.IO.TextWriter,System.String,System.Int32,System.Int32);;Argument[1];Argument[0];taint;generated", "System.Text.Encodings.Web;TextEncoder;true;Encode;(System.String);;Argument[0];ReturnValue;taint;generated", "System.Text.Json.Nodes;JsonArray;false;Add<>;(T);;Argument[0];Argument[Qualifier];taint;generated", - "System.Text.Json.Nodes;JsonArray;false;Add<>;(T);;Argument[Qualifier];Argument[0];taint;generated", "System.Text.Json.Nodes;JsonArray;false;Create;(System.Text.Json.JsonElement,System.Nullable);;Argument[0];ReturnValue;taint;generated", "System.Text.Json.Nodes;JsonArray;false;JsonArray;(System.Text.Json.Nodes.JsonNodeOptions,System.Text.Json.Nodes.JsonNode[]);;Argument[Qualifier];Argument[1].Element;taint;generated", "System.Text.Json.Nodes;JsonArray;false;JsonArray;(System.Text.Json.Nodes.JsonNode[]);;Argument[Qualifier];Argument[0].Element;taint;generated", @@ -7508,7 +7317,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Text.Json.Serialization;JsonSerializerContext;false;JsonSerializerContext;(System.Text.Json.JsonSerializerOptions);;Argument[Qualifier];Argument[0];taint;generated", "System.Text.Json.Serialization;JsonSerializerContext;false;get_Options;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Text.Json.Serialization;JsonStringEnumConverter;false;JsonStringEnumConverter;(System.Text.Json.JsonNamingPolicy,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", - "System.Text.Json.SourceGeneration;JsonSourceGenerator;false;GetSerializableTypes;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Text.Json;JsonDocument;false;Parse;(System.Buffers.ReadOnlySequence,System.Text.Json.JsonDocumentOptions);;Argument[0];ReturnValue;taint;generated", "System.Text.Json;JsonDocument;false;Parse;(System.IO.Stream,System.Text.Json.JsonDocumentOptions);;Argument[0];ReturnValue;taint;generated", "System.Text.Json;JsonDocument;false;Parse;(System.ReadOnlyMemory,System.Text.Json.JsonDocumentOptions);;Argument[0];ReturnValue;taint;generated", @@ -7733,7 +7541,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Threading.RateLimiting;MetadataName<>;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Threading.RateLimiting;MetadataName<>;false;get_Name;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Threading.RateLimiting;RateLimitLease;false;TryGetMetadata<>;(System.Threading.RateLimiting.MetadataName,T);;Argument[Qualifier];ReturnValue;taint;generated", - "System.Threading.RateLimiting;RateLimitLease;true;GetAllMetadata;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Threading.RateLimiting;RateLimiter;false;Acquire;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated", "System.Threading.RateLimiting;RateLimiter;false;WaitAsync;(System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated", "System.Threading.RateLimiting;TokenBucketRateLimiter;false;TokenBucketRateLimiter;(System.Threading.RateLimiting.TokenBucketRateLimiterOptions);;Argument[0];Argument[Qualifier];taint;generated", @@ -7775,10 +7582,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated", "System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock);;Argument[0];ReturnValue;taint;generated", - "System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", - "System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated", - "System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated", "System.Threading.Tasks.Dataflow;DataflowBlock;false;SendAsync<>;(System.Threading.Tasks.Dataflow.ITargetBlock,TInput,System.Threading.CancellationToken);;Argument[1];Argument[0];taint;generated", "System.Threading.Tasks.Dataflow;DataflowBlock;false;TryReceive<>;(System.Threading.Tasks.Dataflow.IReceivableSourceBlock,TOutput);;Argument[0];ReturnValue;taint;generated", "System.Threading.Tasks.Dataflow;DataflowBlockOptions;false;get_CancellationToken;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -8374,12 +8177,9 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Xml.Schema;XmlSchemaSet;false;Add;(System.String,System.Xml.XmlReader);;Argument[Qualifier];ReturnValue;taint;generated", "System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchema);;Argument[0];Argument[Qualifier];taint;generated", "System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated", - "System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchemaSet);;Argument[0];Argument[Qualifier];taint;generated", - "System.Xml.Schema;XmlSchemaSet;false;CopyTo;(System.Xml.Schema.XmlSchema[],System.Int32);;Argument[Qualifier];Argument[0].Element;taint;generated", "System.Xml.Schema;XmlSchemaSet;false;Remove;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated", "System.Xml.Schema;XmlSchemaSet;false;Reprocess;(System.Xml.Schema.XmlSchema);;Argument[0];Argument[Qualifier];taint;generated", "System.Xml.Schema;XmlSchemaSet;false;Reprocess;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated", - "System.Xml.Schema;XmlSchemaSet;false;Schemas;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Xml.Schema;XmlSchemaSet;false;XmlSchemaSet;(System.Xml.XmlNameTable);;Argument[0];Argument[Qualifier];taint;generated", "System.Xml.Schema;XmlSchemaSet;false;get_CompilationSettings;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Xml.Schema;XmlSchemaSet;false;get_GlobalAttributes;();;Argument[Qualifier];ReturnValue;taint;generated", @@ -8466,10 +8266,8 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Xml.Schema;XmlSchemaXPath;false;get_XPath;();;Argument[Qualifier];ReturnValue;taint;generated", "System.Xml.Schema;XmlSchemaXPath;false;set_XPath;(System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Xml.Serialization;CodeIdentifiers;false;Add;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;CodeIdentifiers;false;Add;(System.String,System.Object);;Argument[Qualifier];Argument[1];taint;generated", "System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[0];ReturnValue;taint;generated", "System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[Qualifier];Argument[1];taint;generated", "System.Xml.Serialization;CodeIdentifiers;false;MakeUnique;(System.String);;Argument[0];ReturnValue;taint;generated", "System.Xml.Serialization;CodeIdentifiers;false;ToArray;(System.Type);;Argument[Qualifier];ReturnValue;taint;generated", "System.Xml.Serialization;ImportContext;false;ImportContext;(System.Xml.Serialization.CodeIdentifiers,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", @@ -8752,7 +8550,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.Xml.XmlQualifiedName);;Argument[1];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WriteId;(System.Object);;Argument[Qualifier];Argument[0];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncoded;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncodedRaw;(System.String,System.String,System.Byte[],System.Xml.XmlQualifiedName);;Argument[2].Element;Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncodedRaw;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated", @@ -8760,15 +8557,9 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringLiteralRaw;(System.String,System.String,System.Byte[]);;Argument[2].Element;Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringLiteralRaw;(System.String,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object);;Argument[2];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object);;Argument[Qualifier];Argument[2];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type);;Argument[2];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type);;Argument[Qualifier];Argument[2];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean);;Argument[2];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean,System.Boolean);;Argument[2];Argument[Qualifier];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WriteReferencingElement;(System.String,System.String,System.Object);;Argument[Qualifier];Argument[2];taint;generated", - "System.Xml.Serialization;XmlSerializationWriter;false;WriteReferencingElement;(System.String,System.String,System.Object,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteRpcResult;(System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteRpcResult;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated", "System.Xml.Serialization;XmlSerializationWriter;false;WriteSerializable;(System.Xml.Serialization.IXmlSerializable,System.String,System.String,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated", @@ -9945,27 +9736,6 @@ private class RuntimeSummaryCsv extends SummaryModelCsv { "System;Tuple<,>;false;get_Item2;();;Argument[Qualifier];ReturnValue;taint;generated", "System;Tuple<>;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated", "System;Tuple<>;false;get_Item1;();;Argument[Qualifier];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", - "System;TupleExtensions;false;ToTuple<>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated", "System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated", "System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated", "System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated", From 8899bf7f059ad0630366c53557419af1b0cf5084 Mon Sep 17 00:00:00 2001 From: Michael Nebel Date: Wed, 22 Jun 2022 13:03:23 +0200 Subject: [PATCH 080/465] C#: Update tests. --- .../dataflow/library/FlowSummaries.expected | 241 ------------------ .../library/FlowSummariesFiltered.expected | 170 +----------- 2 files changed, 8 insertions(+), 403 deletions(-) diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected index b6d827ca880..2d9fce246fb 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummaries.expected @@ -336,7 +336,6 @@ | System.Collections.Concurrent;ConcurrentDictionary<,>;false;CopyTo;(System.Collections.Generic.KeyValuePair[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | -| System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetOrAdd;(TKey,TValue);;Argument[1];ReturnValue;taint;generated | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;get_Item;(System.Object);;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue;value;manual | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;get_Item;(TKey);;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue;value;manual | @@ -370,9 +369,6 @@ | System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[1];ReturnValue;taint;generated | | System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated | | System.Collections.Generic;CollectionExtensions;false;Remove<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;Argument[2];taint;generated | -| System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[1];Argument[0].Element;taint;generated | -| System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[2];Argument[0].Element;taint;generated | | System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Entry;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Key;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -451,8 +447,6 @@ | System.Collections.Generic;IList<>;true;get_Item;(System.Int32);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections.Generic;IList<>;true;set_Item;(System.Int32,T);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.Generic;ISet<>;true;Add;(T);;Argument[0];Argument[Qualifier].Element;value;manual | -| System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[1];ReturnValue;taint;generated | | System.Collections.Generic;KeyValuePair<,>;false;Deconstruct;(TKey,TValue);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Generic;KeyValuePair<,>;false;KeyValuePair;(TKey,TValue);;Argument[0];ReturnValue.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Generic;KeyValuePair<,>;false;KeyValuePair;(TKey,TValue);;Argument[1];ReturnValue.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | @@ -726,12 +720,6 @@ | System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;GetValueOrDefault<,>;(System.Collections.Immutable.IImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;taint;generated | @@ -802,8 +790,6 @@ | System.Collections.Immutable;ImmutableDictionary<,>;false;set_Item;(System.Object,System.Object);;Argument[1];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections.Immutable;ImmutableDictionary<,>;false;set_Item;(TKey,TValue);;Argument[0];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Immutable;ImmutableDictionary<,>;false;set_Item;(TKey,TValue);;Argument[1];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | -| System.Collections.Immutable;ImmutableHashSet;false;Create<>;(System.Collections.Generic.IEqualityComparer,T);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableHashSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet;false;ToImmutableHashSet<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | @@ -836,9 +822,6 @@ | System.Collections.Immutable;ImmutableHashSet<>;false;get_KeyComparer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated | | System.Collections.Immutable;ImmutableInterlocked;false;GetOrAdd<,>;(System.Collections.Immutable.ImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableList;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableList;false;Create<>;(T[]);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableList;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableList;false;Remove<>;(System.Collections.Immutable.IImmutableList,T);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableList;false;RemoveRange<>;(System.Collections.Immutable.IImmutableList,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableList;false;Replace<>;(System.Collections.Immutable.IImmutableList,T,T);;Argument[0].Element;ReturnValue;taint;generated | @@ -945,12 +928,6 @@ | System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[1];ReturnValue;taint;generated | @@ -988,7 +965,6 @@ | System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_Item;(TKey,TValue);;Argument[1];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_KeyComparer;(System.Collections.Generic.IComparer);;Argument[0];Argument[Qualifier];taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_ValueComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Add;(System.Collections.Generic.KeyValuePair);;Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Add;(System.Collections.Generic.KeyValuePair);;Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Value];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Add;(System.Collections.Generic.KeyValuePair);;Argument[0];Argument[Qualifier].Element;value;manual | @@ -1027,10 +1003,7 @@ | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;set_Item;(TKey,TValue);;Argument[0];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;set_Item;(TKey,TValue);;Argument[1];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[1];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T[]);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;CreateBuilder<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated | @@ -1047,7 +1020,6 @@ | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;IntersectWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;ToImmutable;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated | @@ -1068,12 +1040,8 @@ | System.Collections.Immutable;ImmutableSortedSet<>;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual | | System.Collections.Immutable;ImmutableSortedSet<>;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.Immutable;ImmutableSortedSet<>;false;Insert;(System.Int32,T);;Argument[1];Argument[Qualifier].Element;value;manual | -| System.Collections.Immutable;ImmutableSortedSet<>;false;Intersect;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;Remove;(T);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;ToBuilder;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated | @@ -1111,27 +1079,21 @@ | System.Collections.ObjectModel;Collection<>;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.ObjectModel;Collection<>;false;Insert;(System.Int32,T);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;Collection<>;false;get_Item;(System.Int32);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections.ObjectModel;Collection<>;false;get_Items;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;Collection<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;Collection<>;false;set_Item;(System.Int32,System.Object);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.ObjectModel;Collection<>;false;set_Item;(System.Int32,T);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;KeyedCollection;(System.Collections.Generic.IEqualityComparer,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;TryGetValue;(TKey,TItem);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;get_Comparer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;get_Dictionary;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;get_Item;(TKey);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;ReadOnlyCollection<>;false;Add;(System.Object);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Collections.ObjectModel;ReadOnlyCollection<>;false;Add;(T);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Collections.ObjectModel;ReadOnlyCollection<>;false;CopyTo;(System.Array,System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | @@ -1328,7 +1290,6 @@ | System.Collections;CollectionBase;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Collections;CollectionBase;false;Insert;(System.Int32,System.Object);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[0];Argument[Qualifier];taint;generated | -| System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[Qualifier];Argument[0];taint;generated | | System.Collections;CollectionBase;false;get_InnerList;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections;CollectionBase;false;get_Item;(System.Int32);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections;CollectionBase;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -1559,9 +1520,7 @@ | System.ComponentModel;BaseNumberConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated | | System.ComponentModel;BindingList<>;false;Find;(System.ComponentModel.PropertyDescriptor,System.Object);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.ComponentModel;CategoryAttribute;false;CategoryAttribute;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.ComponentModel;CategoryAttribute;false;get_Category;();;Argument[Qualifier];ReturnValue;taint;generated | | System.ComponentModel;CharConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated | @@ -1882,10 +1841,6 @@ | System.Data.Common;DataTableMappingCollection;false;set_Item;(System.String,System.Object);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Data.Common;DbCommand;false;ExecuteReader;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;ExecuteReader;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;get_Connection;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;get_Parameters;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;get_Transaction;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -1893,7 +1848,6 @@ | System.Data.Common;DbCommand;false;set_Connection;(System.Data.IDbConnection);;Argument[0];Argument[Qualifier];taint;generated | | System.Data.Common;DbCommand;false;set_Transaction;(System.Data.Common.DbTransaction);;Argument[0];Argument[Qualifier];taint;generated | | System.Data.Common;DbCommand;false;set_Transaction;(System.Data.IDbTransaction);;Argument[0];Argument[Qualifier];taint;generated | -| System.Data.Common;DbCommand;true;ExecuteDbDataReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;true;PrepareAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | @@ -1926,7 +1880,6 @@ | System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String,System.Boolean);;Argument[2];Argument[0];taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;CopyTo;(System.Array,System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data.Common;DbConnectionStringBuilder;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | -| System.Data.Common;DbConnectionStringBuilder;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;GetProperties;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;GetProperties;(System.Attribute[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated | @@ -1961,13 +1914,10 @@ | System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[0];ReturnValue;taint;generated | | System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[1];ReturnValue;taint;generated | | System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[3];ReturnValue;taint;generated | -| System.Data.Common;DbDataReader;false;GetFieldValueAsync<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Data.Common;DbDataReader;true;GetFieldValue<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbDataReader;true;GetFieldValueAsync<>;(System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetProviderSpecificValue;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetProviderSpecificValues;(System.Object[]);;Argument[Qualifier];Argument[0].Element;taint;generated | -| System.Data.Common;DbDataReader;true;GetSchemaTableAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetTextReader;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataRecord;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated | | System.Data.Common;DbEnumerator;false;DbEnumerator;(System.Data.IDataReader);;Argument[0];Argument[Qualifier];taint;generated | @@ -2108,11 +2058,8 @@ | System.Data;DataColumn;false;set_Prefix;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataColumnChangeEventArgs;false;DataColumnChangeEventArgs;(System.Data.DataRow,System.Data.DataColumn,System.Object);;Argument[1];Argument[Qualifier];taint;generated | | System.Data;DataColumnChangeEventArgs;false;get_Column;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataColumnCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataColumnCollection;false;Add;(System.Data.DataColumn);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataColumnCollection;false;Add;(System.String);;Argument[0];Argument[Qualifier].Element;value;manual | -| System.Data;DataColumnCollection;false;Add;(System.String,System.Type);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataColumnCollection;false;Add;(System.String,System.Type,System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataColumnCollection;false;AddRange;(System.Data.DataColumn[]);;Argument[0].Element;Argument[Qualifier].Element;value;manual | | System.Data;DataColumnCollection;false;CopyTo;(System.Data.DataColumn[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data;DataColumnCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | @@ -2120,7 +2067,6 @@ | System.Data;DataColumnCollection;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetDateTime;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetFieldValue<>;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | -| System.Data;DataReaderExtensions;false;GetFieldValueAsync<>;(System.Data.Common.DbDataReader,System.String,System.Threading.CancellationToken);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetGuid;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetProviderSpecificValue;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetString;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | @@ -2152,16 +2098,10 @@ | System.Data;DataRelationCollection;false;Add;(System.Data.DataRelation);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataRelationCollection;false;CopyTo;(System.Data.DataRelation[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data;DataRelationCollection;false;Remove;(System.Data.DataRelation);;Argument[0];Argument[Qualifier];taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataRelationCollection;true;AddRange;(System.Data.DataRelation[]);;Argument[0].Element;Argument[Qualifier].Element;value;manual | | System.Data;DataRow;false;DataRow;(System.Data.DataRowBuilder);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataRow;false;GetChildRows;(System.Data.DataRelation);;Argument[Qualifier];ReturnValue;taint;generated | @@ -2267,12 +2207,10 @@ | System.Data;DataTable;false;set_PrimaryKey;(System.Data.DataColumn[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Data;DataTable;false;set_Site;(System.ComponentModel.ISite);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataTable;false;set_TableName;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.Data;DataTableCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataTableCollection;false;Add;(System.Data.DataTable);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataTableCollection;false;Add;(System.String);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];ReturnValue;taint;generated | -| System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataTableCollection;false;AddRange;(System.Data.DataTable[]);;Argument[0].Element;Argument[Qualifier].Element;value;manual | | System.Data;DataTableCollection;false;CopyTo;(System.Data.DataTable[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data;DataTableCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | @@ -2867,13 +2805,10 @@ | System.IO.Compression;BrotliStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.Compression;BrotliStream;false;BrotliStream;(System.IO.Stream,System.IO.Compression.CompressionMode,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO.Compression;BrotliStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO.Compression;BrotliStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;BrotliStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Compression;BrotliStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO.Compression;BrotliStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;BrotliStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.Compression;BrotliStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO.Compression;BrotliStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;BrotliStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;DeflateStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Compression;DeflateStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | @@ -2884,28 +2819,22 @@ | System.IO.Compression;DeflateStream;false;DeflateStream;(System.IO.Stream,System.IO.Compression.CompressionMode);;Argument[0];ReturnValue;taint;manual | | System.IO.Compression;DeflateStream;false;DeflateStream;(System.IO.Stream,System.IO.Compression.CompressionMode,System.Boolean);;Argument[0];ReturnValue;taint;manual | | System.IO.Compression;DeflateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO.Compression;DeflateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;DeflateStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Compression;DeflateStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO.Compression;DeflateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;DeflateStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.Compression;DeflateStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO.Compression;DeflateStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;DeflateStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;GZipStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Compression;GZipStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.Compression;GZipStream;false;CopyTo;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO.Compression;GZipStream;false;CopyToAsync;(System.IO.Stream,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | | System.IO.Compression;GZipStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO.Compression;GZipStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;GZipStream;false;GZipStream;(System.IO.Stream,System.IO.Compression.CompressionLevel,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO.Compression;GZipStream;false;GZipStream;(System.IO.Stream,System.IO.Compression.CompressionMode,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO.Compression;GZipStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Compression;GZipStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO.Compression;GZipStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;GZipStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.Compression;GZipStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO.Compression;GZipStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;GZipStream;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Compression;ZipArchive;false;CreateEntry;(System.String);;Argument[0];ReturnValue;taint;generated | | System.IO.Compression;ZipArchive;false;CreateEntry;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | @@ -2939,7 +2868,6 @@ | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO.IsolatedStorage;IsolatedStorageFileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | @@ -2965,14 +2893,11 @@ | System.IO.Pipes;NamedPipeServerStream;false;WaitForConnectionAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO.Pipes;PipeStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Pipes;PipeStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO.Pipes;PipeStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Pipes;PipeStream;false;InitializeHandle;(Microsoft.Win32.SafeHandles.SafePipeHandle,System.Boolean,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO.Pipes;PipeStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO.Pipes;PipeStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO.Pipes;PipeStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Pipes;PipeStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO.Pipes;PipeStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO.Pipes;PipeStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.Pipes;PipeStream;false;get_SafePipeHandle;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BinaryReader;false;BinaryReader;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;BinaryReader;false;BinaryReader;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | @@ -2982,7 +2907,6 @@ | System.IO;BinaryReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | -| System.IO;BinaryWriter;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BinaryWriter;false;Write;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;BinaryWriter;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;BinaryWriter;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -2991,13 +2915,10 @@ | System.IO;BufferedStream;false;BufferedStream;(System.IO.Stream,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;BufferedStream;false;CopyTo;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;BufferedStream;false;CopyToAsync;(System.IO.Stream,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | -| System.IO;BufferedStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BufferedStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;BufferedStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO;BufferedStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BufferedStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;BufferedStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO;BufferedStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BufferedStream;false;get_UnderlyingStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Directory;false;CreateDirectory;(System.String);;Argument[0];ReturnValue;taint;generated | | System.IO;Directory;false;GetParent;(System.String);;Argument[0];ReturnValue;taint;generated | @@ -3057,7 +2978,6 @@ | System.IO;FileStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;FileStream;false;CopyToAsync;(System.IO.Stream,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;FileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO;FileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;FileStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;FileStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;FileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | @@ -3091,7 +3011,6 @@ | System.IO;MemoryStream;false;CopyTo;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;MemoryStream;false;CopyToAsync;(System.IO.Stream,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;MemoryStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO;MemoryStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;MemoryStream;false;GetBuffer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;MemoryStream;false;MemoryStream;(System.Byte[]);;Argument[0];ReturnValue;taint;manual | | System.IO;MemoryStream;false;MemoryStream;(System.Byte[],System.Boolean);;Argument[0].Element;ReturnValue;taint;manual | @@ -3100,12 +3019,10 @@ | System.IO;MemoryStream;false;MemoryStream;(System.Byte[],System.Int32,System.Int32,System.Boolean,System.Boolean);;Argument[0].Element;ReturnValue;taint;manual | | System.IO;MemoryStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;MemoryStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO;MemoryStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;MemoryStream;false;ToArray;();;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;MemoryStream;false;TryGetBuffer;(System.ArraySegment);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;MemoryStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;MemoryStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO;MemoryStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;MemoryStream;false;WriteTo;(System.IO.Stream);;Argument[Qualifier];Argument[0];taint;generated | | System.IO;Path;false;ChangeExtension;(System.String,System.String);;Argument[0];ReturnValue;taint;generated | | System.IO;Path;false;Combine;(System.String,System.String);;Argument[0];ReturnValue;taint;manual | @@ -3150,7 +3067,6 @@ | System.IO;Stream;false;CopyToAsync;(System.IO.Stream);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;Stream;false;CopyToAsync;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;Stream;false;CopyToAsync;(System.IO.Stream,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | -| System.IO;Stream;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Stream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;Stream;false;Synchronized;(System.IO.Stream);;Argument[0];ReturnValue;taint;generated | | System.IO;Stream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | @@ -3158,13 +3074,10 @@ | System.IO;Stream;true;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;Stream;true;CopyTo;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;Stream;true;CopyToAsync;(System.IO.Stream,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | -| System.IO;Stream;true;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Stream;true;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;Stream;true;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO;Stream;true;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Stream;true;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;Stream;true;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO;Stream;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamReader;false;Read;();;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;StreamReader;false;Read;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;StreamReader;false;Read;(System.Span);;Argument[Qualifier];ReturnValue;taint;manual | @@ -3182,7 +3095,6 @@ | System.IO;StreamReader;false;StreamReader;(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | | System.IO;StreamReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamReader;false;get_CurrentEncoding;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamWriter;false;StreamWriter;(System.IO.Stream,System.Text.Encoding,System.Int32,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;StreamWriter;(System.IO.Stream,System.Text.Encoding,System.Int32,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;Write;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | @@ -3197,14 +3109,7 @@ | System.IO;StreamWriter;false;Write;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;Write;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;Write;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamWriter;false;WriteLine;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;WriteLine;(System.String,System.Object);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;WriteLine;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated | @@ -3217,15 +3122,7 @@ | System.IO;StreamWriter;false;WriteLine;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;WriteLine;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StreamWriter;false;WriteLine;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;StreamWriter;false;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamWriter;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamWriter;false;get_Encoding;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringReader;false;Read;();;Argument[Qualifier];ReturnValue;taint;manual | @@ -3241,39 +3138,19 @@ | System.IO;StringReader;false;ReadToEnd;();;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;StringReader;false;ReadToEndAsync;();;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;StringReader;false;StringReader;(System.String);;Argument[0];ReturnValue;taint;manual | -| System.IO;StringWriter;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;GetStringBuilder;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;StringWriter;(System.Text.StringBuilder,System.IFormatProvider);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;Write;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;Write;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;Write;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;StringWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;WriteAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLine;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;StringWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;WriteLineAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextReader;false;Synchronized;(System.IO.TextReader);;Argument[0];ReturnValue;taint;generated | | System.IO;TextReader;true;Read;();;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;TextReader;true;Read;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;manual | @@ -3291,12 +3168,7 @@ | System.IO;TextWriter;false;Synchronized;(System.IO.TextWriter);;Argument[0];ReturnValue;taint;generated | | System.IO;TextWriter;false;TextWriter;(System.IFormatProvider);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;Write;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.Object);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.String,System.Object);;Argument[0];Argument[Qualifier];taint;generated | @@ -3310,14 +3182,7 @@ | System.IO;TextWriter;true;Write;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteLine;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;WriteLine;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | @@ -3334,18 +3199,8 @@ | System.IO;TextWriter;true;WriteLine;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;true;WriteLine;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;get_FormatProvider;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;get_NewLine;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;set_NewLine;(System.String);;Argument[0];Argument[Qualifier];taint;generated | @@ -3353,19 +3208,16 @@ | System.IO;UnmanagedMemoryAccessor;false;UnmanagedMemoryAccessor;(System.Runtime.InteropServices.SafeBuffer,System.Int64,System.Int64);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryAccessor;false;UnmanagedMemoryAccessor;(System.Runtime.InteropServices.SafeBuffer,System.Int64,System.Int64,System.IO.FileAccess);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.IO;UnmanagedMemoryStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;UnmanagedMemoryStream;false;Initialize;(System.Byte*,System.Int64,System.Int64,System.IO.FileAccess);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;Initialize;(System.Runtime.InteropServices.SafeBuffer,System.Int64,System.Int64,System.IO.FileAccess);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;UnmanagedMemoryStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO;UnmanagedMemoryStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;UnmanagedMemoryStream;false;UnmanagedMemoryStream;(System.Byte*,System.Int64);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;UnmanagedMemoryStream;(System.Byte*,System.Int64,System.Int64,System.IO.FileAccess);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;UnmanagedMemoryStream;(System.Runtime.InteropServices.SafeBuffer,System.Int64,System.Int64);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;UnmanagedMemoryStream;(System.Runtime.InteropServices.SafeBuffer,System.Int64,System.Int64,System.IO.FileAccess);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;UnmanagedMemoryStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;UnmanagedMemoryStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO;UnmanagedMemoryStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;UnmanagedMemoryStream;false;get_PositionPointer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Linq.Expressions;BinaryExpression;false;Accept;(System.Linq.Expressions.ExpressionVisitor);;Argument[Qualifier];Argument[0];taint;generated | | System.Linq.Expressions;BinaryExpression;false;Accept;(System.Linq.Expressions.ExpressionVisitor);;Argument[Qualifier];ReturnValue;taint;generated | @@ -4687,29 +4539,18 @@ | System.Net.Http.Headers;WarningHeaderValue;false;get_Text;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http.Json;JsonContent;false;Create;(System.Object,System.Type,System.Net.Http.Headers.MediaTypeHeaderValue,System.Text.Json.JsonSerializerOptions);;Argument[3];ReturnValue;taint;generated | | System.Net.Http.Json;JsonContent;false;Create<>;(T,System.Net.Http.Headers.MediaTypeHeaderValue,System.Text.Json.JsonSerializerOptions);;Argument[2];ReturnValue;taint;generated | -| System.Net.Http.Json;JsonContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Http.Json;JsonContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http.Json;JsonContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.Http;ByteArrayContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;ByteArrayContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;DelegatingHandler;false;DelegatingHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;DelegatingHandler;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Http;DelegatingHandler;false;get_InnerHandler;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;DelegatingHandler;false;set_InnerHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | @@ -4736,10 +4577,7 @@ | System.Net.Http;HttpContent;false;ReadAsStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpContent;false;get_Headers;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpContent;true;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;HttpContent;true;CreateContentReadStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpMessageInvoker;false;HttpMessageInvoker;(System.Net.Http.HttpMessageHandler,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;HttpMessageInvoker;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Http;HttpMethod;false;HttpMethod;(System.String);;Argument[0];Argument[Qualifier];taint;generated | @@ -4781,27 +4619,19 @@ | System.Net.Http;MessageProcessingHandler;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Http;MultipartContent;false;Add;(System.Net.Http.HttpContent);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Net.Http;MultipartContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;MultipartContent;false;CreateContentReadStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;MultipartContent;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.Generic.IEnumerator<>.Current];value;manual | | System.Net.Http;MultipartContent;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Net.Http;MultipartContent;false;MultipartContent;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Net.Http;MultipartContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Http;MultipartContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;MultipartContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;MultipartContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;MultipartContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent,System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent,System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;MultipartFormDataContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;MultipartFormDataContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;MultipartFormDataContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;ReadOnlyMemoryContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;ReadOnlyMemoryContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;ReadOnlyMemoryContent;false;ReadOnlyMemoryContent;(System.ReadOnlyMemory);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;ReadOnlyMemoryContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;ReadOnlyMemoryContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;ReadOnlyMemoryContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;SocketsHttpConnectionContext;false;get_DnsEndPoint;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;SocketsHttpConnectionContext;false;get_InitialRequestMessage;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;SocketsHttpHandler;false;get_ConnectCallback;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -4838,19 +4668,11 @@ | System.Net.Http;SocketsHttpPlaintextStreamFilterContext;false;get_PlaintextStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String);;Argument[0];ReturnValue;taint;generated | | System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[0];ReturnValue;taint;generated | | System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[1];ReturnValue;taint;generated | @@ -4996,7 +4818,6 @@ | System.Net.NetworkInformation;UnicastIPAddressInformationCollection;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | | System.Net.NetworkInformation;UnicastIPAddressInformationCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;AuthenticatedStream;false;AuthenticatedStream;(System.IO.Stream,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Security;AuthenticatedStream;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;AuthenticatedStream;false;get_InnerStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[2];Argument[Qualifier];taint;generated | @@ -5017,7 +4838,6 @@ | System.Net.Security;NegotiateStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Security;NegotiateStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.Net.Security;NegotiateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Net.Security;NegotiateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Security;NegotiateStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | @@ -5034,14 +4854,11 @@ | System.Net.Security;SslStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Security;SslStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.Net.Security;SslStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Net.Security;SslStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Security;SslStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.Net.Security;SslStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslStream;false;Write;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.Security;SslStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.Net.Security;SslStream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.Net.Security;SslStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslStream;false;get_LocalCertificate;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslStream;false;get_NegotiatedApplicationProtocol;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslStream;false;get_RemoteCertificate;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -5062,7 +4879,6 @@ | System.Net.Sockets;MulticastOption;false;set_LocalAddress;(System.Net.IPAddress);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;NetworkStream;false;BeginRead;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Sockets;NetworkStream;false;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.Net.Sockets;NetworkStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Sockets;NetworkStream;false;NetworkStream;(System.Net.Sockets.Socket,System.IO.FileAccess,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;NetworkStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Net.Sockets;NetworkStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | @@ -5084,7 +4900,6 @@ | System.Net.Sockets;Socket;false;ConnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;Socket;false;ConnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Sockets;Socket;false;DisconnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Sockets;Socket;false;EndAccept;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;Socket;false;ReceiveAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Sockets;Socket;false;ReceiveFrom;(System.Byte[],System.Int32,System.Int32,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[4];Argument[Qualifier];taint;generated | | System.Net.Sockets;Socket;false;ReceiveFrom;(System.Byte[],System.Int32,System.Int32,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[4];ReturnValue;taint;generated | @@ -5127,7 +4942,6 @@ | System.Net.Sockets;SocketAsyncEventArgs;false;set_SendPacketsElements;(System.Net.Sockets.SendPacketsElement[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.Sockets;SocketAsyncEventArgs;false;set_UserToken;(System.Object);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;SocketException;false;get_Message;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Sockets;SocketTaskExtensions;false;AcceptAsync;(System.Net.Sockets.Socket,System.Net.Sockets.Socket);;Argument[1];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint);;Argument[1];Argument[0];taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[1];Argument[0];taint;generated | @@ -5139,8 +4953,6 @@ | System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated | -| System.Net.Sockets;SocketTaskExtensions;false;ReceiveFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated | -| System.Net.Sockets;SocketTaskExtensions;false;ReceiveMessageFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;SendToAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];Argument[0];taint;generated | @@ -5151,8 +4963,6 @@ | System.Net.Sockets;TcpClient;false;set_Client;(System.Net.Sockets.Socket);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;TcpListener;false;AcceptSocket;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Sockets;TcpListener;false;AcceptTcpClient;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Sockets;TcpListener;false;EndAcceptSocket;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net.Sockets;TcpListener;false;EndAcceptTcpClient;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPAddress,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPEndPoint);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;TcpListener;false;get_LocalEndpoint;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -5230,17 +5040,11 @@ | System.Net;CookieException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[Qualifier];Argument[0];taint;generated | | System.Net;CredentialCache;false;GetCredential;(System.Uri,System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;CredentialCache;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | -| System.Net;Dns;false;EndGetHostAddresses;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;Dns;false;EndGetHostByName;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;Dns;false;EndGetHostEntry;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;Dns;false;EndResolve;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net;DnsEndPoint;false;DnsEndPoint;(System.String,System.Int32,System.Net.Sockets.AddressFamily);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;DnsEndPoint;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;DnsEndPoint;false;get_Host;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;DownloadDataCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;DownloadStringCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net;FileWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;FileWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net;FileWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;FileWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;FileWebRequest;false;get_ContentType;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -5319,9 +5123,6 @@ | System.Net;HttpListenerTimeoutManager;false;get_IdleConnection;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;HttpListenerTimeoutManager;false;set_DrainEntityBody;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;HttpListenerTimeoutManager;false;set_IdleConnection;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated | -| System.Net;HttpWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net;HttpWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;HttpWebRequest;false;GetRequestStream;(System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;HttpWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -5407,8 +5208,6 @@ | System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest);;Argument[0];ReturnValue;taint;generated | | System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];Argument[Qualifier];taint;generated | -| System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];ReturnValue;taint;generated | | System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];ReturnValue;taint;generated | | System.Net;WebClient;false;OpenRead;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | @@ -6342,7 +6141,6 @@ | System.Resources;ResourceReader;false;GetResourceData;(System.String,System.String,System.Byte[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.Resources;ResourceReader;false;ResourceReader;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | | System.Resources;ResourceSet;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.IEnumerator.Current];value;manual | -| System.Resources;ResourceSet;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Resources;ResourceSet;false;ResourceSet;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | | System.Resources;ResourceSet;false;ResourceSet;(System.Resources.IResourceReader);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Resources;ResourceWriter;false;ResourceWriter;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | @@ -6725,7 +6523,6 @@ | System.Security.Cryptography.X509Certificates;X509Certificate;false;ToString;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Issuer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Subject;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;X509CertificateEnumerator;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;Add;(System.Security.Cryptography.X509Certificates.X509Certificate);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;AddRange;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier].Element;value;manual | @@ -6794,7 +6591,6 @@ | System.Security.Cryptography;CryptoStream;false;CryptoStream;(System.IO.Stream,System.Security.Cryptography.ICryptoTransform,System.Security.Cryptography.CryptoStreamMode,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Security.Cryptography;CryptoStream;false;CryptoStream;(System.IO.Stream,System.Security.Cryptography.ICryptoTransform,System.Security.Cryptography.CryptoStreamMode,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | | System.Security.Cryptography;CryptoStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Security.Cryptography;CryptoStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography;CryptoStream;false;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Security.Cryptography;CryptoStream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.Security.Cryptography;CryptoStream;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | @@ -7313,10 +7109,6 @@ | System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;SendAsync<>;(System.Threading.Tasks.Dataflow.ITargetBlock,TInput,System.Threading.CancellationToken);;Argument[1];Argument[0];taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;TryReceive<>;(System.Threading.Tasks.Dataflow.IReceivableSourceBlock,TOutput);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlockOptions;false;get_CancellationToken;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -8103,12 +7895,9 @@ | System.Xml.Schema;XmlSchemaSet;false;Add;(System.String,System.Xml.XmlReader);;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchema);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated | -| System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchemaSet);;Argument[0];Argument[Qualifier];taint;generated | -| System.Xml.Schema;XmlSchemaSet;false;CopyTo;(System.Xml.Schema.XmlSchema[],System.Int32);;Argument[Qualifier];Argument[0].Element;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Remove;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Reprocess;(System.Xml.Schema.XmlSchema);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Reprocess;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated | -| System.Xml.Schema;XmlSchemaSet;false;Schemas;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;XmlSchemaSet;(System.Xml.XmlNameTable);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Schema;XmlSchemaSet;false;get_CompilationSettings;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;get_GlobalAttributes;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -8195,10 +7984,8 @@ | System.Xml.Schema;XmlSchemaXPath;false;get_XPath;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaXPath;false;set_XPath;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;Add;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;CodeIdentifiers;false;Add;(System.String,System.Object);;Argument[Qualifier];Argument[1];taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[0];ReturnValue;taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[Qualifier];Argument[1];taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;MakeUnique;(System.String);;Argument[0];ReturnValue;taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;ToArray;(System.Type);;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Serialization;ImportContext;false;ImportContext;(System.Xml.Serialization.CodeIdentifiers,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | @@ -8505,7 +8292,6 @@ | System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.Xml.XmlQualifiedName);;Argument[1];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WriteId;(System.Object);;Argument[Qualifier];Argument[0];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncoded;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncodedRaw;(System.String,System.String,System.Byte[],System.Xml.XmlQualifiedName);;Argument[2].Element;Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncodedRaw;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated | @@ -8513,15 +8299,9 @@ | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringLiteralRaw;(System.String,System.String,System.Byte[]);;Argument[2].Element;Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringLiteralRaw;(System.String,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean,System.Boolean);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WriteReferencingElement;(System.String,System.String,System.Object);;Argument[Qualifier];Argument[2];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WriteReferencingElement;(System.String,System.String,System.Object,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteRpcResult;(System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteRpcResult;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteSerializable;(System.Xml.Serialization.IXmlSerializable,System.String,System.String,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | @@ -10357,27 +10137,6 @@ | System;TupleExtensions;false;Deconstruct<,>;(System.Tuple,T1,T2);;Argument[0].Property[System.Tuple<,>.Item1];Argument[1];value;manual | | System;TupleExtensions;false;Deconstruct<,>;(System.Tuple,T1,T2);;Argument[0].Property[System.Tuple<,>.Item2];Argument[2];value;manual | | System;TupleExtensions;false;Deconstruct<>;(System.Tuple,T1);;Argument[0].Property[System.Tuple<>.Item1];Argument[1];value;manual | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | | System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated | | System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated | | System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated | diff --git a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected index 1a2f70f48e8..a77b56ab64b 100644 --- a/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected +++ b/csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.expected @@ -255,7 +255,6 @@ | System.Collections.Concurrent;ConcurrentDictionary<,>;false;ConcurrentDictionary;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IEqualityComparer);;Argument[0].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue.Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;ConcurrentDictionary;(System.Int32,System.Collections.Generic.IEnumerable>,System.Collections.Generic.IEqualityComparer);;Argument[1].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];ReturnValue.Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;ConcurrentDictionary;(System.Int32,System.Collections.Generic.IEnumerable>,System.Collections.Generic.IEqualityComparer);;Argument[1].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue.Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | -| System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;GetOrAdd;(TKey,TValue);;Argument[1];ReturnValue;taint;generated | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;get_Keys;();;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];ReturnValue.Element;value;manual | | System.Collections.Concurrent;ConcurrentDictionary<,>;false;get_Values;();;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue.Element;value;manual | @@ -275,9 +274,6 @@ | System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[1];ReturnValue;taint;generated | | System.Collections.Generic;CollectionExtensions;false;GetValueOrDefault<,>;(System.Collections.Generic.IReadOnlyDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated | | System.Collections.Generic;CollectionExtensions;false;Remove<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[0].Element;Argument[2];taint;generated | -| System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[1];Argument[0].Element;taint;generated | -| System.Collections.Generic;CollectionExtensions;false;TryAdd<,>;(System.Collections.Generic.IDictionary,TKey,TValue);;Argument[2];Argument[0].Element;taint;generated | | System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Entry;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Generic;Dictionary<,>+Enumerator;false;get_Key;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -327,8 +323,6 @@ | System.Collections.Generic;IList<>;true;get_Item;(System.Int32);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections.Generic;IList<>;true;set_Item;(System.Int32,T);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Collections.Generic;ISet<>;true;Add;(T);;Argument[0];Argument[Qualifier].Element;value;manual | -| System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Generic;KeyValuePair;false;Create<,>;(TKey,TValue);;Argument[1];ReturnValue;taint;generated | | System.Collections.Generic;KeyValuePair<,>;false;Deconstruct;(TKey,TValue);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Generic;KeyValuePair<,>;false;KeyValuePair;(TKey,TValue);;Argument[0];ReturnValue.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Generic;KeyValuePair<,>;false;KeyValuePair;(TKey,TValue);;Argument[1];ReturnValue.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | @@ -518,12 +512,6 @@ | System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;Create<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableDictionary;false;CreateRange<,>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;GetValueOrDefault<,>;(System.Collections.Immutable.IImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary;false;ToImmutableDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IEqualityComparer);;Argument[0].Element;ReturnValue;taint;generated | @@ -567,8 +555,6 @@ | System.Collections.Immutable;ImmutableDictionary<,>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated | | System.Collections.Immutable;ImmutableDictionary<,>;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableDictionary<,>;false;get_Values;();;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableHashSet;false;Create<>;(System.Collections.Generic.IEqualityComparer,T);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableHashSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet;false;CreateRange<>;(System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet;false;ToImmutableHashSet<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | @@ -593,9 +579,6 @@ | System.Collections.Immutable;ImmutableHashSet<>;false;get_KeyComparer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableHashSet<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated | | System.Collections.Immutable;ImmutableInterlocked;false;GetOrAdd<,>;(System.Collections.Immutable.ImmutableDictionary,TKey,TValue);;Argument[2];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableList;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableList;false;Create<>;(T[]);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableList;false;CreateRange<>;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableList;false;Remove<>;(System.Collections.Immutable.IImmutableList,T);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableList;false;RemoveRange<>;(System.Collections.Immutable.IImmutableList,System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableList;false;Replace<>;(System.Collections.Immutable.IImmutableList,T,T);;Argument[0].Element;ReturnValue;taint;generated | @@ -681,12 +664,6 @@ | System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;CreateBuilder<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable>);;Argument[1].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[1];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEqualityComparer,System.Collections.Generic.IEnumerable>);;Argument[2].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary;false;CreateRange<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[0].Element;ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary;false;ToImmutableSortedDictionary<,>;(System.Collections.Generic.IEnumerable>,System.Collections.Generic.IComparer);;Argument[1];ReturnValue;taint;generated | @@ -709,7 +686,6 @@ | System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;get_Values;();;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_KeyComparer;(System.Collections.Generic.IComparer);;Argument[0];Argument[Qualifier];taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary<,>+Builder;false;set_ValueComparer;(System.Collections.Generic.IEqualityComparer);;Argument[0];Argument[Qualifier];taint;generated | -| System.Collections.Immutable;ImmutableSortedDictionary<,>+Enumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Add;(System.Collections.Generic.KeyValuePair);;Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Add;(System.Collections.Generic.KeyValuePair);;Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Value];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];value;manual | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;Add;(TKey,TValue);;Argument[0];Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key];value;manual | @@ -736,10 +712,7 @@ | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;get_ValueComparer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedDictionary<,>;false;get_Values;();;Argument[Qualifier].Element.Property[System.Collections.Generic.KeyValuePair<,>.Value];ReturnValue.Element;value;manual | | System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T);;Argument[1];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(System.Collections.Generic.IComparer,T[]);;Argument[0];ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet;false;Create<>;(T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;CreateBuilder<>;(System.Collections.Generic.IComparer);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet;false;CreateRange<>;(System.Collections.Generic.IComparer,System.Collections.Generic.IEnumerable);;Argument[1].Element;ReturnValue;taint;generated | @@ -751,7 +724,6 @@ | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;IntersectWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;SymmetricExceptWith;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;ToImmutable;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>+Builder;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated | @@ -765,12 +737,8 @@ | System.Collections.Immutable;ImmutableSortedSet<>;false;Add;(T);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Collections.Immutable;ImmutableSortedSet<>;false;Except;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;GetEnumerator;();;Argument[Qualifier].Element;ReturnValue.Property[System.Collections.Immutable.ImmutableSortedSet<>+Enumerator.Current];value;manual | -| System.Collections.Immutable;ImmutableSortedSet<>;false;Intersect;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;Remove;(T);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;Reverse;();;Argument[0].Element;ReturnValue.Element;value;manual | -| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[0].Element;ReturnValue;taint;generated | -| System.Collections.Immutable;ImmutableSortedSet<>;false;SymmetricExcept;(System.Collections.Generic.IEnumerable);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;ToBuilder;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[0];ReturnValue;taint;generated | | System.Collections.Immutable;ImmutableSortedSet<>;false;TryGetValue;(T,T);;Argument[Qualifier];ReturnValue;taint;generated | @@ -796,24 +764,18 @@ | System.Collections.Immutable;ImmutableStack<>;false;Push;(T);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;Collection<>;false;Collection;(System.Collections.Generic.IList);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;Collection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;Collection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;Collection<>;false;get_Items;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;Collection<>;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;KeyedCollection<,>;false;InsertItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;KeyedCollection;(System.Collections.Generic.IEqualityComparer,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;KeyedCollection<,>;false;SetItem;(System.Int32,TItem);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;TryGetValue;(TKey,TItem);;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;get_Comparer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;get_Dictionary;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections.ObjectModel;KeyedCollection<,>;false;get_Item;(TKey);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;ObservableCollection<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.Collections.ObjectModel;ObservableCollection<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.Collections.ObjectModel;ReadOnlyCollection<>;false;ReadOnlyCollection;(System.Collections.Generic.IList);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Collections.ObjectModel;ReadOnlyCollection<>;false;get_Item;(System.Int32);;Argument[Qualifier].Element;ReturnValue;value;manual | | System.Collections.ObjectModel;ReadOnlyCollection<>;false;get_Items;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -924,7 +886,6 @@ | System.Collections;BitArray;false;Xor;(System.Collections.BitArray);;Argument[Qualifier];ReturnValue;value;generated | | System.Collections;BitArray;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated | | System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[0];Argument[Qualifier];taint;generated | -| System.Collections;CollectionBase;false;Remove;(System.Object);;Argument[Qualifier];Argument[0];taint;generated | | System.Collections;CollectionBase;false;get_InnerList;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections;CollectionBase;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Collections;CollectionBase;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -1101,9 +1062,7 @@ | System.ComponentModel;BaseNumberConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[1];ReturnValue;taint;generated | | System.ComponentModel;BaseNumberConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated | | System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.ComponentModel;BindingList<>;false;InsertItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[1];Argument[Qualifier];taint;generated | -| System.ComponentModel;BindingList<>;false;SetItem;(System.Int32,T);;Argument[Qualifier];Argument[1];taint;generated | | System.ComponentModel;CategoryAttribute;false;CategoryAttribute;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.ComponentModel;CategoryAttribute;false;get_Category;();;Argument[Qualifier];ReturnValue;taint;generated | | System.ComponentModel;CharConverter;false;ConvertTo;(System.ComponentModel.ITypeDescriptorContext,System.Globalization.CultureInfo,System.Object,System.Type);;Argument[2];ReturnValue;taint;generated | @@ -1388,10 +1347,6 @@ | System.Data.Common;DataTableMappingCollection;false;set_Item;(System.String,System.Data.Common.DataTableMapping);;Argument[1];Argument[Qualifier].Element;value;manual | | System.Data.Common;DbCommand;false;ExecuteReader;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;ExecuteReader;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbCommand;false;ExecuteReaderAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;get_Connection;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;get_Parameters;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;false;get_Transaction;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -1399,7 +1354,6 @@ | System.Data.Common;DbCommand;false;set_Connection;(System.Data.IDbConnection);;Argument[0];Argument[Qualifier];taint;generated | | System.Data.Common;DbCommand;false;set_Transaction;(System.Data.Common.DbTransaction);;Argument[0];Argument[Qualifier];taint;generated | | System.Data.Common;DbCommand;false;set_Transaction;(System.Data.IDbTransaction);;Argument[0];Argument[Qualifier];taint;generated | -| System.Data.Common;DbCommand;true;ExecuteDbDataReaderAsync;(System.Data.CommandBehavior,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommand;true;PrepareAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbCommandBuilder;false;GetDeleteCommand;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | @@ -1428,7 +1382,6 @@ | System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String);;Argument[2];Argument[0];taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String,System.Boolean);;Argument[1];Argument[0];taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;AppendKeyValuePair;(System.Text.StringBuilder,System.String,System.String,System.Boolean);;Argument[2];Argument[0];taint;generated | -| System.Data.Common;DbConnectionStringBuilder;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;GetProperties;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;GetProperties;(System.Attribute[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbConnectionStringBuilder;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated | @@ -1458,12 +1411,9 @@ | System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[0];ReturnValue;taint;generated | | System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[1];ReturnValue;taint;generated | | System.Data.Common;DbDataAdapter;true;CreateRowUpdatingEvent;(System.Data.DataRow,System.Data.IDbCommand,System.Data.StatementType,System.Data.Common.DataTableMapping);;Argument[3];ReturnValue;taint;generated | -| System.Data.Common;DbDataReader;false;GetFieldValueAsync<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetFieldValue<>;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data.Common;DbDataReader;true;GetFieldValueAsync<>;(System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetProviderSpecificValue;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetProviderSpecificValues;(System.Object[]);;Argument[Qualifier];Argument[0].Element;taint;generated | -| System.Data.Common;DbDataReader;true;GetSchemaTableAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataReader;true;GetTextReader;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data.Common;DbDataRecord;false;GetPropertyOwner;(System.ComponentModel.PropertyDescriptor);;Argument[Qualifier];ReturnValue;value;generated | | System.Data.Common;DbEnumerator;false;DbEnumerator;(System.Data.IDataReader);;Argument[0];Argument[Qualifier];taint;generated | @@ -1598,11 +1548,8 @@ | System.Data;DataColumn;false;set_Prefix;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataColumnChangeEventArgs;false;DataColumnChangeEventArgs;(System.Data.DataRow,System.Data.DataColumn,System.Object);;Argument[1];Argument[Qualifier];taint;generated | | System.Data;DataColumnChangeEventArgs;false;get_Column;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataColumnCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataColumnCollection;false;Add;(System.Data.DataColumn);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataColumnCollection;false;Add;(System.String);;Argument[0];Argument[Qualifier].Element;value;manual | -| System.Data;DataColumnCollection;false;Add;(System.String,System.Type);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataColumnCollection;false;Add;(System.String,System.Type,System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataColumnCollection;false;AddRange;(System.Data.DataColumn[]);;Argument[0].Element;Argument[Qualifier].Element;value;manual | | System.Data;DataColumnCollection;false;CopyTo;(System.Data.DataColumn[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data;DataColumnCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | @@ -1610,7 +1557,6 @@ | System.Data;DataColumnCollection;false;get_List;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetDateTime;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetFieldValue<>;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | -| System.Data;DataReaderExtensions;false;GetFieldValueAsync<>;(System.Data.Common.DbDataReader,System.String,System.Threading.CancellationToken);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetGuid;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetProviderSpecificValue;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | | System.Data;DataReaderExtensions;false;GetString;(System.Data.Common.DbDataReader,System.String);;Argument[0].Element;ReturnValue;taint;generated | @@ -1642,16 +1588,10 @@ | System.Data;DataRelationCollection;false;Add;(System.Data.DataRelation);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataRelationCollection;false;CopyTo;(System.Data.DataRelation[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data;DataRelationCollection;false;Remove;(System.Data.DataRelation);;Argument[0];Argument[Qualifier];taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[0];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn,System.Data.DataColumn,System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[0];ReturnValue;taint;generated | -| System.Data;DataRelationCollection;true;Add;(System.String,System.Data.DataColumn[],System.Data.DataColumn[],System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataRelationCollection;true;AddRange;(System.Data.DataRelation[]);;Argument[0].Element;Argument[Qualifier].Element;value;manual | | System.Data;DataRow;false;DataRow;(System.Data.DataRowBuilder);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataRow;false;GetChildRows;(System.Data.DataRelation);;Argument[Qualifier];ReturnValue;taint;generated | @@ -1755,12 +1695,10 @@ | System.Data;DataTable;false;set_PrimaryKey;(System.Data.DataColumn[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Data;DataTable;false;set_Site;(System.ComponentModel.ISite);;Argument[0];Argument[Qualifier];taint;generated | | System.Data;DataTable;false;set_TableName;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.Data;DataTableCollection;false;Add;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataTableCollection;false;Add;(System.Data.DataTable);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataTableCollection;false;Add;(System.String);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[1];ReturnValue;taint;generated | -| System.Data;DataTableCollection;false;Add;(System.String,System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.Data;DataTableCollection;false;AddRange;(System.Data.DataTable[]);;Argument[0].Element;Argument[Qualifier].Element;value;manual | | System.Data;DataTableCollection;false;CopyTo;(System.Data.DataTable[],System.Int32);;Argument[Qualifier].Element;Argument[0].Element;value;manual | | System.Data;DataTableCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | @@ -2341,8 +2279,10 @@ | System.IO.IsolatedStorage;IsolatedStorage;false;get_DomainIdentity;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.IO.IsolatedStorage;IsolatedStorageFileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO.IsolatedStorage;IsolatedStorageFileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.IO.IsolatedStorage;IsolatedStorageFileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.MemoryMappedFiles;MemoryMappedFile;false;CreateFromFile;(System.IO.FileStream,System.String,System.Int64,System.IO.MemoryMappedFiles.MemoryMappedFileAccess,System.IO.HandleInheritability,System.Boolean);;Argument[0];ReturnValue;taint;generated | | System.IO.MemoryMappedFiles;MemoryMappedFile;false;get_SafeMemoryMappedFileHandle;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO.MemoryMappedFiles;MemoryMappedViewAccessor;false;get_SafeMemoryMappedViewHandle;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -2367,7 +2307,6 @@ | System.IO;BinaryReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;BinaryWriter;false;BinaryWriter;(System.IO.Stream,System.Text.Encoding,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | -| System.IO;BinaryWriter;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;BinaryWriter;false;Write;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;BinaryWriter;false;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;BinaryWriter;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -2427,8 +2366,10 @@ | System.IO;FileNotFoundException;false;get_Message;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;FileStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;FileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.IO;FileStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;FileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;FileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.IO;FileStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;FileStream;false;get_SafeFileHandle;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;FileSystemEventArgs;false;FileSystemEventArgs;(System.IO.WatcherChangeTypes,System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.IO;FileSystemEventArgs;false;FileSystemEventArgs;(System.IO.WatcherChangeTypes,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated | @@ -2501,7 +2442,6 @@ | System.IO;Stream;false;CopyToAsync;(System.IO.Stream);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;Stream;false;CopyToAsync;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;Stream;false;CopyToAsync;(System.IO.Stream,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | -| System.IO;Stream;false;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Stream;false;ReadAsync;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;Stream;false;Synchronized;(System.IO.Stream);;Argument[0];ReturnValue;taint;generated | | System.IO;Stream;false;WriteAsync;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | @@ -2509,13 +2449,10 @@ | System.IO;Stream;true;BeginWrite;(System.Byte[],System.Int32,System.Int32,System.AsyncCallback,System.Object);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;Stream;true;CopyTo;(System.IO.Stream,System.Int32);;Argument[Qualifier];Argument[0];taint;manual | | System.IO;Stream;true;CopyToAsync;(System.IO.Stream,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;manual | -| System.IO;Stream;true;FlushAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Stream;true;Read;(System.Byte[],System.Int32,System.Int32);;Argument[Qualifier];Argument[0].Element;taint;manual | | System.IO;Stream;true;ReadAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0].Element;taint;manual | -| System.IO;Stream;true;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;Stream;true;Write;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;manual | | System.IO;Stream;true;WriteAsync;(System.Byte[],System.Int32,System.Int32,System.Threading.CancellationToken);;Argument[0].Element;Argument[Qualifier];taint;manual | -| System.IO;Stream;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StreamReader;false;StreamReader;(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StreamReader;false;StreamReader;(System.IO.Stream,System.Text.Encoding,System.Boolean,System.Int32,System.Boolean);;Argument[1];Argument[Qualifier];taint;generated | | System.IO;StreamReader;false;get_BaseStream;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -2530,13 +2467,10 @@ | System.IO;StringWriter;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;StringWriter;false;Write;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;Write;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;Write;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;WriteAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;StringWriter;false;WriteLineAsync;(System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;StringWriter;false;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextReader;false;Synchronized;(System.IO.TextReader);;Argument[0];ReturnValue;taint;generated | | System.IO;TextReader;true;Read;();;Argument[Qualifier];ReturnValue;taint;manual | | System.IO;TextReader;true;Read;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;manual | @@ -2554,12 +2488,7 @@ | System.IO;TextWriter;false;Synchronized;(System.IO.TextWriter);;Argument[0];ReturnValue;taint;generated | | System.IO;TextWriter;false;TextWriter;(System.IFormatProvider);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;false;WriteAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;false;WriteLineAsync;(System.Char[]);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;FlushAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;Write;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.Object);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.String,System.Object);;Argument[0];Argument[Qualifier];taint;generated | @@ -2573,14 +2502,7 @@ | System.IO;TextWriter;true;Write;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;Write;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteLine;(System.Char[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;WriteLine;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | @@ -2597,18 +2519,8 @@ | System.IO;TextWriter;true;WriteLine;(System.String,System.Object,System.Object,System.Object);;Argument[3];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[0];Argument[Qualifier];taint;generated | | System.IO;TextWriter;true;WriteLine;(System.String,System.Object[]);;Argument[1].Element;Argument[Qualifier];taint;generated | -| System.IO;TextWriter;true;WriteLine;(System.Text.StringBuilder);;Argument[0];Argument[Qualifier];taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Char);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[0].Element;ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Char[],System.Int32,System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[0];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | -| System.IO;TextWriter;true;WriteLineAsync;(System.Text.StringBuilder,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;get_FormatProvider;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;get_NewLine;();;Argument[Qualifier];ReturnValue;taint;generated | | System.IO;TextWriter;true;set_NewLine;(System.String);;Argument[0];Argument[Qualifier];taint;generated | @@ -3879,17 +3791,12 @@ | System.Net.Http.Json;JsonContent;false;Create<>;(T,System.Net.Http.Headers.MediaTypeHeaderValue,System.Text.Json.JsonSerializerOptions);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.Http;ByteArrayContent;false;ByteArrayContent;(System.Byte[],System.Int32,System.Int32);;Argument[0].Element;Argument[Qualifier];taint;generated | -| System.Net.Http;ByteArrayContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;ByteArrayContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;DelegatingHandler;false;DelegatingHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;DelegatingHandler;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Http;DelegatingHandler;false;get_InnerHandler;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;DelegatingHandler;false;set_InnerHandler;(System.Net.Http.HttpMessageHandler);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;FormUrlEncodedContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Http;HttpClient;false;Send;(System.Net.Http.HttpRequestMessage,System.Net.Http.HttpCompletionOption,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | @@ -3916,10 +3823,7 @@ | System.Net.Http;HttpContent;false;ReadAsStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpContent;false;get_Headers;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpContent;true;CreateContentReadStream;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;HttpContent;true;CreateContentReadStreamAsync;(System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;HttpContent;true;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;HttpMessageInvoker;false;HttpMessageInvoker;(System.Net.Http.HttpMessageHandler,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;HttpMessageInvoker;false;SendAsync;(System.Net.Http.HttpRequestMessage,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Http;HttpMethod;false;HttpMethod;(System.String);;Argument[0];Argument[Qualifier];taint;generated | @@ -3955,7 +3859,6 @@ | System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent,System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;MultipartFormDataContent;false;Add;(System.Net.Http.HttpContent,System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;ReadOnlyMemoryContent;false;CreateContentReadStreamAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;ReadOnlyMemoryContent;false;ReadOnlyMemoryContent;(System.ReadOnlyMemory);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;SocketsHttpConnectionContext;false;get_DnsEndPoint;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;SocketsHttpConnectionContext;false;get_InitialRequestMessage;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -3992,13 +3895,9 @@ | System.Net.Http;SocketsHttpPlaintextStreamFilterContext;false;get_NegotiatedHttpVersion;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;SocketsHttpPlaintextStreamFilterContext;false;get_PlaintextStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;SerializeToStream;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Http;StreamContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Http;StreamContent;false;StreamContent;(System.IO.Stream,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Http;StringContent;false;SerializeToStreamAsync;(System.IO.Stream,System.Net.TransportContext,System.Threading.CancellationToken);;Argument[2];ReturnValue;taint;generated | | System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String);;Argument[0];ReturnValue;taint;generated | | System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[0];ReturnValue;taint;generated | | System.Net.Mail;AlternateView;false;CreateAlternateViewFromString;(System.String,System.Net.Mime.ContentType);;Argument[1];ReturnValue;taint;generated | @@ -4124,7 +4023,6 @@ | System.Net.NetworkInformation;PhysicalAddress;false;PhysicalAddress;(System.Byte[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.NetworkInformation;UnicastIPAddressInformationCollection;false;get_Item;(System.Int32);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;AuthenticatedStream;false;AuthenticatedStream;(System.IO.Stream,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net.Security;AuthenticatedStream;false;DisposeAsync;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;AuthenticatedStream;false;get_InnerStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Net.Security;NegotiateStream;false;AuthenticateAsClient;(System.Net.NetworkCredential,System.Security.Authentication.ExtendedProtection.ChannelBinding,System.String);;Argument[2];Argument[Qualifier];taint;generated | @@ -4145,8 +4043,10 @@ | System.Net.Security;NegotiateStream;false;FlushAsync;(System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.Net.Security;NegotiateStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.Net.Security;NegotiateStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;NegotiateStream;false;get_RemoteIdentity;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslApplicationProtocol;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Security;SslApplicationProtocol;false;get_Protocol;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -4173,7 +4073,9 @@ | System.Net.Sockets;NetworkStream;false;NetworkStream;(System.Net.Sockets.Socket,System.IO.FileAccess,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;NetworkStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;NetworkStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.Net.Sockets;NetworkStream;false;ReadAsync;(System.Memory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Sockets;NetworkStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | +| System.Net.Sockets;NetworkStream;false;WriteAsync;(System.ReadOnlyMemory,System.Threading.CancellationToken);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Sockets;NetworkStream;false;get_Socket;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Sockets;SafeSocketHandle;false;SafeSocketHandle;(System.IntPtr,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;Socket;false;Accept;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -4185,7 +4087,6 @@ | System.Net.Sockets;Socket;false;ConnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;Socket;false;ConnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Sockets;Socket;false;DisconnectAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated | -| System.Net.Sockets;Socket;false;EndAccept;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;Socket;false;ReceiveAsync;(System.Net.Sockets.SocketAsyncEventArgs);;Argument[Qualifier];Argument[0];taint;generated | | System.Net.Sockets;Socket;false;ReceiveFrom;(System.Byte[],System.Int32,System.Int32,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[4];Argument[Qualifier];taint;generated | | System.Net.Sockets;Socket;false;ReceiveFrom;(System.Byte[],System.Int32,System.Int32,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[4];ReturnValue;taint;generated | @@ -4228,7 +4129,6 @@ | System.Net.Sockets;SocketAsyncEventArgs;false;set_SendPacketsElements;(System.Net.Sockets.SendPacketsElement[]);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Net.Sockets;SocketAsyncEventArgs;false;set_UserToken;(System.Object);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;SocketException;false;get_Message;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Sockets;SocketTaskExtensions;false;AcceptAsync;(System.Net.Sockets.Socket,System.Net.Sockets.Socket);;Argument[1];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint);;Argument[1];Argument[0];taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ConnectAsync;(System.Net.Sockets.Socket,System.Net.EndPoint,System.Threading.CancellationToken);;Argument[1];Argument[0];taint;generated | @@ -4240,8 +4140,6 @@ | System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[1];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;ReceiveAsync;(System.Net.Sockets.Socket,System.Memory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated | -| System.Net.Sockets;SocketTaskExtensions;false;ReceiveFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated | -| System.Net.Sockets;SocketTaskExtensions;false;ReceiveMessageFromAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;SendAsync;(System.Net.Sockets.Socket,System.ReadOnlyMemory,System.Net.Sockets.SocketFlags,System.Threading.CancellationToken);;Argument[3];ReturnValue;taint;generated | | System.Net.Sockets;SocketTaskExtensions;false;SendToAsync;(System.Net.Sockets.Socket,System.ArraySegment,System.Net.Sockets.SocketFlags,System.Net.EndPoint);;Argument[3];Argument[0];taint;generated | @@ -4252,8 +4150,6 @@ | System.Net.Sockets;TcpClient;false;set_Client;(System.Net.Sockets.Socket);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;TcpListener;false;AcceptSocket;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net.Sockets;TcpListener;false;AcceptTcpClient;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net.Sockets;TcpListener;false;EndAcceptSocket;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net.Sockets;TcpListener;false;EndAcceptTcpClient;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPAddress,System.Int32);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;TcpListener;false;TcpListener;(System.Net.IPEndPoint);;Argument[0];Argument[Qualifier];taint;generated | | System.Net.Sockets;TcpListener;false;get_LocalEndpoint;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -4325,17 +4221,11 @@ | System.Net;CookieCollection;false;get_SyncRoot;();;Argument[Qualifier];ReturnValue;value;generated | | System.Net;CookieException;false;GetObjectData;(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext);;Argument[Qualifier];Argument[0];taint;generated | | System.Net;CredentialCache;false;GetCredential;(System.Uri,System.String);;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net;Dns;false;EndGetHostAddresses;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;Dns;false;EndGetHostByName;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;Dns;false;EndGetHostEntry;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;Dns;false;EndResolve;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net;DnsEndPoint;false;DnsEndPoint;(System.String,System.Int32,System.Net.Sockets.AddressFamily);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;DnsEndPoint;false;ToString;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;DnsEndPoint;false;get_Host;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;DownloadDataCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;DownloadStringCompletedEventArgs;false;get_Result;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Net;FileWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;FileWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net;FileWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;FileWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;FileWebRequest;false;get_ContentType;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -4410,9 +4300,6 @@ | System.Net;HttpListenerTimeoutManager;false;get_IdleConnection;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;HttpListenerTimeoutManager;false;set_DrainEntityBody;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;HttpListenerTimeoutManager;false;set_IdleConnection;(System.TimeSpan);;Argument[0];Argument[Qualifier];taint;generated | -| System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;HttpWebRequest;false;EndGetRequestStream;(System.IAsyncResult,System.Net.TransportContext);;Argument[0];ReturnValue;taint;generated | -| System.Net;HttpWebRequest;false;EndGetResponse;(System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | | System.Net;HttpWebRequest;false;GetRequestStream;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;HttpWebRequest;false;GetRequestStream;(System.Net.TransportContext);;Argument[Qualifier];ReturnValue;taint;generated | | System.Net;HttpWebRequest;false;GetResponse;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -4498,8 +4385,6 @@ | System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest);;Argument[0];ReturnValue;taint;generated | | System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[0];ReturnValue;taint;generated | -| System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];Argument[Qualifier];taint;generated | -| System.Net;WebClient;false;GetWebResponse;(System.Net.WebRequest,System.IAsyncResult);;Argument[1];ReturnValue;taint;generated | | System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Net;WebClient;false;OpenRead;(System.String);;Argument[0];ReturnValue;taint;generated | | System.Net;WebClient;false;OpenRead;(System.String);;Argument[Qualifier];ReturnValue;taint;generated | @@ -5368,7 +5253,6 @@ | System.Resources;ResourceReader;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Resources;ResourceReader;false;GetResourceData;(System.String,System.String,System.Byte[]);;Argument[Qualifier];ReturnValue;taint;generated | | System.Resources;ResourceReader;false;ResourceReader;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | -| System.Resources;ResourceSet;false;GetEnumerator;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Resources;ResourceSet;false;ResourceSet;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | | System.Resources;ResourceSet;false;ResourceSet;(System.Resources.IResourceReader);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Resources;ResourceWriter;false;ResourceWriter;(System.IO.Stream);;Argument[0];Argument[Qualifier];taint;generated | @@ -5733,7 +5617,6 @@ | System.Security.Cryptography.X509Certificates;X509Certificate;false;ToString;(System.Boolean);;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Issuer;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography.X509Certificates;X509Certificate;false;get_Subject;();;Argument[Qualifier];ReturnValue;taint;generated | -| System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;X509CertificateEnumerator;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier];taint;generated | | System.Security.Cryptography.X509Certificates;X509CertificateCollection+X509CertificateEnumerator;false;get_Current;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;Add;(System.Security.Cryptography.X509Certificates.X509Certificate);;Argument[0];Argument[Qualifier].Element;value;manual | | System.Security.Cryptography.X509Certificates;X509CertificateCollection;false;AddRange;(System.Security.Cryptography.X509Certificates.X509CertificateCollection);;Argument[0].Element;Argument[Qualifier].Element;value;manual | @@ -6224,10 +6107,6 @@ | System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;Receive<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan);;Argument[0];ReturnValue;taint;generated | -| System.Threading.Tasks.Dataflow;DataflowBlock;false;ReceiveAsync<>;(System.Threading.Tasks.Dataflow.ISourceBlock,System.TimeSpan,System.Threading.CancellationToken);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;SendAsync<>;(System.Threading.Tasks.Dataflow.ITargetBlock,TInput,System.Threading.CancellationToken);;Argument[1];Argument[0];taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlock;false;TryReceive<>;(System.Threading.Tasks.Dataflow.IReceivableSourceBlock,TOutput);;Argument[0];ReturnValue;taint;generated | | System.Threading.Tasks.Dataflow;DataflowBlockOptions;false;get_CancellationToken;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -7010,12 +6889,9 @@ | System.Xml.Schema;XmlSchemaSet;false;Add;(System.String,System.Xml.XmlReader);;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchema);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated | -| System.Xml.Schema;XmlSchemaSet;false;Add;(System.Xml.Schema.XmlSchemaSet);;Argument[0];Argument[Qualifier];taint;generated | -| System.Xml.Schema;XmlSchemaSet;false;CopyTo;(System.Xml.Schema.XmlSchema[],System.Int32);;Argument[Qualifier];Argument[0].Element;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Remove;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Reprocess;(System.Xml.Schema.XmlSchema);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Schema;XmlSchemaSet;false;Reprocess;(System.Xml.Schema.XmlSchema);;Argument[0];ReturnValue;taint;generated | -| System.Xml.Schema;XmlSchemaSet;false;Schemas;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;XmlSchemaSet;(System.Xml.XmlNameTable);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Schema;XmlSchemaSet;false;get_CompilationSettings;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaSet;false;get_GlobalAttributes;();;Argument[Qualifier];ReturnValue;taint;generated | @@ -7102,10 +6978,8 @@ | System.Xml.Schema;XmlSchemaXPath;false;get_XPath;();;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Schema;XmlSchemaXPath;false;set_XPath;(System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;Add;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;CodeIdentifiers;false;Add;(System.String,System.Object);;Argument[Qualifier];Argument[1];taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[0];ReturnValue;taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[1];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;CodeIdentifiers;false;AddUnique;(System.String,System.Object);;Argument[Qualifier];Argument[1];taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;MakeUnique;(System.String);;Argument[0];ReturnValue;taint;generated | | System.Xml.Serialization;CodeIdentifiers;false;ToArray;(System.Type);;Argument[Qualifier];ReturnValue;taint;generated | | System.Xml.Serialization;ImportContext;false;ImportContext;(System.Xml.Serialization.CodeIdentifiers,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | @@ -7411,7 +7285,6 @@ | System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteElementStringRaw;(System.String,System.String,System.Xml.XmlQualifiedName);;Argument[1];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WriteId;(System.Object);;Argument[Qualifier];Argument[0];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncoded;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncodedRaw;(System.String,System.String,System.Byte[],System.Xml.XmlQualifiedName);;Argument[2].Element;Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringEncodedRaw;(System.String,System.String,System.String,System.Xml.XmlQualifiedName);;Argument[2];Argument[Qualifier];taint;generated | @@ -7419,15 +7292,9 @@ | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringLiteralRaw;(System.String,System.String,System.Byte[]);;Argument[2].Element;Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteNullableStringLiteralRaw;(System.String,System.String,System.String);;Argument[2];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean,System.Boolean);;Argument[2];Argument[Qualifier];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WritePotentiallyReferencingElement;(System.String,System.String,System.Object,System.Type,System.Boolean,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WriteReferencingElement;(System.String,System.String,System.Object);;Argument[Qualifier];Argument[2];taint;generated | -| System.Xml.Serialization;XmlSerializationWriter;false;WriteReferencingElement;(System.String,System.String,System.Object,System.Boolean);;Argument[Qualifier];Argument[2];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteRpcResult;(System.String,System.String);;Argument[0];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteRpcResult;(System.String,System.String);;Argument[1];Argument[Qualifier];taint;generated | | System.Xml.Serialization;XmlSerializationWriter;false;WriteSerializable;(System.Xml.Serialization.IXmlSerializable,System.String,System.String,System.Boolean);;Argument[0];Argument[Qualifier];taint;generated | @@ -9087,27 +8954,6 @@ | System;TupleExtensions;false;Deconstruct<,>;(System.Tuple,T1,T2);;Argument[0].Property[System.Tuple<,>.Item1];Argument[1];value;manual | | System;TupleExtensions;false;Deconstruct<,>;(System.Tuple,T1,T2);;Argument[0].Property[System.Tuple<,>.Item2];Argument[2];value;manual | | System;TupleExtensions;false;Deconstruct<>;(System.Tuple,T1);;Argument[0].Property[System.Tuple<>.Item1];Argument[1];value;manual | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,,>;(System.ValueTuple>>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,,>;(System.ValueTuple>);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<,>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | -| System;TupleExtensions;false;ToTuple<>;(System.ValueTuple);;Argument[0];ReturnValue;taint;generated | | System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated | | System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated | | System;TupleExtensions;false;ToValueTuple<,,,,,,,,,,,,,,,,,,>;(System.Tuple>>);;Argument[0];ReturnValue;taint;generated | From e838b83f5f47fe5b2e086d9ee06ff09bb6213173 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 23 Jun 2022 02:21:47 +0000 Subject: [PATCH 081/465] attempt to introduce dataflow tracking --- .../experimental/weak-params/WeakParams.ql | 69 +++++++++++++------ 1 file changed, 48 insertions(+), 21 deletions(-) diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql index d7408f8bea7..1d8ef89e70a 100644 --- a/ruby/ql/src/experimental/weak-params/WeakParams.ql +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -1,7 +1,7 @@ /** * @name Weak or direct parameter references are used * @description Directly checking request parameters without following a strong params pattern can lead to unintentional avenues for injection attacks. - * @kind problem + * @kind path-problem * @problem.severity error * @security-severity 5.0 * @precision low @@ -10,10 +10,13 @@ */ import ruby +import codeql.ruby.DataFlow +import codeql.ruby.TaintTracking +import DataFlow::PathGraph -class WeakParams extends AstNode { +class WeakParams extends Expr { WeakParams() { - this instanceof UnspecificParamsMethod or + allParamsAccess(this) or this instanceof ParamsReference } } @@ -26,27 +29,51 @@ class StrongParamsMethod extends Method { StrongParamsMethod() { this.getName().regexpMatch(".*_params") } } -class UnspecificParamsMethod extends MethodCall { - UnspecificParamsMethod() { - ( - this.getMethodName() = "expose_all" or - this.getMethodName() = "original_hash" or - this.getMethodName() = "path_parametes" or - this.getMethodName() = "query_parameters" or - this.getMethodName() = "request_parameters" or - this.getMethodName() = "GET" or - this.getMethodName() = "POST" - ) - } +predicate allParamsAccess(MethodCall call) { + call.getMethodName() = "expose_all" or + call.getMethodName() = "original_hash" or + call.getMethodName() = "path_parametes" or + call.getMethodName() = "query_parameters" or + call.getMethodName() = "request_parameters" or + call.getMethodName() = "GET" or + call.getMethodName() = "POST" } class ParamsReference extends ElementReference { ParamsReference() { this.getAChild().toString() = "params" } } -from WeakParams params -where - not params.getEnclosingMethod() instanceof StrongParamsMethod and - params.getEnclosingModule() instanceof ControllerClass -select params, - "By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects." +class ModelClass extends ModuleBase { + ModelClass() { + this.getModule().getSuperClass+().toString() = "ViewModel" or + this.getModule().getSuperClass+().getAnIncludedModule().toString() = "ActionModel::Model" + } +} + +class ModelClassMethodArgument extends DataFlow::Node { + private DataFlow::CallNode call; + + ModelClassMethodArgument() { + this = call.getArgument(_) and + call.getExprNode().getNode().getParent+() instanceof ModelClass + } +} + +class Configuration extends TaintTracking::Configuration { + Configuration() { this = "Configuration" } + + override predicate isSource(DataFlow::Node node) { node.asExpr().getNode() instanceof WeakParams } + + // the sink is an instance of a Model class that receives a method call + override predicate isSink(DataFlow::Node node) { node instanceof ModelClassMethodArgument } +} + +from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlowPath(source, sink) +select sink.getNode().(ModelClassMethodArgument), source, sink, "This is bad" +// from WeakParams params +// where +// not params.getEnclosingMethod() instanceof StrongParamsMethod and +// params.getEnclosingModule() instanceof ControllerClass +// select params, +// "By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects." From a74051c658adef6dd58f0c097eb115df12428f5a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 23 Jun 2022 11:17:46 +0000 Subject: [PATCH 082/465] Release preparation for version 2.10.0 --- cpp/ql/lib/CHANGELOG.md | 14 ++++++++++++++ .../change-notes/2022-05-30-braced-initializers.md | 4 ---- .../2022-06-22-class-declaration-entry-fix.md | 4 ---- cpp/ql/lib/change-notes/released/0.3.0.md | 13 +++++++++++++ cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 2 ++ cpp/ql/src/change-notes/released/0.2.0.md | 1 + cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md | 2 ++ .../Solorigate/lib/change-notes/released/1.2.0.md | 1 + .../Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/CHANGELOG.md | 2 ++ .../Solorigate/src/change-notes/released/1.2.0.md | 1 + .../Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 6 ++++++ .../ql/lib/change-notes/released/0.3.0.md | 7 ++++--- csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 11 +++++++++++ .../2022-06-02-aspnetcoretaintedmembers.md | 4 ---- .../src/change-notes/2022-06-14-madformatchange.md | 4 ---- .../2022-06-15-diagnostic-query-metadata.md | 4 ---- csharp/ql/src/change-notes/released/0.2.0.md | 10 ++++++++++ csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 6 ++++++ .../ql/lib/change-notes/released/0.2.0.md | 7 ++++--- go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 2 ++ go/ql/src/change-notes/released/0.2.0.md | 1 + go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 10 ++++++++++ .../2022-05-25-string-valueof-editable-step.md | 4 ---- java/ql/lib/change-notes/released/0.3.0.md | 9 +++++++++ java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 6 ++++++ .../0.2.0.md} | 7 ++++--- java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 10 ++++++++++ .../lib/change-notes/2022-05-24-ecmascript-2022.md | 4 ---- .../lib/change-notes/2022-05-24-typescript-4-7.md | 4 ---- javascript/ql/lib/change-notes/released/0.2.0.md | 9 +++++++++ javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 7 +++++++ .../0.2.0.md} | 7 ++++--- javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 6 ++++++ .../2022-06-21-barrierguard-deprecation.md | 4 ---- .../ql/lib/change-notes/released/0.5.0.md | 7 ++++--- python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 10 ++++++++++ .../2022-05-16-broken-crypto-block-mode.md | 4 ---- ...uest-without-certificate-validation-modeling.md | 4 ---- python/ql/src/change-notes/released/0.2.0.md | 9 +++++++++ python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 10 ++++++++++ .../2022-06-21-barrierguard-deprecation.md | 4 ---- .../ql/lib/change-notes/released/0.3.0.md | 7 ++++--- ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 10 ++++++++++ .../2022-05-16-broken-crypto-message.md | 4 ---- .../2022-05-24-improper-memoization.md | 4 ---- ruby/ql/src/change-notes/released/0.2.0.md | 9 +++++++++ ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- 78 files changed, 233 insertions(+), 106 deletions(-) delete mode 100644 cpp/ql/lib/change-notes/2022-05-30-braced-initializers.md delete mode 100644 cpp/ql/lib/change-notes/2022-06-22-class-declaration-entry-fix.md create mode 100644 cpp/ql/lib/change-notes/released/0.3.0.md create mode 100644 cpp/ql/src/change-notes/released/0.2.0.md create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.0.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.0.md rename go/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md => csharp/ql/lib/change-notes/released/0.3.0.md (83%) delete mode 100644 csharp/ql/src/change-notes/2022-06-02-aspnetcoretaintedmembers.md delete mode 100644 csharp/ql/src/change-notes/2022-06-14-madformatchange.md delete mode 100644 csharp/ql/src/change-notes/2022-06-15-diagnostic-query-metadata.md create mode 100644 csharp/ql/src/change-notes/released/0.2.0.md rename cpp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md => go/ql/lib/change-notes/released/0.2.0.md (83%) create mode 100644 go/ql/src/change-notes/released/0.2.0.md delete mode 100644 java/ql/lib/change-notes/2022-05-25-string-valueof-editable-step.md create mode 100644 java/ql/lib/change-notes/released/0.3.0.md rename java/ql/src/change-notes/{2022-06-22-log-injection-location.md => released/0.2.0.md} (86%) delete mode 100644 javascript/ql/lib/change-notes/2022-05-24-ecmascript-2022.md delete mode 100644 javascript/ql/lib/change-notes/2022-05-24-typescript-4-7.md create mode 100644 javascript/ql/lib/change-notes/released/0.2.0.md rename javascript/ql/src/change-notes/{2022-05-24-resource-exhaustion-no-buffer.from.md => released/0.2.0.md} (77%) delete mode 100644 python/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md rename java/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md => python/ql/lib/change-notes/released/0.5.0.md (83%) delete mode 100644 python/ql/src/change-notes/2022-05-16-broken-crypto-block-mode.md delete mode 100644 python/ql/src/change-notes/2022-06-08-request-without-certificate-validation-modeling.md create mode 100644 python/ql/src/change-notes/released/0.2.0.md delete mode 100644 ruby/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md rename csharp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md => ruby/ql/lib/change-notes/released/0.3.0.md (83%) delete mode 100644 ruby/ql/src/change-notes/2022-05-16-broken-crypto-message.md delete mode 100644 ruby/ql/src/change-notes/2022-05-24-improper-memoization.md create mode 100644 ruby/ql/src/change-notes/released/0.2.0.md diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 52dd2c7a843..3b815104efd 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,17 @@ +## 0.3.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + +### New Features + +* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization. + +### Bug Fixes + +* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`. + ## 0.2.3 ### New Features diff --git a/cpp/ql/lib/change-notes/2022-05-30-braced-initializers.md b/cpp/ql/lib/change-notes/2022-05-30-braced-initializers.md deleted file mode 100644 index 8a31f06ab98..00000000000 --- a/cpp/ql/lib/change-notes/2022-05-30-braced-initializers.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization. diff --git a/cpp/ql/lib/change-notes/2022-06-22-class-declaration-entry-fix.md b/cpp/ql/lib/change-notes/2022-06-22-class-declaration-entry-fix.md deleted file mode 100644 index fb301705e79..00000000000 --- a/cpp/ql/lib/change-notes/2022-06-22-class-declaration-entry-fix.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: fix ---- -* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`. diff --git a/cpp/ql/lib/change-notes/released/0.3.0.md b/cpp/ql/lib/change-notes/released/0.3.0.md new file mode 100644 index 00000000000..c266a3cfa65 --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.3.0.md @@ -0,0 +1,13 @@ +## 0.3.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + +### New Features + +* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization. + +### Bug Fixes + +* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 0b605901b42..95f6e3a0ba6 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.3 +lastReleaseVersion: 0.3.0 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 28cddcb3b00..ad716ce6145 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.3.0-dev +version: 0.3.0 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 449af46b6b8..2b404ff5288 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.2.0 + ## 0.1.4 ## 0.1.3 diff --git a/cpp/ql/src/change-notes/released/0.2.0.md b/cpp/ql/src/change-notes/released/0.2.0.md new file mode 100644 index 00000000000..79a5f33514f --- /dev/null +++ b/cpp/ql/src/change-notes/released/0.2.0.md @@ -0,0 +1 @@ +## 0.2.0 diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index e8ee3af8ef9..5274e27ed52 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.2.0 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index a373e4717d8..4d5444cdb80 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.2.0-dev +version: 0.2.0 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 0bb47844d19..30c583ee913 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.2.0 + ## 1.1.4 ## 1.1.3 diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.0.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.0.md new file mode 100644 index 00000000000..0ff42339575 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.0.md @@ -0,0 +1 @@ +## 1.2.0 diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index 26cbcd3f123..75430e73d1c 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.1.4 +lastReleaseVersion: 1.2.0 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 9cb7bec181f..f411871c1c7 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.2.0-dev +version: 1.2.0 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 0bb47844d19..30c583ee913 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.2.0 + ## 1.1.4 ## 1.1.3 diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.0.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.0.md new file mode 100644 index 00000000000..0ff42339575 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.0.md @@ -0,0 +1 @@ +## 1.2.0 diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index 26cbcd3f123..75430e73d1c 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.1.4 +lastReleaseVersion: 1.2.0 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 07419f1b469..5f5ac8e59e2 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.2.0-dev +version: 1.2.0 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 3df8b95eeb6..3f49fe5ade3 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.3.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + ## 0.2.3 ## 0.2.2 diff --git a/go/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/csharp/ql/lib/change-notes/released/0.3.0.md similarity index 83% rename from go/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md rename to csharp/ql/lib/change-notes/released/0.3.0.md index 2bd95798f89..54af6e00ac0 100644 --- a/go/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md +++ b/csharp/ql/lib/change-notes/released/0.3.0.md @@ -1,4 +1,5 @@ ---- -category: deprecated ---- +## 0.3.0 + +### Deprecated APIs + * The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 0b605901b42..95f6e3a0ba6 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.3 +lastReleaseVersion: 0.3.0 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 2e2d17e36fa..11897f937b9 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.3.0-dev +version: 0.3.0 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index bc553b74fe4..e7ce0b0b471 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,14 @@ +## 0.2.0 + +### Query Metadata Changes + +* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`. + +### Minor Analysis Improvements + +* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`). +* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted. + ## 0.1.4 ## 0.1.3 diff --git a/csharp/ql/src/change-notes/2022-06-02-aspnetcoretaintedmembers.md b/csharp/ql/src/change-notes/2022-06-02-aspnetcoretaintedmembers.md deleted file mode 100644 index b80e90e0434..00000000000 --- a/csharp/ql/src/change-notes/2022-06-02-aspnetcoretaintedmembers.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted. \ No newline at end of file diff --git a/csharp/ql/src/change-notes/2022-06-14-madformatchange.md b/csharp/ql/src/change-notes/2022-06-14-madformatchange.md deleted file mode 100644 index 1dd215a89c7..00000000000 --- a/csharp/ql/src/change-notes/2022-06-14-madformatchange.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`). \ No newline at end of file diff --git a/csharp/ql/src/change-notes/2022-06-15-diagnostic-query-metadata.md b/csharp/ql/src/change-notes/2022-06-15-diagnostic-query-metadata.md deleted file mode 100644 index d5cfc4d35e1..00000000000 --- a/csharp/ql/src/change-notes/2022-06-15-diagnostic-query-metadata.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: queryMetadata ---- -* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`. diff --git a/csharp/ql/src/change-notes/released/0.2.0.md b/csharp/ql/src/change-notes/released/0.2.0.md new file mode 100644 index 00000000000..1b7d3928c1c --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.2.0.md @@ -0,0 +1,10 @@ +## 0.2.0 + +### Query Metadata Changes + +* The `kind` query metadata was changed to `diagnostic` on `cs/compilation-error`, `cs/compilation-message`, `cs/extraction-error`, and `cs/extraction-message`. + +### Minor Analysis Improvements + +* The syntax of the (source|sink|summary)model CSV format has been changed slightly for Java and C#. A new column called `provenance` has been introduced, where the allowed values are `manual` and `generated`. The value used to indicate whether a model as been written by hand (`manual`) or create by the CSV model generator (`generated`). +* All auto implemented public properties with public getters and setters on ASP.NET Core remote flow sources are now also considered to be tainted. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index e8ee3af8ef9..5274e27ed52 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.2.0 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index a9d6dcf0e69..675f8d4a1b0 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.2.0-dev +version: 0.2.0 groups: - csharp - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 1767b297fc6..112f4fab585 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.2.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + ## 0.1.4 ## 0.1.3 diff --git a/cpp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/go/ql/lib/change-notes/released/0.2.0.md similarity index 83% rename from cpp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md rename to go/ql/lib/change-notes/released/0.2.0.md index 2bd95798f89..ded60d11b7e 100644 --- a/cpp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md +++ b/go/ql/lib/change-notes/released/0.2.0.md @@ -1,4 +1,5 @@ ---- -category: deprecated ---- +## 0.2.0 + +### Deprecated APIs + * The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index e8ee3af8ef9..5274e27ed52 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.2.0 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index f416a2612a8..8806039a710 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.2.0-dev +version: 0.2.0 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index 541c8c95377..bed2509f5d3 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.2.0 + ## 0.1.4 ## 0.1.3 diff --git a/go/ql/src/change-notes/released/0.2.0.md b/go/ql/src/change-notes/released/0.2.0.md new file mode 100644 index 00000000000..79a5f33514f --- /dev/null +++ b/go/ql/src/change-notes/released/0.2.0.md @@ -0,0 +1 @@ +## 0.2.0 diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index e8ee3af8ef9..5274e27ed52 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.2.0 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 062631cb68b..f30de39c94e 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.2.0-dev +version: 0.2.0 groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 02f489ea9c5..41b23a74d1f 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.3.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + +### Minor Analysis Improvements + +Added a flow step for `String.valueOf` calls on tainted `android.text.Editable` objects. + ## 0.2.3 ## 0.2.2 diff --git a/java/ql/lib/change-notes/2022-05-25-string-valueof-editable-step.md b/java/ql/lib/change-notes/2022-05-25-string-valueof-editable-step.md deleted file mode 100644 index 60b8a5a8a9d..00000000000 --- a/java/ql/lib/change-notes/2022-05-25-string-valueof-editable-step.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -Added a flow step for `String.valueOf` calls on tainted `android.text.Editable` objects. diff --git a/java/ql/lib/change-notes/released/0.3.0.md b/java/ql/lib/change-notes/released/0.3.0.md new file mode 100644 index 00000000000..0c908384d1e --- /dev/null +++ b/java/ql/lib/change-notes/released/0.3.0.md @@ -0,0 +1,9 @@ +## 0.3.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + +### Minor Analysis Improvements + +Added a flow step for `String.valueOf` calls on tainted `android.text.Editable` objects. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 0b605901b42..95f6e3a0ba6 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.3 +lastReleaseVersion: 0.3.0 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 0eb686d7f94..0b359cd7722 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.3.0-dev +version: 0.3.0 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 4e3bacee693..1f8a00fb1ff 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.2.0 + +### Minor Analysis Improvements + +* The query `java/log-injection` now reports problems at the source (user-controlled data) instead of at the ultimate logging call. This was changed because user functions that wrap the ultimate logging call could result in most alerts being reported in an uninformative location. + ## 0.1.4 ## 0.1.3 diff --git a/java/ql/src/change-notes/2022-06-22-log-injection-location.md b/java/ql/src/change-notes/released/0.2.0.md similarity index 86% rename from java/ql/src/change-notes/2022-06-22-log-injection-location.md rename to java/ql/src/change-notes/released/0.2.0.md index b74f7d5faf9..2deabd93b15 100644 --- a/java/ql/src/change-notes/2022-06-22-log-injection-location.md +++ b/java/ql/src/change-notes/released/0.2.0.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.2.0 + +### Minor Analysis Improvements + * The query `java/log-injection` now reports problems at the source (user-controlled data) instead of at the ultimate logging call. This was changed because user functions that wrap the ultimate logging call could result in most alerts being reported in an uninformative location. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index e8ee3af8ef9..5274e27ed52 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.2.0 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index e9a69afa178..d68826094c7 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.2.0-dev +version: 0.2.0 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index a3699882eab..9df72979ef3 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.2.0 + +### Major Analysis Improvements + +* Added support for TypeScript 4.7. + +### Minor Analysis Improvements + +* All new ECMAScript 2022 features are now supported. + ## 0.1.4 ## 0.1.3 diff --git a/javascript/ql/lib/change-notes/2022-05-24-ecmascript-2022.md b/javascript/ql/lib/change-notes/2022-05-24-ecmascript-2022.md deleted file mode 100644 index 389b7c9044b..00000000000 --- a/javascript/ql/lib/change-notes/2022-05-24-ecmascript-2022.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* All new ECMAScript 2022 features are now supported. diff --git a/javascript/ql/lib/change-notes/2022-05-24-typescript-4-7.md b/javascript/ql/lib/change-notes/2022-05-24-typescript-4-7.md deleted file mode 100644 index 16fe46c675f..00000000000 --- a/javascript/ql/lib/change-notes/2022-05-24-typescript-4-7.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* Added support for TypeScript 4.7. diff --git a/javascript/ql/lib/change-notes/released/0.2.0.md b/javascript/ql/lib/change-notes/released/0.2.0.md new file mode 100644 index 00000000000..6656adbcab5 --- /dev/null +++ b/javascript/ql/lib/change-notes/released/0.2.0.md @@ -0,0 +1,9 @@ +## 0.2.0 + +### Major Analysis Improvements + +* Added support for TypeScript 4.7. + +### Minor Analysis Improvements + +* All new ECMAScript 2022 features are now supported. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index e8ee3af8ef9..5274e27ed52 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.2.0 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 7c558ea66e8..a817864032e 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.2.0-dev +version: 0.2.0 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index d9daf9a44e1..68660fcbb52 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.2.0 + +### Minor Analysis Improvements + +* The `js/resource-exhaustion` query no longer treats the 3-argument version of `Buffer.from` as a sink, + since it does not allocate a new buffer. + ## 0.1.4 ## 0.1.3 diff --git a/javascript/ql/src/change-notes/2022-05-24-resource-exhaustion-no-buffer.from.md b/javascript/ql/src/change-notes/released/0.2.0.md similarity index 77% rename from javascript/ql/src/change-notes/2022-05-24-resource-exhaustion-no-buffer.from.md rename to javascript/ql/src/change-notes/released/0.2.0.md index 8dadbdb4c93..3663154efb6 100644 --- a/javascript/ql/src/change-notes/2022-05-24-resource-exhaustion-no-buffer.from.md +++ b/javascript/ql/src/change-notes/released/0.2.0.md @@ -1,5 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.2.0 + +### Minor Analysis Improvements + * The `js/resource-exhaustion` query no longer treats the 3-argument version of `Buffer.from` as a sink, since it does not allocate a new buffer. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index e8ee3af8ef9..5274e27ed52 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.2.0 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 0b8615cb8e8..0b5bfa5824e 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.2.0-dev +version: 0.2.0 groups: - javascript - queries diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 01b052d3a72..83861bcf61d 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.5.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + ## 0.4.1 ## 0.4.0 diff --git a/python/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/python/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md deleted file mode 100644 index 2bd95798f89..00000000000 --- a/python/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: deprecated ---- -* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. diff --git a/java/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/python/ql/lib/change-notes/released/0.5.0.md similarity index 83% rename from java/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md rename to python/ql/lib/change-notes/released/0.5.0.md index 2bd95798f89..db19d4ebfec 100644 --- a/java/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md +++ b/python/ql/lib/change-notes/released/0.5.0.md @@ -1,4 +1,5 @@ ---- -category: deprecated ---- +## 0.5.0 + +### Deprecated APIs + * The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 89fa3a87180..30e271c5361 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.1 +lastReleaseVersion: 0.5.0 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 10320703ecd..e4da90cbc2b 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.5.0-dev +version: 0.5.0 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index 80db3bd9944..cf3b5f9b4eb 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.2.0 + +### Major Analysis Improvements + +* Improved library modeling for the query "Request without certificate validation" (`py/request-without-cert-validation`), so it now also covers `httpx`, `aiohttp.client`, and `urllib3`. + +### Minor Analysis Improvements + +* The query "Use of a broken or weak cryptographic algorithm" (`py/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode. + ## 0.1.4 ## 0.1.3 diff --git a/python/ql/src/change-notes/2022-05-16-broken-crypto-block-mode.md b/python/ql/src/change-notes/2022-05-16-broken-crypto-block-mode.md deleted file mode 100644 index 3ddf8c2c884..00000000000 --- a/python/ql/src/change-notes/2022-05-16-broken-crypto-block-mode.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The query "Use of a broken or weak cryptographic algorithm" (`py/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode. diff --git a/python/ql/src/change-notes/2022-06-08-request-without-certificate-validation-modeling.md b/python/ql/src/change-notes/2022-06-08-request-without-certificate-validation-modeling.md deleted file mode 100644 index f21f7cb93ba..00000000000 --- a/python/ql/src/change-notes/2022-06-08-request-without-certificate-validation-modeling.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: majorAnalysis ---- -* Improved library modeling for the query "Request without certificate validation" (`py/request-without-cert-validation`), so it now also covers `httpx`, `aiohttp.client`, and `urllib3`. diff --git a/python/ql/src/change-notes/released/0.2.0.md b/python/ql/src/change-notes/released/0.2.0.md new file mode 100644 index 00000000000..3786d910a80 --- /dev/null +++ b/python/ql/src/change-notes/released/0.2.0.md @@ -0,0 +1,9 @@ +## 0.2.0 + +### Major Analysis Improvements + +* Improved library modeling for the query "Request without certificate validation" (`py/request-without-cert-validation`), so it now also covers `httpx`, `aiohttp.client`, and `urllib3`. + +### Minor Analysis Improvements + +* The query "Use of a broken or weak cryptographic algorithm" (`py/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index e8ee3af8ef9..5274e27ed52 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.2.0 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 85db089100e..91284be3afa 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.2.0-dev +version: 0.2.0 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 2da583dd23c..1b060e46141 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,5 +1,15 @@ +## 0.3.0 + +### Deprecated APIs + +* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. + ## 0.2.3 +### Minor Analysis Improvements + +- Calls to `Zip::File.open` and `Zip::File.new` have been added as `FileSystemAccess` sinks. As a result queries like `rb/path-injection` now flag up cases where users may access arbitrary archive files. + ## 0.2.2 ### Major Analysis Improvements diff --git a/ruby/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/ruby/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md deleted file mode 100644 index 2bd95798f89..00000000000 --- a/ruby/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: deprecated ---- -* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. diff --git a/csharp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md b/ruby/ql/lib/change-notes/released/0.3.0.md similarity index 83% rename from csharp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md rename to ruby/ql/lib/change-notes/released/0.3.0.md index 2bd95798f89..54af6e00ac0 100644 --- a/csharp/ql/lib/change-notes/2022-06-21-barrierguard-deprecation.md +++ b/ruby/ql/lib/change-notes/released/0.3.0.md @@ -1,4 +1,5 @@ ---- -category: deprecated ---- +## 0.3.0 + +### Deprecated APIs + * The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 0b605901b42..95f6e3a0ba6 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.3 +lastReleaseVersion: 0.3.0 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index cf53cc3484e..1b419d0bdcf 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.3.0-dev +version: 0.3.0 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index d507f26cb11..0fbab5b5bbf 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.2.0 + +### New Queries + +* Added a new query, `rb/improper-memoization`. The query finds cases where the parameter of a memoization method is not used in the memoization key. + +### Minor Analysis Improvements + +* The query "Use of a broken or weak cryptographic algorithm" (`rb/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode. + ## 0.1.4 ## 0.1.3 diff --git a/ruby/ql/src/change-notes/2022-05-16-broken-crypto-message.md b/ruby/ql/src/change-notes/2022-05-16-broken-crypto-message.md deleted file mode 100644 index 9f851c54819..00000000000 --- a/ruby/ql/src/change-notes/2022-05-16-broken-crypto-message.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The query "Use of a broken or weak cryptographic algorithm" (`rb/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode. diff --git a/ruby/ql/src/change-notes/2022-05-24-improper-memoization.md b/ruby/ql/src/change-notes/2022-05-24-improper-memoization.md deleted file mode 100644 index 940c6ab102a..00000000000 --- a/ruby/ql/src/change-notes/2022-05-24-improper-memoization.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: newQuery ---- -* Added a new query, `rb/improper-memoization`. The query finds cases where the parameter of a memoization method is not used in the memoization key. diff --git a/ruby/ql/src/change-notes/released/0.2.0.md b/ruby/ql/src/change-notes/released/0.2.0.md new file mode 100644 index 00000000000..ed13e617ebe --- /dev/null +++ b/ruby/ql/src/change-notes/released/0.2.0.md @@ -0,0 +1,9 @@ +## 0.2.0 + +### New Queries + +* Added a new query, `rb/improper-memoization`. The query finds cases where the parameter of a memoization method is not used in the memoization key. + +### Minor Analysis Improvements + +* The query "Use of a broken or weak cryptographic algorithm" (`rb/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index e8ee3af8ef9..5274e27ed52 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.4 +lastReleaseVersion: 0.2.0 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 914fb852b4e..159f92016a1 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.2.0-dev +version: 0.2.0 groups: - ruby - queries From bef38a64c3c2c738c800aee896ecf7819c494267 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 23 Jun 2022 14:10:09 +0200 Subject: [PATCH 083/465] Update cpp/ql/lib/CHANGELOG.md --- cpp/ql/lib/CHANGELOG.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 3b815104efd..c1cefbed8f9 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -4,10 +4,6 @@ * The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. -### New Features - -* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization. - ### Bug Fixes * `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`. From d3df2033f0ef480ee4ccc9f6713f1eb3bca0912d Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 23 Jun 2022 14:11:11 +0200 Subject: [PATCH 084/465] Update cpp/ql/lib/change-notes/released/0.3.0.md --- cpp/ql/lib/change-notes/released/0.3.0.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/cpp/ql/lib/change-notes/released/0.3.0.md b/cpp/ql/lib/change-notes/released/0.3.0.md index c266a3cfa65..8c45dc21817 100644 --- a/cpp/ql/lib/change-notes/released/0.3.0.md +++ b/cpp/ql/lib/change-notes/released/0.3.0.md @@ -4,10 +4,6 @@ * The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module. -### New Features - -* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization. - ### Bug Fixes * `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`. From d94010c244833b49d94203515f0abf52c1ba1bc5 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 23 Jun 2022 14:17:52 +0200 Subject: [PATCH 085/465] Grammar: report -> reports --- python/ql/src/CHANGELOG.md | 2 +- python/ql/src/change-notes/released/0.2.0.md | 2 +- ruby/ql/src/CHANGELOG.md | 2 +- ruby/ql/src/change-notes/released/0.2.0.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index cf3b5f9b4eb..3be12c71c5f 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -6,7 +6,7 @@ ### Minor Analysis Improvements -* The query "Use of a broken or weak cryptographic algorithm" (`py/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode. +* The query "Use of a broken or weak cryptographic algorithm" (`py/weak-cryptographic-algorithm`) now reports if a cryptographic operation is potentially insecure due to use of a weak block mode. ## 0.1.4 diff --git a/python/ql/src/change-notes/released/0.2.0.md b/python/ql/src/change-notes/released/0.2.0.md index 3786d910a80..d9816a102f4 100644 --- a/python/ql/src/change-notes/released/0.2.0.md +++ b/python/ql/src/change-notes/released/0.2.0.md @@ -6,4 +6,4 @@ ### Minor Analysis Improvements -* The query "Use of a broken or weak cryptographic algorithm" (`py/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode. +* The query "Use of a broken or weak cryptographic algorithm" (`py/weak-cryptographic-algorithm`) now reports if a cryptographic operation is potentially insecure due to use of a weak block mode. diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index 0fbab5b5bbf..0905f133d16 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -6,7 +6,7 @@ ### Minor Analysis Improvements -* The query "Use of a broken or weak cryptographic algorithm" (`rb/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode. +* The query "Use of a broken or weak cryptographic algorithm" (`rb/weak-cryptographic-algorithm`) now reports if a cryptographic operation is potentially insecure due to use of a weak block mode. ## 0.1.4 diff --git a/ruby/ql/src/change-notes/released/0.2.0.md b/ruby/ql/src/change-notes/released/0.2.0.md index ed13e617ebe..4e00c192dce 100644 --- a/ruby/ql/src/change-notes/released/0.2.0.md +++ b/ruby/ql/src/change-notes/released/0.2.0.md @@ -6,4 +6,4 @@ ### Minor Analysis Improvements -* The query "Use of a broken or weak cryptographic algorithm" (`rb/weak-cryptographic-algorithm`) now report if a cryptographic operation is potentially insecure due to use of a weak block mode. +* The query "Use of a broken or weak cryptographic algorithm" (`rb/weak-cryptographic-algorithm`) now reports if a cryptographic operation is potentially insecure due to use of a weak block mode. From c27290563ad3f5a90d076ac359871acbe1e32677 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 23 Jun 2022 14:34:05 +0200 Subject: [PATCH 086/465] Dataflow: Perf fix, avoid node scans. --- .../java/dataflow/internal/DataFlowImpl2.qll | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } From 4a317a25d32b56dc826b188071135b6cb941b375 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 23 Jun 2022 14:34:52 +0200 Subject: [PATCH 087/465] Dataflow: Sync. --- .../code/cpp/dataflow/internal/DataFlowImpl.qll | 16 ++++++++-------- .../code/cpp/dataflow/internal/DataFlowImpl2.qll | 16 ++++++++-------- .../code/cpp/dataflow/internal/DataFlowImpl3.qll | 16 ++++++++-------- .../code/cpp/dataflow/internal/DataFlowImpl4.qll | 16 ++++++++-------- .../cpp/dataflow/internal/DataFlowImplLocal.qll | 16 ++++++++-------- .../cpp/ir/dataflow/internal/DataFlowImpl.qll | 16 ++++++++-------- .../cpp/ir/dataflow/internal/DataFlowImpl2.qll | 16 ++++++++-------- .../cpp/ir/dataflow/internal/DataFlowImpl3.qll | 16 ++++++++-------- .../cpp/ir/dataflow/internal/DataFlowImpl4.qll | 16 ++++++++-------- .../csharp/dataflow/internal/DataFlowImpl.qll | 16 ++++++++-------- .../csharp/dataflow/internal/DataFlowImpl2.qll | 16 ++++++++-------- .../csharp/dataflow/internal/DataFlowImpl3.qll | 16 ++++++++-------- .../csharp/dataflow/internal/DataFlowImpl4.qll | 16 ++++++++-------- .../csharp/dataflow/internal/DataFlowImpl5.qll | 16 ++++++++-------- .../internal/DataFlowImplForContentDataFlow.qll | 16 ++++++++-------- .../code/java/dataflow/internal/DataFlowImpl.qll | 16 ++++++++-------- .../java/dataflow/internal/DataFlowImpl3.qll | 16 ++++++++-------- .../java/dataflow/internal/DataFlowImpl4.qll | 16 ++++++++-------- .../java/dataflow/internal/DataFlowImpl5.qll | 16 ++++++++-------- .../java/dataflow/internal/DataFlowImpl6.qll | 16 ++++++++-------- .../internal/DataFlowImplForOnActivityResult.qll | 16 ++++++++-------- .../internal/DataFlowImplForSerializability.qll | 16 ++++++++-------- .../dataflow/new/internal/DataFlowImpl.qll | 16 ++++++++-------- .../dataflow/new/internal/DataFlowImpl2.qll | 16 ++++++++-------- .../dataflow/new/internal/DataFlowImpl3.qll | 16 ++++++++-------- .../dataflow/new/internal/DataFlowImpl4.qll | 16 ++++++++-------- .../ruby/dataflow/internal/DataFlowImpl.qll | 16 ++++++++-------- .../ruby/dataflow/internal/DataFlowImpl2.qll | 16 ++++++++-------- .../internal/DataFlowImplForLibraries.qll | 16 ++++++++-------- .../swift/dataflow/internal/DataFlowImpl.qll | 16 ++++++++-------- 30 files changed, 240 insertions(+), 240 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index 7b9e78d2c4b..18e0b54cc73 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -428,7 +428,7 @@ private predicate localFlowStep(NodeEx node1, NodeEx node2, Configuration config exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - simpleLocalFlowStepExt(n1, n2) and + simpleLocalFlowStepExt(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) ) or @@ -447,7 +447,7 @@ private predicate additionalLocalFlowStep(NodeEx node1, NodeEx node2, Configurat exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) ) @@ -466,7 +466,7 @@ private predicate additionalLocalStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) = getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -481,7 +481,7 @@ private predicate jumpStep(NodeEx node1, NodeEx node2, Configuration config) { exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - jumpStepCached(n1, n2) and + jumpStepCached(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext ) @@ -494,7 +494,7 @@ private predicate additionalJumpStep(NodeEx node1, NodeEx node2, Configuration c exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, n2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), pragma[only_bind_into](n2)) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not config.getAFeature() instanceof FeatureEqualSourceSinkCallContext @@ -507,7 +507,7 @@ private predicate additionalJumpStateStep( exists(Node n1, Node n2 | node1.asNode() = n1 and node2.asNode() = n2 and - config.isAdditionalFlowStep(n1, s1, n2, s2) and + config.isAdditionalFlowStep(pragma[only_bind_into](n1), s1, pragma[only_bind_into](n2), s2) and getNodeEnclosingCallable(n1) != getNodeEnclosingCallable(n2) and stepFilter(node1, node2, config) and not stateBarrier(node1, s1, config) and @@ -518,7 +518,7 @@ private predicate additionalJumpStateStep( pragma[nomagic] private predicate readSet(NodeEx node1, ContentSet c, NodeEx node2, Configuration config) { - readSet(node1.asNode(), c, node2.asNode()) and + readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and stepFilter(node1, node2, config) or exists(Node n | @@ -562,7 +562,7 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(node1.asNode(), tc, node2.asNode(), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } From dc517a758e104ce6a91c4f1bcff04548558afe63 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 23 Jun 2022 14:44:40 +0200 Subject: [PATCH 088/465] Autoformat --- cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll | 3 ++- cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll | 3 ++- cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll | 3 ++- cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll | 3 ++- .../semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll | 3 ++- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll | 3 ++- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll | 3 ++- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll | 3 ++- .../lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll | 3 ++- .../lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll | 3 ++- .../lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll | 3 ++- .../lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll | 3 ++- .../lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll | 3 ++- .../lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll | 3 ++- .../dataflow/internal/DataFlowImplForContentDataFlow.qll | 3 ++- .../ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll | 3 ++- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll | 3 ++- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll | 3 ++- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll | 3 ++- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll | 3 ++- .../lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll | 3 ++- .../java/dataflow/internal/DataFlowImplForOnActivityResult.qll | 3 ++- .../java/dataflow/internal/DataFlowImplForSerializability.qll | 3 ++- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll | 3 ++- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll | 3 ++- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll | 3 ++- .../lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll | 3 ++- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll | 3 ++- ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll | 3 ++- .../codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll | 3 ++- swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll | 3 ++- 31 files changed, 62 insertions(+), 31 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index 18e0b54cc73..a076f7a2e45 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -562,7 +562,8 @@ pragma[nomagic] private predicate store( NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config ) { - store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), contentType) and + store(pragma[only_bind_into](node1.asNode()), tc, pragma[only_bind_into](node2.asNode()), + contentType) and read(_, tc.getContent(), _, config) and stepFilter(node1, node2, config) } From fa622f551a2766ff641a8f0b13ddd3f48f37a148 Mon Sep 17 00:00:00 2001 From: Brandon Stewart <20469703+boveus@users.noreply.github.com> Date: Thu, 23 Jun 2022 12:16:50 -0400 Subject: [PATCH 089/465] Update ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll Co-authored-by: Alex Ford --- ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index 5809b35baf4..6ce74550610 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -331,6 +331,9 @@ class ActiveRecordInstance extends DataFlow::Node { } // A call whose receiver may be an active record model object +/** + * A call whose receiver may be an `ActiveRecordInstance`. + */ class ActiveRecordInstanceMethodCall extends DataFlow::CallNode { private ActiveRecordInstance instance; From 173bea25795588544433fd2628979de0cbd2d72f Mon Sep 17 00:00:00 2001 From: Brandon Stewart <20469703+boveus@users.noreply.github.com> Date: Thu, 23 Jun 2022 12:18:26 -0400 Subject: [PATCH 090/465] Update ActiveRecord.qll --- ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index 6ce74550610..225e9b30842 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -331,9 +331,7 @@ class ActiveRecordInstance extends DataFlow::Node { } // A call whose receiver may be an active record model object -/** - * A call whose receiver may be an `ActiveRecordInstance`. - */ +/** Gets the `ActiveRecordInstance` receiver of this call. */ class ActiveRecordInstanceMethodCall extends DataFlow::CallNode { private ActiveRecordInstance instance; From caeef68bde589ecaf4cbdc674ceba55bceeed65a Mon Sep 17 00:00:00 2001 From: Brandon Stewart <20469703+boveus@users.noreply.github.com> Date: Thu, 23 Jun 2022 12:31:05 -0400 Subject: [PATCH 091/465] Update ActiveRecord.qll --- ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index 225e9b30842..3742157a56f 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -331,7 +331,7 @@ class ActiveRecordInstance extends DataFlow::Node { } // A call whose receiver may be an active record model object -/** Gets the `ActiveRecordInstance` receiver of this call. */ +/** The `ActiveRecordInstance` receiver of this call. */ class ActiveRecordInstanceMethodCall extends DataFlow::CallNode { private ActiveRecordInstance instance; From 45dd38df6eb5da24325ebcc0456e250429e7c2b6 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Fri, 24 Jun 2022 01:50:20 +0000 Subject: [PATCH 092/465] polish up dataflow query --- .../experimental/weak-params/WeakParams.ql | 45 +++++++++++++++---- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql index 1d8ef89e70a..e3f63b9bfd8 100644 --- a/ruby/ql/src/experimental/weak-params/WeakParams.ql +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -14,21 +14,38 @@ import codeql.ruby.DataFlow import codeql.ruby.TaintTracking import DataFlow::PathGraph +/** + * any direct parameters reference that happens outside of a strong params method but inside + * of a controller class + */ class WeakParams extends Expr { WeakParams() { - allParamsAccess(this) or - this instanceof ParamsReference + ( + allParamsAccess(this) or + this instanceof ParamsReference + ) and + this.getEnclosingModule() instanceof ControllerClass and + not this.getEnclosingMethod() instanceof StrongParamsMethod } } +/** + * A controller class, which extendsd `ApplicationController` + */ class ControllerClass extends ModuleBase { ControllerClass() { this.getModule().getSuperClass+().toString() = "ApplicationController" } } +/** + * A method that follows the strong params naming convention + */ class StrongParamsMethod extends Method { StrongParamsMethod() { this.getName().regexpMatch(".*_params") } } +/** + * a call to a method that exposes or accesses all parameters from an inbound HTTP request + */ predicate allParamsAccess(MethodCall call) { call.getMethodName() = "expose_all" or call.getMethodName() = "original_hash" or @@ -39,10 +56,17 @@ predicate allParamsAccess(MethodCall call) { call.getMethodName() = "POST" } +/** + * A reference to an element in the `params` object + */ class ParamsReference extends ElementReference { ParamsReference() { this.getAChild().toString() = "params" } } +/** + * returns either Model or ViewModel classes with a base class of `ViewModel` or includes `ActionModel::Model`, + * which are required to support the strong parameters pattern + */ class ModelClass extends ModuleBase { ModelClass() { this.getModule().getSuperClass+().toString() = "ViewModel" or @@ -50,6 +74,10 @@ class ModelClass extends ModuleBase { } } +/** + * A DataFlow::Node representation that corresponds to any argument passed into a method call + * where the receiver is an instance of ModelClass + */ class ModelClassMethodArgument extends DataFlow::Node { private DataFlow::CallNode call; @@ -59,6 +87,10 @@ class ModelClassMethodArgument extends DataFlow::Node { } } +/** + * Taint tracking config where the source is a weak params access in a controller and the sink + * is a method call of a model class + */ class Configuration extends TaintTracking::Configuration { Configuration() { this = "Configuration" } @@ -70,10 +102,5 @@ class Configuration extends TaintTracking::Configuration { from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) -select sink.getNode().(ModelClassMethodArgument), source, sink, "This is bad" -// from WeakParams params -// where -// not params.getEnclosingMethod() instanceof StrongParamsMethod and -// params.getEnclosingModule() instanceof ControllerClass -// select params, -// "By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects." +select sink.getNode().(ModelClassMethodArgument), source, sink, + "By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html" From cf36333082139ae016d3ed1a1c41aa05f9bb50e9 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Fri, 24 Jun 2022 02:18:48 +0000 Subject: [PATCH 093/465] forgot to finish this test --- ruby/ql/test/query-tests/security/weak-params/WeakParams.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb b/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb index cc0dc80341f..a2fedd6ef26 100644 --- a/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb +++ b/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb @@ -7,9 +7,12 @@ class TestController < ActionController::Base TestObject.new(request.query_parameters) end + def update + TestObect.update(object_params) + end + # def object_params - p = params.query_parameters params.require(:uuid).permit(:notes) end end \ No newline at end of file From ca074e2275060a7ad41882d922a14418289605f1 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Fri, 24 Jun 2022 02:19:06 +0000 Subject: [PATCH 094/465] add qhelp file --- .../experimental/weak-params/WeakParams.qhelp | 28 +++++++++++++++++++ .../experimental/weak-params/WeakParams.ql | 6 ++-- 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 ruby/ql/src/experimental/weak-params/WeakParams.qhelp diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.qhelp b/ruby/ql/src/experimental/weak-params/WeakParams.qhelp new file mode 100644 index 00000000000..9bccf15d03d --- /dev/null +++ b/ruby/ql/src/experimental/weak-params/WeakParams.qhelp @@ -0,0 +1,28 @@ + + + +

+ Directly checking request parameters without following a strong params + pattern can lead to unintentional avenues for injection attacks. +

+
+ +

+ Instead of manually checking parameters from the `param` object, it is + recommended that you follow the strong parameters pattern established in + Rails: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html +

+

+ In the strong parameters pattern, you are able to specify required and allowed + parameters for each action called by your controller methods. This acts as an + additional layer of data validation before being passed along to other areas + of your application, such as the model. +

+
+ + + + +
diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql index e3f63b9bfd8..85bb31a7372 100644 --- a/ruby/ql/src/experimental/weak-params/WeakParams.ql +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -4,9 +4,10 @@ * @kind path-problem * @problem.severity error * @security-severity 5.0 - * @precision low + * @precision medium * @id rb/weak-params * @tags security + * external/cwe/cwe-223 */ import ruby @@ -64,12 +65,13 @@ class ParamsReference extends ElementReference { } /** - * returns either Model or ViewModel classes with a base class of `ViewModel` or includes `ActionModel::Model`, + * returns either Model or ViewModel classes with a base class of `ViewModel`, `ApplicationRecord` or includes `ActionModel::Model`, * which are required to support the strong parameters pattern */ class ModelClass extends ModuleBase { ModelClass() { this.getModule().getSuperClass+().toString() = "ViewModel" or + this.getModule().getSuperClass+().toString() = "ApplicationRecord" or this.getModule().getSuperClass+().getAnIncludedModule().toString() = "ActionModel::Model" } } From ce2edd4b28c7895292dfa291b130776c846b4105 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Fri, 24 Jun 2022 02:46:48 +0000 Subject: [PATCH 095/465] style tweaks --- ruby/ql/src/experimental/weak-params/WeakParams.ql | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql index 85bb31a7372..5d77b0e066a 100644 --- a/ruby/ql/src/experimental/weak-params/WeakParams.ql +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -16,7 +16,7 @@ import codeql.ruby.TaintTracking import DataFlow::PathGraph /** - * any direct parameters reference that happens outside of a strong params method but inside + * A direct parameters reference that happens outside of a strong params method but inside * of a controller class */ class WeakParams extends Expr { @@ -45,7 +45,7 @@ class StrongParamsMethod extends Method { } /** - * a call to a method that exposes or accesses all parameters from an inbound HTTP request + * A call to a method that exposes or accesses all parameters from an inbound HTTP request */ predicate allParamsAccess(MethodCall call) { call.getMethodName() = "expose_all" or @@ -65,7 +65,7 @@ class ParamsReference extends ElementReference { } /** - * returns either Model or ViewModel classes with a base class of `ViewModel`, `ApplicationRecord` or includes `ActionModel::Model`, + * A Model or ViewModel classes with a base class of `ViewModel`, `ApplicationRecord` or includes `ActionModel::Model`, * which are required to support the strong parameters pattern */ class ModelClass extends ModuleBase { @@ -81,16 +81,15 @@ class ModelClass extends ModuleBase { * where the receiver is an instance of ModelClass */ class ModelClassMethodArgument extends DataFlow::Node { - private DataFlow::CallNode call; ModelClassMethodArgument() { - this = call.getArgument(_) and - call.getExprNode().getNode().getParent+() instanceof ModelClass + exists( DataFlow::CallNode call | this = call.getArgument(_) | + call.getExprNode().getNode().getParent+() instanceof ModelClass ) } } /** - * Taint tracking config where the source is a weak params access in a controller and the sink + * A Taint tracking config where the source is a weak params access in a controller and the sink * is a method call of a model class */ class Configuration extends TaintTracking::Configuration { From 6ea1aad5fc95445067420ffe91382e37824a5505 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 23 Jun 2022 22:57:51 -0400 Subject: [PATCH 096/465] more style fixes --- ruby/ql/src/experimental/weak-params/WeakParams.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql index 5d77b0e066a..f9af2e5c08c 100644 --- a/ruby/ql/src/experimental/weak-params/WeakParams.ql +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -45,7 +45,7 @@ class StrongParamsMethod extends Method { } /** - * A call to a method that exposes or accesses all parameters from an inbound HTTP request + * Holds call to a method that exposes or accesses all parameters from an inbound HTTP request */ predicate allParamsAccess(MethodCall call) { call.getMethodName() = "expose_all" or From d506f448ef1855aa849638bd347fdd09a55d1ad9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Jun 2022 07:36:33 +0000 Subject: [PATCH 097/465] Post-release preparation for codeql-cli-2.10.0 --- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index ad716ce6145..a20077271d7 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.3.0 +version: 0.3.1-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 4d5444cdb80..62cac967801 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.2.0 +version: 0.2.1-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index f411871c1c7..bc7eaf4142c 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.2.0 +version: 1.2.1-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 5f5ac8e59e2..00725e23666 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.2.0 +version: 1.2.1-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 11897f937b9..3f371c01e92 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.3.0 +version: 0.3.1-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 675f8d4a1b0..1002c6a56ad 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.2.0 +version: 0.2.1-dev groups: - csharp - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 8806039a710..964f5d4dd13 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.2.0 +version: 0.2.1-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index f30de39c94e..80a4430b8da 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.2.0 +version: 0.2.1-dev groups: - go - queries diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 0b359cd7722..541fad197e0 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.3.0 +version: 0.3.1-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index d68826094c7..2366eef3778 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.2.0 +version: 0.2.1-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index a817864032e..b16a8912ccf 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.2.0 +version: 0.2.1-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 0b5bfa5824e..4f54f7dc5bc 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.2.0 +version: 0.2.1-dev groups: - javascript - queries diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index e4da90cbc2b..65145e40d74 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.5.0 +version: 0.5.1-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 91284be3afa..af722116e41 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.2.0 +version: 0.2.1-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 1b419d0bdcf..062d906c9a2 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.3.0 +version: 0.3.1-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 159f92016a1..0bd19b5bdeb 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.2.0 +version: 0.2.1-dev groups: - ruby - queries From 03d0f66247d1c0fe5c171b67bd39e9c5d2c145a9 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 23 Jun 2022 10:03:43 +0100 Subject: [PATCH 098/465] Ruby: add flow summaries for Pathname class --- ruby/ql/lib/codeql/ruby/frameworks/Core.qll | 1 + .../codeql/ruby/frameworks/core/Pathname.qll | 118 ++++++++++++++++++ .../pathname-flow/pathame-flow.expected | 90 +++++++++++++ .../dataflow/pathname-flow/pathame-flow.ql | 11 ++ .../dataflow/pathname-flow/pathname_flow.rb | 61 +++++++++ 5 files changed, 281 insertions(+) create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll create mode 100644 ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected create mode 100644 ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.ql create mode 100644 ruby/ql/test/library-tests/dataflow/pathname-flow/pathname_flow.rb diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Core.qll b/ruby/ql/lib/codeql/ruby/frameworks/Core.qll index 1ef6d8d65e5..b428029c829 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Core.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Core.qll @@ -14,6 +14,7 @@ import core.Hash import core.String import core.Regexp import core.IO +import core.Pathname /** * A system command executed via subshell literal syntax. diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll new file mode 100644 index 00000000000..b88ca128283 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll @@ -0,0 +1,118 @@ +/** Modeling of the `Pathname` class from the Ruby standard library. */ + +private import codeql.ruby.AST +private import codeql.ruby.ApiGraphs +private import codeql.ruby.DataFlow +private import codeql.ruby.dataflow.FlowSummary +private import codeql.ruby.dataflow.internal.DataFlowDispatch +private import codeql.ruby.controlflow.CfgNodes + +/** + * Modeling of the `Pathname` class from the Ruby standard library. + * + * https://docs.ruby-lang.org/en/3.1/Pathname.html + */ +module Pathname { + /// Flow summary for `Pathname.new`. + private class NewSummary extends SummarizedCallable { + NewSummary() { this = "Pathname.new" } + + override MethodCall getACall() { + result = API::getTopLevelMember("Pathname").getAnInstantiation().getExprNode().getExpr() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /// Flow summary for `Pathname#dirname`. + private class DirnameSummary extends SimpleSummarizedCallable { + DirnameSummary() { this = "dirname" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /// Flow summary for `Pathname#each_filename`. + private class EachFilenameSummary extends SimpleSummarizedCallable { + EachFilenameSummary() { this = "each_filename" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self]" and + output = "Argument[block].Parameter[0]" and + preservesValue = false + } + } + + /// Flow summary for `Pathname#expand_path`. + private class ExpandPathSummary extends SimpleSummarizedCallable { + ExpandPathSummary() { this = "expand_path" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /// Flow summary for `Pathname#join`. + private class JoinSummary extends SimpleSummarizedCallable { + JoinSummary() { this = "join" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = ["Argument[self]", "Argument[any]"] and + output = "ReturnValue" and + preservesValue = false + } + } + + /// Flow summary for `Pathname#parent`. + private class ParentSummary extends SimpleSummarizedCallable { + ParentSummary() { this = "parent" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /// Flow summary for `Pathname#realpath`. + private class RealpathSummary extends SimpleSummarizedCallable { + RealpathSummary() { this = "realpath" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /// Flow summary for `Pathname#relative_path_from`. + private class RelativePathFromSummary extends SimpleSummarizedCallable { + RelativePathFromSummary() { this = "relative_path_from" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self]" and + output = "ReturnValue" and + preservesValue = false + } + } + + /// Flow summary for `Pathname#to_path`. + private class ToPathSummary extends SimpleSummarizedCallable { + ToPathSummary() { this = "to_path" } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[self]" and + output = "ReturnValue" and + preservesValue = false + } + } +} diff --git a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected new file mode 100644 index 00000000000..8e3a792af46 --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected @@ -0,0 +1,90 @@ +failures +edges +| pathname_flow.rb:4:10:4:33 | call to new : | pathname_flow.rb:5:10:5:11 | pn | +| pathname_flow.rb:4:23:4:32 | call to source : | pathname_flow.rb:4:10:4:33 | call to new : | +| pathname_flow.rb:9:6:9:29 | call to new : | pathname_flow.rb:11:7:11:11 | ... + ... | +| pathname_flow.rb:9:19:9:28 | call to source : | pathname_flow.rb:9:6:9:29 | call to new : | +| pathname_flow.rb:10:6:10:29 | call to new : | pathname_flow.rb:11:7:11:11 | ... + ... | +| pathname_flow.rb:10:19:10:28 | call to source : | pathname_flow.rb:10:6:10:29 | call to new : | +| pathname_flow.rb:15:7:15:30 | call to new : | pathname_flow.rb:16:7:16:8 | pn : | +| pathname_flow.rb:15:20:15:29 | call to source : | pathname_flow.rb:15:7:15:30 | call to new : | +| pathname_flow.rb:16:7:16:8 | pn : | pathname_flow.rb:16:7:16:16 | call to dirname | +| pathname_flow.rb:20:6:20:29 | call to new : | pathname_flow.rb:21:2:21:2 | a : | +| pathname_flow.rb:20:19:20:28 | call to source : | pathname_flow.rb:20:6:20:29 | call to new : | +| pathname_flow.rb:21:2:21:2 | a : | pathname_flow.rb:21:22:21:22 | x : | +| pathname_flow.rb:21:22:21:22 | x : | pathname_flow.rb:22:8:22:8 | x | +| pathname_flow.rb:27:6:27:29 | call to new : | pathname_flow.rb:28:7:28:7 | a : | +| pathname_flow.rb:27:19:27:28 | call to source : | pathname_flow.rb:27:6:27:29 | call to new : | +| pathname_flow.rb:28:7:28:7 | a : | pathname_flow.rb:28:7:28:21 | call to expand_path | +| pathname_flow.rb:32:6:32:29 | call to new : | pathname_flow.rb:35:7:35:7 | a : | +| pathname_flow.rb:32:19:32:28 | call to source : | pathname_flow.rb:32:6:32:29 | call to new : | +| pathname_flow.rb:34:6:34:29 | call to new : | pathname_flow.rb:35:17:35:17 | c : | +| pathname_flow.rb:34:19:34:28 | call to source : | pathname_flow.rb:34:6:34:29 | call to new : | +| pathname_flow.rb:35:7:35:7 | a : | pathname_flow.rb:35:7:35:18 | call to join | +| pathname_flow.rb:35:17:35:17 | c : | pathname_flow.rb:35:7:35:18 | call to join | +| pathname_flow.rb:39:6:39:29 | call to new : | pathname_flow.rb:40:7:40:7 | a : | +| pathname_flow.rb:39:19:39:28 | call to source : | pathname_flow.rb:39:6:39:29 | call to new : | +| pathname_flow.rb:40:7:40:7 | a : | pathname_flow.rb:40:7:40:16 | call to parent | +| pathname_flow.rb:44:6:44:29 | call to new : | pathname_flow.rb:45:7:45:7 | a : | +| pathname_flow.rb:44:19:44:28 | call to source : | pathname_flow.rb:44:6:44:29 | call to new : | +| pathname_flow.rb:45:7:45:7 | a : | pathname_flow.rb:45:7:45:18 | call to realpath | +| pathname_flow.rb:49:6:49:29 | call to new : | pathname_flow.rb:50:7:50:7 | a : | +| pathname_flow.rb:49:19:49:28 | call to source : | pathname_flow.rb:49:6:49:29 | call to new : | +| pathname_flow.rb:50:7:50:7 | a : | pathname_flow.rb:50:7:50:38 | call to relative_path_from | +| pathname_flow.rb:54:6:54:29 | call to new : | pathname_flow.rb:55:7:55:7 | a : | +| pathname_flow.rb:54:19:54:28 | call to source : | pathname_flow.rb:54:6:54:29 | call to new : | +| pathname_flow.rb:55:7:55:7 | a : | pathname_flow.rb:55:7:55:15 | call to to_path | +| pathname_flow.rb:59:6:59:29 | call to new : | pathname_flow.rb:60:7:60:7 | a : | +| pathname_flow.rb:59:19:59:28 | call to source : | pathname_flow.rb:59:6:59:29 | call to new : | +| pathname_flow.rb:60:7:60:7 | a : | pathname_flow.rb:60:7:60:12 | call to to_s | +nodes +| pathname_flow.rb:4:10:4:33 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:4:23:4:32 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:5:10:5:11 | pn | semmle.label | pn | +| pathname_flow.rb:9:6:9:29 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:9:19:9:28 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:10:6:10:29 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:10:19:10:28 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:11:7:11:11 | ... + ... | semmle.label | ... + ... | +| pathname_flow.rb:15:7:15:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:15:20:15:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:16:7:16:8 | pn : | semmle.label | pn : | +| pathname_flow.rb:16:7:16:16 | call to dirname | semmle.label | call to dirname | +| pathname_flow.rb:20:6:20:29 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:20:19:20:28 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:21:2:21:2 | a : | semmle.label | a : | +| pathname_flow.rb:21:22:21:22 | x : | semmle.label | x : | +| pathname_flow.rb:22:8:22:8 | x | semmle.label | x | +| pathname_flow.rb:27:6:27:29 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:27:19:27:28 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:28:7:28:7 | a : | semmle.label | a : | +| pathname_flow.rb:28:7:28:21 | call to expand_path | semmle.label | call to expand_path | +| pathname_flow.rb:32:6:32:29 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:32:19:32:28 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:34:6:34:29 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:34:19:34:28 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:35:7:35:7 | a : | semmle.label | a : | +| pathname_flow.rb:35:7:35:18 | call to join | semmle.label | call to join | +| pathname_flow.rb:35:17:35:17 | c : | semmle.label | c : | +| pathname_flow.rb:39:6:39:29 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:39:19:39:28 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:40:7:40:7 | a : | semmle.label | a : | +| pathname_flow.rb:40:7:40:16 | call to parent | semmle.label | call to parent | +| pathname_flow.rb:44:6:44:29 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:44:19:44:28 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:45:7:45:7 | a : | semmle.label | a : | +| pathname_flow.rb:45:7:45:18 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:49:6:49:29 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:49:19:49:28 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:50:7:50:7 | a : | semmle.label | a : | +| pathname_flow.rb:50:7:50:38 | call to relative_path_from | semmle.label | call to relative_path_from | +| pathname_flow.rb:54:6:54:29 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:54:19:54:28 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:55:7:55:7 | a : | semmle.label | a : | +| pathname_flow.rb:55:7:55:15 | call to to_path | semmle.label | call to to_path | +| pathname_flow.rb:59:6:59:29 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:59:19:59:28 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:60:7:60:7 | a : | semmle.label | a : | +| pathname_flow.rb:60:7:60:12 | call to to_s | semmle.label | call to to_s | +subpaths +#select diff --git a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.ql b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.ql new file mode 100644 index 00000000000..4e812d32daa --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.ql @@ -0,0 +1,11 @@ +/** + * @kind path-problem + */ + +import ruby +import TestUtilities.InlineFlowTest +import PathGraph + +from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf +where conf.hasFlowPath(source, sink) +select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathname_flow.rb b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathname_flow.rb new file mode 100644 index 00000000000..3434b6093b6 --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathname_flow.rb @@ -0,0 +1,61 @@ +require 'pathname' + +def m_new + pn = Pathname.new(source 'a') + sink pn # $ hasTaintFlow=a +end + +def m_plus + a = Pathname.new(source 'a') + b = Pathname.new(source 'b') + sink(a + b) # $ hasTaintFlow=a $ hasTaintFlow=b +end + +def m_dirname + pn = Pathname.new(source 'a') + sink pn.dirname # $ hasTaintFlow=a +end + +def m_each_filename + a = Pathname.new(source 'a') + a.each_filename do |x| + sink x # $ hasTaintFlow=a + end +end + +def m_expand_path + a = Pathname.new(source 'a') + sink a.expand_path() # $ hasTaintFlow=a +end + +def m_join + a = Pathname.new(source 'a') + b = Pathname.new('foo') + c = Pathname.new(source 'c') + sink a.join(b, c) # $ hasTaintFlow=a $ hasTaintFlow=c +end + +def m_parent + a = Pathname.new(source 'a') + sink a.parent() # $ hasTaintFlow=a +end + +def m_realpath + a = Pathname.new(source 'a') + sink a.realpath() # $ hasTaintFlow=a +end + +def m_relative_path_from + a = Pathname.new(source 'a') + sink a.relative_path_from('/foo/bar') # $ hasTaintFlow=a +end + +def m_to_path + a = Pathname.new(source 'a') + sink a.to_path # $ hasTaintFlow=a +end + +def m_to_s + a = Pathname.new(source 'a') + sink a.to_s # $ hasTaintFlow=a +end \ No newline at end of file From c1515db09c93e65a72a2a6b6af6be9cc464c1ef5 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Fri, 24 Jun 2022 14:13:02 +0100 Subject: [PATCH 099/465] Ruby: modeling of some file-related concepts for the Pathname class --- .../codeql/ruby/frameworks/core/Pathname.qll | 120 ++++++++++++++-- .../frameworks/pathname/Pathname.expected | 134 ++++++++++++++++++ .../frameworks/pathname/Pathname.ql | 26 ++++ .../frameworks/pathname/Pathname.rb | 42 ++++++ 4 files changed, 312 insertions(+), 10 deletions(-) create mode 100644 ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected create mode 100644 ruby/ql/test/library-tests/frameworks/pathname/Pathname.ql create mode 100644 ruby/ql/test/library-tests/frameworks/pathname/Pathname.rb diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll index b88ca128283..d296d9c75ea 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll @@ -2,10 +2,10 @@ private import codeql.ruby.AST private import codeql.ruby.ApiGraphs +private import codeql.ruby.Concepts private import codeql.ruby.DataFlow private import codeql.ruby.dataflow.FlowSummary private import codeql.ruby.dataflow.internal.DataFlowDispatch -private import codeql.ruby.controlflow.CfgNodes /** * Modeling of the `Pathname` class from the Ruby standard library. @@ -13,7 +13,107 @@ private import codeql.ruby.controlflow.CfgNodes * https://docs.ruby-lang.org/en/3.1/Pathname.html */ module Pathname { - /// Flow summary for `Pathname.new`. + /** + * An instance of the `Pathname` class. For example, in + * + * ```rb + * pn = Pathname.new "foo.txt'" + * puts pn.read + * ``` + * + * there are three `PathnameInstance`s – the call to `Pathname.new`, the + * assignment `pn = ...`, and the read access to `pn` on the second line. + * + * Every `PathnameInstance` is considered to be a `FileNameSource`. + */ + class PathnameInstance extends FileNameSource, DataFlow::Node { + PathnameInstance() { this = pathnameInstance() } + } + + private DataFlow::Node pathnameInstance() { + // A call to `Pathname.new`. + result = API::getTopLevelMember("Pathname").getAnInstantiation() + or + // Class methods on `Pathname` that return a new `Pathname`. + result = API::getTopLevelMember("Pathname").getAMethodCall(["getwd", "pwd",]) + or + // Instance methods on `Pathname` that return a new `Pathname`. + exists(DataFlow::CallNode c | result = c | + c.getReceiver() = pathnameInstance() and + c.getMethodName() = + [ + "+", "/", "basename", "cleanpath", "expand_path", "join", "realpath", + "relative_path_from", "sub", "sub_ext", "to_path" + ] + ) + or + exists(DataFlow::Node inst | + inst = pathnameInstance() and + inst.(DataFlow::LocalSourceNode).flowsTo(result) + ) + } + + /** A call where the receiver is a `Pathname`. */ + class PathnameCall extends DataFlow::CallNode { + PathnameCall() { this.getReceiver() instanceof PathnameInstance } + } + + /** + * A call to `Pathname#open` or `Pathname#opendir`, considered as a + * `FileSystemAccess`. + */ + class PathnameOpen extends FileSystemAccess::Range, PathnameCall { + PathnameOpen() { this.getMethodName() = ["open", "opendir"] } + + override DataFlow::Node getAPathArgument() { result = this.getReceiver() } + } + + /** A call to `Pathname#read`, considered as a `FileSystemReadAccess`. */ + class PathnameRead extends FileSystemReadAccess::Range, PathnameCall { + PathnameRead() { this.getMethodName() = "read" } + + // The path is the receiver (the `Pathname` object). + override DataFlow::Node getAPathArgument() { result = this.getReceiver() } + + // The read data is the return value of the call. + override DataFlow::Node getADataNode() { result = this } + } + + /** A call to `Pathname#write`, considered as a `FileSystemWriteAccess`. */ + class PathnameWrite extends FileSystemWriteAccess::Range, PathnameCall { + PathnameWrite() { this.getMethodName() = "write" } + + // The path is the receiver (the `Pathname` object). + override DataFlow::Node getAPathArgument() { result = this.getReceiver() } + + // The data to write is the 0th argument. + override DataFlow::Node getADataNode() { result = this.getArgument(0) } + } + + /** A call to `Pathname#to_s`, considered as a `FileNameSource`. */ + class PathnameToSFilenameSource extends FileNameSource, PathnameCall { + PathnameToSFilenameSource() { this.getMethodName() = "to_s" } + } + + private class PathnamePermissionModification extends FileSystemPermissionModification::Range, + PathnameCall { + private DataFlow::Node permissionArg; + + PathnamePermissionModification() { + exists(string methodName | this.getMethodName() = methodName | + methodName = ["chmod", "mkdir"] and permissionArg = this.getArgument(0) + or + methodName = "mkpath" and permissionArg = this.getKeywordArgument("mode") + or + methodName = "open" and permissionArg = this.getArgument(1) + // TODO: defaults for optional args? This may depend on the umask + ) + } + + override DataFlow::Node getAPermissionNode() { result = permissionArg } + } + + /** Flow summary for `Pathname.new`. */ private class NewSummary extends SummarizedCallable { NewSummary() { this = "Pathname.new" } @@ -28,7 +128,7 @@ module Pathname { } } - /// Flow summary for `Pathname#dirname`. + /** Flow summary for `Pathname#dirname`. */ private class DirnameSummary extends SimpleSummarizedCallable { DirnameSummary() { this = "dirname" } @@ -39,7 +139,7 @@ module Pathname { } } - /// Flow summary for `Pathname#each_filename`. + /** Flow summary for `Pathname#each_filename`. */ private class EachFilenameSummary extends SimpleSummarizedCallable { EachFilenameSummary() { this = "each_filename" } @@ -50,7 +150,7 @@ module Pathname { } } - /// Flow summary for `Pathname#expand_path`. + /** Flow summary for `Pathname#expand_path`. */ private class ExpandPathSummary extends SimpleSummarizedCallable { ExpandPathSummary() { this = "expand_path" } @@ -61,7 +161,7 @@ module Pathname { } } - /// Flow summary for `Pathname#join`. + /** Flow summary for `Pathname#join`. */ private class JoinSummary extends SimpleSummarizedCallable { JoinSummary() { this = "join" } @@ -72,7 +172,7 @@ module Pathname { } } - /// Flow summary for `Pathname#parent`. + /** Flow summary for `Pathname#parent`. */ private class ParentSummary extends SimpleSummarizedCallable { ParentSummary() { this = "parent" } @@ -83,7 +183,7 @@ module Pathname { } } - /// Flow summary for `Pathname#realpath`. + /** Flow summary for `Pathname#realpath`. */ private class RealpathSummary extends SimpleSummarizedCallable { RealpathSummary() { this = "realpath" } @@ -94,7 +194,7 @@ module Pathname { } } - /// Flow summary for `Pathname#relative_path_from`. + /** Flow summary for `Pathname#relative_path_from`. */ private class RelativePathFromSummary extends SimpleSummarizedCallable { RelativePathFromSummary() { this = "relative_path_from" } @@ -105,7 +205,7 @@ module Pathname { } } - /// Flow summary for `Pathname#to_path`. + /** Flow summary for `Pathname#to_path`. */ private class ToPathSummary extends SimpleSummarizedCallable { ToPathSummary() { this = "to_path" } diff --git a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected new file mode 100644 index 00000000000..2550c5b4f0d --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.expected @@ -0,0 +1,134 @@ +pathnameInstances +| Pathname.rb:2:1:2:33 | ... = ... | +| Pathname.rb:2:1:2:33 | ... = ... | +| Pathname.rb:2:12:2:33 | call to new | +| Pathname.rb:3:1:3:20 | ... = ... | +| Pathname.rb:3:13:3:20 | foo_path | +| Pathname.rb:4:1:4:8 | foo_path | +| Pathname.rb:6:1:6:29 | ... = ... | +| Pathname.rb:6:1:6:29 | ... = ... | +| Pathname.rb:6:12:6:29 | call to new | +| Pathname.rb:9:1:9:21 | ... = ... | +| Pathname.rb:9:1:9:21 | ... = ... | +| Pathname.rb:9:8:9:21 | call to getwd | +| Pathname.rb:10:1:10:21 | ... = ... | +| Pathname.rb:10:7:10:10 | pwd1 | +| Pathname.rb:10:7:10:21 | ... + ... | +| Pathname.rb:10:14:10:21 | foo_path | +| Pathname.rb:11:1:11:21 | ... = ... | +| Pathname.rb:11:1:11:21 | ... = ... | +| Pathname.rb:11:7:11:10 | pwd1 | +| Pathname.rb:11:7:11:21 | ... / ... | +| Pathname.rb:11:14:11:21 | bar_path | +| Pathname.rb:12:1:12:19 | ... = ... | +| Pathname.rb:12:7:12:10 | pwd1 | +| Pathname.rb:12:7:12:19 | call to basename | +| Pathname.rb:13:1:13:46 | ... = ... | +| Pathname.rb:13:7:13:36 | call to new | +| Pathname.rb:13:7:13:46 | call to cleanpath | +| Pathname.rb:14:1:14:26 | ... = ... | +| Pathname.rb:14:7:14:14 | foo_path | +| Pathname.rb:14:7:14:26 | call to expand_path | +| Pathname.rb:15:1:15:39 | ... = ... | +| Pathname.rb:15:7:15:10 | pwd1 | +| Pathname.rb:15:7:15:39 | call to join | +| Pathname.rb:16:1:16:23 | ... = ... | +| Pathname.rb:16:7:16:14 | foo_path | +| Pathname.rb:16:7:16:23 | call to realpath | +| Pathname.rb:17:1:17:59 | ... = ... | +| Pathname.rb:17:7:17:33 | call to new | +| Pathname.rb:17:7:17:59 | call to relative_path_from | +| Pathname.rb:18:1:18:33 | ... = ... | +| Pathname.rb:18:1:18:33 | ... = ... | +| Pathname.rb:18:7:18:10 | pwd1 | +| Pathname.rb:18:7:18:33 | call to sub | +| Pathname.rb:19:1:19:29 | ... = ... | +| Pathname.rb:19:7:19:14 | foo_path | +| Pathname.rb:19:7:19:29 | call to sub_ext | +| Pathname.rb:20:1:20:22 | ... = ... | +| Pathname.rb:20:7:20:14 | foo_path | +| Pathname.rb:20:7:20:22 | call to to_path | +| Pathname.rb:23:14:23:21 | foo_path | +| Pathname.rb:26:12:26:19 | foo_path | +| Pathname.rb:28:11:28:14 | pwd1 | +| Pathname.rb:32:12:32:19 | foo_path | +| Pathname.rb:35:1:35:8 | foo_path | +| Pathname.rb:38:1:38:8 | foo_path | +| Pathname.rb:39:12:39:19 | foo_path | +| Pathname.rb:41:1:41:3 | p08 | +| Pathname.rb:42:1:42:3 | p01 | +fileSystemAccesses +| Pathname.rb:26:12:26:24 | call to open | Pathname.rb:26:12:26:19 | foo_path | +| Pathname.rb:28:11:28:22 | call to opendir | Pathname.rb:28:11:28:14 | pwd1 | +| Pathname.rb:32:12:32:24 | call to read | Pathname.rb:32:12:32:19 | foo_path | +| Pathname.rb:35:1:35:23 | call to write | Pathname.rb:35:1:35:8 | foo_path | +| Pathname.rb:39:12:39:34 | call to open | Pathname.rb:39:12:39:19 | foo_path | +fileNameSources +| Pathname.rb:2:1:2:33 | ... = ... | +| Pathname.rb:2:1:2:33 | ... = ... | +| Pathname.rb:2:12:2:33 | call to new | +| Pathname.rb:3:1:3:20 | ... = ... | +| Pathname.rb:3:13:3:20 | foo_path | +| Pathname.rb:4:1:4:8 | foo_path | +| Pathname.rb:6:1:6:29 | ... = ... | +| Pathname.rb:6:1:6:29 | ... = ... | +| Pathname.rb:6:12:6:29 | call to new | +| Pathname.rb:9:1:9:21 | ... = ... | +| Pathname.rb:9:1:9:21 | ... = ... | +| Pathname.rb:9:8:9:21 | call to getwd | +| Pathname.rb:10:1:10:21 | ... = ... | +| Pathname.rb:10:7:10:10 | pwd1 | +| Pathname.rb:10:7:10:21 | ... + ... | +| Pathname.rb:10:14:10:21 | foo_path | +| Pathname.rb:11:1:11:21 | ... = ... | +| Pathname.rb:11:1:11:21 | ... = ... | +| Pathname.rb:11:7:11:10 | pwd1 | +| Pathname.rb:11:7:11:21 | ... / ... | +| Pathname.rb:11:14:11:21 | bar_path | +| Pathname.rb:12:1:12:19 | ... = ... | +| Pathname.rb:12:7:12:10 | pwd1 | +| Pathname.rb:12:7:12:19 | call to basename | +| Pathname.rb:13:1:13:46 | ... = ... | +| Pathname.rb:13:7:13:36 | call to new | +| Pathname.rb:13:7:13:46 | call to cleanpath | +| Pathname.rb:14:1:14:26 | ... = ... | +| Pathname.rb:14:7:14:14 | foo_path | +| Pathname.rb:14:7:14:26 | call to expand_path | +| Pathname.rb:15:1:15:39 | ... = ... | +| Pathname.rb:15:7:15:10 | pwd1 | +| Pathname.rb:15:7:15:39 | call to join | +| Pathname.rb:16:1:16:23 | ... = ... | +| Pathname.rb:16:7:16:14 | foo_path | +| Pathname.rb:16:7:16:23 | call to realpath | +| Pathname.rb:17:1:17:59 | ... = ... | +| Pathname.rb:17:7:17:33 | call to new | +| Pathname.rb:17:7:17:59 | call to relative_path_from | +| Pathname.rb:18:1:18:33 | ... = ... | +| Pathname.rb:18:1:18:33 | ... = ... | +| Pathname.rb:18:7:18:10 | pwd1 | +| Pathname.rb:18:7:18:33 | call to sub | +| Pathname.rb:19:1:19:29 | ... = ... | +| Pathname.rb:19:7:19:14 | foo_path | +| Pathname.rb:19:7:19:29 | call to sub_ext | +| Pathname.rb:20:1:20:22 | ... = ... | +| Pathname.rb:20:7:20:14 | foo_path | +| Pathname.rb:20:7:20:22 | call to to_path | +| Pathname.rb:23:14:23:21 | foo_path | +| Pathname.rb:23:14:23:26 | call to to_s | +| Pathname.rb:26:12:26:19 | foo_path | +| Pathname.rb:28:11:28:14 | pwd1 | +| Pathname.rb:32:12:32:19 | foo_path | +| Pathname.rb:35:1:35:8 | foo_path | +| Pathname.rb:38:1:38:8 | foo_path | +| Pathname.rb:39:12:39:19 | foo_path | +| Pathname.rb:41:1:41:3 | p08 | +| Pathname.rb:42:1:42:3 | p01 | +fileSystemReadAccesses +| Pathname.rb:32:12:32:24 | call to read | Pathname.rb:32:12:32:24 | call to read | +fileSystemWriteAccesses +| Pathname.rb:35:1:35:23 | call to write | Pathname.rb:35:16:35:23 | "output" | +fileSystemPermissionModifications +| Pathname.rb:38:1:38:19 | call to chmod | Pathname.rb:38:16:38:19 | 0644 | +| Pathname.rb:39:12:39:34 | call to open | Pathname.rb:39:31:39:34 | 0666 | +| Pathname.rb:41:1:41:14 | call to mkdir | Pathname.rb:41:11:41:14 | 0755 | +| Pathname.rb:42:1:42:22 | call to mkpath | Pathname.rb:42:18:42:21 | 0644 | diff --git a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.ql b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.ql new file mode 100644 index 00000000000..d624cff3aa3 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.ql @@ -0,0 +1,26 @@ +private import ruby +private import codeql.ruby.Concepts +private import codeql.ruby.DataFlow +private import codeql.ruby.frameworks.core.Pathname + +query predicate pathnameInstances(Pathname::PathnameInstance i) { any() } + +query predicate fileSystemAccesses(FileSystemAccess a, DataFlow::Node p) { + p = a.getAPathArgument() +} + +query predicate fileNameSources(FileNameSource s) { any() } + +query predicate fileSystemReadAccesses(FileSystemReadAccess a, DataFlow::Node d) { + d = a.getADataNode() +} + +query predicate fileSystemWriteAccesses(FileSystemWriteAccess a, DataFlow::Node d) { + d = a.getADataNode() +} + +query predicate fileSystemPermissionModifications( + FileSystemPermissionModification m, DataFlow::Node p +) { + p = m.getAPermissionNode() +} diff --git a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.rb b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.rb new file mode 100644 index 00000000000..ea8f9812281 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.rb @@ -0,0 +1,42 @@ + +foo_path = Pathname.new "foo.txt" +foo_path2 = foo_path +foo_path + +bar_path = Pathname.new 'bar' + +# All these calls return new `Pathname` instances +pwd1 = Pathname.getwd +p00 = pwd1 + foo_path +p01 = pwd1 / bar_path +p02 = pwd1.basename +p03 = Pathname.new('bar/../baz.txt').cleanpath +p04 = foo_path.expand_path +p05 = pwd1.join 'bar', 'baz', 'qux.txt' +p06 = foo_path.realpath +p07 = Pathname.new('foo/bar.txt').relative_path_from('foo') +p08 = pwd1.sub 'wibble', 'wobble' +p09 = foo_path.sub_ext '.log' +p10 = foo_path.to_path + +# `Pathname#to_s` returns a string that we consider to be a filename source. +foo_string = foo_path.to_s + +# File-system accesses +foo_file = foo_path.open +foo_file.close +pwd_dir = pwd1.opendir +pwd_dir.close + +# Read from a file +foo_data = foo_path.read + +# Write to a file +foo_path.write 'output' + +# Permission modifications +foo_path.chmod 0644 +foo_file = foo_path.open 'w', 0666 +foo_file.close +p08.mkdir 0755 +p01.mkpath(mode: 0644) From ff9a7244c25cd334313d726c1f2b4e2f41025313 Mon Sep 17 00:00:00 2001 From: Brandon Stewart <20469703+boveus@users.noreply.github.com> Date: Fri, 24 Jun 2022 15:28:09 -0400 Subject: [PATCH 100/465] Update ActiveRecord.qll --- ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index 3742157a56f..59bd2c699de 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -336,7 +336,7 @@ class ActiveRecordInstanceMethodCall extends DataFlow::CallNode { private ActiveRecordInstance instance; ActiveRecordInstanceMethodCall() { this.getReceiver() = instance } - + /** Gets the `ActiveRecordInstance` that this is the receiver of this call. */ ActiveRecordInstance getInstance() { result = instance } } From 463c096d4cb3714caaf72088519d0a6e6ff744d3 Mon Sep 17 00:00:00 2001 From: Brandon Stewart <20469703+boveus@users.noreply.github.com> Date: Fri, 24 Jun 2022 15:33:02 -0400 Subject: [PATCH 101/465] Update ActiveRecord.qll --- ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index 59bd2c699de..4f25ae20030 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -330,13 +330,14 @@ class ActiveRecordInstance extends DataFlow::Node { ActiveRecordModelClass getClass() { result = instantiation.getClass() } } -// A call whose receiver may be an active record model object -/** The `ActiveRecordInstance` receiver of this call. */ +/** + * The `ActiveRecordInstance` receiver of this call. + */ class ActiveRecordInstanceMethodCall extends DataFlow::CallNode { private ActiveRecordInstance instance; ActiveRecordInstanceMethodCall() { this.getReceiver() = instance } - /** Gets the `ActiveRecordInstance` that this is the receiver of this call. */ + // Gets the `ActiveRecordInstance` that this is the receiver of this call. */ ActiveRecordInstance getInstance() { result = instance } } From 29e73e1a046a16d414c1a6a80e416257985a7c9c Mon Sep 17 00:00:00 2001 From: Brandon Stewart <20469703+boveus@users.noreply.github.com> Date: Fri, 24 Jun 2022 15:35:36 -0400 Subject: [PATCH 102/465] Update ActiveRecord.qll --- ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index 4f25ae20030..ba42a92d626 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -330,14 +330,12 @@ class ActiveRecordInstance extends DataFlow::Node { ActiveRecordModelClass getClass() { result = instantiation.getClass() } } -/** - * The `ActiveRecordInstance` receiver of this call. - */ +/** The `ActiveRecordInstance` receiver of this call. */ class ActiveRecordInstanceMethodCall extends DataFlow::CallNode { private ActiveRecordInstance instance; ActiveRecordInstanceMethodCall() { this.getReceiver() = instance } - // Gets the `ActiveRecordInstance` that this is the receiver of this call. */ + /** Gets the `ActiveRecordInstance` that this is the receiver of this call. */ ActiveRecordInstance getInstance() { result = instance } } From 9e4116618ae79337cb9ee3fc6c3157028c551c93 Mon Sep 17 00:00:00 2001 From: Asger F Date: Sat, 18 Jun 2022 19:51:21 +0200 Subject: [PATCH 103/465] JS: Add CaseSensitiveMiddlewarePath query --- .../ql/lib/semmle/javascript/Routing.qll | 12 ++ .../semmle/javascript/frameworks/Express.qll | 23 ++++ .../CWE-178/CaseSensitiveMiddlewarePath.ql | 112 ++++++++++++++++++ .../CaseSensitiveMiddlewarePath.expected | 3 + .../CWE-178/CaseSensitiveMiddlewarePath.qlref | 1 + .../test/query-tests/Security/CWE-178/tst.js | 61 ++++++++++ 6 files changed, 212 insertions(+) create mode 100644 javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql create mode 100644 javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected create mode 100644 javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.qlref create mode 100644 javascript/ql/test/query-tests/Security/CWE-178/tst.js diff --git a/javascript/ql/lib/semmle/javascript/Routing.qll b/javascript/ql/lib/semmle/javascript/Routing.qll index 858ec1ad238..46fdabba6dc 100644 --- a/javascript/ql/lib/semmle/javascript/Routing.qll +++ b/javascript/ql/lib/semmle/javascript/Routing.qll @@ -148,6 +148,18 @@ module Routing { this instanceof MkRouter } + /** + * Like `mayResumeDispatch` but without the assumption that functions with an unknown + * implementation invoke their continuation. + */ + predicate definitelyResumesDispatch() { + this.getLastChild().definitelyResumesDispatch() + or + exists(this.(RouteHandler).getAContinuationInvocation()) + or + this instanceof MkRouter + } + /** Gets the parent of this node, provided that this node may invoke its continuation. */ private Node getContinuationParent() { result = this.getParent() and diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll index ca9a151e3c6..5a2ad7cc928 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll @@ -33,6 +33,11 @@ module Express { or // `app = [new] express.Router()` result = DataFlow::moduleMember("express", "Router").getAnInvocation() + or + exists(DataFlow::SourceNode app | + app.hasUnderlyingType("probot/lib/application", "Application") and + result = app.getAMethodCall("route") + ) } /** @@ -1043,4 +1048,22 @@ module Express { override DataFlow::SourceNode getOutput() { result = this.getCallback(2).getParameter(1) } } + + private class ResumeDispatchRefinement extends Routing::RouteHandler { + ResumeDispatchRefinement() { getFunction() instanceof RouteHandler } + + override predicate mayResumeDispatch() { getAParameter().getName() = "next" } + + override predicate definitelyResumesDispatch() { getAParameter().getName() = "next" } + } + + private class ExpressStaticResumeDispatchRefinement extends Routing::Node { + ExpressStaticResumeDispatchRefinement() { + this = Routing::getNode(DataFlow::moduleMember("express", "static").getACall()) + } + + override predicate mayResumeDispatch() { none() } + + override predicate definitelyResumesDispatch() { none() } + } } diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql new file mode 100644 index 00000000000..50c5894037e --- /dev/null +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql @@ -0,0 +1,112 @@ +/** + * @name Case-sensitive middleware path + * @description Middleware with case-sensitive paths do not protect endpoints with case-insensitive paths + * @kind problem + * @problem.severity warning + * @security-severity 7.3 + * @precision high + * @id js/case-sensitive-middleware-path + * @tags security + * external/cwe/cwe-178 + */ + +import javascript + +/** + * Converts `s` to upper case, or to lower-case if it was already upper case. + */ +bindingset[s] +string invertCase(string s) { + if s.regexpMatch(".*[a-z].*") then result = s.toUpperCase() else result = s.toLowerCase() +} + +/** + * Holds if `term` distinguishes between upper and lower case letters, assuming the `i` flag is not present. + */ +pragma[inline] +predicate isCaseSensitiveRegExp(RegExpTerm term) { + exists(RegExpConstant const | + const = term.getAChild*() and + const.getValue().regexpMatch(".*[a-zA-Z].*") and + not const.getParent().(RegExpCharacterClass).getAChild().(RegExpConstant).getValue() = + invertCase(const.getValue()) and + not const.getParent*() instanceof RegExpNegativeLookahead and + not const.getParent*() instanceof RegExpNegativeLookbehind + ) +} + +/** + * Gets a string matched by `term`, or part of such a string. + */ +string getExampleString(RegExpTerm term) { + result = term.getAMatchedString() + or + // getAMatchedString does not recurse into sequences. Perform one step manually. + exists(RegExpSequence seq | seq = term | + result = + strictconcat(RegExpTerm child, int i, string text | + child = seq.getChild(i) and + ( + text = child.getAMatchedString() + or + not exists(child.getAMatchedString()) and + text = "" + ) + | + text order by i + ) + ) +} + +string getCaseSensitiveBypassExample(RegExpTerm term) { + result = invertCase(getExampleString(term)) and + result != "" +} + +/** + * Holds if `setup` has a path-argument `arg` referring to the given case-sensitive `regexp`. + */ +predicate isCaseSensitiveMiddleware( + Routing::RouteSetup setup, DataFlow::RegExpCreationNode regexp, DataFlow::Node arg +) { + exists(DataFlow::MethodCallNode call | + setup = Routing::getRouteSetupNode(call) and + ( + setup.definitelyResumesDispatch() + or + // If applied to all HTTP methods, be a bit more lenient in detecting middleware + setup.mayResumeDispatch() and + not exists(setup.getOwnHttpMethod()) + ) and + arg = call.getArgument(0) and + regexp.getAReference().flowsTo(arg) and + isCaseSensitiveRegExp(regexp.getRoot()) and + exists(string flags | + flags = regexp.getFlags() and + not flags.matches("%i%") + ) + ) +} + +predicate isGuardedCaseInsensitiveEndpoint( + Routing::RouteSetup endpoint, Routing::RouteSetup middleware +) { + isCaseSensitiveMiddleware(middleware, _, _) and + exists(DataFlow::MethodCallNode call | + endpoint = Routing::getRouteSetupNode(call) and + endpoint.isGuardedByNode(middleware) and + call.getArgument(0).mayHaveStringValue(_) + ) +} + +from + DataFlow::RegExpCreationNode regexp, Routing::RouteSetup middleware, Routing::RouteSetup endpoint, + DataFlow::Node arg, string example +where + isCaseSensitiveMiddleware(middleware, regexp, arg) and + example = getCaseSensitiveBypassExample(regexp.getRoot()) and + isGuardedCaseInsensitiveEndpoint(endpoint, middleware) and + exists(endpoint.getRelativePath().toLowerCase().indexOf(example.toLowerCase())) +select arg, + "This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '" + + example + "' will bypass the middleware.", regexp, "pattern", endpoint, "here" diff --git a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected new file mode 100644 index 00000000000..a79b3100a80 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.expected @@ -0,0 +1,3 @@ +| tst.js:8:9:8:19 | /\\/foo\\/.*/ | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/FOO/' will bypass the middleware. | tst.js:8:9:8:19 | /\\/foo\\/.*/ | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | here | +| tst.js:14:5:14:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/FOO' will bypass the middleware. | tst.js:14:5:14:28 | new Reg ... (.*)?') | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | here | +| tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | This route uses a case-sensitive path $@, but is guarding a case-insensitive path $@. A path such as '/FOO/' will bypass the middleware. | tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | here | diff --git a/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.qlref b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.qlref new file mode 100644 index 00000000000..75705303770 --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-178/CaseSensitiveMiddlewarePath.qlref @@ -0,0 +1 @@ +Security/CWE-178/CaseSensitiveMiddlewarePath.ql diff --git a/javascript/ql/test/query-tests/Security/CWE-178/tst.js b/javascript/ql/test/query-tests/Security/CWE-178/tst.js new file mode 100644 index 00000000000..1acb57b16ea --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-178/tst.js @@ -0,0 +1,61 @@ +const express = require('express'); +const app = express(); +const unknown = require('~something/blah'); + +app.all(/\/.*/, unknown()); // OK - does not contain letters +app.all(/\/.*/i, unknown()); // OK + +app.all(/\/foo\/.*/, unknown()); // NOT OK +app.all(/\/foo\/.*/i, unknown()); // OK - case insensitive + +app.use(/\/x\/#\d{6}/, express.static('images/')); // OK - not a middleware + +app.get( + new RegExp('^/foo(.*)?'), // NOT OK - case sensitive + unknown(), + function(req, res, next) { + if (req.params.blah) { + next(); + } + } +); + +app.get( + new RegExp('^/foo(.*)?', 'i'), // OK - case insensitive + unknown(), + function(req, res, next) { + if (req.params.blah) { + next(); + } + } +); + +app.get( + new RegExp('^/foo(.*)?'), // OK - not a middleware + unknown(), + function(req,res) { + res.send('Hello World!'); + } +); + +app.use(/\/foo\/([0-9]+)/, (req, res, next) => { // NOT OK - case sensitive + unknown(req); + next(); +}); + +app.use(/\/foo\/([0-9]+)/i, (req, res, next) => { // OK - case insensitive + unknown(req); + next(); +}); + + +app.use(/\/foo\/([0-9]+)/, (req, res) => { // OK - not middleware + unknown(req, res); +}); + +app.use(/\/foo\/([0-9]+)/i, (req, res) => { // OK - not middleware (also case insensitive) + unknown(req, res); +}); + +app.get('/foo/:param', (req, res) => { // OK - not a middleware +}); From d92430b0e79b60cc1047a4a0e84d3aa889b09eb0 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 24 Jun 2022 12:01:36 +0200 Subject: [PATCH 104/465] JS: Fix FP from char class --- .../CWE-178/CaseSensitiveMiddlewarePath.ql | 17 +++++++++++++---- .../query-tests/Security/CWE-178/charclass.js | 9 +++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 javascript/ql/test/query-tests/Security/CWE-178/charclass.js diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql index 50c5894037e..8aca0553c00 100644 --- a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql @@ -20,6 +20,12 @@ string invertCase(string s) { if s.regexpMatch(".*[a-z].*") then result = s.toUpperCase() else result = s.toLowerCase() } +RegExpCharacterClass getEnclosingClass(RegExpTerm term) { + term = result.getAChild() + or + term = result.getAChild().(RegExpRange).getAChild() +} + /** * Holds if `term` distinguishes between upper and lower case letters, assuming the `i` flag is not present. */ @@ -28,7 +34,7 @@ predicate isCaseSensitiveRegExp(RegExpTerm term) { exists(RegExpConstant const | const = term.getAChild*() and const.getValue().regexpMatch(".*[a-zA-Z].*") and - not const.getParent().(RegExpCharacterClass).getAChild().(RegExpConstant).getValue() = + not getEnclosingClass(const).getAChild().(RegExpConstant).getValue() = invertCase(const.getValue()) and not const.getParent*() instanceof RegExpNegativeLookahead and not const.getParent*() instanceof RegExpNegativeLookbehind @@ -59,8 +65,11 @@ string getExampleString(RegExpTerm term) { } string getCaseSensitiveBypassExample(RegExpTerm term) { - result = invertCase(getExampleString(term)) and - result != "" + exists(string example | + example = getExampleString(term) and + result = invertCase(example) and + result != example // getting an example string is approximate; ensure we got a proper case-change example + ) } /** @@ -83,7 +92,7 @@ predicate isCaseSensitiveMiddleware( isCaseSensitiveRegExp(regexp.getRoot()) and exists(string flags | flags = regexp.getFlags() and - not flags.matches("%i%") + not RegExp::isIgnoreCase(flags) ) ) } diff --git a/javascript/ql/test/query-tests/Security/CWE-178/charclass.js b/javascript/ql/test/query-tests/Security/CWE-178/charclass.js new file mode 100644 index 00000000000..f10e0a2d7ab --- /dev/null +++ b/javascript/ql/test/query-tests/Security/CWE-178/charclass.js @@ -0,0 +1,9 @@ +const express = require('express'); +const app = express(); + +app.get(/\/[a-zA-Z]+/, (req, res, next) => { // OK - regexp term is case insensitive + next(); +}); + +app.get('/foo', (req, res) => { +}); From 051b86523092604d661e13ae6da60b25fbc790c4 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Fri, 24 Jun 2022 15:04:08 +0200 Subject: [PATCH 105/465] Ruby: update tree-sitter-ruby --- ruby/Cargo.lock | Bin 15139 -> 15139 bytes ruby/extractor/Cargo.toml | 2 +- ruby/generator/Cargo.toml | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/Cargo.lock b/ruby/Cargo.lock index 3ea76573fa4658c2a03a14b1cab73b03e9c0976a..1be66824a3e4184f0dabbebc3fec55848f3da549 100644 GIT binary patch delta 102 zcmZ2nwzzDAw^^WRlCgnlvT<^Xu~ABrp@E5|NpfmRijldAaZ0LLQc|k1QJP_*skyN- Uu?iv9U>tSz?lLih)U@shPP^N}`#iX^L@@p{Z$dqOq}op{b!^nnj8- Uu?i Date: Mon, 27 Jun 2022 13:53:44 +0200 Subject: [PATCH 106/465] sanitize non-strings from unsafe-html-construction --- .../javascript/dataflow/TaintTracking.qll | 15 +++++++++++++++ .../UnsafeHtmlConstructionCustomizations.qll | 14 ++++++++++++++ .../security/dataflow/XssThroughDomQuery.qll | 19 ++----------------- .../UnsafeHtmlConstruction.expected | 9 +++++++++ .../CWE-079/UnsafeHtmlConstruction/main.js | 10 ++++++++++ 5 files changed, 50 insertions(+), 17 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 0f82ec2e8e6..3e930b652d6 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -1126,6 +1126,21 @@ module TaintTracking { ) } + /** + * Holds if `test` is of the form `typeof x === "something"`, preventing `x` from being a string in some cases. + */ + predicate isStringTypeGuard(EqualityTest test, Expr operand, boolean polarity) { + exists(TypeofTag tag | TaintTracking::isTypeofGuard(test, operand, tag) | + // typeof x === "string" sanitizes `x` when it evaluates to false + tag = "string" and + polarity = test.getPolarity().booleanNot() + or + // typeof x === "object" sanitizes `x` when it evaluates to true + tag != "string" and + polarity = test.getPolarity() + ) + } + /** Holds if `guard` is a test that checks if `operand` is a number. */ predicate isNumberGuard(DataFlow::Node guard, Expr operand, boolean polarity) { exists(DataFlow::CallNode isNaN | diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll index 6ee16daa78f..ffb731aface 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll @@ -180,4 +180,18 @@ module UnsafeHtmlConstruction { override string describe() { result = "Markdown rendering" } } + + /** A test of form `typeof x === "something"`, preventing `x` from being a string in some cases. */ + class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode { + override EqualityTest astNode; + Expr operand; + boolean polarity; + + TypeTestGuard() { TaintTracking::isStringTypeGuard(astNode, operand, polarity) } + + override predicate sanitizes(boolean outcome, Expr e) { + polarity = outcome and + e = operand + } + } } diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll index 767bd66f61c..5863a0db92f 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll @@ -4,7 +4,6 @@ */ import javascript -private import semmle.javascript.dataflow.InferredTypes private import XssThroughDomCustomizations::XssThroughDom private import semmle.javascript.security.dataflow.DomBasedXssCustomizations private import semmle.javascript.security.dataflow.UnsafeJQueryPluginCustomizations::UnsafeJQueryPlugin as UnsafeJQuery @@ -52,27 +51,13 @@ class Configuration extends TaintTracking::Configuration { } } -/** - * A test of form `typeof x === "something"`, preventing `x` from being a string in some cases. - * - * This sanitizer helps prune infeasible paths in type-overloaded functions. - */ +/** A test of form `typeof x === "something"`, preventing `x` from being a string in some cases. */ class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode { override EqualityTest astNode; Expr operand; boolean polarity; - TypeTestGuard() { - exists(TypeofTag tag | TaintTracking::isTypeofGuard(astNode, operand, tag) | - // typeof x === "string" sanitizes `x` when it evaluates to false - tag = "string" and - polarity = astNode.getPolarity().booleanNot() - or - // typeof x === "object" sanitizes `x` when it evaluates to true - tag != "string" and - polarity = astNode.getPolarity() - ) - } + TypeTestGuard() { TaintTracking::isStringTypeGuard(astNode, operand, polarity) } override predicate sanitizes(boolean outcome, Expr e) { polarity = outcome and diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected index 713db4aa08b..c604f4ab2d2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected @@ -46,6 +46,10 @@ nodes | main.js:66:35:66:41 | attrVal | | main.js:67:63:67:69 | attrVal | | main.js:67:63:67:69 | attrVal | +| main.js:79:34:79:36 | val | +| main.js:79:34:79:36 | val | +| main.js:81:35:81:37 | val | +| main.js:81:35:81:37 | val | | typed.ts:1:39:1:39 | s | | typed.ts:1:39:1:39 | s | | typed.ts:2:29:2:29 | s | @@ -107,6 +111,10 @@ edges | main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | | main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | | main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | +| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | +| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | +| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | +| main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | @@ -132,5 +140,6 @@ edges | main.js:47:65:47:73 | this.step | main.js:52:41:52:41 | s | main.js:47:65:47:73 | this.step | $@ based on $@ might later cause $@. | main.js:47:65:47:73 | this.step | HTML construction | main.js:52:41:52:41 | s | library input | main.js:47:54:47:85 | " ... /span>" | cross-site scripting | | main.js:62:19:62:31 | settings.name | main.js:56:28:56:34 | options | main.js:62:19:62:31 | settings.name | $@ based on $@ might later cause $@. | main.js:62:19:62:31 | settings.name | HTML construction | main.js:56:28:56:34 | options | library input | main.js:62:11:62:40 | "" + ... "" | cross-site scripting | | main.js:67:63:67:69 | attrVal | main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | $@ based on $@ might later cause $@. | main.js:67:63:67:69 | attrVal | HTML construction | main.js:66:35:66:41 | attrVal | library input | main.js:67:47:67:78 | "" | cross-site scripting | +| main.js:81:35:81:37 | val | main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | $@ based on $@ might later cause $@. | main.js:81:35:81:37 | val | HTML construction | main.js:79:34:79:36 | val | library input | main.js:81:24:81:49 | " ... /span>" | cross-site scripting | | typed.ts:2:29:2:29 | s | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | $@ based on $@ might later cause $@. | typed.ts:2:29:2:29 | s | HTML construction | typed.ts:1:39:1:39 | s | library input | typed.ts:3:31:3:34 | html | cross-site scripting | | typed.ts:8:40:8:40 | s | typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s | $@ based on $@ might later cause $@. | typed.ts:8:40:8:40 | s | HTML construction | typed.ts:6:43:6:43 | s | library input | typed.ts:8:29:8:52 | " ... /span>" | cross-site scripting | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/main.js b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/main.js index 1097e126feb..1547ae86b24 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/main.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/main.js @@ -75,3 +75,13 @@ module.exports.intentionalTemplate = function (obj) { const html = "" + obj.spanTemplate + ""; // OK document.querySelector("#template").innerHTML = html; } + +module.exports.types = function (val) { + if (typeof val === "string") { + $("#foo").html("" + val + ""); // NOT OK + } else if (typeof val === "number") { + $("#foo").html("" + val + ""); // OK + } else if (typeof val === "boolean") { + $("#foo").html("" + val + ""); // OK + } +} From 52290fd4aee9b7d370c6427032dc9cde22134269 Mon Sep 17 00:00:00 2001 From: Brandon Stewart <20469703+boveus@users.noreply.github.com> Date: Mon, 27 Jun 2022 10:01:40 -0400 Subject: [PATCH 107/465] run codeql query format --- ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index ba42a92d626..bc8a78349c3 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -335,6 +335,7 @@ class ActiveRecordInstanceMethodCall extends DataFlow::CallNode { private ActiveRecordInstance instance; ActiveRecordInstanceMethodCall() { this.getReceiver() = instance } + /** Gets the `ActiveRecordInstance` that this is the receiver of this call. */ ActiveRecordInstance getInstance() { result = instance } } From 17d139c87dd9d0aae3db23062ab3febb60fcc75c Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 27 Jun 2022 16:14:30 +0200 Subject: [PATCH 108/465] JS: Add qhelp --- .../CWE-178/CaseSensitiveMiddlewarePath.qhelp | 43 +++++++++++++++++++ .../examples/CaseSensitiveMiddlewarePath.js | 13 ++++++ .../CaseSensitiveMiddlewarePathGood.js | 13 ++++++ 3 files changed, 69 insertions(+) create mode 100644 javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp create mode 100644 javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePath.js create mode 100644 javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePathGood.js diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp new file mode 100644 index 00000000000..bc91fcf9be0 --- /dev/null +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp @@ -0,0 +1,43 @@ + + + + +

+Using a case-sensitive regular expression path in a middleware route enables an attacker to bypass that middleware +when accessing an endpoint with a case-insensitive path. +

+
+ + +

+When using a regular expression as a middlware path, make sure the regular expression is +case insensitive by adding the i flag. +

+
+ + +

+The following example restricts access to paths in the /admin path to users logged in as +an administrator: +

+ +

+A path such as /admin/users/45 can only be accessed by an administrator. However, the path +/ADMIN/USERS/45 can be accessed by anyone because the upper-case path doesn't match the case-sensitive regular expression, whereas +Express considers it to match the path string /admin/users. +

+

+The issue can be fixed by adding the i flag to the regular expression: +

+ +
+ + +
  • +MDN +Regular Expression Flags. +
  • +
    +
    diff --git a/javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePath.js b/javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePath.js new file mode 100644 index 00000000000..3ae6e071bdd --- /dev/null +++ b/javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePath.js @@ -0,0 +1,13 @@ +const app = require('express')(); + +app.use(/\/admin\/.*/, (req, res, next) => { + if (!req.user.isAdmin) { + res.status(401).send('Unauthorized'); + } else { + next(); + } +}); + +app.get('/admin/users/:id', (req, res) => { + res.send(app.database.users[req.params.id]); +}); diff --git a/javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePathGood.js b/javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePathGood.js new file mode 100644 index 00000000000..1c803bf795d --- /dev/null +++ b/javascript/ql/src/Security/CWE-178/examples/CaseSensitiveMiddlewarePathGood.js @@ -0,0 +1,13 @@ +const app = require('express')(); + +app.use(/\/admin\/.*/i, (req, res, next) => { + if (!req.user.isAdmin) { + res.status(401).send('Unauthorized'); + } else { + next(); + } +}); + +app.get('/admin/users/:id', (req, res) => { + res.send(app.database.users[req.params.id]); +}); From 3c9e7434957b64da523f6b63e1e38e43c9db26ab Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 27 Jun 2022 16:16:38 +0200 Subject: [PATCH 109/465] JS: Add change note --- .../change-notes/2022-06-27-case-sensitive-middleware.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 javascript/ql/src/change-notes/2022-06-27-case-sensitive-middleware.md diff --git a/javascript/ql/src/change-notes/2022-06-27-case-sensitive-middleware.md b/javascript/ql/src/change-notes/2022-06-27-case-sensitive-middleware.md new file mode 100644 index 00000000000..1593596e939 --- /dev/null +++ b/javascript/ql/src/change-notes/2022-06-27-case-sensitive-middleware.md @@ -0,0 +1,6 @@ +--- +category: newQuery +--- + +- A new query "case sensitive middleware path" (`js/case-sensitive-middleware-path`) has been added. + It highlights middleware routes that can be bypassed due to having a case-sensitive regular expression path. From 7f694f3b901bdfcd9e82e0048290032cd8eca0fa Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 27 Jun 2022 16:24:51 +0200 Subject: [PATCH 110/465] Swift: add EnumIsCase test --- .../expr/EnumIsCaseExpr/EnumIsCaseExpr.expected | 6 ++++++ .../expr/EnumIsCaseExpr/EnumIsCaseExpr.ql | 12 ++++++++++++ .../EnumIsCaseExpr/EnumIsCaseExpr_getType.expected | 6 ++++++ .../expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.ql | 7 +++++++ .../expr/EnumIsCaseExpr/MISSING_SOURCE.txt | 4 ---- .../expr/EnumIsCaseExpr/enum_is_case.swift | 14 ++++++++++++++ 6 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected create mode 100644 swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.ql create mode 100644 swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected create mode 100644 swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.ql delete mode 100644 swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/enum_is_case.swift diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected new file mode 100644 index 00000000000..0a4d95cbfee --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected @@ -0,0 +1,6 @@ +| enum_is_case.swift:4:1:4:17 | ... is some | getSubExpr: | enum_is_case.swift:4:1:4:17 | OptionalEvaluationExpr | getTypeRepr: | enum_is_case.swift:4:22:4:22 | SimpleIdentTypeRepr | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:5:1:5:32 | ... is some | getSubExpr: | enum_is_case.swift:5:1:5:32 | OptionalEvaluationExpr | getTypeRepr: | enum_is_case.swift:5:37:5:37 | SimpleIdentTypeRepr | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:6:1:6:1 | ... is some | getSubExpr: | enum_is_case.swift:6:1:6:1 | 42 | getTypeRepr: | enum_is_case.swift:6:7:6:10 | ...? | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:7:1:7:1 | ... is some | getSubExpr: | enum_is_case.swift:7:1:7:1 | 42 | getTypeRepr: | enum_is_case.swift:7:7:7:11 | ...? | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:9:1:9:19 | ... is some | getSubExpr: | enum_is_case.swift:9:1:9:19 | [...] | getTypeRepr: | enum_is_case.swift:9:24:9:28 | [...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:14:1:14:18 | ... is some | getSubExpr: | enum_is_case.swift:14:1:14:18 | OptionalEvaluationExpr | getTypeRepr: | enum_is_case.swift:14:23:14:23 | SimpleIdentTypeRepr | getElement: | file://:0:0:0:0 | some | diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.ql b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.ql new file mode 100644 index 00000000000..e35700dcbe0 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.ql @@ -0,0 +1,12 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from EnumIsCaseExpr x, Expr getSubExpr, TypeRepr getTypeRepr, EnumElementDecl getElement +where + toBeTested(x) and + not x.isUnknown() and + getSubExpr = x.getSubExpr() and + getTypeRepr = x.getTypeRepr() and + getElement = x.getElement() +select x, "getSubExpr:", getSubExpr, "getTypeRepr:", getTypeRepr, "getElement:", getElement diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected new file mode 100644 index 00000000000..a6c49a471c9 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected @@ -0,0 +1,6 @@ +| enum_is_case.swift:4:1:4:17 | ... is some | Bool | +| enum_is_case.swift:5:1:5:32 | ... is some | Bool | +| enum_is_case.swift:6:1:6:1 | ... is some | Bool | +| enum_is_case.swift:7:1:7:1 | ... is some | Bool | +| enum_is_case.swift:9:1:9:19 | ... is some | Bool | +| enum_is_case.swift:14:1:14:18 | ... is some | Bool | diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.ql b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.ql new file mode 100644 index 00000000000..b8d841b545c --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from EnumIsCaseExpr x +where toBeTested(x) and not x.isUnknown() +select x, x.getType() diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/enum_is_case.swift b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/enum_is_case.swift new file mode 100644 index 00000000000..63937f330bf --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/enum_is_case.swift @@ -0,0 +1,14 @@ +// EnumIsCaseExpr despite its generic nature is actually only generated when an `is` expression passes through an +// intrinsic Optional check + +Optional.some(42) is Int +Optional.some(Optional.some(42)) is Int +42 is Int? +42 is Int?? + +[Optional.some(42)] is [Int] +[42] is [Int?] + +class X {} +class Y: X {} +Optional.some(Y()) is X From 9d97fe7f307a3f8789228c2e5dc6041ab182ff1e Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 27 Jun 2022 17:22:48 +0200 Subject: [PATCH 111/465] Swift: generalize EnumIsCaseExpr test --- .../expr/EnumIsCaseExpr/EnumIsCaseExpr.expected | 6 +++++- .../EnumIsCaseExpr/EnumIsCaseExpr_getType.expected | 6 +++++- .../expr/EnumIsCaseExpr/enum_is_case.swift | 14 ++++++++++++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected index 0a4d95cbfee..cdf97ccd73a 100644 --- a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected @@ -3,4 +3,8 @@ | enum_is_case.swift:6:1:6:1 | ... is some | getSubExpr: | enum_is_case.swift:6:1:6:1 | 42 | getTypeRepr: | enum_is_case.swift:6:7:6:10 | ...? | getElement: | file://:0:0:0:0 | some | | enum_is_case.swift:7:1:7:1 | ... is some | getSubExpr: | enum_is_case.swift:7:1:7:1 | 42 | getTypeRepr: | enum_is_case.swift:7:7:7:11 | ...? | getElement: | file://:0:0:0:0 | some | | enum_is_case.swift:9:1:9:19 | ... is some | getSubExpr: | enum_is_case.swift:9:1:9:19 | [...] | getTypeRepr: | enum_is_case.swift:9:24:9:28 | [...] | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:14:1:14:18 | ... is some | getSubExpr: | enum_is_case.swift:14:1:14:18 | OptionalEvaluationExpr | getTypeRepr: | enum_is_case.swift:14:23:14:23 | SimpleIdentTypeRepr | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:20:1:20:18 | ... is some | getSubExpr: | enum_is_case.swift:20:1:20:18 | OptionalEvaluationExpr | getTypeRepr: | enum_is_case.swift:20:23:20:23 | SimpleIdentTypeRepr | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:22:1:22:5 | ... is some | getSubExpr: | enum_is_case.swift:22:1:22:5 | [...] | getTypeRepr: | enum_is_case.swift:22:10:22:12 | [...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:23:1:23:10 | ... is some | getSubExpr: | enum_is_case.swift:23:1:23:10 | [...] | getTypeRepr: | enum_is_case.swift:23:15:23:25 | [... : ...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:24:1:24:10 | ... is some | getSubExpr: | enum_is_case.swift:24:1:24:10 | [...] | getTypeRepr: | enum_is_case.swift:24:15:24:25 | [... : ...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:25:1:25:8 | ... is some | getSubExpr: | enum_is_case.swift:25:1:25:8 | call to ... | getTypeRepr: | enum_is_case.swift:25:13:25:18 | ...<...> | getElement: | file://:0:0:0:0 | some | diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected index a6c49a471c9..b3a0100a061 100644 --- a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected @@ -3,4 +3,8 @@ | enum_is_case.swift:6:1:6:1 | ... is some | Bool | | enum_is_case.swift:7:1:7:1 | ... is some | Bool | | enum_is_case.swift:9:1:9:19 | ... is some | Bool | -| enum_is_case.swift:14:1:14:18 | ... is some | Bool | +| enum_is_case.swift:20:1:20:18 | ... is some | Bool | +| enum_is_case.swift:22:1:22:5 | ... is some | Bool | +| enum_is_case.swift:23:1:23:10 | ... is some | Bool | +| enum_is_case.swift:24:1:24:10 | ... is some | Bool | +| enum_is_case.swift:25:1:25:8 | ... is some | Bool | diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/enum_is_case.swift b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/enum_is_case.swift index 63937f330bf..f33edd6c0c7 100644 --- a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/enum_is_case.swift +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/enum_is_case.swift @@ -1,5 +1,5 @@ // EnumIsCaseExpr despite its generic nature is actually only generated when an `is` expression passes through an -// intrinsic Optional check +// intrinsic Optional check, or an array, dictionary or set downcast Optional.some(42) is Int Optional.some(Optional.some(42)) is Int @@ -9,6 +9,16 @@ Optional.some(Optional.some(42)) is Int [Optional.some(42)] is [Int] [42] is [Int?] -class X {} +class X : Hashable { + static func == (lhs: X, rhs: X) -> Bool { return true } + func hash(into hasher: inout Hasher) {} +} + class Y: X {} + Optional.some(Y()) is X + +[X()] is [Y] +["x": X()] is [String: Y] +["x": X()] is [String: Y] +Set() is Set From 7430a413ad660311ae1aebc8620159b78822670a Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 27 Jun 2022 17:57:40 +0100 Subject: [PATCH 112/465] Kotlin: Mark DELEGATED_PROPERTY_ACCESSORs as compiler-generated --- .../src/main/kotlin/KotlinFileExtractor.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 29376368adc..88288b26fc6 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -881,6 +881,9 @@ open class KotlinFileExtractor( val getterId = extractFunction(getter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast() if (getterId != null) { tw.writeKtPropertyGetters(id, getterId) + if (getter.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR) { + tw.writeCompiler_generated(getterId, CompilerGeneratedKinds.DELEGATED_PROPERTY_GETTER.kind) + } } } else { if (p.modality != Modality.FINAL || !isExternalDeclaration(p)) { @@ -895,6 +898,9 @@ open class KotlinFileExtractor( val setterId = extractFunction(setter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast() if (setterId != null) { tw.writeKtPropertySetters(id, setterId) + if (setter.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR) { + tw.writeCompiler_generated(setterId, CompilerGeneratedKinds.DELEGATED_PROPERTY_SETTER.kind) + } } } else { if (p.isVar && !isExternalDeclaration(p)) { @@ -4383,6 +4389,8 @@ open class KotlinFileExtractor( GENERATED_DATA_CLASS_MEMBER(2), DEFAULT_PROPERTY_ACCESSOR(3), CLASS_INITIALISATION_METHOD(4), - ENUM_CLASS_SPECIAL_MEMBER(5) + ENUM_CLASS_SPECIAL_MEMBER(5), + DELEGATED_PROPERTY_GETTER(6), + DELEGATED_PROPERTY_SETTER(7), } } From 7dc490ff7cd3e53aed21877bab3d2e0de8413481 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 27 Jun 2022 17:59:52 +0100 Subject: [PATCH 113/465] Kotlin: Enhance methods test --- .../kotlin/library-tests/methods/delegates.kt | 12 +++ .../library-tests/methods/exprs.expected | 91 +++++++++++++++++++ .../library-tests/methods/methods.expected | 19 ++++ .../library-tests/methods/parameters.expected | 14 +++ 4 files changed, 136 insertions(+) create mode 100644 java/ql/test/kotlin/library-tests/methods/delegates.kt diff --git a/java/ql/test/kotlin/library-tests/methods/delegates.kt b/java/ql/test/kotlin/library-tests/methods/delegates.kt new file mode 100644 index 00000000000..cd475a51cec --- /dev/null +++ b/java/ql/test/kotlin/library-tests/methods/delegates.kt @@ -0,0 +1,12 @@ +import kotlin.properties.Delegates + +class MyClass { + val lazyProp by lazy { + 5 + } + + var observableProp: String by Delegates.observable("") { + prop, old, new -> + println("Was $old, now $new") + } +} diff --git a/java/ql/test/kotlin/library-tests/methods/exprs.expected b/java/ql/test/kotlin/library-tests/methods/exprs.expected index abad65d5f83..46b61a1edb9 100644 --- a/java/ql/test/kotlin/library-tests/methods/exprs.expected +++ b/java/ql/test/kotlin/library-tests/methods/exprs.expected @@ -104,6 +104,97 @@ | dataClass.kt:1:34:1:46 | this.y | VarAccess | | dataClass.kt:1:34:1:46 | y | VarAccess | | dataClass.kt:1:34:1:46 | y | VarAccess | +| delegates.kt:1:9:1:12 | this | ThisAccess | +| delegates.kt:1:9:1:12 | this | ThisAccess | +| delegates.kt:1:9:1:12 | this | ThisAccess | +| delegates.kt:4:18:6:5 | ...::... | PropertyRefExpr | +| delegates.kt:4:18:6:5 | ...=... | KtInitializerAssignExpr | +| delegates.kt:4:18:6:5 | Integer | TypeAccess | +| delegates.kt:4:18:6:5 | Integer | TypeAccess | +| delegates.kt:4:18:6:5 | KProperty1 | TypeAccess | +| delegates.kt:4:18:6:5 | Lazy | TypeAccess | +| delegates.kt:4:18:6:5 | MyClass | TypeAccess | +| delegates.kt:4:18:6:5 | a0 | VarAccess | +| delegates.kt:4:18:6:5 | a0 | VarAccess | +| delegates.kt:4:18:6:5 | get(...) | MethodAccess | +| delegates.kt:4:18:6:5 | getLazyProp(...) | MethodAccess | +| delegates.kt:4:18:6:5 | int | TypeAccess | +| delegates.kt:4:18:6:5 | lazyProp$delegate | VarAccess | +| delegates.kt:4:18:6:5 | this | ThisAccess | +| delegates.kt:4:18:6:5 | this | ThisAccess | +| delegates.kt:4:18:6:5 | this.lazyProp$delegate | VarAccess | +| delegates.kt:4:21:6:5 | Integer | TypeAccess | +| delegates.kt:4:21:6:5 | Integer | TypeAccess | +| delegates.kt:4:21:6:5 | LazyKt | TypeAccess | +| delegates.kt:4:21:6:5 | LazyKt | TypeAccess | +| delegates.kt:4:21:6:5 | getValue(...) | MethodAccess | +| delegates.kt:4:21:6:5 | lazy(...) | MethodAccess | +| delegates.kt:4:26:6:5 | ...->... | LambdaExpr | +| delegates.kt:4:26:6:5 | Function0 | TypeAccess | +| delegates.kt:4:26:6:5 | Integer | TypeAccess | +| delegates.kt:4:26:6:5 | int | TypeAccess | +| delegates.kt:5:9:5:9 | 5 | IntegerLiteral | +| delegates.kt:8:32:11:5 | ...::... | PropertyRefExpr | +| delegates.kt:8:32:11:5 | ...::... | PropertyRefExpr | +| delegates.kt:8:32:11:5 | ...=... | KtInitializerAssignExpr | +| delegates.kt:8:32:11:5 | KMutableProperty1 | TypeAccess | +| delegates.kt:8:32:11:5 | KMutableProperty1 | TypeAccess | +| delegates.kt:8:32:11:5 | MyClass | TypeAccess | +| delegates.kt:8:32:11:5 | MyClass | TypeAccess | +| delegates.kt:8:32:11:5 | Object | TypeAccess | +| delegates.kt:8:32:11:5 | ReadWriteProperty | TypeAccess | +| delegates.kt:8:32:11:5 | String | TypeAccess | +| delegates.kt:8:32:11:5 | String | TypeAccess | +| delegates.kt:8:32:11:5 | String | TypeAccess | +| delegates.kt:8:32:11:5 | String | TypeAccess | +| delegates.kt:8:32:11:5 | String | TypeAccess | +| delegates.kt:8:32:11:5 | Unit | TypeAccess | +| delegates.kt:8:32:11:5 | a0 | VarAccess | +| delegates.kt:8:32:11:5 | a0 | VarAccess | +| delegates.kt:8:32:11:5 | a0 | VarAccess | +| delegates.kt:8:32:11:5 | a0 | VarAccess | +| delegates.kt:8:32:11:5 | a0 | VarAccess | +| delegates.kt:8:32:11:5 | a0 | VarAccess | +| delegates.kt:8:32:11:5 | a1 | VarAccess | +| delegates.kt:8:32:11:5 | a1 | VarAccess | +| delegates.kt:8:32:11:5 | get(...) | MethodAccess | +| delegates.kt:8:32:11:5 | get(...) | MethodAccess | +| delegates.kt:8:32:11:5 | getObservableProp(...) | MethodAccess | +| delegates.kt:8:32:11:5 | getObservableProp(...) | MethodAccess | +| delegates.kt:8:32:11:5 | observableProp$delegate | VarAccess | +| delegates.kt:8:32:11:5 | setObservableProp(...) | MethodAccess | +| delegates.kt:8:32:11:5 | setObservableProp(...) | MethodAccess | +| delegates.kt:8:32:11:5 | this | ThisAccess | +| delegates.kt:8:32:11:5 | this | ThisAccess | +| delegates.kt:8:32:11:5 | this | ThisAccess | +| delegates.kt:8:32:11:5 | this | ThisAccess | +| delegates.kt:8:32:11:5 | this.observableProp$delegate | VarAccess | +| delegates.kt:8:32:11:5 | this.observableProp$delegate | VarAccess | +| delegates.kt:8:35:8:43 | INSTANCE | VarAccess | +| delegates.kt:8:35:11:5 | | VarAccess | +| delegates.kt:8:35:11:5 | getValue(...) | MethodAccess | +| delegates.kt:8:35:11:5 | setValue(...) | MethodAccess | +| delegates.kt:8:45:11:5 | String | TypeAccess | +| delegates.kt:8:45:11:5 | observable(...) | MethodAccess | +| delegates.kt:8:57:8:62 | | StringLiteral | +| delegates.kt:8:66:11:5 | ...->... | LambdaExpr | +| delegates.kt:8:66:11:5 | Function3,String,String,Unit> | TypeAccess | +| delegates.kt:8:66:11:5 | KProperty | TypeAccess | +| delegates.kt:8:66:11:5 | String | TypeAccess | +| delegates.kt:8:66:11:5 | String | TypeAccess | +| delegates.kt:8:66:11:5 | Unit | TypeAccess | +| delegates.kt:8:66:11:5 | Unit | TypeAccess | +| delegates.kt:9:9:9:12 | ? ... | WildcardTypeAccess | +| delegates.kt:9:9:9:12 | KProperty | TypeAccess | +| delegates.kt:9:15:9:17 | String | TypeAccess | +| delegates.kt:9:20:9:22 | String | TypeAccess | +| delegates.kt:10:9:10:37 | ConsoleKt | TypeAccess | +| delegates.kt:10:9:10:37 | println(...) | MethodAccess | +| delegates.kt:10:17:10:36 | "..." | StringTemplateExpr | +| delegates.kt:10:18:10:21 | Was | StringLiteral | +| delegates.kt:10:23:10:25 | old | VarAccess | +| delegates.kt:10:26:10:31 | , now | StringLiteral | +| delegates.kt:10:33:10:35 | new | VarAccess | | enumClass.kt:0:0:0:0 | EnumClass | TypeAccess | | enumClass.kt:0:0:0:0 | EnumClass | TypeAccess | | enumClass.kt:0:0:0:0 | EnumClass[] | TypeAccess | diff --git a/java/ql/test/kotlin/library-tests/methods/methods.expected b/java/ql/test/kotlin/library-tests/methods/methods.expected index 144e71e5d48..cd9ea6d5bc5 100644 --- a/java/ql/test/kotlin/library-tests/methods/methods.expected +++ b/java/ql/test/kotlin/library-tests/methods/methods.expected @@ -11,6 +11,19 @@ methods | dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:22:1:31 | getX | getX() | public | Compiler generated | | dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:34:1:46 | getY | getY() | public | Compiler generated | | dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:34:1:46 | setY | setY(java.lang.String) | public | Compiler generated | +| delegates.kt:3:1:12:1 | MyClass | delegates.kt:4:18:6:5 | getLazyProp | getLazyProp() | public | Compiler generated | +| delegates.kt:3:1:12:1 | MyClass | delegates.kt:8:32:11:5 | getObservableProp | getObservableProp() | public | Compiler generated | +| delegates.kt:3:1:12:1 | MyClass | delegates.kt:8:32:11:5 | setObservableProp | setObservableProp(java.lang.String) | public | Compiler generated | +| delegates.kt:4:18:6:5 | new KProperty1(...) { ... } | delegates.kt:4:18:6:5 | get | get(MyClass) | override, public | | +| delegates.kt:4:18:6:5 | new KProperty1(...) { ... } | delegates.kt:4:18:6:5 | invoke | invoke(MyClass) | override, public | | +| delegates.kt:4:26:6:5 | new Function0(...) { ... } | delegates.kt:4:26:6:5 | invoke | invoke() | override, public | | +| delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | get | get(MyClass) | override, public | | +| delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | get | get(MyClass) | override, public | | +| delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | invoke | invoke(MyClass) | override, public | | +| delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | invoke | invoke(MyClass) | override, public | | +| delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | set | set(MyClass,java.lang.String) | override, public | | +| delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | set | set(MyClass,java.lang.String) | override, public | | +| delegates.kt:8:66:11:5 | new Function3,String,String,Unit>(...) { ... } | delegates.kt:8:66:11:5 | invoke | invoke(kotlin.reflect.KProperty,java.lang.String,java.lang.String) | override, public | | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | | () | | Compiler generated | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | valueOf | valueOf(java.lang.String) | public, static | Compiler generated | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:0:0:0:0 | values | values() | public, static | Compiler generated | @@ -33,6 +46,12 @@ methods | methods.kt:5:1:19:1 | Class | methods.kt:18:5:18:36 | noExplicitVisibilityFun | noExplicitVisibilityFun() | public | | constructors | dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:6:1:47 | DataClass | DataClass(int,java.lang.String) | +| delegates.kt:3:1:12:1 | MyClass | delegates.kt:3:1:12:1 | MyClass | MyClass() | +| delegates.kt:4:18:6:5 | new KProperty1(...) { ... } | delegates.kt:4:18:6:5 | | | +| delegates.kt:4:26:6:5 | new Function0(...) { ... } | delegates.kt:4:26:6:5 | | | +| delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | | | +| delegates.kt:8:32:11:5 | new KMutableProperty1(...) { ... } | delegates.kt:8:32:11:5 | | | +| delegates.kt:8:66:11:5 | new Function3,String,String,Unit>(...) { ... } | delegates.kt:8:66:11:5 | | | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:6:4:1 | EnumClass | EnumClass(int) | | methods2.kt:7:1:10:1 | Class2 | methods2.kt:7:1:10:1 | Class2 | Class2() | | methods3.kt:5:1:7:1 | Class3 | methods3.kt:5:1:7:1 | Class3 | Class3() | diff --git a/java/ql/test/kotlin/library-tests/methods/parameters.expected b/java/ql/test/kotlin/library-tests/methods/parameters.expected index 8a1ee3fa42f..2b35e69e502 100644 --- a/java/ql/test/kotlin/library-tests/methods/parameters.expected +++ b/java/ql/test/kotlin/library-tests/methods/parameters.expected @@ -3,6 +3,20 @@ | dataClass.kt:0:0:0:0 | copy | dataClass.kt:1:34:1:46 | y | 1 | | dataClass.kt:0:0:0:0 | equals | dataClass.kt:0:0:0:0 | other | 0 | | dataClass.kt:1:34:1:46 | setY | dataClass.kt:1:34:1:46 | | 0 | +| delegates.kt:4:18:6:5 | get | delegates.kt:4:18:6:5 | a0 | 0 | +| delegates.kt:4:18:6:5 | invoke | delegates.kt:4:18:6:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | get | delegates.kt:8:32:11:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | get | delegates.kt:8:32:11:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | invoke | delegates.kt:8:32:11:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | invoke | delegates.kt:8:32:11:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | set | delegates.kt:8:32:11:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | set | delegates.kt:8:32:11:5 | a0 | 0 | +| delegates.kt:8:32:11:5 | set | delegates.kt:8:32:11:5 | a1 | 1 | +| delegates.kt:8:32:11:5 | set | delegates.kt:8:32:11:5 | a1 | 1 | +| delegates.kt:8:32:11:5 | setObservableProp | delegates.kt:8:32:11:5 | | 0 | +| delegates.kt:8:66:11:5 | invoke | delegates.kt:9:9:9:12 | prop | 0 | +| delegates.kt:8:66:11:5 | invoke | delegates.kt:9:15:9:17 | old | 1 | +| delegates.kt:8:66:11:5 | invoke | delegates.kt:9:20:9:22 | new | 2 | | enumClass.kt:0:0:0:0 | valueOf | enumClass.kt:0:0:0:0 | value | 0 | | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | methods2.kt:4:26:4:31 | x | 0 | | methods2.kt:4:1:5:1 | fooBarTopLevelMethod | methods2.kt:4:34:4:39 | y | 1 | From 4e4b34290bbe59df72b573f695fafc0e981a1901 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 27 Jun 2022 18:08:06 +0100 Subject: [PATCH 114/465] Kotlin: Make more methods private --- .../src/main/kotlin/KotlinFileExtractor.kt | 66 +++++++++---------- .../src/main/kotlin/KotlinUsesExtractor.kt | 46 ++++++------- .../src/main/kotlin/utils/ClassNames.kt | 4 +- 3 files changed, 58 insertions(+), 58 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 29376368adc..6a8185d9128 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -181,7 +181,7 @@ open class KotlinFileExtractor( } } - fun extractTypeParameter(tp: IrTypeParameter, apparentIndex: Int, javaTypeParameter: JavaTypeParameter?): Label? { + private fun extractTypeParameter(tp: IrTypeParameter, apparentIndex: Int, javaTypeParameter: JavaTypeParameter?): Label? { with("type parameter", tp) { val parentId = getTypeParameterParentLabel(tp) ?: return null val id = tw.getLabelFor(getTypeParameterLabel(tp)) @@ -216,7 +216,7 @@ open class KotlinFileExtractor( } } - fun extractVisibility(elementForLocation: IrElement, id: Label, v: DescriptorVisibility) { + private fun extractVisibility(elementForLocation: IrElement, id: Label, v: DescriptorVisibility) { with("visibility", elementForLocation) { when (v) { DescriptorVisibilities.PRIVATE -> addModifiers(id, "private") @@ -250,7 +250,7 @@ open class KotlinFileExtractor( } } - fun extractClassModifiers(c: IrClass, id: Label) { + private fun extractClassModifiers(c: IrClass, id: Label) { with("class modifiers", c) { when (c.modality) { Modality.FINAL -> addModifiers(id, "final") @@ -371,7 +371,7 @@ open class KotlinFileExtractor( tw.writeHasLocation(stmtId, locId) } - fun extractObinitFunction(c: IrClass, parentId: Label) { + private fun extractObinitFunction(c: IrClass, parentId: Label) { // add method: val obinitLabel = getObinitLabel(c) val obinitId = tw.getLabelFor(obinitLabel) @@ -506,7 +506,7 @@ open class KotlinFileExtractor( data class FieldResult(val id: Label, val name: String) - fun useCompanionObjectClassInstance(c: IrClass): FieldResult? { + private fun useCompanionObjectClassInstance(c: IrClass): FieldResult? { val parent = c.parent if(!c.isCompanion) { logger.error("Using companion instance for non-companion class") @@ -524,7 +524,7 @@ open class KotlinFileExtractor( } } - fun useObjectClassInstance(c: IrClass): FieldResult { + private fun useObjectClassInstance(c: IrClass): FieldResult { if(!c.isNonCompanionObject) { logger.error("Using instance for non-object class") } @@ -719,13 +719,13 @@ open class KotlinFileExtractor( } } - fun extractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) = + private fun extractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) = if (isFake(f)) null else forceExtractFunction(f, parentId, extractBody, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, null, null) - fun forceExtractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?, idOverride: Label?, locOverride: Label?): Label { + private fun forceExtractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?, idOverride: Label?, locOverride: Label?): Label { with("function", f) { DeclarationStackAdjuster(f).use { @@ -828,7 +828,7 @@ open class KotlinFileExtractor( && f.symbol !is IrConstructorSymbol // not a constructor } - fun extractField(f: IrField, parentId: Label): Label { + private fun extractField(f: IrField, parentId: Label): Label { with("field", f) { DeclarationStackAdjuster(f).use { declarationStack.push(f) @@ -862,7 +862,7 @@ open class KotlinFileExtractor( return id } - fun extractProperty(p: IrProperty, parentId: Label, extractBackingField: Boolean, extractFunctionBodies: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) { + private fun extractProperty(p: IrProperty, parentId: Label, extractBackingField: Boolean, extractFunctionBodies: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) { with("property", p) { if (isFake(p)) return @@ -931,7 +931,7 @@ open class KotlinFileExtractor( } } - fun extractEnumEntry(ee: IrEnumEntry, parentId: Label, extractTypeAccess: Boolean) { + private fun extractEnumEntry(ee: IrEnumEntry, parentId: Label, extractTypeAccess: Boolean) { with("enum entry", ee) { DeclarationStackAdjuster(ee).use { val id = useEnumEntry(ee) @@ -953,7 +953,7 @@ open class KotlinFileExtractor( } } - fun extractTypeAlias(ta: IrTypeAlias) { + private fun extractTypeAlias(ta: IrTypeAlias) { with("type alias", ta) { if (ta.typeParameters.isNotEmpty()) { // TODO: Extract this information @@ -968,7 +968,7 @@ open class KotlinFileExtractor( } } - fun extractBody(b: IrBody, callable: Label) { + private fun extractBody(b: IrBody, callable: Label) { with("body", b) { when (b) { is IrBlockBody -> extractBlockBody(b, callable) @@ -981,7 +981,7 @@ open class KotlinFileExtractor( } } - fun extractBlockBody(b: IrBlockBody, callable: Label) { + private fun extractBlockBody(b: IrBlockBody, callable: Label) { with("block body", b) { val id = tw.getFreshIdLabel() val locId = tw.getLocation(b) @@ -993,7 +993,7 @@ open class KotlinFileExtractor( } } - fun extractSyntheticBody(b: IrSyntheticBody, callable: Label) { + private fun extractSyntheticBody(b: IrSyntheticBody, callable: Label) { with("synthetic body", b) { when (b.kind) { IrSyntheticBodyKind.ENUM_VALUES -> tw.writeKtSyntheticBody(callable, 1) @@ -1002,7 +1002,7 @@ open class KotlinFileExtractor( } } - fun extractExpressionBody(b: IrExpressionBody, callable: Label) { + private fun extractExpressionBody(b: IrExpressionBody, callable: Label) { with("expression body", b) { val blockId = tw.getFreshIdLabel() val locId = tw.getLocation(b) @@ -1026,7 +1026,7 @@ open class KotlinFileExtractor( return v } - fun extractVariable(v: IrVariable, callable: Label, parent: Label, idx: Int) { + private fun extractVariable(v: IrVariable, callable: Label, parent: Label, idx: Int) { with("variable", v) { val stmtId = tw.getFreshIdLabel() val locId = tw.getLocation(getVariableLocationProvider(v)) @@ -1036,7 +1036,7 @@ open class KotlinFileExtractor( } } - fun extractVariableExpr(v: IrVariable, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) { + private fun extractVariableExpr(v: IrVariable, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) { with("variable expr", v) { val varId = useVariable(v) val exprId = tw.getFreshIdLabel() @@ -1060,7 +1060,7 @@ open class KotlinFileExtractor( } } - fun extractStatement(s: IrStatement, callable: Label, parent: Label, idx: Int) { + private fun extractStatement(s: IrStatement, callable: Label, parent: Label, idx: Int) { with("statement", s) { when(s) { is IrExpression -> { @@ -1399,7 +1399,7 @@ open class KotlinFileExtractor( } } - fun findFunction(cls: IrClass, name: String): IrFunction? = cls.declarations.find { it is IrFunction && it.name.asString() == name } as IrFunction? + private fun findFunction(cls: IrClass, name: String): IrFunction? = cls.declarations.find { it is IrFunction && it.name.asString() == name } as IrFunction? val jvmIntrinsicsClass by lazy { val result = pluginContext.referenceClass(FqName("kotlin.jvm.internal.Intrinsics"))?.owner @@ -1407,7 +1407,7 @@ open class KotlinFileExtractor( result } - fun findJdkIntrinsicOrWarn(name: String, warnAgainstElement: IrElement): IrFunction? { + private fun findJdkIntrinsicOrWarn(name: String, warnAgainstElement: IrElement): IrFunction? { val result = jvmIntrinsicsClass?.let { findFunction(it, name) } if(result == null) { logger.errorElement("Couldn't find JVM intrinsic function $name", warnAgainstElement) @@ -1501,7 +1501,7 @@ open class KotlinFileExtractor( result } - fun isFunction(target: IrFunction, pkgName: String, classNameLogged: String, classNamePredicate: (String) -> Boolean, fName: String, hasQuestionMark: Boolean? = false): Boolean { + private fun isFunction(target: IrFunction, pkgName: String, classNameLogged: String, classNamePredicate: (String) -> Boolean, fName: String, hasQuestionMark: Boolean? = false): Boolean { val verbose = false fun verboseln(s: String) { if(verbose) println(s) } verboseln("Attempting match for $pkgName $classNameLogged $fName") @@ -1545,10 +1545,10 @@ open class KotlinFileExtractor( return true } - fun isFunction(target: IrFunction, pkgName: String, className: String, fName: String, hasQuestionMark: Boolean? = false) = + private fun isFunction(target: IrFunction, pkgName: String, className: String, fName: String, hasQuestionMark: Boolean? = false) = isFunction(target, pkgName, className, { it == className }, fName, hasQuestionMark) - fun isNumericFunction(target: IrFunction, fName: String): Boolean { + private fun isNumericFunction(target: IrFunction, fName: String): Boolean { return isFunction(target, "kotlin", "Int", fName) || isFunction(target, "kotlin", "Byte", fName) || isFunction(target, "kotlin", "Short", fName) || @@ -1557,7 +1557,7 @@ open class KotlinFileExtractor( isFunction(target, "kotlin", "Double", fName) } - fun isArrayType(typeName: String) = + private fun isArrayType(typeName: String) = when(typeName) { "Array" -> true "IntArray" -> true @@ -1571,7 +1571,7 @@ open class KotlinFileExtractor( else -> false } - fun extractCall(c: IrCall, callable: Label, stmtExprParent: StmtExprParent) { + private fun extractCall(c: IrCall, callable: Label, stmtExprParent: StmtExprParent) { with("call", c) { val target = tryReplaceSyntheticFunction(c.symbol.owner) @@ -2250,7 +2250,7 @@ open class KotlinFileExtractor( else -> null } - fun getUpdateInPlaceRHS(origin: IrStatementOrigin?, isExpectedLhs: (IrExpression?) -> Boolean, updateRhs: IrExpression): IrExpression? { + private fun getUpdateInPlaceRHS(origin: IrStatementOrigin?, isExpectedLhs: (IrExpression?) -> Boolean, updateRhs: IrExpression): IrExpression? { // Check for a desugared in-place update operator, such as "v += e": return getStatementOriginOperator(origin)?.let { if (updateRhs is IrCall && @@ -2265,7 +2265,7 @@ open class KotlinFileExtractor( } } - fun writeUpdateInPlaceExpr(origin: IrStatementOrigin, tw: TrapWriter, id: Label, type: TypeResults, exprParent: ExprParent): Boolean { + private fun writeUpdateInPlaceExpr(origin: IrStatementOrigin, tw: TrapWriter, id: Label, type: TypeResults, exprParent: ExprParent): Boolean { when(origin) { IrStatementOrigin.PLUSEQ -> tw.writeExprs_assignaddexpr(id.cast(), type.javaResult.id, exprParent.parent, exprParent.idx) IrStatementOrigin.MINUSEQ -> tw.writeExprs_assignsubexpr(id.cast(), type.javaResult.id, exprParent.parent, exprParent.idx) @@ -2277,7 +2277,7 @@ open class KotlinFileExtractor( return true } - fun tryExtractArrayUpdate(e: IrContainerExpression, callable: Label, parent: StmtExprParent): Boolean { + private fun tryExtractArrayUpdate(e: IrContainerExpression, callable: Label, parent: StmtExprParent): Boolean { /* * We're expecting the pattern * { @@ -2348,7 +2348,7 @@ open class KotlinFileExtractor( return false } - fun extractExpressionStmt(e: IrExpression, callable: Label, parent: Label, idx: Int) { + private fun extractExpressionStmt(e: IrExpression, callable: Label, parent: Label, idx: Int) { extractExpression(e, callable, StmtParent(parent, idx)) } @@ -2356,7 +2356,7 @@ open class KotlinFileExtractor( extractExpression(e, callable, ExprParent(parent, idx, enclosingStmt)) } - fun extractExpression(e: IrExpression, callable: Label, parent: StmtExprParent) { + private fun extractExpression(e: IrExpression, callable: Label, parent: StmtExprParent) { with("expression", e) { when(e) { is IrDelegatingConstructorCall -> { @@ -3819,7 +3819,7 @@ open class KotlinFileExtractor( } } - fun extractVarargElement(e: IrVarargElement, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) { + private fun extractVarargElement(e: IrVarargElement, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) { with("vararg element", e) { val argExpr = when(e) { is IrExpression -> e @@ -4011,7 +4011,7 @@ open class KotlinFileExtractor( return initId } - fun extractTypeOperatorCall(e: IrTypeOperatorCall, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) { + private fun extractTypeOperatorCall(e: IrTypeOperatorCall, callable: Label, parent: Label, idx: Int, enclosingStmt: Label) { with("type operator call", e) { when(e.operator) { IrTypeOperator.CAST -> { diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt index 0e2202b583a..530ff47e8ab 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt @@ -49,7 +49,7 @@ open class KotlinUsesExtractor( javaLangObject?.typeWith() } - fun usePackage(pkg: String): Label { + private fun usePackage(pkg: String): Label { return extractPackage(pkg) } @@ -154,12 +154,12 @@ open class KotlinUsesExtractor( } ?: argsIncludingOuterClasses } - fun isStaticClass(c: IrClass) = c.visibility != DescriptorVisibilities.LOCAL && !c.isInner + private fun isStaticClass(c: IrClass) = c.visibility != DescriptorVisibilities.LOCAL && !c.isInner // Gets nested inner classes starting at `c` and proceeding outwards to the innermost enclosing static class. // For example, for (java syntax) `class A { static class B { class C { class D { } } } }`, // `nonStaticParentsWithSelf(D)` = `[D, C, B]`. - fun parentsWithTypeParametersInScope(c: IrClass): List { + private fun parentsWithTypeParametersInScope(c: IrClass): List { val parentsList = c.parentsWithSelf.toList() val firstOuterClassIdx = parentsList.indexOfFirst { it is IrClass && isStaticClass(it) } return if (firstOuterClassIdx == -1) parentsList else parentsList.subList(0, firstOuterClassIdx + 1) @@ -168,14 +168,14 @@ open class KotlinUsesExtractor( // Gets the type parameter symbols that are in scope for class `c` in Kotlin order (i.e. for // `class NotInScope { static class OutermostInScope { class QueryClass { } } }`, // `getTypeParametersInScope(QueryClass)` = `[C, D, A, B]`. - fun getTypeParametersInScope(c: IrClass) = + private fun getTypeParametersInScope(c: IrClass) = parentsWithTypeParametersInScope(c).mapNotNull({ getTypeParameters(it) }).flatten() // Returns a map from `c`'s type variables in scope to type arguments `argsIncludingOuterClasses`. // Hack for the time being: the substituted types are always nullable, to prevent downstream code // from replacing a generic parameter by a primitive. As and when we extract Kotlin types we will // need to track this information in more detail. - fun makeTypeGenericSubstitutionMap(c: IrClass, argsIncludingOuterClasses: List) = + private fun makeTypeGenericSubstitutionMap(c: IrClass, argsIncludingOuterClasses: List) = getTypeParametersInScope(c).map({ it.symbol }).zip(argsIncludingOuterClasses.map { it.withQuestionMark(true) }).toMap() fun makeGenericSubstitutionFunction(c: IrClass, argsIncludingOuterClasses: List) = @@ -239,13 +239,13 @@ open class KotlinUsesExtractor( private fun isArray(t: IrSimpleType) = t.isBoxedArray || t.isPrimitiveArray() - fun extractClassLaterIfExternal(c: IrClass) { + private fun extractClassLaterIfExternal(c: IrClass) { if (isExternalDeclaration(c)) { extractExternalClassLater(c) } } - fun extractExternalEnclosingClassLater(d: IrDeclaration) { + private fun extractExternalEnclosingClassLater(d: IrDeclaration) { when (val parent = d.parent) { is IrClass -> extractExternalClassLater(parent) is IrFunction -> extractExternalEnclosingClassLater(parent) @@ -254,7 +254,7 @@ open class KotlinUsesExtractor( } } - fun extractPropertyLaterIfExternalFileMember(p: IrProperty) { + private fun extractPropertyLaterIfExternalFileMember(p: IrProperty) { if (isExternalFileClassMember(p)) { extractExternalClassLater(p.parentAsClass) dependencyCollector?.addDependency(p, externalClassExtractor.propertySignature) @@ -262,7 +262,7 @@ open class KotlinUsesExtractor( } } - fun extractFieldLaterIfExternalFileMember(f: IrField) { + private fun extractFieldLaterIfExternalFileMember(f: IrField) { if (isExternalFileClassMember(f)) { extractExternalClassLater(f.parentAsClass) dependencyCollector?.addDependency(f, externalClassExtractor.fieldSignature) @@ -270,7 +270,7 @@ open class KotlinUsesExtractor( } } - fun extractFunctionLaterIfExternalFileMember(f: IrFunction) { + private fun extractFunctionLaterIfExternalFileMember(f: IrFunction) { if (isExternalFileClassMember(f)) { extractExternalClassLater(f.parentAsClass) (f as? IrSimpleFunction)?.correspondingPropertySymbol?.let { @@ -301,7 +301,7 @@ open class KotlinUsesExtractor( externalClassExtractor.extractLater(c) } - fun tryReplaceAndroidSyntheticClass(c: IrClass): IrClass { + private fun tryReplaceAndroidSyntheticClass(c: IrClass): IrClass { // The Android Kotlin Extensions Gradle plugin introduces synthetic functions, fields and classes. The most // obvious signature is that they lack any supertype information even though they are not root classes. // If possible, replace them by a real version of the same class. @@ -503,7 +503,7 @@ open class KotlinUsesExtractor( // but returns boxed arrays with a nullable, invariant component type, with any nested arrays // similarly transformed. For example, Array> would become Array?> // Array<*> will become Array. - fun getInvariantNullableArrayType(arrayType: IrSimpleType): IrSimpleType = + private fun getInvariantNullableArrayType(arrayType: IrSimpleType): IrSimpleType = if (arrayType.isPrimitiveArray()) arrayType else { @@ -528,7 +528,7 @@ open class KotlinUsesExtractor( ) } - fun useArrayType(arrayType: IrSimpleType, componentType: IrType, elementType: IrType, dimensions: Int, isPrimitiveArray: Boolean): TypeResults { + private fun useArrayType(arrayType: IrSimpleType, componentType: IrType, elementType: IrType, dimensions: Int, isPrimitiveArray: Boolean): TypeResults { // Ensure we extract Array as Integer[], not int[], for example: fun nullableIfNotPrimitive(type: IrType) = if (type.isPrimitiveType() && !isPrimitiveArray) type.makeNullable() else type @@ -579,7 +579,7 @@ open class KotlinUsesExtractor( RETURN, GENERIC_ARGUMENT, OTHER } - fun useSimpleType(s: IrSimpleType, context: TypeContext): TypeResults { + private fun useSimpleType(s: IrSimpleType, context: TypeContext): TypeResults { if (s.abbreviation != null) { // TODO: Extract this information } @@ -810,14 +810,14 @@ open class KotlinUsesExtractor( return if (f is IrConstructor) f.typeParameters else f.typeParameters.filter { it.parent == f } } - fun getTypeParameters(dp: IrDeclarationParent): List = + private fun getTypeParameters(dp: IrDeclarationParent): List = when(dp) { is IrClass -> dp.typeParameters is IrFunction -> getFunctionTypeParameters(dp) else -> listOf() } - fun getEnclosingClass(it: IrDeclarationParent): IrClass? = + private fun getEnclosingClass(it: IrDeclarationParent): IrClass? = when(it) { is IrClass -> it is IrFunction -> getEnclosingClass(it.parent) @@ -924,7 +924,7 @@ open class KotlinUsesExtractor( null } ?: t - fun getJavaTypeArgument(jt: JavaType, idx: Int) = + private fun getJavaTypeArgument(jt: JavaType, idx: Int) = when(jt) { is JavaClassifierType -> jt.typeArguments.getOrNull(idx) is JavaArrayType -> if (idx == 0) jt.componentType else null @@ -970,7 +970,7 @@ open class KotlinUsesExtractor( * allow it to be passed in. */ @OptIn(ObsoleteDescriptorBasedAPI::class) - fun getFunctionLabel(f: IrFunction, maybeParentId: Label?, classTypeArgsIncludingOuterClasses: List?) = + private fun getFunctionLabel(f: IrFunction, maybeParentId: Label?, classTypeArgsIncludingOuterClasses: List?) = getFunctionLabel( f.parent, maybeParentId, @@ -1153,7 +1153,7 @@ open class KotlinUsesExtractor( "kotlin.Boolean", "kotlin.Byte", "kotlin.Char", "kotlin.Double", "kotlin.Float", "kotlin.Int", "kotlin.Long", "kotlin.Number", "kotlin.Short" ) - fun kotlinFunctionToJavaEquivalent(f: IrFunction, noReplace: Boolean) = + private fun kotlinFunctionToJavaEquivalent(f: IrFunction, noReplace: Boolean) = if (noReplace) f else @@ -1346,14 +1346,14 @@ open class KotlinUsesExtractor( return "@\"typevar;{$parentLabel};${param.name}\"" } - fun useTypeParameter(param: IrTypeParameter) = + private fun useTypeParameter(param: IrTypeParameter) = TypeResult( tw.getLabelFor(getTypeParameterLabel(param)), useType(eraseTypeParameter(param)).javaResult.signature, param.name.asString() ) - fun extractModifier(m: String): Label { + private fun extractModifier(m: String): Label { val modifierLabel = "@\"modifier;$m\"" val id: Label = tw.getLabelFor(modifierLabel, { tw.writeModifiers(it, m) @@ -1435,7 +1435,7 @@ open class KotlinUsesExtractor( * Note that `Array` is retained (with `T` itself erased) because these are expected to be lowered to Java * arrays, which are not generic. */ - fun erase (t: IrType): IrType { + private fun erase (t: IrType): IrType { if (t is IrSimpleType) { val classifier = t.classifier val owner = classifier.owner @@ -1488,7 +1488,7 @@ open class KotlinUsesExtractor( fun useValueParameter(vp: IrValueParameter, parent: Label?): Label = tw.getLabelFor(getValueParameterLabel(vp, parent)) - fun isDirectlyExposedCompanionObjectField(f: IrField) = + private fun isDirectlyExposedCompanionObjectField(f: IrField) = f.hasAnnotation(FqName("kotlin.jvm.JvmField")) || f.correspondingPropertySymbol?.owner?.let { it.isConst || it.isLateinit diff --git a/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt b/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt index 6f3954cfc34..15ca35a1438 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt @@ -68,7 +68,7 @@ fun getIrClassVirtualFile(irClass: IrClass): VirtualFile? { return null } -fun getRawIrClassBinaryPath(irClass: IrClass) = +private fun getRawIrClassBinaryPath(irClass: IrClass) = getIrClassVirtualFile(irClass)?.let { val path = it.path if(it.fileSystem.protocol == StandardFileSystems.JRT_PROTOCOL) @@ -92,4 +92,4 @@ fun getContainingClassOrSelf(decl: IrDeclaration): IrClass? { } fun getJavaEquivalentClassId(c: IrClass) = - c.fqNameWhenAvailable?.toUnsafe()?.let { JavaToKotlinClassMap.mapKotlinToJava(it) } \ No newline at end of file + c.fqNameWhenAvailable?.toUnsafe()?.let { JavaToKotlinClassMap.mapKotlinToJava(it) } From 06060954ec6c7708e67db0ae44851c70f9caf5b6 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 27 Jun 2022 19:25:56 +0100 Subject: [PATCH 115/465] Kotlin: Extract inlineability of functions --- java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 29376368adc..f8b7ab35048 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -809,6 +809,9 @@ open class KotlinFileExtractor( } extractVisibility(f, id, f.visibility) + if (f.isInline) { + addModifiers(id, "inline") + } if (isStaticFunction(f)) { addModifiers(id, "static") } From 4a404aee76aa2f42feda2a7fa2734cccd76a791b Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 27 Jun 2022 19:27:26 +0100 Subject: [PATCH 116/465] Kotlin: Add inline info to methods test --- .../kotlin/library-tests/methods/exprs.expected | 1 + .../library-tests/methods/methods.expected | 17 +++++++++-------- .../kotlin/library-tests/methods/methods.kt | 1 + 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/java/ql/test/kotlin/library-tests/methods/exprs.expected b/java/ql/test/kotlin/library-tests/methods/exprs.expected index abad65d5f83..586df6856c8 100644 --- a/java/ql/test/kotlin/library-tests/methods/exprs.expected +++ b/java/ql/test/kotlin/library-tests/methods/exprs.expected @@ -205,3 +205,4 @@ | methods.kt:16:13:16:31 | Unit | TypeAccess | | methods.kt:17:14:17:33 | Unit | TypeAccess | | methods.kt:18:5:18:36 | Unit | TypeAccess | +| methods.kt:19:12:19:29 | Unit | TypeAccess | diff --git a/java/ql/test/kotlin/library-tests/methods/methods.expected b/java/ql/test/kotlin/library-tests/methods/methods.expected index 144e71e5d48..cb824d228dd 100644 --- a/java/ql/test/kotlin/library-tests/methods/methods.expected +++ b/java/ql/test/kotlin/library-tests/methods/methods.expected @@ -24,13 +24,14 @@ methods | methods5.kt:5:3:5:27 | | methods5.kt:5:3:5:27 | a | a(int) | public | | | methods5.kt:9:3:9:32 | | methods5.kt:9:3:9:32 | f1 | f1(foo.bar.C1,int) | public | | | methods.kt:0:0:0:0 | MethodsKt | methods.kt:2:1:3:1 | topLevelMethod | topLevelMethod(int,int) | public, static | | -| methods.kt:5:1:19:1 | Class | methods.kt:6:5:7:5 | classMethod | classMethod(int,int) | public | | -| methods.kt:5:1:19:1 | Class | methods.kt:9:5:12:5 | anotherClassMethod | anotherClassMethod(int,int) | public | | -| methods.kt:5:1:19:1 | Class | methods.kt:14:12:14:29 | publicFun | publicFun() | public | | -| methods.kt:5:1:19:1 | Class | methods.kt:15:15:15:35 | protectedFun | protectedFun() | protected | | -| methods.kt:5:1:19:1 | Class | methods.kt:16:13:16:31 | privateFun | privateFun() | private | | -| methods.kt:5:1:19:1 | Class | methods.kt:17:14:17:33 | internalFun | internalFun() | internal | | -| methods.kt:5:1:19:1 | Class | methods.kt:18:5:18:36 | noExplicitVisibilityFun | noExplicitVisibilityFun() | public | | +| methods.kt:5:1:20:1 | Class | methods.kt:6:5:7:5 | classMethod | classMethod(int,int) | public | | +| methods.kt:5:1:20:1 | Class | methods.kt:9:5:12:5 | anotherClassMethod | anotherClassMethod(int,int) | public | | +| methods.kt:5:1:20:1 | Class | methods.kt:14:12:14:29 | publicFun | publicFun() | public | | +| methods.kt:5:1:20:1 | Class | methods.kt:15:15:15:35 | protectedFun | protectedFun() | protected | | +| methods.kt:5:1:20:1 | Class | methods.kt:16:13:16:31 | privateFun | privateFun() | private | | +| methods.kt:5:1:20:1 | Class | methods.kt:17:14:17:33 | internalFun | internalFun() | internal | | +| methods.kt:5:1:20:1 | Class | methods.kt:18:5:18:36 | noExplicitVisibilityFun | noExplicitVisibilityFun() | public | | +| methods.kt:5:1:20:1 | Class | methods.kt:19:12:19:29 | inlineFun | inlineFun() | inline, public | | constructors | dataClass.kt:1:1:1:47 | DataClass | dataClass.kt:1:6:1:47 | DataClass | DataClass(int,java.lang.String) | | enumClass.kt:1:1:4:1 | EnumClass | enumClass.kt:1:6:4:1 | EnumClass | EnumClass(int) | @@ -41,7 +42,7 @@ constructors | methods5.kt:5:3:5:27 | | methods5.kt:5:3:5:27 | | | | methods5.kt:9:3:9:32 | | methods5.kt:9:3:9:32 | | | | methods5.kt:13:1:13:14 | C1 | methods5.kt:13:1:13:14 | C1 | C1() | -| methods.kt:5:1:19:1 | Class | methods.kt:5:1:19:1 | Class | Class() | +| methods.kt:5:1:20:1 | Class | methods.kt:5:1:20:1 | Class | Class() | extensions | methods3.kt:3:1:3:42 | fooBarTopLevelMethodExt | file://:0:0:0:0 | int | | methods3.kt:6:5:6:46 | fooBarTopLevelMethodExt | file://:0:0:0:0 | int | diff --git a/java/ql/test/kotlin/library-tests/methods/methods.kt b/java/ql/test/kotlin/library-tests/methods/methods.kt index b59937bc861..48f480f8748 100644 --- a/java/ql/test/kotlin/library-tests/methods/methods.kt +++ b/java/ql/test/kotlin/library-tests/methods/methods.kt @@ -16,5 +16,6 @@ class Class { private fun privateFun() {} internal fun internalFun() {} fun noExplicitVisibilityFun() {} + inline fun inlineFun() {} } From af672b48997fb9e2a3c7cc55d1ab2eb42b9111a8 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 27 Jun 2022 19:31:01 +0100 Subject: [PATCH 117/465] Kotlin: Add a changenote for Modifier.isInline() --- java/ql/lib/change-notes/2022-06-27-isInline.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2022-06-27-isInline.md diff --git a/java/ql/lib/change-notes/2022-06-27-isInline.md b/java/ql/lib/change-notes/2022-06-27-isInline.md new file mode 100644 index 00000000000..ad73ed8bf82 --- /dev/null +++ b/java/ql/lib/change-notes/2022-06-27-isInline.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +Added `Modifier.isInline()`. From 44e69e1c09d0911a157fcf146b009160c1e359dd Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 27 Jun 2022 19:33:08 +0100 Subject: [PATCH 118/465] Kotlin: Add Modifier.isInline() --- java/ql/lib/semmle/code/java/Modifier.qll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/ql/lib/semmle/code/java/Modifier.qll b/java/ql/lib/semmle/code/java/Modifier.qll index d3971e42e59..8f947383d1e 100755 --- a/java/ql/lib/semmle/code/java/Modifier.qll +++ b/java/ql/lib/semmle/code/java/Modifier.qll @@ -58,6 +58,9 @@ abstract class Modifiable extends Element { /** Holds if this element has an `internal` modifier. */ predicate isInternal() { this.hasModifier("internal") } + /** Holds if this element has an `inline` modifier. */ + predicate isInline() { this.hasModifier("inline") } + /** Holds if this element has a `volatile` modifier. */ predicate isVolatile() { this.hasModifier("volatile") } From 43bb439b8286cd76730764e367724ce2d2fe0287 Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Mon, 27 Jun 2022 12:03:23 -0700 Subject: [PATCH 119/465] Add version info for running subset of queries --- .../codeql-cli/analyzing-databases-with-the-codeql-cli.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst index 6c7169634bb..e52cd53e2bd 100644 --- a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst @@ -138,7 +138,7 @@ For further information about default suites, see ":ref:`Publishing and using Co Running a subset of queries in a CodeQL pack ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Additionally, you can include a path at the end of a pack specification to run a subset of queries inside the pack. This applies to any command that locates or runs queries within a pack. +Additionally, CodeQL CLI v2.10.0 or later, you can include a path at the end of a pack specification to run a subset of queries inside the pack. This applies to any command that locates or runs queries within a pack. The complete way to specify a set of queries is in the form ``scope/name@range:path``, where: @@ -174,7 +174,7 @@ To analyze your database using the `cpp-security-and-quality.qls` query suite fr codeql database analyze --format=sarif-latest --output=results \ 'codeql/cpp-queries@~0.0.3:codeql-suites/cpp-security-and-quality.qls' - + For more information about CodeQL packs, see :doc:`About CodeQL Packs `. Running query suites @@ -263,7 +263,7 @@ you can include the query help for your custom queries in SARIF files generated After uploading the SARIF file to GitHub, the query help is shown in the code scanning UI for any alerts generated by the custom queries. -From CodeQL CLI 2.7.1 onwards, you can include markdown-rendered query help in SARIF files +From CodeQL CLI v2.7.1 onwards, you can include markdown-rendered query help in SARIF files by providing the ``--sarif-add-query-help`` option when running ``codeql database analyze``. For more information, see `Configuring CodeQL CLI in your CI system `__ From 829fdd1ff69b345a9963363eabf78a9594261f07 Mon Sep 17 00:00:00 2001 From: Robert Marsh Date: Mon, 27 Jun 2022 15:28:14 -0400 Subject: [PATCH 120/465] C++: fix join order in UsingExpiredStackAddress --- .../Likely Bugs/Memory Management/UsingExpiredStackAddress.ql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql b/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql index 27aeabbaf49..3f3997315d4 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/UsingExpiredStackAddress.ql @@ -133,7 +133,9 @@ TGlobalAddress globalAddress(Instruction instr) { ) or exists(FieldAddressInstruction fai | instr = fai | - result = TFieldAddress(globalAddress(fai.getObjectAddress()), fai.getField()) + result = + TFieldAddress(globalAddress(pragma[only_bind_into](fai.getObjectAddress())), + pragma[only_bind_out](fai.getField())) ) or result = globalAddress(instr.(PointerOffsetInstruction).getLeft()) From 8fc9ce96996067a9b4003452feda951a6cfb833f Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 27 Jun 2022 13:12:16 +0000 Subject: [PATCH 121/465] Python: Fix bad join in MRO Fixes a bad join in `list_of_linearization_of_bases_plus_bases`. Previvously, we joined together `ConsList` and `getBase` before filtering these out using the recursive call. Now we do the recursion first. Co-authored-by: yoff --- python/ql/lib/semmle/python/pointsto/MRO.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/pointsto/MRO.qll b/python/ql/lib/semmle/python/pointsto/MRO.qll index b1ea92b8c24..da9e610ab5d 100644 --- a/python/ql/lib/semmle/python/pointsto/MRO.qll +++ b/python/ql/lib/semmle/python/pointsto/MRO.qll @@ -419,7 +419,9 @@ private ClassListList list_of_linearization_of_bases_plus_bases(ClassObjectInter result = ConsList(bases(cls), EmptyList()) and n = Types::base_count(cls) and n > 1 or exists(ClassListList partial | - partial = list_of_linearization_of_bases_plus_bases(cls, n + 1) and + partial = + list_of_linearization_of_bases_plus_bases(pragma[only_bind_into](cls), + pragma[only_bind_into](n + 1)) and result = ConsList(Mro::newStyleMro(Types::getBase(cls, n)), partial) ) } From dc0f50d49afcb5cde41e61e92ffcda2f7e5ac63b Mon Sep 17 00:00:00 2001 From: Taus Date: Mon, 27 Jun 2022 13:14:35 +0000 Subject: [PATCH 122/465] Python: Clean up variable names Makes it more consistent with the names used in `legalMergeCandidateNonEmpty`. --- python/ql/lib/semmle/python/pointsto/MRO.qll | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/ql/lib/semmle/python/pointsto/MRO.qll b/python/ql/lib/semmle/python/pointsto/MRO.qll index da9e610ab5d..e7248c18c06 100644 --- a/python/ql/lib/semmle/python/pointsto/MRO.qll +++ b/python/ql/lib/semmle/python/pointsto/MRO.qll @@ -344,12 +344,12 @@ private class ClassListList extends TClassListList { ) } - private predicate legalMergeCandidate(ClassObjectInternal cls, ClassListList remaining) { - cls = this.getAHead() and remaining = this + private predicate legalMergeCandidate(ClassObjectInternal cls, ClassListList remainingList) { + cls = this.getAHead() and remainingList = this or - this.legalMergeCandidate(cls, ConsList(Empty(), remaining)) + this.legalMergeCandidate(cls, ConsList(Empty(), remainingList)) or - this.legalMergeCandidateNonEmpty(cls, remaining, Empty()) + this.legalMergeCandidateNonEmpty(cls, remainingList, Empty()) } pragma[noinline] From 882000afb3017fcc2814c3dfaa0aa9cd88bdc83e Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 16 Jun 2022 11:47:34 +0200 Subject: [PATCH 123/465] python: `not` is confusing our logic - added `is_unsafe` - added "negated version" of two tests. These versions do not use `not` and the analysis gets the taint right. --- .../customSanitizer/InlineTaintTest.expected | 16 ++++++------ .../customSanitizer/InlineTaintTest.ql | 8 ++++++ .../customSanitizer/test_logical.py | 25 +++++++++++++++++++ 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected index c8c41375538..6e67de96c62 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected @@ -6,12 +6,14 @@ isSanitizer | TestTaintTrackingConfiguration | test.py:34:39:34:39 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test.py:52:28:52:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test.py:66:10:66:29 | ControlFlowNode for emulated_escaping() | -| TestTaintTrackingConfiguration | test_logical.py:30:28:30:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:45:28:45:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:50:28:50:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:89:28:89:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:100:28:100:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:145:28:145:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:33:28:33:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:48:28:48:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:53:28:53:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:92:28:92:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:103:28:103:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_logical.py:148:28:148:28 | ControlFlowNode for s | -| TestTaintTrackingConfiguration | test_logical.py:155:28:155:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:151:28:151:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:158:28:158:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:176:24:176:24 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:193:24:193:24 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_reference.py:31:28:31:28 | ControlFlowNode for s | diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql index c68bd2d274d..984cf74d036 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.ql @@ -6,6 +6,12 @@ predicate isSafeCheck(DataFlow::GuardNode g, ControlFlowNode node, boolean branc branch = true } +predicate isUnsafeCheck(DataFlow::GuardNode g, ControlFlowNode node, boolean branch) { + g.(CallNode).getNode().getFunc().(Name).getId() in ["is_unsafe", "emulated_is_unsafe"] and + node = g.(CallNode).getAnArg() and + branch = false +} + class CustomSanitizerOverrides extends TestTaintTrackingConfiguration { override predicate isSanitizer(DataFlow::Node node) { exists(Call call | @@ -16,6 +22,8 @@ class CustomSanitizerOverrides extends TestTaintTrackingConfiguration { node.asExpr().(Call).getFunc().(Name).getId() = "emulated_escaping" or node = DataFlow::BarrierGuard::getABarrierNode() + or + node = DataFlow::BarrierGuard::getABarrierNode() } } diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py index a879c3c332c..dc2cc7a5522 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py @@ -22,6 +22,9 @@ def random_choice(): def is_safe(arg): return arg == "safe" +def is_unsafe(arg): + return arg == TAINTED_STRING + def test_basic(): s = TAINTED_STRING @@ -164,6 +167,15 @@ def test_with_return(): ensure_not_tainted(s) # $ SPURIOUS: tainted +def test_with_return_neg(): + s = TAINTED_STRING + + if is_unsafe(s): + return + + ensure_not_tainted(s) + + def test_with_exception(): s = TAINTED_STRING @@ -172,6 +184,14 @@ def test_with_exception(): ensure_not_tainted(s) # $ SPURIOUS: tainted +def test_with_exception_neg(): + s = TAINTED_STRING + + if is_unsafe(s): + raise Exception("unsafe") + + ensure_not_tainted(s) + # Make tests runable test_basic() @@ -182,7 +202,12 @@ test_tricky() test_nesting_not() test_nesting_not_with_and_true() test_with_return() +test_with_return_neg() try: test_with_exception() except: pass +try: + test_with_exception_neg() +except: + pass From a1fe8a5b2b2d9967c47f3c86db3ce430cc8b6605 Mon Sep 17 00:00:00 2001 From: Rasmus Lerchedahl Petersen Date: Thu, 16 Jun 2022 13:53:05 +0200 Subject: [PATCH 124/465] python: handle `not` in BarrierGuard in the program ```python if not is_safe(path): return ``` the last node in the `ConditionBlock` is `not is_safe(path)`, so it would never match "a call to is_safe". Thus, guards inside `not` would not be part of `GuardNode` (nor `BarrierGuard`). Now they can. --- .../dataflow/new/internal/DataFlowPublic.qll | 20 +++++++++++++++++-- .../test_string_const_compare.py | 4 ++-- .../customSanitizer/InlineTaintTest.expected | 6 ++++++ .../customSanitizer/test_logical.py | 12 +++++------ 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index 406f1fb6b12..3ab007b3657 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -527,16 +527,32 @@ class StarPatternElementNode extends Node, TStarPatternElementNode { override Location getLocation() { result = consumer.getLocation() } } +ControlFlowNode guardNode(ConditionBlock conditionBlock, boolean flipped) { + result = conditionBlock.getLastNode() and + flipped = false + or + exists(UnaryExprNode notNode | + result = notNode.getOperand() and + notNode.getNode().getOp() instanceof Not + | + notNode = guardNode(conditionBlock, flipped.booleanNot()) + ) +} + /** * A node that controls whether other nodes are evaluated. */ class GuardNode extends ControlFlowNode { ConditionBlock conditionBlock; + boolean flipped; - GuardNode() { this = conditionBlock.getLastNode() } + GuardNode() { this = guardNode(conditionBlock, flipped) } /** Holds if this guard controls block `b` upon evaluating to `branch`. */ - predicate controlsBlock(BasicBlock b, boolean branch) { conditionBlock.controls(b, branch) } + predicate controlsBlock(BasicBlock b, boolean branch) { + branch in [true, false] and + conditionBlock.controls(b, branch.booleanXor(flipped)) + } } /** diff --git a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py b/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py index 2fc809cf18f..f1b01f4f84a 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py +++ b/python/ql/test/experimental/dataflow/tainttracking/commonSanitizer/test_string_const_compare.py @@ -50,7 +50,7 @@ def test_non_eq2(): if not ts == "safe": ensure_tainted(ts) # $ tainted else: - ensure_not_tainted(ts) # $ SPURIOUS: tainted + ensure_not_tainted(ts) def test_in_list(): @@ -157,7 +157,7 @@ def test_not_in2(): if not ts in ["safe", "also_safe"]: ensure_tainted(ts) # $ tainted else: - ensure_not_tainted(ts) # $ SPURIOUS: tainted + ensure_not_tainted(ts) def is_safe(x): diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected index 6e67de96c62..fdad063534b 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/InlineTaintTest.expected @@ -7,13 +7,19 @@ isSanitizer | TestTaintTrackingConfiguration | test.py:52:28:52:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test.py:66:10:66:29 | ControlFlowNode for emulated_escaping() | | TestTaintTrackingConfiguration | test_logical.py:33:28:33:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:40:28:40:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_logical.py:48:28:48:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_logical.py:53:28:53:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_logical.py:92:28:92:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_logical.py:103:28:103:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:111:28:111:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:130:28:130:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:137:28:137:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_logical.py:148:28:148:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_logical.py:151:28:151:28 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_logical.py:158:28:158:28 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:167:24:167:24 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_logical.py:176:24:176:24 | ControlFlowNode for s | +| TestTaintTrackingConfiguration | test_logical.py:185:24:185:24 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_logical.py:193:24:193:24 | ControlFlowNode for s | | TestTaintTrackingConfiguration | test_reference.py:31:28:31:28 | ControlFlowNode for s | diff --git a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py index dc2cc7a5522..26e69b8fc05 100644 --- a/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py +++ b/python/ql/test/experimental/dataflow/tainttracking/customSanitizer/test_logical.py @@ -37,7 +37,7 @@ def test_basic(): if not is_safe(s): ensure_tainted(s) # $ tainted else: - ensure_not_tainted(s) # $ SPURIOUS: tainted + ensure_not_tainted(s) def test_if_in_depth(): @@ -108,7 +108,7 @@ def test_and(): ensure_tainted(s) # $ tainted else: # cannot be tainted - ensure_not_tainted(s) # $ SPURIOUS: tainted + ensure_not_tainted(s) def test_tricky(): @@ -127,14 +127,14 @@ def test_nesting_not(): s = TAINTED_STRING if not(not(is_safe(s))): - ensure_not_tainted(s) # $ SPURIOUS: tainted + ensure_not_tainted(s) else: ensure_tainted(s) # $ tainted if not(not(not(is_safe(s)))): ensure_tainted(s) # $ tainted else: - ensure_not_tainted(s) # $ SPURIOUS: tainted + ensure_not_tainted(s) # Adding `and True` makes the sanitizer trigger when it would otherwise not. See output in @@ -164,7 +164,7 @@ def test_with_return(): if not is_safe(s): return - ensure_not_tainted(s) # $ SPURIOUS: tainted + ensure_not_tainted(s) def test_with_return_neg(): @@ -182,7 +182,7 @@ def test_with_exception(): if not is_safe(s): raise Exception("unsafe") - ensure_not_tainted(s) # $ SPURIOUS: tainted + ensure_not_tainted(s) def test_with_exception_neg(): s = TAINTED_STRING From 1788507571971a084b6d518033805e2182002a1d Mon Sep 17 00:00:00 2001 From: yoff Date: Mon, 27 Jun 2022 21:00:12 +0000 Subject: [PATCH 125/465] python: add qldoc --- .../dataflow/new/internal/DataFlowPublic.qll | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll index 3ab007b3657..8ab76dc56df 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowPublic.qll @@ -527,10 +527,30 @@ class StarPatternElementNode extends Node, TStarPatternElementNode { override Location getLocation() { result = consumer.getLocation() } } +/** + * Gets a node that controls whether other nodes are evaluated. + * + * In the base case, this is the last node of `conditionBlock`, and `flipped` is `false`. + * This definition accounts for (short circuting) `and`- and `or`-expressions, as the structure + * of basic blocks will reflect their semantics. + * + * However, in the program + * ```python + * if not is_safe(path): + * return + * ``` + * the last node in the `ConditionBlock` is `not is_safe(path)`. + * + * We would like to consider also `is_safe(path)` a guard node, albeit with `flipped` being `true`. + * Thus we recurse through `not`-expressions. + */ ControlFlowNode guardNode(ConditionBlock conditionBlock, boolean flipped) { + // Base case: the last node truly does determine which successor is chosen result = conditionBlock.getLastNode() and flipped = false or + // Recursive case: if a guard node is a `not`-expression, + // the operand is also a guard node, but with inverted polarity. exists(UnaryExprNode notNode | result = notNode.getOperand() and notNode.getNode().getOp() instanceof Not @@ -541,6 +561,9 @@ ControlFlowNode guardNode(ConditionBlock conditionBlock, boolean flipped) { /** * A node that controls whether other nodes are evaluated. + * + * The field `flipped` allows us to match `GuardNode`s underneath + * `not`-expressions and still choose the appropriate branch. */ class GuardNode extends ControlFlowNode { ConditionBlock conditionBlock; From 67b6f215dc0b315a5d5ee6021943dc6ecc98664e Mon Sep 17 00:00:00 2001 From: yoff Date: Tue, 28 Jun 2022 08:05:53 +0200 Subject: [PATCH 126/465] Apply suggestions from code review Co-authored-by: Rasmus Wriedt Larsen --- .../python/security/dataflow/TarSlipCustomizations.qll | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll index 8795bd31c27..db062a23088 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll @@ -112,8 +112,9 @@ module TarSlip { /** * A sanitizer guard heuristic. * - * For a "check-like function-name" (matching `"%path"`), `checkPath`, - * and a call `checkPath(info.name)`, the variable `info` is considered checked. + * The test `if (info.name)` should clear taint for `info`, + * where `` is any function matching `"%path"`. + * `info` is assumed to be a `TarInfo` instance. */ class TarFileInfoSanitizer extends SanitizerGuard { ControlFlowNode tarInfo; From 9b27a7cbcdf2590d2ad17aae66e1414e1806a1c4 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 28 Jun 2022 09:28:26 +0200 Subject: [PATCH 127/465] Python: Dont claim that external libraries are excluded from the database --- python/ql/lib/semmle/python/ApiGraphs.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index 65fffc9aee1..c3aa91b4213 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -48,8 +48,8 @@ module API { * (The current codebase "defines" the value seen by the library). * * API graph nodes are associated with data-flow nodes in the current codebase. - * (Since external libraries are not part of the database, there is no way to associate with concrete - * data-flow nodes from the external library). + * (API graphs are designed to work when external libraries are not part of the database, + * so we do not associate with concrete data-flow nodes from the external library). * - **Use-nodes** are associated with data-flow nodes where a value enters the current codebase, * such as the return value of a call to an external function. * - **Def-nodes** are associated with data-flow nodes where a value leaves the current codebase, From a033338d20edb3a4458181badf014c87939b74ab Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 28 Jun 2022 09:46:26 +0200 Subject: [PATCH 128/465] Python: Explicitly mention lack of transitive flow in asSource/asSink --- python/ql/lib/semmle/python/ApiGraphs.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index c3aa91b4213..a17f93b96d5 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -121,6 +121,9 @@ module API { * obj.prop = x * foo.bar(obj); * ``` + * + * This predicate does not include nodes transitively reaching the sink by data flow; + * use `getAValueReachingSink` for that. */ DataFlow::Node asSink() { Impl::rhs(this, result) } @@ -146,6 +149,9 @@ module API { * # API::moduleImport("re").getMember("escape").getReturn().asSource() * re.escape() * ``` + * + * This predicate does not include nodes transitively reachable by data flow; + * use `getAValueReachableFromSource` for that. */ DataFlow::LocalSourceNode asSource() { Impl::use(this, result) } From 4c73ab2679c442bd6eb8db66e8063e53f5ec52fb Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 28 Jun 2022 09:48:53 +0200 Subject: [PATCH 129/465] Apply suggestions from code review Co-authored-by: Taus --- python/ql/lib/semmle/python/ApiGraphs.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/ApiGraphs.qll b/python/ql/lib/semmle/python/ApiGraphs.qll index a17f93b96d5..cf4e4fb3cd5 100644 --- a/python/ql/lib/semmle/python/ApiGraphs.qll +++ b/python/ql/lib/semmle/python/ApiGraphs.qll @@ -32,7 +32,7 @@ module API { * 2. Follow up with a chain of accessors such as `getMember` describing how to get to the relevant API function. * 3. Map the resulting API graph nodes to data-flow nodes, using `asSource` or `asSink`. * - * For example, a simplified way to get arguments to `json.dumps` would be + * For example, a simplified way to get the first argument of a call to `json.dumps` would be * ```ql * API::moduleImport("json").getMember("dumps").getParameter(0).asSink() * ``` @@ -108,7 +108,7 @@ module API { * external library (or in general, any external codebase). * * Concretely, this is either an argument passed to a call to external code, - * or the right-hand side of a property write on an object flowing into such a call. + * or the right-hand side of an attribute write on an object flowing into such a call. * * For example: * ```python From b1251f0c6357db5c2eedbf09f2cf4574173612a8 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 28 Jun 2022 10:07:57 +0200 Subject: [PATCH 130/465] JS: invertCase -> toOtherCase --- .../ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql index 8aca0553c00..a497f03f076 100644 --- a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql @@ -16,7 +16,7 @@ import javascript * Converts `s` to upper case, or to lower-case if it was already upper case. */ bindingset[s] -string invertCase(string s) { +string toOtherCase(string s) { if s.regexpMatch(".*[a-z].*") then result = s.toUpperCase() else result = s.toLowerCase() } @@ -35,7 +35,7 @@ predicate isCaseSensitiveRegExp(RegExpTerm term) { const = term.getAChild*() and const.getValue().regexpMatch(".*[a-zA-Z].*") and not getEnclosingClass(const).getAChild().(RegExpConstant).getValue() = - invertCase(const.getValue()) and + toOtherCase(const.getValue()) and not const.getParent*() instanceof RegExpNegativeLookahead and not const.getParent*() instanceof RegExpNegativeLookbehind ) @@ -67,7 +67,7 @@ string getExampleString(RegExpTerm term) { string getCaseSensitiveBypassExample(RegExpTerm term) { exists(string example | example = getExampleString(term) and - result = invertCase(example) and + result = toOtherCase(example) and result != example // getting an example string is approximate; ensure we got a proper case-change example ) } From 9cf48fc8042b6a5c4b9a3befc4956994dc875c27 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 28 Jun 2022 10:09:56 +0200 Subject: [PATCH 131/465] JS: Clarify that strings are case insensitive by default --- .../ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp | 1 + 1 file changed, 1 insertion(+) diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp index bc91fcf9be0..7acfb8c95da 100644 --- a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp @@ -7,6 +7,7 @@

    Using a case-sensitive regular expression path in a middleware route enables an attacker to bypass that middleware when accessing an endpoint with a case-insensitive path. +Paths specified using a string are case insensitive, whereas regular expressions are case sensitive by default.

    From fd283970562191a1561d9c93c026850ccad35baf Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 28 Jun 2022 10:10:23 +0200 Subject: [PATCH 132/465] JS: Fix typo --- .../ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp index 7acfb8c95da..13e2331bc62 100644 --- a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp @@ -13,7 +13,7 @@ Paths specified using a string are case insensitive, whereas regular expressions

    -When using a regular expression as a middlware path, make sure the regular expression is +When using a regular expression as a middleware path, make sure the regular expression is case insensitive by adding the i flag.

    From 0e04f2b2e8322e240bfe0ebdfedce69ad97d6818 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 13 May 2022 11:36:43 +0100 Subject: [PATCH 133/465] Add external storage souces --- .../code/java/dataflow/ExternalFlow.qll | 1 + .../semmle/code/java/dataflow/FlowSources.qll | 7 +++ .../frameworks/android/ExternalStorage.qll | 46 +++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index db1b5a61ef6..f518dbd2802 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -84,6 +84,7 @@ private module Frameworks { private import internal.ContainerFlow private import semmle.code.java.frameworks.android.Android private import semmle.code.java.frameworks.android.ContentProviders + private import semmle.code.java.frameworks.android.ExternalStorage private import semmle.code.java.frameworks.android.Intent private import semmle.code.java.frameworks.android.Notifications private import semmle.code.java.frameworks.android.SharedPreferences diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll index 2c44d7a15b6..fcd4fe90b6d 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll @@ -17,6 +17,7 @@ import semmle.code.java.frameworks.android.WebView import semmle.code.java.frameworks.JaxWS import semmle.code.java.frameworks.javase.WebSocket import semmle.code.java.frameworks.android.Android +import semmle.code.java.frameworks.android.ExternalStorage import semmle.code.java.frameworks.android.OnActivityResultSource import semmle.code.java.frameworks.android.Intent import semmle.code.java.frameworks.play.Play @@ -152,6 +153,12 @@ private class ThriftIfaceParameterSource extends RemoteFlowSource { override string getSourceType() { result = "Thrift Iface parameter" } } +private class AndroidExternalStorageSource extends RemoteFlowSource { + AndroidExternalStorageSource() { androidExternalStorageSource(this) } + + override string getSourceType() { result = "Android external storage" } +} + /** Class for `tainted` user input. */ abstract class UserInput extends DataFlow::Node { } diff --git a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll new file mode 100644 index 00000000000..60214f8861a --- /dev/null +++ b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll @@ -0,0 +1,46 @@ +/** Provides definitions for working with uses of Android external storage */ + +import java +import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.ExternalFlow + +private class ExternalStorageDirSourceModel extends SourceModelCsv { + override predicate row(string row) { + row = + [ + //"package;type;overrides;name;signature;ext;spec;kind" + "android.content;Context;true;getExternalFilesDir;(String);;ReturnValue;android-external-storage-dir", + "android.content;Context;true;getExternalFilesDirs;(String);;ReturnValue.ArrayElement;android-external-storage-dir", + "android.content;Context;true;getExternalCachesDir;(String);;ReturnValue;android-external-storage-dir", + "android.content;Context;true;getExternalCachesDirs;(String);;ReturnValue.ArrayElement;android-external-storage-dir", + "android.os;Environment;false;getExternalStorageDirectory;(String);;ReturnValue.ArrayElement;android-external-storage-dir", + "android.os;Environment;false;getExternalStoragePublicDirectory;(String);;ReturnValue.ArrayElement;android-external-storage-dir", + ] + } +} + +private predicate externalStorageFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + DataFlow::localFlowStep(node1, node2) + or + exists(ConstructorCall c | c.getConstructedType() instanceof TypeFile | + node1.asExpr() = c.getArgument(1) and + node2.asExpr() = c + ) +} + +private predicate externalStorageFlow(DataFlow::Node node1, DataFlow::Node node2) { + externalStorageFlowStep*(node1, node2) +} + +/** + * Holds if `n` is a node that reads the contents of an external file in Android. + * This may be controlable by third-party applications, so is treated as a remote flow source. + */ +predicate androidExternalStorageSource(DataFlow::Node n) { + exists(ConstructorCall fInp, DataFlow::Node externalDir | + fInp.getConstructedType().hasQualifiedName("java.io", "FileInputStream") and + n.asExpr() = fInp and + sourceNode(externalDir, "android-external-storage-dir") and + externalStorageFlow(externalDir, DataFlow::exprNode(fInp.getArgument(0))) + ) +} From 810854d6b529abd031253df0688fa147fe791e8c Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 17 May 2022 18:25:43 +0100 Subject: [PATCH 134/465] Add tests --- .../frameworks/android/ExternalStorage.qll | 2 +- .../android/external-storage/Test.java | 51 +++++++++++++++++++ .../android/external-storage/options | 1 + .../android/external-storage/test.expected | 0 .../android/external-storage/test.ql | 20 ++++++++ .../android/os/Environment.java | 50 ++++++++++++++++++ 6 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 java/ql/test/library-tests/frameworks/android/external-storage/Test.java create mode 100644 java/ql/test/library-tests/frameworks/android/external-storage/options create mode 100644 java/ql/test/library-tests/frameworks/android/external-storage/test.expected create mode 100644 java/ql/test/library-tests/frameworks/android/external-storage/test.ql create mode 100644 java/ql/test/stubs/google-android-9.0.0/android/os/Environment.java diff --git a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll index 60214f8861a..b52fad076ed 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll @@ -34,7 +34,7 @@ private predicate externalStorageFlow(DataFlow::Node node1, DataFlow::Node node2 /** * Holds if `n` is a node that reads the contents of an external file in Android. - * This may be controlable by third-party applications, so is treated as a remote flow source. + * This is controlable by third-party applications, so is treated as a remote flow source. */ predicate androidExternalStorageSource(DataFlow::Node n) { exists(ConstructorCall fInp, DataFlow::Node externalDir | diff --git a/java/ql/test/library-tests/frameworks/android/external-storage/Test.java b/java/ql/test/library-tests/frameworks/android/external-storage/Test.java new file mode 100644 index 00000000000..92eb50368ae --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/external-storage/Test.java @@ -0,0 +1,51 @@ +import java.io.File; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.IOException; +import android.content.Context; +import android.os.Environment; + +class Test { + void sink(Object o) {} + + void test1(Context ctx) throws IOException { + File f = new File(ctx.getExternalFilesDir(null), "file.txt"); + InputStream is = new FileInputStream(f); + byte[] data = new byte[is.available()]; + is.read(data); + sink(data); // $hasTaintFlow + is.close(); + } + + void test2(Context ctx) throws IOException { + File f = new File(new File(new File(ctx.getExternalFilesDirs(null)[0], "things"), "stuff"), "file.txt"); + sink(new FileInputStream(f)); // $hasTaintFlow + } + + void test3(Context ctx) throws IOException { + File f = new File(ctx.getExternalCacheDir(), "file.txt"); + sink(new FileInputStream(f)); // $hasTaintFlow + } + + void test4(Context ctx) throws IOException { + File f = new File(ctx.getExternalCacheDirs()[0], "file.txt"); + sink(new FileInputStream(f)); // $hasTaintFlow + } + + void test5(Context ctx) throws IOException { + File f = new File(Environment.getExternalStorageDirectory(), "file.txt"); + sink(new FileInputStream(f)); // $hasTaintFlow + } + + void test6(Context ctx) throws IOException { + File f = new File(Environment.getExternalStoragePublicDirectory(null), "file.txt"); + sink(new FileInputStream(f)); // $hasTaintFlow + } + + static final File dir = Environment.getExternalStorageDirectory(); + + void test7(Context ctx) throws IOException { + File f = new File(dir, "file.txt"); + sink(new FileInputStream(f)); // $hasTaintFlow + } + } \ No newline at end of file diff --git a/java/ql/test/library-tests/frameworks/android/external-storage/options b/java/ql/test/library-tests/frameworks/android/external-storage/options new file mode 100644 index 00000000000..33cdc1ea940 --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/external-storage/options @@ -0,0 +1 @@ +//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/google-android-9.0.0 diff --git a/java/ql/test/library-tests/frameworks/android/external-storage/test.expected b/java/ql/test/library-tests/frameworks/android/external-storage/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/frameworks/android/external-storage/test.ql b/java/ql/test/library-tests/frameworks/android/external-storage/test.ql new file mode 100644 index 00000000000..03509c2d46d --- /dev/null +++ b/java/ql/test/library-tests/frameworks/android/external-storage/test.ql @@ -0,0 +1,20 @@ +import java +import semmle.code.java.dataflow.DataFlow +import semmle.code.java.dataflow.FlowSources +import TestUtilities.InlineFlowTest + +class Conf extends TaintTracking::Configuration { + Conf() { this = "test:AndroidExternalFlowConf" } + + override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource } + + override predicate isSink(DataFlow::Node sink) { + sink.asExpr().(Argument).getCall().getCallee().hasName("sink") + } +} + +class ExternalStorageTest extends InlineFlowTest { + override DataFlow::Configuration getValueFlowConfig() { none() } + + override DataFlow::Configuration getTaintFlowConfig() { result instanceof Conf } +} diff --git a/java/ql/test/stubs/google-android-9.0.0/android/os/Environment.java b/java/ql/test/stubs/google-android-9.0.0/android/os/Environment.java new file mode 100644 index 00000000000..1d7b49061e7 --- /dev/null +++ b/java/ql/test/stubs/google-android-9.0.0/android/os/Environment.java @@ -0,0 +1,50 @@ +// Generated automatically from android.os.Environment for testing purposes + +package android.os; + +import java.io.File; + +public class Environment +{ + public Environment(){} + public static File getDataDirectory(){ return null; } + public static File getDownloadCacheDirectory(){ return null; } + public static File getExternalStorageDirectory(){ return null; } + public static File getExternalStoragePublicDirectory(String p0){ return null; } + public static File getRootDirectory(){ return null; } + public static File getStorageDirectory(){ return null; } + public static String DIRECTORY_ALARMS = null; + public static String DIRECTORY_AUDIOBOOKS = null; + public static String DIRECTORY_DCIM = null; + public static String DIRECTORY_DOCUMENTS = null; + public static String DIRECTORY_DOWNLOADS = null; + public static String DIRECTORY_MOVIES = null; + public static String DIRECTORY_MUSIC = null; + public static String DIRECTORY_NOTIFICATIONS = null; + public static String DIRECTORY_PICTURES = null; + public static String DIRECTORY_PODCASTS = null; + public static String DIRECTORY_RINGTONES = null; + public static String DIRECTORY_SCREENSHOTS = null; + public static String MEDIA_BAD_REMOVAL = null; + public static String MEDIA_CHECKING = null; + public static String MEDIA_EJECTING = null; + public static String MEDIA_MOUNTED = null; + public static String MEDIA_MOUNTED_READ_ONLY = null; + public static String MEDIA_NOFS = null; + public static String MEDIA_REMOVED = null; + public static String MEDIA_SHARED = null; + public static String MEDIA_UNKNOWN = null; + public static String MEDIA_UNMOUNTABLE = null; + public static String MEDIA_UNMOUNTED = null; + public static String getExternalStorageState(){ return null; } + public static String getExternalStorageState(File p0){ return null; } + public static String getStorageState(File p0){ return null; } + public static boolean isExternalStorageEmulated(){ return false; } + public static boolean isExternalStorageEmulated(File p0){ return false; } + public static boolean isExternalStorageLegacy(){ return false; } + public static boolean isExternalStorageLegacy(File p0){ return false; } + public static boolean isExternalStorageManager(){ return false; } + public static boolean isExternalStorageManager(File p0){ return false; } + public static boolean isExternalStorageRemovable(){ return false; } + public static boolean isExternalStorageRemovable(File p0){ return false; } +} From cb717a22bf981f59a518b6f73f83a5677abdcad9 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 18 May 2022 17:49:38 +0100 Subject: [PATCH 135/465] Fix failing test cases --- .../frameworks/android/ExternalStorage.qll | 18 +++++++++++------- .../android/external-storage/Test.java | 14 +++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll index b52fad076ed..8fa914d6dfc 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll @@ -1,7 +1,7 @@ /** Provides definitions for working with uses of Android external storage */ import java -import semmle.code.java.dataflow.DataFlow +private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow private class ExternalStorageDirSourceModel extends SourceModelCsv { @@ -10,11 +10,11 @@ private class ExternalStorageDirSourceModel extends SourceModelCsv { [ //"package;type;overrides;name;signature;ext;spec;kind" "android.content;Context;true;getExternalFilesDir;(String);;ReturnValue;android-external-storage-dir", - "android.content;Context;true;getExternalFilesDirs;(String);;ReturnValue.ArrayElement;android-external-storage-dir", - "android.content;Context;true;getExternalCachesDir;(String);;ReturnValue;android-external-storage-dir", - "android.content;Context;true;getExternalCachesDirs;(String);;ReturnValue.ArrayElement;android-external-storage-dir", - "android.os;Environment;false;getExternalStorageDirectory;(String);;ReturnValue.ArrayElement;android-external-storage-dir", - "android.os;Environment;false;getExternalStoragePublicDirectory;(String);;ReturnValue.ArrayElement;android-external-storage-dir", + "android.content;Context;true;getExternalFilesDirs;(String);;ReturnValue;android-external-storage-dir", + "android.content;Context;true;getExternalCacheDir;();;ReturnValue;android-external-storage-dir", + "android.content;Context;true;getExternalCacheDirs;();;ReturnValue;android-external-storage-dir", + "android.os;Environment;false;getExternalStorageDirectory;();;ReturnValue;android-external-storage-dir", + "android.os;Environment;false;getExternalStoragePublicDirectory;(String);;ReturnValue;android-external-storage-dir", ] } } @@ -23,9 +23,13 @@ private predicate externalStorageFlowStep(DataFlow::Node node1, DataFlow::Node n DataFlow::localFlowStep(node1, node2) or exists(ConstructorCall c | c.getConstructedType() instanceof TypeFile | - node1.asExpr() = c.getArgument(1) and + node1.asExpr() = c.getArgument(0) and node2.asExpr() = c ) + or + node2.asExpr().(ArrayAccess).getArray() = node1.asExpr() + or + node2.asExpr().(FieldRead).getField().getInitializer() = node1.asExpr() } private predicate externalStorageFlow(DataFlow::Node node1, DataFlow::Node node2) { diff --git a/java/ql/test/library-tests/frameworks/android/external-storage/Test.java b/java/ql/test/library-tests/frameworks/android/external-storage/Test.java index 92eb50368ae..0955abc4828 100644 --- a/java/ql/test/library-tests/frameworks/android/external-storage/Test.java +++ b/java/ql/test/library-tests/frameworks/android/external-storage/Test.java @@ -13,39 +13,39 @@ class Test { InputStream is = new FileInputStream(f); byte[] data = new byte[is.available()]; is.read(data); - sink(data); // $hasTaintFlow + sink(data); // $ hasTaintFlow is.close(); } void test2(Context ctx) throws IOException { File f = new File(new File(new File(ctx.getExternalFilesDirs(null)[0], "things"), "stuff"), "file.txt"); - sink(new FileInputStream(f)); // $hasTaintFlow + sink(new FileInputStream(f)); // $ hasTaintFlow } void test3(Context ctx) throws IOException { File f = new File(ctx.getExternalCacheDir(), "file.txt"); - sink(new FileInputStream(f)); // $hasTaintFlow + sink(new FileInputStream(f)); // $ hasTaintFlow } void test4(Context ctx) throws IOException { File f = new File(ctx.getExternalCacheDirs()[0], "file.txt"); - sink(new FileInputStream(f)); // $hasTaintFlow + sink(new FileInputStream(f)); // $ hasTaintFlow } void test5(Context ctx) throws IOException { File f = new File(Environment.getExternalStorageDirectory(), "file.txt"); - sink(new FileInputStream(f)); // $hasTaintFlow + sink(new FileInputStream(f)); // $ hasTaintFlow } void test6(Context ctx) throws IOException { File f = new File(Environment.getExternalStoragePublicDirectory(null), "file.txt"); - sink(new FileInputStream(f)); // $hasTaintFlow + sink(new FileInputStream(f)); // $ hasTaintFlow } static final File dir = Environment.getExternalStorageDirectory(); void test7(Context ctx) throws IOException { File f = new File(dir, "file.txt"); - sink(new FileInputStream(f)); // $hasTaintFlow + sink(new FileInputStream(f)); // $ hasTaintFlow } } \ No newline at end of file From 58fba206899202d17980b3c18184d273e9fa5455 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 18 May 2022 17:59:01 +0100 Subject: [PATCH 136/465] Add change note --- .../lib/change-notes/2022-05-18-android-external-storage.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2022-05-18-android-external-storage.md diff --git a/java/ql/lib/change-notes/2022-05-18-android-external-storage.md b/java/ql/lib/change-notes/2022-05-18-android-external-storage.md new file mode 100644 index 00000000000..b3d5fa793b3 --- /dev/null +++ b/java/ql/lib/change-notes/2022-05-18-android-external-storage.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +Added additional flow sources for uses of external storage on Android. \ No newline at end of file From a41f28ebe5902a656050753fa6ecb3f89da70da2 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Fri, 20 May 2022 16:27:45 +0100 Subject: [PATCH 137/465] Use more file openning methods --- .../frameworks/android/ExternalStorage.qll | 8 +++---- .../code/java/security/FileReadWrite.qll | 23 +++++++++++++++++-- .../android/external-storage/Test.java | 8 +++++++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll index 8fa914d6dfc..dd1c680641d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll @@ -1,6 +1,7 @@ /** Provides definitions for working with uses of Android external storage */ import java +private import semmle.code.java.security.FileReadWrite private import semmle.code.java.dataflow.DataFlow private import semmle.code.java.dataflow.ExternalFlow @@ -41,10 +42,9 @@ private predicate externalStorageFlow(DataFlow::Node node1, DataFlow::Node node2 * This is controlable by third-party applications, so is treated as a remote flow source. */ predicate androidExternalStorageSource(DataFlow::Node n) { - exists(ConstructorCall fInp, DataFlow::Node externalDir | - fInp.getConstructedType().hasQualifiedName("java.io", "FileInputStream") and - n.asExpr() = fInp and + exists(DataFlow::Node externalDir, DirectFileReadExpr read | sourceNode(externalDir, "android-external-storage-dir") and - externalStorageFlow(externalDir, DataFlow::exprNode(fInp.getArgument(0))) + n.asExpr() = read and + externalStorageFlow(externalDir, DataFlow::exprNode(read.getFileExpr())) ) } diff --git a/java/ql/lib/semmle/code/java/security/FileReadWrite.qll b/java/ql/lib/semmle/code/java/security/FileReadWrite.qll index e79f98bdca4..bcb2c378902 100644 --- a/java/ql/lib/semmle/code/java/security/FileReadWrite.qll +++ b/java/ql/lib/semmle/code/java/security/FileReadWrite.qll @@ -1,9 +1,9 @@ import java /** - * Holds if `fileAccess` is used in the `fileReadingExpr` to read the represented file. + * Holds if `fileAccess` is directly used in the `fileReadingExpr` to read the represented file. */ -private predicate fileRead(VarAccess fileAccess, Expr fileReadingExpr) { +predicate directFileRead(Expr fileAccess, Expr fileReadingExpr) { // `fileAccess` used to construct a class that reads a file. exists(ClassInstanceExpr cie | cie = fileReadingExpr and @@ -28,6 +28,13 @@ private predicate fileRead(VarAccess fileAccess, Expr fileReadingExpr) { ]) ) ) +} + +/** + * Holds if `fileAccess` is used in the `fileReadingExpr` to read the represented file. + */ +private predicate fileRead(VarAccess fileAccess, Expr fileReadingExpr) { + directFileRead(fileAccess, fileReadingExpr) or // The `fileAccess` is used in a call which directly or indirectly accesses the file. exists(Call call, int parameterPos, VarAccess nestedFileAccess, Expr nestedFileReadingExpr | @@ -49,3 +56,15 @@ class FileReadExpr extends Expr { */ VarAccess getFileVarAccess() { fileRead(result, this) } } + +/** + * An expression that directly reads from a file and returns its contents. + */ +class DirectFileReadExpr extends Expr { + DirectFileReadExpr() { directFileRead(_, this) } + + /** + * Gets the `Expr` representing the file that is read + */ + Expr getFileExpr() { directFileRead(result, this) } +} diff --git a/java/ql/test/library-tests/frameworks/android/external-storage/Test.java b/java/ql/test/library-tests/frameworks/android/external-storage/Test.java index 0955abc4828..2b4aec0c86a 100644 --- a/java/ql/test/library-tests/frameworks/android/external-storage/Test.java +++ b/java/ql/test/library-tests/frameworks/android/external-storage/Test.java @@ -2,6 +2,8 @@ import java.io.File; import java.io.InputStream; import java.io.FileInputStream; import java.io.IOException; +import java.io.FileReader; +import java.io.RandomAccessFile; import android.content.Context; import android.os.Environment; @@ -48,4 +50,10 @@ class Test { File f = new File(dir, "file.txt"); sink(new FileInputStream(f)); // $ hasTaintFlow } + + void test8() throws IOException { + File f = new File(dir, "file.txt"); + sink(new FileReader(f)); // $ hasTaintFlow + sink(new RandomAccessFile(f, "r")); // $ hasTaintFlow + } } \ No newline at end of file From 55e78e3e25b03565fb7e05191d7d693029f1728c Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Tue, 24 May 2022 13:53:51 +0100 Subject: [PATCH 138/465] Minor doc fixes + making directFileRead private --- .../semmle/code/java/frameworks/android/ExternalStorage.qll | 2 +- java/ql/lib/semmle/code/java/security/FileReadWrite.qll | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll index dd1c680641d..364145cd430 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll @@ -39,7 +39,7 @@ private predicate externalStorageFlow(DataFlow::Node node1, DataFlow::Node node2 /** * Holds if `n` is a node that reads the contents of an external file in Android. - * This is controlable by third-party applications, so is treated as a remote flow source. + * This is controllable by third-party applications, so is treated as a remote flow source. */ predicate androidExternalStorageSource(DataFlow::Node n) { exists(DataFlow::Node externalDir, DirectFileReadExpr read | diff --git a/java/ql/lib/semmle/code/java/security/FileReadWrite.qll b/java/ql/lib/semmle/code/java/security/FileReadWrite.qll index bcb2c378902..84be71d6a04 100644 --- a/java/ql/lib/semmle/code/java/security/FileReadWrite.qll +++ b/java/ql/lib/semmle/code/java/security/FileReadWrite.qll @@ -3,7 +3,7 @@ import java /** * Holds if `fileAccess` is directly used in the `fileReadingExpr` to read the represented file. */ -predicate directFileRead(Expr fileAccess, Expr fileReadingExpr) { +private predicate directFileRead(Expr fileAccess, Expr fileReadingExpr) { // `fileAccess` used to construct a class that reads a file. exists(ClassInstanceExpr cie | cie = fileReadingExpr and @@ -64,7 +64,7 @@ class DirectFileReadExpr extends Expr { DirectFileReadExpr() { directFileRead(_, this) } /** - * Gets the `Expr` representing the file that is read + * Gets the `Expr` representing the file that is read. */ Expr getFileExpr() { directFileRead(result, this) } } From 49b419c52ec0cacafc66631819e18c46e24b0240 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Wed, 22 Jun 2022 14:29:41 +0100 Subject: [PATCH 139/465] Update models to include `manual` tag --- .../code/java/frameworks/android/ExternalStorage.qll | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll index 364145cd430..1e6919c023b 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/ExternalStorage.qll @@ -10,12 +10,12 @@ private class ExternalStorageDirSourceModel extends SourceModelCsv { row = [ //"package;type;overrides;name;signature;ext;spec;kind" - "android.content;Context;true;getExternalFilesDir;(String);;ReturnValue;android-external-storage-dir", - "android.content;Context;true;getExternalFilesDirs;(String);;ReturnValue;android-external-storage-dir", - "android.content;Context;true;getExternalCacheDir;();;ReturnValue;android-external-storage-dir", - "android.content;Context;true;getExternalCacheDirs;();;ReturnValue;android-external-storage-dir", - "android.os;Environment;false;getExternalStorageDirectory;();;ReturnValue;android-external-storage-dir", - "android.os;Environment;false;getExternalStoragePublicDirectory;(String);;ReturnValue;android-external-storage-dir", + "android.content;Context;true;getExternalFilesDir;(String);;ReturnValue;android-external-storage-dir;manual", + "android.content;Context;true;getExternalFilesDirs;(String);;ReturnValue;android-external-storage-dir;manual", + "android.content;Context;true;getExternalCacheDir;();;ReturnValue;android-external-storage-dir;manual", + "android.content;Context;true;getExternalCacheDirs;();;ReturnValue;android-external-storage-dir;manual", + "android.os;Environment;false;getExternalStorageDirectory;();;ReturnValue;android-external-storage-dir;manual", + "android.os;Environment;false;getExternalStoragePublicDirectory;(String);;ReturnValue;android-external-storage-dir;manual", ] } } From e0b4c63a5368a9024d90a726b4ccff6cb7d4d202 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 28 Jun 2022 10:16:40 +0200 Subject: [PATCH 140/465] Add new source kind to CsvValidation --- java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll index f518dbd2802..e8c1034a83a 100644 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll @@ -647,7 +647,7 @@ module CsvValidation { or exists(string row, string kind | sourceModel(row) | kind = row.splitAt(";", 7) and - not kind = ["remote", "contentprovider", "android-widget"] and + not kind = ["remote", "contentprovider", "android-widget", "android-external-storage-dir"] and not kind.matches("qltest%") and msg = "Invalid kind \"" + kind + "\" in source model." ) From c1a2e2abe06bbdc533bb434150b9c00e7743d07c Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 28 Jun 2022 10:21:33 +0200 Subject: [PATCH 141/465] JS: Rename to `isLikelyCaseSensitiveRegExp` --- .../ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql index a497f03f076..df3beecfb13 100644 --- a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql @@ -27,10 +27,10 @@ RegExpCharacterClass getEnclosingClass(RegExpTerm term) { } /** - * Holds if `term` distinguishes between upper and lower case letters, assuming the `i` flag is not present. + * Holds if `term` seems to distinguish between upper and lower case letters, assuming the `i` flag is not present. */ pragma[inline] -predicate isCaseSensitiveRegExp(RegExpTerm term) { +predicate isLikelyCaseSensitiveRegExp(RegExpTerm term) { exists(RegExpConstant const | const = term.getAChild*() and const.getValue().regexpMatch(".*[a-zA-Z].*") and @@ -89,7 +89,7 @@ predicate isCaseSensitiveMiddleware( ) and arg = call.getArgument(0) and regexp.getAReference().flowsTo(arg) and - isCaseSensitiveRegExp(regexp.getRoot()) and + isLikelyCaseSensitiveRegExp(regexp.getRoot()) and exists(string flags | flags = regexp.getFlags() and not RegExp::isIgnoreCase(flags) From c33690381eca82f3292f0bd526cba5e9b7780d97 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 28 Jun 2022 10:21:44 +0200 Subject: [PATCH 142/465] JS: Add explicit 'this' --- javascript/ql/lib/semmle/javascript/frameworks/Express.qll | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll index 5a2ad7cc928..19616530763 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll @@ -1050,11 +1050,11 @@ module Express { } private class ResumeDispatchRefinement extends Routing::RouteHandler { - ResumeDispatchRefinement() { getFunction() instanceof RouteHandler } + ResumeDispatchRefinement() { this.getFunction() instanceof RouteHandler } - override predicate mayResumeDispatch() { getAParameter().getName() = "next" } + override predicate mayResumeDispatch() { this.getAParameter().getName() = "next" } - override predicate definitelyResumesDispatch() { getAParameter().getName() = "next" } + override predicate definitelyResumesDispatch() { this.getAParameter().getName() = "next" } } private class ExpressStaticResumeDispatchRefinement extends Routing::Node { From 6d25fb69882858862b7b2d2735611ceb933b179e Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 28 Jun 2022 11:27:28 +0200 Subject: [PATCH 143/465] Python: add change note --- python/ql/lib/change-notes/api-graph-api.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 python/ql/lib/change-notes/api-graph-api.md diff --git a/python/ql/lib/change-notes/api-graph-api.md b/python/ql/lib/change-notes/api-graph-api.md new file mode 100644 index 00000000000..caae8e33a70 --- /dev/null +++ b/python/ql/lib/change-notes/api-graph-api.md @@ -0,0 +1,10 @@ +--- +category: library +--- + +* The documentation of API graphs (the `API` module) has been expanded, and some of the members predicates of `API::Node` + have been renamed as follows: + - `getAnImmediateUse` -> `asSource` + - `getARhs` -> `asSink` + - `getAUse` -> `getAValueReachableFromSource` + - `getAValueReachingRhs` -> `getAValueReachingSink` From d9f57e6d23d0d430b37d5a1b4828b675f6d007f6 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 28 Jun 2022 11:41:07 +0200 Subject: [PATCH 144/465] Python: rename change note file --- .../{api-graph-api.md => 2022-28-06-api-graph-api.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/lib/change-notes/{api-graph-api.md => 2022-28-06-api-graph-api.md} (100%) diff --git a/python/ql/lib/change-notes/api-graph-api.md b/python/ql/lib/change-notes/2022-28-06-api-graph-api.md similarity index 100% rename from python/ql/lib/change-notes/api-graph-api.md rename to python/ql/lib/change-notes/2022-28-06-api-graph-api.md From f2b589743a3fe9431f0deafa8e2e5562989e7110 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 28 Jun 2022 11:51:06 +0200 Subject: [PATCH 145/465] Swift: add possibility to collapse class hierarchy in tests --- swift/codegen/generators/qlgen.py | 23 ++++++-- swift/codegen/lib/ql.py | 6 ++- swift/codegen/test/test_qlgen.py | 54 ++++++++++++++++--- .../extractor-tests/generated/File/File.ql | 5 +- .../generated/Location/MISSING_SOURCE.txt | 4 ++ .../decl/AccessorDecl/AccessorDecl.ql | 9 ++-- .../AccessorDecl/AccessorDecl_getLocation.ql | 7 +++ .../AssociatedTypeDecl/AssociatedTypeDecl.ql | 5 +- .../AssociatedTypeDecl_getLocation.ql | 7 +++ .../generated/decl/ClassDecl/ClassDecl.ql | 6 ++- .../decl/ClassDecl/ClassDecl_getLocation.ql | 7 +++ .../decl/ConcreteFuncDecl/ConcreteFuncDecl.ql | 5 +- .../ConcreteFuncDecl_getLocation.ql | 7 +++ .../generated/decl/EnumDecl/EnumDecl.ql | 6 ++- .../decl/EnumDecl/EnumDecl_getLocation.ql | 7 +++ .../BridgeFromObjCExpr/MISSING_SOURCE.txt | 4 ++ .../expr/BridgeToObjCExpr/BridgeToObjCExpr.ql | 11 ++++ .../BridgeToObjCExpr_getLocation.ql | 7 +++ .../BridgeToObjCExpr_getType.ql | 7 +++ .../MISSING_SOURCE.txt | 4 ++ .../generated/expr/DotSelfExpr/DotSelfExpr.ql | 5 +- .../DotSelfExpr/DotSelfExpr_getLocation.ql | 7 +++ .../expr/ErrorExpr/MISSING_SOURCE.txt | 4 ++ .../expr/ObjCSelectorExpr/MISSING_SOURCE.txt | 4 ++ .../expr/SequenceExpr/MISSING_SOURCE.txt | 4 ++ .../UnresolvedDeclRefExpr/MISSING_SOURCE.txt | 4 ++ .../UnresolvedDotExpr/UnresolvedDotExpr.ql | 5 +- .../UnresolvedDotExpr_getLocation.ql | 7 +++ .../UnresolvedMemberExpr/MISSING_SOURCE.txt | 4 ++ .../UnresolvedPatternExpr/MISSING_SOURCE.txt | 4 ++ .../MISSING_SOURCE.txt | 4 ++ .../type/DynamicSelfType/DynamicSelfType.ql | 9 ++-- .../type/ExistentialType/ExistentialType.ql | 9 ++-- .../generated/type/InOutType/InOutType.ql | 9 ++-- .../NestedArchetypeType.ql | 12 +++-- .../PrimaryArchetypeType.ql | 9 ++-- .../UnmanagedStorageType.ql | 9 ++-- .../UnownedStorageType/UnownedStorageType.ql | 9 ++-- .../VariadicSequenceType.ql | 9 ++-- .../type/WeakStorageType/WeakStorageType.ql | 9 ++-- 40 files changed, 267 insertions(+), 60 deletions(-) create mode 100644 swift/ql/test/extractor-tests/generated/Location/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getLocation.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl_getLocation.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl_getLocation.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl_getLocation.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl_getLocation.ql create mode 100644 swift/ql/test/extractor-tests/generated/expr/BridgeFromObjCExpr/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr.ql create mode 100644 swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getLocation.ql create mode 100644 swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getType.ql create mode 100644 swift/ql/test/extractor-tests/generated/expr/ConditionalBridgeFromObjCExpr/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr_getLocation.ql create mode 100644 swift/ql/test/extractor-tests/generated/expr/ErrorExpr/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/expr/ObjCSelectorExpr/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/expr/SequenceExpr/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getLocation.ql create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedMemberExpr/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedSpecializeExpr/MISSING_SOURCE.txt diff --git a/swift/codegen/generators/qlgen.py b/swift/codegen/generators/qlgen.py index 26cce2ec430..b2e65cf86cb 100755 --- a/swift/codegen/generators/qlgen.py +++ b/swift/codegen/generators/qlgen.py @@ -30,7 +30,7 @@ class ModifiedStubMarkedAsGeneratedError(Error): def get_ql_property(cls: schema.Class, prop: schema.Property): common_args = dict( type=prop.type if not prop.is_predicate else "predicate", - skip_qltest="skip_qltest" in prop.pragmas, + qltest_skip="qltest_skip" in prop.pragmas, is_child=prop.is_child, is_optional=prop.is_optional, is_predicate=prop.is_predicate, @@ -69,13 +69,14 @@ def get_ql_property(cls: schema.Class, prop: schema.Property): def get_ql_class(cls: schema.Class): + pragmas = {k: True for k in cls.pragmas if k.startswith("ql")} return ql.Class( name=cls.name, bases=cls.bases, final=not cls.derived, properties=[get_ql_property(cls, p) for p in cls.properties], dir=cls.dir, - skip_qltest="skip_qltest" in cls.pragmas, + **pragmas, ) @@ -143,7 +144,7 @@ def _get_all_properties_to_be_tested(cls: ql.Class, lookup: typing.Dict[str, ql. # deduplicate using id already_seen = set() for c, p in _get_all_properties(cls, lookup): - if not (c.skip_qltest or p.skip_qltest or id(p) in already_seen): + if not (c.qltest_skip or p.qltest_skip or id(p) in already_seen): already_seen.add(id(p)) yield ql.PropertyForTest(p.getter, p.type, p.is_single, p.is_predicate, p.is_repeated) @@ -156,6 +157,20 @@ def _partition(l, pred): return res +def _is_in_qltest_collapsed_hierachy(cls: ql.Class, lookup: typing.Dict[str, ql.Class]): + return cls.qltest_collapse_hierarchy or _is_under_qltest_collapsed_hierachy(cls, lookup) + + +def _is_under_qltest_collapsed_hierachy(cls: ql.Class, lookup: typing.Dict[str, ql.Class]): + return not cls.qltest_uncollapse_hierarchy and any( + _is_in_qltest_collapsed_hierachy(lookup[b], lookup) for b in cls.bases) + + +def _should_skip_qltest(cls: ql.Class, lookup: typing.Dict[str, ql.Class]): + return cls.qltest_skip or not (cls.final or cls.qltest_collapse_hierarchy) or _is_under_qltest_collapsed_hierachy( + cls, lookup) + + def generate(opts, renderer): input = opts.schema out = opts.ql_output @@ -196,7 +211,7 @@ def generate(opts, renderer): classes), out / 'GetImmediateParent.qll') for c in classes: - if not c.final or c.skip_qltest: + if _should_skip_qltest(c, lookup): continue test_dir = test_out / c.path test_dir.mkdir(parents=True, exist_ok=True) diff --git a/swift/codegen/lib/ql.py b/swift/codegen/lib/ql.py index ce8dbed3a90..1635fd70689 100644 --- a/swift/codegen/lib/ql.py +++ b/swift/codegen/lib/ql.py @@ -37,7 +37,7 @@ class Property: is_optional: bool = False is_predicate: bool = False is_child: bool = False - skip_qltest: bool = False + qltest_skip: bool = False def __post_init__(self): if self.tableparams: @@ -79,7 +79,9 @@ class Class: properties: List[Property] = field(default_factory=list) dir: pathlib.Path = pathlib.Path() imports: List[str] = field(default_factory=list) - skip_qltest: bool = False + qltest_skip: bool = False + qltest_collapse_hierarchy: bool = False + qltest_uncollapse_hierarchy: bool = False def __post_init__(self): self.bases = sorted(self.bases) diff --git a/swift/codegen/test/test_qlgen.py b/swift/codegen/test/test_qlgen.py index 78f67012077..f861d14f2de 100644 --- a/swift/codegen/test/test_qlgen.py +++ b/swift/codegen/test/test_qlgen.py @@ -480,13 +480,13 @@ def test_test_properties_skipped(opts, generate_tests): write(opts.ql_test_output / "Derived" / "test.swift") assert generate_tests([ schema.Class("Base", derived={"Derived"}, properties=[ - schema.SingleProperty("x", "string", pragmas=["skip_qltest", "foo"]), - schema.RepeatedProperty("y", "int", pragmas=["bar", "skip_qltest"]), + schema.SingleProperty("x", "string", pragmas=["qltest_skip", "foo"]), + schema.RepeatedProperty("y", "int", pragmas=["bar", "qltest_skip"]), ]), schema.Class("Derived", bases={"Base"}, properties=[ - schema.PredicateProperty("a", pragmas=["skip_qltest"]), + schema.PredicateProperty("a", pragmas=["qltest_skip"]), schema.OptionalProperty( - "b", "int", pragmas=["bar", "skip_qltest", "baz"]), + "b", "int", pragmas=["bar", "qltest_skip", "baz"]), ]), ]) == { "Derived/Derived.ql": ql.ClassTester(class_name="Derived"), @@ -496,7 +496,7 @@ def test_test_properties_skipped(opts, generate_tests): def test_test_base_class_skipped(opts, generate_tests): write(opts.ql_test_output / "Derived" / "test.swift") assert generate_tests([ - schema.Class("Base", derived={"Derived"}, pragmas=["skip_qltest", "foo"], properties=[ + schema.Class("Base", derived={"Derived"}, pragmas=["qltest_skip", "foo"], properties=[ schema.SingleProperty("x", "string"), schema.RepeatedProperty("y", "int"), ]), @@ -510,12 +510,54 @@ def test_test_final_class_skipped(opts, generate_tests): write(opts.ql_test_output / "Derived" / "test.swift") assert generate_tests([ schema.Class("Base", derived={"Derived"}), - schema.Class("Derived", bases={"Base"}, pragmas=["skip_qltest", "foo"], properties=[ + schema.Class("Derived", bases={"Base"}, pragmas=["qltest_skip", "foo"], properties=[ schema.SingleProperty("x", "string"), schema.RepeatedProperty("y", "int"), ]), ]) == {} +def test_test_class_hierarchy_collapse(opts, generate_tests): + write(opts.ql_test_output / "Base" / "test.swift") + assert generate_tests([ + schema.Class("Base", derived={"D1", "D2"}, pragmas=["foo", "qltest_collapse_hierarchy"]), + schema.Class("D1", bases={"Base"}, properties=[schema.SingleProperty("x", "string")]), + schema.Class("D2", bases={"Base"}, derived={"D3"}, properties=[schema.SingleProperty("y", "string")]), + schema.Class("D3", bases={"D2"}, properties=[schema.SingleProperty("z", "string")]), + ]) == { + "Base/Base.ql": ql.ClassTester(class_name="Base"), + } + + +def test_test_class_hierarchy_uncollapse(opts, generate_tests): + for d in ("Base", "D3", "D4"): + write(opts.ql_test_output / d / "test.swift") + assert generate_tests([ + schema.Class("Base", derived={"D1", "D2"}, pragmas=["foo", "qltest_collapse_hierarchy"]), + schema.Class("D1", bases={"Base"}, properties=[schema.SingleProperty("x", "string")]), + schema.Class("D2", bases={"Base"}, derived={"D3", "D4"}, pragmas=["qltest_uncollapse_hierarchy", "bar"]), + schema.Class("D3", bases={"D2"}), + schema.Class("D4", bases={"D2"}), + ]) == { + "Base/Base.ql": ql.ClassTester(class_name="Base"), + "D3/D3.ql": ql.ClassTester(class_name="D3"), + "D4/D4.ql": ql.ClassTester(class_name="D4"), + } + + +def test_test_class_hierarchy_uncollapse_at_final(opts, generate_tests): + for d in ("Base", "D3"): + write(opts.ql_test_output / d / "test.swift") + assert generate_tests([ + schema.Class("Base", derived={"D1", "D2"}, pragmas=["foo", "qltest_collapse_hierarchy"]), + schema.Class("D1", bases={"Base"}, properties=[schema.SingleProperty("x", "string")]), + schema.Class("D2", bases={"Base"}, derived={"D3"}), + schema.Class("D3", bases={"D2"}, pragmas=["qltest_uncollapse_hierarchy", "bar"]), + ]) == { + "Base/Base.ql": ql.ClassTester(class_name="Base"), + "D3/D3.ql": ql.ClassTester(class_name="D3"), + } + + if __name__ == '__main__': sys.exit(pytest.main([__file__] + sys.argv[1:])) diff --git a/swift/ql/test/extractor-tests/generated/File/File.ql b/swift/ql/test/extractor-tests/generated/File/File.ql index 158dca707f5..9307342f2ff 100644 --- a/swift/ql/test/extractor-tests/generated/File/File.ql +++ b/swift/ql/test/extractor-tests/generated/File/File.ql @@ -2,9 +2,10 @@ import codeql.swift.elements import TestUtils -from File x, string getName +from File x, string isUnknown, string getName where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getName = x.getName() -select x, "getName:", getName +select x, "isUnknown:", isUnknown, "getName:", getName diff --git a/swift/ql/test/extractor-tests/generated/Location/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/Location/MISSING_SOURCE.txt new file mode 100644 index 00000000000..0d319d9a669 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/Location/MISSING_SOURCE.txt @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py + +After a swift source file is added in this directory and codegen/codegen.py is run again, test queries +will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql index 34180566f00..99207338efe 100644 --- a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql +++ b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql @@ -3,16 +3,17 @@ import codeql.swift.elements import TestUtils from - AccessorDecl x, Type getInterfaceType, string getName, string isGetter, string isSetter, - string isWillSet, string isDidSet + AccessorDecl x, string isUnknown, Type getInterfaceType, string getName, string isGetter, + string isSetter, string isWillSet, string isDidSet where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getInterfaceType = x.getInterfaceType() and getName = x.getName() and (if x.isGetter() then isGetter = "yes" else isGetter = "no") and (if x.isSetter() then isSetter = "yes" else isSetter = "no") and (if x.isWillSet() then isWillSet = "yes" else isWillSet = "no") and if x.isDidSet() then isDidSet = "yes" else isDidSet = "no" -select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "isGetter:", isGetter, - "isSetter:", isSetter, "isWillSet:", isWillSet, "isDidSet:", isDidSet +select x, "isUnknown:", isUnknown, "getInterfaceType:", getInterfaceType, "getName:", getName, + "isGetter:", isGetter, "isSetter:", isSetter, "isWillSet:", isWillSet, "isDidSet:", isDidSet diff --git a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getLocation.ql b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getLocation.ql new file mode 100644 index 00000000000..92be90de057 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getLocation.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from AccessorDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl.ql b/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl.ql index d49e513615c..5db864bfc22 100644 --- a/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl.ql +++ b/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl.ql @@ -2,10 +2,11 @@ import codeql.swift.elements import TestUtils -from AssociatedTypeDecl x, Type getInterfaceType, string getName +from AssociatedTypeDecl x, string isUnknown, Type getInterfaceType, string getName where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getInterfaceType = x.getInterfaceType() and getName = x.getName() -select x, "getInterfaceType:", getInterfaceType, "getName:", getName +select x, "isUnknown:", isUnknown, "getInterfaceType:", getInterfaceType, "getName:", getName diff --git a/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl_getLocation.ql b/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl_getLocation.ql new file mode 100644 index 00000000000..0a3561ae7b1 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl_getLocation.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from AssociatedTypeDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl.ql index 89f9f86507f..9cef07648fa 100644 --- a/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl.ql +++ b/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl.ql @@ -2,11 +2,13 @@ import codeql.swift.elements import TestUtils -from ClassDecl x, Type getInterfaceType, string getName, Type getType +from ClassDecl x, string isUnknown, Type getInterfaceType, string getName, Type getType where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getInterfaceType = x.getInterfaceType() and getName = x.getName() and getType = x.getType() -select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "getType:", getType +select x, "isUnknown:", isUnknown, "getInterfaceType:", getInterfaceType, "getName:", getName, + "getType:", getType diff --git a/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl_getLocation.ql b/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl_getLocation.ql new file mode 100644 index 00000000000..3231b1dd58a --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl_getLocation.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ClassDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl.ql index 7b10f703bff..28736643fdb 100644 --- a/swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl.ql +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl.ql @@ -2,10 +2,11 @@ import codeql.swift.elements import TestUtils -from ConcreteFuncDecl x, Type getInterfaceType, string getName +from ConcreteFuncDecl x, string isUnknown, Type getInterfaceType, string getName where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getInterfaceType = x.getInterfaceType() and getName = x.getName() -select x, "getInterfaceType:", getInterfaceType, "getName:", getName +select x, "isUnknown:", isUnknown, "getInterfaceType:", getInterfaceType, "getName:", getName diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl_getLocation.ql b/swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl_getLocation.ql new file mode 100644 index 00000000000..eeb02bedc0f --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl_getLocation.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ConcreteFuncDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl.ql b/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl.ql index 6f5c19ec720..6575ebfb2cd 100644 --- a/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl.ql +++ b/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl.ql @@ -2,11 +2,13 @@ import codeql.swift.elements import TestUtils -from EnumDecl x, Type getInterfaceType, string getName, Type getType +from EnumDecl x, string isUnknown, Type getInterfaceType, string getName, Type getType where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getInterfaceType = x.getInterfaceType() and getName = x.getName() and getType = x.getType() -select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "getType:", getType +select x, "isUnknown:", isUnknown, "getInterfaceType:", getInterfaceType, "getName:", getName, + "getType:", getType diff --git a/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl_getLocation.ql b/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl_getLocation.ql new file mode 100644 index 00000000000..4f8482a4e06 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl_getLocation.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from EnumDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/expr/BridgeFromObjCExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/BridgeFromObjCExpr/MISSING_SOURCE.txt new file mode 100644 index 00000000000..0d319d9a669 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/BridgeFromObjCExpr/MISSING_SOURCE.txt @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py + +After a swift source file is added in this directory and codegen/codegen.py is run again, test queries +will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr.ql b/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr.ql new file mode 100644 index 00000000000..7412b7819fe --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr.ql @@ -0,0 +1,11 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from BridgeToObjCExpr x, string isUnknown, Expr getSubExpr +where + toBeTested(x) and + not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and + getSubExpr = x.getSubExpr() +select x, "isUnknown:", isUnknown, "getSubExpr:", getSubExpr diff --git a/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getLocation.ql b/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getLocation.ql new file mode 100644 index 00000000000..605f328ed19 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getLocation.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from BridgeToObjCExpr x +where toBeTested(x) and not x.isUnknown() +select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getType.ql b/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getType.ql new file mode 100644 index 00000000000..077a2a9e82e --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from BridgeToObjCExpr x +where toBeTested(x) and not x.isUnknown() +select x, x.getType() diff --git a/swift/ql/test/extractor-tests/generated/expr/ConditionalBridgeFromObjCExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/ConditionalBridgeFromObjCExpr/MISSING_SOURCE.txt new file mode 100644 index 00000000000..0d319d9a669 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/ConditionalBridgeFromObjCExpr/MISSING_SOURCE.txt @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py + +After a swift source file is added in this directory and codegen/codegen.py is run again, test queries +will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr.ql b/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr.ql index 91ec5342fb6..3c66ef1f469 100644 --- a/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr.ql +++ b/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr.ql @@ -2,9 +2,10 @@ import codeql.swift.elements import TestUtils -from DotSelfExpr x, Expr getSubExpr +from DotSelfExpr x, string isUnknown, Expr getSubExpr where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getSubExpr = x.getSubExpr() -select x, "getSubExpr:", getSubExpr +select x, "isUnknown:", isUnknown, "getSubExpr:", getSubExpr diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr_getLocation.ql b/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr_getLocation.ql new file mode 100644 index 00000000000..a337b217c60 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr_getLocation.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from DotSelfExpr x +where toBeTested(x) and not x.isUnknown() +select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/expr/ErrorExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/ErrorExpr/MISSING_SOURCE.txt new file mode 100644 index 00000000000..0d319d9a669 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/ErrorExpr/MISSING_SOURCE.txt @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py + +After a swift source file is added in this directory and codegen/codegen.py is run again, test queries +will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/ObjCSelectorExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/ObjCSelectorExpr/MISSING_SOURCE.txt new file mode 100644 index 00000000000..0d319d9a669 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/ObjCSelectorExpr/MISSING_SOURCE.txt @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py + +After a swift source file is added in this directory and codegen/codegen.py is run again, test queries +will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/SequenceExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/SequenceExpr/MISSING_SOURCE.txt new file mode 100644 index 00000000000..0d319d9a669 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/SequenceExpr/MISSING_SOURCE.txt @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py + +After a swift source file is added in this directory and codegen/codegen.py is run again, test queries +will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/MISSING_SOURCE.txt new file mode 100644 index 00000000000..0d319d9a669 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/MISSING_SOURCE.txt @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py + +After a swift source file is added in this directory and codegen/codegen.py is run again, test queries +will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql index 29327a3f86c..774f1119727 100644 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql @@ -2,10 +2,11 @@ import codeql.swift.elements import TestUtils -from UnresolvedDotExpr x, Expr getBase, string getName +from UnresolvedDotExpr x, string isUnknown, Expr getBase, string getName where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getBase = x.getBase() and getName = x.getName() -select x, "getBase:", getBase, "getName:", getName +select x, "isUnknown:", isUnknown, "getBase:", getBase, "getName:", getName diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getLocation.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getLocation.ql new file mode 100644 index 00000000000..562131422a2 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getLocation.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from UnresolvedDotExpr x +where toBeTested(x) and not x.isUnknown() +select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedMemberExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/UnresolvedMemberExpr/MISSING_SOURCE.txt new file mode 100644 index 00000000000..0d319d9a669 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedMemberExpr/MISSING_SOURCE.txt @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py + +After a swift source file is added in this directory and codegen/codegen.py is run again, test queries +will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/MISSING_SOURCE.txt new file mode 100644 index 00000000000..0d319d9a669 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/MISSING_SOURCE.txt @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py + +After a swift source file is added in this directory and codegen/codegen.py is run again, test queries +will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedSpecializeExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/UnresolvedSpecializeExpr/MISSING_SOURCE.txt new file mode 100644 index 00000000000..0d319d9a669 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedSpecializeExpr/MISSING_SOURCE.txt @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py + +After a swift source file is added in this directory and codegen/codegen.py is run again, test queries +will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql b/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql index a9ae23f6bab..68468498ea9 100644 --- a/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql +++ b/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql @@ -2,12 +2,15 @@ import codeql.swift.elements import TestUtils -from DynamicSelfType x, string getDiagnosticsName, Type getCanonicalType, Type getStaticSelfType +from + DynamicSelfType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, + Type getStaticSelfType where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getStaticSelfType = x.getStaticSelfType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getStaticSelfType:", getStaticSelfType +select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", + getCanonicalType, "getStaticSelfType:", getStaticSelfType diff --git a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql index b679d5d89a2..22ad73eb91e 100644 --- a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql +++ b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql @@ -2,12 +2,15 @@ import codeql.swift.elements import TestUtils -from ExistentialType x, string getDiagnosticsName, Type getCanonicalType, Type getConstraint +from + ExistentialType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, + Type getConstraint where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getConstraint = x.getConstraint() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getConstraint:", getConstraint +select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", + getCanonicalType, "getConstraint:", getConstraint diff --git a/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql b/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql index 973d0257381..cb004070ca5 100644 --- a/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql +++ b/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql @@ -2,12 +2,15 @@ import codeql.swift.elements import TestUtils -from InOutType x, string getDiagnosticsName, Type getCanonicalType, Type getObjectType +from + InOutType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, + Type getObjectType where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getObjectType = x.getObjectType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getObjectType:", getObjectType +select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", + getCanonicalType, "getObjectType:", getObjectType diff --git a/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql b/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql index 8306bfeacac..e5862e67de7 100644 --- a/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql +++ b/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql @@ -3,17 +3,19 @@ import codeql.swift.elements import TestUtils from - NestedArchetypeType x, string getDiagnosticsName, Type getCanonicalType, string getName, - Type getInterfaceType, ArchetypeType getParent, AssociatedTypeDecl getAssociatedTypeDeclaration + NestedArchetypeType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, + string getName, Type getInterfaceType, ArchetypeType getParent, + AssociatedTypeDecl getAssociatedTypeDeclaration where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getName = x.getName() and getInterfaceType = x.getInterfaceType() and getParent = x.getParent() and getAssociatedTypeDeclaration = x.getAssociatedTypeDeclaration() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getName:", getName, "getInterfaceType:", getInterfaceType, "getParent:", getParent, - "getAssociatedTypeDeclaration:", getAssociatedTypeDeclaration +select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", + getCanonicalType, "getName:", getName, "getInterfaceType:", getInterfaceType, "getParent:", + getParent, "getAssociatedTypeDeclaration:", getAssociatedTypeDeclaration diff --git a/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql b/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql index 925bf85dcbf..63a04cfb03c 100644 --- a/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql +++ b/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql @@ -3,14 +3,15 @@ import codeql.swift.elements import TestUtils from - PrimaryArchetypeType x, string getDiagnosticsName, Type getCanonicalType, string getName, - Type getInterfaceType + PrimaryArchetypeType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, + string getName, Type getInterfaceType where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getName = x.getName() and getInterfaceType = x.getInterfaceType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getName:", getName, "getInterfaceType:", getInterfaceType +select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", + getCanonicalType, "getName:", getName, "getInterfaceType:", getInterfaceType diff --git a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql index 396988db25e..8f1acefdf8e 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql +++ b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql @@ -2,12 +2,15 @@ import codeql.swift.elements import TestUtils -from UnmanagedStorageType x, string getDiagnosticsName, Type getCanonicalType, Type getReferentType +from + UnmanagedStorageType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, + Type getReferentType where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getReferentType = x.getReferentType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getReferentType:", getReferentType +select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", + getCanonicalType, "getReferentType:", getReferentType diff --git a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql index 17744a437d7..fbe93938336 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql +++ b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql @@ -2,12 +2,15 @@ import codeql.swift.elements import TestUtils -from UnownedStorageType x, string getDiagnosticsName, Type getCanonicalType, Type getReferentType +from + UnownedStorageType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, + Type getReferentType where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getReferentType = x.getReferentType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getReferentType:", getReferentType +select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", + getCanonicalType, "getReferentType:", getReferentType diff --git a/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql b/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql index 5a89dbcafab..7dc29f0861c 100644 --- a/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql +++ b/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql @@ -2,12 +2,15 @@ import codeql.swift.elements import TestUtils -from VariadicSequenceType x, string getDiagnosticsName, Type getCanonicalType, Type getBaseType +from + VariadicSequenceType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, + Type getBaseType where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getBaseType = x.getBaseType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getBaseType:", getBaseType +select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", + getCanonicalType, "getBaseType:", getBaseType diff --git a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql index 3209b0e7d3d..03e8331f3ab 100644 --- a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql +++ b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql @@ -2,12 +2,15 @@ import codeql.swift.elements import TestUtils -from WeakStorageType x, string getDiagnosticsName, Type getCanonicalType, Type getReferentType +from + WeakStorageType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, + Type getReferentType where toBeTested(x) and not x.isUnknown() and + (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getReferentType = x.getReferentType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getReferentType:", getReferentType +select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", + getCanonicalType, "getReferentType:", getReferentType From b41cbaec33909a891103aa5961abc3b6c76701dc Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 28 Jun 2022 11:54:11 +0200 Subject: [PATCH 146/465] Swift: add possibility to add flags in tests --- swift/tools/qltest.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/swift/tools/qltest.sh b/swift/tools/qltest.sh index 59d576af431..2232350c5b0 100755 --- a/swift/tools/qltest.sh +++ b/swift/tools/qltest.sh @@ -7,5 +7,8 @@ QLTEST_LOG="$CODEQL_EXTRACTOR_SWIFT_LOG_DIR"/qltest.log export LD_LIBRARY_PATH="$CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM" for src in *.swift; do - "$CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM/extractor" -sdk "$CODEQL_EXTRACTOR_SWIFT_ROOT/qltest/$CODEQL_PLATFORM/sdk" -c -primary-file $src >> $QLTEST_LOG 2>&1 + opts=(-sdk "$CODEQL_EXTRACTOR_SWIFT_ROOT/qltest/$CODEQL_PLATFORM/sdk" -c -primary-file $src) + opts+=($(sed -n '1 s=//codeql-extractor-options:==p' $src)) + echo -e "calling extractor with flags: ${opts[@]}\n" >> $QLTEST_LOG + "$CODEQL_EXTRACTOR_SWIFT_ROOT/tools/$CODEQL_PLATFORM/extractor" "${opts[@]}" >> $QLTEST_LOG 2>&1 done From 57981384dfef209bfc508c787a5bfc7ef4bb647c Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 28 Jun 2022 11:57:11 +0200 Subject: [PATCH 147/465] Swift: extract ProtocolComposition- and BuiltinType --- swift/codegen/schema.yml | 29 ++++---- swift/extractor/visitors/TypeVisitor.cpp | 70 +++++++++++++++++++ swift/extractor/visitors/TypeVisitor.h | 28 ++++++++ .../swift/elements/type/ExistentialType.qll | 6 +- .../type/ProtocolCompositionType.qll | 11 +++ swift/ql/lib/swift.dbscheme | 7 ++ swift/ql/test/TestUtils.qll | 19 +++-- .../extractor-tests/generated/File/File.ql | 5 +- .../generated/Location/MISSING_SOURCE.txt | 4 -- .../decl/AccessorDecl/AccessorDecl.ql | 9 ++- .../AccessorDecl/AccessorDecl_getLocation.ql | 7 -- .../AssociatedTypeDecl/AssociatedTypeDecl.ql | 5 +- .../AssociatedTypeDecl_getLocation.ql | 7 -- .../generated/decl/ClassDecl/ClassDecl.ql | 6 +- .../decl/ClassDecl/ClassDecl_getLocation.ql | 7 -- .../decl/ConcreteFuncDecl/ConcreteFuncDecl.ql | 5 +- .../generated/decl/EnumDecl/EnumDecl.ql | 6 +- .../decl/EnumDecl/EnumDecl_getLocation.ql | 7 -- .../BridgeFromObjCExpr/MISSING_SOURCE.txt | 4 -- .../expr/BridgeToObjCExpr/BridgeToObjCExpr.ql | 11 --- .../BridgeToObjCExpr_getLocation.ql | 7 -- .../MISSING_SOURCE.txt | 4 -- .../generated/expr/DotSelfExpr/DotSelfExpr.ql | 5 +- .../DotSelfExpr/DotSelfExpr_getLocation.ql | 7 -- .../expr/ErrorExpr/MISSING_SOURCE.txt | 4 -- .../expr/ObjCSelectorExpr/MISSING_SOURCE.txt | 4 -- .../expr/SequenceExpr/MISSING_SOURCE.txt | 4 -- .../UnresolvedDeclRefExpr/MISSING_SOURCE.txt | 4 -- .../UnresolvedDotExpr/UnresolvedDotExpr.ql | 5 +- .../UnresolvedDotExpr_getLocation.ql | 7 -- .../UnresolvedMemberExpr/MISSING_SOURCE.txt | 4 -- .../UnresolvedPatternExpr/MISSING_SOURCE.txt | 4 -- .../MISSING_SOURCE.txt | 4 -- .../MISSING_SOURCE.txt | 4 -- .../MISSING_SOURCE.txt | 4 -- .../BuiltinExecutorType/MISSING_SOURCE.txt | 4 -- .../type/BuiltinFloatType/MISSING_SOURCE.txt | 4 -- .../MISSING_SOURCE.txt | 4 -- .../BuiltinIntegerType.expected | 5 ++ .../BuiltinIntegerType/BuiltinIntegerType.ql | 11 +++ .../BuiltinIntegerType_getWidth.expected | 4 ++ .../BuiltinIntegerType_getWidth.ql} | 4 +- .../BuiltinIntegerType/MISSING_SOURCE.txt | 4 -- .../builtin_integer_types.swift | 8 +++ .../type/BuiltinJobType/MISSING_SOURCE.txt | 4 -- .../MISSING_SOURCE.txt | 4 -- .../BuiltinRawPointerType/MISSING_SOURCE.txt | 4 -- .../MISSING_SOURCE.txt | 4 -- .../type/BuiltinType/BuiltinType.expected | 11 +++ .../generated/type/BuiltinType/BuiltinType.ql | 11 +++ .../type/BuiltinType/builtin_types.swift | 14 ++++ .../MISSING_SOURCE.txt | 4 -- .../type/BuiltinVectorType/MISSING_SOURCE.txt | 4 -- .../type/DynamicSelfType/DynamicSelfType.ql | 9 +-- .../ExistentialType/ExistentialType.expected | 1 + .../type/ExistentialType/ExistentialType.ql | 9 +-- .../ExistentialType/existential_types.swift | 3 + .../generated/type/InOutType/InOutType.ql | 9 +-- .../NestedArchetypeType.ql | 12 ++-- .../PrimaryArchetypeType.ql | 9 ++- .../MISSING_SOURCE.txt | 4 -- .../ProtocolCompositionType.expected | 4 ++ .../ProtocolCompositionType.ql | 11 +++ ...ProtocolCompositionType_getMember.expected | 9 +++ .../ProtocolCompositionType_getMember.ql} | 4 +- .../protocol_composition.swift | 13 ++++ .../UnmanagedStorageType.ql | 9 +-- .../UnownedStorageType/UnownedStorageType.ql | 9 +-- .../VariadicSequenceType.ql | 9 +-- .../type/WeakStorageType/WeakStorageType.ql | 9 +-- 70 files changed, 303 insertions(+), 262 deletions(-) delete mode 100644 swift/ql/test/extractor-tests/generated/Location/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getLocation.ql delete mode 100644 swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl_getLocation.ql delete mode 100644 swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl_getLocation.ql delete mode 100644 swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl_getLocation.ql delete mode 100644 swift/ql/test/extractor-tests/generated/expr/BridgeFromObjCExpr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr.ql delete mode 100644 swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getLocation.ql delete mode 100644 swift/ql/test/extractor-tests/generated/expr/ConditionalBridgeFromObjCExpr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr_getLocation.ql delete mode 100644 swift/ql/test/extractor-tests/generated/expr/ErrorExpr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/expr/ObjCSelectorExpr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/expr/SequenceExpr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getLocation.ql delete mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedMemberExpr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedSpecializeExpr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinBridgeObjectType/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinDefaultActorStorageType/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinExecutorType/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinFloatType/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinIntegerLiteralType/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.expected create mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.ql create mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.expected rename swift/ql/test/extractor-tests/generated/{expr/BridgeToObjCExpr/BridgeToObjCExpr_getType.ql => type/BuiltinIntegerType/BuiltinIntegerType_getWidth.ql} (71%) delete mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/builtin_integer_types.swift delete mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinJobType/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinNativeObjectType/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinRawPointerType/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinRawUnsafeContinuationType/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.expected create mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.ql create mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinType/builtin_types.swift delete mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinUnsafeValueBufferType/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/type/BuiltinVectorType/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.expected create mode 100644 swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.ql create mode 100644 swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.expected rename swift/ql/test/extractor-tests/generated/{decl/ConcreteFuncDecl/ConcreteFuncDecl_getLocation.ql => type/ProtocolCompositionType/ProtocolCompositionType_getMember.ql} (61%) create mode 100644 swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/protocol_composition.swift diff --git a/swift/codegen/schema.yml b/swift/codegen/schema.yml index ce071b930d2..b95fedc10a9 100644 --- a/swift/codegen/schema.yml +++ b/swift/codegen/schema.yml @@ -14,14 +14,14 @@ _directories: Element: is_unknown: predicate - _pragma: skip_qltest + _pragma: qltest_skip File: name: string Locatable: location: Location? - _pragma: skip_qltest + _pragma: qltest_skip Location: file: File @@ -29,7 +29,7 @@ Location: start_column: int end_line: int end_column: int - _pragma: skip_qltest + _pragma: qltest_skip Type: diagnostics_name: string @@ -85,6 +85,7 @@ AnyMetatypeType: BuiltinType: _extends: Type + _pragma: qltest_collapse_hierarchy DependentMemberType: _extends: Type @@ -114,6 +115,7 @@ PlaceholderType: ProtocolCompositionType: _extends: Type + members: Type* ExistentialType: _extends: Type @@ -393,7 +395,7 @@ EnumIsCaseExpr: ErrorExpr: _extends: Expr - _pragma: skip_qltest # unexpected emission + _pragma: qltest_skip # unexpected emission ExplicitCastExpr: _extends: Expr @@ -468,7 +470,7 @@ ObjCSelectorExpr: _children: sub_expr: Expr method: AbstractFunctionDecl - _pragma: skip_qltest # to be tested in integration tests + _pragma: qltest_skip # to be tested in integration tests OneWayExpr: _extends: Expr @@ -510,7 +512,7 @@ SequenceExpr: _extends: Expr _children: elements: Expr* - _pragma: skip_qltest # we should really never extract these, as these should be resolved to trees of operations + _pragma: qltest_skip # we should really never extract these, as these should be resolved to trees of operations SuperRefExpr: _extends: Expr @@ -542,7 +544,7 @@ TypeExpr: UnresolvedDeclRefExpr: _extends: Expr name: string? - _pragma: skip_qltest # we should really never extract these + _pragma: qltest_skip # we should really never extract these UnresolvedDotExpr: _extends: Expr @@ -553,15 +555,15 @@ UnresolvedDotExpr: UnresolvedMemberExpr: _extends: Expr name: string - _pragma: skip_qltest # we should really never extract these + _pragma: qltest_skip # we should really never extract these UnresolvedPatternExpr: _extends: Expr - _pragma: skip_qltest # we should really never extract these + _pragma: qltest_skip # we should really never extract these UnresolvedSpecializeExpr: _extends: Expr - _pragma: skip_qltest # we should really never extract these + _pragma: qltest_skip # we should really never extract these VarargExpansionExpr: _extends: Expr @@ -698,6 +700,7 @@ BuiltinIntegerLiteralType: BuiltinIntegerType: _extends: AnyBuiltinIntegerType + _pragma: qltest_uncollapse_hierarchy width: int? NestedArchetypeType: @@ -830,11 +833,11 @@ ArrayToPointerExpr: BridgeFromObjCExpr: _extends: ImplicitConversionExpr - _pragma: skip_qltest # to be tested in integration tests + _pragma: qltest_skip # to be tested in integration tests BridgeToObjCExpr: _extends: ImplicitConversionExpr - _pragma: skip_qltest # to be tested in integration tests + _pragma: qltest_skip # to be tested in integration tests ClassMetatypeToObjectExpr: _extends: ImplicitConversionExpr @@ -844,7 +847,7 @@ CollectionUpcastConversionExpr: ConditionalBridgeFromObjCExpr: _extends: ImplicitConversionExpr - _pragma: skip_qltest # to be tested in integration tests + _pragma: qltest_skip # to be tested in integration tests CovariantFunctionConversionExpr: _extends: ImplicitConversionExpr diff --git a/swift/extractor/visitors/TypeVisitor.cpp b/swift/extractor/visitors/TypeVisitor.cpp index 897cc58625e..807e484e2d3 100644 --- a/swift/extractor/visitors/TypeVisitor.cpp +++ b/swift/extractor/visitors/TypeVisitor.cpp @@ -304,4 +304,74 @@ void TypeVisitor::fillReferenceStorageType(const swift::ReferenceStorageType& ty fillType(type, entry); } +codeql::ProtocolCompositionType TypeVisitor::translateProtocolCompositionType( + const swift::ProtocolCompositionType& type) { + auto entry = createEntry(type); + entry.members = dispatcher_.fetchRepeatedLabels(type.getMembers()); + return entry; +} + +codeql::BuiltinIntegerLiteralType TypeVisitor::translateBuiltinIntegerLiteralType( + const swift::BuiltinIntegerLiteralType& type) { + return createEntry(type); +} + +codeql::BuiltinIntegerType TypeVisitor::translateBuiltinIntegerType( + const swift::BuiltinIntegerType& type) { + auto entry = createEntry(type); + if (type.isFixedWidth()) { + entry.width = type.getFixedWidth(); + } + return entry; +} + +codeql::BuiltinBridgeObjectType TypeVisitor::translateBuiltinBridgeObjectType( + const swift::BuiltinBridgeObjectType& type) { + return createEntry(type); +} + +codeql::BuiltinDefaultActorStorageType TypeVisitor::translateBuiltinDefaultActorStorageType( + const swift::BuiltinDefaultActorStorageType& type) { + return createEntry(type); +} + +codeql::BuiltinExecutorType TypeVisitor::translateBuiltinExecutorType( + const swift::BuiltinExecutorType& type) { + return createEntry(type); +} + +codeql::BuiltinFloatType TypeVisitor::translateBuiltinFloatType( + const swift::BuiltinFloatType& type) { + return createEntry(type); +} + +codeql::BuiltinJobType TypeVisitor::translateBuiltinJobType(const swift::BuiltinJobType& type) { + return createEntry(type); +} + +codeql::BuiltinNativeObjectType TypeVisitor::translateBuiltinNativeObjectType( + const swift::BuiltinNativeObjectType& type) { + return createEntry(type); +} + +codeql::BuiltinRawPointerType TypeVisitor::translateBuiltinRawPointerType( + const swift::BuiltinRawPointerType& type) { + return createEntry(type); +} + +codeql::BuiltinRawUnsafeContinuationType TypeVisitor::translateBuiltinRawUnsafeContinuationType( + const swift::BuiltinRawUnsafeContinuationType& type) { + return createEntry(type); +} + +codeql::BuiltinUnsafeValueBufferType TypeVisitor::translateBuiltinUnsafeValueBufferType( + const swift::BuiltinUnsafeValueBufferType& type) { + return createEntry(type); +} + +codeql::BuiltinVectorType TypeVisitor::translateBuiltinVectorType( + const swift::BuiltinVectorType& type) { + return createEntry(type); +} + } // namespace codeql diff --git a/swift/extractor/visitors/TypeVisitor.h b/swift/extractor/visitors/TypeVisitor.h index fa8c0d0ed09..99d1ca7fdbb 100644 --- a/swift/extractor/visitors/TypeVisitor.h +++ b/swift/extractor/visitors/TypeVisitor.h @@ -47,6 +47,27 @@ class TypeVisitor : public TypeVisitorBase { const swift::UnmanagedStorageType& type); codeql::WeakStorageType translateWeakStorageType(const swift::WeakStorageType& type); codeql::UnownedStorageType translateUnownedStorageType(const swift::UnownedStorageType& type); + codeql::ProtocolCompositionType translateProtocolCompositionType( + const swift::ProtocolCompositionType& type); + codeql::BuiltinIntegerLiteralType translateBuiltinIntegerLiteralType( + const swift::BuiltinIntegerLiteralType& type); + codeql::BuiltinIntegerType translateBuiltinIntegerType(const swift::BuiltinIntegerType& type); + codeql::BuiltinBridgeObjectType translateBuiltinBridgeObjectType( + const swift::BuiltinBridgeObjectType& type); + codeql::BuiltinDefaultActorStorageType translateBuiltinDefaultActorStorageType( + const swift::BuiltinDefaultActorStorageType& type); + codeql::BuiltinExecutorType translateBuiltinExecutorType(const swift::BuiltinExecutorType& type); + codeql::BuiltinFloatType translateBuiltinFloatType(const swift::BuiltinFloatType& type); + codeql::BuiltinJobType translateBuiltinJobType(const swift::BuiltinJobType& type); + codeql::BuiltinNativeObjectType translateBuiltinNativeObjectType( + const swift::BuiltinNativeObjectType& type); + codeql::BuiltinRawPointerType translateBuiltinRawPointerType( + const swift::BuiltinRawPointerType& type); + codeql::BuiltinRawUnsafeContinuationType translateBuiltinRawUnsafeContinuationType( + const swift::BuiltinRawUnsafeContinuationType& type); + codeql::BuiltinUnsafeValueBufferType translateBuiltinUnsafeValueBufferType( + const swift::BuiltinUnsafeValueBufferType& type); + codeql::BuiltinVectorType translateBuiltinVectorType(const swift::BuiltinVectorType& type); private: void fillType(const swift::TypeBase& type, codeql::Type& entry); @@ -58,6 +79,13 @@ class TypeVisitor : public TypeVisitorBase { void emitAnyFunctionType(const swift::AnyFunctionType* type, TrapLabel label); void emitBoundGenericType(swift::BoundGenericType* type, TrapLabel label); void emitAnyGenericType(swift::AnyGenericType* type, TrapLabel label); + + template + auto createEntry(const T& type) { + TrapClassOf entry{dispatcher_.assignNewLabel(type)}; + fillType(type, entry); + return entry; + } }; } // namespace codeql diff --git a/swift/ql/lib/codeql/swift/elements/type/ExistentialType.qll b/swift/ql/lib/codeql/swift/elements/type/ExistentialType.qll index 2f3241dcc44..6730daf49cf 100644 --- a/swift/ql/lib/codeql/swift/elements/type/ExistentialType.qll +++ b/swift/ql/lib/codeql/swift/elements/type/ExistentialType.qll @@ -1,6 +1,4 @@ +// generated by codegen/codegen.py, remove this comment if you wish to edit this file private import codeql.swift.generated.type.ExistentialType -private import codeql.swift.elements.type.ProtocolType -class ExistentialType extends ExistentialTypeBase { - override ProtocolType getConstraint() { result = super.getConstraint() } -} +class ExistentialType extends ExistentialTypeBase { } diff --git a/swift/ql/lib/codeql/swift/generated/type/ProtocolCompositionType.qll b/swift/ql/lib/codeql/swift/generated/type/ProtocolCompositionType.qll index 863f8c8ca8b..594338def93 100644 --- a/swift/ql/lib/codeql/swift/generated/type/ProtocolCompositionType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/ProtocolCompositionType.qll @@ -3,4 +3,15 @@ import codeql.swift.elements.type.Type class ProtocolCompositionTypeBase extends @protocol_composition_type, Type { override string getAPrimaryQlClass() { result = "ProtocolCompositionType" } + + Type getMember(int index) { + exists(Type x | + protocol_composition_type_members(this, index, x) and + result = x.resolve() + ) + } + + Type getAMember() { result = getMember(_) } + + int getNumberOfMembers() { result = count(getAMember()) } } diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index f306d471380..c726cd7635b 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -274,6 +274,13 @@ protocol_composition_types( //dir=type unique int id: @protocol_composition_type ); +#keyset[id, index] +protocol_composition_type_members( //dir=type + int id: @protocol_composition_type ref, + int index: int ref, + int member: @type ref +); + existential_types( //dir=type unique int id: @existential_type, int constraint: @type ref diff --git a/swift/ql/test/TestUtils.qll b/swift/ql/test/TestUtils.qll index 9bfff38db4f..9359944fe90 100644 --- a/swift/ql/test/TestUtils.qll +++ b/swift/ql/test/TestUtils.qll @@ -9,13 +9,18 @@ predicate toBeTested(Element e) { ( e = loc or - e = loc.(ValueDecl).getInterfaceType() - or - e = loc.(NominalTypeDecl).getType() - or - e = loc.(VarDecl).getType() - or - e = loc.(Expr).getType() + exists(Type t | + (e = t or e = t.(ExistentialType).getConstraint() or e = t.getCanonicalType()) and + ( + t = loc.(ValueDecl).getInterfaceType() + or + t = loc.(NominalTypeDecl).getType() + or + t = loc.(VarDecl).getType() + or + t = loc.(Expr).getType() + ) + ) ) ) } diff --git a/swift/ql/test/extractor-tests/generated/File/File.ql b/swift/ql/test/extractor-tests/generated/File/File.ql index 9307342f2ff..158dca707f5 100644 --- a/swift/ql/test/extractor-tests/generated/File/File.ql +++ b/swift/ql/test/extractor-tests/generated/File/File.ql @@ -2,10 +2,9 @@ import codeql.swift.elements import TestUtils -from File x, string isUnknown, string getName +from File x, string getName where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getName = x.getName() -select x, "isUnknown:", isUnknown, "getName:", getName +select x, "getName:", getName diff --git a/swift/ql/test/extractor-tests/generated/Location/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/Location/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/Location/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql index 99207338efe..34180566f00 100644 --- a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql +++ b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl.ql @@ -3,17 +3,16 @@ import codeql.swift.elements import TestUtils from - AccessorDecl x, string isUnknown, Type getInterfaceType, string getName, string isGetter, - string isSetter, string isWillSet, string isDidSet + AccessorDecl x, Type getInterfaceType, string getName, string isGetter, string isSetter, + string isWillSet, string isDidSet where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getInterfaceType = x.getInterfaceType() and getName = x.getName() and (if x.isGetter() then isGetter = "yes" else isGetter = "no") and (if x.isSetter() then isSetter = "yes" else isSetter = "no") and (if x.isWillSet() then isWillSet = "yes" else isWillSet = "no") and if x.isDidSet() then isDidSet = "yes" else isDidSet = "no" -select x, "isUnknown:", isUnknown, "getInterfaceType:", getInterfaceType, "getName:", getName, - "isGetter:", isGetter, "isSetter:", isSetter, "isWillSet:", isWillSet, "isDidSet:", isDidSet +select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "isGetter:", isGetter, + "isSetter:", isSetter, "isWillSet:", isWillSet, "isDidSet:", isDidSet diff --git a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getLocation.ql b/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getLocation.ql deleted file mode 100644 index 92be90de057..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/AccessorDecl/AccessorDecl_getLocation.ql +++ /dev/null @@ -1,7 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements -import TestUtils - -from AccessorDecl x -where toBeTested(x) and not x.isUnknown() -select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl.ql b/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl.ql index 5db864bfc22..d49e513615c 100644 --- a/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl.ql +++ b/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl.ql @@ -2,11 +2,10 @@ import codeql.swift.elements import TestUtils -from AssociatedTypeDecl x, string isUnknown, Type getInterfaceType, string getName +from AssociatedTypeDecl x, Type getInterfaceType, string getName where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getInterfaceType = x.getInterfaceType() and getName = x.getName() -select x, "isUnknown:", isUnknown, "getInterfaceType:", getInterfaceType, "getName:", getName +select x, "getInterfaceType:", getInterfaceType, "getName:", getName diff --git a/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl_getLocation.ql b/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl_getLocation.ql deleted file mode 100644 index 0a3561ae7b1..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/AssociatedTypeDecl/AssociatedTypeDecl_getLocation.ql +++ /dev/null @@ -1,7 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements -import TestUtils - -from AssociatedTypeDecl x -where toBeTested(x) and not x.isUnknown() -select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl.ql index 9cef07648fa..89f9f86507f 100644 --- a/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl.ql +++ b/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl.ql @@ -2,13 +2,11 @@ import codeql.swift.elements import TestUtils -from ClassDecl x, string isUnknown, Type getInterfaceType, string getName, Type getType +from ClassDecl x, Type getInterfaceType, string getName, Type getType where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getInterfaceType = x.getInterfaceType() and getName = x.getName() and getType = x.getType() -select x, "isUnknown:", isUnknown, "getInterfaceType:", getInterfaceType, "getName:", getName, - "getType:", getType +select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "getType:", getType diff --git a/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl_getLocation.ql b/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl_getLocation.ql deleted file mode 100644 index 3231b1dd58a..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/ClassDecl/ClassDecl_getLocation.ql +++ /dev/null @@ -1,7 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements -import TestUtils - -from ClassDecl x -where toBeTested(x) and not x.isUnknown() -select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl.ql index 28736643fdb..7b10f703bff 100644 --- a/swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl.ql +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl.ql @@ -2,11 +2,10 @@ import codeql.swift.elements import TestUtils -from ConcreteFuncDecl x, string isUnknown, Type getInterfaceType, string getName +from ConcreteFuncDecl x, Type getInterfaceType, string getName where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getInterfaceType = x.getInterfaceType() and getName = x.getName() -select x, "isUnknown:", isUnknown, "getInterfaceType:", getInterfaceType, "getName:", getName +select x, "getInterfaceType:", getInterfaceType, "getName:", getName diff --git a/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl.ql b/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl.ql index 6575ebfb2cd..6f5c19ec720 100644 --- a/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl.ql +++ b/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl.ql @@ -2,13 +2,11 @@ import codeql.swift.elements import TestUtils -from EnumDecl x, string isUnknown, Type getInterfaceType, string getName, Type getType +from EnumDecl x, Type getInterfaceType, string getName, Type getType where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getInterfaceType = x.getInterfaceType() and getName = x.getName() and getType = x.getType() -select x, "isUnknown:", isUnknown, "getInterfaceType:", getInterfaceType, "getName:", getName, - "getType:", getType +select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "getType:", getType diff --git a/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl_getLocation.ql b/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl_getLocation.ql deleted file mode 100644 index 4f8482a4e06..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/EnumDecl/EnumDecl_getLocation.ql +++ /dev/null @@ -1,7 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements -import TestUtils - -from EnumDecl x -where toBeTested(x) and not x.isUnknown() -select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/expr/BridgeFromObjCExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/BridgeFromObjCExpr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/BridgeFromObjCExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr.ql b/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr.ql deleted file mode 100644 index 7412b7819fe..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr.ql +++ /dev/null @@ -1,11 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements -import TestUtils - -from BridgeToObjCExpr x, string isUnknown, Expr getSubExpr -where - toBeTested(x) and - not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and - getSubExpr = x.getSubExpr() -select x, "isUnknown:", isUnknown, "getSubExpr:", getSubExpr diff --git a/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getLocation.ql b/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getLocation.ql deleted file mode 100644 index 605f328ed19..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getLocation.ql +++ /dev/null @@ -1,7 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements -import TestUtils - -from BridgeToObjCExpr x -where toBeTested(x) and not x.isUnknown() -select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/expr/ConditionalBridgeFromObjCExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/ConditionalBridgeFromObjCExpr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/ConditionalBridgeFromObjCExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr.ql b/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr.ql index 3c66ef1f469..91ec5342fb6 100644 --- a/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr.ql +++ b/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr.ql @@ -2,10 +2,9 @@ import codeql.swift.elements import TestUtils -from DotSelfExpr x, string isUnknown, Expr getSubExpr +from DotSelfExpr x, Expr getSubExpr where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getSubExpr = x.getSubExpr() -select x, "isUnknown:", isUnknown, "getSubExpr:", getSubExpr +select x, "getSubExpr:", getSubExpr diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr_getLocation.ql b/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr_getLocation.ql deleted file mode 100644 index a337b217c60..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/DotSelfExpr/DotSelfExpr_getLocation.ql +++ /dev/null @@ -1,7 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements -import TestUtils - -from DotSelfExpr x -where toBeTested(x) and not x.isUnknown() -select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/expr/ErrorExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/ErrorExpr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/ErrorExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/ObjCSelectorExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/ObjCSelectorExpr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/ObjCSelectorExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/SequenceExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/SequenceExpr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/SequenceExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql index 774f1119727..29327a3f86c 100644 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql @@ -2,11 +2,10 @@ import codeql.swift.elements import TestUtils -from UnresolvedDotExpr x, string isUnknown, Expr getBase, string getName +from UnresolvedDotExpr x, Expr getBase, string getName where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getBase = x.getBase() and getName = x.getName() -select x, "isUnknown:", isUnknown, "getBase:", getBase, "getName:", getName +select x, "getBase:", getBase, "getName:", getName diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getLocation.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getLocation.ql deleted file mode 100644 index 562131422a2..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getLocation.ql +++ /dev/null @@ -1,7 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements -import TestUtils - -from UnresolvedDotExpr x -where toBeTested(x) and not x.isUnknown() -select x, x.getLocation() diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedMemberExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/UnresolvedMemberExpr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedMemberExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedSpecializeExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/UnresolvedSpecializeExpr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedSpecializeExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinBridgeObjectType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinBridgeObjectType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinBridgeObjectType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinDefaultActorStorageType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinDefaultActorStorageType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinDefaultActorStorageType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinExecutorType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinExecutorType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinExecutorType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinFloatType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinFloatType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinFloatType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerLiteralType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerLiteralType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerLiteralType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.expected b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.expected new file mode 100644 index 00000000000..f50efd8d8d7 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.expected @@ -0,0 +1,5 @@ +| Builtin.Int8 | getDiagnosticsName: | Builtin.Int8 | getCanonicalType: | Builtin.Int8 | +| Builtin.Int16 | getDiagnosticsName: | Builtin.Int16 | getCanonicalType: | Builtin.Int16 | +| Builtin.Int32 | getDiagnosticsName: | Builtin.Int32 | getCanonicalType: | Builtin.Int32 | +| Builtin.Int64 | getDiagnosticsName: | Builtin.Int64 | getCanonicalType: | Builtin.Int64 | +| Builtin.Word | getDiagnosticsName: | Builtin.Word | getCanonicalType: | Builtin.Word | diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.ql b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.ql new file mode 100644 index 00000000000..6828ace5d1f --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.ql @@ -0,0 +1,11 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from BuiltinIntegerType x, string getDiagnosticsName, Type getCanonicalType +where + toBeTested(x) and + not x.isUnknown() and + getDiagnosticsName = x.getDiagnosticsName() and + getCanonicalType = x.getCanonicalType() +select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.expected b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.expected new file mode 100644 index 00000000000..350ab9ee53a --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.expected @@ -0,0 +1,4 @@ +| Builtin.Int8 | 8 | +| Builtin.Int16 | 16 | +| Builtin.Int32 | 32 | +| Builtin.Int64 | 64 | diff --git a/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getType.ql b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.ql similarity index 71% rename from swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getType.ql rename to swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.ql index 077a2a9e82e..ebe05b7b0cb 100644 --- a/swift/ql/test/extractor-tests/generated/expr/BridgeToObjCExpr/BridgeToObjCExpr_getType.ql +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType_getWidth.ql @@ -2,6 +2,6 @@ import codeql.swift.elements import TestUtils -from BridgeToObjCExpr x +from BuiltinIntegerType x where toBeTested(x) and not x.isUnknown() -select x, x.getType() +select x, x.getWidth() diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/builtin_integer_types.swift b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/builtin_integer_types.swift new file mode 100644 index 00000000000..66c832a5ebc --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/builtin_integer_types.swift @@ -0,0 +1,8 @@ +//codeql-extractor-options: -parse-stdlib +func foo( + _: Builtin.Int8, + _: Builtin.Int16, + _: Builtin.Int32, + _: Builtin.Int64, + _: Builtin.Word +) {} diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinJobType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinJobType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinJobType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinNativeObjectType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinNativeObjectType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinNativeObjectType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinRawPointerType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinRawPointerType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinRawPointerType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinRawUnsafeContinuationType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinRawUnsafeContinuationType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinRawUnsafeContinuationType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.expected b/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.expected new file mode 100644 index 00000000000..be0aaa1c1ca --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.expected @@ -0,0 +1,11 @@ +| Builtin.BridgeObject | getDiagnosticsName: | Builtin.BridgeObject | getCanonicalType: | Builtin.BridgeObject | +| Builtin.DefaultActorStorage | getDiagnosticsName: | Builtin.DefaultActorStorage | getCanonicalType: | Builtin.DefaultActorStorage | +| Builtin.Executor | getDiagnosticsName: | Builtin.Executor | getCanonicalType: | Builtin.Executor | +| Builtin.FPIEEE32 | getDiagnosticsName: | Builtin.FPIEEE32 | getCanonicalType: | Builtin.FPIEEE32 | +| Builtin.FPIEEE64 | getDiagnosticsName: | Builtin.FPIEEE64 | getCanonicalType: | Builtin.FPIEEE64 | +| Builtin.IntLiteral | getDiagnosticsName: | Builtin.IntLiteral | getCanonicalType: | Builtin.IntLiteral | +| Builtin.Job | getDiagnosticsName: | Builtin.Job | getCanonicalType: | Builtin.Job | +| Builtin.NativeObject | getDiagnosticsName: | Builtin.NativeObject | getCanonicalType: | Builtin.NativeObject | +| Builtin.RawPointer | getDiagnosticsName: | Builtin.RawPointer | getCanonicalType: | Builtin.RawPointer | +| Builtin.RawUnsafeContinuation | getDiagnosticsName: | Builtin.RawUnsafeContinuation | getCanonicalType: | Builtin.RawUnsafeContinuation | +| Builtin.UnsafeValueBuffer | getDiagnosticsName: | Builtin.UnsafeValueBuffer | getCanonicalType: | Builtin.UnsafeValueBuffer | diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.ql b/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.ql new file mode 100644 index 00000000000..d858afd70c8 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.ql @@ -0,0 +1,11 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from BuiltinType x, string getDiagnosticsName, Type getCanonicalType +where + toBeTested(x) and + not x.isUnknown() and + getDiagnosticsName = x.getDiagnosticsName() and + getCanonicalType = x.getCanonicalType() +select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinType/builtin_types.swift b/swift/ql/test/extractor-tests/generated/type/BuiltinType/builtin_types.swift new file mode 100644 index 00000000000..671a1b8eca7 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinType/builtin_types.swift @@ -0,0 +1,14 @@ +//codeql-extractor-options: -parse-stdlib +func foo( + _: Builtin.IntLiteral, + _: Builtin.FPIEEE32, + _: Builtin.FPIEEE64, + _: Builtin.BridgeObject, + _: Builtin.DefaultActorStorage, + _: Builtin.Executor, + _: Builtin.Job, + _: Builtin.NativeObject, + _: Builtin.RawPointer, + _: Builtin.RawUnsafeContinuation, + _: Builtin.UnsafeValueBuffer +) {} diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinUnsafeValueBufferType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinUnsafeValueBufferType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinUnsafeValueBufferType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinVectorType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/BuiltinVectorType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinVectorType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql b/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql index 68468498ea9..a9ae23f6bab 100644 --- a/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql +++ b/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql @@ -2,15 +2,12 @@ import codeql.swift.elements import TestUtils -from - DynamicSelfType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, - Type getStaticSelfType +from DynamicSelfType x, string getDiagnosticsName, Type getCanonicalType, Type getStaticSelfType where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getStaticSelfType = x.getStaticSelfType() -select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", - getCanonicalType, "getStaticSelfType:", getStaticSelfType +select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, + "getStaticSelfType:", getStaticSelfType diff --git a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.expected b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.expected index 30cd19ebd4e..22277bec084 100644 --- a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.expected +++ b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.expected @@ -1,2 +1,3 @@ | ExplicitExistential | getDiagnosticsName: | ExplicitExistential | getCanonicalType: | ExplicitExistential | getConstraint: | ExplicitExistential | | ImplicitExistential | getDiagnosticsName: | ImplicitExistential | getCanonicalType: | ImplicitExistential | getConstraint: | ImplicitExistential | +| P1 & P2 | getDiagnosticsName: | P1 & P2 | getCanonicalType: | P1 & P2 | getConstraint: | P1 & P2 | diff --git a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql index 22ad73eb91e..b679d5d89a2 100644 --- a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql +++ b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql @@ -2,15 +2,12 @@ import codeql.swift.elements import TestUtils -from - ExistentialType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, - Type getConstraint +from ExistentialType x, string getDiagnosticsName, Type getCanonicalType, Type getConstraint where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getConstraint = x.getConstraint() -select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", - getCanonicalType, "getConstraint:", getConstraint +select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, + "getConstraint:", getConstraint diff --git a/swift/ql/test/extractor-tests/generated/type/ExistentialType/existential_types.swift b/swift/ql/test/extractor-tests/generated/type/ExistentialType/existential_types.swift index ade646efc74..8fad6cce47a 100644 --- a/swift/ql/test/extractor-tests/generated/type/ExistentialType/existential_types.swift +++ b/swift/ql/test/extractor-tests/generated/type/ExistentialType/existential_types.swift @@ -1,5 +1,8 @@ protocol ExplicitExistential {} protocol ImplicitExistential {} +protocol P1 {} +protocol P2 {} func foo1(_: any ExplicitExistential) {} func foo2(_: ImplicitExistential) {} // valid for now, will be an error in some future swift release +func foo3(_: any P1 & P2) {} diff --git a/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql b/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql index cb004070ca5..973d0257381 100644 --- a/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql +++ b/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql @@ -2,15 +2,12 @@ import codeql.swift.elements import TestUtils -from - InOutType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, - Type getObjectType +from InOutType x, string getDiagnosticsName, Type getCanonicalType, Type getObjectType where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getObjectType = x.getObjectType() -select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", - getCanonicalType, "getObjectType:", getObjectType +select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, + "getObjectType:", getObjectType diff --git a/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql b/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql index e5862e67de7..8306bfeacac 100644 --- a/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql +++ b/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql @@ -3,19 +3,17 @@ import codeql.swift.elements import TestUtils from - NestedArchetypeType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, - string getName, Type getInterfaceType, ArchetypeType getParent, - AssociatedTypeDecl getAssociatedTypeDeclaration + NestedArchetypeType x, string getDiagnosticsName, Type getCanonicalType, string getName, + Type getInterfaceType, ArchetypeType getParent, AssociatedTypeDecl getAssociatedTypeDeclaration where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getName = x.getName() and getInterfaceType = x.getInterfaceType() and getParent = x.getParent() and getAssociatedTypeDeclaration = x.getAssociatedTypeDeclaration() -select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", - getCanonicalType, "getName:", getName, "getInterfaceType:", getInterfaceType, "getParent:", - getParent, "getAssociatedTypeDeclaration:", getAssociatedTypeDeclaration +select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, + "getName:", getName, "getInterfaceType:", getInterfaceType, "getParent:", getParent, + "getAssociatedTypeDeclaration:", getAssociatedTypeDeclaration diff --git a/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql b/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql index 63a04cfb03c..925bf85dcbf 100644 --- a/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql +++ b/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql @@ -3,15 +3,14 @@ import codeql.swift.elements import TestUtils from - PrimaryArchetypeType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, - string getName, Type getInterfaceType + PrimaryArchetypeType x, string getDiagnosticsName, Type getCanonicalType, string getName, + Type getInterfaceType where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getName = x.getName() and getInterfaceType = x.getInterfaceType() -select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", - getCanonicalType, "getName:", getName, "getInterfaceType:", getInterfaceType +select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, + "getName:", getName, "getInterfaceType:", getInterfaceType diff --git a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.expected b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.expected new file mode 100644 index 00000000000..31d909f4c17 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.expected @@ -0,0 +1,4 @@ +| P1 & (P2 & P3) | getDiagnosticsName: | P1 & (P2 & P3) | getCanonicalType: | P1 & P2 & P3 | +| P1 & P2 & P3 | getDiagnosticsName: | P1 & P2 & P3 | getCanonicalType: | P1 & P2 & P3 | +| P1 & P23 | getDiagnosticsName: | P1 & P23 | getCanonicalType: | P1 & P2 & P3 | +| P2 & P4 | getDiagnosticsName: | P2 & P4 | getCanonicalType: | P2 & P4 | diff --git a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.ql b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.ql new file mode 100644 index 00000000000..2253a888b1f --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.ql @@ -0,0 +1,11 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ProtocolCompositionType x, string getDiagnosticsName, Type getCanonicalType +where + toBeTested(x) and + not x.isUnknown() and + getDiagnosticsName = x.getDiagnosticsName() and + getCanonicalType = x.getCanonicalType() +select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType diff --git a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.expected b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.expected new file mode 100644 index 00000000000..4792394a757 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.expected @@ -0,0 +1,9 @@ +| P1 & (P2 & P3) | 0 | P1 | +| P1 & (P2 & P3) | 1 | (P2 & P3) | +| P1 & P2 & P3 | 0 | P1 | +| P1 & P2 & P3 | 1 | P2 | +| P1 & P2 & P3 | 2 | P3 | +| P1 & P23 | 0 | P1 | +| P1 & P23 | 1 | P23 | +| P2 & P4 | 0 | P2 | +| P2 & P4 | 1 | P4 | diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl_getLocation.ql b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.ql similarity index 61% rename from swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl_getLocation.ql rename to swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.ql index eeb02bedc0f..4804b223727 100644 --- a/swift/ql/test/extractor-tests/generated/decl/ConcreteFuncDecl/ConcreteFuncDecl_getLocation.ql +++ b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType_getMember.ql @@ -2,6 +2,6 @@ import codeql.swift.elements import TestUtils -from ConcreteFuncDecl x +from ProtocolCompositionType x, int index where toBeTested(x) and not x.isUnknown() -select x, x.getLocation() +select x, index, x.getMember(index) diff --git a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/protocol_composition.swift b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/protocol_composition.swift new file mode 100644 index 00000000000..ba760d00ef6 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/protocol_composition.swift @@ -0,0 +1,13 @@ +protocol P1 {} +protocol P2 {} +protocol P3 {} + +var x: P1 & P2 & P3 + +protocol P4: P1 {} +var y: P1 & P2 & P4 + +var z: P1 & (P2 & P3) + +typealias P23 = P2 & P3 +var zz: P1 & P23 diff --git a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql index 8f1acefdf8e..396988db25e 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql +++ b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql @@ -2,15 +2,12 @@ import codeql.swift.elements import TestUtils -from - UnmanagedStorageType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, - Type getReferentType +from UnmanagedStorageType x, string getDiagnosticsName, Type getCanonicalType, Type getReferentType where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getReferentType = x.getReferentType() -select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", - getCanonicalType, "getReferentType:", getReferentType +select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, + "getReferentType:", getReferentType diff --git a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql index fbe93938336..17744a437d7 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql +++ b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql @@ -2,15 +2,12 @@ import codeql.swift.elements import TestUtils -from - UnownedStorageType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, - Type getReferentType +from UnownedStorageType x, string getDiagnosticsName, Type getCanonicalType, Type getReferentType where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getReferentType = x.getReferentType() -select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", - getCanonicalType, "getReferentType:", getReferentType +select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, + "getReferentType:", getReferentType diff --git a/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql b/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql index 7dc29f0861c..5a89dbcafab 100644 --- a/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql +++ b/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql @@ -2,15 +2,12 @@ import codeql.swift.elements import TestUtils -from - VariadicSequenceType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, - Type getBaseType +from VariadicSequenceType x, string getDiagnosticsName, Type getCanonicalType, Type getBaseType where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getBaseType = x.getBaseType() -select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", - getCanonicalType, "getBaseType:", getBaseType +select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, + "getBaseType:", getBaseType diff --git a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql index 03e8331f3ab..3209b0e7d3d 100644 --- a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql +++ b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql @@ -2,15 +2,12 @@ import codeql.swift.elements import TestUtils -from - WeakStorageType x, string isUnknown, string getDiagnosticsName, Type getCanonicalType, - Type getReferentType +from WeakStorageType x, string getDiagnosticsName, Type getCanonicalType, Type getReferentType where toBeTested(x) and not x.isUnknown() and - (if x.isUnknown() then isUnknown = "yes" else isUnknown = "no") and getDiagnosticsName = x.getDiagnosticsName() and getCanonicalType = x.getCanonicalType() and getReferentType = x.getReferentType() -select x, "isUnknown:", isUnknown, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", - getCanonicalType, "getReferentType:", getReferentType +select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, + "getReferentType:", getReferentType From 68a341d72c373c5131bef21782f400da39f1320b Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 28 Jun 2022 12:06:19 +0200 Subject: [PATCH 148/465] Swift: use `createEntry` in the whole type visitor --- swift/extractor/visitors/TypeVisitor.cpp | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/swift/extractor/visitors/TypeVisitor.cpp b/swift/extractor/visitors/TypeVisitor.cpp index 807e484e2d3..5754abf7aba 100644 --- a/swift/extractor/visitors/TypeVisitor.cpp +++ b/swift/extractor/visitors/TypeVisitor.cpp @@ -122,13 +122,13 @@ void TypeVisitor::visitParenType(swift::ParenType* type) { } codeql::OptionalType TypeVisitor::translateOptionalType(const swift::OptionalType& type) { - codeql::OptionalType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createEntry(type); fillUnarySyntaxSugarType(type, entry); return entry; } codeql::ArraySliceType TypeVisitor::translateArraySliceType(const swift::ArraySliceType& type) { - codeql::ArraySliceType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createEntry(type); fillUnarySyntaxSugarType(type, entry); return entry; } @@ -163,7 +163,7 @@ void TypeVisitor::visitLValueType(swift::LValueType* type) { codeql::PrimaryArchetypeType TypeVisitor::translatePrimaryArchetypeType( const swift::PrimaryArchetypeType& type) { - PrimaryArchetypeType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createEntry(type); fillArchetypeType(type, entry); return entry; } @@ -183,7 +183,6 @@ void TypeVisitor::fillUnarySyntaxSugarType(const swift::UnarySyntaxSugarType& ty codeql::UnarySyntaxSugarType& entry) { assert(type.getBaseType() && "expect UnarySyntaxSugarType to have BaseType"); entry.base_type = dispatcher_.fetchLabel(type.getBaseType()); - fillType(type, entry); } void TypeVisitor::emitAnyFunctionType(const swift::AnyFunctionType* type, @@ -230,7 +229,7 @@ void TypeVisitor::emitAnyGenericType(swift::AnyGenericType* type, codeql::NestedArchetypeType TypeVisitor::translateNestedArchetypeType( const swift::NestedArchetypeType& type) { - codeql::NestedArchetypeType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createEntry(type); entry.parent = dispatcher_.fetchLabel(type.getParent()); entry.associated_type_declaration = dispatcher_.fetchLabel(type.getAssocType()); fillArchetypeType(type, entry); @@ -247,34 +246,30 @@ void TypeVisitor::fillArchetypeType(const swift::ArchetypeType& type, ArchetypeT entry.name = type.getName().str().str(); entry.protocols = dispatcher_.fetchRepeatedLabels(type.getConformsTo()); entry.superclass = dispatcher_.fetchOptionalLabel(type.getSuperclass()); - fillType(type, entry); } codeql::ExistentialType TypeVisitor::translateExistentialType(const swift::ExistentialType& type) { - codeql::ExistentialType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createEntry(type); entry.constraint = dispatcher_.fetchLabel(type.getConstraintType()); - fillType(type, entry); return entry; } codeql::DynamicSelfType TypeVisitor::translateDynamicSelfType(const swift::DynamicSelfType& type) { - codeql::DynamicSelfType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createEntry(type); entry.static_self_type = dispatcher_.fetchLabel(type.getSelfType()); - fillType(type, entry); return entry; } codeql::VariadicSequenceType TypeVisitor::translateVariadicSequenceType( const swift::VariadicSequenceType& type) { - codeql::VariadicSequenceType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createEntry(type); fillUnarySyntaxSugarType(type, entry); return entry; } codeql::InOutType TypeVisitor::translateInOutType(const swift::InOutType& type) { - codeql::InOutType entry{dispatcher_.assignNewLabel(type)}; + auto entry = createEntry(type); entry.object_type = dispatcher_.fetchLabel(type.getObjectType()); - fillType(type, entry); return entry; } From 5dfc3c65373d938acba55f2a69b998dad1c39d31 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 28 Jun 2022 12:10:26 +0200 Subject: [PATCH 149/465] Python: rename change note again --- .../{2022-28-06-api-graph-api.md => 2022-06-28-api-graph-api.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename python/ql/lib/change-notes/{2022-28-06-api-graph-api.md => 2022-06-28-api-graph-api.md} (100%) diff --git a/python/ql/lib/change-notes/2022-28-06-api-graph-api.md b/python/ql/lib/change-notes/2022-06-28-api-graph-api.md similarity index 100% rename from python/ql/lib/change-notes/2022-28-06-api-graph-api.md rename to python/ql/lib/change-notes/2022-06-28-api-graph-api.md From b3b53360ae80fbcd54be1ef5cf413117a382298a Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 28 Jun 2022 12:14:28 +0200 Subject: [PATCH 150/465] Python: change category to deprecated because library is apparently supported anymore --- python/ql/lib/change-notes/2022-06-28-api-graph-api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/change-notes/2022-06-28-api-graph-api.md b/python/ql/lib/change-notes/2022-06-28-api-graph-api.md index caae8e33a70..ef6ff3d4f76 100644 --- a/python/ql/lib/change-notes/2022-06-28-api-graph-api.md +++ b/python/ql/lib/change-notes/2022-06-28-api-graph-api.md @@ -1,8 +1,8 @@ --- -category: library +category: deprecated --- -* The documentation of API graphs (the `API` module) has been expanded, and some of the members predicates of `API::Node` +- The documentation of API graphs (the `API` module) has been expanded, and some of the members predicates of `API::Node` have been renamed as follows: - `getAnImmediateUse` -> `asSource` - `getARhs` -> `asSink` From 131524d867e2b63d892decf4872a7cd2c2e29fd1 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 28 Jun 2022 12:16:08 +0200 Subject: [PATCH 151/465] Swift: accept test changes These are due to the changes on `toBeTested` that include canonical types. --- .../type/UnmanagedStorageType/UnmanagedStorageType.expected | 1 + .../type/UnownedStorageType/UnownedStorageType.expected | 1 + .../generated/type/WeakStorageType/WeakStorageType.expected | 1 + 3 files changed, 3 insertions(+) diff --git a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.expected b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.expected index 1841fffc8c2..bd7b78838c7 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.expected +++ b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.expected @@ -1 +1,2 @@ | A? | getDiagnosticsName: | A? | getCanonicalType: | Optional | getReferentType: | A? | +| Optional | getDiagnosticsName: | Optional | getCanonicalType: | Optional | getReferentType: | Optional | diff --git a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.expected b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.expected index 1841fffc8c2..bd7b78838c7 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.expected +++ b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.expected @@ -1 +1,2 @@ | A? | getDiagnosticsName: | A? | getCanonicalType: | Optional | getReferentType: | A? | +| Optional | getDiagnosticsName: | Optional | getCanonicalType: | Optional | getReferentType: | Optional | diff --git a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.expected b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.expected index 1841fffc8c2..bd7b78838c7 100644 --- a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.expected +++ b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.expected @@ -1 +1,2 @@ | A? | getDiagnosticsName: | A? | getCanonicalType: | Optional | getReferentType: | A? | +| Optional | getDiagnosticsName: | Optional | getCanonicalType: | Optional | getReferentType: | Optional | From 834d2603a27c70bb3d884b5539350b792d1eedff Mon Sep 17 00:00:00 2001 From: yoff Date: Tue, 28 Jun 2022 11:15:37 +0000 Subject: [PATCH 152/465] python: update use of barrier guard --- .../dataflow/TarSlipCustomizations.qll | 53 +++++++++++-------- .../{TarSlip.qll => TarSlipQuery.qll} | 2 +- python/ql/src/Security/CWE-022/TarSlip.ql | 2 +- 3 files changed, 32 insertions(+), 25 deletions(-) rename python/ql/lib/semmle/python/security/dataflow/{TarSlip.qll => TarSlipQuery.qll} (91%) diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll index db062a23088..38fb99c49c3 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll @@ -32,12 +32,14 @@ module TarSlip { abstract class Sanitizer extends DataFlow::Node { } /** + * DEPRECATED: Use `Sanitizer` instead. + * * A sanitizer guard for "tar slip" vulnerabilities. */ - abstract class SanitizerGuard extends DataFlow::BarrierGuard { } + abstract deprecated class SanitizerGuard extends DataFlow::BarrierGuard { } /** - * A source of exception info, considered as a flow source. + * A call to `tarfile.open`, considered as a flow source. */ class TarfileOpen extends Source { TarfileOpen() { @@ -45,7 +47,7 @@ module TarSlip { // If argument refers to a string object, then it's a hardcoded path and // this tarfile is safe. not this.(DataFlow::CallCfgNode).getArg(0).getALocalSource().asExpr() instanceof StrConst and - /* Ignore opens within the tarfile module itself */ + // Ignore opens within the tarfile module itself not this.getLocation().getFile().getBaseName() = "tarfile.py" } } @@ -109,6 +111,29 @@ module TarSlip { } } + /** + * Holds if `g` clears taint for `tarInfo`. + * + * The test `if (info.name)` should clear taint for `info`, + * where `` is any function matching `"%path"`. + * `info` is assumed to be a `TarInfo` instance. + */ + predicate tarFileInfoSanitizer(DataFlow::GuardNode g, ControlFlowNode tarInfo, boolean branch) { + exists(CallNode call, AttrNode attr | + g = call and + // We must test the name of the tar info object. + attr = call.getAnArg() and + attr.getName() = "name" and + attr.getObject() = tarInfo + | + // Assume that any test with "path" in it is a sanitizer + call.getAChild*().(AttrNode).getName().matches("%path") + or + call.getAChild*().(NameNode).getId().matches("%path") + ) and + branch in [true, false] + } + /** * A sanitizer guard heuristic. * @@ -116,27 +141,9 @@ module TarSlip { * where `` is any function matching `"%path"`. * `info` is assumed to be a `TarInfo` instance. */ - class TarFileInfoSanitizer extends SanitizerGuard { - ControlFlowNode tarInfo; - + class TarFileInfoSanitizer extends Sanitizer { TarFileInfoSanitizer() { - exists(CallNode call, AttrNode attr | - this = call and - // We must test the name of the tar info object. - attr = call.getAnArg() and - attr.getName() = "name" and - attr.getObject() = tarInfo - | - // Assume that any test with "path" in it is a sanitizer - call.getAChild*().(AttrNode).getName().matches("%path") - or - call.getAChild*().(NameNode).getId().matches("%path") - ) - } - - override predicate checks(ControlFlowNode checked, boolean branch) { - checked = tarInfo and - branch in [true, false] + this = DataFlow::BarrierGuard::getABarrierNode() } } } diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlip.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll similarity index 91% rename from python/ql/lib/semmle/python/security/dataflow/TarSlip.qll rename to python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll index 90c79da1f04..e69d63fedbc 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TarSlip.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll @@ -23,7 +23,7 @@ class Configuration extends TaintTracking::Configuration { override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { + deprecated override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { guard instanceof SanitizerGuard } } diff --git a/python/ql/src/Security/CWE-022/TarSlip.ql b/python/ql/src/Security/CWE-022/TarSlip.ql index 1528be7377d..b2ad6cb3372 100644 --- a/python/ql/src/Security/CWE-022/TarSlip.ql +++ b/python/ql/src/Security/CWE-022/TarSlip.ql @@ -13,7 +13,7 @@ */ import python -import semmle.python.security.dataflow.TarSlip +import semmle.python.security.dataflow.TarSlipQuery import DataFlow::PathGraph from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink From 112caa3f5d851b8d372af44cfa8768b688a10df0 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Tue, 28 Jun 2022 13:23:44 +0200 Subject: [PATCH 153/465] rewrite qldoc based on review --- .../ql/lib/semmle/javascript/dataflow/TaintTracking.qll | 4 +--- .../dataflow/UnsafeHtmlConstructionCustomizations.qll | 2 +- .../javascript/security/dataflow/XssThroughDomQuery.qll | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll index 3e930b652d6..6b5604f9135 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TaintTracking.qll @@ -1126,9 +1126,7 @@ module TaintTracking { ) } - /** - * Holds if `test` is of the form `typeof x === "something"`, preventing `x` from being a string in some cases. - */ + /** A test for the value of `typeof x`, restricting the potential types of `x`. */ predicate isStringTypeGuard(EqualityTest test, Expr operand, boolean polarity) { exists(TypeofTag tag | TaintTracking::isTypeofGuard(test, operand, tag) | // typeof x === "string" sanitizes `x` when it evaluates to false diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll index ffb731aface..d594da271b8 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll @@ -181,7 +181,7 @@ module UnsafeHtmlConstruction { override string describe() { result = "Markdown rendering" } } - /** A test of form `typeof x === "something"`, preventing `x` from being a string in some cases. */ + /** A test for the value of `typeof x`, restricting the potential types of `x`. */ class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode { override EqualityTest astNode; Expr operand; diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll index 5863a0db92f..38246762c49 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/XssThroughDomQuery.qll @@ -51,7 +51,7 @@ class Configuration extends TaintTracking::Configuration { } } -/** A test of form `typeof x === "something"`, preventing `x` from being a string in some cases. */ +/** A test for the value of `typeof x`, restricting the potential types of `x`. */ class TypeTestGuard extends TaintTracking::SanitizerGuardNode, DataFlow::ValueNode { override EqualityTest astNode; Expr operand; From 1dc26a0ca3a37ea2fdd1f484679b7f06afc25871 Mon Sep 17 00:00:00 2001 From: Brandon Stewart <20469703+boveus@users.noreply.github.com> Date: Tue, 28 Jun 2022 08:50:54 -0400 Subject: [PATCH 154/465] Update ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll Co-authored-by: Harry Maclean --- ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index 16e52f62ff5..30e2e0e992f 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -336,7 +336,7 @@ class ActiveRecordInstanceMethodCall extends DataFlow::CallNode { ActiveRecordInstanceMethodCall() { this.getReceiver() = instance } - /** Gets the `ActiveRecordInstance` that this is the receiver of this call. */ + /** Gets the `ActiveRecordInstance` that is the receiver of this call. */ ActiveRecordInstance getInstance() { result = instance } } From 33d1aae92a67ff2446f355d834a7801c6d5eefab Mon Sep 17 00:00:00 2001 From: Brandon Stewart <20469703+boveus@users.noreply.github.com> Date: Tue, 28 Jun 2022 08:51:01 -0400 Subject: [PATCH 155/465] Update ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll Co-authored-by: Harry Maclean --- ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index 30e2e0e992f..cc63e64a083 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -330,7 +330,7 @@ class ActiveRecordInstance extends DataFlow::Node { ActiveRecordModelClass getClass() { result = instantiation.getClass() } } -/** The `ActiveRecordInstance` receiver of this call. */ +/** A call whose receiver may be an active record model object */ class ActiveRecordInstanceMethodCall extends DataFlow::CallNode { private ActiveRecordInstance instance; From a7bd2030b670d6d73766b5b7c514af15b2e4044c Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Tue, 28 Jun 2022 13:52:26 +0100 Subject: [PATCH 156/465] Address review comments --- .../creating-and-working-with-codeql-packs.rst | 2 +- .../codeql-cli/publishing-and-using-codeql-packs.rst | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst b/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst index e6a679c89a9..da7a0872803 100644 --- a/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst +++ b/docs/codeql/codeql-cli/creating-and-working-with-codeql-packs.rst @@ -73,6 +73,6 @@ This command downloads all dependencies to the shared cache on the local disk. Note - By default ``codeql pack install`` will install dependencies from the GitHub.com Container registry. + By default ``codeql pack install`` will install dependencies from the Container registry on GitHub.com. You can install dependencies from a GitHub Enterprise Server Container registry by creating a ``qlconfig.yml`` file. For more information, see ":doc:`Publishing and using CodeQL packs `." diff --git a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst index 4e7b8d452ac..e58277d3113 100644 --- a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst +++ b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst @@ -76,10 +76,16 @@ The ``analyze`` command will run the default suite of any specified CodeQL packs Managing packs on GitHub Enterprise Server ------------------------------------------ -By default, CodeQL will download packs from and publish packs to the GitHub.com Container registry. +.. pull-quote:: + + Note + + Managing packs on GitHub Enterprise Server is only available for GitHub Enterprise Server 3.6 and later. + +By default, CodeQL will download packs from and publish packs to the Container registry on GitHub.com. You can manage packs on GitHub Enterprise Server 3.6 and later by creating a ``qlconfig.yml`` file to tell CodeQL which Container registry to use for each pack. Create the ``~/.codeql/qlconfig.yml`` file using your preferred text editor, and add entries to specify which registry to use for each pack name pattern. -For example, the following ``qlconfig.yml`` file associates all packs with the Container registry for the GitHub Enterprise Server at ``GHE_HOSTNAME``, except packs matching ``codeql/*``, which are associated with the GitHub.com Container registry: +For example, the following ``qlconfig.yml`` file associates all packs with the Container registry for the GitHub Enterprise Server at ``GHE_HOSTNAME``, except packs matching ``codeql/*``, which are associated with the Container registry on GitHub.com: .. code-block:: yaml @@ -96,7 +102,7 @@ Authenticating to GitHub Container registries You can download a private pack or publish a pack by authenticating to the appropriate GitHub Container registry. -You can authenticate to the GitHub.com Container registry in two ways: +You can authenticate to the Container registry on GitHub.com in two ways: 1. Pass the ``--github-auth-stdin`` option to the CodeQL CLI, then supply a GitHub Apps token or personal access token via standard input. 2. Set the ``GITHUB_TOKEN`` environment variable to a GitHub Apps token or personal access token. From 71758695189bbbfc581c36296193b36ab82f8596 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 28 Jun 2022 15:17:18 +0200 Subject: [PATCH 157/465] Swift: add missing newlines in trap This is mostly cosmetic and for debugging, as the trap importer is perfectly happy with trap entries on the same line without spaces between them. --- swift/codegen/templates/cpp_classes_cpp.mustache | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swift/codegen/templates/cpp_classes_cpp.mustache b/swift/codegen/templates/cpp_classes_cpp.mustache index fbe403bcc0f..d78c89fc3c7 100644 --- a/swift/codegen/templates/cpp_classes_cpp.mustache +++ b/swift/codegen/templates/cpp_classes_cpp.mustache @@ -24,10 +24,10 @@ void {{name}}::emit({{^final}}TrapLabel<{{name}}Tag> id, {{/final}}std::ostream& {{#is_repeated}} for (auto i = 0u; i < {{field_name}}.size(); ++i) { {{^is_optional}} - out << {{trap_name}}Trap{id, i, {{field_name}}[i]}; + out << {{trap_name}}Trap{id, i, {{field_name}}[i]} << '\n'; {{/is_optional}} {{#is_optional}} - if ({{field_name}}[i]) out << {{trap_name}}Trap{id, i, *{{field_name}}[i]}; + if ({{field_name}}[i]) out << {{trap_name}}Trap{id, i, *{{field_name}}[i]} << '\n'; {{/is_optional}} } {{/is_repeated}} From 82c9b8b49485ff0b54300464fc4b785f9e90a5f0 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 23 Jun 2022 18:19:30 +0200 Subject: [PATCH 158/465] C++: Ensure only one `Variable` exists for every global variable Depending on the extraction order, before this change there might be multiple `GlobalVariable`s per declared global variable. See the tests in `cpp/ql/test/library-tests/variables/global`. This change ensures that only one of those `GlobalVariable`s is visible to the user if we can locate a unique definition. If not, the old situation persists. Note that an exception needs to be made for templated variables. Here, the definition refers to the non-instantiated template, while a declaration that is not a definition refers to an instantiation. In case the instantiation refers to a template parameter, the mangled names of the template and the instantiation will be identical. This happens for example in the following case: ``` template T x = T(42); // Uninstantiated templated variable template class C { T y = x; // Instantiation using a template parameter }; ``` Since the uninstantiated template and the instantiation are two different entities, we do not unify them as described above. --- cpp/ql/lib/semmle/code/cpp/Element.qll | 4 ++ cpp/ql/lib/semmle/code/cpp/Variable.qll | 3 + .../cpp/internal/ResolveGlobalVariable.qll | 60 +++++++++++++++++++ .../variables/global/variables.expected | 4 -- 4 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 cpp/ql/lib/semmle/code/cpp/internal/ResolveGlobalVariable.qll diff --git a/cpp/ql/lib/semmle/code/cpp/Element.qll b/cpp/ql/lib/semmle/code/cpp/Element.qll index 9e4ef7f5f8d..79df774d80f 100644 --- a/cpp/ql/lib/semmle/code/cpp/Element.qll +++ b/cpp/ql/lib/semmle/code/cpp/Element.qll @@ -6,6 +6,7 @@ import semmle.code.cpp.Location private import semmle.code.cpp.Enclosing private import semmle.code.cpp.internal.ResolveClass +private import semmle.code.cpp.internal.ResolveGlobalVariable /** * Get the `Element` that represents this `@element`. @@ -28,9 +29,12 @@ Element mkElement(@element e) { unresolveElement(result) = e } pragma[inline] @element unresolveElement(Element e) { not result instanceof @usertype and + not result instanceof @variable and result = e or e = resolveClass(result) + or + e = resolveGlobalVariable(result) } /** diff --git a/cpp/ql/lib/semmle/code/cpp/Variable.qll b/cpp/ql/lib/semmle/code/cpp/Variable.qll index 2e3d6bf3ca2..7e188980b9c 100644 --- a/cpp/ql/lib/semmle/code/cpp/Variable.qll +++ b/cpp/ql/lib/semmle/code/cpp/Variable.qll @@ -6,6 +6,7 @@ import semmle.code.cpp.Element import semmle.code.cpp.exprs.Access import semmle.code.cpp.Initializer private import semmle.code.cpp.internal.ResolveClass +private import semmle.code.cpp.internal.ResolveGlobalVariable /** * A C/C++ variable. For example, in the following code there are four @@ -32,6 +33,8 @@ private import semmle.code.cpp.internal.ResolveClass * can have multiple declarations. */ class Variable extends Declaration, @variable { + Variable() { isVariable(underlyingElement(this)) } + override string getAPrimaryQlClass() { result = "Variable" } /** Gets the initializer of this variable, if any. */ diff --git a/cpp/ql/lib/semmle/code/cpp/internal/ResolveGlobalVariable.qll b/cpp/ql/lib/semmle/code/cpp/internal/ResolveGlobalVariable.qll new file mode 100644 index 00000000000..219d45e2991 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/internal/ResolveGlobalVariable.qll @@ -0,0 +1,60 @@ +private predicate hasDefinition(@globalvariable g) { + exists(@var_decl vd | var_decls(vd, g, _, _, _) | var_def(vd)) +} + +pragma[noinline] +private predicate onlyOneCompleteGlobalVariableExistsWithMangledName(@mangledname name) { + strictcount(@globalvariable g | hasDefinition(g) and mangled_name(g, name)) = 1 +} + +/** Holds if `g` is a unique global variable with a definition named `name`. */ +pragma[noinline] +private predicate isGlobalWithMangledNameAndWithDefinition(@mangledname name, @globalvariable g) { + hasDefinition(g) and + mangled_name(g, name) and + onlyOneCompleteGlobalVariableExistsWithMangledName(name) +} + +/** Holds if `g` is a global variable without a definition named `name`. */ +pragma[noinline] +private predicate isGlobalWithMangledNameAndWithoutDefinition(@mangledname name, @globalvariable g) { + not hasDefinition(g) and + mangled_name(g, name) +} + +/** + * Holds if `incomplete` is a global variable without a definition, and there exists + * a unique global variable `complete` with the same name that does have a definition. + */ +private predicate hasTwinWithDefinition(@globalvariable incomplete, @globalvariable complete) { + exists(@mangledname name | + not variable_instantiation(incomplete, complete) and + isGlobalWithMangledNameAndWithoutDefinition(name, incomplete) and + isGlobalWithMangledNameAndWithDefinition(name, complete) + ) +} + +import Cached + +cached +private module Cached { + /** + * If `v` is a global variable without a definition, and there exists a unique + * global variable with the same name that does have a definition, then the + * result is that unique global variable. Otherwise, the result is `v`. + */ + cached + @variable resolveGlobalVariable(@variable v) { + hasTwinWithDefinition(v, result) + or + not hasTwinWithDefinition(v, _) and + result = v + } + + cached + predicate isVariable(@variable v) { + not v instanceof @globalvariable + or + v = resolveGlobalVariable(_) + } +} diff --git a/cpp/ql/test/library-tests/variables/global/variables.expected b/cpp/ql/test/library-tests/variables/global/variables.expected index d66899e62fa..9d022a98264 100644 --- a/cpp/ql/test/library-tests/variables/global/variables.expected +++ b/cpp/ql/test/library-tests/variables/global/variables.expected @@ -4,11 +4,7 @@ | c.c:6:5:6:6 | ls | array of 4 {int} | 1 | | c.c:8:5:8:7 | iss | array of 4 {array of 2 {int}} | 1 | | c.c:12:11:12:11 | i | typedef {int} as "int_alias" | 1 | -| c.h:4:12:4:13 | ks | array of {int} | 1 | -| c.h:8:12:8:14 | iss | array of {array of 2 {int}} | 1 | -| c.h:10:12:10:12 | i | int | 1 | | d.cpp:3:7:3:8 | xs | array of {int} | 1 | -| d.h:3:14:3:15 | xs | array of 2 {int} | 1 | | file://:0:0:0:0 | (unnamed parameter 0) | reference to {const {struct __va_list_tag}} | 1 | | file://:0:0:0:0 | (unnamed parameter 0) | rvalue reference to {struct __va_list_tag} | 1 | | file://:0:0:0:0 | fp_offset | unsigned int | 1 | From a7956ad422d6a8d46128b69824dc87d2b5dccc27 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Fri, 24 Jun 2022 10:15:17 +0200 Subject: [PATCH 159/465] C++: Add change note --- cpp/ql/lib/change-notes/2022-06-24-unique-variable.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2022-06-24-unique-variable.md diff --git a/cpp/ql/lib/change-notes/2022-06-24-unique-variable.md b/cpp/ql/lib/change-notes/2022-06-24-unique-variable.md new file mode 100644 index 00000000000..e04dde1290a --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-06-24-unique-variable.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Under certain circumstances a variable declaration that is not also a definition could be associated with a `Variable` that did not have the definition as a `VariableDeclarationEntry`. This is now fixed, and a unique `Variable` will exist that has both the declaration and the definition as a `VariableDeclarationEntry`. From 3026456a39b77361ae5821e95ca2a6aee17b8688 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Tue, 28 Jun 2022 14:38:13 +0100 Subject: [PATCH 160/465] Kotlin: Make more methods private --- java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt | 4 ++-- .../src/main/kotlin/utils/TypeSubstitution.kt | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt b/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt index dce49790e0e..57a3e92e6b2 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt @@ -55,7 +55,7 @@ private val specialFunctions = mapOf( private val specialFunctionShortNames = specialFunctions.keys.map { it.functionName }.toSet() -fun getSpecialJvmName(f: IrFunction): String? { +private fun getSpecialJvmName(f: IrFunction): String? { if (specialFunctionShortNames.contains(f.name) && f is IrSimpleFunction) { f.allOverridden(true).forEach { overriddenFunc -> overriddenFunc.parentClassOrNull?.fqNameWhenAvailable?.let { parentFqName -> @@ -87,4 +87,4 @@ fun getJvmName(container: IrAnnotationContainer): String? { } } return (container as? IrFunction)?.let { getSpecialJvmName(container) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt b/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt index b249bb0091a..694b3dff289 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/TypeSubstitution.kt @@ -37,7 +37,7 @@ fun IrType.substituteTypeArguments(params: List, arguments: Lis else -> this } -fun IrSimpleType.substituteTypeArguments(substitutionMap: Map): IrSimpleType { +private fun IrSimpleType.substituteTypeArguments(substitutionMap: Map): IrSimpleType { if (substitutionMap.isEmpty()) return this val newArguments = arguments.map { @@ -100,7 +100,7 @@ private fun subProjectedType(substitutionMap: Map context.irBuiltIns.anyNType is IrTypeProjection -> when(this.variance) { @@ -111,7 +111,7 @@ fun IrTypeArgument.upperBound(context: IrPluginContext) = else -> context.irBuiltIns.anyNType } -fun IrTypeArgument.lowerBound(context: IrPluginContext) = +private fun IrTypeArgument.lowerBound(context: IrPluginContext) = when(this) { is IrStarProjection -> context.irBuiltIns.nothingType is IrTypeProjection -> when(this.variance) { @@ -200,7 +200,7 @@ fun IrTypeArgument.withQuestionMark(b: Boolean): IrTypeArgument = typealias TypeSubstitution = (IrType, KotlinUsesExtractor.TypeContext, IrPluginContext) -> IrType -fun matchingTypeParameters(l: IrTypeParameter?, r: IrTypeParameter): Boolean { +private fun matchingTypeParameters(l: IrTypeParameter?, r: IrTypeParameter): Boolean { if (l === r) return true if (l == null) From 364085a596592f0f28ec9afff6339aa7616dfcf5 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 28 Jun 2022 15:44:42 +0200 Subject: [PATCH 161/465] Swift: add DotSyntaxCallExpr tests --- .../expr/DotSyntaxCallExpr/DotSyntaxCallExpr.expected | 2 ++ .../expr/DotSyntaxCallExpr/DotSyntaxCallExpr.ql | 11 +++++++++++ .../DotSyntaxCallExpr_getArgument.expected | 2 ++ .../DotSyntaxCallExpr_getArgument.ql | 7 +++++++ .../DotSyntaxCallExpr_getType.expected | 2 ++ .../DotSyntaxCallExpr/DotSyntaxCallExpr_getType.ql | 7 +++++++ .../expr/DotSyntaxCallExpr/MISSING_SOURCE.txt | 4 ---- .../expr/DotSyntaxCallExpr/dot_syntax_call.swift | 7 +++++++ 8 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.expected create mode 100644 swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.ql create mode 100644 swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.expected create mode 100644 swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.ql create mode 100644 swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.expected create mode 100644 swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.ql delete mode 100644 swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/dot_syntax_call.swift diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.expected b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.expected new file mode 100644 index 00000000000..d9f729ea4ac --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.expected @@ -0,0 +1,2 @@ +| dot_syntax_call.swift:6:1:6:3 | call to foo(_:_:) | getFunction: | dot_syntax_call.swift:6:3:6:3 | foo(_:_:) | getBaseExpr: | dot_syntax_call.swift:6:1:6:1 | X.Type | +| dot_syntax_call.swift:7:1:7:3 | call to bar() | getFunction: | dot_syntax_call.swift:7:3:7:3 | bar() | getBaseExpr: | dot_syntax_call.swift:7:1:7:1 | X.Type | diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.ql b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.ql new file mode 100644 index 00000000000..d4fce9de8bc --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr.ql @@ -0,0 +1,11 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from DotSyntaxCallExpr x, Expr getFunction, Expr getBaseExpr +where + toBeTested(x) and + not x.isUnknown() and + getFunction = x.getFunction() and + getBaseExpr = x.getBaseExpr() +select x, "getFunction:", getFunction, "getBaseExpr:", getBaseExpr diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.expected b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.expected new file mode 100644 index 00000000000..64bdae371b7 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.expected @@ -0,0 +1,2 @@ +| dot_syntax_call.swift:6:1:6:3 | call to foo(_:_:) | 0 | : X.Type | +| dot_syntax_call.swift:7:1:7:3 | call to bar() | 0 | : X.Type | diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.ql b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.ql new file mode 100644 index 00000000000..384f99edb51 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from DotSyntaxCallExpr x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getArgument(index) diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.expected b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.expected new file mode 100644 index 00000000000..f59178625cf --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.expected @@ -0,0 +1,2 @@ +| dot_syntax_call.swift:6:1:6:3 | call to foo(_:_:) | (Int, Int) -> () | +| dot_syntax_call.swift:7:1:7:3 | call to bar() | () -> () | diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.ql b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.ql new file mode 100644 index 00000000000..b7711a5d67c --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from DotSyntaxCallExpr x +where toBeTested(x) and not x.isUnknown() +select x, x.getType() diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/dot_syntax_call.swift b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/dot_syntax_call.swift new file mode 100644 index 00000000000..f8b97e23898 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/dot_syntax_call.swift @@ -0,0 +1,7 @@ +class X { + static func foo(_: Int, _:Int) {} + class func bar() {} +} + +X.foo(1, 2) +X.bar() From 63376da90f1b3181654c394e7aff21dbb61e70f7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 27 Jun 2022 17:39:48 +0100 Subject: [PATCH 162/465] Swift: Add tests for LogicalOperaion.qll. --- .../expr/logicaloperation/logicaloperation.expected | 0 .../expr/logicaloperation/logicaloperation.ql | 12 ++++++++++++ .../expr/logicaloperation/logicaloperation.swift | 8 ++++++++ 3 files changed, 20 insertions(+) create mode 100644 swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.expected create mode 100644 swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.ql create mode 100644 swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.swift diff --git a/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.expected b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.ql b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.ql new file mode 100644 index 00000000000..8d943f725b2 --- /dev/null +++ b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.ql @@ -0,0 +1,12 @@ +import swift + +string describe(LogicalOperation e) { + (e instanceof BinaryLogicalOperation and result = "BinaryLogicalExpr") or + (e instanceof LogicalAndExpr and result = "LogicalAndExpr") or + (e instanceof LogicalOrExpr and result = "LogicalOrExpr") or + (e instanceof UnaryLogicalOperation and result = "UnaryLogicalOperation") or + (e instanceof NotExpr and result = "NotExpr") +} + +from LogicalOperation e +select e, concat(describe(e), ", ") diff --git a/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.swift b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.swift new file mode 100644 index 00000000000..a1af03ab2c0 --- /dev/null +++ b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.swift @@ -0,0 +1,8 @@ + +func test(a: Bool, b: Bool, c: Bool) { + // logical operations + if (a && b) {} + if (a || b) {} + if (!a) {} + if (!((a && b) || c)) {} +} From 5c6ac2a5f2b14f761fed6974ac48d9731c0604c5 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 28 Jun 2022 16:15:05 +0200 Subject: [PATCH 163/465] Swift: accept test results --- .../generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected | 8 ++++---- .../expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected index cdf97ccd73a..9b22d5b34d4 100644 --- a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected @@ -3,8 +3,8 @@ | enum_is_case.swift:6:1:6:1 | ... is some | getSubExpr: | enum_is_case.swift:6:1:6:1 | 42 | getTypeRepr: | enum_is_case.swift:6:7:6:10 | ...? | getElement: | file://:0:0:0:0 | some | | enum_is_case.swift:7:1:7:1 | ... is some | getSubExpr: | enum_is_case.swift:7:1:7:1 | 42 | getTypeRepr: | enum_is_case.swift:7:7:7:11 | ...? | getElement: | file://:0:0:0:0 | some | | enum_is_case.swift:9:1:9:19 | ... is some | getSubExpr: | enum_is_case.swift:9:1:9:19 | [...] | getTypeRepr: | enum_is_case.swift:9:24:9:28 | [...] | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:20:1:20:18 | ... is some | getSubExpr: | enum_is_case.swift:20:1:20:18 | OptionalEvaluationExpr | getTypeRepr: | enum_is_case.swift:20:23:20:23 | SimpleIdentTypeRepr | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:22:1:22:5 | ... is some | getSubExpr: | enum_is_case.swift:22:1:22:5 | [...] | getTypeRepr: | enum_is_case.swift:22:10:22:12 | [...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:19:1:19:18 | ... is some | getSubExpr: | enum_is_case.swift:19:1:19:18 | OptionalEvaluationExpr | getTypeRepr: | enum_is_case.swift:19:23:19:23 | SimpleIdentTypeRepr | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:21:1:21:5 | ... is some | getSubExpr: | enum_is_case.swift:21:1:21:5 | [...] | getTypeRepr: | enum_is_case.swift:21:10:21:12 | [...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:22:1:22:10 | ... is some | getSubExpr: | enum_is_case.swift:22:1:22:10 | [...] | getTypeRepr: | enum_is_case.swift:22:15:22:25 | [... : ...] | getElement: | file://:0:0:0:0 | some | | enum_is_case.swift:23:1:23:10 | ... is some | getSubExpr: | enum_is_case.swift:23:1:23:10 | [...] | getTypeRepr: | enum_is_case.swift:23:15:23:25 | [... : ...] | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:24:1:24:10 | ... is some | getSubExpr: | enum_is_case.swift:24:1:24:10 | [...] | getTypeRepr: | enum_is_case.swift:24:15:24:25 | [... : ...] | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:25:1:25:8 | ... is some | getSubExpr: | enum_is_case.swift:25:1:25:8 | call to ... | getTypeRepr: | enum_is_case.swift:25:13:25:18 | ...<...> | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:24:1:24:8 | ... is some | getSubExpr: | enum_is_case.swift:24:1:24:8 | call to ... | getTypeRepr: | enum_is_case.swift:24:13:24:18 | ...<...> | getElement: | file://:0:0:0:0 | some | diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected index b3a0100a061..f1a8bd34fda 100644 --- a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr_getType.expected @@ -3,8 +3,8 @@ | enum_is_case.swift:6:1:6:1 | ... is some | Bool | | enum_is_case.swift:7:1:7:1 | ... is some | Bool | | enum_is_case.swift:9:1:9:19 | ... is some | Bool | -| enum_is_case.swift:20:1:20:18 | ... is some | Bool | -| enum_is_case.swift:22:1:22:5 | ... is some | Bool | +| enum_is_case.swift:19:1:19:18 | ... is some | Bool | +| enum_is_case.swift:21:1:21:5 | ... is some | Bool | +| enum_is_case.swift:22:1:22:10 | ... is some | Bool | | enum_is_case.swift:23:1:23:10 | ... is some | Bool | -| enum_is_case.swift:24:1:24:10 | ... is some | Bool | -| enum_is_case.swift:25:1:25:8 | ... is some | Bool | +| enum_is_case.swift:24:1:24:8 | ... is some | Bool | From b98c482c47daf1f9b199e76ec9e5a725d8103e7b Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 28 Jun 2022 14:00:56 +0000 Subject: [PATCH 164/465] Python: Fix bad join in MRO `flatten_list` This bad join was identified by the join-order-badness report, which showed that: py/use-of-input:MRO::flatten_list#f4eaf05f#fff#9c5fe54whnlqffdgu65vhb8uhpg# (order_500000) calculated a whopping 212,820,108 tuples in order to produce an output of size 55516, roughly 3833 times more effort than needed. Here's a snippet of the slowest iteration of that predicate: ``` Tuple counts for MRO::flatten_list#f4eaf05f#fff/3@i1839#0265eb3w after 14ms: 0 ~0% {3} r1 = JOIN MRO::need_flattening#f4eaf05f#f#prev_delta WITH MRO::ConsList#f4eaf05f#fff#reorder_2_0_1#prev ON FIRST 1 OUTPUT Rhs.1, Lhs.0 'list', Rhs.2 0 ~0% {3} r2 = JOIN r1 WITH MRO::ClassList::length#f0820431#ff#prev ON FIRST 1 OUTPUT Lhs.2, Lhs.1 'list', Rhs.1 'n' 0 ~0% {3} r3 = JOIN r2 WITH MRO::ClassListList::flatten#dispred#f0820431#ff#prev ON FIRST 1 OUTPUT Lhs.1 'list', Lhs.2 'n', Rhs.1 'result' 0 ~0% {3} r4 = SCAN MRO::ConsList#f4eaf05f#fff#prev_delta OUTPUT In.2 'list', In.0, In.1 0 ~0% {3} r5 = JOIN r4 WITH MRO::need_flattening#f4eaf05f#f#prev ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.0 'list' 0 ~0% {3} r6 = JOIN r5 WITH MRO::ClassList::length#f0820431#ff#prev ON FIRST 1 OUTPUT Lhs.1, Lhs.2 'list', Rhs.1 'n' 0 ~0% {3} r7 = JOIN r6 WITH MRO::ClassListList::flatten#dispred#f0820431#ff#prev ON FIRST 1 OUTPUT Lhs.1 'list', Lhs.2 'n', Rhs.1 'result' 0 ~0% {3} r8 = r3 UNION r7 26355 ~2% {3} r9 = SCAN MRO::ConsList#f4eaf05f#fff#prev OUTPUT In.2 'list', In.0, In.1 0 ~0% {3} r10 = JOIN r9 WITH MRO::need_flattening#f4eaf05f#f#prev ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.0 'list' 0 ~0% {3} r11 = JOIN r10 WITH MRO::ClassList::length#f0820431#ff#prev_delta ON FIRST 1 OUTPUT Lhs.1, Lhs.2 'list', Rhs.1 'n' 0 ~0% {3} r12 = JOIN r11 WITH MRO::ClassListList::flatten#dispred#f0820431#ff#prev ON FIRST 1 OUTPUT Lhs.1 'list', Lhs.2 'n', Rhs.1 'result' ... ``` (... and a bunch more lines. The same construction appears several times, but the join order is the same each time.) Clearly it would be better to start with whatever is in `need_flattening`, and then do the other joins. This is what the present fix does (by unbinding `list` in all but the `needs_flattening` call). After the fix, the slowest iteration is as follows: ``` Tuple counts for MRO::flatten_list#f4eaf05f#fff/3@i2617#8155ab3w after 9ms: 0 ~0% {2} r1 = SCAN MRO::need_flattening#f4eaf05f#f#prev_delta OUTPUT In.0 'list', In.0 'list' 0 ~0% {3} r2 = JOIN r1 WITH MRO::ConsList#f4eaf05f#fff#reorder_2_0_1#prev ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'list', Rhs.2 0 ~0% {3} r3 = JOIN r2 WITH MRO::ClassList::length#f0820431#ff#prev ON FIRST 1 OUTPUT Lhs.2, Lhs.1 'list', Rhs.1 'n' 0 ~0% {3} r4 = JOIN r3 WITH MRO::ClassListList::flatten#dispred#f0820431#ff#prev ON FIRST 1 OUTPUT Lhs.1 'list', Lhs.2 'n', Rhs.1 'result' 1 ~0% {2} r5 = SCAN MRO::need_flattening#f4eaf05f#f#prev OUTPUT In.0 'list', In.0 'list' 0 ~0% {3} r6 = JOIN r5 WITH MRO::ConsList#f4eaf05f#fff#reorder_2_0_1#prev_delta ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'list', Rhs.2 0 ~0% {3} r7 = JOIN r6 WITH MRO::ClassList::length#f0820431#ff#prev ON FIRST 1 OUTPUT Lhs.2, Lhs.1 'list', Rhs.1 'n' 0 ~0% {3} r8 = JOIN r7 WITH MRO::ClassListList::flatten#dispred#f0820431#ff#prev ON FIRST 1 OUTPUT Lhs.1 'list', Lhs.2 'n', Rhs.1 'result' ... ``` (... and so on. The remainder is 0 tuples all the way.) In total, we went from ``` 40.6s | 7614 | 15ms @ 1839 | MRO::flatten_list#f4eaf05f#fff@0265eb3w ``` to ``` 7.8s | 7614 | 11ms @ 2617 | MRO::flatten_list#f4eaf05f#fff@8155ab3w ``` --- python/ql/lib/semmle/python/pointsto/MRO.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/lib/semmle/python/pointsto/MRO.qll b/python/ql/lib/semmle/python/pointsto/MRO.qll index b1ea92b8c24..c1b9e859925 100644 --- a/python/ql/lib/semmle/python/pointsto/MRO.qll +++ b/python/ql/lib/semmle/python/pointsto/MRO.qll @@ -386,10 +386,10 @@ private class ClassListList extends TClassListList { private ClassList flatten_list(ClassListList list, int n) { need_flattening(list) and - exists(ClassList head, ClassListList tail | list = ConsList(head, tail) | + exists(ClassList head, ClassListList tail | pragma[only_bind_out](list) = ConsList(head, tail) | n = head.length() and result = tail.flatten() or - result = Cons(head.getItem(n), flatten_list(list, n + 1)) + result = Cons(head.getItem(n), flatten_list(pragma[only_bind_out](list), n + 1)) ) } From 363f7a88a9ac9c14d68c03473eeb707ea0c60ddc Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 28 Jun 2022 16:30:25 +0200 Subject: [PATCH 165/465] Swift: fix QL warnings about overriding methods The `getName` in `Type.qll` was issuing a warning in other generated classes having a `getName` from a `name` property in `schema.yml`. To fix the possible inconsistency, `diagnostic_name` is being renamed to `name` in the schema. Despite the scary doc comment on `swift::Type::getString` (namely `for use in diagnostics only`), that seems to be the right generic naming mechanism for types, and it coincides with the name we were extracting on types with an explicit `name` property. In case we find a case where `Type::getString` gives something wrong, we can probably just patch it on that specific type class. --- swift/codegen/schema.yml | 4 +--- swift/extractor/visitors/TypeVisitor.cpp | 5 ++--- .../swift/elements/type/AnyGenericType.qll | 6 ++--- .../lib/codeql/swift/elements/type/Type.qll | 4 +--- .../swift/generated/type/ArchetypeType.qll | 4 +--- .../generated/type/GenericTypeParamType.qll | 2 -- .../lib/codeql/swift/generated/type/Type.qll | 2 +- swift/ql/lib/swift.dbscheme | 6 ++--- .../BuiltinIntegerType.expected | 10 ++++----- .../BuiltinIntegerType/BuiltinIntegerType.ql | 6 ++--- .../type/BuiltinType/BuiltinType.expected | 22 +++++++++---------- .../generated/type/BuiltinType/BuiltinType.ql | 6 ++--- .../DynamicSelfType/DynamicSelfType.expected | 2 +- .../type/DynamicSelfType/DynamicSelfType.ql | 8 +++---- .../ExistentialType/ExistentialType.expected | 6 ++--- .../type/ExistentialType/ExistentialType.ql | 8 +++---- .../type/InOutType/InOutType.expected | 4 ++-- .../generated/type/InOutType/InOutType.ql | 8 +++---- .../NestedArchetypeType.expected | 8 +++---- .../NestedArchetypeType.ql | 13 +++++------ .../PrimaryArchetypeType.expected | 8 +++---- .../PrimaryArchetypeType.ql | 11 ++++------ .../ProtocolCompositionType.expected | 8 +++---- .../ProtocolCompositionType.ql | 6 ++--- .../UnmanagedStorageType.expected | 4 ++-- .../UnmanagedStorageType.ql | 8 +++---- .../UnownedStorageType.expected | 4 ++-- .../UnownedStorageType/UnownedStorageType.ql | 8 +++---- .../VariadicSequenceType.expected | 6 ++--- .../VariadicSequenceType.ql | 7 +++--- .../WeakStorageType/WeakStorageType.expected | 4 ++-- .../type/WeakStorageType/WeakStorageType.ql | 8 +++---- 32 files changed, 99 insertions(+), 117 deletions(-) diff --git a/swift/codegen/schema.yml b/swift/codegen/schema.yml index b95fedc10a9..f2e7837f2b2 100644 --- a/swift/codegen/schema.yml +++ b/swift/codegen/schema.yml @@ -32,7 +32,7 @@ Location: _pragma: qltest_skip Type: - diagnostics_name: string + name: string canonical_type: Type IterableDeclContext: @@ -245,14 +245,12 @@ WeakStorageType: ArchetypeType: _extends: SubstitutableType - name: string interface_type: Type superclass: Type? protocols: ProtocolDecl* GenericTypeParamType: _extends: SubstitutableType - name: string ParenType: _extends: SugarType diff --git a/swift/extractor/visitors/TypeVisitor.cpp b/swift/extractor/visitors/TypeVisitor.cpp index 5754abf7aba..4514692421e 100644 --- a/swift/extractor/visitors/TypeVisitor.cpp +++ b/swift/extractor/visitors/TypeVisitor.cpp @@ -152,7 +152,7 @@ void TypeVisitor::visitGenericFunctionType(swift::GenericFunctionType* type) { void TypeVisitor::visitGenericTypeParamType(swift::GenericTypeParamType* type) { auto label = dispatcher_.assignNewLabel(type); - dispatcher_.emit(GenericTypeParamTypesTrap{label, type->getName().str().str()}); + dispatcher_.emit(GenericTypeParamTypesTrap{label}); } void TypeVisitor::visitLValueType(swift::LValueType* type) { @@ -237,13 +237,12 @@ codeql::NestedArchetypeType TypeVisitor::translateNestedArchetypeType( } void TypeVisitor::fillType(const swift::TypeBase& type, codeql::Type& entry) { - entry.diagnostics_name = type.getString(); + entry.name = type.getString(); entry.canonical_type = dispatcher_.fetchLabel(type.getCanonicalType()); } void TypeVisitor::fillArchetypeType(const swift::ArchetypeType& type, ArchetypeType& entry) { entry.interface_type = dispatcher_.fetchLabel(type.getInterfaceType()); - entry.name = type.getName().str().str(); entry.protocols = dispatcher_.fetchRepeatedLabels(type.getConformsTo()); entry.superclass = dispatcher_.fetchOptionalLabel(type.getSuperclass()); } diff --git a/swift/ql/lib/codeql/swift/elements/type/AnyGenericType.qll b/swift/ql/lib/codeql/swift/elements/type/AnyGenericType.qll index dbdf4a9b27b..1dac1499152 100644 --- a/swift/ql/lib/codeql/swift/elements/type/AnyGenericType.qll +++ b/swift/ql/lib/codeql/swift/elements/type/AnyGenericType.qll @@ -1,6 +1,4 @@ +// generated by codegen/codegen.py, remove this comment if you wish to edit this file private import codeql.swift.generated.type.AnyGenericType -private import codeql.swift.elements.decl.GenericTypeDecl -class AnyGenericType extends AnyGenericTypeBase { - string getName() { result = this.getDeclaration().(GenericTypeDecl).getName() } -} +class AnyGenericType extends AnyGenericTypeBase { } diff --git a/swift/ql/lib/codeql/swift/elements/type/Type.qll b/swift/ql/lib/codeql/swift/elements/type/Type.qll index 18d37ff8b40..1b357e65560 100644 --- a/swift/ql/lib/codeql/swift/elements/type/Type.qll +++ b/swift/ql/lib/codeql/swift/elements/type/Type.qll @@ -1,7 +1,5 @@ private import codeql.swift.generated.type.Type class Type extends TypeBase { - override string toString() { result = this.getDiagnosticsName() } - - string getName() { result = this.getDiagnosticsName() } + override string toString() { result = this.getName() } } diff --git a/swift/ql/lib/codeql/swift/generated/type/ArchetypeType.qll b/swift/ql/lib/codeql/swift/generated/type/ArchetypeType.qll index a3184728112..ef257500f64 100644 --- a/swift/ql/lib/codeql/swift/generated/type/ArchetypeType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/ArchetypeType.qll @@ -4,11 +4,9 @@ import codeql.swift.elements.type.SubstitutableType import codeql.swift.elements.type.Type class ArchetypeTypeBase extends @archetype_type, SubstitutableType { - string getName() { archetype_types(this, result, _) } - Type getInterfaceType() { exists(Type x | - archetype_types(this, _, x) and + archetype_types(this, x) and result = x.resolve() ) } diff --git a/swift/ql/lib/codeql/swift/generated/type/GenericTypeParamType.qll b/swift/ql/lib/codeql/swift/generated/type/GenericTypeParamType.qll index c0b13904806..9f286d86cc7 100644 --- a/swift/ql/lib/codeql/swift/generated/type/GenericTypeParamType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/GenericTypeParamType.qll @@ -3,6 +3,4 @@ import codeql.swift.elements.type.SubstitutableType class GenericTypeParamTypeBase extends @generic_type_param_type, SubstitutableType { override string getAPrimaryQlClass() { result = "GenericTypeParamType" } - - string getName() { generic_type_param_types(this, result) } } diff --git a/swift/ql/lib/codeql/swift/generated/type/Type.qll b/swift/ql/lib/codeql/swift/generated/type/Type.qll index cfe4b638da3..ee55d9ce9d6 100644 --- a/swift/ql/lib/codeql/swift/generated/type/Type.qll +++ b/swift/ql/lib/codeql/swift/generated/type/Type.qll @@ -3,7 +3,7 @@ import codeql.swift.elements.Element import codeql.swift.elements.type.Type class TypeBase extends @type, Element { - string getDiagnosticsName() { types(this, result, _) } + string getName() { types(this, result, _) } Type getCanonicalType() { exists(Type x | diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index c726cd7635b..7937e938e70 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -82,7 +82,7 @@ locations( #keyset[id] types( //dir=type int id: @type ref, - string diagnostics_name: string ref, + string name: string ref, int canonical_type: @type ref ); @@ -593,7 +593,6 @@ weak_storage_types( //dir=type #keyset[id] archetype_types( //dir=type int id: @archetype_type ref, - string name: string ref, int interface_type: @type ref ); @@ -611,8 +610,7 @@ archetype_type_protocols( //dir=type ); generic_type_param_types( //dir=type - unique int id: @generic_type_param_type, - string name: string ref + unique int id: @generic_type_param_type ); paren_types( //dir=type diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.expected b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.expected index f50efd8d8d7..410b13be428 100644 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.expected +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.expected @@ -1,5 +1,5 @@ -| Builtin.Int8 | getDiagnosticsName: | Builtin.Int8 | getCanonicalType: | Builtin.Int8 | -| Builtin.Int16 | getDiagnosticsName: | Builtin.Int16 | getCanonicalType: | Builtin.Int16 | -| Builtin.Int32 | getDiagnosticsName: | Builtin.Int32 | getCanonicalType: | Builtin.Int32 | -| Builtin.Int64 | getDiagnosticsName: | Builtin.Int64 | getCanonicalType: | Builtin.Int64 | -| Builtin.Word | getDiagnosticsName: | Builtin.Word | getCanonicalType: | Builtin.Word | +| Builtin.Int8 | getName: | Builtin.Int8 | getCanonicalType: | Builtin.Int8 | +| Builtin.Int16 | getName: | Builtin.Int16 | getCanonicalType: | Builtin.Int16 | +| Builtin.Int32 | getName: | Builtin.Int32 | getCanonicalType: | Builtin.Int32 | +| Builtin.Int64 | getName: | Builtin.Int64 | getCanonicalType: | Builtin.Int64 | +| Builtin.Word | getName: | Builtin.Word | getCanonicalType: | Builtin.Word | diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.ql b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.ql index 6828ace5d1f..05131e5b9fd 100644 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.ql +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinIntegerType/BuiltinIntegerType.ql @@ -2,10 +2,10 @@ import codeql.swift.elements import TestUtils -from BuiltinIntegerType x, string getDiagnosticsName, Type getCanonicalType +from BuiltinIntegerType x, string getName, Type getCanonicalType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.expected b/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.expected index be0aaa1c1ca..5df760136c3 100644 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.expected +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.expected @@ -1,11 +1,11 @@ -| Builtin.BridgeObject | getDiagnosticsName: | Builtin.BridgeObject | getCanonicalType: | Builtin.BridgeObject | -| Builtin.DefaultActorStorage | getDiagnosticsName: | Builtin.DefaultActorStorage | getCanonicalType: | Builtin.DefaultActorStorage | -| Builtin.Executor | getDiagnosticsName: | Builtin.Executor | getCanonicalType: | Builtin.Executor | -| Builtin.FPIEEE32 | getDiagnosticsName: | Builtin.FPIEEE32 | getCanonicalType: | Builtin.FPIEEE32 | -| Builtin.FPIEEE64 | getDiagnosticsName: | Builtin.FPIEEE64 | getCanonicalType: | Builtin.FPIEEE64 | -| Builtin.IntLiteral | getDiagnosticsName: | Builtin.IntLiteral | getCanonicalType: | Builtin.IntLiteral | -| Builtin.Job | getDiagnosticsName: | Builtin.Job | getCanonicalType: | Builtin.Job | -| Builtin.NativeObject | getDiagnosticsName: | Builtin.NativeObject | getCanonicalType: | Builtin.NativeObject | -| Builtin.RawPointer | getDiagnosticsName: | Builtin.RawPointer | getCanonicalType: | Builtin.RawPointer | -| Builtin.RawUnsafeContinuation | getDiagnosticsName: | Builtin.RawUnsafeContinuation | getCanonicalType: | Builtin.RawUnsafeContinuation | -| Builtin.UnsafeValueBuffer | getDiagnosticsName: | Builtin.UnsafeValueBuffer | getCanonicalType: | Builtin.UnsafeValueBuffer | +| Builtin.BridgeObject | getName: | Builtin.BridgeObject | getCanonicalType: | Builtin.BridgeObject | +| Builtin.DefaultActorStorage | getName: | Builtin.DefaultActorStorage | getCanonicalType: | Builtin.DefaultActorStorage | +| Builtin.Executor | getName: | Builtin.Executor | getCanonicalType: | Builtin.Executor | +| Builtin.FPIEEE32 | getName: | Builtin.FPIEEE32 | getCanonicalType: | Builtin.FPIEEE32 | +| Builtin.FPIEEE64 | getName: | Builtin.FPIEEE64 | getCanonicalType: | Builtin.FPIEEE64 | +| Builtin.IntLiteral | getName: | Builtin.IntLiteral | getCanonicalType: | Builtin.IntLiteral | +| Builtin.Job | getName: | Builtin.Job | getCanonicalType: | Builtin.Job | +| Builtin.NativeObject | getName: | Builtin.NativeObject | getCanonicalType: | Builtin.NativeObject | +| Builtin.RawPointer | getName: | Builtin.RawPointer | getCanonicalType: | Builtin.RawPointer | +| Builtin.RawUnsafeContinuation | getName: | Builtin.RawUnsafeContinuation | getCanonicalType: | Builtin.RawUnsafeContinuation | +| Builtin.UnsafeValueBuffer | getName: | Builtin.UnsafeValueBuffer | getCanonicalType: | Builtin.UnsafeValueBuffer | diff --git a/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.ql b/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.ql index d858afd70c8..d6b019a4a6d 100644 --- a/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.ql +++ b/swift/ql/test/extractor-tests/generated/type/BuiltinType/BuiltinType.ql @@ -2,10 +2,10 @@ import codeql.swift.elements import TestUtils -from BuiltinType x, string getDiagnosticsName, Type getCanonicalType +from BuiltinType x, string getName, Type getCanonicalType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType diff --git a/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.expected b/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.expected index 833a3098c1f..6e36cc0e55f 100644 --- a/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.expected +++ b/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.expected @@ -1 +1 @@ -| Self | getDiagnosticsName: | Self | getCanonicalType: | Self | getStaticSelfType: | X | +| Self | getName: | Self | getCanonicalType: | Self | getStaticSelfType: | X | diff --git a/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql b/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql index a9ae23f6bab..24168993ef3 100644 --- a/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql +++ b/swift/ql/test/extractor-tests/generated/type/DynamicSelfType/DynamicSelfType.ql @@ -2,12 +2,12 @@ import codeql.swift.elements import TestUtils -from DynamicSelfType x, string getDiagnosticsName, Type getCanonicalType, Type getStaticSelfType +from DynamicSelfType x, string getName, Type getCanonicalType, Type getStaticSelfType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getStaticSelfType = x.getStaticSelfType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getStaticSelfType:", getStaticSelfType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getStaticSelfType:", + getStaticSelfType diff --git a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.expected b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.expected index 22277bec084..39ad24b358b 100644 --- a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.expected +++ b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.expected @@ -1,3 +1,3 @@ -| ExplicitExistential | getDiagnosticsName: | ExplicitExistential | getCanonicalType: | ExplicitExistential | getConstraint: | ExplicitExistential | -| ImplicitExistential | getDiagnosticsName: | ImplicitExistential | getCanonicalType: | ImplicitExistential | getConstraint: | ImplicitExistential | -| P1 & P2 | getDiagnosticsName: | P1 & P2 | getCanonicalType: | P1 & P2 | getConstraint: | P1 & P2 | +| ExplicitExistential | getName: | ExplicitExistential | getCanonicalType: | ExplicitExistential | getConstraint: | ExplicitExistential | +| ImplicitExistential | getName: | ImplicitExistential | getCanonicalType: | ImplicitExistential | getConstraint: | ImplicitExistential | +| P1 & P2 | getName: | P1 & P2 | getCanonicalType: | P1 & P2 | getConstraint: | P1 & P2 | diff --git a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql index b679d5d89a2..70fd9f1ea2b 100644 --- a/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql +++ b/swift/ql/test/extractor-tests/generated/type/ExistentialType/ExistentialType.ql @@ -2,12 +2,12 @@ import codeql.swift.elements import TestUtils -from ExistentialType x, string getDiagnosticsName, Type getCanonicalType, Type getConstraint +from ExistentialType x, string getName, Type getCanonicalType, Type getConstraint where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getConstraint = x.getConstraint() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getConstraint:", getConstraint +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getConstraint:", + getConstraint diff --git a/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.expected b/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.expected index b227fccd42b..a9d0e530015 100644 --- a/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.expected +++ b/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.expected @@ -1,2 +1,2 @@ -| inout Int | getDiagnosticsName: | inout Int | getCanonicalType: | inout Int | getObjectType: | Int | -| inout S | getDiagnosticsName: | inout S | getCanonicalType: | inout S | getObjectType: | S | +| inout Int | getName: | inout Int | getCanonicalType: | inout Int | getObjectType: | Int | +| inout S | getName: | inout S | getCanonicalType: | inout S | getObjectType: | S | diff --git a/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql b/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql index 973d0257381..1120208101d 100644 --- a/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql +++ b/swift/ql/test/extractor-tests/generated/type/InOutType/InOutType.ql @@ -2,12 +2,12 @@ import codeql.swift.elements import TestUtils -from InOutType x, string getDiagnosticsName, Type getCanonicalType, Type getObjectType +from InOutType x, string getName, Type getCanonicalType, Type getObjectType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getObjectType = x.getObjectType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getObjectType:", getObjectType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getObjectType:", + getObjectType diff --git a/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.expected b/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.expected index 30f113c662f..0575e43769c 100644 --- a/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.expected +++ b/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.expected @@ -1,4 +1,4 @@ -| Impl1.Associated | getDiagnosticsName: | Impl1.Associated | getCanonicalType: | Impl1.Associated | getName: | Associated | getInterfaceType: | Impl1.Associated | getParent: | Impl1 | getAssociatedTypeDeclaration: | nested_archetypes.swift:2:5:2:20 | Associated | -| Impl2.AssociatedWithProtocols | getDiagnosticsName: | Impl2.AssociatedWithProtocols | getCanonicalType: | Impl2.AssociatedWithProtocols | getName: | AssociatedWithProtocols | getInterfaceType: | Impl2.AssociatedWithProtocols | getParent: | Impl2 | getAssociatedTypeDeclaration: | nested_archetypes.swift:6:5:6:57 | AssociatedWithProtocols | -| Impl3.AssociatedWithSuperclass | getDiagnosticsName: | Impl3.AssociatedWithSuperclass | getCanonicalType: | Impl3.AssociatedWithSuperclass | getName: | AssociatedWithSuperclass | getInterfaceType: | Impl3.AssociatedWithSuperclass | getParent: | Impl3 | getAssociatedTypeDeclaration: | nested_archetypes.swift:12:5:12:47 | AssociatedWithSuperclass | -| Impl4.AssociatedWithSuperclassAndProtocols | getDiagnosticsName: | Impl4.AssociatedWithSuperclassAndProtocols | getCanonicalType: | Impl4.AssociatedWithSuperclassAndProtocols | getName: | AssociatedWithSuperclassAndProtocols | getInterfaceType: | Impl4.AssociatedWithSuperclassAndProtocols | getParent: | Impl4 | getAssociatedTypeDeclaration: | nested_archetypes.swift:16:5:16:73 | AssociatedWithSuperclassAndProtocols | +| Impl1.Associated | getName: | Impl1.Associated | getCanonicalType: | Impl1.Associated | getInterfaceType: | Impl1.Associated | getParent: | Impl1 | getAssociatedTypeDeclaration: | nested_archetypes.swift:2:5:2:20 | Associated | +| Impl2.AssociatedWithProtocols | getName: | Impl2.AssociatedWithProtocols | getCanonicalType: | Impl2.AssociatedWithProtocols | getInterfaceType: | Impl2.AssociatedWithProtocols | getParent: | Impl2 | getAssociatedTypeDeclaration: | nested_archetypes.swift:6:5:6:57 | AssociatedWithProtocols | +| Impl3.AssociatedWithSuperclass | getName: | Impl3.AssociatedWithSuperclass | getCanonicalType: | Impl3.AssociatedWithSuperclass | getInterfaceType: | Impl3.AssociatedWithSuperclass | getParent: | Impl3 | getAssociatedTypeDeclaration: | nested_archetypes.swift:12:5:12:47 | AssociatedWithSuperclass | +| Impl4.AssociatedWithSuperclassAndProtocols | getName: | Impl4.AssociatedWithSuperclassAndProtocols | getCanonicalType: | Impl4.AssociatedWithSuperclassAndProtocols | getInterfaceType: | Impl4.AssociatedWithSuperclassAndProtocols | getParent: | Impl4 | getAssociatedTypeDeclaration: | nested_archetypes.swift:16:5:16:73 | AssociatedWithSuperclassAndProtocols | diff --git a/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql b/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql index 8306bfeacac..b74c0e43099 100644 --- a/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql +++ b/swift/ql/test/extractor-tests/generated/type/NestedArchetypeType/NestedArchetypeType.ql @@ -3,17 +3,16 @@ import codeql.swift.elements import TestUtils from - NestedArchetypeType x, string getDiagnosticsName, Type getCanonicalType, string getName, - Type getInterfaceType, ArchetypeType getParent, AssociatedTypeDecl getAssociatedTypeDeclaration + NestedArchetypeType x, string getName, Type getCanonicalType, Type getInterfaceType, + ArchetypeType getParent, AssociatedTypeDecl getAssociatedTypeDeclaration where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and - getCanonicalType = x.getCanonicalType() and getName = x.getName() and + getCanonicalType = x.getCanonicalType() and getInterfaceType = x.getInterfaceType() and getParent = x.getParent() and getAssociatedTypeDeclaration = x.getAssociatedTypeDeclaration() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getName:", getName, "getInterfaceType:", getInterfaceType, "getParent:", getParent, - "getAssociatedTypeDeclaration:", getAssociatedTypeDeclaration +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getInterfaceType:", + getInterfaceType, "getParent:", getParent, "getAssociatedTypeDeclaration:", + getAssociatedTypeDeclaration diff --git a/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.expected b/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.expected index 47d540c489a..c29242f0b27 100644 --- a/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.expected +++ b/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.expected @@ -1,4 +1,4 @@ -| Param | getDiagnosticsName: | Param | getCanonicalType: | Param | getName: | Param | getInterfaceType: | Param | -| ParamWithProtocols | getDiagnosticsName: | ParamWithProtocols | getCanonicalType: | ParamWithProtocols | getName: | ParamWithProtocols | getInterfaceType: | ParamWithProtocols | -| ParamWithSuperclass | getDiagnosticsName: | ParamWithSuperclass | getCanonicalType: | ParamWithSuperclass | getName: | ParamWithSuperclass | getInterfaceType: | ParamWithSuperclass | -| ParamWithSuperclassAndProtocols | getDiagnosticsName: | ParamWithSuperclassAndProtocols | getCanonicalType: | ParamWithSuperclassAndProtocols | getName: | ParamWithSuperclassAndProtocols | getInterfaceType: | ParamWithSuperclassAndProtocols | +| Param | getName: | Param | getCanonicalType: | Param | getInterfaceType: | Param | +| ParamWithProtocols | getName: | ParamWithProtocols | getCanonicalType: | ParamWithProtocols | getInterfaceType: | ParamWithProtocols | +| ParamWithSuperclass | getName: | ParamWithSuperclass | getCanonicalType: | ParamWithSuperclass | getInterfaceType: | ParamWithSuperclass | +| ParamWithSuperclassAndProtocols | getName: | ParamWithSuperclassAndProtocols | getCanonicalType: | ParamWithSuperclassAndProtocols | getInterfaceType: | ParamWithSuperclassAndProtocols | diff --git a/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql b/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql index 925bf85dcbf..32cb2204418 100644 --- a/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql +++ b/swift/ql/test/extractor-tests/generated/type/PrimaryArchetypeType/PrimaryArchetypeType.ql @@ -2,15 +2,12 @@ import codeql.swift.elements import TestUtils -from - PrimaryArchetypeType x, string getDiagnosticsName, Type getCanonicalType, string getName, - Type getInterfaceType +from PrimaryArchetypeType x, string getName, Type getCanonicalType, Type getInterfaceType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and - getCanonicalType = x.getCanonicalType() and getName = x.getName() and + getCanonicalType = x.getCanonicalType() and getInterfaceType = x.getInterfaceType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getName:", getName, "getInterfaceType:", getInterfaceType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getInterfaceType:", + getInterfaceType diff --git a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.expected b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.expected index 31d909f4c17..7be629a81ca 100644 --- a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.expected +++ b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.expected @@ -1,4 +1,4 @@ -| P1 & (P2 & P3) | getDiagnosticsName: | P1 & (P2 & P3) | getCanonicalType: | P1 & P2 & P3 | -| P1 & P2 & P3 | getDiagnosticsName: | P1 & P2 & P3 | getCanonicalType: | P1 & P2 & P3 | -| P1 & P23 | getDiagnosticsName: | P1 & P23 | getCanonicalType: | P1 & P2 & P3 | -| P2 & P4 | getDiagnosticsName: | P2 & P4 | getCanonicalType: | P2 & P4 | +| P1 & (P2 & P3) | getName: | P1 & (P2 & P3) | getCanonicalType: | P1 & P2 & P3 | +| P1 & P2 & P3 | getName: | P1 & P2 & P3 | getCanonicalType: | P1 & P2 & P3 | +| P1 & P23 | getName: | P1 & P23 | getCanonicalType: | P1 & P2 & P3 | +| P2 & P4 | getName: | P2 & P4 | getCanonicalType: | P2 & P4 | diff --git a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.ql b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.ql index 2253a888b1f..8d3b769eff5 100644 --- a/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.ql +++ b/swift/ql/test/extractor-tests/generated/type/ProtocolCompositionType/ProtocolCompositionType.ql @@ -2,10 +2,10 @@ import codeql.swift.elements import TestUtils -from ProtocolCompositionType x, string getDiagnosticsName, Type getCanonicalType +from ProtocolCompositionType x, string getName, Type getCanonicalType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType diff --git a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.expected b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.expected index bd7b78838c7..fd0739cefbc 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.expected +++ b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.expected @@ -1,2 +1,2 @@ -| A? | getDiagnosticsName: | A? | getCanonicalType: | Optional | getReferentType: | A? | -| Optional | getDiagnosticsName: | Optional | getCanonicalType: | Optional | getReferentType: | Optional | +| A? | getName: | A? | getCanonicalType: | Optional | getReferentType: | A? | +| Optional | getName: | Optional | getCanonicalType: | Optional | getReferentType: | Optional | diff --git a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql index 396988db25e..747bfa62e43 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql +++ b/swift/ql/test/extractor-tests/generated/type/UnmanagedStorageType/UnmanagedStorageType.ql @@ -2,12 +2,12 @@ import codeql.swift.elements import TestUtils -from UnmanagedStorageType x, string getDiagnosticsName, Type getCanonicalType, Type getReferentType +from UnmanagedStorageType x, string getName, Type getCanonicalType, Type getReferentType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getReferentType = x.getReferentType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getReferentType:", getReferentType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getReferentType:", + getReferentType diff --git a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.expected b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.expected index bd7b78838c7..fd0739cefbc 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.expected +++ b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.expected @@ -1,2 +1,2 @@ -| A? | getDiagnosticsName: | A? | getCanonicalType: | Optional | getReferentType: | A? | -| Optional | getDiagnosticsName: | Optional | getCanonicalType: | Optional | getReferentType: | Optional | +| A? | getName: | A? | getCanonicalType: | Optional | getReferentType: | A? | +| Optional | getName: | Optional | getCanonicalType: | Optional | getReferentType: | Optional | diff --git a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql index 17744a437d7..85a48fd3710 100644 --- a/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql +++ b/swift/ql/test/extractor-tests/generated/type/UnownedStorageType/UnownedStorageType.ql @@ -2,12 +2,12 @@ import codeql.swift.elements import TestUtils -from UnownedStorageType x, string getDiagnosticsName, Type getCanonicalType, Type getReferentType +from UnownedStorageType x, string getName, Type getCanonicalType, Type getReferentType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getReferentType = x.getReferentType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getReferentType:", getReferentType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getReferentType:", + getReferentType diff --git a/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.expected b/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.expected index 117748421b6..3bc4a94f39b 100644 --- a/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.expected +++ b/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.expected @@ -1,3 +1,3 @@ -| Int... | getDiagnosticsName: | Int... | getCanonicalType: | Array | getBaseType: | Int | -| T... | getDiagnosticsName: | T... | getCanonicalType: | Array | getBaseType: | T | -| T... | getDiagnosticsName: | T... | getCanonicalType: | Array<\u03c4_0_0> | getBaseType: | T | +| Int... | getName: | Int... | getCanonicalType: | Array | getBaseType: | Int | +| T... | getName: | T... | getCanonicalType: | Array | getBaseType: | T | +| T... | getName: | T... | getCanonicalType: | Array<\u03c4_0_0> | getBaseType: | T | diff --git a/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql b/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql index 5a89dbcafab..7d4a8ea1af7 100644 --- a/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql +++ b/swift/ql/test/extractor-tests/generated/type/VariadicSequenceType/VariadicSequenceType.ql @@ -2,12 +2,11 @@ import codeql.swift.elements import TestUtils -from VariadicSequenceType x, string getDiagnosticsName, Type getCanonicalType, Type getBaseType +from VariadicSequenceType x, string getName, Type getCanonicalType, Type getBaseType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getBaseType = x.getBaseType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getBaseType:", getBaseType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getBaseType:", getBaseType diff --git a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.expected b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.expected index bd7b78838c7..fd0739cefbc 100644 --- a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.expected +++ b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.expected @@ -1,2 +1,2 @@ -| A? | getDiagnosticsName: | A? | getCanonicalType: | Optional | getReferentType: | A? | -| Optional | getDiagnosticsName: | Optional | getCanonicalType: | Optional | getReferentType: | Optional | +| A? | getName: | A? | getCanonicalType: | Optional | getReferentType: | A? | +| Optional | getName: | Optional | getCanonicalType: | Optional | getReferentType: | Optional | diff --git a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql index 3209b0e7d3d..e332f518a40 100644 --- a/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql +++ b/swift/ql/test/extractor-tests/generated/type/WeakStorageType/WeakStorageType.ql @@ -2,12 +2,12 @@ import codeql.swift.elements import TestUtils -from WeakStorageType x, string getDiagnosticsName, Type getCanonicalType, Type getReferentType +from WeakStorageType x, string getName, Type getCanonicalType, Type getReferentType where toBeTested(x) and not x.isUnknown() and - getDiagnosticsName = x.getDiagnosticsName() and + getName = x.getName() and getCanonicalType = x.getCanonicalType() and getReferentType = x.getReferentType() -select x, "getDiagnosticsName:", getDiagnosticsName, "getCanonicalType:", getCanonicalType, - "getReferentType:", getReferentType +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getReferentType:", + getReferentType From 9e0cf62cdae127b96ef70f49d2e0f56bc1ccc959 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 28 Jun 2022 14:57:52 +0100 Subject: [PATCH 166/465] Swift: Fix + simplify LogicalOperation.qll. --- .../swift/elements/expr/LogicalOperation.qll | 22 +++++-------------- .../logicaloperation.expected | 6 +++++ 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/swift/ql/lib/codeql/swift/elements/expr/LogicalOperation.qll b/swift/ql/lib/codeql/swift/elements/expr/LogicalOperation.qll index 928e25cccfd..5a550923199 100644 --- a/swift/ql/lib/codeql/swift/elements/expr/LogicalOperation.qll +++ b/swift/ql/lib/codeql/swift/elements/expr/LogicalOperation.qll @@ -6,31 +6,19 @@ private import codeql.swift.elements.expr.DeclRefExpr private import codeql.swift.elements.decl.ConcreteFuncDecl private predicate unaryHasName(PrefixUnaryExpr e, string name) { - e.getFunction() - .(DotSyntaxCallExpr) - .getFunction() - .(DeclRefExpr) - .getDecl() - .(ConcreteFuncDecl) - .getName() = name + e.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = name } private predicate binaryHasName(BinaryExpr e, string name) { - e.getFunction() - .(DotSyntaxCallExpr) - .getFunction() - .(DeclRefExpr) - .getDecl() - .(ConcreteFuncDecl) - .getName() = name + e.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = name } class LogicalAndExpr extends BinaryExpr { - LogicalAndExpr() { binaryHasName(this, "&&") } + LogicalAndExpr() { binaryHasName(this, "&&(_:_:)") } } class LogicalOrExpr extends BinaryExpr { - LogicalOrExpr() { binaryHasName(this, "||") } + LogicalOrExpr() { binaryHasName(this, "||(_:_:)") } } class BinaryLogicalOperation extends BinaryExpr { @@ -41,7 +29,7 @@ class BinaryLogicalOperation extends BinaryExpr { } class NotExpr extends PrefixUnaryExpr { - NotExpr() { unaryHasName(this, "!") } + NotExpr() { unaryHasName(this, "!(_:)") } } class UnaryLogicalOperation extends PrefixUnaryExpr { diff --git a/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.expected b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.expected index e69de29bb2d..1b3ccaab17f 100644 --- a/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.expected +++ b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.expected @@ -0,0 +1,6 @@ +| logicaloperation.swift:4:6:4:11 | ... call to &&(_:_:) ... | BinaryLogicalExpr, LogicalAndExpr | +| logicaloperation.swift:5:6:5:11 | ... call to \|\|(_:_:) ... | BinaryLogicalExpr, LogicalOrExpr | +| logicaloperation.swift:6:6:6:7 | call to ... | NotExpr, UnaryLogicalOperation | +| logicaloperation.swift:7:6:7:21 | call to ... | NotExpr, UnaryLogicalOperation | +| logicaloperation.swift:7:8:7:20 | ... call to \|\|(_:_:) ... | BinaryLogicalExpr, LogicalOrExpr | +| logicaloperation.swift:7:9:7:14 | ... call to &&(_:_:) ... | BinaryLogicalExpr, LogicalAndExpr | From a5fff9af5d20350fc3d62ac61139747ec2259948 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 27 Jun 2022 18:08:19 +0100 Subject: [PATCH 167/465] Swift: Create ArithmeticOperation.qll. --- .../elements/expr/ArithmeticOperation.qll | 99 +++++++++++++++++++ swift/ql/lib/swift.qll | 1 + 2 files changed, 100 insertions(+) create mode 100644 swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll diff --git a/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll b/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll new file mode 100644 index 00000000000..04d2185aab6 --- /dev/null +++ b/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll @@ -0,0 +1,99 @@ +private import codeql.swift.elements.expr.Expr +private import codeql.swift.elements.expr.BinaryExpr +private import codeql.swift.elements.expr.PrefixUnaryExpr +private import codeql.swift.elements.expr.DotSyntaxCallExpr + +/** + * An arithmetic operation, such as: + * ``` + * a + b + * ``` + */ +class ArithmeticOperation extends Expr { + ArithmeticOperation() { + this instanceof BinaryArithmeticOperation or + this instanceof UnaryArithmeticOperation + } + + Expr getAnOperand() { + result = this.(BinaryArithmeticOperation).getAnOperand() + or + result = this.(UnaryArithmeticOperation).getOperand() + } +} + +/** + * A binary arithmetic operation, such as: + * ``` + * a + b + * ``` + */ +abstract class BinaryArithmeticOperation extends BinaryExpr { } + +/** + * An add expression. + * ``` + * a + b + * ``` + */ +class AddExpr extends BinaryArithmeticOperation { + AddExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "+(_:_:)" } +} + +/** + * A subtract expression. + * ``` + * a - b + * ``` + */ +class SubExpr extends BinaryArithmeticOperation { + SubExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "-(_:_:)" } +} + +/** + * A multiply expression. + * ``` + * a * b + * ``` + */ +class MulExpr extends BinaryArithmeticOperation { + MulExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "*(_:_:)" } +} + +/** + * A divide expression. + * ``` + * a / b + * ``` + */ +class DivExpr extends BinaryArithmeticOperation { + DivExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "/(_:_:)" } +} + +/** + * A remainder expression. + * ``` + * a % b + * ``` + */ +class RemExpr extends BinaryArithmeticOperation { + RemExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "%(_:_:)" } +} + +/** + * A unary arithmetic operation, such as: + * ``` + * -a + * ``` + */ +abstract class UnaryArithmeticOperation extends PrefixUnaryExpr { } + +/** + * A unary minus expression. + * ``` + * -a + * ``` + */ +class UnaryMinusExpr extends UnaryArithmeticOperation { + UnaryMinusExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "-(_:)" } +} diff --git a/swift/ql/lib/swift.qll b/swift/ql/lib/swift.qll index a0b0f019400..d9281ba1093 100644 --- a/swift/ql/lib/swift.qll +++ b/swift/ql/lib/swift.qll @@ -1,5 +1,6 @@ /** Top-level import for the Swift language pack */ import codeql.swift.elements +import codeql.swift.elements.expr.ArithmeticOperation import codeql.swift.elements.expr.LogicalOperation import codeql.swift.elements.decl.MethodDecl From 8a8a7ead9b707b89399fcb0b43afc1a2453e0427 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 27 Jun 2022 17:42:20 +0100 Subject: [PATCH 168/465] Swift: Add tests for ArithmeticOperation.qll. --- .../arithmeticoperation.expected | 6 ++++++ .../arithmeticoperation/arithmeticoperation.ql | 15 +++++++++++++++ .../arithmeticoperation/arithmeticoperation.swift | 12 ++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.expected create mode 100644 swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.ql create mode 100644 swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.swift diff --git a/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.expected b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.expected new file mode 100644 index 00000000000..3d20366aec6 --- /dev/null +++ b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.expected @@ -0,0 +1,6 @@ +| arithmeticoperation.swift:6:6:6:10 | ... call to +(_:_:) ... | AddExpr, BinaryArithmeticOperation | +| arithmeticoperation.swift:7:6:7:10 | ... call to -(_:_:) ... | BinaryArithmeticOperation, SubExpr | +| arithmeticoperation.swift:8:6:8:10 | ... call to *(_:_:) ... | BinaryArithmeticOperation, MulExpr | +| arithmeticoperation.swift:9:6:9:10 | ... call to /(_:_:) ... | BinaryArithmeticOperation, DivExpr | +| arithmeticoperation.swift:10:6:10:10 | ... call to %(_:_:) ... | BinaryArithmeticOperation, RemExpr | +| arithmeticoperation.swift:11:6:11:7 | call to ... | UnaryArithmeticOperation, UnaryMinusExpr | diff --git a/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.ql b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.ql new file mode 100644 index 00000000000..2aeba5981b8 --- /dev/null +++ b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.ql @@ -0,0 +1,15 @@ +import swift + +string describe(ArithmeticOperation e) { + (e instanceof BinaryArithmeticOperation and result = "BinaryArithmeticOperation") or + (e instanceof AddExpr and result = "AddExpr") or + (e instanceof SubExpr and result = "SubExpr") or + (e instanceof MulExpr and result = "MulExpr") or + (e instanceof DivExpr and result = "DivExpr") or + (e instanceof RemExpr and result = "RemExpr") or + (e instanceof UnaryArithmeticOperation and result = "UnaryArithmeticOperation") or + (e instanceof UnaryMinusExpr and result = "UnaryMinusExpr") +} + +from ArithmeticOperation e +select e, concat(describe(e), ", ") diff --git a/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.swift b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.swift new file mode 100644 index 00000000000..096b6709600 --- /dev/null +++ b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.swift @@ -0,0 +1,12 @@ + +func test(c: Bool, x: Int, y: Int, z: Int) { + var v = 0 + + // arithmetic operations + v = x + y; + v = x - 1; + v = 2 * y; + v = 3 / 4; + v = x % y; + v = -x; +} From ff06e3cb6bb9614288f9b050bb9194feeb151583 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 28 Jun 2022 09:12:23 +0100 Subject: [PATCH 169/465] Swift: Add a Locatable.getFile() shortcut similar to the one in CPP. --- swift/ql/lib/codeql/swift/elements/Locatable.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/swift/ql/lib/codeql/swift/elements/Locatable.qll b/swift/ql/lib/codeql/swift/elements/Locatable.qll index 19b5cc4818e..f07641af07b 100644 --- a/swift/ql/lib/codeql/swift/elements/Locatable.qll +++ b/swift/ql/lib/codeql/swift/elements/Locatable.qll @@ -1,4 +1,5 @@ private import codeql.swift.generated.Locatable +private import codeql.swift.elements.File class Locatable extends LocatableBase { pragma[nomagic] @@ -7,4 +8,9 @@ class Locatable extends LocatableBase { or not exists(LocatableBase.super.getLocation()) and result instanceof UnknownLocation } + + /** + * Gets the primary file where this element occurs. + */ + File getFile() { result = getLocation().getFile() } } From 1a7f5db8e2815b32d6bc15b885206725bfac9fc8 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 28 Jun 2022 17:01:06 +0100 Subject: [PATCH 170/465] Swift: Set 'swift/string-length-conflation' to precision high and delete the placeholder query. --- .../queries/Security/CWE-135/StringLengthConflation.ql | 2 +- swift/ql/src/queries/placeholder.ql | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) delete mode 100644 swift/ql/src/queries/placeholder.ql diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 9dd758e7d33..461b1741e24 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -4,7 +4,7 @@ * @kind problem * @problem.severity error * @security-severity 7.8 - * @precision TODO + * @precision high * @id swift/string-length-conflation * @tags security * external/cwe/cwe-135 diff --git a/swift/ql/src/queries/placeholder.ql b/swift/ql/src/queries/placeholder.ql deleted file mode 100644 index 24a95c4899c..00000000000 --- a/swift/ql/src/queries/placeholder.ql +++ /dev/null @@ -1,9 +0,0 @@ -/** - * @kind problem - * @id swift/placeholder - */ - -import swift - -from IntegerLiteralExpr lit -select lit, "A literal" From 0f8ffb12e63389cf30228fe2e197bd5fd5deca88 Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Tue, 28 Jun 2022 09:45:54 -0700 Subject: [PATCH 171/465] Update docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst --- .../codeql-cli/analyzing-databases-with-the-codeql-cli.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst index e52cd53e2bd..6953d67f81b 100644 --- a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst @@ -138,7 +138,7 @@ For further information about default suites, see ":ref:`Publishing and using Co Running a subset of queries in a CodeQL pack ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Additionally, CodeQL CLI v2.10.0 or later, you can include a path at the end of a pack specification to run a subset of queries inside the pack. This applies to any command that locates or runs queries within a pack. +Additionally, CodeQL CLI v2.8.1 or later, you can include a path at the end of a pack specification to run a subset of queries inside the pack. This applies to any command that locates or runs queries within a pack. The complete way to specify a set of queries is in the form ``scope/name@range:path``, where: From 38b86405827c7a76e83cd2c6bf69d5e341166589 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 28 Jun 2022 16:39:20 +0000 Subject: [PATCH 172/465] Python: Fix bad join in `RegExpBackRef::getGroup` Although this wasn't (as far as I know) causing any performance issues, it was making the join-order badness report quite noisy, and so I figured it was worth fixing. Before: ``` Tuple counts for RegexTreeView::RegExpBackRef::getGroup#dispred#f0820431#ff/2@d3441d0b after 84ms: 1501195 ~3% {2} r1 = JOIN RegexTreeView::RegExpTerm::getLiteral#dispred#f0820431#ff_10#join_rhs WITH RegexTreeView::RegExpTerm::getLiteral#dispred#f0820431#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1 'result', Lhs.1 'result' 149 ~0% {5} r2 = JOIN r1 WITH RegexTreeView::RegExpBackRef#class#31aac2a7#ffff ON FIRST 1 OUTPUT Rhs.1, Rhs.2, Rhs.3, Lhs.1 'result', Lhs.0 'this' 149 ~1% {3} r3 = JOIN r2 WITH regex::RegexString::numbered_backreference#dispred#f0820431#ffff ON FIRST 3 OUTPUT Lhs.3 'result', Rhs.3, Lhs.4 'this' 4 ~0% {2} r4 = JOIN r3 WITH RegexTreeView::RegExpGroup::getNumber#dispred#f0820431#ff ON FIRST 2 OUTPUT Lhs.2 'this', Lhs.0 'result' 1501195 ~3% {2} r5 = JOIN RegexTreeView::RegExpTerm::getLiteral#dispred#f0820431#ff_10#join_rhs WITH RegexTreeView::RegExpTerm::getLiteral#dispred#f0820431#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1 'result', Rhs.1 'result' 42526 ~0% {5} r6 = JOIN r5 WITH RegexTreeView::RegExpGroup#31aac2a7#ffff ON FIRST 1 OUTPUT Lhs.1 'this', Lhs.0 'result', Rhs.1, Rhs.2, Rhs.3 22 ~0% {8} r7 = JOIN r6 WITH RegexTreeView::RegExpBackRef#class#31aac2a7#ffff ON FIRST 1 OUTPUT Lhs.2, Lhs.3, Lhs.4, Lhs.1 'result', Lhs.0 'this', Rhs.1, Rhs.2, Rhs.3 0 ~0% {6} r8 = JOIN r7 WITH regex::RegexString::getGroupName#dispred#f0820431#ffff ON FIRST 3 OUTPUT Lhs.5, Lhs.6, Lhs.7, Rhs.3, Lhs.3 'result', Lhs.4 'this' 0 ~0% {2} r9 = JOIN r8 WITH regex::RegexString::named_backreference#dispred#f0820431#ffff ON FIRST 4 OUTPUT Lhs.5 'this', Lhs.4 'result' 4 ~0% {2} r10 = r4 UNION r9 return r10 ``` In this case I opted for a classical solution: tying together the literal and number (or name) part of the backreference in order to encourage a two-column join. After: ``` Tuple counts for RegexTreeView::RegExpBackRef::getGroup#dispred#f0820431#ff/2@b0cc4d5n after 0ms: 898 ~1% {3} r1 = JOIN RegexTreeView::RegExpTerm::getLiteral#dispred#f0820431#ff WITH RegexTreeView::RegExpGroup::getNumber#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.0 'result' 4 ~0% {2} r2 = JOIN r1 WITH RegexTreeView::RegExpBackRef::hasLiteralAndNumber#f0820431#fff_120#join_rhs ON FIRST 2 OUTPUT Rhs.2 'this', Lhs.2 'result' 1110 ~0% {5} r3 = JOIN RegexTreeView::RegExpGroup#31aac2a7#ffff WITH RegexTreeView::RegExpTerm::getLiteral#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.3, Lhs.0 'result', Rhs.1 146 ~0% {3} r4 = JOIN r3 WITH regex::RegexString::getGroupName#dispred#f0820431#ffff ON FIRST 3 OUTPUT Lhs.4, Rhs.3, Lhs.3 'result' 0 ~0% {2} r5 = JOIN r4 WITH RegexTreeView::RegExpBackRef::hasLiteralAndName#f0820431#fff_120#join_rhs ON FIRST 2 OUTPUT Rhs.2 'this', Lhs.2 'result' 4 ~0% {2} r6 = r2 UNION r5 return r6 ``` --- python/ql/lib/semmle/python/RegexTreeView.qll | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/python/ql/lib/semmle/python/RegexTreeView.qll b/python/ql/lib/semmle/python/RegexTreeView.qll index 8e2ae1e90f3..80a5e6a4be4 100644 --- a/python/ql/lib/semmle/python/RegexTreeView.qll +++ b/python/ql/lib/semmle/python/RegexTreeView.qll @@ -1000,11 +1000,22 @@ class RegExpBackRef extends RegExpTerm, TRegExpBackRef { /** Gets the capture group this back reference refers to. */ RegExpGroup getGroup() { - result.getLiteral() = this.getLiteral() and - ( - result.getNumber() = this.getNumber() or - result.getName() = this.getName() - ) + this.hasLiteralAndNumber(result.getLiteral(), result.getNumber()) or + this.hasLiteralAndName(result.getLiteral(), result.getName()) + } + + /** Join-order helper for `getGroup`. */ + pragma[nomagic] + private predicate hasLiteralAndNumber(RegExpLiteral literal, int number) { + literal = this.getLiteral() and + number = this.getNumber() + } + + /** Join-order helper for `getGroup`. */ + pragma[nomagic] + private predicate hasLiteralAndName(RegExpLiteral literal, string name) { + literal = this.getLiteral() and + name = this.getName() } override RegExpTerm getChild(int i) { none() } From ac0c8d238f3c44f4121dffe16837ee3c494f3fc5 Mon Sep 17 00:00:00 2001 From: yoff Date: Tue, 28 Jun 2022 20:14:52 +0000 Subject: [PATCH 173/465] python: only clear taint on false-edge --- .../semmle/python/security/dataflow/TarSlipCustomizations.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll index 38fb99c49c3..8e742c61288 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll @@ -131,7 +131,7 @@ module TarSlip { or call.getAChild*().(NameNode).getId().matches("%path") ) and - branch in [true, false] + branch = false } /** From c2e57c3c9bbead36d0ef41fd61566285c90c239d Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Tue, 28 Jun 2022 22:33:28 +0100 Subject: [PATCH 174/465] Swift: Fix 'kind' in 'swift/string-length-conflation'. --- swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 461b1741e24..78a19e0949d 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -1,7 +1,7 @@ /** * @name String length conflation * @description Using a length value from an `NSString` in a `String`, or a count from a `String` in an `NSString`, may cause unexpected behavior. - * @kind problem + * @kind path-problem * @problem.severity error * @security-severity 7.8 * @precision high From 488befb57760b7b6caf493c9021d45facd950c2a Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Wed, 29 Jun 2022 07:16:59 +0200 Subject: [PATCH 175/465] Swift: store TRAP files in a temporary folder until the extraction is complete Currently, we have a number of assertions in the codebase and certain assumptions about the AST. These don't always hold, sometimes leading to a crash in the extractor. The crashes leave incomplete TRAP files that cannot be imported into the database. With this change, we still get those incomplete TRAP files, but we also get a database in the end (even thoough it is also incomplete as we cannot import everything). --- swift/extractor/SwiftExtractor.cpp | 17 ++++++++++++----- swift/extractor/SwiftExtractorConfiguration.h | 9 ++++++++- swift/extractor/main.cpp | 4 ++++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 6c210bdeefe..2708b0241a4 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -62,13 +62,13 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, // TODO: find a more robust approach to avoid collisions? llvm::StringRef filename = primaryFile ? primaryFile->getFilename() : module.getModuleFilename(); std::string tempTrapName = filename.str() + '.' + std::to_string(getpid()) + ".trap"; - llvm::SmallString tempTrapPath(config.trapDir); + llvm::SmallString tempTrapPath(config.tempTrapDir); llvm::sys::path::append(tempTrapPath, tempTrapName); - llvm::StringRef trapParent = llvm::sys::path::parent_path(tempTrapPath); - if (std::error_code ec = llvm::sys::fs::create_directories(trapParent)) { - std::cerr << "Cannot create trap directory '" << trapParent.str() << "': " << ec.message() - << "\n"; + llvm::StringRef tempTrapParent = llvm::sys::path::parent_path(tempTrapPath); + if (std::error_code ec = llvm::sys::fs::create_directories(tempTrapParent)) { + std::cerr << "Cannot create temp trap directory '" << tempTrapParent.str() + << "': " << ec.message() << "\n"; return; } @@ -117,6 +117,13 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, llvm::SmallString trapPath(config.trapDir); llvm::sys::path::append(trapPath, trapName); + llvm::StringRef trapParent = llvm::sys::path::parent_path(trapPath); + if (std::error_code ec = llvm::sys::fs::create_directories(trapParent)) { + std::cerr << "Cannot create trap directory '" << trapParent.str() << "': " << ec.message() + << "\n"; + return; + } + // TODO: The last process wins. Should we do better than that? if (std::error_code ec = llvm::sys::fs::rename(tempTrapPath, trapPath)) { std::cerr << "Cannot rename temp trap file '" << tempTrapPath.str().str() << "' -> '" diff --git a/swift/extractor/SwiftExtractorConfiguration.h b/swift/extractor/SwiftExtractorConfiguration.h index bf75fdb3b41..b953e589e46 100644 --- a/swift/extractor/SwiftExtractorConfiguration.h +++ b/swift/extractor/SwiftExtractorConfiguration.h @@ -9,7 +9,14 @@ struct SwiftExtractorConfiguration { std::string trapDir; // The location for storing extracted source files. std::string sourceArchiveDir; - // The arguments passed to the extractor. Used for debugging. + // A temporary directory that exists during database creation, but is deleted once the DB is + // finalized. + std::string scratchDir; + // A temporary directory that contains TRAP files before they moved into the final destination. + // Subdirectory of the scratchDir. + std::string tempTrapDir; + + // The original arguments passed to the extractor. Used for debugging. std::vector frontendOptions; }; } // namespace codeql diff --git a/swift/extractor/main.cpp b/swift/extractor/main.cpp index 547225d6cd9..a493a501411 100644 --- a/swift/extractor/main.cpp +++ b/swift/extractor/main.cpp @@ -51,6 +51,10 @@ int main(int argc, char** argv) { codeql::SwiftExtractorConfiguration configuration{}; configuration.trapDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_TRAP_DIR", "."); configuration.sourceArchiveDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_SOURCE_ARCHIVE_DIR", "."); + configuration.scratchDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_SCRATCH_DIR", "."); + + configuration.tempTrapDir = configuration.scratchDir + "/swift-trap-temp"; + std::vector args; for (int i = 1; i < argc; i++) { args.push_back(argv[i]); From 57811a4efcbc3cb75f13af46586c931b68c6849f Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Tue, 21 Jun 2022 16:58:13 +0200 Subject: [PATCH 176/465] Swift: add a test case showing module loading problem Extractor fails to load separate modules that were built by another version of an actual compiler. --- .../partial-modules/A/Package.swift | 18 +++++++++++++++ .../partial-modules/A/Sources/A/A.swift | 5 ++++ .../partial-modules/A/Sources/A/Asup.swift | 1 + .../partial-modules/B/Package.swift | 18 +++++++++++++++ .../partial-modules/B/Sources/B/B.swift | 5 ++++ .../partial-modules/B/Sources/B/Bsup.swift | 1 + .../partial-modules/Package.swift | 23 +++++++++++++++++++ .../partial-modules/partial_modules.swift | 11 +++++++++ .../partial-modules/Unknown.expected | 0 .../partial-modules/Unknown.ql | 4 ++++ .../integration-tests/partial-modules/test.py | 7 ++++++ 11 files changed, 93 insertions(+) create mode 100644 swift/integration-tests/partial-modules/A/Package.swift create mode 100644 swift/integration-tests/partial-modules/A/Sources/A/A.swift create mode 100644 swift/integration-tests/partial-modules/A/Sources/A/Asup.swift create mode 100644 swift/integration-tests/partial-modules/B/Package.swift create mode 100644 swift/integration-tests/partial-modules/B/Sources/B/B.swift create mode 100644 swift/integration-tests/partial-modules/B/Sources/B/Bsup.swift create mode 100644 swift/integration-tests/partial-modules/Package.swift create mode 100644 swift/integration-tests/partial-modules/Sources/partial-modules/partial_modules.swift create mode 100644 swift/integration-tests/partial-modules/Unknown.expected create mode 100644 swift/integration-tests/partial-modules/Unknown.ql create mode 100644 swift/integration-tests/partial-modules/test.py diff --git a/swift/integration-tests/partial-modules/A/Package.swift b/swift/integration-tests/partial-modules/A/Package.swift new file mode 100644 index 00000000000..41bf0b6d70d --- /dev/null +++ b/swift/integration-tests/partial-modules/A/Package.swift @@ -0,0 +1,18 @@ +// swift-tools-version: 5.5 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "A", + products: [ + .library( + name: "A", + targets: ["A"]), + ], + targets: [ + .target( + name: "A", + dependencies: []), + ] +) diff --git a/swift/integration-tests/partial-modules/A/Sources/A/A.swift b/swift/integration-tests/partial-modules/A/Sources/A/A.swift new file mode 100644 index 00000000000..b8554b24b6c --- /dev/null +++ b/swift/integration-tests/partial-modules/A/Sources/A/A.swift @@ -0,0 +1,5 @@ +public struct A { + public private(set) var text = Atext + + public init() {} +} diff --git a/swift/integration-tests/partial-modules/A/Sources/A/Asup.swift b/swift/integration-tests/partial-modules/A/Sources/A/Asup.swift new file mode 100644 index 00000000000..a2af1709c3c --- /dev/null +++ b/swift/integration-tests/partial-modules/A/Sources/A/Asup.swift @@ -0,0 +1 @@ +let Atext = "Hello, A" diff --git a/swift/integration-tests/partial-modules/B/Package.swift b/swift/integration-tests/partial-modules/B/Package.swift new file mode 100644 index 00000000000..dffa5b10771 --- /dev/null +++ b/swift/integration-tests/partial-modules/B/Package.swift @@ -0,0 +1,18 @@ +// swift-tools-version: 5.5 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "B", + products: [ + .library( + name: "B", + targets: ["B"]), + ], + targets: [ + .target( + name: "B", + dependencies: []), + ] +) diff --git a/swift/integration-tests/partial-modules/B/Sources/B/B.swift b/swift/integration-tests/partial-modules/B/Sources/B/B.swift new file mode 100644 index 00000000000..1954601508c --- /dev/null +++ b/swift/integration-tests/partial-modules/B/Sources/B/B.swift @@ -0,0 +1,5 @@ +public struct B { + public private(set) var text = Btext + + public init() {} +} diff --git a/swift/integration-tests/partial-modules/B/Sources/B/Bsup.swift b/swift/integration-tests/partial-modules/B/Sources/B/Bsup.swift new file mode 100644 index 00000000000..80634b1065d --- /dev/null +++ b/swift/integration-tests/partial-modules/B/Sources/B/Bsup.swift @@ -0,0 +1 @@ +let Btext = "Hello, B" diff --git a/swift/integration-tests/partial-modules/Package.swift b/swift/integration-tests/partial-modules/Package.swift new file mode 100644 index 00000000000..362476ab0c4 --- /dev/null +++ b/swift/integration-tests/partial-modules/Package.swift @@ -0,0 +1,23 @@ +// swift-tools-version: 5.5 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "partial-modules", + products: [ + .library( + name: "partial-modules", + targets: ["partial-modules"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + .package(path: "./A"), + .package(path: "./B"), + ], + targets: [ + .target( + name: "partial-modules", + dependencies: ["A", "B"]), + ] +) diff --git a/swift/integration-tests/partial-modules/Sources/partial-modules/partial_modules.swift b/swift/integration-tests/partial-modules/Sources/partial-modules/partial_modules.swift new file mode 100644 index 00000000000..ee70ae483c8 --- /dev/null +++ b/swift/integration-tests/partial-modules/Sources/partial-modules/partial_modules.swift @@ -0,0 +1,11 @@ +import A +import B + +public struct partial_modules { + public init() { + let a = A() + let b = B() + print(a.text) + print(b.text) + } +} diff --git a/swift/integration-tests/partial-modules/Unknown.expected b/swift/integration-tests/partial-modules/Unknown.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/integration-tests/partial-modules/Unknown.ql b/swift/integration-tests/partial-modules/Unknown.ql new file mode 100644 index 00000000000..222ef6339a7 --- /dev/null +++ b/swift/integration-tests/partial-modules/Unknown.ql @@ -0,0 +1,4 @@ +import swift + +from UnresolvedDotExpr e +select e diff --git a/swift/integration-tests/partial-modules/test.py b/swift/integration-tests/partial-modules/test.py new file mode 100644 index 00000000000..ae89d5da5d7 --- /dev/null +++ b/swift/integration-tests/partial-modules/test.py @@ -0,0 +1,7 @@ +from create_database_utils import * + +run_codeql_database_create([ + 'env', + 'swift package clean', + 'swift build' +], lang='swift', keep_trap=True) From e1ef637c5479eb93f25273bd687feb05e9573ab7 Mon Sep 17 00:00:00 2001 From: AlexDenisov Date: Wed, 29 Jun 2022 10:16:14 +0200 Subject: [PATCH 177/465] Update swift/extractor/SwiftExtractorConfiguration.h Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- swift/extractor/SwiftExtractorConfiguration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/extractor/SwiftExtractorConfiguration.h b/swift/extractor/SwiftExtractorConfiguration.h index b953e589e46..a8bba93e498 100644 --- a/swift/extractor/SwiftExtractorConfiguration.h +++ b/swift/extractor/SwiftExtractorConfiguration.h @@ -12,7 +12,7 @@ struct SwiftExtractorConfiguration { // A temporary directory that exists during database creation, but is deleted once the DB is // finalized. std::string scratchDir; - // A temporary directory that contains TRAP files before they moved into the final destination. + // A temporary directory that contains TRAP files before they are moved into their final destination. // Subdirectory of the scratchDir. std::string tempTrapDir; From 4d81206a877f52481be8dccd2585699956ad7a22 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Thu, 23 Jun 2022 09:17:02 +0200 Subject: [PATCH 178/465] Swift: teach extractor to emit build artifacts for later consumption --- swift/extractor/BUILD.bazel | 2 + swift/extractor/SwiftExtractor.cpp | 12 +- swift/extractor/SwiftExtractorConfiguration.h | 15 + swift/extractor/SwiftOutputRewrite.cpp | 318 ++++++++++++++++++ swift/extractor/SwiftOutputRewrite.h | 30 ++ swift/extractor/main.cpp | 37 +- swift/tools/tracing-config.lua | 3 - 7 files changed, 402 insertions(+), 15 deletions(-) create mode 100644 swift/extractor/SwiftOutputRewrite.cpp create mode 100644 swift/extractor/SwiftOutputRewrite.h diff --git a/swift/extractor/BUILD.bazel b/swift/extractor/BUILD.bazel index b81778e8fe2..b22841ca819 100644 --- a/swift/extractor/BUILD.bazel +++ b/swift/extractor/BUILD.bazel @@ -3,6 +3,8 @@ load("//swift:rules.bzl", "swift_cc_binary") swift_cc_binary( name = "extractor", srcs = [ + "SwiftOutputRewrite.cpp", + "SwiftOutputRewrite.h", "SwiftExtractor.cpp", "SwiftExtractor.h", "SwiftExtractorConfiguration.h", diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 2708b0241a4..9e65c77838a 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -80,11 +80,17 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, << "': " << ec.message() << "\n"; return; } - trapStream << "// extractor-args: "; + trapStream << "/* extractor-args:\n"; for (auto opt : config.frontendOptions) { - trapStream << std::quoted(opt) << " "; + trapStream << " " << std::quoted(opt) << " \\\n"; } - trapStream << "\n\n"; + trapStream << "\n*/\n"; + + trapStream << "/* swift-frontend-args:\n"; + for (auto opt : config.patchedFrontendOptions) { + trapStream << " " << std::quoted(opt) << " \\\n"; + } + trapStream << "\n*/\n"; TrapOutput trap{trapStream}; TrapArena arena{}; diff --git a/swift/extractor/SwiftExtractorConfiguration.h b/swift/extractor/SwiftExtractorConfiguration.h index a8bba93e498..230ee661ac2 100644 --- a/swift/extractor/SwiftExtractorConfiguration.h +++ b/swift/extractor/SwiftExtractorConfiguration.h @@ -16,7 +16,22 @@ struct SwiftExtractorConfiguration { // Subdirectory of the scratchDir. std::string tempTrapDir; + // VFS (virtual file system) support. + // A temporary directory that contains VFS files used during extraction. + // Subdirectory of the scratchDir. + std::string VFSDir; + // A temporary directory that contains temp VFS files before they moved into VFSDir. + // Subdirectory of the scratchDir. + std::string tempVFSDir; + + // A temporary directory that contains build artifacts generated by the extractor during the + // overall extraction process. + // Subdirectory of the scratchDir. + std::string tempArtifactDir; + // The original arguments passed to the extractor. Used for debugging. std::vector frontendOptions; + // The patched arguments passed to the swift::performFrontend/ Used for debugging. + std::vector patchedFrontendOptions; }; } // namespace codeql diff --git a/swift/extractor/SwiftOutputRewrite.cpp b/swift/extractor/SwiftOutputRewrite.cpp new file mode 100644 index 00000000000..b48fd4cfc3e --- /dev/null +++ b/swift/extractor/SwiftOutputRewrite.cpp @@ -0,0 +1,318 @@ +#include "SwiftOutputRewrite.h" +#include "swift/extractor/SwiftExtractorConfiguration.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Creates a copy of the output file map and updated remapping table in place +// It does not change the original map file as it is dependent upon by the original compiler +// Returns path to the newly created output file map on success, or None in a case of failure +static std::optional rewriteOutputFileMap( + const codeql::SwiftExtractorConfiguration& config, + const std::string& outputFileMapPath, + const std::vector& inputs, + std::unordered_map& remapping) { + auto newPath = config.tempArtifactDir + '/' + outputFileMapPath; + + // TODO: do not assume absolute path for the second parameter + auto outputMapOrError = swift::OutputFileMap::loadFromPath(outputFileMapPath, ""); + if (!outputMapOrError) { + return std::nullopt; + } + auto oldOutputMap = outputMapOrError.get(); + swift::OutputFileMap newOutputMap; + std::vector keys; + for (auto& key : inputs) { + auto oldMap = oldOutputMap.getOutputMapForInput(key); + if (!oldMap) { + continue; + } + keys.push_back(key); + auto& newMap = newOutputMap.getOrCreateOutputMapForInput(key); + newMap.copyFrom(*oldMap); + for (auto& entry : newMap) { + auto oldPath = entry.getSecond(); + auto newPath = config.tempArtifactDir + '/' + oldPath; + entry.getSecond() = newPath; + remapping[oldPath] = newPath; + } + } + std::error_code ec; + llvm::SmallString filepath(newPath); + llvm::StringRef parent = llvm::sys::path::parent_path(filepath); + if (std::error_code ec = llvm::sys::fs::create_directories(parent)) { + std::cerr << "Cannot create relocated output map dir: '" << parent.str() + << "': " << ec.message() << "\n"; + return std::nullopt; + } + + llvm::raw_fd_ostream fd(newPath, ec, llvm::sys::fs::OF_None); + newOutputMap.write(fd, keys); + return newPath; +} + +// This is Xcode-specific workaround to produce alias names for an existing .swiftmodule file. +// In the case of Xcode, it calls the Swift compiler and asks it to produce a Swift module. +// Once it's done, Xcode moves the .swiftmodule file in another location, and the location is +// rather arbitrary. Here are examples of such locations: +// Original file produced by the frontend: +// DerivedData//Build/Intermediates.noindex/.build/-/.build/Objects-normal//.swiftmodule +// where: +// Project: name of a project, target, or scheme +// BuildType: Debug, Release, etc. +// Target: macOS, iphoneos, appletvsimulator, etc. +// Arch: arm64, x86_64, etc. +// +// So far we observed that Xcode can move the module into different locations, and it's not +// entirely clear how to deduce the destination from the context available for the extractor. +// 1. First case: +// DerivedData//Build/Products/-/.swiftmodule/.swiftmodule +// DerivedData//Build/Products/-/.swiftmodule/.swiftmodule +// 2. Second case: +// DerivedData//Build/Products/-//.swiftmodule/.swiftmodule +// DerivedData//Build/Products/-//.swiftmodule/.swiftmodule +// 2. Third case: +// DerivedData//Build/Products/-//.framework/Modules/.swiftmodule/.swiftmodule +// DerivedData//Build/Products/-//.framework/Modules/.swiftmodule/.swiftmodule +// The here is a normalized target triple (e.g. arm64-apple-iphoneos15.4 -> +// arm64-apple-iphoneos). +// +// This method construct those aliases for a module only if it comes from Xcode, which is detected +// by the presence of `Intermediates.noindex` directory in the module path. +// +// In the case of Swift Package Manager (`swift build`) this is not needed. +static std::vector computeModuleAliases(llvm::StringRef modulePath, + const std::string& targetTriple) { + if (modulePath.empty()) { + return {}; + } + if (!modulePath.endswith(".swiftmodule")) { + return {}; + } + + llvm::SmallVector chunks; + modulePath.split(chunks, '/'); + size_t intermediatesDirIndex = 0; + for (size_t i = 0; i < chunks.size(); i++) { + if (chunks[i] == "Intermediates.noindex") { + intermediatesDirIndex = i; + break; + } + } + // Not built by Xcode, skipping + if (intermediatesDirIndex == 0) { + return {}; + } + // e.g. Debug-iphoneos, Release-iphonesimulator, etc. + auto destinationDir = chunks[intermediatesDirIndex + 2].str(); + auto arch = chunks[intermediatesDirIndex + 5].str(); + auto moduleNameWithExt = chunks.back(); + auto moduleName = moduleNameWithExt.substr(0, moduleNameWithExt.find_last_of('.')); + std::string relocatedModulePath = chunks[0].str(); + for (size_t i = 1; i < intermediatesDirIndex; i++) { + relocatedModulePath += '/' + chunks[i].str(); + } + relocatedModulePath += "/Products/"; + relocatedModulePath += destinationDir + '/'; + + std::vector moduleLocations; + + std::string firstCase = relocatedModulePath; + firstCase += moduleNameWithExt.str() + '/'; + moduleLocations.push_back(firstCase); + + std::string secondCase = relocatedModulePath; + secondCase += moduleName.str() + '/'; + secondCase += moduleNameWithExt.str() + '/'; + moduleLocations.push_back(secondCase); + + std::string thirdCase = relocatedModulePath; + thirdCase += moduleName.str() + '/'; + thirdCase += moduleName.str() + ".framework/Modules/"; + thirdCase += moduleNameWithExt.str() + '/'; + moduleLocations.push_back(thirdCase); + + std::vector aliases; + for (auto& location : moduleLocations) { + aliases.push_back(location + arch + ".swiftmodule"); + if (!targetTriple.empty()) { + llvm::Triple triple(targetTriple); + auto moduleTriple = swift::getTargetSpecificModuleTriple(triple); + aliases.push_back(location + moduleTriple.normalize() + ".swiftmodule"); + } + } + + return aliases; +} + +namespace codeql { + +std::unordered_map rewriteOutputsInPlace( + SwiftExtractorConfiguration& config, + std::vector& CLIArgs) { + std::unordered_map remapping; + + // TODO: handle filelists? + std::unordered_set pathRewriteOptions({ + "-emit-dependencies-path", + "-emit-module-path", + "-emit-module-doc-path", + "-emit-module-source-info-path", + "-emit-objc-header-path", + "-emit-reference-dependencies-path", + "-index-store-path", + "-module-cache-path", + "-o", + "-pch-output-dir", + "-serialize-diagnostics-path", + }); + + std::unordered_set outputFileMaps( + {"-supplementary-output-file-map", "-output-file-map"}); + + std::vector outputFileMapIndexes; + std::vector maybeInput; + std::string targetTriple; + + std::vector newLocations; + for (size_t i = 0; i < CLIArgs.size(); i++) { + if (pathRewriteOptions.count(CLIArgs[i])) { + auto oldPath = CLIArgs[i + 1]; + auto newPath = config.tempArtifactDir + '/' + oldPath; + CLIArgs[++i] = newPath; + newLocations.push_back(newPath); + + remapping[oldPath] = newPath; + } else if (outputFileMaps.count(CLIArgs[i])) { + // collect output map indexes for further rewriting and skip the following argument + // We don't patch the map in place as we need to collect all the input files first + outputFileMapIndexes.push_back(++i); + } else if (CLIArgs[i] == "-target") { + targetTriple = CLIArgs[++i]; + } else if (CLIArgs[i][0] != '-') { + // TODO: add support for input file lists? + // We need to collect input file names to later use them to extract information from the + // output file maps. + maybeInput.push_back(CLIArgs[i]); + } + } + + for (auto index : outputFileMapIndexes) { + auto oldPath = CLIArgs[index]; + auto maybeNewPath = rewriteOutputFileMap(config, oldPath, maybeInput, remapping); + if (maybeNewPath) { + auto newPath = maybeNewPath.value(); + CLIArgs[index] = newPath; + remapping[oldPath] = newPath; + } + } + + // This doesn't really belong here, but we've got Xcode... + for (auto& [oldPath, newPath] : remapping) { + llvm::StringRef path(oldPath); + auto aliases = computeModuleAliases(path, targetTriple); + for (auto& alias : aliases) { + remapping[alias] = newPath; + } + } + + return remapping; +} + +void ensureNewPathsExist(const std::unordered_map& remapping) { + for (auto& [_, newPath] : remapping) { + llvm::SmallString filepath(newPath); + llvm::StringRef parent = llvm::sys::path::parent_path(filepath); + if (std::error_code ec = llvm::sys::fs::create_directories(parent)) { + std::cerr << "Cannot create redirected directory: " << ec.message() << "\n"; + } + } +} + +void storeRemappingForVFS(const SwiftExtractorConfiguration& config, + const std::unordered_map& remapping) { + // Only create remapping for the .swiftmodule files + std::unordered_map modules; + for (auto& [oldPath, newPath] : remapping) { + if (llvm::StringRef(oldPath).endswith(".swiftmodule")) { + modules[oldPath] = newPath; + } + } + + if (modules.empty()) { + return; + } + + if (std::error_code ec = llvm::sys::fs::create_directories(config.tempVFSDir)) { + std::cerr << "Cannot create temp VFS directory: " << ec.message() << "\n"; + return; + } + + if (std::error_code ec = llvm::sys::fs::create_directories(config.VFSDir)) { + std::cerr << "Cannot create VFS directory: " << ec.message() << "\n"; + return; + } + + // Constructing the VFS yaml file in a temp folder so that the other process doesn't read it + // while it is not complete + // TODO: Pick a more robust way to not collide with files from other processes + auto tempVfsPath = config.tempVFSDir + '/' + std::to_string(getpid()) + "-vfs.yaml"; + std::error_code ec; + llvm::raw_fd_ostream fd(tempVfsPath, ec, llvm::sys::fs::OF_None); + if (ec) { + std::cerr << "Cannot create temp VFS file: '" << tempVfsPath << "': " << ec.message() << "\n"; + return; + } + // TODO: there must be a better API than this + // LLVM expects the version to be 0 + fd << "{ version: 0,\n"; + // This tells the FS not to fallback to the physical file system in case the remapped file is not + // present + fd << " fallthrough: false,\n"; + fd << " roots: [\n"; + for (auto& [oldPath, newPath] : modules) { + fd << " {\n"; + fd << " type: 'file',\n"; + fd << " name: '" << oldPath << "\',\n"; + fd << " external-contents: '" << newPath << "\'\n"; + fd << " },\n"; + } + fd << " ]\n"; + fd << "}\n"; + + fd.flush(); + auto vfsPath = config.VFSDir + '/' + std::to_string(getpid()) + "-vfs.yaml"; + if (std::error_code ec = llvm::sys::fs::rename(tempVfsPath, vfsPath)) { + std::cerr << "Cannot move temp VFS file '" << tempVfsPath << "' -> '" << vfsPath + << "': " << ec.message() << "\n"; + return; + } +} + +std::vector collectVFSFiles(const SwiftExtractorConfiguration& config) { + auto vfsDir = config.VFSDir + '/'; + if (!llvm::sys::fs::exists(vfsDir)) { + return {}; + } + std::vector overlays; + std::error_code ec; + llvm::sys::fs::directory_iterator it(vfsDir, ec); + while (!ec && it != llvm::sys::fs::directory_iterator()) { + llvm::StringRef path(it->path()); + if (path.endswith("vfs.yaml")) { + overlays.push_back(path.str()); + } + it.increment(ec); + } + + return overlays; +} + +} // namespace codeql diff --git a/swift/extractor/SwiftOutputRewrite.h b/swift/extractor/SwiftOutputRewrite.h new file mode 100644 index 00000000000..3f96608b501 --- /dev/null +++ b/swift/extractor/SwiftOutputRewrite.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include + +namespace codeql { + +struct SwiftExtractorConfiguration; + +// Rewrites all the output CLI args to point to a scratch dir instead of the actual locations. +// This is needed to ensure that the artifacts produced by the extractor do not collide with the +// artifacts produced by the actual Swift compiler. +// Returns the map containing remapping oldpath -> newPath. +std::unordered_map rewriteOutputsInPlace( + SwiftExtractorConfiguration& config, + std::vector& CLIArgs); + +// Recreate all the redirected new paths as the Swift compiler expects them to be present +void ensureNewPathsExist(const std::unordered_map& remapping); + +// Stores remapped `.swiftmoduile`s in a YAML file for later consumption by the +// llvm::RedirectingFileSystem via Swift's VFSOverlayFiles. +void storeRemappingForVFS(const SwiftExtractorConfiguration& config, + const std::unordered_map& remapping); + +// Returns a list of VFS YAML files produced by all the extractor processes. +std::vector collectVFSFiles(const SwiftExtractorConfiguration& config); + +} // namespace codeql diff --git a/swift/extractor/main.cpp b/swift/extractor/main.cpp index a493a501411..2a3d23e87e5 100644 --- a/swift/extractor/main.cpp +++ b/swift/extractor/main.cpp @@ -1,27 +1,32 @@ #include #include #include +#include +#include +#include +#include #include #include #include "SwiftExtractor.h" +#include "SwiftOutputRewrite.h" using namespace std::string_literals; // This is part of the swiftFrontendTool interface, we hook into the // compilation pipeline and extract files after the Swift frontend performed -// semantic analysys +// semantic analysis class Observer : public swift::FrontendObserver { public: explicit Observer(const codeql::SwiftExtractorConfiguration& config) : config{config} {} void parsedArgs(swift::CompilerInvocation& invocation) override { - // Original compiler and the extractor-compiler get into conflicts when - // both produce the same output files. - // TODO: change the final artifact destinations instead of disabling - // the artifact generation completely? - invocation.getFrontendOptions().RequestedAction = swift::FrontendOptions::ActionType::Typecheck; + auto& overlays = invocation.getSearchPathOptions().VFSOverlayFiles; + auto vfsFiles = codeql::collectVFSFiles(config); + for (auto& vfsFile : vfsFiles) { + overlays.push_back(vfsFile); + } } void performedSemanticAnalysis(swift::CompilerInstance& compiler) override { @@ -54,12 +59,26 @@ int main(int argc, char** argv) { configuration.scratchDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_SCRATCH_DIR", "."); configuration.tempTrapDir = configuration.scratchDir + "/swift-trap-temp"; + configuration.VFSDir = configuration.scratchDir + "/swift-vfs"; + configuration.tempVFSDir = configuration.scratchDir + "/swift-vfs-temp"; + configuration.tempArtifactDir = configuration.scratchDir + "/swift-extraction-artifacts"; + + configuration.frontendOptions.reserve(argc - 1); + for (int i = 1; i < argc; i++) { + configuration.frontendOptions.push_back(argv[i]); + } + configuration.patchedFrontendOptions = configuration.frontendOptions; + + auto remapping = + codeql::rewriteOutputsInPlace(configuration, configuration.patchedFrontendOptions); + codeql::ensureNewPathsExist(remapping); + codeql::storeRemappingForVFS(configuration, remapping); std::vector args; - for (int i = 1; i < argc; i++) { - args.push_back(argv[i]); + for (auto& arg : configuration.patchedFrontendOptions) { + args.push_back(arg.c_str()); } - std::copy(std::begin(args), std::end(args), std::back_inserter(configuration.frontendOptions)); + Observer observer(configuration); int frontend_rc = swift::performFrontend(args, "swift-extractor", (void*)main, &observer); return frontend_rc; diff --git a/swift/tools/tracing-config.lua b/swift/tools/tracing-config.lua index 558d6a95d3f..d9343285099 100644 --- a/swift/tools/tracing-config.lua +++ b/swift/tools/tracing-config.lua @@ -67,9 +67,6 @@ function RegisterExtractorPack(id) return nil end - -- Skip actions in which we cannot extract anything - if compilerArguments.argv[1] == '-merge-modules' then return nil end - strip_unsupported_args(compilerArguments.argv) insert_resource_dir_if_needed(compilerPath, compilerArguments.argv) From cc25e2644f2c85137d7f337f83e236eb5aae9188 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 29 Jun 2022 11:40:46 +0100 Subject: [PATCH 179/465] Swift: Don't join on index in 'swift/string-length-conflation'. --- .../queries/Security/CWE-135/StringLengthConflation.ql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 78a19e0949d..2bccba41b25 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -63,8 +63,8 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { c.getAMember() = f and // TODO: will this even work if its defined in a parent class? call.getFunction().(ApplyExpr).getStaticTarget() = f and f.getName() = methodName and - f.getParam(arg).getName() = paramName and - call.getArgument(arg).getExpr() = node.asExpr() and + f.getParam(pragma[only_bind_into](arg)).getName() = paramName and + call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and flowstate = "String" // `String` length flowing into `NSString` ) or @@ -74,8 +74,8 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { funcName = "NSMakeRange(_:_:)" and paramName = ["loc", "len"] and call.getStaticTarget().getName() = funcName and - call.getStaticTarget().getParam(arg).getName() = paramName and - call.getArgument(arg).getExpr() = node.asExpr() and + call.getStaticTarget().getParam(pragma[only_bind_into](arg)).getName() = paramName and + call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and flowstate = "String" // `String` length flowing into `NSString` ) } From 822002d37d7546c6246d1e0700eec4626fdce780 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 28 Jun 2022 15:42:19 +0100 Subject: [PATCH 180/465] Swift: Missing qldoc. --- .../ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll | 3 +++ 1 file changed, 3 insertions(+) diff --git a/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll b/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll index 04d2185aab6..cca41098f9c 100644 --- a/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll +++ b/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll @@ -15,6 +15,9 @@ class ArithmeticOperation extends Expr { this instanceof UnaryArithmeticOperation } + /** + * Gets an operand of this arithmetic operation. + */ Expr getAnOperand() { result = this.(BinaryArithmeticOperation).getAnOperand() or From 2cf65c7d35dae24b6d1e281aa0f3db62819a5019 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 28 Jun 2022 16:39:11 +0100 Subject: [PATCH 181/465] Swift: Autoformat tests. --- .../arithmeticoperation.ql | 23 ++++++++++++------- .../expr/logicaloperation/logicaloperation.ql | 14 +++++++---- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.ql b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.ql index 2aeba5981b8..9d98daa68af 100644 --- a/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.ql +++ b/swift/ql/test/library-tests/elements/expr/arithmeticoperation/arithmeticoperation.ql @@ -1,14 +1,21 @@ import swift string describe(ArithmeticOperation e) { - (e instanceof BinaryArithmeticOperation and result = "BinaryArithmeticOperation") or - (e instanceof AddExpr and result = "AddExpr") or - (e instanceof SubExpr and result = "SubExpr") or - (e instanceof MulExpr and result = "MulExpr") or - (e instanceof DivExpr and result = "DivExpr") or - (e instanceof RemExpr and result = "RemExpr") or - (e instanceof UnaryArithmeticOperation and result = "UnaryArithmeticOperation") or - (e instanceof UnaryMinusExpr and result = "UnaryMinusExpr") + e instanceof BinaryArithmeticOperation and result = "BinaryArithmeticOperation" + or + e instanceof AddExpr and result = "AddExpr" + or + e instanceof SubExpr and result = "SubExpr" + or + e instanceof MulExpr and result = "MulExpr" + or + e instanceof DivExpr and result = "DivExpr" + or + e instanceof RemExpr and result = "RemExpr" + or + e instanceof UnaryArithmeticOperation and result = "UnaryArithmeticOperation" + or + e instanceof UnaryMinusExpr and result = "UnaryMinusExpr" } from ArithmeticOperation e diff --git a/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.ql b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.ql index 8d943f725b2..f9c361ed214 100644 --- a/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.ql +++ b/swift/ql/test/library-tests/elements/expr/logicaloperation/logicaloperation.ql @@ -1,11 +1,15 @@ import swift string describe(LogicalOperation e) { - (e instanceof BinaryLogicalOperation and result = "BinaryLogicalExpr") or - (e instanceof LogicalAndExpr and result = "LogicalAndExpr") or - (e instanceof LogicalOrExpr and result = "LogicalOrExpr") or - (e instanceof UnaryLogicalOperation and result = "UnaryLogicalOperation") or - (e instanceof NotExpr and result = "NotExpr") + e instanceof BinaryLogicalOperation and result = "BinaryLogicalExpr" + or + e instanceof LogicalAndExpr and result = "LogicalAndExpr" + or + e instanceof LogicalOrExpr and result = "LogicalOrExpr" + or + e instanceof UnaryLogicalOperation and result = "UnaryLogicalOperation" + or + e instanceof NotExpr and result = "NotExpr" } from LogicalOperation e From 8b7535af81b18a20e49bae79bb4b0e575f1d31b2 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 28 Jun 2022 16:47:44 +0100 Subject: [PATCH 182/465] Swift: Don't use abstract classes. --- .../elements/expr/ArithmeticOperation.qll | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll b/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll index cca41098f9c..27e7e42e4fa 100644 --- a/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll +++ b/swift/ql/lib/codeql/swift/elements/expr/ArithmeticOperation.qll @@ -31,7 +31,15 @@ class ArithmeticOperation extends Expr { * a + b * ``` */ -abstract class BinaryArithmeticOperation extends BinaryExpr { } +class BinaryArithmeticOperation extends BinaryExpr { + BinaryArithmeticOperation() { + this instanceof AddExpr or + this instanceof SubExpr or + this instanceof MulExpr or + this instanceof DivExpr or + this instanceof RemExpr + } +} /** * An add expression. @@ -39,7 +47,7 @@ abstract class BinaryArithmeticOperation extends BinaryExpr { } * a + b * ``` */ -class AddExpr extends BinaryArithmeticOperation { +class AddExpr extends BinaryExpr { AddExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "+(_:_:)" } } @@ -49,7 +57,7 @@ class AddExpr extends BinaryArithmeticOperation { * a - b * ``` */ -class SubExpr extends BinaryArithmeticOperation { +class SubExpr extends BinaryExpr { SubExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "-(_:_:)" } } @@ -59,7 +67,7 @@ class SubExpr extends BinaryArithmeticOperation { * a * b * ``` */ -class MulExpr extends BinaryArithmeticOperation { +class MulExpr extends BinaryExpr { MulExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "*(_:_:)" } } @@ -69,7 +77,7 @@ class MulExpr extends BinaryArithmeticOperation { * a / b * ``` */ -class DivExpr extends BinaryArithmeticOperation { +class DivExpr extends BinaryExpr { DivExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "/(_:_:)" } } @@ -79,7 +87,7 @@ class DivExpr extends BinaryArithmeticOperation { * a % b * ``` */ -class RemExpr extends BinaryArithmeticOperation { +class RemExpr extends BinaryExpr { RemExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "%(_:_:)" } } @@ -89,7 +97,9 @@ class RemExpr extends BinaryArithmeticOperation { * -a * ``` */ -abstract class UnaryArithmeticOperation extends PrefixUnaryExpr { } +class UnaryArithmeticOperation extends PrefixUnaryExpr { + UnaryArithmeticOperation() { this instanceof UnaryMinusExpr } +} /** * A unary minus expression. @@ -97,6 +107,6 @@ abstract class UnaryArithmeticOperation extends PrefixUnaryExpr { } * -a * ``` */ -class UnaryMinusExpr extends UnaryArithmeticOperation { +class UnaryMinusExpr extends PrefixUnaryExpr { UnaryMinusExpr() { this.getFunction().(DotSyntaxCallExpr).getStaticTarget().getName() = "-(_:)" } } From f35ab7c2924b27137bc12e5f6bf0e98c6bd16533 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Wed, 29 Jun 2022 12:20:07 +0100 Subject: [PATCH 183/465] Swift: Accept test changes to the cfg. These happen due to the fixes in 9e0cf62cdae127b96ef70f49d2e0f56bc1ccc959. --- .../controlflow/graph/Cfg.expected | 136 +++++++++--------- 1 file changed, 72 insertions(+), 64 deletions(-) diff --git a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected index 3164022150d..ff9094e0f98 100644 --- a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -1670,11 +1670,17 @@ cfg.swift: #-----| -> 2 # 185| ... call to <=(_:_:) ... -#-----| -> { ... } +#-----| false -> [false] ... call to &&(_:_:) ... +#-----| true -> { ... } # 185| ... call to &&(_:_:) ... #-----| exception -> exit m1(x:) (normal) -#-----| -> { ... } +#-----| false -> [false] ... call to &&(_:_:) ... +#-----| true -> { ... } + +# 185| [false] ... call to &&(_:_:) ... +#-----| exception -> exit m1(x:) (normal) +#-----| false -> [false] ... call to &&(_:_:) ... # 185| ... call to &&(_:_:) ... #-----| exception -> exit m1(x:) (normal) @@ -1682,7 +1688,11 @@ cfg.swift: #-----| false -> print(_:separator:terminator:) # 185| StmtCondition -#-----| -> &&(_:_:) +#-----| -> <=(_:_:) + +# 185| [false] ... call to &&(_:_:) ... +#-----| exception -> exit m1(x:) (normal) +#-----| false -> print(_:separator:terminator:) # 185| <=(_:_:) #-----| -> Int.Type @@ -1696,29 +1706,59 @@ cfg.swift: # 185| 2 #-----| -> ... call to <=(_:_:) ... -# 185| &&(_:_:) -#-----| -> Bool.Type +# 185| x +#-----| -> 0 -# 185| Bool.Type -#-----| -> call to &&(_:_:) +# 185| ... call to >(_:_:) ... +#-----| -> return ... -# 185| call to &&(_:_:) -#-----| -> <=(_:_:) - -# 185| { ... } +# 185| return ... #-----| -> ... call to &&(_:_:) ... -# 185| &&(_:_:) -#-----| -> Bool.Type +# 185| { ... } +#-----| -> >(_:_:) -# 185| Bool.Type -#-----| -> call to &&(_:_:) +# 185| >(_:_:) +#-----| -> Int.Type -# 185| call to &&(_:_:) -#-----| -> &&(_:_:) +# 185| Int.Type +#-----| -> call to >(_:_:) + +# 185| call to >(_:_:) +#-----| -> x + +# 185| 0 +#-----| -> ... call to >(_:_:) ... + +# 185| call to ... +#-----| -> return ... + +# 185| return ... +#-----| -> ... call to &&(_:_:) ... # 185| { ... } -#-----| -> ... call to &&(_:_:) ... +#-----| -> ==(_:_:) + +# 185| (...) +#-----| -> call to ... + +# 185| x +#-----| -> 5 + +# 185| ... call to ==(_:_:) ... +#-----| -> (...) + +# 185| ==(_:_:) +#-----| -> Int.Type + +# 185| Int.Type +#-----| -> call to ==(_:_:) + +# 185| call to ==(_:_:) +#-----| -> x + +# 185| 5 +#-----| -> ... call to ==(_:_:) ... # 186| print(_:separator:terminator:) #-----| -> x is 1 @@ -2058,48 +2098,14 @@ cfg.swift: # 224| if ... then { ... } #-----| -> StmtCondition -# 224| !(_:) -#-----| -> Bool.Type - -# 224| Bool.Type -#-----| -> call to !(_:) - -# 224| call to !(_:) +# 224| StmtCondition #-----| -> true -# 224| StmtCondition -#-----| -> !(_:) - -# 224| call to ... +# 224| [false] call to ... #-----| false -> exit constant_condition() (normal) -#-----| true -> print(_:separator:terminator:) # 224| true -#-----| -> call to ... - -# 225| print(_:separator:terminator:) -#-----| -> Impossible - -# 225| call to print(_:separator:terminator:) -#-----| -> exit constant_condition() (normal) - -# 225| default separator -#-----| -> default terminator - -# 225| default terminator -#-----| -> call to print(_:separator:terminator:) - -# 225| (Any) ... -#-----| -> [...] - -# 225| Impossible -#-----| -> (Any) ... - -# 225| [...] -#-----| -> default separator - -# 225| [...] -#-----| -> [...] +#-----| true -> [false] call to ... # 229| empty_else(b:) #-----| -> b @@ -2197,7 +2203,7 @@ cfg.swift: #-----| -> StmtCondition # 238| StmtCondition -#-----| -> ||(_:_:) +#-----| -> b1 # 238| [false] (...) #-----| false -> exit disjunct(b1:b2:) (normal) @@ -2206,24 +2212,26 @@ cfg.swift: #-----| true -> print(_:separator:terminator:) # 238| b1 -#-----| -> { ... } +#-----| true -> [true] ... call to ||(_:_:) ... +#-----| false -> { ... } # 238| ... call to ||(_:_:) ... #-----| exception -> exit disjunct(b1:b2:) (normal) #-----| false -> [false] (...) #-----| true -> [true] (...) -# 238| Bool.Type -#-----| -> call to ||(_:_:) +# 238| [true] ... call to ||(_:_:) ... +#-----| exception -> exit disjunct(b1:b2:) (normal) +#-----| true -> [true] (...) -# 238| call to ||(_:_:) -#-----| -> b1 +# 238| b2 +#-----| -> return ... -# 238| ||(_:_:) -#-----| -> Bool.Type +# 238| return ... +#-----| -> ... call to ||(_:_:) ... # 238| { ... } -#-----| -> ... call to ||(_:_:) ... +#-----| -> b2 # 239| print(_:separator:terminator:) #-----| -> b1 or b2 From c1302a90e0201f98ada5aa0cb0edff76767a26ae Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Wed, 29 Jun 2022 13:16:18 +0100 Subject: [PATCH 184/465] Ruby: use MaD for more precise Pathname flow summaries --- .../codeql/ruby/frameworks/core/Pathname.qll | 164 ++++------ .../pathname-flow/pathame-flow.expected | 289 +++++++++++++----- .../dataflow/pathname-flow/pathname_flow.rb | 124 ++++++-- 3 files changed, 375 insertions(+), 202 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll b/ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll index d296d9c75ea..e2cea924838 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll @@ -6,6 +6,7 @@ private import codeql.ruby.Concepts private import codeql.ruby.DataFlow private import codeql.ruby.dataflow.FlowSummary private import codeql.ruby.dataflow.internal.DataFlowDispatch +private import codeql.ruby.frameworks.data.ModelsAsData /** * Modeling of the `Pathname` class from the Ruby standard library. @@ -113,106 +114,75 @@ module Pathname { override DataFlow::Node getAPermissionNode() { result = permissionArg } } - /** Flow summary for `Pathname.new`. */ - private class NewSummary extends SummarizedCallable { - NewSummary() { this = "Pathname.new" } - - override MethodCall getACall() { - result = API::getTopLevelMember("Pathname").getAnInstantiation().getExprNode().getExpr() - } - - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - input = "Argument[0]" and - output = "ReturnValue" and - preservesValue = false + /** + * Type summaries for the `Pathname` class, i.e. method calls that produce new + * `Pathname` instances. + */ + private class PathnameTypeSummary extends ModelInput::TypeModelCsv { + override predicate row(string row) { + // package1;type1;package2;type2;path + row = + [ + // Pathname.new : Pathname + ";Pathname;;;Member[Pathname].Instance", + // Pathname#+(path) : Pathname + ";Pathname;;Pathname;Method[+].ReturnValue", + // Pathname#/(path) : Pathname + ";Pathname;;Pathname;Method[/].ReturnValue", + // Pathname#basename(path) : Pathname + ";Pathname;;Pathname;Method[basename].ReturnValue", + // Pathname#cleanpath(path) : Pathname + ";Pathname;;Pathname;Method[cleanpath].ReturnValue", + // Pathname#expand_path(path) : Pathname + ";Pathname;;Pathname;Method[expand_path].ReturnValue", + // Pathname#join(path) : Pathname + ";Pathname;;Pathname;Method[join].ReturnValue", + // Pathname#realpath(path) : Pathname + ";Pathname;;Pathname;Method[realpath].ReturnValue", + // Pathname#relative_path_from(path) : Pathname + ";Pathname;;Pathname;Method[relative_path_from].ReturnValue", + // Pathname#sub(path) : Pathname + ";Pathname;;Pathname;Method[sub].ReturnValue", + // Pathname#sub_ext(path) : Pathname + ";Pathname;;Pathname;Method[sub_ext].ReturnValue", + // Pathname#to_path(path) : Pathname + ";Pathname;;Pathname;Method[to_path].ReturnValue", + ] } } - /** Flow summary for `Pathname#dirname`. */ - private class DirnameSummary extends SimpleSummarizedCallable { - DirnameSummary() { this = "dirname" } - - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - input = "Argument[self]" and - output = "ReturnValue" and - preservesValue = false - } - } - - /** Flow summary for `Pathname#each_filename`. */ - private class EachFilenameSummary extends SimpleSummarizedCallable { - EachFilenameSummary() { this = "each_filename" } - - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - input = "Argument[self]" and - output = "Argument[block].Parameter[0]" and - preservesValue = false - } - } - - /** Flow summary for `Pathname#expand_path`. */ - private class ExpandPathSummary extends SimpleSummarizedCallable { - ExpandPathSummary() { this = "expand_path" } - - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - input = "Argument[self]" and - output = "ReturnValue" and - preservesValue = false - } - } - - /** Flow summary for `Pathname#join`. */ - private class JoinSummary extends SimpleSummarizedCallable { - JoinSummary() { this = "join" } - - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - input = ["Argument[self]", "Argument[any]"] and - output = "ReturnValue" and - preservesValue = false - } - } - - /** Flow summary for `Pathname#parent`. */ - private class ParentSummary extends SimpleSummarizedCallable { - ParentSummary() { this = "parent" } - - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - input = "Argument[self]" and - output = "ReturnValue" and - preservesValue = false - } - } - - /** Flow summary for `Pathname#realpath`. */ - private class RealpathSummary extends SimpleSummarizedCallable { - RealpathSummary() { this = "realpath" } - - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - input = "Argument[self]" and - output = "ReturnValue" and - preservesValue = false - } - } - - /** Flow summary for `Pathname#relative_path_from`. */ - private class RelativePathFromSummary extends SimpleSummarizedCallable { - RelativePathFromSummary() { this = "relative_path_from" } - - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - input = "Argument[self]" and - output = "ReturnValue" and - preservesValue = false - } - } - - /** Flow summary for `Pathname#to_path`. */ - private class ToPathSummary extends SimpleSummarizedCallable { - ToPathSummary() { this = "to_path" } - - override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { - input = "Argument[self]" and - output = "ReturnValue" and - preservesValue = false + /** Taint flow summaries for the `Pathname` class. */ + private class PathnameTaintSummary extends ModelInput::SummaryModelCsv { + override predicate row(string row) { + row = + [ + // Pathname.new(path) + ";;Member[Pathname].Method[new];Argument[0];ReturnValue;taint", + // Pathname#dirname + ";Pathname;Method[dirname];Argument[self];ReturnValue;taint", + // Pathname#each_filename + ";Pathname;Method[each_filename];Argument[self];Argument[block].Parameter[0];taint", + // Pathname#expand_path + ";Pathname;Method[expand_path];Argument[self];ReturnValue;taint", + // Pathname#join + ";Pathname;Method[join];Argument[self,any];ReturnValue;taint", + // Pathname#parent + ";Pathname;Method[parent];Argument[self];ReturnValue;taint", + // Pathname#realpath + ";Pathname;Method[realpath];Argument[self];ReturnValue;taint", + // Pathname#relative_path_from + ";Pathname;Method[relative_path_from];Argument[self];ReturnValue;taint", + // Pathname#to_path + ";Pathname;Method[to_path];Argument[self];ReturnValue;taint", + // Pathname#basename + ";Pathname;Method[basename];Argument[self];ReturnValue;taint", + // Pathname#cleanpath + ";Pathname;Method[cleanpath];Argument[self];ReturnValue;taint", + // Pathname#sub + ";Pathname;Method[sub];Argument[self];ReturnValue;taint", + // Pathname#sub_ext + ";Pathname;Method[sub_ext];Argument[self];ReturnValue;taint", + ] } } } diff --git a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected index 8e3a792af46..a13e860bd04 100644 --- a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected +++ b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathame-flow.expected @@ -2,89 +2,218 @@ failures edges | pathname_flow.rb:4:10:4:33 | call to new : | pathname_flow.rb:5:10:5:11 | pn | | pathname_flow.rb:4:23:4:32 | call to source : | pathname_flow.rb:4:10:4:33 | call to new : | -| pathname_flow.rb:9:6:9:29 | call to new : | pathname_flow.rb:11:7:11:11 | ... + ... | -| pathname_flow.rb:9:19:9:28 | call to source : | pathname_flow.rb:9:6:9:29 | call to new : | -| pathname_flow.rb:10:6:10:29 | call to new : | pathname_flow.rb:11:7:11:11 | ... + ... | -| pathname_flow.rb:10:19:10:28 | call to source : | pathname_flow.rb:10:6:10:29 | call to new : | -| pathname_flow.rb:15:7:15:30 | call to new : | pathname_flow.rb:16:7:16:8 | pn : | -| pathname_flow.rb:15:20:15:29 | call to source : | pathname_flow.rb:15:7:15:30 | call to new : | -| pathname_flow.rb:16:7:16:8 | pn : | pathname_flow.rb:16:7:16:16 | call to dirname | -| pathname_flow.rb:20:6:20:29 | call to new : | pathname_flow.rb:21:2:21:2 | a : | -| pathname_flow.rb:20:19:20:28 | call to source : | pathname_flow.rb:20:6:20:29 | call to new : | -| pathname_flow.rb:21:2:21:2 | a : | pathname_flow.rb:21:22:21:22 | x : | -| pathname_flow.rb:21:22:21:22 | x : | pathname_flow.rb:22:8:22:8 | x | -| pathname_flow.rb:27:6:27:29 | call to new : | pathname_flow.rb:28:7:28:7 | a : | -| pathname_flow.rb:27:19:27:28 | call to source : | pathname_flow.rb:27:6:27:29 | call to new : | -| pathname_flow.rb:28:7:28:7 | a : | pathname_flow.rb:28:7:28:21 | call to expand_path | -| pathname_flow.rb:32:6:32:29 | call to new : | pathname_flow.rb:35:7:35:7 | a : | -| pathname_flow.rb:32:19:32:28 | call to source : | pathname_flow.rb:32:6:32:29 | call to new : | -| pathname_flow.rb:34:6:34:29 | call to new : | pathname_flow.rb:35:17:35:17 | c : | -| pathname_flow.rb:34:19:34:28 | call to source : | pathname_flow.rb:34:6:34:29 | call to new : | -| pathname_flow.rb:35:7:35:7 | a : | pathname_flow.rb:35:7:35:18 | call to join | -| pathname_flow.rb:35:17:35:17 | c : | pathname_flow.rb:35:7:35:18 | call to join | -| pathname_flow.rb:39:6:39:29 | call to new : | pathname_flow.rb:40:7:40:7 | a : | -| pathname_flow.rb:39:19:39:28 | call to source : | pathname_flow.rb:39:6:39:29 | call to new : | -| pathname_flow.rb:40:7:40:7 | a : | pathname_flow.rb:40:7:40:16 | call to parent | -| pathname_flow.rb:44:6:44:29 | call to new : | pathname_flow.rb:45:7:45:7 | a : | -| pathname_flow.rb:44:19:44:28 | call to source : | pathname_flow.rb:44:6:44:29 | call to new : | -| pathname_flow.rb:45:7:45:7 | a : | pathname_flow.rb:45:7:45:18 | call to realpath | -| pathname_flow.rb:49:6:49:29 | call to new : | pathname_flow.rb:50:7:50:7 | a : | -| pathname_flow.rb:49:19:49:28 | call to source : | pathname_flow.rb:49:6:49:29 | call to new : | -| pathname_flow.rb:50:7:50:7 | a : | pathname_flow.rb:50:7:50:38 | call to relative_path_from | -| pathname_flow.rb:54:6:54:29 | call to new : | pathname_flow.rb:55:7:55:7 | a : | -| pathname_flow.rb:54:19:54:28 | call to source : | pathname_flow.rb:54:6:54:29 | call to new : | -| pathname_flow.rb:55:7:55:7 | a : | pathname_flow.rb:55:7:55:15 | call to to_path | -| pathname_flow.rb:59:6:59:29 | call to new : | pathname_flow.rb:60:7:60:7 | a : | -| pathname_flow.rb:59:19:59:28 | call to source : | pathname_flow.rb:59:6:59:29 | call to new : | -| pathname_flow.rb:60:7:60:7 | a : | pathname_flow.rb:60:7:60:12 | call to to_s | +| pathname_flow.rb:9:7:9:30 | call to new : | pathname_flow.rb:11:8:11:12 | ... + ... | +| pathname_flow.rb:9:20:9:29 | call to source : | pathname_flow.rb:9:7:9:30 | call to new : | +| pathname_flow.rb:10:7:10:30 | call to new : | pathname_flow.rb:11:8:11:12 | ... + ... | +| pathname_flow.rb:10:20:10:29 | call to source : | pathname_flow.rb:10:7:10:30 | call to new : | +| pathname_flow.rb:15:8:15:31 | call to new : | pathname_flow.rb:16:8:16:9 | pn : | +| pathname_flow.rb:15:21:15:30 | call to source : | pathname_flow.rb:15:8:15:31 | call to new : | +| pathname_flow.rb:16:8:16:9 | pn : | pathname_flow.rb:16:8:16:17 | call to dirname | +| pathname_flow.rb:20:7:20:30 | call to new : | pathname_flow.rb:21:3:21:3 | a : | +| pathname_flow.rb:20:20:20:29 | call to source : | pathname_flow.rb:20:7:20:30 | call to new : | +| pathname_flow.rb:21:3:21:3 | a : | pathname_flow.rb:21:23:21:23 | x : | +| pathname_flow.rb:21:23:21:23 | x : | pathname_flow.rb:22:10:22:10 | x | +| pathname_flow.rb:27:7:27:30 | call to new : | pathname_flow.rb:28:8:28:8 | a : | +| pathname_flow.rb:27:20:27:29 | call to source : | pathname_flow.rb:27:7:27:30 | call to new : | +| pathname_flow.rb:28:8:28:8 | a : | pathname_flow.rb:28:8:28:22 | call to expand_path | +| pathname_flow.rb:32:7:32:30 | call to new : | pathname_flow.rb:35:8:35:8 | a : | +| pathname_flow.rb:32:20:32:29 | call to source : | pathname_flow.rb:32:7:32:30 | call to new : | +| pathname_flow.rb:34:7:34:30 | call to new : | pathname_flow.rb:35:18:35:18 | c : | +| pathname_flow.rb:34:20:34:29 | call to source : | pathname_flow.rb:34:7:34:30 | call to new : | +| pathname_flow.rb:35:8:35:8 | a : | pathname_flow.rb:35:8:35:19 | call to join | +| pathname_flow.rb:35:18:35:18 | c : | pathname_flow.rb:35:8:35:19 | call to join | +| pathname_flow.rb:39:7:39:30 | call to new : | pathname_flow.rb:40:8:40:8 | a : | +| pathname_flow.rb:39:20:39:29 | call to source : | pathname_flow.rb:39:7:39:30 | call to new : | +| pathname_flow.rb:40:8:40:8 | a : | pathname_flow.rb:40:8:40:17 | call to parent | +| pathname_flow.rb:44:7:44:30 | call to new : | pathname_flow.rb:45:8:45:8 | a : | +| pathname_flow.rb:44:20:44:29 | call to source : | pathname_flow.rb:44:7:44:30 | call to new : | +| pathname_flow.rb:45:8:45:8 | a : | pathname_flow.rb:45:8:45:19 | call to realpath | +| pathname_flow.rb:49:7:49:30 | call to new : | pathname_flow.rb:50:8:50:8 | a : | +| pathname_flow.rb:49:20:49:29 | call to source : | pathname_flow.rb:49:7:49:30 | call to new : | +| pathname_flow.rb:50:8:50:8 | a : | pathname_flow.rb:50:8:50:39 | call to relative_path_from | +| pathname_flow.rb:54:7:54:30 | call to new : | pathname_flow.rb:55:8:55:8 | a : | +| pathname_flow.rb:54:20:54:29 | call to source : | pathname_flow.rb:54:7:54:30 | call to new : | +| pathname_flow.rb:55:8:55:8 | a : | pathname_flow.rb:55:8:55:16 | call to to_path | +| pathname_flow.rb:59:7:59:30 | call to new : | pathname_flow.rb:60:8:60:8 | a : | +| pathname_flow.rb:59:20:59:29 | call to source : | pathname_flow.rb:59:7:59:30 | call to new : | +| pathname_flow.rb:60:8:60:8 | a : | pathname_flow.rb:60:8:60:13 | call to to_s | +| pathname_flow.rb:64:7:64:30 | call to new : | pathname_flow.rb:66:8:66:8 | b | +| pathname_flow.rb:64:20:64:29 | call to source : | pathname_flow.rb:64:7:64:30 | call to new : | +| pathname_flow.rb:70:7:70:30 | call to new : | pathname_flow.rb:72:8:72:8 | b | +| pathname_flow.rb:70:20:70:29 | call to source : | pathname_flow.rb:70:7:70:30 | call to new : | +| pathname_flow.rb:76:7:76:30 | call to new : | pathname_flow.rb:77:7:77:7 | a : | +| pathname_flow.rb:76:20:76:29 | call to source : | pathname_flow.rb:76:7:76:30 | call to new : | +| pathname_flow.rb:77:7:77:7 | a : | pathname_flow.rb:77:7:77:16 | call to basename : | +| pathname_flow.rb:77:7:77:16 | call to basename : | pathname_flow.rb:78:8:78:8 | b | +| pathname_flow.rb:82:7:82:30 | call to new : | pathname_flow.rb:83:7:83:7 | a : | +| pathname_flow.rb:82:20:82:29 | call to source : | pathname_flow.rb:82:7:82:30 | call to new : | +| pathname_flow.rb:83:7:83:7 | a : | pathname_flow.rb:83:7:83:17 | call to cleanpath : | +| pathname_flow.rb:83:7:83:17 | call to cleanpath : | pathname_flow.rb:84:8:84:8 | b | +| pathname_flow.rb:88:7:88:30 | call to new : | pathname_flow.rb:89:7:89:7 | a : | +| pathname_flow.rb:88:20:88:29 | call to source : | pathname_flow.rb:88:7:88:30 | call to new : | +| pathname_flow.rb:89:7:89:7 | a : | pathname_flow.rb:89:7:89:25 | call to sub : | +| pathname_flow.rb:89:7:89:25 | call to sub : | pathname_flow.rb:90:8:90:8 | b | +| pathname_flow.rb:94:7:94:30 | call to new : | pathname_flow.rb:95:7:95:7 | a : | +| pathname_flow.rb:94:20:94:29 | call to source : | pathname_flow.rb:94:7:94:30 | call to new : | +| pathname_flow.rb:95:7:95:7 | a : | pathname_flow.rb:95:7:95:23 | call to sub_ext : | +| pathname_flow.rb:95:7:95:23 | call to sub_ext : | pathname_flow.rb:96:8:96:8 | b | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:104:8:104:8 | b : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:107:8:107:8 | c : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:109:7:109:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:112:7:112:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:115:7:115:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:118:7:118:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:121:7:121:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:124:7:124:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:127:7:127:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:130:7:130:7 | a : | +| pathname_flow.rb:101:7:101:30 | call to new : | pathname_flow.rb:133:7:133:7 | a : | +| pathname_flow.rb:101:20:101:29 | call to source : | pathname_flow.rb:101:7:101:30 | call to new : | +| pathname_flow.rb:104:8:104:8 | b : | pathname_flow.rb:104:8:104:17 | call to realpath | +| pathname_flow.rb:107:8:107:8 | c : | pathname_flow.rb:107:8:107:17 | call to realpath | +| pathname_flow.rb:109:7:109:7 | a : | pathname_flow.rb:109:7:109:16 | call to basename : | +| pathname_flow.rb:109:7:109:16 | call to basename : | pathname_flow.rb:110:8:110:8 | d : | +| pathname_flow.rb:110:8:110:8 | d : | pathname_flow.rb:110:8:110:17 | call to realpath | +| pathname_flow.rb:112:7:112:7 | a : | pathname_flow.rb:112:7:112:17 | call to cleanpath : | +| pathname_flow.rb:112:7:112:17 | call to cleanpath : | pathname_flow.rb:113:8:113:8 | e : | +| pathname_flow.rb:113:8:113:8 | e : | pathname_flow.rb:113:8:113:17 | call to realpath | +| pathname_flow.rb:115:7:115:7 | a : | pathname_flow.rb:115:7:115:19 | call to expand_path : | +| pathname_flow.rb:115:7:115:19 | call to expand_path : | pathname_flow.rb:116:8:116:8 | f : | +| pathname_flow.rb:116:8:116:8 | f : | pathname_flow.rb:116:8:116:17 | call to realpath | +| pathname_flow.rb:118:7:118:7 | a : | pathname_flow.rb:118:7:118:19 | call to join : | +| pathname_flow.rb:118:7:118:19 | call to join : | pathname_flow.rb:119:8:119:8 | g : | +| pathname_flow.rb:119:8:119:8 | g : | pathname_flow.rb:119:8:119:17 | call to realpath | +| pathname_flow.rb:121:7:121:7 | a : | pathname_flow.rb:121:7:121:16 | call to realpath : | +| pathname_flow.rb:121:7:121:16 | call to realpath : | pathname_flow.rb:122:8:122:8 | h : | +| pathname_flow.rb:122:8:122:8 | h : | pathname_flow.rb:122:8:122:17 | call to realpath | +| pathname_flow.rb:124:7:124:7 | a : | pathname_flow.rb:124:7:124:38 | call to relative_path_from : | +| pathname_flow.rb:124:7:124:38 | call to relative_path_from : | pathname_flow.rb:125:8:125:8 | i : | +| pathname_flow.rb:125:8:125:8 | i : | pathname_flow.rb:125:8:125:17 | call to realpath | +| pathname_flow.rb:127:7:127:7 | a : | pathname_flow.rb:127:7:127:25 | call to sub : | +| pathname_flow.rb:127:7:127:25 | call to sub : | pathname_flow.rb:128:8:128:8 | j : | +| pathname_flow.rb:128:8:128:8 | j : | pathname_flow.rb:128:8:128:17 | call to realpath | +| pathname_flow.rb:130:7:130:7 | a : | pathname_flow.rb:130:7:130:23 | call to sub_ext : | +| pathname_flow.rb:130:7:130:23 | call to sub_ext : | pathname_flow.rb:131:8:131:8 | k : | +| pathname_flow.rb:131:8:131:8 | k : | pathname_flow.rb:131:8:131:17 | call to realpath | +| pathname_flow.rb:133:7:133:7 | a : | pathname_flow.rb:133:7:133:15 | call to to_path : | +| pathname_flow.rb:133:7:133:15 | call to to_path : | pathname_flow.rb:134:8:134:8 | l : | +| pathname_flow.rb:134:8:134:8 | l : | pathname_flow.rb:134:8:134:17 | call to realpath | nodes | pathname_flow.rb:4:10:4:33 | call to new : | semmle.label | call to new : | | pathname_flow.rb:4:23:4:32 | call to source : | semmle.label | call to source : | | pathname_flow.rb:5:10:5:11 | pn | semmle.label | pn | -| pathname_flow.rb:9:6:9:29 | call to new : | semmle.label | call to new : | -| pathname_flow.rb:9:19:9:28 | call to source : | semmle.label | call to source : | -| pathname_flow.rb:10:6:10:29 | call to new : | semmle.label | call to new : | -| pathname_flow.rb:10:19:10:28 | call to source : | semmle.label | call to source : | -| pathname_flow.rb:11:7:11:11 | ... + ... | semmle.label | ... + ... | -| pathname_flow.rb:15:7:15:30 | call to new : | semmle.label | call to new : | -| pathname_flow.rb:15:20:15:29 | call to source : | semmle.label | call to source : | -| pathname_flow.rb:16:7:16:8 | pn : | semmle.label | pn : | -| pathname_flow.rb:16:7:16:16 | call to dirname | semmle.label | call to dirname | -| pathname_flow.rb:20:6:20:29 | call to new : | semmle.label | call to new : | -| pathname_flow.rb:20:19:20:28 | call to source : | semmle.label | call to source : | -| pathname_flow.rb:21:2:21:2 | a : | semmle.label | a : | -| pathname_flow.rb:21:22:21:22 | x : | semmle.label | x : | -| pathname_flow.rb:22:8:22:8 | x | semmle.label | x | -| pathname_flow.rb:27:6:27:29 | call to new : | semmle.label | call to new : | -| pathname_flow.rb:27:19:27:28 | call to source : | semmle.label | call to source : | -| pathname_flow.rb:28:7:28:7 | a : | semmle.label | a : | -| pathname_flow.rb:28:7:28:21 | call to expand_path | semmle.label | call to expand_path | -| pathname_flow.rb:32:6:32:29 | call to new : | semmle.label | call to new : | -| pathname_flow.rb:32:19:32:28 | call to source : | semmle.label | call to source : | -| pathname_flow.rb:34:6:34:29 | call to new : | semmle.label | call to new : | -| pathname_flow.rb:34:19:34:28 | call to source : | semmle.label | call to source : | -| pathname_flow.rb:35:7:35:7 | a : | semmle.label | a : | -| pathname_flow.rb:35:7:35:18 | call to join | semmle.label | call to join | -| pathname_flow.rb:35:17:35:17 | c : | semmle.label | c : | -| pathname_flow.rb:39:6:39:29 | call to new : | semmle.label | call to new : | -| pathname_flow.rb:39:19:39:28 | call to source : | semmle.label | call to source : | -| pathname_flow.rb:40:7:40:7 | a : | semmle.label | a : | -| pathname_flow.rb:40:7:40:16 | call to parent | semmle.label | call to parent | -| pathname_flow.rb:44:6:44:29 | call to new : | semmle.label | call to new : | -| pathname_flow.rb:44:19:44:28 | call to source : | semmle.label | call to source : | -| pathname_flow.rb:45:7:45:7 | a : | semmle.label | a : | -| pathname_flow.rb:45:7:45:18 | call to realpath | semmle.label | call to realpath | -| pathname_flow.rb:49:6:49:29 | call to new : | semmle.label | call to new : | -| pathname_flow.rb:49:19:49:28 | call to source : | semmle.label | call to source : | -| pathname_flow.rb:50:7:50:7 | a : | semmle.label | a : | -| pathname_flow.rb:50:7:50:38 | call to relative_path_from | semmle.label | call to relative_path_from | -| pathname_flow.rb:54:6:54:29 | call to new : | semmle.label | call to new : | -| pathname_flow.rb:54:19:54:28 | call to source : | semmle.label | call to source : | -| pathname_flow.rb:55:7:55:7 | a : | semmle.label | a : | -| pathname_flow.rb:55:7:55:15 | call to to_path | semmle.label | call to to_path | -| pathname_flow.rb:59:6:59:29 | call to new : | semmle.label | call to new : | -| pathname_flow.rb:59:19:59:28 | call to source : | semmle.label | call to source : | -| pathname_flow.rb:60:7:60:7 | a : | semmle.label | a : | -| pathname_flow.rb:60:7:60:12 | call to to_s | semmle.label | call to to_s | +| pathname_flow.rb:9:7:9:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:9:20:9:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:10:7:10:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:10:20:10:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:11:8:11:12 | ... + ... | semmle.label | ... + ... | +| pathname_flow.rb:15:8:15:31 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:15:21:15:30 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:16:8:16:9 | pn : | semmle.label | pn : | +| pathname_flow.rb:16:8:16:17 | call to dirname | semmle.label | call to dirname | +| pathname_flow.rb:20:7:20:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:20:20:20:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:21:3:21:3 | a : | semmle.label | a : | +| pathname_flow.rb:21:23:21:23 | x : | semmle.label | x : | +| pathname_flow.rb:22:10:22:10 | x | semmle.label | x | +| pathname_flow.rb:27:7:27:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:27:20:27:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:28:8:28:8 | a : | semmle.label | a : | +| pathname_flow.rb:28:8:28:22 | call to expand_path | semmle.label | call to expand_path | +| pathname_flow.rb:32:7:32:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:32:20:32:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:34:7:34:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:34:20:34:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:35:8:35:8 | a : | semmle.label | a : | +| pathname_flow.rb:35:8:35:19 | call to join | semmle.label | call to join | +| pathname_flow.rb:35:18:35:18 | c : | semmle.label | c : | +| pathname_flow.rb:39:7:39:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:39:20:39:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:40:8:40:8 | a : | semmle.label | a : | +| pathname_flow.rb:40:8:40:17 | call to parent | semmle.label | call to parent | +| pathname_flow.rb:44:7:44:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:44:20:44:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:45:8:45:8 | a : | semmle.label | a : | +| pathname_flow.rb:45:8:45:19 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:49:7:49:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:49:20:49:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:50:8:50:8 | a : | semmle.label | a : | +| pathname_flow.rb:50:8:50:39 | call to relative_path_from | semmle.label | call to relative_path_from | +| pathname_flow.rb:54:7:54:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:54:20:54:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:55:8:55:8 | a : | semmle.label | a : | +| pathname_flow.rb:55:8:55:16 | call to to_path | semmle.label | call to to_path | +| pathname_flow.rb:59:7:59:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:59:20:59:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:60:8:60:8 | a : | semmle.label | a : | +| pathname_flow.rb:60:8:60:13 | call to to_s | semmle.label | call to to_s | +| pathname_flow.rb:64:7:64:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:64:20:64:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:66:8:66:8 | b | semmle.label | b | +| pathname_flow.rb:70:7:70:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:70:20:70:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:72:8:72:8 | b | semmle.label | b | +| pathname_flow.rb:76:7:76:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:76:20:76:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:77:7:77:7 | a : | semmle.label | a : | +| pathname_flow.rb:77:7:77:16 | call to basename : | semmle.label | call to basename : | +| pathname_flow.rb:78:8:78:8 | b | semmle.label | b | +| pathname_flow.rb:82:7:82:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:82:20:82:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:83:7:83:7 | a : | semmle.label | a : | +| pathname_flow.rb:83:7:83:17 | call to cleanpath : | semmle.label | call to cleanpath : | +| pathname_flow.rb:84:8:84:8 | b | semmle.label | b | +| pathname_flow.rb:88:7:88:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:88:20:88:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:89:7:89:7 | a : | semmle.label | a : | +| pathname_flow.rb:89:7:89:25 | call to sub : | semmle.label | call to sub : | +| pathname_flow.rb:90:8:90:8 | b | semmle.label | b | +| pathname_flow.rb:94:7:94:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:94:20:94:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:95:7:95:7 | a : | semmle.label | a : | +| pathname_flow.rb:95:7:95:23 | call to sub_ext : | semmle.label | call to sub_ext : | +| pathname_flow.rb:96:8:96:8 | b | semmle.label | b | +| pathname_flow.rb:101:7:101:30 | call to new : | semmle.label | call to new : | +| pathname_flow.rb:101:20:101:29 | call to source : | semmle.label | call to source : | +| pathname_flow.rb:104:8:104:8 | b : | semmle.label | b : | +| pathname_flow.rb:104:8:104:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:107:8:107:8 | c : | semmle.label | c : | +| pathname_flow.rb:107:8:107:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:109:7:109:7 | a : | semmle.label | a : | +| pathname_flow.rb:109:7:109:16 | call to basename : | semmle.label | call to basename : | +| pathname_flow.rb:110:8:110:8 | d : | semmle.label | d : | +| pathname_flow.rb:110:8:110:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:112:7:112:7 | a : | semmle.label | a : | +| pathname_flow.rb:112:7:112:17 | call to cleanpath : | semmle.label | call to cleanpath : | +| pathname_flow.rb:113:8:113:8 | e : | semmle.label | e : | +| pathname_flow.rb:113:8:113:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:115:7:115:7 | a : | semmle.label | a : | +| pathname_flow.rb:115:7:115:19 | call to expand_path : | semmle.label | call to expand_path : | +| pathname_flow.rb:116:8:116:8 | f : | semmle.label | f : | +| pathname_flow.rb:116:8:116:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:118:7:118:7 | a : | semmle.label | a : | +| pathname_flow.rb:118:7:118:19 | call to join : | semmle.label | call to join : | +| pathname_flow.rb:119:8:119:8 | g : | semmle.label | g : | +| pathname_flow.rb:119:8:119:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:121:7:121:7 | a : | semmle.label | a : | +| pathname_flow.rb:121:7:121:16 | call to realpath : | semmle.label | call to realpath : | +| pathname_flow.rb:122:8:122:8 | h : | semmle.label | h : | +| pathname_flow.rb:122:8:122:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:124:7:124:7 | a : | semmle.label | a : | +| pathname_flow.rb:124:7:124:38 | call to relative_path_from : | semmle.label | call to relative_path_from : | +| pathname_flow.rb:125:8:125:8 | i : | semmle.label | i : | +| pathname_flow.rb:125:8:125:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:127:7:127:7 | a : | semmle.label | a : | +| pathname_flow.rb:127:7:127:25 | call to sub : | semmle.label | call to sub : | +| pathname_flow.rb:128:8:128:8 | j : | semmle.label | j : | +| pathname_flow.rb:128:8:128:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:130:7:130:7 | a : | semmle.label | a : | +| pathname_flow.rb:130:7:130:23 | call to sub_ext : | semmle.label | call to sub_ext : | +| pathname_flow.rb:131:8:131:8 | k : | semmle.label | k : | +| pathname_flow.rb:131:8:131:17 | call to realpath | semmle.label | call to realpath | +| pathname_flow.rb:133:7:133:7 | a : | semmle.label | a : | +| pathname_flow.rb:133:7:133:15 | call to to_path : | semmle.label | call to to_path : | +| pathname_flow.rb:134:8:134:8 | l : | semmle.label | l : | +| pathname_flow.rb:134:8:134:17 | call to realpath | semmle.label | call to realpath | subpaths #select diff --git a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathname_flow.rb b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathname_flow.rb index 3434b6093b6..dab4adec6c6 100644 --- a/ruby/ql/test/library-tests/dataflow/pathname-flow/pathname_flow.rb +++ b/ruby/ql/test/library-tests/dataflow/pathname-flow/pathname_flow.rb @@ -6,56 +6,130 @@ def m_new end def m_plus - a = Pathname.new(source 'a') - b = Pathname.new(source 'b') - sink(a + b) # $ hasTaintFlow=a $ hasTaintFlow=b + a = Pathname.new(source 'a') + b = Pathname.new(source 'b') + sink(a + b) # $ hasTaintFlow=a $ hasTaintFlow=b end def m_dirname - pn = Pathname.new(source 'a') - sink pn.dirname # $ hasTaintFlow=a + pn = Pathname.new(source 'a') + sink pn.dirname # $ hasTaintFlow=a end def m_each_filename - a = Pathname.new(source 'a') - a.each_filename do |x| - sink x # $ hasTaintFlow=a - end + a = Pathname.new(source 'a') + a.each_filename do |x| + sink x # $ hasTaintFlow=a + end end def m_expand_path - a = Pathname.new(source 'a') - sink a.expand_path() # $ hasTaintFlow=a + a = Pathname.new(source 'a') + sink a.expand_path() # $ hasTaintFlow=a end def m_join - a = Pathname.new(source 'a') - b = Pathname.new('foo') - c = Pathname.new(source 'c') - sink a.join(b, c) # $ hasTaintFlow=a $ hasTaintFlow=c + a = Pathname.new(source 'a') + b = Pathname.new('foo') + c = Pathname.new(source 'c') + sink a.join(b, c) # $ hasTaintFlow=a $ hasTaintFlow=c end def m_parent - a = Pathname.new(source 'a') - sink a.parent() # $ hasTaintFlow=a + a = Pathname.new(source 'a') + sink a.parent() # $ hasTaintFlow=a end def m_realpath - a = Pathname.new(source 'a') - sink a.realpath() # $ hasTaintFlow=a + a = Pathname.new(source 'a') + sink a.realpath() # $ hasTaintFlow=a end def m_relative_path_from - a = Pathname.new(source 'a') - sink a.relative_path_from('/foo/bar') # $ hasTaintFlow=a + a = Pathname.new(source 'a') + sink a.relative_path_from('/foo/bar') # $ hasTaintFlow=a end def m_to_path - a = Pathname.new(source 'a') - sink a.to_path # $ hasTaintFlow=a + a = Pathname.new(source 'a') + sink a.to_path # $ hasTaintFlow=a end def m_to_s - a = Pathname.new(source 'a') - sink a.to_s # $ hasTaintFlow=a + a = Pathname.new(source 'a') + sink a.to_s # $ hasTaintFlow=a +end + +def m_plus + a = Pathname.new(source 'a') + b = a + 'foo' + sink b # $ hasTaintFlow=a +end + +def m_slash + a = Pathname.new(source 'a') + b = a / 'foo' + sink b # $ hasTaintFlow=a +end + +def m_basename + a = Pathname.new(source 'a') + b = a.basename + sink b # $ hasTaintFlow=a +end + +def m_cleanpath + a = Pathname.new(source 'a') + b = a.cleanpath + sink b # $ hasTaintFlow=a +end + +def m_sub + a = Pathname.new(source 'a') + b = a.sub('foo', 'bar') + sink b # $ hasTaintFlow=a +end + +def m_sub_ext + a = Pathname.new(source 'a') + b = a.sub_ext('.txt') + sink b # $ hasTaintFlow=a +end + +# Test flow through intermediate pathnames +def intermediate_pathnames + a = Pathname.new(source 'a') + + b = a + 'foo' + sink b.realpath # $ hasTaintFlow=a + + c = a / 'foo' + sink c.realpath # $ hasTaintFlow=a + + d = a.basename + sink d.realpath # $ hasTaintFlow=a + + e = a.cleanpath + sink e.realpath # $ hasTaintFlow=a + + f = a.expand_path + sink f.realpath # $ hasTaintFlow=a + + g = a.join('foo') + sink g.realpath # $ hasTaintFlow=a + + h = a.realpath + sink h.realpath # $ hasTaintFlow=a + + i = a.relative_path_from('/foo/bar') + sink i.realpath # $ hasTaintFlow=a + + j = a.sub('foo', 'bar') + sink j.realpath # $ hasTaintFlow=a + + k = a.sub_ext('.txt') + sink k.realpath # $ hasTaintFlow=a + + l = a.to_path + sink l.realpath # $ hasTaintFlow=a end \ No newline at end of file From 0e4954a68cce78906282243d88fa2de2cd6a4f7c Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 29 Jun 2022 14:56:20 +0200 Subject: [PATCH 185/465] add navigation.navigate as an XSS / URL sink --- .../dataflow/ClientSideUrlRedirectCustomizations.qll | 4 ++++ .../Security/CWE-079/DomBasedXss/Xss.expected | 9 +++++++++ .../DomBasedXss/XssWithAdditionalSources.expected | 8 ++++++++ .../test/query-tests/Security/CWE-079/DomBasedXss/tst.js | 4 +++- 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll index e643387c5e4..1884496fff9 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/ClientSideUrlRedirectCustomizations.qll @@ -106,6 +106,10 @@ module ClientSideUrlRedirect { ) and xss = true or + // A call to `navigation.navigate` + this = DataFlow::globalVarRef("navigation").getAMethodCall("navigate").getArgument(0) and + xss = true + or // An assignment to `location` exists(Assignment assgn | isLocation(assgn.getTarget()) and astNode = assgn.getRhs()) and xss = true diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected index e81dbd4d99a..3af55bfd598 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/Xss.expected @@ -1026,6 +1026,10 @@ nodes | tst.js:476:20:476:22 | url | | tst.js:486:22:486:24 | url | | tst.js:486:22:486:24 | url | +| tst.js:491:23:491:35 | location.hash | +| tst.js:491:23:491:35 | location.hash | +| tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:45 | locatio ... bstr(1) | | typeahead.js:20:13:20:45 | target | | typeahead.js:20:22:20:45 | documen ... .search | | typeahead.js:20:22:20:45 | documen ... .search | @@ -2081,6 +2085,10 @@ edges | tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | | tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | | tst.js:471:13:471:46 | documen ... bstr(1) | tst.js:471:7:471:46 | url | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | | typeahead.js:20:13:20:45 | target | typeahead.js:21:12:21:17 | target | | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target | @@ -2354,6 +2362,7 @@ edges | tst.js:475:25:475:27 | url | tst.js:471:13:471:36 | documen ... .search | tst.js:475:25:475:27 | url | Cross-site scripting vulnerability due to $@. | tst.js:471:13:471:36 | documen ... .search | user-provided value | | tst.js:476:20:476:22 | url | tst.js:471:13:471:36 | documen ... .search | tst.js:476:20:476:22 | url | Cross-site scripting vulnerability due to $@. | tst.js:471:13:471:36 | documen ... .search | user-provided value | | tst.js:486:22:486:24 | url | tst.js:471:13:471:36 | documen ... .search | tst.js:486:22:486:24 | url | Cross-site scripting vulnerability due to $@. | tst.js:471:13:471:36 | documen ... .search | user-provided value | +| tst.js:491:23:491:45 | locatio ... bstr(1) | tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | Cross-site scripting vulnerability due to $@. | tst.js:491:23:491:35 | location.hash | user-provided value | | typeahead.js:25:18:25:20 | val | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:25:18:25:20 | val | Cross-site scripting vulnerability due to $@. | typeahead.js:20:22:20:45 | documen ... .search | user-provided value | | v-html.vue:2:8:2:23 | v-html=tainted | v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | Cross-site scripting vulnerability due to $@. | v-html.vue:6:42:6:58 | document.location | user-provided value | | various-concat-obfuscations.js:4:4:4:31 | "
    " ...
    " | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:4:4:4:31 | "
    " ...
    " | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected index e72df859347..f8f72db0b4a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/XssWithAdditionalSources.expected @@ -1038,6 +1038,10 @@ nodes | tst.js:476:20:476:22 | url | | tst.js:486:22:486:24 | url | | tst.js:486:22:486:24 | url | +| tst.js:491:23:491:35 | location.hash | +| tst.js:491:23:491:35 | location.hash | +| tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:45 | locatio ... bstr(1) | | typeahead.js:9:28:9:30 | loc | | typeahead.js:9:28:9:30 | loc | | typeahead.js:9:28:9:30 | loc | @@ -2143,6 +2147,10 @@ edges | tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | | tst.js:471:13:471:36 | documen ... .search | tst.js:471:13:471:46 | documen ... bstr(1) | | tst.js:471:13:471:46 | documen ... bstr(1) | tst.js:471:7:471:46 | url | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | +| tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | | typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js index bc2b9a6a358..3c609ddcc92 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/DomBasedXss/tst.js @@ -487,4 +487,6 @@ function urlStuff() { } window.open(location.hash.substr(1)); // OK - any JavaScript is executed in another context -} \ No newline at end of file + + navigation.navigate(location.hash.substr(1)); // NOT OK +} From a3f4d1bf669f51dc4452113b060ba70df7a2c004 Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Tue, 28 Jun 2022 14:36:07 -0700 Subject: [PATCH 186/465] Move contextual queries from src to lib With this change, users are now able to run View AST command in vscode within vscode workspaces that do not include the core libraries. The relevant core library only needs to be installed in the package cache. --- config/identical-files.json | 10 +++++----- cpp/ql/{src => lib}/IDEContextual.qll | 0 cpp/ql/{src => lib}/definitions.qll | 0 cpp/ql/{src => lib}/localDefinitions.ql | 0 cpp/ql/{src => lib}/localReferences.ql | 0 cpp/ql/{src => lib}/printAst.ql | 0 csharp/ql/{src => lib}/IDEContextual.qll | 0 csharp/ql/{src => lib}/definitions.qll | 0 csharp/ql/{src => lib}/localDefinitions.ql | 0 csharp/ql/{src => lib}/localReferences.ql | 0 csharp/ql/{src => lib}/printAst.ql | 0 java/ql/{src => lib}/IDEContextual.qll | 0 java/ql/{src => lib}/definitions.qll | 0 java/ql/{src => lib}/localDefinitions.ql | 0 java/ql/{src => lib}/localReferences.ql | 0 java/ql/{src => lib}/printAst.ql | 0 .../ql/{src => lib}/Declarations/Declarations.qll | 0 javascript/ql/{src => lib}/IDEContextual.qll | 0 javascript/ql/{src => lib}/definitions.ql | 0 javascript/ql/{src => lib}/definitions.qll | 0 javascript/ql/{src => lib}/localDefinitions.ql | 0 javascript/ql/{src => lib}/localReferences.ql | 0 javascript/ql/{src => lib}/printAst.ql | 0 python/ql/{src => lib}/analysis/DefinitionTracking.qll | 0 python/ql/{src => lib}/analysis/IDEContextual.qll | 0 python/ql/{src => lib}/printAst.ql | 0 .../ide-contextual-queries/localDefinitions.ql | 0 .../ide-contextual-queries/localReferences.ql | 0 .../ql/{src => lib}/ide-contextual-queries/printAst.ql | 0 29 files changed, 5 insertions(+), 5 deletions(-) rename cpp/ql/{src => lib}/IDEContextual.qll (100%) rename cpp/ql/{src => lib}/definitions.qll (100%) rename cpp/ql/{src => lib}/localDefinitions.ql (100%) rename cpp/ql/{src => lib}/localReferences.ql (100%) rename cpp/ql/{src => lib}/printAst.ql (100%) rename csharp/ql/{src => lib}/IDEContextual.qll (100%) rename csharp/ql/{src => lib}/definitions.qll (100%) rename csharp/ql/{src => lib}/localDefinitions.ql (100%) rename csharp/ql/{src => lib}/localReferences.ql (100%) rename csharp/ql/{src => lib}/printAst.ql (100%) rename java/ql/{src => lib}/IDEContextual.qll (100%) rename java/ql/{src => lib}/definitions.qll (100%) rename java/ql/{src => lib}/localDefinitions.ql (100%) rename java/ql/{src => lib}/localReferences.ql (100%) rename java/ql/{src => lib}/printAst.ql (100%) rename javascript/ql/{src => lib}/Declarations/Declarations.qll (100%) rename javascript/ql/{src => lib}/IDEContextual.qll (100%) rename javascript/ql/{src => lib}/definitions.ql (100%) rename javascript/ql/{src => lib}/definitions.qll (100%) rename javascript/ql/{src => lib}/localDefinitions.ql (100%) rename javascript/ql/{src => lib}/localReferences.ql (100%) rename javascript/ql/{src => lib}/printAst.ql (100%) rename python/ql/{src => lib}/analysis/DefinitionTracking.qll (100%) rename python/ql/{src => lib}/analysis/IDEContextual.qll (100%) rename python/ql/{src => lib}/printAst.ql (100%) rename ruby/ql/{src => lib}/ide-contextual-queries/localDefinitions.ql (100%) rename ruby/ql/{src => lib}/ide-contextual-queries/localReferences.ql (100%) rename ruby/ql/{src => lib}/ide-contextual-queries/printAst.ql (100%) diff --git a/config/identical-files.json b/config/identical-files.json index 77e39399cec..990ba49f033 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -453,11 +453,11 @@ "python/ql/src/Lexical/CommentedOutCodeReferences.inc.qhelp" ], "IDE Contextual Queries": [ - "cpp/ql/src/IDEContextual.qll", - "csharp/ql/src/IDEContextual.qll", - "java/ql/src/IDEContextual.qll", - "javascript/ql/src/IDEContextual.qll", - "python/ql/src/analysis/IDEContextual.qll" + "cpp/ql/lib/IDEContextual.qll", + "csharp/ql/lib/IDEContextual.qll", + "java/ql/lib/IDEContextual.qll", + "javascript/ql/lib/IDEContextual.qll", + "python/ql/lib/analysis/IDEContextual.qll" ], "SSA C#": [ "csharp/ql/lib/semmle/code/csharp/dataflow/internal/SsaImplCommon.qll", diff --git a/cpp/ql/src/IDEContextual.qll b/cpp/ql/lib/IDEContextual.qll similarity index 100% rename from cpp/ql/src/IDEContextual.qll rename to cpp/ql/lib/IDEContextual.qll diff --git a/cpp/ql/src/definitions.qll b/cpp/ql/lib/definitions.qll similarity index 100% rename from cpp/ql/src/definitions.qll rename to cpp/ql/lib/definitions.qll diff --git a/cpp/ql/src/localDefinitions.ql b/cpp/ql/lib/localDefinitions.ql similarity index 100% rename from cpp/ql/src/localDefinitions.ql rename to cpp/ql/lib/localDefinitions.ql diff --git a/cpp/ql/src/localReferences.ql b/cpp/ql/lib/localReferences.ql similarity index 100% rename from cpp/ql/src/localReferences.ql rename to cpp/ql/lib/localReferences.ql diff --git a/cpp/ql/src/printAst.ql b/cpp/ql/lib/printAst.ql similarity index 100% rename from cpp/ql/src/printAst.ql rename to cpp/ql/lib/printAst.ql diff --git a/csharp/ql/src/IDEContextual.qll b/csharp/ql/lib/IDEContextual.qll similarity index 100% rename from csharp/ql/src/IDEContextual.qll rename to csharp/ql/lib/IDEContextual.qll diff --git a/csharp/ql/src/definitions.qll b/csharp/ql/lib/definitions.qll similarity index 100% rename from csharp/ql/src/definitions.qll rename to csharp/ql/lib/definitions.qll diff --git a/csharp/ql/src/localDefinitions.ql b/csharp/ql/lib/localDefinitions.ql similarity index 100% rename from csharp/ql/src/localDefinitions.ql rename to csharp/ql/lib/localDefinitions.ql diff --git a/csharp/ql/src/localReferences.ql b/csharp/ql/lib/localReferences.ql similarity index 100% rename from csharp/ql/src/localReferences.ql rename to csharp/ql/lib/localReferences.ql diff --git a/csharp/ql/src/printAst.ql b/csharp/ql/lib/printAst.ql similarity index 100% rename from csharp/ql/src/printAst.ql rename to csharp/ql/lib/printAst.ql diff --git a/java/ql/src/IDEContextual.qll b/java/ql/lib/IDEContextual.qll similarity index 100% rename from java/ql/src/IDEContextual.qll rename to java/ql/lib/IDEContextual.qll diff --git a/java/ql/src/definitions.qll b/java/ql/lib/definitions.qll similarity index 100% rename from java/ql/src/definitions.qll rename to java/ql/lib/definitions.qll diff --git a/java/ql/src/localDefinitions.ql b/java/ql/lib/localDefinitions.ql similarity index 100% rename from java/ql/src/localDefinitions.ql rename to java/ql/lib/localDefinitions.ql diff --git a/java/ql/src/localReferences.ql b/java/ql/lib/localReferences.ql similarity index 100% rename from java/ql/src/localReferences.ql rename to java/ql/lib/localReferences.ql diff --git a/java/ql/src/printAst.ql b/java/ql/lib/printAst.ql similarity index 100% rename from java/ql/src/printAst.ql rename to java/ql/lib/printAst.ql diff --git a/javascript/ql/src/Declarations/Declarations.qll b/javascript/ql/lib/Declarations/Declarations.qll similarity index 100% rename from javascript/ql/src/Declarations/Declarations.qll rename to javascript/ql/lib/Declarations/Declarations.qll diff --git a/javascript/ql/src/IDEContextual.qll b/javascript/ql/lib/IDEContextual.qll similarity index 100% rename from javascript/ql/src/IDEContextual.qll rename to javascript/ql/lib/IDEContextual.qll diff --git a/javascript/ql/src/definitions.ql b/javascript/ql/lib/definitions.ql similarity index 100% rename from javascript/ql/src/definitions.ql rename to javascript/ql/lib/definitions.ql diff --git a/javascript/ql/src/definitions.qll b/javascript/ql/lib/definitions.qll similarity index 100% rename from javascript/ql/src/definitions.qll rename to javascript/ql/lib/definitions.qll diff --git a/javascript/ql/src/localDefinitions.ql b/javascript/ql/lib/localDefinitions.ql similarity index 100% rename from javascript/ql/src/localDefinitions.ql rename to javascript/ql/lib/localDefinitions.ql diff --git a/javascript/ql/src/localReferences.ql b/javascript/ql/lib/localReferences.ql similarity index 100% rename from javascript/ql/src/localReferences.ql rename to javascript/ql/lib/localReferences.ql diff --git a/javascript/ql/src/printAst.ql b/javascript/ql/lib/printAst.ql similarity index 100% rename from javascript/ql/src/printAst.ql rename to javascript/ql/lib/printAst.ql diff --git a/python/ql/src/analysis/DefinitionTracking.qll b/python/ql/lib/analysis/DefinitionTracking.qll similarity index 100% rename from python/ql/src/analysis/DefinitionTracking.qll rename to python/ql/lib/analysis/DefinitionTracking.qll diff --git a/python/ql/src/analysis/IDEContextual.qll b/python/ql/lib/analysis/IDEContextual.qll similarity index 100% rename from python/ql/src/analysis/IDEContextual.qll rename to python/ql/lib/analysis/IDEContextual.qll diff --git a/python/ql/src/printAst.ql b/python/ql/lib/printAst.ql similarity index 100% rename from python/ql/src/printAst.ql rename to python/ql/lib/printAst.ql diff --git a/ruby/ql/src/ide-contextual-queries/localDefinitions.ql b/ruby/ql/lib/ide-contextual-queries/localDefinitions.ql similarity index 100% rename from ruby/ql/src/ide-contextual-queries/localDefinitions.ql rename to ruby/ql/lib/ide-contextual-queries/localDefinitions.ql diff --git a/ruby/ql/src/ide-contextual-queries/localReferences.ql b/ruby/ql/lib/ide-contextual-queries/localReferences.ql similarity index 100% rename from ruby/ql/src/ide-contextual-queries/localReferences.ql rename to ruby/ql/lib/ide-contextual-queries/localReferences.ql diff --git a/ruby/ql/src/ide-contextual-queries/printAst.ql b/ruby/ql/lib/ide-contextual-queries/printAst.ql similarity index 100% rename from ruby/ql/src/ide-contextual-queries/printAst.ql rename to ruby/ql/lib/ide-contextual-queries/printAst.ql From 5233a5e17bf43c12830bacd4c2c19245ef8a1b91 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Wed, 29 Jun 2022 17:03:04 +0200 Subject: [PATCH 187/465] Swift: also extract imported modules --- swift/extractor/SwiftExtractor.cpp | 40 +++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 2708b0241a4..6fefc77e2c7 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -51,6 +52,18 @@ static void archiveFile(const SwiftExtractorConfiguration& config, swift::Source } } +static std::string getTrapFilename(swift::ModuleDecl& module, swift::SourceFile* primaryFile) { + if (primaryFile) { + return primaryFile->getFilename().str(); + } + // Several modules with different name might come from .pcm (clang module) files + // In this case we want to differentiate them + std::string filename = module.getModuleFilename().str(); + filename += "-"; + filename += module.getName().str(); + return filename; +} + static void extractDeclarations(const SwiftExtractorConfiguration& config, llvm::ArrayRef topLevelDecls, swift::CompilerInstance& compiler, @@ -60,7 +73,8 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, // the same input file(s) // We are using PID to avoid concurrent access // TODO: find a more robust approach to avoid collisions? - llvm::StringRef filename = primaryFile ? primaryFile->getFilename() : module.getModuleFilename(); + auto name = getTrapFilename(module, primaryFile); + llvm::StringRef filename(name); std::string tempTrapName = filename.str() + '.' + std::to_string(getpid()) + ".trap"; llvm::SmallString tempTrapPath(config.tempTrapDir); llvm::sys::path::append(tempTrapPath, tempTrapName); @@ -144,7 +158,31 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, } } + // getASTContext().getLoadedModules() does not provide all the modules available within the + // program. + // We need to iterate over all the imported modules (recursively) to see the whole "universe." + std::unordered_set allModules; + std::queue worklist; for (auto& [_, module] : compiler.getASTContext().getLoadedModules()) { + worklist.push(module); + allModules.insert(module); + } + + while (!worklist.empty()) { + auto module = worklist.front(); + worklist.pop(); + llvm::SmallVector importedModules; + // TODO: we may need more than just Exported ones + module->getImportedModules(importedModules, swift::ModuleDecl::ImportFilterKind::Exported); + for (auto& imported : importedModules) { + if (allModules.count(imported.importedModule) == 0) { + worklist.push(imported.importedModule); + allModules.insert(imported.importedModule); + } + } + } + + for (auto& module : allModules) { // We only extract system and builtin modules here as the other "user" modules can be built // during the build process and then re-used at a later stage. In this case, we extract the // user code twice: once during the module build in a form of a source file, and then as From 4dcec2b98ca49e66935976c2816345b396ce954b Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Wed, 29 Jun 2022 17:49:59 +0100 Subject: [PATCH 188/465] Apply suggestions from code review Co-authored-by: Felicity Chapman Co-authored-by: Andrew Eisenberg --- .../publishing-and-using-codeql-packs.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst index e58277d3113..c3a3a2d9ed2 100644 --- a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst +++ b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst @@ -73,27 +73,27 @@ The ``analyze`` command will run the default suite of any specified CodeQL packs codeql analyze / / -Managing packs on GitHub Enterprise Server +Working with CodeQL packs on GitHub Enterprise Server ------------------------------------------ .. pull-quote:: Note - Managing packs on GitHub Enterprise Server is only available for GitHub Enterprise Server 3.6 and later. + The Container registry for GitHub Enterprise Server supports CodeQL query packs from GitHub Enterprise Server 3.6 onward. -By default, CodeQL will download packs from and publish packs to the Container registry on GitHub.com. -You can manage packs on GitHub Enterprise Server 3.6 and later by creating a ``qlconfig.yml`` file to tell CodeQL which Container registry to use for each pack. -Create the ``~/.codeql/qlconfig.yml`` file using your preferred text editor, and add entries to specify which registry to use for each pack name pattern. +By default, the CodeQL CLI expects to download CodeQL packs from and publish packs to the Container registry on GitHub.com. However, you can also work with CodeQL packs in a Container registry on GitHub Enterprise Server 3.6, and later, by creating a ``qlconfig.yml`` file to tell the CLI which Container registry to use for each pack. + +Create a ``~/.codeql/qlconfig.yml`` file using your preferred text editor, and add entries to specify which registry to use for one or more package name patterns. For example, the following ``qlconfig.yml`` file associates all packs with the Container registry for the GitHub Enterprise Server at ``GHE_HOSTNAME``, except packs matching ``codeql/*``, which are associated with the Container registry on GitHub.com: .. code-block:: yaml registries: - packages: '*' - url: https://containers.GHE_HOSTNAME/v2/ + url: https://containers.GHE_HOSTNAME/v2/ - packages: 'codeql/*' - url: https://ghcr.io/v2/ + url: https://ghcr.io/v2/ You can now use ``codeql pack publish``, ``codeql pack download``, and ``codeql database analyze`` to manage packs on GitHub Enterprise Server. @@ -107,7 +107,7 @@ You can authenticate to the Container registry on GitHub.com in two ways: 1. Pass the ``--github-auth-stdin`` option to the CodeQL CLI, then supply a GitHub Apps token or personal access token via standard input. 2. Set the ``GITHUB_TOKEN`` environment variable to a GitHub Apps token or personal access token. -Similarly, you can authenticate to a GHES Container registry, or authenticate to multiple registries simultaneously (for example to download or analyze private packs from multiple registries) in two ways: +Similarly, you can authenticate to a GHES Container registry, or authenticate to multiple registries simultaneously (for example, to download or run private packs from multiple registries) in two ways: 1. Pass the ``--registries-auth-stdin`` option to the CodeQL CLI, then supply a registry authentication string via standard input. 2. Set the ``CODEQL_REGISTRIES_AUTH`` environment variable to a registry authentication string. From ddf06f861776450f491712cfa0e36df1396472ab Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Wed, 29 Jun 2022 10:03:12 -0700 Subject: [PATCH 189/465] Add change notes and qldoc for moved files --- cpp/ql/src/change-notes/2022-06-29-move-contextual-queries.md | 4 ++++ .../ql/src/change-notes/2022-06-29-move-contextual-queries.md | 4 ++++ .../ql/src/change-notes/2022-06-29-move-contextual-queries.md | 4 ++++ .../ql/src/change-notes/2022-06-29-move-contextual-queries.md | 4 ++++ python/ql/lib/analysis/DefinitionTracking.qll | 3 +++ .../ql/src/change-notes/2022-06-29-move-contextual-queries.md | 4 ++++ .../ql/src/change-notes/2022-06-29-move-contextual-queries.md | 4 ++++ 7 files changed, 27 insertions(+) create mode 100644 cpp/ql/src/change-notes/2022-06-29-move-contextual-queries.md create mode 100644 csharp/ql/src/change-notes/2022-06-29-move-contextual-queries.md create mode 100644 java/ql/src/change-notes/2022-06-29-move-contextual-queries.md create mode 100644 javascript/ql/src/change-notes/2022-06-29-move-contextual-queries.md create mode 100644 python/ql/src/change-notes/2022-06-29-move-contextual-queries.md create mode 100644 ruby/ql/src/change-notes/2022-06-29-move-contextual-queries.md diff --git a/cpp/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/cpp/ql/src/change-notes/2022-06-29-move-contextual-queries.md new file mode 100644 index 00000000000..cc5464d58b3 --- /dev/null +++ b/cpp/ql/src/change-notes/2022-06-29-move-contextual-queries.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Contextual queries and the query libraries they depend on have been moved to the `codeql/cpp-all` package. diff --git a/csharp/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/csharp/ql/src/change-notes/2022-06-29-move-contextual-queries.md new file mode 100644 index 00000000000..a27c68766c0 --- /dev/null +++ b/csharp/ql/src/change-notes/2022-06-29-move-contextual-queries.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Contextual queries and the query libraries they depend on have been moved to the `codeql/csharp-all` package. diff --git a/java/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/java/ql/src/change-notes/2022-06-29-move-contextual-queries.md new file mode 100644 index 00000000000..02ff5b6d59c --- /dev/null +++ b/java/ql/src/change-notes/2022-06-29-move-contextual-queries.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Contextual queries and the query libraries they depend on have been moved to the `codeql/java-all` package. diff --git a/javascript/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/javascript/ql/src/change-notes/2022-06-29-move-contextual-queries.md new file mode 100644 index 00000000000..ff190788cd4 --- /dev/null +++ b/javascript/ql/src/change-notes/2022-06-29-move-contextual-queries.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Contextual queries and the query libraries they depend on have been moved to the `codeql/javascript-all` package. diff --git a/python/ql/lib/analysis/DefinitionTracking.qll b/python/ql/lib/analysis/DefinitionTracking.qll index 90166b84991..dafbffad64e 100644 --- a/python/ql/lib/analysis/DefinitionTracking.qll +++ b/python/ql/lib/analysis/DefinitionTracking.qll @@ -14,10 +14,13 @@ class Definition extends TLocalDefinition { /** Gets a textual representation of this element. */ string toString() { result = "Definition " + this.getAstNode().getLocation().toString() } + /** Gets the AST Node associated with this element */ AstNode getAstNode() { this = TLocalDefinition(result) } + /** Gets the Module associated with this element */ Module getModule() { result = this.getAstNode().getScope().getEnclosingModule() } + /** Gets the source location of the AST Node associated with this element */ Location getLocation() { result = this.getAstNode().getLocation() } } diff --git a/python/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/python/ql/src/change-notes/2022-06-29-move-contextual-queries.md new file mode 100644 index 00000000000..2e8562e66f8 --- /dev/null +++ b/python/ql/src/change-notes/2022-06-29-move-contextual-queries.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Contextual queries and the query libraries they depend on have been moved to the `codeql/python-all` package. diff --git a/ruby/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/ruby/ql/src/change-notes/2022-06-29-move-contextual-queries.md new file mode 100644 index 00000000000..bc85eb9361e --- /dev/null +++ b/ruby/ql/src/change-notes/2022-06-29-move-contextual-queries.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* Contextual queries and the query libraries they depend on have been moved to the `codeql/ruby-all` package. From 41244180b3bcdfea10d063d2cd7ce7b168aad67f Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Wed, 29 Jun 2022 10:18:13 -0700 Subject: [PATCH 190/465] Apply suggestions from code review Co-authored-by: Felicity Chapman --- .../analyzing-databases-with-the-codeql-cli.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst index 6953d67f81b..bb428f2c00d 100644 --- a/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst +++ b/docs/codeql/codeql-cli/analyzing-databases-with-the-codeql-cli.rst @@ -138,7 +138,7 @@ For further information about default suites, see ":ref:`Publishing and using Co Running a subset of queries in a CodeQL pack ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Additionally, CodeQL CLI v2.8.1 or later, you can include a path at the end of a pack specification to run a subset of queries inside the pack. This applies to any command that locates or runs queries within a pack. +If you are using CodeQL CLI v2.8.1 or later, you can include a path at the end of a pack specification to run a subset of queries inside the pack. This applies to any command that locates or runs queries within a pack. The complete way to specify a set of queries is in the form ``scope/name@range:path``, where: @@ -146,20 +146,21 @@ The complete way to specify a set of queries is in the form ``scope/name@range:p - ``range`` is a `semver range `_. - ``path`` is a file system path to a single query, a directory containing queries, or a query suite file. -If a ``scope/name`` is specified, the ``range`` and ``path`` are -optional. A missing ``range`` implies the latest version of the -specified pack. A missing ``path`` implies the default query suite -of the specified pack. +When you specify a ``scope/name``, the ``range`` and ``path`` are +optional. If you omit a ``range`` then the latest version of the +specified pack is used. If you omit a ``path`` then the default query suite +of the specified pack is used. The ``path`` can be one of a ``*.ql`` query file, a directory containing one or more queries, or a ``.qls`` query suite file. If -there is no pack name specified, then a ``path`` must be provided, -and will be interpreted relative to the current working directory +you omit a pack name, then you must provide a ``path``, +which will be interpreted relative to the working directory of the current process. -If a ``scope/name`` and ``path`` are specified, then the ``path`` cannot +If you specify a ``scope/name`` and ``path``, then the ``path`` cannot be absolute. It is considered relative to the root of the CodeQL pack. + To analyze a database using all queries in the `experimental/Security` folder within the `codeql/cpp-queries` CodeQL pack you can use:: codeql database analyze --format=sarif-latest --output=results \ From 7864a7580e8d3b8eefe72a083a2283cd63465e5c Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Wed, 29 Jun 2022 10:22:45 -0700 Subject: [PATCH 191/465] Fix import statements --- javascript/ql/src/Declarations/DeclBeforeUse.ql | 2 +- javascript/ql/src/Declarations/RedeclaredVariable.ql | 2 +- python/ql/src/analysis/Consistency.ql | 2 +- python/ql/src/analysis/Definitions.ql | 2 +- python/ql/src/analysis/LocalDefinitions.ql | 2 +- python/ql/src/analysis/LocalReferences.ql | 2 +- python/ql/src/analysis/RatioOfDefinitions.ql | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/javascript/ql/src/Declarations/DeclBeforeUse.ql b/javascript/ql/src/Declarations/DeclBeforeUse.ql index 49a7a3f01c8..b58fab9e465 100644 --- a/javascript/ql/src/Declarations/DeclBeforeUse.ql +++ b/javascript/ql/src/Declarations/DeclBeforeUse.ql @@ -10,7 +10,7 @@ */ import javascript -private import Declarations +private import Declarations.Declarations from VarAccess acc, VarDecl decl, Variable var, StmtContainer sc where diff --git a/javascript/ql/src/Declarations/RedeclaredVariable.ql b/javascript/ql/src/Declarations/RedeclaredVariable.ql index cdce959e66d..7f07378cef7 100644 --- a/javascript/ql/src/Declarations/RedeclaredVariable.ql +++ b/javascript/ql/src/Declarations/RedeclaredVariable.ql @@ -10,7 +10,7 @@ */ import javascript -private import Declarations +private import Declarations.Declarations from Variable v, TopLevel tl, VarDecl decl, VarDecl redecl where diff --git a/python/ql/src/analysis/Consistency.ql b/python/ql/src/analysis/Consistency.ql index d6f1bbc32c5..9f739d18415 100644 --- a/python/ql/src/analysis/Consistency.ql +++ b/python/ql/src/analysis/Consistency.ql @@ -5,7 +5,7 @@ */ import python -import DefinitionTracking +import analysis.DefinitionTracking predicate uniqueness_error(int number, string what, string problem) { what in [ diff --git a/python/ql/src/analysis/Definitions.ql b/python/ql/src/analysis/Definitions.ql index a2ed4f36bf6..bf2458dd8ab 100644 --- a/python/ql/src/analysis/Definitions.ql +++ b/python/ql/src/analysis/Definitions.ql @@ -6,7 +6,7 @@ */ import python -import DefinitionTracking +import analysis.DefinitionTracking from NiceLocationExpr use, Definition defn, string kind where defn = definitionOf(use, kind) diff --git a/python/ql/src/analysis/LocalDefinitions.ql b/python/ql/src/analysis/LocalDefinitions.ql index fae19995f57..d86e3e9254b 100644 --- a/python/ql/src/analysis/LocalDefinitions.ql +++ b/python/ql/src/analysis/LocalDefinitions.ql @@ -8,7 +8,7 @@ */ import python -import DefinitionTracking +import analysis.DefinitionTracking external string selectedSourceFile(); diff --git a/python/ql/src/analysis/LocalReferences.ql b/python/ql/src/analysis/LocalReferences.ql index cf254e9fc3d..6eea0846e85 100644 --- a/python/ql/src/analysis/LocalReferences.ql +++ b/python/ql/src/analysis/LocalReferences.ql @@ -8,7 +8,7 @@ */ import python -import DefinitionTracking +import analysis.DefinitionTracking external string selectedSourceFile(); diff --git a/python/ql/src/analysis/RatioOfDefinitions.ql b/python/ql/src/analysis/RatioOfDefinitions.ql index f7ef4741ee6..562deb75005 100644 --- a/python/ql/src/analysis/RatioOfDefinitions.ql +++ b/python/ql/src/analysis/RatioOfDefinitions.ql @@ -3,7 +3,7 @@ */ import python -import DefinitionTracking +import analysis.DefinitionTracking predicate want_to_have_definition(Expr e) { /* not builtin object like len, tuple, etc. */ From 3c8f415f69f0a41be5638be7a3fe77dc14de6b2c Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Wed, 29 Jun 2022 10:33:27 -0700 Subject: [PATCH 192/465] Recommend installing the latest version of the CLI to use packaging --- docs/codeql/reusables/beta-note-package-management.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/reusables/beta-note-package-management.rst b/docs/codeql/reusables/beta-note-package-management.rst index a4fd362a70c..7697c9a47d9 100644 --- a/docs/codeql/reusables/beta-note-package-management.rst +++ b/docs/codeql/reusables/beta-note-package-management.rst @@ -2,4 +2,4 @@ Note - The CodeQL package management functionality, including CodeQL packs, is currently available as a beta release and is subject to change. During the beta release, CodeQL packs are available only using GitHub Packages - the GitHub Container registry. To use this beta functionality, install version 2.6.0 or higher of the CodeQL CLI bundle from: https://github.com/github/codeql-action/releases. \ No newline at end of file + The CodeQL package management functionality, including CodeQL packs, is currently available as a beta release and is subject to change. During the beta release, CodeQL packs are available only using GitHub Packages - the GitHub Container registry. To use this beta functionality, install the latest version of the CodeQL CLI bundle from: https://github.com/github/codeql-action/releases. From 7cef4322e70e10c0c62e9ce933ca9f6db44b6ec1 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 29 Jun 2022 22:09:23 +0200 Subject: [PATCH 193/465] add model for chownr --- javascript/externs/nodejs/fs.js | 1 - .../semmle/javascript/frameworks/Files.qll | 12 ++ .../CWE-022/TaintedPath/TaintedPath.expected | 199 ++++++++++++++++++ .../TaintedPath/tainted-access-paths.js | 9 +- 4 files changed, 219 insertions(+), 2 deletions(-) diff --git a/javascript/externs/nodejs/fs.js b/javascript/externs/nodejs/fs.js index a1ce1f83a7e..1afdf83bcd0 100644 --- a/javascript/externs/nodejs/fs.js +++ b/javascript/externs/nodejs/fs.js @@ -1696,4 +1696,3 @@ module.exports.R_OK = fs.R_OK; module.exports.W_OK = fs.W_OK; module.exports.X_OK = fs.X_OK; - diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Files.qll b/javascript/ql/lib/semmle/javascript/frameworks/Files.qll index f03f5ee1458..244c9c502c2 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Files.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Files.qll @@ -192,6 +192,18 @@ private class WriteFileAtomic extends FileSystemWriteAccess, DataFlow::CallNode override DataFlow::Node getADataNode() { result = this.getArgument(1) } } +/** + * A call to the library `chownr`. + * The library changes the owner of a file or directory recursively. + */ +private class Chownr extends FileSystemWriteAccess, DataFlow::CallNode { + Chownr() { this = DataFlow::moduleImport("chownr").getACall() } + + override DataFlow::Node getAPathArgument() { result = this.getArgument(0) } + + override DataFlow::Node getADataNode() { none() } +} + /** * A call to the library `recursive-readdir`. */ diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected index e8ca5f0f5ff..887b95b2b96 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/TaintedPath.expected @@ -3235,6 +3235,92 @@ nodes | tainted-access-paths.js:40:23:40:26 | path | | tainted-access-paths.js:40:23:40:26 | path | | tainted-access-paths.js:40:23:40:26 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:24:48:30 | req.url | +| tainted-access-paths.js:48:24:48:30 | req.url | +| tainted-access-paths.js:48:24:48:30 | req.url | +| tainted-access-paths.js:48:24:48:30 | req.url | +| tainted-access-paths.js:48:24:48:30 | req.url | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:49:10:49:13 | path | | tainted-require.js:7:19:7:37 | req.param("module") | | tainted-require.js:7:19:7:37 | req.param("module") | | tainted-require.js:7:19:7:37 | req.param("module") | @@ -8759,6 +8845,118 @@ edges | tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | | tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | | tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:39:14:39:37 | url.par ... , true) | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:7:48:48 | path | tainted-access-paths.js:49:10:49:13 | path | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:37 | url.par ... , true) | tainted-access-paths.js:48:14:48:43 | url.par ... ).query | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:43 | url.par ... ).query | tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:14:48:48 | url.par ... ry.path | tainted-access-paths.js:48:7:48:48 | path | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | +| tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:48:14:48:37 | url.par ... , true) | | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | | tainted-require.js:12:29:12:47 | req.param("module") | tainted-require.js:12:29:12:47 | req.param("module") | | tainted-require.js:14:11:14:29 | req.param("module") | tainted-require.js:14:11:14:29 | req.param("module") | @@ -10000,6 +10198,7 @@ edges | tainted-access-paths.js:30:23:30:30 | obj.sub4 | tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:30:23:30:30 | obj.sub4 | This path depends on $@. | tainted-access-paths.js:6:24:6:30 | req.url | a user-provided value | | tainted-access-paths.js:31:23:31:30 | obj.sub4 | tainted-access-paths.js:6:24:6:30 | req.url | tainted-access-paths.js:31:23:31:30 | obj.sub4 | This path depends on $@. | tainted-access-paths.js:6:24:6:30 | req.url | a user-provided value | | tainted-access-paths.js:40:23:40:26 | path | tainted-access-paths.js:39:24:39:30 | req.url | tainted-access-paths.js:40:23:40:26 | path | This path depends on $@. | tainted-access-paths.js:39:24:39:30 | req.url | a user-provided value | +| tainted-access-paths.js:49:10:49:13 | path | tainted-access-paths.js:48:24:48:30 | req.url | tainted-access-paths.js:49:10:49:13 | path | This path depends on $@. | tainted-access-paths.js:48:24:48:30 | req.url | a user-provided value | | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | This path depends on $@. | tainted-require.js:7:19:7:37 | req.param("module") | a user-provided value | | tainted-require.js:12:29:12:47 | req.param("module") | tainted-require.js:12:29:12:47 | req.param("module") | tainted-require.js:12:29:12:47 | req.param("module") | This path depends on $@. | tainted-require.js:12:29:12:47 | req.param("module") | a user-provided value | | tainted-require.js:14:11:14:29 | req.param("module") | tainted-require.js:14:11:14:29 | req.param("module") | tainted-require.js:14:11:14:29 | req.param("module") | This path depends on $@. | tainted-require.js:14:11:14:29 | req.param("module") | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/tainted-access-paths.js b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/tainted-access-paths.js index e439628d065..465b5b70b69 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/tainted-access-paths.js +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath/tainted-access-paths.js @@ -40,4 +40,11 @@ var server2 = http.createServer(function(req, res) { nodefs.readFileSync(path); // NOT OK }); -server2.listen(); \ No newline at end of file +server2.listen(); + +const chownr = require("chownr"); + +var server3 = http.createServer(function (req, res) { + let path = url.parse(req.url, true).query.path; + chownr(path, "someuid", "somegid", function (err) {}); // NOT OK +}); From e9d3f658a3e6dd917075df2e1a660a4ea9aeee57 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 30 Jun 2022 00:18:31 +0000 Subject: [PATCH 194/465] Add changed framework coverage reports --- .../library-coverage/coverage.csv | 242 +++++++++--------- .../library-coverage/coverage.rst | 4 +- 2 files changed, 123 insertions(+), 123 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index b9d52d9d75e..06ec8d978d4 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -1,121 +1,121 @@ -package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value -android.app,16,,103,,,,,,7,,,,,,,,,9,,,,,,,,,,,,,,,,,,18,85 -android.content,24,27,108,,,,,,16,,,,,,,,,,,,,,,,,8,,,,,,,,27,,31,77 -android.database,59,,30,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,30, -android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 -android.os,,,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,41,81 -android.util,6,16,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,16,, -android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,2,, -android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1, -androidx.slice,2,5,88,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,5,,27,61 -cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, -com.google.common.base,4,,85,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,62,23 -com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 -com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 -com.google.common.flogger,29,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,, -com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,72,1 -com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,, -com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, -com.unboundid.ldap.sdk,17,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,, -com.zaxxer.hikari,2,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,, -flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,7,, -jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, -jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,94,55 -java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -java.io,37,,39,,15,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,39, -java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,46,12 -java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,3,7, -java.nio,15,,6,,13,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,6, -java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,, -java.util,44,,438,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,24,414 -javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,7,, -javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, -javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 -javax.management.remote,2,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,, -javax.naming,7,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,, -javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,, -javax.script,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,, -javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2, -javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, -javax.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, -javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, -javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,94,55 -javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,6, -javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,, -jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 -kotlin.jvm.internal,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,, -ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,, -okhttp3,2,,47,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,22,25 -org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, -org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 -org.apache.commons.io,104,,561,,89,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,547,14 -org.apache.commons.jexl2,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.jexl3,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.lang3,,,424,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,293,131 -org.apache.commons.logging,6,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,, -org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 -org.apache.directory.ldap.client.api,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,, -org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,2,39, -org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2, -org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 -org.apache.http,27,3,70,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,2,,,3,62,8 -org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,57, -org.apache.log4j,11,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,, -org.apache.logging.log4j,359,,8,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,4,4 -org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.apache.shiro.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,, -org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,, -org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,, -org.jboss.logging,324,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,, -org.jdbi.v3.core,6,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,, -org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 -org.mvel2,16,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,, -org.scijava.log,13,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,, -org.slf4j,55,,6,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,2,4 -org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 -org.springframework.boot.jdbc,1,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 -org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -org.springframework.http,14,,70,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,60,10 -org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,, -org.springframework.jdbc.datasource,4,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,, -org.springframework.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.ldap,47,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,, -org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, -org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 -org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52 -org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, -org.springframework.web.client,13,3,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,3,, -org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, -org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, -org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,, -org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25 -org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, -org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, -play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,, -ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 -ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, -ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, -ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, -ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 -retrofit2,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,, +package,sink,source,summary,sink:bean-validation,sink:create-file,sink:groovy,sink:header-splitting,sink:information-leak,sink:intent-start,sink:jdbc-url,sink:jexl,sink:jndi-injection,sink:ldap,sink:logging,sink:mvel,sink:ognl-injection,sink:open-url,sink:pending-intent-sent,sink:regex-use[-1],sink:regex-use[0],sink:regex-use[],sink:regex-use[f-1],sink:regex-use[f1],sink:regex-use[f],sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:write-file,sink:xpath,sink:xslt,sink:xss,source:android-external-storage-dir,source:android-widget,source:contentprovider,source:remote,summary:taint,summary:value +android.app,16,,103,,,,,,7,,,,,,,,,9,,,,,,,,,,,,,,,,,,,18,85 +android.content,24,31,108,,,,,,16,,,,,,,,,,,,,,,,,8,,,,,,,4,,27,,31,77 +android.database,59,,30,,,,,,,,,,,,,,,,,,,,,,,59,,,,,,,,,,,30, +android.net,,,60,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,45,15 +android.os,,2,122,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,41,81 +android.util,6,16,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,16,, +android.webkit,3,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,2,, +android.widget,,1,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,1, +androidx.slice,2,5,88,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,5,,27,61 +cn.hutool.core.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.esotericsoftware.kryo5.io,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.core,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +com.fasterxml.jackson.databind,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +com.google.common.base,4,,85,,,,,,,,,,,,,,,,,3,1,,,,,,,,,,,,,,,,62,23 +com.google.common.cache,,,17,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17 +com.google.common.collect,,,553,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,551 +com.google.common.flogger,29,,,,,,,,,,,,,29,,,,,,,,,,,,,,,,,,,,,,,, +com.google.common.io,6,,73,,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,72,1 +com.opensymphony.xwork2.ognl,3,,,,,,,,,,,,,,,3,,,,,,,,,,,,,,,,,,,,,, +com.rabbitmq.client,,21,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,7, +com.unboundid.ldap.sdk,17,,,,,,,,,,,,17,,,,,,,,,,,,,,,,,,,,,,,,, +com.zaxxer.hikari,2,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,, +flexjson,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +groovy.lang,26,,,,,26,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +groovy.util,5,,,,,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +jakarta.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, +jakarta.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +jakarta.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, +jakarta.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +jakarta.ws.rs.core,2,,149,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 +java.beans,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +java.io,37,,39,,15,,,,,,,,,,,,,,,,,,,,,,,,22,,,,,,,,39, +java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12 +java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,3,7, +java.nio,15,,6,,13,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,6, +java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,,, +java.util,44,,438,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,24,414 +javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, +javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, +javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 +javax.management.remote,2,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,,,,,,, +javax.naming,7,,,,,,,,,,,6,1,,,,,,,,,,,,,,,,,,,,,,,,, +javax.net.ssl,2,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,, +javax.script,1,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,, +javax.servlet,4,21,2,,,,3,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,21,2, +javax.validation,1,1,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,, +javax.ws.rs.client,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, +javax.ws.rs.container,,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,, +javax.ws.rs.core,3,,149,,,,1,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,94,55 +javax.xml.transform,1,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,6, +javax.xml.xpath,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,,,,,,,, +jodd.json,,,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10 +kotlin.jvm.internal,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 +net.sf.saxon.s9api,5,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,5,,,,,,, +ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,, +okhttp3,2,,47,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,22,25 +org.apache.commons.codec,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6, +org.apache.commons.collections,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.collections4,,,800,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,17,783 +org.apache.commons.io,104,,561,,89,,,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,547,14 +org.apache.commons.jexl2,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.jexl3,15,,,,,,,,,,15,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.lang3,,,424,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,293,131 +org.apache.commons.logging,6,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.ognl,6,,,,,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,, +org.apache.commons.text,,,272,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,220,52 +org.apache.directory.ldap.client.api,1,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.hc.core5.function,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.hc.core5.http,1,2,39,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,2,39, +org.apache.hc.core5.net,,,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2, +org.apache.hc.core5.util,,,24,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,18,6 +org.apache.http,27,3,70,,,,,,,,,,,,,,25,,,,,,,,,,,,,,,2,,,,3,62,8 +org.apache.ibatis.jdbc,6,,57,,,,,,,,,,,,,,,,,,,,,,,6,,,,,,,,,,,57, +org.apache.log4j,11,,,,,,,,,,,,,11,,,,,,,,,,,,,,,,,,,,,,,, +org.apache.logging.log4j,359,,8,,,,,,,,,,,359,,,,,,,,,,,,,,,,,,,,,,,4,4 +org.apache.shiro.codec,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.apache.shiro.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,, +org.codehaus.groovy.control,1,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.dom4j,20,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20,,,,,,,, +org.hibernate,7,,,,,,,,,,,,,,,,,,,,,,,,,7,,,,,,,,,,,, +org.jboss.logging,324,,,,,,,,,,,,,324,,,,,,,,,,,,,,,,,,,,,,,, +org.jdbi.v3.core,6,,,,,,,,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.jooq,1,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,, +org.json,,,236,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,198,38 +org.mvel2,16,,,,,,,,,,,,,,16,,,,,,,,,,,,,,,,,,,,,,, +org.scijava.log,13,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,,,,,, +org.slf4j,55,,6,,,,,,,,,,,55,,,,,,,,,,,,,,,,,,,,,,,2,4 +org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,30 +org.springframework.boot.jdbc,1,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 +org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +org.springframework.http,14,,70,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,,,,,,60,10 +org.springframework.jdbc.core,10,,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,, +org.springframework.jdbc.datasource,4,,,,,,,,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,, +org.springframework.jndi,1,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.ldap,47,,,,,,,,,,,33,14,,,,,,,,,,,,,,,,,,,,,,,,, +org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,, +org.springframework.ui,,,32,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,32 +org.springframework.util,,,139,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,87,52 +org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13, +org.springframework.web.client,13,3,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,,,,,,3,, +org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,, +org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13, +org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,,,,,, +org.springframework.web.util,,,163,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,138,25 +org.xml.sax,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1, +org.xmlpull.v1,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,, +play.mvc,,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,, +ratpack.core.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.core.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.core.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.exec,,,48,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,48 +ratpack.form,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, +ratpack.func,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +ratpack.handling,,6,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,6,4, +ratpack.http,,10,10,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,10,10, +ratpack.util,,,35,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,35 +retrofit2,1,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index cd8995b77d5..7b45a3115b1 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -7,7 +7,7 @@ Java framework & library support :widths: auto Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE‑022` :sub:`Path injection`,`CWE‑036` :sub:`Path traversal`,`CWE‑079` :sub:`Cross-site scripting`,`CWE‑089` :sub:`SQL injection`,`CWE‑090` :sub:`LDAP injection`,`CWE‑094` :sub:`Code injection`,`CWE‑319` :sub:`Cleartext transmission` - Android,``android.*``,46,424,108,,,3,67,,, + Android,``android.*``,52,424,108,,,3,67,,, `Apache Commons Collections `_,"``org.apache.commons.collections``, ``org.apache.commons.collections4``",,1600,,,,,,,, `Apache Commons IO `_,``org.apache.commons.io``,,561,104,89,,,,,,15 `Apache Commons Lang `_,``org.apache.commons.lang3``,,424,,,,,,,, @@ -19,5 +19,5 @@ Java framework & library support Java extensions,"``javax.*``, ``jakarta.*``",63,609,32,,,4,,1,1,2 `Spring `_,``org.springframework.*``,29,476,101,,,,19,14,,29 Others,"``androidx.slice``, ``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``kotlin.jvm.internal``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.logging.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jboss.logging``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",65,395,932,,,,14,18,,3 - Totals,,211,6410,1474,117,6,10,107,33,1,84 + Totals,,217,6410,1474,117,6,10,107,33,1,84 From 5d5f3f82b1ba752d4b41d66498aff62535020dc7 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Thu, 30 Jun 2022 07:41:28 +0200 Subject: [PATCH 195/465] Swift: fix test case --- .../test/extractor-tests/generated/type/InOutType/in_out.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/test/extractor-tests/generated/type/InOutType/in_out.swift b/swift/ql/test/extractor-tests/generated/type/InOutType/in_out.swift index ae15ad1b884..54bf9be192d 100644 --- a/swift/ql/test/extractor-tests/generated/type/InOutType/in_out.swift +++ b/swift/ql/test/extractor-tests/generated/type/InOutType/in_out.swift @@ -8,5 +8,5 @@ struct S { mutating func bar() {} } -var s: S +var s: S = S() s.bar() From 522d48aa33b02ec6f7e9ab9aa55850af34716efa Mon Sep 17 00:00:00 2001 From: AlexDenisov Date: Thu, 30 Jun 2022 08:47:17 +0200 Subject: [PATCH 196/465] Apply suggestions from code review Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- swift/extractor/SwiftOutputRewrite.cpp | 10 +++++----- swift/extractor/SwiftOutputRewrite.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/swift/extractor/SwiftOutputRewrite.cpp b/swift/extractor/SwiftOutputRewrite.cpp index b48fd4cfc3e..cb6e4729928 100644 --- a/swift/extractor/SwiftOutputRewrite.cpp +++ b/swift/extractor/SwiftOutputRewrite.cpp @@ -12,7 +12,7 @@ #include // Creates a copy of the output file map and updated remapping table in place -// It does not change the original map file as it is dependent upon by the original compiler +// It does not change the original map file as it is depended upon by the original compiler // Returns path to the newly created output file map on success, or None in a case of failure static std::optional rewriteOutputFileMap( const codeql::SwiftExtractorConfiguration& config, @@ -58,7 +58,7 @@ static std::optional rewriteOutputFileMap( return newPath; } -// This is Xcode-specific workaround to produce alias names for an existing .swiftmodule file. +// This is an Xcode-specific workaround to produce alias names for an existing .swiftmodule file. // In the case of Xcode, it calls the Swift compiler and asks it to produce a Swift module. // Once it's done, Xcode moves the .swiftmodule file in another location, and the location is // rather arbitrary. Here are examples of such locations: @@ -84,10 +84,10 @@ static std::optional rewriteOutputFileMap( // The here is a normalized target triple (e.g. arm64-apple-iphoneos15.4 -> // arm64-apple-iphoneos). // -// This method construct those aliases for a module only if it comes from Xcode, which is detected -// by the presence of `Intermediates.noindex` directory in the module path. +// This method constructs those aliases for a module only if it comes from Xcode, which is detected +// by the presence of an `Intermediates.noindex` directory in the module path. // -// In the case of Swift Package Manager (`swift build`) this is not needed. +// In the case of the Swift Package Manager (`swift build`) this is not needed. static std::vector computeModuleAliases(llvm::StringRef modulePath, const std::string& targetTriple) { if (modulePath.empty()) { diff --git a/swift/extractor/SwiftOutputRewrite.h b/swift/extractor/SwiftOutputRewrite.h index 3f96608b501..03b247bd3dd 100644 --- a/swift/extractor/SwiftOutputRewrite.h +++ b/swift/extractor/SwiftOutputRewrite.h @@ -16,8 +16,8 @@ std::unordered_map rewriteOutputsInPlace( SwiftExtractorConfiguration& config, std::vector& CLIArgs); -// Recreate all the redirected new paths as the Swift compiler expects them to be present -void ensureNewPathsExist(const std::unordered_map& remapping); +// Create directories for all the redirected new paths as the Swift compiler expects them to exist. +void ensureDirectoriesForNewPathsExist(const std::unordered_map& remapping); // Stores remapped `.swiftmoduile`s in a YAML file for later consumption by the // llvm::RedirectingFileSystem via Swift's VFSOverlayFiles. From 35da75f68542883a42bc37059b09f5141eb43ee7 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Thu, 30 Jun 2022 08:48:36 +0200 Subject: [PATCH 197/465] Swift: rename method --- swift/extractor/SwiftOutputRewrite.cpp | 3 ++- swift/extractor/main.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/swift/extractor/SwiftOutputRewrite.cpp b/swift/extractor/SwiftOutputRewrite.cpp index cb6e4729928..153526f9fde 100644 --- a/swift/extractor/SwiftOutputRewrite.cpp +++ b/swift/extractor/SwiftOutputRewrite.cpp @@ -226,7 +226,8 @@ std::unordered_map rewriteOutputsInPlace( return remapping; } -void ensureNewPathsExist(const std::unordered_map& remapping) { +void ensureDirectoriesForNewPathsExist( + const std::unordered_map& remapping) { for (auto& [_, newPath] : remapping) { llvm::SmallString filepath(newPath); llvm::StringRef parent = llvm::sys::path::parent_path(filepath); diff --git a/swift/extractor/main.cpp b/swift/extractor/main.cpp index 2a3d23e87e5..59bbfa690f0 100644 --- a/swift/extractor/main.cpp +++ b/swift/extractor/main.cpp @@ -71,7 +71,7 @@ int main(int argc, char** argv) { auto remapping = codeql::rewriteOutputsInPlace(configuration, configuration.patchedFrontendOptions); - codeql::ensureNewPathsExist(remapping); + codeql::ensureDirectoriesForNewPathsExist(remapping); codeql::storeRemappingForVFS(configuration, remapping); std::vector args; From 1dd3141e2d1e4559550766c81334572168576f24 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Thu, 30 Jun 2022 08:57:22 +0200 Subject: [PATCH 198/465] Swift: address more code review comments --- swift/extractor/SwiftOutputRewrite.cpp | 18 ++++++++++++++---- swift/extractor/SwiftOutputRewrite.h | 4 +++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/swift/extractor/SwiftOutputRewrite.cpp b/swift/extractor/SwiftOutputRewrite.cpp index 153526f9fde..ff3a860be83 100644 --- a/swift/extractor/SwiftOutputRewrite.cpp +++ b/swift/extractor/SwiftOutputRewrite.cpp @@ -11,7 +11,7 @@ #include #include -// Creates a copy of the output file map and updated remapping table in place +// Creates a copy of the output file map and updates remapping table in place // It does not change the original map file as it is depended upon by the original compiler // Returns path to the newly created output file map on success, or None in a case of failure static std::optional rewriteOutputFileMap( @@ -96,7 +96,12 @@ static std::vector computeModuleAliases(llvm::StringRef modulePath, if (!modulePath.endswith(".swiftmodule")) { return {}; } - + // Deconstructing the Xcode generated path + // + // clang-format off + // intermediatesDirIndex destinationDir (2) arch(5) + // DerivedData/FooBar/Build/Intermediates.noindex/FooBar.build/Debug-iphonesimulator/FooBar.build/Objects-normal/x86_64/FooBar.swiftmodule + // clang-format on llvm::SmallVector chunks; modulePath.split(chunks, '/'); size_t intermediatesDirIndex = 0; @@ -110,9 +115,14 @@ static std::vector computeModuleAliases(llvm::StringRef modulePath, if (intermediatesDirIndex == 0) { return {}; } + size_t destinationDirIndex = intermediatesDirIndex + 2; + size_t archIndex = intermediatesDirIndex + 5; + if (archIndex >= chunks.size()) { + return {}; + } // e.g. Debug-iphoneos, Release-iphonesimulator, etc. - auto destinationDir = chunks[intermediatesDirIndex + 2].str(); - auto arch = chunks[intermediatesDirIndex + 5].str(); + auto destinationDir = chunks[destinationDirIndex].str(); + auto arch = chunks[archIndex].str(); auto moduleNameWithExt = chunks.back(); auto moduleName = moduleNameWithExt.substr(0, moduleNameWithExt.find_last_of('.')); std::string relocatedModulePath = chunks[0].str(); diff --git a/swift/extractor/SwiftOutputRewrite.h b/swift/extractor/SwiftOutputRewrite.h index 03b247bd3dd..b7ee7fa3829 100644 --- a/swift/extractor/SwiftOutputRewrite.h +++ b/swift/extractor/SwiftOutputRewrite.h @@ -17,7 +17,8 @@ std::unordered_map rewriteOutputsInPlace( std::vector& CLIArgs); // Create directories for all the redirected new paths as the Swift compiler expects them to exist. -void ensureDirectoriesForNewPathsExist(const std::unordered_map& remapping); +void ensureDirectoriesForNewPathsExist( + const std::unordered_map& remapping); // Stores remapped `.swiftmoduile`s in a YAML file for later consumption by the // llvm::RedirectingFileSystem via Swift's VFSOverlayFiles. @@ -25,6 +26,7 @@ void storeRemappingForVFS(const SwiftExtractorConfiguration& config, const std::unordered_map& remapping); // Returns a list of VFS YAML files produced by all the extractor processes. +// This is separate from storeRemappingForVFS as we also collect files produced by other processes. std::vector collectVFSFiles(const SwiftExtractorConfiguration& config); } // namespace codeql From 22d285f77766e690f6b52862e013875f1bebd110 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 29 Jun 2022 23:11:10 +0200 Subject: [PATCH 199/465] add model for the gray-matter libary to js/code-injection --- .../2022-06-22-sensitive-common-words copy.md | 4 ++++ .../dataflow/CodeInjectionCustomizations.qll | 5 +++++ .../CodeInjection/UnsafeCodeConstruction.expected | 9 +++++++++ .../Security/CWE-094/CodeInjection/lib/index.js | 14 +++++++++++++- 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words copy.md diff --git a/javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words copy.md b/javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words copy.md new file mode 100644 index 00000000000..8a0151df015 --- /dev/null +++ b/javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words copy.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `gray-matter` library is now modeled as a sink for the `js/code-injection` query. diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll index 69427e12d7b..a500d737b36 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll @@ -51,6 +51,11 @@ module CodeInjection { } } + /** An expression parsed by the `gray-matter` library. */ + class GrayMatterSink extends Sink { + GrayMatterSink() { this = DataFlow::moduleImport("gray-matter").getACall().getArgument(0) } + } + /** * A template tag occurring in JS code, viewed as a code injection sink. */ diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected index dfc86af8cf1..9109bbc239b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected @@ -11,6 +11,10 @@ nodes | lib/index.js:13:38:13:41 | data | | lib/index.js:14:21:14:24 | data | | lib/index.js:14:21:14:24 | data | +| lib/index.js:19:26:19:29 | data | +| lib/index.js:19:26:19:29 | data | +| lib/index.js:22:7:22:10 | data | +| lib/index.js:22:7:22:10 | data | edges | lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | | lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | @@ -24,7 +28,12 @@ edges | lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | | lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | | lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | +| lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | +| lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | +| lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | +| lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | #select | lib/index.js:2:21:2:24 | data | lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | $@ flows to here and is later $@. | lib/index.js:1:35:1:38 | data | Library input | lib/index.js:2:15:2:30 | "(" + data + ")" | interpreted as code | | lib/index.js:6:26:6:29 | name | lib/index.js:5:35:5:38 | name | lib/index.js:6:26:6:29 | name | $@ flows to here and is later $@. | lib/index.js:5:35:5:38 | name | Library input | lib/index.js:6:17:6:29 | "obj." + name | interpreted as code | | lib/index.js:14:21:14:24 | data | lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | $@ flows to here and is later $@. | lib/index.js:13:38:13:41 | data | Library input | lib/index.js:14:15:14:30 | "(" + data + ")" | interpreted as code | +| lib/index.js:22:7:22:10 | data | lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | $@ flows to here and is later $@. | lib/index.js:19:26:19:29 | data | Library input | lib/index.js:25:32:25:34 | str | interpreted as code | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/lib/index.js b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/lib/index.js index b5df26c11d5..764925cae84 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/lib/index.js +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/lib/index.js @@ -12,4 +12,16 @@ export function safeAssignment(obj, value) { global.unsafeDeserialize = function (data) { return eval("(" + data + ")"); // NOT OK -} \ No newline at end of file +} + +const matter = require("gray-matter"); + +export function greySink(data) { + const str = ` + ---js + ${data} + --- + ` + const { content } = matter(str); + console.log(content); +} From f71a64b99d7e80b395b82694d7c02d201432fe0c Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 29 Jun 2022 23:32:41 +0200 Subject: [PATCH 200/465] recognize when the js engine in gray-matter is set to something safe --- .../dataflow/CodeInjectionCustomizations.qll | 9 ++++++++- .../CodeInjection/UnsafeCodeConstruction.expected | 2 +- .../Security/CWE-094/CodeInjection/lib/index.js | 12 ++++++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll index a500d737b36..b691e00e541 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll @@ -53,7 +53,14 @@ module CodeInjection { /** An expression parsed by the `gray-matter` library. */ class GrayMatterSink extends Sink { - GrayMatterSink() { this = DataFlow::moduleImport("gray-matter").getACall().getArgument(0) } + API::CallNode call; + + GrayMatterSink() { + call = DataFlow::moduleImport("gray-matter").getACall() and + this = call.getArgument(0) and + // if the js/javascript engine is set, then we assume they are set to something safe. + not exists(call.getParameter(1).getMember("engines").getMember(["js", "javascript"])) + } } /** diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected index 9109bbc239b..49511750e6f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/UnsafeCodeConstruction.expected @@ -36,4 +36,4 @@ edges | lib/index.js:2:21:2:24 | data | lib/index.js:1:35:1:38 | data | lib/index.js:2:21:2:24 | data | $@ flows to here and is later $@. | lib/index.js:1:35:1:38 | data | Library input | lib/index.js:2:15:2:30 | "(" + data + ")" | interpreted as code | | lib/index.js:6:26:6:29 | name | lib/index.js:5:35:5:38 | name | lib/index.js:6:26:6:29 | name | $@ flows to here and is later $@. | lib/index.js:5:35:5:38 | name | Library input | lib/index.js:6:17:6:29 | "obj." + name | interpreted as code | | lib/index.js:14:21:14:24 | data | lib/index.js:13:38:13:41 | data | lib/index.js:14:21:14:24 | data | $@ flows to here and is later $@. | lib/index.js:13:38:13:41 | data | Library input | lib/index.js:14:15:14:30 | "(" + data + ")" | interpreted as code | -| lib/index.js:22:7:22:10 | data | lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | $@ flows to here and is later $@. | lib/index.js:19:26:19:29 | data | Library input | lib/index.js:25:32:25:34 | str | interpreted as code | +| lib/index.js:22:7:22:10 | data | lib/index.js:19:26:19:29 | data | lib/index.js:22:7:22:10 | data | $@ flows to here and is later $@. | lib/index.js:19:26:19:29 | data | Library input | lib/index.js:25:24:25:26 | str | interpreted as code | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/lib/index.js b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/lib/index.js index 764925cae84..4289ebfc686 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/lib/index.js +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/lib/index.js @@ -22,6 +22,14 @@ export function greySink(data) { ${data} --- ` - const { content } = matter(str); - console.log(content); + const res = matter(str); + console.log(res); + + matter(str, { // OK + engines: { + js: function (data) { + console.log("NOPE"); + } + } + }); } From 11be15aab1c67f44248a4d0bbd6da4c69299b258 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Thu, 30 Jun 2022 08:59:50 +0200 Subject: [PATCH 201/465] inline field into the charpred --- .../dataflow/CodeInjectionCustomizations.qll | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll index b691e00e541..9e72cc9ee82 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/CodeInjectionCustomizations.qll @@ -53,13 +53,13 @@ module CodeInjection { /** An expression parsed by the `gray-matter` library. */ class GrayMatterSink extends Sink { - API::CallNode call; - GrayMatterSink() { - call = DataFlow::moduleImport("gray-matter").getACall() and - this = call.getArgument(0) and - // if the js/javascript engine is set, then we assume they are set to something safe. - not exists(call.getParameter(1).getMember("engines").getMember(["js", "javascript"])) + exists(API::CallNode call | + call = DataFlow::moduleImport("gray-matter").getACall() and + this = call.getArgument(0) and + // if the js/javascript engine is set, then we assume they are set to something safe. + not exists(call.getParameter(1).getMember("engines").getMember(["js", "javascript"])) + ) } } From 6b0e734c470bd086f19cd0f60d495125f5de7a62 Mon Sep 17 00:00:00 2001 From: AlexDenisov Date: Thu, 30 Jun 2022 11:06:03 +0200 Subject: [PATCH 202/465] Update swift/extractor/SwiftOutputRewrite.cpp Co-authored-by: Paolo Tranquilli --- swift/extractor/SwiftOutputRewrite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/extractor/SwiftOutputRewrite.cpp b/swift/extractor/SwiftOutputRewrite.cpp index ff3a860be83..b014b0a9afd 100644 --- a/swift/extractor/SwiftOutputRewrite.cpp +++ b/swift/extractor/SwiftOutputRewrite.cpp @@ -170,7 +170,7 @@ std::unordered_map rewriteOutputsInPlace( std::unordered_map remapping; // TODO: handle filelists? - std::unordered_set pathRewriteOptions({ + const std::unordered_set pathRewriteOptions({ "-emit-dependencies-path", "-emit-module-path", "-emit-module-doc-path", From b5c1ec895896aee35e8cc077fd5467dcd6f89edd Mon Sep 17 00:00:00 2001 From: AlexDenisov Date: Thu, 30 Jun 2022 11:08:23 +0200 Subject: [PATCH 203/465] Update swift/extractor/SwiftOutputRewrite.cpp Co-authored-by: Paolo Tranquilli --- swift/extractor/SwiftOutputRewrite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/extractor/SwiftOutputRewrite.cpp b/swift/extractor/SwiftOutputRewrite.cpp index b014b0a9afd..d1e9fc313ca 100644 --- a/swift/extractor/SwiftOutputRewrite.cpp +++ b/swift/extractor/SwiftOutputRewrite.cpp @@ -225,7 +225,7 @@ std::unordered_map rewriteOutputsInPlace( } // This doesn't really belong here, but we've got Xcode... - for (auto& [oldPath, newPath] : remapping) { + for (const auto& [oldPath, newPath] : remapping) { llvm::StringRef path(oldPath); auto aliases = computeModuleAliases(path, targetTriple); for (auto& alias : aliases) { From 02dd933e5f51932c45893f5fad18dea1c1b53c1f Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 30 Jun 2022 09:32:23 +0100 Subject: [PATCH 204/465] Ruby: move Pathname from core to stdlib --- ruby/ql/lib/codeql/ruby/frameworks/Core.qll | 1 - ruby/ql/lib/codeql/ruby/frameworks/Stdlib.qll | 1 + .../ql/lib/codeql/ruby/frameworks/{core => stdlib}/Pathname.qll | 0 ruby/ql/test/library-tests/frameworks/pathname/Pathname.ql | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename ruby/ql/lib/codeql/ruby/frameworks/{core => stdlib}/Pathname.qll (100%) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Core.qll b/ruby/ql/lib/codeql/ruby/frameworks/Core.qll index b428029c829..1ef6d8d65e5 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Core.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Core.qll @@ -14,7 +14,6 @@ import core.Hash import core.String import core.Regexp import core.IO -import core.Pathname /** * A system command executed via subshell literal syntax. diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Stdlib.qll b/ruby/ql/lib/codeql/ruby/frameworks/Stdlib.qll index 11c993b1170..f735f9daf8b 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Stdlib.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Stdlib.qll @@ -4,3 +4,4 @@ import stdlib.Open3 import stdlib.Logger +import stdlib.Pathname diff --git a/ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll similarity index 100% rename from ruby/ql/lib/codeql/ruby/frameworks/core/Pathname.qll rename to ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll diff --git a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.ql b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.ql index d624cff3aa3..71150ae5376 100644 --- a/ruby/ql/test/library-tests/frameworks/pathname/Pathname.ql +++ b/ruby/ql/test/library-tests/frameworks/pathname/Pathname.ql @@ -1,7 +1,7 @@ private import ruby private import codeql.ruby.Concepts private import codeql.ruby.DataFlow -private import codeql.ruby.frameworks.core.Pathname +private import codeql.ruby.frameworks.stdlib.Pathname query predicate pathnameInstances(Pathname::PathnameInstance i) { any() } From d42b752c6d8773bbf4dc723b199312b04409f6c3 Mon Sep 17 00:00:00 2001 From: AlexDenisov Date: Thu, 30 Jun 2022 11:10:43 +0200 Subject: [PATCH 205/465] Apply suggestions from code review Co-authored-by: Paolo Tranquilli --- swift/extractor/SwiftOutputRewrite.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swift/extractor/SwiftOutputRewrite.cpp b/swift/extractor/SwiftOutputRewrite.cpp index d1e9fc313ca..978f8417f81 100644 --- a/swift/extractor/SwiftOutputRewrite.cpp +++ b/swift/extractor/SwiftOutputRewrite.cpp @@ -251,9 +251,9 @@ void storeRemappingForVFS(const SwiftExtractorConfiguration& config, const std::unordered_map& remapping) { // Only create remapping for the .swiftmodule files std::unordered_map modules; - for (auto& [oldPath, newPath] : remapping) { + for (const auto& [oldPath, newPath] : remapping) { if (llvm::StringRef(oldPath).endswith(".swiftmodule")) { - modules[oldPath] = newPath; + modules.emplace(oldPath, newPath); } } From 2d98eb591eb173781790ac2ccd9b4c45987f0f1f Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 24 Jun 2022 11:33:18 +0100 Subject: [PATCH 206/465] Kotlin: note that raw inner classes nest within a raw outer. Previously the Java extractor did this but the Kotlin extractor nested them within an unbound outer type. --- .../src/main/kotlin/KotlinFileExtractor.kt | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index b82b71faccf..147df667ddf 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -6,6 +6,7 @@ import com.github.codeql.utils.versions.functionN import com.github.codeql.utils.versions.getIrStubFromDescriptor import com.semmle.extractor.java.OdasaOutput import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext +import org.jetbrains.kotlin.backend.common.lower.parents import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity import org.jetbrains.kotlin.descriptors.* @@ -314,8 +315,21 @@ open class KotlinFileExtractor( val locId = getLocation(c, argsIncludingOuterClasses) tw.writeHasLocation(id, locId) - // Extract the outer <-> inner class relationship, passing on any type arguments in excess to this class' parameters. - extractEnclosingClass(c, id, locId, argsIncludingOuterClasses?.drop(c.typeParameters.size) ?: listOf()) + // Extract the outer <-> inner class relationship, passing on any type arguments in excess to this class' parameters if this is an inner class. + // For example, in `class Outer { inner class Inner { } }`, `Inner` nests within `Outer` and raw `Inner<>` within `Outer<>`, + // but for a similar non-`inner` (in Java terms, static nested) class both `Inner` and `Inner<>` nest within the unbound type `Outer`. + val useBoundOuterType = (c.isInner || c.isLocal) && (c.parents.firstNotNullOfOrNull { + when(it) { + is IrClass -> when { + it.typeParameters.isNotEmpty() -> true // Type parameters visible to this class -- extract an enclosing bound or raw type. + !(it.isInner || it.isLocal) -> false // No type parameters seen yet, and this is a static class -- extract an enclosing unbound type. + else -> null // No type parameters seen here, but may be visible enclosing type parameters; keep searching. + } + else -> null // Look through enclosing non-class entities (this may need to change) + } + } ?: false) + + extractEnclosingClass(c, id, locId, if (useBoundOuterType) argsIncludingOuterClasses?.drop(c.typeParameters.size) else listOf()) return id } @@ -458,7 +472,8 @@ open class KotlinFileExtractor( } } - private fun extractEnclosingClass(innerDeclaration: IrDeclaration, innerId: Label, innerLocId: Label, parentClassTypeArguments: List) { + // If `parentClassTypeArguments` is null, the parent class is a raw type. + private fun extractEnclosingClass(innerDeclaration: IrDeclaration, innerId: Label, innerLocId: Label, parentClassTypeArguments: List?) { with("enclosing class", innerDeclaration) { var parent: IrDeclarationParent? = innerDeclaration.parent while (parent != null) { From 8e5bbea9f96b94bc2eb46b3ab862fdf5f9da2a63 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 24 Jun 2022 14:22:45 +0100 Subject: [PATCH 207/465] Use map...firstOrNull not firstNotNullOfOrNull The latter was introduced in Kotlin 1.5, so we can't use it in all supported versions. --- java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 147df667ddf..a0e3004985a 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -318,7 +318,7 @@ open class KotlinFileExtractor( // Extract the outer <-> inner class relationship, passing on any type arguments in excess to this class' parameters if this is an inner class. // For example, in `class Outer { inner class Inner { } }`, `Inner` nests within `Outer` and raw `Inner<>` within `Outer<>`, // but for a similar non-`inner` (in Java terms, static nested) class both `Inner` and `Inner<>` nest within the unbound type `Outer`. - val useBoundOuterType = (c.isInner || c.isLocal) && (c.parents.firstNotNullOfOrNull { + val useBoundOuterType = (c.isInner || c.isLocal) && (c.parents.map { // Would use `firstNotNullOfOrNull`, but this doesn't exist in Kotlin 1.4 when(it) { is IrClass -> when { it.typeParameters.isNotEmpty() -> true // Type parameters visible to this class -- extract an enclosing bound or raw type. @@ -327,7 +327,7 @@ open class KotlinFileExtractor( } else -> null // Look through enclosing non-class entities (this may need to change) } - } ?: false) + }.firstOrNull { it != null } ?: false) extractEnclosingClass(c, id, locId, if (useBoundOuterType) argsIncludingOuterClasses?.drop(c.typeParameters.size) else listOf()) From ab52a020fa6760cb0acf3aa56de9a6082f0cabca Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 30 Jun 2022 10:22:56 +0100 Subject: [PATCH 208/465] Add test --- .../kotlin/nested_generic_types/JavaUser.java | 9 ++ .../kotlin/nested_generic_types/KotlinUser.kt | 9 ++ .../libsrc/extlib/OuterGeneric.java | 2 + .../libsrc/extlib/OuterNotGeneric.java | 6 + .../libsrc/extlib/TypeParamVisibility.java | 29 +++++ .../kotlin/nested_generic_types/test.expected | 103 ++++++++++++++++++ 6 files changed, 158 insertions(+) create mode 100644 java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/TypeParamVisibility.java diff --git a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/JavaUser.java b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/JavaUser.java index 3c79f5828c8..f54b65bde92 100644 --- a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/JavaUser.java +++ b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/JavaUser.java @@ -21,6 +21,15 @@ public class JavaUser { String result4 = d.identity("goodbye"); Short result5 = e.returnSixth(1, "hello", 1.0f, 1.0, 1L, (short)1); + OuterGeneric.InnerNotGeneric innerGetterTest = (new OuterGeneric()).getInnerNotGeneric(); + OuterNotGeneric.InnerGeneric innerGetterTest2 = (new OuterNotGeneric()).getInnerGeneric(); + + TypeParamVisibility tpv = new TypeParamVisibility(); + TypeParamVisibility.VisibleBecauseInner visibleBecauseInner = tpv.getVisibleBecauseInner(); + TypeParamVisibility.VisibleBecauseInnerIndirectContainer.VisibleBecauseInnerIndirect visibleBecauseInnerIndirect = tpv.getVisibleBecauseInnerIndirect(); + TypeParamVisibility.NotVisibleBecauseStatic notVisibleBecauseStatic = tpv.getNotVisibleBecauseStatic(); + TypeParamVisibility.NotVisibleBecauseStaticIndirectContainer.NotVisibleBecauseStaticIndirect notVisibleBecauseStaticIndirect = tpv.getNotVisibleBecauseStaticIndirect(); + } } diff --git a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/KotlinUser.kt b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/KotlinUser.kt index 01102e86881..44474b84619 100644 --- a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/KotlinUser.kt +++ b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/KotlinUser.kt @@ -22,6 +22,15 @@ class User { val result4 = d.identity("goodbye") val result5 = e.returnSixth(1, "hello", 1.0f, 1.0, 1L, 1.toShort()) + val innerGetterTest = OuterGeneric().getInnerNotGeneric() + val innerGetterTest2 = OuterNotGeneric().getInnerGeneric() + + val tpv = TypeParamVisibility() + val visibleBecauseInner = tpv.getVisibleBecauseInner(); + val visibleBecauseInnerIndirect = tpv.getVisibleBecauseInnerIndirect() + val notVisibleBecauseStatic = tpv.getNotVisibleBecauseStatic() + val notVisibleBecauseStaticIndirect = tpv.getNotVisibleBecauseStaticIndirect() + } } diff --git a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterGeneric.java b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterGeneric.java index 36706f2cd42..b98950ad6dc 100644 --- a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterGeneric.java +++ b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterGeneric.java @@ -8,6 +8,8 @@ public class OuterGeneric { } + public InnerNotGeneric getInnerNotGeneric() { return null; } + public class InnerGeneric { public InnerGeneric(R r) { } diff --git a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterNotGeneric.java b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterNotGeneric.java index 8f998968960..68a0f62d768 100644 --- a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterNotGeneric.java +++ b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/OuterNotGeneric.java @@ -8,4 +8,10 @@ public class OuterNotGeneric { } + public InnerGeneric getInnerGeneric() { + + return new InnerGeneric(); + + } + } diff --git a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/TypeParamVisibility.java b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/TypeParamVisibility.java new file mode 100644 index 00000000000..1ac6d4892e3 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/libsrc/extlib/TypeParamVisibility.java @@ -0,0 +1,29 @@ +package extlib; + +public class TypeParamVisibility { + + public class VisibleBecauseInner { } + + public class VisibleBecauseInnerIndirectContainer { + + public class VisibleBecauseInnerIndirect { } + + } + + public static class NotVisibleBecauseStatic { } + + public static class NotVisibleBecauseStaticIndirectContainer { + + public class NotVisibleBecauseStaticIndirect { } + + } + + public VisibleBecauseInner getVisibleBecauseInner() { return new VisibleBecauseInner(); } + + public VisibleBecauseInnerIndirectContainer.VisibleBecauseInnerIndirect getVisibleBecauseInnerIndirect() { return (new VisibleBecauseInnerIndirectContainer()).new VisibleBecauseInnerIndirect(); } + + public NotVisibleBecauseStatic getNotVisibleBecauseStatic() { return new NotVisibleBecauseStatic(); } + + public NotVisibleBecauseStaticIndirectContainer.NotVisibleBecauseStaticIndirect getNotVisibleBecauseStaticIndirect() { return (new NotVisibleBecauseStaticIndirectContainer()).new NotVisibleBecauseStaticIndirect(); } + +} diff --git a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/test.expected b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/test.expected index e7c0acaa8f6..1c37ebd0eff 100644 --- a/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/test.expected +++ b/java/ql/integration-tests/posix-only/kotlin/nested_generic_types/test.expected @@ -59,6 +59,15 @@ callArgs | JavaUser.java:22:21:22:70 | returnSixth(...) | JavaUser.java:22:53:22:55 | 1.0 | 3 | | JavaUser.java:22:21:22:70 | returnSixth(...) | JavaUser.java:22:58:22:59 | 1L | 4 | | JavaUser.java:22:21:22:70 | returnSixth(...) | JavaUser.java:22:62:22:69 | (...)... | 5 | +| JavaUser.java:24:60:24:108 | getInnerNotGeneric(...) | JavaUser.java:24:61:24:86 | new OuterGeneric(...) | -1 | +| JavaUser.java:24:61:24:86 | new OuterGeneric(...) | JavaUser.java:24:65:24:84 | OuterGeneric | -3 | +| JavaUser.java:25:61:25:101 | getInnerGeneric(...) | JavaUser.java:25:62:25:82 | new OuterNotGeneric(...) | -1 | +| JavaUser.java:25:62:25:82 | new OuterNotGeneric(...) | JavaUser.java:25:66:25:80 | OuterNotGeneric | -3 | +| JavaUser.java:27:39:27:71 | new TypeParamVisibility(...) | JavaUser.java:27:43:27:69 | TypeParamVisibility | -3 | +| JavaUser.java:28:83:28:110 | getVisibleBecauseInner(...) | JavaUser.java:28:83:28:85 | tpv | -1 | +| JavaUser.java:29:136:29:171 | getVisibleBecauseInnerIndirect(...) | JavaUser.java:29:136:29:138 | tpv | -1 | +| JavaUser.java:30:83:30:114 | getNotVisibleBecauseStatic(...) | JavaUser.java:30:83:30:85 | tpv | -1 | +| JavaUser.java:31:140:31:179 | getNotVisibleBecauseStaticIndirect(...) | JavaUser.java:31:140:31:142 | tpv | -1 | | KotlinUser.kt:9:13:9:31 | new OuterGeneric(...) | KotlinUser.kt:9:13:9:31 | OuterGeneric | -3 | | KotlinUser.kt:9:33:9:63 | new InnerGeneric(...) | KotlinUser.kt:9:13:9:31 | new OuterGeneric(...) | -2 | | KotlinUser.kt:9:33:9:63 | new InnerGeneric(...) | KotlinUser.kt:9:33:9:63 | InnerGeneric | -3 | @@ -116,6 +125,15 @@ callArgs | KotlinUser.kt:23:21:23:71 | returnSixth(...) | KotlinUser.kt:23:56:23:57 | 1 | 4 | | KotlinUser.kt:23:21:23:71 | returnSixth(...) | KotlinUser.kt:23:62:23:70 | shortValue(...) | 5 | | KotlinUser.kt:23:62:23:70 | shortValue(...) | KotlinUser.kt:23:60:23:60 | 1 | -1 | +| KotlinUser.kt:25:27:25:48 | new OuterGeneric(...) | KotlinUser.kt:25:27:25:48 | OuterGeneric | -3 | +| KotlinUser.kt:25:50:25:69 | getInnerNotGeneric(...) | KotlinUser.kt:25:27:25:48 | new OuterGeneric(...) | -1 | +| KotlinUser.kt:26:28:26:44 | new OuterNotGeneric(...) | KotlinUser.kt:26:28:26:44 | OuterNotGeneric | -3 | +| KotlinUser.kt:26:46:26:62 | getInnerGeneric(...) | KotlinUser.kt:26:28:26:44 | new OuterNotGeneric(...) | -1 | +| KotlinUser.kt:28:15:28:43 | new TypeParamVisibility(...) | KotlinUser.kt:28:15:28:43 | TypeParamVisibility | -3 | +| KotlinUser.kt:29:35:29:58 | getVisibleBecauseInner(...) | KotlinUser.kt:29:31:29:33 | tpv | -1 | +| KotlinUser.kt:30:43:30:74 | getVisibleBecauseInnerIndirect(...) | KotlinUser.kt:30:39:30:41 | tpv | -1 | +| KotlinUser.kt:31:39:31:66 | getNotVisibleBecauseStatic(...) | KotlinUser.kt:31:35:31:37 | tpv | -1 | +| KotlinUser.kt:32:47:32:82 | getNotVisibleBecauseStaticIndirect(...) | KotlinUser.kt:32:43:32:45 | tpv | -1 | genericTypes | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | S | | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | S | @@ -127,6 +145,11 @@ genericTypes | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | A | | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | B | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | S | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | S | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | S | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | S | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | S | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | T | paramTypes | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | S | | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | String | @@ -149,6 +172,18 @@ paramTypes | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | String | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | S | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | String | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | S | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | String | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | S | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | String | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | S | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | String | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | String | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | S | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | String | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | String | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | T | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | String | constructors | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | InnerGeneric(java.lang.Object) | | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | InnerGeneric(java.lang.Object,java.lang.Object) | @@ -171,6 +206,14 @@ constructors | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | InnerGeneric() | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | InnerGeneric() | | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | OuterNotGeneric() | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | NotVisibleBecauseStatic() | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | NotVisibleBecauseStaticIndirect() | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer.class:0:0:0:0 | NotVisibleBecauseStaticIndirectContainer | NotVisibleBecauseStaticIndirectContainer() | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | VisibleBecauseInner() | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | VisibleBecauseInnerIndirect() | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer | VisibleBecauseInnerIndirectContainer() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | TypeParamVisibility() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | TypeParamVisibility() | methods | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | returnsecond | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | returnsecond(java.lang.Object,java.lang.Object) | | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | returnsecond | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | returnsecond(java.lang.Object,java.lang.Object,java.lang.Object) | @@ -181,14 +224,27 @@ methods | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | identity | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | identity(java.lang.String) | | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | identity | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | identity(java.lang.Object) | | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | identity | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | identity(java.lang.String) | +| extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | getInnerNotGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | getInnerNotGeneric() | +| extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | getInnerNotGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | getInnerNotGeneric() | +| extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | getInnerNotGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | getInnerNotGeneric() | | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | returnSixth | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | returnSixth(java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object) | | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | returnSixth | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | returnSixth(java.lang.Integer,java.lang.String,java.lang.Float,java.lang.Double,java.lang.Long,java.lang.Short) | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | identity | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | identity(java.lang.Object) | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | identity | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | identity(java.lang.String) | +| extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | getInnerGeneric | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | getInnerGeneric() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getNotVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getNotVisibleBecauseStatic() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getNotVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getNotVisibleBecauseStatic() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getNotVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getNotVisibleBecauseStaticIndirect() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getNotVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getNotVisibleBecauseStaticIndirect() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getVisibleBecauseInner | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getVisibleBecauseInner() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getVisibleBecauseInner | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getVisibleBecauseInner() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getVisibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getVisibleBecauseInnerIndirect() | +| extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getVisibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | getVisibleBecauseInnerIndirect() | nestedTypes | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | +| extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric<> | | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | @@ -198,7 +254,26 @@ nestedTypes | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | +| extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric<> | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic<> | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer.class:0:0:0:0 | NotVisibleBecauseStaticIndirectContainer | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect<> | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer.class:0:0:0:0 | NotVisibleBecauseStaticIndirectContainer | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer.class:0:0:0:0 | NotVisibleBecauseStaticIndirectContainer | +| extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer.class:0:0:0:0 | NotVisibleBecauseStaticIndirectContainer | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner<> | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility<> | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect<> | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer<> | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer<> | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer<> | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility<> | +| extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer.class:0:0:0:0 | VisibleBecauseInnerIndirectContainer<> | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | javaKotlinCalleeAgreement | JavaUser.java:16:22:16:47 | returnsecond(...) | KotlinUser.kt:17:21:17:44 | returnsecond(...) | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | returnsecond | | JavaUser.java:17:23:17:53 | returnsecond(...) | KotlinUser.kt:18:22:18:50 | returnsecond(...) | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | returnsecond | @@ -207,6 +282,12 @@ javaKotlinCalleeAgreement | JavaUser.java:20:22:20:40 | identity(...) | KotlinUser.kt:21:21:21:37 | identity(...) | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | identity | | JavaUser.java:21:22:21:42 | identity(...) | KotlinUser.kt:22:21:22:39 | identity(...) | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | identity | | JavaUser.java:22:21:22:70 | returnSixth(...) | KotlinUser.kt:23:21:23:71 | returnSixth(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | returnSixth | +| JavaUser.java:24:60:24:108 | getInnerNotGeneric(...) | KotlinUser.kt:25:50:25:69 | getInnerNotGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | getInnerNotGeneric | +| JavaUser.java:25:61:25:101 | getInnerGeneric(...) | KotlinUser.kt:26:46:26:62 | getInnerGeneric(...) | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | getInnerGeneric | +| JavaUser.java:28:83:28:110 | getVisibleBecauseInner(...) | KotlinUser.kt:29:35:29:58 | getVisibleBecauseInner(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getVisibleBecauseInner | +| JavaUser.java:29:136:29:171 | getVisibleBecauseInnerIndirect(...) | KotlinUser.kt:30:43:30:74 | getVisibleBecauseInnerIndirect(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getVisibleBecauseInnerIndirect | +| JavaUser.java:30:83:30:114 | getNotVisibleBecauseStatic(...) | KotlinUser.kt:31:39:31:66 | getNotVisibleBecauseStatic(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getNotVisibleBecauseStatic | +| JavaUser.java:31:140:31:179 | getNotVisibleBecauseStaticIndirect(...) | KotlinUser.kt:32:47:32:82 | getNotVisibleBecauseStaticIndirect(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | getNotVisibleBecauseStaticIndirect | javaKotlinConstructorAgreement | JavaUser.java:7:52:7:110 | new InnerGeneric(...) | KotlinUser.kt:9:33:9:63 | new InnerGeneric(...) | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | | JavaUser.java:7:53:7:79 | new OuterGeneric(...) | KotlinUser.kt:9:13:9:31 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | @@ -224,12 +305,19 @@ javaKotlinConstructorAgreement | JavaUser.java:10:48:10:74 | new OuterGeneric(...) | KotlinUser.kt:10:14:10:32 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | JavaUser.java:10:48:10:74 | new OuterGeneric(...) | KotlinUser.kt:11:13:11:31 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | JavaUser.java:11:48:11:73 | new OuterGeneric(...) | KotlinUser.kt:12:14:12:35 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | +| JavaUser.java:11:48:11:73 | new OuterGeneric(...) | KotlinUser.kt:25:27:25:48 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | | JavaUser.java:12:46:12:95 | new InnerGeneric(...) | KotlinUser.kt:13:31:13:52 | new InnerGeneric(...) | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | | JavaUser.java:12:47:12:67 | new OuterNotGeneric(...) | KotlinUser.kt:13:13:13:29 | new OuterNotGeneric(...) | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | +| JavaUser.java:12:47:12:67 | new OuterNotGeneric(...) | KotlinUser.kt:26:28:26:44 | new OuterNotGeneric(...) | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | | JavaUser.java:13:49:13:111 | new InnerStaticGeneric(...) | KotlinUser.kt:14:26:14:63 | new InnerStaticGeneric(...) | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | | JavaUser.java:14:103:14:248 | new InnerManyParams(...) | KotlinUser.kt:15:69:15:100 | new InnerManyParams(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | | JavaUser.java:14:104:14:200 | new MiddleManyParams(...) | KotlinUser.kt:15:41:15:67 | new MiddleManyParams(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | | JavaUser.java:14:105:14:152 | new OuterManyParams(...) | KotlinUser.kt:15:13:15:39 | new OuterManyParams(...) | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | +| JavaUser.java:24:61:24:86 | new OuterGeneric(...) | KotlinUser.kt:12:14:12:35 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | +| JavaUser.java:24:61:24:86 | new OuterGeneric(...) | KotlinUser.kt:25:27:25:48 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | +| JavaUser.java:25:62:25:82 | new OuterNotGeneric(...) | KotlinUser.kt:13:13:13:29 | new OuterNotGeneric(...) | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | +| JavaUser.java:25:62:25:82 | new OuterNotGeneric(...) | KotlinUser.kt:26:28:26:44 | new OuterNotGeneric(...) | extlib.jar/extlib/OuterNotGeneric.class:0:0:0:0 | OuterNotGeneric | +| JavaUser.java:27:39:27:71 | new TypeParamVisibility(...) | KotlinUser.kt:28:15:28:43 | new TypeParamVisibility(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | javaKotlinLocalTypeAgreement | JavaUser.java:7:5:7:111 | InnerGeneric a | KotlinUser.kt:9:5:9:63 | InnerGeneric a | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | | JavaUser.java:7:5:7:111 | InnerGeneric a | KotlinUser.kt:10:5:10:65 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | @@ -239,9 +327,20 @@ javaKotlinLocalTypeAgreement | JavaUser.java:9:5:9:139 | InnerGeneric a3 | KotlinUser.kt:10:5:10:65 | InnerGeneric a2 | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | | JavaUser.java:10:5:10:98 | InnerNotGeneric<> b | KotlinUser.kt:11:5:11:49 | InnerNotGeneric<> b | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | | JavaUser.java:11:5:11:97 | InnerNotGeneric<> b2 | KotlinUser.kt:12:5:12:53 | InnerNotGeneric<> b2 | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | +| JavaUser.java:11:5:11:97 | InnerNotGeneric<> b2 | KotlinUser.kt:25:5:25:69 | InnerNotGeneric<> innerGetterTest | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | | JavaUser.java:12:5:12:96 | InnerGeneric c | KotlinUser.kt:13:5:13:52 | InnerGeneric c | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:12:5:12:96 | InnerGeneric c | KotlinUser.kt:26:5:26:62 | InnerGeneric innerGetterTest2 | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | | JavaUser.java:13:5:13:112 | InnerStaticGeneric d | KotlinUser.kt:14:5:14:63 | InnerStaticGeneric d | extlib.jar/extlib/OuterGeneric$InnerStaticGeneric.class:0:0:0:0 | InnerStaticGeneric | | JavaUser.java:14:5:14:249 | InnerManyParams e | KotlinUser.kt:15:5:15:100 | InnerManyParams e | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | +| JavaUser.java:24:5:24:109 | InnerNotGeneric<> innerGetterTest | KotlinUser.kt:12:5:12:53 | InnerNotGeneric<> b2 | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | +| JavaUser.java:24:5:24:109 | InnerNotGeneric<> innerGetterTest | KotlinUser.kt:25:5:25:69 | InnerNotGeneric<> innerGetterTest | extlib.jar/extlib/OuterGeneric$InnerNotGeneric.class:0:0:0:0 | InnerNotGeneric<> | +| JavaUser.java:25:5:25:102 | InnerGeneric innerGetterTest2 | KotlinUser.kt:13:5:13:52 | InnerGeneric c | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:25:5:25:102 | InnerGeneric innerGetterTest2 | KotlinUser.kt:26:5:26:62 | InnerGeneric innerGetterTest2 | extlib.jar/extlib/OuterNotGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | +| JavaUser.java:27:5:27:72 | TypeParamVisibility tpv | KotlinUser.kt:28:5:28:43 | TypeParamVisibility tpv | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | +| JavaUser.java:28:5:28:111 | VisibleBecauseInner visibleBecauseInner | KotlinUser.kt:29:5:29:58 | VisibleBecauseInner visibleBecauseInner | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInner.class:0:0:0:0 | VisibleBecauseInner | +| JavaUser.java:29:5:29:172 | VisibleBecauseInnerIndirect visibleBecauseInnerIndirect | KotlinUser.kt:30:5:30:74 | VisibleBecauseInnerIndirect visibleBecauseInnerIndirect | extlib.jar/extlib/TypeParamVisibility$VisibleBecauseInnerIndirectContainer$VisibleBecauseInnerIndirect.class:0:0:0:0 | VisibleBecauseInnerIndirect | +| JavaUser.java:30:5:30:115 | NotVisibleBecauseStatic notVisibleBecauseStatic | KotlinUser.kt:31:5:31:66 | NotVisibleBecauseStatic notVisibleBecauseStatic | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStatic.class:0:0:0:0 | NotVisibleBecauseStatic | +| JavaUser.java:31:5:31:180 | NotVisibleBecauseStaticIndirect notVisibleBecauseStaticIndirect | KotlinUser.kt:32:5:32:82 | NotVisibleBecauseStaticIndirect notVisibleBecauseStaticIndirect | extlib.jar/extlib/TypeParamVisibility$NotVisibleBecauseStaticIndirectContainer$NotVisibleBecauseStaticIndirect.class:0:0:0:0 | NotVisibleBecauseStaticIndirect | #select | JavaUser.java:7:52:7:110 | new InnerGeneric(...) | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | JavaUser.java:7:99:7:104 | String | | JavaUser.java:7:53:7:79 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | JavaUser.java:7:70:7:76 | Integer | @@ -259,6 +358,8 @@ javaKotlinLocalTypeAgreement | JavaUser.java:14:104:14:200 | new MiddleManyParams(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | JavaUser.java:14:183:14:188 | Double | | JavaUser.java:14:105:14:152 | new OuterManyParams(...) | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | JavaUser.java:14:125:14:131 | Integer | | JavaUser.java:14:105:14:152 | new OuterManyParams(...) | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | extlib.jar/extlib/OuterManyParams.class:0:0:0:0 | OuterManyParams | JavaUser.java:14:134:14:139 | String | +| JavaUser.java:24:61:24:86 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | JavaUser.java:24:78:24:83 | String | +| JavaUser.java:27:39:27:71 | new TypeParamVisibility(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | JavaUser.java:27:63:27:68 | String | | KotlinUser.kt:9:13:9:31 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | KotlinUser.kt:9:13:9:31 | Integer | | KotlinUser.kt:9:33:9:63 | new InnerGeneric(...) | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | extlib.jar/extlib/OuterGeneric$InnerGeneric.class:0:0:0:0 | InnerGeneric | KotlinUser.kt:9:33:9:63 | String | | KotlinUser.kt:10:14:10:32 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | KotlinUser.kt:10:14:10:32 | Integer | @@ -273,3 +374,5 @@ javaKotlinLocalTypeAgreement | KotlinUser.kt:15:41:15:67 | new MiddleManyParams(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | extlib.jar/extlib/OuterManyParams$MiddleManyParams.class:0:0:0:0 | MiddleManyParams | KotlinUser.kt:15:41:15:67 | Float | | KotlinUser.kt:15:69:15:100 | new InnerManyParams(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | KotlinUser.kt:15:69:15:100 | Long | | KotlinUser.kt:15:69:15:100 | new InnerManyParams(...) | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | extlib.jar/extlib/OuterManyParams$MiddleManyParams$InnerManyParams.class:0:0:0:0 | InnerManyParams | KotlinUser.kt:15:69:15:100 | Short | +| KotlinUser.kt:25:27:25:48 | new OuterGeneric(...) | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | extlib.jar/extlib/OuterGeneric.class:0:0:0:0 | OuterGeneric | KotlinUser.kt:25:27:25:48 | String | +| KotlinUser.kt:28:15:28:43 | new TypeParamVisibility(...) | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | extlib.jar/extlib/TypeParamVisibility.class:0:0:0:0 | TypeParamVisibility | KotlinUser.kt:28:15:28:43 | String | From 133a6caaa386f17770f3b202d45fda55c787ed8a Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Thu, 30 Jun 2022 12:03:53 +0200 Subject: [PATCH 209/465] Swift: cleanup output rewriting code --- swift/extractor/SwiftExtractor.cpp | 2 +- swift/extractor/SwiftExtractorConfiguration.h | 31 +++++----- swift/extractor/SwiftOutputRewrite.cpp | 60 +++++++++---------- swift/extractor/main.cpp | 5 -- 4 files changed, 45 insertions(+), 53 deletions(-) diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 175975be8ed..91d25ce9c1b 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -76,7 +76,7 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, auto name = getTrapFilename(module, primaryFile); llvm::StringRef filename(name); std::string tempTrapName = filename.str() + '.' + std::to_string(getpid()) + ".trap"; - llvm::SmallString tempTrapPath(config.tempTrapDir); + llvm::SmallString tempTrapPath(config.getTempTrapDir()); llvm::sys::path::append(tempTrapPath, tempTrapName); llvm::StringRef tempTrapParent = llvm::sys::path::parent_path(tempTrapPath); diff --git a/swift/extractor/SwiftExtractorConfiguration.h b/swift/extractor/SwiftExtractorConfiguration.h index 230ee661ac2..3365da5f268 100644 --- a/swift/extractor/SwiftExtractorConfiguration.h +++ b/swift/extractor/SwiftExtractorConfiguration.h @@ -12,26 +12,25 @@ struct SwiftExtractorConfiguration { // A temporary directory that exists during database creation, but is deleted once the DB is // finalized. std::string scratchDir; - // A temporary directory that contains TRAP files before they are moved into their final destination. - // Subdirectory of the scratchDir. - std::string tempTrapDir; - - // VFS (virtual file system) support. - // A temporary directory that contains VFS files used during extraction. - // Subdirectory of the scratchDir. - std::string VFSDir; - // A temporary directory that contains temp VFS files before they moved into VFSDir. - // Subdirectory of the scratchDir. - std::string tempVFSDir; - - // A temporary directory that contains build artifacts generated by the extractor during the - // overall extraction process. - // Subdirectory of the scratchDir. - std::string tempArtifactDir; // The original arguments passed to the extractor. Used for debugging. std::vector frontendOptions; // The patched arguments passed to the swift::performFrontend/ Used for debugging. std::vector patchedFrontendOptions; + + // A temporary directory that contains TRAP files before they are moved into their final + // destination. + std::string getTempTrapDir() const { return scratchDir + "/swift-trap-temp"; } + + // VFS (virtual file system) support. + // A temporary directory that contains VFS files used during extraction. + std::string getVFSDir() const { return scratchDir + "/swift-vfs"; } + + // A temporary directory that contains temp VFS files before they moved into VFSDir. + std::string getTempVFSDir() const { return scratchDir + "/swift-vfs-temp"; } + + // A temporary directory that contains build artifacts generated by the extractor during the + // overall extraction process. + std::string getTempArtifactDir() const { return scratchDir + "/swift-extraction-artifacts"; } }; } // namespace codeql diff --git a/swift/extractor/SwiftOutputRewrite.cpp b/swift/extractor/SwiftOutputRewrite.cpp index 978f8417f81..35a38512ff8 100644 --- a/swift/extractor/SwiftOutputRewrite.cpp +++ b/swift/extractor/SwiftOutputRewrite.cpp @@ -19,11 +19,12 @@ static std::optional rewriteOutputFileMap( const std::string& outputFileMapPath, const std::vector& inputs, std::unordered_map& remapping) { - auto newPath = config.tempArtifactDir + '/' + outputFileMapPath; + auto newMapPath = config.getTempArtifactDir() + '/' + outputFileMapPath; // TODO: do not assume absolute path for the second parameter auto outputMapOrError = swift::OutputFileMap::loadFromPath(outputFileMapPath, ""); if (!outputMapOrError) { + std::cerr << "Cannot load output map: '" << outputFileMapPath << "'\n"; return std::nullopt; } auto oldOutputMap = outputMapOrError.get(); @@ -39,13 +40,13 @@ static std::optional rewriteOutputFileMap( newMap.copyFrom(*oldMap); for (auto& entry : newMap) { auto oldPath = entry.getSecond(); - auto newPath = config.tempArtifactDir + '/' + oldPath; + auto newPath = config.getTempArtifactDir() + '/' + oldPath; entry.getSecond() = newPath; remapping[oldPath] = newPath; } } std::error_code ec; - llvm::SmallString filepath(newPath); + llvm::SmallString filepath(newMapPath); llvm::StringRef parent = llvm::sys::path::parent_path(filepath); if (std::error_code ec = llvm::sys::fs::create_directories(parent)) { std::cerr << "Cannot create relocated output map dir: '" << parent.str() @@ -53,9 +54,9 @@ static std::optional rewriteOutputFileMap( return std::nullopt; } - llvm::raw_fd_ostream fd(newPath, ec, llvm::sys::fs::OF_None); + llvm::raw_fd_ostream fd(newMapPath, ec, llvm::sys::fs::OF_None); newOutputMap.write(fd, keys); - return newPath; + return newMapPath; } // This is an Xcode-specific workaround to produce alias names for an existing .swiftmodule file. @@ -132,30 +133,27 @@ static std::vector computeModuleAliases(llvm::StringRef modulePath, relocatedModulePath += "/Products/"; relocatedModulePath += destinationDir + '/'; - std::vector moduleLocations; + // clang-format off + std::vector moduleLocations = { + // First case + relocatedModulePath + moduleNameWithExt.str() + '/', + // Second case + relocatedModulePath + moduleName.str() + '/' + moduleNameWithExt.str() + '/', + // Third case + relocatedModulePath + moduleName.str() + '/' + moduleName.str() + ".framework/Modules/" + moduleNameWithExt.str() + '/', + }; + // clang-format on - std::string firstCase = relocatedModulePath; - firstCase += moduleNameWithExt.str() + '/'; - moduleLocations.push_back(firstCase); - - std::string secondCase = relocatedModulePath; - secondCase += moduleName.str() + '/'; - secondCase += moduleNameWithExt.str() + '/'; - moduleLocations.push_back(secondCase); - - std::string thirdCase = relocatedModulePath; - thirdCase += moduleName.str() + '/'; - thirdCase += moduleName.str() + ".framework/Modules/"; - thirdCase += moduleNameWithExt.str() + '/'; - moduleLocations.push_back(thirdCase); + std::vector archs({arch}); + if (!targetTriple.empty()) { + llvm::Triple triple(targetTriple); + archs.push_back(swift::getTargetSpecificModuleTriple(triple).normalize()); + } std::vector aliases; for (auto& location : moduleLocations) { - aliases.push_back(location + arch + ".swiftmodule"); - if (!targetTriple.empty()) { - llvm::Triple triple(targetTriple); - auto moduleTriple = swift::getTargetSpecificModuleTriple(triple); - aliases.push_back(location + moduleTriple.normalize() + ".swiftmodule"); + for (auto& a : archs) { + aliases.push_back(location + a + ".swiftmodule"); } } @@ -195,7 +193,7 @@ std::unordered_map rewriteOutputsInPlace( for (size_t i = 0; i < CLIArgs.size(); i++) { if (pathRewriteOptions.count(CLIArgs[i])) { auto oldPath = CLIArgs[i + 1]; - auto newPath = config.tempArtifactDir + '/' + oldPath; + auto newPath = config.getTempArtifactDir() + '/' + oldPath; CLIArgs[++i] = newPath; newLocations.push_back(newPath); @@ -261,12 +259,12 @@ void storeRemappingForVFS(const SwiftExtractorConfiguration& config, return; } - if (std::error_code ec = llvm::sys::fs::create_directories(config.tempVFSDir)) { + if (std::error_code ec = llvm::sys::fs::create_directories(config.getTempVFSDir())) { std::cerr << "Cannot create temp VFS directory: " << ec.message() << "\n"; return; } - if (std::error_code ec = llvm::sys::fs::create_directories(config.VFSDir)) { + if (std::error_code ec = llvm::sys::fs::create_directories(config.getVFSDir())) { std::cerr << "Cannot create VFS directory: " << ec.message() << "\n"; return; } @@ -274,7 +272,7 @@ void storeRemappingForVFS(const SwiftExtractorConfiguration& config, // Constructing the VFS yaml file in a temp folder so that the other process doesn't read it // while it is not complete // TODO: Pick a more robust way to not collide with files from other processes - auto tempVfsPath = config.tempVFSDir + '/' + std::to_string(getpid()) + "-vfs.yaml"; + auto tempVfsPath = config.getTempVFSDir() + '/' + std::to_string(getpid()) + "-vfs.yaml"; std::error_code ec; llvm::raw_fd_ostream fd(tempVfsPath, ec, llvm::sys::fs::OF_None); if (ec) { @@ -299,7 +297,7 @@ void storeRemappingForVFS(const SwiftExtractorConfiguration& config, fd << "}\n"; fd.flush(); - auto vfsPath = config.VFSDir + '/' + std::to_string(getpid()) + "-vfs.yaml"; + auto vfsPath = config.getVFSDir() + '/' + std::to_string(getpid()) + "-vfs.yaml"; if (std::error_code ec = llvm::sys::fs::rename(tempVfsPath, vfsPath)) { std::cerr << "Cannot move temp VFS file '" << tempVfsPath << "' -> '" << vfsPath << "': " << ec.message() << "\n"; @@ -308,7 +306,7 @@ void storeRemappingForVFS(const SwiftExtractorConfiguration& config, } std::vector collectVFSFiles(const SwiftExtractorConfiguration& config) { - auto vfsDir = config.VFSDir + '/'; + auto vfsDir = config.getVFSDir() + '/'; if (!llvm::sys::fs::exists(vfsDir)) { return {}; } diff --git a/swift/extractor/main.cpp b/swift/extractor/main.cpp index 59bbfa690f0..bde37b0ccb5 100644 --- a/swift/extractor/main.cpp +++ b/swift/extractor/main.cpp @@ -58,11 +58,6 @@ int main(int argc, char** argv) { configuration.sourceArchiveDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_SOURCE_ARCHIVE_DIR", "."); configuration.scratchDir = getenv_or("CODEQL_EXTRACTOR_SWIFT_SCRATCH_DIR", "."); - configuration.tempTrapDir = configuration.scratchDir + "/swift-trap-temp"; - configuration.VFSDir = configuration.scratchDir + "/swift-vfs"; - configuration.tempVFSDir = configuration.scratchDir + "/swift-vfs-temp"; - configuration.tempArtifactDir = configuration.scratchDir + "/swift-extraction-artifacts"; - configuration.frontendOptions.reserve(argc - 1); for (int i = 1; i < argc; i++) { configuration.frontendOptions.push_back(argv[i]); From 5a04d6296999ed2c84119717276c1b82cb282982 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Thu, 30 Jun 2022 12:32:03 +0200 Subject: [PATCH 210/465] Swift: cleanup extraction --- swift/extractor/SwiftExtractor.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 91d25ce9c1b..65f0ae150cc 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -151,8 +151,7 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, } } -void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, - swift::CompilerInstance& compiler) { +static std::unordered_set collectInputFilenames(swift::CompilerInstance& compiler) { // The frontend can be called in many different ways. // At each invocation we only extract system and builtin modules and any input source files that // have an output associated with them. @@ -163,7 +162,10 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, sourceFiles.insert(input.getFileName()); } } + return sourceFiles; +} +static std::unordered_set collectModules(swift::CompilerInstance& compiler) { // getASTContext().getLoadedModules() does not provide all the modules available within the // program. // We need to iterate over all the imported modules (recursively) to see the whole "universe." @@ -187,8 +189,15 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, } } } + return allModules; +} - for (auto& module : allModules) { +void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, + swift::CompilerInstance& compiler) { + auto inputFiles = collectInputFilenames(compiler); + auto modules = collectModules(compiler); + + for (auto& module : modules) { // We only extract system and builtin modules here as the other "user" modules can be built // during the build process and then re-used at a later stage. In this case, we extract the // user code twice: once during the module build in a form of a source file, and then as @@ -201,7 +210,7 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, } else { for (auto file : module->getFiles()) { auto sourceFile = llvm::dyn_cast(file); - if (!sourceFile || sourceFiles.count(sourceFile->getFilename().str()) == 0) { + if (!sourceFile || inputFiles.count(sourceFile->getFilename().str()) == 0) { continue; } archiveFile(config, *sourceFile); From 2bd25fc58945d0b32019f06dc0964add5db5f822 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 27 Jun 2022 17:13:17 +0100 Subject: [PATCH 211/465] Swift: Add QLDoc. --- .../src/queries/Security/CWE-135/StringLengthConflation.ql | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 2bccba41b25..9db5eaca5fa 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -14,6 +14,11 @@ import swift import codeql.swift.dataflow.DataFlow import DataFlow::PathGraph +/** + * A configuration for tracking string lengths originating from source that is + * a `String` or an `NSString` object, to a sink of a different kind that + * expects an incompatible measure of length. + */ class StringLengthConflationConfiguration extends DataFlow::Configuration { StringLengthConflationConfiguration() { this = "StringLengthConflationConfiguration" } From 0251fb2d3538a22c142cc6b15ddcb9791b6ed4ef Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 30 Jun 2022 11:50:32 +0100 Subject: [PATCH 212/465] Swift: Add result annotations to test. --- .../CWE-135/StringLengthConflation.swift | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift index b8174455f9d..c104d71f886 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift @@ -50,28 +50,28 @@ func test(s: String) { // --- constructing a String.Index from integer --- let ix1 = String.Index(encodedOffset: s.count) // GOOD - let ix2 = String.Index(encodedOffset: ns.length) // BAD: NSString length used in String.Index - let ix3 = String.Index(encodedOffset: s.utf8.count) // BAD: String.utf8 length used in String.Index - let ix4 = String.Index(encodedOffset: s.utf16.count) // BAD: String.utf16 length used in String.Index - let ix5 = String.Index(encodedOffset: s.unicodeScalars.count) // BAD: string.unicodeScalars length used in String.Index + let ix2 = String.Index(encodedOffset: ns.length) // BAD: NSString length used in String.Index [NOT DETECTED] + let ix3 = String.Index(encodedOffset: s.utf8.count) // BAD: String.utf8 length used in String.Index [NOT DETECTED] + let ix4 = String.Index(encodedOffset: s.utf16.count) // BAD: String.utf16 length used in String.Index [NOT DETECTED] + let ix5 = String.Index(encodedOffset: s.unicodeScalars.count) // BAD: string.unicodeScalars length used in String.Index [NOT DETECTED] print("String.Index '\(ix1.encodedOffset)' / '\(ix2.encodedOffset)' '\(ix3.encodedOffset)' '\(ix4.encodedOffset)' '\(ix5.encodedOffset)'") let ix6 = s.index(s.startIndex, offsetBy: s.count / 2) // GOOD - let ix7 = s.index(s.startIndex, offsetBy: ns.length / 2) // BAD: NSString length used in String.Index + let ix7 = s.index(s.startIndex, offsetBy: ns.length / 2) // BAD: NSString length used in String.Index [NOT DETECTED] print("index '\(ix6.encodedOffset)' / '\(ix7.encodedOffset)'") var ix8 = s.startIndex s.formIndex(&ix8, offsetBy: s.count / 2) // GOOD var ix9 = s.startIndex - s.formIndex(&ix9, offsetBy: ns.length / 2) // BAD: NSString length used in String.Index + s.formIndex(&ix9, offsetBy: ns.length / 2) // BAD: NSString length used in String.Index [NOT DETECTED] print("formIndex '\(ix8.encodedOffset)' / '\(ix9.encodedOffset)'") // --- constructing an NSRange from integers --- let range1 = NSMakeRange(0, ns.length) // GOOD let range2 = NSMakeRange(0, s.count) // BAD: String length used in NSMakeRange - let range3 = NSMakeRange(0, s.reversed().count) // BAD: String length used in NSMakeRange - let range4 = NSMakeRange(0, s.distance(from: s.startIndex, to: s.endIndex)) // BAD: String length used in NSMakeRange + let range3 = NSMakeRange(0, s.reversed().count) // BAD: String length used in NSMakeRange [NOT DETECTED] + let range4 = NSMakeRange(0, s.distance(from: s.startIndex, to: s.endIndex)) // BAD: String length used in NSMakeRange [NOT DETECTED] print("NSMakeRange '\(range1.description)' / '\(range2.description)' '\(range3.description)' '\(range4.description)'") let range5 = NSRange(location: 0, length: ns.length) // GOOD @@ -81,43 +81,43 @@ func test(s: String) { // --- String operations using an integer directly --- let str1 = s.dropFirst(s.count - 1) // GOOD - let str2 = s.dropFirst(ns.length - 1) // BAD: NSString length used in String + let str2 = s.dropFirst(ns.length - 1) // BAD: NSString length used in String [NOT DETECTED] print("dropFirst '\(str1)' / '\(str2)'") let str3 = s.dropLast(s.count - 1) // GOOD - let str4 = s.dropLast(ns.length - 1) // BAD: NSString length used in String + let str4 = s.dropLast(ns.length - 1) // BAD: NSString length used in String [NOT DETECTED] print("dropLast '\(str3)' / '\(str4)'") let str5 = s.prefix(s.count - 1) // GOOD - let str6 = s.prefix(ns.length - 1) // BAD: NSString length used in String + let str6 = s.prefix(ns.length - 1) // BAD: NSString length used in String [NOT DETECTED] print("prefix '\(str5)' / '\(str6)'") let str7 = s.suffix(s.count - 1) // GOOD - let str8 = s.suffix(ns.length - 1) // BAD: NSString length used in String + let str8 = s.suffix(ns.length - 1) // BAD: NSString length used in String [NOT DETECTED] print("suffix '\(str7)' / '\(str8)'") let nstr1 = ns.character(at: ns.length - 1) // GOOD let nmstr1 = nms.character(at: nms.length - 1) // GOOD - let nstr2 = ns.character(at: s.count - 1) // BAD: String length used in NSString - let nmstr2 = nms.character(at: s.count - 1) // BAD: String length used in NString + let nstr2 = ns.character(at: s.count - 1) // BAD: String length used in NSString [NOT DETECTED] + let nmstr2 = nms.character(at: s.count - 1) // BAD: String length used in NString [NOT DETECTED] print("character '\(nstr1)' '\(nmstr1)' / '\(nstr2)' '\(nmstr2)'") let nstr3 = ns.substring(from: ns.length - 1) // GOOD let nmstr3 = nms.substring(from: nms.length - 1) // GOOD - let nstr4 = ns.substring(from: s.count - 1) // BAD: String length used in NSString - let nmstr4 = nms.substring(from: s.count - 1) // BAD: String length used in NString + let nstr4 = ns.substring(from: s.count - 1) // BAD: String length used in NSString [NOT DETECTED] + let nmstr4 = nms.substring(from: s.count - 1) // BAD: String length used in NString [NOT DETECTED] print("substring from '\(nstr3)' '\(nmstr3)' / '\(nstr4)' '\(nmstr4)'") let nstr5 = ns.substring(to: ns.length - 1) // GOOD let nmstr5 = nms.substring(to: nms.length - 1) // GOOD - let nstr6 = ns.substring(to: s.count - 1) // BAD: String length used in NSString - let nmstr6 = nms.substring(to: s.count - 1) // BAD: String length used in NString + let nstr6 = ns.substring(to: s.count - 1) // BAD: String length used in NSString [NOT DETECTED] + let nmstr6 = nms.substring(to: s.count - 1) // BAD: String length used in NString [NOT DETECTED] print("substring to '\(nstr5)' '\(nmstr5)' / '\(nstr6)' '\(nmstr6)'") let nmstr7 = NSMutableString(string: s) nmstr7.insert("*", at: nms.length - 1) // GOOD let nmstr8 = NSMutableString(string: s) - nmstr8.insert("*", at: s.count - 1) // BAD: String length used in NSString + nmstr8.insert("*", at: s.count - 1) // BAD: String length used in NSString [NOT DETECTED] print("insert '\(nmstr7)' / '\(nmstr8)'") } From 68c76006bdc04407e4c17968e9d989e68571affb Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 30 Jun 2022 11:48:08 +0100 Subject: [PATCH 213/465] Swift: Allow trivial taint-like flow. --- .../CWE-135/StringLengthConflation.ql | 6 ++++ .../CWE-135/StringLengthConflation.expected | 28 +++++++++++++++++++ .../CWE-135/StringLengthConflation.swift | 14 +++++----- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 9db5eaca5fa..a4e731e18ea 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -84,6 +84,12 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { flowstate = "String" // `String` length flowing into `NSString` ) } + + override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + // allow flow through `+` and `-`. + node2.asExpr().(AddExpr).getAnOperand() = node1.asExpr() or + node2.asExpr().(SubExpr).getAnOperand() = node1.asExpr() + } } from diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index 0dd91ca7b53..1bb4de15325 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -1,8 +1,36 @@ edges +| StringLengthConflation.swift:101:34:101:36 | .count : | StringLengthConflation.swift:101:34:101:44 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:102:36:102:38 | .count : | StringLengthConflation.swift:102:36:102:46 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:107:36:107:38 | .count : | StringLengthConflation.swift:107:36:107:46 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:108:38:108:40 | .count : | StringLengthConflation.swift:108:38:108:48 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:113:34:113:36 | .count : | StringLengthConflation.swift:113:34:113:44 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:114:36:114:38 | .count : | StringLengthConflation.swift:114:36:114:46 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:120:28:120:30 | .count : | StringLengthConflation.swift:120:28:120:38 | ... call to -(_:_:) ... | nodes | StringLengthConflation.swift:72:33:72:35 | .count | semmle.label | .count | | StringLengthConflation.swift:78:47:78:49 | .count | semmle.label | .count | +| StringLengthConflation.swift:101:34:101:36 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:101:34:101:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:102:36:102:38 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:102:36:102:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:107:36:107:38 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:107:36:107:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:108:38:108:40 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:108:38:108:48 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:113:34:113:36 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:113:34:113:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:114:36:114:38 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:114:36:114:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:120:28:120:30 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:120:28:120:38 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | subpaths #select | 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:101:34:101:44 | ... call to -(_:_:) ... | StringLengthConflation.swift:101:34:101:36 | .count : | StringLengthConflation.swift:101:34:101:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:102:36:102:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:102:36:102:38 | .count : | StringLengthConflation.swift:102:36:102:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:107:36:107:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:107:36:107:38 | .count : | StringLengthConflation.swift:107:36:107:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:108:38:108:48 | ... call to -(_:_:) ... | StringLengthConflation.swift:108:38:108:40 | .count : | StringLengthConflation.swift:108:38:108:48 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:113:34:113:44 | ... call to -(_:_:) ... | StringLengthConflation.swift:113:34:113:36 | .count : | StringLengthConflation.swift:113:34:113:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:114:36:114:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:114:36:114:38 | .count : | StringLengthConflation.swift:114:36:114:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:120:28:120:38 | ... call to -(_:_:) ... | StringLengthConflation.swift:120:28:120:30 | .count : | StringLengthConflation.swift:120:28:120:38 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift index c104d71f886..8cb698009b6 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift @@ -98,26 +98,26 @@ func test(s: String) { let nstr1 = ns.character(at: ns.length - 1) // GOOD let nmstr1 = nms.character(at: nms.length - 1) // GOOD - let nstr2 = ns.character(at: s.count - 1) // BAD: String length used in NSString [NOT DETECTED] - let nmstr2 = nms.character(at: s.count - 1) // BAD: String length used in NString [NOT DETECTED] + let nstr2 = ns.character(at: s.count - 1) // BAD: String length used in NSString + let nmstr2 = nms.character(at: s.count - 1) // BAD: String length used in NString print("character '\(nstr1)' '\(nmstr1)' / '\(nstr2)' '\(nmstr2)'") let nstr3 = ns.substring(from: ns.length - 1) // GOOD let nmstr3 = nms.substring(from: nms.length - 1) // GOOD - let nstr4 = ns.substring(from: s.count - 1) // BAD: String length used in NSString [NOT DETECTED] - let nmstr4 = nms.substring(from: s.count - 1) // BAD: String length used in NString [NOT DETECTED] + let nstr4 = ns.substring(from: s.count - 1) // BAD: String length used in NSString + let nmstr4 = nms.substring(from: s.count - 1) // BAD: String length used in NString print("substring from '\(nstr3)' '\(nmstr3)' / '\(nstr4)' '\(nmstr4)'") let nstr5 = ns.substring(to: ns.length - 1) // GOOD let nmstr5 = nms.substring(to: nms.length - 1) // GOOD - let nstr6 = ns.substring(to: s.count - 1) // BAD: String length used in NSString [NOT DETECTED] - let nmstr6 = nms.substring(to: s.count - 1) // BAD: String length used in NString [NOT DETECTED] + let nstr6 = ns.substring(to: s.count - 1) // BAD: String length used in NSString + let nmstr6 = nms.substring(to: s.count - 1) // BAD: String length used in NString print("substring to '\(nstr5)' '\(nmstr5)' / '\(nstr6)' '\(nmstr6)'") let nmstr7 = NSMutableString(string: s) nmstr7.insert("*", at: nms.length - 1) // GOOD let nmstr8 = NSMutableString(string: s) - nmstr8.insert("*", at: s.count - 1) // BAD: String length used in NSString [NOT DETECTED] + nmstr8.insert("*", at: s.count - 1) // BAD: String length used in NSString print("insert '\(nmstr7)' / '\(nmstr8)'") } From bfdb21d5517e57a13513c2b41891ce8623d90614 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 29 Jun 2022 21:54:41 +0100 Subject: [PATCH 214/465] Kotlin: support JvmStatic annotation This makes non-companion object methods into static methods, and for companion objects introduces static proxy methods that call the companion instance method. Note this doesn't quite implement what kotlinc does, since it will also eliminate getters and setters by promoting an object field into a static field, but our translation is simpler and only differs in private members' details. --- .../src/main/kotlin/KotlinFileExtractor.kt | 315 ++++++++++++------ .../src/main/kotlin/KotlinUsesExtractor.kt | 2 +- 2 files changed, 222 insertions(+), 95 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index a0e3004985a..89e61b4ca96 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -406,6 +406,8 @@ open class KotlinFileExtractor( extractDeclInitializers(c.declarations, false) { Pair(blockId, obinitId) } } + val jvmStaticFqName = FqName("kotlin.jvm.JvmStatic") + fun extractClassSource(c: IrClass, extractDeclarations: Boolean, extractStaticInitializer: Boolean, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean): Label { with("class source", c) { DeclarationStackAdjuster(c).use { @@ -442,9 +444,10 @@ open class KotlinFileExtractor( c.typeParameters.mapIndexed { idx, param -> extractTypeParameter(param, idx, javaClass?.typeParameters?.getOrNull(idx)) } if (extractDeclarations) { - c.declarations.map { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) } + c.declarations.forEach { extractDeclaration(it, extractPrivateMembers = extractPrivateMembers, extractFunctionBodies = extractFunctionBodies) } if (extractStaticInitializer) extractStaticInitializer(c, id) + extractJvmStaticProxyMethods(c, id, extractPrivateMembers, extractFunctionBodies) } if (c.isNonCompanionObject) { // For `object MyObject { ... }`, the .class has an @@ -472,6 +475,75 @@ open class KotlinFileExtractor( } } + private fun extractJvmStaticProxyMethods(c: IrClass, classId: Label, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean) { + + // Add synthetic forwarders for any JvmStatic methods or properties: + val companionObject = c.companionObject() ?: return + + val cType = c.typeWith() + val companionType = companionObject.typeWith() + + fun makeProxyFunction(f: IrFunction) { + // Emit a function in class `c` that delegates to the same function defined on `c.CompanionInstance`. + val proxyFunctionId = tw.getLabelFor(getFunctionLabel(f, classId, listOf())) + // We extract the function prototype with its ID overridden to belong to `c` not the companion object, + // but suppress outputting the body, which we will replace with a delegating call below. + forceExtractFunction(f, classId, extractBody = false, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution = null, classTypeArgsIncludingOuterClasses = listOf(), idOverride = proxyFunctionId, locOverride = null) + addModifiers(proxyFunctionId, "static") + if (extractFunctionBodies) { + val realFunctionLocId = tw.getLocation(f) + extractExpressionBody(proxyFunctionId, realFunctionLocId).also { returnId -> + extractRawMethodAccess( + f, + realFunctionLocId, + f.returnType, + proxyFunctionId, + returnId, + 0, + returnId, + f.valueParameters.size, + { argParent, idxOffset -> + f.valueParameters.forEachIndexed { idx, param -> + val syntheticParamId = useValueParameter(param, proxyFunctionId) + extractVariableAccess(syntheticParamId, param.type, realFunctionLocId, argParent, idxOffset + idx, proxyFunctionId, returnId) + } + }, + companionType, + { callId -> + val companionField = useCompanionObjectClassInstance(companionObject)?.id + extractVariableAccess(companionField, companionType, realFunctionLocId, callId, -1, proxyFunctionId, returnId).also { varAccessId -> + extractTypeAccessRecursive(cType, realFunctionLocId, varAccessId, -1, proxyFunctionId, returnId) + } + }, + null + ) + } + } + } + + companionObject.declarations.forEach { + if (shouldExtractDecl(it, extractPrivateMembers)) { + val wholeDeclAnnotated = it.hasAnnotation(jvmStaticFqName) + when(it) { + is IrFunction -> { + if (wholeDeclAnnotated) + makeProxyFunction(it) + } + is IrProperty -> { + it.getter?.let { getter -> + if (wholeDeclAnnotated || getter.hasAnnotation(jvmStaticFqName)) + makeProxyFunction(getter) + } + it.setter?.let { setter -> + if (wholeDeclAnnotated || setter.hasAnnotation(jvmStaticFqName)) + makeProxyFunction(setter) + } + } + } + } + } + } + // If `parentClassTypeArguments` is null, the parent class is a raw type. private fun extractEnclosingClass(innerDeclaration: IrDeclaration, innerId: Label, innerLocId: Label, parentClassTypeArguments: List?) { with("enclosing class", innerDeclaration) { @@ -824,13 +896,13 @@ open class KotlinFileExtractor( } extractVisibility(f, id, f.visibility) + if (f.isInline) { addModifiers(id, "inline") } - if (isStaticFunction(f)) { + if (f.willExtractAsStatic) { addModifiers(id, "static") } - if (f is IrSimpleFunction && f.overriddenSymbols.isNotEmpty()) { addModifiers(id, "override") } @@ -1028,15 +1100,21 @@ open class KotlinFileExtractor( private fun extractExpressionBody(b: IrExpressionBody, callable: Label) { with("expression body", b) { - val blockId = tw.getFreshIdLabel() val locId = tw.getLocation(b) - tw.writeStmts_block(blockId, callable, 0, callable) - tw.writeHasLocation(blockId, locId) + extractExpressionBody(callable, locId).also { returnId -> + extractExpressionExpr(b.expression, callable, returnId, 0, returnId) + } + } + } - val returnId = tw.getFreshIdLabel() + fun extractExpressionBody(callable: Label, locId: Label): Label { + val blockId = tw.getFreshIdLabel() + tw.writeStmts_block(blockId, callable, 0, callable) + tw.writeHasLocation(blockId, locId) + + return tw.getFreshIdLabel().also { returnId -> tw.writeStmts_returnstmt(returnId, blockId, 0, callable) tw.writeHasLocation(returnId, locId) - extractExpressionExpr(b.expression, callable, returnId, 0, returnId) } } @@ -1307,10 +1385,48 @@ open class KotlinFileExtractor( typeArguments: List = listOf(), extractClassTypeArguments: Boolean = false) { + val locId = tw.getLocation(callsite) + + extractRawMethodAccess( + syntacticCallTarget, + locId, + callsite.type, + enclosingCallable, + callsiteParent, + childIdx, + enclosingStmt, + valueArguments.size, + { argParent, idxOffset -> extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) }, + dispatchReceiver?.type, + dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } }, + extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } }, + typeArguments, + extractClassTypeArguments + ) + + } + + + fun extractRawMethodAccess( + syntacticCallTarget: IrFunction, + locId: Label, + returnType: IrType, + enclosingCallable: Label, + callsiteParent: Label, + childIdx: Int, + enclosingStmt: Label, + nValueArguments: Int, + extractValueArguments: (Label, Int) -> Unit, + drType: IrType?, + extractDispatchReceiver: ((Label) -> Unit)?, + extractExtensionReceiver: ((Label) -> Unit)?, + typeArguments: List = listOf(), + extractClassTypeArguments: Boolean = false) { + val callTarget = syntacticCallTarget.target.realOverrideTarget val id = tw.getFreshIdLabel() - val type = useType(callsite.type) - val locId = tw.getLocation(callsite) + val type = useType(returnType) + tw.writeExprs_methodaccess(id, type.javaResult.id, callsiteParent, childIdx) tw.writeExprsKotlinType(id, type.kotlinResult.id) tw.writeHasLocation(id, locId) @@ -1320,8 +1436,6 @@ open class KotlinFileExtractor( // type arguments at index -2, -3, ... extractTypeArguments(typeArguments, locId, id, enclosingCallable, enclosingStmt, -2, true) - val drType = dispatchReceiver?.type - val isFunctionInvoke = drType != null && drType is IrSimpleType && drType.isFunctionOrKFunction() @@ -1364,44 +1478,48 @@ open class KotlinFileExtractor( tw.writeCallableBinding(id, methodId) - if (dispatchReceiver != null) { - extractExpressionExpr(dispatchReceiver, enclosingCallable, id, -1, enclosingStmt) - } else if (isStaticFunction(callTarget)) { + if (callTarget.willExtractAsStatic) { extractStaticTypeAccessQualifier(callTarget, id, locId, enclosingCallable, enclosingStmt) + } else if (extractDispatchReceiver != null) { + extractDispatchReceiver(id) } } - val idxOffset = if (extensionReceiver != null) 1 else 0 + val idxOffset = if (extractExtensionReceiver != null) 1 else 0 val argParent = if (isBigArityFunctionInvoke) { - extractArrayCreationWithInitializer(id, valueArguments.size + idxOffset, locId, enclosingCallable, enclosingStmt) + extractArrayCreationWithInitializer(id, nValueArguments + idxOffset, locId, enclosingCallable, enclosingStmt) } else { id } - if (extensionReceiver != null) { - extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) + if (extractExtensionReceiver != null) { + extractExtensionReceiver(argParent) } - extractCallValueArguments(argParent, valueArguments, enclosingStmt, enclosingCallable, idxOffset) + extractValueArguments(argParent, idxOffset) } private fun extractStaticTypeAccessQualifier(target: IrDeclaration, parentExpr: Label, locId: Label, enclosingCallable: Label, enclosingStmt: Label) { - if (target.isStaticOfClass) { + if (target.willExtractAsStaticMemberOfClass) { extractTypeAccessRecursive(target.parentAsClass.toRawType(), locId, parentExpr, -1, enclosingCallable, enclosingStmt) - } else if (target.isStaticOfFile) { + } else if (target.willExtractAsStaticMemberOfFile) { extractTypeAccess(useFileClassType(target.parent as IrFile), locId, parentExpr, -1, enclosingCallable, enclosingStmt) } } - private val IrDeclaration.isStaticOfClass: Boolean - get() = this.isStatic && parent is IrClass + private val IrDeclaration.willExtractAsStaticMemberOfClass: Boolean + get() = this.willExtractAsStatic && parent is IrClass - private val IrDeclaration.isStaticOfFile: Boolean - get() = this.isStatic && parent is IrFile + private val IrDeclaration.willExtractAsStaticMemberOfFile: Boolean + get() = this.willExtractAsStatic && parent is IrFile - private val IrDeclaration.isStatic: Boolean - get() = this is IrSimpleFunction && dispatchReceiverParameter == null || + private fun isStaticAnnotatedNonCompanionMember(f: IrSimpleFunction) = + f.parentClassOrNull?.isNonCompanionObject == true && + (f.hasAnnotation(jvmStaticFqName) || f.correspondingPropertySymbol?.owner?.hasAnnotation(jvmStaticFqName) == true) + + private val IrDeclaration.willExtractAsStatic: Boolean + get() = this is IrSimpleFunction && (isStaticFunction(this) || isStaticAnnotatedNonCompanionMember(this)) || this is IrField && this.isStatic || this is IrEnumEntry @@ -2623,78 +2741,22 @@ open class KotlinFileExtractor( val exprParent = parent.expr(e, callable) val owner = e.symbol.owner if (owner is IrValueParameter && owner.index == -1 && !owner.isExtensionReceiver()) { - val id = tw.getFreshIdLabel() - val type = useType(e.type) - val locId = tw.getLocation(e) - tw.writeExprs_thisaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - tw.writeHasLocation(id, locId) - tw.writeCallableEnclosingExpr(id, callable) - tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt) - - - fun extractTypeAccess(parent: IrClass){ - extractTypeAccessRecursive(parent.typeWith(listOf()), locId, id, 0, callable, exprParent.enclosingStmt) - } - - when(val ownerParent = owner.parent) { - is IrFunction -> { - if (ownerParent.dispatchReceiverParameter == owner && - ownerParent.extensionReceiverParameter != null) { - - val ownerParent2 = ownerParent.parent - if (ownerParent2 is IrClass){ - extractTypeAccess(ownerParent2) - } else { - logger.errorElement("Unhandled qualifier for this", e) - } - } - } - is IrClass -> { - if (ownerParent.thisReceiver == owner) { - extractTypeAccess(ownerParent) - } - } - else -> { - logger.errorElement("Unexpected owner parent for this access: " + ownerParent.javaClass, e) - } - } + extractThisAccess(e, exprParent, callable) } else { - val id = tw.getFreshIdLabel() - val type = useType(e.type) - val locId = tw.getLocation(e) - tw.writeExprs_varaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - tw.writeHasLocation(id, locId) - tw.writeCallableEnclosingExpr(id, callable) - tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt) - - val vId = useValueDeclaration(owner) - if (vId != null) { - tw.writeVariableBinding(id, vId) - } + extractVariableAccess(useValueDeclaration(owner), e.type, tw.getLocation(e), exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt) } } is IrGetField -> { val exprParent = parent.expr(e, callable) - val id = tw.getFreshIdLabel() - val type = useType(e.type) - val locId = tw.getLocation(e) - tw.writeExprs_varaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx) - tw.writeExprsKotlinType(id, type.kotlinResult.id) - tw.writeHasLocation(id, locId) - tw.writeCallableEnclosingExpr(id, callable) - tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt) val owner = tryReplaceAndroidSyntheticField(e.symbol.owner) - val vId = useField(owner) - tw.writeVariableBinding(id, vId) - tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt) - - val receiver = e.receiver - if (receiver != null) { - extractExpressionExpr(receiver, callable, id, -1, exprParent.enclosingStmt) - } else if (owner.isStatic) { - extractStaticTypeAccessQualifier(owner, id, locId, callable, exprParent.enclosingStmt) + val locId = tw.getLocation(e) + extractVariableAccess(useField(owner), e.type, locId, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt).also { id -> + val receiver = e.receiver + if (receiver != null) { + extractExpressionExpr(receiver, callable, id, -1, exprParent.enclosingStmt) + } else if (owner.isStatic) { + extractStaticTypeAccessQualifier(owner, id, locId, callable, exprParent.enclosingStmt) + } } } is IrGetEnumValue -> { @@ -2995,6 +3057,71 @@ open class KotlinFileExtractor( } } + private fun extractThisAccess(e: IrGetValue, exprParent: ExprParent, callable: Label) { + val containingDeclaration = declarationStack.peek() + val locId = tw.getLocation(e) + val type = useType(e.type) + + if (containingDeclaration.willExtractAsStatic && containingDeclaration.parentClassOrNull?.isNonCompanionObject == true) { + // Use of `this` in a non-companion object member that will be lowered to a static function -- replace with a reference + // to the corresponding static object instance. + val instanceField = useObjectClassInstance(containingDeclaration.parentAsClass) + extractVariableAccess(instanceField.id, e.type, locId, exprParent.parent, exprParent.idx, callable, exprParent.enclosingStmt).also { varAccessId -> + extractStaticTypeAccessQualifier(containingDeclaration, varAccessId, locId, callable, exprParent.enclosingStmt) + } + } else { + val id = tw.getFreshIdLabel() + + tw.writeExprs_thisaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx) + tw.writeExprsKotlinType(id, type.kotlinResult.id) + tw.writeHasLocation(id, locId) + tw.writeCallableEnclosingExpr(id, callable) + tw.writeStatementEnclosingExpr(id, exprParent.enclosingStmt) + + fun extractTypeAccess(parent: IrClass) { + extractTypeAccessRecursive(parent.typeWith(listOf()), locId, id, 0, callable, exprParent.enclosingStmt) + } + + val owner = e.symbol.owner + when(val ownerParent = owner.parent) { + is IrFunction -> { + if (ownerParent.dispatchReceiverParameter == owner && + ownerParent.extensionReceiverParameter != null) { + + val ownerParent2 = ownerParent.parent + if (ownerParent2 is IrClass){ + extractTypeAccess(ownerParent2) + } else { + logger.errorElement("Unhandled qualifier for this", e) + } + } + } + is IrClass -> { + if (ownerParent.thisReceiver == owner) { + extractTypeAccess(ownerParent) + } + } + else -> { + logger.errorElement("Unexpected owner parent for this access: " + ownerParent.javaClass, e) + } + } + } + } + + private fun extractVariableAccess(variable: Label?, irType: IrType, locId: Label, parent: Label, idx: Int, callable: Label, enclosingStmt: Label) = + tw.getFreshIdLabel().also { + val type = useType(irType) + tw.writeExprs_varaccess(it, type.javaResult.id, parent, idx) + tw.writeExprsKotlinType(it, type.kotlinResult.id) + tw.writeHasLocation(it, locId) + tw.writeCallableEnclosingExpr(it, callable) + tw.writeStatementEnclosingExpr(it, enclosingStmt) + + if (variable != null) { + tw.writeVariableBinding(it, variable) + } + } + private fun extractLoop( loop: IrLoop, stmtExprParent: StmtExprParent, diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt index 530ff47e8ab..2412131af25 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt @@ -970,7 +970,7 @@ open class KotlinUsesExtractor( * allow it to be passed in. */ @OptIn(ObsoleteDescriptorBasedAPI::class) - private fun getFunctionLabel(f: IrFunction, maybeParentId: Label?, classTypeArgsIncludingOuterClasses: List?) = + fun getFunctionLabel(f: IrFunction, maybeParentId: Label?, classTypeArgsIncludingOuterClasses: List?) = getFunctionLabel( f.parent, maybeParentId, From b4124ac553cd8cc5d4b9ac78c3cda635e6b342d5 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 30 Jun 2022 11:26:29 +0100 Subject: [PATCH 215/465] Add test --- .../jvmstatic-annotation/JavaUser.java | 22 ++++++ .../jvmstatic-annotation/test.expected | 74 +++++++++++++++++++ .../jvmstatic-annotation/test.kt | 67 +++++++++++++++++ .../jvmstatic-annotation/test.ql | 14 ++++ 4 files changed, 177 insertions(+) create mode 100644 java/ql/test/kotlin/library-tests/jvmstatic-annotation/JavaUser.java create mode 100644 java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.expected create mode 100644 java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt create mode 100644 java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.ql diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/JavaUser.java b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/JavaUser.java new file mode 100644 index 00000000000..fc079df1ba8 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/JavaUser.java @@ -0,0 +1,22 @@ +public class JavaUser { + + public static void test() { + + HasCompanion.staticMethod("1"); + HasCompanion.Companion.nonStaticMethod("2"); + HasCompanion.setStaticProp(HasCompanion.Companion.getNonStaticProp()); + HasCompanion.Companion.setNonStaticProp(HasCompanion.getStaticProp()); + HasCompanion.Companion.setPropWithStaticGetter(HasCompanion.Companion.getPropWithStaticSetter()); + HasCompanion.setPropWithStaticSetter(HasCompanion.getPropWithStaticGetter()); + + // These extract as static methods, since there is no proxy method in the non-companion object case. + NonCompanion.staticMethod("1"); + NonCompanion.INSTANCE.nonStaticMethod("2"); + NonCompanion.setStaticProp(NonCompanion.INSTANCE.getNonStaticProp()); + NonCompanion.INSTANCE.setNonStaticProp(NonCompanion.getStaticProp()); + NonCompanion.INSTANCE.setPropWithStaticGetter(NonCompanion.INSTANCE.getPropWithStaticSetter()); + NonCompanion.setPropWithStaticSetter(NonCompanion.getPropWithStaticGetter()); + + } + +} diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.expected b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.expected new file mode 100644 index 00000000000..ae431e80343 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.expected @@ -0,0 +1,74 @@ +staticMembers +| JavaUser.java:1:14:1:21 | JavaUser | JavaUser.java:3:22:3:25 | test | Method | +| test.kt:0:0:0:0 | TestKt | test.kt:49:1:67:1 | externalUser | Method | +| test.kt:9:1:29:1 | HasCompanion | test.kt:11:3:27:3 | Companion | Class | +| test.kt:9:1:29:1 | HasCompanion | test.kt:11:3:27:3 | Companion | Field | +| test.kt:9:1:29:1 | HasCompanion | test.kt:13:16:13:71 | staticMethod | Method | +| test.kt:9:1:29:1 | HasCompanion | test.kt:16:16:16:43 | getStaticProp | Method | +| test.kt:9:1:29:1 | HasCompanion | test.kt:16:16:16:43 | setStaticProp | Method | +| test.kt:9:1:29:1 | HasCompanion | test.kt:20:18:20:45 | getPropWithStaticGetter | Method | +| test.kt:9:1:29:1 | HasCompanion | test.kt:25:18:25:60 | setPropWithStaticSetter | Method | +| test.kt:31:1:47:1 | NonCompanion | test.kt:31:1:47:1 | INSTANCE | Field | +| test.kt:31:1:47:1 | NonCompanion | test.kt:33:14:33:69 | staticMethod | Method | +| test.kt:31:1:47:1 | NonCompanion | test.kt:36:14:36:41 | getStaticProp | Method | +| test.kt:31:1:47:1 | NonCompanion | test.kt:36:14:36:41 | setStaticProp | Method | +| test.kt:31:1:47:1 | NonCompanion | test.kt:40:16:40:43 | getPropWithStaticGetter | Method | +| test.kt:31:1:47:1 | NonCompanion | test.kt:45:16:45:58 | setPropWithStaticSetter | Method | +#select +| test.kt:9:1:29:1 | HasCompanion | JavaUser.java:5:5:5:34 | staticMethod(...) | JavaUser.java:5:5:5:16 | HasCompanion | static | +| test.kt:9:1:29:1 | HasCompanion | JavaUser.java:7:5:7:73 | setStaticProp(...) | JavaUser.java:7:5:7:16 | HasCompanion | static | +| test.kt:9:1:29:1 | HasCompanion | JavaUser.java:8:45:8:72 | getStaticProp(...) | JavaUser.java:8:45:8:56 | HasCompanion | static | +| test.kt:9:1:29:1 | HasCompanion | JavaUser.java:10:5:10:80 | setPropWithStaticSetter(...) | JavaUser.java:10:5:10:16 | HasCompanion | static | +| test.kt:9:1:29:1 | HasCompanion | JavaUser.java:10:42:10:79 | getPropWithStaticGetter(...) | JavaUser.java:10:42:10:53 | HasCompanion | static | +| test.kt:11:3:27:3 | Companion | JavaUser.java:6:5:6:47 | nonStaticMethod(...) | JavaUser.java:6:5:6:26 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | JavaUser.java:7:32:7:72 | getNonStaticProp(...) | JavaUser.java:7:32:7:53 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | JavaUser.java:8:5:8:73 | setNonStaticProp(...) | JavaUser.java:8:5:8:26 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | JavaUser.java:9:5:9:100 | setPropWithStaticGetter(...) | JavaUser.java:9:5:9:26 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | JavaUser.java:9:52:9:99 | getPropWithStaticSetter(...) | JavaUser.java:9:52:9:73 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:13:16:13:71 | staticMethod(...) | test.kt:13:16:13:71 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:13:54:13:71 | nonStaticMethod(...) | test.kt:13:54:13:71 | this | instance | +| test.kt:11:3:27:3 | Companion | test.kt:14:46:14:60 | staticMethod(...) | test.kt:14:46:14:60 | this | instance | +| test.kt:11:3:27:3 | Companion | test.kt:16:16:16:43 | getStaticProp(...) | test.kt:16:16:16:43 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:16:16:16:43 | setStaticProp(...) | test.kt:16:16:16:43 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:20:18:20:45 | getPropWithStaticGetter(...) | test.kt:20:18:20:45 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:20:26:20:45 | getPropWithStaticSetter(...) | test.kt:20:26:20:45 | this | instance | +| test.kt:11:3:27:3 | Companion | test.kt:21:24:21:43 | setPropWithStaticSetter(...) | test.kt:21:24:21:43 | this | instance | +| test.kt:11:3:27:3 | Companion | test.kt:24:15:24:34 | getPropWithStaticGetter(...) | test.kt:24:15:24:34 | this | instance | +| test.kt:11:3:27:3 | Companion | test.kt:25:18:25:60 | setPropWithStaticSetter(...) | test.kt:25:18:25:60 | HasCompanion.Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:25:35:25:54 | setPropWithStaticGetter(...) | test.kt:25:35:25:54 | this | instance | +| test.kt:11:3:27:3 | Companion | test.kt:52:16:52:32 | staticMethod(...) | test.kt:52:3:52:14 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:53:16:53:35 | nonStaticMethod(...) | test.kt:53:3:53:14 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:54:3:54:25 | setStaticProp(...) | test.kt:54:3:54:14 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:54:42:54:54 | getNonStaticProp(...) | test.kt:54:29:54:40 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:55:3:55:28 | setNonStaticProp(...) | test.kt:55:3:55:14 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:55:45:55:54 | getStaticProp(...) | test.kt:55:32:55:43 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:56:3:56:35 | setPropWithStaticGetter(...) | test.kt:56:3:56:14 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:56:52:56:71 | getPropWithStaticSetter(...) | test.kt:56:39:56:50 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:57:3:57:35 | setPropWithStaticSetter(...) | test.kt:57:3:57:14 | Companion | instance | +| test.kt:11:3:27:3 | Companion | test.kt:57:52:57:71 | getPropWithStaticGetter(...) | test.kt:57:39:57:50 | Companion | instance | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:13:5:13:34 | staticMethod(...) | JavaUser.java:13:5:13:16 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:14:5:14:46 | nonStaticMethod(...) | JavaUser.java:14:5:14:25 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:15:5:15:72 | setStaticProp(...) | JavaUser.java:15:5:15:16 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:15:32:15:71 | getNonStaticProp(...) | JavaUser.java:15:32:15:52 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:16:5:16:72 | setNonStaticProp(...) | JavaUser.java:16:5:16:25 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:16:44:16:71 | getStaticProp(...) | JavaUser.java:16:44:16:55 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:17:5:17:98 | setPropWithStaticGetter(...) | JavaUser.java:17:5:17:25 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:17:51:17:97 | getPropWithStaticSetter(...) | JavaUser.java:17:51:17:71 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:18:5:18:80 | setPropWithStaticSetter(...) | JavaUser.java:18:5:18:16 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | JavaUser.java:18:42:18:79 | getPropWithStaticGetter(...) | JavaUser.java:18:42:18:53 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:33:52:33:69 | nonStaticMethod(...) | test.kt:33:52:33:69 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:34:44:34:58 | staticMethod(...) | test.kt:34:44:34:58 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:40:24:40:43 | getPropWithStaticSetter(...) | test.kt:40:24:40:43 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:41:22:41:41 | setPropWithStaticSetter(...) | test.kt:41:22:41:41 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:44:13:44:32 | getPropWithStaticGetter(...) | test.kt:44:13:44:32 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:45:33:45:52 | setPropWithStaticGetter(...) | test.kt:45:33:45:52 | NonCompanion.INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:60:16:60:32 | staticMethod(...) | test.kt:60:16:60:32 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:61:16:61:35 | nonStaticMethod(...) | test.kt:61:3:61:14 | INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:62:3:62:25 | setStaticProp(...) | test.kt:62:3:62:25 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:62:42:62:54 | getNonStaticProp(...) | test.kt:62:29:62:40 | INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:63:3:63:28 | setNonStaticProp(...) | test.kt:63:3:63:14 | INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:63:45:63:54 | getStaticProp(...) | test.kt:63:45:63:54 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:64:3:64:35 | setPropWithStaticGetter(...) | test.kt:64:3:64:14 | INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:64:52:64:71 | getPropWithStaticSetter(...) | test.kt:64:39:64:50 | INSTANCE | instance | +| test.kt:31:1:47:1 | NonCompanion | test.kt:65:3:65:35 | setPropWithStaticSetter(...) | test.kt:65:3:65:35 | NonCompanion | static | +| test.kt:31:1:47:1 | NonCompanion | test.kt:65:52:65:71 | getPropWithStaticGetter(...) | test.kt:65:52:65:71 | NonCompanion | static | diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt new file mode 100644 index 00000000000..cbf553725b4 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.kt @@ -0,0 +1,67 @@ +// Test both definining static members, and referring to an object's other static members, in companion object and non-companion object contexts. +// For the companion object all the references to other properties and methods should extract as ordinary instance calls and field read and writes, +// but those methods / getters / setters that are annotated static should get an additional static proxy method defined on the surrounding class-- +// for example, we should see (using Java notation) public static String HasCompanion.staticMethod(String s) { return Companion.staticMethod(s); }. +// For the non-companion object, the static-annotated methods should themselves be extracted as static members, and calls / gets / sets that use them +// should extract as static calls. Static members using non-static ones should extract like staticMethod(...) { INSTANCE.nonStaticMethod(...) }, +// where the reference to INSTANCE replaces what would normally be a `this` reference. + +public class HasCompanion { + + companion object { + + @JvmStatic fun staticMethod(s: String): String = nonStaticMethod(s) + fun nonStaticMethod(s: String): String = staticMethod(s) + + @JvmStatic var staticProp: String = "a" + var nonStaticProp: String = "b" + + var propWithStaticGetter: String + @JvmStatic get() = propWithStaticSetter + set(s: String) { propWithStaticSetter = s } + + var propWithStaticSetter: String + get() = propWithStaticGetter + @JvmStatic set(s: String) { propWithStaticGetter = s } + + } + +} + +object NonCompanion { + + @JvmStatic fun staticMethod(s: String): String = nonStaticMethod(s) + fun nonStaticMethod(s: String): String = staticMethod(s) + + @JvmStatic var staticProp: String = "a" + var nonStaticProp: String = "b" + + var propWithStaticGetter: String + @JvmStatic get() = propWithStaticSetter + set(s: String) { propWithStaticSetter = s } + + var propWithStaticSetter: String + get() = propWithStaticGetter + @JvmStatic set(s: String) { propWithStaticGetter = s } + +} + +fun externalUser() { + + // These all extract as instance calls (to HasCompanion.Companion), since a Kotlin caller won't use the static proxy methods generated by the @JvmStatic annotation. + HasCompanion.staticMethod("1") + HasCompanion.nonStaticMethod("2") + HasCompanion.staticProp = HasCompanion.nonStaticProp + HasCompanion.nonStaticProp = HasCompanion.staticProp + HasCompanion.propWithStaticGetter = HasCompanion.propWithStaticSetter + HasCompanion.propWithStaticSetter = HasCompanion.propWithStaticGetter + + // These extract as static methods, since there is no proxy method in the non-companion object case. + NonCompanion.staticMethod("1") + NonCompanion.nonStaticMethod("2") + NonCompanion.staticProp = NonCompanion.nonStaticProp + NonCompanion.nonStaticProp = NonCompanion.staticProp + NonCompanion.propWithStaticGetter = NonCompanion.propWithStaticSetter + NonCompanion.propWithStaticSetter = NonCompanion.propWithStaticGetter + +} diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.ql b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.ql new file mode 100644 index 00000000000..555182c6bbd --- /dev/null +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.ql @@ -0,0 +1,14 @@ +import java + +query predicate staticMembers(RefType declType, Member m, string kind) { + + m.fromSource() and m.isStatic() and m.getDeclaringType() = declType and kind = m.getAPrimaryQlClass() + +} + +from Call call, Callable callable, RefType declType, Expr qualifier, string callType +where call.getCallee() = callable and +declType = callable.getDeclaringType() and +qualifier = call.getQualifier() and +if callable.isStatic() then callType = "static" else callType = "instance" +select declType, call, qualifier, callType From 466cf7573bf4b5a1d2aeb4b7903f9476eafd7d14 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 30 Jun 2022 12:13:00 +0100 Subject: [PATCH 216/465] Autoformat --- .../library-tests/jvmstatic-annotation/test.ql | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.ql b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.ql index 555182c6bbd..725ba05a106 100644 --- a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.ql +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/test.ql @@ -1,14 +1,16 @@ import java query predicate staticMembers(RefType declType, Member m, string kind) { - - m.fromSource() and m.isStatic() and m.getDeclaringType() = declType and kind = m.getAPrimaryQlClass() - + m.fromSource() and + m.isStatic() and + m.getDeclaringType() = declType and + kind = m.getAPrimaryQlClass() } from Call call, Callable callable, RefType declType, Expr qualifier, string callType -where call.getCallee() = callable and -declType = callable.getDeclaringType() and -qualifier = call.getQualifier() and -if callable.isStatic() then callType = "static" else callType = "instance" +where + call.getCallee() = callable and + declType = callable.getDeclaringType() and + qualifier = call.getQualifier() and + if callable.isStatic() then callType = "static" else callType = "instance" select declType, call, qualifier, callType From 5a47e1dd9594a3808731b886e06b0dbf9496f67a Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 30 Jun 2022 12:48:11 +0100 Subject: [PATCH 217/465] Annotate generated static proxy methods as compiler-generated --- .../kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt | 2 ++ java/ql/lib/semmle/code/java/Element.qll | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 89e61b4ca96..b425aa965be 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -490,6 +490,7 @@ open class KotlinFileExtractor( // but suppress outputting the body, which we will replace with a delegating call below. forceExtractFunction(f, classId, extractBody = false, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution = null, classTypeArgsIncludingOuterClasses = listOf(), idOverride = proxyFunctionId, locOverride = null) addModifiers(proxyFunctionId, "static") + tw.writeCompiler_generated(proxyFunctionId, CompilerGeneratedKinds.JVMSTATIC_PROXY_METHOD.kind) if (extractFunctionBodies) { val realFunctionLocId = tw.getLocation(f) extractExpressionBody(proxyFunctionId, realFunctionLocId).also { returnId -> @@ -4537,5 +4538,6 @@ open class KotlinFileExtractor( ENUM_CLASS_SPECIAL_MEMBER(5), DELEGATED_PROPERTY_GETTER(6), DELEGATED_PROPERTY_SETTER(7), + JVMSTATIC_PROXY_METHOD(8), } } diff --git a/java/ql/lib/semmle/code/java/Element.qll b/java/ql/lib/semmle/code/java/Element.qll index dbf2efc71b5..96c8a8c5c21 100755 --- a/java/ql/lib/semmle/code/java/Element.qll +++ b/java/ql/lib/semmle/code/java/Element.qll @@ -57,6 +57,12 @@ class Element extends @element, Top { i = 4 and result = "Class initialisation method " or i = 5 and result = "Enum class special member" + or + i = 6 and result = "Getter for a Kotlin delegated property" + or + i = 7 and result = "Setter for a Kotlin delegated property" + or + i = 8 and result = "Proxy static method for a @JvmStatic-annotated function or property" ) } } From bf581b971ca4c706da18486526de51dee62a3875 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 30 Jun 2022 12:51:09 +0100 Subject: [PATCH 218/465] Rename willExtract properties to shouldExtract --- .../src/main/kotlin/KotlinFileExtractor.kt | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index b425aa965be..5143855386d 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -901,7 +901,7 @@ open class KotlinFileExtractor( if (f.isInline) { addModifiers(id, "inline") } - if (f.willExtractAsStatic) { + if (f.shouldExtractAsStatic) { addModifiers(id, "static") } if (f is IrSimpleFunction && f.overriddenSymbols.isNotEmpty()) { @@ -1479,7 +1479,7 @@ open class KotlinFileExtractor( tw.writeCallableBinding(id, methodId) - if (callTarget.willExtractAsStatic) { + if (callTarget.shouldExtractAsStatic) { extractStaticTypeAccessQualifier(callTarget, id, locId, enclosingCallable, enclosingStmt) } else if (extractDispatchReceiver != null) { extractDispatchReceiver(id) @@ -1502,24 +1502,24 @@ open class KotlinFileExtractor( } private fun extractStaticTypeAccessQualifier(target: IrDeclaration, parentExpr: Label, locId: Label, enclosingCallable: Label, enclosingStmt: Label) { - if (target.willExtractAsStaticMemberOfClass) { + if (target.shouldExtractAsStaticMemberOfClass) { extractTypeAccessRecursive(target.parentAsClass.toRawType(), locId, parentExpr, -1, enclosingCallable, enclosingStmt) - } else if (target.willExtractAsStaticMemberOfFile) { + } else if (target.shouldExtractAsStaticMemberOfFile) { extractTypeAccess(useFileClassType(target.parent as IrFile), locId, parentExpr, -1, enclosingCallable, enclosingStmt) } } - private val IrDeclaration.willExtractAsStaticMemberOfClass: Boolean - get() = this.willExtractAsStatic && parent is IrClass + private val IrDeclaration.shouldExtractAsStaticMemberOfClass: Boolean + get() = this.shouldExtractAsStatic && parent is IrClass - private val IrDeclaration.willExtractAsStaticMemberOfFile: Boolean - get() = this.willExtractAsStatic && parent is IrFile + private val IrDeclaration.shouldExtractAsStaticMemberOfFile: Boolean + get() = this.shouldExtractAsStatic && parent is IrFile private fun isStaticAnnotatedNonCompanionMember(f: IrSimpleFunction) = f.parentClassOrNull?.isNonCompanionObject == true && (f.hasAnnotation(jvmStaticFqName) || f.correspondingPropertySymbol?.owner?.hasAnnotation(jvmStaticFqName) == true) - private val IrDeclaration.willExtractAsStatic: Boolean + private val IrDeclaration.shouldExtractAsStatic: Boolean get() = this is IrSimpleFunction && (isStaticFunction(this) || isStaticAnnotatedNonCompanionMember(this)) || this is IrField && this.isStatic || this is IrEnumEntry @@ -3063,7 +3063,7 @@ open class KotlinFileExtractor( val locId = tw.getLocation(e) val type = useType(e.type) - if (containingDeclaration.willExtractAsStatic && containingDeclaration.parentClassOrNull?.isNonCompanionObject == true) { + if (containingDeclaration.shouldExtractAsStatic && containingDeclaration.parentClassOrNull?.isNonCompanionObject == true) { // Use of `this` in a non-companion object member that will be lowered to a static function -- replace with a reference // to the corresponding static object instance. val instanceField = useObjectClassInstance(containingDeclaration.parentAsClass) From 98761041f1547bf9bdce2f8a8a7ac87b9df05303 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 30 Jun 2022 13:11:00 +0100 Subject: [PATCH 219/465] Prevent labelling proxies of default getters and setters as themselves default getters and setters --- .../src/main/kotlin/KotlinFileExtractor.kt | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 5143855386d..3a55214d34a 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -488,7 +488,7 @@ open class KotlinFileExtractor( val proxyFunctionId = tw.getLabelFor(getFunctionLabel(f, classId, listOf())) // We extract the function prototype with its ID overridden to belong to `c` not the companion object, // but suppress outputting the body, which we will replace with a delegating call below. - forceExtractFunction(f, classId, extractBody = false, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution = null, classTypeArgsIncludingOuterClasses = listOf(), idOverride = proxyFunctionId, locOverride = null) + forceExtractFunction(f, classId, extractBody = false, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution = null, classTypeArgsIncludingOuterClasses = listOf(), idOverride = proxyFunctionId, locOverride = null, extractOrigin = false) addModifiers(proxyFunctionId, "static") tw.writeCompiler_generated(proxyFunctionId, CompilerGeneratedKinds.JVMSTATIC_PROXY_METHOD.kind) if (extractFunctionBodies) { @@ -813,7 +813,7 @@ open class KotlinFileExtractor( else forceExtractFunction(f, parentId, extractBody, extractMethodAndParameterTypeAccesses, typeSubstitution, classTypeArgsIncludingOuterClasses, null, null) - private fun forceExtractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?, idOverride: Label?, locOverride: Label?): Label { + private fun forceExtractFunction(f: IrFunction, parentId: Label, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?, idOverride: Label?, locOverride: Label?, extractOrigin: Boolean = true): Label { with("function", f) { DeclarationStackAdjuster(f).use { @@ -870,13 +870,15 @@ open class KotlinFileExtractor( val methodId = id.cast() tw.writeMethods(methodId, shortName.nameInDB, "${shortName.nameInDB}$paramsSignature", returnType.javaResult.id, parentId, sourceDeclaration.cast()) tw.writeMethodsKotlinType(methodId, returnType.kotlinResult.id) - when (f.origin) { - IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER -> - tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.GENERATED_DATA_CLASS_MEMBER.kind) - IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR -> - tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.DEFAULT_PROPERTY_ACCESSOR.kind) - IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER -> - tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.ENUM_CLASS_SPECIAL_MEMBER.kind) + if (extractOrigin) { + when (f.origin) { + IrDeclarationOrigin.GENERATED_DATA_CLASS_MEMBER -> + tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.GENERATED_DATA_CLASS_MEMBER.kind) + IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR -> + tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.DEFAULT_PROPERTY_ACCESSOR.kind) + IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER -> + tw.writeCompiler_generated(methodId, CompilerGeneratedKinds.ENUM_CLASS_SPECIAL_MEMBER.kind) + } } if (extractMethodAndParameterTypeAccesses) { From 8214c3b78eadc9bb8a2b86d48db1524edb203411 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 30 Jun 2022 13:11:43 +0100 Subject: [PATCH 220/465] Add AST dump for JvmStatic annotation test --- .../jvmstatic-annotation/PrintAst.expected | 441 ++++++++++++++++++ .../jvmstatic-annotation/PrintAst.qlref | 1 + 2 files changed, 442 insertions(+) create mode 100644 java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected create mode 100644 java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.qlref diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected new file mode 100644 index 00000000000..5a17ed98591 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected @@ -0,0 +1,441 @@ +JavaUser.java: +# 0| [CompilationUnit] JavaUser +# 1| 1: [Class] JavaUser +# 3| 2: [Method] test +# 3| 3: [TypeAccess] void +# 3| 5: [BlockStmt] { ... } +# 5| 0: [ExprStmt] ; +# 5| 0: [MethodAccess] staticMethod(...) +# 5| -1: [TypeAccess] HasCompanion +# 5| 0: [StringLiteral] "1" +# 6| 1: [ExprStmt] ; +# 6| 0: [MethodAccess] nonStaticMethod(...) +# 6| -1: [VarAccess] HasCompanion.Companion +# 6| -1: [TypeAccess] HasCompanion +# 6| 0: [StringLiteral] "2" +# 7| 2: [ExprStmt] ; +# 7| 0: [MethodAccess] setStaticProp(...) +# 7| -1: [TypeAccess] HasCompanion +# 7| 0: [MethodAccess] getNonStaticProp(...) +# 7| -1: [VarAccess] HasCompanion.Companion +# 7| -1: [TypeAccess] HasCompanion +# 8| 3: [ExprStmt] ; +# 8| 0: [MethodAccess] setNonStaticProp(...) +# 8| -1: [VarAccess] HasCompanion.Companion +# 8| -1: [TypeAccess] HasCompanion +# 8| 0: [MethodAccess] getStaticProp(...) +# 8| -1: [TypeAccess] HasCompanion +# 9| 4: [ExprStmt] ; +# 9| 0: [MethodAccess] setPropWithStaticGetter(...) +# 9| -1: [VarAccess] HasCompanion.Companion +# 9| -1: [TypeAccess] HasCompanion +# 9| 0: [MethodAccess] getPropWithStaticSetter(...) +# 9| -1: [VarAccess] HasCompanion.Companion +# 9| -1: [TypeAccess] HasCompanion +# 10| 5: [ExprStmt] ; +# 10| 0: [MethodAccess] setPropWithStaticSetter(...) +# 10| -1: [TypeAccess] HasCompanion +# 10| 0: [MethodAccess] getPropWithStaticGetter(...) +# 10| -1: [TypeAccess] HasCompanion +# 13| 6: [ExprStmt] ; +# 13| 0: [MethodAccess] staticMethod(...) +# 13| -1: [TypeAccess] NonCompanion +# 13| 0: [StringLiteral] "1" +# 14| 7: [ExprStmt] ; +# 14| 0: [MethodAccess] nonStaticMethod(...) +# 14| -1: [VarAccess] NonCompanion.INSTANCE +# 14| -1: [TypeAccess] NonCompanion +# 14| 0: [StringLiteral] "2" +# 15| 8: [ExprStmt] ; +# 15| 0: [MethodAccess] setStaticProp(...) +# 15| -1: [TypeAccess] NonCompanion +# 15| 0: [MethodAccess] getNonStaticProp(...) +# 15| -1: [VarAccess] NonCompanion.INSTANCE +# 15| -1: [TypeAccess] NonCompanion +# 16| 9: [ExprStmt] ; +# 16| 0: [MethodAccess] setNonStaticProp(...) +# 16| -1: [VarAccess] NonCompanion.INSTANCE +# 16| -1: [TypeAccess] NonCompanion +# 16| 0: [MethodAccess] getStaticProp(...) +# 16| -1: [TypeAccess] NonCompanion +# 17| 10: [ExprStmt] ; +# 17| 0: [MethodAccess] setPropWithStaticGetter(...) +# 17| -1: [VarAccess] NonCompanion.INSTANCE +# 17| -1: [TypeAccess] NonCompanion +# 17| 0: [MethodAccess] getPropWithStaticSetter(...) +# 17| -1: [VarAccess] NonCompanion.INSTANCE +# 17| -1: [TypeAccess] NonCompanion +# 18| 11: [ExprStmt] ; +# 18| 0: [MethodAccess] setPropWithStaticSetter(...) +# 18| -1: [TypeAccess] NonCompanion +# 18| 0: [MethodAccess] getPropWithStaticGetter(...) +# 18| -1: [TypeAccess] NonCompanion +test.kt: +# 0| [CompilationUnit] test +# 0| 1: [Class] TestKt +# 49| 1: [Method] externalUser +# 49| 3: [TypeAccess] Unit +# 49| 5: [BlockStmt] { ... } +# 52| 0: [ExprStmt] ; +# 52| 0: [ImplicitCoercionToUnitExpr] +# 52| 0: [TypeAccess] Unit +# 52| 1: [MethodAccess] staticMethod(...) +# 52| -1: [VarAccess] Companion +# 52| 0: [StringLiteral] 1 +# 53| 1: [ExprStmt] ; +# 53| 0: [ImplicitCoercionToUnitExpr] +# 53| 0: [TypeAccess] Unit +# 53| 1: [MethodAccess] nonStaticMethod(...) +# 53| -1: [VarAccess] Companion +# 53| 0: [StringLiteral] 2 +# 54| 2: [ExprStmt] ; +# 54| 0: [MethodAccess] setStaticProp(...) +# 54| -1: [VarAccess] Companion +# 54| 0: [MethodAccess] getNonStaticProp(...) +# 54| -1: [VarAccess] Companion +# 55| 3: [ExprStmt] ; +# 55| 0: [MethodAccess] setNonStaticProp(...) +# 55| -1: [VarAccess] Companion +# 55| 0: [MethodAccess] getStaticProp(...) +# 55| -1: [VarAccess] Companion +# 56| 4: [ExprStmt] ; +# 56| 0: [MethodAccess] setPropWithStaticGetter(...) +# 56| -1: [VarAccess] Companion +# 56| 0: [MethodAccess] getPropWithStaticSetter(...) +# 56| -1: [VarAccess] Companion +# 57| 5: [ExprStmt] ; +# 57| 0: [MethodAccess] setPropWithStaticSetter(...) +# 57| -1: [VarAccess] Companion +# 57| 0: [MethodAccess] getPropWithStaticGetter(...) +# 57| -1: [VarAccess] Companion +# 60| 6: [ExprStmt] ; +# 60| 0: [ImplicitCoercionToUnitExpr] +# 60| 0: [TypeAccess] Unit +# 60| 1: [MethodAccess] staticMethod(...) +# 60| -1: [TypeAccess] NonCompanion +# 60| 0: [StringLiteral] 1 +# 61| 7: [ExprStmt] ; +# 61| 0: [ImplicitCoercionToUnitExpr] +# 61| 0: [TypeAccess] Unit +# 61| 1: [MethodAccess] nonStaticMethod(...) +# 61| -1: [VarAccess] INSTANCE +# 61| 0: [StringLiteral] 2 +# 62| 8: [ExprStmt] ; +# 62| 0: [MethodAccess] setStaticProp(...) +# 62| -1: [TypeAccess] NonCompanion +# 62| 0: [MethodAccess] getNonStaticProp(...) +# 62| -1: [VarAccess] INSTANCE +# 63| 9: [ExprStmt] ; +# 63| 0: [MethodAccess] setNonStaticProp(...) +# 63| -1: [VarAccess] INSTANCE +# 63| 0: [MethodAccess] getStaticProp(...) +# 63| -1: [TypeAccess] NonCompanion +# 64| 10: [ExprStmt] ; +# 64| 0: [MethodAccess] setPropWithStaticGetter(...) +# 64| -1: [VarAccess] INSTANCE +# 64| 0: [MethodAccess] getPropWithStaticSetter(...) +# 64| -1: [VarAccess] INSTANCE +# 65| 11: [ExprStmt] ; +# 65| 0: [MethodAccess] setPropWithStaticSetter(...) +# 65| -1: [TypeAccess] NonCompanion +# 65| 0: [MethodAccess] getPropWithStaticGetter(...) +# 65| -1: [TypeAccess] NonCompanion +# 9| 2: [Class] HasCompanion +#-----| -3: (Annotations) +# 9| 2: [Constructor] HasCompanion +# 9| 5: [BlockStmt] { ... } +# 9| 0: [SuperConstructorInvocationStmt] super(...) +# 9| 1: [BlockStmt] { ... } +# 11| 3: [Class] Companion +#-----| -3: (Annotations) +# 11| 1: [Constructor] Companion +# 11| 5: [BlockStmt] { ... } +# 11| 0: [SuperConstructorInvocationStmt] super(...) +# 11| 1: [BlockStmt] { ... } +# 16| 0: [ExprStmt] ; +# 16| 0: [KtInitializerAssignExpr] ...=... +# 16| 0: [VarAccess] staticProp +# 17| 1: [ExprStmt] ; +# 17| 0: [KtInitializerAssignExpr] ...=... +# 17| 0: [VarAccess] nonStaticProp +# 13| 2: [Method] staticMethod +#-----| 1: (Annotations) +# 13| 3: [TypeAccess] String +#-----| 4: (Parameters) +# 13| 0: [Parameter] s +#-----| -1: (Annotations) +# 13| 0: [TypeAccess] String +# 13| 5: [BlockStmt] { ... } +# 13| 0: [ReturnStmt] return ... +# 13| 0: [MethodAccess] nonStaticMethod(...) +# 13| -1: [ThisAccess] this +# 13| 0: [VarAccess] s +# 14| 3: [Method] nonStaticMethod +#-----| 1: (Annotations) +# 14| 3: [TypeAccess] String +#-----| 4: (Parameters) +# 14| 0: [Parameter] s +#-----| -1: (Annotations) +# 14| 0: [TypeAccess] String +# 14| 5: [BlockStmt] { ... } +# 14| 0: [ReturnStmt] return ... +# 14| 0: [MethodAccess] staticMethod(...) +# 14| -1: [ThisAccess] this +# 14| 0: [VarAccess] s +# 16| 4: [FieldDeclaration] String staticProp; +# 16| -1: [TypeAccess] String +# 16| 0: [StringLiteral] a +# 16| 5: [Method] getStaticProp +#-----| 1: (Annotations) +# 16| 3: [TypeAccess] String +# 16| 5: [BlockStmt] { ... } +# 16| 0: [ReturnStmt] return ... +# 16| 0: [VarAccess] this.staticProp +# 16| -1: [ThisAccess] this +# 16| 5: [Method] setStaticProp +# 16| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 16| 0: [Parameter] +#-----| -1: (Annotations) +# 16| 0: [TypeAccess] String +# 16| 5: [BlockStmt] { ... } +# 16| 0: [ExprStmt] ; +# 16| 0: [AssignExpr] ...=... +# 16| 0: [VarAccess] this.staticProp +# 16| -1: [ThisAccess] this +# 16| 1: [VarAccess] +# 17| 7: [Method] getNonStaticProp +#-----| 1: (Annotations) +# 17| 3: [TypeAccess] String +# 17| 5: [BlockStmt] { ... } +# 17| 0: [ReturnStmt] return ... +# 17| 0: [VarAccess] this.nonStaticProp +# 17| -1: [ThisAccess] this +# 17| 7: [Method] setNonStaticProp +# 17| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 17| 0: [Parameter] +#-----| -1: (Annotations) +# 17| 0: [TypeAccess] String +# 17| 5: [BlockStmt] { ... } +# 17| 0: [ExprStmt] ; +# 17| 0: [AssignExpr] ...=... +# 17| 0: [VarAccess] this.nonStaticProp +# 17| -1: [ThisAccess] this +# 17| 1: [VarAccess] +# 17| 7: [FieldDeclaration] String nonStaticProp; +# 17| -1: [TypeAccess] String +# 17| 0: [StringLiteral] b +# 20| 10: [Method] getPropWithStaticGetter +#-----| 1: (Annotations) +# 20| 3: [TypeAccess] String +# 20| 5: [BlockStmt] { ... } +# 20| 0: [ReturnStmt] return ... +# 20| 0: [MethodAccess] getPropWithStaticSetter(...) +# 20| -1: [ThisAccess] this +# 21| 11: [Method] setPropWithStaticGetter +# 21| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 21| 0: [Parameter] s +#-----| -1: (Annotations) +# 21| 0: [TypeAccess] String +# 21| 5: [BlockStmt] { ... } +# 21| 0: [ExprStmt] ; +# 21| 0: [MethodAccess] setPropWithStaticSetter(...) +# 21| -1: [ThisAccess] this +# 21| 0: [VarAccess] s +# 24| 12: [Method] getPropWithStaticSetter +#-----| 1: (Annotations) +# 24| 3: [TypeAccess] String +# 24| 5: [BlockStmt] { ... } +# 24| 0: [ReturnStmt] return ... +# 24| 0: [MethodAccess] getPropWithStaticGetter(...) +# 24| -1: [ThisAccess] this +# 25| 13: [Method] setPropWithStaticSetter +#-----| 1: (Annotations) +# 25| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 25| 0: [Parameter] s +#-----| -1: (Annotations) +# 25| 0: [TypeAccess] String +# 25| 5: [BlockStmt] { ... } +# 25| 0: [ExprStmt] ; +# 25| 0: [MethodAccess] setPropWithStaticGetter(...) +# 25| -1: [ThisAccess] this +# 25| 0: [VarAccess] s +# 13| 4: [Method] staticMethod +#-----| 1: (Annotations) +# 13| 3: [TypeAccess] String +#-----| 4: (Parameters) +# 13| 0: [Parameter] s +#-----| -1: (Annotations) +# 13| 0: [TypeAccess] String +# 13| 5: [BlockStmt] { ... } +# 13| 0: [ReturnStmt] return ... +# 13| 0: [MethodAccess] staticMethod(...) +# 13| -1: [VarAccess] HasCompanion.Companion +# 13| -1: [TypeAccess] HasCompanion +# 13| 0: [VarAccess] s +# 16| 5: [Method] setStaticProp +# 16| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 16| 0: [Parameter] +#-----| -1: (Annotations) +# 16| 0: [TypeAccess] String +# 16| 5: [BlockStmt] { ... } +# 16| 0: [ReturnStmt] return ... +# 16| 0: [MethodAccess] setStaticProp(...) +# 16| -1: [VarAccess] HasCompanion.Companion +# 16| -1: [TypeAccess] HasCompanion +# 16| 0: [VarAccess] +# 16| 5: [Method] getStaticProp +#-----| 1: (Annotations) +# 16| 3: [TypeAccess] String +# 16| 5: [BlockStmt] { ... } +# 16| 0: [ReturnStmt] return ... +# 16| 0: [MethodAccess] getStaticProp(...) +# 16| -1: [VarAccess] HasCompanion.Companion +# 16| -1: [TypeAccess] HasCompanion +# 20| 7: [Method] getPropWithStaticGetter +#-----| 1: (Annotations) +# 20| 3: [TypeAccess] String +# 20| 5: [BlockStmt] { ... } +# 20| 0: [ReturnStmt] return ... +# 20| 0: [MethodAccess] getPropWithStaticGetter(...) +# 20| -1: [VarAccess] HasCompanion.Companion +# 20| -1: [TypeAccess] HasCompanion +# 25| 8: [Method] setPropWithStaticSetter +#-----| 1: (Annotations) +# 25| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 25| 0: [Parameter] s +#-----| -1: (Annotations) +# 25| 0: [TypeAccess] String +# 25| 5: [BlockStmt] { ... } +# 25| 0: [ReturnStmt] return ... +# 25| 0: [MethodAccess] setPropWithStaticSetter(...) +# 25| -1: [VarAccess] HasCompanion.Companion +# 25| -1: [TypeAccess] HasCompanion +# 25| 0: [VarAccess] s +# 31| 3: [Class] NonCompanion +#-----| -3: (Annotations) +# 31| 2: [Constructor] NonCompanion +# 31| 5: [BlockStmt] { ... } +# 31| 0: [SuperConstructorInvocationStmt] super(...) +# 31| 1: [BlockStmt] { ... } +# 36| 0: [ExprStmt] ; +# 36| 0: [KtInitializerAssignExpr] ...=... +# 36| 0: [VarAccess] staticProp +# 37| 1: [ExprStmt] ; +# 37| 0: [KtInitializerAssignExpr] ...=... +# 37| 0: [VarAccess] nonStaticProp +# 33| 3: [Method] staticMethod +#-----| 1: (Annotations) +# 33| 3: [TypeAccess] String +#-----| 4: (Parameters) +# 33| 0: [Parameter] s +#-----| -1: (Annotations) +# 33| 0: [TypeAccess] String +# 33| 5: [BlockStmt] { ... } +# 33| 0: [ReturnStmt] return ... +# 33| 0: [MethodAccess] nonStaticMethod(...) +# 33| -1: [VarAccess] NonCompanion.INSTANCE +# 33| -1: [TypeAccess] NonCompanion +# 33| 0: [VarAccess] s +# 34| 4: [Method] nonStaticMethod +#-----| 1: (Annotations) +# 34| 3: [TypeAccess] String +#-----| 4: (Parameters) +# 34| 0: [Parameter] s +#-----| -1: (Annotations) +# 34| 0: [TypeAccess] String +# 34| 5: [BlockStmt] { ... } +# 34| 0: [ReturnStmt] return ... +# 34| 0: [MethodAccess] staticMethod(...) +# 34| -1: [TypeAccess] NonCompanion +# 34| 0: [VarAccess] s +# 36| 5: [FieldDeclaration] String staticProp; +# 36| -1: [TypeAccess] String +# 36| 0: [StringLiteral] a +# 36| 6: [Method] setStaticProp +# 36| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 36| 0: [Parameter] +#-----| -1: (Annotations) +# 36| 0: [TypeAccess] String +# 36| 5: [BlockStmt] { ... } +# 36| 0: [ExprStmt] ; +# 36| 0: [AssignExpr] ...=... +# 36| 0: [VarAccess] NonCompanion.INSTANCE.staticProp +# 36| -1: [VarAccess] NonCompanion.INSTANCE +# 36| -1: [TypeAccess] NonCompanion +# 36| 1: [VarAccess] +# 36| 6: [Method] getStaticProp +#-----| 1: (Annotations) +# 36| 3: [TypeAccess] String +# 36| 5: [BlockStmt] { ... } +# 36| 0: [ReturnStmt] return ... +# 36| 0: [VarAccess] NonCompanion.INSTANCE.staticProp +# 36| -1: [VarAccess] NonCompanion.INSTANCE +# 36| -1: [TypeAccess] NonCompanion +# 37| 8: [Method] getNonStaticProp +#-----| 1: (Annotations) +# 37| 3: [TypeAccess] String +# 37| 5: [BlockStmt] { ... } +# 37| 0: [ReturnStmt] return ... +# 37| 0: [VarAccess] this.nonStaticProp +# 37| -1: [ThisAccess] this +# 37| 8: [Method] setNonStaticProp +# 37| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 37| 0: [Parameter] +#-----| -1: (Annotations) +# 37| 0: [TypeAccess] String +# 37| 5: [BlockStmt] { ... } +# 37| 0: [ExprStmt] ; +# 37| 0: [AssignExpr] ...=... +# 37| 0: [VarAccess] this.nonStaticProp +# 37| -1: [ThisAccess] this +# 37| 1: [VarAccess] +# 37| 8: [FieldDeclaration] String nonStaticProp; +# 37| -1: [TypeAccess] String +# 37| 0: [StringLiteral] b +# 40| 11: [Method] getPropWithStaticGetter +#-----| 1: (Annotations) +# 40| 3: [TypeAccess] String +# 40| 5: [BlockStmt] { ... } +# 40| 0: [ReturnStmt] return ... +# 40| 0: [MethodAccess] getPropWithStaticSetter(...) +# 40| -1: [VarAccess] NonCompanion.INSTANCE +# 40| -1: [TypeAccess] NonCompanion +# 41| 12: [Method] setPropWithStaticGetter +# 41| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 41| 0: [Parameter] s +#-----| -1: (Annotations) +# 41| 0: [TypeAccess] String +# 41| 5: [BlockStmt] { ... } +# 41| 0: [ExprStmt] ; +# 41| 0: [MethodAccess] setPropWithStaticSetter(...) +# 41| -1: [TypeAccess] NonCompanion +# 41| 0: [VarAccess] s +# 44| 13: [Method] getPropWithStaticSetter +#-----| 1: (Annotations) +# 44| 3: [TypeAccess] String +# 44| 5: [BlockStmt] { ... } +# 44| 0: [ReturnStmt] return ... +# 44| 0: [MethodAccess] getPropWithStaticGetter(...) +# 44| -1: [TypeAccess] NonCompanion +# 45| 14: [Method] setPropWithStaticSetter +#-----| 1: (Annotations) +# 45| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 45| 0: [Parameter] s +#-----| -1: (Annotations) +# 45| 0: [TypeAccess] String +# 45| 5: [BlockStmt] { ... } +# 45| 0: [ExprStmt] ; +# 45| 0: [MethodAccess] setPropWithStaticGetter(...) +# 45| -1: [VarAccess] NonCompanion.INSTANCE +# 45| -1: [TypeAccess] NonCompanion +# 45| 0: [VarAccess] s diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.qlref b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.qlref new file mode 100644 index 00000000000..c7fd5faf239 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.qlref @@ -0,0 +1 @@ +semmle/code/java/PrintAst.ql \ No newline at end of file From 0e56e50d189f89e15470d985bbe4d043bb6fd9be Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Thu, 30 Jun 2022 13:50:22 +0100 Subject: [PATCH 221/465] Kotlin: Replace a map call with forEach --- java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index b82b71faccf..d48acf2da61 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -80,7 +80,7 @@ open class KotlinFileExtractor( } } - file.declarations.map { extractDeclaration(it, extractPrivateMembers = true, extractFunctionBodies = true) } + file.declarations.forEach { extractDeclaration(it, extractPrivateMembers = true, extractFunctionBodies = true) } extractStaticInitializer(file, null) CommentExtractor(this, file, tw.fileId).extract() } From df7ffb28806d0c1e136229b0ff5c3ca1f25d9c58 Mon Sep 17 00:00:00 2001 From: yoff Date: Thu, 30 Jun 2022 14:53:49 +0200 Subject: [PATCH 222/465] Update python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll Co-authored-by: Rasmus Wriedt Larsen --- .../python/security/dataflow/TarSlipCustomizations.qll | 7 ------- 1 file changed, 7 deletions(-) diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll index 8e742c61288..22788453ebf 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll @@ -31,13 +31,6 @@ module TarSlip { */ abstract class Sanitizer extends DataFlow::Node { } - /** - * DEPRECATED: Use `Sanitizer` instead. - * - * A sanitizer guard for "tar slip" vulnerabilities. - */ - abstract deprecated class SanitizerGuard extends DataFlow::BarrierGuard { } - /** * A call to `tarfile.open`, considered as a flow source. */ From b0a29b146a7d7ca4fec773298f1851de77411fc0 Mon Sep 17 00:00:00 2001 From: yoff Date: Thu, 30 Jun 2022 14:54:01 +0200 Subject: [PATCH 223/465] Update python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll Co-authored-by: Rasmus Wriedt Larsen --- .../ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll | 4 ---- 1 file changed, 4 deletions(-) diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll index e69d63fedbc..6cf41742a66 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipQuery.qll @@ -22,8 +22,4 @@ class Configuration extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } override predicate isSanitizer(DataFlow::Node node) { node instanceof Sanitizer } - - deprecated override predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { - guard instanceof SanitizerGuard - } } From cf9b69b5f24d295f1d1dd7ecc2eac029b0c421b9 Mon Sep 17 00:00:00 2001 From: yoff Date: Thu, 30 Jun 2022 13:07:13 +0000 Subject: [PATCH 224/465] python: More helpful comment --- .../semmle/python/security/dataflow/TarSlipCustomizations.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll index 22788453ebf..1a3df320358 100644 --- a/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/TarSlipCustomizations.qll @@ -119,7 +119,7 @@ module TarSlip { attr.getName() = "name" and attr.getObject() = tarInfo | - // Assume that any test with "path" in it is a sanitizer + // The assumption that any test that matches %path is a sanitizer might be too broad. call.getAChild*().(AttrNode).getName().matches("%path") or call.getAChild*().(NameNode).getId().matches("%path") From eaec1ac56181722200be70fff1e933766cde4585 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Thu, 30 Jun 2022 15:11:49 +0200 Subject: [PATCH 225/465] add change-note --- javascript/ql/lib/change-notes/2022-06-30-chownr.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 javascript/ql/lib/change-notes/2022-06-30-chownr.md diff --git a/javascript/ql/lib/change-notes/2022-06-30-chownr.md b/javascript/ql/lib/change-notes/2022-06-30-chownr.md new file mode 100644 index 00000000000..1ad13fb8113 --- /dev/null +++ b/javascript/ql/lib/change-notes/2022-06-30-chownr.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The `chownr` library is now modeled as a sink for the `js/path-injection` query. From 0d0d240fd4272cac927c84945a5075869a3b7f69 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 30 Jun 2022 15:29:20 +0100 Subject: [PATCH 226/465] Accept test changes re: new compiler-generated nodes --- .../test/kotlin/library-tests/reflection/reflection.expected | 3 +++ 1 file changed, 3 insertions(+) diff --git a/java/ql/test/kotlin/library-tests/reflection/reflection.expected b/java/ql/test/kotlin/library-tests/reflection/reflection.expected index 1e249da402d..9b6899f4b6e 100644 --- a/java/ql/test/kotlin/library-tests/reflection/reflection.expected +++ b/java/ql/test/kotlin/library-tests/reflection/reflection.expected @@ -232,6 +232,9 @@ modifiers compGenerated | file:///Class2.class:0:0:0:0 | getValue | 3 | | file:///Class2.class:0:0:0:0 | getValue | 3 | +| file:///KTypeProjection.class:0:0:0:0 | contravariant | 8 | +| file:///KTypeProjection.class:0:0:0:0 | covariant | 8 | +| file:///KTypeProjection.class:0:0:0:0 | invariant | 8 | | reflection.kt:33:9:33:23 | getP0 | 3 | | reflection.kt:34:9:34:23 | getP1 | 3 | | reflection.kt:34:9:34:23 | setP1 | 3 | From ec95cbace42471066863f3442b697e24bfd7d022 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 30 Jun 2022 15:29:56 +0100 Subject: [PATCH 227/465] PrintAst: Tie-break multiple class members created at the same source location Otherwise Kotlin introducing a getter, setter and field declaration based on the same property tied in the sort order, and so could be output in different orders on different machines. --- java/ql/lib/semmle/code/java/PrintAst.qll | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/PrintAst.qll b/java/ql/lib/semmle/code/java/PrintAst.qll index 05453baa045..d6e263e778a 100644 --- a/java/ql/lib/semmle/code/java/PrintAst.qll +++ b/java/ql/lib/semmle/code/java/PrintAst.qll @@ -534,10 +534,12 @@ final class ClassInterfaceNode extends ElementNode { or childIndex >= 0 and result.(ElementNode).getElement() = - rank[childIndex](Element e, string file, int line, int column | - e = this.getADeclaration() and locationSortKeys(e, file, line, column) + rank[childIndex](Element e, string file, int line, int column, string childStr | + e = this.getADeclaration() and + locationSortKeys(e, file, line, column) and + childStr = result.toString() | - e order by file, line, column + e order by file, line, column, childStr ) } } From 570e418b22ff1e22a7ffc38795188a0389e053b3 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 30 Jun 2022 16:07:32 +0100 Subject: [PATCH 228/465] Fix ordering PrintAst nodes --- java/ql/lib/semmle/code/java/PrintAst.qll | 2 +- .../library-tests/classes/PrintAst.expected | 122 +- .../data-classes/PrintAst.expected | 104 +- .../library-tests/exprs/PrintAst.expected | 1134 ++++++++--------- .../exprs_typeaccess/PrintAst.expected | 10 +- .../library-tests/generics/PrintAst.expected | 8 +- .../jvmstatic-annotation/PrintAst.expected | 58 +- .../reflection/PrintAst.expected | 182 +-- 8 files changed, 810 insertions(+), 810 deletions(-) diff --git a/java/ql/lib/semmle/code/java/PrintAst.qll b/java/ql/lib/semmle/code/java/PrintAst.qll index d6e263e778a..9d88550faa3 100644 --- a/java/ql/lib/semmle/code/java/PrintAst.qll +++ b/java/ql/lib/semmle/code/java/PrintAst.qll @@ -537,7 +537,7 @@ final class ClassInterfaceNode extends ElementNode { rank[childIndex](Element e, string file, int line, int column, string childStr | e = this.getADeclaration() and locationSortKeys(e, file, line, column) and - childStr = result.toString() + childStr = e.toString() | e order by file, line, column, childStr ) diff --git a/java/ql/test/kotlin/library-tests/classes/PrintAst.expected b/java/ql/test/kotlin/library-tests/classes/PrintAst.expected index 0346a4e0292..1ba8a3396bf 100644 --- a/java/ql/test/kotlin/library-tests/classes/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/classes/PrintAst.expected @@ -32,7 +32,7 @@ classes.kt: # 4| 0: [ReturnStmt] return ... # 4| 0: [VarAccess] this.arg # 4| -1: [ThisAccess] this -# 4| 2: [FieldDeclaration] int arg; +# 4| 3: [FieldDeclaration] int arg; # 4| -1: [TypeAccess] int # 4| 0: [VarAccess] arg # 5| 4: [Method] getX @@ -41,7 +41,7 @@ classes.kt: # 5| 0: [ReturnStmt] return ... # 5| 0: [VarAccess] this.x # 5| -1: [ThisAccess] this -# 5| 4: [FieldDeclaration] int x; +# 5| 5: [FieldDeclaration] int x; # 5| -1: [TypeAccess] int # 5| 0: [IntegerLiteral] 3 # 8| 4: [Class] ClassThree @@ -118,18 +118,18 @@ classes.kt: # 42| 0: [ReturnStmt] return ... # 42| 0: [VarAccess] this.x # 42| -1: [ThisAccess] this -# 42| 2: [FieldDeclaration] int x; +# 42| 3: [FieldDeclaration] int x; # 42| -1: [TypeAccess] int # 42| 0: [IntegerLiteral] 3 # 49| 11: [Class] Direction -# 0| 1: [Method] values -# 0| 3: [TypeAccess] Direction[] -# 0| 0: [TypeAccess] Direction -# 0| 1: [Method] valueOf +# 0| 2: [Method] valueOf # 0| 3: [TypeAccess] Direction #-----| 4: (Parameters) # 0| 0: [Parameter] value # 0| 0: [TypeAccess] String +# 0| 3: [Method] values +# 0| 3: [TypeAccess] Direction[] +# 0| 0: [TypeAccess] Direction # 49| 4: [Constructor] Direction # 49| 5: [BlockStmt] { ... } # 49| 0: [ExprStmt] ; @@ -154,14 +154,14 @@ classes.kt: # 50| 0: [ClassInstanceExpr] new Direction(...) # 50| -3: [TypeAccess] Direction # 53| 12: [Class] Color -# 0| 1: [Method] values -# 0| 3: [TypeAccess] Color[] -# 0| 0: [TypeAccess] Color -# 0| 1: [Method] valueOf +# 0| 2: [Method] valueOf # 0| 3: [TypeAccess] Color #-----| 4: (Parameters) # 0| 0: [Parameter] value # 0| 0: [TypeAccess] String +# 0| 3: [Method] values +# 0| 3: [TypeAccess] Color[] +# 0| 0: [TypeAccess] Color # 53| 4: [Constructor] Color #-----| 4: (Parameters) # 53| 0: [Parameter] rgb @@ -181,7 +181,7 @@ classes.kt: # 53| 0: [ReturnStmt] return ... # 53| 0: [VarAccess] this.rgb # 53| -1: [ThisAccess] this -# 53| 5: [FieldDeclaration] int rgb; +# 53| 6: [FieldDeclaration] int rgb; # 53| -1: [TypeAccess] int # 53| 0: [VarAccess] rgb # 54| 7: [FieldDeclaration] Color RED; @@ -266,7 +266,7 @@ classes.kt: # 73| 0: [ReturnStmt] return ... # 73| 0: [VarAccess] this.x # 73| -1: [ThisAccess] this -# 73| 2: [FieldDeclaration] int x; +# 73| 3: [FieldDeclaration] int x; # 73| -1: [TypeAccess] int # 73| 0: [IntegerLiteral] 1 # 74| 4: [Method] foo @@ -434,7 +434,7 @@ classes.kt: # 118| 1: [Constructor] # 118| 5: [BlockStmt] { ... } # 118| 0: [SuperConstructorInvocationStmt] super(...) -# 118| 1: [Method] localFn +# 118| 2: [Method] localFn # 118| 3: [TypeAccess] Unit # 118| 5: [BlockStmt] { ... } # 119| 0: [LocalTypeDeclStmt] class ... @@ -541,15 +541,15 @@ generic_anonymous.kt: # 3| 1: [ExprStmt] ; # 3| 0: [KtInitializerAssignExpr] ...=... # 3| 0: [VarAccess] x -# 1| 2: [Method] getT +# 1| 2: [FieldDeclaration] T t; +# 1| -1: [TypeAccess] T +# 1| 0: [VarAccess] t +# 1| 3: [Method] getT # 1| 3: [TypeAccess] T # 1| 5: [BlockStmt] { ... } # 1| 0: [ReturnStmt] return ... # 1| 0: [VarAccess] this.t # 1| -1: [ThisAccess] this -# 1| 2: [FieldDeclaration] T t; -# 1| -1: [TypeAccess] T -# 1| 0: [VarAccess] t # 3| 4: [FieldDeclaration] new Object(...) { ... } x; # 3| -1: [TypeAccess] new Object(...) { ... } # 3| 0: [TypeAccess] T @@ -564,17 +564,17 @@ generic_anonymous.kt: # 4| 0: [ExprStmt] ; # 4| 0: [KtInitializerAssignExpr] ...=... # 4| 0: [VarAccess] member -# 4| 2: [Method] getMember -# 4| 3: [TypeAccess] T -# 4| 5: [BlockStmt] { ... } -# 4| 0: [ReturnStmt] return ... -# 4| 0: [VarAccess] this.member -# 4| -1: [ThisAccess] this # 4| 2: [FieldDeclaration] T member; # 4| -1: [TypeAccess] T # 4| 0: [MethodAccess] getT(...) # 4| -1: [ThisAccess] Generic.this # 4| 0: [TypeAccess] Generic +# 4| 3: [Method] getMember +# 4| 3: [TypeAccess] T +# 4| 5: [BlockStmt] { ... } +# 4| 0: [ReturnStmt] return ... +# 4| 0: [VarAccess] this.member +# 4| -1: [ThisAccess] this # 3| 1: [ExprStmt] ; # 3| 0: [ClassInstanceExpr] new (...) # 3| -3: [TypeAccess] Object @@ -605,12 +605,6 @@ localClassField.kt: # 7| 1: [ExprStmt] ; # 7| 0: [KtInitializerAssignExpr] ...=... # 7| 0: [VarAccess] y -# 2| 2: [Method] getX -# 2| 3: [TypeAccess] Object -# 2| 5: [BlockStmt] { ... } -# 2| 0: [ReturnStmt] return ... -# 2| 0: [VarAccess] this.x -# 2| -1: [ThisAccess] this # 2| 2: [FieldDeclaration] Object x; # 2| -1: [TypeAccess] Object # 2| 0: [WhenExpr] when ... @@ -629,12 +623,12 @@ localClassField.kt: # 2| 1: [WhenBranch] ... -> ... # 2| 0: [BooleanLiteral] true # 5| 1: [BlockStmt] { ... } -# 7| 4: [Method] getY -# 7| 3: [TypeAccess] Object -# 7| 5: [BlockStmt] { ... } -# 7| 0: [ReturnStmt] return ... -# 7| 0: [VarAccess] this.y -# 7| -1: [ThisAccess] this +# 2| 3: [Method] getX +# 2| 3: [TypeAccess] Object +# 2| 5: [BlockStmt] { ... } +# 2| 0: [ReturnStmt] return ... +# 2| 0: [VarAccess] this.x +# 2| -1: [ThisAccess] this # 7| 4: [FieldDeclaration] Object y; # 7| -1: [TypeAccess] Object # 7| 0: [WhenExpr] when ... @@ -653,6 +647,12 @@ localClassField.kt: # 7| 1: [WhenBranch] ... -> ... # 7| 0: [BooleanLiteral] true # 10| 1: [BlockStmt] { ... } +# 7| 5: [Method] getY +# 7| 3: [TypeAccess] Object +# 7| 5: [BlockStmt] { ... } +# 7| 0: [ReturnStmt] return ... +# 7| 0: [VarAccess] this.y +# 7| -1: [ThisAccess] this local_anonymous.kt: # 0| [CompilationUnit] local_anonymous # 3| 1: [Class] Class1 @@ -686,7 +686,7 @@ local_anonymous.kt: # 11| 1: [Constructor] # 11| 5: [BlockStmt] { ... } # 11| 0: [SuperConstructorInvocationStmt] super(...) -# 11| 1: [Method] fnLocal +# 11| 2: [Method] fnLocal # 11| 3: [TypeAccess] Unit # 11| 5: [BlockStmt] { ... } # 12| 1: [ExprStmt] ; @@ -703,7 +703,7 @@ local_anonymous.kt: # 16| 1: [Constructor] # 16| 5: [BlockStmt] { ... } # 16| 0: [SuperConstructorInvocationStmt] super(...) -# 16| 1: [Method] invoke +# 16| 2: [Method] invoke # 16| 3: [TypeAccess] int #-----| 4: (Parameters) # 16| 0: [Parameter] a @@ -726,7 +726,7 @@ local_anonymous.kt: # 17| 1: [Constructor] # 17| 5: [BlockStmt] { ... } # 17| 0: [SuperConstructorInvocationStmt] super(...) -# 17| 1: [Method] invoke +# 17| 2: [Method] invoke # 17| 3: [TypeAccess] int #-----| 4: (Parameters) # 17| 0: [Parameter] a @@ -752,7 +752,7 @@ local_anonymous.kt: # 21| 1: [Constructor] # 21| 5: [BlockStmt] { ... } # 21| 0: [SuperConstructorInvocationStmt] super(...) -# 21| 1: [Method] invoke +# 21| 2: [Method] invoke #-----| 4: (Parameters) # 21| 0: [Parameter] a0 # 21| 5: [BlockStmt] { ... } @@ -797,7 +797,10 @@ local_anonymous.kt: # 30| 0: [ReturnStmt] return ... # 30| 0: [VarAccess] this.x # 30| -1: [ThisAccess] this -# 30| 2: [Method] setX +# 30| 3: [FieldDeclaration] int x; +# 30| -1: [TypeAccess] int +# 30| 0: [IntegerLiteral] 1 +# 30| 4: [Method] setX # 30| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 30| 0: [Parameter] @@ -808,9 +811,6 @@ local_anonymous.kt: # 30| 0: [VarAccess] this.x # 30| -1: [ThisAccess] this # 30| 1: [VarAccess] -# 30| 2: [FieldDeclaration] int x; -# 30| -1: [TypeAccess] int -# 30| 0: [IntegerLiteral] 1 # 32| 5: [Method] member # 32| 3: [TypeAccess] Unit # 32| 5: [BlockStmt] { ... } @@ -840,23 +840,6 @@ local_anonymous.kt: # 40| 0: [ExprStmt] ; # 40| 0: [KtInitializerAssignExpr] ...=... # 40| 0: [VarAccess] i -# 40| 2: [Method] getI -# 40| 3: [TypeAccess] Interface2 -# 40| 5: [BlockStmt] { ... } -# 40| 0: [ReturnStmt] return ... -# 40| 0: [VarAccess] this.i -# 40| -1: [ThisAccess] this -# 40| 2: [Method] setI -# 40| 3: [TypeAccess] Unit -#-----| 4: (Parameters) -# 40| 0: [Parameter] -# 40| 0: [TypeAccess] Interface2 -# 40| 5: [BlockStmt] { ... } -# 40| 0: [ExprStmt] ; -# 40| 0: [AssignExpr] ...=... -# 40| 0: [VarAccess] this.i -# 40| -1: [ThisAccess] this -# 40| 1: [VarAccess] # 40| 2: [FieldDeclaration] Interface2 i; # 40| -1: [TypeAccess] Interface2 # 40| 0: [StmtExpr] @@ -873,6 +856,23 @@ local_anonymous.kt: # 40| 1: [ExprStmt] ; # 40| 0: [ClassInstanceExpr] new (...) # 40| -3: [TypeAccess] Interface2 +# 40| 3: [Method] getI +# 40| 3: [TypeAccess] Interface2 +# 40| 5: [BlockStmt] { ... } +# 40| 0: [ReturnStmt] return ... +# 40| 0: [VarAccess] this.i +# 40| -1: [ThisAccess] this +# 40| 4: [Method] setI +# 40| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 40| 0: [Parameter] +# 40| 0: [TypeAccess] Interface2 +# 40| 5: [BlockStmt] { ... } +# 40| 0: [ExprStmt] ; +# 40| 0: [AssignExpr] ...=... +# 40| 0: [VarAccess] this.i +# 40| -1: [ThisAccess] this +# 40| 1: [VarAccess] superChain.kt: # 0| [CompilationUnit] superChain # 1| 1: [Class,GenericType,ParameterizedType] SuperChain1 diff --git a/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected b/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected index 06f6a78ce60..aa31626daeb 100644 --- a/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/data-classes/PrintAst.expected @@ -7,14 +7,14 @@ dc.kt: # 0| 0: [ReturnStmt] return ... # 0| 0: [VarAccess] this.bytes # 0| -1: [ThisAccess] this -# 0| 1: [Method] component2 +# 0| 2: [Method] component2 # 0| 3: [TypeAccess] String[] # 0| 0: [TypeAccess] String # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... # 0| 0: [VarAccess] this.strs # 0| -1: [ThisAccess] this -# 0| 1: [Method] copy +# 0| 3: [Method] copy # 0| 3: [TypeAccess] ProtoMapValue #-----| 4: (Parameters) # 1| 0: [Parameter] bytes @@ -28,47 +28,7 @@ dc.kt: # 0| -3: [TypeAccess] ProtoMapValue # 0| 0: [VarAccess] bytes # 0| 1: [VarAccess] strs -# 0| 1: [Method] toString -# 0| 3: [TypeAccess] String -# 0| 5: [BlockStmt] { ... } -# 0| 0: [ReturnStmt] return ... -# 0| 0: [StringTemplateExpr] "..." -# 0| 0: [StringLiteral] ProtoMapValue( -# 0| 1: [StringLiteral] bytes= -# 0| 2: [MethodAccess] toString(...) -# 0| -1: [TypeAccess] Arrays -# 0| 0: [VarAccess] this.bytes -# 0| -1: [ThisAccess] this -# 0| 3: [StringLiteral] , -# 0| 4: [StringLiteral] strs= -# 0| 5: [MethodAccess] toString(...) -# 0| -1: [TypeAccess] Arrays -# 0| 0: [VarAccess] this.strs -# 0| -1: [ThisAccess] this -# 0| 6: [StringLiteral] ) -# 0| 1: [Method] hashCode -# 0| 3: [TypeAccess] int -# 0| 5: [BlockStmt] { ... } -# 0| 0: [LocalVariableDeclStmt] var ...; -# 0| 1: [LocalVariableDeclExpr] result -# 0| 0: [MethodAccess] hashCode(...) -# 0| -1: [TypeAccess] Arrays -# 0| 0: [VarAccess] this.bytes -# 0| -1: [ThisAccess] this -# 0| 1: [ExprStmt] ; -# 0| 0: [AssignExpr] ...=... -# 0| 0: [VarAccess] result -# 0| 1: [MethodAccess] plus(...) -# 0| -1: [MethodAccess] times(...) -# 0| -1: [VarAccess] result -# 0| 0: [IntegerLiteral] 31 -# 0| 0: [MethodAccess] hashCode(...) -# 0| -1: [TypeAccess] Arrays -# 0| 0: [VarAccess] this.strs -# 0| -1: [ThisAccess] this -# 0| 2: [ReturnStmt] return ... -# 0| 0: [VarAccess] result -# 0| 1: [Method] equals +# 0| 4: [Method] equals # 0| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 0| 0: [Parameter] other @@ -117,6 +77,46 @@ dc.kt: # 0| 0: [BooleanLiteral] false # 0| 5: [ReturnStmt] return ... # 0| 0: [BooleanLiteral] true +# 0| 5: [Method] hashCode +# 0| 3: [TypeAccess] int +# 0| 5: [BlockStmt] { ... } +# 0| 0: [LocalVariableDeclStmt] var ...; +# 0| 1: [LocalVariableDeclExpr] result +# 0| 0: [MethodAccess] hashCode(...) +# 0| -1: [TypeAccess] Arrays +# 0| 0: [VarAccess] this.bytes +# 0| -1: [ThisAccess] this +# 0| 1: [ExprStmt] ; +# 0| 0: [AssignExpr] ...=... +# 0| 0: [VarAccess] result +# 0| 1: [MethodAccess] plus(...) +# 0| -1: [MethodAccess] times(...) +# 0| -1: [VarAccess] result +# 0| 0: [IntegerLiteral] 31 +# 0| 0: [MethodAccess] hashCode(...) +# 0| -1: [TypeAccess] Arrays +# 0| 0: [VarAccess] this.strs +# 0| -1: [ThisAccess] this +# 0| 2: [ReturnStmt] return ... +# 0| 0: [VarAccess] result +# 0| 6: [Method] toString +# 0| 3: [TypeAccess] String +# 0| 5: [BlockStmt] { ... } +# 0| 0: [ReturnStmt] return ... +# 0| 0: [StringTemplateExpr] "..." +# 0| 0: [StringLiteral] ProtoMapValue( +# 0| 1: [StringLiteral] bytes= +# 0| 2: [MethodAccess] toString(...) +# 0| -1: [TypeAccess] Arrays +# 0| 0: [VarAccess] this.bytes +# 0| -1: [ThisAccess] this +# 0| 3: [StringLiteral] , +# 0| 4: [StringLiteral] strs= +# 0| 5: [MethodAccess] toString(...) +# 0| -1: [TypeAccess] Arrays +# 0| 0: [VarAccess] this.strs +# 0| -1: [ThisAccess] this +# 0| 6: [StringLiteral] ) # 1| 7: [Constructor] ProtoMapValue #-----| 4: (Parameters) # 1| 0: [Parameter] bytes @@ -133,23 +133,23 @@ dc.kt: # 1| 1: [ExprStmt] ; # 1| 0: [KtInitializerAssignExpr] ...=... # 1| 0: [VarAccess] strs -# 1| 8: [Method] getBytes +# 1| 8: [FieldDeclaration] byte[] bytes; +# 1| -1: [TypeAccess] byte[] +# 1| 0: [VarAccess] bytes +# 1| 9: [Method] getBytes # 1| 3: [TypeAccess] byte[] # 1| 5: [BlockStmt] { ... } # 1| 0: [ReturnStmt] return ... # 1| 0: [VarAccess] this.bytes # 1| -1: [ThisAccess] this -# 1| 8: [FieldDeclaration] byte[] bytes; -# 1| -1: [TypeAccess] byte[] -# 1| 0: [VarAccess] bytes -# 1| 10: [Method] getStrs +# 1| 10: [FieldDeclaration] String[] strs; +# 1| -1: [TypeAccess] String[] +# 1| 0: [TypeAccess] String +# 1| 0: [VarAccess] strs +# 1| 11: [Method] getStrs # 1| 3: [TypeAccess] String[] # 1| 0: [TypeAccess] String # 1| 5: [BlockStmt] { ... } # 1| 0: [ReturnStmt] return ... # 1| 0: [VarAccess] this.strs # 1| -1: [ThisAccess] this -# 1| 10: [FieldDeclaration] String[] strs; -# 1| -1: [TypeAccess] String[] -# 1| 0: [TypeAccess] String -# 1| 0: [VarAccess] strs diff --git a/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected b/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected index 8696254be8f..879eb93c94e 100644 --- a/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/exprs/PrintAst.expected @@ -7,7 +7,10 @@ delegatedProperties.kt: # 60| 0: [ReturnStmt] return ... # 60| 0: [VarAccess] DelegatedPropertiesKt.topLevelInt # 60| -1: [TypeAccess] DelegatedPropertiesKt -# 60| 2: [Method] setTopLevelInt +# 60| 3: [FieldDeclaration] int topLevelInt; +# 60| -1: [TypeAccess] int +# 60| 0: [IntegerLiteral] 0 +# 60| 4: [Method] setTopLevelInt # 60| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 60| 0: [Parameter] @@ -18,10 +21,35 @@ delegatedProperties.kt: # 60| 0: [VarAccess] DelegatedPropertiesKt.topLevelInt # 60| -1: [TypeAccess] DelegatedPropertiesKt # 60| 1: [VarAccess] -# 60| 2: [FieldDeclaration] int topLevelInt; -# 60| -1: [TypeAccess] int -# 60| 0: [IntegerLiteral] 0 -# 87| 5: [ExtensionMethod] getExtDelegated +# 87| 5: [FieldDeclaration] KMutableProperty0 extDelegated$delegateMyClass; +# 87| -1: [TypeAccess] KMutableProperty0 +# 87| 0: [TypeAccess] Integer +# 87| 0: [PropertyRefExpr] ...::... +# 87| -4: [AnonymousClass] new KMutableProperty0(...) { ... } +# 87| 1: [Constructor] +# 87| 5: [BlockStmt] { ... } +# 87| 0: [SuperConstructorInvocationStmt] super(...) +# 87| 2: [Method] get +# 87| 5: [BlockStmt] { ... } +# 87| 0: [ReturnStmt] return ... +# 87| 0: [MethodAccess] getTopLevelInt(...) +# 87| -1: [TypeAccess] DelegatedPropertiesKt +# 87| 3: [Method] invoke +# 87| 5: [BlockStmt] { ... } +# 87| 0: [ReturnStmt] return ... +# 87| 0: [MethodAccess] get(...) +# 87| -1: [ThisAccess] this +# 87| 4: [Method] set +#-----| 4: (Parameters) +# 87| 0: [Parameter] a0 +# 87| 5: [BlockStmt] { ... } +# 87| 0: [ReturnStmt] return ... +# 87| 0: [MethodAccess] setTopLevelInt(...) +# 87| -1: [TypeAccess] DelegatedPropertiesKt +# 87| 0: [VarAccess] a0 +# 87| -3: [TypeAccess] KMutableProperty0 +# 87| 0: [TypeAccess] Integer +# 87| 6: [ExtensionMethod] getExtDelegated # 87| 3: [TypeAccess] int #-----| 4: (Parameters) # 87| 0: [Parameter] @@ -39,7 +67,7 @@ delegatedProperties.kt: # 87| 1: [Constructor] # 87| 5: [BlockStmt] { ... } # 87| 0: [SuperConstructorInvocationStmt] super(...) -# 87| 1: [Method] get +# 87| 2: [Method] get #-----| 4: (Parameters) # 87| 0: [Parameter] a0 # 87| 5: [BlockStmt] { ... } @@ -47,7 +75,7 @@ delegatedProperties.kt: # 87| 0: [MethodAccess] getExtDelegated(...) # 87| -1: [TypeAccess] DelegatedPropertiesKt # 87| 0: [VarAccess] a0 -# 87| 1: [Method] invoke +# 87| 3: [Method] invoke #-----| 4: (Parameters) # 87| 0: [Parameter] a0 # 87| 5: [BlockStmt] { ... } @@ -55,7 +83,7 @@ delegatedProperties.kt: # 87| 0: [MethodAccess] get(...) # 87| -1: [ThisAccess] this # 87| 0: [VarAccess] a0 -# 87| 1: [Method] set +# 87| 4: [Method] set #-----| 4: (Parameters) # 87| 0: [Parameter] a0 # 87| 1: [Parameter] a1 @@ -68,7 +96,7 @@ delegatedProperties.kt: # 87| -3: [TypeAccess] KMutableProperty1 # 87| 0: [TypeAccess] MyClass # 87| 1: [TypeAccess] Integer -# 87| 5: [ExtensionMethod] setExtDelegated +# 87| 7: [ExtensionMethod] setExtDelegated # 87| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 87| 0: [Parameter] @@ -88,7 +116,7 @@ delegatedProperties.kt: # 87| 1: [Constructor] # 87| 5: [BlockStmt] { ... } # 87| 0: [SuperConstructorInvocationStmt] super(...) -# 87| 1: [Method] get +# 87| 2: [Method] get #-----| 4: (Parameters) # 87| 0: [Parameter] a0 # 87| 5: [BlockStmt] { ... } @@ -96,7 +124,7 @@ delegatedProperties.kt: # 87| 0: [MethodAccess] getExtDelegated(...) # 87| -1: [TypeAccess] DelegatedPropertiesKt # 87| 0: [VarAccess] a0 -# 87| 1: [Method] invoke +# 87| 3: [Method] invoke #-----| 4: (Parameters) # 87| 0: [Parameter] a0 # 87| 5: [BlockStmt] { ... } @@ -104,7 +132,7 @@ delegatedProperties.kt: # 87| 0: [MethodAccess] get(...) # 87| -1: [ThisAccess] this # 87| 0: [VarAccess] a0 -# 87| 1: [Method] set +# 87| 4: [Method] set #-----| 4: (Parameters) # 87| 0: [Parameter] a0 # 87| 1: [Parameter] a1 @@ -118,34 +146,6 @@ delegatedProperties.kt: # 87| 0: [TypeAccess] MyClass # 87| 1: [TypeAccess] Integer # 87| 3: [VarAccess] -# 87| 5: [FieldDeclaration] KMutableProperty0 extDelegated$delegateMyClass; -# 87| -1: [TypeAccess] KMutableProperty0 -# 87| 0: [TypeAccess] Integer -# 87| 0: [PropertyRefExpr] ...::... -# 87| -4: [AnonymousClass] new KMutableProperty0(...) { ... } -# 87| 1: [Constructor] -# 87| 5: [BlockStmt] { ... } -# 87| 0: [SuperConstructorInvocationStmt] super(...) -# 87| 1: [Method] get -# 87| 5: [BlockStmt] { ... } -# 87| 0: [ReturnStmt] return ... -# 87| 0: [MethodAccess] getTopLevelInt(...) -# 87| -1: [TypeAccess] DelegatedPropertiesKt -# 87| 1: [Method] invoke -# 87| 5: [BlockStmt] { ... } -# 87| 0: [ReturnStmt] return ... -# 87| 0: [MethodAccess] get(...) -# 87| -1: [ThisAccess] this -# 87| 1: [Method] set -#-----| 4: (Parameters) -# 87| 0: [Parameter] a0 -# 87| 5: [BlockStmt] { ... } -# 87| 0: [ReturnStmt] return ... -# 87| 0: [MethodAccess] setTopLevelInt(...) -# 87| -1: [TypeAccess] DelegatedPropertiesKt -# 87| 0: [VarAccess] a0 -# 87| -3: [TypeAccess] KMutableProperty0 -# 87| 0: [TypeAccess] Integer # 4| 2: [Class] ClassProp1 # 4| 1: [Constructor] ClassProp1 # 4| 5: [BlockStmt] { ... } @@ -165,7 +165,7 @@ delegatedProperties.kt: # 6| 1: [Constructor] # 6| 5: [BlockStmt] { ... } # 6| 0: [SuperConstructorInvocationStmt] super(...) -# 6| 1: [Method] invoke +# 6| 2: [Method] invoke # 6| 3: [TypeAccess] int # 7| 5: [BlockStmt] { ... } # 7| 0: [ExprStmt] ; @@ -181,7 +181,7 @@ delegatedProperties.kt: # 6| 1: [Constructor] # 6| 5: [BlockStmt] { ... } # 6| 0: [SuperConstructorInvocationStmt] super(...) -# 6| 1: [Method] +# 6| 2: [Method] # 6| 3: [TypeAccess] int # 6| 5: [BlockStmt] { ... } # 6| 0: [ReturnStmt] return ... @@ -195,13 +195,13 @@ delegatedProperties.kt: # 6| 1: [Constructor] # 6| 5: [BlockStmt] { ... } # 6| 0: [SuperConstructorInvocationStmt] super(...) -# 6| 1: [Method] get +# 6| 2: [Method] get # 6| 5: [BlockStmt] { ... } # 6| 0: [ReturnStmt] return ... # 6| 0: [MethodAccess] (...) # 6| -1: [ClassInstanceExpr] new (...) # 6| -3: [TypeAccess] Object -# 6| 1: [Method] invoke +# 6| 3: [Method] invoke # 6| 5: [BlockStmt] { ... } # 6| 0: [ReturnStmt] return ... # 6| 0: [MethodAccess] get(...) @@ -252,7 +252,7 @@ delegatedProperties.kt: # 19| 1: [Constructor] # 19| 5: [BlockStmt] { ... } # 19| 0: [SuperConstructorInvocationStmt] super(...) -# 19| 1: [Method] +# 19| 2: [Method] # 19| 3: [TypeAccess] int # 19| 5: [BlockStmt] { ... } # 19| 0: [ReturnStmt] return ... @@ -264,18 +264,18 @@ delegatedProperties.kt: # 19| 1: [Constructor] # 19| 5: [BlockStmt] { ... } # 19| 0: [SuperConstructorInvocationStmt] super(...) -# 19| 1: [Method] get +# 19| 2: [Method] get # 19| 5: [BlockStmt] { ... } # 19| 0: [ReturnStmt] return ... # 19| 0: [MethodAccess] (...) # 19| -1: [ClassInstanceExpr] new (...) # 19| -3: [TypeAccess] Object -# 19| 1: [Method] invoke +# 19| 3: [Method] invoke # 19| 5: [BlockStmt] { ... } # 19| 0: [ReturnStmt] return ... # 19| 0: [MethodAccess] get(...) # 19| -1: [ThisAccess] this -# 19| 1: [Method] set +# 19| 4: [Method] set #-----| 4: (Parameters) # 19| 0: [Parameter] a0 # 19| 5: [BlockStmt] { ... } @@ -291,7 +291,7 @@ delegatedProperties.kt: # 19| 1: [Constructor] # 19| 5: [BlockStmt] { ... } # 19| 0: [SuperConstructorInvocationStmt] super(...) -# 19| 1: [Method] +# 19| 2: [Method] # 19| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 19| 0: [Parameter] value @@ -306,18 +306,18 @@ delegatedProperties.kt: # 19| 1: [Constructor] # 19| 5: [BlockStmt] { ... } # 19| 0: [SuperConstructorInvocationStmt] super(...) -# 19| 1: [Method] get +# 19| 2: [Method] get # 19| 5: [BlockStmt] { ... } # 19| 0: [ReturnStmt] return ... # 19| 0: [MethodAccess] (...) # 19| -1: [ClassInstanceExpr] new (...) # 19| -3: [TypeAccess] Object -# 19| 1: [Method] invoke +# 19| 3: [Method] invoke # 19| 5: [BlockStmt] { ... } # 19| 0: [ReturnStmt] return ... # 19| 0: [MethodAccess] get(...) # 19| -1: [ThisAccess] this -# 19| 1: [Method] set +# 19| 4: [Method] set #-----| 4: (Parameters) # 19| 0: [Parameter] a0 # 19| 5: [BlockStmt] { ... } @@ -349,7 +349,7 @@ delegatedProperties.kt: # 23| 1: [Constructor] # 23| 5: [BlockStmt] { ... } # 23| 0: [SuperConstructorInvocationStmt] super(...) -# 23| 1: [Method] +# 23| 2: [Method] # 23| 3: [TypeAccess] String # 23| 5: [BlockStmt] { ... } # 23| 0: [ReturnStmt] return ... @@ -364,13 +364,13 @@ delegatedProperties.kt: # 23| 1: [Constructor] # 23| 5: [BlockStmt] { ... } # 23| 0: [SuperConstructorInvocationStmt] super(...) -# 23| 1: [Method] get +# 23| 2: [Method] get # 23| 5: [BlockStmt] { ... } # 23| 0: [ReturnStmt] return ... # 23| 0: [MethodAccess] (...) # 23| -1: [ClassInstanceExpr] new (...) # 23| -3: [TypeAccess] Object -# 23| 1: [Method] invoke +# 23| 3: [Method] invoke # 23| 5: [BlockStmt] { ... } # 23| 0: [ReturnStmt] return ... # 23| 0: [MethodAccess] get(...) @@ -382,7 +382,7 @@ delegatedProperties.kt: # 25| 1: [Constructor] # 25| 5: [BlockStmt] { ... } # 25| 0: [SuperConstructorInvocationStmt] super(...) -# 25| 1: [Method] resourceDelegate +# 25| 2: [Method] resourceDelegate # 25| 3: [TypeAccess] ReadWriteProperty # 25| 0: [TypeAccess] Object # 25| 1: [TypeAccess] Integer @@ -405,7 +405,10 @@ delegatedProperties.kt: # 26| 0: [ReturnStmt] return ... # 26| 0: [VarAccess] this.curValue # 26| -1: [ThisAccess] this -# 26| 2: [Method] setCurValue +# 26| 3: [FieldDeclaration] int curValue; +# 26| -1: [TypeAccess] int +# 26| 0: [IntegerLiteral] 0 +# 26| 4: [Method] setCurValue # 26| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 26| 0: [Parameter] @@ -416,9 +419,6 @@ delegatedProperties.kt: # 26| 0: [VarAccess] this.curValue # 26| -1: [ThisAccess] this # 26| 1: [VarAccess] -# 26| 2: [FieldDeclaration] int curValue; -# 26| -1: [TypeAccess] int -# 26| 0: [IntegerLiteral] 0 # 27| 5: [Method] getValue # 27| 3: [TypeAccess] int #-----| 4: (Parameters) @@ -460,7 +460,7 @@ delegatedProperties.kt: # 33| 1: [Constructor] # 33| 5: [BlockStmt] { ... } # 33| 0: [SuperConstructorInvocationStmt] super(...) -# 33| 1: [Method] +# 33| 2: [Method] # 33| 3: [TypeAccess] int # 33| 5: [BlockStmt] { ... } # 33| 0: [ReturnStmt] return ... @@ -472,13 +472,13 @@ delegatedProperties.kt: # 33| 1: [Constructor] # 33| 5: [BlockStmt] { ... } # 33| 0: [SuperConstructorInvocationStmt] super(...) -# 33| 1: [Method] get +# 33| 2: [Method] get # 33| 5: [BlockStmt] { ... } # 33| 0: [ReturnStmt] return ... # 33| 0: [MethodAccess] (...) # 33| -1: [ClassInstanceExpr] new (...) # 33| -3: [TypeAccess] Object -# 33| 1: [Method] invoke +# 33| 3: [Method] invoke # 33| 5: [BlockStmt] { ... } # 33| 0: [ReturnStmt] return ... # 33| 0: [MethodAccess] get(...) @@ -496,7 +496,7 @@ delegatedProperties.kt: # 34| 1: [Constructor] # 34| 5: [BlockStmt] { ... } # 34| 0: [SuperConstructorInvocationStmt] super(...) -# 34| 1: [Method] +# 34| 2: [Method] # 34| 3: [TypeAccess] int # 34| 5: [BlockStmt] { ... } # 34| 0: [ReturnStmt] return ... @@ -508,18 +508,18 @@ delegatedProperties.kt: # 34| 1: [Constructor] # 34| 5: [BlockStmt] { ... } # 34| 0: [SuperConstructorInvocationStmt] super(...) -# 34| 1: [Method] get +# 34| 2: [Method] get # 34| 5: [BlockStmt] { ... } # 34| 0: [ReturnStmt] return ... # 34| 0: [MethodAccess] (...) # 34| -1: [ClassInstanceExpr] new (...) # 34| -3: [TypeAccess] Object -# 34| 1: [Method] invoke +# 34| 3: [Method] invoke # 34| 5: [BlockStmt] { ... } # 34| 0: [ReturnStmt] return ... # 34| 0: [MethodAccess] get(...) # 34| -1: [ThisAccess] this -# 34| 1: [Method] set +# 34| 4: [Method] set #-----| 4: (Parameters) # 34| 0: [Parameter] a0 # 34| 5: [BlockStmt] { ... } @@ -535,7 +535,7 @@ delegatedProperties.kt: # 34| 1: [Constructor] # 34| 5: [BlockStmt] { ... } # 34| 0: [SuperConstructorInvocationStmt] super(...) -# 34| 1: [Method] +# 34| 2: [Method] # 34| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 34| 0: [Parameter] value @@ -550,18 +550,18 @@ delegatedProperties.kt: # 34| 1: [Constructor] # 34| 5: [BlockStmt] { ... } # 34| 0: [SuperConstructorInvocationStmt] super(...) -# 34| 1: [Method] get +# 34| 2: [Method] get # 34| 5: [BlockStmt] { ... } # 34| 0: [ReturnStmt] return ... # 34| 0: [MethodAccess] (...) # 34| -1: [ClassInstanceExpr] new (...) # 34| -3: [TypeAccess] Object -# 34| 1: [Method] invoke +# 34| 3: [Method] invoke # 34| 5: [BlockStmt] { ... } # 34| 0: [ReturnStmt] return ... # 34| 0: [MethodAccess] get(...) # 34| -1: [ThisAccess] this -# 34| 1: [Method] set +# 34| 4: [Method] set #-----| 4: (Parameters) # 34| 0: [Parameter] a0 # 34| 5: [BlockStmt] { ... } @@ -594,13 +594,13 @@ delegatedProperties.kt: # 39| 1: [Constructor] # 39| 5: [BlockStmt] { ... } # 39| 0: [SuperConstructorInvocationStmt] super(...) -# 39| 1: [Method] get +# 39| 2: [Method] get # 39| 5: [BlockStmt] { ... } # 39| 0: [ReturnStmt] return ... # 39| 0: [MethodAccess] (...) # 39| -1: [ClassInstanceExpr] new (...) # 39| -3: [TypeAccess] Object -# 39| 1: [Method] invoke +# 39| 3: [Method] invoke # 39| 5: [BlockStmt] { ... } # 39| 0: [ReturnStmt] return ... # 39| 0: [MethodAccess] get(...) @@ -612,7 +612,7 @@ delegatedProperties.kt: # 39| 1: [Constructor] # 39| 5: [BlockStmt] { ... } # 39| 0: [SuperConstructorInvocationStmt] super(...) -# 39| 1: [Method] +# 39| 2: [Method] # 39| 3: [TypeAccess] int # 39| 5: [BlockStmt] { ... } # 39| 0: [ReturnStmt] return ... @@ -624,20 +624,24 @@ delegatedProperties.kt: # 39| 1: [Constructor] # 39| 5: [BlockStmt] { ... } # 39| 0: [SuperConstructorInvocationStmt] super(...) -# 39| 1: [Method] get +# 39| 2: [Method] get # 39| 5: [BlockStmt] { ... } # 39| 0: [ReturnStmt] return ... # 39| 0: [MethodAccess] (...) # 39| -1: [ClassInstanceExpr] new (...) # 39| -3: [TypeAccess] Object -# 39| 1: [Method] invoke +# 39| 3: [Method] invoke # 39| 5: [BlockStmt] { ... } # 39| 0: [ReturnStmt] return ... # 39| 0: [MethodAccess] get(...) # 39| -1: [ThisAccess] this # 39| -3: [TypeAccess] KProperty0 # 39| 0: [TypeAccess] Integer -# 42| 3: [Method] getVarResource0 +# 42| 3: [FieldDeclaration] ResourceDelegate varResource0$delegate; +# 42| -1: [TypeAccess] ResourceDelegate +# 42| 0: [ClassInstanceExpr] new ResourceDelegate(...) +# 42| -3: [TypeAccess] ResourceDelegate +# 42| 4: [Method] getVarResource0 # 42| 3: [TypeAccess] int # 42| 5: [BlockStmt] { ... } # 42| 0: [ReturnStmt] return ... @@ -650,14 +654,14 @@ delegatedProperties.kt: # 42| 1: [Constructor] # 42| 5: [BlockStmt] { ... } # 42| 0: [SuperConstructorInvocationStmt] super(...) -# 42| 1: [Method] get +# 42| 2: [Method] get #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 5: [BlockStmt] { ... } # 42| 0: [ReturnStmt] return ... # 42| 0: [MethodAccess] getVarResource0(...) # 42| -1: [VarAccess] a0 -# 42| 1: [Method] invoke +# 42| 3: [Method] invoke #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 5: [BlockStmt] { ... } @@ -665,7 +669,7 @@ delegatedProperties.kt: # 42| 0: [MethodAccess] get(...) # 42| -1: [ThisAccess] this # 42| 0: [VarAccess] a0 -# 42| 1: [Method] set +# 42| 4: [Method] set #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 1: [Parameter] a1 @@ -677,7 +681,7 @@ delegatedProperties.kt: # 42| -3: [TypeAccess] KMutableProperty1 # 42| 0: [TypeAccess] Owner # 42| 1: [TypeAccess] Integer -# 42| 3: [Method] setVarResource0 +# 42| 5: [Method] setVarResource0 # 42| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 42| 0: [Parameter] @@ -693,14 +697,14 @@ delegatedProperties.kt: # 42| 1: [Constructor] # 42| 5: [BlockStmt] { ... } # 42| 0: [SuperConstructorInvocationStmt] super(...) -# 42| 1: [Method] get +# 42| 2: [Method] get #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 5: [BlockStmt] { ... } # 42| 0: [ReturnStmt] return ... # 42| 0: [MethodAccess] getVarResource0(...) # 42| -1: [VarAccess] a0 -# 42| 1: [Method] invoke +# 42| 3: [Method] invoke #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 5: [BlockStmt] { ... } @@ -708,7 +712,7 @@ delegatedProperties.kt: # 42| 0: [MethodAccess] get(...) # 42| -1: [ThisAccess] this # 42| 0: [VarAccess] a0 -# 42| 1: [Method] set +# 42| 4: [Method] set #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 1: [Parameter] a1 @@ -721,10 +725,6 @@ delegatedProperties.kt: # 42| 0: [TypeAccess] Owner # 42| 1: [TypeAccess] Integer # 42| 2: [VarAccess] -# 42| 3: [FieldDeclaration] ResourceDelegate varResource0$delegate; -# 42| -1: [TypeAccess] ResourceDelegate -# 42| 0: [ClassInstanceExpr] new ResourceDelegate(...) -# 42| -3: [TypeAccess] ResourceDelegate # 45| 5: [Class] ResourceDelegate # 45| 1: [Constructor] ResourceDelegate # 45| 5: [BlockStmt] { ... } @@ -786,7 +786,7 @@ delegatedProperties.kt: # 62| 0: [ReturnStmt] return ... # 62| 0: [VarAccess] this.anotherClassInt # 62| -1: [ThisAccess] this -# 62| 2: [FieldDeclaration] int anotherClassInt; +# 62| 3: [FieldDeclaration] int anotherClassInt; # 62| -1: [TypeAccess] int # 62| 0: [VarAccess] anotherClassInt # 63| 8: [Class] Base @@ -806,7 +806,7 @@ delegatedProperties.kt: # 63| 0: [ReturnStmt] return ... # 63| 0: [VarAccess] this.baseClassInt # 63| -1: [ThisAccess] this -# 63| 2: [FieldDeclaration] int baseClassInt; +# 63| 3: [FieldDeclaration] int baseClassInt; # 63| -1: [TypeAccess] int # 63| 0: [VarAccess] baseClassInt # 65| 9: [Class] MyClass @@ -859,7 +859,10 @@ delegatedProperties.kt: # 65| 0: [ReturnStmt] return ... # 65| 0: [VarAccess] this.memberInt # 65| -1: [ThisAccess] this -# 65| 2: [Method] setMemberInt +# 65| 3: [FieldDeclaration] int memberInt; +# 65| -1: [TypeAccess] int +# 65| 0: [VarAccess] memberInt +# 65| 4: [Method] setMemberInt # 65| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 65| 0: [Parameter] @@ -870,19 +873,57 @@ delegatedProperties.kt: # 65| 0: [VarAccess] this.memberInt # 65| -1: [ThisAccess] this # 65| 1: [VarAccess] -# 65| 2: [FieldDeclaration] int memberInt; -# 65| -1: [TypeAccess] int -# 65| 0: [VarAccess] memberInt -# 65| 5: [Method] getAnotherClassInstance +# 65| 5: [FieldDeclaration] ClassWithDelegate anotherClassInstance; +# 65| -1: [TypeAccess] ClassWithDelegate +# 65| 0: [VarAccess] anotherClassInstance +# 65| 6: [Method] getAnotherClassInstance # 65| 3: [TypeAccess] ClassWithDelegate # 65| 5: [BlockStmt] { ... } # 65| 0: [ReturnStmt] return ... # 65| 0: [VarAccess] this.anotherClassInstance # 65| -1: [ThisAccess] this -# 65| 5: [FieldDeclaration] ClassWithDelegate anotherClassInstance; -# 65| -1: [TypeAccess] ClassWithDelegate -# 65| 0: [VarAccess] anotherClassInstance -# 66| 7: [Method] getDelegatedToMember1 +# 66| 7: [FieldDeclaration] KMutableProperty0 delegatedToMember1$delegate; +# 66| -1: [TypeAccess] KMutableProperty0 +# 66| 0: [TypeAccess] Integer +# 66| 0: [PropertyRefExpr] ...::... +# 66| -4: [AnonymousClass] new KMutableProperty0(...) { ... } +# 66| 1: [Constructor] +#-----| 4: (Parameters) +# 66| 0: [Parameter] +# 66| 5: [BlockStmt] { ... } +# 66| 0: [SuperConstructorInvocationStmt] super(...) +# 66| 1: [ExprStmt] ; +# 66| 0: [AssignExpr] ...=... +# 66| 0: [VarAccess] this. +# 66| -1: [ThisAccess] this +# 66| 1: [VarAccess] +# 66| 2: [FieldDeclaration] MyClass ; +# 66| -1: [TypeAccess] MyClass +# 66| 3: [Method] get +# 66| 5: [BlockStmt] { ... } +# 66| 0: [ReturnStmt] return ... +# 66| 0: [MethodAccess] getMemberInt(...) +# 66| -1: [VarAccess] this. +# 66| -1: [ThisAccess] this +# 66| 4: [Method] invoke +# 66| 5: [BlockStmt] { ... } +# 66| 0: [ReturnStmt] return ... +# 66| 0: [MethodAccess] get(...) +# 66| -1: [ThisAccess] this +# 66| 5: [Method] set +#-----| 4: (Parameters) +# 66| 0: [Parameter] a0 +# 66| 5: [BlockStmt] { ... } +# 66| 0: [ReturnStmt] return ... +# 66| 0: [MethodAccess] setMemberInt(...) +# 66| -1: [VarAccess] this. +# 66| -1: [ThisAccess] this +# 66| 0: [VarAccess] a0 +# 66| -3: [TypeAccess] KMutableProperty0 +# 66| 0: [TypeAccess] Integer +# 66| 0: [ThisAccess] MyClass.this +# 66| 0: [TypeAccess] MyClass +# 66| 8: [Method] getDelegatedToMember1 # 66| 3: [TypeAccess] int # 66| 5: [BlockStmt] { ... } # 66| 0: [ReturnStmt] return ... @@ -897,14 +938,14 @@ delegatedProperties.kt: # 66| 1: [Constructor] # 66| 5: [BlockStmt] { ... } # 66| 0: [SuperConstructorInvocationStmt] super(...) -# 66| 1: [Method] get +# 66| 2: [Method] get #-----| 4: (Parameters) # 66| 0: [Parameter] a0 # 66| 5: [BlockStmt] { ... } # 66| 0: [ReturnStmt] return ... # 66| 0: [MethodAccess] getDelegatedToMember1(...) # 66| -1: [VarAccess] a0 -# 66| 1: [Method] invoke +# 66| 3: [Method] invoke #-----| 4: (Parameters) # 66| 0: [Parameter] a0 # 66| 5: [BlockStmt] { ... } @@ -912,7 +953,7 @@ delegatedProperties.kt: # 66| 0: [MethodAccess] get(...) # 66| -1: [ThisAccess] this # 66| 0: [VarAccess] a0 -# 66| 1: [Method] set +# 66| 4: [Method] set #-----| 4: (Parameters) # 66| 0: [Parameter] a0 # 66| 1: [Parameter] a1 @@ -924,7 +965,7 @@ delegatedProperties.kt: # 66| -3: [TypeAccess] KMutableProperty1 # 66| 0: [TypeAccess] MyClass # 66| 1: [TypeAccess] Integer -# 66| 7: [Method] setDelegatedToMember1 +# 66| 9: [Method] setDelegatedToMember1 # 66| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 66| 0: [Parameter] @@ -942,14 +983,14 @@ delegatedProperties.kt: # 66| 1: [Constructor] # 66| 5: [BlockStmt] { ... } # 66| 0: [SuperConstructorInvocationStmt] super(...) -# 66| 1: [Method] get +# 66| 2: [Method] get #-----| 4: (Parameters) # 66| 0: [Parameter] a0 # 66| 5: [BlockStmt] { ... } # 66| 0: [ReturnStmt] return ... # 66| 0: [MethodAccess] getDelegatedToMember1(...) # 66| -1: [VarAccess] a0 -# 66| 1: [Method] invoke +# 66| 3: [Method] invoke #-----| 4: (Parameters) # 66| 0: [Parameter] a0 # 66| 5: [BlockStmt] { ... } @@ -957,7 +998,7 @@ delegatedProperties.kt: # 66| 0: [MethodAccess] get(...) # 66| -1: [ThisAccess] this # 66| 0: [VarAccess] a0 -# 66| 1: [Method] set +# 66| 4: [Method] set #-----| 4: (Parameters) # 66| 0: [Parameter] a0 # 66| 1: [Parameter] a1 @@ -970,48 +1011,43 @@ delegatedProperties.kt: # 66| 0: [TypeAccess] MyClass # 66| 1: [TypeAccess] Integer # 66| 3: [VarAccess] -# 66| 7: [FieldDeclaration] KMutableProperty0 delegatedToMember1$delegate; -# 66| -1: [TypeAccess] KMutableProperty0 -# 66| 0: [TypeAccess] Integer -# 66| 0: [PropertyRefExpr] ...::... -# 66| -4: [AnonymousClass] new KMutableProperty0(...) { ... } -# 66| 1: [Constructor] +# 67| 10: [FieldDeclaration] KMutableProperty1 delegatedToMember2$delegate; +# 67| -1: [TypeAccess] KMutableProperty1 +# 67| 0: [TypeAccess] MyClass +# 67| 1: [TypeAccess] Integer +# 67| 0: [PropertyRefExpr] ...::... +# 67| -4: [AnonymousClass] new KMutableProperty1(...) { ... } +# 67| 1: [Constructor] +# 67| 5: [BlockStmt] { ... } +# 67| 0: [SuperConstructorInvocationStmt] super(...) +# 67| 2: [Method] get #-----| 4: (Parameters) -# 66| 0: [Parameter] -# 66| 5: [BlockStmt] { ... } -# 66| 0: [SuperConstructorInvocationStmt] super(...) -# 66| 1: [ExprStmt] ; -# 66| 0: [AssignExpr] ...=... -# 66| 0: [VarAccess] this. -# 66| -1: [ThisAccess] this -# 66| 1: [VarAccess] -# 66| 1: [FieldDeclaration] MyClass ; -# 66| -1: [TypeAccess] MyClass -# 66| 1: [Method] get -# 66| 5: [BlockStmt] { ... } -# 66| 0: [ReturnStmt] return ... -# 66| 0: [MethodAccess] getMemberInt(...) -# 66| -1: [VarAccess] this. -# 66| -1: [ThisAccess] this -# 66| 1: [Method] invoke -# 66| 5: [BlockStmt] { ... } -# 66| 0: [ReturnStmt] return ... -# 66| 0: [MethodAccess] get(...) -# 66| -1: [ThisAccess] this -# 66| 1: [Method] set +# 67| 0: [Parameter] a0 +# 67| 5: [BlockStmt] { ... } +# 67| 0: [ReturnStmt] return ... +# 67| 0: [MethodAccess] getMemberInt(...) +# 67| -1: [VarAccess] a0 +# 67| 3: [Method] invoke #-----| 4: (Parameters) -# 66| 0: [Parameter] a0 -# 66| 5: [BlockStmt] { ... } -# 66| 0: [ReturnStmt] return ... -# 66| 0: [MethodAccess] setMemberInt(...) -# 66| -1: [VarAccess] this. -# 66| -1: [ThisAccess] this -# 66| 0: [VarAccess] a0 -# 66| -3: [TypeAccess] KMutableProperty0 -# 66| 0: [TypeAccess] Integer -# 66| 0: [ThisAccess] MyClass.this -# 66| 0: [TypeAccess] MyClass -# 67| 10: [Method] getDelegatedToMember2 +# 67| 0: [Parameter] a0 +# 67| 5: [BlockStmt] { ... } +# 67| 0: [ReturnStmt] return ... +# 67| 0: [MethodAccess] get(...) +# 67| -1: [ThisAccess] this +# 67| 0: [VarAccess] a0 +# 67| 4: [Method] set +#-----| 4: (Parameters) +# 67| 0: [Parameter] a0 +# 67| 1: [Parameter] a1 +# 67| 5: [BlockStmt] { ... } +# 67| 0: [ReturnStmt] return ... +# 67| 0: [MethodAccess] setMemberInt(...) +# 67| -1: [VarAccess] a0 +# 67| 0: [VarAccess] a1 +# 67| -3: [TypeAccess] KMutableProperty1 +# 67| 0: [TypeAccess] MyClass +# 67| 1: [TypeAccess] Integer +# 67| 11: [Method] getDelegatedToMember2 # 67| 3: [TypeAccess] int # 67| 5: [BlockStmt] { ... } # 67| 0: [ReturnStmt] return ... @@ -1027,14 +1063,14 @@ delegatedProperties.kt: # 67| 1: [Constructor] # 67| 5: [BlockStmt] { ... } # 67| 0: [SuperConstructorInvocationStmt] super(...) -# 67| 1: [Method] get +# 67| 2: [Method] get #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 5: [BlockStmt] { ... } # 67| 0: [ReturnStmt] return ... # 67| 0: [MethodAccess] getDelegatedToMember2(...) # 67| -1: [VarAccess] a0 -# 67| 1: [Method] invoke +# 67| 3: [Method] invoke #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 5: [BlockStmt] { ... } @@ -1042,7 +1078,7 @@ delegatedProperties.kt: # 67| 0: [MethodAccess] get(...) # 67| -1: [ThisAccess] this # 67| 0: [VarAccess] a0 -# 67| 1: [Method] set +# 67| 4: [Method] set #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 1: [Parameter] a1 @@ -1054,7 +1090,7 @@ delegatedProperties.kt: # 67| -3: [TypeAccess] KMutableProperty1 # 67| 0: [TypeAccess] MyClass # 67| 1: [TypeAccess] Integer -# 67| 10: [Method] setDelegatedToMember2 +# 67| 12: [Method] setDelegatedToMember2 # 67| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 67| 0: [Parameter] @@ -1073,14 +1109,14 @@ delegatedProperties.kt: # 67| 1: [Constructor] # 67| 5: [BlockStmt] { ... } # 67| 0: [SuperConstructorInvocationStmt] super(...) -# 67| 1: [Method] get +# 67| 2: [Method] get #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 5: [BlockStmt] { ... } # 67| 0: [ReturnStmt] return ... # 67| 0: [MethodAccess] getDelegatedToMember2(...) # 67| -1: [VarAccess] a0 -# 67| 1: [Method] invoke +# 67| 3: [Method] invoke #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 5: [BlockStmt] { ... } @@ -1088,7 +1124,7 @@ delegatedProperties.kt: # 67| 0: [MethodAccess] get(...) # 67| -1: [ThisAccess] this # 67| 0: [VarAccess] a0 -# 67| 1: [Method] set +# 67| 4: [Method] set #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 1: [Parameter] a1 @@ -1101,43 +1137,50 @@ delegatedProperties.kt: # 67| 0: [TypeAccess] MyClass # 67| 1: [TypeAccess] Integer # 67| 3: [VarAccess] -# 67| 10: [FieldDeclaration] KMutableProperty1 delegatedToMember2$delegate; -# 67| -1: [TypeAccess] KMutableProperty1 -# 67| 0: [TypeAccess] MyClass -# 67| 1: [TypeAccess] Integer -# 67| 0: [PropertyRefExpr] ...::... -# 67| -4: [AnonymousClass] new KMutableProperty1(...) { ... } -# 67| 1: [Constructor] -# 67| 5: [BlockStmt] { ... } -# 67| 0: [SuperConstructorInvocationStmt] super(...) -# 67| 1: [Method] get +# 69| 13: [FieldDeclaration] KMutableProperty0 delegatedToExtMember1$delegate; +# 69| -1: [TypeAccess] KMutableProperty0 +# 69| 0: [TypeAccess] Integer +# 69| 0: [PropertyRefExpr] ...::... +# 69| -4: [AnonymousClass] new KMutableProperty0(...) { ... } +# 69| 1: [Constructor] #-----| 4: (Parameters) -# 67| 0: [Parameter] a0 -# 67| 5: [BlockStmt] { ... } -# 67| 0: [ReturnStmt] return ... -# 67| 0: [MethodAccess] getMemberInt(...) -# 67| -1: [VarAccess] a0 -# 67| 1: [Method] invoke +# 69| 0: [Parameter] +# 69| 5: [BlockStmt] { ... } +# 69| 0: [SuperConstructorInvocationStmt] super(...) +# 69| 1: [ExprStmt] ; +# 69| 0: [AssignExpr] ...=... +# 69| 0: [VarAccess] this. +# 69| -1: [ThisAccess] this +# 69| 1: [VarAccess] +# 69| 2: [FieldDeclaration] MyClass ; +# 69| -1: [TypeAccess] MyClass +# 69| 3: [Method] get +# 69| 5: [BlockStmt] { ... } +# 69| 0: [ReturnStmt] return ... +# 69| 0: [MethodAccess] getExtDelegated(...) +# 69| -1: [TypeAccess] DelegatedPropertiesKt +# 69| 0: [VarAccess] this. +# 69| -1: [ThisAccess] this +# 69| 4: [Method] invoke +# 69| 5: [BlockStmt] { ... } +# 69| 0: [ReturnStmt] return ... +# 69| 0: [MethodAccess] get(...) +# 69| -1: [ThisAccess] this +# 69| 5: [Method] set #-----| 4: (Parameters) -# 67| 0: [Parameter] a0 -# 67| 5: [BlockStmt] { ... } -# 67| 0: [ReturnStmt] return ... -# 67| 0: [MethodAccess] get(...) -# 67| -1: [ThisAccess] this -# 67| 0: [VarAccess] a0 -# 67| 1: [Method] set -#-----| 4: (Parameters) -# 67| 0: [Parameter] a0 -# 67| 1: [Parameter] a1 -# 67| 5: [BlockStmt] { ... } -# 67| 0: [ReturnStmt] return ... -# 67| 0: [MethodAccess] setMemberInt(...) -# 67| -1: [VarAccess] a0 -# 67| 0: [VarAccess] a1 -# 67| -3: [TypeAccess] KMutableProperty1 -# 67| 0: [TypeAccess] MyClass -# 67| 1: [TypeAccess] Integer -# 69| 13: [Method] getDelegatedToExtMember1 +# 69| 0: [Parameter] a0 +# 69| 5: [BlockStmt] { ... } +# 69| 0: [ReturnStmt] return ... +# 69| 0: [MethodAccess] setExtDelegated(...) +# 69| -1: [TypeAccess] DelegatedPropertiesKt +# 69| 0: [VarAccess] this. +# 69| -1: [ThisAccess] this +# 69| 1: [VarAccess] a0 +# 69| -3: [TypeAccess] KMutableProperty0 +# 69| 0: [TypeAccess] Integer +# 69| 0: [ThisAccess] MyClass.this +# 69| 0: [TypeAccess] MyClass +# 69| 14: [Method] getDelegatedToExtMember1 # 69| 3: [TypeAccess] int # 69| 5: [BlockStmt] { ... } # 69| 0: [ReturnStmt] return ... @@ -1152,14 +1195,14 @@ delegatedProperties.kt: # 69| 1: [Constructor] # 69| 5: [BlockStmt] { ... } # 69| 0: [SuperConstructorInvocationStmt] super(...) -# 69| 1: [Method] get +# 69| 2: [Method] get #-----| 4: (Parameters) # 69| 0: [Parameter] a0 # 69| 5: [BlockStmt] { ... } # 69| 0: [ReturnStmt] return ... # 69| 0: [MethodAccess] getDelegatedToExtMember1(...) # 69| -1: [VarAccess] a0 -# 69| 1: [Method] invoke +# 69| 3: [Method] invoke #-----| 4: (Parameters) # 69| 0: [Parameter] a0 # 69| 5: [BlockStmt] { ... } @@ -1167,7 +1210,7 @@ delegatedProperties.kt: # 69| 0: [MethodAccess] get(...) # 69| -1: [ThisAccess] this # 69| 0: [VarAccess] a0 -# 69| 1: [Method] set +# 69| 4: [Method] set #-----| 4: (Parameters) # 69| 0: [Parameter] a0 # 69| 1: [Parameter] a1 @@ -1179,7 +1222,7 @@ delegatedProperties.kt: # 69| -3: [TypeAccess] KMutableProperty1 # 69| 0: [TypeAccess] MyClass # 69| 1: [TypeAccess] Integer -# 69| 13: [Method] setDelegatedToExtMember1 +# 69| 15: [Method] setDelegatedToExtMember1 # 69| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 69| 0: [Parameter] @@ -1197,14 +1240,14 @@ delegatedProperties.kt: # 69| 1: [Constructor] # 69| 5: [BlockStmt] { ... } # 69| 0: [SuperConstructorInvocationStmt] super(...) -# 69| 1: [Method] get +# 69| 2: [Method] get #-----| 4: (Parameters) # 69| 0: [Parameter] a0 # 69| 5: [BlockStmt] { ... } # 69| 0: [ReturnStmt] return ... # 69| 0: [MethodAccess] getDelegatedToExtMember1(...) # 69| -1: [VarAccess] a0 -# 69| 1: [Method] invoke +# 69| 3: [Method] invoke #-----| 4: (Parameters) # 69| 0: [Parameter] a0 # 69| 5: [BlockStmt] { ... } @@ -1212,7 +1255,7 @@ delegatedProperties.kt: # 69| 0: [MethodAccess] get(...) # 69| -1: [ThisAccess] this # 69| 0: [VarAccess] a0 -# 69| 1: [Method] set +# 69| 4: [Method] set #-----| 4: (Parameters) # 69| 0: [Parameter] a0 # 69| 1: [Parameter] a1 @@ -1225,50 +1268,45 @@ delegatedProperties.kt: # 69| 0: [TypeAccess] MyClass # 69| 1: [TypeAccess] Integer # 69| 3: [VarAccess] -# 69| 13: [FieldDeclaration] KMutableProperty0 delegatedToExtMember1$delegate; -# 69| -1: [TypeAccess] KMutableProperty0 -# 69| 0: [TypeAccess] Integer -# 69| 0: [PropertyRefExpr] ...::... -# 69| -4: [AnonymousClass] new KMutableProperty0(...) { ... } -# 69| 1: [Constructor] +# 70| 16: [FieldDeclaration] KMutableProperty1 delegatedToExtMember2$delegate; +# 70| -1: [TypeAccess] KMutableProperty1 +# 70| 0: [TypeAccess] MyClass +# 70| 1: [TypeAccess] Integer +# 70| 0: [PropertyRefExpr] ...::... +# 70| -4: [AnonymousClass] new KMutableProperty1(...) { ... } +# 70| 1: [Constructor] +# 70| 5: [BlockStmt] { ... } +# 70| 0: [SuperConstructorInvocationStmt] super(...) +# 70| 2: [Method] get #-----| 4: (Parameters) -# 69| 0: [Parameter] -# 69| 5: [BlockStmt] { ... } -# 69| 0: [SuperConstructorInvocationStmt] super(...) -# 69| 1: [ExprStmt] ; -# 69| 0: [AssignExpr] ...=... -# 69| 0: [VarAccess] this. -# 69| -1: [ThisAccess] this -# 69| 1: [VarAccess] -# 69| 1: [FieldDeclaration] MyClass ; -# 69| -1: [TypeAccess] MyClass -# 69| 1: [Method] get -# 69| 5: [BlockStmt] { ... } -# 69| 0: [ReturnStmt] return ... -# 69| 0: [MethodAccess] getExtDelegated(...) -# 69| -1: [TypeAccess] DelegatedPropertiesKt -# 69| 0: [VarAccess] this. -# 69| -1: [ThisAccess] this -# 69| 1: [Method] invoke -# 69| 5: [BlockStmt] { ... } -# 69| 0: [ReturnStmt] return ... -# 69| 0: [MethodAccess] get(...) -# 69| -1: [ThisAccess] this -# 69| 1: [Method] set +# 70| 0: [Parameter] a0 +# 70| 5: [BlockStmt] { ... } +# 70| 0: [ReturnStmt] return ... +# 70| 0: [MethodAccess] getExtDelegated(...) +# 70| -1: [TypeAccess] DelegatedPropertiesKt +# 70| 0: [VarAccess] a0 +# 70| 3: [Method] invoke #-----| 4: (Parameters) -# 69| 0: [Parameter] a0 -# 69| 5: [BlockStmt] { ... } -# 69| 0: [ReturnStmt] return ... -# 69| 0: [MethodAccess] setExtDelegated(...) -# 69| -1: [TypeAccess] DelegatedPropertiesKt -# 69| 0: [VarAccess] this. -# 69| -1: [ThisAccess] this -# 69| 1: [VarAccess] a0 -# 69| -3: [TypeAccess] KMutableProperty0 -# 69| 0: [TypeAccess] Integer -# 69| 0: [ThisAccess] MyClass.this -# 69| 0: [TypeAccess] MyClass -# 70| 16: [Method] getDelegatedToExtMember2 +# 70| 0: [Parameter] a0 +# 70| 5: [BlockStmt] { ... } +# 70| 0: [ReturnStmt] return ... +# 70| 0: [MethodAccess] get(...) +# 70| -1: [ThisAccess] this +# 70| 0: [VarAccess] a0 +# 70| 4: [Method] set +#-----| 4: (Parameters) +# 70| 0: [Parameter] a0 +# 70| 1: [Parameter] a1 +# 70| 5: [BlockStmt] { ... } +# 70| 0: [ReturnStmt] return ... +# 70| 0: [MethodAccess] setExtDelegated(...) +# 70| -1: [TypeAccess] DelegatedPropertiesKt +# 70| 0: [VarAccess] a0 +# 70| 1: [VarAccess] a1 +# 70| -3: [TypeAccess] KMutableProperty1 +# 70| 0: [TypeAccess] MyClass +# 70| 1: [TypeAccess] Integer +# 70| 17: [Method] getDelegatedToExtMember2 # 70| 3: [TypeAccess] int # 70| 5: [BlockStmt] { ... } # 70| 0: [ReturnStmt] return ... @@ -1284,14 +1322,14 @@ delegatedProperties.kt: # 70| 1: [Constructor] # 70| 5: [BlockStmt] { ... } # 70| 0: [SuperConstructorInvocationStmt] super(...) -# 70| 1: [Method] get +# 70| 2: [Method] get #-----| 4: (Parameters) # 70| 0: [Parameter] a0 # 70| 5: [BlockStmt] { ... } # 70| 0: [ReturnStmt] return ... # 70| 0: [MethodAccess] getDelegatedToExtMember2(...) # 70| -1: [VarAccess] a0 -# 70| 1: [Method] invoke +# 70| 3: [Method] invoke #-----| 4: (Parameters) # 70| 0: [Parameter] a0 # 70| 5: [BlockStmt] { ... } @@ -1299,7 +1337,7 @@ delegatedProperties.kt: # 70| 0: [MethodAccess] get(...) # 70| -1: [ThisAccess] this # 70| 0: [VarAccess] a0 -# 70| 1: [Method] set +# 70| 4: [Method] set #-----| 4: (Parameters) # 70| 0: [Parameter] a0 # 70| 1: [Parameter] a1 @@ -1311,7 +1349,7 @@ delegatedProperties.kt: # 70| -3: [TypeAccess] KMutableProperty1 # 70| 0: [TypeAccess] MyClass # 70| 1: [TypeAccess] Integer -# 70| 16: [Method] setDelegatedToExtMember2 +# 70| 18: [Method] setDelegatedToExtMember2 # 70| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 70| 0: [Parameter] @@ -1330,14 +1368,14 @@ delegatedProperties.kt: # 70| 1: [Constructor] # 70| 5: [BlockStmt] { ... } # 70| 0: [SuperConstructorInvocationStmt] super(...) -# 70| 1: [Method] get +# 70| 2: [Method] get #-----| 4: (Parameters) # 70| 0: [Parameter] a0 # 70| 5: [BlockStmt] { ... } # 70| 0: [ReturnStmt] return ... # 70| 0: [MethodAccess] getDelegatedToExtMember2(...) # 70| -1: [VarAccess] a0 -# 70| 1: [Method] invoke +# 70| 3: [Method] invoke #-----| 4: (Parameters) # 70| 0: [Parameter] a0 # 70| 5: [BlockStmt] { ... } @@ -1345,7 +1383,7 @@ delegatedProperties.kt: # 70| 0: [MethodAccess] get(...) # 70| -1: [ThisAccess] this # 70| 0: [VarAccess] a0 -# 70| 1: [Method] set +# 70| 4: [Method] set #-----| 4: (Parameters) # 70| 0: [Parameter] a0 # 70| 1: [Parameter] a1 @@ -1358,77 +1396,6 @@ delegatedProperties.kt: # 70| 0: [TypeAccess] MyClass # 70| 1: [TypeAccess] Integer # 70| 3: [VarAccess] -# 70| 16: [FieldDeclaration] KMutableProperty1 delegatedToExtMember2$delegate; -# 70| -1: [TypeAccess] KMutableProperty1 -# 70| 0: [TypeAccess] MyClass -# 70| 1: [TypeAccess] Integer -# 70| 0: [PropertyRefExpr] ...::... -# 70| -4: [AnonymousClass] new KMutableProperty1(...) { ... } -# 70| 1: [Constructor] -# 70| 5: [BlockStmt] { ... } -# 70| 0: [SuperConstructorInvocationStmt] super(...) -# 70| 1: [Method] get -#-----| 4: (Parameters) -# 70| 0: [Parameter] a0 -# 70| 5: [BlockStmt] { ... } -# 70| 0: [ReturnStmt] return ... -# 70| 0: [MethodAccess] getExtDelegated(...) -# 70| -1: [TypeAccess] DelegatedPropertiesKt -# 70| 0: [VarAccess] a0 -# 70| 1: [Method] invoke -#-----| 4: (Parameters) -# 70| 0: [Parameter] a0 -# 70| 5: [BlockStmt] { ... } -# 70| 0: [ReturnStmt] return ... -# 70| 0: [MethodAccess] get(...) -# 70| -1: [ThisAccess] this -# 70| 0: [VarAccess] a0 -# 70| 1: [Method] set -#-----| 4: (Parameters) -# 70| 0: [Parameter] a0 -# 70| 1: [Parameter] a1 -# 70| 5: [BlockStmt] { ... } -# 70| 0: [ReturnStmt] return ... -# 70| 0: [MethodAccess] setExtDelegated(...) -# 70| -1: [TypeAccess] DelegatedPropertiesKt -# 70| 0: [VarAccess] a0 -# 70| 1: [VarAccess] a1 -# 70| -3: [TypeAccess] KMutableProperty1 -# 70| 0: [TypeAccess] MyClass -# 70| 1: [TypeAccess] Integer -# 72| 19: [Method] getDelegatedToBaseClass1 -# 72| 3: [TypeAccess] int -# 72| 5: [BlockStmt] { ... } -# 72| 0: [ReturnStmt] return ... -# 72| 0: [MethodAccess] getValue(...) -# 72| -2: [TypeAccess] Integer -# 72| -1: [TypeAccess] PropertyReferenceDelegatesKt -# 72| 0: [VarAccess] this.delegatedToBaseClass1$delegate -# 72| -1: [ThisAccess] this -# 1| 1: [ThisAccess] this -# 72| 2: [PropertyRefExpr] ...::... -# 72| -4: [AnonymousClass] new KProperty1(...) { ... } -# 72| 1: [Constructor] -# 72| 5: [BlockStmt] { ... } -# 72| 0: [SuperConstructorInvocationStmt] super(...) -# 72| 1: [Method] get -#-----| 4: (Parameters) -# 72| 0: [Parameter] a0 -# 72| 5: [BlockStmt] { ... } -# 72| 0: [ReturnStmt] return ... -# 72| 0: [MethodAccess] getDelegatedToBaseClass1(...) -# 72| -1: [VarAccess] a0 -# 72| 1: [Method] invoke -#-----| 4: (Parameters) -# 72| 0: [Parameter] a0 -# 72| 5: [BlockStmt] { ... } -# 72| 0: [ReturnStmt] return ... -# 72| 0: [MethodAccess] get(...) -# 72| -1: [ThisAccess] this -# 72| 0: [VarAccess] a0 -# 72| -3: [TypeAccess] KProperty1 -# 72| 0: [TypeAccess] MyClass -# 72| 1: [TypeAccess] Integer # 72| 19: [FieldDeclaration] KProperty0 delegatedToBaseClass1$delegate; # 72| -1: [TypeAccess] KProperty0 # 72| 0: [TypeAccess] Integer @@ -1444,15 +1411,15 @@ delegatedProperties.kt: # 72| 0: [VarAccess] this. # 72| -1: [ThisAccess] this # 72| 1: [VarAccess] -# 72| 1: [FieldDeclaration] MyClass ; +# 72| 2: [FieldDeclaration] MyClass ; # 72| -1: [TypeAccess] MyClass -# 72| 1: [Method] get +# 72| 3: [Method] get # 72| 5: [BlockStmt] { ... } # 72| 0: [ReturnStmt] return ... # 72| 0: [MethodAccess] getBaseClassInt(...) # 72| -1: [VarAccess] this. # 72| -1: [ThisAccess] this -# 72| 1: [Method] invoke +# 72| 4: [Method] invoke # 72| 5: [BlockStmt] { ... } # 72| 0: [ReturnStmt] return ... # 72| 0: [MethodAccess] get(...) @@ -1461,7 +1428,67 @@ delegatedProperties.kt: # 72| 0: [TypeAccess] Integer # 72| 0: [ThisAccess] MyClass.this # 72| 0: [TypeAccess] MyClass -# 73| 21: [Method] getDelegatedToBaseClass2 +# 72| 20: [Method] getDelegatedToBaseClass1 +# 72| 3: [TypeAccess] int +# 72| 5: [BlockStmt] { ... } +# 72| 0: [ReturnStmt] return ... +# 72| 0: [MethodAccess] getValue(...) +# 72| -2: [TypeAccess] Integer +# 72| -1: [TypeAccess] PropertyReferenceDelegatesKt +# 72| 0: [VarAccess] this.delegatedToBaseClass1$delegate +# 72| -1: [ThisAccess] this +# 1| 1: [ThisAccess] this +# 72| 2: [PropertyRefExpr] ...::... +# 72| -4: [AnonymousClass] new KProperty1(...) { ... } +# 72| 1: [Constructor] +# 72| 5: [BlockStmt] { ... } +# 72| 0: [SuperConstructorInvocationStmt] super(...) +# 72| 2: [Method] get +#-----| 4: (Parameters) +# 72| 0: [Parameter] a0 +# 72| 5: [BlockStmt] { ... } +# 72| 0: [ReturnStmt] return ... +# 72| 0: [MethodAccess] getDelegatedToBaseClass1(...) +# 72| -1: [VarAccess] a0 +# 72| 3: [Method] invoke +#-----| 4: (Parameters) +# 72| 0: [Parameter] a0 +# 72| 5: [BlockStmt] { ... } +# 72| 0: [ReturnStmt] return ... +# 72| 0: [MethodAccess] get(...) +# 72| -1: [ThisAccess] this +# 72| 0: [VarAccess] a0 +# 72| -3: [TypeAccess] KProperty1 +# 72| 0: [TypeAccess] MyClass +# 72| 1: [TypeAccess] Integer +# 73| 21: [FieldDeclaration] KProperty1 delegatedToBaseClass2$delegate; +# 73| -1: [TypeAccess] KProperty1 +# 73| 0: [TypeAccess] Base +# 73| 1: [TypeAccess] Integer +# 73| 0: [PropertyRefExpr] ...::... +# 73| -4: [AnonymousClass] new KProperty1(...) { ... } +# 73| 1: [Constructor] +# 73| 5: [BlockStmt] { ... } +# 73| 0: [SuperConstructorInvocationStmt] super(...) +# 73| 2: [Method] get +#-----| 4: (Parameters) +# 73| 0: [Parameter] a0 +# 73| 5: [BlockStmt] { ... } +# 73| 0: [ReturnStmt] return ... +# 73| 0: [MethodAccess] getBaseClassInt(...) +# 73| -1: [VarAccess] a0 +# 73| 3: [Method] invoke +#-----| 4: (Parameters) +# 73| 0: [Parameter] a0 +# 73| 5: [BlockStmt] { ... } +# 73| 0: [ReturnStmt] return ... +# 73| 0: [MethodAccess] get(...) +# 73| -1: [ThisAccess] this +# 73| 0: [VarAccess] a0 +# 73| -3: [TypeAccess] KProperty1 +# 73| 0: [TypeAccess] Base +# 73| 1: [TypeAccess] Integer +# 73| 22: [Method] getDelegatedToBaseClass2 # 73| 3: [TypeAccess] int # 73| 5: [BlockStmt] { ... } # 73| 0: [ReturnStmt] return ... @@ -1477,14 +1504,14 @@ delegatedProperties.kt: # 73| 1: [Constructor] # 73| 5: [BlockStmt] { ... } # 73| 0: [SuperConstructorInvocationStmt] super(...) -# 73| 1: [Method] get +# 73| 2: [Method] get #-----| 4: (Parameters) # 73| 0: [Parameter] a0 # 73| 5: [BlockStmt] { ... } # 73| 0: [ReturnStmt] return ... # 73| 0: [MethodAccess] getDelegatedToBaseClass2(...) # 73| -1: [VarAccess] a0 -# 73| 1: [Method] invoke +# 73| 3: [Method] invoke #-----| 4: (Parameters) # 73| 0: [Parameter] a0 # 73| 5: [BlockStmt] { ... } @@ -1495,66 +1522,6 @@ delegatedProperties.kt: # 73| -3: [TypeAccess] KProperty1 # 73| 0: [TypeAccess] MyClass # 73| 1: [TypeAccess] Integer -# 73| 21: [FieldDeclaration] KProperty1 delegatedToBaseClass2$delegate; -# 73| -1: [TypeAccess] KProperty1 -# 73| 0: [TypeAccess] Base -# 73| 1: [TypeAccess] Integer -# 73| 0: [PropertyRefExpr] ...::... -# 73| -4: [AnonymousClass] new KProperty1(...) { ... } -# 73| 1: [Constructor] -# 73| 5: [BlockStmt] { ... } -# 73| 0: [SuperConstructorInvocationStmt] super(...) -# 73| 1: [Method] get -#-----| 4: (Parameters) -# 73| 0: [Parameter] a0 -# 73| 5: [BlockStmt] { ... } -# 73| 0: [ReturnStmt] return ... -# 73| 0: [MethodAccess] getBaseClassInt(...) -# 73| -1: [VarAccess] a0 -# 73| 1: [Method] invoke -#-----| 4: (Parameters) -# 73| 0: [Parameter] a0 -# 73| 5: [BlockStmt] { ... } -# 73| 0: [ReturnStmt] return ... -# 73| 0: [MethodAccess] get(...) -# 73| -1: [ThisAccess] this -# 73| 0: [VarAccess] a0 -# 73| -3: [TypeAccess] KProperty1 -# 73| 0: [TypeAccess] Base -# 73| 1: [TypeAccess] Integer -# 75| 23: [Method] getDelegatedToAnotherClass1 -# 75| 3: [TypeAccess] int -# 75| 5: [BlockStmt] { ... } -# 75| 0: [ReturnStmt] return ... -# 75| 0: [MethodAccess] getValue(...) -# 75| -2: [TypeAccess] Integer -# 75| -1: [TypeAccess] PropertyReferenceDelegatesKt -# 75| 0: [VarAccess] this.delegatedToAnotherClass1$delegate -# 75| -1: [ThisAccess] this -# 1| 1: [ThisAccess] this -# 75| 2: [PropertyRefExpr] ...::... -# 75| -4: [AnonymousClass] new KProperty1(...) { ... } -# 75| 1: [Constructor] -# 75| 5: [BlockStmt] { ... } -# 75| 0: [SuperConstructorInvocationStmt] super(...) -# 75| 1: [Method] get -#-----| 4: (Parameters) -# 75| 0: [Parameter] a0 -# 75| 5: [BlockStmt] { ... } -# 75| 0: [ReturnStmt] return ... -# 75| 0: [MethodAccess] getDelegatedToAnotherClass1(...) -# 75| -1: [VarAccess] a0 -# 75| 1: [Method] invoke -#-----| 4: (Parameters) -# 75| 0: [Parameter] a0 -# 75| 5: [BlockStmt] { ... } -# 75| 0: [ReturnStmt] return ... -# 75| 0: [MethodAccess] get(...) -# 75| -1: [ThisAccess] this -# 75| 0: [VarAccess] a0 -# 75| -3: [TypeAccess] KProperty1 -# 75| 0: [TypeAccess] MyClass -# 75| 1: [TypeAccess] Integer # 75| 23: [FieldDeclaration] KProperty0 delegatedToAnotherClass1$delegate; # 75| -1: [TypeAccess] KProperty0 # 75| 0: [TypeAccess] Integer @@ -1570,15 +1537,15 @@ delegatedProperties.kt: # 75| 0: [VarAccess] this. # 75| -1: [ThisAccess] this # 75| 1: [VarAccess] -# 75| 1: [FieldDeclaration] ClassWithDelegate ; +# 75| 2: [FieldDeclaration] ClassWithDelegate ; # 75| -1: [TypeAccess] ClassWithDelegate -# 75| 1: [Method] get +# 75| 3: [Method] get # 75| 5: [BlockStmt] { ... } # 75| 0: [ReturnStmt] return ... # 75| 0: [MethodAccess] getAnotherClassInt(...) # 75| -1: [VarAccess] this. # 75| -1: [ThisAccess] this -# 75| 1: [Method] invoke +# 75| 4: [Method] invoke # 75| 5: [BlockStmt] { ... } # 75| 0: [ReturnStmt] return ... # 75| 0: [MethodAccess] get(...) @@ -1588,7 +1555,68 @@ delegatedProperties.kt: # 75| 0: [MethodAccess] getAnotherClassInstance(...) # 75| -1: [ThisAccess] MyClass.this # 75| 0: [TypeAccess] MyClass -# 77| 25: [Method] getDelegatedToTopLevel +# 75| 24: [Method] getDelegatedToAnotherClass1 +# 75| 3: [TypeAccess] int +# 75| 5: [BlockStmt] { ... } +# 75| 0: [ReturnStmt] return ... +# 75| 0: [MethodAccess] getValue(...) +# 75| -2: [TypeAccess] Integer +# 75| -1: [TypeAccess] PropertyReferenceDelegatesKt +# 75| 0: [VarAccess] this.delegatedToAnotherClass1$delegate +# 75| -1: [ThisAccess] this +# 1| 1: [ThisAccess] this +# 75| 2: [PropertyRefExpr] ...::... +# 75| -4: [AnonymousClass] new KProperty1(...) { ... } +# 75| 1: [Constructor] +# 75| 5: [BlockStmt] { ... } +# 75| 0: [SuperConstructorInvocationStmt] super(...) +# 75| 2: [Method] get +#-----| 4: (Parameters) +# 75| 0: [Parameter] a0 +# 75| 5: [BlockStmt] { ... } +# 75| 0: [ReturnStmt] return ... +# 75| 0: [MethodAccess] getDelegatedToAnotherClass1(...) +# 75| -1: [VarAccess] a0 +# 75| 3: [Method] invoke +#-----| 4: (Parameters) +# 75| 0: [Parameter] a0 +# 75| 5: [BlockStmt] { ... } +# 75| 0: [ReturnStmt] return ... +# 75| 0: [MethodAccess] get(...) +# 75| -1: [ThisAccess] this +# 75| 0: [VarAccess] a0 +# 75| -3: [TypeAccess] KProperty1 +# 75| 0: [TypeAccess] MyClass +# 75| 1: [TypeAccess] Integer +# 77| 25: [FieldDeclaration] KMutableProperty0 delegatedToTopLevel$delegate; +# 77| -1: [TypeAccess] KMutableProperty0 +# 77| 0: [TypeAccess] Integer +# 77| 0: [PropertyRefExpr] ...::... +# 77| -4: [AnonymousClass] new KMutableProperty0(...) { ... } +# 77| 1: [Constructor] +# 77| 5: [BlockStmt] { ... } +# 77| 0: [SuperConstructorInvocationStmt] super(...) +# 77| 2: [Method] get +# 77| 5: [BlockStmt] { ... } +# 77| 0: [ReturnStmt] return ... +# 77| 0: [MethodAccess] getTopLevelInt(...) +# 77| -1: [TypeAccess] DelegatedPropertiesKt +# 77| 3: [Method] invoke +# 77| 5: [BlockStmt] { ... } +# 77| 0: [ReturnStmt] return ... +# 77| 0: [MethodAccess] get(...) +# 77| -1: [ThisAccess] this +# 77| 4: [Method] set +#-----| 4: (Parameters) +# 77| 0: [Parameter] a0 +# 77| 5: [BlockStmt] { ... } +# 77| 0: [ReturnStmt] return ... +# 77| 0: [MethodAccess] setTopLevelInt(...) +# 77| -1: [TypeAccess] DelegatedPropertiesKt +# 77| 0: [VarAccess] a0 +# 77| -3: [TypeAccess] KMutableProperty0 +# 77| 0: [TypeAccess] Integer +# 77| 26: [Method] getDelegatedToTopLevel # 77| 3: [TypeAccess] int # 77| 5: [BlockStmt] { ... } # 77| 0: [ReturnStmt] return ... @@ -1603,14 +1631,14 @@ delegatedProperties.kt: # 77| 1: [Constructor] # 77| 5: [BlockStmt] { ... } # 77| 0: [SuperConstructorInvocationStmt] super(...) -# 77| 1: [Method] get +# 77| 2: [Method] get #-----| 4: (Parameters) # 77| 0: [Parameter] a0 # 77| 5: [BlockStmt] { ... } # 77| 0: [ReturnStmt] return ... # 77| 0: [MethodAccess] getDelegatedToTopLevel(...) # 77| -1: [VarAccess] a0 -# 77| 1: [Method] invoke +# 77| 3: [Method] invoke #-----| 4: (Parameters) # 77| 0: [Parameter] a0 # 77| 5: [BlockStmt] { ... } @@ -1618,7 +1646,7 @@ delegatedProperties.kt: # 77| 0: [MethodAccess] get(...) # 77| -1: [ThisAccess] this # 77| 0: [VarAccess] a0 -# 77| 1: [Method] set +# 77| 4: [Method] set #-----| 4: (Parameters) # 77| 0: [Parameter] a0 # 77| 1: [Parameter] a1 @@ -1630,7 +1658,7 @@ delegatedProperties.kt: # 77| -3: [TypeAccess] KMutableProperty1 # 77| 0: [TypeAccess] MyClass # 77| 1: [TypeAccess] Integer -# 77| 25: [Method] setDelegatedToTopLevel +# 77| 27: [Method] setDelegatedToTopLevel # 77| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 77| 0: [Parameter] @@ -1648,14 +1676,14 @@ delegatedProperties.kt: # 77| 1: [Constructor] # 77| 5: [BlockStmt] { ... } # 77| 0: [SuperConstructorInvocationStmt] super(...) -# 77| 1: [Method] get +# 77| 2: [Method] get #-----| 4: (Parameters) # 77| 0: [Parameter] a0 # 77| 5: [BlockStmt] { ... } # 77| 0: [ReturnStmt] return ... # 77| 0: [MethodAccess] getDelegatedToTopLevel(...) # 77| -1: [VarAccess] a0 -# 77| 1: [Method] invoke +# 77| 3: [Method] invoke #-----| 4: (Parameters) # 77| 0: [Parameter] a0 # 77| 5: [BlockStmt] { ... } @@ -1663,7 +1691,7 @@ delegatedProperties.kt: # 77| 0: [MethodAccess] get(...) # 77| -1: [ThisAccess] this # 77| 0: [VarAccess] a0 -# 77| 1: [Method] set +# 77| 4: [Method] set #-----| 4: (Parameters) # 77| 0: [Parameter] a0 # 77| 1: [Parameter] a1 @@ -1676,35 +1704,26 @@ delegatedProperties.kt: # 77| 0: [TypeAccess] MyClass # 77| 1: [TypeAccess] Integer # 77| 3: [VarAccess] -# 77| 25: [FieldDeclaration] KMutableProperty0 delegatedToTopLevel$delegate; -# 77| -1: [TypeAccess] KMutableProperty0 -# 77| 0: [TypeAccess] Integer -# 77| 0: [PropertyRefExpr] ...::... -# 77| -4: [AnonymousClass] new KMutableProperty0(...) { ... } -# 77| 1: [Constructor] -# 77| 5: [BlockStmt] { ... } -# 77| 0: [SuperConstructorInvocationStmt] super(...) -# 77| 1: [Method] get -# 77| 5: [BlockStmt] { ... } -# 77| 0: [ReturnStmt] return ... -# 77| 0: [MethodAccess] getTopLevelInt(...) -# 77| -1: [TypeAccess] DelegatedPropertiesKt -# 77| 1: [Method] invoke -# 77| 5: [BlockStmt] { ... } -# 77| 0: [ReturnStmt] return ... -# 77| 0: [MethodAccess] get(...) -# 77| -1: [ThisAccess] this -# 77| 1: [Method] set -#-----| 4: (Parameters) -# 77| 0: [Parameter] a0 -# 77| 5: [BlockStmt] { ... } -# 77| 0: [ReturnStmt] return ... -# 77| 0: [MethodAccess] setTopLevelInt(...) -# 77| -1: [TypeAccess] DelegatedPropertiesKt -# 77| 0: [VarAccess] a0 -# 77| -3: [TypeAccess] KMutableProperty0 -# 77| 0: [TypeAccess] Integer -# 79| 28: [Method] getMax +# 79| 28: [FieldDeclaration] KProperty0 max$delegate; +# 79| -1: [TypeAccess] KProperty0 +# 79| 0: [TypeAccess] Integer +# 79| 0: [PropertyRefExpr] ...::... +# 79| -4: [AnonymousClass] new KProperty0(...) { ... } +# 79| 1: [Constructor] +# 79| 5: [BlockStmt] { ... } +# 79| 0: [SuperConstructorInvocationStmt] super(...) +# 79| 2: [Method] get +# 79| 5: [BlockStmt] { ... } +# 79| 0: [ReturnStmt] return ... +# 79| 0: [VarAccess] MAX_VALUE +# 79| 3: [Method] invoke +# 79| 5: [BlockStmt] { ... } +# 79| 0: [ReturnStmt] return ... +# 79| 0: [MethodAccess] get(...) +# 79| -1: [ThisAccess] this +# 79| -3: [TypeAccess] KProperty0 +# 79| 0: [TypeAccess] Integer +# 79| 29: [Method] getMax # 79| 3: [TypeAccess] int # 79| 5: [BlockStmt] { ... } # 79| 0: [ReturnStmt] return ... @@ -1719,14 +1738,14 @@ delegatedProperties.kt: # 79| 1: [Constructor] # 79| 5: [BlockStmt] { ... } # 79| 0: [SuperConstructorInvocationStmt] super(...) -# 79| 1: [Method] get +# 79| 2: [Method] get #-----| 4: (Parameters) # 79| 0: [Parameter] a0 # 79| 5: [BlockStmt] { ... } # 79| 0: [ReturnStmt] return ... # 79| 0: [MethodAccess] getMax(...) # 79| -1: [VarAccess] a0 -# 79| 1: [Method] invoke +# 79| 3: [Method] invoke #-----| 4: (Parameters) # 79| 0: [Parameter] a0 # 79| 5: [BlockStmt] { ... } @@ -1737,25 +1756,6 @@ delegatedProperties.kt: # 79| -3: [TypeAccess] KProperty1 # 79| 0: [TypeAccess] MyClass # 79| 1: [TypeAccess] Integer -# 79| 28: [FieldDeclaration] KProperty0 max$delegate; -# 79| -1: [TypeAccess] KProperty0 -# 79| 0: [TypeAccess] Integer -# 79| 0: [PropertyRefExpr] ...::... -# 79| -4: [AnonymousClass] new KProperty0(...) { ... } -# 79| 1: [Constructor] -# 79| 5: [BlockStmt] { ... } -# 79| 0: [SuperConstructorInvocationStmt] super(...) -# 79| 1: [Method] get -# 79| 5: [BlockStmt] { ... } -# 79| 0: [ReturnStmt] return ... -# 79| 0: [VarAccess] MAX_VALUE -# 79| 1: [Method] invoke -# 79| 5: [BlockStmt] { ... } -# 79| 0: [ReturnStmt] return ... -# 79| 0: [MethodAccess] get(...) -# 79| -1: [ThisAccess] this -# 79| -3: [TypeAccess] KProperty0 -# 79| 0: [TypeAccess] Integer # 81| 30: [Method] fn # 81| 3: [TypeAccess] Unit # 81| 5: [BlockStmt] { ... } @@ -1774,20 +1774,20 @@ delegatedProperties.kt: # 82| 0: [VarAccess] this. # 82| -1: [ThisAccess] this # 82| 1: [VarAccess] -# 82| 1: [FieldDeclaration] MyClass ; +# 82| 2: [FieldDeclaration] MyClass ; # 82| -1: [TypeAccess] MyClass -# 82| 1: [Method] get +# 82| 3: [Method] get # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... # 82| 0: [MethodAccess] getMemberInt(...) # 82| -1: [VarAccess] this. # 82| -1: [ThisAccess] this -# 82| 1: [Method] invoke +# 82| 4: [Method] invoke # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... # 82| 0: [MethodAccess] get(...) # 82| -1: [ThisAccess] this -# 82| 1: [Method] set +# 82| 5: [Method] set #-----| 4: (Parameters) # 82| 0: [Parameter] a0 # 82| 5: [BlockStmt] { ... } @@ -1804,7 +1804,7 @@ delegatedProperties.kt: # 82| 1: [Constructor] # 82| 5: [BlockStmt] { ... } # 82| 0: [SuperConstructorInvocationStmt] super(...) -# 82| 1: [Method] +# 82| 2: [Method] # 82| 3: [TypeAccess] int # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... @@ -1818,18 +1818,18 @@ delegatedProperties.kt: # 82| 1: [Constructor] # 82| 5: [BlockStmt] { ... } # 82| 0: [SuperConstructorInvocationStmt] super(...) -# 82| 1: [Method] get +# 82| 2: [Method] get # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... # 82| 0: [MethodAccess] (...) # 82| -1: [ClassInstanceExpr] new (...) # 82| -3: [TypeAccess] Object -# 82| 1: [Method] invoke +# 82| 3: [Method] invoke # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... # 82| 0: [MethodAccess] get(...) # 82| -1: [ThisAccess] this -# 82| 1: [Method] set +# 82| 4: [Method] set #-----| 4: (Parameters) # 82| 0: [Parameter] a0 # 82| 5: [BlockStmt] { ... } @@ -1845,7 +1845,7 @@ delegatedProperties.kt: # 82| 1: [Constructor] # 82| 5: [BlockStmt] { ... } # 82| 0: [SuperConstructorInvocationStmt] super(...) -# 82| 1: [Method] +# 82| 2: [Method] # 82| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 82| 0: [Parameter] value @@ -1862,18 +1862,18 @@ delegatedProperties.kt: # 82| 1: [Constructor] # 82| 5: [BlockStmt] { ... } # 82| 0: [SuperConstructorInvocationStmt] super(...) -# 82| 1: [Method] get +# 82| 2: [Method] get # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... # 82| 0: [MethodAccess] (...) # 82| -1: [ClassInstanceExpr] new (...) # 82| -3: [TypeAccess] Object -# 82| 1: [Method] invoke +# 82| 3: [Method] invoke # 82| 5: [BlockStmt] { ... } # 82| 0: [ReturnStmt] return ... # 82| 0: [MethodAccess] get(...) # 82| -1: [ThisAccess] this -# 82| 1: [Method] set +# 82| 4: [Method] set #-----| 4: (Parameters) # 82| 0: [Parameter] a0 # 82| 5: [BlockStmt] { ... } @@ -2849,7 +2849,7 @@ exprs.kt: # 142| 0: [ReturnStmt] return ... # 142| 0: [VarAccess] this.n # 142| -1: [ThisAccess] this -# 142| 2: [FieldDeclaration] int n; +# 142| 3: [FieldDeclaration] int n; # 142| -1: [TypeAccess] int # 142| 0: [VarAccess] n # 143| 4: [Method] foo @@ -2875,14 +2875,14 @@ exprs.kt: # 148| 0: [SuperConstructorInvocationStmt] super(...) # 148| 1: [BlockStmt] { ... } # 168| 6: [Class] Direction -# 0| 1: [Method] values -# 0| 3: [TypeAccess] Direction[] -# 0| 0: [TypeAccess] Direction -# 0| 1: [Method] valueOf +# 0| 2: [Method] valueOf # 0| 3: [TypeAccess] Direction #-----| 4: (Parameters) # 0| 0: [Parameter] value # 0| 0: [TypeAccess] String +# 0| 3: [Method] values +# 0| 3: [TypeAccess] Direction[] +# 0| 0: [TypeAccess] Direction # 168| 4: [Constructor] Direction # 168| 5: [BlockStmt] { ... } # 168| 0: [ExprStmt] ; @@ -2907,14 +2907,14 @@ exprs.kt: # 169| 0: [ClassInstanceExpr] new Direction(...) # 169| -3: [TypeAccess] Direction # 172| 7: [Class] Color -# 0| 1: [Method] values -# 0| 3: [TypeAccess] Color[] -# 0| 0: [TypeAccess] Color -# 0| 1: [Method] valueOf +# 0| 2: [Method] valueOf # 0| 3: [TypeAccess] Color #-----| 4: (Parameters) # 0| 0: [Parameter] value # 0| 0: [TypeAccess] String +# 0| 3: [Method] values +# 0| 3: [TypeAccess] Color[] +# 0| 0: [TypeAccess] Color # 172| 4: [Constructor] Color #-----| 4: (Parameters) # 172| 0: [Parameter] rgb @@ -2934,7 +2934,7 @@ exprs.kt: # 172| 0: [ReturnStmt] return ... # 172| 0: [VarAccess] this.rgb # 172| -1: [ThisAccess] this -# 172| 5: [FieldDeclaration] int rgb; +# 172| 6: [FieldDeclaration] int rgb; # 172| -1: [TypeAccess] int # 172| 0: [VarAccess] rgb # 173| 7: [FieldDeclaration] Color RED; @@ -2967,7 +2967,7 @@ exprs.kt: # 186| 0: [ReturnStmt] return ... # 186| 0: [VarAccess] this.a1 # 186| -1: [ThisAccess] this -# 186| 2: [FieldDeclaration] int a1; +# 186| 3: [FieldDeclaration] int a1; # 186| -1: [TypeAccess] int # 186| 0: [IntegerLiteral] 1 # 187| 4: [Method] getObject @@ -2988,12 +2988,6 @@ exprs.kt: # 190| 0: [ExprStmt] ; # 190| 0: [KtInitializerAssignExpr] ...=... # 190| 0: [VarAccess] a3 -# 190| 2: [Method] getA3 -# 190| 3: [TypeAccess] String -# 190| 5: [BlockStmt] { ... } -# 190| 0: [ReturnStmt] return ... -# 190| 0: [VarAccess] this.a3 -# 190| -1: [ThisAccess] this # 190| 2: [FieldDeclaration] String a3; # 190| -1: [TypeAccess] String # 190| 0: [MethodAccess] toString(...) @@ -3001,6 +2995,12 @@ exprs.kt: # 190| 0: [MethodAccess] getA1(...) # 190| -1: [ThisAccess] this # 190| 1: [VarAccess] a2 +# 190| 3: [Method] getA3 +# 190| 3: [TypeAccess] String +# 190| 5: [BlockStmt] { ... } +# 190| 0: [ReturnStmt] return ... +# 190| 0: [VarAccess] this.a3 +# 190| -1: [ThisAccess] this # 189| 1: [ExprStmt] ; # 189| 0: [ClassInstanceExpr] new (...) # 189| -3: [TypeAccess] Interface1 @@ -3494,7 +3494,7 @@ funcExprs.kt: # 22| 1: [Constructor] # 22| 5: [BlockStmt] { ... } # 22| 0: [SuperConstructorInvocationStmt] super(...) -# 22| 1: [Method] invoke +# 22| 2: [Method] invoke # 22| 3: [TypeAccess] int # 22| 5: [BlockStmt] { ... } # 22| 0: [ReturnStmt] return ... @@ -3509,7 +3509,7 @@ funcExprs.kt: # 23| 1: [Constructor] # 23| 5: [BlockStmt] { ... } # 23| 0: [SuperConstructorInvocationStmt] super(...) -# 23| 1: [Method] invoke +# 23| 2: [Method] invoke # 23| 3: [TypeAccess] Object # 23| 5: [BlockStmt] { ... } # 23| 0: [ReturnStmt] return ... @@ -3524,7 +3524,7 @@ funcExprs.kt: # 24| 1: [Constructor] # 24| 5: [BlockStmt] { ... } # 24| 0: [SuperConstructorInvocationStmt] super(...) -# 24| 1: [Method] invoke +# 24| 2: [Method] invoke # 24| 3: [TypeAccess] Object # 24| 5: [BlockStmt] { ... } # 24| 0: [ReturnStmt] return ... @@ -3540,7 +3540,7 @@ funcExprs.kt: # 25| 1: [Constructor] # 25| 5: [BlockStmt] { ... } # 25| 0: [SuperConstructorInvocationStmt] super(...) -# 25| 1: [Method] invoke +# 25| 2: [Method] invoke # 25| 3: [TypeAccess] int #-----| 4: (Parameters) # 25| 0: [Parameter] a @@ -3560,7 +3560,7 @@ funcExprs.kt: # 26| 1: [Constructor] # 26| 5: [BlockStmt] { ... } # 26| 0: [SuperConstructorInvocationStmt] super(...) -# 26| 1: [Method] invoke +# 26| 2: [Method] invoke # 26| 3: [TypeAccess] int #-----| 4: (Parameters) # 26| 0: [Parameter] it @@ -3580,7 +3580,7 @@ funcExprs.kt: # 27| 1: [Constructor] # 27| 5: [BlockStmt] { ... } # 27| 0: [SuperConstructorInvocationStmt] super(...) -# 27| 1: [Method] invoke +# 27| 2: [Method] invoke # 27| 3: [TypeAccess] int #-----| 4: (Parameters) # 27| 0: [Parameter] @@ -3606,7 +3606,7 @@ funcExprs.kt: # 29| 1: [Constructor] # 29| 5: [BlockStmt] { ... } # 29| 0: [SuperConstructorInvocationStmt] super(...) -# 29| 1: [Method] invoke +# 29| 2: [Method] invoke # 29| 3: [TypeAccess] Object #-----| 4: (Parameters) # 29| 0: [Parameter] a @@ -3626,7 +3626,7 @@ funcExprs.kt: # 30| 1: [Constructor] # 30| 5: [BlockStmt] { ... } # 30| 0: [SuperConstructorInvocationStmt] super(...) -# 30| 1: [Method] invoke +# 30| 2: [Method] invoke # 30| 3: [TypeAccess] int #-----| 4: (Parameters) # 30| 0: [Parameter] @@ -3649,7 +3649,7 @@ funcExprs.kt: # 31| 1: [Constructor] # 31| 5: [BlockStmt] { ... } # 31| 0: [SuperConstructorInvocationStmt] super(...) -# 31| 1: [Method] invoke +# 31| 2: [Method] invoke # 31| 3: [TypeAccess] int #-----| 4: (Parameters) # 31| 0: [Parameter] @@ -3672,7 +3672,7 @@ funcExprs.kt: # 32| 1: [Constructor] # 32| 5: [BlockStmt] { ... } # 32| 0: [SuperConstructorInvocationStmt] super(...) -# 32| 1: [ExtensionMethod] invoke +# 32| 2: [ExtensionMethod] invoke # 32| 3: [TypeAccess] int #-----| 4: (Parameters) # 32| 0: [Parameter] $this$functionExpression3 @@ -3697,7 +3697,7 @@ funcExprs.kt: # 33| 1: [Constructor] # 33| 5: [BlockStmt] { ... } # 33| 0: [SuperConstructorInvocationStmt] super(...) -# 33| 1: [Method] invoke +# 33| 2: [Method] invoke # 33| 3: [TypeAccess] Function1 # 33| 0: [TypeAccess] Integer # 33| 1: [TypeAccess] Double @@ -3711,7 +3711,7 @@ funcExprs.kt: # 33| 1: [Constructor] # 33| 5: [BlockStmt] { ... } # 33| 0: [SuperConstructorInvocationStmt] super(...) -# 33| 1: [Method] invoke +# 33| 2: [Method] invoke # 33| 3: [TypeAccess] double #-----| 4: (Parameters) # 33| 0: [Parameter] b @@ -3736,7 +3736,7 @@ funcExprs.kt: # 35| 1: [Constructor] # 35| 5: [BlockStmt] { ... } # 35| 0: [SuperConstructorInvocationStmt] super(...) -# 35| 1: [Method] invoke +# 35| 2: [Method] invoke # 35| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 35| 0: [Parameter] a0 @@ -3821,7 +3821,7 @@ funcExprs.kt: # 36| 1: [Constructor] # 36| 5: [BlockStmt] { ... } # 36| 0: [SuperConstructorInvocationStmt] super(...) -# 36| 1: [Method] invoke +# 36| 2: [Method] invoke # 36| 3: [TypeAccess] String #-----| 4: (Parameters) # 36| 0: [Parameter] a0 @@ -3873,7 +3873,7 @@ funcExprs.kt: # 36| 5: [BlockStmt] { ... } # 36| 0: [ReturnStmt] return ... # 36| 0: [StringLiteral] -# 36| 1: [Method] invoke +# 36| 2: [Method] invoke #-----| 4: (Parameters) # 36| 0: [Parameter] a0 # 36| 5: [BlockStmt] { ... } @@ -4012,14 +4012,14 @@ funcExprs.kt: # 38| 0: [VarAccess] this. # 38| -1: [ThisAccess] this # 38| 1: [VarAccess] -# 38| 1: [Method] invoke +# 38| 2: [FieldDeclaration] FuncRef ; +# 38| -1: [TypeAccess] FuncRef +# 38| 3: [Method] invoke # 38| 5: [BlockStmt] { ... } # 38| 0: [ReturnStmt] return ... # 38| 0: [MethodAccess] f0(...) # 38| -1: [VarAccess] this. # 38| -1: [ThisAccess] this -# 38| 1: [FieldDeclaration] FuncRef ; -# 38| -1: [TypeAccess] FuncRef # 38| -3: [TypeAccess] Function0 # 38| 0: [TypeAccess] Integer # 38| 0: [ClassInstanceExpr] new FuncRef(...) @@ -4039,14 +4039,14 @@ funcExprs.kt: # 39| 0: [VarAccess] this. # 39| -1: [ThisAccess] this # 39| 1: [VarAccess] -# 39| 1: [Method] invoke +# 39| 2: [FieldDeclaration] Companion ; +# 39| -1: [TypeAccess] Companion +# 39| 3: [Method] invoke # 39| 5: [BlockStmt] { ... } # 39| 0: [ReturnStmt] return ... # 39| 0: [MethodAccess] f0(...) # 39| -1: [VarAccess] this. # 39| -1: [ThisAccess] this -# 39| 1: [FieldDeclaration] Companion ; -# 39| -1: [TypeAccess] Companion # 39| -3: [TypeAccess] Function0 # 39| 0: [TypeAccess] Integer # 39| 0: [VarAccess] Companion @@ -4066,7 +4066,9 @@ funcExprs.kt: # 40| 0: [VarAccess] this. # 40| -1: [ThisAccess] this # 40| 1: [VarAccess] -# 40| 1: [Method] invoke +# 40| 2: [FieldDeclaration] FuncRef ; +# 40| -1: [TypeAccess] FuncRef +# 40| 3: [Method] invoke #-----| 4: (Parameters) # 40| 0: [Parameter] a0 # 40| 5: [BlockStmt] { ... } @@ -4075,8 +4077,6 @@ funcExprs.kt: # 40| -1: [VarAccess] this. # 40| -1: [ThisAccess] this # 40| 0: [VarAccess] a0 -# 40| 1: [FieldDeclaration] FuncRef ; -# 40| -1: [TypeAccess] FuncRef # 40| -3: [TypeAccess] Function1 # 40| 0: [TypeAccess] Integer # 40| 1: [TypeAccess] Integer @@ -4091,7 +4091,7 @@ funcExprs.kt: # 41| 1: [Constructor] # 41| 5: [BlockStmt] { ... } # 41| 0: [SuperConstructorInvocationStmt] super(...) -# 41| 1: [Method] invoke +# 41| 2: [Method] invoke #-----| 4: (Parameters) # 41| 0: [Parameter] a0 # 41| 1: [Parameter] a1 @@ -4120,7 +4120,9 @@ funcExprs.kt: # 42| 0: [VarAccess] this. # 42| -1: [ThisAccess] this # 42| 1: [VarAccess] -# 42| 1: [Method] invoke +# 42| 2: [FieldDeclaration] int ; +# 42| -1: [TypeAccess] int +# 42| 3: [Method] invoke #-----| 4: (Parameters) # 42| 0: [Parameter] a0 # 42| 5: [BlockStmt] { ... } @@ -4130,8 +4132,6 @@ funcExprs.kt: # 42| 0: [VarAccess] this. # 42| -1: [ThisAccess] this # 42| 1: [VarAccess] a0 -# 42| 1: [FieldDeclaration] int ; -# 42| -1: [TypeAccess] int # 42| -3: [TypeAccess] Function1 # 42| 0: [TypeAccess] Integer # 42| 1: [TypeAccess] Integer @@ -4145,7 +4145,7 @@ funcExprs.kt: # 43| 1: [Constructor] # 43| 5: [BlockStmt] { ... } # 43| 0: [SuperConstructorInvocationStmt] super(...) -# 43| 1: [Method] invoke +# 43| 2: [Method] invoke #-----| 4: (Parameters) # 43| 0: [Parameter] a0 # 43| 1: [Parameter] a1 @@ -4175,7 +4175,9 @@ funcExprs.kt: # 44| 0: [VarAccess] this. # 44| -1: [ThisAccess] this # 44| 1: [VarAccess] -# 44| 1: [Method] invoke +# 44| 2: [FieldDeclaration] FuncRef ; +# 44| -1: [TypeAccess] FuncRef +# 44| 3: [Method] invoke #-----| 4: (Parameters) # 44| 0: [Parameter] a0 # 44| 1: [Parameter] a1 @@ -4226,8 +4228,6 @@ funcExprs.kt: # 44| 19: [VarAccess] a19 # 44| 20: [VarAccess] a20 # 44| 21: [VarAccess] a21 -# 44| 1: [FieldDeclaration] FuncRef ; -# 44| -1: [TypeAccess] FuncRef # 44| -3: [TypeAccess] Function22 # 44| 0: [TypeAccess] Integer # 44| 1: [TypeAccess] Integer @@ -4270,7 +4270,9 @@ funcExprs.kt: # 45| 0: [VarAccess] this. # 45| -1: [ThisAccess] this # 45| 1: [VarAccess] -# 45| 1: [Method] invoke +# 45| 2: [FieldDeclaration] FuncRef ; +# 45| -1: [TypeAccess] FuncRef +# 45| 3: [Method] invoke #-----| 4: (Parameters) # 45| 0: [Parameter] a0 # 45| 5: [BlockStmt] { ... } @@ -4393,8 +4395,6 @@ funcExprs.kt: # 45| 1: [ArrayAccess] ...[...] # 45| 0: [VarAccess] a0 # 45| 1: [IntegerLiteral] 22 -# 45| 1: [FieldDeclaration] FuncRef ; -# 45| -1: [TypeAccess] FuncRef # 45| -3: [TypeAccess] FunctionN # 45| 0: [TypeAccess] String # 45| 0: [ClassInstanceExpr] new FuncRef(...) @@ -4408,7 +4408,7 @@ funcExprs.kt: # 46| 1: [Constructor] # 46| 5: [BlockStmt] { ... } # 46| 0: [SuperConstructorInvocationStmt] super(...) -# 46| 1: [Method] invoke +# 46| 2: [Method] invoke #-----| 4: (Parameters) # 46| 0: [Parameter] a0 # 46| 5: [BlockStmt] { ... } @@ -4541,7 +4541,7 @@ funcExprs.kt: # 48| 1: [Constructor] # 48| 5: [BlockStmt] { ... } # 48| 0: [SuperConstructorInvocationStmt] super(...) -# 48| 1: [Method] local +# 48| 2: [Method] local # 48| 3: [TypeAccess] int # 48| 5: [BlockStmt] { ... } # 48| 0: [ReturnStmt] return ... @@ -4554,7 +4554,7 @@ funcExprs.kt: # 49| 1: [Constructor] # 49| 5: [BlockStmt] { ... } # 49| 0: [SuperConstructorInvocationStmt] super(...) -# 49| 1: [Method] invoke +# 49| 2: [Method] invoke # 49| 5: [BlockStmt] { ... } # 49| 0: [ReturnStmt] return ... # 49| 0: [MethodAccess] local(...) @@ -4571,7 +4571,7 @@ funcExprs.kt: # 51| 1: [Constructor] # 51| 5: [BlockStmt] { ... } # 51| 0: [SuperConstructorInvocationStmt] super(...) -# 51| 1: [Method] invoke +# 51| 2: [Method] invoke # 51| 5: [BlockStmt] { ... } # 51| 0: [ReturnStmt] return ... # 51| 0: [ClassInstanceExpr] new FuncRef(...) @@ -4755,7 +4755,7 @@ funcExprs.kt: # 75| 1: [Constructor] # 75| 5: [BlockStmt] { ... } # 75| 0: [SuperConstructorInvocationStmt] super(...) -# 75| 1: [Method] invoke +# 75| 2: [Method] invoke # 75| 3: [TypeAccess] String #-----| 4: (Parameters) # 75| 0: [Parameter] a @@ -4813,7 +4813,9 @@ kFunctionInvoke.kt: # 8| 0: [VarAccess] this. # 8| -1: [ThisAccess] this # 8| 1: [VarAccess] -# 8| 1: [Method] invoke +# 8| 2: [FieldDeclaration] A ; +# 8| -1: [TypeAccess] A +# 8| 3: [Method] invoke #-----| 4: (Parameters) # 8| 0: [Parameter] a0 # 8| 5: [BlockStmt] { ... } @@ -4822,8 +4824,6 @@ kFunctionInvoke.kt: # 8| -1: [VarAccess] this. # 8| -1: [ThisAccess] this # 8| 0: [VarAccess] a0 -# 8| 1: [FieldDeclaration] A ; -# 8| -1: [TypeAccess] A # 8| -3: [TypeAccess] Function1 # 8| 0: [TypeAccess] String # 8| 1: [TypeAccess] Unit @@ -4857,7 +4857,7 @@ localFunctionCalls.kt: # 5| 1: [Constructor] # 5| 5: [BlockStmt] { ... } # 5| 0: [SuperConstructorInvocationStmt] super(...) -# 5| 1: [Method] a +# 5| 2: [Method] a #-----| 2: (Generic Parameters) # 5| 0: [TypeVariable] T # 5| 3: [TypeAccess] int @@ -4890,7 +4890,7 @@ localFunctionCalls.kt: # 9| 1: [Constructor] # 9| 5: [BlockStmt] { ... } # 9| 0: [SuperConstructorInvocationStmt] super(...) -# 9| 1: [ExtensionMethod] f1 +# 9| 2: [ExtensionMethod] f1 #-----| 2: (Generic Parameters) # 9| 0: [TypeVariable] T1 # 9| 3: [TypeAccess] int @@ -4957,7 +4957,11 @@ samConversion.kt: # 2| 0: [VarAccess] this. # 2| -1: [ThisAccess] this # 2| 1: [VarAccess] -# 2| 1: [Method] accept +# 2| 2: [FieldDeclaration] Function1 ; +# 2| -1: [TypeAccess] Function1 +# 2| 0: [TypeAccess] Integer +# 2| 1: [TypeAccess] Boolean +# 2| 3: [Method] accept # 2| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 2| 0: [Parameter] i @@ -4967,17 +4971,13 @@ samConversion.kt: # 2| 0: [MethodAccess] invoke(...) # 2| -1: [VarAccess] # 2| 0: [VarAccess] i -# 2| 1: [FieldDeclaration] Function1 ; -# 2| -1: [TypeAccess] Function1 -# 2| 0: [TypeAccess] Integer -# 2| 1: [TypeAccess] Boolean # 2| -3: [TypeAccess] IntPredicate # 2| 0: [LambdaExpr] ...->... # 2| -4: [AnonymousClass] new Function1(...) { ... } # 2| 1: [Constructor] # 2| 5: [BlockStmt] { ... } # 2| 0: [SuperConstructorInvocationStmt] super(...) -# 2| 1: [Method] invoke +# 2| 2: [Method] invoke # 2| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 2| 0: [Parameter] it @@ -5008,7 +5008,12 @@ samConversion.kt: # 4| 0: [VarAccess] this. # 4| -1: [ThisAccess] this # 4| 1: [VarAccess] -# 4| 1: [Method] fn1 +# 4| 2: [FieldDeclaration] Function2 ; +# 4| -1: [TypeAccess] Function2 +# 4| 0: [TypeAccess] Integer +# 4| 1: [TypeAccess] Integer +# 4| 2: [TypeAccess] Unit +# 4| 3: [Method] fn1 # 4| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 4| 0: [Parameter] i @@ -5021,18 +5026,13 @@ samConversion.kt: # 4| -1: [VarAccess] # 4| 0: [VarAccess] i # 4| 1: [VarAccess] j -# 4| 1: [FieldDeclaration] Function2 ; -# 4| -1: [TypeAccess] Function2 -# 4| 0: [TypeAccess] Integer -# 4| 1: [TypeAccess] Integer -# 4| 2: [TypeAccess] Unit # 4| -3: [TypeAccess] InterfaceFn1 # 4| 0: [LambdaExpr] ...->... # 4| -4: [AnonymousClass] new Function2(...) { ... } # 4| 1: [Constructor] # 4| 5: [BlockStmt] { ... } # 4| 0: [SuperConstructorInvocationStmt] super(...) -# 4| 1: [Method] invoke +# 4| 2: [Method] invoke # 4| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 4| 0: [Parameter] a @@ -5062,7 +5062,12 @@ samConversion.kt: # 5| 0: [VarAccess] this. # 5| -1: [ThisAccess] this # 5| 1: [VarAccess] -# 5| 1: [Method] fn1 +# 5| 2: [FieldDeclaration] Function2 ; +# 5| -1: [TypeAccess] Function2 +# 5| 0: [TypeAccess] Integer +# 5| 1: [TypeAccess] Integer +# 5| 2: [TypeAccess] Unit +# 5| 3: [Method] fn1 # 5| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 5| 0: [Parameter] i @@ -5075,18 +5080,13 @@ samConversion.kt: # 5| -1: [VarAccess] # 5| 0: [VarAccess] i # 5| 1: [VarAccess] j -# 5| 1: [FieldDeclaration] Function2 ; -# 5| -1: [TypeAccess] Function2 -# 5| 0: [TypeAccess] Integer -# 5| 1: [TypeAccess] Integer -# 5| 2: [TypeAccess] Unit # 5| -3: [TypeAccess] InterfaceFn1 # 5| 0: [MemberRefExpr] ...::... # 5| -4: [AnonymousClass] new Function2(...) { ... } # 5| 1: [Constructor] # 5| 5: [BlockStmt] { ... } # 5| 0: [SuperConstructorInvocationStmt] super(...) -# 5| 1: [Method] invoke +# 5| 2: [Method] invoke #-----| 4: (Parameters) # 5| 0: [Parameter] a0 # 5| 1: [Parameter] a1 @@ -5116,7 +5116,12 @@ samConversion.kt: # 7| 0: [VarAccess] this. # 7| -1: [ThisAccess] this # 7| 1: [VarAccess] -# 7| 1: [ExtensionMethod] ext +# 7| 2: [FieldDeclaration] Function2 ; +# 7| -1: [TypeAccess] Function2 +# 7| 0: [TypeAccess] String +# 7| 1: [TypeAccess] Integer +# 7| 2: [TypeAccess] Boolean +# 7| 3: [ExtensionMethod] ext # 7| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 7| 0: [Parameter] @@ -5129,18 +5134,13 @@ samConversion.kt: # 7| -1: [VarAccess] # 7| 0: [ExtensionReceiverAccess] this # 7| 1: [VarAccess] i -# 7| 1: [FieldDeclaration] Function2 ; -# 7| -1: [TypeAccess] Function2 -# 7| 0: [TypeAccess] String -# 7| 1: [TypeAccess] Integer -# 7| 2: [TypeAccess] Boolean # 7| -3: [TypeAccess] InterfaceFnExt1 # 7| 0: [LambdaExpr] ...->... # 7| -4: [AnonymousClass] new Function2(...) { ... } # 7| 1: [Constructor] # 7| 5: [BlockStmt] { ... } # 7| 0: [SuperConstructorInvocationStmt] super(...) -# 7| 1: [ExtensionMethod] invoke +# 7| 2: [ExtensionMethod] invoke # 7| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 7| 0: [Parameter] $this$InterfaceFnExt1 @@ -5172,7 +5172,11 @@ samConversion.kt: # 9| 0: [VarAccess] this. # 9| -1: [ThisAccess] this # 9| 1: [VarAccess] -# 9| 1: [Method] accept +# 9| 2: [FieldDeclaration] Function1 ; +# 9| -1: [TypeAccess] Function1 +# 9| 0: [TypeAccess] Integer +# 9| 1: [TypeAccess] Boolean +# 9| 3: [Method] accept # 9| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 9| 0: [Parameter] i @@ -5182,10 +5186,6 @@ samConversion.kt: # 9| 0: [MethodAccess] invoke(...) # 9| -1: [VarAccess] # 9| 0: [VarAccess] i -# 9| 1: [FieldDeclaration] Function1 ; -# 9| -1: [TypeAccess] Function1 -# 9| 0: [TypeAccess] Integer -# 9| 1: [TypeAccess] Boolean # 9| -3: [TypeAccess] IntPredicate # 9| 0: [WhenExpr] when ... # 9| 0: [WhenBranch] ... -> ... @@ -5196,7 +5196,7 @@ samConversion.kt: # 9| 1: [Constructor] # 9| 5: [BlockStmt] { ... } # 9| 0: [SuperConstructorInvocationStmt] super(...) -# 9| 1: [Method] invoke +# 9| 2: [Method] invoke # 9| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 10| 0: [Parameter] j @@ -5219,7 +5219,7 @@ samConversion.kt: # 11| 1: [Constructor] # 11| 5: [BlockStmt] { ... } # 11| 0: [SuperConstructorInvocationStmt] super(...) -# 11| 1: [Method] invoke +# 11| 2: [Method] invoke # 11| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 12| 0: [Parameter] j @@ -5307,7 +5307,7 @@ samConversion.kt: # 41| 1: [Constructor] # 41| 5: [BlockStmt] { ... } # 41| 0: [SuperConstructorInvocationStmt] super(...) -# 41| 1: [Method] invoke +# 41| 2: [Method] invoke #-----| 4: (Parameters) # 41| 0: [Parameter] a0 # 41| 5: [BlockStmt] { ... } @@ -5447,7 +5447,10 @@ samConversion.kt: # 42| 0: [VarAccess] this. # 42| -1: [ThisAccess] this # 42| 1: [VarAccess] -# 42| 1: [Method] accept +# 42| 2: [FieldDeclaration] FunctionN ; +# 42| -1: [TypeAccess] FunctionN +# 42| 0: [TypeAccess] Boolean +# 42| 3: [Method] accept # 42| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 42| 0: [Parameter] i0 @@ -5527,9 +5530,6 @@ samConversion.kt: # 42| 22: [VarAccess] i22 # 42| -1: [TypeAccess] Object # 42| 0: [IntegerLiteral] 23 -# 42| 1: [FieldDeclaration] FunctionN ; -# 42| -1: [TypeAccess] FunctionN -# 42| 0: [TypeAccess] Boolean # 42| -3: [TypeAccess] BigArityPredicate # 42| 0: [VarAccess] a # 43| 2: [LocalVariableDeclStmt] var ...; @@ -5548,7 +5548,10 @@ samConversion.kt: # 43| 0: [VarAccess] this. # 43| -1: [ThisAccess] this # 43| 1: [VarAccess] -# 43| 1: [Method] accept +# 43| 2: [FieldDeclaration] FunctionN ; +# 43| -1: [TypeAccess] FunctionN +# 43| 0: [TypeAccess] Boolean +# 43| 3: [Method] accept # 43| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 43| 0: [Parameter] i0 @@ -5628,16 +5631,13 @@ samConversion.kt: # 43| 22: [VarAccess] i22 # 43| -1: [TypeAccess] Object # 43| 0: [IntegerLiteral] 23 -# 43| 1: [FieldDeclaration] FunctionN ; -# 43| -1: [TypeAccess] FunctionN -# 43| 0: [TypeAccess] Boolean # 43| -3: [TypeAccess] BigArityPredicate # 43| 0: [LambdaExpr] ...->... # 43| -4: [AnonymousClass] new FunctionN(...) { ... } # 43| 1: [Constructor] # 43| 5: [BlockStmt] { ... } # 43| 0: [SuperConstructorInvocationStmt] super(...) -# 43| 1: [Method] invoke +# 43| 2: [Method] invoke # 43| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 43| 0: [Parameter] i0 @@ -5689,7 +5689,7 @@ samConversion.kt: # 45| 5: [BlockStmt] { ... } # 45| 0: [ReturnStmt] return ... # 45| 0: [BooleanLiteral] true -# 43| 1: [Method] invoke +# 43| 2: [Method] invoke #-----| 4: (Parameters) # 43| 0: [Parameter] a0 # 43| 5: [BlockStmt] { ... } @@ -5830,7 +5830,11 @@ samConversion.kt: # 46| 0: [VarAccess] this. # 46| -1: [ThisAccess] this # 46| 1: [VarAccess] -# 46| 1: [Method] fn +# 46| 2: [FieldDeclaration] Function1 ; +# 46| -1: [TypeAccess] Function1 +# 46| 0: [TypeAccess] Integer +# 46| 1: [TypeAccess] Boolean +# 46| 3: [Method] fn # 46| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 46| 0: [Parameter] i @@ -5840,10 +5844,6 @@ samConversion.kt: # 46| 0: [MethodAccess] invoke(...) # 46| -1: [VarAccess] # 46| 0: [VarAccess] i -# 46| 1: [FieldDeclaration] Function1 ; -# 46| -1: [TypeAccess] Function1 -# 46| 0: [TypeAccess] Integer -# 46| 1: [TypeAccess] Boolean # 46| -3: [TypeAccess] SomePredicate # 46| 0: [TypeAccess] Integer # 46| 0: [LambdaExpr] ...->... @@ -5851,7 +5851,7 @@ samConversion.kt: # 46| 1: [Constructor] # 46| 5: [BlockStmt] { ... } # 46| 0: [SuperConstructorInvocationStmt] super(...) -# 46| 1: [Method] invoke +# 46| 2: [Method] invoke # 46| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 46| 0: [Parameter] a diff --git a/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected b/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected index ae2d5911e7e..a3ed7a0d3a0 100644 --- a/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/exprs_typeaccess/PrintAst.expected @@ -34,7 +34,7 @@ A.kt: # 13| 0: [ReturnStmt] return ... # 13| 0: [VarAccess] this.prop # 13| -1: [ThisAccess] this -# 13| 6: [FieldDeclaration] int prop; +# 13| 7: [FieldDeclaration] int prop; # 13| -1: [TypeAccess] int # 13| 0: [MethodAccess] fn(...) # 13| -1: [ThisAccess] A.this @@ -74,14 +74,14 @@ A.kt: # 20| 0: [VarAccess] B.x # 20| -1: [TypeAccess] B # 23| 11: [Class] Enu -# 0| 1: [Method] values -# 0| 3: [TypeAccess] Enu[] -# 0| 0: [TypeAccess] Enu -# 0| 1: [Method] valueOf +# 0| 2: [Method] valueOf # 0| 3: [TypeAccess] Enu #-----| 4: (Parameters) # 0| 0: [Parameter] value # 0| 0: [TypeAccess] String +# 0| 3: [Method] values +# 0| 3: [TypeAccess] Enu[] +# 0| 0: [TypeAccess] Enu # 23| 4: [Constructor] Enu # 23| 5: [BlockStmt] { ... } # 23| 0: [ExprStmt] ; diff --git a/java/ql/test/kotlin/library-tests/generics/PrintAst.expected b/java/ql/test/kotlin/library-tests/generics/PrintAst.expected index 37f27bdb483..619ba5f3bcc 100644 --- a/java/ql/test/kotlin/library-tests/generics/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/generics/PrintAst.expected @@ -98,15 +98,15 @@ generics.kt: # 13| 0: [ExprStmt] ; # 13| 0: [KtInitializerAssignExpr] ...=... # 13| 0: [VarAccess] t -# 13| 2: [Method] getT +# 13| 2: [FieldDeclaration] T t; +# 13| -1: [TypeAccess] T +# 13| 0: [VarAccess] t +# 13| 3: [Method] getT # 13| 3: [TypeAccess] T # 13| 5: [BlockStmt] { ... } # 13| 0: [ReturnStmt] return ... # 13| 0: [VarAccess] this.t # 13| -1: [ThisAccess] this -# 13| 2: [FieldDeclaration] T t; -# 13| -1: [TypeAccess] T -# 13| 0: [VarAccess] t # 14| 4: [Method] f1 # 14| 3: [TypeAccess] Unit #-----| 4: (Parameters) diff --git a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected index 5a17ed98591..1376baa4f1d 100644 --- a/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/jvmstatic-annotation/PrintAst.expected @@ -192,7 +192,7 @@ test.kt: # 16| 0: [ReturnStmt] return ... # 16| 0: [VarAccess] this.staticProp # 16| -1: [ThisAccess] this -# 16| 5: [Method] setStaticProp +# 16| 6: [Method] setStaticProp # 16| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 16| 0: [Parameter] @@ -204,14 +204,17 @@ test.kt: # 16| 0: [VarAccess] this.staticProp # 16| -1: [ThisAccess] this # 16| 1: [VarAccess] -# 17| 7: [Method] getNonStaticProp +# 17| 7: [FieldDeclaration] String nonStaticProp; +# 17| -1: [TypeAccess] String +# 17| 0: [StringLiteral] b +# 17| 8: [Method] getNonStaticProp #-----| 1: (Annotations) # 17| 3: [TypeAccess] String # 17| 5: [BlockStmt] { ... } # 17| 0: [ReturnStmt] return ... # 17| 0: [VarAccess] this.nonStaticProp # 17| -1: [ThisAccess] this -# 17| 7: [Method] setNonStaticProp +# 17| 9: [Method] setNonStaticProp # 17| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 17| 0: [Parameter] @@ -223,9 +226,6 @@ test.kt: # 17| 0: [VarAccess] this.nonStaticProp # 17| -1: [ThisAccess] this # 17| 1: [VarAccess] -# 17| 7: [FieldDeclaration] String nonStaticProp; -# 17| -1: [TypeAccess] String -# 17| 0: [StringLiteral] b # 20| 10: [Method] getPropWithStaticGetter #-----| 1: (Annotations) # 20| 3: [TypeAccess] String @@ -276,7 +276,15 @@ test.kt: # 13| -1: [VarAccess] HasCompanion.Companion # 13| -1: [TypeAccess] HasCompanion # 13| 0: [VarAccess] s -# 16| 5: [Method] setStaticProp +# 16| 5: [Method] getStaticProp +#-----| 1: (Annotations) +# 16| 3: [TypeAccess] String +# 16| 5: [BlockStmt] { ... } +# 16| 0: [ReturnStmt] return ... +# 16| 0: [MethodAccess] getStaticProp(...) +# 16| -1: [VarAccess] HasCompanion.Companion +# 16| -1: [TypeAccess] HasCompanion +# 16| 6: [Method] setStaticProp # 16| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 16| 0: [Parameter] @@ -288,14 +296,6 @@ test.kt: # 16| -1: [VarAccess] HasCompanion.Companion # 16| -1: [TypeAccess] HasCompanion # 16| 0: [VarAccess] -# 16| 5: [Method] getStaticProp -#-----| 1: (Annotations) -# 16| 3: [TypeAccess] String -# 16| 5: [BlockStmt] { ... } -# 16| 0: [ReturnStmt] return ... -# 16| 0: [MethodAccess] getStaticProp(...) -# 16| -1: [VarAccess] HasCompanion.Companion -# 16| -1: [TypeAccess] HasCompanion # 20| 7: [Method] getPropWithStaticGetter #-----| 1: (Annotations) # 20| 3: [TypeAccess] String @@ -357,7 +357,15 @@ test.kt: # 36| 5: [FieldDeclaration] String staticProp; # 36| -1: [TypeAccess] String # 36| 0: [StringLiteral] a -# 36| 6: [Method] setStaticProp +# 36| 6: [Method] getStaticProp +#-----| 1: (Annotations) +# 36| 3: [TypeAccess] String +# 36| 5: [BlockStmt] { ... } +# 36| 0: [ReturnStmt] return ... +# 36| 0: [VarAccess] NonCompanion.INSTANCE.staticProp +# 36| -1: [VarAccess] NonCompanion.INSTANCE +# 36| -1: [TypeAccess] NonCompanion +# 36| 7: [Method] setStaticProp # 36| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 36| 0: [Parameter] @@ -370,22 +378,17 @@ test.kt: # 36| -1: [VarAccess] NonCompanion.INSTANCE # 36| -1: [TypeAccess] NonCompanion # 36| 1: [VarAccess] -# 36| 6: [Method] getStaticProp -#-----| 1: (Annotations) -# 36| 3: [TypeAccess] String -# 36| 5: [BlockStmt] { ... } -# 36| 0: [ReturnStmt] return ... -# 36| 0: [VarAccess] NonCompanion.INSTANCE.staticProp -# 36| -1: [VarAccess] NonCompanion.INSTANCE -# 36| -1: [TypeAccess] NonCompanion -# 37| 8: [Method] getNonStaticProp +# 37| 8: [FieldDeclaration] String nonStaticProp; +# 37| -1: [TypeAccess] String +# 37| 0: [StringLiteral] b +# 37| 9: [Method] getNonStaticProp #-----| 1: (Annotations) # 37| 3: [TypeAccess] String # 37| 5: [BlockStmt] { ... } # 37| 0: [ReturnStmt] return ... # 37| 0: [VarAccess] this.nonStaticProp # 37| -1: [ThisAccess] this -# 37| 8: [Method] setNonStaticProp +# 37| 10: [Method] setNonStaticProp # 37| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 37| 0: [Parameter] @@ -397,9 +400,6 @@ test.kt: # 37| 0: [VarAccess] this.nonStaticProp # 37| -1: [ThisAccess] this # 37| 1: [VarAccess] -# 37| 8: [FieldDeclaration] String nonStaticProp; -# 37| -1: [TypeAccess] String -# 37| 0: [StringLiteral] b # 40| 11: [Method] getPropWithStaticGetter #-----| 1: (Annotations) # 40| 3: [TypeAccess] String diff --git a/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected b/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected index c29df0de6ef..dd47be234c3 100644 --- a/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected @@ -26,7 +26,7 @@ reflection.kt: # 50| 1: [Constructor] # 50| 5: [BlockStmt] { ... } # 50| 0: [SuperConstructorInvocationStmt] super(...) -# 50| 1: [Method] get +# 50| 2: [Method] get #-----| 4: (Parameters) # 50| 0: [Parameter] a0 # 50| 5: [BlockStmt] { ... } @@ -34,7 +34,7 @@ reflection.kt: # 50| 0: [MethodAccess] getLastChar(...) # 50| -1: [TypeAccess] ReflectionKt # 50| 0: [VarAccess] a0 -# 50| 1: [Method] invoke +# 50| 3: [Method] invoke #-----| 4: (Parameters) # 50| 0: [Parameter] a0 # 50| 5: [BlockStmt] { ... } @@ -62,16 +62,16 @@ reflection.kt: # 51| 0: [VarAccess] this. # 51| -1: [ThisAccess] this # 51| 1: [VarAccess] -# 51| 1: [FieldDeclaration] String ; +# 51| 2: [FieldDeclaration] String ; # 51| -1: [TypeAccess] String -# 51| 1: [Method] get +# 51| 3: [Method] get # 51| 5: [BlockStmt] { ... } # 51| 0: [ReturnStmt] return ... # 51| 0: [MethodAccess] getLastChar(...) # 51| -1: [TypeAccess] ReflectionKt # 51| 0: [VarAccess] this. # 51| -1: [ThisAccess] this -# 51| 1: [Method] invoke +# 51| 4: [Method] invoke # 51| 5: [BlockStmt] { ... } # 51| 0: [ReturnStmt] return ... # 51| 0: [MethodAccess] get(...) @@ -124,7 +124,7 @@ reflection.kt: # 97| 1: [Constructor] # 97| 5: [BlockStmt] { ... } # 97| 0: [SuperConstructorInvocationStmt] super(...) -# 97| 1: [Method] invoke +# 97| 2: [Method] invoke #-----| 4: (Parameters) # 97| 0: [Parameter] a0 # 97| 5: [BlockStmt] { ... } @@ -148,7 +148,7 @@ reflection.kt: # 98| 1: [Constructor] # 98| 5: [BlockStmt] { ... } # 98| 0: [SuperConstructorInvocationStmt] super(...) -# 98| 1: [Method] invoke +# 98| 2: [Method] invoke #-----| 4: (Parameters) # 98| 0: [Parameter] a0 # 98| 5: [BlockStmt] { ... } @@ -180,7 +180,10 @@ reflection.kt: # 99| 0: [VarAccess] this. # 99| -1: [ThisAccess] this # 99| 1: [VarAccess] -# 99| 1: [Method] invoke +# 99| 2: [FieldDeclaration] Class2 ; +# 99| -1: [TypeAccess] Class2 +# 99| 0: [TypeAccess] Integer +# 99| 3: [Method] invoke #-----| 4: (Parameters) # 99| 0: [Parameter] a0 # 99| 5: [BlockStmt] { ... } @@ -191,9 +194,6 @@ reflection.kt: # 99| -2: [VarAccess] this. # 99| -1: [ThisAccess] this # 99| 0: [VarAccess] a0 -# 99| 1: [FieldDeclaration] Class2 ; -# 99| -1: [TypeAccess] Class2 -# 99| 0: [TypeAccess] Integer # 99| -3: [TypeAccess] Function1> # 99| 0: [TypeAccess] String # 99| 1: [TypeAccess] Inner @@ -260,7 +260,7 @@ reflection.kt: # 126| 1: [Constructor] # 126| 5: [BlockStmt] { ... } # 126| 0: [SuperConstructorInvocationStmt] super(...) -# 126| 1: [Method] fn1 +# 126| 2: [Method] fn1 # 126| 3: [TypeAccess] Unit # 126| 5: [BlockStmt] { ... } # 126| 0: [ExprStmt] ; @@ -274,7 +274,7 @@ reflection.kt: # 126| 1: [Constructor] # 126| 5: [BlockStmt] { ... } # 126| 0: [SuperConstructorInvocationStmt] super(...) -# 126| 1: [Method] invoke +# 126| 2: [Method] invoke # 126| 5: [BlockStmt] { ... } # 126| 0: [ReturnStmt] return ... # 126| 0: [MethodAccess] fn1(...) @@ -296,7 +296,7 @@ reflection.kt: # 7| 1: [Constructor] # 7| 5: [BlockStmt] { ... } # 7| 0: [SuperConstructorInvocationStmt] super(...) -# 7| 1: [Method] invoke +# 7| 2: [Method] invoke #-----| 4: (Parameters) # 7| 0: [Parameter] a0 # 7| 1: [Parameter] a1 @@ -321,14 +321,14 @@ reflection.kt: # 10| 1: [Constructor] # 10| 5: [BlockStmt] { ... } # 10| 0: [SuperConstructorInvocationStmt] super(...) -# 10| 1: [Method] get +# 10| 2: [Method] get #-----| 4: (Parameters) # 10| 0: [Parameter] a0 # 10| 5: [BlockStmt] { ... } # 10| 0: [ReturnStmt] return ... # 10| 0: [MethodAccess] getP0(...) # 10| -1: [VarAccess] a0 -# 10| 1: [Method] invoke +# 10| 3: [Method] invoke #-----| 4: (Parameters) # 10| 0: [Parameter] a0 # 10| 5: [BlockStmt] { ... } @@ -367,7 +367,11 @@ reflection.kt: # 14| 0: [VarAccess] this. # 14| -1: [ThisAccess] this # 14| 1: [VarAccess] -# 14| 1: [Method] invoke +# 14| 2: [FieldDeclaration] KProperty1 ; +# 14| -1: [TypeAccess] KProperty1 +# 14| 0: [TypeAccess] C +# 14| 1: [TypeAccess] Integer +# 14| 3: [Method] invoke #-----| 4: (Parameters) # 14| 0: [Parameter] a0 # 14| 5: [BlockStmt] { ... } @@ -376,10 +380,6 @@ reflection.kt: # 14| -1: [VarAccess] this. # 14| -1: [ThisAccess] this # 14| 0: [VarAccess] a0 -# 14| 1: [FieldDeclaration] KProperty1 ; -# 14| -1: [TypeAccess] KProperty1 -# 14| 0: [TypeAccess] C -# 14| 1: [TypeAccess] Integer # 14| -3: [TypeAccess] Function1 # 14| 0: [TypeAccess] C # 14| 1: [TypeAccess] Integer @@ -398,15 +398,15 @@ reflection.kt: # 15| 0: [VarAccess] this. # 15| -1: [ThisAccess] this # 15| 1: [VarAccess] -# 15| 1: [FieldDeclaration] C ; +# 15| 2: [FieldDeclaration] C ; # 15| -1: [TypeAccess] C -# 15| 1: [Method] get +# 15| 3: [Method] get # 15| 5: [BlockStmt] { ... } # 15| 0: [ReturnStmt] return ... # 15| 0: [MethodAccess] getP0(...) # 15| -1: [VarAccess] this. # 15| -1: [ThisAccess] this -# 15| 1: [Method] invoke +# 15| 4: [Method] invoke # 15| 5: [BlockStmt] { ... } # 15| 0: [ReturnStmt] return ... # 15| 0: [MethodAccess] get(...) @@ -422,14 +422,14 @@ reflection.kt: # 17| 1: [Constructor] # 17| 5: [BlockStmt] { ... } # 17| 0: [SuperConstructorInvocationStmt] super(...) -# 17| 1: [Method] get +# 17| 2: [Method] get #-----| 4: (Parameters) # 17| 0: [Parameter] a0 # 17| 5: [BlockStmt] { ... } # 17| 0: [ReturnStmt] return ... # 17| 0: [MethodAccess] getP1(...) # 17| -1: [VarAccess] a0 -# 17| 1: [Method] invoke +# 17| 3: [Method] invoke #-----| 4: (Parameters) # 17| 0: [Parameter] a0 # 17| 5: [BlockStmt] { ... } @@ -437,7 +437,7 @@ reflection.kt: # 17| 0: [MethodAccess] get(...) # 17| -1: [ThisAccess] this # 17| 0: [VarAccess] a0 -# 17| 1: [Method] set +# 17| 4: [Method] set #-----| 4: (Parameters) # 17| 0: [Parameter] a0 # 17| 1: [Parameter] a1 @@ -478,7 +478,11 @@ reflection.kt: # 21| 0: [VarAccess] this. # 21| -1: [ThisAccess] this # 21| 1: [VarAccess] -# 21| 1: [Method] invoke +# 21| 2: [FieldDeclaration] KMutableProperty1 ; +# 21| -1: [TypeAccess] KMutableProperty1 +# 21| 0: [TypeAccess] C +# 21| 1: [TypeAccess] Integer +# 21| 3: [Method] invoke #-----| 4: (Parameters) # 21| 0: [Parameter] a0 # 21| 1: [Parameter] a1 @@ -489,10 +493,6 @@ reflection.kt: # 21| -1: [ThisAccess] this # 21| 0: [VarAccess] a0 # 21| 1: [VarAccess] a1 -# 21| 1: [FieldDeclaration] KMutableProperty1 ; -# 21| -1: [TypeAccess] KMutableProperty1 -# 21| 0: [TypeAccess] C -# 21| 1: [TypeAccess] Integer # 21| -3: [TypeAccess] Function2 # 21| 0: [TypeAccess] C # 21| 1: [TypeAccess] Integer @@ -512,20 +512,20 @@ reflection.kt: # 22| 0: [VarAccess] this. # 22| -1: [ThisAccess] this # 22| 1: [VarAccess] -# 22| 1: [FieldDeclaration] C ; +# 22| 2: [FieldDeclaration] C ; # 22| -1: [TypeAccess] C -# 22| 1: [Method] get +# 22| 3: [Method] get # 22| 5: [BlockStmt] { ... } # 22| 0: [ReturnStmt] return ... # 22| 0: [MethodAccess] getP1(...) # 22| -1: [VarAccess] this. # 22| -1: [ThisAccess] this -# 22| 1: [Method] invoke +# 22| 4: [Method] invoke # 22| 5: [BlockStmt] { ... } # 22| 0: [ReturnStmt] return ... # 22| 0: [MethodAccess] get(...) # 22| -1: [ThisAccess] this -# 22| 1: [Method] set +# 22| 5: [Method] set #-----| 4: (Parameters) # 22| 0: [Parameter] a0 # 22| 5: [BlockStmt] { ... } @@ -556,7 +556,7 @@ reflection.kt: # 24| 1: [Constructor] # 24| 5: [BlockStmt] { ... } # 24| 0: [SuperConstructorInvocationStmt] super(...) -# 24| 1: [Method] invoke +# 24| 2: [Method] invoke # 24| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 24| 0: [Parameter] it @@ -608,7 +608,7 @@ reflection.kt: # 33| 0: [ReturnStmt] return ... # 33| 0: [VarAccess] this.p0 # 33| -1: [ThisAccess] this -# 33| 2: [FieldDeclaration] int p0; +# 33| 3: [FieldDeclaration] int p0; # 33| -1: [TypeAccess] int # 33| 0: [IntegerLiteral] 1 # 34| 4: [Method] getP1 @@ -617,7 +617,10 @@ reflection.kt: # 34| 0: [ReturnStmt] return ... # 34| 0: [VarAccess] this.p1 # 34| -1: [ThisAccess] this -# 34| 4: [Method] setP1 +# 34| 5: [FieldDeclaration] int p1; +# 34| -1: [TypeAccess] int +# 34| 0: [IntegerLiteral] 2 +# 34| 6: [Method] setP1 # 34| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 34| 0: [Parameter] @@ -628,9 +631,6 @@ reflection.kt: # 34| 0: [VarAccess] this.p1 # 34| -1: [ThisAccess] this # 34| 1: [VarAccess] -# 34| 4: [FieldDeclaration] int p1; -# 34| -1: [TypeAccess] int -# 34| 0: [IntegerLiteral] 2 # 36| 7: [Method] getP2 # 36| 3: [TypeAccess] int # 36| 5: [BlockStmt] { ... } @@ -678,7 +678,7 @@ reflection.kt: # 60| 1: [Constructor] # 60| 5: [BlockStmt] { ... } # 60| 0: [SuperConstructorInvocationStmt] super(...) -# 60| 1: [Method] invoke +# 60| 2: [Method] invoke #-----| 4: (Parameters) # 60| 0: [Parameter] a0 # 60| 1: [Parameter] a1 @@ -707,7 +707,10 @@ reflection.kt: # 61| 0: [VarAccess] this. # 61| -1: [ThisAccess] this # 61| 1: [VarAccess] -# 61| 1: [Method] invoke +# 61| 2: [FieldDeclaration] Generic ; +# 61| -1: [TypeAccess] Generic +# 61| 0: [TypeAccess] Integer +# 61| 3: [Method] invoke #-----| 4: (Parameters) # 61| 0: [Parameter] a0 # 61| 5: [BlockStmt] { ... } @@ -716,9 +719,6 @@ reflection.kt: # 61| -1: [VarAccess] this. # 61| -1: [ThisAccess] this # 61| 0: [VarAccess] a0 -# 61| 1: [FieldDeclaration] Generic ; -# 61| -1: [TypeAccess] Generic -# 61| 0: [TypeAccess] Integer # 61| -3: [TypeAccess] Function1 # 61| 0: [TypeAccess] Integer # 61| 1: [TypeAccess] String @@ -733,7 +733,7 @@ reflection.kt: # 62| 1: [Constructor] # 62| 5: [BlockStmt] { ... } # 62| 0: [SuperConstructorInvocationStmt] super(...) -# 62| 1: [Method] invoke +# 62| 2: [Method] invoke #-----| 4: (Parameters) # 62| 0: [Parameter] a0 # 62| 5: [BlockStmt] { ... } @@ -761,7 +761,10 @@ reflection.kt: # 63| 0: [VarAccess] this. # 63| -1: [ThisAccess] this # 63| 1: [VarAccess] -# 63| 1: [Method] invoke +# 63| 2: [FieldDeclaration] Generic ; +# 63| -1: [TypeAccess] Generic +# 63| 0: [TypeAccess] Integer +# 63| 3: [Method] invoke # 63| 5: [BlockStmt] { ... } # 63| 0: [ReturnStmt] return ... # 63| 0: [MethodAccess] ext1(...) @@ -769,9 +772,6 @@ reflection.kt: # 63| -1: [TypeAccess] ReflectionKt # 63| 0: [VarAccess] this. # 63| -1: [ThisAccess] this -# 63| 1: [FieldDeclaration] Generic ; -# 63| -1: [TypeAccess] Generic -# 63| 0: [TypeAccess] Integer # 63| -3: [TypeAccess] Function0 # 63| 0: [TypeAccess] String # 63| 0: [ClassInstanceExpr] new Generic(...) @@ -785,7 +785,7 @@ reflection.kt: # 64| 1: [Constructor] # 64| 5: [BlockStmt] { ... } # 64| 0: [SuperConstructorInvocationStmt] super(...) -# 64| 1: [Method] invoke +# 64| 2: [Method] invoke #-----| 4: (Parameters) # 64| 0: [Parameter] a0 # 64| 5: [BlockStmt] { ... } @@ -812,16 +812,16 @@ reflection.kt: # 65| 0: [VarAccess] this. # 65| -1: [ThisAccess] this # 65| 1: [VarAccess] -# 65| 1: [Method] invoke +# 65| 2: [FieldDeclaration] Generic ; +# 65| -1: [TypeAccess] Generic +# 65| 0: [TypeAccess] Integer +# 65| 3: [Method] invoke # 65| 5: [BlockStmt] { ... } # 65| 0: [ReturnStmt] return ... # 65| 0: [MethodAccess] ext2(...) # 65| -1: [TypeAccess] ReflectionKt # 65| 0: [VarAccess] this. # 65| -1: [ThisAccess] this -# 65| 1: [FieldDeclaration] Generic ; -# 65| -1: [TypeAccess] Generic -# 65| 0: [TypeAccess] Integer # 65| -3: [TypeAccess] Function0 # 65| 0: [TypeAccess] String # 65| 0: [ClassInstanceExpr] new Generic(...) @@ -835,14 +835,14 @@ reflection.kt: # 67| 1: [Constructor] # 67| 5: [BlockStmt] { ... } # 67| 0: [SuperConstructorInvocationStmt] super(...) -# 67| 1: [Method] get +# 67| 2: [Method] get #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 5: [BlockStmt] { ... } # 67| 0: [ReturnStmt] return ... # 67| 0: [MethodAccess] getP2(...) # 67| -1: [VarAccess] a0 -# 67| 1: [Method] invoke +# 67| 3: [Method] invoke #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 5: [BlockStmt] { ... } @@ -850,7 +850,7 @@ reflection.kt: # 67| 0: [MethodAccess] get(...) # 67| -1: [ThisAccess] this # 67| 0: [VarAccess] a0 -# 67| 1: [Method] set +# 67| 4: [Method] set #-----| 4: (Parameters) # 67| 0: [Parameter] a0 # 67| 1: [Parameter] a1 @@ -878,21 +878,21 @@ reflection.kt: # 68| 0: [VarAccess] this. # 68| -1: [ThisAccess] this # 68| 1: [VarAccess] -# 68| 1: [FieldDeclaration] Generic ; +# 68| 2: [FieldDeclaration] Generic ; # 68| -1: [TypeAccess] Generic # 68| 0: [TypeAccess] Integer -# 68| 1: [Method] get +# 68| 3: [Method] get # 68| 5: [BlockStmt] { ... } # 68| 0: [ReturnStmt] return ... # 68| 0: [MethodAccess] getP2(...) # 68| -1: [VarAccess] this. # 68| -1: [ThisAccess] this -# 68| 1: [Method] invoke +# 68| 4: [Method] invoke # 68| 5: [BlockStmt] { ... } # 68| 0: [ReturnStmt] return ... # 68| 0: [MethodAccess] get(...) # 68| -1: [ThisAccess] this -# 68| 1: [Method] set +# 68| 5: [Method] set #-----| 4: (Parameters) # 68| 0: [Parameter] a0 # 68| 5: [BlockStmt] { ... } @@ -921,15 +921,15 @@ reflection.kt: # 70| 0: [VarAccess] this. # 70| -1: [ThisAccess] this # 70| 1: [VarAccess] -# 70| 1: [FieldDeclaration] IntCompanionObject ; +# 70| 2: [FieldDeclaration] IntCompanionObject ; # 70| -1: [TypeAccess] IntCompanionObject -# 70| 1: [Method] get +# 70| 3: [Method] get # 70| 5: [BlockStmt] { ... } # 70| 0: [ReturnStmt] return ... # 70| 0: [MethodAccess] getMAX_VALUE(...) # 70| -1: [VarAccess] this. # 70| -1: [ThisAccess] this -# 70| 1: [Method] invoke +# 70| 4: [Method] invoke # 70| 5: [BlockStmt] { ... } # 70| 0: [ReturnStmt] return ... # 70| 0: [MethodAccess] get(...) @@ -945,11 +945,11 @@ reflection.kt: # 71| 1: [Constructor] # 71| 5: [BlockStmt] { ... } # 71| 0: [SuperConstructorInvocationStmt] super(...) -# 71| 1: [Method] get +# 71| 2: [Method] get # 71| 5: [BlockStmt] { ... } # 71| 0: [ReturnStmt] return ... # 71| 0: [VarAccess] MAX_VALUE -# 71| 1: [Method] invoke +# 71| 3: [Method] invoke # 71| 5: [BlockStmt] { ... } # 71| 0: [ReturnStmt] return ... # 71| 0: [MethodAccess] get(...) @@ -971,20 +971,20 @@ reflection.kt: # 72| 0: [VarAccess] this. # 72| -1: [ThisAccess] this # 72| 1: [VarAccess] -# 72| 1: [FieldDeclaration] Rectangle ; +# 72| 2: [FieldDeclaration] Rectangle ; # 72| -1: [TypeAccess] Rectangle -# 72| 1: [Method] get +# 72| 3: [Method] get # 72| 5: [BlockStmt] { ... } # 72| 0: [ReturnStmt] return ... # 72| 0: [VarAccess] this..height # 72| -1: [VarAccess] this. # 72| -1: [ThisAccess] this -# 72| 1: [Method] invoke +# 72| 4: [Method] invoke # 72| 5: [BlockStmt] { ... } # 72| 0: [ReturnStmt] return ... # 72| 0: [MethodAccess] get(...) # 72| -1: [ThisAccess] this -# 72| 1: [Method] set +# 72| 5: [Method] set #-----| 4: (Parameters) # 72| 0: [Parameter] a0 # 72| 5: [BlockStmt] { ... } @@ -1040,15 +1040,15 @@ reflection.kt: # 83| 0: [ExprStmt] ; # 83| 0: [KtInitializerAssignExpr] ...=... # 83| 0: [VarAccess] value -# 83| 4: [Method] getValue +# 83| 4: [FieldDeclaration] T value; +# 83| -1: [TypeAccess] T +# 83| 0: [VarAccess] value +# 83| 5: [Method] getValue # 83| 3: [TypeAccess] T # 83| 5: [BlockStmt] { ... } # 83| 0: [ReturnStmt] return ... # 83| 0: [VarAccess] this.value # 83| -1: [ThisAccess] this -# 83| 4: [FieldDeclaration] T value; -# 83| -1: [TypeAccess] T -# 83| 0: [VarAccess] value # 85| 6: [Class,GenericType,ParameterizedType] Inner #-----| -2: (Generic Parameters) # 85| 0: [TypeVariable] T1 @@ -1082,7 +1082,10 @@ reflection.kt: # 90| 0: [VarAccess] this. # 90| -1: [ThisAccess] this # 90| 1: [VarAccess] -# 90| 1: [Method] invoke +# 90| 2: [FieldDeclaration] Class2 ; +# 90| -1: [TypeAccess] Class2 +# 90| 0: [TypeAccess] T +# 90| 3: [Method] invoke #-----| 4: (Parameters) # 90| 0: [Parameter] a0 # 90| 5: [BlockStmt] { ... } @@ -1093,9 +1096,6 @@ reflection.kt: # 90| -2: [VarAccess] this. # 90| -1: [ThisAccess] this # 90| 0: [VarAccess] a0 -# 90| 1: [FieldDeclaration] Class2 ; -# 90| -1: [TypeAccess] Class2 -# 90| 0: [TypeAccess] T # 90| -3: [TypeAccess] Function1> # 90| 0: [TypeAccess] String # 90| 1: [TypeAccess] Inner @@ -1118,7 +1118,10 @@ reflection.kt: # 105| 0: [ReturnStmt] return ... # 105| 0: [VarAccess] this.prop1 # 105| -1: [ThisAccess] this -# 105| 2: [Method] setProp1 +# 105| 3: [FieldDeclaration] int prop1; +# 105| -1: [TypeAccess] int +# 105| 0: [VarAccess] prop1 +# 105| 4: [Method] setProp1 # 105| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 105| 0: [Parameter] @@ -1129,9 +1132,6 @@ reflection.kt: # 105| 0: [VarAccess] this.prop1 # 105| -1: [ThisAccess] this # 105| 1: [VarAccess] -# 105| 2: [FieldDeclaration] int prop1; -# 105| -1: [TypeAccess] int -# 105| 0: [VarAccess] prop1 # 107| 7: [Class] Derived1 # 107| 1: [Constructor] Derived1 #-----| 4: (Parameters) @@ -1159,20 +1159,20 @@ reflection.kt: # 109| 0: [VarAccess] this. # 109| -1: [ThisAccess] this # 109| 1: [VarAccess] -# 109| 1: [FieldDeclaration] Derived1 ; +# 109| 2: [FieldDeclaration] Derived1 ; # 109| -1: [TypeAccess] Derived1 -# 109| 1: [Method] get +# 109| 3: [Method] get # 109| 5: [BlockStmt] { ... } # 109| 0: [ReturnStmt] return ... # 109| 0: [MethodAccess] getProp1(...) # 109| -1: [VarAccess] this. # 109| -1: [ThisAccess] this -# 109| 1: [Method] invoke +# 109| 4: [Method] invoke # 109| 5: [BlockStmt] { ... } # 109| 0: [ReturnStmt] return ... # 109| 0: [MethodAccess] get(...) # 109| -1: [ThisAccess] this -# 109| 1: [Method] set +# 109| 5: [Method] set #-----| 4: (Parameters) # 109| 0: [Parameter] a0 # 109| 5: [BlockStmt] { ... } @@ -1197,7 +1197,7 @@ reflection.kt: # 115| 1: [Constructor] # 115| 5: [BlockStmt] { ... } # 115| 0: [SuperConstructorInvocationStmt] super(...) -# 115| 1: [Method] fn1 +# 115| 2: [Method] fn1 # 115| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 115| 0: [Parameter] i @@ -1210,7 +1210,7 @@ reflection.kt: # 116| 1: [Constructor] # 116| 5: [BlockStmt] { ... } # 116| 0: [SuperConstructorInvocationStmt] super(...) -# 116| 1: [Method] invoke +# 116| 2: [Method] invoke #-----| 4: (Parameters) # 116| 0: [Parameter] a0 # 116| 5: [BlockStmt] { ... } From b373af47d1c10af377aa776dfad87d575c4d5632 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Thu, 30 Jun 2022 16:59:18 +0100 Subject: [PATCH 229/465] Kotlin: Fix a label We want the .javaResult.id of a TypeResults. --- java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt index 530ff47e8ab..4ce9f0316a4 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt @@ -1514,7 +1514,7 @@ open class KotlinUsesExtractor( // otherwise two extension properties declared in the same enclosing context will get // clashing trap labels. These are always private, so we can just make up a label without // worrying about their names as seen from Java. - val extensionPropertyDiscriminator = getExtensionReceiverType(f)?.let { "extension;${useType(it)}" } ?: "" + val extensionPropertyDiscriminator = getExtensionReceiverType(f)?.let { "extension;${useType(it).javaResult.id}" } ?: "" return "@\"field;{$parentId};${extensionPropertyDiscriminator}${f.name.asString()}\"" } From 3bb51c2643f331704d06d06d7a297ed7b9863c0b Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Thu, 30 Jun 2022 17:07:42 +0100 Subject: [PATCH 230/465] Fix rst header --- docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst index c3a3a2d9ed2..3d5ca470644 100644 --- a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst +++ b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst @@ -74,7 +74,7 @@ The ``analyze`` command will run the default suite of any specified CodeQL packs codeql analyze / / Working with CodeQL packs on GitHub Enterprise Server ------------------------------------------- +----------------------------------------------------- .. pull-quote:: From 92a9738bd5f25543667049b7e8e75284306b4991 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Thu, 30 Jun 2022 17:32:00 +0100 Subject: [PATCH 231/465] Docs: Fix precedence of `registries` list --- .../codeql-cli/publishing-and-using-codeql-packs.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst index 3d5ca470644..67e90b5ba3f 100644 --- a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst +++ b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst @@ -90,10 +90,13 @@ For example, the following ``qlconfig.yml`` file associates all packs with the C .. code-block:: yaml registries: - - packages: '*' - url: https://containers.GHE_HOSTNAME/v2/ - packages: 'codeql/*' url: https://ghcr.io/v2/ + - packages: '*' + url: https://containers.GHE_HOSTNAME/v2/ + +The CodeQL CLI will determine which registry to use for a given package name by finding the first item in the ``registries`` list with a ``packages`` property that matches that package name. +This means that you'll generally want to define the most specific package name patterns first. You can now use ``codeql pack publish``, ``codeql pack download``, and ``codeql database analyze`` to manage packs on GitHub Enterprise Server. From 9b424ac8b2a43d1f156b93c52fc8d4d758957400 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Thu, 30 Jun 2022 17:38:18 +0100 Subject: [PATCH 232/465] Docs: Update guidance to install the _latest_ version of the bundle --- docs/codeql/reusables/beta-note-package-management.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/reusables/beta-note-package-management.rst b/docs/codeql/reusables/beta-note-package-management.rst index a4fd362a70c..7697c9a47d9 100644 --- a/docs/codeql/reusables/beta-note-package-management.rst +++ b/docs/codeql/reusables/beta-note-package-management.rst @@ -2,4 +2,4 @@ Note - The CodeQL package management functionality, including CodeQL packs, is currently available as a beta release and is subject to change. During the beta release, CodeQL packs are available only using GitHub Packages - the GitHub Container registry. To use this beta functionality, install version 2.6.0 or higher of the CodeQL CLI bundle from: https://github.com/github/codeql-action/releases. \ No newline at end of file + The CodeQL package management functionality, including CodeQL packs, is currently available as a beta release and is subject to change. During the beta release, CodeQL packs are available only using GitHub Packages - the GitHub Container registry. To use this beta functionality, install the latest version of the CodeQL CLI bundle from: https://github.com/github/codeql-action/releases. From 57e026d6173bd29fb1be6caa2a6f4c4a7b30c222 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Thu, 30 Jun 2022 18:22:17 +0100 Subject: [PATCH 233/465] C++: Typo: intrepret --- .../Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql index c72e25f61df..bd55008677c 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql @@ -18,7 +18,7 @@ import semmle.code.cpp.ir.IR import semmle.code.cpp.ir.dataflow.MustFlow import PathGraph -/** Holds if `f` has a name that we intrepret as evidence of intentionally returning the value of the stack pointer. */ +/** Holds if `f` has a name that we interpret as evidence of intentionally returning the value of the stack pointer. */ predicate intentionallyReturnsStackPointer(Function f) { f.getName().toLowerCase().matches(["%stack%", "%sp%"]) } From dd9306210150b9d63bbc0e4226c8037d2cf58d2f Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 30 Jun 2022 21:46:55 +0100 Subject: [PATCH 234/465] Kotlin: Mangle names of internal functions to match JVM symbols --- .../src/main/kotlin/KotlinUsesExtractor.kt | 52 +++++++++++-------- java/ql/consistency-queries/visibility.ql | 3 +- .../kotlin/module_mangled_names/User.java | 9 ++++ .../kotlin/module_mangled_names/test.expected | 4 ++ .../kotlin/module_mangled_names/test.py | 3 ++ .../kotlin/module_mangled_names/test.ql | 5 ++ .../kotlin/module_mangled_names/test1.kt | 5 ++ .../kotlin/module_mangled_names/test2.kt | 5 ++ .../kotlin/module_mangled_names/test3.kt | 5 ++ .../internal-public-alias/User.java | 11 ++++ .../internal-public-alias/test.expected | 6 +++ .../internal-public-alias/test.kt | 12 +++++ .../internal-public-alias/test.ql | 5 ++ .../library-tests/methods/methods.expected | 2 +- .../modifiers/modifiers.expected | 2 +- .../properties/properties.expected | 2 +- 16 files changed, 105 insertions(+), 26 deletions(-) create mode 100644 java/ql/integration-tests/posix-only/kotlin/module_mangled_names/User.java create mode 100644 java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.expected create mode 100644 java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.py create mode 100644 java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.ql create mode 100644 java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test1.kt create mode 100644 java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test2.kt create mode 100644 java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test3.kt create mode 100644 java/ql/test/kotlin/library-tests/internal-public-alias/User.java create mode 100644 java/ql/test/kotlin/library-tests/internal-public-alias/test.expected create mode 100644 java/ql/test/kotlin/library-tests/internal-public-alias/test.kt create mode 100644 java/ql/test/kotlin/library-tests/internal-public-alias/test.ql diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt index 530ff47e8ab..63b78e36a19 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.lower.parents import org.jetbrains.kotlin.backend.common.lower.parentsWithSelf import org.jetbrains.kotlin.backend.jvm.ir.propertyIfAccessor import org.jetbrains.kotlin.builtins.StandardNames +import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.declarations.* @@ -23,8 +24,10 @@ import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.sources.JavaSourceElement import org.jetbrains.kotlin.load.java.structure.* +import org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.NameUtils import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.util.OperatorNameConventions @@ -754,11 +757,25 @@ open class KotlinUsesExtractor( data class FunctionNames(val nameInDB: String, val kotlinName: String) + @OptIn(ObsoleteDescriptorBasedAPI::class) + private fun getJvmModuleName(f: IrFunction) = + NameUtils.sanitizeAsJavaIdentifier( + getJvmModuleNameForDeserializedDescriptor(f.descriptor) ?: JvmCodegenUtil.getModuleName(pluginContext.moduleDescriptor) + ) + fun getFunctionShortName(f: IrFunction) : FunctionNames { if (f.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA || f.isAnonymousFunction) return FunctionNames( OperatorNameConventions.INVOKE.asString(), OperatorNameConventions.INVOKE.asString()) + + fun getSuffixIfInternal() = + if (f.visibility == DescriptorVisibilities.INTERNAL) { + "\$" + getJvmModuleName(f) + } else { + "" + } + (f as? IrSimpleFunction)?.correspondingPropertySymbol?.let { val propName = it.owner.name.asString() val getter = it.owner.getter @@ -774,35 +791,26 @@ open class KotlinUsesExtractor( } } - when (f) { - getter -> { - val defaultFunctionName = JvmAbi.getterName(propName) - val defaultDbName = if (getter.visibility == DescriptorVisibilities.PRIVATE && getter.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) { - // In JVM these functions don't exist, instead the backing field is accessed directly - defaultFunctionName + "\$private" - } else { - defaultFunctionName - } - return FunctionNames(getJvmName(getter) ?: defaultDbName, defaultFunctionName) - } - setter -> { - val defaultFunctionName = JvmAbi.setterName(propName) - val defaultDbName = if (setter.visibility == DescriptorVisibilities.PRIVATE && setter.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) { - // In JVM these functions don't exist, instead the backing field is accessed directly - defaultFunctionName + "\$private" - } else { - defaultFunctionName - } - return FunctionNames(getJvmName(setter) ?: defaultDbName, defaultFunctionName) - } + val maybeFunctionName = when (f) { + getter -> JvmAbi.getterName(propName) + setter -> JvmAbi.setterName(propName) else -> { logger.error( "Function has a corresponding property, but is neither the getter nor the setter" ) + null } } + maybeFunctionName?.let { defaultFunctionName -> + val suffix = if (f.visibility == DescriptorVisibilities.PRIVATE && f.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) { + "\$private" + } else { + getSuffixIfInternal() + } + return FunctionNames(getJvmName(f) ?: "$defaultFunctionName$suffix", defaultFunctionName) + } } - return FunctionNames(getJvmName(f) ?: f.name.asString(), f.name.asString()) + return FunctionNames(getJvmName(f) ?: "${f.name.asString()}${getSuffixIfInternal()}", f.name.asString()) } // This excludes class type parameters that show up in (at least) constructors' typeParameters list. diff --git a/java/ql/consistency-queries/visibility.ql b/java/ql/consistency-queries/visibility.ql index ba90d598236..1b6744cea1d 100644 --- a/java/ql/consistency-queries/visibility.ql +++ b/java/ql/consistency-queries/visibility.ql @@ -18,5 +18,6 @@ where m.getFile().isKotlinSourceFile() and // TODO: This ought to have visibility information not m.getName() = "" and - count(visibility(m)) != 1 + count(visibility(m)) != 1 and + not (count(visibility(m)) = 2 and visibility(m) = "public" and visibility(m) = "internal") // This is a reasonable result, since the JVM symbol is declared public, but Kotlin metadata flags it as internal select m, concat(visibility(m), ", ") diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/User.java b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/User.java new file mode 100644 index 00000000000..12d4b0937da --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/User.java @@ -0,0 +1,9 @@ +public class User { + + public static int test(Test1 test1, Test2 test2, Test3 test3) { + + return test1.f$main() + test2.f$mymodule() + test3.f$reservedchars___(); + + } + +} diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.expected b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.expected new file mode 100644 index 00000000000..a1fc953a254 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.expected @@ -0,0 +1,4 @@ +| User.java:3:21:3:24 | test | +| test1.kt:3:12:3:22 | f$main | +| test2.kt:3:12:3:22 | f$mymodule | +| test3.kt:3:12:3:22 | f$reservedchars___ | diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.py b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.py new file mode 100644 index 00000000000..0a41ac5b3bf --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.py @@ -0,0 +1,3 @@ +from create_database_utils import * + +run_codeql_database_create(["kotlinc test1.kt", "kotlinc test2.kt -module-name mymodule", "kotlinc test3.kt -module-name reservedchars\\\"${}/", "javac User.java -cp ." ], lang="java") diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.ql b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.ql new file mode 100644 index 00000000000..f1355df2e88 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test.ql @@ -0,0 +1,5 @@ +import java + +from Method m +where m.fromSource() +select m diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test1.kt b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test1.kt new file mode 100644 index 00000000000..c14fec0452e --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test1.kt @@ -0,0 +1,5 @@ +public class Test1 { + + internal fun f() = 1 + +} diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test2.kt b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test2.kt new file mode 100644 index 00000000000..c37d26c39fc --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test2.kt @@ -0,0 +1,5 @@ +public class Test2 { + + internal fun f() = 2 + +} diff --git a/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test3.kt b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test3.kt new file mode 100644 index 00000000000..5fcdaced80c --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/module_mangled_names/test3.kt @@ -0,0 +1,5 @@ +public class Test3 { + + internal fun f() = 3 + +} diff --git a/java/ql/test/kotlin/library-tests/internal-public-alias/User.java b/java/ql/test/kotlin/library-tests/internal-public-alias/User.java new file mode 100644 index 00000000000..d249e1d36f2 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/internal-public-alias/User.java @@ -0,0 +1,11 @@ +public class User { + + public static int test(Test t) { + + t.setInternalVar$main(t.getInternalVal$main()); + + return t.internalFun$main(); + + } + +} diff --git a/java/ql/test/kotlin/library-tests/internal-public-alias/test.expected b/java/ql/test/kotlin/library-tests/internal-public-alias/test.expected new file mode 100644 index 00000000000..77a06cf7310 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/internal-public-alias/test.expected @@ -0,0 +1,6 @@ +| User.java:3:21:3:24 | test | +| test.kt:3:12:3:30 | getInternalVal$main | +| test.kt:6:3:6:36 | getInternalVal | +| test.kt:8:12:8:30 | getInternalVar$main | +| test.kt:8:12:8:30 | setInternalVar$main | +| test.kt:10:12:10:32 | internalFun$main | diff --git a/java/ql/test/kotlin/library-tests/internal-public-alias/test.kt b/java/ql/test/kotlin/library-tests/internal-public-alias/test.kt new file mode 100644 index 00000000000..e79e6d2f907 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/internal-public-alias/test.kt @@ -0,0 +1,12 @@ +public class Test { + + internal val internalVal = 1 + + // Would clash with the internal val's getter without name mangling and provoke a database inconsistency: + fun getInternalVal() = internalVal + + internal var internalVar = 2 + + internal fun internalFun() = 3 + +} diff --git a/java/ql/test/kotlin/library-tests/internal-public-alias/test.ql b/java/ql/test/kotlin/library-tests/internal-public-alias/test.ql new file mode 100644 index 00000000000..f1355df2e88 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/internal-public-alias/test.ql @@ -0,0 +1,5 @@ +import java + +from Method m +where m.fromSource() +select m diff --git a/java/ql/test/kotlin/library-tests/methods/methods.expected b/java/ql/test/kotlin/library-tests/methods/methods.expected index 11fa8762e28..8067838d889 100644 --- a/java/ql/test/kotlin/library-tests/methods/methods.expected +++ b/java/ql/test/kotlin/library-tests/methods/methods.expected @@ -42,7 +42,7 @@ methods | methods.kt:5:1:20:1 | Class | methods.kt:14:12:14:29 | publicFun | publicFun() | public | | | methods.kt:5:1:20:1 | Class | methods.kt:15:15:15:35 | protectedFun | protectedFun() | protected | | | methods.kt:5:1:20:1 | Class | methods.kt:16:13:16:31 | privateFun | privateFun() | private | | -| methods.kt:5:1:20:1 | Class | methods.kt:17:14:17:33 | internalFun | internalFun() | internal | | +| methods.kt:5:1:20:1 | Class | methods.kt:17:14:17:33 | internalFun$main | internalFun$main() | internal | | | methods.kt:5:1:20:1 | Class | methods.kt:18:5:18:36 | noExplicitVisibilityFun | noExplicitVisibilityFun() | public | | | methods.kt:5:1:20:1 | Class | methods.kt:19:12:19:29 | inlineFun | inlineFun() | inline, public | | constructors diff --git a/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected b/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected index 70345c576b0..14b5124b7ae 100644 --- a/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected +++ b/java/ql/test/kotlin/library-tests/modifiers/modifiers.expected @@ -11,7 +11,7 @@ | modifiers.kt:4:5:4:22 | c | Field | final | | modifiers.kt:4:5:4:22 | c | Field | private | | modifiers.kt:4:5:4:22 | c | Property | internal | -| modifiers.kt:4:14:4:22 | getC | Method | internal | +| modifiers.kt:4:14:4:22 | getC$main | Method | internal | | modifiers.kt:5:5:5:34 | d | Field | final | | modifiers.kt:5:5:5:34 | d | Field | private | | modifiers.kt:5:5:5:34 | d | Property | public | diff --git a/java/ql/test/kotlin/library-tests/properties/properties.expected b/java/ql/test/kotlin/library-tests/properties/properties.expected index 05870c7b6e1..7bbe706923c 100644 --- a/java/ql/test/kotlin/library-tests/properties/properties.expected +++ b/java/ql/test/kotlin/library-tests/properties/properties.expected @@ -45,7 +45,7 @@ fieldDeclarations | properties.kt:35:5:35:32 | privateProp | properties.kt:35:13:35:32 | getPrivateProp$private | file://:0:0:0:0 | | properties.kt:35:5:35:32 | privateProp | private | | properties.kt:36:5:36:36 | protectedProp | properties.kt:36:15:36:36 | getProtectedProp | file://:0:0:0:0 | | properties.kt:36:5:36:36 | protectedProp | protected | | properties.kt:37:5:37:30 | publicProp | properties.kt:37:12:37:30 | getPublicProp | file://:0:0:0:0 | | properties.kt:37:5:37:30 | publicProp | public | -| properties.kt:38:5:38:34 | internalProp | properties.kt:38:14:38:34 | getInternalProp | file://:0:0:0:0 | | properties.kt:38:5:38:34 | internalProp | internal | +| properties.kt:38:5:38:34 | internalProp | properties.kt:38:14:38:34 | getInternalProp$main | file://:0:0:0:0 | | properties.kt:38:5:38:34 | internalProp | internal | | properties.kt:67:1:67:23 | constVal | properties.kt:67:7:67:23 | getConstVal | file://:0:0:0:0 | | properties.kt:67:1:67:23 | constVal | public | | properties.kt:70:5:70:16 | prop | properties.kt:70:5:70:16 | getProp | file://:0:0:0:0 | | properties.kt:70:5:70:16 | prop | public | | properties.kt:78:1:79:13 | x | properties.kt:79:5:79:13 | getX | file://:0:0:0:0 | | file://:0:0:0:0 | | public | From b9eec1346658a116d39f996c885fd4938e2317d3 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 30 Jun 2022 22:21:04 +0100 Subject: [PATCH 235/465] Accept integration test changes --- .../kotlin/custom_plugin/PrintAst.expected | 4 +- .../PrintAst.expected | 174 +++++++++--------- 2 files changed, 89 insertions(+), 89 deletions(-) diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected index a4d9d37a8e2..51186ef7b15 100644 --- a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected +++ b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected @@ -48,7 +48,7 @@ c.kt: d.kt: # 0| [CompilationUnit] d # 1| 1: [Class] D -# 0| 1: [FieldDeclaration] String bar; +# 0| 2: [FieldDeclaration] String bar; # 0| -1: [TypeAccess] String # 0| 0: [StringLiteral] Foobar # 1| 3: [Constructor] D @@ -67,7 +67,7 @@ e.kt: # 0| -3: [TypeAccess] ArrayList # 0| 0: [IntegerLiteral] 1 # 0| 0: [NullLiteral] null -# 0| 1: [Method] +# 0| 2: [Method] # 0| 3: [TypeAccess] Object # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... diff --git a/java/ql/integration-tests/posix-only/kotlin/gradle_kotlinx_serialization/PrintAst.expected b/java/ql/integration-tests/posix-only/kotlin/gradle_kotlinx_serialization/PrintAst.expected index f5a92b6fd3d..e37e65dc3c8 100644 --- a/java/ql/integration-tests/posix-only/kotlin/gradle_kotlinx_serialization/PrintAst.expected +++ b/java/ql/integration-tests/posix-only/kotlin/gradle_kotlinx_serialization/PrintAst.expected @@ -40,43 +40,19 @@ app/src/main/kotlin/testProject/App.kt: # 7| -1: [ThisAccess] Project.this # 7| 0: [TypeAccess] Project # 7| 1: [VarAccess] language -# 0| 1: [Method] write$Self -# 0| 3: [TypeAccess] Unit -#-----| 4: (Parameters) -# 0| 0: [Parameter] self -# 0| 0: [TypeAccess] Project -# 0| 1: [Parameter] output -# 0| 0: [TypeAccess] CompositeEncoder -# 0| 2: [Parameter] serialDesc -# 0| 0: [TypeAccess] SerialDescriptor -# 7| 5: [BlockStmt] { ... } -# 7| 0: [ExprStmt] ; -# 7| 0: [MethodAccess] encodeStringElement(...) -# 7| -1: [VarAccess] output -# 7| 0: [VarAccess] serialDesc -# 7| 1: [IntegerLiteral] 0 -# 7| 2: [MethodAccess] getName(...) -# 7| -1: [VarAccess] self -# 7| 1: [ExprStmt] ; -# 7| 0: [MethodAccess] encodeIntElement(...) -# 7| -1: [VarAccess] output -# 7| 0: [VarAccess] serialDesc -# 7| 1: [IntegerLiteral] 1 -# 7| 2: [MethodAccess] getLanguage(...) -# 7| -1: [VarAccess] self -# 0| 1: [Method] component1 +# 0| 2: [Method] component1 # 0| 3: [TypeAccess] String # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... # 0| 0: [VarAccess] this.name # 0| -1: [ThisAccess] this -# 0| 1: [Method] component2 +# 0| 3: [Method] component2 # 0| 3: [TypeAccess] int # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... # 0| 0: [VarAccess] this.language # 0| -1: [ThisAccess] this -# 0| 1: [Method] copy +# 0| 4: [Method] copy # 0| 3: [TypeAccess] Project #-----| 4: (Parameters) # 8| 0: [Parameter] name @@ -89,41 +65,7 @@ app/src/main/kotlin/testProject/App.kt: # 0| -3: [TypeAccess] Project # 0| 0: [VarAccess] name # 0| 1: [VarAccess] language -# 0| 1: [Method] toString -# 0| 3: [TypeAccess] String -# 0| 5: [BlockStmt] { ... } -# 0| 0: [ReturnStmt] return ... -# 0| 0: [StringTemplateExpr] "..." -# 0| 0: [StringLiteral] Project( -# 0| 1: [StringLiteral] name= -# 0| 2: [VarAccess] this.name -# 0| -1: [ThisAccess] this -# 0| 3: [StringLiteral] , -# 0| 4: [StringLiteral] language= -# 0| 5: [VarAccess] this.language -# 0| -1: [ThisAccess] this -# 0| 6: [StringLiteral] ) -# 0| 1: [Method] hashCode -# 0| 3: [TypeAccess] int -# 0| 5: [BlockStmt] { ... } -# 0| 0: [LocalVariableDeclStmt] var ...; -# 0| 1: [LocalVariableDeclExpr] result -# 0| 0: [MethodAccess] hashCode(...) -# 0| -1: [VarAccess] this.name -# 0| -1: [ThisAccess] this -# 0| 1: [ExprStmt] ; -# 0| 0: [AssignExpr] ...=... -# 0| 0: [VarAccess] result -# 0| 1: [MethodAccess] plus(...) -# 0| -1: [MethodAccess] times(...) -# 0| -1: [VarAccess] result -# 0| 0: [IntegerLiteral] 31 -# 0| 0: [MethodAccess] hashCode(...) -# 0| -1: [VarAccess] this.language -# 0| -1: [ThisAccess] this -# 0| 2: [ReturnStmt] return ... -# 0| 0: [VarAccess] result -# 0| 1: [Method] equals +# 0| 5: [Method] equals # 0| 3: [TypeAccess] boolean #-----| 4: (Parameters) # 0| 0: [Parameter] other @@ -172,27 +114,68 @@ app/src/main/kotlin/testProject/App.kt: # 0| 0: [BooleanLiteral] false # 0| 5: [ReturnStmt] return ... # 0| 0: [BooleanLiteral] true -# 7| 9: [Class] Companion -# 0| 1: [Method] serializer -# 0| 3: [TypeAccess] KSerializer -# 0| 0: [TypeAccess] Project -# 7| 5: [BlockStmt] { ... } -# 7| 0: [ReturnStmt] return ... -# 7| 0: [VarAccess] INSTANCE -# 7| 2: [Constructor] Companion -# 7| 5: [BlockStmt] { ... } -# 7| 0: [SuperConstructorInvocationStmt] super(...) -# 7| 1: [BlockStmt] { ... } -# 7| 9: [Class] $serializer -# 0| 1: [Method] getDescriptor -# 0| 3: [TypeAccess] SerialDescriptor -# 0| 5: [BlockStmt] { ... } -# 0| 0: [ReturnStmt] return ... -# 0| 0: [VarAccess] this.descriptor +# 0| 6: [Method] hashCode +# 0| 3: [TypeAccess] int +# 0| 5: [BlockStmt] { ... } +# 0| 0: [LocalVariableDeclStmt] var ...; +# 0| 1: [LocalVariableDeclExpr] result +# 0| 0: [MethodAccess] hashCode(...) +# 0| -1: [VarAccess] this.name +# 0| -1: [ThisAccess] this +# 0| 1: [ExprStmt] ; +# 0| 0: [AssignExpr] ...=... +# 0| 0: [VarAccess] result +# 0| 1: [MethodAccess] plus(...) +# 0| -1: [MethodAccess] times(...) +# 0| -1: [VarAccess] result +# 0| 0: [IntegerLiteral] 31 +# 0| 0: [MethodAccess] hashCode(...) +# 0| -1: [VarAccess] this.language +# 0| -1: [ThisAccess] this +# 0| 2: [ReturnStmt] return ... +# 0| 0: [VarAccess] result +# 0| 7: [Method] toString +# 0| 3: [TypeAccess] String +# 0| 5: [BlockStmt] { ... } +# 0| 0: [ReturnStmt] return ... +# 0| 0: [StringTemplateExpr] "..." +# 0| 0: [StringLiteral] Project( +# 0| 1: [StringLiteral] name= +# 0| 2: [VarAccess] this.name # 0| -1: [ThisAccess] this +# 0| 3: [StringLiteral] , +# 0| 4: [StringLiteral] language= +# 0| 5: [VarAccess] this.language +# 0| -1: [ThisAccess] this +# 0| 6: [StringLiteral] ) +# 0| 8: [Method] write$Self +# 0| 3: [TypeAccess] Unit +#-----| 4: (Parameters) +# 0| 0: [Parameter] self +# 0| 0: [TypeAccess] Project +# 0| 1: [Parameter] output +# 0| 0: [TypeAccess] CompositeEncoder +# 0| 2: [Parameter] serialDesc +# 0| 0: [TypeAccess] SerialDescriptor +# 7| 5: [BlockStmt] { ... } +# 7| 0: [ExprStmt] ; +# 7| 0: [MethodAccess] encodeStringElement(...) +# 7| -1: [VarAccess] output +# 7| 0: [VarAccess] serialDesc +# 7| 1: [IntegerLiteral] 0 +# 7| 2: [MethodAccess] getName(...) +# 7| -1: [VarAccess] self +# 7| 1: [ExprStmt] ; +# 7| 0: [MethodAccess] encodeIntElement(...) +# 7| -1: [VarAccess] output +# 7| 0: [VarAccess] serialDesc +# 7| 1: [IntegerLiteral] 1 +# 7| 2: [MethodAccess] getLanguage(...) +# 7| -1: [VarAccess] self +# 7| 9: [Class] $serializer # 0| 1: [FieldDeclaration] SerialDescriptor descriptor; # 0| -1: [TypeAccess] SerialDescriptor -# 0| 1: [Method] childSerializers +# 0| 2: [Method] childSerializers # 0| 3: [TypeAccess] KSerializer[] # 0| 0: [TypeAccess] KSerializer # 0| 0: [WildcardTypeAccess] ? ... @@ -204,7 +187,7 @@ app/src/main/kotlin/testProject/App.kt: # 7| 1: [VarAccess] INSTANCE # 7| -1: [TypeAccess] KSerializer # 7| 0: [IntegerLiteral] 2 -# 0| 1: [Method] deserialize +# 0| 3: [Method] deserialize # 0| 3: [TypeAccess] Project #-----| 4: (Parameters) # 0| 0: [Parameter] decoder @@ -342,7 +325,13 @@ app/src/main/kotlin/testProject/App.kt: # 7| 1: [VarAccess] tmp4_local0 # 7| 2: [VarAccess] tmp5_local1 # 7| 3: [NullLiteral] null -# 0| 1: [Method] serialize +# 0| 4: [Method] getDescriptor +# 0| 3: [TypeAccess] SerialDescriptor +# 0| 5: [BlockStmt] { ... } +# 0| 0: [ReturnStmt] return ... +# 0| 0: [VarAccess] this.descriptor +# 0| -1: [ThisAccess] this +# 0| 5: [Method] serialize # 0| 3: [TypeAccess] Unit #-----| 4: (Parameters) # 0| 0: [Parameter] encoder @@ -397,6 +386,17 @@ app/src/main/kotlin/testProject/App.kt: # 7| -1: [ThisAccess] $serializer.this # 7| 0: [TypeAccess] $serializer # 7| 1: [VarAccess] tmp0_serialDesc +# 7| 10: [Class] Companion +# 0| 1: [Method] serializer +# 0| 3: [TypeAccess] KSerializer +# 0| 0: [TypeAccess] Project +# 7| 5: [BlockStmt] { ... } +# 7| 0: [ReturnStmt] return ... +# 7| 0: [VarAccess] INSTANCE +# 7| 2: [Constructor] Companion +# 7| 5: [BlockStmt] { ... } +# 7| 0: [SuperConstructorInvocationStmt] super(...) +# 7| 1: [BlockStmt] { ... } # 8| 11: [Constructor] Project #-----| 4: (Parameters) # 8| 0: [Parameter] name @@ -412,21 +412,21 @@ app/src/main/kotlin/testProject/App.kt: # 8| 1: [ExprStmt] ; # 8| 0: [KtInitializerAssignExpr] ...=... # 8| 0: [VarAccess] language -# 8| 12: [Method] getName +# 8| 12: [FieldDeclaration] String name; +# 8| -1: [TypeAccess] String +# 8| 0: [VarAccess] name +# 8| 13: [Method] getName # 8| 3: [TypeAccess] String # 8| 5: [BlockStmt] { ... } # 8| 0: [ReturnStmt] return ... # 8| 0: [VarAccess] this.name # 8| -1: [ThisAccess] this -# 8| 12: [FieldDeclaration] String name; -# 8| -1: [TypeAccess] String -# 8| 0: [VarAccess] name # 8| 14: [Method] getLanguage # 8| 3: [TypeAccess] int # 8| 5: [BlockStmt] { ... } # 8| 0: [ReturnStmt] return ... # 8| 0: [VarAccess] this.language # 8| -1: [ThisAccess] this -# 8| 14: [FieldDeclaration] int language; +# 8| 15: [FieldDeclaration] int language; # 8| -1: [TypeAccess] int # 8| 0: [VarAccess] language From 14aef792e0b7db92b303eaf57cfbc9132c0f1e6b Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 1 Jul 2022 10:35:17 +0100 Subject: [PATCH 236/465] Accept test changes --- .../java-kotlin-collection-type-generic-methods/test.expected | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/test/kotlin/library-tests/java-kotlin-collection-type-generic-methods/test.expected b/java/ql/test/kotlin/library-tests/java-kotlin-collection-type-generic-methods/test.expected index 417b8a22399..7995948aa78 100644 --- a/java/ql/test/kotlin/library-tests/java-kotlin-collection-type-generic-methods/test.expected +++ b/java/ql/test/kotlin/library-tests/java-kotlin-collection-type-generic-methods/test.expected @@ -54,7 +54,7 @@ methodWithDuplicate | AbstractList | set | int | | AbstractList | subList | int | | AbstractList | subListRangeCheck | int | -| AbstractMap | containsEntry | Entry | +| AbstractMap | containsEntry$kotlin_stdlib | Entry | | AbstractMap | containsKey | Object | | AbstractMap | containsValue | Object | | AbstractMap | equals | Object | @@ -79,7 +79,7 @@ methodWithDuplicate | AbstractMap | put | V | | AbstractMap | putAll | Map | | AbstractMap | remove | Object | -| AbstractMap | containsEntry | Entry | +| AbstractMap | containsEntry$kotlin_stdlib | Entry | | AbstractMap | containsKey | Object | | AbstractMap | containsValue | Object | | AbstractMap | equals | Object | From e4636be8dbb91fb01b5607c5600c5b906009f521 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Fri, 1 Jul 2022 11:07:18 +0100 Subject: [PATCH 237/465] C++: Add 'nomagic' to the charpred of 'VariableAccessInInitializer'. --- cpp/ql/src/Likely Bugs/UseInOwnInitializer.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/ql/src/Likely Bugs/UseInOwnInitializer.ql b/cpp/ql/src/Likely Bugs/UseInOwnInitializer.ql index 6bb411b7844..054fdccbb99 100644 --- a/cpp/ql/src/Likely Bugs/UseInOwnInitializer.ql +++ b/cpp/ql/src/Likely Bugs/UseInOwnInitializer.ql @@ -15,6 +15,7 @@ class VariableAccessInInitializer extends VariableAccess { Variable var; Initializer init; + pragma[nomagic] VariableAccessInInitializer() { init.getDeclaration() = var and init.getExpr().getAChild*() = this From 901e0663557571604239ec44e44ddefaacf3dc1f Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 1 Jul 2022 13:39:28 +0200 Subject: [PATCH 238/465] Swift: locally run integration tests Minimal recreations of internal `integration-tests-runner.py` and `create_database_utils.py` are provided to be able to run the integration tests on the codeql repository with a released codeql CLI. For the moment we skip the database checks by default, as we are still producing inconsistent results. --- .github/workflows/swift-integration-tests.yml | 32 ++++++++ swift/integration-tests/.gitignore | 1 + .../create_database_utils.py | 26 ++++++ .../cross-references/Functions.expected | 4 - .../frontend-invocations/A.swift | 0 .../frontend-invocations/B.swift | 0 .../frontend-invocations/C.swift | 0 .../frontend-invocations/D.swift | 0 .../frontend-invocations/E.swift | 0 .../frontend-invocations/Esup.swift | 0 .../frontend-invocations/Files.expected | 0 .../frontend-invocations/Files.ql | 0 .../frontend-invocations/Makefile | 0 .../frontend-invocations/test.py | 0 .../cross-references/Classes.expected | 0 .../cross-references/Classes.ql | 0 .../cross-references/Constructors.expected | 0 .../cross-references/Constructors.ql | 0 .../cross-references/Destructors.expected | 0 .../cross-references/Destructors.ql | 0 .../cross-references/Enums.expected | 0 .../cross-references/Enums.ql | 0 .../cross-references/Functions.expected | 4 + .../cross-references/Functions.ql | 0 .../cross-references/Operators.expected | 0 .../cross-references/Operators.ql | 0 .../cross-references/Package.swift | 0 .../cross-references/Protocols.expected | 0 .../cross-references/Protocols.ql | 0 .../Sources/cross-references/lib.swift | 1 - .../Sources/cross-references/main.swift | 1 - .../cross-references/Structs.expected | 0 .../cross-references/Structs.ql | 0 .../cross-references/VarDecls.expected | 0 .../cross-references/VarDecls.ql | 0 .../{ => posix-only}/cross-references/test.py | 0 .../hello-world/Package.swift | 0 .../Sources/hello-world/hello_world.swift | 0 .../hello-world/test.expected | 0 .../{ => posix-only}/hello-world/test.py | 0 .../{ => posix-only}/hello-world/test.ql | 0 .../partial-modules/A/Package.swift | 0 .../partial-modules/A/Sources/A/A.swift | 0 .../partial-modules/A/Sources/A/Asup.swift | 0 .../partial-modules/B/Package.swift | 0 .../partial-modules/B/Sources/B/B.swift | 0 .../partial-modules/B/Sources/B/Bsup.swift | 0 .../partial-modules/Package.swift | 0 .../partial-modules/partial_modules.swift | 0 .../partial-modules/Unknown.expected | 0 .../partial-modules/Unknown.ql | 0 .../{ => posix-only}/partial-modules/test.py | 0 swift/integration-tests/runner.py | 80 +++++++++++++++++++ 53 files changed, 143 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/swift-integration-tests.yml create mode 100644 swift/integration-tests/create_database_utils.py delete mode 100644 swift/integration-tests/cross-references/Functions.expected rename swift/integration-tests/{ => osx-only}/frontend-invocations/A.swift (100%) rename swift/integration-tests/{ => osx-only}/frontend-invocations/B.swift (100%) rename swift/integration-tests/{ => osx-only}/frontend-invocations/C.swift (100%) rename swift/integration-tests/{ => osx-only}/frontend-invocations/D.swift (100%) rename swift/integration-tests/{ => osx-only}/frontend-invocations/E.swift (100%) rename swift/integration-tests/{ => osx-only}/frontend-invocations/Esup.swift (100%) rename swift/integration-tests/{ => osx-only}/frontend-invocations/Files.expected (100%) rename swift/integration-tests/{ => osx-only}/frontend-invocations/Files.ql (100%) rename swift/integration-tests/{ => osx-only}/frontend-invocations/Makefile (100%) rename swift/integration-tests/{ => osx-only}/frontend-invocations/test.py (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Classes.expected (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Classes.ql (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Constructors.expected (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Constructors.ql (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Destructors.expected (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Destructors.ql (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Enums.expected (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Enums.ql (100%) create mode 100644 swift/integration-tests/posix-only/cross-references/Functions.expected rename swift/integration-tests/{ => posix-only}/cross-references/Functions.ql (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Operators.expected (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Operators.ql (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Package.swift (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Protocols.expected (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Protocols.ql (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Sources/cross-references/lib.swift (99%) rename swift/integration-tests/{ => posix-only}/cross-references/Sources/cross-references/main.swift (98%) rename swift/integration-tests/{ => posix-only}/cross-references/Structs.expected (100%) rename swift/integration-tests/{ => posix-only}/cross-references/Structs.ql (100%) rename swift/integration-tests/{ => posix-only}/cross-references/VarDecls.expected (100%) rename swift/integration-tests/{ => posix-only}/cross-references/VarDecls.ql (100%) rename swift/integration-tests/{ => posix-only}/cross-references/test.py (100%) rename swift/integration-tests/{ => posix-only}/hello-world/Package.swift (100%) rename swift/integration-tests/{ => posix-only}/hello-world/Sources/hello-world/hello_world.swift (100%) rename swift/integration-tests/{ => posix-only}/hello-world/test.expected (100%) rename swift/integration-tests/{ => posix-only}/hello-world/test.py (100%) rename swift/integration-tests/{ => posix-only}/hello-world/test.ql (100%) rename swift/integration-tests/{ => posix-only}/partial-modules/A/Package.swift (100%) rename swift/integration-tests/{ => posix-only}/partial-modules/A/Sources/A/A.swift (100%) rename swift/integration-tests/{ => posix-only}/partial-modules/A/Sources/A/Asup.swift (100%) rename swift/integration-tests/{ => posix-only}/partial-modules/B/Package.swift (100%) rename swift/integration-tests/{ => posix-only}/partial-modules/B/Sources/B/B.swift (100%) rename swift/integration-tests/{ => posix-only}/partial-modules/B/Sources/B/Bsup.swift (100%) rename swift/integration-tests/{ => posix-only}/partial-modules/Package.swift (100%) rename swift/integration-tests/{ => posix-only}/partial-modules/Sources/partial-modules/partial_modules.swift (100%) rename swift/integration-tests/{ => posix-only}/partial-modules/Unknown.expected (100%) rename swift/integration-tests/{ => posix-only}/partial-modules/Unknown.ql (100%) rename swift/integration-tests/{ => posix-only}/partial-modules/test.py (100%) create mode 100755 swift/integration-tests/runner.py diff --git a/.github/workflows/swift-integration-tests.yml b/.github/workflows/swift-integration-tests.yml new file mode 100644 index 00000000000..a9028d6c89a --- /dev/null +++ b/.github/workflows/swift-integration-tests.yml @@ -0,0 +1,32 @@ +name: "Swift: Run Integration Tests" + +on: + pull_request: + paths: + - "swift/**" + - .github/workflows/swift-integration-tests.yml + - codeql-workspace.yml + branches: + - main +defaults: + run: + working-directory: swift + +jobs: + integration-tests: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os : [ubuntu-20.04, macos-latest] + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/fetch-codeql + - uses: bazelbuild/setup-bazelisk@v2 + - uses: actions/setup-python@v3 + - name: Build Swift extractor + run: | + bazel run //swift:create-extractor-pack + - name: Run integration tests + run: | + python integration-tests/runner.py diff --git a/swift/integration-tests/.gitignore b/swift/integration-tests/.gitignore index 8e66c817556..9ea4244ad91 100644 --- a/swift/integration-tests/.gitignore +++ b/swift/integration-tests/.gitignore @@ -6,3 +6,4 @@ xcuserdata/ DerivedData/ .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata *.actual +db diff --git a/swift/integration-tests/create_database_utils.py b/swift/integration-tests/create_database_utils.py new file mode 100644 index 00000000000..3f2d11a39f7 --- /dev/null +++ b/swift/integration-tests/create_database_utils.py @@ -0,0 +1,26 @@ +""" +recreation of internal `create_database_utils.py` to run the tests locally, with minimal +and swift-specialized functionality +""" +import subprocess +import pathlib +import sys + + +def run_codeql_database_create(cmds, lang, keep_trap=True): + assert lang == 'swift' + codeql_root = pathlib.Path(__file__).parents[2] + cmd = [ + "codeql", "database", "create", + "-s", ".", "-l", "swift", "--internal-use-lua-tracing", f"--search-path={codeql_root}", + ] + if keep_trap: + cmd.append("--keep-trap") + for c in cmds: + cmd += ["-c", c] + cmd.append("db") + res = subprocess.run(cmd) + if res.returncode: + print("FAILED", file=sys.stderr) + print(" ", *cmd, file=sys.stderr) + sys.exit(res.returncode) diff --git a/swift/integration-tests/cross-references/Functions.expected b/swift/integration-tests/cross-references/Functions.expected deleted file mode 100644 index 76335112240..00000000000 --- a/swift/integration-tests/cross-references/Functions.expected +++ /dev/null @@ -1,4 +0,0 @@ -| Sources/cross-references/lib.swift:1:1:1:11 | f | -| Sources/cross-references/lib.swift:17:8:19:1 | ~ | -| Sources/cross-references/lib.swift:22:9:24:1 | ~ | -| Sources/cross-references/lib.swift:27:1:29:1 | ~ | diff --git a/swift/integration-tests/frontend-invocations/A.swift b/swift/integration-tests/osx-only/frontend-invocations/A.swift similarity index 100% rename from swift/integration-tests/frontend-invocations/A.swift rename to swift/integration-tests/osx-only/frontend-invocations/A.swift diff --git a/swift/integration-tests/frontend-invocations/B.swift b/swift/integration-tests/osx-only/frontend-invocations/B.swift similarity index 100% rename from swift/integration-tests/frontend-invocations/B.swift rename to swift/integration-tests/osx-only/frontend-invocations/B.swift diff --git a/swift/integration-tests/frontend-invocations/C.swift b/swift/integration-tests/osx-only/frontend-invocations/C.swift similarity index 100% rename from swift/integration-tests/frontend-invocations/C.swift rename to swift/integration-tests/osx-only/frontend-invocations/C.swift diff --git a/swift/integration-tests/frontend-invocations/D.swift b/swift/integration-tests/osx-only/frontend-invocations/D.swift similarity index 100% rename from swift/integration-tests/frontend-invocations/D.swift rename to swift/integration-tests/osx-only/frontend-invocations/D.swift diff --git a/swift/integration-tests/frontend-invocations/E.swift b/swift/integration-tests/osx-only/frontend-invocations/E.swift similarity index 100% rename from swift/integration-tests/frontend-invocations/E.swift rename to swift/integration-tests/osx-only/frontend-invocations/E.swift diff --git a/swift/integration-tests/frontend-invocations/Esup.swift b/swift/integration-tests/osx-only/frontend-invocations/Esup.swift similarity index 100% rename from swift/integration-tests/frontend-invocations/Esup.swift rename to swift/integration-tests/osx-only/frontend-invocations/Esup.swift diff --git a/swift/integration-tests/frontend-invocations/Files.expected b/swift/integration-tests/osx-only/frontend-invocations/Files.expected similarity index 100% rename from swift/integration-tests/frontend-invocations/Files.expected rename to swift/integration-tests/osx-only/frontend-invocations/Files.expected diff --git a/swift/integration-tests/frontend-invocations/Files.ql b/swift/integration-tests/osx-only/frontend-invocations/Files.ql similarity index 100% rename from swift/integration-tests/frontend-invocations/Files.ql rename to swift/integration-tests/osx-only/frontend-invocations/Files.ql diff --git a/swift/integration-tests/frontend-invocations/Makefile b/swift/integration-tests/osx-only/frontend-invocations/Makefile similarity index 100% rename from swift/integration-tests/frontend-invocations/Makefile rename to swift/integration-tests/osx-only/frontend-invocations/Makefile diff --git a/swift/integration-tests/frontend-invocations/test.py b/swift/integration-tests/osx-only/frontend-invocations/test.py similarity index 100% rename from swift/integration-tests/frontend-invocations/test.py rename to swift/integration-tests/osx-only/frontend-invocations/test.py diff --git a/swift/integration-tests/cross-references/Classes.expected b/swift/integration-tests/posix-only/cross-references/Classes.expected similarity index 100% rename from swift/integration-tests/cross-references/Classes.expected rename to swift/integration-tests/posix-only/cross-references/Classes.expected diff --git a/swift/integration-tests/cross-references/Classes.ql b/swift/integration-tests/posix-only/cross-references/Classes.ql similarity index 100% rename from swift/integration-tests/cross-references/Classes.ql rename to swift/integration-tests/posix-only/cross-references/Classes.ql diff --git a/swift/integration-tests/cross-references/Constructors.expected b/swift/integration-tests/posix-only/cross-references/Constructors.expected similarity index 100% rename from swift/integration-tests/cross-references/Constructors.expected rename to swift/integration-tests/posix-only/cross-references/Constructors.expected diff --git a/swift/integration-tests/cross-references/Constructors.ql b/swift/integration-tests/posix-only/cross-references/Constructors.ql similarity index 100% rename from swift/integration-tests/cross-references/Constructors.ql rename to swift/integration-tests/posix-only/cross-references/Constructors.ql diff --git a/swift/integration-tests/cross-references/Destructors.expected b/swift/integration-tests/posix-only/cross-references/Destructors.expected similarity index 100% rename from swift/integration-tests/cross-references/Destructors.expected rename to swift/integration-tests/posix-only/cross-references/Destructors.expected diff --git a/swift/integration-tests/cross-references/Destructors.ql b/swift/integration-tests/posix-only/cross-references/Destructors.ql similarity index 100% rename from swift/integration-tests/cross-references/Destructors.ql rename to swift/integration-tests/posix-only/cross-references/Destructors.ql diff --git a/swift/integration-tests/cross-references/Enums.expected b/swift/integration-tests/posix-only/cross-references/Enums.expected similarity index 100% rename from swift/integration-tests/cross-references/Enums.expected rename to swift/integration-tests/posix-only/cross-references/Enums.expected diff --git a/swift/integration-tests/cross-references/Enums.ql b/swift/integration-tests/posix-only/cross-references/Enums.ql similarity index 100% rename from swift/integration-tests/cross-references/Enums.ql rename to swift/integration-tests/posix-only/cross-references/Enums.ql diff --git a/swift/integration-tests/posix-only/cross-references/Functions.expected b/swift/integration-tests/posix-only/cross-references/Functions.expected new file mode 100644 index 00000000000..2ecf78a6be4 --- /dev/null +++ b/swift/integration-tests/posix-only/cross-references/Functions.expected @@ -0,0 +1,4 @@ +| Sources/cross-references/lib.swift:1:1:1:11 | f() | +| Sources/cross-references/lib.swift:17:8:19:1 | ~(_:) | +| Sources/cross-references/lib.swift:22:9:24:1 | ~(_:) | +| Sources/cross-references/lib.swift:27:1:29:1 | ~(_:_:) | diff --git a/swift/integration-tests/cross-references/Functions.ql b/swift/integration-tests/posix-only/cross-references/Functions.ql similarity index 100% rename from swift/integration-tests/cross-references/Functions.ql rename to swift/integration-tests/posix-only/cross-references/Functions.ql diff --git a/swift/integration-tests/cross-references/Operators.expected b/swift/integration-tests/posix-only/cross-references/Operators.expected similarity index 100% rename from swift/integration-tests/cross-references/Operators.expected rename to swift/integration-tests/posix-only/cross-references/Operators.expected diff --git a/swift/integration-tests/cross-references/Operators.ql b/swift/integration-tests/posix-only/cross-references/Operators.ql similarity index 100% rename from swift/integration-tests/cross-references/Operators.ql rename to swift/integration-tests/posix-only/cross-references/Operators.ql diff --git a/swift/integration-tests/cross-references/Package.swift b/swift/integration-tests/posix-only/cross-references/Package.swift similarity index 100% rename from swift/integration-tests/cross-references/Package.swift rename to swift/integration-tests/posix-only/cross-references/Package.swift diff --git a/swift/integration-tests/cross-references/Protocols.expected b/swift/integration-tests/posix-only/cross-references/Protocols.expected similarity index 100% rename from swift/integration-tests/cross-references/Protocols.expected rename to swift/integration-tests/posix-only/cross-references/Protocols.expected diff --git a/swift/integration-tests/cross-references/Protocols.ql b/swift/integration-tests/posix-only/cross-references/Protocols.ql similarity index 100% rename from swift/integration-tests/cross-references/Protocols.ql rename to swift/integration-tests/posix-only/cross-references/Protocols.ql diff --git a/swift/integration-tests/cross-references/Sources/cross-references/lib.swift b/swift/integration-tests/posix-only/cross-references/Sources/cross-references/lib.swift similarity index 99% rename from swift/integration-tests/cross-references/Sources/cross-references/lib.swift rename to swift/integration-tests/posix-only/cross-references/Sources/cross-references/lib.swift index 39acad28b14..1155935d326 100644 --- a/swift/integration-tests/cross-references/Sources/cross-references/lib.swift +++ b/swift/integration-tests/posix-only/cross-references/Sources/cross-references/lib.swift @@ -27,4 +27,3 @@ infix operator ~ func ~(lhs: Int, rhs: Int) -> Int { return lhs } - diff --git a/swift/integration-tests/cross-references/Sources/cross-references/main.swift b/swift/integration-tests/posix-only/cross-references/Sources/cross-references/main.swift similarity index 98% rename from swift/integration-tests/cross-references/Sources/cross-references/main.swift rename to swift/integration-tests/posix-only/cross-references/Sources/cross-references/main.swift index b4143493c41..474d885af58 100644 --- a/swift/integration-tests/cross-references/Sources/cross-references/main.swift +++ b/swift/integration-tests/posix-only/cross-references/Sources/cross-references/main.swift @@ -15,4 +15,3 @@ struct s : P {} 42~ 15 ~ 42 - diff --git a/swift/integration-tests/cross-references/Structs.expected b/swift/integration-tests/posix-only/cross-references/Structs.expected similarity index 100% rename from swift/integration-tests/cross-references/Structs.expected rename to swift/integration-tests/posix-only/cross-references/Structs.expected diff --git a/swift/integration-tests/cross-references/Structs.ql b/swift/integration-tests/posix-only/cross-references/Structs.ql similarity index 100% rename from swift/integration-tests/cross-references/Structs.ql rename to swift/integration-tests/posix-only/cross-references/Structs.ql diff --git a/swift/integration-tests/cross-references/VarDecls.expected b/swift/integration-tests/posix-only/cross-references/VarDecls.expected similarity index 100% rename from swift/integration-tests/cross-references/VarDecls.expected rename to swift/integration-tests/posix-only/cross-references/VarDecls.expected diff --git a/swift/integration-tests/cross-references/VarDecls.ql b/swift/integration-tests/posix-only/cross-references/VarDecls.ql similarity index 100% rename from swift/integration-tests/cross-references/VarDecls.ql rename to swift/integration-tests/posix-only/cross-references/VarDecls.ql diff --git a/swift/integration-tests/cross-references/test.py b/swift/integration-tests/posix-only/cross-references/test.py similarity index 100% rename from swift/integration-tests/cross-references/test.py rename to swift/integration-tests/posix-only/cross-references/test.py diff --git a/swift/integration-tests/hello-world/Package.swift b/swift/integration-tests/posix-only/hello-world/Package.swift similarity index 100% rename from swift/integration-tests/hello-world/Package.swift rename to swift/integration-tests/posix-only/hello-world/Package.swift diff --git a/swift/integration-tests/hello-world/Sources/hello-world/hello_world.swift b/swift/integration-tests/posix-only/hello-world/Sources/hello-world/hello_world.swift similarity index 100% rename from swift/integration-tests/hello-world/Sources/hello-world/hello_world.swift rename to swift/integration-tests/posix-only/hello-world/Sources/hello-world/hello_world.swift diff --git a/swift/integration-tests/hello-world/test.expected b/swift/integration-tests/posix-only/hello-world/test.expected similarity index 100% rename from swift/integration-tests/hello-world/test.expected rename to swift/integration-tests/posix-only/hello-world/test.expected diff --git a/swift/integration-tests/hello-world/test.py b/swift/integration-tests/posix-only/hello-world/test.py similarity index 100% rename from swift/integration-tests/hello-world/test.py rename to swift/integration-tests/posix-only/hello-world/test.py diff --git a/swift/integration-tests/hello-world/test.ql b/swift/integration-tests/posix-only/hello-world/test.ql similarity index 100% rename from swift/integration-tests/hello-world/test.ql rename to swift/integration-tests/posix-only/hello-world/test.ql diff --git a/swift/integration-tests/partial-modules/A/Package.swift b/swift/integration-tests/posix-only/partial-modules/A/Package.swift similarity index 100% rename from swift/integration-tests/partial-modules/A/Package.swift rename to swift/integration-tests/posix-only/partial-modules/A/Package.swift diff --git a/swift/integration-tests/partial-modules/A/Sources/A/A.swift b/swift/integration-tests/posix-only/partial-modules/A/Sources/A/A.swift similarity index 100% rename from swift/integration-tests/partial-modules/A/Sources/A/A.swift rename to swift/integration-tests/posix-only/partial-modules/A/Sources/A/A.swift diff --git a/swift/integration-tests/partial-modules/A/Sources/A/Asup.swift b/swift/integration-tests/posix-only/partial-modules/A/Sources/A/Asup.swift similarity index 100% rename from swift/integration-tests/partial-modules/A/Sources/A/Asup.swift rename to swift/integration-tests/posix-only/partial-modules/A/Sources/A/Asup.swift diff --git a/swift/integration-tests/partial-modules/B/Package.swift b/swift/integration-tests/posix-only/partial-modules/B/Package.swift similarity index 100% rename from swift/integration-tests/partial-modules/B/Package.swift rename to swift/integration-tests/posix-only/partial-modules/B/Package.swift diff --git a/swift/integration-tests/partial-modules/B/Sources/B/B.swift b/swift/integration-tests/posix-only/partial-modules/B/Sources/B/B.swift similarity index 100% rename from swift/integration-tests/partial-modules/B/Sources/B/B.swift rename to swift/integration-tests/posix-only/partial-modules/B/Sources/B/B.swift diff --git a/swift/integration-tests/partial-modules/B/Sources/B/Bsup.swift b/swift/integration-tests/posix-only/partial-modules/B/Sources/B/Bsup.swift similarity index 100% rename from swift/integration-tests/partial-modules/B/Sources/B/Bsup.swift rename to swift/integration-tests/posix-only/partial-modules/B/Sources/B/Bsup.swift diff --git a/swift/integration-tests/partial-modules/Package.swift b/swift/integration-tests/posix-only/partial-modules/Package.swift similarity index 100% rename from swift/integration-tests/partial-modules/Package.swift rename to swift/integration-tests/posix-only/partial-modules/Package.swift diff --git a/swift/integration-tests/partial-modules/Sources/partial-modules/partial_modules.swift b/swift/integration-tests/posix-only/partial-modules/Sources/partial-modules/partial_modules.swift similarity index 100% rename from swift/integration-tests/partial-modules/Sources/partial-modules/partial_modules.swift rename to swift/integration-tests/posix-only/partial-modules/Sources/partial-modules/partial_modules.swift diff --git a/swift/integration-tests/partial-modules/Unknown.expected b/swift/integration-tests/posix-only/partial-modules/Unknown.expected similarity index 100% rename from swift/integration-tests/partial-modules/Unknown.expected rename to swift/integration-tests/posix-only/partial-modules/Unknown.expected diff --git a/swift/integration-tests/partial-modules/Unknown.ql b/swift/integration-tests/posix-only/partial-modules/Unknown.ql similarity index 100% rename from swift/integration-tests/partial-modules/Unknown.ql rename to swift/integration-tests/posix-only/partial-modules/Unknown.ql diff --git a/swift/integration-tests/partial-modules/test.py b/swift/integration-tests/posix-only/partial-modules/test.py similarity index 100% rename from swift/integration-tests/partial-modules/test.py rename to swift/integration-tests/posix-only/partial-modules/test.py diff --git a/swift/integration-tests/runner.py b/swift/integration-tests/runner.py new file mode 100755 index 00000000000..b9e39325fd9 --- /dev/null +++ b/swift/integration-tests/runner.py @@ -0,0 +1,80 @@ +#!/bin/env python3 +""" +recreation of internal `integration-tests-runner.py` to run the tests locally, with minimal +and swift-specialized functionality. + +This runner requires: +* a codeql CLI binary in PATH +* `bazel run //swift:create_extractor_pack` to have been run +""" + +import pathlib +import os +import sys +import subprocess +import argparse +import shutil +import platform + +this_dir = pathlib.Path(__file__).parent + + +def options(): + p = argparse.ArgumentParser() + p.add_argument("--test-dir", "-d", type=pathlib.Path, action="append") + #FIXME: the following should be the default + p.add_argument("--check-databases", action="store_true") + p.add_argument("--learn", action="store_true") + p.add_argument("--threads", "-j", type=int, default=0) + return p.parse_args() + + +def execute_test(path): + shutil.rmtree(path.parent / "db", ignore_errors=True) + return subprocess.run([sys.executable, "-u", path.name], cwd=path.parent).returncode == 0 + +def skipped(test): + return platform.system() != "Darwin" and "osx-only" in test.parts + + +def main(opts): + test_dirs = opts.test_dir or [this_dir] + tests = [t for d in test_dirs for t in d.rglob("test.py") if not skipped(t)] + + if not tests: + print("No tests found", file=sys.stderr) + return False + + os.environ["PYTHONPATH"] = str(this_dir) + failed_db_creation = [] + succesful_db_creation = [] + for t in tests: + (succesful_db_creation if execute_test(t) else failed_db_creation).append(t) + + if succesful_db_creation: + codeql_root = this_dir.parents[1] + cmd = [ + "codeql", "test", "run", + f"--search-path={codeql_root}", + "--keep-databases", + "--dataset=db/db-swift", + f"--threads={opts.threads}", + ] + if opts.check_databases: + cmd.append("--check-databases") + if opts.learn: + cmd.append("--learn") + cmd.extend(str(t.parent) for t in succesful_db_creation) + ql_test_success = subprocess.run(cmd).returncode == 0 + + if failed_db_creation: + print("Database creation failed:", file=sys.stderr) + for t in failed_db_creation: + print(" ", t.parent, file=sys.stderr) + return False + + return ql_test_success + + +if __name__ == "__main__": + sys.exit(0 if main(options()) else 1) From 24da81fdb068e2ea0cc43b27686d6281fe042eb1 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 1 Jul 2022 14:56:14 +0200 Subject: [PATCH 239/465] Swift: disable integration tests on macOS for now Also, add swift workflow to code owned by the C team --- .github/workflows/swift-integration-tests.yml | 4 +++- CODEOWNERS | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/swift-integration-tests.yml b/.github/workflows/swift-integration-tests.yml index a9028d6c89a..591ea2b12f7 100644 --- a/.github/workflows/swift-integration-tests.yml +++ b/.github/workflows/swift-integration-tests.yml @@ -18,7 +18,9 @@ jobs: strategy: fail-fast: false matrix: - os : [ubuntu-20.04, macos-latest] + os: + - ubuntu-20.04 +# - macos-latest TODO steps: - uses: actions/checkout@v3 - uses: ./.github/actions/fetch-codeql diff --git a/CODEOWNERS b/CODEOWNERS index da71d1ec5d8..1754d58af63 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -42,3 +42,4 @@ WORKSPACE.bazel @github/codeql-ci-reviewers /.github/workflows/js-ml-tests.yml @github/codeql-ml-powered-queries-reviewers /.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers /.github/workflows/ruby-* @github/codeql-ruby +/.github/workflows/swift-* @github/codeql-c From 7a7440a1155ed927d8ac242d2acf3f9494ace486 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 29 Jun 2022 10:52:18 +0200 Subject: [PATCH 240/465] Swift: move `createEntry` to `SwiftDispatcher` --- .../collections4/map/AbstractHashedMap.java | 2 +- .../collections4/map/AbstractLinkedMap.java | 2 +- swift/extractor/infra/SwiftDispatcher.h | 6 +++ swift/extractor/visitors/TypeVisitor.cpp | 42 +++++++++---------- swift/extractor/visitors/TypeVisitor.h | 4 +- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractHashedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractHashedMap.java index f79236e4f10..35d673df2c8 100644 --- a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractHashedMap.java +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractHashedMap.java @@ -30,7 +30,7 @@ public class AbstractHashedMap extends AbstractMap implements Iterab protected AbstractHashedMap(int p0){} protected AbstractHashedMap(int p0, float p1){} protected AbstractHashedMap(int p0, float p1, int p2){} - protected AbstractHashedMap.HashEntry createEntry(AbstractHashedMap.HashEntry p0, int p1, K p2, V p3){ return null; } + protected AbstractHashedMap.HashEntry createTypeEntry(AbstractHashedMap.HashEntry p0, int p1, K p2, V p3){ return null; } protected AbstractHashedMap.HashEntry entryNext(AbstractHashedMap.HashEntry p0){ return null; } protected AbstractHashedMap.HashEntry getEntry(Object p0){ return null; } protected AbstractHashedMap clone(){ return null; } diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractLinkedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractLinkedMap.java index b96404dd5b9..6d349ee1130 100644 --- a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractLinkedMap.java +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractLinkedMap.java @@ -16,7 +16,7 @@ abstract public class AbstractLinkedMap extends AbstractHashedMap im protected AbstractLinkedMap(int p0){} protected AbstractLinkedMap(int p0, float p1){} protected AbstractLinkedMap(int p0, float p1, int p2){} - protected AbstractLinkedMap.LinkEntry createEntry(AbstractHashedMap.HashEntry p0, int p1, K p2, V p3){ return null; } + protected AbstractLinkedMap.LinkEntry createTypeEntry(AbstractHashedMap.HashEntry p0, int p1, K p2, V p3){ return null; } protected AbstractLinkedMap.LinkEntry entryAfter(AbstractLinkedMap.LinkEntry p0){ return null; } protected AbstractLinkedMap.LinkEntry entryBefore(AbstractLinkedMap.LinkEntry p0){ return null; } protected AbstractLinkedMap.LinkEntry getEntry(Object p0){ return null; } diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index e7aaa5af612..525cb74330a 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -112,6 +112,12 @@ class SwiftDispatcher { return assignNewLabel(&e, std::forward(args)...); } + // convenience methods for structured C++ creation + template >* = nullptr> + auto createEntry(const E& e, Args&&... args) { + return TrapClassOf{assignNewLabel(&e, std::forward(args)...)}; + } + template TrapLabel createLabel() { auto ret = arena.allocateLabel(); diff --git a/swift/extractor/visitors/TypeVisitor.cpp b/swift/extractor/visitors/TypeVisitor.cpp index 4514692421e..4b6733312d3 100644 --- a/swift/extractor/visitors/TypeVisitor.cpp +++ b/swift/extractor/visitors/TypeVisitor.cpp @@ -122,13 +122,13 @@ void TypeVisitor::visitParenType(swift::ParenType* type) { } codeql::OptionalType TypeVisitor::translateOptionalType(const swift::OptionalType& type) { - auto entry = createEntry(type); + auto entry = createTypeEntry(type); fillUnarySyntaxSugarType(type, entry); return entry; } codeql::ArraySliceType TypeVisitor::translateArraySliceType(const swift::ArraySliceType& type) { - auto entry = createEntry(type); + auto entry = createTypeEntry(type); fillUnarySyntaxSugarType(type, entry); return entry; } @@ -163,7 +163,7 @@ void TypeVisitor::visitLValueType(swift::LValueType* type) { codeql::PrimaryArchetypeType TypeVisitor::translatePrimaryArchetypeType( const swift::PrimaryArchetypeType& type) { - auto entry = createEntry(type); + auto entry = createTypeEntry(type); fillArchetypeType(type, entry); return entry; } @@ -229,7 +229,7 @@ void TypeVisitor::emitAnyGenericType(swift::AnyGenericType* type, codeql::NestedArchetypeType TypeVisitor::translateNestedArchetypeType( const swift::NestedArchetypeType& type) { - auto entry = createEntry(type); + auto entry = createTypeEntry(type); entry.parent = dispatcher_.fetchLabel(type.getParent()); entry.associated_type_declaration = dispatcher_.fetchLabel(type.getAssocType()); fillArchetypeType(type, entry); @@ -248,26 +248,26 @@ void TypeVisitor::fillArchetypeType(const swift::ArchetypeType& type, ArchetypeT } codeql::ExistentialType TypeVisitor::translateExistentialType(const swift::ExistentialType& type) { - auto entry = createEntry(type); + auto entry = createTypeEntry(type); entry.constraint = dispatcher_.fetchLabel(type.getConstraintType()); return entry; } codeql::DynamicSelfType TypeVisitor::translateDynamicSelfType(const swift::DynamicSelfType& type) { - auto entry = createEntry(type); + auto entry = createTypeEntry(type); entry.static_self_type = dispatcher_.fetchLabel(type.getSelfType()); return entry; } codeql::VariadicSequenceType TypeVisitor::translateVariadicSequenceType( const swift::VariadicSequenceType& type) { - auto entry = createEntry(type); + auto entry = createTypeEntry(type); fillUnarySyntaxSugarType(type, entry); return entry; } codeql::InOutType TypeVisitor::translateInOutType(const swift::InOutType& type) { - auto entry = createEntry(type); + auto entry = createTypeEntry(type); entry.object_type = dispatcher_.fetchLabel(type.getObjectType()); return entry; } @@ -300,19 +300,19 @@ void TypeVisitor::fillReferenceStorageType(const swift::ReferenceStorageType& ty codeql::ProtocolCompositionType TypeVisitor::translateProtocolCompositionType( const swift::ProtocolCompositionType& type) { - auto entry = createEntry(type); + auto entry = createTypeEntry(type); entry.members = dispatcher_.fetchRepeatedLabels(type.getMembers()); return entry; } codeql::BuiltinIntegerLiteralType TypeVisitor::translateBuiltinIntegerLiteralType( const swift::BuiltinIntegerLiteralType& type) { - return createEntry(type); + return createTypeEntry(type); } codeql::BuiltinIntegerType TypeVisitor::translateBuiltinIntegerType( const swift::BuiltinIntegerType& type) { - auto entry = createEntry(type); + auto entry = createTypeEntry(type); if (type.isFixedWidth()) { entry.width = type.getFixedWidth(); } @@ -321,51 +321,51 @@ codeql::BuiltinIntegerType TypeVisitor::translateBuiltinIntegerType( codeql::BuiltinBridgeObjectType TypeVisitor::translateBuiltinBridgeObjectType( const swift::BuiltinBridgeObjectType& type) { - return createEntry(type); + return createTypeEntry(type); } codeql::BuiltinDefaultActorStorageType TypeVisitor::translateBuiltinDefaultActorStorageType( const swift::BuiltinDefaultActorStorageType& type) { - return createEntry(type); + return createTypeEntry(type); } codeql::BuiltinExecutorType TypeVisitor::translateBuiltinExecutorType( const swift::BuiltinExecutorType& type) { - return createEntry(type); + return createTypeEntry(type); } codeql::BuiltinFloatType TypeVisitor::translateBuiltinFloatType( const swift::BuiltinFloatType& type) { - return createEntry(type); + return createTypeEntry(type); } codeql::BuiltinJobType TypeVisitor::translateBuiltinJobType(const swift::BuiltinJobType& type) { - return createEntry(type); + return createTypeEntry(type); } codeql::BuiltinNativeObjectType TypeVisitor::translateBuiltinNativeObjectType( const swift::BuiltinNativeObjectType& type) { - return createEntry(type); + return createTypeEntry(type); } codeql::BuiltinRawPointerType TypeVisitor::translateBuiltinRawPointerType( const swift::BuiltinRawPointerType& type) { - return createEntry(type); + return createTypeEntry(type); } codeql::BuiltinRawUnsafeContinuationType TypeVisitor::translateBuiltinRawUnsafeContinuationType( const swift::BuiltinRawUnsafeContinuationType& type) { - return createEntry(type); + return createTypeEntry(type); } codeql::BuiltinUnsafeValueBufferType TypeVisitor::translateBuiltinUnsafeValueBufferType( const swift::BuiltinUnsafeValueBufferType& type) { - return createEntry(type); + return createTypeEntry(type); } codeql::BuiltinVectorType TypeVisitor::translateBuiltinVectorType( const swift::BuiltinVectorType& type) { - return createEntry(type); + return createTypeEntry(type); } } // namespace codeql diff --git a/swift/extractor/visitors/TypeVisitor.h b/swift/extractor/visitors/TypeVisitor.h index 99d1ca7fdbb..77ae8ee13bf 100644 --- a/swift/extractor/visitors/TypeVisitor.h +++ b/swift/extractor/visitors/TypeVisitor.h @@ -81,8 +81,8 @@ class TypeVisitor : public TypeVisitorBase { void emitAnyGenericType(swift::AnyGenericType* type, TrapLabel label); template - auto createEntry(const T& type) { - TrapClassOf entry{dispatcher_.assignNewLabel(type)}; + auto createTypeEntry(const T& type) { + auto entry = dispatcher_.createEntry(type); fillType(type, entry); return entry; } From 3a975174c38001553c02144c7654651d5d99399e Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 1 Jul 2022 15:17:21 +0200 Subject: [PATCH 241/465] Swift: extract `ImportDecl` and `ModuleDecl` As `ASTMangler` crashes when called on `ModuleDecl`, we simply use its name. This might probably not work reliably in a scenario where multiple modules are compiled with the same name (like `main`), but this is left for future work. At the moment this cannot create DB inconsistencies. --- swift/codegen/schema.yml | 5 +++ swift/extractor/SwiftExtractor.cpp | 21 +++++++---- swift/extractor/infra/SwiftDispatcher.h | 9 ++++- swift/extractor/trap/TrapOutput.h | 4 +-- swift/extractor/visitors/DeclVisitor.cpp | 36 +++++++++++++++---- swift/extractor/visitors/DeclVisitor.h | 11 ++++++ .../swift/generated/decl/ImportDecl.qll | 22 ++++++++++++ .../swift/generated/decl/ModuleDecl.qll | 4 +++ swift/ql/lib/swift.dbscheme | 25 ++++++++++++- swift/ql/test/TestUtils.qll | 2 ++ .../decl/ImportDecl/ImportDecl.expected | 5 +++ .../generated/decl/ImportDecl/ImportDecl.ql | 11 ++++++ .../ImportDecl_getDeclaration.expected | 5 +++ .../ImportDecl/ImportDecl_getDeclaration.ql | 7 ++++ .../decl/ImportDecl/MISSING_SOURCE.txt | 4 --- .../generated/decl/ImportDecl/import.swift | 5 +++ .../decl/ModuleDecl/MISSING_SOURCE.txt | 4 --- .../decl/ModuleDecl/ModuleDecl.expected | 1 + .../generated/decl/ModuleDecl/ModuleDecl.ql | 15 ++++++++ .../ModuleDecl_getBaseType.expected | 0 .../decl/ModuleDecl/ModuleDecl_getBaseType.ql | 7 ++++ .../generated/decl/ModuleDecl/modules.swift | 1 + 22 files changed, 180 insertions(+), 24 deletions(-) create mode 100644 swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.ql delete mode 100644 swift/ql/test/extractor-tests/generated/decl/ImportDecl/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/decl/ImportDecl/import.swift delete mode 100644 swift/ql/test/extractor-tests/generated/decl/ModuleDecl/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ModuleDecl/modules.swift diff --git a/swift/codegen/schema.yml b/swift/codegen/schema.yml index f2e7837f2b2..01bb0c2feba 100644 --- a/swift/codegen/schema.yml +++ b/swift/codegen/schema.yml @@ -273,6 +273,9 @@ IfConfigDecl: ImportDecl: _extends: Decl + is_exported: predicate + module: ModuleDecl + declarations: ValueDecl* MissingMemberDecl: _extends: Decl @@ -1067,6 +1070,8 @@ GenericTypeDecl: ModuleDecl: _extends: TypeDecl + is_builtin_module: predicate + is_system_module: predicate ConstructorRefCallExpr: _extends: SelfApplyExpr diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 65f0ae150cc..dd8b2569e3c 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -64,8 +64,19 @@ static std::string getTrapFilename(swift::ModuleDecl& module, swift::SourceFile* return filename; } +static llvm::SmallVector getTopLevelDecls(swift::ModuleDecl& module, + swift::SourceFile* primaryFile = nullptr) { + llvm::SmallVector ret; + ret.push_back(&module); + if (primaryFile) { + primaryFile->getTopLevelDecls(ret); + } else { + module.getTopLevelDecls(ret); + } + return ret; +} + static void extractDeclarations(const SwiftExtractorConfiguration& config, - llvm::ArrayRef topLevelDecls, swift::CompilerInstance& compiler, swift::ModuleDecl& module, swift::SourceFile* primaryFile = nullptr) { @@ -119,6 +130,7 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, trap.emit(LocationsTrap{unknownLocationLabel, unknownFileLabel}); SwiftVisitor visitor(compiler.getSourceMgr(), arena, trap, module, primaryFile); + auto topLevelDecls = getTopLevelDecls(module, primaryFile); for (auto decl : topLevelDecls) { visitor.extract(decl); } @@ -203,10 +215,7 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, // user code twice: once during the module build in a form of a source file, and then as // a pre-built module during building of the dependent source files. if (module->isSystemModule() || module->isBuiltinModule()) { - llvm::SmallVector decls; - module->getTopLevelDecls(decls); - // TODO: pass ModuleDecl directly when we have module extraction in place? - extractDeclarations(config, decls, compiler, *module); + extractDeclarations(config, compiler, *module); } else { for (auto file : module->getFiles()) { auto sourceFile = llvm::dyn_cast(file); @@ -214,7 +223,7 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, continue; } archiveFile(config, *sourceFile); - extractDeclarations(config, sourceFile->getTopLevelDecls(), compiler, *module, sourceFile); + extractDeclarations(config, compiler, *module, sourceFile); } } } diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index 525cb74330a..c7ca43a1614 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -179,6 +179,11 @@ class SwiftDispatcher { return ret; } + template + void emitDebugInfo(const Args&... args) { + trap.debug(std::forward(args)...); + } + // In order to not emit duplicated entries for declarations, we restrict emission to only // Decls declared within the current "scope". // Depending on the whether we are extracting a primary source file or not the scope is defined as @@ -192,7 +197,9 @@ class SwiftDispatcher { if (decl.getModuleContext() != ¤tModule) { return false; } - if (!currentPrimarySourceFile) { + // ModuleDecl is a special case: if it passed the previous test, it is the current module + // but it never has a source file, so we short circuit to emit it in any case + if (!currentPrimarySourceFile || decl.getKind() == swift::DeclKind::Module) { return true; } if (auto context = decl.getDeclContext()) { diff --git a/swift/extractor/trap/TrapOutput.h b/swift/extractor/trap/TrapOutput.h index b9104b9118a..0e3f61d39e7 100644 --- a/swift/extractor/trap/TrapOutput.h +++ b/swift/extractor/trap/TrapOutput.h @@ -41,8 +41,8 @@ class TrapOutput { template void debug(const Args&... args) { - out_ << "// DEBUG: "; - (out_ << ... << args) << '\n'; + out_ << "/* DEBUG:\n"; + (out_ << ... << args) << "\n*/\n"; } private: diff --git a/swift/extractor/visitors/DeclVisitor.cpp b/swift/extractor/visitors/DeclVisitor.cpp index ed47f1e5fb1..33f746f6634 100644 --- a/swift/extractor/visitors/DeclVisitor.cpp +++ b/swift/extractor/visitors/DeclVisitor.cpp @@ -241,16 +241,15 @@ std::variant DeclVisitor::trans std::optional DeclVisitor::translateSubscriptDecl( const swift::SubscriptDecl& decl) { - auto id = dispatcher_.assignNewLabel(decl, mangledName(decl)); - if (!dispatcher_.shouldEmitDeclBody(decl)) { + auto entry = createNamedEntry(decl); + if (!entry) { return std::nullopt; } - SubscriptDecl entry{id}; - entry.element_type = dispatcher_.fetchLabel(decl.getElementInterfaceType()); + entry->element_type = dispatcher_.fetchLabel(decl.getElementInterfaceType()); if (auto indices = decl.getIndices()) { - entry.params = dispatcher_.fetchRepeatedLabels(*indices); + entry->params = dispatcher_.fetchRepeatedLabels(*indices); } - fillAbstractStorageDecl(decl, entry); + fillAbstractStorageDecl(decl, *entry); return entry; } @@ -262,7 +261,32 @@ codeql::ExtensionDecl DeclVisitor::translateExtensionDecl(const swift::Extension return entry; } +codeql::ImportDecl DeclVisitor::translateImportDecl(const swift::ImportDecl& decl) { + auto entry = dispatcher_.createEntry(decl); + entry.is_exported = decl.isExported(); + entry.module = dispatcher_.fetchLabel(decl.getModule()); + entry.declarations = dispatcher_.fetchRepeatedLabels(decl.getDecls()); + return entry; +} + +std::optional DeclVisitor::translateModuleDecl(const swift::ModuleDecl& decl) { + auto entry = createNamedEntry(decl); + if (!entry) { + return std::nullopt; + } + entry->is_builtin_module = decl.isBuiltinModule(); + entry->is_system_module = decl.isSystemModule(); + fillTypeDecl(decl, *entry); + return entry; +} + std::string DeclVisitor::mangledName(const swift::ValueDecl& decl) { + // ASTMangler::mangleAnyDecl crashes when called on `ModuleDecl` + // TODO find a more unique string working also when different modules are compiled with the same + // name + if (decl.getKind() == swift::DeclKind::Module) { + return static_cast(decl).getRealName().str().str(); + } // prefix adds a couple of special symbols, we don't necessary need them return mangler.mangleAnyDecl(&decl, /* prefix = */ false); } diff --git a/swift/extractor/visitors/DeclVisitor.h b/swift/extractor/visitors/DeclVisitor.h index 0527513d859..c9a1b43556d 100644 --- a/swift/extractor/visitors/DeclVisitor.h +++ b/swift/extractor/visitors/DeclVisitor.h @@ -50,6 +50,8 @@ class DeclVisitor : public AstVisitorBase { const swift::AccessorDecl& decl); std::optional translateSubscriptDecl(const swift::SubscriptDecl& decl); codeql::ExtensionDecl translateExtensionDecl(const swift::ExtensionDecl& decl); + codeql::ImportDecl translateImportDecl(const swift::ImportDecl& decl); + std::optional translateModuleDecl(const swift::ModuleDecl& decl); private: std::string mangledName(const swift::ValueDecl& decl); @@ -66,6 +68,15 @@ class DeclVisitor : public AstVisitorBase { void fillAbstractStorageDecl(const swift::AbstractStorageDecl& decl, codeql::AbstractStorageDecl& entry); + template + std::optional> createNamedEntry(const D& decl) { + auto id = dispatcher_.assignNewLabel(decl, mangledName(decl)); + if (dispatcher_.shouldEmitDeclBody(decl)) { + return TrapClassOf{id}; + } + return std::nullopt; + } + private: swift::Mangle::ASTMangler mangler; }; diff --git a/swift/ql/lib/codeql/swift/generated/decl/ImportDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/ImportDecl.qll index fdd89db170a..8f5638ad069 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/ImportDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/ImportDecl.qll @@ -1,6 +1,28 @@ // generated by codegen/codegen.py import codeql.swift.elements.decl.Decl +import codeql.swift.elements.decl.ModuleDecl +import codeql.swift.elements.decl.ValueDecl class ImportDeclBase extends @import_decl, Decl { override string getAPrimaryQlClass() { result = "ImportDecl" } + + predicate isExported() { import_decl_is_exported(this) } + + ModuleDecl getModule() { + exists(ModuleDecl x | + import_decls(this, x) and + result = x.resolve() + ) + } + + ValueDecl getDeclaration(int index) { + exists(ValueDecl x | + import_decl_declarations(this, index, x) and + result = x.resolve() + ) + } + + ValueDecl getADeclaration() { result = getDeclaration(_) } + + int getNumberOfDeclarations() { result = count(getADeclaration()) } } diff --git a/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll index aad5d00c0c6..3a1931b2d52 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/ModuleDecl.qll @@ -3,4 +3,8 @@ import codeql.swift.elements.decl.TypeDecl class ModuleDeclBase extends @module_decl, TypeDecl { override string getAPrimaryQlClass() { result = "ModuleDecl" } + + predicate isBuiltinModule() { module_decl_is_builtin_module(this) } + + predicate isSystemModule() { module_decl_is_system_module(this) } } diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index 7937e938e70..83ee8412131 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -644,7 +644,20 @@ if_config_decls( //dir=decl ); import_decls( //dir=decl - unique int id: @import_decl + unique int id: @import_decl, + int module: @module_decl ref +); + +#keyset[id] +import_decl_is_exported( //dir=decl + int id: @import_decl ref +); + +#keyset[id, index] +import_decl_declarations( //dir=decl + int id: @import_decl ref, + int index: int ref, + int declaration: @value_decl ref ); missing_member_decls( //dir=decl @@ -2018,6 +2031,16 @@ module_decls( //dir=decl unique int id: @module_decl ); +#keyset[id] +module_decl_is_builtin_module( //dir=decl + int id: @module_decl ref +); + +#keyset[id] +module_decl_is_system_module( //dir=decl + int id: @module_decl ref +); + constructor_ref_call_exprs( //dir=expr unique int id: @constructor_ref_call_expr ); diff --git a/swift/ql/test/TestUtils.qll b/swift/ql/test/TestUtils.qll index 9359944fe90..0c04fcb5989 100644 --- a/swift/ql/test/TestUtils.qll +++ b/swift/ql/test/TestUtils.qll @@ -4,6 +4,8 @@ cached predicate toBeTested(Element e) { e instanceof File or + exists(ModuleDecl m | m = e and not m.isBuiltinModule() and not m.isSystemModule()) + or exists(Locatable loc | loc.getLocation().getFile().getName().matches("%swift/ql/test%") and ( diff --git a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.expected new file mode 100644 index 00000000000..3e9fd295744 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.expected @@ -0,0 +1,5 @@ +| import.swift:1:1:1:8 | import ... | isExported: | no | getModule: | file://:0:0:0:0 | Swift | +| import.swift:2:1:2:24 | import ... | isExported: | no | getModule: | file://:0:0:0:0 | Swift | +| import.swift:3:12:3:32 | import ... | isExported: | yes | getModule: | file://:0:0:0:0 | Swift | +| import.swift:4:1:4:19 | import ... | isExported: | no | getModule: | file://:0:0:0:0 | Swift | +| import.swift:5:1:5:23 | import ... | isExported: | no | getModule: | file://:0:0:0:0 | Swift | diff --git a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.ql new file mode 100644 index 00000000000..34978aae118 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl.ql @@ -0,0 +1,11 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ImportDecl x, string isExported, ModuleDecl getModule +where + toBeTested(x) and + not x.isUnknown() and + (if x.isExported() then isExported = "yes" else isExported = "no") and + getModule = x.getModule() +select x, "isExported:", isExported, "getModule:", getModule diff --git a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.expected b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.expected new file mode 100644 index 00000000000..b877b113bc6 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.expected @@ -0,0 +1,5 @@ +| import.swift:2:1:2:24 | import ... | 0 | file://:0:0:0:0 | Int | +| import.swift:3:12:3:32 | import ... | 0 | file://:0:0:0:0 | Double | +| import.swift:4:1:4:19 | import ... | 0 | file://:0:0:0:0 | print(_:separator:terminator:) | +| import.swift:4:1:4:19 | import ... | 1 | file://:0:0:0:0 | print(_:separator:terminator:to:) | +| import.swift:5:1:5:23 | import ... | 0 | file://:0:0:0:0 | Hashable | diff --git a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.ql b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.ql new file mode 100644 index 00000000000..852fe518ed2 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/ImportDecl_getDeclaration.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ImportDecl x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getDeclaration(index) diff --git a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/decl/ImportDecl/import.swift b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/import.swift new file mode 100644 index 00000000000..bcb562996ae --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ImportDecl/import.swift @@ -0,0 +1,5 @@ +import Swift +import typealias Swift.Int +@_exported import struct Swift.Double +import func Swift.print // imports all overloads +import protocol Swift.Hashable diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.expected new file mode 100644 index 00000000000..ef50edbe828 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.expected @@ -0,0 +1 @@ +| file://:0:0:0:0 | Foo | getInterfaceType: | module | getName: | Foo | isBuiltinModule: | no | isSystemModule: | no | diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.ql new file mode 100644 index 00000000000..73e912a8245 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.ql @@ -0,0 +1,15 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from + ModuleDecl x, Type getInterfaceType, string getName, string isBuiltinModule, string isSystemModule +where + toBeTested(x) and + not x.isUnknown() and + getInterfaceType = x.getInterfaceType() and + getName = x.getName() and + (if x.isBuiltinModule() then isBuiltinModule = "yes" else isBuiltinModule = "no") and + if x.isSystemModule() then isSystemModule = "yes" else isSystemModule = "no" +select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "isBuiltinModule:", + isBuiltinModule, "isSystemModule:", isSystemModule diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.expected b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.ql b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.ql new file mode 100644 index 00000000000..0c0cec75d86 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl_getBaseType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ModuleDecl x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getBaseType(index) diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/modules.swift b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/modules.swift new file mode 100644 index 00000000000..bb12ed63ddd --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/modules.swift @@ -0,0 +1 @@ +//codeql-extractor-options: -module-name Foo From f9143f7855ab00b464b42320e54acd5366690898 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 1 Jul 2022 15:43:16 +0200 Subject: [PATCH 242/465] Swift: fix extraction of empty files --- swift/extractor/SwiftExtractor.cpp | 5 ++++- swift/ql/test/extractor-tests/generated/File/File.expected | 3 ++- .../generated/File/{hello.swift => empty.swift} | 0 swift/ql/test/extractor-tests/generated/File/non_empty.swift | 1 + 4 files changed, 7 insertions(+), 2 deletions(-) rename swift/ql/test/extractor-tests/generated/File/{hello.swift => empty.swift} (100%) create mode 100644 swift/ql/test/extractor-tests/generated/File/non_empty.swift diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index dd8b2569e3c..44d2309cb2a 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -134,7 +134,10 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, for (auto decl : topLevelDecls) { visitor.extract(decl); } - if (topLevelDecls.empty()) { + // TODO the following will be moved to the dispatcher when we start caching swift file objects + // for the moment, topLevelDecls always contains the current module, which does not have a file + // associated with it, so we need a special case when there are no top level declarations + if (topLevelDecls.size() == 1) { // In the case of empty files, the dispatcher is not called, but we still want to 'record' the // fact that the file was extracted llvm::SmallString name(filename); diff --git a/swift/ql/test/extractor-tests/generated/File/File.expected b/swift/ql/test/extractor-tests/generated/File/File.expected index d2ef49d491d..73437ea7a92 100644 --- a/swift/ql/test/extractor-tests/generated/File/File.expected +++ b/swift/ql/test/extractor-tests/generated/File/File.expected @@ -1,2 +1,3 @@ +| empty.swift:0:0:0:0 | empty.swift | getName: | empty.swift | | file://:0:0:0:0 | | getName: | | -| hello.swift:0:0:0:0 | hello.swift | getName: | hello.swift | +| non_empty.swift:0:0:0:0 | non_empty.swift | getName: | non_empty.swift | diff --git a/swift/ql/test/extractor-tests/generated/File/hello.swift b/swift/ql/test/extractor-tests/generated/File/empty.swift similarity index 100% rename from swift/ql/test/extractor-tests/generated/File/hello.swift rename to swift/ql/test/extractor-tests/generated/File/empty.swift diff --git a/swift/ql/test/extractor-tests/generated/File/non_empty.swift b/swift/ql/test/extractor-tests/generated/File/non_empty.swift new file mode 100644 index 00000000000..11b15b1a458 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/File/non_empty.swift @@ -0,0 +1 @@ +print("hello") From e575bab9d6d0288c4ba136a6fb2cacfdca8b05b4 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 1 Jul 2022 15:45:28 +0200 Subject: [PATCH 243/465] Revert unwanted committed files --- .../org/apache/commons/collections4/map/AbstractHashedMap.java | 2 +- .../org/apache/commons/collections4/map/AbstractLinkedMap.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractHashedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractHashedMap.java index 35d673df2c8..f79236e4f10 100644 --- a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractHashedMap.java +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractHashedMap.java @@ -30,7 +30,7 @@ public class AbstractHashedMap extends AbstractMap implements Iterab protected AbstractHashedMap(int p0){} protected AbstractHashedMap(int p0, float p1){} protected AbstractHashedMap(int p0, float p1, int p2){} - protected AbstractHashedMap.HashEntry createTypeEntry(AbstractHashedMap.HashEntry p0, int p1, K p2, V p3){ return null; } + protected AbstractHashedMap.HashEntry createEntry(AbstractHashedMap.HashEntry p0, int p1, K p2, V p3){ return null; } protected AbstractHashedMap.HashEntry entryNext(AbstractHashedMap.HashEntry p0){ return null; } protected AbstractHashedMap.HashEntry getEntry(Object p0){ return null; } protected AbstractHashedMap clone(){ return null; } diff --git a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractLinkedMap.java b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractLinkedMap.java index 6d349ee1130..b96404dd5b9 100644 --- a/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractLinkedMap.java +++ b/java/ql/test/stubs/apache-commons-collections4-4.4/org/apache/commons/collections4/map/AbstractLinkedMap.java @@ -16,7 +16,7 @@ abstract public class AbstractLinkedMap extends AbstractHashedMap im protected AbstractLinkedMap(int p0){} protected AbstractLinkedMap(int p0, float p1){} protected AbstractLinkedMap(int p0, float p1, int p2){} - protected AbstractLinkedMap.LinkEntry createTypeEntry(AbstractHashedMap.HashEntry p0, int p1, K p2, V p3){ return null; } + protected AbstractLinkedMap.LinkEntry createEntry(AbstractHashedMap.HashEntry p0, int p1, K p2, V p3){ return null; } protected AbstractLinkedMap.LinkEntry entryAfter(AbstractLinkedMap.LinkEntry p0){ return null; } protected AbstractLinkedMap.LinkEntry entryBefore(AbstractLinkedMap.LinkEntry p0){ return null; } protected AbstractLinkedMap.LinkEntry getEntry(Object p0){ return null; } From 8addc0679949d762820d365de03299ff61f79ee3 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 1 Jul 2022 15:59:36 +0200 Subject: [PATCH 244/465] Swift: add integration test for multiple modules --- .../posix-only/partial-modules/Modules.expected | 4 ++++ .../integration-tests/posix-only/partial-modules/Modules.ql | 5 +++++ 2 files changed, 9 insertions(+) create mode 100644 swift/integration-tests/posix-only/partial-modules/Modules.expected create mode 100644 swift/integration-tests/posix-only/partial-modules/Modules.ql diff --git a/swift/integration-tests/posix-only/partial-modules/Modules.expected b/swift/integration-tests/posix-only/partial-modules/Modules.expected new file mode 100644 index 00000000000..4c738975f34 --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/Modules.expected @@ -0,0 +1,4 @@ +| file://:0:0:0:0 | A | +| file://:0:0:0:0 | B | +| file://:0:0:0:0 | main | +| file://:0:0:0:0 | partial_modules | diff --git a/swift/integration-tests/posix-only/partial-modules/Modules.ql b/swift/integration-tests/posix-only/partial-modules/Modules.ql new file mode 100644 index 00000000000..d456e261a3c --- /dev/null +++ b/swift/integration-tests/posix-only/partial-modules/Modules.ql @@ -0,0 +1,5 @@ +import swift + +from ModuleDecl decl +where not decl.isBuiltinModule() and not decl.isSystemModule() +select decl From 416977dc5003fabc74dc09190f91f8374c8dc0fe Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 1 Jul 2022 09:27:12 +0100 Subject: [PATCH 245/465] Swift: Add test cases for removeFirst, removeLast. --- .../CWE-135/StringLengthConflation.expected | 40 +++++++++---------- .../CWE-135/StringLengthConflation.swift | 12 ++++++ 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index 1bb4de15325..8e42c4a145d 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -1,36 +1,36 @@ edges -| StringLengthConflation.swift:101:34:101:36 | .count : | StringLengthConflation.swift:101:34:101:44 | ... call to -(_:_:) ... | -| StringLengthConflation.swift:102:36:102:38 | .count : | StringLengthConflation.swift:102:36:102:46 | ... call to -(_:_:) ... | -| StringLengthConflation.swift:107:36:107:38 | .count : | StringLengthConflation.swift:107:36:107:46 | ... call to -(_:_:) ... | -| StringLengthConflation.swift:108:38:108:40 | .count : | StringLengthConflation.swift:108:38:108:48 | ... call to -(_:_:) ... | | StringLengthConflation.swift:113:34:113:36 | .count : | StringLengthConflation.swift:113:34:113:44 | ... call to -(_:_:) ... | | StringLengthConflation.swift:114:36:114:38 | .count : | StringLengthConflation.swift:114:36:114:46 | ... call to -(_:_:) ... | -| StringLengthConflation.swift:120:28:120:30 | .count : | StringLengthConflation.swift:120:28:120:38 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:119:36:119:38 | .count : | StringLengthConflation.swift:119:36:119:46 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:120:38:120:40 | .count : | StringLengthConflation.swift:120:38:120:48 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:125:34:125:36 | .count : | StringLengthConflation.swift:125:34:125:44 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:126:36:126:38 | .count : | StringLengthConflation.swift:126:36:126:46 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:132:28:132:30 | .count : | StringLengthConflation.swift:132:28:132:38 | ... call to -(_:_:) ... | nodes | StringLengthConflation.swift:72:33:72:35 | .count | semmle.label | .count | | StringLengthConflation.swift:78:47:78:49 | .count | semmle.label | .count | -| StringLengthConflation.swift:101:34:101:36 | .count : | semmle.label | .count : | -| StringLengthConflation.swift:101:34:101:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | -| StringLengthConflation.swift:102:36:102:38 | .count : | semmle.label | .count : | -| StringLengthConflation.swift:102:36:102:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | -| StringLengthConflation.swift:107:36:107:38 | .count : | semmle.label | .count : | -| StringLengthConflation.swift:107:36:107:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | -| StringLengthConflation.swift:108:38:108:40 | .count : | semmle.label | .count : | -| StringLengthConflation.swift:108:38:108:48 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | | StringLengthConflation.swift:113:34:113:36 | .count : | semmle.label | .count : | | StringLengthConflation.swift:113:34:113:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | | StringLengthConflation.swift:114:36:114:38 | .count : | semmle.label | .count : | | StringLengthConflation.swift:114:36:114:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | -| StringLengthConflation.swift:120:28:120:30 | .count : | semmle.label | .count : | -| StringLengthConflation.swift:120:28:120:38 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:119:36:119:38 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:119:36:119:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:120:38:120:40 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:120:38:120:48 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:125:34:125:36 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:125:34:125:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:126:36:126:38 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:126:36:126:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:132:28:132:30 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:132:28:132:38 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | subpaths #select | 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:101:34:101:44 | ... call to -(_:_:) ... | StringLengthConflation.swift:101:34:101:36 | .count : | StringLengthConflation.swift:101:34:101:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | -| StringLengthConflation.swift:102:36:102:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:102:36:102:38 | .count : | StringLengthConflation.swift:102:36:102:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | -| StringLengthConflation.swift:107:36:107:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:107:36:107:38 | .count : | StringLengthConflation.swift:107:36:107:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | -| StringLengthConflation.swift:108:38:108:48 | ... call to -(_:_:) ... | StringLengthConflation.swift:108:38:108:40 | .count : | StringLengthConflation.swift:108:38:108:48 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:113:34:113:44 | ... call to -(_:_:) ... | StringLengthConflation.swift:113:34:113:36 | .count : | StringLengthConflation.swift:113:34:113:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:114:36:114:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:114:36:114:38 | .count : | StringLengthConflation.swift:114:36:114:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | -| StringLengthConflation.swift:120:28:120:38 | ... call to -(_:_:) ... | StringLengthConflation.swift:120:28:120:30 | .count : | StringLengthConflation.swift:120:28:120:38 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:119:36:119:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:119:36:119:38 | .count : | StringLengthConflation.swift:119:36:119:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:120:38:120:48 | ... call to -(_:_:) ... | StringLengthConflation.swift:120:38:120:40 | .count : | StringLengthConflation.swift:120:38:120:48 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:125:34:125:44 | ... call to -(_:_:) ... | StringLengthConflation.swift:125:34:125:36 | .count : | StringLengthConflation.swift:125:34:125:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:126:36:126:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:126:36:126:38 | .count : | StringLengthConflation.swift:126:36:126:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:132:28:132:38 | ... call to -(_:_:) ... | StringLengthConflation.swift:132:28:132:30 | .count : | StringLengthConflation.swift:132:28:132:38 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift index 8cb698009b6..7a083267aa4 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift @@ -96,6 +96,18 @@ func test(s: String) { let str8 = s.suffix(ns.length - 1) // BAD: NSString length used in String [NOT DETECTED] print("suffix '\(str7)' / '\(str8)'") + var str9 = s + str9.removeFirst(s.count - 1) // GOOD + var str10 = s + str10.removeFirst(ns.length - 1) // BAD: NSString length used in String [NOT DETECTED] + print("removeFirst '\(str9)' / '\(str10)'") + + var str11 = s + str11.removeLast(s.count - 1) // GOOD + var str12 = s + str12.removeLast(ns.length - 1) // BAD: NSString length used in String [NOT DETECTED] + print("removeLast '\(str11)' / '\(str12)'") + let nstr1 = ns.character(at: ns.length - 1) // GOOD let nmstr1 = nms.character(at: nms.length - 1) // GOOD let nstr2 = ns.character(at: s.count - 1) // BAD: String length used in NSString From a306f312cd62388a2b0bf1ec346e548f0de0cfb4 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 1 Jul 2022 11:01:12 +0100 Subject: [PATCH 246/465] Swift: Add a test of converting Range to NSRange. --- .../CWE-135/StringLengthConflation.expected | 56 +++++++++---------- .../CWE-135/StringLengthConflation.swift | 11 +++- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index 8e42c4a145d..2654d28d334 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -1,36 +1,36 @@ edges -| StringLengthConflation.swift:113:34:113:36 | .count : | StringLengthConflation.swift:113:34:113:44 | ... call to -(_:_:) ... | -| StringLengthConflation.swift:114:36:114:38 | .count : | StringLengthConflation.swift:114:36:114:46 | ... call to -(_:_:) ... | -| StringLengthConflation.swift:119:36:119:38 | .count : | StringLengthConflation.swift:119:36:119:46 | ... call to -(_:_:) ... | -| StringLengthConflation.swift:120:38:120:40 | .count : | StringLengthConflation.swift:120:38:120:48 | ... call to -(_:_:) ... | -| StringLengthConflation.swift:125:34:125:36 | .count : | StringLengthConflation.swift:125:34:125:44 | ... call to -(_:_:) ... | -| StringLengthConflation.swift:126:36:126:38 | .count : | StringLengthConflation.swift:126:36:126:46 | ... call to -(_:_:) ... | -| StringLengthConflation.swift:132:28:132:30 | .count : | StringLengthConflation.swift:132:28:132:38 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:122:34:122:36 | .count : | StringLengthConflation.swift:122:34:122:44 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:123:36:123:38 | .count : | StringLengthConflation.swift:123:36:123:46 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:128:36:128:38 | .count : | StringLengthConflation.swift:128:36:128:46 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:129:38:129:40 | .count : | StringLengthConflation.swift:129:38:129:48 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:134:34:134:36 | .count : | StringLengthConflation.swift:134:34:134:44 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:135:36:135:38 | .count : | StringLengthConflation.swift:135:36:135:46 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:141:28:141:30 | .count : | StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | nodes | StringLengthConflation.swift:72:33:72:35 | .count | semmle.label | .count | | StringLengthConflation.swift:78:47:78:49 | .count | semmle.label | .count | -| StringLengthConflation.swift:113:34:113:36 | .count : | semmle.label | .count : | -| StringLengthConflation.swift:113:34:113:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | -| StringLengthConflation.swift:114:36:114:38 | .count : | semmle.label | .count : | -| StringLengthConflation.swift:114:36:114:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | -| StringLengthConflation.swift:119:36:119:38 | .count : | semmle.label | .count : | -| StringLengthConflation.swift:119:36:119:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | -| StringLengthConflation.swift:120:38:120:40 | .count : | semmle.label | .count : | -| StringLengthConflation.swift:120:38:120:48 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | -| StringLengthConflation.swift:125:34:125:36 | .count : | semmle.label | .count : | -| StringLengthConflation.swift:125:34:125:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | -| StringLengthConflation.swift:126:36:126:38 | .count : | semmle.label | .count : | -| StringLengthConflation.swift:126:36:126:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | -| StringLengthConflation.swift:132:28:132:30 | .count : | semmle.label | .count : | -| StringLengthConflation.swift:132:28:132:38 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:122:34:122:36 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:122:34:122:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:123:36:123:38 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:123:36:123:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:128:36:128:38 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:128:36:128:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:129:38:129:40 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:129:38:129:48 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:134:34:134:36 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:134:34:134:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:135:36:135:38 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:135:36:135:46 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:141:28:141:30 | .count : | semmle.label | .count : | +| StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | subpaths #select | 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:113:34:113:44 | ... call to -(_:_:) ... | StringLengthConflation.swift:113:34:113:36 | .count : | StringLengthConflation.swift:113:34:113:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | -| StringLengthConflation.swift:114:36:114:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:114:36:114:38 | .count : | StringLengthConflation.swift:114:36:114:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | -| StringLengthConflation.swift:119:36:119:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:119:36:119:38 | .count : | StringLengthConflation.swift:119:36:119:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | -| StringLengthConflation.swift:120:38:120:48 | ... call to -(_:_:) ... | StringLengthConflation.swift:120:38:120:40 | .count : | StringLengthConflation.swift:120:38:120:48 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | -| StringLengthConflation.swift:125:34:125:44 | ... call to -(_:_:) ... | StringLengthConflation.swift:125:34:125:36 | .count : | StringLengthConflation.swift:125:34:125:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | -| StringLengthConflation.swift:126:36:126:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:126:36:126:38 | .count : | StringLengthConflation.swift:126:36:126:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | -| StringLengthConflation.swift:132:28:132:38 | ... call to -(_:_:) ... | StringLengthConflation.swift:132:28:132:30 | .count : | StringLengthConflation.swift:132:28:132:38 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:122:34:122:44 | ... call to -(_:_:) ... | StringLengthConflation.swift:122:34:122:36 | .count : | StringLengthConflation.swift:122:34:122:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:123:36:123:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:123:36:123:38 | .count : | StringLengthConflation.swift:123:36:123:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:128:36:128:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:128:36:128:38 | .count : | StringLengthConflation.swift:128:36:128:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:129:38:129:48 | ... call to -(_:_:) ... | StringLengthConflation.swift:129:38:129:40 | .count : | StringLengthConflation.swift:129:38:129:48 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:134:34:134:44 | ... call to -(_:_:) ... | StringLengthConflation.swift:134:34:134:36 | .count : | StringLengthConflation.swift:134:34:134:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:135:36:135:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:135:36:135:38 | .count : | StringLengthConflation.swift:135:36:135:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | +| StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | StringLengthConflation.swift:141:28:141:30 | .count : | StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift index 7a083267aa4..cf248a9a221 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift @@ -28,6 +28,7 @@ class NSMutableString : NSString class NSRange { init(location: Int, length: Int) { self.description = "" } + init(_ r: R, in: S) { self.description = "" } private(set) var description: String } @@ -36,7 +37,6 @@ func NSMakeRange(_ loc: Int, _ len: Int) -> NSRange { return NSRange(location: l - // --- tests --- func test(s: String) { @@ -78,6 +78,15 @@ func test(s: String) { let range6 = NSRange(location: 0, length: s.count) // BAD: String length used in NSMakeRange print("NSRange '\(range5.description)' / '\(range6.description)'") + // --- converting Range to NSRange --- + + let range7 = s.startIndex ..< s.endIndex + let range8 = NSRange(range7, in: s) // GOOD + let location = s.distance(from: s.startIndex, to: range7.lowerBound) + let length = s.distance(from: range7.lowerBound, to: range7.upperBound) + let range9 = NSRange(location: location, length: length) // BAD [NOT DETECTED] + print("NSRange '\(range8.description)' / '\(range9.description)'") + // --- String operations using an integer directly --- let str1 = s.dropFirst(s.count - 1) // GOOD From bc03f6959c46c26773679620298fba0188b8efce Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 1 Jul 2022 09:16:05 +0100 Subject: [PATCH 247/465] Swift: Detect String -> NSString results. --- .../CWE-135/StringLengthConflation.ql | 29 +++++++++++++++++++ .../CWE-135/StringLengthConflation.expected | 24 +++++++++++++++ .../CWE-135/StringLengthConflation.swift | 12 ++++---- 3 files changed, 59 insertions(+), 6 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index a4e731e18ea..fc62309cdee 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -30,6 +30,14 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { node.asExpr() = member and flowstate = "String" ) + or + // result of a call to to `NSString.length` + exists(MemberRefExpr member | + member.getBaseExpr().getType().getName() = ["NSString", "NSMutableString"] and + member.getMember().(VarDecl).getName() = "length" and + node.asExpr() = member and + flowstate = "NSString" + ) } override predicate isSink(DataFlow::Node node, string flowstate) { @@ -83,6 +91,27 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and flowstate = "String" // `String` length flowing into `NSString` ) + or + // arguments to function calls... + exists(string funcName, string paramName, CallExpr call, int arg | + ( + // `dropFirst`, `dropLast`, `removeFirst`, `removeLast` + funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and + paramName = "k" + or + // `prefix`, `suffix` + funcName = ["prefix(_:)", "suffix(_:)"] and + paramName = "maxLength" + ) and + call.getFunction().(ApplyExpr).getStaticTarget().getName() = funcName and + call.getFunction() + .(ApplyExpr) + .getStaticTarget() + .getParam(pragma[only_bind_into](arg)) + .getName() = paramName and + call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and + flowstate = "NSString" // `NSString` length flowing into `String` + ) } override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index 2654d28d334..a68894b7d9c 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -1,4 +1,10 @@ edges +| StringLengthConflation.swift:93:28:93:31 | .length : | StringLengthConflation.swift:93:28:93:40 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:97:27:97:30 | .length : | StringLengthConflation.swift:97:27:97:39 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:101:25:101:28 | .length : | StringLengthConflation.swift:101:25:101:37 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:105:25:105:28 | .length : | StringLengthConflation.swift:105:25:105:37 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:111:23:111:26 | .length : | StringLengthConflation.swift:111:23:111:35 | ... call to -(_:_:) ... | +| StringLengthConflation.swift:117:22:117:25 | .length : | StringLengthConflation.swift:117:22:117:34 | ... call to -(_:_:) ... | | StringLengthConflation.swift:122:34:122:36 | .count : | StringLengthConflation.swift:122:34:122:44 | ... call to -(_:_:) ... | | StringLengthConflation.swift:123:36:123:38 | .count : | StringLengthConflation.swift:123:36:123:46 | ... call to -(_:_:) ... | | StringLengthConflation.swift:128:36:128:38 | .count : | StringLengthConflation.swift:128:36:128:46 | ... call to -(_:_:) ... | @@ -9,6 +15,18 @@ edges nodes | StringLengthConflation.swift:72:33:72:35 | .count | semmle.label | .count | | StringLengthConflation.swift:78:47:78:49 | .count | semmle.label | .count | +| StringLengthConflation.swift:93:28:93:31 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:93:28:93:40 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:97:27:97:30 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:97:27:97:39 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:101:25:101:28 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:101:25:101:37 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:105:25:105:28 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:105:25:105:37 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:111:23:111:26 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:111:23:111:35 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | +| StringLengthConflation.swift:117:22:117:25 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:117:22:117:34 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | | StringLengthConflation.swift:122:34:122:36 | .count : | semmle.label | .count : | | StringLengthConflation.swift:122:34:122:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | | StringLengthConflation.swift:123:36:123:38 | .count : | semmle.label | .count : | @@ -27,6 +45,12 @@ subpaths #select | 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:93:28:93:40 | ... call to -(_:_:) ... | StringLengthConflation.swift:93:28:93:31 | .length : | StringLengthConflation.swift:93:28:93:40 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:97:27:97:39 | ... call to -(_:_:) ... | StringLengthConflation.swift:97:27:97:30 | .length : | StringLengthConflation.swift:97:27:97:39 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:101:25:101:37 | ... call to -(_:_:) ... | StringLengthConflation.swift:101:25:101:28 | .length : | StringLengthConflation.swift:101:25:101:37 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:105:25:105:37 | ... call to -(_:_:) ... | StringLengthConflation.swift:105:25:105:28 | .length : | StringLengthConflation.swift:105:25:105:37 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:111:23:111:35 | ... call to -(_:_:) ... | StringLengthConflation.swift:111:23:111:26 | .length : | StringLengthConflation.swift:111:23:111:35 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:117:22:117:34 | ... call to -(_:_:) ... | StringLengthConflation.swift:117:22:117:25 | .length : | StringLengthConflation.swift:117:22:117:34 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:122:34:122:44 | ... call to -(_:_:) ... | StringLengthConflation.swift:122:34:122:36 | .count : | StringLengthConflation.swift:122:34:122:44 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:123:36:123:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:123:36:123:38 | .count : | StringLengthConflation.swift:123:36:123:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | | StringLengthConflation.swift:128:36:128:46 | ... call to -(_:_:) ... | StringLengthConflation.swift:128:36:128:38 | .count : | StringLengthConflation.swift:128:36:128:46 | ... call to -(_:_:) ... | This String length is used in an NSString, but it may not be equivalent. | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift index cf248a9a221..60037ffd676 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift @@ -90,31 +90,31 @@ func test(s: String) { // --- String operations using an integer directly --- let str1 = s.dropFirst(s.count - 1) // GOOD - let str2 = s.dropFirst(ns.length - 1) // BAD: NSString length used in String [NOT DETECTED] + let str2 = s.dropFirst(ns.length - 1) // BAD: NSString length used in String print("dropFirst '\(str1)' / '\(str2)'") let str3 = s.dropLast(s.count - 1) // GOOD - let str4 = s.dropLast(ns.length - 1) // BAD: NSString length used in String [NOT DETECTED] + let str4 = s.dropLast(ns.length - 1) // BAD: NSString length used in String print("dropLast '\(str3)' / '\(str4)'") let str5 = s.prefix(s.count - 1) // GOOD - let str6 = s.prefix(ns.length - 1) // BAD: NSString length used in String [NOT DETECTED] + let str6 = s.prefix(ns.length - 1) // BAD: NSString length used in String print("prefix '\(str5)' / '\(str6)'") let str7 = s.suffix(s.count - 1) // GOOD - let str8 = s.suffix(ns.length - 1) // BAD: NSString length used in String [NOT DETECTED] + let str8 = s.suffix(ns.length - 1) // BAD: NSString length used in String print("suffix '\(str7)' / '\(str8)'") var str9 = s str9.removeFirst(s.count - 1) // GOOD var str10 = s - str10.removeFirst(ns.length - 1) // BAD: NSString length used in String [NOT DETECTED] + str10.removeFirst(ns.length - 1) // BAD: NSString length used in String print("removeFirst '\(str9)' / '\(str10)'") var str11 = s str11.removeLast(s.count - 1) // GOOD var str12 = s - str12.removeLast(ns.length - 1) // BAD: NSString length used in String [NOT DETECTED] + str12.removeLast(ns.length - 1) // BAD: NSString length used in String print("removeLast '\(str11)' / '\(str12)'") let nstr1 = ns.character(at: ns.length - 1) // GOOD From d60d2457c215def7b2e838c2aee0b44c7dc816e5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 1 Jul 2022 13:33:25 +0100 Subject: [PATCH 248/465] Swift: Add String.Index.init as a source as as well. --- .../ql/src/queries/Security/CWE-135/StringLengthConflation.ql | 4 ++++ .../Security/CWE-135/StringLengthConflation.expected | 2 ++ .../query-tests/Security/CWE-135/StringLengthConflation.swift | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index fc62309cdee..38485aa119d 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -102,6 +102,10 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { // `prefix`, `suffix` funcName = ["prefix(_:)", "suffix(_:)"] and paramName = "maxLength" + or + // `String.Index.init` + funcName = "init(encodedOffset:)" and + paramName = "offset" ) and call.getFunction().(ApplyExpr).getStaticTarget().getName() = funcName and call.getFunction() diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index a68894b7d9c..411a938ba0e 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -13,6 +13,7 @@ edges | StringLengthConflation.swift:135:36:135:38 | .count : | StringLengthConflation.swift:135:36:135:46 | ... call to -(_:_:) ... | | StringLengthConflation.swift:141:28:141:30 | .count : | StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | nodes +| StringLengthConflation.swift:53:43:53:46 | .length | semmle.label | .length | | StringLengthConflation.swift:72:33:72:35 | .count | semmle.label | .count | | StringLengthConflation.swift:78:47:78:49 | .count | semmle.label | .count | | StringLengthConflation.swift:93:28:93:31 | .length : | semmle.label | .length : | @@ -43,6 +44,7 @@ nodes | StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | subpaths #select +| 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: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:93:28:93:40 | ... call to -(_:_:) ... | StringLengthConflation.swift:93:28:93:31 | .length : | StringLengthConflation.swift:93:28:93:40 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift index 60037ffd676..87985d6c8fe 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift @@ -50,7 +50,7 @@ func test(s: String) { // --- constructing a String.Index from integer --- let ix1 = String.Index(encodedOffset: s.count) // GOOD - let ix2 = String.Index(encodedOffset: ns.length) // BAD: NSString length used in String.Index [NOT DETECTED] + let ix2 = String.Index(encodedOffset: ns.length) // BAD: NSString length used in String.Index let ix3 = String.Index(encodedOffset: s.utf8.count) // BAD: String.utf8 length used in String.Index [NOT DETECTED] let ix4 = String.Index(encodedOffset: s.utf16.count) // BAD: String.utf16 length used in String.Index [NOT DETECTED] let ix5 = String.Index(encodedOffset: s.unicodeScalars.count) // BAD: string.unicodeScalars length used in String.Index [NOT DETECTED] From 34ffd1aac58267468ac10ffdb22f0a7f8502fead Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 1 Jul 2022 13:43:37 +0100 Subject: [PATCH 249/465] Swift: Support String.Index and flow through * /. --- .../Security/CWE-135/StringLengthConflation.ql | 17 ++++++++++++----- .../CWE-135/StringLengthConflation.expected | 8 ++++++++ .../CWE-135/StringLengthConflation.swift | 4 ++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 38485aa119d..59146dfba7a 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -95,17 +95,25 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { // arguments to function calls... exists(string funcName, string paramName, CallExpr call, int arg | ( - // `dropFirst`, `dropLast`, `removeFirst`, `removeLast` + // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and paramName = "k" or - // `prefix`, `suffix` + // `String.prefix`, `String.suffix` funcName = ["prefix(_:)", "suffix(_:)"] and paramName = "maxLength" or // `String.Index.init` funcName = "init(encodedOffset:)" and paramName = "offset" + or + // `String.index` + funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and + paramName = "n" + or + // `String.formIndex` + funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and + paramName = "distance" ) and call.getFunction().(ApplyExpr).getStaticTarget().getName() = funcName and call.getFunction() @@ -119,9 +127,8 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { } override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { - // allow flow through `+` and `-`. - node2.asExpr().(AddExpr).getAnOperand() = node1.asExpr() or - node2.asExpr().(SubExpr).getAnOperand() = node1.asExpr() + // allow flow through `+`, `-`, `*` etc. + node2.asExpr().(ArithmeticOperation).getAnOperand() = node1.asExpr() } } diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index 411a938ba0e..1af416dad2f 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -1,4 +1,6 @@ edges +| StringLengthConflation.swift:60:47:60:50 | .length : | StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | +| StringLengthConflation.swift:66:33:66:36 | .length : | StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | | StringLengthConflation.swift:93:28:93:31 | .length : | StringLengthConflation.swift:93:28:93:40 | ... call to -(_:_:) ... | | StringLengthConflation.swift:97:27:97:30 | .length : | StringLengthConflation.swift:97:27:97:39 | ... call to -(_:_:) ... | | StringLengthConflation.swift:101:25:101:28 | .length : | StringLengthConflation.swift:101:25:101:37 | ... call to -(_:_:) ... | @@ -14,6 +16,10 @@ edges | StringLengthConflation.swift:141:28:141:30 | .count : | StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | nodes | StringLengthConflation.swift:53:43:53:46 | .length | semmle.label | .length | +| StringLengthConflation.swift:60:47:60:50 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | semmle.label | ... call to /(_:_:) ... | +| StringLengthConflation.swift:66:33:66:36 | .length : | semmle.label | .length : | +| StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | semmle.label | ... call to /(_:_:) ... | | StringLengthConflation.swift:72:33:72:35 | .count | semmle.label | .count | | StringLengthConflation.swift:78:47:78:49 | .count | semmle.label | .count | | StringLengthConflation.swift:93:28:93:31 | .length : | semmle.label | .length : | @@ -45,6 +51,8 @@ nodes subpaths #select | 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:60:47:60:59 | ... call to /(_:_:) ... | StringLengthConflation.swift:60:47:60:50 | .length : | StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | +| StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | StringLengthConflation.swift:66:33:66:36 | .length : | StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | 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:93:28:93:40 | ... call to -(_:_:) ... | StringLengthConflation.swift:93:28:93:31 | .length : | StringLengthConflation.swift:93:28:93:40 | ... call to -(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift index 87985d6c8fe..527cacd772b 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.swift @@ -57,13 +57,13 @@ func test(s: String) { print("String.Index '\(ix1.encodedOffset)' / '\(ix2.encodedOffset)' '\(ix3.encodedOffset)' '\(ix4.encodedOffset)' '\(ix5.encodedOffset)'") let ix6 = s.index(s.startIndex, offsetBy: s.count / 2) // GOOD - let ix7 = s.index(s.startIndex, offsetBy: ns.length / 2) // BAD: NSString length used in String.Index [NOT DETECTED] + let ix7 = s.index(s.startIndex, offsetBy: ns.length / 2) // BAD: NSString length used in String.Index print("index '\(ix6.encodedOffset)' / '\(ix7.encodedOffset)'") var ix8 = s.startIndex s.formIndex(&ix8, offsetBy: s.count / 2) // GOOD var ix9 = s.startIndex - s.formIndex(&ix9, offsetBy: ns.length / 2) // BAD: NSString length used in String.Index [NOT DETECTED] + s.formIndex(&ix9, offsetBy: ns.length / 2) // BAD: NSString length used in String.Index print("formIndex '\(ix8.encodedOffset)' / '\(ix9.encodedOffset)'") // --- constructing an NSRange from integers --- From e88cc314681ee626a8603a5d2c53321a26372cb3 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 1 Jul 2022 16:16:21 +0200 Subject: [PATCH 250/465] Swift: disable change note checking for now --- .github/workflows/check-change-note.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/check-change-note.yml b/.github/workflows/check-change-note.yml index 672202444bb..b60a590ab09 100644 --- a/.github/workflows/check-change-note.yml +++ b/.github/workflows/check-change-note.yml @@ -10,6 +10,7 @@ on: - "*/ql/lib/**/*.qll" - "!**/experimental/**" - "!ql/**" + - "!swift/**" - ".github/workflows/check-change-note.yml" jobs: From 2dca78295d5b3cd68387e8258fd32c69b5c8c418 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 1 Jul 2022 16:35:30 +0200 Subject: [PATCH 251/465] Fix change note check to accept changes to itself The file is not removed from the triggers, as we still want to check that the workflow file itself is correct. --- .github/workflows/check-change-note.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-change-note.yml b/.github/workflows/check-change-note.yml index b60a590ab09..8a450474e06 100644 --- a/.github/workflows/check-change-note.yml +++ b/.github/workflows/check-change-note.yml @@ -24,5 +24,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - gh api 'repos/${{github.repository}}/pulls/${{github.event.number}}/files' --paginate --jq 'any(.[].filename ; test("/change-notes/.*[.]md$"))' | + gh api 'repos/${{github.repository}}/pulls/${{github.event.number}}/files' --paginate --jq \ + 'any(.[].filename ; test("/change-notes/.*[.]md$")) or + all(.[].filename ; .==".github/workflows/check-change-note.yml")' | grep true -c From c393c9b03e9e747e0cc57979b8e56012fafd12fa Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 1 Jul 2022 16:41:09 +0200 Subject: [PATCH 252/465] Revert "Fix change note check to accept changes to itself" This reverts commit 2dca78295d5b3cd68387e8258fd32c69b5c8c418. --- .github/workflows/check-change-note.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/check-change-note.yml b/.github/workflows/check-change-note.yml index 8a450474e06..b60a590ab09 100644 --- a/.github/workflows/check-change-note.yml +++ b/.github/workflows/check-change-note.yml @@ -24,7 +24,5 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - gh api 'repos/${{github.repository}}/pulls/${{github.event.number}}/files' --paginate --jq \ - 'any(.[].filename ; test("/change-notes/.*[.]md$")) or - all(.[].filename ; .==".github/workflows/check-change-note.yml")' | + gh api 'repos/${{github.repository}}/pulls/${{github.event.number}}/files' --paginate --jq 'any(.[].filename ; test("/change-notes/.*[.]md$"))' | grep true -c From b499ba5aa8b97478b12041fe1882ec7fc3c5d6c4 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Fri, 1 Jul 2022 15:35:32 +0100 Subject: [PATCH 253/465] Kotlin: don't extract private setters of external classes Previously these would get extracted unlike other private methods even if the class was a standard library or other external class. This could cause inconsistencies because if we also compiled the class from source we could end up deciding different names for the property's setter: setXyz$private when seen from source, and setXyz without a suffix when seen as an external .class file. Avoiding extracting these functions from the external perspective both restores consistency with other kinds of method and avoids these consistency problems. --- .../src/main/kotlin/KotlinFileExtractor.kt | 26 +++++++++---------- .../private_property_accessors/hasprops.kt | 9 +++++++ .../private_property_accessors/test.expected | 7 +++++ .../kotlin/private_property_accessors/test.py | 3 +++ .../kotlin/private_property_accessors/test.ql | 5 ++++ .../private_property_accessors/usesprops.kt | 9 +++++++ 6 files changed, 46 insertions(+), 13 deletions(-) create mode 100644 java/ql/integration-tests/posix-only/kotlin/private_property_accessors/hasprops.kt create mode 100644 java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.expected create mode 100644 java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.py create mode 100644 java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.ql create mode 100644 java/ql/integration-tests/posix-only/kotlin/private_property_accessors/usesprops.kt diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 21b35fbcdd1..9bdf40fdca0 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -134,7 +134,7 @@ open class KotlinFileExtractor( is IrProperty -> { val parentId = useDeclarationParent(declaration.parent, false)?.cast() if (parentId != null) { - extractProperty(declaration, parentId, extractBackingField = true, extractFunctionBodies = extractFunctionBodies, null, listOf()) + extractProperty(declaration, parentId, extractBackingField = true, extractFunctionBodies = extractFunctionBodies, extractPrivateMembers = extractPrivateMembers, null, listOf()) } Unit } @@ -364,7 +364,7 @@ open class KotlinFileExtractor( if (shouldExtractDecl(it, false)) { when(it) { is IrFunction -> extractFunction(it, id, extractBody = false, extractMethodAndParameterTypeAccesses = false, typeParamSubstitution, argsIncludingOuterClasses) - is IrProperty -> extractProperty(it, id, extractBackingField = false, extractFunctionBodies = false, typeParamSubstitution, argsIncludingOuterClasses) + is IrProperty -> extractProperty(it, id, extractBackingField = false, extractFunctionBodies = false, extractPrivateMembers = false, typeParamSubstitution, argsIncludingOuterClasses) else -> {} } } @@ -955,7 +955,7 @@ open class KotlinFileExtractor( return id } - private fun extractProperty(p: IrProperty, parentId: Label, extractBackingField: Boolean, extractFunctionBodies: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) { + private fun extractProperty(p: IrProperty, parentId: Label, extractBackingField: Boolean, extractFunctionBodies: Boolean, extractPrivateMembers: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List?) { with("property", p) { if (isFake(p)) return @@ -970,7 +970,11 @@ open class KotlinFileExtractor( val getter = p.getter val setter = p.setter - if (getter != null) { + if (getter == null) { + if (p.modality != Modality.FINAL || !isExternalDeclaration(p)) { + logger.warnElement("IrProperty without a getter", p) + } + } else if (shouldExtractDecl(getter, extractPrivateMembers)) { val getterId = extractFunction(getter, parentId, extractBody = extractFunctionBodies, extractMethodAndParameterTypeAccesses = extractFunctionBodies, typeSubstitution, classTypeArgsIncludingOuterClasses)?.cast() if (getterId != null) { tw.writeKtPropertyGetters(id, getterId) @@ -978,13 +982,13 @@ open class KotlinFileExtractor( tw.writeCompiler_generated(getterId, CompilerGeneratedKinds.DELEGATED_PROPERTY_GETTER.kind) } } - } else { - if (p.modality != Modality.FINAL || !isExternalDeclaration(p)) { - logger.warnElement("IrProperty without a getter", p) - } } - if (setter != null) { + if (setter == null) { + if (p.isVar && !isExternalDeclaration(p)) { + logger.warnElement("isVar property without a setter", p) + } + } else if (shouldExtractDecl(setter, extractPrivateMembers)) { if (!p.isVar) { logger.warnElement("!isVar property with a setter", p) } @@ -995,10 +999,6 @@ open class KotlinFileExtractor( tw.writeCompiler_generated(setterId, CompilerGeneratedKinds.DELEGATED_PROPERTY_SETTER.kind) } } - } else { - if (p.isVar && !isExternalDeclaration(p)) { - logger.warnElement("isVar property without a setter", p) - } } if (bf != null && extractBackingField) { diff --git a/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/hasprops.kt b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/hasprops.kt new file mode 100644 index 00000000000..ff83b18a31a --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/hasprops.kt @@ -0,0 +1,9 @@ +class HasProps { + + var accessorsPublic = 1 + + var setterPrivate = 3 + private set + +} + diff --git a/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.expected b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.expected new file mode 100644 index 00000000000..c497684b152 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.expected @@ -0,0 +1,7 @@ +| hasprops.kt:3:3:3:25 | getAccessorsPublic | +| hasprops.kt:3:3:3:25 | setAccessorsPublic | +| hasprops.kt:5:3:6:15 | getSetterPrivate | +| hasprops.kt:6:13:6:15 | setSetterPrivate$private | +| usesprops.kt:1:1:9:1 | user | +| usesprops.kt:3:3:3:58 | useGetters | +| usesprops.kt:5:3:7:3 | useSetter | diff --git a/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.py b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.py new file mode 100644 index 00000000000..5599f459849 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.py @@ -0,0 +1,3 @@ +from create_database_utils import * + +run_codeql_database_create(["kotlinc hasprops.kt", "kotlinc usesprops.kt -cp ."], lang="java") diff --git a/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.ql b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.ql new file mode 100644 index 00000000000..f1355df2e88 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/test.ql @@ -0,0 +1,5 @@ +import java + +from Method m +where m.fromSource() +select m diff --git a/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/usesprops.kt b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/usesprops.kt new file mode 100644 index 00000000000..5157865df17 --- /dev/null +++ b/java/ql/integration-tests/posix-only/kotlin/private_property_accessors/usesprops.kt @@ -0,0 +1,9 @@ +fun user(hp: HasProps) { + + fun useGetters() = hp.accessorsPublic + hp.setterPrivate + + fun useSetter(x: Int) { + hp.accessorsPublic = x + } + +} From 1730ec22d92cd1dfd0bcf57590c85240cdd341af Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Thu, 30 Jun 2022 15:34:45 +0100 Subject: [PATCH 254/465] Kotlin: Extract an ErrorType if we fail to correctly extract a type --- .../src/main/kotlin/KotlinUsesExtractor.kt | 18 +++++++++++++++--- java/ql/lib/config/semmlecode.dbscheme | 12 ++++++++++-- java/ql/lib/semmle/code/Location.qll | 2 ++ java/ql/lib/semmle/code/java/Type.qll | 8 ++++++++ 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt index 530ff47e8ab..bf3056b079b 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt @@ -108,14 +108,26 @@ open class KotlinUsesExtractor( } data class TypeResults(val javaResult: TypeResult, val kotlinResult: TypeResult) - fun useType(t: IrType, context: TypeContext = TypeContext.OTHER) = + fun useType(t: IrType, context: TypeContext = TypeContext.OTHER): TypeResults { when(t) { - is IrSimpleType -> useSimpleType(t, context) + is IrSimpleType -> return useSimpleType(t, context) else -> { logger.error("Unrecognised IrType: " + t.javaClass) - TypeResults(TypeResult(fakeLabel(), "unknown", "unknown"), TypeResult(fakeLabel(), "unknown", "unknown")) + return extractErrorType() } } + } + + private fun extractErrorType(): TypeResults { + val typeId = tw.getLabelFor("@\"errorType\"") { + tw.writeError_type(it) + } + val kotlinTypeId = tw.getLabelFor("@\"errorKotlinType\"") { + tw.writeKt_nullable_types(it, typeId) + } + return TypeResults(TypeResult(typeId, null, ""), + TypeResult(kotlinTypeId, null, "")) + } fun getJavaEquivalentClass(c: IrClass) = getJavaEquivalentClassId(c)?.let { pluginContext.referenceClass(it.asSingleFqName()) }?.owner diff --git a/java/ql/lib/config/semmlecode.dbscheme b/java/ql/lib/config/semmlecode.dbscheme index cf58c7d9b1f..81ccfabe82e 100755 --- a/java/ql/lib/config/semmlecode.dbscheme +++ b/java/ql/lib/config/semmlecode.dbscheme @@ -332,6 +332,14 @@ modifiers( string nodeName: string ref ); +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + classes( unique int id: @class, string nodeName: string ref, @@ -1012,13 +1020,13 @@ javadocText( @classorinterfaceorpackage = @classorinterface | @package; @classorinterfaceorcallable = @classorinterface | @callable; @boundedtype = @typevariable | @wildcard; -@reftype = @classorinterface | @array | @boundedtype; +@reftype = @classorinterface | @array | @boundedtype | @errortype; @classorarray = @class | @array; @type = @primitive | @reftype; @callable = @method | @constructor; /** A program element that has a name. */ -@element = @package | @modifier | @annotation | +@element = @package | @modifier | @annotation | @errortype | @locatableElement; @locatableElement = @file | @primitive | @class | @interface | @method | @constructor | @param | @exception | @field | diff --git a/java/ql/lib/semmle/code/Location.qll b/java/ql/lib/semmle/code/Location.qll index d977395a83c..8bb81becb11 100755 --- a/java/ql/lib/semmle/code/Location.qll +++ b/java/ql/lib/semmle/code/Location.qll @@ -47,6 +47,8 @@ predicate hasName(Element e, string name) { kt_type_alias(e, name, _) or ktProperties(e, name) + or + e instanceof ErrorType and name = "" } /** diff --git a/java/ql/lib/semmle/code/java/Type.qll b/java/ql/lib/semmle/code/java/Type.qll index a37f9810c44..2193720c8fe 100755 --- a/java/ql/lib/semmle/code/java/Type.qll +++ b/java/ql/lib/semmle/code/java/Type.qll @@ -666,6 +666,14 @@ class RefType extends Type, Annotatable, Modifiable, @reftype { } } +/** + * An `ErrorType` is generated when CodeQL is unable to correctly + * extract a type. + */ +class ErrorType extends RefType, @errortype { + override string getAPrimaryQlClass() { result = "ErrorType" } +} + /** A type that is the same as its source declaration. */ class SrcRefType extends RefType { SrcRefType() { this.isSourceDeclaration() } From e38254c05e1f32916e55c0e3e48aebf9a70ffc02 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 1 Jul 2022 17:00:36 +0100 Subject: [PATCH 255/465] Swift: Fix typo. --- .../ql/src/queries/Security/CWE-135/StringLengthConflation.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 59146dfba7a..398c48f01e5 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -23,7 +23,7 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { StringLengthConflationConfiguration() { this = "StringLengthConflationConfiguration" } override predicate isSource(DataFlow::Node node, string flowstate) { - // result of a call to to `String.count` + // result of a call to `String.count` exists(MemberRefExpr member | member.getBaseExpr().getType().getName() = "String" and member.getMember().(VarDecl).getName() = "count" and @@ -31,7 +31,7 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { flowstate = "String" ) or - // result of a call to to `NSString.length` + // result of a call to `NSString.length` exists(MemberRefExpr member | member.getBaseExpr().getType().getName() = ["NSString", "NSMutableString"] and member.getMember().(VarDecl).getName() = "length" and From e43e5810cfcff8e2d333473a43604d7b2d997396 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Fri, 1 Jul 2022 17:08:35 -0700 Subject: [PATCH 256/465] New queries to detect unsafe client side encryption in Azure Storage --- ...nsafeUsageOfClientSideEncryptionVersion.cs | 33 ++++++++ ...feUsageOfClientSideEncryptionVersion.qhelp | 31 ++++++++ ...nsafeUsageOfClientSideEncryptionVersion.ql | 75 +++++++++++++++++++ ...afeUsageOfClientSideEncryptionVersion.java | 46 ++++++++++++ ...feUsageOfClientSideEncryptionVersion.qhelp | 31 ++++++++ ...nsafeUsageOfClientSideEncryptionVersion.ql | 71 ++++++++++++++++++ ...nsafeUsageOfClientSideEncryptionVersion.py | 7 ++ ...feUsageOfClientSideEncryptionVersion.qhelp | 31 ++++++++ ...nsafeUsageOfClientSideEncryptionVersion.ql | 55 ++++++++++++++ 9 files changed, 380 insertions(+) create mode 100644 csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs create mode 100644 csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp create mode 100644 csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql create mode 100644 java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.java create mode 100644 java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp create mode 100644 java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql create mode 100644 python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py create mode 100644 python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp create mode 100644 python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs new file mode 100644 index 00000000000..39928d9e2c7 --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs @@ -0,0 +1,33 @@ + +var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions() +{ + // BAD: Using an outdated SDK that does not support client side encryption version V2_0 + ClientSideEncryption = new ClientSideEncryptionOptions() + { + KeyEncryptionKey = myKey, + KeyResolver = myKeyResolver, + KeyWrapAlgorihm = myKeyWrapAlgorithm + } +}); + +var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions() +{ + // BAD: Using the outdated client side encryption version V1_0 + ClientSideEncryption = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V1_0) + { + KeyEncryptionKey = myKey, + KeyResolver = myKeyResolver, + KeyWrapAlgorihm = myKeyWrapAlgorithm + } +}); + +var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions() +{ + // GOOD: Using client side encryption version V2_0 + ClientSideEncryption = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V2_0) + { + KeyEncryptionKey = myKey, + KeyResolver = myKeyResolver, + KeyWrapAlgorihm = myKeyWrapAlgorithm + } +}); \ No newline at end of file diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp new file mode 100644 index 00000000000..3bf46ab9f89 --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -0,0 +1,31 @@ + + + + + +

    Azure Storage .NET, Java, and Python SDKs support encryption on the client with a customer-managed key that is maintained in Azure Key Vault or another key store.

    +

    Current release versions of the Azure Storage SDKs use cipher block chaining (CBC mode) for client-side encryption (referred to as v1).

    + +
    + + +

    Consider switching to v1 client-side encryption.

    + +
    + + +

    The following example shows an HTTP request parameter being used directly in a forming a +new request without validating the input, which facilitates SSRF attacks. +It also shows how to remedy the problem by validating the user input against a known fixed string. +

    + + + +
    + +
  • + Azure Storage Client Encryption Blog. +
  • + +
    +
    diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql new file mode 100644 index 00000000000..cb986754958 --- /dev/null +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -0,0 +1,75 @@ +/** + * @name Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). + * @description Unsafe usage of v1 version of Azure Storage client-side encryption, please refer to http://aka.ms/azstorageclientencryptionblog + * @kind problem + * @tags security + * cryptography + * external/cwe/cwe-327 + * @id cs/azure-storage/unsafe-usage-of-client-side-encryption-version + * @problem.severity error + * @precision high + */ + +import csharp + +/** + * Holds if `oc` is creating an object of type `c` = `Azure.Storage.ClientSideEncryptionOptions` + * and `e` is the `version` argument to the contructor + */ +predicate isCreatingAzureClientSideEncryptionObject(ObjectCreation oc, Class c, Expr e) { + exists(Parameter p | p.hasName("version") | + c.getQualifiedName() in ["Azure.Storage.ClientSideEncryptionOptions"] and + oc.getTarget() = c.getAConstructor() and + e = oc.getArgumentForParameter(p) + ) +} + +/** + * Holds if `oc` is an object creation of the outdated type `c` = `Microsoft.Azure.Storage.Blob.BlobEncryptionPolicy` + */ +predicate isCreatingOutdatedAzureClientSideEncryptionObject(ObjectCreation oc, Class c) { + c.getQualifiedName() in ["Microsoft.Azure.Storage.Blob.BlobEncryptionPolicy"] and + oc.getTarget() = c.getAConstructor() +} + +/** + * Holds if the Azure.Storage assembly for `c` is a version knwon to support + * version 2+ for client-side encryption and if the argument for the constructor `version` + * is set to a secure value. + */ +predicate isObjectCreationSafe(Class c, Expr versionExpr, Assembly asm) { + // Check if the Azure.Storage assembly version has the fix + exists(int versionCompare | + versionCompare = asm.getVersion().compareTo("12.12.0.0") and + versionCompare >= 0 + ) and + // and that the version argument for the constructor is guaranteed to be Version2 + isExprAnAccessToSafeClientSideEncryptionVersionValue(versionExpr) +} + +/** + * Holds if the expression `e` is an access to a safe version of the enum `ClientSideEncryptionVersion` + * or an equivalent numeric value + */ +predicate isExprAnAccessToSafeClientSideEncryptionVersionValue(Expr e) { + exists(EnumConstant ec | + ec.hasQualifiedName("Azure.Storage.ClientSideEncryptionVersion.V2_0") and + ec.getAnAccess() = e + ) + or + e.getValue().toInt() >= 2 +} + +from Expr e, Class c, Assembly asm +where + asm = c.getLocation() and + ( + exists(Expr e2 | + isCreatingAzureClientSideEncryptionObject(e, c, e2) and + not isObjectCreationSafe(c, e2, asm) + ) + or + isCreatingOutdatedAzureClientSideEncryptionObject(e, c) + ) +select e, + "Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). See http://aka.ms/azstorageclientencryptionblog" diff --git a/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.java b/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.java new file mode 100644 index 00000000000..83157c14251 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.java @@ -0,0 +1,46 @@ + +// BAD: Using an outdated SDK that does not support client side encryption version V2_0 +new EncryptedBlobClientBuilder() + .blobClient(blobClient) + .key(resolver.buildAsyncKeyEncryptionKey(keyid).block(), keyWrapAlgorithm) + .buildEncryptedBlobClient() + .uploadWithResponse(new BlobParallelUploadOptions(data) + .setMetadata(metadata) + .setHeaders(headers) + .setTags(tags) + .setTier(tier) + .setRequestConditions(requestConditions) + .setComputeMd5(computeMd5) + .setParallelTransferOptions(parallelTransferOptions), + timeout, context); + +// BAD: Using the deprecatedd client side encryption version V1_0 +new EncryptedBlobClientBuilder(EncryptionVersion.V1) + .blobClient(blobClient) + .key(resolver.buildAsyncKeyEncryptionKey(keyid).block(), keyWrapAlgorithm) + .buildEncryptedBlobClient() + .uploadWithResponse(new BlobParallelUploadOptions(data) + .setMetadata(metadata) + .setHeaders(headers) + .setTags(tags) + .setTier(tier) + .setRequestConditions(requestConditions) + .setComputeMd5(computeMd5) + .setParallelTransferOptions(parallelTransferOptions), + timeout, context); + + +// GOOD: Using client side encryption version V2_0 +new EncryptedBlobClientBuilder(EncryptionVersion.V2) + .blobClient(blobClient) + .key(resolver.buildAsyncKeyEncryptionKey(keyid).block(), keyWrapAlgorithm) + .buildEncryptedBlobClient() + .uploadWithResponse(new BlobParallelUploadOptions(data) + .setMetadata(metadata) + .setHeaders(headers) + .setTags(tags) + .setTier(tier) + .setRequestConditions(requestConditions) + .setComputeMd5(computeMd5) + .setParallelTransferOptions(parallelTransferOptions), + timeout, context); diff --git a/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp new file mode 100644 index 00000000000..ed05e5f3370 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -0,0 +1,31 @@ + + + + + +

    Azure Storage .NET, Java, and Python SDKs support encryption on the client with a customer-managed key that is maintained in Azure Key Vault or another key store.

    +

    Current release versions of the Azure Storage SDKs use cipher block chaining (CBC mode) for client-side encryption (referred to as v1).

    + +
    + + +

    Consider switching to v1 client-side encryption.

    + +
    + + +

    The following example shows an HTTP request parameter being used directly in a forming a +new request without validating the input, which facilitates SSRF attacks. +It also shows how to remedy the problem by validating the user input against a known fixed string. +

    + + + +
    + +
  • + Azure Storage Client Encryption Blog. +
  • + +
    +
    diff --git a/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql new file mode 100644 index 00000000000..7f1ec039d20 --- /dev/null +++ b/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -0,0 +1,71 @@ +/** + * @name Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). + * @description Unsafe usage of v1 version of Azure Storage client-side encryption, please refer to http://aka.ms/azstorageclientencryptionblog + * @kind problem + * @tags security + * cryptography + * external/cwe/cwe-327 + * @id java/azure-storage/unsafe-client-side-encryption-in-use + * @problem.severity error + * @precision high + */ + +import java + +/** + * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` + * that takes no arguments, which means that it is using V1 encryption + */ +predicate isCreatingOutdatedAzureClientSideEncryptionObject(Call call, Class c) { + exists(string package, string type, Constructor constructor | + c.hasQualifiedName(package, type) and + c.getAConstructor() = constructor and + call.getCallee() = constructor and + ( + type = "EncryptedBlobClientBuilder" and + package = "com.azure.storage.blob.specialized.cryptography" and + not exists(Expr e | e = call.getArgument(0)) + or + type = "BlobEncryptionPolicy" and package = "com.microsoft.azure.storage.blob" + ) + ) +} + +/** + * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` + * that takes `versionArg` as the argument for the version. + */ +predicate isCreatingAzureClientSideEncryptionObjectNewVersion(Call call, Class c, Expr versionArg) { + exists(string package, string type, Constructor constructor | + c.hasQualifiedName(package, type) and + c.getAConstructor() = constructor and + call.getCallee() = constructor and + type = "EncryptedBlobClientBuilder" and + package = "com.azure.storage.blob.specialized.cryptography" and + versionArg = call.getArgument(0) + ) +} + +/** + * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` + * that takes `versionArg` as the argument for the version, and the version number is safe + */ +predicate isCreatingSafeAzureClientSideEncryptionObject(Call call, Class c, Expr versionArg) { + isCreatingAzureClientSideEncryptionObjectNewVersion(call, c, versionArg) and + exists(FieldRead fr, Field f | + fr = versionArg and + f.getAnAccess() = fr and + f.hasQualifiedName("com.azure.storage.blob.specialized.cryptography", "EncryptionVersion", "V2") + ) +} + +from Expr e, Class c +where + exists(Expr argVersion | + isCreatingAzureClientSideEncryptionObjectNewVersion(e, c, argVersion) and + not isCreatingSafeAzureClientSideEncryptionObject(e, c, argVersion) + ) + or + isCreatingOutdatedAzureClientSideEncryptionObject(e, c) +select e, + "Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). See http://aka.ms/azstorageclientencryptionblog" diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py new file mode 100644 index 00000000000..c4a0519f29d --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py @@ -0,0 +1,7 @@ +blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name) + blob_client.require_encryption = True + blob_client.key_encryption_key = kek + # GOOD: Must use `encryption_version` set to `2.0` + blob_client.encryption_version = '2.0' # Use Version 2.0! + with open(“decryptedcontentfile.txt”, “rb”) as stream: + blob_client.upload_blob(stream, overwrite=OVERWRITE_EXISTING) \ No newline at end of file diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp new file mode 100644 index 00000000000..9571e1150ef --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -0,0 +1,31 @@ + + + + + +

    Azure Storage .NET, Java, and Python SDKs support encryption on the client with a customer-managed key that is maintained in Azure Key Vault or another key store.

    +

    Current release versions of the Azure Storage SDKs use cipher block chaining (CBC mode) for client-side encryption (referred to as v1).

    + +
    + + +

    Consider switching to v1 client-side encryption.

    + +
    + + +

    The following example shows an HTTP request parameter being used directly in a forming a +new request without validating the input, which facilitates SSRF attacks. +It also shows how to remedy the problem by validating the user input against a known fixed string. +

    + + + +
    + +
  • + Azure Storage Client Encryption Blog. +
  • + +
    +
    diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql new file mode 100644 index 00000000000..8db450a5ecb --- /dev/null +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -0,0 +1,55 @@ +/** + * @name Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). + * @description Unsafe usage of v1 version of Azure Storage client-side encryption, please refer to http://aka.ms/azstorageclientencryptionblog + * @kind problem + * @tags security + * cryptography + * external/cwe/cwe-327 + * @id python/azure-storage/unsafe-client-side-encryption-in-use + * @problem.severity error + * @precision medium + */ + +import python + +predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrNode node) { + exists(ControlFlowNode ctrlFlowNode, AssignStmt astmt, Attribute a | + astmt.getATarget() = a and + a.getAttr() in ["key_encryption_key", "key_resolver_function"] and + a.getAFlowNode() = node and + node.strictlyReaches(ctrlFlowNode) and + node != ctrlFlowNode and + call.getAChildNode().(Attribute).getAttr() = "upload_blob" and + ctrlFlowNode = call.getAFlowNode() and + not astmt.getValue() instanceof None and + not exists(AssignStmt astmt2, Attribute a2, AttrNode encryptionVersionSet, StrConst uc | + uc = astmt2.getValue() and + uc.getLiteralValue().toString() in ["'2.0'", "2.0"] and + a2.getAttr() = "encryption_version" and + a2.getAFlowNode() = encryptionVersionSet and + encryptionVersionSet.strictlyReaches(ctrlFlowNode) + ) + ) +} + +predicate isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(Call call, ControlFlowNode node) { + exists(Keyword k | k.getAFlowNode() = node | + call.getFunc().(Name).getId().toString() in [ + "ContainerClient", "BlobClient", "BlobServiceClient" + ] and + k.getArg() = "key_encryption_key" and + k = call.getANamedArg() and + not k.getValue() instanceof None and + not exists(Keyword k2 | k2 = call.getANamedArg() | + k2.getArg() = "encryption_version" and + k2.getValue().(StrConst).getLiteralValue().toString() in ["'2.0'", "2.0"] + ) + ) +} + +from Call call, ControlFlowNode node +where + isUnsafeClientSideAzureStorageEncryptionViaAttributes(call, node) or + isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(call, node) +select node, + "Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). See http://aka.ms/azstorageclientencryptionblog" From 56060e06107d60feee0c83b59e8de159e76632bc Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Tue, 5 Jul 2022 13:57:28 -0700 Subject: [PATCH 257/465] Update csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp Co-authored-by: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com> --- .../Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp index 3bf46ab9f89..49aa5623570 100644 --- a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -9,7 +9,7 @@ -

    Consider switching to v1 client-side encryption.

    +

    Consider switching to v2 client-side encryption.

    From f5c6b45014aedac11b614b65fe7bcb59dfe519c9 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Tue, 5 Jul 2022 13:58:11 -0700 Subject: [PATCH 258/465] Update UnsafeUsageOfClientSideEncryptionVersion.qhelp --- .../Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp index ed05e5f3370..3fca30a7926 100644 --- a/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp +++ b/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -9,7 +9,7 @@ -

    Consider switching to v1 client-side encryption.

    +

    Consider switching to v2 client-side encryption.

    From dd1a9a22e3027836f2be9524ebac4cd8fe2f320a Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Tue, 5 Jul 2022 13:58:38 -0700 Subject: [PATCH 259/465] Update UnsafeUsageOfClientSideEncryptionVersion.qhelp --- .../Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp index 9571e1150ef..c4111a166de 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -9,7 +9,7 @@ -

    Consider switching to v1 client-side encryption.

    +

    Consider switching to v2 client-side encryption.

    From 74ff579dbc0bbea1d9353382a17ebac3337e208a Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Wed, 6 Jul 2022 15:19:36 -0400 Subject: [PATCH 260/465] Fixing logic bug with LogicalAndExpr --- cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll index 40c975873b4..fac6a57f8cf 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll @@ -46,7 +46,7 @@ predicate nullCheckExpr(Expr checkExpr, Variable var) { or exists(LogicalAndExpr op, AnalysedExpr child | expr = op and - op.getRightOperand() = child and + (op.getRightOperand() = child or op.getLeftOperand() = child) and nullCheckExpr(child, v) ) or @@ -99,7 +99,7 @@ predicate validCheckExpr(Expr checkExpr, Variable var) { or exists(LogicalAndExpr op, AnalysedExpr child | expr = op and - op.getRightOperand() = child and + (op.getRightOperand() = child or op.getLeftOperand() = child) and validCheckExpr(child, v) ) or From 7d6fb7f91a2deaab8855a8b2060d866d97029631 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 6 Jul 2022 21:52:13 +0200 Subject: [PATCH 261/465] C++: Rename LossyFunctionResultCast tests to be correctly named --- ...castFromBitfield.expected => LossyFunctionResultCast.expected} | 0 ...itDowncastFromBitfield.qlref => LossyFunctionResultCast.qlref} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/{ImplicitDowncastFromBitfield.expected => LossyFunctionResultCast.expected} (100%) rename cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/{ImplicitDowncastFromBitfield.qlref => LossyFunctionResultCast.qlref} (100%) diff --git a/cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/ImplicitDowncastFromBitfield.expected b/cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/LossyFunctionResultCast.expected similarity index 100% rename from cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/ImplicitDowncastFromBitfield.expected rename to cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/LossyFunctionResultCast.expected diff --git a/cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/ImplicitDowncastFromBitfield.qlref b/cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/LossyFunctionResultCast.qlref similarity index 100% rename from cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/ImplicitDowncastFromBitfield.qlref rename to cpp/ql/test/query-tests/Likely Bugs/Conversion/LossyFunctionResultCast/LossyFunctionResultCast.qlref From 0b471c2007e66938250bea985afeb8f6851660e8 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 6 Jul 2022 21:53:12 +0200 Subject: [PATCH 262/465] C++: Improve LossyFunctionResultCast join order Before on wireshark: ``` Tuple counts for #select#ff@eca61bf2: 180100 ~2% {2} r1 = SCAN Type::Type::getUnderlyingType#dispred#f0820431#ff OUTPUT In.1, In.0 84 ~2% {2} r2 = JOIN r1 WITH project#Type::FloatingPointType#class#2e8eb3ef#fffff ON FIRST 1 OUTPUT Lhs.1, Rhs.0 2021 ~0% {2} r3 = JOIN r2 WITH Function::Function::getType#dispred#f0820431#fb_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1 2437 ~0% {2} r4 = JOIN r3 WITH Call::FunctionCall::getTarget#dispred#f0820431#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1, Rhs.1 2150 ~0% {2} r5 = r4 AND NOT LossyFunctionResultCast::whiteListWrapped#377b528a#f(Lhs.1) 2150 ~0% {2} r6 = SCAN r5 OUTPUT In.1, In.0 313 ~0% {3} r7 = JOIN r6 WITH exprconv ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.0 313 ~0% {3} r8 = JOIN r7 WITH Cast::Conversion#class#1f33e835#b ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2 148 ~3% {2} r9 = JOIN r8 WITH Expr::Expr::isCompilerGenerated#f0820431#b ON FIRST 1 OUTPUT Lhs.2, Lhs.1 148 ~1% {3} r10 = JOIN r9 WITH Expr::Expr::getActualType#dispred#f0820431#bf ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.0 21 ~0% {3} r11 = JOIN r10 WITH Type::IntegralType#class#2e8eb3ef#ff ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.0 21 ~0% {3} r12 = JOIN r11 WITH Element::ElementBase::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Rhs.1 21 ~0% {2} r13 = JOIN r12 WITH Element::ElementBase::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.1, ("Return value of type " ++ Lhs.2 ++ " is implicitly converted to " ++ Rhs.1 ++ " here.") return r13 ``` After: ``` Tuple counts for #select#ff@a5a185eg: 20 ~0% {2} r1 = SCAN project#Type::FloatingPointType#class#2e8eb3ef#fffff OUTPUT In.0, In.0 20 ~0% {2} r2 = JOIN r1 WITH project#Type::FloatingPointType#class#2e8eb3ef#fffff ON FIRST 1 OUTPUT Lhs.1, Lhs.0 84 ~2% {2} r3 = JOIN r2 WITH Type::Type::getUnderlyingType#dispred#f0820431#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1 2021 ~0% {2} r4 = JOIN r3 WITH Function::Function::getType#dispred#f0820431#fb_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1 2437 ~0% {2} r5 = JOIN r4 WITH Call::FunctionCall::getTarget#dispred#f0820431#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.1, Rhs.1 2150 ~0% {2} r6 = r5 AND NOT LossyFunctionResultCast::whiteListWrapped#377b528a#f(Lhs.1) 2150 ~0% {2} r7 = SCAN r6 OUTPUT In.1, In.0 313 ~0% {3} r8 = JOIN r7 WITH exprconv ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.0 313 ~0% {3} r9 = JOIN r8 WITH Cast::Conversion#class#1f33e835#b ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2 148 ~3% {2} r10 = JOIN r9 WITH Expr::Expr::isCompilerGenerated#f0820431#b ON FIRST 1 OUTPUT Lhs.2, Lhs.1 148 ~1% {3} r11 = JOIN r10 WITH Expr::Expr::getActualType#dispred#f0820431#bf ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.0 21 ~0% {3} r12 = JOIN r11 WITH Type::IntegralType#class#2e8eb3ef#ff ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.0 21 ~0% {3} r13 = JOIN r12 WITH Element::ElementBase::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Rhs.1 21 ~0% {2} r14 = JOIN r13 WITH Element::ElementBase::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.1, ("Return value of type " ++ Lhs.2 ++ " is implicitly converted to " ++ Rhs.1 ++ " here.") return r14 ``` --- cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql b/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql index dee723e2686..3cbcffe0ce3 100644 --- a/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql +++ b/cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql @@ -44,7 +44,7 @@ predicate whiteListWrapped(FunctionCall fc) { from FunctionCall c, FloatingPointType t1, IntegralType t2 where - t1 = c.getTarget().getType().getUnderlyingType() and + pragma[only_bind_into](t1) = c.getTarget().getType().getUnderlyingType() and t2 = c.getActualType() and c.hasImplicitConversion() and not whiteListWrapped(c) From 01da877d0ebb101ba7ccf1c33c6cb113fb0d930b Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Wed, 6 Jul 2022 14:07:14 -0700 Subject: [PATCH 263/465] Moving the new query to experimental. It was added to the wrong folder initially. --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.java | 0 .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp | 0 .../CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename java/ql/src/{ => experimental}/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.java (100%) rename java/ql/src/{ => experimental}/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp (100%) rename java/ql/src/{ => experimental}/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql (100%) diff --git a/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.java b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.java similarity index 100% rename from java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.java rename to java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.java diff --git a/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp similarity index 100% rename from java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp rename to java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp diff --git a/java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql similarity index 100% rename from java/ql/src/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql rename to java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql From 4379aa4398f59d48cba6efdbcc75cc0afc1db68d Mon Sep 17 00:00:00 2001 From: "REDMOND\\brodes" Date: Thu, 7 Jul 2022 10:32:36 -0400 Subject: [PATCH 264/465] Adding Initializer in condition as an occurance of isDef --- cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll index fac6a57f8cf..92beb5c9d99 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll @@ -169,7 +169,10 @@ class AnalysedExpr extends Expr { */ predicate isDef(LocalScopeVariable v) { this.inCondition() and - this.(Assignment).getLValue() = v.getAnAccess() + ( + this.(Assignment).getLValue() = v.getAnAccess() or + exists(Initializer i | this.getEnclosingStmt() = i.getEnclosingStmt() and v = i.getDeclaration()) + ) } /** From f8994d04d652af02b888221feacb37763016aece Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Thu, 7 Jul 2022 11:49:05 -0700 Subject: [PATCH 265/465] Clean up --- .../Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index cb986754958..0de3d020e4f 100644 --- a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -18,7 +18,7 @@ import csharp */ predicate isCreatingAzureClientSideEncryptionObject(ObjectCreation oc, Class c, Expr e) { exists(Parameter p | p.hasName("version") | - c.getQualifiedName() in ["Azure.Storage.ClientSideEncryptionOptions"] and + c.hasQualifiedName("Azure.Storage.ClientSideEncryptionOptions") and oc.getTarget() = c.getAConstructor() and e = oc.getArgumentForParameter(p) ) @@ -28,7 +28,7 @@ predicate isCreatingAzureClientSideEncryptionObject(ObjectCreation oc, Class c, * Holds if `oc` is an object creation of the outdated type `c` = `Microsoft.Azure.Storage.Blob.BlobEncryptionPolicy` */ predicate isCreatingOutdatedAzureClientSideEncryptionObject(ObjectCreation oc, Class c) { - c.getQualifiedName() in ["Microsoft.Azure.Storage.Blob.BlobEncryptionPolicy"] and + c.hasQualifiedName("Microsoft.Azure.Storage.Blob.BlobEncryptionPolicy") and oc.getTarget() = c.getAConstructor() } @@ -37,7 +37,7 @@ predicate isCreatingOutdatedAzureClientSideEncryptionObject(ObjectCreation oc, C * version 2+ for client-side encryption and if the argument for the constructor `version` * is set to a secure value. */ -predicate isObjectCreationSafe(Class c, Expr versionExpr, Assembly asm) { +predicate isObjectCreationSafe(Expr versionExpr, Assembly asm) { // Check if the Azure.Storage assembly version has the fix exists(int versionCompare | versionCompare = asm.getVersion().compareTo("12.12.0.0") and @@ -66,7 +66,7 @@ where ( exists(Expr e2 | isCreatingAzureClientSideEncryptionObject(e, c, e2) and - not isObjectCreationSafe(c, e2, asm) + not isObjectCreationSafe(e2, asm) ) or isCreatingOutdatedAzureClientSideEncryptionObject(e, c) From 2f1cfa816fd7eefb3bab86dae9ed1344479b8607 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 7 Jul 2022 19:23:06 +0000 Subject: [PATCH 266/465] Add annotate arguments as sqli sink --- .../security/cwe-089/ActiveRecordInjection.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ruby/ql/test/query-tests/security/cwe-089/ActiveRecordInjection.rb b/ruby/ql/test/query-tests/security/cwe-089/ActiveRecordInjection.rb index 9c314a82b34..4c8dfcca10d 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/ActiveRecordInjection.rb +++ b/ruby/ql/test/query-tests/security/cwe-089/ActiveRecordInjection.rb @@ -137,3 +137,17 @@ class BazController < BarController Admin.delete_by(params[:admin_condition]) end end + +class AnnotatedController < ActionController::Base + def index + name = params[:user_name] + # GOOD: string literal arguments not controlled by user are safe for annotations + users = User.annotate("this is a safe annotation").find_by(user_name: name) + end + + def unsafe_action + name = params[:user_name] + # BAD: user input passed into annotations are vulnerable to SQLi + users = User.annotate("this is an unsafe annotation:#{params[:comment]}").find_by(user_name: name) + end +end From b4869158f2970dc462c78e2ebafcf90ea4b83f33 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 7 Jul 2022 19:23:57 +0000 Subject: [PATCH 267/465] expand query tests for cwe-089 --- ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll | 5 +++++ .../test/query-tests/security/cwe-089/SqlInjection.expected | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index cc63e64a083..b56304a657b 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -133,6 +133,11 @@ private Expr sqlFragmentArgument(MethodCall call) { or methodName = "reload" and result = call.getKeywordArgument("lock") + or + // Calls to `annotate` can be used to add block comments to SQL queries. These are potentially vulnerable to + // SQLi if user supplied input is passed in as an argument. + methodName = "annotate" and + result = call.getArgument(_) ) ) } diff --git a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected index 6a9f5f771fb..dc814977cae 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected @@ -31,6 +31,8 @@ edges | ActiveRecordInjection.rb:99:11:99:17 | ...[...] : | ActiveRecordInjection.rb:104:20:104:32 | ... + ... | | ActiveRecordInjection.rb:137:21:137:26 | call to params : | ActiveRecordInjection.rb:137:21:137:44 | ...[...] : | | ActiveRecordInjection.rb:137:21:137:44 | ...[...] : | ActiveRecordInjection.rb:20:22:20:30 | condition : | +| ActiveRecordInjection.rb:151:59:151:64 | call to params : | ActiveRecordInjection.rb:151:59:151:74 | ...[...] : | +| ActiveRecordInjection.rb:151:59:151:74 | ...[...] : | ActiveRecordInjection.rb:151:27:151:76 | "this is an unsafe annotation:..." | nodes | ActiveRecordInjection.rb:8:25:8:28 | name : | semmle.label | name : | | ActiveRecordInjection.rb:8:31:8:34 | pass : | semmle.label | pass : | @@ -80,6 +82,9 @@ nodes | ActiveRecordInjection.rb:104:20:104:32 | ... + ... | semmle.label | ... + ... | | ActiveRecordInjection.rb:137:21:137:26 | call to params : | semmle.label | call to params : | | ActiveRecordInjection.rb:137:21:137:44 | ...[...] : | semmle.label | ...[...] : | +| ActiveRecordInjection.rb:151:27:151:76 | "this is an unsafe annotation:..." | semmle.label | "this is an unsafe annotation:..." | +| ActiveRecordInjection.rb:151:59:151:64 | call to params : | semmle.label | call to params : | +| ActiveRecordInjection.rb:151:59:151:74 | ...[...] : | semmle.label | ...[...] : | subpaths #select | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | ActiveRecordInjection.rb:70:23:70:28 | call to params : | ActiveRecordInjection.rb:10:33:10:67 | "name='#{...}' and pass='#{...}'" | This SQL query depends on $@. | ActiveRecordInjection.rb:70:23:70:28 | call to params | a user-provided value | @@ -99,3 +104,4 @@ subpaths | ActiveRecordInjection.rb:88:18:88:35 | ...[...] | ActiveRecordInjection.rb:88:18:88:23 | call to params : | ActiveRecordInjection.rb:88:18:88:35 | ...[...] | This SQL query depends on $@. | ActiveRecordInjection.rb:88:18:88:23 | call to params | a user-provided value | | ActiveRecordInjection.rb:92:21:92:35 | ...[...] | ActiveRecordInjection.rb:92:21:92:26 | call to params : | ActiveRecordInjection.rb:92:21:92:35 | ...[...] | This SQL query depends on $@. | ActiveRecordInjection.rb:92:21:92:26 | call to params | a user-provided value | | ActiveRecordInjection.rb:104:20:104:32 | ... + ... | ActiveRecordInjection.rb:98:10:98:15 | call to params : | ActiveRecordInjection.rb:104:20:104:32 | ... + ... | This SQL query depends on $@. | ActiveRecordInjection.rb:98:10:98:15 | call to params | a user-provided value | +| ActiveRecordInjection.rb:151:27:151:76 | "this is an unsafe annotation:..." | ActiveRecordInjection.rb:151:59:151:64 | call to params : | ActiveRecordInjection.rb:151:27:151:76 | "this is an unsafe annotation:..." | This SQL query depends on $@. | ActiveRecordInjection.rb:151:59:151:64 | call to params | a user-provided value | From 940254d2516be52e2aace4a27083d407b9bcb83d Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 7 Jul 2022 19:39:59 +0000 Subject: [PATCH 268/465] update framework tests --- .../library-tests/frameworks/ActiveRecord.expected | 4 ++++ ruby/ql/test/library-tests/frameworks/ActiveRecord.rb | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/ruby/ql/test/library-tests/frameworks/ActiveRecord.expected b/ruby/ql/test/library-tests/frameworks/ActiveRecord.expected index d8509f6a218..b416d853440 100644 --- a/ruby/ql/test/library-tests/frameworks/ActiveRecord.expected +++ b/ruby/ql/test/library-tests/frameworks/ActiveRecord.expected @@ -22,6 +22,7 @@ activeRecordSqlExecutionRanges | ActiveRecord.rb:46:20:46:32 | ... + ... | | ActiveRecord.rb:52:16:52:28 | "name #{...}" | | ActiveRecord.rb:56:20:56:39 | "username = #{...}" | +| ActiveRecord.rb:78:27:78:76 | "this is an unsafe annotation:..." | activeRecordModelClassMethodCalls | ActiveRecord.rb:2:3:2:17 | call to has_many | | ActiveRecord.rb:6:3:6:24 | call to belongs_to | @@ -44,6 +45,8 @@ activeRecordModelClassMethodCalls | ActiveRecord.rb:60:5:60:33 | call to find_by | | ActiveRecord.rb:62:5:62:34 | call to find | | ActiveRecord.rb:68:5:68:45 | call to delete_by | +| ActiveRecord.rb:74:13:74:54 | call to annotate | +| ActiveRecord.rb:78:13:78:77 | call to annotate | potentiallyUnsafeSqlExecutingMethodCall | ActiveRecord.rb:9:5:9:68 | call to find | | ActiveRecord.rb:19:5:19:25 | call to destroy_by | @@ -55,6 +58,7 @@ potentiallyUnsafeSqlExecutingMethodCall | ActiveRecord.rb:46:5:46:33 | call to delete_by | | ActiveRecord.rb:52:5:52:29 | call to order | | ActiveRecord.rb:56:7:56:40 | call to find_by | +| ActiveRecord.rb:78:13:78:77 | call to annotate | activeRecordModelInstantiations | ActiveRecord.rb:9:5:9:68 | call to find | ActiveRecord.rb:5:1:15:3 | User | | ActiveRecord.rb:13:5:13:40 | call to find_by | ActiveRecord.rb:1:1:3:3 | UserGroup | diff --git a/ruby/ql/test/library-tests/frameworks/ActiveRecord.rb b/ruby/ql/test/library-tests/frameworks/ActiveRecord.rb index 5045a5c2264..d25cbf901c3 100644 --- a/ruby/ql/test/library-tests/frameworks/ActiveRecord.rb +++ b/ruby/ql/test/library-tests/frameworks/ActiveRecord.rb @@ -68,3 +68,13 @@ class BazController < BarController Admin.delete_by(params[:admin_condition]) end end + +class AnnotatedController < ActionController::Base + def index + users = User.annotate("this is a safe annotation") + end + + def unsafe_action + users = User.annotate("this is an unsafe annotation:#{params[:comment]}") + end +end From 11e39aa0303d7207f5a03981fe69c651232828e6 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 7 Jul 2022 21:40:16 +0000 Subject: [PATCH 269/465] Add changelog --- ruby/ql/lib/change-notes/released/0.3.1.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ruby/ql/lib/change-notes/released/0.3.1.md diff --git a/ruby/ql/lib/change-notes/released/0.3.1.md b/ruby/ql/lib/change-notes/released/0.3.1.md new file mode 100644 index 00000000000..64efa15884a --- /dev/null +++ b/ruby/ql/lib/change-notes/released/0.3.1.md @@ -0,0 +1,5 @@ +## 0.3.1 + +### Minor Analysis Improvements + +- Calls to `ActiveRecord::Relation#annotate` have now been added to `ActiveRecordModelClass#sqlFragmentArgument` so that it can be used as a sink for queries like rb/sql-injection. \ No newline at end of file From bd50fd7f1e5413d1bd92ee95f43f15a46e63f7b0 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Fri, 8 Jul 2022 17:20:41 +0000 Subject: [PATCH 270/465] format fix --- ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll index b56304a657b..142d1455ce4 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActiveRecord.qll @@ -135,7 +135,7 @@ private Expr sqlFragmentArgument(MethodCall call) { result = call.getKeywordArgument("lock") or // Calls to `annotate` can be used to add block comments to SQL queries. These are potentially vulnerable to - // SQLi if user supplied input is passed in as an argument. + // SQLi if user supplied input is passed in as an argument. methodName = "annotate" and result = call.getArgument(_) ) From 6aab970a9e86ff0dd0aa1660c489d4d0bcba525c Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Fri, 8 Jul 2022 18:32:54 +0000 Subject: [PATCH 271/465] refactor query to use cfg and dataflow --- .../ManuallyCheckHttpVerb.ql | 96 +++++++++++++------ .../ExampleController.rb | 11 --- .../ManuallyCheckHttpVerb.expected | 0 .../ManuallyCheckHttpVerb.qlref | 0 .../manually-check-http-verb/NotController.rb | 17 ++++ .../manually-check-http-verb/NotController.rb | 28 ------ 6 files changed, 85 insertions(+), 67 deletions(-) rename ruby/ql/test/query-tests/{security => experimental}/manually-check-http-verb/ExampleController.rb (70%) rename ruby/ql/test/query-tests/{security => experimental}/manually-check-http-verb/ManuallyCheckHttpVerb.expected (100%) rename ruby/ql/test/query-tests/{security => experimental}/manually-check-http-verb/ManuallyCheckHttpVerb.qlref (100%) create mode 100644 ruby/ql/test/query-tests/experimental/manually-check-http-verb/NotController.rb delete mode 100644 ruby/ql/test/query-tests/security/manually-check-http-verb/NotController.rb diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql index a006587a13e..5e1db6f0de7 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -11,43 +11,83 @@ import ruby import codeql.ruby.DataFlow +import codeql.ruby.controlflow.CfgNodes +import codeql.ruby.frameworks.ActionController -class CheckNotGetRequest extends ConditionalExpr { - CheckNotGetRequest() { this.getCondition() instanceof CheckGetRequest } +// any `request` calls in an action method +class Request extends DataFlow::CallNode { + Request() { + this.getMethodName() = "request" and + this.asExpr().getExpr() instanceof ActionControllerActionMethod + } } -class CheckGetRequest extends MethodCall { - CheckGetRequest() { this.getMethodName() = "get?" } +// `request.request_method` +class RequestRequestMethod extends DataFlow::CallNode { + RequestRequestMethod() { + this.getMethodName() = "request_method" and + any(Request r).flowsTo(this.getReceiver()) + } } -class ControllerClass extends ModuleBase { - ControllerClass() { this.getModule().getSuperClass+().toString() = "ApplicationController" } +// `request.method` +class RequestMethod extends DataFlow::CallNode { + RequestMethod() { + this.getMethodName() = "method" and + any(Request r).flowsTo(this.getReceiver()) + } } -class CheckGetFromEnv extends AstNode { - CheckGetFromEnv() { - // is this node an instance of `env["REQUEST_METHOD"] - this instanceof GetRequestMethodFromEnv and - // check if env["REQUEST_METHOD"] is compared to GET - exists(EqualityOperation eq | eq.getAChild() = this | - eq.getAChild().(StringLiteral).toString() = "GET" +// `request.raw_request_method` +class RequestRawRequestMethod extends DataFlow::CallNode { + RequestRawRequestMethod() { + this.getMethodName() = "raw_request_method" and + any(Request r).flowsTo(this.getReceiver()) + } +} + +// `request.request_method_symbol` +class RequestRequestMethodSymbol extends DataFlow::CallNode { + RequestRequestMethodSymbol() { + this.getMethodName() = "request_method_symbol" and + any(Request r).flowsTo(this.getReceiver()) + } +} + +// `request.get?` +class RequestGet extends DataFlow::CallNode { + RequestGet() { + this.getMethodName() = "get?" and + any(Request r).flowsTo(this.getReceiver()) + } +} + +// A conditional expression where the condition uses `request.method`, `request.request_method`, `request.raw_request_method`, `request.request_method_symbol`, or `request.get?` in some way. +// e.g. +// ``` +// r = request.request_method +// if r == "GET" +// ... +// ``` +class RequestMethodConditional extends DataFlow::Node { + RequestMethodConditional() { + // We have to cast the dataflow node down to a specific CFG node (`ExprNodes::ConditionalExprCfgNode`) to be able to call `getCondition()`. + // We then find the dataflow node corresponding to the condition CFG node, + // and filter for just nodes where a request method accessor value flows to them. + exists(DataFlow::Node conditionNode | + conditionNode.asExpr() = this.asExpr().(ExprNodes::ConditionalExprCfgNode).getCondition() + | + ( + any(RequestMethod r).flowsTo(conditionNode) or + any(RequestRequestMethod r).flowsTo(conditionNode) or + any(RequestRawRequestMethod r).flowsTo(conditionNode) or + any(RequestRequestMethodSymbol r).flowsTo(conditionNode) or + any(RequestGet r).flowsTo(conditionNode) + ) ) } } -class GetRequestMethodFromEnv extends ElementReference { - GetRequestMethodFromEnv() { - this.getAChild+().toString() = "REQUEST_METHOD" and - this.getAChild+().toString() = "env" - } -} - -from AstNode node -where - ( - node instanceof CheckNotGetRequest or - node instanceof CheckGetFromEnv - ) and - node.getEnclosingModule() instanceof ControllerClass -select node, +from RequestMethodConditional req +select req, "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods." diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ExampleController.rb similarity index 70% rename from ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb rename to ruby/ql/test/query-tests/experimental/manually-check-http-verb/ExampleController.rb index c3e913367b8..7e4ab4a1a77 100644 --- a/ruby/ql/test/query-tests/security/manually-check-http-verb/ExampleController.rb +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ExampleController.rb @@ -3,17 +3,6 @@ class ExampleController < ActionController::Base def example_action if request.get? Example.find(params[:example_id]) - elsif request.post? - Example.new(params[:example_name], params[:example_details]) - elsif request.delete? - example = Example.find(params[:example_id]) - example.delete - elsif request.put? - Example.upsert(params[:example_name], params[:example_details]) - elsif request.path? - Example.update(params[:example_name], params[:example_details]) - elsif request.head? - "This is the endpoint for the Example resource." end end end diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.expected b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected similarity index 100% rename from ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.expected rename to ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.qlref b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qlref similarity index 100% rename from ruby/ql/test/query-tests/security/manually-check-http-verb/ManuallyCheckHttpVerb.qlref rename to ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qlref diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/NotController.rb b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/NotController.rb new file mode 100644 index 00000000000..78e194245e2 --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/NotController.rb @@ -0,0 +1,17 @@ +# There should be no hits from this class because it does not inherit from ActionController +class NotAController + def example_action + if request.get? + Example.find(params[:example_id]) + end + end + + def resource_action + case env['REQUEST_METHOD'] + when "GET" + Resource.find(params[:id]) + when "POST" + Resource.new(params[:id], params[:details]) + end + end +end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/manually-check-http-verb/NotController.rb b/ruby/ql/test/query-tests/security/manually-check-http-verb/NotController.rb deleted file mode 100644 index 81a73d72410..00000000000 --- a/ruby/ql/test/query-tests/security/manually-check-http-verb/NotController.rb +++ /dev/null @@ -1,28 +0,0 @@ -# There should be no hits from this class because it does not inherit from ActionController -class NotAController - def example_action - if request.get? - Example.find(params[:example_id]) - elsif request.post? - Example.new(params[:example_name], params[:example_details]) - elsif request.delete? - example = Example.find(params[:example_id]) - example.delete - elsif request.put? - Example.upsert(params[:example_name], params[:example_details]) - elsif request.path? - Example.update(params[:example_name], params[:example_details]) - elsif request.head? - "This is the endpoint for the Example resource." - end - end - - def resource_action - case env['REQUEST_METHOD'] - when "GET" - Resource.find(params[:id]) - when "POST" - Resource.new(params[:id], params[:details]) - end - end -end \ No newline at end of file From 96e66c4a504cdd473f52e8b50140f6261d3a6542 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Fri, 8 Jul 2022 18:39:04 +0000 Subject: [PATCH 272/465] move tests --- .../{security => experimental}/weak-params/WeakParams.expected | 0 .../{security => experimental}/weak-params/WeakParams.qlref | 0 .../{security => experimental}/weak-params/WeakParams.rb | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename ruby/ql/test/query-tests/{security => experimental}/weak-params/WeakParams.expected (100%) rename ruby/ql/test/query-tests/{security => experimental}/weak-params/WeakParams.qlref (100%) rename ruby/ql/test/query-tests/{security => experimental}/weak-params/WeakParams.rb (100%) diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.expected b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.expected similarity index 100% rename from ruby/ql/test/query-tests/security/weak-params/WeakParams.expected rename to ruby/ql/test/query-tests/experimental/weak-params/WeakParams.expected diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.qlref similarity index 100% rename from ruby/ql/test/query-tests/security/weak-params/WeakParams.qlref rename to ruby/ql/test/query-tests/experimental/weak-params/WeakParams.qlref diff --git a/ruby/ql/test/query-tests/security/weak-params/WeakParams.rb b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb similarity index 100% rename from ruby/ql/test/query-tests/security/weak-params/WeakParams.rb rename to ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb From 5d3232c614b591cf234c6e8ebc0dc2e099228dcc Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Fri, 8 Jul 2022 18:53:24 +0000 Subject: [PATCH 273/465] refactor to use data flow --- .../experimental/weak-params/WeakParams.ql | 79 ++++++------------- .../experimental/weak-params/WeakParams.rb | 2 +- 2 files changed, 23 insertions(+), 58 deletions(-) diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql index f9af2e5c08c..6ea73aa42de 100644 --- a/ruby/ql/src/experimental/weak-params/WeakParams.ql +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -11,45 +11,41 @@ */ import ruby +import codeql.ruby.Concepts import codeql.ruby.DataFlow import codeql.ruby.TaintTracking +import codeql.ruby.frameworks.ActionController import DataFlow::PathGraph /** - * A direct parameters reference that happens outside of a strong params method but inside - * of a controller class + * A call to `request` in an ActionController controller class. + * This probably refers to the incoming HTTP request object. */ -class WeakParams extends Expr { - WeakParams() { - ( - allParamsAccess(this) or - this instanceof ParamsReference - ) and - this.getEnclosingModule() instanceof ControllerClass and - not this.getEnclosingMethod() instanceof StrongParamsMethod +class ActionControllerRequest extends DataFlow::Node { + ActionControllerRequest() { + exists(DataFlow::CallNode c | + c.asExpr().getExpr().getEnclosingModule() instanceof ActionControllerControllerClass and + c.getMethodName() = "request" + | + c.flowsTo(this) + ) } } /** - * A controller class, which extendsd `ApplicationController` + * A direct parameters reference that happens inside a controller class. */ -class ControllerClass extends ModuleBase { - ControllerClass() { this.getModule().getSuperClass+().toString() = "ApplicationController" } -} - -/** - * A method that follows the strong params naming convention - */ -class StrongParamsMethod extends Method { - StrongParamsMethod() { this.getName().regexpMatch(".*_params") } +class WeakParams extends DataFlow::CallNode { + WeakParams() { + this.getReceiver() instanceof ActionControllerRequest and + allParamsAccess(this.asExpr().getExpr()) + } } /** * Holds call to a method that exposes or accesses all parameters from an inbound HTTP request */ predicate allParamsAccess(MethodCall call) { - call.getMethodName() = "expose_all" or - call.getMethodName() = "original_hash" or call.getMethodName() = "path_parametes" or call.getMethodName() = "query_parameters" or call.getMethodName() = "request_parameters" or @@ -57,51 +53,20 @@ predicate allParamsAccess(MethodCall call) { call.getMethodName() = "POST" } -/** - * A reference to an element in the `params` object - */ -class ParamsReference extends ElementReference { - ParamsReference() { this.getAChild().toString() = "params" } -} - -/** - * A Model or ViewModel classes with a base class of `ViewModel`, `ApplicationRecord` or includes `ActionModel::Model`, - * which are required to support the strong parameters pattern - */ -class ModelClass extends ModuleBase { - ModelClass() { - this.getModule().getSuperClass+().toString() = "ViewModel" or - this.getModule().getSuperClass+().toString() = "ApplicationRecord" or - this.getModule().getSuperClass+().getAnIncludedModule().toString() = "ActionModel::Model" - } -} - -/** - * A DataFlow::Node representation that corresponds to any argument passed into a method call - * where the receiver is an instance of ModelClass - */ -class ModelClassMethodArgument extends DataFlow::Node { - - ModelClassMethodArgument() { - exists( DataFlow::CallNode call | this = call.getArgument(_) | - call.getExprNode().getNode().getParent+() instanceof ModelClass ) - } -} - /** * A Taint tracking config where the source is a weak params access in a controller and the sink * is a method call of a model class */ class Configuration extends TaintTracking::Configuration { - Configuration() { this = "Configuration" } + Configuration() { this = "WeakParamsConfiguration" } - override predicate isSource(DataFlow::Node node) { node.asExpr().getNode() instanceof WeakParams } + override predicate isSource(DataFlow::Node node) { node instanceof WeakParams } // the sink is an instance of a Model class that receives a method call - override predicate isSink(DataFlow::Node node) { node instanceof ModelClassMethodArgument } + override predicate isSink(DataFlow::Node node) { node = any(PersistentWriteAccess a).getValue() } } from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink where config.hasFlowPath(source, sink) -select sink.getNode().(ModelClassMethodArgument), source, sink, +select sink.getNode(), source, sink, "By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html" diff --git a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb index a2fedd6ef26..81d57239f29 100644 --- a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb +++ b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb @@ -8,7 +8,7 @@ class TestController < ActionController::Base end def update - TestObect.update(object_params) + TestObject.update(object_params) end # From e8e8da1b3189adba08fe944db5df482287b52a49 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Fri, 8 Jul 2022 19:01:01 +0000 Subject: [PATCH 274/465] fix lib test expect for ActionController --- .../test/library-tests/frameworks/ActionController.expected | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ruby/ql/test/library-tests/frameworks/ActionController.expected b/ruby/ql/test/library-tests/frameworks/ActionController.expected index d306f09b64b..52ab15995c7 100644 --- a/ruby/ql/test/library-tests/frameworks/ActionController.expected +++ b/ruby/ql/test/library-tests/frameworks/ActionController.expected @@ -2,6 +2,7 @@ actionControllerControllerClasses | ActiveRecord.rb:23:1:39:3 | FooController | | ActiveRecord.rb:41:1:64:3 | BarController | | ActiveRecord.rb:66:1:70:3 | BazController | +| ActiveRecord.rb:72:1:80:3 | AnnotatedController | | app/controllers/comments_controller.rb:1:1:7:3 | CommentsController | | app/controllers/foo/bars_controller.rb:3:1:39:3 | BarsController | | app/controllers/photos_controller.rb:1:1:4:3 | PhotosController | @@ -12,6 +13,8 @@ actionControllerActionMethods | ActiveRecord.rb:42:3:47:5 | some_other_request_handler | | ActiveRecord.rb:49:3:63:5 | safe_paths | | ActiveRecord.rb:67:3:69:5 | yet_another_handler | +| ActiveRecord.rb:73:3:75:5 | index | +| ActiveRecord.rb:77:3:79:5 | unsafe_action | | app/controllers/comments_controller.rb:2:3:3:5 | index | | app/controllers/comments_controller.rb:5:3:6:5 | show | | app/controllers/foo/bars_controller.rb:5:3:7:5 | index | @@ -38,6 +41,7 @@ paramsCalls | ActiveRecord.rb:59:12:59:17 | call to params | | ActiveRecord.rb:62:15:62:20 | call to params | | ActiveRecord.rb:68:21:68:26 | call to params | +| ActiveRecord.rb:78:59:78:64 | call to params | | app/controllers/foo/bars_controller.rb:13:21:13:26 | call to params | | app/controllers/foo/bars_controller.rb:14:10:14:15 | call to params | | app/controllers/foo/bars_controller.rb:21:21:21:26 | call to params | @@ -57,6 +61,7 @@ paramsSources | ActiveRecord.rb:59:12:59:17 | call to params | | ActiveRecord.rb:62:15:62:20 | call to params | | ActiveRecord.rb:68:21:68:26 | call to params | +| ActiveRecord.rb:78:59:78:64 | call to params | | app/controllers/foo/bars_controller.rb:13:21:13:26 | call to params | | app/controllers/foo/bars_controller.rb:14:10:14:15 | call to params | | app/controllers/foo/bars_controller.rb:21:21:21:26 | call to params | From 7c3cadc9b6c7b2556f9a76b469b3f36f97133415 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 11 Jul 2022 10:40:45 +0200 Subject: [PATCH 275/465] Swift: extract `OpenedArchetypeType` --- swift/extractor/visitors/TypeVisitor.cpp | 7 +++++- swift/extractor/visitors/TypeVisitor.h | 1 + .../OpenedArchetypeType/MISSING_SOURCE.txt | 4 --- .../OpenedArchetypeType.expected | 1 + .../OpenedArchetypeType.ql | 13 ++++++++++ .../OpenedArchetypeType_getProtocol.expected | 2 ++ .../OpenedArchetypeType_getProtocol.ql | 7 ++++++ ...OpenedArchetypeType_getSuperclass.expected | 1 + .../OpenedArchetypeType_getSuperclass.ql | 7 ++++++ .../opened_archetypes.swift | 25 +++++++++++++++++++ 10 files changed, 63 insertions(+), 5 deletions(-) delete mode 100644 swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.expected create mode 100644 swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.ql create mode 100644 swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.expected create mode 100644 swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.ql create mode 100644 swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.expected create mode 100644 swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.ql create mode 100644 swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/opened_archetypes.swift diff --git a/swift/extractor/visitors/TypeVisitor.cpp b/swift/extractor/visitors/TypeVisitor.cpp index 4b6733312d3..945ef5693ce 100644 --- a/swift/extractor/visitors/TypeVisitor.cpp +++ b/swift/extractor/visitors/TypeVisitor.cpp @@ -367,5 +367,10 @@ codeql::BuiltinVectorType TypeVisitor::translateBuiltinVectorType( const swift::BuiltinVectorType& type) { return createTypeEntry(type); } - +codeql::OpenedArchetypeType TypeVisitor::translateOpenedArchetypeType( + const swift::OpenedArchetypeType& type) { + auto entry = createTypeEntry(type); + fillArchetypeType(type, entry); + return entry; +} } // namespace codeql diff --git a/swift/extractor/visitors/TypeVisitor.h b/swift/extractor/visitors/TypeVisitor.h index 77ae8ee13bf..61ec7796cf9 100644 --- a/swift/extractor/visitors/TypeVisitor.h +++ b/swift/extractor/visitors/TypeVisitor.h @@ -68,6 +68,7 @@ class TypeVisitor : public TypeVisitorBase { codeql::BuiltinUnsafeValueBufferType translateBuiltinUnsafeValueBufferType( const swift::BuiltinUnsafeValueBufferType& type); codeql::BuiltinVectorType translateBuiltinVectorType(const swift::BuiltinVectorType& type); + codeql::OpenedArchetypeType translateOpenedArchetypeType(const swift::OpenedArchetypeType& type); private: void fillType(const swift::TypeBase& type, codeql::Type& entry); diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.expected b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.expected new file mode 100644 index 00000000000..f6c15bca419 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.expected @@ -0,0 +1 @@ +| C & P1 & P2 | getName: | C & P1 & P2 | getCanonicalType: | C & P1 & P2 | getInterfaceType: | \u03c4_0_0 | diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.ql b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.ql new file mode 100644 index 00000000000..b558c08f666 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType.ql @@ -0,0 +1,13 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from OpenedArchetypeType x, string getName, Type getCanonicalType, Type getInterfaceType +where + toBeTested(x) and + not x.isUnknown() and + getName = x.getName() and + getCanonicalType = x.getCanonicalType() and + getInterfaceType = x.getInterfaceType() +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getInterfaceType:", + getInterfaceType diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.expected b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.expected new file mode 100644 index 00000000000..5899ea9308a --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.expected @@ -0,0 +1,2 @@ +| C & P1 & P2 | 0 | opened_archetypes.swift:3:1:3:14 | P1 | +| C & P1 & P2 | 1 | opened_archetypes.swift:9:1:9:14 | P2 | diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.ql b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.ql new file mode 100644 index 00000000000..58fed5dda7b --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getProtocol.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from OpenedArchetypeType x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getProtocol(index) diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.expected b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.expected new file mode 100644 index 00000000000..be1cb7dcb05 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.expected @@ -0,0 +1 @@ +| C & P1 & P2 | C | diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.ql b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.ql new file mode 100644 index 00000000000..46f00a08c88 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/OpenedArchetypeType_getSuperclass.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from OpenedArchetypeType x +where toBeTested(x) and not x.isUnknown() +select x, x.getSuperclass() diff --git a/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/opened_archetypes.swift b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/opened_archetypes.swift new file mode 100644 index 00000000000..93d58b6163f --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/OpenedArchetypeType/opened_archetypes.swift @@ -0,0 +1,25 @@ +// code inspired by https://github.com/apple/swift-evolution/blob/main/proposals/0352-implicit-open-existentials.md + +protocol P1 {} + +func isFoo(_: T) -> Bool { + return true +} + +protocol P2 {} + +class C {} + +// will be ok with swift 5.7 +// func test(value: any P1 & P2 & C) -> Bool { return isFoo(value) } + +extension P1 { + var isFooMember: Bool { + isFoo(self) + } +} + + +func testMember(value: any P1 & P2 & C) -> Bool { + return value.isFooMember // here the existential type is implicitly "opened" +} From 7d5dd384c374457846a9d1de5f7d8b95947f19ec Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 11 Jul 2022 10:59:00 +0200 Subject: [PATCH 276/465] Swift: extract `UnresolvedPatternExpr` --- swift/codegen/schema.yml | 2 ++ swift/extractor/visitors/ExprVisitor.cpp | 6 ++++++ swift/extractor/visitors/ExprVisitor.h | 5 +++++ swift/extractor/visitors/VisitorBase.h | 2 +- .../ql/lib/codeql/swift/generated/GetImmediateParent.qll | 2 ++ .../codeql/swift/generated/expr/UnresolvedPatternExpr.qll | 8 ++++++++ swift/ql/lib/swift.dbscheme | 3 ++- 7 files changed, 26 insertions(+), 2 deletions(-) diff --git a/swift/codegen/schema.yml b/swift/codegen/schema.yml index 01bb0c2feba..96da8c96936 100644 --- a/swift/codegen/schema.yml +++ b/swift/codegen/schema.yml @@ -561,6 +561,8 @@ UnresolvedMemberExpr: UnresolvedPatternExpr: _extends: Expr _pragma: qltest_skip # we should really never extract these + _children: + sub_pattern: Pattern UnresolvedSpecializeExpr: _extends: Expr diff --git a/swift/extractor/visitors/ExprVisitor.cpp b/swift/extractor/visitors/ExprVisitor.cpp index e6aabef4cea..90ca0a168ee 100644 --- a/swift/extractor/visitors/ExprVisitor.cpp +++ b/swift/extractor/visitors/ExprVisitor.cpp @@ -667,5 +667,11 @@ void ExprVisitor::emitLookupExpr(const swift::LookupExpr* expr, TrapLabel { codeql::BridgeFromObjCExpr translateBridgeFromObjCExpr(const swift::BridgeFromObjCExpr& expr); codeql::DotSelfExpr translateDotSelfExpr(const swift::DotSelfExpr& expr); codeql::ErrorExpr translateErrorExpr(const swift::ErrorExpr& expr); + // following requires non-const because: + // * `swift::UnresolvedPatternExpr::getSubPattern` gives `const swift::Pattern*` on const refs + // * `swift::ASTVisitor` only visits non-const pointers + // either we accept this, or we fix constness by providing our own const visiting in VisitorBase + codeql::UnresolvedPatternExpr translateUnresolvedPatternExpr(swift::UnresolvedPatternExpr& expr); private: void fillAbstractClosureExpr(const swift::AbstractClosureExpr& expr, diff --git a/swift/extractor/visitors/VisitorBase.h b/swift/extractor/visitors/VisitorBase.h index 8402e8924af..b835492d00d 100644 --- a/swift/extractor/visitors/VisitorBase.h +++ b/swift/extractor/visitors/VisitorBase.h @@ -29,7 +29,7 @@ class VisitorBase { public: \ void visit##CLASS##KIND(swift::CLASS##KIND* e) { \ using TranslateResult = std::invoke_result_t; \ + CrtpSubclass, swift::CLASS##KIND&>; \ constexpr bool hasTranslateImplementation = !std::is_same_v; \ if constexpr (hasTranslateImplementation) { \ dispatcher_.emit(static_cast(this)->translate##CLASS##KIND(*e)); \ diff --git a/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll b/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll index aaf3dec16bd..4cecd1a3ce6 100644 --- a/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll +++ b/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll @@ -144,6 +144,8 @@ Element getAnImmediateChild(Element e) { or unresolved_dot_exprs(e, x, _) or + unresolved_pattern_exprs(e, x) + or vararg_expansion_exprs(e, x) or binding_patterns(e, x) diff --git a/swift/ql/lib/codeql/swift/generated/expr/UnresolvedPatternExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/UnresolvedPatternExpr.qll index 8d03b2079aa..ae62f2df23b 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/UnresolvedPatternExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/UnresolvedPatternExpr.qll @@ -1,6 +1,14 @@ // generated by codegen/codegen.py import codeql.swift.elements.expr.Expr +import codeql.swift.elements.pattern.Pattern class UnresolvedPatternExprBase extends @unresolved_pattern_expr, Expr { override string getAPrimaryQlClass() { result = "UnresolvedPatternExpr" } + + Pattern getSubPattern() { + exists(Pattern x | + unresolved_pattern_exprs(this, x) and + result = x.resolve() + ) + } } diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index 83ee8412131..c12e00e028d 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -1141,7 +1141,8 @@ unresolved_member_exprs( //dir=expr ); unresolved_pattern_exprs( //dir=expr - unique int id: @unresolved_pattern_expr + unique int id: @unresolved_pattern_expr, + int sub_pattern: @pattern ref ); unresolved_specialize_exprs( //dir=expr From 6b2154eb8b464b58e44f3416824fe0bdd2285f35 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Mon, 11 Jul 2022 11:54:48 +0200 Subject: [PATCH 277/465] C++: Add tests for `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` --- .../controlflow/nullness/nullness.expected | 15 ++++++++++++ .../controlflow/nullness/nullness.ql | 9 ++++++++ .../controlflow/nullness/test.cpp | 23 +++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 cpp/ql/test/library-tests/controlflow/nullness/nullness.expected create mode 100644 cpp/ql/test/library-tests/controlflow/nullness/nullness.ql create mode 100644 cpp/ql/test/library-tests/controlflow/nullness/test.cpp diff --git a/cpp/ql/test/library-tests/controlflow/nullness/nullness.expected b/cpp/ql/test/library-tests/controlflow/nullness/nullness.expected new file mode 100644 index 00000000000..db5c795fd5b --- /dev/null +++ b/cpp/ql/test/library-tests/controlflow/nullness/nullness.expected @@ -0,0 +1,15 @@ +| test.cpp:9:9:9:9 | v | test.cpp:5:13:5:13 | v | is not null | is valid | +| test.cpp:10:9:10:10 | ! ... | test.cpp:5:13:5:13 | v | is null | is not valid | +| test.cpp:11:9:11:14 | ... == ... | test.cpp:5:13:5:13 | v | is null | is not valid | +| test.cpp:12:9:12:17 | ... == ... | test.cpp:5:13:5:13 | v | is not null | is valid | +| test.cpp:13:9:13:14 | ... != ... | test.cpp:5:13:5:13 | v | is not null | is valid | +| test.cpp:14:9:14:17 | ... != ... | test.cpp:5:13:5:13 | v | is null | is not valid | +| test.cpp:15:8:15:23 | call to __builtin_expect | test.cpp:5:13:5:13 | v | is not null | is valid | +| test.cpp:16:8:16:23 | call to __builtin_expect | test.cpp:5:13:5:13 | v | is null | is not valid | +| test.cpp:17:9:17:17 | ... && ... | test.cpp:5:13:5:13 | v | is not null | is valid | +| test.cpp:18:9:18:17 | ... && ... | test.cpp:5:13:5:13 | v | is not null | is not valid | +| test.cpp:19:9:19:18 | ... && ... | test.cpp:5:13:5:13 | v | is null | is not valid | +| test.cpp:20:9:20:18 | ... && ... | test.cpp:5:13:5:13 | v | is not null | is not valid | +| test.cpp:21:9:21:14 | ... = ... | test.cpp:5:13:5:13 | v | is null | is not valid | +| test.cpp:21:9:21:14 | ... = ... | test.cpp:7:10:7:10 | b | is not null | is valid | +| test.cpp:22:17:22:17 | b | test.cpp:7:10:7:10 | b | is not null | is valid | diff --git a/cpp/ql/test/library-tests/controlflow/nullness/nullness.ql b/cpp/ql/test/library-tests/controlflow/nullness/nullness.ql new file mode 100644 index 00000000000..ed1ba15aa2b --- /dev/null +++ b/cpp/ql/test/library-tests/controlflow/nullness/nullness.ql @@ -0,0 +1,9 @@ +import cpp + +from AnalysedExpr a, LocalScopeVariable v, string isNullCheck, string isValidCheck +where + a.getParent() instanceof IfStmt and + v.getAnAccess().getEnclosingStmt() = a.getParent() and + (if a.isNullCheck(v) then isNullCheck = "is null" else isNullCheck = "is not null") and + (if a.isValidCheck(v) then isValidCheck = "is valid" else isValidCheck = "is not valid") +select a, v, isNullCheck, isValidCheck diff --git a/cpp/ql/test/library-tests/controlflow/nullness/test.cpp b/cpp/ql/test/library-tests/controlflow/nullness/test.cpp new file mode 100644 index 00000000000..03369c811d5 --- /dev/null +++ b/cpp/ql/test/library-tests/controlflow/nullness/test.cpp @@ -0,0 +1,23 @@ +// semmle-extractor-options: -std=c++17 + +long __builtin_expect(long); + +void f(int *v) { + int *w; + bool b; + + if (v) {} + if (!v) {} + if (v == 0) {} + if ((!v) == 0) {} + if (v != 0) {} + if ((!v) != 0) {} + if(__builtin_expect((long)v)) {} + if(__builtin_expect((long)!v)) {} + if (true && v) {} + if (v && true) {} + if (true && !v) {} + if (!v && true) {} + if (b = !v) {} + if (b = !v; b) {} +} From 74641ccfee54e6c7fd824b9ffc9726cd6f3c2291 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 11 Jul 2022 11:01:19 +0100 Subject: [PATCH 278/465] Simplify test for no-arg constructor --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 7f1ec039d20..a109e945343 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -24,7 +24,7 @@ predicate isCreatingOutdatedAzureClientSideEncryptionObject(Call call, Class c) ( type = "EncryptedBlobClientBuilder" and package = "com.azure.storage.blob.specialized.cryptography" and - not exists(Expr e | e = call.getArgument(0)) + constructor.hasNoParameters() or type = "BlobEncryptionPolicy" and package = "com.microsoft.azure.storage.blob" ) From 9ed7aa9fae85df1a40c65f6bcd89fcd52ea45926 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 11 Jul 2022 12:52:23 +0200 Subject: [PATCH 279/465] exclude variables in .vue files form js/unused-local-variable --- javascript/ql/src/Declarations/UnusedVariable.ql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/javascript/ql/src/Declarations/UnusedVariable.ql b/javascript/ql/src/Declarations/UnusedVariable.ql index 254c8c206b1..f678c7d5b19 100644 --- a/javascript/ql/src/Declarations/UnusedVariable.ql +++ b/javascript/ql/src/Declarations/UnusedVariable.ql @@ -144,6 +144,9 @@ predicate whitelisted(UnusedLocal v) { // exclude variables mentioned in JSDoc comments in externs mentionedInJSDocComment(v) or + // the attributes in .vue files are not extracted, so we can get false positives in those. + v.getADeclaration().getFile().getExtension() = "vue" + or // exclude variables used to filter out unwanted properties isPropertyFilter(v) or From aa07600f5a5694b6739ae2fa15474fd7fc99b4ec Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Fri, 1 Jul 2022 12:20:26 +0100 Subject: [PATCH 280/465] Java: Update stats --- java/ql/lib/config/semmlecode.dbscheme.stats | 4260 +++++++++--------- 1 file changed, 2165 insertions(+), 2095 deletions(-) diff --git a/java/ql/lib/config/semmlecode.dbscheme.stats b/java/ql/lib/config/semmlecode.dbscheme.stats index 2fc1431a73f..0490619a996 100644 --- a/java/ql/lib/config/semmlecode.dbscheme.stats +++ b/java/ql/lib/config/semmlecode.dbscheme.stats @@ -1,20 +1,20 @@ - - @diagnostic - 634718 - - - @externalDataElement - 1 - @javacompilation 8629 @kotlincompilation - 6824 + 6822 + + + @diagnostic + 624933 + + + @externalDataElement + 1 @duplication @@ -26,27 +26,31 @@ @file - 8020653 + 8017700 @folder - 1280356 + 1279884 @package - 612878 + 612652 @primitive - 12284 + 12280 @modifier - 12284 + 13644 + + + @errortype + 1 @class - 12579704 + 12579165 @kt_nullable_type @@ -54,7 +58,7 @@ @kt_notnull_type - 193427 + 194340 @kt_type_alias @@ -66,27 +70,27 @@ @fielddecl - 399940 + 399793 @field - 27583622 + 27573466 @constructor - 6889080 + 6886544 @method - 93482380 - - - @location_default - 431212495 + 93447961 @param - 101137218 + 101099980 + + + @location_default + 431053728 @exception @@ -94,19 +98,19 @@ @typevariable - 5118694 + 5116810 @wildcard - 3116261 + 3637710 @typebound - 3872463 + 4393634 @array - 1119287 + 1118875 @import @@ -114,7 +118,7 @@ @block - 846290 + 845979 @ifstmt @@ -130,7 +134,7 @@ @whilestmt - 19743 + 19739 @dostmt @@ -146,11 +150,11 @@ @synchronizedstmt - 18562 + 18706 @returnstmt - 675212 + 675118 @throwstmt @@ -182,7 +186,7 @@ @localtypedeclstmt - 4069 + 4110 @constructorinvocationstmt @@ -190,7 +194,7 @@ @superconstructorinvocationstmt - 225902 + 226569 @case @@ -202,7 +206,7 @@ @labeledstmt - 2443 + 2518 @yieldstmt @@ -214,7 +218,7 @@ @whenbranch - 238370 + 233347 @arrayaccess @@ -334,7 +338,7 @@ @andlogicalexpr - 41441 + 41715 @orlogicalexpr @@ -410,7 +414,7 @@ @instanceofexpr - 31274 + 31086 @localvariabledeclexpr @@ -418,11 +422,11 @@ @typeliteral - 147176 + 148317 @thisaccess - 952512 + 952380 @superaccess @@ -434,11 +438,11 @@ @methodaccess - 1551591 + 1551738 @unannotatedtypeaccess - 2874591 + 2867985 @arraytypeaccess @@ -486,7 +490,7 @@ @lambdaexpr - 185816 + 186985 @memberref @@ -514,7 +518,7 @@ @whenexpr - 172153 + 172129 @getclassexpr @@ -522,35 +526,35 @@ @safecastexpr - 6986 + 6943 @implicitcastexpr - 33111 + 32911 @implicitnotnullexpr - 241008 + 239473 @implicitcoerciontounitexpr - 93086 + 92272 @notinstanceofexpr - 19586 + 19583 @stmtexpr - 58107 + 57757 @stringtemplateexpr - 55964 + 55943 @notnullexpr - 21375 + 21370 @unsafecoerceexpr @@ -558,15 +562,15 @@ @valueeqexpr - 103390 + 104218 @valueneexpr - 108240 + 108225 @propertyref - 9721 + 9663 @localvar @@ -610,7 +614,7 @@ @xmlelement - 106792352 + 106753032 @javadocText @@ -618,19 +622,19 @@ @xmlattribute - 129898822 + 129850995 @xmlnamespace - 8189 + 8186 @xmlcomment - 107485764 + 107446189 @xmlcharacters - 101574013 + 101536615 @config @@ -646,15 +650,15 @@ @ktcomment - 133768 + 133719 @ktcommentsection - 59246 + 59191 @kt_property - 30317687 + 30306525 @@ -876,30 +880,30 @@ compilation_started - 6824 + 6822 id - 6824 + 6822 compilation_args - 158338 + 158279 id - 6824 + 6822 num - 38219 + 38205 arg - 90089 + 90055 @@ -913,7 +917,7 @@ 20 21 - 2729 + 2728 23 @@ -944,7 +948,7 @@ 20 21 - 2729 + 2728 23 @@ -975,22 +979,22 @@ 1 2 - 4094 + 4093 2 3 - 2729 + 2728 3 4 - 4094 + 4093 5 6 - 27299 + 27289 @@ -1006,27 +1010,27 @@ 1 2 - 8189 + 8186 2 3 - 5459 + 5457 3 4 - 10919 + 10915 4 5 - 6824 + 6822 5 6 - 6824 + 6822 @@ -1042,22 +1046,22 @@ 1 2 - 69614 + 69588 2 3 - 2729 + 2728 4 5 - 6824 + 6822 5 6 - 10919 + 10915 @@ -1073,17 +1077,17 @@ 1 2 - 72344 + 72317 2 3 - 15014 + 15009 4 5 - 2729 + 2728 @@ -1093,19 +1097,19 @@ compilation_compiling_files - 60660 + 61130 id - 2320 + 2338 num - 17899 + 18038 file - 50716 + 51109 @@ -1119,22 +1123,22 @@ 1 2 - 331 + 334 2 3 - 662 + 668 35 36 - 662 + 668 54 55 - 662 + 668 @@ -1150,22 +1154,22 @@ 1 2 - 331 + 334 2 3 - 662 + 668 35 36 - 662 + 668 54 55 - 662 + 668 @@ -1181,17 +1185,17 @@ 2 3 - 6298 + 6346 4 5 - 10938 + 11023 6 8 - 662 + 668 @@ -1207,17 +1211,17 @@ 2 3 - 6298 + 6346 3 4 - 9944 + 10021 4 8 - 1657 + 1670 @@ -1233,12 +1237,12 @@ 1 2 - 40771 + 41087 2 3 - 9944 + 10021 @@ -1254,7 +1258,7 @@ 1 2 - 50716 + 51109 @@ -1264,19 +1268,19 @@ compilation_compiling_files_completed - 60660 + 61130 id - 2320 + 2338 num - 17899 + 18038 result - 331 + 668 @@ -1290,22 +1294,22 @@ 1 2 - 331 + 334 2 3 - 662 + 668 35 36 - 662 + 668 54 55 - 662 + 668 @@ -1321,7 +1325,12 @@ 1 2 - 2320 + 1670 + + + 2 + 3 + 668 @@ -1337,17 +1346,17 @@ 2 3 - 6298 + 6346 4 5 - 10938 + 11023 6 8 - 662 + 668 @@ -1363,7 +1372,12 @@ 1 2 - 17899 + 17704 + + + 2 + 3 + 334 @@ -1376,10 +1390,15 @@ 12 + + 2 + 3 + 334 + 7 8 - 331 + 334 @@ -1392,10 +1411,15 @@ 12 + + 1 + 2 + 334 + 54 55 - 331 + 334 @@ -1826,23 +1850,23 @@ diagnostic_for - 634718 + 624933 diagnostic - 634718 + 624933 compilation - 6824 + 6822 file_number - 8189 + 8186 file_number_diagnostic_number - 60059 + 60037 @@ -1856,7 +1880,7 @@ 1 2 - 634718 + 624933 @@ -1872,7 +1896,7 @@ 1 2 - 634718 + 624933 @@ -1888,7 +1912,7 @@ 1 2 - 634718 + 624933 @@ -1907,18 +1931,18 @@ 1364 - 86 - 87 + 84 + 85 1364 100 101 - 2729 + 2728 - 106 - 107 + 101 + 102 1364 @@ -1935,7 +1959,7 @@ 3 4 - 2729 + 2728 4 @@ -1969,8 +1993,8 @@ 1364 - 36 - 37 + 34 + 35 1364 @@ -1979,8 +2003,8 @@ 1364 - 43 - 44 + 41 + 42 1364 @@ -2005,23 +2029,23 @@ 1364 - 32 - 33 + 34 + 35 1364 - 49 - 50 + 48 + 49 1364 - 106 - 107 + 100 + 101 1364 - 130 - 131 + 128 + 129 1364 @@ -2058,7 +2082,7 @@ 5 6 - 4094 + 4093 @@ -2082,8 +2106,13 @@ 1364 - 36 - 37 + 34 + 35 + 1364 + + + 40 + 41 1364 @@ -2091,11 +2120,6 @@ 42 1364 - - 43 - 44 - 1364 - 44 45 @@ -2114,63 +2138,63 @@ 1 + 3 + 5457 + + + 3 4 - 5459 + 1364 4 5 - 5459 + 5457 5 - 7 - 2729 + 6 + 1364 7 8 - 6824 + 6822 8 9 - 4094 + 4093 9 10 - 6824 + 9551 10 - 12 - 4094 - - - 12 14 - 4094 + 5457 15 16 - 2729 + 4093 16 17 - 9554 + 6822 - 17 + 18 20 - 4094 + 5457 20 22 - 4094 + 4093 @@ -2186,22 +2210,22 @@ 1 3 - 5459 + 5457 3 4 - 5459 + 8186 4 5 - 9554 + 6822 5 6 - 39584 + 39569 @@ -2217,27 +2241,27 @@ 1 3 - 4094 + 5457 3 4 - 6824 + 8186 4 5 - 28664 + 25925 5 6 - 13649 + 13644 6 7 - 6824 + 6822 @@ -2247,11 +2271,11 @@ compilation_compiler_times - 6824 + 6822 id - 6824 + 6822 cpu_seconds @@ -2259,7 +2283,7 @@ elapsed_seconds - 6824 + 6822 @@ -2273,7 +2297,7 @@ 1 2 - 6824 + 6822 @@ -2289,7 +2313,7 @@ 1 2 - 6824 + 6822 @@ -2337,7 +2361,7 @@ 1 2 - 6824 + 6822 @@ -2353,7 +2377,7 @@ 1 2 - 6824 + 6822 @@ -2579,11 +2603,11 @@ diagnostics - 634718 + 624933 id - 634718 + 624933 generated_by @@ -2599,11 +2623,11 @@ error_message - 96913 + 95513 full_error_message - 499584 + 502129 location @@ -2621,7 +2645,7 @@ 1 2 - 634718 + 624933 @@ -2637,7 +2661,7 @@ 1 2 - 634718 + 624933 @@ -2653,7 +2677,7 @@ 1 2 - 634718 + 624933 @@ -2669,7 +2693,7 @@ 1 2 - 634718 + 624933 @@ -2685,7 +2709,7 @@ 1 2 - 634718 + 624933 @@ -2701,7 +2725,7 @@ 1 2 - 634718 + 624933 @@ -2715,8 +2739,8 @@ 12 - 465 - 466 + 458 + 459 1364 @@ -2763,8 +2787,8 @@ 12 - 71 - 72 + 70 + 71 1364 @@ -2779,8 +2803,8 @@ 12 - 366 - 367 + 368 + 369 1364 @@ -2811,8 +2835,8 @@ 12 - 465 - 466 + 458 + 459 1364 @@ -2859,8 +2883,8 @@ 12 - 71 - 72 + 70 + 71 1364 @@ -2875,8 +2899,8 @@ 12 - 366 - 367 + 368 + 369 1364 @@ -2907,8 +2931,8 @@ 12 - 465 - 466 + 458 + 459 1364 @@ -2955,8 +2979,8 @@ 12 - 71 - 72 + 70 + 71 1364 @@ -2971,8 +2995,8 @@ 12 - 366 - 367 + 368 + 369 1364 @@ -3005,67 +3029,62 @@ 1 2 - 19109 + 19102 2 3 - 6824 + 5457 3 4 - 13649 + 12280 4 5 - 4094 + 5457 5 6 - 5459 + 5457 6 7 - 6824 + 6822 7 8 - 2729 + 2728 8 9 - 9554 + 9551 9 10 - 5459 + 6822 10 11 - 6824 + 8186 - 13 - 15 - 5459 + 14 + 17 + 6822 - 16 - 19 - 8189 - - - 20 + 17 21 - 2729 + 6822 @@ -3081,7 +3100,7 @@ 1 2 - 96913 + 95513 @@ -3097,7 +3116,7 @@ 1 2 - 96913 + 95513 @@ -3113,7 +3132,7 @@ 1 2 - 96913 + 95513 @@ -3129,52 +3148,62 @@ 1 2 - 23204 + 21831 2 3 - 5459 + 5457 3 4 - 13649 + 12280 4 + 5 + 5457 + + + 5 6 - 8189 + 4093 6 7 - 6824 + 8186 7 8 - 6824 + 12280 8 9 - 16379 + 6822 9 10 - 2729 + 4093 10 11 - 6824 + 5457 11 12 - 6824 + 5457 + + + 12 + 13 + 4093 @@ -3190,7 +3219,7 @@ 1 2 - 96913 + 95513 @@ -3206,17 +3235,17 @@ 1 2 - 409495 + 418896 2 3 - 49139 + 49121 3 5 - 40949 + 34112 @@ -3232,7 +3261,7 @@ 1 2 - 499584 + 502129 @@ -3248,7 +3277,7 @@ 1 2 - 499584 + 502129 @@ -3264,7 +3293,7 @@ 1 2 - 499584 + 502129 @@ -3280,7 +3309,7 @@ 1 2 - 499584 + 502129 @@ -3296,7 +3325,7 @@ 1 2 - 499584 + 502129 @@ -3310,8 +3339,8 @@ 12 - 465 - 466 + 458 + 459 1364 @@ -3374,8 +3403,8 @@ 12 - 71 - 72 + 70 + 71 1364 @@ -3390,8 +3419,8 @@ 12 - 366 - 367 + 368 + 369 1364 @@ -4848,31 +4877,31 @@ locations_default - 431212495 + 431053728 id - 431212495 + 431053728 file - 8020653 + 8017700 beginLine - 2802314 + 2801282 beginColumn - 176083 + 176018 endLine - 2803679 + 2802647 endColumn - 621068 + 620839 @@ -4886,7 +4915,7 @@ 1 2 - 431212495 + 431053728 @@ -4902,7 +4931,7 @@ 1 2 - 431212495 + 431053728 @@ -4918,7 +4947,7 @@ 1 2 - 431212495 + 431053728 @@ -4934,7 +4963,7 @@ 1 2 - 431212495 + 431053728 @@ -4950,7 +4979,7 @@ 1 2 - 431212495 + 431053728 @@ -4966,17 +4995,17 @@ 1 2 - 7179822 + 7177178 2 20 - 604688 + 604465 20 3605 - 236142 + 236055 @@ -4992,17 +5021,17 @@ 1 2 - 7179822 + 7177178 2 15 - 601958 + 601736 15 1830 - 238872 + 238784 @@ -5018,17 +5047,17 @@ 1 2 - 7179822 + 7177178 2 7 - 629258 + 629026 7 105 - 211572 + 211494 @@ -5044,17 +5073,17 @@ 1 2 - 7179822 + 7177178 2 18 - 601958 + 601736 18 1834 - 238872 + 238784 @@ -5070,17 +5099,17 @@ 1 2 - 7179822 + 7177178 2 15 - 604688 + 604465 15 205 - 236142 + 236055 @@ -5096,67 +5125,67 @@ 1 14 - 222492 + 222410 14 125 - 215667 + 215588 125 142 - 215667 + 215588 142 152 - 223857 + 223775 152 159 - 249792 + 249700 159 165 - 257982 + 257887 165 170 - 226587 + 226504 170 174 - 217032 + 216952 174 179 - 229317 + 229233 179 185 - 214302 + 214223 185 194 - 222492 + 222410 194 215 - 215667 + 215588 215 5877 - 91454 + 91420 @@ -5172,67 +5201,67 @@ 1 7 - 229317 + 229233 7 65 - 212937 + 212859 65 73 - 217032 + 216952 73 78 - 207477 + 207401 78 81 - 191097 + 191027 81 84 - 249792 + 249700 84 86 - 215667 + 215588 86 88 - 257982 + 257887 88 90 - 222492 + 222410 90 93 - 248427 + 248335 93 97 - 218397 + 218317 97 106 - 214302 + 214223 106 5877 - 117388 + 117345 @@ -5248,62 +5277,62 @@ 1 5 - 222492 + 222410 5 17 - 196557 + 196485 17 19 - 167893 + 167831 19 20 - 214302 + 214223 20 21 - 268902 + 268803 21 22 - 283916 + 283812 22 23 - 330326 + 330204 23 24 - 304391 + 304279 24 25 - 236142 + 236055 25 26 - 170623 + 170560 26 28 - 212937 + 212859 28 45 - 193827 + 193756 @@ -5319,32 +5348,32 @@ 1 2 - 904985 + 904652 2 3 - 896795 + 896465 3 4 - 483204 + 483026 4 5 - 211572 + 211494 5 11 - 221127 + 221046 11 97 - 84629 + 84597 @@ -5360,72 +5389,72 @@ 1 13 - 219762 + 219681 13 60 - 210207 + 210130 60 64 - 223857 + 223775 64 66 - 210207 + 210130 66 68 - 259347 + 259251 68 69 - 131038 + 130990 69 70 - 155608 + 155551 70 71 - 135133 + 135083 71 73 - 236142 + 236055 73 75 - 212937 + 212859 75 78 - 234777 + 234691 78 82 - 252522 + 252429 82 89 - 214302 + 214223 89 104 - 106468 + 106429 @@ -5441,67 +5470,67 @@ 1 11 - 15014 + 15009 15 34 - 15014 + 15009 36 58 - 13649 + 13644 63 88 - 13649 + 13644 89 132 - 13649 + 13644 141 196 - 15014 + 15009 210 285 - 13649 + 13644 316 468 - 13649 + 13644 496 853 - 13649 + 13644 899 1420 - 13649 + 13644 1472 2256 - 13649 + 13644 2300 2526 - 13649 + 13644 2589 226687 - 8189 + 8186 @@ -5517,72 +5546,72 @@ 1 9 - 9554 + 9551 9 11 - 13649 + 13644 12 16 - 8189 + 8186 16 19 - 13649 + 13644 19 31 - 13649 + 13644 35 73 - 13649 + 13644 73 83 - 13649 + 13644 85 104 - 15014 + 15009 104 110 - 10919 + 10915 110 114 - 15014 + 15009 115 119 - 13649 + 13644 119 121 - 12284 + 12280 121 126 - 13649 + 13644 126 5877 - 9554 + 9551 @@ -5598,67 +5627,67 @@ 1 10 - 15014 + 15009 10 29 - 13649 + 13644 29 43 - 13649 + 13644 45 58 - 13649 + 13644 58 85 - 13649 + 13644 86 106 - 13649 + 13644 108 167 - 13649 + 13644 171 227 - 13649 + 13644 231 379 - 13649 + 13644 383 650 - 13649 + 13644 651 891 - 13649 + 13644 940 1086 - 13649 + 13644 1093 2051 - 10919 + 10915 @@ -5674,67 +5703,67 @@ 1 10 - 15014 + 15009 10 30 - 13649 + 13644 30 43 - 13649 + 13644 46 59 - 13649 + 13644 60 87 - 13649 + 13644 87 109 - 13649 + 13644 115 173 - 13649 + 13644 174 226 - 13649 + 13644 230 380 - 13649 + 13644 383 650 - 13649 + 13644 653 892 - 13649 + 13644 940 1084 - 13649 + 13644 1092 2051 - 10919 + 10915 @@ -5750,67 +5779,67 @@ 1 8 - 15014 + 15009 8 17 - 13649 + 13644 18 25 - 10919 + 10915 25 30 - 13649 + 13644 30 36 - 13649 + 13644 36 44 - 13649 + 13644 45 56 - 12284 + 12280 57 64 - 13649 + 13644 64 73 - 13649 + 13644 73 86 - 13649 + 13644 86 106 - 13649 + 13644 107 129 - 13649 + 13644 129 197 - 13649 + 13644 392 @@ -5831,67 +5860,67 @@ 1 14 - 221127 + 221046 14 124 - 215667 + 215588 124 143 - 218397 + 218317 143 152 - 236142 + 236055 152 159 - 223857 + 223775 159 165 - 257982 + 257887 165 170 - 240237 + 240148 170 174 - 222492 + 222410 174 179 - 222492 + 222410 179 185 - 211572 + 211494 185 194 - 217032 + 216952 194 217 - 212937 + 212859 217 5877 - 103738 + 103700 @@ -5907,67 +5936,67 @@ 1 7 - 232047 + 231962 7 66 - 225222 + 225139 66 74 - 227952 + 227868 74 80 - 251157 + 251064 80 83 - 241602 + 241513 83 85 - 185637 + 185569 85 87 - 247062 + 246971 87 89 - 247062 + 246971 89 91 - 188367 + 188298 91 94 - 248427 + 248335 94 99 - 226587 + 226504 99 127 - 212937 + 212859 127 5877 - 69614 + 69588 @@ -5983,32 +6012,32 @@ 1 2 - 711157 + 710895 2 3 - 989614 + 989249 3 4 - 644273 + 644035 4 6 - 237507 + 237419 6 18 - 212937 + 212859 18 22 - 8189 + 8186 @@ -6024,62 +6053,62 @@ 1 5 - 219762 + 219681 5 17 - 199287 + 199214 17 19 - 163798 + 163737 19 20 - 192462 + 192392 20 21 - 281186 + 281083 21 22 - 272997 + 272896 22 23 - 330326 + 330204 23 24 - 307121 + 307008 24 25 - 225222 + 225139 25 26 - 184273 + 184205 26 28 - 223857 + 223775 28 44 - 203382 + 203307 @@ -6095,72 +6124,72 @@ 1 13 - 222492 + 222410 13 61 - 251157 + 251064 61 64 - 173353 + 173289 64 66 - 218397 + 218317 66 68 - 251157 + 251064 68 69 - 137863 + 137812 69 70 - 137863 + 137812 70 71 - 158338 + 158279 71 73 - 232047 + 231962 73 75 - 192462 + 192392 75 77 - 184273 + 184205 77 80 - 211572 + 211494 80 85 - 227952 + 227868 85 119 - 204747 + 204672 @@ -6176,57 +6205,57 @@ 1 2 - 146053 + 145999 2 3 - 64154 + 64130 3 5 - 50504 + 50485 5 13 - 50504 + 50485 13 53 - 47774 + 47756 53 146 - 47774 + 47756 146 351 - 47774 + 47756 357 997 - 47774 + 47756 1053 2396 - 47774 + 47756 2407 4957 - 47774 + 47756 5022 5934 - 23204 + 23196 @@ -6242,57 +6271,57 @@ 1 2 - 151513 + 151457 2 3 - 61424 + 61401 3 5 - 53234 + 53214 5 13 - 50504 + 50485 13 42 - 47774 + 47756 42 77 - 47774 + 47756 77 103 - 51869 + 51850 103 116 - 47774 + 47756 116 144 - 49139 + 49121 144 181 - 47774 + 47756 181 5877 - 12284 + 12280 @@ -6308,57 +6337,57 @@ 1 2 - 154243 + 154186 2 3 - 62789 + 62766 3 5 - 49139 + 49121 5 13 - 49139 + 49121 13 52 - 49139 + 49121 52 115 - 47774 + 47756 123 271 - 47774 + 47756 277 658 - 47774 + 47756 669 1200 - 47774 + 47756 1219 1635 - 47774 + 47756 1639 1722 - 17744 + 17738 @@ -6374,47 +6403,47 @@ 1 2 - 195192 + 195121 2 3 - 75074 + 75046 3 6 - 54599 + 54579 6 14 - 54599 + 54579 14 26 - 47774 + 47756 26 36 - 49139 + 49121 36 47 - 49139 + 49121 47 55 - 47774 + 47756 55 68 - 47774 + 47756 @@ -6430,57 +6459,57 @@ 1 2 - 154243 + 154186 2 3 - 61424 + 61401 3 5 - 49139 + 49121 5 13 - 49139 + 49121 13 53 - 50504 + 50485 53 115 - 47774 + 47756 123 271 - 47774 + 47756 280 656 - 47774 + 47756 669 1200 - 47774 + 47756 1217 1638 - 47774 + 47756 1640 1722 - 17744 + 17738 @@ -6490,15 +6519,15 @@ hasLocation - 316110113 + 316902470 locatableid - 315965424 + 316759199 id - 11558695 + 11554439 @@ -6512,12 +6541,12 @@ 1 2 - 315820736 + 316615929 2 3 - 144688 + 143270 @@ -6533,62 +6562,62 @@ 1 2 - 2097982 + 2097209 2 3 - 1008724 + 1008352 3 4 - 719347 + 717717 4 6 - 977329 + 978334 6 7 - 773946 + 773661 7 9 - 1019643 + 1019268 9 12 - 850385 + 848708 12 16 - 925460 + 926483 16 23 - 883145 + 882820 23 39 - 888605 + 888278 39 89 - 874955 + 873268 89 - 9987 - 539169 + 9991 + 540335 @@ -6598,23 +6627,23 @@ numlines - 215080728 + 215001538 element_id - 215080728 + 215001538 num_lines - 432700 + 432541 num_code - 434065 + 433905 num_comment - 1345875 + 1345379 @@ -6628,7 +6657,7 @@ 1 2 - 215080728 + 215001538 @@ -6644,7 +6673,7 @@ 1 2 - 215080728 + 215001538 @@ -6660,7 +6689,7 @@ 1 2 - 215080728 + 215001538 @@ -6676,37 +6705,37 @@ 1 2 - 232047 + 231962 2 3 - 53234 + 53214 3 4 - 45044 + 45027 4 7 - 34124 + 34112 7 14 - 32759 + 32747 15 839 - 32759 + 32747 3519 149603 - 2729 + 2728 @@ -6722,12 +6751,12 @@ 1 2 - 423145 + 422989 2 3 - 9554 + 9551 @@ -6743,27 +6772,27 @@ 1 2 - 274362 + 274261 2 3 - 69614 + 69588 3 4 - 36854 + 36841 4 6 - 34124 + 34112 6 987 - 17744 + 17738 @@ -6779,37 +6808,37 @@ 1 2 - 232047 + 231962 2 3 - 53234 + 53214 3 4 - 45044 + 45027 4 7 - 34124 + 34112 7 14 - 32759 + 32747 15 468 - 32759 + 32747 495 78746 - 4094 + 4093 @@ -6825,7 +6854,7 @@ 1 2 - 432700 + 432541 7 @@ -6846,27 +6875,27 @@ 1 2 - 274362 + 274261 2 3 - 69614 + 69588 3 4 - 36854 + 36841 4 6 - 34124 + 34112 6 987 - 19109 + 19102 @@ -6882,77 +6911,77 @@ 1 7 - 109198 + 109158 7 49 - 101008 + 100971 49 71 - 105103 + 105065 71 78 - 107833 + 107794 78 83 - 103738 + 103700 83 87 - 116023 + 115981 87 89 - 99643 + 99607 89 91 - 95548 + 95513 91 92 - 57329 + 57308 92 93 - 68249 + 68224 93 94 - 75074 + 75046 94 95 - 69614 + 69588 95 97 - 109198 + 109158 97 119 - 101008 + 100971 119 75115 - 27299 + 27289 @@ -6968,22 +6997,22 @@ 1 2 - 1104273 + 1103866 2 3 - 114658 + 114616 3 6 - 102373 + 102336 6 120 - 24569 + 24560 @@ -6999,22 +7028,22 @@ 1 2 - 1104273 + 1103866 2 3 - 114658 + 114616 3 6 - 101008 + 100971 6 121 - 25934 + 25925 @@ -7024,15 +7053,15 @@ files - 8020653 + 8017700 id - 8020653 + 8017700 name - 8020653 + 8017700 @@ -7046,7 +7075,7 @@ 1 2 - 8020653 + 8017700 @@ -7062,7 +7091,7 @@ 1 2 - 8020653 + 8017700 @@ -7072,15 +7101,15 @@ folders - 1280356 + 1279884 id - 1280356 + 1279884 name - 1280356 + 1279884 @@ -7094,7 +7123,7 @@ 1 2 - 1280356 + 1279884 @@ -7110,7 +7139,7 @@ 1 2 - 1280356 + 1279884 @@ -7120,15 +7149,15 @@ containerparent - 9298279 + 9294856 parent - 1321305 + 1320819 child - 9298279 + 9294856 @@ -7142,37 +7171,37 @@ 1 2 - 713887 + 713624 2 3 - 140593 + 140541 3 4 - 79169 + 79139 4 7 - 113293 + 113252 7 14 - 111928 + 111887 14 29 - 102373 + 102336 29 194 - 60059 + 60037 @@ -7188,7 +7217,7 @@ 1 2 - 9298279 + 9294856 @@ -7198,15 +7227,15 @@ cupackage - 7160712 + 7158076 id - 7160712 + 7158076 packageid - 611513 + 611288 @@ -7220,7 +7249,7 @@ 1 2 - 7160712 + 7158076 @@ -7236,52 +7265,52 @@ 1 2 - 148783 + 148728 2 3 - 80534 + 80504 3 4 - 55964 + 55943 4 5 - 42314 + 42298 5 7 - 46409 + 46392 7 10 - 50504 + 50485 10 15 - 50504 + 50485 15 21 - 49139 + 49121 21 36 - 47774 + 47756 39 187 - 39584 + 39569 @@ -8043,15 +8072,15 @@ packages - 612878 + 612652 id - 612878 + 612652 nodeName - 612878 + 612652 @@ -8065,7 +8094,7 @@ 1 2 - 612878 + 612652 @@ -8081,7 +8110,7 @@ 1 2 - 612878 + 612652 @@ -8091,15 +8120,15 @@ primitives - 12284 + 12280 id - 12284 + 12280 nodeName - 12284 + 12280 @@ -8113,7 +8142,7 @@ 1 2 - 12284 + 12280 @@ -8129,7 +8158,7 @@ 1 2 - 12284 + 12280 @@ -8139,15 +8168,15 @@ modifiers - 12284 + 13644 id - 12284 + 13644 nodeName - 12284 + 13644 @@ -8161,7 +8190,7 @@ 1 2 - 12284 + 13644 @@ -8177,7 +8206,7 @@ 1 2 - 12284 + 13644 @@ -8186,24 +8215,35 @@ - classes - 12579704 + error_type + 1 id - 12579704 + 1 + + + + + + classes + 12579165 + + + id + 12579165 nodeName - 6868605 + 6871534 parentid - 443620 + 443456 sourceid - 4519466 + 4517802 @@ -8217,7 +8257,7 @@ 1 2 - 12579704 + 12579165 @@ -8233,7 +8273,7 @@ 1 2 - 12579704 + 12579165 @@ -8249,7 +8289,7 @@ 1 2 - 12579704 + 12579165 @@ -8265,17 +8305,17 @@ 1 2 - 5735668 + 5740378 2 3 - 746646 + 745007 3 236 - 386290 + 386148 @@ -8291,17 +8331,17 @@ 1 2 - 6252997 + 6256153 2 3 - 547359 + 547157 3 52 - 68249 + 68224 @@ -8317,17 +8357,17 @@ 1 2 - 6229792 + 6232956 2 3 - 536439 + 536241 3 160 - 102373 + 102336 @@ -8343,57 +8383,57 @@ 1 2 - 107833 + 107794 2 3 - 54599 + 54579 3 4 - 32759 + 32747 4 5 - 30029 + 30018 5 7 - 34124 + 34112 7 11 - 40949 + 40934 11 17 - 34124 + 34112 17 23 - 34124 + 34112 23 40 - 36854 + 36841 40 707 - 34124 + 34112 1013 - 1412 - 4094 + 1414 + 4093 @@ -8409,52 +8449,52 @@ 1 2 - 107833 + 107794 2 3 - 54599 + 54579 3 4 - 35489 + 35476 4 5 - 34124 + 34112 5 7 - 38219 + 38205 7 11 - 40949 + 40934 11 17 - 36854 + 36841 17 23 - 34124 + 34112 23 40 - 35489 + 35476 40 - 828 - 25934 + 830 + 25925 @@ -8470,52 +8510,52 @@ 1 2 - 118753 + 118709 2 3 - 64154 + 64130 3 4 - 36854 + 36841 4 5 - 34124 + 34112 5 7 - 35489 + 35476 7 11 - 40949 + 40934 11 17 - 34124 + 34112 17 26 - 34124 + 34112 26 56 - 34124 + 34112 64 138 - 10919 + 10915 @@ -8531,17 +8571,17 @@ 1 2 - 4052641 + 4051149 2 11 - 342611 + 342485 11 1358 - 124213 + 124167 @@ -8557,17 +8597,17 @@ 1 2 - 4052641 + 4051149 2 6 - 360356 + 360223 6 783 - 106468 + 106429 @@ -8583,7 +8623,7 @@ 1 2 - 4519466 + 4517802 @@ -8593,26 +8633,26 @@ file_class - 15014 + 15009 id - 15014 + 15009 class_object - 122848 + 122803 id - 122848 + 122803 instance - 122848 + 122803 @@ -8626,7 +8666,7 @@ 1 2 - 122848 + 122803 @@ -8642,7 +8682,7 @@ 1 2 - 122848 + 122803 @@ -8652,19 +8692,19 @@ type_companion_object - 218397 + 218317 id - 218397 + 218317 instance - 218397 + 218317 companion_object - 218397 + 218317 @@ -8678,7 +8718,7 @@ 1 2 - 218397 + 218317 @@ -8694,7 +8734,7 @@ 1 2 - 218397 + 218317 @@ -8710,7 +8750,7 @@ 1 2 - 218397 + 218317 @@ -8726,7 +8766,7 @@ 1 2 - 218397 + 218317 @@ -8742,7 +8782,7 @@ 1 2 - 218397 + 218317 @@ -8758,7 +8798,7 @@ 1 2 - 218397 + 218317 @@ -8816,15 +8856,15 @@ kt_notnull_types - 193427 + 194340 id - 193427 + 194340 classid - 193427 + 194340 @@ -8838,7 +8878,7 @@ 1 2 - 193427 + 194340 @@ -8854,7 +8894,7 @@ 1 2 - 193427 + 194340 @@ -9437,15 +9477,15 @@ fielddecls - 399940 + 399793 id - 399940 + 399793 parentid - 60059 + 60037 @@ -9459,7 +9499,7 @@ 1 2 - 399940 + 399793 @@ -9475,32 +9515,32 @@ 1 2 - 30029 + 30018 2 3 - 13649 + 13644 3 4 - 5459 + 5457 4 5 - 2729 + 2728 6 16 - 5459 + 5457 40 159 - 2729 + 2728 @@ -9510,15 +9550,15 @@ fieldDeclaredIn - 399940 + 399793 fieldId - 399940 + 399793 fieldDeclId - 399940 + 399793 pos @@ -9536,7 +9576,7 @@ 1 2 - 399940 + 399793 @@ -9552,7 +9592,7 @@ 1 2 - 399940 + 399793 @@ -9568,7 +9608,7 @@ 1 2 - 399940 + 399793 @@ -9584,7 +9624,7 @@ 1 2 - 399940 + 399793 @@ -9626,27 +9666,27 @@ fields - 27583622 + 27573466 id - 27583622 + 27573466 nodeName - 10929437 + 10925412 typeid - 2735430 + 2734423 parentid - 3861543 + 3860121 sourceid - 27583622 + 27573466 @@ -9660,7 +9700,7 @@ 1 2 - 27583622 + 27573466 @@ -9676,7 +9716,7 @@ 1 2 - 27583622 + 27573466 @@ -9692,7 +9732,7 @@ 1 2 - 27583622 + 27573466 @@ -9708,7 +9748,7 @@ 1 2 - 27583622 + 27573466 @@ -9724,22 +9764,22 @@ 1 2 - 8083442 + 8080466 2 3 - 1437329 + 1436800 3 11 - 763026 + 762745 11 828 - 645638 + 645400 @@ -9755,17 +9795,17 @@ 1 2 - 9901603 + 9897957 2 4 - 853115 + 852801 4 160 - 174718 + 174653 @@ -9781,22 +9821,22 @@ 1 2 - 8083442 + 8080466 2 3 - 1437329 + 1436800 3 11 - 763026 + 762745 11 828 - 645638 + 645400 @@ -9812,22 +9852,22 @@ 1 2 - 8083442 + 8080466 2 3 - 1437329 + 1436800 3 11 - 763026 + 762745 11 828 - 645638 + 645400 @@ -9843,32 +9883,32 @@ 1 2 - 1737626 + 1736986 2 3 - 339881 + 339756 3 4 - 176083 + 176018 4 7 - 208842 + 208765 7 24 - 206112 + 206036 24 7479 - 66884 + 66859 @@ -9884,27 +9924,27 @@ 1 2 - 1900059 + 1899359 2 3 - 303026 + 302915 3 4 - 184273 + 184205 4 9 - 212937 + 212859 9 2335 - 135133 + 135083 @@ -9920,17 +9960,17 @@ 1 2 - 2332759 + 2331900 2 4 - 229317 + 229233 4 1392 - 173353 + 173289 @@ -9946,32 +9986,32 @@ 1 2 - 1737626 + 1736986 2 3 - 339881 + 339756 3 4 - 176083 + 176018 4 7 - 208842 + 208765 7 24 - 206112 + 206036 24 7479 - 66884 + 66859 @@ -9987,37 +10027,37 @@ 1 2 - 1942374 + 1941658 2 3 - 485934 + 485755 3 4 - 304391 + 304279 4 6 - 342611 + 342485 6 10 - 301661 + 301550 10 27 - 292106 + 291999 27 1610 - 192462 + 192392 @@ -10033,37 +10073,37 @@ 1 2 - 1942374 + 1941658 2 3 - 485934 + 485755 3 4 - 304391 + 304279 4 6 - 342611 + 342485 6 10 - 301661 + 301550 10 27 - 292106 + 291999 27 1610 - 192462 + 192392 @@ -10079,27 +10119,27 @@ 1 2 - 2506112 + 2505190 2 3 - 625163 + 624933 3 4 - 244332 + 244242 4 7 - 339881 + 339756 7 76 - 146053 + 145999 @@ -10115,37 +10155,37 @@ 1 2 - 1942374 + 1941658 2 3 - 485934 + 485755 3 4 - 304391 + 304279 4 6 - 342611 + 342485 6 10 - 301661 + 301550 10 27 - 292106 + 291999 27 1610 - 192462 + 192392 @@ -10161,7 +10201,7 @@ 1 2 - 27583622 + 27573466 @@ -10177,7 +10217,7 @@ 1 2 - 27583622 + 27573466 @@ -10193,7 +10233,7 @@ 1 2 - 27583622 + 27573466 @@ -10209,7 +10249,7 @@ 1 2 - 27583622 + 27573466 @@ -10219,11 +10259,11 @@ fieldsKotlinType - 27583622 + 27573466 id - 27583622 + 27573466 kttypeid @@ -10241,7 +10281,7 @@ 1 2 - 27583622 + 27573466 @@ -10267,31 +10307,31 @@ constrs - 6889080 + 6886544 id - 6889080 + 6886544 nodeName - 3756439 + 3755056 signature - 5887181 + 5885013 typeid - 2729 + 2728 parentid - 4849792 + 4848007 sourceid - 5069555 + 5067688 @@ -10305,7 +10345,7 @@ 1 2 - 6889080 + 6886544 @@ -10321,7 +10361,7 @@ 1 2 - 6889080 + 6886544 @@ -10337,7 +10377,7 @@ 1 2 - 6889080 + 6886544 @@ -10353,7 +10393,7 @@ 1 2 - 6889080 + 6886544 @@ -10369,7 +10409,7 @@ 1 2 - 6889080 + 6886544 @@ -10385,22 +10425,22 @@ 1 2 - 2366884 + 2366012 2 3 - 839465 + 839156 3 5 - 346706 + 346578 5 42 - 203382 + 203307 @@ -10416,22 +10456,22 @@ 1 2 - 2635786 + 2634816 2 3 - 685222 + 684970 3 5 - 303026 + 302915 5 19 - 132403 + 132354 @@ -10447,7 +10487,7 @@ 1 2 - 3756439 + 3755056 @@ -10463,17 +10503,17 @@ 1 2 - 3295074 + 3293861 2 3 - 316676 + 316559 3 42 - 144688 + 144635 @@ -10489,22 +10529,22 @@ 1 2 - 2458338 + 2457433 2 3 - 831276 + 830969 3 5 - 319406 + 319288 5 38 - 147418 + 147364 @@ -10520,12 +10560,12 @@ 1 2 - 5474955 + 5472940 2 42 - 412225 + 412073 @@ -10541,7 +10581,7 @@ 1 2 - 5887181 + 5885013 @@ -10557,7 +10597,7 @@ 1 2 - 5887181 + 5885013 @@ -10573,12 +10613,12 @@ 1 2 - 5474955 + 5472940 2 42 - 412225 + 412073 @@ -10594,12 +10634,12 @@ 1 2 - 5604629 + 5602565 2 32 - 282551 + 282447 @@ -10720,22 +10760,22 @@ 1 2 - 3688190 + 3686832 2 3 - 739822 + 739549 3 6 - 367181 + 367045 6 19 - 54599 + 54579 @@ -10751,7 +10791,7 @@ 1 2 - 4849792 + 4848007 @@ -10767,22 +10807,22 @@ 1 2 - 3688190 + 3686832 2 3 - 739822 + 739549 3 6 - 367181 + 367045 6 19 - 54599 + 54579 @@ -10798,7 +10838,7 @@ 1 2 - 4849792 + 4848007 @@ -10814,22 +10854,22 @@ 1 2 - 3688190 + 3686832 2 3 - 739822 + 739549 3 6 - 367181 + 367045 6 19 - 54599 + 54579 @@ -10845,12 +10885,12 @@ 1 2 - 4756973 + 4755222 2 259 - 312581 + 312466 @@ -10866,12 +10906,12 @@ 1 2 - 4756973 + 4755222 2 212 - 312581 + 312466 @@ -10887,12 +10927,12 @@ 1 2 - 4756973 + 4755222 2 212 - 312581 + 312466 @@ -10908,7 +10948,7 @@ 1 2 - 5069555 + 5067688 @@ -10924,12 +10964,12 @@ 1 2 - 4756973 + 4755222 2 259 - 312581 + 312466 @@ -10939,11 +10979,11 @@ constrsKotlinType - 6889080 + 6886544 id - 6889080 + 6886544 kttypeid @@ -10961,7 +11001,7 @@ 1 2 - 6889080 + 6886544 @@ -10987,31 +11027,31 @@ methods - 93482380 + 93447961 id - 93482380 + 93447961 nodeName - 20395609 + 20385371 signature - 29871337 + 29857610 typeid - 11611929 + 11610383 parentid - 11303442 + 11299281 sourceid - 58623387 + 58601802 @@ -11025,7 +11065,7 @@ 1 2 - 93482380 + 93447961 @@ -11041,7 +11081,7 @@ 1 2 - 93482380 + 93447961 @@ -11057,7 +11097,7 @@ 1 2 - 93482380 + 93447961 @@ -11073,7 +11113,7 @@ 1 2 - 93482380 + 93447961 @@ -11089,7 +11129,7 @@ 1 2 - 93482380 + 93447961 @@ -11105,32 +11145,32 @@ 1 2 - 11927241 + 11921485 2 3 - 3791929 + 3790532 3 4 - 1317210 + 1316725 4 7 - 1789495 + 1788836 7 - 259 - 1530148 + 271 + 1529585 - 270 + 276 2134 - 39584 + 38205 @@ -11146,17 +11186,17 @@ 1 2 - 16912167 + 16903211 2 3 - 2122552 + 2121770 3 361 - 1360890 + 1360389 @@ -11172,22 +11212,22 @@ 1 2 - 17141484 + 17133809 2 3 - 1683026 + 1682407 3 - 52 - 1530148 + 53 + 1529585 - 52 + 53 845 - 40949 + 39569 @@ -11203,27 +11243,27 @@ 1 2 - 12654778 + 12648754 2 3 - 3558516 + 3557206 3 4 - 1250326 + 1249866 4 7 - 1575192 + 1574613 7 1278 - 1356795 + 1354931 @@ -11239,27 +11279,27 @@ 1 2 - 12309437 + 12302175 2 3 - 3921602 + 3921523 3 4 - 1298100 + 1297623 4 7 - 1654362 + 1653753 7 928 - 1212106 + 1210296 @@ -11275,22 +11315,22 @@ 1 2 - 20522553 + 20513632 2 3 - 4879822 + 4878025 3 5 - 2368249 + 2367377 5 1275 - 2100712 + 2098574 @@ -11306,7 +11346,7 @@ 1 2 - 29871337 + 29857610 @@ -11322,17 +11362,17 @@ 1 2 - 26823325 + 26812084 2 5 - 2390089 + 2389209 5 843 - 657922 + 656316 @@ -11348,22 +11388,22 @@ 1 2 - 20526648 + 20517726 2 3 - 4878457 + 4876661 3 5 - 2366884 + 2366012 5 1275 - 2099347 + 2097209 @@ -11379,22 +11419,22 @@ 1 2 - 21147716 + 21137201 2 3 - 4997211 + 4996735 3 6 - 2537507 + 2536573 6 923 - 1188902 + 1187099 @@ -11410,32 +11450,32 @@ 1 2 - 5705638 + 5703537 2 3 - 2455608 + 2457433 3 4 - 1087893 + 1087492 4 6 - 924095 + 925119 6 14 - 877685 + 875997 14 11682 - 561008 + 560802 @@ -11451,22 +11491,22 @@ 1 2 - 7632997 + 7632916 2 3 - 2222196 + 2221377 3 6 - 1063323 + 1064296 6 3956 - 693412 + 691792 @@ -11482,27 +11522,27 @@ 1 2 - 7390030 + 7388673 2 3 - 2276795 + 2278686 3 5 - 879050 + 878726 5 17 - 884510 + 882820 17 5707 - 181543 + 181476 @@ -11518,27 +11558,27 @@ 1 2 - 6811276 + 6808768 2 3 - 2467893 + 2471078 3 4 - 1004629 + 1004259 4 9 - 917270 + 915567 9 3421 - 410860 + 410709 @@ -11554,32 +11594,32 @@ 1 2 - 6202493 + 6200209 2 3 - 2268605 + 2270499 3 4 - 984154 + 983792 4 6 - 909080 + 910109 6 16 - 892700 + 891007 16 8870 - 354896 + 354765 @@ -11595,52 +11635,52 @@ 1 2 - 3200890 + 3199711 2 3 - 1298100 + 1297623 3 4 - 1027833 + 1027455 4 5 - 748011 + 747736 5 7 - 925460 + 925119 7 10 - 959584 + 959231 10 13 - 997804 + 997436 13 19 - 909080 + 908745 19 38 - 910445 + 910109 38 319 - 326231 + 326111 @@ -11656,52 +11696,52 @@ 1 2 - 3254124 + 3252926 2 3 - 1318575 + 1318090 3 4 - 1108368 + 1107959 4 5 - 788961 + 788670 5 7 - 888605 + 888278 7 10 - 1021008 + 1020633 10 13 - 941839 + 942857 13 17 - 876320 + 874633 17 35 - 850385 + 850072 35 290 - 255252 + 255158 @@ -11717,52 +11757,52 @@ 1 2 - 3200890 + 3199711 2 3 - 1298100 + 1297623 3 4 - 1027833 + 1027455 4 5 - 748011 + 747736 5 7 - 925460 + 925119 7 10 - 959584 + 959231 10 13 - 997804 + 997436 13 19 - 909080 + 908745 19 38 - 910445 + 910109 38 319 - 326231 + 326111 @@ -11778,47 +11818,47 @@ 1 2 - 3901127 + 3899691 2 3 - 1624332 + 1623734 3 4 - 1329495 + 1329006 4 5 - 790326 + 790035 5 6 - 636083 + 635848 6 7 - 502314 + 502129 7 9 - 1034658 + 1034277 9 13 - 881780 + 881455 13 78 - 603323 + 603101 @@ -11834,52 +11874,52 @@ 1 2 - 3200890 + 3199711 2 3 - 1298100 + 1297623 3 4 - 1027833 + 1027455 4 5 - 748011 + 747736 5 7 - 925460 + 925119 7 10 - 959584 + 959231 10 13 - 997804 + 997436 13 19 - 909080 + 908745 19 38 - 910445 + 910109 38 319 - 326231 + 326111 @@ -11895,12 +11935,12 @@ 1 2 - 54259529 + 54239551 2 349 - 4363857 + 4362251 @@ -11916,7 +11956,7 @@ 1 2 - 58623387 + 58601802 @@ -11932,12 +11972,12 @@ 1 2 - 58339470 + 58317990 2 347 - 283916 + 283812 @@ -11953,12 +11993,12 @@ 1 2 - 56923980 + 56903021 2 259 - 1699406 + 1698780 @@ -11974,12 +12014,12 @@ 1 2 - 54259529 + 54239551 2 349 - 4363857 + 4362251 @@ -11989,11 +12029,11 @@ methodsKotlinType - 93482380 + 93447961 id - 93482380 + 93447961 kttypeid @@ -12011,7 +12051,7 @@ 1 2 - 93482380 + 93447961 @@ -12037,27 +12077,27 @@ params - 101137218 + 101099980 id - 101137218 + 101099980 typeid - 11278873 + 11198309 pos - 30029 + 30018 parentid - 56339766 + 56319023 sourceid - 61326058 + 61303478 @@ -12071,7 +12111,7 @@ 1 2 - 101137218 + 101099980 @@ -12087,7 +12127,7 @@ 1 2 - 101137218 + 101099980 @@ -12103,7 +12143,7 @@ 1 2 - 101137218 + 101099980 @@ -12119,7 +12159,7 @@ 1 2 - 101137218 + 101099980 @@ -12135,32 +12175,32 @@ 1 2 - 6038694 + 5955966 2 3 - 1756736 + 1720612 3 4 - 853115 + 873268 4 6 - 966409 + 974240 6 12 - 854480 + 866446 12 7464 - 809436 + 807773 @@ -12176,17 +12216,17 @@ 1 2 - 9331039 + 9255286 2 3 - 1156142 + 1159810 3 17 - 791691 + 783213 @@ -12202,32 +12242,32 @@ 1 2 - 6227062 + 6146994 2 3 - 1726706 + 1685136 3 4 - 873590 + 893736 4 6 - 909080 + 918296 6 13 - 854480 + 866446 13 5239 - 687952 + 687699 @@ -12243,32 +12283,32 @@ 1 2 - 6433175 + 6350302 2 3 - 1613412 + 1577341 3 4 - 884510 + 904652 4 6 - 943204 + 951044 6 - 14 - 889970 + 13 + 854166 - 14 + 13 6287 - 514599 + 560802 @@ -12284,57 +12324,57 @@ 1 2 - 2729 + 2728 53 56 - 2729 + 2728 110 112 - 2729 + 2728 165 172 - 2729 + 2728 224 242 - 2729 + 2728 304 329 - 2729 + 2728 523 665 - 2729 + 2728 879 1140 - 2729 + 2728 1514 2087 - 2729 + 2728 3295 5932 - 2729 + 2728 15024 41276 - 2729 + 2728 @@ -12350,57 +12390,57 @@ 1 2 - 2729 + 2728 2 5 - 2729 + 2728 6 7 - 2729 + 2728 10 12 - 2729 + 2728 13 19 - 2729 + 2728 26 38 - 2729 + 2728 57 76 - 2729 + 2728 99 159 - 2729 + 2728 212 - 305 - 2729 + 306 + 2728 - 451 + 452 888 - 2729 + 2728 - 2378 - 6326 - 2729 + 2370 + 6266 + 2728 @@ -12416,57 +12456,57 @@ 1 2 - 2729 + 2728 53 56 - 2729 + 2728 110 112 - 2729 + 2728 165 172 - 2729 + 2728 224 242 - 2729 + 2728 304 329 - 2729 + 2728 523 665 - 2729 + 2728 879 1140 - 2729 + 2728 1514 2087 - 2729 + 2728 3295 5932 - 2729 + 2728 15024 41276 - 2729 + 2728 @@ -12482,57 +12522,57 @@ 1 2 - 2729 + 2728 2 5 - 2729 + 2728 6 8 - 2729 + 2728 10 13 - 2729 + 2728 14 28 - 2729 + 2728 37 62 - 2729 + 2728 97 137 - 2729 + 2728 192 342 - 2729 + 2728 553 963 - 2729 + 2728 1950 4155 - 2729 + 2728 10027 26335 - 2729 + 2728 @@ -12548,27 +12588,27 @@ 1 2 - 35832228 + 35819035 2 3 - 12411811 + 12407241 3 4 - 3598101 + 3596776 4 15 - 4264213 + 4262643 15 23 - 233412 + 233326 @@ -12584,17 +12624,17 @@ 1 2 - 39830270 + 39815605 2 3 - 12671158 + 12666492 3 23 - 3838338 + 3836925 @@ -12610,27 +12650,27 @@ 1 2 - 35832228 + 35819035 2 3 - 12411811 + 12407241 3 4 - 3598101 + 3596776 4 15 - 4264213 + 4262643 15 23 - 233412 + 233326 @@ -12646,27 +12686,27 @@ 1 2 - 35832228 + 35819035 2 3 - 12411811 + 12407241 3 4 - 3598101 + 3596776 4 15 - 4264213 + 4262643 15 23 - 233412 + 233326 @@ -12682,12 +12722,12 @@ 1 2 - 56895315 + 56874367 2 349 - 4430742 + 4429110 @@ -12703,12 +12743,12 @@ 1 2 - 59783624 + 59761613 2 349 - 1542433 + 1541865 @@ -12724,7 +12764,7 @@ 1 2 - 61326058 + 61303478 @@ -12740,12 +12780,12 @@ 1 2 - 56895315 + 56874367 2 349 - 4430742 + 4429110 @@ -12755,11 +12795,11 @@ paramsKotlinType - 101137218 + 101099980 id - 101137218 + 101099980 kttypeid @@ -12777,7 +12817,7 @@ 1 2 - 101137218 + 101099980 @@ -12803,15 +12843,15 @@ paramName - 101137218 + 10199508 id - 101137218 + 10199508 nodeName - 1688486 + 1666033 @@ -12825,7 +12865,7 @@ 1 2 - 101137218 + 10199508 @@ -12841,37 +12881,37 @@ 1 2 - 719347 + 729998 2 3 - 331691 + 338391 3 4 - 173353 + 169195 4 5 - 114658 + 117345 5 9 - 144688 + 140541 9 25 - 126943 + 126896 25 - 32680 - 77804 + 516 + 43663 @@ -12881,11 +12921,11 @@ isVarargsParam - 1005994 + 1005623 param - 1005994 + 1005623 @@ -13108,11 +13148,11 @@ isAnnotType - 29833 + 30064 interfaceid - 29833 + 30064 @@ -13396,11 +13436,11 @@ isEnumType - 350801 + 350672 classid - 350801 + 350672 @@ -13418,19 +13458,19 @@ typeVars - 5118694 + 5116810 id - 5118694 + 5116810 nodeName - 70979 + 70953 pos - 5459 + 5457 kind @@ -13438,7 +13478,7 @@ parentid - 3725044 + 3723673 @@ -13452,7 +13492,7 @@ 1 2 - 5118694 + 5116810 @@ -13468,7 +13508,7 @@ 1 2 - 5118694 + 5116810 @@ -13484,7 +13524,7 @@ 1 2 - 5118694 + 5116810 @@ -13500,7 +13540,7 @@ 1 2 - 5118694 + 5116810 @@ -13516,47 +13556,47 @@ 1 2 - 20474 + 20467 2 3 - 10919 + 10915 3 4 - 6824 + 6822 4 7 - 5459 + 5457 7 10 - 5459 + 5457 10 28 - 5459 + 5457 37 71 - 5459 + 5457 71 253 - 5459 + 5457 459 951 - 5459 + 5457 @@ -13572,17 +13612,17 @@ 1 2 - 45044 + 45027 2 3 - 16379 + 16373 3 4 - 8189 + 8186 4 @@ -13603,7 +13643,7 @@ 1 2 - 70979 + 70953 @@ -13619,47 +13659,47 @@ 1 2 - 20474 + 20467 2 3 - 10919 + 10915 3 4 - 6824 + 6822 4 7 - 5459 + 5457 7 10 - 5459 + 5457 10 28 - 5459 + 5457 37 71 - 5459 + 5457 71 253 - 5459 + 5457 459 951 - 5459 + 5457 @@ -13737,7 +13777,7 @@ 1 2 - 5459 + 5457 @@ -13848,17 +13888,17 @@ 1 2 - 2467893 + 2466984 2 3 - 1128842 + 1128427 3 5 - 128308 + 128261 @@ -13874,17 +13914,17 @@ 1 2 - 2467893 + 2466984 2 3 - 1128842 + 1128427 3 5 - 128308 + 128261 @@ -13900,17 +13940,17 @@ 1 2 - 2467893 + 2466984 2 3 - 1128842 + 1128427 3 5 - 128308 + 128261 @@ -13926,7 +13966,7 @@ 1 2 - 3725044 + 3723673 @@ -13936,19 +13976,19 @@ wildcards - 3116261 + 3637710 id - 3116261 + 3637710 nodeName - 859940 + 982427 kind - 2729 + 2728 @@ -13962,7 +14002,7 @@ 1 2 - 3116261 + 3637710 @@ -13978,7 +14018,7 @@ 1 2 - 3116261 + 3637710 @@ -13994,17 +14034,17 @@ 1 2 - 683857 + 791399 2 3 - 110563 + 120074 3 - 170 - 65519 + 214 + 70953 @@ -14020,7 +14060,7 @@ 1 2 - 859940 + 982427 @@ -14034,13 +14074,13 @@ 12 - 898 - 899 + 1027 + 1028 1364 - 1385 - 1386 + 1639 + 1640 1364 @@ -14055,13 +14095,13 @@ 12 - 196 - 197 + 222 + 223 1364 - 434 - 435 + 498 + 499 1364 @@ -14072,15 +14112,15 @@ typeBounds - 3872463 + 4393634 id - 3872463 + 4393634 typeid - 2723145 + 3191525 pos @@ -14088,7 +14128,7 @@ parentid - 3872463 + 4393634 @@ -14102,7 +14142,7 @@ 1 2 - 3872463 + 4393634 @@ -14118,7 +14158,7 @@ 1 2 - 3872463 + 4393634 @@ -14134,7 +14174,7 @@ 1 2 - 3872463 + 4393634 @@ -14150,17 +14190,17 @@ 1 2 - 2093887 + 2512012 2 3 - 552819 + 603101 3 - 51 - 76439 + 52 + 76411 @@ -14176,7 +14216,7 @@ 1 2 - 2723145 + 3191525 @@ -14192,17 +14232,17 @@ 1 2 - 2093887 + 2512012 2 3 - 552819 + 603101 3 - 51 - 76439 + 52 + 76411 @@ -14216,8 +14256,8 @@ 12 - 2837 - 2838 + 3220 + 3221 1364 @@ -14232,8 +14272,8 @@ 12 - 1995 - 1996 + 2339 + 2340 1364 @@ -14248,8 +14288,8 @@ 12 - 2837 - 2838 + 3220 + 3221 1364 @@ -14266,7 +14306,7 @@ 1 2 - 3872463 + 4393634 @@ -14282,7 +14322,7 @@ 1 2 - 3872463 + 4393634 @@ -14298,7 +14338,7 @@ 1 2 - 3872463 + 4393634 @@ -14604,37 +14644,37 @@ isParameterized - 24792227 + 25167883 memberid - 24792227 + 25167883 isRaw - 642908 + 642671 memberid - 642908 + 642671 erasure - 25435135 + 25810554 memberid - 25435135 + 25810554 erasureid - 868130 + 867810 @@ -14648,7 +14688,7 @@ 1 2 - 25435135 + 25810554 @@ -14664,57 +14704,57 @@ 1 2 - 144688 + 144635 2 3 - 133768 + 133719 3 4 - 88724 + 88691 4 5 - 55964 + 54579 5 6 - 51869 + 50485 6 8 - 62789 + 64130 8 11 - 77804 + 79139 11 19 - 70979 + 70953 19 33 - 70979 + 70953 33 93 - 65519 + 65495 97 - 1723 - 45044 + 1848 + 45027 @@ -14724,15 +14764,15 @@ isAnonymClass - 194713 + 195608 classid - 194713 + 195608 parent - 194713 + 195608 @@ -14746,7 +14786,7 @@ 1 2 - 194713 + 195608 @@ -14762,7 +14802,7 @@ 1 2 - 194713 + 195608 @@ -14772,15 +14812,15 @@ isLocalClassOrInterface - 4069 + 4110 typeid - 4069 + 4110 parent - 4069 + 4110 @@ -14794,7 +14834,7 @@ 1 2 - 4069 + 4110 @@ -14810,7 +14850,7 @@ 1 2 - 4069 + 4110 @@ -14831,15 +14871,15 @@ lambdaKind - 185816 + 186985 exprId - 185816 + 186985 bodyKind - 15 + 16 @@ -14853,7 +14893,7 @@ 1 2 - 185816 + 186985 @@ -14867,9 +14907,9 @@ 12 - 11987 - 11988 - 15 + 11644 + 11645 + 16 @@ -14879,27 +14919,27 @@ arrays - 1119287 + 1118875 id - 1119287 + 1118875 nodeName - 689317 + 689063 elementtypeid - 1112462 + 1112053 dimension - 2729 + 2728 componenttypeid - 1119287 + 1118875 @@ -14913,7 +14953,7 @@ 1 2 - 1119287 + 1118875 @@ -14929,7 +14969,7 @@ 1 2 - 1119287 + 1118875 @@ -14945,7 +14985,7 @@ 1 2 - 1119287 + 1118875 @@ -14961,7 +15001,7 @@ 1 2 - 1119287 + 1118875 @@ -14977,17 +15017,17 @@ 1 2 - 563738 + 563531 2 3 - 99643 + 99607 3 95 - 25934 + 25925 @@ -15003,17 +15043,17 @@ 1 2 - 563738 + 563531 2 3 - 99643 + 99607 3 95 - 25934 + 25925 @@ -15029,7 +15069,7 @@ 1 2 - 689317 + 689063 @@ -15045,17 +15085,17 @@ 1 2 - 563738 + 563531 2 3 - 99643 + 99607 3 95 - 25934 + 25925 @@ -15071,12 +15111,12 @@ 1 2 - 1105638 + 1105230 2 3 - 6824 + 6822 @@ -15092,12 +15132,12 @@ 1 2 - 1105638 + 1105230 2 3 - 6824 + 6822 @@ -15113,12 +15153,12 @@ 1 2 - 1105638 + 1105230 2 3 - 6824 + 6822 @@ -15134,12 +15174,12 @@ 1 2 - 1105638 + 1105230 2 3 - 6824 + 6822 @@ -15239,7 +15279,7 @@ 1 2 - 1119287 + 1118875 @@ -15255,7 +15295,7 @@ 1 2 - 1119287 + 1118875 @@ -15271,7 +15311,7 @@ 1 2 - 1119287 + 1118875 @@ -15287,7 +15327,7 @@ 1 2 - 1119287 + 1118875 @@ -15297,15 +15337,15 @@ enclInReftype - 3417923 + 3419393 child - 3417923 + 3419393 parent - 928189 + 927848 @@ -15319,7 +15359,7 @@ 1 2 - 3417923 + 3419393 @@ -15335,32 +15375,32 @@ 1 2 - 545994 + 545793 2 3 - 150148 + 150093 3 4 - 70979 + 70953 4 7 - 83264 + 83233 7 48 - 69614 + 69588 50 - 277 - 8189 + 279 + 8186 @@ -15370,15 +15410,15 @@ extendsReftype - 47612051 + 47979305 id1 - 33730150 + 34102515 id2 - 13910564 + 14050078 @@ -15392,22 +15432,22 @@ 1 2 - 25830981 + 26206254 2 3 - 3150385 + 3149226 3 4 - 3643145 + 3641804 4 10 - 1105638 + 1105230 @@ -15423,17 +15463,17 @@ 1 2 - 11822137 + 11956961 2 3 - 1423679 + 1429977 3 - 12114 - 664747 + 12283 + 663138 @@ -15526,15 +15566,15 @@ permits - 125 + 143 id1 - 32 + 36 id2 - 125 + 143 @@ -15548,12 +15588,12 @@ 1 2 - 2 + 1 2 3 - 9 + 12 3 @@ -15563,27 +15603,27 @@ 4 5 - 1 + 2 5 6 - 4 + 2 6 + 7 + 4 + + + 7 8 2 8 - 9 - 2 - - - 10 11 - 1 + 2 @@ -15599,7 +15639,7 @@ 1 2 - 125 + 143 @@ -15609,15 +15649,15 @@ hasModifier - 248786309 + 249505212 id1 - 166367134 + 166690663 id2 - 12284 + 13644 @@ -15631,17 +15671,17 @@ 1 2 - 84399769 + 84359142 2 3 - 81515555 + 81848494 3 4 - 451810 + 483026 @@ -15654,6 +15694,11 @@ 12 + + 31 + 32 + 1364 + 34 35 @@ -15680,13 +15725,13 @@ 1364 - 17754 - 17755 + 18033 + 18034 1364 - 18275 - 18276 + 18277 + 18278 1364 @@ -15695,8 +15740,8 @@ 1364 - 116552 - 116553 + 116834 + 116835 1364 @@ -16038,27 +16083,27 @@ stmts - 2534777 + 2533844 id - 2534777 + 2533844 kind - 13649 + 13644 parent - 1785400 + 1784743 idx - 217032 + 216952 bodydecl - 704332 + 704073 @@ -16072,7 +16117,7 @@ 1 2 - 2534777 + 2533844 @@ -16088,7 +16133,7 @@ 1 2 - 2534777 + 2533844 @@ -16104,7 +16149,7 @@ 1 2 - 2534777 + 2533844 @@ -16120,7 +16165,7 @@ 1 2 - 2534777 + 2533844 @@ -16136,7 +16181,7 @@ 2 3 - 4094 + 4093 4 @@ -16192,7 +16237,7 @@ 2 3 - 2729 + 2728 4 @@ -16243,7 +16288,7 @@ 1 2 - 5459 + 5457 2 @@ -16263,7 +16308,7 @@ 7 8 - 2729 + 2728 158 @@ -16289,7 +16334,7 @@ 2 3 - 4094 + 4093 25 @@ -16335,17 +16380,17 @@ 1 2 - 1502848 + 1502295 2 3 - 199287 + 199214 3 159 - 83264 + 83233 @@ -16361,17 +16406,17 @@ 1 2 - 1588842 + 1588257 2 3 - 189732 + 189663 3 4 - 6824 + 6822 @@ -16387,17 +16432,17 @@ 1 2 - 1502848 + 1502295 2 3 - 199287 + 199214 3 159 - 83264 + 83233 @@ -16413,7 +16458,7 @@ 1 2 - 1785400 + 1784743 @@ -16429,22 +16474,22 @@ 1 2 - 161068 + 161008 2 3 - 34124 + 34112 3 24 - 16379 + 16373 34 1211 - 5459 + 5457 @@ -16460,12 +16505,12 @@ 1 2 - 204747 + 204672 2 9 - 12284 + 12280 @@ -16481,22 +16526,22 @@ 1 2 - 161068 + 161008 2 3 - 34124 + 34112 3 24 - 16379 + 16373 34 1211 - 5459 + 5457 @@ -16512,22 +16557,22 @@ 1 2 - 161068 + 161008 2 3 - 34124 + 34112 3 19 - 16379 + 16373 29 517 - 5459 + 5457 @@ -16543,22 +16588,22 @@ 2 3 - 544629 + 544428 3 4 - 58694 + 58672 4 7 - 53234 + 53214 7 162 - 47774 + 47756 @@ -16574,17 +16619,17 @@ 2 3 - 576023 + 575811 3 4 - 81899 + 81868 4 7 - 46409 + 46392 @@ -16600,17 +16645,17 @@ 2 3 - 630623 + 630391 3 8 - 57329 + 57308 9 47 - 16379 + 16373 @@ -16626,22 +16671,22 @@ 1 2 - 544629 + 544428 2 3 - 92818 + 92784 3 7 - 54599 + 54579 7 159 - 12284 + 12280 @@ -17522,7 +17567,7 @@
    kttypeid - 12370 + 12368 @@ -17552,7 +17597,7 @@ 1 2 - 9277 + 9276 2 @@ -17560,8 +17605,8 @@ 2061 - 7177 - 7178 + 7178 + 7179 1030 @@ -17841,22 +17886,22 @@ when_if - 83447 + 84712 id - 83447 + 84712 when_branch_else - 80753 + 79813 id - 80753 + 79813 @@ -17901,12 +17946,12 @@ 1 2 - 162246 + 162245 2 3 - 33026 + 33027 3 @@ -17999,15 +18044,15 @@ propertyRefGetBinding - 9718 + 9660 id - 9718 + 9660 getter - 5873 + 5838 @@ -18021,7 +18066,7 @@ 1 2 - 9718 + 9660 @@ -18037,12 +18082,12 @@ 1 2 - 2132 + 2119 2 3 - 3646 + 3624 3 @@ -18105,15 +18150,15 @@ propertyRefSetBinding - 2651 + 2672 id - 2651 + 2672 setter - 1325 + 1336 @@ -18127,7 +18172,7 @@ 1 2 - 2651 + 2672 @@ -18143,7 +18188,7 @@ 2 3 - 1325 + 1336 @@ -18602,11 +18647,11 @@ localvarsKotlinType - 227623 + 227573 id - 227623 + 227573 kttypeid @@ -18624,7 +18669,7 @@ 1 2 - 227623 + 227573 @@ -20540,11 +20585,11 @@ xmlEncoding - 802611 + 802315 id - 802611 + 802315 encoding @@ -20562,7 +20607,7 @@ 1 2 - 802611 + 802315 @@ -20936,27 +20981,27 @@ xmlElements - 106792352 + 106753032 id - 106792352 + 106753032 name - 338516 + 338391 parentid - 2754540 + 2753526 idx - 1210741 + 1210296 fileid - 802611 + 802315 @@ -20970,7 +21015,7 @@ 1 2 - 106792352 + 106753032 @@ -20986,7 +21031,7 @@ 1 2 - 106792352 + 106753032 @@ -21002,7 +21047,7 @@ 1 2 - 106792352 + 106753032 @@ -21018,7 +21063,7 @@ 1 2 - 106792352 + 106753032 @@ -21034,57 +21079,57 @@ 1 2 - 106468 + 106429 2 3 - 40949 + 40934 3 4 - 16379 + 16373 4 6 - 30029 + 30018 6 8 - 24569 + 24560 8 9 - 12284 + 12280 9 10 - 23204 + 23196 10 18 - 28664 + 28654 18 48 - 25934 + 25925 52 250 - 25934 + 25925 342 73380 - 4094 + 4093 @@ -21100,52 +21145,52 @@ 1 2 - 124213 + 124167 2 3 - 46409 + 46392 3 4 - 17744 + 17738 4 5 - 15014 + 15009 5 6 - 19109 + 19102 6 8 - 28664 + 28654 8 10 - 28664 + 28654 10 21 - 27299 + 27289 22 128 - 25934 + 25925 130 229 - 5459 + 5457 @@ -21161,37 +21206,37 @@ 1 2 - 187002 + 186934 2 3 - 49139 + 49121 3 4 - 24569 + 24560 4 6 - 20474 + 20467 6 9 - 20474 + 20467 9 38 - 25934 + 25925 45 888 - 10919 + 10915 @@ -21207,42 +21252,42 @@ 1 2 - 184273 + 184205 2 3 - 36854 + 36841 3 4 - 17744 + 17738 4 5 - 13649 + 13644 5 7 - 30029 + 30018 7 16 - 25934 + 25925 17 114 - 27299 + 27289 118 131 - 2729 + 2728 @@ -21258,32 +21303,32 @@ 1 2 - 1676201 + 1675584 2 3 - 429970 + 429812 3 4 - 178813 + 178747 4 8 - 214302 + 214223 8 777 - 225222 + 225139 777 888 - 30029 + 30018 @@ -21299,17 +21344,17 @@ 1 2 - 2274065 + 2273228 2 3 - 292106 + 291999 3 17 - 188367 + 188298 @@ -21325,32 +21370,32 @@ 1 2 - 1676201 + 1675584 2 3 - 429970 + 429812 3 4 - 178813 + 178747 4 8 - 214302 + 214223 8 777 - 225222 + 225139 777 888 - 30029 + 30018 @@ -21366,7 +21411,7 @@ 1 2 - 2754540 + 2753526 @@ -21382,67 +21427,67 @@ 2 8 - 102373 + 102336 9 76 - 96913 + 96878 76 82 - 91454 + 91420 82 89 - 87359 + 87326 89 92 - 79169 + 79139 92 95 - 95548 + 95513 95 97 - 106468 + 106429 97 98 - 150148 + 150093 98 99 - 92818 + 92784 99 104 - 110563 + 110523 104 106 - 92818 + 92784 106 159 - 91454 + 91420 162 2019 - 13649 + 13644 @@ -21458,22 +21503,22 @@ 1 2 - 981424 + 981063 2 5 - 90089 + 90055 5 9 - 103738 + 103700 9 150 - 35489 + 35476 @@ -21489,67 +21534,67 @@ 2 8 - 102373 + 102336 9 76 - 96913 + 96878 76 82 - 91454 + 91420 82 89 - 87359 + 87326 89 92 - 79169 + 79139 92 95 - 95548 + 95513 95 97 - 106468 + 106429 97 98 - 150148 + 150093 98 99 - 92818 + 92784 99 104 - 110563 + 110523 104 106 - 92818 + 92784 106 159 - 91454 + 91420 162 2019 - 13649 + 13644 @@ -21565,67 +21610,67 @@ 2 8 - 102373 + 102336 9 76 - 96913 + 96878 76 82 - 91454 + 91420 82 89 - 87359 + 87326 89 92 - 79169 + 79139 92 95 - 95548 + 95513 95 97 - 106468 + 106429 97 98 - 150148 + 150093 98 99 - 92818 + 92784 99 104 - 110563 + 110523 104 106 - 92818 + 92784 106 139 - 91454 + 91420 141 589 - 13649 + 13644 @@ -21641,57 +21686,57 @@ 1 2 - 58694 + 58672 2 3 - 135133 + 135083 3 4 - 177448 + 177382 4 5 - 75074 + 75046 5 7 - 60059 + 60037 7 10 - 66884 + 66859 10 31 - 62789 + 62766 35 694 - 61424 + 61401 738 776 - 20474 + 20467 777 779 - 65519 + 65495 788 889 - 19109 + 19102 @@ -21707,37 +21752,37 @@ 1 2 - 58694 + 58672 2 3 - 399940 + 399793 3 4 - 139228 + 139177 4 5 - 65519 + 65495 5 6 - 61424 + 61401 6 9 - 65519 + 65495 9 69 - 12284 + 12280 @@ -21753,27 +21798,27 @@ 1 2 - 58694 + 58672 2 3 - 569198 + 568989 3 4 - 57329 + 57308 4 6 - 58694 + 58672 6 165 - 58694 + 58672 @@ -21789,42 +21834,42 @@ 1 2 - 203382 + 203307 2 3 - 219762 + 219681 3 4 - 88724 + 88691 4 7 - 66884 + 66859 7 17 - 66884 + 66859 18 763 - 61424 + 61401 764 777 - 65519 + 65495 777 888 - 30029 + 30018 @@ -21834,31 +21879,31 @@ xmlAttrs - 129898822 + 129850995 id - 129898822 + 129850995 elementid - 105883272 + 105844287 name - 513234 + 513045 value - 8206291 + 8203269 idx - 31394 + 31383 fileid - 801246 + 800951 @@ -21872,7 +21917,7 @@ 1 2 - 129898822 + 129850995 @@ -21888,7 +21933,7 @@ 1 2 - 129898822 + 129850995 @@ -21904,7 +21949,7 @@ 1 2 - 129898822 + 129850995 @@ -21920,7 +21965,7 @@ 1 2 - 129898822 + 129850995 @@ -21936,7 +21981,7 @@ 1 2 - 129898822 + 129850995 @@ -21952,17 +21997,17 @@ 1 2 - 96893479 + 96857804 2 6 - 7961959 + 7959027 6 24 - 1027833 + 1027455 @@ -21978,17 +22023,17 @@ 1 2 - 96893479 + 96857804 2 6 - 7975608 + 7972672 6 23 - 1014184 + 1013810 @@ -22004,17 +22049,17 @@ 1 2 - 96946713 + 96911018 2 6 - 8015193 + 8012242 6 21 - 921365 + 921025 @@ -22030,17 +22075,17 @@ 1 2 - 96893479 + 96857804 2 6 - 7961959 + 7959027 6 24 - 1027833 + 1027455 @@ -22056,7 +22101,7 @@ 1 2 - 105883272 + 105844287 @@ -22072,62 +22117,62 @@ 1 2 - 106468 + 106429 2 3 - 55964 + 55943 3 4 - 31394 + 31383 4 5 - 17744 + 17738 5 6 - 30029 + 30018 6 8 - 36854 + 36841 8 11 - 42314 + 42298 11 22 - 39584 + 39569 23 38 - 40949 + 40934 38 79 - 40949 + 40934 81 168 - 39584 + 39569 168 74700 - 31394 + 31383 @@ -22143,62 +22188,62 @@ 1 2 - 106468 + 106429 2 3 - 55964 + 55943 3 4 - 31394 + 31383 4 5 - 17744 + 17738 5 6 - 30029 + 30018 6 8 - 36854 + 36841 8 11 - 46409 + 46392 11 25 - 43679 + 43663 25 39 - 42314 + 42298 43 91 - 40949 + 40934 91 227 - 39584 + 39569 227 74700 - 21839 + 21831 @@ -22214,42 +22259,42 @@ 1 2 - 215667 + 215588 2 3 - 80534 + 80504 3 4 - 34124 + 34112 4 5 - 36854 + 36841 5 9 - 42314 + 42298 9 21 - 39584 + 39569 22 64 - 42314 + 42298 68 2100 - 21839 + 21831 @@ -22265,37 +22310,37 @@ 1 2 - 202017 + 201943 2 3 - 95548 + 95513 3 4 - 49139 + 49121 4 5 - 54599 + 54579 5 7 - 32759 + 32747 7 10 - 40949 + 40934 10 21 - 38219 + 38205 @@ -22311,52 +22356,52 @@ 1 2 - 178813 + 178747 2 3 - 53234 + 53214 3 4 - 27299 + 27289 4 5 - 24569 + 24560 5 6 - 38219 + 38205 6 9 - 42314 + 42298 9 17 - 45044 + 45027 17 34 - 39584 + 39569 36 91 - 39584 + 39569 91 223 - 24569 + 24560 @@ -22372,32 +22417,32 @@ 1 2 - 4482611 + 4480961 2 3 - 1213471 + 1213025 3 5 - 629258 + 629026 5 31 - 618338 + 618110 31 91 - 645638 + 645400 91 1111 - 615608 + 615381 3397 @@ -22418,32 +22463,32 @@ 1 2 - 4572700 + 4571017 2 3 - 1156142 + 1155716 3 5 - 637448 + 637213 5 33 - 647003 + 646764 33 93 - 633353 + 633119 93 3398 - 559643 + 559437 @@ -22459,17 +22504,17 @@ 1 2 - 7447359 + 7444617 2 4 - 660652 + 660409 4 53 - 98278 + 98242 @@ -22485,17 +22530,17 @@ 1 2 - 6796261 + 6793759 2 3 - 992344 + 991978 3 20 - 417685 + 417531 @@ -22511,32 +22556,32 @@ 1 2 - 5282492 + 5280548 2 3 - 889970 + 889642 3 10 - 637448 + 637213 10 83 - 623798 + 623568 83 99 - 626528 + 626297 99 182 - 146053 + 145999 @@ -22552,57 +22597,57 @@ 1 6 - 2729 + 2728 12 14 - 2729 + 2728 17 26 - 2729 + 2728 39 56 - 2729 + 2728 83 110 - 2729 + 2728 153 232 - 2729 + 2728 316 400 - 2729 + 2728 468 545 - 2729 + 2728 626 754 - 2729 + 2728 951 1491 - 2729 + 2728 4718 6587 - 2729 + 2728 77571 @@ -22623,57 +22668,57 @@ 1 6 - 2729 + 2728 12 14 - 2729 + 2728 17 26 - 2729 + 2728 39 56 - 2729 + 2728 83 110 - 2729 + 2728 153 232 - 2729 + 2728 316 400 - 2729 + 2728 468 545 - 2729 + 2728 626 754 - 2729 + 2728 951 1491 - 2729 + 2728 4718 6587 - 2729 + 2728 77571 @@ -22694,57 +22739,57 @@ 1 4 - 2729 + 2728 7 10 - 2729 + 2728 11 17 - 2729 + 2728 18 23 - 2729 + 2728 26 38 - 2729 + 2728 39 49 - 2729 + 2728 57 67 - 2729 + 2728 72 79 - 2729 + 2728 95 101 - 2729 + 2728 105 106 - 2729 + 2728 106 132 - 2729 + 2728 140 @@ -22765,57 +22810,57 @@ 1 5 - 2729 + 2728 7 10 - 2729 + 2728 11 18 - 2729 + 2728 22 32 - 2729 + 2728 46 63 - 2729 + 2728 85 119 - 2729 + 2728 142 185 - 2729 + 2728 212 228 - 2729 + 2728 253 275 - 2729 + 2728 307 423 - 2729 + 2728 580 1324 - 2729 + 2728 3579 @@ -22836,57 +22881,57 @@ 1 6 - 2729 + 2728 7 8 - 2729 + 2728 10 19 - 2729 + 2728 23 36 - 2729 + 2728 45 59 - 2729 + 2728 73 97 - 2729 + 2728 115 131 - 2729 + 2728 140 148 - 2729 + 2728 168 181 - 2729 + 2728 248 363 - 2729 + 2728 473 530 - 2729 + 2728 587 @@ -22907,72 +22952,72 @@ 1 3 - 60059 + 60037 3 5 - 61424 + 61401 5 6 - 36854 + 36841 6 7 - 61424 + 61401 7 8 - 51869 + 51850 8 10 - 58694 + 58672 10 15 - 65519 + 65495 15 27 - 61424 + 61401 27 41 - 61424 + 61401 41 65 - 61424 + 61401 65 157 - 65519 + 65495 162 817 - 61424 + 61401 818 832 - 66884 + 66859 832 1187 - 27299 + 27289 @@ -22988,52 +23033,52 @@ 1 2 - 91454 + 91420 2 3 - 188367 + 188298 3 4 - 113293 + 113252 4 5 - 77804 + 77775 5 8 - 72344 + 72317 8 14 - 61424 + 61401 14 295 - 61424 + 61401 330 775 - 50504 + 50485 776 778 - 65519 + 65495 787 888 - 19109 + 19102 @@ -23049,62 +23094,62 @@ 1 2 - 50504 + 50485 2 3 - 65519 + 65495 3 4 - 50504 + 50485 4 5 - 66884 + 66859 5 6 - 121483 + 121438 6 7 - 114658 + 114616 7 8 - 50504 + 50485 8 12 - 61424 + 61401 12 18 - 69614 + 69588 18 24 - 68249 + 68224 24 37 - 62789 + 62766 37 55 - 19109 + 19102 @@ -23120,67 +23165,67 @@ 1 3 - 69614 + 69588 3 4 - 39584 + 39569 4 5 - 73709 + 73682 5 6 - 88724 + 88691 6 8 - 62789 + 62766 8 12 - 70979 + 70953 12 19 - 61424 + 61401 19 27 - 69614 + 69588 27 41 - 61424 + 61401 42 170 - 61424 + 61401 205 780 - 57329 + 57308 781 783 - 65519 + 65495 791 893 - 19109 + 19102 @@ -23196,47 +23241,47 @@ 1 2 - 79169 + 79139 2 3 - 76439 + 76411 3 4 - 151513 + 151457 4 5 - 155608 + 155551 5 6 - 92818 + 92784 6 10 - 68249 + 68224 10 12 - 46409 + 46392 12 15 - 69614 + 69588 15 24 - 61424 + 61401 @@ -23246,23 +23291,23 @@ xmlNs - 1287181 + 1286707 id - 8189 + 8186 prefixName - 9554 + 9551 URI - 8189 + 8186 fileid - 749376 + 749100 @@ -23276,7 +23321,7 @@ 1 2 - 6824 + 6822 2 @@ -23297,7 +23342,7 @@ 1 2 - 8189 + 8186 @@ -23354,7 +23399,7 @@ 1 2 - 9554 + 9551 @@ -23370,7 +23415,7 @@ 1 2 - 9554 + 9551 @@ -23432,7 +23477,7 @@ 1 2 - 8189 + 8186 @@ -23448,7 +23493,7 @@ 1 2 - 6824 + 6822 2 @@ -23510,17 +23555,17 @@ 1 2 - 334421 + 334298 2 3 - 292106 + 291999 3 4 - 122848 + 122803 @@ -23536,17 +23581,17 @@ 1 2 - 334421 + 334298 2 3 - 292106 + 291999 3 4 - 122848 + 122803 @@ -23562,17 +23607,17 @@ 1 2 - 334421 + 334298 2 3 - 292106 + 291999 3 4 - 122848 + 122803 @@ -23582,19 +23627,19 @@ xmlHasNs - 25966114 + 25956554 elementId - 25966114 + 25956554 nsId - 8189 + 8186 fileid - 745281 + 745007 @@ -23608,7 +23653,7 @@ 1 2 - 25966114 + 25956554 @@ -23624,7 +23669,7 @@ 1 2 - 25966114 + 25956554 @@ -23722,77 +23767,77 @@ 1 3 - 45044 + 45027 3 5 - 62789 + 62766 5 6 - 34124 + 34112 6 7 - 65519 + 65495 7 8 - 49139 + 49121 8 10 - 61424 + 61401 10 15 - 65519 + 65495 15 25 - 55964 + 55943 25 36 - 57329 + 57308 36 49 - 58694 + 58672 49 54 - 15014 + 15009 54 55 - 58694 + 58672 55 81 - 57329 + 57308 81 298 - 55964 + 55943 298 833 - 2729 + 2728 @@ -23808,17 +23853,17 @@ 1 2 - 335786 + 335662 2 3 - 289376 + 289270 3 4 - 120118 + 120074 @@ -23828,23 +23873,23 @@ xmlComments - 107485764 + 107446189 id - 107485764 + 107446189 text - 1696676 + 1696051 parentid - 842195 + 841885 fileid - 787596 + 787306 @@ -23858,7 +23903,7 @@ 1 2 - 107485764 + 107446189 @@ -23874,7 +23919,7 @@ 1 2 - 107485764 + 107446189 @@ -23890,7 +23935,7 @@ 1 2 - 107485764 + 107446189 @@ -23906,67 +23951,67 @@ 1 2 - 233412 + 233326 2 7 - 139228 + 139177 7 32 - 140593 + 140541 32 61 - 128308 + 128261 61 76 - 128308 + 128261 76 84 - 136498 + 136448 84 90 - 125578 + 125532 90 94 - 111928 + 111887 94 95 - 60059 + 60037 95 96 - 101008 + 100971 96 98 - 140593 + 140541 98 100 - 126943 + 126896 100 460 - 124213 + 124167 @@ -23982,67 +24027,67 @@ 1 2 - 236142 + 236055 2 6 - 135133 + 135083 6 32 - 143323 + 143270 32 61 - 129673 + 129625 61 75 - 132403 + 132354 75 84 - 148783 + 148728 84 90 - 122848 + 122803 90 94 - 120118 + 120074 94 95 - 66884 + 66859 95 96 - 103738 + 103700 96 98 - 143323 + 143270 98 100 - 135133 + 135083 100 460 - 79169 + 79139 @@ -24058,67 +24103,67 @@ 1 2 - 247062 + 246971 2 7 - 133768 + 133719 7 32 - 133768 + 133719 32 61 - 129673 + 129625 61 75 - 132403 + 132354 75 84 - 148783 + 148728 84 90 - 122848 + 122803 90 94 - 120118 + 120074 94 95 - 66884 + 66859 95 96 - 103738 + 103700 96 98 - 143323 + 143270 98 100 - 135133 + 135083 100 460 - 79169 + 79139 @@ -24134,22 +24179,22 @@ 1 2 - 670207 + 669961 2 724 - 64154 + 64130 726 830 - 77804 + 77775 831 941 - 30029 + 30018 @@ -24165,27 +24210,27 @@ 1 2 - 670207 + 669961 2 697 - 64154 + 64130 697 795 - 34124 + 34112 795 827 - 64154 + 64130 838 899 - 9554 + 9551 @@ -24201,7 +24246,7 @@ 1 2 - 842195 + 841885 @@ -24217,27 +24262,27 @@ 1 2 - 601958 + 601736 2 549 - 60059 + 60037 579 829 - 40949 + 40934 829 832 - 65519 + 65495 834 941 - 19109 + 19102 @@ -24253,27 +24298,27 @@ 1 2 - 601958 + 601736 2 536 - 60059 + 60037 560 795 - 51869 + 51850 795 812 - 60059 + 60037 819 899 - 13649 + 13644 @@ -24289,12 +24334,12 @@ 1 2 - 748011 + 747736 2 6 - 39584 + 39569 @@ -24304,19 +24349,19 @@ xmlChars - 101574013 + 101536615 id - 101574013 + 101536615 text - 78006178 + 77977457 parentid - 101574013 + 101536615 idx @@ -24324,11 +24369,11 @@ isCDATA - 2729 + 2728 fileid - 177448 + 177382 @@ -24342,7 +24387,7 @@ 1 2 - 101574013 + 101536615 @@ -24358,7 +24403,7 @@ 1 2 - 101574013 + 101536615 @@ -24374,7 +24419,7 @@ 1 2 - 101574013 + 101536615 @@ -24390,7 +24435,7 @@ 1 2 - 101574013 + 101536615 @@ -24406,7 +24451,7 @@ 1 2 - 101574013 + 101536615 @@ -24422,17 +24467,17 @@ 1 2 - 66746414 + 66721839 2 3 - 7010564 + 7007983 3 128 - 4249199 + 4247634 @@ -24448,17 +24493,17 @@ 1 2 - 66746414 + 66721839 2 3 - 7010564 + 7007983 3 128 - 4249199 + 4247634 @@ -24474,7 +24519,7 @@ 1 2 - 78006178 + 77977457 @@ -24490,7 +24535,7 @@ 1 2 - 78006178 + 77977457 @@ -24506,12 +24551,12 @@ 1 2 - 74636029 + 74608549 2 76 - 3370148 + 3368907 @@ -24527,7 +24572,7 @@ 1 2 - 101574013 + 101536615 @@ -24543,7 +24588,7 @@ 1 2 - 101574013 + 101536615 @@ -24559,7 +24604,7 @@ 1 2 - 101574013 + 101536615 @@ -24575,7 +24620,7 @@ 1 2 - 101574013 + 101536615 @@ -24591,7 +24636,7 @@ 1 2 - 101574013 + 101536615 @@ -24750,7 +24795,7 @@ 1 2 - 2729 + 2728 @@ -24787,57 +24832,57 @@ 1 2 - 15014 + 15009 2 23 - 13649 + 13644 24 243 - 13649 + 13644 294 566 - 13649 + 13644 610 686 - 13649 + 13644 691 764 - 13649 + 13644 765 775 - 13649 + 13644 775 776 - 4094 + 4093 776 777 - 49139 + 49121 777 803 - 13649 + 13644 807 888 - 13649 + 13644 @@ -24853,67 +24898,67 @@ 1 2 - 15014 + 15009 2 21 - 13649 + 13644 22 188 - 13649 + 13644 208 492 - 13649 + 13644 525 589 - 13649 + 13644 590 638 - 13649 + 13644 639 651 - 13649 + 13644 652 656 - 12284 + 12280 656 659 - 16379 + 16373 659 663 - 15014 + 15009 663 667 - 13649 + 13644 667 701 - 13649 + 13644 702 744 - 9554 + 9551 @@ -24929,57 +24974,57 @@ 1 2 - 15014 + 15009 2 23 - 13649 + 13644 24 243 - 13649 + 13644 294 566 - 13649 + 13644 610 686 - 13649 + 13644 691 764 - 13649 + 13644 765 775 - 13649 + 13644 775 776 - 4094 + 4093 776 777 - 49139 + 49121 777 803 - 13649 + 13644 807 888 - 13649 + 13644 @@ -24995,7 +25040,7 @@ 1 2 - 177448 + 177382 @@ -25011,12 +25056,12 @@ 1 2 - 43679 + 43663 2 3 - 133768 + 133719 @@ -25026,15 +25071,15 @@ xmllocations - 447840746 + 447675856 xmlElement - 446561755 + 446397336 location - 419653800 + 419499288 @@ -25048,12 +25093,12 @@ 1 2 - 446553565 + 446389149 2 454 - 8189 + 8186 @@ -25069,12 +25114,12 @@ 1 2 - 410141218 + 409990208 2 25 - 9512582 + 9509079 @@ -25315,19 +25360,19 @@ ktComments - 133768 + 133719 id - 133768 + 133719 kind - 4094 + 4093 text - 96913 + 96878 @@ -25341,7 +25386,7 @@ 1 2 - 133768 + 133719 @@ -25357,7 +25402,7 @@ 1 2 - 133768 + 133719 @@ -25425,12 +25470,12 @@ 1 2 - 92818 + 92784 4 23 - 4094 + 4093 @@ -25446,7 +25491,7 @@ 1 2 - 96913 + 96878 @@ -25456,19 +25501,19 @@ ktCommentSections - 59246 + 59191 id - 59246 + 59191 comment - 54224 + 54069 content - 50410 + 50263 @@ -25482,7 +25527,7 @@ 1 2 - 59246 + 59191 @@ -25498,7 +25543,7 @@ 1 2 - 59246 + 59191 @@ -25514,12 +25559,12 @@ 1 2 - 52208 + 52013 2 18 - 2015 + 2055 @@ -25535,12 +25580,12 @@ 1 2 - 52208 + 52013 2 18 - 2015 + 2055 @@ -25556,17 +25601,17 @@ 1 2 - 44628 + 44482 2 3 - 4836 + 4801 3 63 - 945 + 979 @@ -25582,17 +25627,17 @@ 1 2 - 44737 + 44594 2 3 - 4743 + 4705 3 56 - 930 + 963 @@ -25602,15 +25647,15 @@ ktCommentSectionNames - 5022 + 5122 id - 5022 + 5122 name - 15 + 16 @@ -25624,7 +25669,7 @@ 1 2 - 5022 + 5122 @@ -25638,9 +25683,9 @@ 12 - 324 - 325 - 15 + 319 + 320 + 16 @@ -25650,15 +25695,15 @@ ktCommentSectionSubjectNames - 5022 + 5122 id - 5022 + 5122 subjectname - 3301 + 3388 @@ -25672,7 +25717,7 @@ 1 2 - 5022 + 5122 @@ -25688,22 +25733,22 @@ 1 2 - 2511 + 2601 2 3 - 496 + 497 3 - 9 - 248 + 10 + 256 - 10 - 15 - 46 + 13 + 16 + 32 @@ -25713,15 +25758,15 @@ ktCommentOwners - 84203 + 82540 id - 53480 + 53314 owner - 82173 + 80437 @@ -25735,22 +25780,22 @@ 1 2 - 34335 + 34638 2 3 - 12184 + 12076 3 4 - 4526 + 4496 4 6 - 2433 + 2103 @@ -25766,12 +25811,12 @@ 1 2 - 80142 + 78333 2 3 - 2030 + 2103 @@ -25781,15 +25826,15 @@ ktExtensionFunctions - 702967 + 702708 id - 702967 + 702708 typeid - 84629 + 84597 kttypeid @@ -25807,7 +25852,7 @@ 1 2 - 702967 + 702708 @@ -25823,7 +25868,7 @@ 1 2 - 702967 + 702708 @@ -25839,12 +25884,12 @@ 1 2 - 53234 + 53214 2 3 - 6824 + 6822 3 @@ -25854,22 +25899,22 @@ 4 5 - 6824 + 6822 5 12 - 6824 + 6822 12 69 - 6824 + 6822 84 174 - 2729 + 2728 @@ -25885,7 +25930,7 @@ 1 2 - 84629 + 84597 @@ -25927,15 +25972,15 @@ ktProperties - 30317687 + 30306525 id - 30317687 + 30306525 nodeName - 10696024 + 10692086 @@ -25949,7 +25994,7 @@ 1 2 - 30317687 + 30306525 @@ -25965,22 +26010,22 @@ 1 2 - 7889614 + 7886709 2 3 - 1216201 + 1215754 3 8 - 809436 + 809138 8 554 - 780771 + 780484 @@ -25990,15 +26035,15 @@ ktPropertyGetters - 4569970 + 4568288 id - 4569970 + 4568288 getter - 4569970 + 4568288 @@ -26012,7 +26057,7 @@ 1 2 - 4569970 + 4568288 @@ -26028,7 +26073,7 @@ 1 2 - 4569970 + 4568288 @@ -26038,15 +26083,15 @@ ktPropertySetters - 290741 + 290634 id - 290741 + 290634 setter - 290741 + 290634 @@ -26060,7 +26105,7 @@ 1 2 - 290741 + 290634 @@ -26076,7 +26121,7 @@ 1 2 - 290741 + 290634 @@ -26086,15 +26131,15 @@ ktPropertyBackingFields - 23615610 + 23606915 id - 23615610 + 23606915 backingField - 23615610 + 23606915 @@ -26108,7 +26153,7 @@ 1 2 - 23615610 + 23606915 @@ -26124,7 +26169,7 @@ 1 2 - 23615610 + 23606915 @@ -26134,11 +26179,11 @@ ktSyntheticBody - 10308 + 10307 id - 10308 + 10307 kind @@ -26156,7 +26201,7 @@ 1 2 - 10308 + 10307 @@ -26182,37 +26227,37 @@ ktLocalFunction - 2729 + 2728 id - 2729 + 2728 ktInitializerAssignment - 393115 + 392971 id - 393115 + 392971 ktPropertyDelegates - 5698 + 5664 id - 5698 + 5664 variableId - 5698 + 5664 @@ -26226,7 +26271,7 @@ 1 2 - 5698 + 5664 @@ -26242,7 +26287,7 @@ 1 2 - 5698 + 5664 @@ -26252,15 +26297,15 @@ compiler_generated - 120 + 491650 id - 120 + 491650 kind - 2 + 5153 @@ -26274,7 +26319,7 @@ 1 2 - 120 + 491650 @@ -26288,9 +26333,29 @@ 12 - 42 - 43 - 2 + 2 + 3 + 1030 + + + 5 + 6 + 1030 + + + 10 + 11 + 1030 + + + 184 + 185 + 1030 + + + 276 + 277 + 1030 @@ -26300,15 +26365,15 @@ ktFunctionOriginalNames - 981424 + 1147529 id - 981424 + 1147529 name - 66884 + 79139 @@ -26322,7 +26387,7 @@ 1 2 - 981424 + 1147529 @@ -26338,22 +26403,27 @@ 1 2 - 53234 + 55943 2 - 3 - 5459 + 4 + 6822 - 3 - 96 - 5459 + 7 + 14 + 4093 - 96 + 16 + 31 + 6822 + + + 92 380 - 2729 + 5457 From 28a8999b7472cf8d1feba71e7576d32a165446a3 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Fri, 1 Jul 2022 12:42:15 +0100 Subject: [PATCH 281/465] Java: Add an upgrade script --- .../old.dbscheme | 1228 ++++++++++++++++ .../semmlecode.dbscheme | 1236 +++++++++++++++++ .../upgrade.properties | 2 + 3 files changed, 2466 insertions(+) create mode 100644 java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/old.dbscheme create mode 100755 java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/semmlecode.dbscheme create mode 100644 java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/upgrade.properties diff --git a/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/old.dbscheme b/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/old.dbscheme new file mode 100644 index 00000000000..cf58c7d9b1f --- /dev/null +++ b/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/old.dbscheme @@ -0,0 +1,1228 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +file_class( + int id: @class ref +); + +class_object( + unique int id: @class ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @class ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isRecord( + unique int id: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterface = @interface | @class; +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | + @locatableElement; + +@locatableElement = @file | @primitive | @class | @interface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar ; + +@member_modifiable = @class | @interface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) diff --git a/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/semmlecode.dbscheme b/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/semmlecode.dbscheme new file mode 100755 index 00000000000..81ccfabe82e --- /dev/null +++ b/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/semmlecode.dbscheme @@ -0,0 +1,1236 @@ +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * javac A.java B.java C.java + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * javac A.java B.java C.java + */ + unique int id : @compilation, + int kind: int ref, + string cwd : string ref, + string name : string ref +); + +case @compilation.kind of + 1 = @javacompilation +| 2 = @kotlincompilation +; + +compilation_started( + int id : @compilation ref +) + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--javac-args` + * 2 | A.java + * 3 | B.java + * 4 | C.java + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * javac A.java B.java C.java + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | A.java + * 1 | B.java + * 2 | C.java + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * For each file recorded in `compilation_compiling_files`, + * there will be a corresponding row in + * `compilation_compiling_files_completed` once extraction + * of that file is complete. The `result` will indicate the + * extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +#keyset[id, num] +compilation_compiling_files_completed( + int id : @compilation ref, + int num : int ref, + int result : int ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + unique int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * The `cpu_seconds` and `elapsed_seconds` are the CPU time and elapsed + * time (respectively) that the original compilation (not the extraction) + * took for compiler invocation `id`. + */ +compilation_compiler_times( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + * The `result` will indicate the extraction result: + * + * 0: Successfully extracted + * 1: Errors were encountered, but extraction recovered + * 2: Errors were encountered, and extraction could not recover + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref, + int result : int ref +); + +diagnostics( + unique int id: @diagnostic, + string generated_by: string ref, // TODO: Sync this with the other languages? + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +/* + * External artifacts + */ + +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +snapshotDate( + unique date snapshotDate : date ref +); + +sourceLocationPrefix( + string prefix : string ref +); + +/* + * Duplicate code + */ + +duplicateCode( + unique int id : @duplication, + string relativePath : string ref, + int equivClass : int ref +); + +similarCode( + unique int id : @similarity, + string relativePath : string ref, + int equivClass : int ref +); + +@duplication_or_similarity = @duplication | @similarity + +tokens( + int id : @duplication_or_similarity ref, + int offset : int ref, + int beginLine : int ref, + int beginColumn : int ref, + int endLine : int ref, + int endColumn : int ref +); + +/* + * SMAP + */ + +smap_header( + int outputFileId: @file ref, + string outputFilename: string ref, + string defaultStratum: string ref +); + +smap_files( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + string inputFileName: string ref, + int inputFileId: @file ref +); + +smap_lines( + int outputFileId: @file ref, + string stratum: string ref, + int inputFileNum: int ref, + int inputStartLine: int ref, + int inputLineCount: int ref, + int outputStartLine: int ref, + int outputLineIncrement: int ref +); + +/* + * Locations and files + */ + +@location = @location_default ; + +locations_default( + unique int id: @location_default, + int file: @file ref, + int beginLine: int ref, + int beginColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +hasLocation( + int locatableid: @locatable ref, + int id: @location ref +); + +@sourceline = @locatable ; + +#keyset[element_id] +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/* + * Java + */ + +cupackage( + unique int id: @file ref, + int packageid: @package ref +); + +#keyset[fileid,keyName] +jarManifestMain( + int fileid: @file ref, + string keyName: string ref, + string value: string ref +); + +#keyset[fileid,entryName,keyName] +jarManifestEntries( + int fileid: @file ref, + string entryName: string ref, + string keyName: string ref, + string value: string ref +); + +packages( + unique int id: @package, + string nodeName: string ref +); + +primitives( + unique int id: @primitive, + string nodeName: string ref +); + +modifiers( + unique int id: @modifier, + string nodeName: string ref +); + +/** + * An errortype is used when the extractor is unable to extract a type + * correctly for some reason. + */ +error_type( + unique int id: @errortype +); + +classes( + unique int id: @class, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @class ref +); + +file_class( + int id: @class ref +); + +class_object( + unique int id: @class ref, + unique int instance: @field ref +); + +type_companion_object( + unique int id: @classorinterface ref, + unique int instance: @field ref, + unique int companion_object: @class ref +); + +kt_nullable_types( + unique int id: @kt_nullable_type, + int classid: @reftype ref +) + +kt_notnull_types( + unique int id: @kt_notnull_type, + int classid: @reftype ref +) + +kt_type_alias( + unique int id: @kt_type_alias, + string name: string ref, + int kttypeid: @kt_type ref +) + +@kt_type = @kt_nullable_type | @kt_notnull_type + +isRecord( + unique int id: @class ref +); + +interfaces( + unique int id: @interface, + string nodeName: string ref, + int parentid: @package ref, + int sourceid: @interface ref +); + +fielddecls( + unique int id: @fielddecl, + int parentid: @reftype ref +); + +#keyset[fieldId] #keyset[fieldDeclId,pos] +fieldDeclaredIn( + int fieldId: @field ref, + int fieldDeclId: @fielddecl ref, + int pos: int ref +); + +fields( + unique int id: @field, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @field ref +); + +fieldsKotlinType( + unique int id: @field ref, + int kttypeid: @kt_type ref +); + +constrs( + unique int id: @constructor, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @constructor ref +); + +constrsKotlinType( + unique int id: @constructor ref, + int kttypeid: @kt_type ref +); + +methods( + unique int id: @method, + string nodeName: string ref, + string signature: string ref, + int typeid: @type ref, + int parentid: @reftype ref, + int sourceid: @method ref +); + +methodsKotlinType( + unique int id: @method ref, + int kttypeid: @kt_type ref +); + +#keyset[parentid,pos] +params( + unique int id: @param, + int typeid: @type ref, + int pos: int ref, + int parentid: @callable ref, + int sourceid: @param ref +); + +paramsKotlinType( + unique int id: @param ref, + int kttypeid: @kt_type ref +); + +paramName( + unique int id: @param ref, + string nodeName: string ref +); + +isVarargsParam( + int param: @param ref +); + +exceptions( + unique int id: @exception, + int typeid: @type ref, + int parentid: @callable ref +); + +isAnnotType( + int interfaceid: @interface ref +); + +isAnnotElem( + int methodid: @method ref +); + +annotValue( + int parentid: @annotation ref, + int id2: @method ref, + unique int value: @expr ref +); + +isEnumType( + int classid: @class ref +); + +isEnumConst( + int fieldid: @field ref +); + +#keyset[parentid,pos] +typeVars( + unique int id: @typevariable, + string nodeName: string ref, + int pos: int ref, + int kind: int ref, // deprecated + int parentid: @classorinterfaceorcallable ref +); + +wildcards( + unique int id: @wildcard, + string nodeName: string ref, + int kind: int ref +); + +#keyset[parentid,pos] +typeBounds( + unique int id: @typebound, + int typeid: @reftype ref, + int pos: int ref, + int parentid: @boundedtype ref +); + +#keyset[parentid,pos] +typeArgs( + int argumentid: @reftype ref, + int pos: int ref, + int parentid: @classorinterfaceorcallable ref +); + +isParameterized( + int memberid: @member ref +); + +isRaw( + int memberid: @member ref +); + +erasure( + unique int memberid: @member ref, + int erasureid: @member ref +); + +#keyset[classid] #keyset[parent] +isAnonymClass( + int classid: @class ref, + int parent: @classinstancexpr ref +); + +#keyset[typeid] #keyset[parent] +isLocalClassOrInterface( + int typeid: @classorinterface ref, + int parent: @localtypedeclstmt ref +); + +isDefConstr( + int constructorid: @constructor ref +); + +#keyset[exprId] +lambdaKind( + int exprId: @lambdaexpr ref, + int bodyKind: int ref +); + +arrays( + unique int id: @array, + string nodeName: string ref, + int elementtypeid: @type ref, + int dimension: int ref, + int componenttypeid: @type ref +); + +enclInReftype( + unique int child: @reftype ref, + int parent: @reftype ref +); + +extendsReftype( + int id1: @reftype ref, + int id2: @classorinterface ref +); + +implInterface( + int id1: @classorarray ref, + int id2: @interface ref +); + +permits( + int id1: @classorinterface ref, + int id2: @classorinterface ref +); + +hasModifier( + int id1: @modifiable ref, + int id2: @modifier ref +); + +imports( + unique int id: @import, + int holder: @classorinterfaceorpackage ref, + string name: string ref, + int kind: int ref +); + +#keyset[parent,idx] +stmts( + unique int id: @stmt, + int kind: int ref, + int parent: @stmtparent ref, + int idx: int ref, + int bodydecl: @callable ref +); + +@stmtparent = @callable | @stmt | @switchexpr | @whenexpr| @stmtexpr; + +case @stmt.kind of + 0 = @block +| 1 = @ifstmt +| 2 = @forstmt +| 3 = @enhancedforstmt +| 4 = @whilestmt +| 5 = @dostmt +| 6 = @trystmt +| 7 = @switchstmt +| 8 = @synchronizedstmt +| 9 = @returnstmt +| 10 = @throwstmt +| 11 = @breakstmt +| 12 = @continuestmt +| 13 = @emptystmt +| 14 = @exprstmt +| 15 = @labeledstmt +| 16 = @assertstmt +| 17 = @localvariabledeclstmt +| 18 = @localtypedeclstmt +| 19 = @constructorinvocationstmt +| 20 = @superconstructorinvocationstmt +| 21 = @case +| 22 = @catchclause +| 23 = @yieldstmt +| 24 = @errorstmt +| 25 = @whenbranch +; + +#keyset[parent,idx] +exprs( + unique int id: @expr, + int kind: int ref, + int typeid: @type ref, + int parent: @exprparent ref, + int idx: int ref +); + +exprsKotlinType( + unique int id: @expr ref, + int kttypeid: @kt_type ref +); + +callableEnclosingExpr( + unique int id: @expr ref, + int callable_id: @callable ref +); + +statementEnclosingExpr( + unique int id: @expr ref, + int statement_id: @stmt ref +); + +isParenthesized( + unique int id: @expr ref, + int parentheses: int ref +); + +case @expr.kind of + 1 = @arrayaccess +| 2 = @arraycreationexpr +| 3 = @arrayinit +| 4 = @assignexpr +| 5 = @assignaddexpr +| 6 = @assignsubexpr +| 7 = @assignmulexpr +| 8 = @assigndivexpr +| 9 = @assignremexpr +| 10 = @assignandexpr +| 11 = @assignorexpr +| 12 = @assignxorexpr +| 13 = @assignlshiftexpr +| 14 = @assignrshiftexpr +| 15 = @assignurshiftexpr +| 16 = @booleanliteral +| 17 = @integerliteral +| 18 = @longliteral +| 19 = @floatingpointliteral +| 20 = @doubleliteral +| 21 = @characterliteral +| 22 = @stringliteral +| 23 = @nullliteral +| 24 = @mulexpr +| 25 = @divexpr +| 26 = @remexpr +| 27 = @addexpr +| 28 = @subexpr +| 29 = @lshiftexpr +| 30 = @rshiftexpr +| 31 = @urshiftexpr +| 32 = @andbitexpr +| 33 = @orbitexpr +| 34 = @xorbitexpr +| 35 = @andlogicalexpr +| 36 = @orlogicalexpr +| 37 = @ltexpr +| 38 = @gtexpr +| 39 = @leexpr +| 40 = @geexpr +| 41 = @eqexpr +| 42 = @neexpr +| 43 = @postincexpr +| 44 = @postdecexpr +| 45 = @preincexpr +| 46 = @predecexpr +| 47 = @minusexpr +| 48 = @plusexpr +| 49 = @bitnotexpr +| 50 = @lognotexpr +| 51 = @castexpr +| 52 = @newexpr +| 53 = @conditionalexpr +| 54 = @parexpr // deprecated +| 55 = @instanceofexpr +| 56 = @localvariabledeclexpr +| 57 = @typeliteral +| 58 = @thisaccess +| 59 = @superaccess +| 60 = @varaccess +| 61 = @methodaccess +| 62 = @unannotatedtypeaccess +| 63 = @arraytypeaccess +| 64 = @packageaccess +| 65 = @wildcardtypeaccess +| 66 = @declannotation +| 67 = @uniontypeaccess +| 68 = @lambdaexpr +| 69 = @memberref +| 70 = @annotatedtypeaccess +| 71 = @typeannotation +| 72 = @intersectiontypeaccess +| 73 = @switchexpr +| 74 = @errorexpr +| 75 = @whenexpr +| 76 = @getclassexpr +| 77 = @safecastexpr +| 78 = @implicitcastexpr +| 79 = @implicitnotnullexpr +| 80 = @implicitcoerciontounitexpr +| 81 = @notinstanceofexpr +| 82 = @stmtexpr +| 83 = @stringtemplateexpr +| 84 = @notnullexpr +| 85 = @unsafecoerceexpr +| 86 = @valueeqexpr +| 87 = @valueneexpr +| 88 = @propertyref +; + +/** Holds if this `when` expression was written as an `if` expression. */ +when_if(unique int id: @whenexpr ref); + +/** Holds if this `when` branch was written as an `else` branch. */ +when_branch_else(unique int id: @whenbranch ref); + +@classinstancexpr = @newexpr | @lambdaexpr | @memberref | @propertyref + +@annotation = @declannotation | @typeannotation +@typeaccess = @unannotatedtypeaccess | @annotatedtypeaccess + +@assignment = @assignexpr + | @assignop; + +@unaryassignment = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr; + +@assignop = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + | @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignurshiftexpr; + +@literal = @booleanliteral + | @integerliteral + | @longliteral + | @floatingpointliteral + | @doubleliteral + | @characterliteral + | @stringliteral + | @nullliteral; + +@binaryexpr = @mulexpr + | @divexpr + | @remexpr + | @addexpr + | @subexpr + | @lshiftexpr + | @rshiftexpr + | @urshiftexpr + | @andbitexpr + | @orbitexpr + | @xorbitexpr + | @andlogicalexpr + | @orlogicalexpr + | @ltexpr + | @gtexpr + | @leexpr + | @geexpr + | @eqexpr + | @neexpr + | @valueeqexpr + | @valueneexpr; + +@unaryexpr = @postincexpr + | @postdecexpr + | @preincexpr + | @predecexpr + | @minusexpr + | @plusexpr + | @bitnotexpr + | @lognotexpr + | @notnullexpr; + +@caller = @classinstancexpr + | @methodaccess + | @constructorinvocationstmt + | @superconstructorinvocationstmt; + +callableBinding( + unique int callerid: @caller ref, + int callee: @callable ref +); + +memberRefBinding( + unique int id: @expr ref, + int callable: @callable ref +); + +propertyRefGetBinding( + unique int id: @expr ref, + int getter: @callable ref +); + +propertyRefFieldBinding( + unique int id: @expr ref, + int field: @field ref +); + +propertyRefSetBinding( + unique int id: @expr ref, + int setter: @callable ref +); + +@exprparent = @stmt | @expr | @whenbranch | @callable | @field | @fielddecl | @class | @interface | @param | @localvar | @typevariable; + +variableBinding( + unique int expr: @varaccess ref, + int variable: @variable ref +); + +@variable = @localscopevariable | @field; + +@localscopevariable = @localvar | @param; + +localvars( + unique int id: @localvar, + string nodeName: string ref, + int typeid: @type ref, + int parentid: @localvariabledeclexpr ref +); + +localvarsKotlinType( + unique int id: @localvar ref, + int kttypeid: @kt_type ref +); + +@namedexprorstmt = @breakstmt + | @continuestmt + | @labeledstmt + | @literal; + +namestrings( + string name: string ref, + string value: string ref, + unique int parent: @namedexprorstmt ref +); + +/* + * Modules + */ + +#keyset[name] +modules( + unique int id: @module, + string name: string ref +); + +isOpen( + int id: @module ref +); + +#keyset[fileId] +cumodule( + int fileId: @file ref, + int moduleId: @module ref +); + +@directive = @requires + | @exports + | @opens + | @uses + | @provides + +#keyset[directive] +directives( + int id: @module ref, + int directive: @directive ref +); + +requires( + unique int id: @requires, + int target: @module ref +); + +isTransitive( + int id: @requires ref +); + +isStatic( + int id: @requires ref +); + +exports( + unique int id: @exports, + int target: @package ref +); + +exportsTo( + int id: @exports ref, + int target: @module ref +); + +opens( + unique int id: @opens, + int target: @package ref +); + +opensTo( + int id: @opens ref, + int target: @module ref +); + +uses( + unique int id: @uses, + string serviceInterface: string ref +); + +provides( + unique int id: @provides, + string serviceInterface: string ref +); + +providesWith( + int id: @provides ref, + string serviceImpl: string ref +); + +/* + * Javadoc + */ + +javadoc( + unique int id: @javadoc +); + +isNormalComment( + int commentid : @javadoc ref +); + +isEolComment( + int commentid : @javadoc ref +); + +hasJavadoc( + int documentableid: @member ref, + int javadocid: @javadoc ref +); + +#keyset[parentid,idx] +javadocTag( + unique int id: @javadocTag, + string name: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +#keyset[parentid,idx] +javadocText( + unique int id: @javadocText, + string text: string ref, + int parentid: @javadocParent ref, + int idx: int ref +); + +@javadocParent = @javadoc | @javadocTag; +@javadocElement = @javadocTag | @javadocText; + +@classorinterface = @interface | @class; +@classorinterfaceorpackage = @classorinterface | @package; +@classorinterfaceorcallable = @classorinterface | @callable; +@boundedtype = @typevariable | @wildcard; +@reftype = @classorinterface | @array | @boundedtype | @errortype; +@classorarray = @class | @array; +@type = @primitive | @reftype; +@callable = @method | @constructor; + +/** A program element that has a name. */ +@element = @package | @modifier | @annotation | @errortype | + @locatableElement; + +@locatableElement = @file | @primitive | @class | @interface | @method | @constructor | @param | @exception | @field | + @boundedtype | @array | @localvar | @expr | @stmt | @import | @fielddecl | @kt_type | @kt_type_alias | + @kt_property; + +@modifiable = @member_modifiable| @param | @localvar ; + +@member_modifiable = @class | @interface | @method | @constructor | @field | @kt_property; + +@member = @method | @constructor | @field | @reftype ; + +/** A program element that has a location. */ +@locatable = @typebound | @javadoc | @javadocTag | @javadocText | @xmllocatable | @ktcomment | + @locatableElement; + +@top = @element | @locatable | @folder; + +/* + * XML Files + */ + +xmlEncoding( + unique int id: @file ref, + string encoding: string ref +); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters | @xmlelement | @xmlcomment | @xmlattribute | @xmldtd | @file | @xmlnamespace; + +/* + * configuration files with key value pairs + */ + +configs( + unique int id: @config +); + +configNames( + unique int id: @configName, + int config: @config ref, + string name: string ref +); + +configValues( + unique int id: @configValue, + int config: @config ref, + string value: string ref +); + +configLocations( + int locatable: @configLocatable ref, + int location: @location_default ref +); + +@configLocatable = @config | @configName | @configValue; + +ktComments( + unique int id: @ktcomment, + int kind: int ref, + string text : string ref +) + +ktCommentSections( + unique int id: @ktcommentsection, + int comment: @ktcomment ref, + string content : string ref +) + +ktCommentSectionNames( + unique int id: @ktcommentsection ref, + string name : string ref +) + +ktCommentSectionSubjectNames( + unique int id: @ktcommentsection ref, + string subjectname : string ref +) + +#keyset[id, owner] +ktCommentOwners( + int id: @ktcomment ref, + int owner: @top ref +) + +ktExtensionFunctions( + unique int id: @method ref, + int typeid: @type ref, + int kttypeid: @kt_type ref +) + +ktProperties( + unique int id: @kt_property, + string nodeName: string ref +) + +ktPropertyGetters( + unique int id: @kt_property ref, + int getter: @method ref +) + +ktPropertySetters( + unique int id: @kt_property ref, + int setter: @method ref +) + +ktPropertyBackingFields( + unique int id: @kt_property ref, + int backingField: @field ref +) + +ktSyntheticBody( + unique int id: @callable ref, + int kind: int ref + // 1: ENUM_VALUES + // 2: ENUM_VALUEOF +) + +ktLocalFunction( + unique int id: @method ref +) + +ktInitializerAssignment( + unique int id: @assignexpr ref +) + +ktPropertyDelegates( + unique int id: @kt_property ref, + unique int variableId: @variable ref +) + +/** + * If `id` is a compiler generated element, then the kind indicates the + * reason that the compiler generated it. + * See `Element.compilerGeneratedReason()` for an explanation of what + * each `kind` means. + */ +compiler_generated( + unique int id: @element ref, + int kind: int ref +) + +ktFunctionOriginalNames( + unique int id: @method ref, + string name: string ref +) diff --git a/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/upgrade.properties b/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/upgrade.properties new file mode 100644 index 00000000000..25c651f591b --- /dev/null +++ b/java/ql/lib/upgrades/cf58c7d9b1fa1eae9cdc20ce8f157c140ac0c3de/upgrade.properties @@ -0,0 +1,2 @@ +description: Add errortype +compatibility: full From 39406436bfa54a3ee3581573f4e4f1928c7a6c80 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 11 Jul 2022 15:11:13 +0200 Subject: [PATCH 282/465] Swift: extract `IfConfigDecl` This also adds `UnresolvedDeclRefExpr` tests, as `IfConfigDecl` consistently introduces those. --- swift/codegen/schema.yml | 11 ++++++- swift/extractor/infra/SwiftDispatcher.h | 19 ++++++++++-- swift/extractor/infra/SwiftTagTraits.h | 1 + swift/extractor/visitors/DeclVisitor.cpp | 14 +++++++++ swift/extractor/visitors/DeclVisitor.h | 7 +++++ swift/extractor/visitors/SwiftVisitor.h | 1 + swift/ql/lib/codeql/swift/elements.qll | 1 + .../swift/elements/decl/IfConfigClause.qll | 4 +++ .../elements/expr/UnresolvedDeclRefExpr.qll | 9 ++++-- .../swift/generated/GetImmediateParent.qll | 6 ++++ .../swift/generated/decl/IfConfigClause.qll | 30 +++++++++++++++++++ .../swift/generated/decl/IfConfigDecl.qll | 12 ++++++++ swift/ql/lib/swift.dbscheme | 30 +++++++++++++++++++ .../IfConfigClause/IfConfigClause.expected | 6 ++++ .../decl/IfConfigClause/IfConfigClause.ql | 10 +++++++ .../IfConfigClause_getCondition.expected | 4 +++ .../IfConfigClause_getCondition.ql | 7 +++++ .../IfConfigClause_getElement.expected | 18 +++++++++++ .../IfConfigClause_getElement.ql | 7 +++++ .../decl/IfConfigClause/if_config.swift | 10 +++++++ .../IfConfigClause/if_config_active.swift | 12 ++++++++ .../decl/IfConfigDecl/IfConfigDecl.expected | 1 + .../decl/IfConfigDecl/IfConfigDecl.ql | 7 +++++ .../IfConfigDecl_getClause.expected | 3 ++ .../IfConfigDecl/IfConfigDecl_getClause.ql | 7 +++++ .../decl/IfConfigDecl/MISSING_SOURCE.txt | 4 --- .../decl/IfConfigDecl/if_config.swift | 10 +++++++ .../UnresolvedDeclRefExpr.expected | 10 +++++++ .../UnresolvedDeclRefExpr.ql | 7 +++++ .../UnresolvedDeclRefExpr_getName.expected | 10 +++++++ .../UnresolvedDeclRefExpr_getName.ql | 7 +++++ .../UnresolvedDeclRefExpr_getType.expected | 0 .../UnresolvedDeclRefExpr_getType.ql | 7 +++++ .../unresolved_decl_ref.swift | 10 +++++++ 34 files changed, 293 insertions(+), 9 deletions(-) create mode 100644 swift/ql/lib/codeql/swift/elements/decl/IfConfigClause.qll create mode 100644 swift/ql/lib/codeql/swift/generated/decl/IfConfigClause.qll create mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config.swift create mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config_active.swift create mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.ql delete mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/if_config.swift create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.expected create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.ql create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.expected create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.ql create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getType.expected create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getType.ql create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/unresolved_decl_ref.swift diff --git a/swift/codegen/schema.yml b/swift/codegen/schema.yml index 96da8c96936..540f187d021 100644 --- a/swift/codegen/schema.yml +++ b/swift/codegen/schema.yml @@ -270,6 +270,16 @@ EnumCaseDecl: IfConfigDecl: _extends: Decl + _children: + clauses: IfConfigClause* + +IfConfigClause: + _extends: Locatable + _children: + condition: Expr? + elements: AstNode* + is_active: predicate + _dir: decl ImportDecl: _extends: Decl @@ -545,7 +555,6 @@ TypeExpr: UnresolvedDeclRefExpr: _extends: Expr name: string? - _pragma: qltest_skip # we should really never extract these UnresolvedDotExpr: _extends: Expr diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index c7ca43a1614..095ddf0a7aa 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -78,7 +78,7 @@ class SwiftDispatcher { waitingForNewLabel = e; visit(e); if (auto l = store.get(e)) { - if constexpr (!std::is_base_of_v) { + if constexpr (std::is_base_of_v>) { attachLocation(e, *l); } return *l; @@ -95,6 +95,10 @@ class SwiftDispatcher { return fetchLabelFromUnion(node); } + TrapLabel fetchLabel(const swift::IfConfigClause& clause) { + return fetchLabel(&clause); + } + // Due to the lazy emission approach, we must assign a label to a corresponding AST node before // it actually gets emitted to handle recursive cases such as recursive calls, or recursive type // declarations @@ -143,6 +147,15 @@ class SwiftDispatcher { attachLocation(locatable->getStartLoc(), locatable->getEndLoc(), locatableLabel); } + void attachLocation(const swift::IfConfigClause* clause, TrapLabel locatableLabel) { + attachLocation(clause->Loc, clause->Loc, locatableLabel); + } + + // Emits a Location TRAP entry and attaches it to a `Locatable` trap label for a given `SourceLoc` + void attachLocation(swift::SourceLoc loc, TrapLabel locatableLabel) { + attachLocation(loc, loc, locatableLabel); + } + // Emits a Location TRAP entry for a list of swift entities and attaches it to a `Locatable` trap // label template @@ -217,7 +230,8 @@ class SwiftDispatcher { swift::Expr, swift::Pattern, swift::TypeRepr, - swift::TypeBase>; + swift::TypeBase, + swift::IfConfigClause>; void attachLocation(swift::SourceLoc start, swift::SourceLoc end, @@ -274,6 +288,7 @@ class SwiftDispatcher { // TODO: The following methods are supposed to redirect TRAP emission to correpsonding visitors, // which are to be introduced in follow-up PRs virtual void visit(swift::Decl* decl) = 0; + virtual void visit(const swift::IfConfigClause* clause) = 0; virtual void visit(swift::Stmt* stmt) = 0; virtual void visit(swift::StmtCondition* cond) = 0; virtual void visit(swift::CaseLabelItem* item) = 0; diff --git a/swift/extractor/infra/SwiftTagTraits.h b/swift/extractor/infra/SwiftTagTraits.h index 8a2e489683d..1de7312df50 100644 --- a/swift/extractor/infra/SwiftTagTraits.h +++ b/swift/extractor/infra/SwiftTagTraits.h @@ -47,6 +47,7 @@ MAP_TAG(Expr); #include MAP_TAG(Decl); +MAP_TAG(IfConfigClause); #define ABSTRACT_DECL(CLASS, PARENT) MAP_SUBTAG(CLASS##Decl, PARENT) #define DECL(CLASS, PARENT) ABSTRACT_DECL(CLASS, PARENT) #include diff --git a/swift/extractor/visitors/DeclVisitor.cpp b/swift/extractor/visitors/DeclVisitor.cpp index 33f746f6634..819c959a6d2 100644 --- a/swift/extractor/visitors/DeclVisitor.cpp +++ b/swift/extractor/visitors/DeclVisitor.cpp @@ -358,4 +358,18 @@ void DeclVisitor::fillAbstractStorageDecl(const swift::AbstractStorageDecl& decl fillValueDecl(decl, entry); } +codeql::IfConfigDecl DeclVisitor::translateIfConfigDecl(const swift::IfConfigDecl& decl) { + auto entry = dispatcher_.createEntry(decl); + entry.clauses = dispatcher_.fetchRepeatedLabels(decl.getClauses()); + return entry; +} + +codeql::IfConfigClause DeclVisitor::translateIfConfigClause(const swift::IfConfigClause& clause) { + auto entry = dispatcher_.createEntry(clause); + entry.condition = dispatcher_.fetchOptionalLabel(clause.Cond); + entry.elements = dispatcher_.fetchRepeatedLabels(clause.Elements); + entry.is_active = clause.isActive; + return entry; +} + } // namespace codeql diff --git a/swift/extractor/visitors/DeclVisitor.h b/swift/extractor/visitors/DeclVisitor.h index c9a1b43556d..0d6296591a0 100644 --- a/swift/extractor/visitors/DeclVisitor.h +++ b/swift/extractor/visitors/DeclVisitor.h @@ -14,6 +14,11 @@ namespace codeql { class DeclVisitor : public AstVisitorBase { public: using AstVisitorBase::AstVisitorBase; + using AstVisitorBase::visit; + + void visit(const swift::IfConfigClause* clause) { + dispatcher_.emit(translateIfConfigClause(*clause)); + } std::variant translateFuncDecl( const swift::FuncDecl& decl); @@ -52,6 +57,8 @@ class DeclVisitor : public AstVisitorBase { codeql::ExtensionDecl translateExtensionDecl(const swift::ExtensionDecl& decl); codeql::ImportDecl translateImportDecl(const swift::ImportDecl& decl); std::optional translateModuleDecl(const swift::ModuleDecl& decl); + codeql::IfConfigDecl translateIfConfigDecl(const swift::IfConfigDecl& decl); + codeql::IfConfigClause translateIfConfigClause(const swift::IfConfigClause& clause); private: std::string mangledName(const swift::ValueDecl& decl); diff --git a/swift/extractor/visitors/SwiftVisitor.h b/swift/extractor/visitors/SwiftVisitor.h index 6380390af82..66c11b5227b 100644 --- a/swift/extractor/visitors/SwiftVisitor.h +++ b/swift/extractor/visitors/SwiftVisitor.h @@ -21,6 +21,7 @@ class SwiftVisitor : private SwiftDispatcher { private: void visit(swift::Decl* decl) override { declVisitor.visit(decl); } + void visit(const swift::IfConfigClause* clause) override { declVisitor.visit(clause); } void visit(swift::Stmt* stmt) override { stmtVisitor.visit(stmt); } void visit(swift::StmtCondition* cond) override { stmtVisitor.visitStmtCondition(cond); } void visit(swift::CaseLabelItem* item) override { stmtVisitor.visitCaseLabelItem(item); } diff --git a/swift/ql/lib/codeql/swift/elements.qll b/swift/ql/lib/codeql/swift/elements.qll index c10706d7c7a..bb3087936b9 100644 --- a/swift/ql/lib/codeql/swift/elements.qll +++ b/swift/ql/lib/codeql/swift/elements.qll @@ -24,6 +24,7 @@ import codeql.swift.elements.decl.FuncDecl import codeql.swift.elements.decl.GenericContext import codeql.swift.elements.decl.GenericTypeDecl import codeql.swift.elements.decl.GenericTypeParamDecl +import codeql.swift.elements.decl.IfConfigClause import codeql.swift.elements.decl.IfConfigDecl import codeql.swift.elements.decl.ImportDecl import codeql.swift.elements.decl.InfixOperatorDecl diff --git a/swift/ql/lib/codeql/swift/elements/decl/IfConfigClause.qll b/swift/ql/lib/codeql/swift/elements/decl/IfConfigClause.qll new file mode 100644 index 00000000000..6ab22e67989 --- /dev/null +++ b/swift/ql/lib/codeql/swift/elements/decl/IfConfigClause.qll @@ -0,0 +1,4 @@ +// generated by codegen/codegen.py, remove this comment if you wish to edit this file +private import codeql.swift.generated.decl.IfConfigClause + +class IfConfigClause extends IfConfigClauseBase { } diff --git a/swift/ql/lib/codeql/swift/elements/expr/UnresolvedDeclRefExpr.qll b/swift/ql/lib/codeql/swift/elements/expr/UnresolvedDeclRefExpr.qll index 281e1db01a7..3cbe55fe9a6 100644 --- a/swift/ql/lib/codeql/swift/elements/expr/UnresolvedDeclRefExpr.qll +++ b/swift/ql/lib/codeql/swift/elements/expr/UnresolvedDeclRefExpr.qll @@ -1,4 +1,9 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file private import codeql.swift.generated.expr.UnresolvedDeclRefExpr -class UnresolvedDeclRefExpr extends UnresolvedDeclRefExprBase { } +class UnresolvedDeclRefExpr extends UnresolvedDeclRefExprBase { + override string toString() { + result = getName() + " (unresolved)" + or + not hasName() and result = "(unresolved)" + } +} diff --git a/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll b/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll index 4cecd1a3ce6..9ca82a5e47d 100644 --- a/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll +++ b/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll @@ -28,6 +28,12 @@ Element getAnImmediateChild(Element e) { or enum_element_decl_params(e, _, x) or + if_config_clause_conditions(e, x) + or + if_config_clause_elements(e, _, x) + or + if_config_decl_clauses(e, _, x) + or pattern_binding_decl_inits(e, _, x) or pattern_binding_decl_patterns(e, _, x) diff --git a/swift/ql/lib/codeql/swift/generated/decl/IfConfigClause.qll b/swift/ql/lib/codeql/swift/generated/decl/IfConfigClause.qll new file mode 100644 index 00000000000..89a1cb277ed --- /dev/null +++ b/swift/ql/lib/codeql/swift/generated/decl/IfConfigClause.qll @@ -0,0 +1,30 @@ +// generated by codegen/codegen.py +import codeql.swift.elements.AstNode +import codeql.swift.elements.expr.Expr +import codeql.swift.elements.Locatable + +class IfConfigClauseBase extends @if_config_clause, Locatable { + override string getAPrimaryQlClass() { result = "IfConfigClause" } + + Expr getCondition() { + exists(Expr x | + if_config_clause_conditions(this, x) and + result = x.resolve() + ) + } + + predicate hasCondition() { exists(getCondition()) } + + AstNode getElement(int index) { + exists(AstNode x | + if_config_clause_elements(this, index, x) and + result = x.resolve() + ) + } + + AstNode getAnElement() { result = getElement(_) } + + int getNumberOfElements() { result = count(getAnElement()) } + + predicate isActive() { if_config_clause_is_active(this) } +} diff --git a/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll b/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll index 578051e9f8b..5d13959a227 100644 --- a/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll +++ b/swift/ql/lib/codeql/swift/generated/decl/IfConfigDecl.qll @@ -1,6 +1,18 @@ // generated by codegen/codegen.py import codeql.swift.elements.decl.Decl +import codeql.swift.elements.decl.IfConfigClause class IfConfigDeclBase extends @if_config_decl, Decl { override string getAPrimaryQlClass() { result = "IfConfigDecl" } + + IfConfigClause getClause(int index) { + exists(IfConfigClause x | + if_config_decl_clauses(this, index, x) and + result = x.resolve() + ) + } + + IfConfigClause getAClause() { result = getClause(_) } + + int getNumberOfClauses() { result = count(getAClause()) } } diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index c12e00e028d..e181cef772a 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -36,6 +36,7 @@ files( @locatable = @ast_node | @condition_element +| @if_config_clause ; #keyset[id] @@ -643,6 +644,35 @@ if_config_decls( //dir=decl unique int id: @if_config_decl ); +#keyset[id, index] +if_config_decl_clauses( //dir=decl + int id: @if_config_decl ref, + int index: int ref, + int clause: @if_config_clause ref +); + +if_config_clauses( //dir=decl + unique int id: @if_config_clause +); + +#keyset[id] +if_config_clause_conditions( //dir=decl + int id: @if_config_clause ref, + int condition: @expr ref +); + +#keyset[id, index] +if_config_clause_elements( //dir=decl + int id: @if_config_clause ref, + int index: int ref, + int element: @ast_node ref +); + +#keyset[id] +if_config_clause_is_active( //dir=decl + int id: @if_config_clause ref +); + import_decls( //dir=decl unique int id: @import_decl, int module: @module_decl ref diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.expected b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.expected new file mode 100644 index 00000000000..d4230ce830c --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.expected @@ -0,0 +1,6 @@ +| if_config.swift:1:1:1:1 | IfConfigClause | isActive: | no | +| if_config.swift:4:1:4:1 | IfConfigClause | isActive: | no | +| if_config.swift:7:1:7:1 | IfConfigClause | isActive: | yes | +| if_config_active.swift:3:1:3:1 | IfConfigClause | isActive: | yes | +| if_config_active.swift:6:1:6:1 | IfConfigClause | isActive: | no | +| if_config_active.swift:9:1:9:1 | IfConfigClause | isActive: | no | diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.ql b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.ql new file mode 100644 index 00000000000..832025712f0 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause.ql @@ -0,0 +1,10 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from IfConfigClause x, string isActive +where + toBeTested(x) and + not x.isUnknown() and + if x.isActive() then isActive = "yes" else isActive = "no" +select x, "isActive:", isActive diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.expected b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.expected new file mode 100644 index 00000000000..f4955665acd --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.expected @@ -0,0 +1,4 @@ +| if_config.swift:1:1:1:1 | IfConfigClause | if_config.swift:1:5:1:5 | FOO (unresolved) | +| if_config.swift:4:1:4:1 | IfConfigClause | if_config.swift:4:9:4:19 | call to ... | +| if_config_active.swift:3:1:3:1 | IfConfigClause | if_config_active.swift:3:5:3:5 | FOO (unresolved) | +| if_config_active.swift:6:1:6:1 | IfConfigClause | if_config_active.swift:6:9:6:17 | call to ... | diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.ql b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.ql new file mode 100644 index 00000000000..174c1a4994d --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getCondition.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from IfConfigClause x +where toBeTested(x) and not x.isUnknown() +select x, x.getCondition() diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.expected b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.expected new file mode 100644 index 00000000000..11dd2b54127 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.expected @@ -0,0 +1,18 @@ +| if_config.swift:1:1:1:1 | IfConfigClause | 0 | if_config.swift:2:1:2:16 | { ... } | +| if_config.swift:1:1:1:1 | IfConfigClause | 1 | if_config.swift:2:5:2:5 | foo | +| if_config.swift:1:1:1:1 | IfConfigClause | 2 | if_config.swift:3:1:3:12 | { ... } | +| if_config.swift:4:1:4:1 | IfConfigClause | 0 | if_config.swift:5:1:5:16 | { ... } | +| if_config.swift:4:1:4:1 | IfConfigClause | 1 | if_config.swift:5:5:5:5 | bar | +| if_config.swift:4:1:4:1 | IfConfigClause | 2 | if_config.swift:6:1:6:12 | { ... } | +| if_config.swift:7:1:7:1 | IfConfigClause | 0 | if_config.swift:8:1:8:16 | { ... } | +| if_config.swift:7:1:7:1 | IfConfigClause | 1 | if_config.swift:8:5:8:5 | baz | +| if_config.swift:7:1:7:1 | IfConfigClause | 2 | if_config.swift:9:1:9:12 | { ... } | +| if_config_active.swift:3:1:3:1 | IfConfigClause | 0 | if_config_active.swift:4:1:4:16 | { ... } | +| if_config_active.swift:3:1:3:1 | IfConfigClause | 1 | if_config_active.swift:4:5:4:5 | foo | +| if_config_active.swift:3:1:3:1 | IfConfigClause | 2 | if_config_active.swift:5:1:5:12 | { ... } | +| if_config_active.swift:6:1:6:1 | IfConfigClause | 0 | if_config_active.swift:7:1:7:16 | { ... } | +| if_config_active.swift:6:1:6:1 | IfConfigClause | 1 | if_config_active.swift:7:5:7:5 | bar | +| if_config_active.swift:6:1:6:1 | IfConfigClause | 2 | if_config_active.swift:8:1:8:12 | { ... } | +| if_config_active.swift:9:1:9:1 | IfConfigClause | 0 | if_config_active.swift:10:1:10:16 | { ... } | +| if_config_active.swift:9:1:9:1 | IfConfigClause | 1 | if_config_active.swift:10:5:10:5 | baz | +| if_config_active.swift:9:1:9:1 | IfConfigClause | 2 | if_config_active.swift:11:1:11:12 | { ... } | diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.ql b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.ql new file mode 100644 index 00000000000..02c0eec17c9 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/IfConfigClause_getElement.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from IfConfigClause x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getElement(index) diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config.swift b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config.swift new file mode 100644 index 00000000000..87cbc8ecd42 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config.swift @@ -0,0 +1,10 @@ +#if FOO +var foo: Int = 1 +print("foo") +#elseif os(watchOS) +var bar: Int = 2 +print("bar") +#else +var baz: Int = 3 +print("baz") +#endif diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config_active.swift b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config_active.swift new file mode 100644 index 00000000000..89849731bfe --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigClause/if_config_active.swift @@ -0,0 +1,12 @@ +//codeql-extractor-options: -D FOO + +#if FOO +var foo: Int = 1 +print("foo") +#elseif os(macOS) +var bar: Int = 2 +print("bar") +#else +var baz: Int = 3 +print("baz") +#endif diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.expected b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.expected new file mode 100644 index 00000000000..3fed7a7fcc1 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.expected @@ -0,0 +1 @@ +| if_config.swift:1:1:10:1 | #if ... | diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.ql b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.ql new file mode 100644 index 00000000000..a43d57b1d93 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from IfConfigDecl x +where toBeTested(x) and not x.isUnknown() +select x diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.expected b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.expected new file mode 100644 index 00000000000..d90ba458397 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.expected @@ -0,0 +1,3 @@ +| if_config.swift:1:1:10:1 | #if ... | 0 | if_config.swift:1:1:1:1 | IfConfigClause | +| if_config.swift:1:1:10:1 | #if ... | 1 | if_config.swift:4:1:4:1 | IfConfigClause | +| if_config.swift:1:1:10:1 | #if ... | 2 | if_config.swift:7:1:7:1 | IfConfigClause | diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.ql b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.ql new file mode 100644 index 00000000000..5ffaf75e476 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/IfConfigDecl_getClause.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from IfConfigDecl x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getClause(index) diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/if_config.swift b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/if_config.swift new file mode 100644 index 00000000000..6f492013933 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/IfConfigDecl/if_config.swift @@ -0,0 +1,10 @@ +#if FOO +var foo: Int = 1 +print("foo") +#elseif BAR +var bar: Int = 2 +print("bar") +#else +var baz: Int = 3 +print("baz") +#endif diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.expected b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.expected new file mode 100644 index 00000000000..ecf2a57ba5d --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.expected @@ -0,0 +1,10 @@ +| unresolved_decl_ref.swift:4:5:4:5 | FOO (unresolved) | +| unresolved_decl_ref.swift:4:9:4:9 | && (unresolved) | +| unresolved_decl_ref.swift:4:12:4:12 | os (unresolved) | +| unresolved_decl_ref.swift:4:15:4:15 | Windows (unresolved) | +| unresolved_decl_ref.swift:5:1:5:1 | print (unresolved) | +| unresolved_decl_ref.swift:6:9:6:9 | BAR (unresolved) | +| unresolved_decl_ref.swift:6:13:6:13 | \|\| (unresolved) | +| unresolved_decl_ref.swift:6:16:6:16 | arch (unresolved) | +| unresolved_decl_ref.swift:6:21:6:21 | i386 (unresolved) | +| unresolved_decl_ref.swift:9:1:9:1 | print (unresolved) | diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.ql new file mode 100644 index 00000000000..507d2fcf87d --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from UnresolvedDeclRefExpr x +where toBeTested(x) and not x.isUnknown() +select x diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.expected b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.expected new file mode 100644 index 00000000000..1ea60aabedc --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.expected @@ -0,0 +1,10 @@ +| unresolved_decl_ref.swift:4:5:4:5 | FOO (unresolved) | FOO | +| unresolved_decl_ref.swift:4:9:4:9 | && (unresolved) | && | +| unresolved_decl_ref.swift:4:12:4:12 | os (unresolved) | os | +| unresolved_decl_ref.swift:4:15:4:15 | Windows (unresolved) | Windows | +| unresolved_decl_ref.swift:5:1:5:1 | print (unresolved) | print | +| unresolved_decl_ref.swift:6:9:6:9 | BAR (unresolved) | BAR | +| unresolved_decl_ref.swift:6:13:6:13 | \|\| (unresolved) | \|\| | +| unresolved_decl_ref.swift:6:16:6:16 | arch (unresolved) | arch | +| unresolved_decl_ref.swift:6:21:6:21 | i386 (unresolved) | i386 | +| unresolved_decl_ref.swift:9:1:9:1 | print (unresolved) | print | diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.ql new file mode 100644 index 00000000000..1424e3443d9 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getName.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from UnresolvedDeclRefExpr x +where toBeTested(x) and not x.isUnknown() +select x, x.getName() diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getType.expected b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getType.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getType.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getType.ql new file mode 100644 index 00000000000..27953cceeb1 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/UnresolvedDeclRefExpr_getType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from UnresolvedDeclRefExpr x +where toBeTested(x) and not x.isUnknown() +select x, x.getType() diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/unresolved_decl_ref.swift b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/unresolved_decl_ref.swift new file mode 100644 index 00000000000..94dee19d618 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDeclRefExpr/unresolved_decl_ref.swift @@ -0,0 +1,10 @@ +//codeql-extractor-options: -D BAR + +// conditions and inactive branches in conditional compilation blocks are not resolved +#if FOO && os(Windows) +print(1) +#elseif BAR || arch(i386) +print(2) +#else +print(3) +#endif From 93d06daf6738843472c72c4ae80e3396a08d1891 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 11 Jul 2022 15:59:21 +0200 Subject: [PATCH 283/465] Swift: allow skipping fields in cppgen Some fields of base classes pose some problems with diamond hierarchies, and we don't use them any way as we are emitting them using directly trap entries instead of structured C++ classes. This introduces a `cpp_skip` pragma to skip generation of those fields in structured generated C++ classes, and applies it to `is_unknown` and `location`. --- swift/codegen/generators/cppgen.py | 38 +++++++++++++++++------------- swift/codegen/schema.yml | 8 +++++-- swift/codegen/test/test_cppgen.py | 13 ++++++++++ 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/swift/codegen/generators/cppgen.py b/swift/codegen/generators/cppgen.py index ef042f42dbd..08af5fb82f9 100644 --- a/swift/codegen/generators/cppgen.py +++ b/swift/codegen/generators/cppgen.py @@ -13,6 +13,7 @@ Each class in the schema gets a corresponding `struct` in `TrapClasses.h`, where import functools import pathlib +import typing from typing import Dict import inflection @@ -34,22 +35,25 @@ def _get_type(t: str) -> str: return t -def _get_field(cls: schema.Class, p: schema.Property) -> cpp.Field: - trap_name = None - if not p.is_single: - trap_name = inflection.camelize(f"{cls.name}_{p.name}") - if not p.is_predicate: - trap_name = inflection.pluralize(trap_name) - args = dict( - field_name=p.name + ("_" if p.name in cpp.cpp_keywords else ""), - type=_get_type(p.type), - is_optional=p.is_optional, - is_repeated=p.is_repeated, - is_predicate=p.is_predicate, - trap_name=trap_name, - ) - args.update(cpp.get_field_override(p.name)) - return cpp.Field(**args) +def _get_fields(cls: schema.Class) -> typing.Iterable[cpp.Field]: + for p in cls.properties: + if "cpp_skip" in p.pragmas: + continue + trap_name = None + if not p.is_single: + trap_name = inflection.camelize(f"{cls.name}_{p.name}") + if not p.is_predicate: + trap_name = inflection.pluralize(trap_name) + args = dict( + field_name=p.name + ("_" if p.name in cpp.cpp_keywords else ""), + type=_get_type(p.type), + is_optional=p.is_optional, + is_repeated=p.is_repeated, + is_predicate=p.is_predicate, + trap_name=trap_name, + ) + args.update(cpp.get_field_override(p.name)) + yield cpp.Field(**args) class Processor: @@ -65,7 +69,7 @@ class Processor: return cpp.Class( name=name, bases=[self._get_class(b) for b in cls.bases], - fields=[_get_field(cls, p) for p in cls.properties], + fields=list(_get_fields(cls)), final=not cls.derived, trap_name=trap_name, ) diff --git a/swift/codegen/schema.yml b/swift/codegen/schema.yml index 01bb0c2feba..ed3d4433a9f 100644 --- a/swift/codegen/schema.yml +++ b/swift/codegen/schema.yml @@ -13,14 +13,18 @@ _directories: stmt: Stmt$ Element: - is_unknown: predicate + is_unknown: + type: predicate + _pragma: cpp_skip # this is emitted using trap entries directly _pragma: qltest_skip File: name: string Locatable: - location: Location? + location: + type: Location? + _pragma: cpp_skip # this is emitted using trap entries directly _pragma: qltest_skip Location: diff --git a/swift/codegen/test/test_cppgen.py b/swift/codegen/test/test_cppgen.py index 160dd6cd2c1..7938cb6decd 100644 --- a/swift/codegen/test/test_cppgen.py +++ b/swift/codegen/test/test_cppgen.py @@ -165,5 +165,18 @@ def test_classes_with_dirs(generate_grouped): } +def test_cpp_skip_pragma(generate): + assert generate([ + schema.Class(name="A", properties=[ + schema.SingleProperty("x", "foo"), + schema.SingleProperty("y", "bar", pragmas=["x", "cpp_skip", "y"]), + ]) + ]) == [ + cpp.Class(name="A", final=True, trap_name="As", fields=[ + cpp.Field("x", "foo"), + ]), + ] + + if __name__ == '__main__': sys.exit(pytest.main([__file__] + sys.argv[1:])) From 348ad95fc001b154f9640108b8d04e7ececdc56c Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Mon, 11 Jul 2022 15:06:27 +0100 Subject: [PATCH 284/465] Ruby: fix defining every dataflow node as a command execution sink --- ruby/ql/lib/codeql/ruby/frameworks/Railties.qll | 4 ++-- .../library-tests/frameworks/railties/Railties.expected | 9 +++++++++ .../test/library-tests/frameworks/railties/Railties.ql | 5 +++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Railties.qll b/ruby/ql/lib/codeql/ruby/frameworks/Railties.qll index 4a61eb1dd20..807cc9f9c51 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Railties.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Railties.qll @@ -43,7 +43,7 @@ module Railties { override DataFlow::Node getAnArgument() { result = this.getArgument([0, 1]) } - override predicate isShellInterpreted(DataFlow::Node arg) { any() } + override predicate isShellInterpreted(DataFlow::Node arg) { arg = this.getAnArgument() } } /** @@ -57,6 +57,6 @@ module Railties { override DataFlow::Node getAnArgument() { result = this.getArgument(0) } - override predicate isShellInterpreted(DataFlow::Node arg) { any() } + override predicate isShellInterpreted(DataFlow::Node arg) { arg = this.getAnArgument() } } } diff --git a/ruby/ql/test/library-tests/frameworks/railties/Railties.expected b/ruby/ql/test/library-tests/frameworks/railties/Railties.expected index c012090bbe1..42cac29b7c5 100644 --- a/ruby/ql/test/library-tests/frameworks/railties/Railties.expected +++ b/ruby/ql/test/library-tests/frameworks/railties/Railties.expected @@ -1,5 +1,14 @@ +systemCommandExecutions | Railties.rb:5:5:5:34 | call to execute_command | | Railties.rb:6:5:6:37 | call to execute_command | | Railties.rb:8:5:8:16 | call to rake | | Railties.rb:10:5:10:27 | call to rails_command | | Railties.rb:12:5:12:17 | call to git | +shellInterpretedArguments +| Railties.rb:5:5:5:34 | call to execute_command | Railties.rb:5:21:5:25 | :rake | +| Railties.rb:5:5:5:34 | call to execute_command | Railties.rb:5:28:5:33 | "test" | +| Railties.rb:6:5:6:37 | call to execute_command | Railties.rb:6:21:6:26 | :rails | +| Railties.rb:6:5:6:37 | call to execute_command | Railties.rb:6:29:6:36 | "server" | +| Railties.rb:8:5:8:16 | call to rake | Railties.rb:8:10:8:15 | "test" | +| Railties.rb:10:5:10:27 | call to rails_command | Railties.rb:10:19:10:26 | "server" | +| Railties.rb:12:5:12:17 | call to git | Railties.rb:12:9:12:16 | "status" | diff --git a/ruby/ql/test/library-tests/frameworks/railties/Railties.ql b/ruby/ql/test/library-tests/frameworks/railties/Railties.ql index 9a9731befb4..4dee50abcd5 100644 --- a/ruby/ql/test/library-tests/frameworks/railties/Railties.ql +++ b/ruby/ql/test/library-tests/frameworks/railties/Railties.ql @@ -1,5 +1,10 @@ private import ruby private import codeql.ruby.Concepts private import codeql.ruby.frameworks.Railties +private import codeql.ruby.DataFlow query predicate systemCommandExecutions(SystemCommandExecution e) { any() } + +query predicate shellInterpretedArguments(SystemCommandExecution e, DataFlow::Node arg) { + e.isShellInterpreted(arg) +} From 156bc34cdadbd1913cc2c3ae93fc0953c04c5bdc Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Mon, 11 Jul 2022 08:41:05 -0700 Subject: [PATCH 285/465] Update UnsafeUsageOfClientSideEncryptionVersion.qhelp --- .../Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp index 49aa5623570..a3a33691854 100644 --- a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -14,11 +14,6 @@ -

    The following example shows an HTTP request parameter being used directly in a forming a -new request without validating the input, which facilitates SSRF attacks. -It also shows how to remedy the problem by validating the user input against a known fixed string. -

    -
    From 5d89a5d164f111e9080d711e16a903b8d7af291f Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Mon, 11 Jul 2022 08:42:50 -0700 Subject: [PATCH 286/465] Update csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql Co-authored-by: Taus --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 0de3d020e4f..095c154e9a3 100644 --- a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -14,7 +14,7 @@ import csharp /** * Holds if `oc` is creating an object of type `c` = `Azure.Storage.ClientSideEncryptionOptions` - * and `e` is the `version` argument to the contructor + * and `e` is the `version` argument to the constructor */ predicate isCreatingAzureClientSideEncryptionObject(ObjectCreation oc, Class c, Expr e) { exists(Parameter p | p.hasName("version") | From 6632dfaf88eaa2dd266ee5dfa745142678844de4 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Mon, 11 Jul 2022 16:34:38 +0100 Subject: [PATCH 287/465] Ruby: fix another SystemCommandExecution::isShellInterpreted implementation --- ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll | 2 +- ruby/ql/test/library-tests/frameworks/PosixSpawn.ql | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll b/ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll index 6a27018fcf5..6c4d2ab1a47 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/PosixSpawn.qll @@ -62,9 +62,9 @@ module PosixSpawn { // is shell interpreted unless there is another argument with a string // constant value. override predicate isShellInterpreted(DataFlow::Node arg) { + this.argument(arg) and not exists(DataFlow::Node otherArg | otherArg != arg and - this.argument(arg) and this.argument(otherArg) and otherArg.asExpr().getConstantValue().isString(_) ) diff --git a/ruby/ql/test/library-tests/frameworks/PosixSpawn.ql b/ruby/ql/test/library-tests/frameworks/PosixSpawn.ql index 12fb445cf15..994f0d162f0 100644 --- a/ruby/ql/test/library-tests/frameworks/PosixSpawn.ql +++ b/ruby/ql/test/library-tests/frameworks/PosixSpawn.ql @@ -5,11 +5,13 @@ import codeql.ruby.DataFlow query predicate systemCalls( PosixSpawn::SystemCall call, DataFlow::Node arg, boolean shellInterpreted ) { - arg = call.getAnArgument() and - if call.isShellInterpreted(arg) then shellInterpreted = true else shellInterpreted = false + call.isShellInterpreted(arg) and shellInterpreted = true + or + not call.isShellInterpreted(arg) and arg = call.getAnArgument() and shellInterpreted = false } query predicate childCalls(PosixSpawn::ChildCall call, DataFlow::Node arg, boolean shellInterpreted) { - arg = call.getAnArgument() and - if call.isShellInterpreted(arg) then shellInterpreted = true else shellInterpreted = false + call.isShellInterpreted(arg) and shellInterpreted = true + or + not call.isShellInterpreted(arg) and arg = call.getAnArgument() and shellInterpreted = false } From 032aa56dc3abbd8bfbab44212ecc730ebd7ae7d0 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Mon, 11 Jul 2022 17:00:07 +0100 Subject: [PATCH 288/465] Ruby: add change note for system command execution sink bug --- ruby/ql/lib/change-notes/2022-07-11-command-execution.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 ruby/ql/lib/change-notes/2022-07-11-command-execution.md diff --git a/ruby/ql/lib/change-notes/2022-07-11-command-execution.md b/ruby/ql/lib/change-notes/2022-07-11-command-execution.md new file mode 100644 index 00000000000..c95b9afb133 --- /dev/null +++ b/ruby/ql/lib/change-notes/2022-07-11-command-execution.md @@ -0,0 +1,6 @@ +--- +category: minorAnalysis +--- +* Fixed a bug causing every expression in the database to be a considered a system-command execution sink when calls to any of the following methods exist: + * The `spawn", "fspawn", "popen4", "pspawn", "system", "_pspawn" methods and the backtick operator from the `POSIX::spawn` gem. + * The `execute_command`, `rake`, `rails_command`, and `git` methods in `Rails::Generation::Actions`. From a3628b06f1f0efa57d6f705259c53aee736bc96c Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Mon, 11 Jul 2022 17:23:45 +0100 Subject: [PATCH 289/465] Ruby: fix markup in changenote --- ruby/ql/lib/change-notes/2022-07-11-command-execution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/change-notes/2022-07-11-command-execution.md b/ruby/ql/lib/change-notes/2022-07-11-command-execution.md index c95b9afb133..2c5addba1f5 100644 --- a/ruby/ql/lib/change-notes/2022-07-11-command-execution.md +++ b/ruby/ql/lib/change-notes/2022-07-11-command-execution.md @@ -2,5 +2,5 @@ category: minorAnalysis --- * Fixed a bug causing every expression in the database to be a considered a system-command execution sink when calls to any of the following methods exist: - * The `spawn", "fspawn", "popen4", "pspawn", "system", "_pspawn" methods and the backtick operator from the `POSIX::spawn` gem. + * The `spawn`, `fspawn`, `popen4`, `pspawn`, `system`, `_pspawn` methods and the backtick operator from the `POSIX::spawn` gem. * The `execute_command`, `rake`, `rails_command`, and `git` methods in `Rails::Generation::Actions`. From 4704269086c6fadec3d97c7ad16bf056946d1ae8 Mon Sep 17 00:00:00 2001 From: Henry Mercer Date: Mon, 11 Jul 2022 18:36:03 +0100 Subject: [PATCH 290/465] Add example registry authentication string --- .../codeql-cli/publishing-and-using-codeql-packs.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst index 67e90b5ba3f..985ca2659f3 100644 --- a/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst +++ b/docs/codeql/codeql-cli/publishing-and-using-codeql-packs.rst @@ -103,7 +103,7 @@ You can now use ``codeql pack publish``, ``codeql pack download``, and ``codeql Authenticating to GitHub Container registries --------------------------------------------- -You can download a private pack or publish a pack by authenticating to the appropriate GitHub Container registry. +You can publish packs and download private packs by authenticating to the appropriate GitHub Container registry. You can authenticate to the Container registry on GitHub.com in two ways: @@ -115,5 +115,10 @@ Similarly, you can authenticate to a GHES Container registry, or authenticate to 1. Pass the ``--registries-auth-stdin`` option to the CodeQL CLI, then supply a registry authentication string via standard input. 2. Set the ``CODEQL_REGISTRIES_AUTH`` environment variable to a registry authentication string. -A registry authentication string is a comma-separated list of ``=`` pairs, where ``registry-url`` is a GitHub Container registry URL, for example ``https://containers.GHE_HOSTNAME/v2/`` and ``token`` is a GitHub Apps token or personal access token for that GitHub Container registry. +A registry authentication string is a comma-separated list of ``=`` pairs, where ``registry-url`` is a GitHub Container registry URL, such as ``https://containers.GHE_HOSTNAME/v2/``, and ``token`` is a GitHub Apps token or personal access token for that GitHub Container registry. This ensures that each token is only passed to the Container registry you specify. +For instance, the following registry authentication string specifies that the CodeQL CLI should authenticate to the Container registry on GitHub.com using the token ```` and to the Container registry for the GHES instance at ``GHE_HOSTNAME`` using the token ````: + +.. code-block:: none + + https://ghcr.io/v2/=,https://containers.GHE_HOSTNAME/v2/= From b9072a35943c1f6845124ed71c995e1dfca2cb32 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 11 Jul 2022 18:57:43 +0100 Subject: [PATCH 291/465] Kotlin: Share a Psi2Ir instance --- .../src/main/kotlin/comments/CommentExtractor.kt | 5 +++-- .../src/main/kotlin/utils/IrVisitorLookup.kt | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt index 93d3c0534de..f3fef96a338 100644 --- a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt @@ -16,7 +16,8 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset class CommentExtractor(private val fileExtractor: KotlinFileExtractor, private val file: IrFile, private val fileLabel: Label) { private val tw = fileExtractor.tw private val logger = fileExtractor.logger - private val ktFile = Psi2Ir().getKtFile(file) + private val psi2Ir = Psi2Ir() + private val ktFile = psi2Ir.getKtFile(file) fun extract() { if (ktFile == null) { @@ -85,7 +86,7 @@ class CommentExtractor(private val fileExtractor: KotlinFileExtractor, private v val ownerPsi = getKDocOwner(comment) ?: return val owners = mutableListOf() - file.accept(IrVisitorLookup(ownerPsi, file), owners) + file.accept(IrVisitorLookup(psi2Ir, ownerPsi, file), owners) for (ownerIr in owners) { val ownerLabel = diff --git a/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt b/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt index 0020d00fac4..a25c1a4534f 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt @@ -8,7 +8,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.util.isFakeOverride import org.jetbrains.kotlin.ir.visitors.IrElementVisitor -class IrVisitorLookup(private val psi: PsiElement, private val file: IrFile) : +class IrVisitorLookup(private val psi2Ir: Psi2Ir, private val psi: PsiElement, private val file: IrFile) : IrElementVisitor> { private val location = psi.getLocation() @@ -27,7 +27,7 @@ class IrVisitorLookup(private val psi: PsiElement, private val file: IrFile) : } if (location.contains(elementLocation)) { - val psiElement = Psi2Ir().findPsiElement(element, file) + val psiElement = psi2Ir.findPsiElement(element, file) if (psiElement == psi) { // There can be multiple IrElements that match the same PSI element. data.add(element) @@ -35,4 +35,4 @@ class IrVisitorLookup(private val psi: PsiElement, private val file: IrFile) : } element.acceptChildren(this, data) } -} \ No newline at end of file +} From 4c68624b00bff04949c11f4d7b408c97fc8f71c8 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 11 Jul 2022 19:17:21 +0100 Subject: [PATCH 292/465] Kotlin: Pass a FileLogger to Psi2Ir --- .../src/main/kotlin/comments/CommentExtractor.kt | 2 +- .../src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt | 5 +++-- .../src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt | 5 +++-- .../src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt | 5 +++-- .../src/main/kotlin/utils/versions/v_1_5_21/Psi2Ir.kt | 5 +++-- .../src/main/kotlin/utils/versions/v_1_5_31/Psi2Ir.kt | 5 +++-- .../src/main/kotlin/utils/versions/v_1_6_10/Psi2Ir.kt | 5 +++-- .../src/main/kotlin/utils/versions/v_1_6_20/Psi2Ir.kt | 5 +++-- .../src/main/kotlin/utils/versions/v_1_7_0/Psi2Ir.kt | 5 +++-- 9 files changed, 25 insertions(+), 17 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt index f3fef96a338..03f032f8810 100644 --- a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt @@ -16,7 +16,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset class CommentExtractor(private val fileExtractor: KotlinFileExtractor, private val file: IrFile, private val fileLabel: Label) { private val tw = fileExtractor.tw private val logger = fileExtractor.logger - private val psi2Ir = Psi2Ir() + private val psi2Ir = Psi2Ir(logger) private val ktFile = psi2Ir.getKtFile(file) fun extract() { diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt index 16ee288d05a..392e7cf6c28 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt @@ -1,12 +1,13 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi2ir.PsiSourceManager -class Psi2Ir : Psi2IrFacade { +class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade { companion object { val psiManager = PsiSourceManager() } @@ -18,4 +19,4 @@ class Psi2Ir : Psi2IrFacade { override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { return psiManager.findPsiElement(irElement, irFile) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt index 16ee288d05a..392e7cf6c28 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt @@ -1,12 +1,13 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi2ir.PsiSourceManager -class Psi2Ir : Psi2IrFacade { +class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade { companion object { val psiManager = PsiSourceManager() } @@ -18,4 +19,4 @@ class Psi2Ir : Psi2IrFacade { override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { return psiManager.findPsiElement(irElement, irFile) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt index 16ee288d05a..392e7cf6c28 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt @@ -1,12 +1,13 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi2ir.PsiSourceManager -class Psi2Ir : Psi2IrFacade { +class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade { companion object { val psiManager = PsiSourceManager() } @@ -18,4 +19,4 @@ class Psi2Ir : Psi2IrFacade { override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { return psiManager.findPsiElement(irElement, irFile) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_21/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_21/Psi2Ir.kt index 256a8b3bb63..8e21191f2a0 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_21/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_21/Psi2Ir.kt @@ -1,5 +1,6 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.ir.getKtFile @@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -class Psi2Ir: Psi2IrFacade { +class Psi2Ir(private val logger: FileLogger): Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { return irFile.getKtFile() } @@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade { override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { return PsiSourceManager.findPsiElement(irElement, irFile) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_31/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_31/Psi2Ir.kt index 256a8b3bb63..8e21191f2a0 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_31/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_31/Psi2Ir.kt @@ -1,5 +1,6 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.ir.getKtFile @@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -class Psi2Ir: Psi2IrFacade { +class Psi2Ir(private val logger: FileLogger): Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { return irFile.getKtFile() } @@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade { override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { return PsiSourceManager.findPsiElement(irElement, irFile) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_10/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_10/Psi2Ir.kt index 256a8b3bb63..8e21191f2a0 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_10/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_10/Psi2Ir.kt @@ -1,5 +1,6 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.ir.getKtFile @@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -class Psi2Ir: Psi2IrFacade { +class Psi2Ir(private val logger: FileLogger): Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { return irFile.getKtFile() } @@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade { override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { return PsiSourceManager.findPsiElement(irElement, irFile) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_20/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_20/Psi2Ir.kt index 256a8b3bb63..8e21191f2a0 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_20/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_6_20/Psi2Ir.kt @@ -1,5 +1,6 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.ir.getKtFile @@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -class Psi2Ir: Psi2IrFacade { +class Psi2Ir(private val logger: FileLogger): Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { return irFile.getKtFile() } @@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade { override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { return PsiSourceManager.findPsiElement(irElement, irFile) } -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Psi2Ir.kt index 256a8b3bb63..8e21191f2a0 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_7_0/Psi2Ir.kt @@ -1,5 +1,6 @@ package com.github.codeql.utils.versions +import com.github.codeql.FileLogger import com.intellij.psi.PsiElement import org.jetbrains.kotlin.backend.common.psi.PsiSourceManager import org.jetbrains.kotlin.backend.jvm.ir.getKtFile @@ -7,7 +8,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -class Psi2Ir: Psi2IrFacade { +class Psi2Ir(private val logger: FileLogger): Psi2IrFacade { override fun getKtFile(irFile: IrFile): KtFile? { return irFile.getKtFile() } @@ -15,4 +16,4 @@ class Psi2Ir: Psi2IrFacade { override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { return PsiSourceManager.findPsiElement(irElement, irFile) } -} \ No newline at end of file +} From 960d1dba8a5dd72af2f3d070646dcea56b71cb20 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Mon, 11 Jul 2022 19:36:43 +0100 Subject: [PATCH 293/465] Kotlin: We can't etract comments for < 1.5.20 We were making our own PsiSourceManager, but that didn't know about any IrFile -> PsiFile mappings. --- .../src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt | 11 ++++------- .../src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt | 11 ++++------- .../src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt | 11 ++++------- 3 files changed, 12 insertions(+), 21 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt index 392e7cf6c28..fce55c87cd6 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/Psi2Ir.kt @@ -5,18 +5,15 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi2ir.PsiSourceManager class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade { - companion object { - val psiManager = PsiSourceManager() - } - override fun getKtFile(irFile: IrFile): KtFile? { - return psiManager.getKtFile(irFile) + logger.warn("Comment extraction is not supported for Kotlin < 1.5.20") + return null } override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { - return psiManager.findPsiElement(irElement, irFile) + logger.error("Attempted comment extraction for Kotlin < 1.5.20") + return null } } diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt index 392e7cf6c28..fce55c87cd6 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_0/Psi2Ir.kt @@ -5,18 +5,15 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi2ir.PsiSourceManager class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade { - companion object { - val psiManager = PsiSourceManager() - } - override fun getKtFile(irFile: IrFile): KtFile? { - return psiManager.getKtFile(irFile) + logger.warn("Comment extraction is not supported for Kotlin < 1.5.20") + return null } override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { - return psiManager.findPsiElement(irElement, irFile) + logger.error("Attempted comment extraction for Kotlin < 1.5.20") + return null } } diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt index 392e7cf6c28..fce55c87cd6 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_10/Psi2Ir.kt @@ -5,18 +5,15 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi2ir.PsiSourceManager class Psi2Ir(private val logger: FileLogger) : Psi2IrFacade { - companion object { - val psiManager = PsiSourceManager() - } - override fun getKtFile(irFile: IrFile): KtFile? { - return psiManager.getKtFile(irFile) + logger.warn("Comment extraction is not supported for Kotlin < 1.5.20") + return null } override fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? { - return psiManager.findPsiElement(irElement, irFile) + logger.error("Attempted comment extraction for Kotlin < 1.5.20") + return null } } From 7fc9ae6c49eb9e7c7af20c6ddc0a907758422cfc Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Mon, 11 Jul 2022 13:07:20 -0700 Subject: [PATCH 294/465] Update python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql Co-authored-by: Taus --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 8db450a5ecb..df8182f5545 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -1,6 +1,6 @@ /** - * @name Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). - * @description Unsafe usage of v1 version of Azure Storage client-side encryption, please refer to http://aka.ms/azstorageclientencryptionblog + * @name Unsafe usage of v1 version of Azure Storage client-side encryption. + * @description Using version v1 of Azure Storage client-side encryption is insecure, and may enable an attacker to decrypt encrypted data * @kind problem * @tags security * cryptography From e5702d0e1596c1d6b59bdca7d228c886942bf744 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Mon, 11 Jul 2022 13:07:37 -0700 Subject: [PATCH 295/465] Update python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql Co-authored-by: Taus --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index df8182f5545..6a489bf6774 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -5,7 +5,7 @@ * @tags security * cryptography * external/cwe/cwe-327 - * @id python/azure-storage/unsafe-client-side-encryption-in-use + * @id py/azure-storage/unsafe-client-side-encryption-in-use * @problem.severity error * @precision medium */ From ac055779669ffad52d5229f138e31487c88a4b0e Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Mon, 11 Jul 2022 13:25:35 -0700 Subject: [PATCH 296/465] Making various changes based on the feedback. Pending: 2 non-trivial fixes for Java & Python. --- ...nsafeUsageOfClientSideEncryptionVersion.cs | 11 ++++++++ ...feUsageOfClientSideEncryptionVersion.qhelp | 3 +++ ...nsafeUsageOfClientSideEncryptionVersion.ql | 26 ++++++++++++------- ...feUsageOfClientSideEncryptionVersion.qhelp | 8 +++--- ...nsafeUsageOfClientSideEncryptionVersion.ql | 11 ++++---- ...nsafeUsageOfClientSideEncryptionVersion.py | 12 ++++----- ...feUsageOfClientSideEncryptionVersion.qhelp | 8 +++--- ...nsafeUsageOfClientSideEncryptionVersion.ql | 11 +++----- 8 files changed, 51 insertions(+), 39 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs index 39928d9e2c7..bee97118ea8 100644 --- a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.cs @@ -1,4 +1,15 @@ +{ + SymmetricKey aesKey = new SymmetricKey(kid: "symencryptionkey"); + + // BAD: Using the outdated client side encryption version V1_0 + BlobEncryptionPolicy uploadPolicy = new BlobEncryptionPolicy(key: aesKey, keyResolver: null); + BlobRequestOptions uploadOptions = new BlobRequestOptions() { EncryptionPolicy = uploadPolicy }; + + MemoryStream stream = new MemoryStream(buffer); + blob.UploadFromStream(stream, length: size, accessCondition: null, options: uploadOptions); +} + var client = new BlobClient(myConnectionString, new SpecializedBlobClientOptions() { // BAD: Using an outdated SDK that does not support client side encryption version V2_0 diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp index a3a33691854..e0ee017cb14 100644 --- a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -21,6 +21,9 @@
  • Azure Storage Client Encryption Blog.
  • +
  • + CVE-2022-PENDING +
  • diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 095c154e9a3..b150ca71060 100644 --- a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -33,16 +33,25 @@ predicate isCreatingOutdatedAzureClientSideEncryptionObject(ObjectCreation oc, C } /** - * Holds if the Azure.Storage assembly for `c` is a version knwon to support - * version 2+ for client-side encryption and if the argument for the constructor `version` - * is set to a secure value. + * Holds if the Azure.Storage assembly for `c` is a version known to support + * version 2+ for client-side encryption */ -predicate isObjectCreationSafe(Expr versionExpr, Assembly asm) { - // Check if the Azure.Storage assembly version has the fix +predicate doesAzureStorageAssemblySupportSafeClientSideEncryption(Assembly asm) { exists(int versionCompare | versionCompare = asm.getVersion().compareTo("12.12.0.0") and versionCompare >= 0 ) and + asm.getName() = "Azure.Storage.Common" +} + +/** + * Holds if the Azure.Storage assembly for `c` is a version known to support + * version 2+ for client-side encryption and if the argument for the constructor `version` + * is set to a secure value. + */ +predicate isObjectCreationArgumentSafeAndUsingSafeVersionOfAssembly(Expr versionExpr, Assembly asm) { + // Check if the Azure.Storage assembly version has the fix + doesAzureStorageAssemblySupportSafeClientSideEncryption(asm) and // and that the version argument for the constructor is guaranteed to be Version2 isExprAnAccessToSafeClientSideEncryptionVersionValue(versionExpr) } @@ -56,8 +65,6 @@ predicate isExprAnAccessToSafeClientSideEncryptionVersionValue(Expr e) { ec.hasQualifiedName("Azure.Storage.ClientSideEncryptionVersion.V2_0") and ec.getAnAccess() = e ) - or - e.getValue().toInt() >= 2 } from Expr e, Class c, Assembly asm @@ -66,10 +73,9 @@ where ( exists(Expr e2 | isCreatingAzureClientSideEncryptionObject(e, c, e2) and - not isObjectCreationSafe(e2, asm) + not isObjectCreationArgumentSafeAndUsingSafeVersionOfAssembly(e2, asm) ) or isCreatingOutdatedAzureClientSideEncryptionObject(e, c) ) -select e, - "Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). See http://aka.ms/azstorageclientencryptionblog" +select e, "Unsafe usage of v1 version of Azure Storage client-side encryption." diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp index 3fca30a7926..45d919ec702 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -14,11 +14,6 @@ -

    The following example shows an HTTP request parameter being used directly in a forming a -new request without validating the input, which facilitates SSRF attacks. -It also shows how to remedy the problem by validating the user input against a known fixed string. -

    -
    @@ -26,6 +21,9 @@ It also shows how to remedy the problem by validating the user input against a k
  • Azure Storage Client Encryption Blog.
  • +
  • + CVE-2022-PENDING +
  • diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index a109e945343..97bccf67314 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -13,7 +13,7 @@ import java /** - * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` + * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` * that takes no arguments, which means that it is using V1 encryption */ predicate isCreatingOutdatedAzureClientSideEncryptionObject(Call call, Class c) { @@ -31,8 +31,8 @@ predicate isCreatingOutdatedAzureClientSideEncryptionObject(Call call, Class c) ) } -/** - * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` +/** + * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` * that takes `versionArg` as the argument for the version. */ predicate isCreatingAzureClientSideEncryptionObjectNewVersion(Call call, Class c, Expr versionArg) { @@ -47,7 +47,7 @@ predicate isCreatingAzureClientSideEncryptionObjectNewVersion(Call call, Class c } /** - * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` + * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` * that takes `versionArg` as the argument for the version, and the version number is safe */ predicate isCreatingSafeAzureClientSideEncryptionObject(Call call, Class c, Expr versionArg) { @@ -67,5 +67,4 @@ where ) or isCreatingOutdatedAzureClientSideEncryptionObject(e, c) -select e, - "Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). See http://aka.ms/azstorageclientencryptionblog" +select e, "Unsafe usage of v1 version of Azure Storage client-side encryption." diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py index c4a0519f29d..b7099b3d6c0 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py @@ -1,7 +1,7 @@ blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name) - blob_client.require_encryption = True - blob_client.key_encryption_key = kek - # GOOD: Must use `encryption_version` set to `2.0` - blob_client.encryption_version = '2.0' # Use Version 2.0! - with open(“decryptedcontentfile.txt”, “rb”) as stream: - blob_client.upload_blob(stream, overwrite=OVERWRITE_EXISTING) \ No newline at end of file +blob_client.require_encryption = True +blob_client.key_encryption_key = kek +# GOOD: Must use `encryption_version` set to `2.0` +blob_client.encryption_version = '2.0' # Use Version 2.0! +with open(“decryptedcontentfile.txt”, “rb”) as stream: + blob_client.upload_blob(stream, overwrite=OVERWRITE_EXISTING) \ No newline at end of file diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp index c4111a166de..eaf49f371e6 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -14,11 +14,6 @@ -

    The following example shows an HTTP request parameter being used directly in a forming a -new request without validating the input, which facilitates SSRF attacks. -It also shows how to remedy the problem by validating the user input against a known fixed string. -

    -
    @@ -26,6 +21,9 @@ It also shows how to remedy the problem by validating the user input against a k
  • Azure Storage Client Encryption Blog.
  • +
  • + CVE-2022-PENDING +
  • diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 6a489bf6774..55f695ca061 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -24,7 +24,7 @@ predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrN not astmt.getValue() instanceof None and not exists(AssignStmt astmt2, Attribute a2, AttrNode encryptionVersionSet, StrConst uc | uc = astmt2.getValue() and - uc.getLiteralValue().toString() in ["'2.0'", "2.0"] and + uc.getText() in ["'2.0'", "2.0"] and a2.getAttr() = "encryption_version" and a2.getAFlowNode() = encryptionVersionSet and encryptionVersionSet.strictlyReaches(ctrlFlowNode) @@ -34,15 +34,13 @@ predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrN predicate isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(Call call, ControlFlowNode node) { exists(Keyword k | k.getAFlowNode() = node | - call.getFunc().(Name).getId().toString() in [ - "ContainerClient", "BlobClient", "BlobServiceClient" - ] and + call.getFunc().(Name).getId() in ["ContainerClient", "BlobClient", "BlobServiceClient"] and k.getArg() = "key_encryption_key" and k = call.getANamedArg() and not k.getValue() instanceof None and not exists(Keyword k2 | k2 = call.getANamedArg() | k2.getArg() = "encryption_version" and - k2.getValue().(StrConst).getLiteralValue().toString() in ["'2.0'", "2.0"] + k2.getValue().(StrConst).getText() in ["'2.0'", "2.0"] ) ) } @@ -51,5 +49,4 @@ from Call call, ControlFlowNode node where isUnsafeClientSideAzureStorageEncryptionViaAttributes(call, node) or isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(call, node) -select node, - "Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). See http://aka.ms/azstorageclientencryptionblog" +select node, "Unsafe usage of v1 version of Azure Storage client-side encryption." From 02e11b7ee92d78b7451a3e70e79c147da1a33524 Mon Sep 17 00:00:00 2001 From: Aditya Sharad Date: Mon, 11 Jul 2022 13:59:38 -0700 Subject: [PATCH 297/465] Docs: Add links from query help to query pack changelog for each language --- docs/codeql/query-help/cpp.rst | 4 +++- docs/codeql/query-help/csharp.rst | 4 +++- docs/codeql/query-help/go.rst | 4 +++- docs/codeql/query-help/java.rst | 4 +++- docs/codeql/query-help/javascript.rst | 4 +++- docs/codeql/query-help/python.rst | 4 +++- docs/codeql/query-help/ruby.rst | 4 +++- 7 files changed, 21 insertions(+), 7 deletions(-) diff --git a/docs/codeql/query-help/cpp.rst b/docs/codeql/query-help/cpp.rst index 7c3cbe304d7..12d2dfbf53e 100644 --- a/docs/codeql/query-help/cpp.rst +++ b/docs/codeql/query-help/cpp.rst @@ -3,7 +3,9 @@ CodeQL query help for C and C++ .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/cpp-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-cpp.rst \ No newline at end of file diff --git a/docs/codeql/query-help/csharp.rst b/docs/codeql/query-help/csharp.rst index 9c5c6351ce3..5d7f732a588 100644 --- a/docs/codeql/query-help/csharp.rst +++ b/docs/codeql/query-help/csharp.rst @@ -3,6 +3,8 @@ CodeQL query help for C# .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/csharp-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-csharp.rst \ No newline at end of file diff --git a/docs/codeql/query-help/go.rst b/docs/codeql/query-help/go.rst index 9e3050f74d0..bcd4aba9b51 100644 --- a/docs/codeql/query-help/go.rst +++ b/docs/codeql/query-help/go.rst @@ -3,6 +3,8 @@ CodeQL query help for Go .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/go-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-go.rst diff --git a/docs/codeql/query-help/java.rst b/docs/codeql/query-help/java.rst index 8af2ee52890..4876546d2dc 100644 --- a/docs/codeql/query-help/java.rst +++ b/docs/codeql/query-help/java.rst @@ -3,6 +3,8 @@ CodeQL query help for Java .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/java-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-java.rst diff --git a/docs/codeql/query-help/javascript.rst b/docs/codeql/query-help/javascript.rst index d7cf6797852..ae85de99f7b 100644 --- a/docs/codeql/query-help/javascript.rst +++ b/docs/codeql/query-help/javascript.rst @@ -3,6 +3,8 @@ CodeQL query help for JavaScript .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/javascript-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-javascript.rst \ No newline at end of file diff --git a/docs/codeql/query-help/python.rst b/docs/codeql/query-help/python.rst index da68c1caa9b..9d915d443f3 100644 --- a/docs/codeql/query-help/python.rst +++ b/docs/codeql/query-help/python.rst @@ -3,6 +3,8 @@ CodeQL query help for Python .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/python-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-python.rst \ No newline at end of file diff --git a/docs/codeql/query-help/ruby.rst b/docs/codeql/query-help/ruby.rst index 3ce1304ba76..e733aecaf79 100644 --- a/docs/codeql/query-help/ruby.rst +++ b/docs/codeql/query-help/ruby.rst @@ -3,6 +3,8 @@ CodeQL query help for Ruby .. include:: ../reusables/query-help-overview.rst -For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. +These queries are published in the CodeQL query pack ``codeql/ruby-queries`` (`changelog `__, `source `__). + +For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. .. include:: toc-ruby.rst From d5791e2d56e8dfd348747f09e23f69596f5c7619 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Mon, 11 Jul 2022 15:45:15 -0700 Subject: [PATCH 298/465] Addressing feedback from the PR --- ...nsafeUsageOfClientSideEncryptionVersion.ql | 30 ++++++++++++++++--- ...nsafeUsageOfClientSideEncryptionVersion.ql | 7 +++-- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 97bccf67314..50840b67f0b 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -11,6 +11,7 @@ */ import java +import semmle.code.java.dataflow.DataFlow /** * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` @@ -46,16 +47,37 @@ predicate isCreatingAzureClientSideEncryptionObjectNewVersion(Call call, Class c ) } +/** + * A config that tracks `EncryptedBlobClientBuilder.version` argument initialization. + */ +private class EncryptedBlobClientBuilderEncryptionVersionConfig extends DataFlow::Configuration { + EncryptedBlobClientBuilderEncryptionVersionConfig() { + this = "EncryptedBlobClientBuilderEncryptionVersionConfig" + } + + override predicate isSource(DataFlow::Node source) { + exists(FieldRead fr, Field f | fr = source.asExpr() | + f.getAnAccess() = fr and + f.hasQualifiedName("com.azure.storage.blob.specialized.cryptography", "EncryptionVersion", + "V2") + ) + } + + override predicate isSink(DataFlow::Node sink) { + isCreatingAzureClientSideEncryptionObjectNewVersion(_, _, sink.asExpr()) + } +} + /** * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` * that takes `versionArg` as the argument for the version, and the version number is safe */ predicate isCreatingSafeAzureClientSideEncryptionObject(Call call, Class c, Expr versionArg) { isCreatingAzureClientSideEncryptionObjectNewVersion(call, c, versionArg) and - exists(FieldRead fr, Field f | - fr = versionArg and - f.getAnAccess() = fr and - f.hasQualifiedName("com.azure.storage.blob.specialized.cryptography", "EncryptionVersion", "V2") + exists(EncryptedBlobClientBuilderEncryptionVersionConfig config, DataFlow::Node sink | + sink.asExpr() = versionArg + | + config.hasFlow(_, sink) ) } diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 55f695ca061..442399e658f 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -11,6 +11,7 @@ */ import python +import semmle.python.ApiGraphs predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrNode node) { exists(ControlFlowNode ctrlFlowNode, AssignStmt astmt, Attribute a | @@ -33,8 +34,10 @@ predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrN } predicate isUnsafeClientSideAzureStorageEncryptionViaObjectCreation(Call call, ControlFlowNode node) { - exists(Keyword k | k.getAFlowNode() = node | - call.getFunc().(Name).getId() in ["ContainerClient", "BlobClient", "BlobServiceClient"] and + exists(API::Node c, string s, Keyword k | k.getAFlowNode() = node | + c.getACall().asExpr() = call and + c = API::moduleImport("azure").getMember("storage").getMember("blob").getMember(s) and + s in ["ContainerClient", "BlobClient", "BlobServiceClient"] and k.getArg() = "key_encryption_key" and k = call.getANamedArg() and not k.getValue() instanceof None and From 217c9a8aaf680e47b66031a88b3ac04e6c7a85e2 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Tue, 12 Jul 2022 08:50:58 +0100 Subject: [PATCH 299/465] Fix typo in changenote Co-authored-by: intrigus-lgtm <60750685+intrigus-lgtm@users.noreply.github.com> --- ruby/ql/lib/change-notes/2022-07-11-command-execution.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/change-notes/2022-07-11-command-execution.md b/ruby/ql/lib/change-notes/2022-07-11-command-execution.md index 2c5addba1f5..f6548719b57 100644 --- a/ruby/ql/lib/change-notes/2022-07-11-command-execution.md +++ b/ruby/ql/lib/change-notes/2022-07-11-command-execution.md @@ -1,6 +1,6 @@ --- category: minorAnalysis --- -* Fixed a bug causing every expression in the database to be a considered a system-command execution sink when calls to any of the following methods exist: +* Fixed a bug causing every expression in the database to be considered a system-command execution sink when calls to any of the following methods exist: * The `spawn`, `fspawn`, `popen4`, `pspawn`, `system`, `_pspawn` methods and the backtick operator from the `POSIX::spawn` gem. * The `execute_command`, `rake`, `rails_command`, and `git` methods in `Rails::Generation::Actions`. From c75599c3da63e8a2f99319dfa29131bdec9ab396 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 12 Jul 2022 10:27:22 +0200 Subject: [PATCH 300/465] C++: Clarify the "most-specific" part of `FunctionCall:getTarget` --- cpp/ql/lib/semmle/code/cpp/exprs/Call.qll | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll index 7ceda8ddbff..dba3d16997f 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Call.qll @@ -255,8 +255,10 @@ class FunctionCall extends Call, @funbindexpr { /** * Gets the function called by this call. * - * In the case of virtual function calls, the result is the most-specific function in the override tree (as - * determined by the compiler) such that the target at runtime will be one of `result.getAnOverridingFunction*()`. + * In the case of virtual function calls, the result is the most-specific function in the override tree + * such that the target at runtime will be one of `result.getAnOverridingFunction*()`. The most-specific + * function is determined by the compiler based on the compile time type of the object the function is a + * member of. */ override Function getTarget() { funbind(underlyingElement(this), unresolveElement(result)) } From 033b239b22cb3ccabb988b9f9587ce8e59826895 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 12 Jul 2022 10:33:54 +0200 Subject: [PATCH 301/465] Swift: collapse `TypeRepr` hierarchy Now `TypeRepr` is a final class in the AST, which is more or less just a type with a location in code. As the frontend does not provide a direct way to get a type from a type representation, this information must be provided when fetching the label of a type repr. This meant: * removing the type repr field from `EnumIsCaseExpr`: this is a virtual AST node introduced in place of some kinds of `IsEpxr`. The type repr is still available from the `ConditionalCheckedCastExpr` wrapped by this virtual node, and we will rebuild the original `IsExpr` with the IPA layer. * some logic to get the type of keypath roots has been added to `KeyPathExpr`. This was done to keep the `TypeRepr` to `Type` relation total in the DB, but goes against the design of a dumb extractor. The logic could be moved to QL in the future * in the control flow library, `TypeRepr` children are now ignored. As far as I can tell, there is no runtime evaluation going on in `TypeRepr`s, so it does not make much sense to have control flow through them. --- swift/codegen/schema.yml | 91 +--- swift/extractor/infra/SwiftDispatcher.h | 22 +- swift/extractor/infra/SwiftTagTraits.h | 4 - swift/extractor/trap/BUILD.bazel | 2 +- swift/extractor/visitors/ExprVisitor.cpp | 18 +- swift/extractor/visitors/PatternVisitor.cpp | 7 +- swift/extractor/visitors/SwiftVisitor.h | 6 +- swift/extractor/visitors/TypeReprVisitor.cpp | 3 - swift/extractor/visitors/TypeReprVisitor.h | 13 - swift/extractor/visitors/TypeVisitor.cpp | 6 + swift/extractor/visitors/TypeVisitor.h | 2 + .../internal/ControlFlowGraphImpl.qll | 15 +- swift/ql/lib/codeql/swift/elements.qll | 30 +- .../codeql/swift/elements/type/TypeRepr.qll | 5 + .../typerepr/ComponentIdentTypeRepr.qll | 4 - .../elements/typerepr/CompositionTypeRepr.qll | 4 - .../swift/elements/typerepr/ErrorTypeRepr.qll | 4 - .../elements/typerepr/ExistentialTypeRepr.qll | 4 - .../swift/elements/typerepr/FixedTypeRepr.qll | 4 - .../swift/elements/typerepr/IdentTypeRepr.qll | 4 - .../typerepr/NamedOpaqueReturnTypeRepr.qll | 4 - .../typerepr/OpaqueReturnTypeRepr.qll | 4 - .../elements/typerepr/PlaceholderTypeRepr.qll | 4 - .../elements/typerepr/SimpleIdentTypeRepr.qll | 4 - .../elements/typerepr/SpecifierTypeRepr.qll | 4 - .../swift/elements/typerepr/TypeRepr.qll | 4 - .../swift/generated/GetImmediateParent.qll | 8 +- .../swift/generated/expr/EnumIsCaseExpr.qll | 12 +- .../swift/generated/expr/KeyPathExpr.qll | 9 +- .../codeql/swift/generated/expr/TypeExpr.qll | 2 +- .../swift/generated/pattern/IsPattern.qll | 2 +- .../swift/generated/pattern/TypedPattern.qll | 2 +- .../codeql/swift/generated/type/TypeRepr.qll | 14 + .../generated/typerepr/ArrayTypeRepr.qll | 6 - .../generated/typerepr/AttributedTypeRepr.qll | 6 - .../typerepr/CompileTimeConstTypeRepr.qll | 6 - .../typerepr/ComponentIdentTypeRepr.qll | 4 - .../typerepr/CompositionTypeRepr.qll | 6 - .../typerepr/CompoundIdentTypeRepr.qll | 6 - .../generated/typerepr/DictionaryTypeRepr.qll | 6 - .../generated/typerepr/ErrorTypeRepr.qll | 6 - .../typerepr/ExistentialTypeRepr.qll | 6 - .../generated/typerepr/FixedTypeRepr.qll | 6 - .../generated/typerepr/FunctionTypeRepr.qll | 6 - .../typerepr/GenericIdentTypeRepr.qll | 6 - .../generated/typerepr/IdentTypeRepr.qll | 4 - .../ImplicitlyUnwrappedOptionalTypeRepr.qll | 7 - .../generated/typerepr/InOutTypeRepr.qll | 6 - .../generated/typerepr/IsolatedTypeRepr.qll | 6 - .../generated/typerepr/MetatypeTypeRepr.qll | 6 - .../typerepr/NamedOpaqueReturnTypeRepr.qll | 6 - .../typerepr/OpaqueReturnTypeRepr.qll | 6 - .../generated/typerepr/OptionalTypeRepr.qll | 6 - .../generated/typerepr/OwnedTypeRepr.qll | 6 - .../typerepr/PlaceholderTypeRepr.qll | 6 - .../generated/typerepr/ProtocolTypeRepr.qll | 6 - .../generated/typerepr/SharedTypeRepr.qll | 6 - .../generated/typerepr/SilBoxTypeRepr.qll | 6 - .../typerepr/SimpleIdentTypeRepr.qll | 6 - .../generated/typerepr/SpecifierTypeRepr.qll | 4 - .../generated/typerepr/TupleTypeRepr.qll | 6 - .../swift/generated/typerepr/TypeRepr.qll | 4 - swift/ql/lib/swift.dbscheme | 148 +----- .../extractor-tests/expressions/all.expected | 4 - .../EnumIsCaseExpr/EnumIsCaseExpr.expected | 20 +- .../expr/EnumIsCaseExpr/EnumIsCaseExpr.ql | 5 +- .../UnresolvedDotExpr}/MISSING_SOURCE.txt | 0 .../UnresolvedDotExpr.expected | 3 - .../UnresolvedDotExpr/UnresolvedDotExpr.ql | 11 - .../UnresolvedDotExpr_getType.expected | 0 .../UnresolvedDotExpr_getType.ql | 7 - .../unresolved_dot_expr.swift | 11 - .../TypeRepr}/MISSING_SOURCE.txt | 0 .../MISSING_SOURCE.txt | 4 - .../CompositionTypeRepr/MISSING_SOURCE.txt | 4 - .../CompoundIdentTypeRepr/MISSING_SOURCE.txt | 4 - .../DictionaryTypeRepr/MISSING_SOURCE.txt | 4 - .../typerepr/ErrorTypeRepr/MISSING_SOURCE.txt | 4 - .../ExistentialTypeRepr/MISSING_SOURCE.txt | 4 - .../typerepr/FixedTypeRepr/MISSING_SOURCE.txt | 4 - .../FunctionTypeRepr/MISSING_SOURCE.txt | 4 - .../GenericIdentTypeRepr/MISSING_SOURCE.txt | 4 - .../MISSING_SOURCE.txt | 4 - .../typerepr/InOutTypeRepr/MISSING_SOURCE.txt | 4 - .../IsolatedTypeRepr/MISSING_SOURCE.txt | 4 - .../MetatypeTypeRepr/MISSING_SOURCE.txt | 4 - .../MISSING_SOURCE.txt | 4 - .../OpaqueReturnTypeRepr/MISSING_SOURCE.txt | 4 - .../OptionalTypeRepr/MISSING_SOURCE.txt | 4 - .../typerepr/OwnedTypeRepr/MISSING_SOURCE.txt | 4 - .../PlaceholderTypeRepr/MISSING_SOURCE.txt | 4 - .../ProtocolTypeRepr/MISSING_SOURCE.txt | 4 - .../SharedTypeRepr/MISSING_SOURCE.txt | 4 - .../SilBoxTypeRepr/MISSING_SOURCE.txt | 4 - .../SimpleIdentTypeRepr/MISSING_SOURCE.txt | 4 - .../typerepr/TupleTypeRepr/MISSING_SOURCE.txt | 4 - .../controlflow/graph/Cfg.expected | 481 +++++++++++++++++- .../test/library-tests/parent/parent.expected | 136 +++-- 98 files changed, 646 insertions(+), 760 deletions(-) delete mode 100644 swift/extractor/visitors/TypeReprVisitor.cpp delete mode 100644 swift/extractor/visitors/TypeReprVisitor.h create mode 100644 swift/ql/lib/codeql/swift/elements/type/TypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/elements/typerepr/ComponentIdentTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/elements/typerepr/CompositionTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/elements/typerepr/ErrorTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/elements/typerepr/ExistentialTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/elements/typerepr/FixedTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/elements/typerepr/IdentTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/elements/typerepr/NamedOpaqueReturnTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/elements/typerepr/OpaqueReturnTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/elements/typerepr/PlaceholderTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/elements/typerepr/SimpleIdentTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/elements/typerepr/SpecifierTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/elements/typerepr/TypeRepr.qll create mode 100644 swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/ArrayTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/AttributedTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/CompileTimeConstTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/ComponentIdentTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/CompositionTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/CompoundIdentTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/DictionaryTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/ErrorTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/ExistentialTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/FixedTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/FunctionTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/GenericIdentTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/IdentTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/InOutTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/IsolatedTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/MetatypeTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/NamedOpaqueReturnTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/OpaqueReturnTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/OptionalTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/OwnedTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/PlaceholderTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/ProtocolTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/SharedTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/SilBoxTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/SimpleIdentTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/SpecifierTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/TupleTypeRepr.qll delete mode 100644 swift/ql/lib/codeql/swift/generated/typerepr/TypeRepr.qll rename swift/ql/test/extractor-tests/generated/{typerepr/ArrayTypeRepr => expr/UnresolvedDotExpr}/MISSING_SOURCE.txt (100%) delete mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.expected delete mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql delete mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getType.expected delete mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getType.ql delete mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/unresolved_dot_expr.swift rename swift/ql/test/extractor-tests/generated/{typerepr/AttributedTypeRepr => type/TypeRepr}/MISSING_SOURCE.txt (100%) delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/CompileTimeConstTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/CompositionTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/CompoundIdentTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/DictionaryTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/ErrorTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/ExistentialTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/FixedTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/FunctionTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/GenericIdentTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/InOutTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/IsolatedTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/MetatypeTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/NamedOpaqueReturnTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/OpaqueReturnTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/OptionalTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/OwnedTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/PlaceholderTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/ProtocolTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/SharedTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/SilBoxTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/SimpleIdentTypeRepr/MISSING_SOURCE.txt delete mode 100644 swift/ql/test/extractor-tests/generated/typerepr/TupleTypeRepr/MISSING_SOURCE.txt diff --git a/swift/codegen/schema.yml b/swift/codegen/schema.yml index 01bb0c2feba..7d6d530170d 100644 --- a/swift/codegen/schema.yml +++ b/swift/codegen/schema.yml @@ -7,8 +7,7 @@ _includes: _directories: decl: Decl$|Context$ pattern: Pattern$ - type: Type$ - typerepr: TypeRepr$ + type: Type(Repr)?$ expr: Expr$ stmt: Stmt$ @@ -181,6 +180,7 @@ Stmt: TypeRepr: _extends: AstNode + type: Type FunctionType: _extends: AnyFunctionType @@ -391,7 +391,6 @@ EnumIsCaseExpr: _extends: Expr _children: sub_expr: Expr - type_repr: TypeRepr element: EnumElementDecl ErrorExpr: @@ -442,7 +441,7 @@ KeyPathDotExpr: KeyPathExpr: _extends: Expr _children: - parsed_root: Expr? + root: TypeRepr? parsed_path: Expr? LazyInitializerExpr: @@ -1162,87 +1161,3 @@ FloatLiteralExpr: IntegerLiteralExpr: _extends: NumberLiteralExpr string_value: string - -ErrorTypeRepr: - _extends: TypeRepr - -AttributedTypeRepr: - _extends: TypeRepr - -IdentTypeRepr: - _extends: TypeRepr - -ComponentIdentTypeRepr: - _extends: IdentTypeRepr - -SimpleIdentTypeRepr: - _extends: ComponentIdentTypeRepr - -GenericIdentTypeRepr: - _extends: ComponentIdentTypeRepr - -CompoundIdentTypeRepr: - _extends: IdentTypeRepr - -FunctionTypeRepr: - _extends: TypeRepr - -ArrayTypeRepr: - _extends: TypeRepr - -DictionaryTypeRepr: - _extends: TypeRepr - -OptionalTypeRepr: - _extends: TypeRepr - -ImplicitlyUnwrappedOptionalTypeRepr: - _extends: TypeRepr - -TupleTypeRepr: - _extends: TypeRepr - -CompositionTypeRepr: - _extends: TypeRepr - -MetatypeTypeRepr: - _extends: TypeRepr - -ProtocolTypeRepr: - _extends: TypeRepr - -OpaqueReturnTypeRepr: - _extends: TypeRepr - -NamedOpaqueReturnTypeRepr: - _extends: TypeRepr - -ExistentialTypeRepr: - _extends: TypeRepr - -PlaceholderTypeRepr: - _extends: TypeRepr - -SpecifierTypeRepr: - _extends: TypeRepr - -InOutTypeRepr: - _extends: SpecifierTypeRepr - -SharedTypeRepr: - _extends: SpecifierTypeRepr - -OwnedTypeRepr: - _extends: SpecifierTypeRepr - -IsolatedTypeRepr: - _extends: SpecifierTypeRepr - -CompileTimeConstTypeRepr: - _extends: SpecifierTypeRepr - -FixedTypeRepr: - _extends: TypeRepr - -SilBoxTypeRepr: - _extends: TypeRepr diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index c7ca43a1614..0f1753cda1d 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -64,8 +64,8 @@ class SwiftDispatcher { // This method gives a TRAP label for already emitted AST node. // If the AST node was not emitted yet, then the emission is dispatched to a corresponding // visitor (see `visit(T *)` methods below). - template - TrapLabelOf fetchLabel(E* e) { + template + TrapLabelOf fetchLabel(E* e, Args&&... args) { assert(e && "trying to fetch a label on nullptr, maybe fetchOptionalLabel is to be used?"); // this is required so we avoid any recursive loop: a `fetchLabel` during the visit of `e` might // end up calling `fetchLabel` on `e` itself, so we want the visit of `e` to call `fetchLabel` @@ -76,7 +76,7 @@ class SwiftDispatcher { return *l; } waitingForNewLabel = e; - visit(e); + visit(e, std::forward(args)...); if (auto l = store.get(e)) { if constexpr (!std::is_base_of_v) { attachLocation(e, *l); @@ -158,10 +158,10 @@ class SwiftDispatcher { // return `std::optional(fetchLabel(arg))` if arg converts to true, otherwise std::nullopt // universal reference `Arg&&` is used to catch both temporary and non-const references, not // for perfect forwarding - template - auto fetchOptionalLabel(Arg&& arg) -> std::optional { + template + auto fetchOptionalLabel(Arg&& arg, Args&&... args) -> std::optional { if (arg) { - return fetchLabel(arg); + return fetchLabel(arg, std::forward(args)...); } return std::nullopt; } @@ -251,9 +251,11 @@ class SwiftDispatcher { template bool fetchLabelFromUnionCase(const llvm::PointerUnion u, TrapLabel& output) { - if (auto e = u.template dyn_cast()) { - output = fetchLabel(e); - return true; + if constexpr (!std::is_same_v) { + if (auto e = u.template dyn_cast()) { + output = fetchLabel(e); + return true; + } } return false; } @@ -279,7 +281,7 @@ class SwiftDispatcher { virtual void visit(swift::CaseLabelItem* item) = 0; virtual void visit(swift::Expr* expr) = 0; virtual void visit(swift::Pattern* pattern) = 0; - virtual void visit(swift::TypeRepr* type) = 0; + virtual void visit(swift::TypeRepr* typeRepr, swift::Type type) = 0; virtual void visit(swift::TypeBase* type) = 0; const swift::SourceManager& sourceManager; diff --git a/swift/extractor/infra/SwiftTagTraits.h b/swift/extractor/infra/SwiftTagTraits.h index 8a2e489683d..96da48813d3 100644 --- a/swift/extractor/infra/SwiftTagTraits.h +++ b/swift/extractor/infra/SwiftTagTraits.h @@ -14,7 +14,6 @@ using SILBlockStorageTypeTag = SilBlockStorageTypeTag; using SILBoxTypeTag = SilBoxTypeTag; using SILFunctionTypeTag = SilFunctionTypeTag; using SILTokenTypeTag = SilTokenTypeTag; -using SILBoxTypeReprTag = SilBoxTypeReprTag; #define MAP_TYPE_TO_TAG(TYPE, TAG) \ template <> \ @@ -57,9 +56,6 @@ MAP_TAG(Pattern); #include MAP_TAG(TypeRepr); -#define ABSTRACT_TYPEREPR(CLASS, PARENT) MAP_SUBTAG(CLASS##TypeRepr, PARENT) -#define TYPEREPR(CLASS, PARENT) ABSTRACT_TYPEREPR(CLASS, PARENT) -#include MAP_TYPE_TO_TAG(TypeBase, TypeTag); #define ABSTRACT_TYPE(CLASS, PARENT) MAP_SUBTAG(CLASS##Type, PARENT) diff --git a/swift/extractor/trap/BUILD.bazel b/swift/extractor/trap/BUILD.bazel index b1860142866..08875c45263 100644 --- a/swift/extractor/trap/BUILD.bazel +++ b/swift/extractor/trap/BUILD.bazel @@ -1,6 +1,6 @@ load("//swift:rules.bzl", "swift_cc_library") -_dirs = ("", "decl/", "expr/", "pattern/", "stmt/", "type/", "typerepr/") +_dirs = ("", "decl/", "expr/", "pattern/", "stmt/", "type/") genrule( name = "cppgen", diff --git a/swift/extractor/visitors/ExprVisitor.cpp b/swift/extractor/visitors/ExprVisitor.cpp index e6aabef4cea..8d07372d024 100644 --- a/swift/extractor/visitors/ExprVisitor.cpp +++ b/swift/extractor/visitors/ExprVisitor.cpp @@ -188,9 +188,8 @@ void ExprVisitor::visitEnumIsCaseExpr(swift::EnumIsCaseExpr* expr) { assert(expr->getCaseTypeRepr() && "EnumIsCaseExpr has CaseTypeRepr"); assert(expr->getEnumElement() && "EnumIsCaseExpr has EnumElement"); auto subExpr = dispatcher_.fetchLabel(expr->getSubExpr()); - auto typeRepr = dispatcher_.fetchLabel(expr->getCaseTypeRepr()); auto enumElement = dispatcher_.fetchLabel(expr->getEnumElement()); - dispatcher_.emit(EnumIsCaseExprsTrap{label, subExpr, typeRepr, enumElement}); + dispatcher_.emit(EnumIsCaseExprsTrap{label, subExpr, enumElement}); } void ExprVisitor::visitMakeTemporarilyEscapableExpr(swift::MakeTemporarilyEscapableExpr* expr) { @@ -288,7 +287,9 @@ void ExprVisitor::visitErasureExpr(swift::ErasureExpr* expr) { codeql::TypeExpr ExprVisitor::translateTypeExpr(const swift::TypeExpr& expr) { TypeExpr entry{dispatcher_.assignNewLabel(expr)}; - entry.type_repr = dispatcher_.fetchOptionalLabel(expr.getTypeRepr()); + if (expr.getTypeRepr() && expr.getInstanceType()) { + entry.type_repr = dispatcher_.fetchLabel(expr.getTypeRepr(), expr.getInstanceType()); + } return entry; } @@ -478,9 +479,14 @@ void ExprVisitor::visitKeyPathExpr(swift::KeyPathExpr* expr) { auto pathLabel = dispatcher_.fetchLabel(path); dispatcher_.emit(KeyPathExprParsedPathsTrap{label, pathLabel}); } - if (auto root = expr->getParsedRoot()) { - auto rootLabel = dispatcher_.fetchLabel(root); - dispatcher_.emit(KeyPathExprParsedRootsTrap{label, rootLabel}); + // TODO maybe move this logic to QL? + if (auto rootTypeRepr = expr->getRootType()) { + auto keyPathType = expr->getType()->getAs(); + assert(keyPathType && "KeyPathExpr must have BoundGenericClassType"); + auto keyPathTypeArgs = keyPathType->getGenericArgs(); + assert(keyPathTypeArgs.size() != 0 && "KeyPathExpr type must have generic args"); + auto rootLabel = dispatcher_.fetchLabel(rootTypeRepr, keyPathTypeArgs[0]); + dispatcher_.emit(KeyPathExprRootsTrap{label, rootLabel}); } } } diff --git a/swift/extractor/visitors/PatternVisitor.cpp b/swift/extractor/visitors/PatternVisitor.cpp index 43421fcbede..4ef90aa56a4 100644 --- a/swift/extractor/visitors/PatternVisitor.cpp +++ b/swift/extractor/visitors/PatternVisitor.cpp @@ -18,8 +18,8 @@ void PatternVisitor::visitTypedPattern(swift::TypedPattern* pattern) { assert(pattern->getSubPattern() && "expect TypedPattern to have a SubPattern"); dispatcher_.emit(TypedPatternsTrap{label, dispatcher_.fetchLabel(pattern->getSubPattern())}); if (auto typeRepr = pattern->getTypeRepr()) { - dispatcher_.emit( - TypedPatternTypeReprsTrap{label, dispatcher_.fetchLabel(pattern->getTypeRepr())}); + dispatcher_.emit(TypedPatternTypeReprsTrap{ + label, dispatcher_.fetchLabel(pattern->getTypeRepr(), pattern->getType())}); } } @@ -63,7 +63,8 @@ void PatternVisitor::visitIsPattern(swift::IsPattern* pattern) { dispatcher_.emit(IsPatternsTrap{label}); if (auto typeRepr = pattern->getCastTypeRepr()) { - dispatcher_.emit(IsPatternCastTypeReprsTrap{label, dispatcher_.fetchLabel(typeRepr)}); + dispatcher_.emit(IsPatternCastTypeReprsTrap{ + label, dispatcher_.fetchLabel(typeRepr, pattern->getCastType())}); } if (auto subPattern = pattern->getSubPattern()) { dispatcher_.emit(IsPatternSubPatternsTrap{label, dispatcher_.fetchLabel(subPattern)}); diff --git a/swift/extractor/visitors/SwiftVisitor.h b/swift/extractor/visitors/SwiftVisitor.h index 6380390af82..f9464eafa46 100644 --- a/swift/extractor/visitors/SwiftVisitor.h +++ b/swift/extractor/visitors/SwiftVisitor.h @@ -5,7 +5,6 @@ #include "swift/extractor/visitors/ExprVisitor.h" #include "swift/extractor/visitors/StmtVisitor.h" #include "swift/extractor/visitors/TypeVisitor.h" -#include "swift/extractor/visitors/TypeReprVisitor.h" #include "swift/extractor/visitors/PatternVisitor.h" namespace codeql { @@ -26,13 +25,14 @@ class SwiftVisitor : private SwiftDispatcher { void visit(swift::CaseLabelItem* item) override { stmtVisitor.visitCaseLabelItem(item); } void visit(swift::Expr* expr) override { exprVisitor.visit(expr); } void visit(swift::Pattern* pattern) override { patternVisitor.visit(pattern); } - void visit(swift::TypeRepr* type) override { typeReprVisitor.visit(type); } void visit(swift::TypeBase* type) override { typeVisitor.visit(type); } + void visit(swift::TypeRepr* typeRepr, swift::Type type) override { + typeVisitor.visit(*typeRepr, type); + } DeclVisitor declVisitor{*this}; ExprVisitor exprVisitor{*this}; StmtVisitor stmtVisitor{*this}; - TypeReprVisitor typeReprVisitor{*this}; TypeVisitor typeVisitor{*this}; PatternVisitor patternVisitor{*this}; }; diff --git a/swift/extractor/visitors/TypeReprVisitor.cpp b/swift/extractor/visitors/TypeReprVisitor.cpp deleted file mode 100644 index a3daa7938bb..00000000000 --- a/swift/extractor/visitors/TypeReprVisitor.cpp +++ /dev/null @@ -1,3 +0,0 @@ -#include "swift/extractor/visitors/TypeReprVisitor.h" - -namespace codeql {} // namespace codeql diff --git a/swift/extractor/visitors/TypeReprVisitor.h b/swift/extractor/visitors/TypeReprVisitor.h deleted file mode 100644 index dba2198cc6c..00000000000 --- a/swift/extractor/visitors/TypeReprVisitor.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "swift/extractor/visitors/VisitorBase.h" -#include "swift/extractor/trap/generated/typerepr/TrapClasses.h" - -namespace codeql { - -class TypeReprVisitor : public AstVisitorBase { - public: - using AstVisitorBase::AstVisitorBase; -}; - -} // namespace codeql diff --git a/swift/extractor/visitors/TypeVisitor.cpp b/swift/extractor/visitors/TypeVisitor.cpp index 4b6733312d3..5a1896080e0 100644 --- a/swift/extractor/visitors/TypeVisitor.cpp +++ b/swift/extractor/visitors/TypeVisitor.cpp @@ -8,6 +8,12 @@ void TypeVisitor::visit(swift::TypeBase* type) { dispatcher_.emit(TypesTrap{label, type->getString(), canonicalLabel}); } +void TypeVisitor::visit(const swift::TypeRepr& typeRepr, swift::Type type) { + auto entry = dispatcher_.createEntry(typeRepr); + entry.type = dispatcher_.fetchLabel(type); + dispatcher_.emit(entry); +} + void TypeVisitor::visitProtocolType(swift::ProtocolType* type) { auto label = dispatcher_.assignNewLabel(type); dispatcher_.emit(ProtocolTypesTrap{label}); diff --git a/swift/extractor/visitors/TypeVisitor.h b/swift/extractor/visitors/TypeVisitor.h index 77ae8ee13bf..b2deab60369 100644 --- a/swift/extractor/visitors/TypeVisitor.h +++ b/swift/extractor/visitors/TypeVisitor.h @@ -9,6 +9,8 @@ class TypeVisitor : public TypeVisitorBase { using TypeVisitorBase::TypeVisitorBase; void visit(swift::TypeBase* type); + void visit(const swift::TypeRepr& typeRepr, swift::Type type); + void visitProtocolType(swift::ProtocolType* type); void visitEnumType(swift::EnumType* type); void visitStructType(swift::StructType* type); diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll index b9d3cc2a6ec..c3eda3a98f5 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImpl.qll @@ -59,7 +59,7 @@ module CfgScope { private class KeyPathScope extends Range_ instanceof KeyPathExpr { AstControlFlowTree tree; - KeyPathScope() { tree.getAst() = this.getParsedRoot().getFullyConverted() } + KeyPathScope() { tree.getAst() = this } final override predicate entry(ControlFlowElement first) { first(tree, first) } @@ -836,9 +836,6 @@ module Patterns { // Note: `getSubPattern` only has a result if the `is` pattern is of the form `pattern as type`. i = 0 and result.asAstNode() = ast.getSubPattern().getFullyUnresolved() - or - i = 1 and - result.asAstNode() = ast.getCastTypeRepr() } } @@ -1604,8 +1601,14 @@ module Exprs { final override ControlFlowElement getChildElement(int i) { result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0 - or - result.asAstNode() = ast.getTypeRepr().getFullyUnresolved() and i = 1 + } + } + + private class IsTree extends AstStandardPostOrderTree { + override IsExpr ast; + + final override ControlFlowElement getChildElement(int i) { + result.asAstNode() = ast.getSubExpr().getFullyConverted() and i = 0 } } diff --git a/swift/ql/lib/codeql/swift/elements.qll b/swift/ql/lib/codeql/swift/elements.qll index c10706d7c7a..5f5b2a04757 100644 --- a/swift/ql/lib/codeql/swift/elements.qll +++ b/swift/ql/lib/codeql/swift/elements.qll @@ -271,6 +271,7 @@ import codeql.swift.elements.type.SyntaxSugarType import codeql.swift.elements.type.TupleType import codeql.swift.elements.type.Type import codeql.swift.elements.type.TypeAliasType +import codeql.swift.elements.type.TypeRepr import codeql.swift.elements.type.TypeVariableType import codeql.swift.elements.type.UnarySyntaxSugarType import codeql.swift.elements.type.UnboundGenericType @@ -279,32 +280,3 @@ import codeql.swift.elements.type.UnownedStorageType import codeql.swift.elements.type.UnresolvedType import codeql.swift.elements.type.VariadicSequenceType import codeql.swift.elements.type.WeakStorageType -import codeql.swift.elements.typerepr.ArrayTypeRepr -import codeql.swift.elements.typerepr.AttributedTypeRepr -import codeql.swift.elements.typerepr.CompileTimeConstTypeRepr -import codeql.swift.elements.typerepr.ComponentIdentTypeRepr -import codeql.swift.elements.typerepr.CompositionTypeRepr -import codeql.swift.elements.typerepr.CompoundIdentTypeRepr -import codeql.swift.elements.typerepr.DictionaryTypeRepr -import codeql.swift.elements.typerepr.ErrorTypeRepr -import codeql.swift.elements.typerepr.ExistentialTypeRepr -import codeql.swift.elements.typerepr.FixedTypeRepr -import codeql.swift.elements.typerepr.FunctionTypeRepr -import codeql.swift.elements.typerepr.GenericIdentTypeRepr -import codeql.swift.elements.typerepr.IdentTypeRepr -import codeql.swift.elements.typerepr.ImplicitlyUnwrappedOptionalTypeRepr -import codeql.swift.elements.typerepr.InOutTypeRepr -import codeql.swift.elements.typerepr.IsolatedTypeRepr -import codeql.swift.elements.typerepr.MetatypeTypeRepr -import codeql.swift.elements.typerepr.NamedOpaqueReturnTypeRepr -import codeql.swift.elements.typerepr.OpaqueReturnTypeRepr -import codeql.swift.elements.typerepr.OptionalTypeRepr -import codeql.swift.elements.typerepr.OwnedTypeRepr -import codeql.swift.elements.typerepr.PlaceholderTypeRepr -import codeql.swift.elements.typerepr.ProtocolTypeRepr -import codeql.swift.elements.typerepr.SharedTypeRepr -import codeql.swift.elements.typerepr.SilBoxTypeRepr -import codeql.swift.elements.typerepr.SimpleIdentTypeRepr -import codeql.swift.elements.typerepr.SpecifierTypeRepr -import codeql.swift.elements.typerepr.TupleTypeRepr -import codeql.swift.elements.typerepr.TypeRepr diff --git a/swift/ql/lib/codeql/swift/elements/type/TypeRepr.qll b/swift/ql/lib/codeql/swift/elements/type/TypeRepr.qll new file mode 100644 index 00000000000..8462ceb1b6b --- /dev/null +++ b/swift/ql/lib/codeql/swift/elements/type/TypeRepr.qll @@ -0,0 +1,5 @@ +private import codeql.swift.generated.type.TypeRepr + +class TypeRepr extends TypeReprBase { + override string toString() { result = getType().toString() } +} diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/ComponentIdentTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/ComponentIdentTypeRepr.qll deleted file mode 100644 index 0b5640208f4..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/ComponentIdentTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.ComponentIdentTypeRepr - -class ComponentIdentTypeRepr extends ComponentIdentTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/CompositionTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/CompositionTypeRepr.qll deleted file mode 100644 index 4f79f493e7e..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/CompositionTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.CompositionTypeRepr - -class CompositionTypeRepr extends CompositionTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/ErrorTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/ErrorTypeRepr.qll deleted file mode 100644 index bc3a125e0ac..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/ErrorTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.ErrorTypeRepr - -class ErrorTypeRepr extends ErrorTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/ExistentialTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/ExistentialTypeRepr.qll deleted file mode 100644 index 7762a02bb64..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/ExistentialTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.ExistentialTypeRepr - -class ExistentialTypeRepr extends ExistentialTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/FixedTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/FixedTypeRepr.qll deleted file mode 100644 index 8c1687c8853..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/FixedTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.FixedTypeRepr - -class FixedTypeRepr extends FixedTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/IdentTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/IdentTypeRepr.qll deleted file mode 100644 index 5fa70e354e4..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/IdentTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.IdentTypeRepr - -class IdentTypeRepr extends IdentTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/NamedOpaqueReturnTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/NamedOpaqueReturnTypeRepr.qll deleted file mode 100644 index 115b02b9858..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/NamedOpaqueReturnTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.NamedOpaqueReturnTypeRepr - -class NamedOpaqueReturnTypeRepr extends NamedOpaqueReturnTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/OpaqueReturnTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/OpaqueReturnTypeRepr.qll deleted file mode 100644 index cd0586d67f4..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/OpaqueReturnTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.OpaqueReturnTypeRepr - -class OpaqueReturnTypeRepr extends OpaqueReturnTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/PlaceholderTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/PlaceholderTypeRepr.qll deleted file mode 100644 index 423ced1a5d8..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/PlaceholderTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.PlaceholderTypeRepr - -class PlaceholderTypeRepr extends PlaceholderTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/SimpleIdentTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/SimpleIdentTypeRepr.qll deleted file mode 100644 index 070146f5ace..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/SimpleIdentTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.SimpleIdentTypeRepr - -class SimpleIdentTypeRepr extends SimpleIdentTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/SpecifierTypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/SpecifierTypeRepr.qll deleted file mode 100644 index 40d1d648881..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/SpecifierTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.SpecifierTypeRepr - -class SpecifierTypeRepr extends SpecifierTypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/elements/typerepr/TypeRepr.qll b/swift/ql/lib/codeql/swift/elements/typerepr/TypeRepr.qll deleted file mode 100644 index 4a4ea87833e..00000000000 --- a/swift/ql/lib/codeql/swift/elements/typerepr/TypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py, remove this comment if you wish to edit this file -private import codeql.swift.generated.typerepr.TypeRepr - -class TypeRepr extends TypeReprBase { } diff --git a/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll b/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll index aaf3dec16bd..0d7bdb0a91d 100644 --- a/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll +++ b/swift/ql/lib/codeql/swift/generated/GetImmediateParent.qll @@ -64,11 +64,9 @@ Element getAnImmediateChild(Element e) { or dynamic_type_exprs(e, x) or - enum_is_case_exprs(e, x, _, _) + enum_is_case_exprs(e, x, _) or - enum_is_case_exprs(e, _, x, _) - or - enum_is_case_exprs(e, _, _, x) + enum_is_case_exprs(e, _, x) or explicit_cast_exprs(e, x) or @@ -96,7 +94,7 @@ Element getAnImmediateChild(Element e) { or key_path_application_exprs(e, _, x) or - key_path_expr_parsed_roots(e, x) + key_path_expr_roots(e, x) or key_path_expr_parsed_paths(e, x) or diff --git a/swift/ql/lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll index e02b97813a4..1dfdb7d0d2c 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/EnumIsCaseExpr.qll @@ -1,28 +1,20 @@ // generated by codegen/codegen.py import codeql.swift.elements.decl.EnumElementDecl import codeql.swift.elements.expr.Expr -import codeql.swift.elements.typerepr.TypeRepr class EnumIsCaseExprBase extends @enum_is_case_expr, Expr { override string getAPrimaryQlClass() { result = "EnumIsCaseExpr" } Expr getSubExpr() { exists(Expr x | - enum_is_case_exprs(this, x, _, _) and - result = x.resolve() - ) - } - - TypeRepr getTypeRepr() { - exists(TypeRepr x | - enum_is_case_exprs(this, _, x, _) and + enum_is_case_exprs(this, x, _) and result = x.resolve() ) } EnumElementDecl getElement() { exists(EnumElementDecl x | - enum_is_case_exprs(this, _, _, x) and + enum_is_case_exprs(this, _, x) and result = x.resolve() ) } diff --git a/swift/ql/lib/codeql/swift/generated/expr/KeyPathExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/KeyPathExpr.qll index 7ac3d4614f0..faeeb4fde9b 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/KeyPathExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/KeyPathExpr.qll @@ -1,17 +1,18 @@ // generated by codegen/codegen.py import codeql.swift.elements.expr.Expr +import codeql.swift.elements.type.TypeRepr class KeyPathExprBase extends @key_path_expr, Expr { override string getAPrimaryQlClass() { result = "KeyPathExpr" } - Expr getParsedRoot() { - exists(Expr x | - key_path_expr_parsed_roots(this, x) and + TypeRepr getRoot() { + exists(TypeRepr x | + key_path_expr_roots(this, x) and result = x.resolve() ) } - predicate hasParsedRoot() { exists(getParsedRoot()) } + predicate hasRoot() { exists(getRoot()) } Expr getParsedPath() { exists(Expr x | diff --git a/swift/ql/lib/codeql/swift/generated/expr/TypeExpr.qll b/swift/ql/lib/codeql/swift/generated/expr/TypeExpr.qll index 8b9e238b3ca..3c5816624d1 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/TypeExpr.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/TypeExpr.qll @@ -1,6 +1,6 @@ // generated by codegen/codegen.py import codeql.swift.elements.expr.Expr -import codeql.swift.elements.typerepr.TypeRepr +import codeql.swift.elements.type.TypeRepr class TypeExprBase extends @type_expr, Expr { override string getAPrimaryQlClass() { result = "TypeExpr" } diff --git a/swift/ql/lib/codeql/swift/generated/pattern/IsPattern.qll b/swift/ql/lib/codeql/swift/generated/pattern/IsPattern.qll index 8caf5493b36..b83c0af7d65 100644 --- a/swift/ql/lib/codeql/swift/generated/pattern/IsPattern.qll +++ b/swift/ql/lib/codeql/swift/generated/pattern/IsPattern.qll @@ -1,6 +1,6 @@ // generated by codegen/codegen.py import codeql.swift.elements.pattern.Pattern -import codeql.swift.elements.typerepr.TypeRepr +import codeql.swift.elements.type.TypeRepr class IsPatternBase extends @is_pattern, Pattern { override string getAPrimaryQlClass() { result = "IsPattern" } diff --git a/swift/ql/lib/codeql/swift/generated/pattern/TypedPattern.qll b/swift/ql/lib/codeql/swift/generated/pattern/TypedPattern.qll index 9a16c9cfe02..aebb2a6527c 100644 --- a/swift/ql/lib/codeql/swift/generated/pattern/TypedPattern.qll +++ b/swift/ql/lib/codeql/swift/generated/pattern/TypedPattern.qll @@ -1,6 +1,6 @@ // generated by codegen/codegen.py import codeql.swift.elements.pattern.Pattern -import codeql.swift.elements.typerepr.TypeRepr +import codeql.swift.elements.type.TypeRepr class TypedPatternBase extends @typed_pattern, Pattern { override string getAPrimaryQlClass() { result = "TypedPattern" } diff --git a/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll b/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll new file mode 100644 index 00000000000..829960deda9 --- /dev/null +++ b/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll @@ -0,0 +1,14 @@ +// generated by codegen/codegen.py +import codeql.swift.elements.AstNode +import codeql.swift.elements.type.Type + +class TypeReprBase extends @type_repr, AstNode { + override string getAPrimaryQlClass() { result = "TypeRepr" } + + Type getType() { + exists(Type x | + type_reprs(this, x) and + result = x.resolve() + ) + } +} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/ArrayTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/ArrayTypeRepr.qll deleted file mode 100644 index 486a98a541e..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/ArrayTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class ArrayTypeReprBase extends @array_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "ArrayTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/AttributedTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/AttributedTypeRepr.qll deleted file mode 100644 index 96d78c7c933..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/AttributedTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class AttributedTypeReprBase extends @attributed_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "AttributedTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/CompileTimeConstTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/CompileTimeConstTypeRepr.qll deleted file mode 100644 index eecb67b9218..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/CompileTimeConstTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.SpecifierTypeRepr - -class CompileTimeConstTypeReprBase extends @compile_time_const_type_repr, SpecifierTypeRepr { - override string getAPrimaryQlClass() { result = "CompileTimeConstTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/ComponentIdentTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/ComponentIdentTypeRepr.qll deleted file mode 100644 index d0323ad681d..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/ComponentIdentTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.IdentTypeRepr - -class ComponentIdentTypeReprBase extends @component_ident_type_repr, IdentTypeRepr { } diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/CompositionTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/CompositionTypeRepr.qll deleted file mode 100644 index b0789100618..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/CompositionTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class CompositionTypeReprBase extends @composition_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "CompositionTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/CompoundIdentTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/CompoundIdentTypeRepr.qll deleted file mode 100644 index 7c1c3548272..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/CompoundIdentTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.IdentTypeRepr - -class CompoundIdentTypeReprBase extends @compound_ident_type_repr, IdentTypeRepr { - override string getAPrimaryQlClass() { result = "CompoundIdentTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/DictionaryTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/DictionaryTypeRepr.qll deleted file mode 100644 index 692b9352e20..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/DictionaryTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class DictionaryTypeReprBase extends @dictionary_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "DictionaryTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/ErrorTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/ErrorTypeRepr.qll deleted file mode 100644 index 511f7e25569..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/ErrorTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class ErrorTypeReprBase extends @error_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "ErrorTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/ExistentialTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/ExistentialTypeRepr.qll deleted file mode 100644 index 43aefeed5a9..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/ExistentialTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class ExistentialTypeReprBase extends @existential_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "ExistentialTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/FixedTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/FixedTypeRepr.qll deleted file mode 100644 index 2a6e59a90a8..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/FixedTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class FixedTypeReprBase extends @fixed_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "FixedTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/FunctionTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/FunctionTypeRepr.qll deleted file mode 100644 index da781a90d4b..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/FunctionTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class FunctionTypeReprBase extends @function_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "FunctionTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/GenericIdentTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/GenericIdentTypeRepr.qll deleted file mode 100644 index 101985aca56..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/GenericIdentTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.ComponentIdentTypeRepr - -class GenericIdentTypeReprBase extends @generic_ident_type_repr, ComponentIdentTypeRepr { - override string getAPrimaryQlClass() { result = "GenericIdentTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/IdentTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/IdentTypeRepr.qll deleted file mode 100644 index d71eca38b92..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/IdentTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class IdentTypeReprBase extends @ident_type_repr, TypeRepr { } diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr.qll deleted file mode 100644 index e0759e0fa3c..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr.qll +++ /dev/null @@ -1,7 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class ImplicitlyUnwrappedOptionalTypeReprBase extends @implicitly_unwrapped_optional_type_repr, - TypeRepr { - override string getAPrimaryQlClass() { result = "ImplicitlyUnwrappedOptionalTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/InOutTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/InOutTypeRepr.qll deleted file mode 100644 index a7adf859579..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/InOutTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.SpecifierTypeRepr - -class InOutTypeReprBase extends @in_out_type_repr, SpecifierTypeRepr { - override string getAPrimaryQlClass() { result = "InOutTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/IsolatedTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/IsolatedTypeRepr.qll deleted file mode 100644 index 63dcdd9e379..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/IsolatedTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.SpecifierTypeRepr - -class IsolatedTypeReprBase extends @isolated_type_repr, SpecifierTypeRepr { - override string getAPrimaryQlClass() { result = "IsolatedTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/MetatypeTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/MetatypeTypeRepr.qll deleted file mode 100644 index e0477db158b..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/MetatypeTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class MetatypeTypeReprBase extends @metatype_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "MetatypeTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/NamedOpaqueReturnTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/NamedOpaqueReturnTypeRepr.qll deleted file mode 100644 index af885d21ab4..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/NamedOpaqueReturnTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class NamedOpaqueReturnTypeReprBase extends @named_opaque_return_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "NamedOpaqueReturnTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/OpaqueReturnTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/OpaqueReturnTypeRepr.qll deleted file mode 100644 index 7ecb38e22c6..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/OpaqueReturnTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class OpaqueReturnTypeReprBase extends @opaque_return_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "OpaqueReturnTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/OptionalTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/OptionalTypeRepr.qll deleted file mode 100644 index 62a24285ef5..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/OptionalTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class OptionalTypeReprBase extends @optional_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "OptionalTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/OwnedTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/OwnedTypeRepr.qll deleted file mode 100644 index b24ca1aa597..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/OwnedTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.SpecifierTypeRepr - -class OwnedTypeReprBase extends @owned_type_repr, SpecifierTypeRepr { - override string getAPrimaryQlClass() { result = "OwnedTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/PlaceholderTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/PlaceholderTypeRepr.qll deleted file mode 100644 index 5bb446c9c73..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/PlaceholderTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class PlaceholderTypeReprBase extends @placeholder_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "PlaceholderTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/ProtocolTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/ProtocolTypeRepr.qll deleted file mode 100644 index 1b2e7fb2652..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/ProtocolTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class ProtocolTypeReprBase extends @protocol_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "ProtocolTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/SharedTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/SharedTypeRepr.qll deleted file mode 100644 index ca9254217c9..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/SharedTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.SpecifierTypeRepr - -class SharedTypeReprBase extends @shared_type_repr, SpecifierTypeRepr { - override string getAPrimaryQlClass() { result = "SharedTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/SilBoxTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/SilBoxTypeRepr.qll deleted file mode 100644 index 47d4585511b..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/SilBoxTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class SilBoxTypeReprBase extends @sil_box_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "SilBoxTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/SimpleIdentTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/SimpleIdentTypeRepr.qll deleted file mode 100644 index 328b8bc7e69..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/SimpleIdentTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.ComponentIdentTypeRepr - -class SimpleIdentTypeReprBase extends @simple_ident_type_repr, ComponentIdentTypeRepr { - override string getAPrimaryQlClass() { result = "SimpleIdentTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/SpecifierTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/SpecifierTypeRepr.qll deleted file mode 100644 index 469aa3413d1..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/SpecifierTypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class SpecifierTypeReprBase extends @specifier_type_repr, TypeRepr { } diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/TupleTypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/TupleTypeRepr.qll deleted file mode 100644 index 79e65037aa9..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/TupleTypeRepr.qll +++ /dev/null @@ -1,6 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.typerepr.TypeRepr - -class TupleTypeReprBase extends @tuple_type_repr, TypeRepr { - override string getAPrimaryQlClass() { result = "TupleTypeRepr" } -} diff --git a/swift/ql/lib/codeql/swift/generated/typerepr/TypeRepr.qll b/swift/ql/lib/codeql/swift/generated/typerepr/TypeRepr.qll deleted file mode 100644 index 497ac46fa64..00000000000 --- a/swift/ql/lib/codeql/swift/generated/typerepr/TypeRepr.qll +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements.AstNode - -class TypeReprBase extends @type_repr, AstNode { } diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index 83ee8412131..61cda563d66 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -471,27 +471,10 @@ expr_types( //dir=expr | @yield_stmt ; -@type_repr = - @array_type_repr -| @attributed_type_repr -| @composition_type_repr -| @dictionary_type_repr -| @error_type_repr -| @existential_type_repr -| @fixed_type_repr -| @function_type_repr -| @ident_type_repr -| @implicitly_unwrapped_optional_type_repr -| @metatype_type_repr -| @named_opaque_return_type_repr -| @opaque_return_type_repr -| @optional_type_repr -| @placeholder_type_repr -| @protocol_type_repr -| @sil_box_type_repr -| @specifier_type_repr -| @tuple_type_repr -; +type_reprs( //dir=type + unique int id: @type_repr, + int type_: @type ref +); function_types( //dir=type unique int id: @function_type @@ -865,7 +848,6 @@ editor_placeholder_exprs( //dir=expr enum_is_case_exprs( //dir=expr unique int id: @enum_is_case_expr, int sub_expr: @expr ref, - int type_repr: @type_repr ref, int element: @enum_element_decl ref ); @@ -969,9 +951,9 @@ key_path_exprs( //dir=expr ); #keyset[id] -key_path_expr_parsed_roots( //dir=expr +key_path_expr_roots( //dir=expr int id: @key_path_expr ref, - int parsed_root: @expr ref + int root: @type_repr ref ); #keyset[id] @@ -2177,121 +2159,3 @@ integer_literal_exprs( //dir=expr unique int id: @integer_literal_expr, string string_value: string ref ); - -error_type_reprs( //dir=typerepr - unique int id: @error_type_repr -); - -attributed_type_reprs( //dir=typerepr - unique int id: @attributed_type_repr -); - -@ident_type_repr = - @component_ident_type_repr -| @compound_ident_type_repr -; - -@component_ident_type_repr = - @generic_ident_type_repr -| @simple_ident_type_repr -; - -simple_ident_type_reprs( //dir=typerepr - unique int id: @simple_ident_type_repr -); - -generic_ident_type_reprs( //dir=typerepr - unique int id: @generic_ident_type_repr -); - -compound_ident_type_reprs( //dir=typerepr - unique int id: @compound_ident_type_repr -); - -function_type_reprs( //dir=typerepr - unique int id: @function_type_repr -); - -array_type_reprs( //dir=typerepr - unique int id: @array_type_repr -); - -dictionary_type_reprs( //dir=typerepr - unique int id: @dictionary_type_repr -); - -optional_type_reprs( //dir=typerepr - unique int id: @optional_type_repr -); - -implicitly_unwrapped_optional_type_reprs( //dir=typerepr - unique int id: @implicitly_unwrapped_optional_type_repr -); - -tuple_type_reprs( //dir=typerepr - unique int id: @tuple_type_repr -); - -composition_type_reprs( //dir=typerepr - unique int id: @composition_type_repr -); - -metatype_type_reprs( //dir=typerepr - unique int id: @metatype_type_repr -); - -protocol_type_reprs( //dir=typerepr - unique int id: @protocol_type_repr -); - -opaque_return_type_reprs( //dir=typerepr - unique int id: @opaque_return_type_repr -); - -named_opaque_return_type_reprs( //dir=typerepr - unique int id: @named_opaque_return_type_repr -); - -existential_type_reprs( //dir=typerepr - unique int id: @existential_type_repr -); - -placeholder_type_reprs( //dir=typerepr - unique int id: @placeholder_type_repr -); - -@specifier_type_repr = - @compile_time_const_type_repr -| @in_out_type_repr -| @isolated_type_repr -| @owned_type_repr -| @shared_type_repr -; - -in_out_type_reprs( //dir=typerepr - unique int id: @in_out_type_repr -); - -shared_type_reprs( //dir=typerepr - unique int id: @shared_type_repr -); - -owned_type_reprs( //dir=typerepr - unique int id: @owned_type_repr -); - -isolated_type_reprs( //dir=typerepr - unique int id: @isolated_type_repr -); - -compile_time_const_type_reprs( //dir=typerepr - unique int id: @compile_time_const_type_repr -); - -fixed_type_reprs( //dir=typerepr - unique int id: @fixed_type_repr -); - -sil_box_type_reprs( //dir=typerepr - unique int id: @sil_box_type_repr -); diff --git a/swift/ql/test/extractor-tests/expressions/all.expected b/swift/ql/test/extractor-tests/expressions/all.expected index 20951358f73..b34ca7349cd 100644 --- a/swift/ql/test/extractor-tests/expressions/all.expected +++ b/swift/ql/test/extractor-tests/expressions/all.expected @@ -123,8 +123,6 @@ | expressions.swift:54:1:54:1 | _ | DiscardAssignmentExpr | | expressions.swift:54:1:54:8 | ... = ... | AssignExpr | | expressions.swift:54:5:54:8 | #keyPath(...) | KeyPathExpr | -| expressions.swift:54:6:54:6 | (no string representation) | TypeExpr | -| expressions.swift:54:6:54:8 | ... .x | UnresolvedDotExpr | | expressions.swift:58:16:58:16 | 1234 | IntegerLiteralExpr | | expressions.swift:59:1:59:1 | unsafeFunction(pointer:) | DeclRefExpr | | expressions.swift:59:1:59:34 | call to unsafeFunction(pointer:) | CallExpr | @@ -242,5 +240,3 @@ | expressions.swift:154:22:154:56 | \\...[...] | KeyPathApplicationExpr | | expressions.swift:154:33:154:33 | keyPathB | DeclRefExpr | | expressions.swift:154:52:154:55 | #keyPath(...) | KeyPathExpr | -| expressions.swift:154:53:154:53 | (no string representation) | TypeExpr | -| expressions.swift:154:53:154:55 | ... .x | UnresolvedDotExpr | diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected index 9b22d5b34d4..6076a256058 100644 --- a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.expected @@ -1,10 +1,10 @@ -| enum_is_case.swift:4:1:4:17 | ... is some | getSubExpr: | enum_is_case.swift:4:1:4:17 | OptionalEvaluationExpr | getTypeRepr: | enum_is_case.swift:4:22:4:22 | SimpleIdentTypeRepr | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:5:1:5:32 | ... is some | getSubExpr: | enum_is_case.swift:5:1:5:32 | OptionalEvaluationExpr | getTypeRepr: | enum_is_case.swift:5:37:5:37 | SimpleIdentTypeRepr | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:6:1:6:1 | ... is some | getSubExpr: | enum_is_case.swift:6:1:6:1 | 42 | getTypeRepr: | enum_is_case.swift:6:7:6:10 | ...? | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:7:1:7:1 | ... is some | getSubExpr: | enum_is_case.swift:7:1:7:1 | 42 | getTypeRepr: | enum_is_case.swift:7:7:7:11 | ...? | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:9:1:9:19 | ... is some | getSubExpr: | enum_is_case.swift:9:1:9:19 | [...] | getTypeRepr: | enum_is_case.swift:9:24:9:28 | [...] | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:19:1:19:18 | ... is some | getSubExpr: | enum_is_case.swift:19:1:19:18 | OptionalEvaluationExpr | getTypeRepr: | enum_is_case.swift:19:23:19:23 | SimpleIdentTypeRepr | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:21:1:21:5 | ... is some | getSubExpr: | enum_is_case.swift:21:1:21:5 | [...] | getTypeRepr: | enum_is_case.swift:21:10:21:12 | [...] | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:22:1:22:10 | ... is some | getSubExpr: | enum_is_case.swift:22:1:22:10 | [...] | getTypeRepr: | enum_is_case.swift:22:15:22:25 | [... : ...] | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:23:1:23:10 | ... is some | getSubExpr: | enum_is_case.swift:23:1:23:10 | [...] | getTypeRepr: | enum_is_case.swift:23:15:23:25 | [... : ...] | getElement: | file://:0:0:0:0 | some | -| enum_is_case.swift:24:1:24:8 | ... is some | getSubExpr: | enum_is_case.swift:24:1:24:8 | call to ... | getTypeRepr: | enum_is_case.swift:24:13:24:18 | ...<...> | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:4:1:4:17 | ... is some | getSubExpr: | enum_is_case.swift:4:1:4:17 | OptionalEvaluationExpr | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:5:1:5:32 | ... is some | getSubExpr: | enum_is_case.swift:5:1:5:32 | OptionalEvaluationExpr | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:6:1:6:1 | ... is some | getSubExpr: | enum_is_case.swift:6:1:6:1 | 42 | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:7:1:7:1 | ... is some | getSubExpr: | enum_is_case.swift:7:1:7:1 | 42 | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:9:1:9:19 | ... is some | getSubExpr: | enum_is_case.swift:9:1:9:19 | [...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:19:1:19:18 | ... is some | getSubExpr: | enum_is_case.swift:19:1:19:18 | OptionalEvaluationExpr | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:21:1:21:5 | ... is some | getSubExpr: | enum_is_case.swift:21:1:21:5 | [...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:22:1:22:10 | ... is some | getSubExpr: | enum_is_case.swift:22:1:22:10 | [...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:23:1:23:10 | ... is some | getSubExpr: | enum_is_case.swift:23:1:23:10 | [...] | getElement: | file://:0:0:0:0 | some | +| enum_is_case.swift:24:1:24:8 | ... is some | getSubExpr: | enum_is_case.swift:24:1:24:8 | call to ... | getElement: | file://:0:0:0:0 | some | diff --git a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.ql b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.ql index e35700dcbe0..9c3340d4ff5 100644 --- a/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.ql +++ b/swift/ql/test/extractor-tests/generated/expr/EnumIsCaseExpr/EnumIsCaseExpr.ql @@ -2,11 +2,10 @@ import codeql.swift.elements import TestUtils -from EnumIsCaseExpr x, Expr getSubExpr, TypeRepr getTypeRepr, EnumElementDecl getElement +from EnumIsCaseExpr x, Expr getSubExpr, EnumElementDecl getElement where toBeTested(x) and not x.isUnknown() and getSubExpr = x.getSubExpr() and - getTypeRepr = x.getTypeRepr() and getElement = x.getElement() -select x, "getSubExpr:", getSubExpr, "getTypeRepr:", getTypeRepr, "getElement:", getElement +select x, "getSubExpr:", getSubExpr, "getElement:", getElement diff --git a/swift/ql/test/extractor-tests/generated/typerepr/ArrayTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/MISSING_SOURCE.txt similarity index 100% rename from swift/ql/test/extractor-tests/generated/typerepr/ArrayTypeRepr/MISSING_SOURCE.txt rename to swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/MISSING_SOURCE.txt diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.expected b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.expected deleted file mode 100644 index 2bb615eb361..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.expected +++ /dev/null @@ -1,3 +0,0 @@ -| unresolved_dot_expr.swift:5:6:5:8 | ... .x | getBase: | unresolved_dot_expr.swift:5:6:5:6 | (no string representation) | getName: | x | -| unresolved_dot_expr.swift:11:6:11:8 | ... .a | getBase: | unresolved_dot_expr.swift:11:6:11:6 | (no string representation) | getName: | a | -| unresolved_dot_expr.swift:11:6:11:10 | ... .x | getBase: | unresolved_dot_expr.swift:11:6:11:8 | ... .a | getName: | x | diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql deleted file mode 100644 index 29327a3f86c..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr.ql +++ /dev/null @@ -1,11 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements -import TestUtils - -from UnresolvedDotExpr x, Expr getBase, string getName -where - toBeTested(x) and - not x.isUnknown() and - getBase = x.getBase() and - getName = x.getName() -select x, "getBase:", getBase, "getName:", getName diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getType.expected b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getType.expected deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getType.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getType.ql deleted file mode 100644 index f91cc957ef7..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/UnresolvedDotExpr_getType.ql +++ /dev/null @@ -1,7 +0,0 @@ -// generated by codegen/codegen.py -import codeql.swift.elements -import TestUtils - -from UnresolvedDotExpr x -where toBeTested(x) and not x.isUnknown() -select x, x.getType() diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/unresolved_dot_expr.swift b/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/unresolved_dot_expr.swift deleted file mode 100644 index 3003e6efe82..00000000000 --- a/swift/ql/test/extractor-tests/generated/expr/UnresolvedDotExpr/unresolved_dot_expr.swift +++ /dev/null @@ -1,11 +0,0 @@ -struct A { - var x: Int = 42 -} - -_ = \A.x - -struct B { - var a: A -} - -_ = \B.a.x diff --git a/swift/ql/test/extractor-tests/generated/typerepr/AttributedTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/TypeRepr/MISSING_SOURCE.txt similarity index 100% rename from swift/ql/test/extractor-tests/generated/typerepr/AttributedTypeRepr/MISSING_SOURCE.txt rename to swift/ql/test/extractor-tests/generated/type/TypeRepr/MISSING_SOURCE.txt diff --git a/swift/ql/test/extractor-tests/generated/typerepr/CompileTimeConstTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/CompileTimeConstTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/CompileTimeConstTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/CompositionTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/CompositionTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/CompositionTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/CompoundIdentTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/CompoundIdentTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/CompoundIdentTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/DictionaryTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/DictionaryTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/DictionaryTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/ErrorTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/ErrorTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/ErrorTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/ExistentialTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/ExistentialTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/ExistentialTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/FixedTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/FixedTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/FixedTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/FunctionTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/FunctionTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/FunctionTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/GenericIdentTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/GenericIdentTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/GenericIdentTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/ImplicitlyUnwrappedOptionalTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/InOutTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/InOutTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/InOutTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/IsolatedTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/IsolatedTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/IsolatedTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/MetatypeTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/MetatypeTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/MetatypeTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/NamedOpaqueReturnTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/NamedOpaqueReturnTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/NamedOpaqueReturnTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/OpaqueReturnTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/OpaqueReturnTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/OpaqueReturnTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/OptionalTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/OptionalTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/OptionalTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/OwnedTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/OwnedTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/OwnedTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/PlaceholderTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/PlaceholderTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/PlaceholderTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/ProtocolTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/ProtocolTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/ProtocolTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/SharedTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/SharedTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/SharedTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/SilBoxTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/SilBoxTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/SilBoxTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/SimpleIdentTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/SimpleIdentTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/SimpleIdentTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/typerepr/TupleTypeRepr/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/typerepr/TupleTypeRepr/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/typerepr/TupleTypeRepr/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected index 4d38d88d82c..d14ec33b48e 100644 --- a/swift/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/swift/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -281,15 +281,12 @@ cfg.swift: #-----| -> ... is ... # 37| ... is ... -#-----| -> SimpleIdentTypeRepr +#-----| -> ... is ... # 37| ... is ... #-----| match -> print(_:separator:terminator:) #-----| no-match -> case ... -# 37| SimpleIdentTypeRepr -#-----| -> ... is ... - # 38| print(_:separator:terminator:) #-----| -> MyError @@ -5575,15 +5572,39 @@ cfg.swift: # 456| var ... = ... #-----| -> kpGet_b_x +# 456| var ... = ... +#-----| -> kpGet_b_x + # 456| kpGet_b_x #-----| match -> #keyPath(...) # 456| kpGet_b_x #-----| -> kpGet_bs_0_x +# 456| kpGet_b_x +#-----| -> kpGet_bs_0_x + # 456| #keyPath(...) #-----| -> var ... = ... +# 456| #keyPath(...) +#-----| -> var ... = ... +#-----| -> exit #keyPath(...) (normal) + +# 456| enter #keyPath(...) +#-----| -> #keyPath(...) + +# 456| exit #keyPath(...) + +# 456| exit #keyPath(...) (normal) +#-----| -> exit #keyPath(...) + +# 457| var ... = ... +#-----| -> kpGet_bs_0_x + +# 457| var ... = ... +#-----| -> kpGet_bs_0_x + # 457| var ... = ... #-----| -> kpGet_bs_0_x @@ -5593,9 +5614,42 @@ cfg.swift: # 457| kpGet_bs_0_x #-----| -> kpGet_mayB_force_x +# 457| kpGet_bs_0_x +#-----| match -> #keyPath(...) + +# 457| kpGet_bs_0_x +#-----| -> kpGet_mayB_force_x + +# 457| kpGet_bs_0_x +#-----| -> kpGet_mayB_force_x + # 457| #keyPath(...) #-----| -> var ... = ... +# 457| #keyPath(...) +#-----| -> var ... = ... + +# 457| #keyPath(...) +#-----| -> var ... = ... +#-----| -> exit #keyPath(...) (normal) + +# 457| enter #keyPath(...) +#-----| -> #keyPath(...) + +# 457| exit #keyPath(...) + +# 457| exit #keyPath(...) (normal) +#-----| -> exit #keyPath(...) + +# 458| var ... = ... +#-----| -> kpGet_mayB_force_x + +# 458| var ... = ... +#-----| -> kpGet_mayB_force_x + +# 458| var ... = ... +#-----| -> kpGet_mayB_force_x + # 458| var ... = ... #-----| -> kpGet_mayB_force_x @@ -5605,9 +5659,54 @@ cfg.swift: # 458| kpGet_mayB_force_x #-----| -> kpGet_mayB_x +# 458| kpGet_mayB_force_x +#-----| match -> #keyPath(...) + +# 458| kpGet_mayB_force_x +#-----| -> kpGet_mayB_x + +# 458| kpGet_mayB_force_x +#-----| match -> #keyPath(...) + +# 458| kpGet_mayB_force_x +#-----| -> kpGet_mayB_x + +# 458| kpGet_mayB_force_x +#-----| -> kpGet_mayB_x + # 458| #keyPath(...) #-----| -> var ... = ... +# 458| #keyPath(...) +#-----| -> var ... = ... + +# 458| #keyPath(...) +#-----| -> var ... = ... + +# 458| #keyPath(...) +#-----| -> var ... = ... +#-----| -> exit #keyPath(...) (normal) + +# 458| enter #keyPath(...) +#-----| -> #keyPath(...) + +# 458| exit #keyPath(...) + +# 458| exit #keyPath(...) (normal) +#-----| -> exit #keyPath(...) + +# 459| var ... = ... +#-----| -> kpGet_mayB_x + +# 459| var ... = ... +#-----| -> kpGet_mayB_x + +# 459| var ... = ... +#-----| -> kpGet_mayB_x + +# 459| var ... = ... +#-----| -> kpGet_mayB_x + # 459| var ... = ... #-----| -> kpGet_mayB_x @@ -5617,9 +5716,63 @@ cfg.swift: # 459| kpGet_mayB_x #-----| -> apply_kpGet_b_x +# 459| kpGet_mayB_x +#-----| match -> #keyPath(...) + +# 459| kpGet_mayB_x +#-----| -> apply_kpGet_b_x + +# 459| kpGet_mayB_x +#-----| match -> #keyPath(...) + +# 459| kpGet_mayB_x +#-----| -> apply_kpGet_b_x + +# 459| kpGet_mayB_x +#-----| match -> #keyPath(...) + +# 459| kpGet_mayB_x +#-----| -> apply_kpGet_b_x + +# 459| kpGet_mayB_x +#-----| -> apply_kpGet_b_x + # 459| #keyPath(...) #-----| -> var ... = ... +# 459| #keyPath(...) +#-----| -> var ... = ... + +# 459| #keyPath(...) +#-----| -> var ... = ... + +# 459| #keyPath(...) +#-----| -> var ... = ... + +# 459| #keyPath(...) +#-----| -> var ... = ... +#-----| -> exit #keyPath(...) (normal) + +# 459| enter #keyPath(...) +#-----| -> #keyPath(...) + +# 459| exit #keyPath(...) + +# 459| exit #keyPath(...) (normal) +#-----| -> exit #keyPath(...) + +# 461| var ... = ... +#-----| -> apply_kpGet_b_x + +# 461| var ... = ... +#-----| -> apply_kpGet_b_x + +# 461| var ... = ... +#-----| -> apply_kpGet_b_x + +# 461| var ... = ... +#-----| -> apply_kpGet_b_x + # 461| var ... = ... #-----| -> apply_kpGet_b_x @@ -5629,18 +5782,102 @@ cfg.swift: # 461| apply_kpGet_b_x #-----| -> apply_kpGet_bs_0_x +# 461| apply_kpGet_b_x +#-----| match -> a + +# 461| apply_kpGet_b_x +#-----| -> apply_kpGet_bs_0_x + +# 461| apply_kpGet_b_x +#-----| match -> a + +# 461| apply_kpGet_b_x +#-----| -> apply_kpGet_bs_0_x + +# 461| apply_kpGet_b_x +#-----| match -> a + +# 461| apply_kpGet_b_x +#-----| -> apply_kpGet_bs_0_x + +# 461| apply_kpGet_b_x +#-----| match -> a + +# 461| apply_kpGet_b_x +#-----| -> apply_kpGet_bs_0_x + # 461| a #-----| -> kpGet_b_x +# 461| a +#-----| -> kpGet_b_x + +# 461| a +#-----| -> kpGet_b_x + +# 461| a +#-----| -> kpGet_b_x + +# 461| a +#-----| -> kpGet_b_x + +# 461| \...[...] +#-----| -> var ... = ... + +# 461| \...[...] +#-----| -> var ... = ... + +# 461| \...[...] +#-----| -> var ... = ... + +# 461| \...[...] +#-----| -> var ... = ... + # 461| \...[...] #-----| -> var ... = ... # 461| (WritableKeyPath) ... #-----| -> \...[...] +# 461| (WritableKeyPath) ... +#-----| -> \...[...] + +# 461| (WritableKeyPath) ... +#-----| -> \...[...] + +# 461| (WritableKeyPath) ... +#-----| -> \...[...] + +# 461| (WritableKeyPath) ... +#-----| -> \...[...] + # 461| kpGet_b_x #-----| -> (WritableKeyPath) ... +# 461| kpGet_b_x +#-----| -> (WritableKeyPath) ... + +# 461| kpGet_b_x +#-----| -> (WritableKeyPath) ... + +# 461| kpGet_b_x +#-----| -> (WritableKeyPath) ... + +# 461| kpGet_b_x +#-----| -> (WritableKeyPath) ... + +# 462| var ... = ... +#-----| -> apply_kpGet_bs_0_x + +# 462| var ... = ... +#-----| -> apply_kpGet_bs_0_x + +# 462| var ... = ... +#-----| -> apply_kpGet_bs_0_x + +# 462| var ... = ... +#-----| -> apply_kpGet_bs_0_x + # 462| var ... = ... #-----| -> apply_kpGet_bs_0_x @@ -5650,18 +5887,102 @@ cfg.swift: # 462| apply_kpGet_bs_0_x #-----| -> apply_kpGet_mayB_force_x +# 462| apply_kpGet_bs_0_x +#-----| match -> a + +# 462| apply_kpGet_bs_0_x +#-----| -> apply_kpGet_mayB_force_x + +# 462| apply_kpGet_bs_0_x +#-----| match -> a + +# 462| apply_kpGet_bs_0_x +#-----| -> apply_kpGet_mayB_force_x + +# 462| apply_kpGet_bs_0_x +#-----| match -> a + +# 462| apply_kpGet_bs_0_x +#-----| -> apply_kpGet_mayB_force_x + +# 462| apply_kpGet_bs_0_x +#-----| match -> a + +# 462| apply_kpGet_bs_0_x +#-----| -> apply_kpGet_mayB_force_x + # 462| a #-----| -> kpGet_bs_0_x +# 462| a +#-----| -> kpGet_bs_0_x + +# 462| a +#-----| -> kpGet_bs_0_x + +# 462| a +#-----| -> kpGet_bs_0_x + +# 462| a +#-----| -> kpGet_bs_0_x + +# 462| \...[...] +#-----| -> var ... = ... + +# 462| \...[...] +#-----| -> var ... = ... + +# 462| \...[...] +#-----| -> var ... = ... + +# 462| \...[...] +#-----| -> var ... = ... + # 462| \...[...] #-----| -> var ... = ... # 462| (WritableKeyPath) ... #-----| -> \...[...] +# 462| (WritableKeyPath) ... +#-----| -> \...[...] + +# 462| (WritableKeyPath) ... +#-----| -> \...[...] + +# 462| (WritableKeyPath) ... +#-----| -> \...[...] + +# 462| (WritableKeyPath) ... +#-----| -> \...[...] + # 462| kpGet_bs_0_x #-----| -> (WritableKeyPath) ... +# 462| kpGet_bs_0_x +#-----| -> (WritableKeyPath) ... + +# 462| kpGet_bs_0_x +#-----| -> (WritableKeyPath) ... + +# 462| kpGet_bs_0_x +#-----| -> (WritableKeyPath) ... + +# 462| kpGet_bs_0_x +#-----| -> (WritableKeyPath) ... + +# 463| var ... = ... +#-----| -> apply_kpGet_mayB_force_x + +# 463| var ... = ... +#-----| -> apply_kpGet_mayB_force_x + +# 463| var ... = ... +#-----| -> apply_kpGet_mayB_force_x + +# 463| var ... = ... +#-----| -> apply_kpGet_mayB_force_x + # 463| var ... = ... #-----| -> apply_kpGet_mayB_force_x @@ -5671,18 +5992,102 @@ cfg.swift: # 463| apply_kpGet_mayB_force_x #-----| -> apply_kpGet_mayB_x +# 463| apply_kpGet_mayB_force_x +#-----| match -> a + +# 463| apply_kpGet_mayB_force_x +#-----| -> apply_kpGet_mayB_x + +# 463| apply_kpGet_mayB_force_x +#-----| match -> a + +# 463| apply_kpGet_mayB_force_x +#-----| -> apply_kpGet_mayB_x + +# 463| apply_kpGet_mayB_force_x +#-----| match -> a + +# 463| apply_kpGet_mayB_force_x +#-----| -> apply_kpGet_mayB_x + +# 463| apply_kpGet_mayB_force_x +#-----| match -> a + +# 463| apply_kpGet_mayB_force_x +#-----| -> apply_kpGet_mayB_x + # 463| a #-----| -> kpGet_mayB_force_x +# 463| a +#-----| -> kpGet_mayB_force_x + +# 463| a +#-----| -> kpGet_mayB_force_x + +# 463| a +#-----| -> kpGet_mayB_force_x + +# 463| a +#-----| -> kpGet_mayB_force_x + +# 463| \...[...] +#-----| -> var ... = ... + +# 463| \...[...] +#-----| -> var ... = ... + +# 463| \...[...] +#-----| -> var ... = ... + +# 463| \...[...] +#-----| -> var ... = ... + # 463| \...[...] #-----| -> var ... = ... # 463| (WritableKeyPath) ... #-----| -> \...[...] +# 463| (WritableKeyPath) ... +#-----| -> \...[...] + +# 463| (WritableKeyPath) ... +#-----| -> \...[...] + +# 463| (WritableKeyPath) ... +#-----| -> \...[...] + +# 463| (WritableKeyPath) ... +#-----| -> \...[...] + # 463| kpGet_mayB_force_x #-----| -> (WritableKeyPath) ... +# 463| kpGet_mayB_force_x +#-----| -> (WritableKeyPath) ... + +# 463| kpGet_mayB_force_x +#-----| -> (WritableKeyPath) ... + +# 463| kpGet_mayB_force_x +#-----| -> (WritableKeyPath) ... + +# 463| kpGet_mayB_force_x +#-----| -> (WritableKeyPath) ... + +# 464| var ... = ... +#-----| -> apply_kpGet_mayB_x + +# 464| var ... = ... +#-----| -> apply_kpGet_mayB_x + +# 464| var ... = ... +#-----| -> apply_kpGet_mayB_x + +# 464| var ... = ... +#-----| -> apply_kpGet_mayB_x + # 464| var ... = ... #-----| -> apply_kpGet_mayB_x @@ -5692,14 +6097,82 @@ cfg.swift: # 464| apply_kpGet_mayB_x #-----| -> exit test(a:) (normal) +# 464| apply_kpGet_mayB_x +#-----| match -> a + +# 464| apply_kpGet_mayB_x + +# 464| apply_kpGet_mayB_x +#-----| match -> a + +# 464| apply_kpGet_mayB_x + +# 464| apply_kpGet_mayB_x +#-----| match -> a + +# 464| apply_kpGet_mayB_x + +# 464| apply_kpGet_mayB_x +#-----| match -> a + +# 464| apply_kpGet_mayB_x + # 464| a #-----| -> kpGet_mayB_x +# 464| a +#-----| -> kpGet_mayB_x + +# 464| a +#-----| -> kpGet_mayB_x + +# 464| a +#-----| -> kpGet_mayB_x + +# 464| a +#-----| -> kpGet_mayB_x + +# 464| \...[...] +#-----| -> var ... = ... + +# 464| \...[...] +#-----| -> var ... = ... + +# 464| \...[...] +#-----| -> var ... = ... + +# 464| \...[...] +#-----| -> var ... = ... + # 464| \...[...] #-----| -> var ... = ... # 464| (KeyPath) ... #-----| -> \...[...] +# 464| (KeyPath) ... +#-----| -> \...[...] + +# 464| (KeyPath) ... +#-----| -> \...[...] + +# 464| (KeyPath) ... +#-----| -> \...[...] + +# 464| (KeyPath) ... +#-----| -> \...[...] + +# 464| kpGet_mayB_x +#-----| -> (KeyPath) ... + +# 464| kpGet_mayB_x +#-----| -> (KeyPath) ... + +# 464| kpGet_mayB_x +#-----| -> (KeyPath) ... + +# 464| kpGet_mayB_x +#-----| -> (KeyPath) ... + # 464| kpGet_mayB_x #-----| -> (KeyPath) ... diff --git a/swift/ql/test/library-tests/parent/parent.expected b/swift/ql/test/library-tests/parent/parent.expected index ab98c789f82..8ebbf1dd372 100644 --- a/swift/ql/test/library-tests/parent/parent.expected +++ b/swift/ql/test/library-tests/parent/parent.expected @@ -22,13 +22,13 @@ | declarations.swift:3:7:3:7 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr | | declarations.swift:3:7:3:7 | { ... } | BraceStmt | declarations.swift:3:7:3:7 | yield ... | YieldStmt | | declarations.swift:3:7:3:14 | ... as ... | TypedPattern | declarations.swift:3:7:3:7 | next | NamedPattern | -| declarations.swift:3:7:3:14 | ... as ... | TypedPattern | declarations.swift:3:14:3:14 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:3:7:3:14 | ... as ... | TypedPattern | declarations.swift:3:14:3:14 | Int | TypeRepr | | declarations.swift:4:5:4:24 | get | AccessorDecl | declarations.swift:4:9:4:24 | { ... } | BraceStmt | | declarations.swift:4:9:4:24 | { ... } | BraceStmt | declarations.swift:4:11:4:22 | return ... | ReturnStmt | | declarations.swift:4:11:4:22 | return ... | ReturnStmt | declarations.swift:4:18:4:22 | ... call to +(_:_:) ... | BinaryExpr | | declarations.swift:4:18:4:18 | .x | MemberRefExpr | declarations.swift:4:18:4:18 | self | DeclRefExpr | | declarations.swift:4:18:4:22 | ... call to +(_:_:) ... | BinaryExpr | declarations.swift:4:20:4:20 | call to +(_:_:) | DotSyntaxCallExpr | -| declarations.swift:4:20:4:20 | Int.Type | TypeExpr | declarations.swift:4:20:4:20 | FixedTypeRepr | FixedTypeRepr | +| declarations.swift:4:20:4:20 | Int.Type | TypeExpr | declarations.swift:4:20:4:20 | Int | TypeRepr | | declarations.swift:4:20:4:20 | call to +(_:_:) | DotSyntaxCallExpr | declarations.swift:4:20:4:20 | +(_:_:) | DeclRefExpr | | declarations.swift:5:5:5:38 | set | AccessorDecl | declarations.swift:5:9:5:9 | newValue | ParamDecl | | declarations.swift:5:5:5:38 | set | AccessorDecl | declarations.swift:5:19:5:38 | { ... } | BraceStmt | @@ -37,7 +37,7 @@ | declarations.swift:5:21:5:36 | ... = ... | AssignExpr | declarations.swift:5:21:5:21 | .x | MemberRefExpr | | declarations.swift:5:21:5:36 | ... = ... | AssignExpr | declarations.swift:5:25:5:36 | ... call to -(_:_:) ... | BinaryExpr | | declarations.swift:5:25:5:36 | ... call to -(_:_:) ... | BinaryExpr | declarations.swift:5:34:5:34 | call to -(_:_:) | DotSyntaxCallExpr | -| declarations.swift:5:34:5:34 | Int.Type | TypeExpr | declarations.swift:5:34:5:34 | FixedTypeRepr | FixedTypeRepr | +| declarations.swift:5:34:5:34 | Int.Type | TypeExpr | declarations.swift:5:34:5:34 | Int | TypeRepr | | declarations.swift:5:34:5:34 | call to -(_:_:) | DotSyntaxCallExpr | declarations.swift:5:34:5:34 | -(_:_:) | DeclRefExpr | | declarations.swift:9:7:9:7 | deinit | DestructorDecl | declarations.swift:9:7:9:7 | { ... } | BraceStmt | | declarations.swift:9:7:9:7 | init | ConstructorDecl | declarations.swift:9:7:9:7 | { ... } | BraceStmt | @@ -56,7 +56,7 @@ | declarations.swift:9:17:9:17 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | declarations.swift:9:17:9:17 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:9:17:9:21 | ... as ... | TypedPattern | declarations.swift:9:17:9:17 | x | NamedPattern | -| declarations.swift:9:17:9:21 | ... as ... | TypedPattern | declarations.swift:9:21:9:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:9:17:9:21 | ... as ... | TypedPattern | declarations.swift:9:21:9:21 | Double | TypeRepr | | declarations.swift:12:5:12:18 | case ... | EnumCaseDecl | declarations.swift:12:10:12:10 | value1 | EnumElementDecl | | declarations.swift:12:5:12:18 | case ... | EnumCaseDecl | declarations.swift:12:18:12:18 | value2 | EnumElementDecl | | declarations.swift:13:5:13:26 | case ... | EnumCaseDecl | declarations.swift:13:10:13:10 | value3 | EnumElementDecl | @@ -75,12 +75,12 @@ | declarations.swift:23:9:23:9 | mustBeSettable | ConcreteVarDecl | declarations.swift:23:31:23:31 | get | AccessorDecl | | declarations.swift:23:9:23:9 | mustBeSettable | ConcreteVarDecl | declarations.swift:23:35:23:35 | set | AccessorDecl | | declarations.swift:23:9:23:25 | ... as ... | TypedPattern | declarations.swift:23:9:23:9 | mustBeSettable | NamedPattern | -| declarations.swift:23:9:23:25 | ... as ... | TypedPattern | declarations.swift:23:25:23:25 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:23:9:23:25 | ... as ... | TypedPattern | declarations.swift:23:25:23:25 | Int | TypeRepr | | declarations.swift:23:35:23:35 | set | AccessorDecl | declarations.swift:23:35:23:35 | newValue | ParamDecl | | declarations.swift:24:5:24:44 | var ... = ... | PatternBindingDecl | declarations.swift:24:9:24:34 | ... as ... | TypedPattern | | declarations.swift:24:9:24:9 | doesNotNeedToBeSettable | ConcreteVarDecl | declarations.swift:24:40:24:40 | get | AccessorDecl | | declarations.swift:24:9:24:34 | ... as ... | TypedPattern | declarations.swift:24:9:24:9 | doesNotNeedToBeSettable | NamedPattern | -| declarations.swift:24:9:24:34 | ... as ... | TypedPattern | declarations.swift:24:34:24:34 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:24:9:24:34 | ... as ... | TypedPattern | declarations.swift:24:34:24:34 | Int | TypeRepr | | declarations.swift:28:1:28:37 | a_function(a_parameter:) | ConcreteFuncDecl | declarations.swift:28:17:28:31 | a_parameter | ParamDecl | | declarations.swift:28:1:28:37 | a_function(a_parameter:) | ConcreteFuncDecl | declarations.swift:28:36:28:37 | { ... } | BraceStmt | | declarations.swift:30:1:30:18 | var ... = ... | PatternBindingDecl | declarations.swift:30:5:30:5 | a_variable | NamedPattern | @@ -93,7 +93,7 @@ | declarations.swift:31:5:31:5 | a_property | ConcreteVarDecl | declarations.swift:32:3:34:3 | get | AccessorDecl | | declarations.swift:31:5:31:5 | a_property | ConcreteVarDecl | declarations.swift:35:3:35:18 | set | AccessorDecl | | declarations.swift:31:5:31:18 | ... as ... | TypedPattern | declarations.swift:31:5:31:5 | a_property | NamedPattern | -| declarations.swift:31:5:31:18 | ... as ... | TypedPattern | declarations.swift:31:18:31:18 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:31:5:31:18 | ... as ... | TypedPattern | declarations.swift:31:18:31:18 | String | TypeRepr | | declarations.swift:32:3:34:3 | get | AccessorDecl | declarations.swift:32:7:34:3 | { ... } | BraceStmt | | declarations.swift:32:7:34:3 | { ... } | BraceStmt | declarations.swift:33:5:33:12 | return ... | ReturnStmt | | declarations.swift:33:5:33:12 | return ... | ReturnStmt | declarations.swift:33:12:33:12 | here | StringLiteralExpr | @@ -118,7 +118,7 @@ | declarations.swift:41:7:41:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | declarations.swift:41:7:41:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:41:7:41:14 | ... as ... | TypedPattern | declarations.swift:41:7:41:7 | field | NamedPattern | -| declarations.swift:41:7:41:14 | ... as ... | TypedPattern | declarations.swift:41:14:41:14 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:41:7:41:14 | ... as ... | TypedPattern | declarations.swift:41:14:41:14 | Int | TypeRepr | | declarations.swift:42:3:44:3 | init | ConstructorDecl | declarations.swift:42:10:44:3 | { ... } | BraceStmt | | declarations.swift:42:10:44:3 | { ... } | BraceStmt | declarations.swift:43:5:43:13 | ... = ... | AssignExpr | | declarations.swift:42:10:44:3 | { ... } | BraceStmt | declarations.swift:44:3:44:3 | return | ReturnStmt | @@ -139,7 +139,7 @@ | declarations.swift:69:3:73:3 | var ... = ... | PatternBindingDecl | declarations.swift:69:7:69:21 | ... as ... | TypedPattern | | declarations.swift:69:7:69:7 | wrappedValue | ConcreteVarDecl | declarations.swift:70:5:72:5 | get | AccessorDecl | | declarations.swift:69:7:69:21 | ... as ... | TypedPattern | declarations.swift:69:7:69:7 | wrappedValue | NamedPattern | -| declarations.swift:69:7:69:21 | ... as ... | TypedPattern | declarations.swift:69:21:69:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:69:7:69:21 | ... as ... | TypedPattern | declarations.swift:69:21:69:21 | Int | TypeRepr | | declarations.swift:70:5:72:5 | get | AccessorDecl | declarations.swift:70:9:72:5 | { ... } | BraceStmt | | declarations.swift:70:9:72:5 | { ... } | BraceStmt | declarations.swift:71:7:71:14 | return ... | ReturnStmt | | declarations.swift:71:7:71:14 | return ... | ReturnStmt | declarations.swift:71:14:71:14 | 0 | IntegerLiteralExpr | @@ -147,7 +147,7 @@ | declarations.swift:76:19:79:1 | { ... } | BraceStmt | declarations.swift:77:16:77:23 | var ... = ... | PatternBindingDecl | | declarations.swift:76:19:79:1 | { ... } | BraceStmt | declarations.swift:77:20:77:20 | x | ConcreteVarDecl | | declarations.swift:76:19:79:1 | { ... } | BraceStmt | declarations.swift:78:3:78:10 | return ... | ReturnStmt | -| declarations.swift:77:4:77:4 | ZeroWrapper.Type | TypeExpr | declarations.swift:77:4:77:4 | FixedTypeRepr | FixedTypeRepr | +| declarations.swift:77:4:77:4 | ZeroWrapper.Type | TypeExpr | declarations.swift:77:4:77:4 | ZeroWrapper | TypeRepr | | declarations.swift:77:4:77:4 | call to ... | CallExpr | declarations.swift:77:4:77:4 | call to init | ConstructorRefCallExpr | | declarations.swift:77:4:77:4 | call to init | ConstructorRefCallExpr | declarations.swift:77:4:77:4 | init | DeclRefExpr | | declarations.swift:77:16:77:23 | var ... = ... | PatternBindingDecl | declarations.swift:77:20:77:23 | ... as ... | TypedPattern | @@ -156,7 +156,7 @@ | declarations.swift:77:20:77:20 | x | ConcreteVarDecl | declarations.swift:77:20:77:20 | get | AccessorDecl | | declarations.swift:77:20:77:20 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:77:20:77:23 | ... as ... | TypedPattern | declarations.swift:77:20:77:20 | x | NamedPattern | -| declarations.swift:77:20:77:23 | ... as ... | TypedPattern | declarations.swift:77:23:77:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:77:20:77:23 | ... as ... | TypedPattern | declarations.swift:77:23:77:23 | Int | TypeRepr | | declarations.swift:78:3:78:10 | return ... | ReturnStmt | declarations.swift:78:10:78:10 | x | DeclRefExpr | | declarations.swift:81:8:81:8 | init | ConstructorDecl | declarations.swift:81:8:81:8 | hasBoth | ParamDecl | | declarations.swift:81:8:81:8 | init | ConstructorDecl | declarations.swift:81:8:81:8 | hasDidSet1 | ParamDecl | @@ -172,7 +172,7 @@ | declarations.swift:82:7:82:7 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr | | declarations.swift:82:7:82:7 | { ... } | BraceStmt | declarations.swift:82:7:82:7 | yield ... | YieldStmt | | declarations.swift:82:7:82:22 | ... as ... | TypedPattern | declarations.swift:82:7:82:7 | settableField | NamedPattern | -| declarations.swift:82:7:82:22 | ... as ... | TypedPattern | declarations.swift:82:22:82:22 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:82:7:82:22 | ... as ... | TypedPattern | declarations.swift:82:22:82:22 | Int | TypeRepr | | declarations.swift:83:5:83:11 | set | AccessorDecl | declarations.swift:83:5:83:5 | newValue | ParamDecl | | declarations.swift:83:5:83:11 | set | AccessorDecl | declarations.swift:83:9:83:11 | { ... } | BraceStmt | | declarations.swift:84:5:86:5 | get | AccessorDecl | declarations.swift:84:9:86:5 | { ... } | BraceStmt | @@ -181,14 +181,14 @@ | declarations.swift:91:3:93:3 | var ... = ... | PatternBindingDecl | declarations.swift:91:7:91:23 | ... as ... | TypedPattern | | declarations.swift:91:7:91:7 | readOnlyField1 | ConcreteVarDecl | declarations.swift:91:27:93:3 | get | AccessorDecl | | declarations.swift:91:7:91:23 | ... as ... | TypedPattern | declarations.swift:91:7:91:7 | readOnlyField1 | NamedPattern | -| declarations.swift:91:7:91:23 | ... as ... | TypedPattern | declarations.swift:91:23:91:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:91:7:91:23 | ... as ... | TypedPattern | declarations.swift:91:23:91:23 | Int | TypeRepr | | declarations.swift:91:27:93:3 | get | AccessorDecl | declarations.swift:91:27:93:3 | { ... } | BraceStmt | | declarations.swift:91:27:93:3 | { ... } | BraceStmt | declarations.swift:92:5:92:12 | return ... | ReturnStmt | | declarations.swift:92:5:92:12 | return ... | ReturnStmt | declarations.swift:92:12:92:12 | 0 | IntegerLiteralExpr | | declarations.swift:96:3:100:3 | var ... = ... | PatternBindingDecl | declarations.swift:96:7:96:23 | ... as ... | TypedPattern | | declarations.swift:96:7:96:7 | readOnlyField2 | ConcreteVarDecl | declarations.swift:97:5:99:5 | get | AccessorDecl | | declarations.swift:96:7:96:23 | ... as ... | TypedPattern | declarations.swift:96:7:96:7 | readOnlyField2 | NamedPattern | -| declarations.swift:96:7:96:23 | ... as ... | TypedPattern | declarations.swift:96:23:96:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:96:7:96:23 | ... as ... | TypedPattern | declarations.swift:96:23:96:23 | Int | TypeRepr | | declarations.swift:97:5:99:5 | get | AccessorDecl | declarations.swift:97:9:99:5 | { ... } | BraceStmt | | declarations.swift:97:9:99:5 | { ... } | BraceStmt | declarations.swift:98:7:98:14 | return ... | ReturnStmt | | declarations.swift:98:7:98:14 | return ... | ReturnStmt | declarations.swift:98:14:98:14 | 0 | IntegerLiteralExpr | @@ -205,7 +205,7 @@ | declarations.swift:102:7:102:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | declarations.swift:102:7:102:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:102:7:102:21 | ... as ... | TypedPattern | declarations.swift:102:7:102:7 | normalField | NamedPattern | -| declarations.swift:102:7:102:21 | ... as ... | TypedPattern | declarations.swift:102:21:102:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:102:7:102:21 | ... as ... | TypedPattern | declarations.swift:102:21:102:21 | Int | TypeRepr | | declarations.swift:104:3:104:3 | (unnamed function decl) | AccessorDecl | declarations.swift:104:3:104:3 | { ... } | BraceStmt | | declarations.swift:104:3:104:3 | (unnamed function decl) | AccessorDecl | file://:0:0:0:0 | x | ParamDecl | | declarations.swift:104:3:104:3 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr | @@ -244,7 +244,7 @@ | declarations.swift:115:7:115:7 | { ... } | BraceStmt | file://:0:0:0:0 | call to ... | CallExpr | | declarations.swift:115:7:115:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:115:7:115:21 | ... as ... | TypedPattern | declarations.swift:115:7:115:7 | hasWillSet1 | NamedPattern | -| declarations.swift:115:7:115:21 | ... as ... | TypedPattern | declarations.swift:115:21:115:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:115:7:115:21 | ... as ... | TypedPattern | declarations.swift:115:21:115:21 | Int | TypeRepr | | declarations.swift:116:5:116:25 | willSet | AccessorDecl | declarations.swift:116:13:116:13 | newValue | ParamDecl | | declarations.swift:116:5:116:25 | willSet | AccessorDecl | declarations.swift:116:23:116:25 | { ... } | BraceStmt | | declarations.swift:119:3:121:3 | var ... = ... | PatternBindingDecl | declarations.swift:119:7:119:21 | ... as ... | TypedPattern | @@ -262,7 +262,7 @@ | declarations.swift:119:7:119:7 | { ... } | BraceStmt | file://:0:0:0:0 | call to ... | CallExpr | | declarations.swift:119:7:119:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:119:7:119:21 | ... as ... | TypedPattern | declarations.swift:119:7:119:7 | hasWillSet2 | NamedPattern | -| declarations.swift:119:7:119:21 | ... as ... | TypedPattern | declarations.swift:119:21:119:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:119:7:119:21 | ... as ... | TypedPattern | declarations.swift:119:21:119:21 | Int | TypeRepr | | declarations.swift:120:5:120:15 | willSet | AccessorDecl | declarations.swift:120:5:120:5 | newValue | ParamDecl | | declarations.swift:120:5:120:15 | willSet | AccessorDecl | declarations.swift:120:13:120:15 | { ... } | BraceStmt | | declarations.swift:123:3:125:3 | var ... = ... | PatternBindingDecl | declarations.swift:123:7:123:20 | ... as ... | TypedPattern | @@ -282,7 +282,7 @@ | declarations.swift:123:7:123:7 | { ... } | BraceStmt | file://:0:0:0:0 | tmp | ConcreteVarDecl | | declarations.swift:123:7:123:7 | { ... } | BraceStmt | file://:0:0:0:0 | var ... = ... | PatternBindingDecl | | declarations.swift:123:7:123:20 | ... as ... | TypedPattern | declarations.swift:123:7:123:7 | hasDidSet1 | NamedPattern | -| declarations.swift:123:7:123:20 | ... as ... | TypedPattern | declarations.swift:123:20:123:20 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:123:7:123:20 | ... as ... | TypedPattern | declarations.swift:123:20:123:20 | Int | TypeRepr | | declarations.swift:124:5:124:24 | didSet | AccessorDecl | declarations.swift:124:12:124:12 | oldValue | ParamDecl | | declarations.swift:124:5:124:24 | didSet | AccessorDecl | declarations.swift:124:22:124:24 | { ... } | BraceStmt | | declarations.swift:127:3:129:3 | var ... = ... | PatternBindingDecl | declarations.swift:127:7:127:20 | ... as ... | TypedPattern | @@ -301,7 +301,7 @@ | declarations.swift:127:7:127:7 | { ... } | BraceStmt | file://:0:0:0:0 | call to ... | CallExpr | | declarations.swift:127:7:127:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:127:7:127:20 | ... as ... | TypedPattern | declarations.swift:127:7:127:7 | hasDidSet2 | NamedPattern | -| declarations.swift:127:7:127:20 | ... as ... | TypedPattern | declarations.swift:127:20:127:20 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:127:7:127:20 | ... as ... | TypedPattern | declarations.swift:127:20:127:20 | Int | TypeRepr | | declarations.swift:128:5:128:14 | didSet | AccessorDecl | declarations.swift:128:12:128:14 | { ... } | BraceStmt | | declarations.swift:131:3:135:3 | var ... = ... | PatternBindingDecl | declarations.swift:131:7:131:17 | ... as ... | TypedPattern | | declarations.swift:131:7:131:7 | (unnamed function decl) | AccessorDecl | declarations.swift:131:7:131:7 | { ... } | BraceStmt | @@ -320,7 +320,7 @@ | declarations.swift:131:7:131:7 | { ... } | BraceStmt | file://:0:0:0:0 | call to ... | CallExpr | | declarations.swift:131:7:131:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | declarations.swift:131:7:131:17 | ... as ... | TypedPattern | declarations.swift:131:7:131:7 | hasBoth | NamedPattern | -| declarations.swift:131:7:131:17 | ... as ... | TypedPattern | declarations.swift:131:17:131:17 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| declarations.swift:131:7:131:17 | ... as ... | TypedPattern | declarations.swift:131:17:131:17 | Int | TypeRepr | | declarations.swift:132:5:132:15 | willSet | AccessorDecl | declarations.swift:132:5:132:5 | newValue | ParamDecl | | declarations.swift:132:5:132:15 | willSet | AccessorDecl | declarations.swift:132:13:132:15 | { ... } | BraceStmt | | declarations.swift:134:5:134:14 | didSet | AccessorDecl | declarations.swift:134:12:134:14 | { ... } | BraceStmt | @@ -382,7 +382,7 @@ | expressions.swift:8:1:8:15 | { ... } | BraceStmt | expressions.swift:8:1:8:15 | var ... = ... | PatternBindingDecl | | expressions.swift:8:1:8:15 | { ... } | TopLevelCodeDecl | expressions.swift:8:1:8:15 | { ... } | BraceStmt | | expressions.swift:8:5:8:11 | ... as ... | TypedPattern | expressions.swift:8:5:8:5 | n | NamedPattern | -| expressions.swift:8:5:8:11 | ... as ... | TypedPattern | expressions.swift:8:8:8:11 | ...? | OptionalTypeRepr | +| expressions.swift:8:5:8:11 | ... as ... | TypedPattern | expressions.swift:8:8:8:11 | Int? | TypeRepr | | expressions.swift:11:3:11:8 | case ... | EnumCaseDecl | expressions.swift:11:8:11:8 | failed | EnumElementDecl | | expressions.swift:14:1:18:1 | failure(_:) | ConcreteFuncDecl | expressions.swift:14:14:14:19 | x | ParamDecl | | expressions.swift:14:1:18:1 | failure(_:) | ConcreteFuncDecl | expressions.swift:14:31:18:1 | { ... } | BraceStmt | @@ -390,11 +390,11 @@ | expressions.swift:15:3:17:3 | guard ... else { ... } | GuardStmt | expressions.swift:15:9:15:14 | StmtCondition | StmtCondition | | expressions.swift:15:3:17:3 | guard ... else { ... } | GuardStmt | expressions.swift:15:21:17:3 | { ... } | BraceStmt | | expressions.swift:15:9:15:14 | ... call to !=(_:_:) ... | BinaryExpr | expressions.swift:15:11:15:11 | call to !=(_:_:) | DotSyntaxCallExpr | -| expressions.swift:15:11:15:11 | Int.Type | TypeExpr | expressions.swift:15:11:15:11 | FixedTypeRepr | FixedTypeRepr | +| expressions.swift:15:11:15:11 | Int.Type | TypeExpr | expressions.swift:15:11:15:11 | Int | TypeRepr | | expressions.swift:15:11:15:11 | call to !=(_:_:) | DotSyntaxCallExpr | expressions.swift:15:11:15:11 | !=(_:_:) | DeclRefExpr | | expressions.swift:15:21:17:3 | { ... } | BraceStmt | expressions.swift:16:5:16:19 | throw ... | ThrowStmt | | expressions.swift:16:5:16:19 | throw ... | ThrowStmt | expressions.swift:16:11:16:19 | (Error) ... | ErasureExpr | -| expressions.swift:16:11:16:11 | AnError.Type | TypeExpr | expressions.swift:16:11:16:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:16:11:16:11 | AnError.Type | TypeExpr | expressions.swift:16:11:16:11 | AnError | TypeRepr | | expressions.swift:16:11:16:19 | (Error) ... | ErasureExpr | expressions.swift:16:11:16:19 | call to ... | DotSyntaxCallExpr | | expressions.swift:16:11:16:19 | call to ... | DotSyntaxCallExpr | expressions.swift:16:19:16:19 | failed | DeclRefExpr | | expressions.swift:20:1:20:16 | try! ... | ForceTryExpr | expressions.swift:20:6:20:16 | call to failure(_:) | CallExpr | @@ -413,7 +413,7 @@ | expressions.swift:27:1:27:19 | var ... = ... | PatternBindingDecl | expressions.swift:27:13:27:19 | call to ... | CallExpr | | expressions.swift:27:1:27:19 | { ... } | BraceStmt | expressions.swift:27:1:27:19 | var ... = ... | PatternBindingDecl | | expressions.swift:27:1:27:19 | { ... } | TopLevelCodeDecl | expressions.swift:27:1:27:19 | { ... } | BraceStmt | -| expressions.swift:27:13:27:13 | Klass.Type | TypeExpr | expressions.swift:27:13:27:13 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:27:13:27:13 | Klass.Type | TypeExpr | expressions.swift:27:13:27:13 | Klass | TypeRepr | | expressions.swift:27:13:27:13 | call to init | ConstructorRefCallExpr | expressions.swift:27:13:27:13 | init | DeclRefExpr | | expressions.swift:27:13:27:19 | call to ... | CallExpr | expressions.swift:27:13:27:13 | call to init | ConstructorRefCallExpr | | expressions.swift:29:1:29:19 | var ... = ... | PatternBindingDecl | expressions.swift:29:5:29:5 | d | NamedPattern | @@ -467,7 +467,7 @@ | expressions.swift:41:10:43:1 | { ... } | ClosureExpr | expressions.swift:41:21:41:24 | y | ParamDecl | | expressions.swift:42:5:42:16 | return ... | ReturnStmt | expressions.swift:42:12:42:16 | ... call to +(_:_:) ... | BinaryExpr | | expressions.swift:42:12:42:16 | ... call to +(_:_:) ... | BinaryExpr | expressions.swift:42:14:42:14 | call to +(_:_:) | DotSyntaxCallExpr | -| expressions.swift:42:14:42:14 | Int.Type | TypeExpr | expressions.swift:42:14:42:14 | FixedTypeRepr | FixedTypeRepr | +| expressions.swift:42:14:42:14 | Int.Type | TypeExpr | expressions.swift:42:14:42:14 | Int | TypeRepr | | expressions.swift:42:14:42:14 | call to +(_:_:) | DotSyntaxCallExpr | expressions.swift:42:14:42:14 | +(_:_:) | DeclRefExpr | | expressions.swift:44:1:46:1 | call to closured(closure:) | CallExpr | expressions.swift:44:1:44:1 | closured(closure:) | DeclRefExpr | | expressions.swift:44:1:46:1 | { ... } | BraceStmt | expressions.swift:44:1:46:1 | call to closured(closure:) | CallExpr | @@ -478,7 +478,7 @@ | expressions.swift:44:10:46:1 | { ... } | ClosureExpr | expressions.swift:44:15:44:15 | y | ParamDecl | | expressions.swift:45:5:45:16 | return ... | ReturnStmt | expressions.swift:45:12:45:16 | ... call to +(_:_:) ... | BinaryExpr | | expressions.swift:45:12:45:16 | ... call to +(_:_:) ... | BinaryExpr | expressions.swift:45:14:45:14 | call to +(_:_:) | DotSyntaxCallExpr | -| expressions.swift:45:14:45:14 | Int.Type | TypeExpr | expressions.swift:45:14:45:14 | FixedTypeRepr | FixedTypeRepr | +| expressions.swift:45:14:45:14 | Int.Type | TypeExpr | expressions.swift:45:14:45:14 | Int | TypeRepr | | expressions.swift:45:14:45:14 | call to +(_:_:) | DotSyntaxCallExpr | expressions.swift:45:14:45:14 | +(_:_:) | DeclRefExpr | | expressions.swift:47:1:47:27 | call to closured(closure:) | CallExpr | expressions.swift:47:1:47:1 | closured(closure:) | DeclRefExpr | | expressions.swift:47:1:47:27 | { ... } | BraceStmt | expressions.swift:47:1:47:27 | call to closured(closure:) | CallExpr | @@ -489,7 +489,7 @@ | expressions.swift:47:10:47:27 | { ... } | ClosureExpr | expressions.swift:47:10:47:27 | { ... } | BraceStmt | | expressions.swift:47:12:47:24 | return ... | ReturnStmt | expressions.swift:47:19:47:24 | ... call to +(_:_:) ... | BinaryExpr | | expressions.swift:47:19:47:24 | ... call to +(_:_:) ... | BinaryExpr | expressions.swift:47:22:47:22 | call to +(_:_:) | DotSyntaxCallExpr | -| expressions.swift:47:22:47:22 | Int.Type | TypeExpr | expressions.swift:47:22:47:22 | FixedTypeRepr | FixedTypeRepr | +| expressions.swift:47:22:47:22 | Int.Type | TypeExpr | expressions.swift:47:22:47:22 | Int | TypeRepr | | expressions.swift:47:22:47:22 | call to +(_:_:) | DotSyntaxCallExpr | expressions.swift:47:22:47:22 | +(_:_:) | DeclRefExpr | | expressions.swift:48:1:48:20 | call to closured(closure:) | CallExpr | expressions.swift:48:1:48:1 | closured(closure:) | DeclRefExpr | | expressions.swift:48:1:48:20 | { ... } | BraceStmt | expressions.swift:48:1:48:20 | call to closured(closure:) | CallExpr | @@ -500,7 +500,7 @@ | expressions.swift:48:10:48:20 | { ... } | ClosureExpr | expressions.swift:48:10:48:20 | { ... } | BraceStmt | | expressions.swift:48:12:48:17 | ... call to +(_:_:) ... | BinaryExpr | expressions.swift:48:15:48:15 | call to +(_:_:) | DotSyntaxCallExpr | | expressions.swift:48:12:48:17 | return ... | ReturnStmt | expressions.swift:48:12:48:17 | ... call to +(_:_:) ... | BinaryExpr | -| expressions.swift:48:15:48:15 | Int.Type | TypeExpr | expressions.swift:48:15:48:15 | FixedTypeRepr | FixedTypeRepr | +| expressions.swift:48:15:48:15 | Int.Type | TypeExpr | expressions.swift:48:15:48:15 | Int | TypeRepr | | expressions.swift:48:15:48:15 | call to +(_:_:) | DotSyntaxCallExpr | expressions.swift:48:15:48:15 | +(_:_:) | DeclRefExpr | | expressions.swift:50:8:50:8 | init | ConstructorDecl | expressions.swift:50:8:50:8 | x | ParamDecl | | expressions.swift:51:3:51:10 | var ... = ... | PatternBindingDecl | expressions.swift:51:7:51:10 | ... as ... | TypedPattern | @@ -508,14 +508,12 @@ | expressions.swift:51:7:51:7 | x | ConcreteVarDecl | expressions.swift:51:7:51:7 | get | AccessorDecl | | expressions.swift:51:7:51:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:51:7:51:10 | ... as ... | TypedPattern | expressions.swift:51:7:51:7 | x | NamedPattern | -| expressions.swift:51:7:51:10 | ... as ... | TypedPattern | expressions.swift:51:10:51:10 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:51:7:51:10 | ... as ... | TypedPattern | expressions.swift:51:10:51:10 | Int | TypeRepr | | expressions.swift:54:1:54:8 | ... = ... | AssignExpr | expressions.swift:54:1:54:1 | _ | DiscardAssignmentExpr | | expressions.swift:54:1:54:8 | ... = ... | AssignExpr | expressions.swift:54:5:54:8 | #keyPath(...) | KeyPathExpr | | expressions.swift:54:1:54:8 | { ... } | BraceStmt | expressions.swift:54:1:54:8 | ... = ... | AssignExpr | | expressions.swift:54:1:54:8 | { ... } | TopLevelCodeDecl | expressions.swift:54:1:54:8 | { ... } | BraceStmt | -| expressions.swift:54:5:54:8 | #keyPath(...) | KeyPathExpr | expressions.swift:54:6:54:8 | ... .x | UnresolvedDotExpr | -| expressions.swift:54:6:54:6 | (no string representation) | TypeExpr | expressions.swift:54:6:54:6 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | -| expressions.swift:54:6:54:8 | ... .x | UnresolvedDotExpr | expressions.swift:54:6:54:6 | (no string representation) | TypeExpr | +| expressions.swift:54:5:54:8 | #keyPath(...) | KeyPathExpr | expressions.swift:54:6:54:6 | S | TypeRepr | | expressions.swift:56:1:57:1 | unsafeFunction(pointer:) | ConcreteFuncDecl | expressions.swift:56:21:56:47 | pointer | ParamDecl | | expressions.swift:56:1:57:1 | unsafeFunction(pointer:) | ConcreteFuncDecl | expressions.swift:56:50:57:1 | { ... } | BraceStmt | | expressions.swift:58:1:58:16 | var ... = ... | PatternBindingDecl | expressions.swift:58:5:58:5 | myNumber | NamedPattern | @@ -545,7 +543,7 @@ | expressions.swift:64:5:66:5 | if ... then { ... } | IfStmt | expressions.swift:64:8:64:12 | StmtCondition | StmtCondition | | expressions.swift:64:5:66:5 | if ... then { ... } | IfStmt | expressions.swift:64:14:66:5 | { ... } | BraceStmt | | expressions.swift:64:8:64:12 | ... call to <(_:_:) ... | BinaryExpr | expressions.swift:64:10:64:10 | call to <(_:_:) | DotSyntaxCallExpr | -| expressions.swift:64:10:64:10 | Int.Type | TypeExpr | expressions.swift:64:10:64:10 | FixedTypeRepr | FixedTypeRepr | +| expressions.swift:64:10:64:10 | Int.Type | TypeExpr | expressions.swift:64:10:64:10 | Int | TypeRepr | | expressions.swift:64:10:64:10 | call to <(_:_:) | DotSyntaxCallExpr | expressions.swift:64:10:64:10 | <(_:_:) | DeclRefExpr | | expressions.swift:64:14:66:5 | { ... } | BraceStmt | expressions.swift:65:7:65:14 | fail | FailStmt | | expressions.swift:70:7:70:7 | deinit | DestructorDecl | expressions.swift:70:7:70:7 | { ... } | BraceStmt | @@ -554,7 +552,7 @@ | expressions.swift:71:7:71:7 | xx | ConcreteVarDecl | expressions.swift:71:7:71:7 | get | AccessorDecl | | expressions.swift:71:7:71:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:71:7:71:11 | ... as ... | TypedPattern | expressions.swift:71:7:71:7 | xx | NamedPattern | -| expressions.swift:71:7:71:11 | ... as ... | TypedPattern | expressions.swift:71:11:71:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:71:7:71:11 | ... as ... | TypedPattern | expressions.swift:71:11:71:11 | Int | TypeRepr | | expressions.swift:72:3:74:3 | init | ConstructorDecl | expressions.swift:72:8:72:11 | x | ParamDecl | | expressions.swift:72:3:74:3 | init | ConstructorDecl | expressions.swift:72:16:74:3 | { ... } | BraceStmt | | expressions.swift:72:16:74:3 | { ... } | BraceStmt | expressions.swift:73:5:73:10 | ... = ... | AssignExpr | @@ -577,7 +575,7 @@ | expressions.swift:83:1:83:23 | var ... = ... | PatternBindingDecl | expressions.swift:83:15:83:23 | call to ... | CallExpr | | expressions.swift:83:1:83:23 | { ... } | BraceStmt | expressions.swift:83:1:83:23 | var ... = ... | PatternBindingDecl | | expressions.swift:83:1:83:23 | { ... } | TopLevelCodeDecl | expressions.swift:83:1:83:23 | { ... } | BraceStmt | -| expressions.swift:83:15:83:15 | Derived.Type | TypeExpr | expressions.swift:83:15:83:15 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:83:15:83:15 | Derived.Type | TypeExpr | expressions.swift:83:15:83:15 | Derived | TypeRepr | | expressions.swift:83:15:83:15 | call to init | ConstructorRefCallExpr | expressions.swift:83:15:83:15 | init | DeclRefExpr | | expressions.swift:83:15:83:23 | call to ... | CallExpr | expressions.swift:83:15:83:15 | call to init | ConstructorRefCallExpr | | expressions.swift:84:1:84:13 | ... = ... | AssignExpr | expressions.swift:84:1:84:1 | _ | DiscardAssignmentExpr | @@ -591,7 +589,7 @@ | expressions.swift:86:1:86:13 | { ... } | BraceStmt | expressions.swift:86:1:86:13 | var ... = ... | PatternBindingDecl | | expressions.swift:86:1:86:13 | { ... } | TopLevelCodeDecl | expressions.swift:86:1:86:13 | { ... } | BraceStmt | | expressions.swift:86:5:86:13 | ... as ... | TypedPattern | expressions.swift:86:5:86:5 | opt | NamedPattern | -| expressions.swift:86:5:86:13 | ... as ... | TypedPattern | expressions.swift:86:10:86:13 | ...? | OptionalTypeRepr | +| expressions.swift:86:5:86:13 | ... as ... | TypedPattern | expressions.swift:86:10:86:13 | Int? | TypeRepr | | expressions.swift:87:1:87:4 | ...! | ForceValueExpr | expressions.swift:87:1:87:1 | opt | DeclRefExpr | | expressions.swift:87:1:87:4 | { ... } | BraceStmt | expressions.swift:87:1:87:4 | ...! | ForceValueExpr | | expressions.swift:87:1:87:4 | { ... } | TopLevelCodeDecl | expressions.swift:87:1:87:4 | { ... } | BraceStmt | @@ -606,15 +604,15 @@ | expressions.swift:92:1:92:55 | var ... = ... | PatternBindingDecl | expressions.swift:92:14:92:55 | call to ... | CallExpr | | expressions.swift:92:1:92:55 | { ... } | BraceStmt | expressions.swift:92:1:92:55 | var ... = ... | PatternBindingDecl | | expressions.swift:92:1:92:55 | { ... } | TopLevelCodeDecl | expressions.swift:92:1:92:55 | { ... } | BraceStmt | -| expressions.swift:92:14:92:14 | Unmanaged.Type | TypeExpr | expressions.swift:92:14:92:14 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:92:14:92:14 | Unmanaged.Type | TypeExpr | expressions.swift:92:14:92:14 | Unmanaged | TypeRepr | | expressions.swift:92:14:92:24 | call to passRetained(_:) | DotSyntaxCallExpr | expressions.swift:92:24:92:24 | passRetained(_:) | DeclRefExpr | | expressions.swift:92:14:92:44 | call to ... | CallExpr | expressions.swift:92:14:92:24 | call to passRetained(_:) | DotSyntaxCallExpr | | expressions.swift:92:14:92:46 | call to toOpaque() | DotSyntaxCallExpr | expressions.swift:92:46:92:46 | toOpaque() | DeclRefExpr | | expressions.swift:92:14:92:55 | call to ... | CallExpr | expressions.swift:92:14:92:46 | call to toOpaque() | DotSyntaxCallExpr | -| expressions.swift:92:37:92:37 | ToPtr.Type | TypeExpr | expressions.swift:92:37:92:37 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:92:37:92:37 | ToPtr.Type | TypeExpr | expressions.swift:92:37:92:37 | ToPtr | TypeRepr | | expressions.swift:92:37:92:37 | call to init | ConstructorRefCallExpr | expressions.swift:92:37:92:37 | init | DeclRefExpr | | expressions.swift:92:37:92:43 | call to ... | CallExpr | expressions.swift:92:37:92:37 | call to init | ConstructorRefCallExpr | -| expressions.swift:93:1:93:16 | Unmanaged.Type | TypeExpr | expressions.swift:93:1:93:16 | ...<...> | GenericIdentTypeRepr | +| expressions.swift:93:1:93:16 | Unmanaged.Type | TypeExpr | expressions.swift:93:1:93:16 | Unmanaged | TypeRepr | | expressions.swift:93:1:93:18 | call to fromOpaque(_:) | DotSyntaxCallExpr | expressions.swift:93:18:93:18 | fromOpaque(_:) | DeclRefExpr | | expressions.swift:93:1:93:35 | call to ... | CallExpr | expressions.swift:93:1:93:18 | call to fromOpaque(_:) | DotSyntaxCallExpr | | expressions.swift:93:1:93:35 | { ... } | BraceStmt | expressions.swift:93:1:93:35 | call to ... | CallExpr | @@ -629,7 +627,7 @@ | expressions.swift:96:7:96:7 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr | | expressions.swift:96:7:96:7 | { ... } | BraceStmt | expressions.swift:96:7:96:7 | yield ... | YieldStmt | | expressions.swift:96:7:96:22 | ... as ... | TypedPattern | expressions.swift:96:7:96:7 | settableField | NamedPattern | -| expressions.swift:96:7:96:22 | ... as ... | TypedPattern | expressions.swift:96:22:96:22 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:96:7:96:22 | ... as ... | TypedPattern | expressions.swift:96:22:96:22 | Int | TypeRepr | | expressions.swift:97:5:97:11 | set | AccessorDecl | expressions.swift:97:5:97:5 | newValue | ParamDecl | | expressions.swift:97:5:97:11 | set | AccessorDecl | expressions.swift:97:9:97:11 | { ... } | BraceStmt | | expressions.swift:98:5:100:5 | get | AccessorDecl | expressions.swift:98:9:100:5 | { ... } | BraceStmt | @@ -638,14 +636,14 @@ | expressions.swift:105:3:107:3 | var ... = ... | PatternBindingDecl | expressions.swift:105:7:105:23 | ... as ... | TypedPattern | | expressions.swift:105:7:105:7 | readOnlyField1 | ConcreteVarDecl | expressions.swift:105:27:107:3 | get | AccessorDecl | | expressions.swift:105:7:105:23 | ... as ... | TypedPattern | expressions.swift:105:7:105:7 | readOnlyField1 | NamedPattern | -| expressions.swift:105:7:105:23 | ... as ... | TypedPattern | expressions.swift:105:23:105:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:105:7:105:23 | ... as ... | TypedPattern | expressions.swift:105:23:105:23 | Int | TypeRepr | | expressions.swift:105:27:107:3 | get | AccessorDecl | expressions.swift:105:27:107:3 | { ... } | BraceStmt | | expressions.swift:105:27:107:3 | { ... } | BraceStmt | expressions.swift:106:5:106:12 | return ... | ReturnStmt | | expressions.swift:106:5:106:12 | return ... | ReturnStmt | expressions.swift:106:12:106:12 | 0 | IntegerLiteralExpr | | expressions.swift:110:3:114:3 | var ... = ... | PatternBindingDecl | expressions.swift:110:7:110:23 | ... as ... | TypedPattern | | expressions.swift:110:7:110:7 | readOnlyField2 | ConcreteVarDecl | expressions.swift:111:5:113:5 | get | AccessorDecl | | expressions.swift:110:7:110:23 | ... as ... | TypedPattern | expressions.swift:110:7:110:7 | readOnlyField2 | NamedPattern | -| expressions.swift:110:7:110:23 | ... as ... | TypedPattern | expressions.swift:110:23:110:23 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:110:7:110:23 | ... as ... | TypedPattern | expressions.swift:110:23:110:23 | Int | TypeRepr | | expressions.swift:111:5:113:5 | get | AccessorDecl | expressions.swift:111:9:113:5 | { ... } | BraceStmt | | expressions.swift:111:9:113:5 | { ... } | BraceStmt | expressions.swift:112:7:112:14 | return ... | ReturnStmt | | expressions.swift:112:7:112:14 | return ... | ReturnStmt | expressions.swift:112:14:112:14 | 0 | IntegerLiteralExpr | @@ -662,7 +660,7 @@ | expressions.swift:116:7:116:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | expressions.swift:116:7:116:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:116:7:116:21 | ... as ... | TypedPattern | expressions.swift:116:7:116:7 | normalField | NamedPattern | -| expressions.swift:116:7:116:21 | ... as ... | TypedPattern | expressions.swift:116:21:116:21 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:116:7:116:21 | ... as ... | TypedPattern | expressions.swift:116:21:116:21 | Int | TypeRepr | | expressions.swift:118:3:118:3 | (unnamed function decl) | AccessorDecl | expressions.swift:118:3:118:3 | { ... } | BraceStmt | | expressions.swift:118:3:118:3 | (unnamed function decl) | AccessorDecl | file://:0:0:0:0 | x | ParamDecl | | expressions.swift:118:3:118:3 | yield ... | YieldStmt | file://:0:0:0:0 | &... | InOutExpr | @@ -743,7 +741,7 @@ | expressions.swift:142:7:142:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | expressions.swift:142:7:142:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:142:7:142:11 | ... as ... | TypedPattern | expressions.swift:142:7:142:7 | x | NamedPattern | -| expressions.swift:142:7:142:11 | ... as ... | TypedPattern | expressions.swift:142:11:142:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:142:7:142:11 | ... as ... | TypedPattern | expressions.swift:142:11:142:11 | Int | TypeRepr | | expressions.swift:145:8:145:8 | init | ConstructorDecl | expressions.swift:145:8:145:8 | b | ParamDecl | | expressions.swift:145:8:145:8 | init | ConstructorDecl | expressions.swift:145:8:145:8 | bs | ParamDecl | | expressions.swift:145:8:145:8 | init | ConstructorDecl | expressions.swift:145:8:145:8 | mayB | ParamDecl | @@ -760,7 +758,7 @@ | expressions.swift:146:7:146:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | expressions.swift:146:7:146:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:146:7:146:11 | ... as ... | TypedPattern | expressions.swift:146:7:146:7 | b | NamedPattern | -| expressions.swift:146:7:146:11 | ... as ... | TypedPattern | expressions.swift:146:11:146:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| expressions.swift:146:7:146:11 | ... as ... | TypedPattern | expressions.swift:146:11:146:11 | B | TypeRepr | | expressions.swift:147:3:147:14 | var ... = ... | PatternBindingDecl | expressions.swift:147:7:147:14 | ... as ... | TypedPattern | | expressions.swift:147:7:147:7 | (unnamed function decl) | AccessorDecl | expressions.swift:147:7:147:7 | { ... } | BraceStmt | | expressions.swift:147:7:147:7 | bs | ConcreteVarDecl | expressions.swift:147:7:147:7 | (unnamed function decl) | AccessorDecl | @@ -774,7 +772,7 @@ | expressions.swift:147:7:147:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | expressions.swift:147:7:147:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:147:7:147:14 | ... as ... | TypedPattern | expressions.swift:147:7:147:7 | bs | NamedPattern | -| expressions.swift:147:7:147:14 | ... as ... | TypedPattern | expressions.swift:147:12:147:14 | [...] | ArrayTypeRepr | +| expressions.swift:147:7:147:14 | ... as ... | TypedPattern | expressions.swift:147:12:147:14 | [B] | TypeRepr | | expressions.swift:148:3:148:15 | var ... = ... | PatternBindingDecl | expressions.swift:148:7:148:15 | ... as ... | TypedPattern | | expressions.swift:148:3:148:15 | var ... = ... | PatternBindingDecl | file://:0:0:0:0 | nil | NilLiteralExpr | | expressions.swift:148:7:148:7 | (unnamed function decl) | AccessorDecl | expressions.swift:148:7:148:7 | { ... } | BraceStmt | @@ -789,7 +787,7 @@ | expressions.swift:148:7:148:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | expressions.swift:148:7:148:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | expressions.swift:148:7:148:15 | ... as ... | TypedPattern | expressions.swift:148:7:148:7 | mayB | NamedPattern | -| expressions.swift:148:7:148:15 | ... as ... | TypedPattern | expressions.swift:148:14:148:15 | ...? | OptionalTypeRepr | +| expressions.swift:148:7:148:15 | ... as ... | TypedPattern | expressions.swift:148:14:148:15 | B? | TypeRepr | | expressions.swift:151:1:155:1 | test(a:keyPathInt:keyPathB:) | ConcreteFuncDecl | expressions.swift:151:11:151:15 | a | ParamDecl | | expressions.swift:151:1:155:1 | test(a:keyPathInt:keyPathB:) | ConcreteFuncDecl | expressions.swift:151:18:151:53 | keyPathInt | ParamDecl | | expressions.swift:151:1:155:1 | test(a:keyPathInt:keyPathB:) | ConcreteFuncDecl | expressions.swift:151:56:151:87 | keyPathB | ParamDecl | @@ -814,9 +812,7 @@ | expressions.swift:154:22:154:41 | \\...[...] | KeyPathApplicationExpr | expressions.swift:154:33:154:33 | keyPathB | DeclRefExpr | | expressions.swift:154:22:154:56 | \\...[...] | KeyPathApplicationExpr | expressions.swift:154:22:154:41 | \\...[...] | KeyPathApplicationExpr | | expressions.swift:154:22:154:56 | \\...[...] | KeyPathApplicationExpr | expressions.swift:154:52:154:55 | #keyPath(...) | KeyPathExpr | -| expressions.swift:154:52:154:55 | #keyPath(...) | KeyPathExpr | expressions.swift:154:53:154:55 | ... .x | UnresolvedDotExpr | -| expressions.swift:154:53:154:53 | (no string representation) | TypeExpr | expressions.swift:154:53:154:53 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | -| expressions.swift:154:53:154:55 | ... .x | UnresolvedDotExpr | expressions.swift:154:53:154:53 | (no string representation) | TypeExpr | +| expressions.swift:154:52:154:55 | #keyPath(...) | KeyPathExpr | expressions.swift:154:53:154:53 | B | TypeRepr | | patterns.swift:1:1:7:1 | basic_patterns() | ConcreteFuncDecl | patterns.swift:1:23:7:1 | { ... } | BraceStmt | | patterns.swift:1:23:7:1 | { ... } | BraceStmt | patterns.swift:2:5:2:18 | var ... = ... | PatternBindingDecl | | patterns.swift:1:23:7:1 | { ... } | BraceStmt | patterns.swift:2:9:2:9 | an_int | ConcreteVarDecl | @@ -833,7 +829,7 @@ | patterns.swift:3:5:3:28 | var ... = ... | PatternBindingDecl | patterns.swift:3:9:3:19 | ... as ... | TypedPattern | | patterns.swift:3:5:3:28 | var ... = ... | PatternBindingDecl | patterns.swift:3:28:3:28 | here | StringLiteralExpr | | patterns.swift:3:9:3:19 | ... as ... | TypedPattern | patterns.swift:3:9:3:9 | a_string | NamedPattern | -| patterns.swift:3:9:3:19 | ... as ... | TypedPattern | patterns.swift:3:19:3:19 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| patterns.swift:3:9:3:19 | ... as ... | TypedPattern | patterns.swift:3:19:3:19 | String | TypeRepr | | patterns.swift:4:5:4:29 | var ... = ... | PatternBindingDecl | patterns.swift:4:9:4:17 | (...) | TuplePattern | | patterns.swift:4:5:4:29 | var ... = ... | PatternBindingDecl | patterns.swift:4:21:4:29 | (...) | TupleExpr | | patterns.swift:4:9:4:17 | (...) | TuplePattern | patterns.swift:4:10:4:10 | x | NamedPattern | @@ -900,8 +896,8 @@ | patterns.swift:24:5:24:19 | var ... = ... | PatternBindingDecl | patterns.swift:24:9:24:12 | ... as ... | TypedPattern | | patterns.swift:24:5:24:19 | var ... = ... | PatternBindingDecl | patterns.swift:24:18:24:19 | call to ... | DotSyntaxCallExpr | | patterns.swift:24:9:24:12 | ... as ... | TypedPattern | patterns.swift:24:9:24:9 | v | NamedPattern | -| patterns.swift:24:9:24:12 | ... as ... | TypedPattern | patterns.swift:24:12:24:12 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | -| patterns.swift:24:18:24:18 | Foo.Type | TypeExpr | patterns.swift:24:18:24:18 | FixedTypeRepr | FixedTypeRepr | +| patterns.swift:24:9:24:12 | ... as ... | TypedPattern | patterns.swift:24:12:24:12 | Foo | TypeRepr | +| patterns.swift:24:18:24:18 | Foo.Type | TypeExpr | patterns.swift:24:18:24:18 | Foo | TypeRepr | | patterns.swift:24:18:24:19 | call to ... | DotSyntaxCallExpr | patterns.swift:24:19:24:19 | bar | DeclRefExpr | | patterns.swift:26:5:29:5 | switch v { ... } | SwitchStmt | patterns.swift:26:12:26:12 | v | DeclRefExpr | | patterns.swift:26:5:29:5 | switch v { ... } | SwitchStmt | patterns.swift:27:5:27:16 | case ... | CaseStmt | @@ -921,7 +917,7 @@ | patterns.swift:31:5:31:19 | var ... = ... | PatternBindingDecl | patterns.swift:31:9:31:15 | ... as ... | TypedPattern | | patterns.swift:31:5:31:19 | var ... = ... | PatternBindingDecl | patterns.swift:31:19:31:19 | nil | NilLiteralExpr | | patterns.swift:31:9:31:15 | ... as ... | TypedPattern | patterns.swift:31:9:31:9 | w | NamedPattern | -| patterns.swift:31:9:31:15 | ... as ... | TypedPattern | patterns.swift:31:12:31:15 | ...? | OptionalTypeRepr | +| patterns.swift:31:9:31:15 | ... as ... | TypedPattern | patterns.swift:31:12:31:15 | Int? | TypeRepr | | patterns.swift:33:5:36:5 | switch w { ... } | SwitchStmt | patterns.swift:33:12:33:12 | w | DeclRefExpr | | patterns.swift:33:5:36:5 | switch w { ... } | SwitchStmt | patterns.swift:34:5:34:18 | case ... | CaseStmt | | patterns.swift:33:5:36:5 | switch w { ... } | SwitchStmt | patterns.swift:35:5:35:13 | case ... | CaseStmt | @@ -938,7 +934,7 @@ | patterns.swift:38:5:38:18 | var ... = ... | PatternBindingDecl | patterns.swift:38:9:38:12 | ... as ... | TypedPattern | | patterns.swift:38:5:38:18 | var ... = ... | PatternBindingDecl | patterns.swift:38:18:38:18 | (Any) ... | ErasureExpr | | patterns.swift:38:9:38:12 | ... as ... | TypedPattern | patterns.swift:38:9:38:9 | a | NamedPattern | -| patterns.swift:38:9:38:12 | ... as ... | TypedPattern | patterns.swift:38:12:38:12 | CompositionTypeRepr | CompositionTypeRepr | +| patterns.swift:38:9:38:12 | ... as ... | TypedPattern | patterns.swift:38:12:38:12 | Any | TypeRepr | | patterns.swift:38:18:38:18 | (Any) ... | ErasureExpr | patterns.swift:38:18:38:18 | any | StringLiteralExpr | | patterns.swift:40:5:44:5 | switch a { ... } | SwitchStmt | patterns.swift:40:12:40:12 | a | DeclRefExpr | | patterns.swift:40:5:44:5 | switch a { ... } | SwitchStmt | patterns.swift:41:5:41:18 | case ... | CaseStmt | @@ -947,14 +943,14 @@ | patterns.swift:41:5:41:18 | case ... | CaseStmt | patterns.swift:41:10:41:13 | ... is ... | CaseLabelItem | | patterns.swift:41:5:41:18 | case ... | CaseStmt | patterns.swift:41:18:41:18 | { ... } | BraceStmt | | patterns.swift:41:10:41:13 | ... is ... | CaseLabelItem | patterns.swift:41:10:41:13 | ... is ... | IsPattern | -| patterns.swift:41:10:41:13 | ... is ... | IsPattern | patterns.swift:41:13:41:13 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| patterns.swift:41:10:41:13 | ... is ... | IsPattern | patterns.swift:41:13:41:13 | Int | TypeRepr | | patterns.swift:41:18:41:18 | { ... } | BraceStmt | patterns.swift:41:18:41:18 | is pattern | StringLiteralExpr | | patterns.swift:42:5:42:27 | case ... | CaseStmt | patterns.swift:42:10:42:19 | let ... | CaseLabelItem | | patterns.swift:42:5:42:27 | case ... | CaseStmt | patterns.swift:42:27:42:27 | { ... } | BraceStmt | | patterns.swift:42:10:42:19 | let ... | BindingPattern | patterns.swift:42:14:42:19 | ... is ... | IsPattern | | patterns.swift:42:10:42:19 | let ... | CaseLabelItem | patterns.swift:42:10:42:19 | let ... | BindingPattern | | patterns.swift:42:14:42:19 | ... is ... | IsPattern | patterns.swift:42:14:42:14 | x | NamedPattern | -| patterns.swift:42:14:42:19 | ... is ... | IsPattern | patterns.swift:42:19:42:19 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| patterns.swift:42:14:42:19 | ... is ... | IsPattern | patterns.swift:42:19:42:19 | String | TypeRepr | | patterns.swift:42:27:42:27 | { ... } | BraceStmt | patterns.swift:42:27:42:27 | as pattern | StringLiteralExpr | | patterns.swift:43:5:43:13 | case ... | CaseStmt | patterns.swift:43:10:43:10 | _ | CaseLabelItem | | patterns.swift:43:5:43:13 | case ... | CaseStmt | patterns.swift:43:13:43:13 | { ... } | BraceStmt | @@ -986,14 +982,14 @@ | statements.swift:2:3:8:3 | for ... in ... { ... } | ForEachStmt | statements.swift:2:20:2:24 | ... call to ...(_:_:) ... | BinaryExpr | | statements.swift:2:3:8:3 | for ... in ... { ... } | ForEachStmt | statements.swift:2:26:8:3 | { ... } | BraceStmt | | statements.swift:2:20:2:24 | ... call to ...(_:_:) ... | BinaryExpr | statements.swift:2:21:2:21 | call to ...(_:_:) | DotSyntaxCallExpr | -| statements.swift:2:21:2:21 | Int.Type | TypeExpr | statements.swift:2:21:2:21 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:2:21:2:21 | Int.Type | TypeExpr | statements.swift:2:21:2:21 | Int | TypeRepr | | statements.swift:2:21:2:21 | call to ...(_:_:) | DotSyntaxCallExpr | statements.swift:2:21:2:21 | ...(_:_:) | DeclRefExpr | | statements.swift:2:26:8:3 | { ... } | BraceStmt | statements.swift:3:5:7:5 | if ... then { ... } else { ... } | IfStmt | | statements.swift:3:5:7:5 | if ... then { ... } else { ... } | IfStmt | statements.swift:3:8:3:13 | StmtCondition | StmtCondition | | statements.swift:3:5:7:5 | if ... then { ... } else { ... } | IfStmt | statements.swift:3:15:5:5 | { ... } | BraceStmt | | statements.swift:3:5:7:5 | if ... then { ... } else { ... } | IfStmt | statements.swift:5:12:7:5 | { ... } | BraceStmt | | statements.swift:3:8:3:13 | ... call to ==(_:_:) ... | BinaryExpr | statements.swift:3:10:3:10 | call to ==(_:_:) | DotSyntaxCallExpr | -| statements.swift:3:10:3:10 | Int.Type | TypeExpr | statements.swift:3:10:3:10 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:3:10:3:10 | Int.Type | TypeExpr | statements.swift:3:10:3:10 | Int | TypeRepr | | statements.swift:3:10:3:10 | call to ==(_:_:) | DotSyntaxCallExpr | statements.swift:3:10:3:10 | ==(_:_:) | DeclRefExpr | | statements.swift:3:15:5:5 | { ... } | BraceStmt | statements.swift:4:9:4:9 | break | BreakStmt | | statements.swift:5:12:7:5 | { ... } | BraceStmt | statements.swift:6:9:6:9 | continue | ContinueStmt | @@ -1004,14 +1000,14 @@ | statements.swift:10:17:10:24 | (...) | ParenExpr | statements.swift:10:18:10:22 | ... call to <(_:_:) ... | BinaryExpr | | statements.swift:10:18:10:18 | (Int) ... | LoadExpr | statements.swift:10:18:10:18 | i | DeclRefExpr | | statements.swift:10:18:10:22 | ... call to <(_:_:) ... | BinaryExpr | statements.swift:10:20:10:20 | call to <(_:_:) | DotSyntaxCallExpr | -| statements.swift:10:20:10:20 | Int.Type | TypeExpr | statements.swift:10:20:10:20 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:10:20:10:20 | Int.Type | TypeExpr | statements.swift:10:20:10:20 | Int | TypeRepr | | statements.swift:10:20:10:20 | call to <(_:_:) | DotSyntaxCallExpr | statements.swift:10:20:10:20 | <(_:_:) | DeclRefExpr | | statements.swift:10:26:12:3 | { ... } | BraceStmt | statements.swift:11:5:11:13 | ... = ... | AssignExpr | | statements.swift:11:5:11:13 | ... = ... | AssignExpr | statements.swift:11:5:11:5 | i | DeclRefExpr | | statements.swift:11:5:11:13 | ... = ... | AssignExpr | statements.swift:11:9:11:13 | ... call to +(_:_:) ... | BinaryExpr | | statements.swift:11:9:11:9 | (Int) ... | LoadExpr | statements.swift:11:9:11:9 | i | DeclRefExpr | | statements.swift:11:9:11:13 | ... call to +(_:_:) ... | BinaryExpr | statements.swift:11:11:11:11 | call to +(_:_:) | DotSyntaxCallExpr | -| statements.swift:11:11:11:11 | Int.Type | TypeExpr | statements.swift:11:11:11:11 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:11:11:11:11 | Int.Type | TypeExpr | statements.swift:11:11:11:11 | Int | TypeRepr | | statements.swift:11:11:11:11 | call to +(_:_:) | DotSyntaxCallExpr | statements.swift:11:11:11:11 | +(_:_:) | DeclRefExpr | | statements.swift:14:3:14:7 | ... = ... | AssignExpr | statements.swift:14:3:14:3 | i | DeclRefExpr | | statements.swift:14:3:14:7 | ... = ... | AssignExpr | statements.swift:14:7:14:7 | 0 | IntegerLiteralExpr | @@ -1022,12 +1018,12 @@ | statements.swift:16:5:16:13 | ... = ... | AssignExpr | statements.swift:16:9:16:13 | ... call to +(_:_:) ... | BinaryExpr | | statements.swift:16:9:16:9 | (Int) ... | LoadExpr | statements.swift:16:9:16:9 | i | DeclRefExpr | | statements.swift:16:9:16:13 | ... call to +(_:_:) ... | BinaryExpr | statements.swift:16:11:16:11 | call to +(_:_:) | DotSyntaxCallExpr | -| statements.swift:16:11:16:11 | Int.Type | TypeExpr | statements.swift:16:11:16:11 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:16:11:16:11 | Int.Type | TypeExpr | statements.swift:16:11:16:11 | Int | TypeRepr | | statements.swift:16:11:16:11 | call to +(_:_:) | DotSyntaxCallExpr | statements.swift:16:11:16:11 | +(_:_:) | DeclRefExpr | | statements.swift:17:11:17:18 | (...) | ParenExpr | statements.swift:17:12:17:16 | ... call to <(_:_:) ... | BinaryExpr | | statements.swift:17:12:17:12 | (Int) ... | LoadExpr | statements.swift:17:12:17:12 | i | DeclRefExpr | | statements.swift:17:12:17:16 | ... call to <(_:_:) ... | BinaryExpr | statements.swift:17:14:17:14 | call to <(_:_:) | DotSyntaxCallExpr | -| statements.swift:17:14:17:14 | Int.Type | TypeExpr | statements.swift:17:14:17:14 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:17:14:17:14 | Int.Type | TypeExpr | statements.swift:17:14:17:14 | Int | TypeRepr | | statements.swift:17:14:17:14 | call to <(_:_:) | DotSyntaxCallExpr | statements.swift:17:14:17:14 | <(_:_:) | DeclRefExpr | | statements.swift:19:3:23:3 | do { ... } catch { ... } | DoCatchStmt | statements.swift:19:6:21:3 | { ... } | BraceStmt | | statements.swift:19:3:23:3 | do { ... } catch { ... } | DoCatchStmt | statements.swift:21:5:23:3 | case ... | CaseStmt | @@ -1074,11 +1070,11 @@ | statements.swift:39:3:41:3 | guard ... else { ... } | GuardStmt | statements.swift:39:9:39:14 | StmtCondition | StmtCondition | | statements.swift:39:3:41:3 | guard ... else { ... } | GuardStmt | statements.swift:39:21:41:3 | { ... } | BraceStmt | | statements.swift:39:9:39:14 | ... call to !=(_:_:) ... | BinaryExpr | statements.swift:39:11:39:11 | call to !=(_:_:) | DotSyntaxCallExpr | -| statements.swift:39:11:39:11 | Int.Type | TypeExpr | statements.swift:39:11:39:11 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:39:11:39:11 | Int.Type | TypeExpr | statements.swift:39:11:39:11 | Int | TypeRepr | | statements.swift:39:11:39:11 | call to !=(_:_:) | DotSyntaxCallExpr | statements.swift:39:11:39:11 | !=(_:_:) | DeclRefExpr | | statements.swift:39:21:41:3 | { ... } | BraceStmt | statements.swift:40:5:40:19 | throw ... | ThrowStmt | | statements.swift:40:5:40:19 | throw ... | ThrowStmt | statements.swift:40:11:40:19 | (Error) ... | ErasureExpr | -| statements.swift:40:11:40:11 | AnError.Type | TypeExpr | statements.swift:40:11:40:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| statements.swift:40:11:40:11 | AnError.Type | TypeExpr | statements.swift:40:11:40:11 | AnError | TypeRepr | | statements.swift:40:11:40:19 | (Error) ... | ErasureExpr | statements.swift:40:11:40:19 | call to ... | DotSyntaxCallExpr | | statements.swift:40:11:40:19 | call to ... | DotSyntaxCallExpr | statements.swift:40:19:40:19 | failed | DeclRefExpr | | statements.swift:44:1:46:1 | defer { ... } | DeferStmt | statements.swift:44:7:46:1 | { ... } | BraceStmt | @@ -1143,7 +1139,7 @@ | statements.swift:64:1:64:15 | { ... } | BraceStmt | statements.swift:64:1:64:15 | var ... = ... | PatternBindingDecl | | statements.swift:64:1:64:15 | { ... } | TopLevelCodeDecl | statements.swift:64:1:64:15 | { ... } | BraceStmt | | statements.swift:64:5:64:11 | ... as ... | TypedPattern | statements.swift:64:5:64:5 | x | NamedPattern | -| statements.swift:64:5:64:11 | ... as ... | TypedPattern | statements.swift:64:8:64:11 | ...? | OptionalTypeRepr | +| statements.swift:64:5:64:11 | ... as ... | TypedPattern | statements.swift:64:8:64:11 | Int? | TypeRepr | | statements.swift:64:15:64:15 | (Int?) ... | InjectIntoOptionalExpr | statements.swift:64:15:64:15 | 4 | IntegerLiteralExpr | | statements.swift:65:1:66:1 | if ... then { ... } | IfStmt | statements.swift:65:4:65:19 | StmtCondition | StmtCondition | | statements.swift:65:1:66:1 | if ... then { ... } | IfStmt | statements.swift:65:21:66:1 | { ... } | BraceStmt | @@ -1172,9 +1168,9 @@ | statements.swift:71:1:72:1 | { ... } | TopLevelCodeDecl | statements.swift:71:1:72:1 | { ... } | BraceStmt | | statements.swift:71:29:71:38 | ... call to %(_:_:) ... | BinaryExpr | statements.swift:71:36:71:36 | call to %(_:_:) | DotSyntaxCallExpr | | statements.swift:71:29:71:43 | ... call to ==(_:_:) ... | BinaryExpr | statements.swift:71:40:71:40 | call to ==(_:_:) | DotSyntaxCallExpr | -| statements.swift:71:36:71:36 | Int.Type | TypeExpr | statements.swift:71:36:71:36 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:71:36:71:36 | Int.Type | TypeExpr | statements.swift:71:36:71:36 | Int | TypeRepr | | statements.swift:71:36:71:36 | call to %(_:_:) | DotSyntaxCallExpr | statements.swift:71:36:71:36 | %(_:_:) | DeclRefExpr | -| statements.swift:71:40:71:40 | Int.Type | TypeExpr | statements.swift:71:40:71:40 | FixedTypeRepr | FixedTypeRepr | +| statements.swift:71:40:71:40 | Int.Type | TypeExpr | statements.swift:71:40:71:40 | Int | TypeRepr | | statements.swift:71:40:71:40 | call to ==(_:_:) | DotSyntaxCallExpr | statements.swift:71:40:71:40 | ==(_:_:) | DeclRefExpr | | statements.swift:74:8:74:8 | init | ConstructorDecl | statements.swift:74:8:74:8 | x | ParamDecl | | statements.swift:75:3:75:11 | var ... = ... | PatternBindingDecl | statements.swift:75:7:75:11 | ... as ... | TypedPattern | @@ -1190,7 +1186,7 @@ | statements.swift:75:7:75:7 | { ... } | BraceStmt | file://:0:0:0:0 | return ... | ReturnStmt | | statements.swift:75:7:75:7 | { ... } | BraceStmt | statements.swift:75:7:75:7 | yield ... | YieldStmt | | statements.swift:75:7:75:11 | ... as ... | TypedPattern | statements.swift:75:7:75:7 | x | NamedPattern | -| statements.swift:75:7:75:11 | ... as ... | TypedPattern | statements.swift:75:11:75:11 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| statements.swift:75:7:75:11 | ... as ... | TypedPattern | statements.swift:75:11:75:11 | Int | TypeRepr | | statements.swift:76:3:84:3 | var ... = ... | PatternBindingDecl | statements.swift:76:7:76:19 | ... as ... | TypedPattern | | statements.swift:76:7:76:7 | hasModify | ConcreteVarDecl | statements.swift:76:7:76:7 | set | AccessorDecl | | statements.swift:76:7:76:7 | hasModify | ConcreteVarDecl | statements.swift:77:5:79:5 | (unnamed function decl) | AccessorDecl | @@ -1199,7 +1195,7 @@ | statements.swift:76:7:76:7 | set | AccessorDecl | statements.swift:76:7:76:7 | { ... } | BraceStmt | | statements.swift:76:7:76:7 | { ... } | BraceStmt | file://:0:0:0:0 | ... = ... | AssignExpr | | statements.swift:76:7:76:19 | ... as ... | TypedPattern | statements.swift:76:7:76:7 | hasModify | NamedPattern | -| statements.swift:76:7:76:19 | ... as ... | TypedPattern | statements.swift:76:19:76:19 | SimpleIdentTypeRepr | SimpleIdentTypeRepr | +| statements.swift:76:7:76:19 | ... as ... | TypedPattern | statements.swift:76:19:76:19 | Int | TypeRepr | | statements.swift:77:5:79:5 | (unnamed function decl) | AccessorDecl | statements.swift:77:13:79:5 | { ... } | BraceStmt | | statements.swift:77:13:79:5 | { ... } | BraceStmt | statements.swift:78:7:78:14 | yield ... | YieldStmt | | statements.swift:78:7:78:14 | yield ... | YieldStmt | statements.swift:78:13:78:14 | &... | InOutExpr | From 965f5a980af40bc7101a3d093818ca70087a7ebe Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Tue, 12 Jul 2022 10:58:16 +0100 Subject: [PATCH 302/465] Java/Kotlin: Add changenote for ErrorType --- java/ql/lib/change-notes/2022-07-12-errortype.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2022-07-12-errortype.md diff --git a/java/ql/lib/change-notes/2022-07-12-errortype.md b/java/ql/lib/change-notes/2022-07-12-errortype.md new file mode 100644 index 00000000000..7f7e1231ddc --- /dev/null +++ b/java/ql/lib/change-notes/2022-07-12-errortype.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Added an `ErrorType` class. An instance of this class will be used if an extractor is unable to extract as type, or if an up/downgrade script is unable to provide a type. From 48c71c94076b8953930de958978fcd9f1b92905c Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 12 Jul 2022 12:10:22 +0200 Subject: [PATCH 303/465] Swift: add comment about `TypeRepr` in `ASTNode` fetching --- swift/extractor/infra/SwiftDispatcher.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index 0f1753cda1d..42b0faa5a5a 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -251,6 +251,10 @@ class SwiftDispatcher { template bool fetchLabelFromUnionCase(const llvm::PointerUnion u, TrapLabel& output) { + // we rely on the fact that when we extract `ASTNode` instances (which only happens + // on `BraceStmt` elements), we cannot encounter a standalone `TypeRepr` there, so we skip + // this case, which would be problematic as we would not be able to provide the corresponding + // type if constexpr (!std::is_same_v) { if (auto e = u.template dyn_cast()) { output = fetchLabel(e); From 1bcb17b760c3be7cd6508800baafa427545c81b9 Mon Sep 17 00:00:00 2001 From: Ian Lynagh Date: Tue, 12 Jul 2022 12:16:24 +0100 Subject: [PATCH 304/465] Update java/ql/lib/change-notes/2022-07-12-errortype.md Co-authored-by: Anders Schack-Mulligen --- java/ql/lib/change-notes/2022-07-12-errortype.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/lib/change-notes/2022-07-12-errortype.md b/java/ql/lib/change-notes/2022-07-12-errortype.md index 7f7e1231ddc..97f851bb936 100644 --- a/java/ql/lib/change-notes/2022-07-12-errortype.md +++ b/java/ql/lib/change-notes/2022-07-12-errortype.md @@ -1,4 +1,4 @@ --- category: feature --- -* Added an `ErrorType` class. An instance of this class will be used if an extractor is unable to extract as type, or if an up/downgrade script is unable to provide a type. +* Added an `ErrorType` class. An instance of this class will be used if an extractor is unable to extract a type, or if an up/downgrade script is unable to provide a type. From 2ceb25dc9a7d40f20170afc15b25ba639daa6e41 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 12 Jul 2022 15:21:37 +0200 Subject: [PATCH 305/465] C++: Order left and right operands in the logical left to right order --- cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll index 92beb5c9d99..baa78f7be7c 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll @@ -46,7 +46,7 @@ predicate nullCheckExpr(Expr checkExpr, Variable var) { or exists(LogicalAndExpr op, AnalysedExpr child | expr = op and - (op.getRightOperand() = child or op.getLeftOperand() = child) and + (op.getLeftOperand() = child or op.getRightOperand() = child) and nullCheckExpr(child, v) ) or @@ -99,7 +99,7 @@ predicate validCheckExpr(Expr checkExpr, Variable var) { or exists(LogicalAndExpr op, AnalysedExpr child | expr = op and - (op.getRightOperand() = child or op.getLeftOperand() = child) and + (op.getLeftOperand() = child or op.getRightOperand() = child) and validCheckExpr(child, v) ) or From d63b0946d98eb65edc87f31ce2005f73cdcbdb3d Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 12 Jul 2022 15:22:13 +0200 Subject: [PATCH 306/465] C++: Use `ConditionDeclExpr` in `AnalysedExpr::isDef` --- cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll index baa78f7be7c..a64c6a277d4 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll @@ -171,8 +171,8 @@ class AnalysedExpr extends Expr { this.inCondition() and ( this.(Assignment).getLValue() = v.getAnAccess() or - exists(Initializer i | this.getEnclosingStmt() = i.getEnclosingStmt() and v = i.getDeclaration()) - ) + this.(ConditionDeclExpr).getVariableAccess() = v.getAnAccess() + ) } /** From e5eabc4e4730f7ed7fd0f2735baf3e64cc998f10 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 12 Jul 2022 15:23:33 +0200 Subject: [PATCH 307/465] C++: Slightly tweak nullness test and update test results --- .../controlflow/nullness/nullness.expected | 11 ++++++++--- .../library-tests/controlflow/nullness/nullness.ql | 1 - .../test/library-tests/controlflow/nullness/test.cpp | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/cpp/ql/test/library-tests/controlflow/nullness/nullness.expected b/cpp/ql/test/library-tests/controlflow/nullness/nullness.expected index db5c795fd5b..bcf301ba47b 100644 --- a/cpp/ql/test/library-tests/controlflow/nullness/nullness.expected +++ b/cpp/ql/test/library-tests/controlflow/nullness/nullness.expected @@ -7,9 +7,14 @@ | test.cpp:15:8:15:23 | call to __builtin_expect | test.cpp:5:13:5:13 | v | is not null | is valid | | test.cpp:16:8:16:23 | call to __builtin_expect | test.cpp:5:13:5:13 | v | is null | is not valid | | test.cpp:17:9:17:17 | ... && ... | test.cpp:5:13:5:13 | v | is not null | is valid | -| test.cpp:18:9:18:17 | ... && ... | test.cpp:5:13:5:13 | v | is not null | is not valid | +| test.cpp:18:9:18:17 | ... && ... | test.cpp:5:13:5:13 | v | is not null | is valid | | test.cpp:19:9:19:18 | ... && ... | test.cpp:5:13:5:13 | v | is null | is not valid | -| test.cpp:20:9:20:18 | ... && ... | test.cpp:5:13:5:13 | v | is not null | is not valid | +| test.cpp:20:9:20:18 | ... && ... | test.cpp:5:13:5:13 | v | is null | is not valid | | test.cpp:21:9:21:14 | ... = ... | test.cpp:5:13:5:13 | v | is null | is not valid | | test.cpp:21:9:21:14 | ... = ... | test.cpp:7:10:7:10 | b | is not null | is valid | -| test.cpp:22:17:22:17 | b | test.cpp:7:10:7:10 | b | is not null | is valid | +| test.cpp:22:9:22:14 | ... = ... | test.cpp:5:13:5:13 | v | is not null | is not valid | +| test.cpp:22:9:22:14 | ... = ... | test.cpp:7:13:7:13 | c | is not null | is not valid | +| test.cpp:22:17:22:17 | c | test.cpp:7:13:7:13 | c | is not null | is valid | +| test.cpp:23:21:23:21 | x | test.cpp:23:14:23:14 | x | is not null | is valid | +| test.cpp:24:9:24:18 | (condition decl) | test.cpp:5:13:5:13 | v | is not null | is not valid | +| test.cpp:24:9:24:18 | (condition decl) | test.cpp:24:14:24:14 | y | is not null | is valid | diff --git a/cpp/ql/test/library-tests/controlflow/nullness/nullness.ql b/cpp/ql/test/library-tests/controlflow/nullness/nullness.ql index ed1ba15aa2b..864fd04f920 100644 --- a/cpp/ql/test/library-tests/controlflow/nullness/nullness.ql +++ b/cpp/ql/test/library-tests/controlflow/nullness/nullness.ql @@ -2,7 +2,6 @@ import cpp from AnalysedExpr a, LocalScopeVariable v, string isNullCheck, string isValidCheck where - a.getParent() instanceof IfStmt and v.getAnAccess().getEnclosingStmt() = a.getParent() and (if a.isNullCheck(v) then isNullCheck = "is null" else isNullCheck = "is not null") and (if a.isValidCheck(v) then isValidCheck = "is valid" else isValidCheck = "is not valid") diff --git a/cpp/ql/test/library-tests/controlflow/nullness/test.cpp b/cpp/ql/test/library-tests/controlflow/nullness/test.cpp index 03369c811d5..407753be17a 100644 --- a/cpp/ql/test/library-tests/controlflow/nullness/test.cpp +++ b/cpp/ql/test/library-tests/controlflow/nullness/test.cpp @@ -4,7 +4,7 @@ long __builtin_expect(long); void f(int *v) { int *w; - bool b; + bool b, c; if (v) {} if (!v) {} @@ -19,5 +19,7 @@ void f(int *v) { if (true && !v) {} if (!v && true) {} if (b = !v) {} - if (b = !v; b) {} + if (c = !v; c) {} + if (int *x = v; x) {} + if (int *y = v) {} } From 8f9d4194413f5c836ff53f6312e0a9ecfc8251c7 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 12 Jul 2022 15:24:09 +0200 Subject: [PATCH 308/465] C++: Add change note --- .../lib/change-notes/2022-07-12-cover-more-nullness-cases.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2022-07-12-cover-more-nullness-cases.md diff --git a/cpp/ql/lib/change-notes/2022-07-12-cover-more-nullness-cases.md b/cpp/ql/lib/change-notes/2022-07-12-cover-more-nullness-cases.md new file mode 100644 index 00000000000..eef564991f5 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-07-12-cover-more-nullness-cases.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the the C++ logical and variable declarations in conditions. From f7c4fa691d7918c86be65f20ae1778bc2ff0097b Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <93738568+jketema@users.noreply.github.com> Date: Tue, 12 Jul 2022 16:59:15 +0200 Subject: [PATCH 309/465] Apply suggestions from code review Co-authored-by: Geoffrey White <40627776+geoffw0@users.noreply.github.com> --- cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll index a64c6a277d4..0fb46f75c94 100644 --- a/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll +++ b/cpp/ql/lib/semmle/code/cpp/controlflow/Nullness.qll @@ -46,7 +46,7 @@ predicate nullCheckExpr(Expr checkExpr, Variable var) { or exists(LogicalAndExpr op, AnalysedExpr child | expr = op and - (op.getLeftOperand() = child or op.getRightOperand() = child) and + op.getAnOperand() = child and nullCheckExpr(child, v) ) or @@ -99,7 +99,7 @@ predicate validCheckExpr(Expr checkExpr, Variable var) { or exists(LogicalAndExpr op, AnalysedExpr child | expr = op and - (op.getLeftOperand() = child or op.getRightOperand() = child) and + op.getAnOperand() = child and validCheckExpr(child, v) ) or From a51d713925cd351664efa9e2905f1b63b2b8b32f Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Tue, 12 Jul 2022 08:13:12 -0700 Subject: [PATCH 310/465] Update java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql Co-authored-by: Chris Smowton --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 50840b67f0b..d3b742f7c95 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -14,8 +14,8 @@ import java import semmle.code.java.dataflow.DataFlow /** - * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` - * that takes no arguments, which means that it is using V1 encryption + * Holds if `call` is an object creation for a class `EncryptedBlobClientBuilder` + * that takes no arguments, which means that it is using V1 encryption. */ predicate isCreatingOutdatedAzureClientSideEncryptionObject(Call call, Class c) { exists(string package, string type, Constructor constructor | From a4e35a97eac187d0b6a3a6cb2f72c9f0d8340bb6 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Tue, 12 Jul 2022 08:13:38 -0700 Subject: [PATCH 311/465] Update java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql Co-authored-by: Chris Smowton --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index d3b742f7c95..c0fd959b790 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -33,8 +33,8 @@ predicate isCreatingOutdatedAzureClientSideEncryptionObject(Call call, Class c) } /** - * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` - * that takes `versionArg` as the argument for the version. + * Holds if `call` is an object creation for a class `EncryptedBlobClientBuilder` + * that takes `versionArg` as the argument specifying the encryption version. */ predicate isCreatingAzureClientSideEncryptionObjectNewVersion(Call call, Class c, Expr versionArg) { exists(string package, string type, Constructor constructor | From 2bac18109487a757e72f997bab20c2fd01ba6b50 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Tue, 12 Jul 2022 08:13:53 -0700 Subject: [PATCH 312/465] Update java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql Co-authored-by: Chris Smowton --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index c0fd959b790..5f73e4322b0 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -48,7 +48,7 @@ predicate isCreatingAzureClientSideEncryptionObjectNewVersion(Call call, Class c } /** - * A config that tracks `EncryptedBlobClientBuilder.version` argument initialization. + * A dataflow config that tracks `EncryptedBlobClientBuilder.version` argument initialization. */ private class EncryptedBlobClientBuilderEncryptionVersionConfig extends DataFlow::Configuration { EncryptedBlobClientBuilderEncryptionVersionConfig() { From 8a48708014bfcd4afb9dd6c3d8d0123bc707ae97 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Tue, 12 Jul 2022 08:14:13 -0700 Subject: [PATCH 313/465] Update java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql Co-authored-by: Chris Smowton --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 5f73e4322b0..b5ac2cabd7e 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -50,7 +50,7 @@ predicate isCreatingAzureClientSideEncryptionObjectNewVersion(Call call, Class c /** * A dataflow config that tracks `EncryptedBlobClientBuilder.version` argument initialization. */ -private class EncryptedBlobClientBuilderEncryptionVersionConfig extends DataFlow::Configuration { +private class EncryptedBlobClientBuilderSafeEncryptionVersionConfig extends DataFlow::Configuration { EncryptedBlobClientBuilderEncryptionVersionConfig() { this = "EncryptedBlobClientBuilderEncryptionVersionConfig" } From 64343e00f4c6fe61b9f6ed263c5f3a3c843605f7 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Tue, 12 Jul 2022 08:14:25 -0700 Subject: [PATCH 314/465] Update java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql Co-authored-by: Chris Smowton --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index b5ac2cabd7e..5977d29f26e 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -69,8 +69,8 @@ private class EncryptedBlobClientBuilderSafeEncryptionVersionConfig extends Data } /** - * Holds if the call `call` is an object creation for a class `EncryptedBlobClientBuilder` - * that takes `versionArg` as the argument for the version, and the version number is safe + * Holds if `call` is an object creation for a class `EncryptedBlobClientBuilder` + * that takes `versionArg` as the argument specifying the encryption version, and that version is safe. */ predicate isCreatingSafeAzureClientSideEncryptionObject(Call call, Class c, Expr versionArg) { isCreatingAzureClientSideEncryptionObjectNewVersion(call, c, versionArg) and From d929b1338b6f1f5a51e50510ed393c6931c9e282 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Tue, 12 Jul 2022 11:55:06 -0700 Subject: [PATCH 315/465] Addressing API::Node feedback for all predicates --- ...nsafeUsageOfClientSideEncryptionVersion.ql | 49 ++++++++++++++++--- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 442399e658f..3b35f2350bd 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -14,19 +14,54 @@ import python import semmle.python.ApiGraphs predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrNode node) { - exists(ControlFlowNode ctrlFlowNode, AssignStmt astmt, Attribute a | + exists( + API::Node n, API::Node n2, Attribute a, AssignStmt astmt, API::Node uploadBlob, + ControlFlowNode ctrlFlowNode, string s + | + s in ["key_encryption_key", "key_resolver_function"] and + n = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember("BlobClient") + .getReturn() + .getMember(s) and + n2 = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember("BlobClient") + .getReturn() + .getMember("upload_blob") and + n.getAUse().asExpr() = a and astmt.getATarget() = a and - a.getAttr() in ["key_encryption_key", "key_resolver_function"] and a.getAFlowNode() = node and + uploadBlob = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember("BlobClient") + .getReturn() + .getMember("upload_blob") and + uploadBlob.getACall().asExpr() = call and + ctrlFlowNode = call.getAFlowNode() and node.strictlyReaches(ctrlFlowNode) and node != ctrlFlowNode and - call.getAChildNode().(Attribute).getAttr() = "upload_blob" and - ctrlFlowNode = call.getAFlowNode() and - not astmt.getValue() instanceof None and - not exists(AssignStmt astmt2, Attribute a2, AttrNode encryptionVersionSet, StrConst uc | + not exists( + AssignStmt astmt2, Attribute a2, AttrNode encryptionVersionSet, StrConst uc, + API::Node encryptionVersion + | uc = astmt2.getValue() and uc.getText() in ["'2.0'", "2.0"] and - a2.getAttr() = "encryption_version" and + encryptionVersion = + API::moduleImport("azure") + .getMember("storage") + .getMember("blob") + .getMember("BlobClient") + .getReturn() + .getMember("encryption_version") and + encryptionVersion.getAUse().asExpr() = a2 and + astmt2.getATarget() = a2 and a2.getAFlowNode() = encryptionVersionSet and encryptionVersionSet.strictlyReaches(ctrlFlowNode) ) From a4adf067135b6f3573b6093c86572e8ab3b7449d Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Tue, 12 Jul 2022 13:51:12 -0700 Subject: [PATCH 316/465] Addressing feedback for the qhelp file. --- .../Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp index 45d919ec702..190ce5e25dc 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -4,12 +4,12 @@

    Azure Storage .NET, Java, and Python SDKs support encryption on the client with a customer-managed key that is maintained in Azure Key Vault or another key store.

    -

    Current release versions of the Azure Storage SDKs use cipher block chaining (CBC mode) for client-side encryption (referred to as v1).

    +

    The Azure Storage SDK version 12.18.0 or later supports version V2 for client-side encryption. All previous versions of Azure Storage SDK only support client-side encryption V1 which is unsafe.

    -

    Consider switching to v2 client-side encryption.

    +

    Consider switching to V2 client-side encryption.

    From 7facc63699ed709c25af772c981d2a4aa2d0072b Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Tue, 12 Jul 2022 22:59:48 +0000 Subject: [PATCH 317/465] remove predicate --- .../experimental/weak-params/WeakParams.ql | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql index 6ea73aa42de..86ba72cbd91 100644 --- a/ruby/ql/src/experimental/weak-params/WeakParams.ql +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -38,21 +38,16 @@ class ActionControllerRequest extends DataFlow::Node { class WeakParams extends DataFlow::CallNode { WeakParams() { this.getReceiver() instanceof ActionControllerRequest and - allParamsAccess(this.asExpr().getExpr()) + ( + this.getMethodName() = "path_parametes" or + this.getMethodName() = "query_parameters" or + this.getMethodName() = "request_parameters" or + this.getMethodName() = "GET" or + this.getMethodName() = "POST" + ) } } -/** - * Holds call to a method that exposes or accesses all parameters from an inbound HTTP request - */ -predicate allParamsAccess(MethodCall call) { - call.getMethodName() = "path_parametes" or - call.getMethodName() = "query_parameters" or - call.getMethodName() = "request_parameters" or - call.getMethodName() = "GET" or - call.getMethodName() = "POST" -} - /** * A Taint tracking config where the source is a weak params access in a controller and the sink * is a method call of a model class From db5f63b20876b26a73ea829fe3cba206ae26ac95 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Tue, 12 Jul 2022 23:14:16 +0000 Subject: [PATCH 318/465] add tests --- .../weak-params/WeakParams.expected | 20 +++++++++++++ .../experimental/weak-params/WeakParams.rb | 28 +++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.expected b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.expected index e69de29bb2d..14bd3e4e13f 100644 --- a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.expected +++ b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.expected @@ -0,0 +1,20 @@ +edges +| WeakParams.rb:5:28:5:53 | call to request_parameters : | WeakParams.rb:5:28:5:59 | ...[...] | +| WeakParams.rb:10:28:10:51 | call to query_parameters : | WeakParams.rb:10:28:10:57 | ...[...] | +| WeakParams.rb:15:28:15:39 | call to POST : | WeakParams.rb:15:28:15:45 | ...[...] | +| WeakParams.rb:20:28:20:38 | call to GET : | WeakParams.rb:20:28:20:44 | ...[...] | +nodes +| WeakParams.rb:5:28:5:53 | call to request_parameters : | semmle.label | call to request_parameters : | +| WeakParams.rb:5:28:5:59 | ...[...] | semmle.label | ...[...] | +| WeakParams.rb:10:28:10:51 | call to query_parameters : | semmle.label | call to query_parameters : | +| WeakParams.rb:10:28:10:57 | ...[...] | semmle.label | ...[...] | +| WeakParams.rb:15:28:15:39 | call to POST : | semmle.label | call to POST : | +| WeakParams.rb:15:28:15:45 | ...[...] | semmle.label | ...[...] | +| WeakParams.rb:20:28:20:38 | call to GET : | semmle.label | call to GET : | +| WeakParams.rb:20:28:20:44 | ...[...] | semmle.label | ...[...] | +subpaths +#select +| WeakParams.rb:5:28:5:59 | ...[...] | WeakParams.rb:5:28:5:53 | call to request_parameters : | WeakParams.rb:5:28:5:59 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | +| WeakParams.rb:10:28:10:57 | ...[...] | WeakParams.rb:10:28:10:51 | call to query_parameters : | WeakParams.rb:10:28:10:57 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | +| WeakParams.rb:15:28:15:45 | ...[...] | WeakParams.rb:15:28:15:39 | call to POST : | WeakParams.rb:15:28:15:45 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | +| WeakParams.rb:20:28:20:44 | ...[...] | WeakParams.rb:20:28:20:38 | call to GET : | WeakParams.rb:20:28:20:44 | ...[...] | By exposing all keys in request parameters or by blindy accessing them, unintended parameters could be used and lead to mass-assignment or have other unexpected side-effects. It is safer to follow the 'strong parameters' pattern in Rails, which is outlined here: https://api.rubyonrails.org/classes/ActionController/StrongParameters.html | diff --git a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb index 81d57239f29..a5edef2e6dc 100644 --- a/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb +++ b/ruby/ql/test/query-tests/experimental/weak-params/WeakParams.rb @@ -1,18 +1,40 @@ class TestController < ActionController::Base + + # Should catch def create - TestObject.new(request.request_parameters) + TestObject.create(foo: request.request_parameters[:foo]) end + # Should catch def create_query - TestObject.new(request.query_parameters) + TestObject.create(foo: request.query_parameters[:foo]) end + # Should catch + def update_unsafe + TestObject.update(foo: request.POST[:foo]) + end + + # Should catch + def update_unsafe_get + TestObject.update(foo: request.GET[:foo]) + end + + # Should not catch def update TestObject.update(object_params) end - # + # strong params method def object_params params.require(:uuid).permit(:notes) end + + # Should not catch + def test_non_sink + puts request.request_parameters + end +end + +class TestObject < ActiveRecord::Base end \ No newline at end of file From b3f1a513d148eac778dfe66afc2c0254591e8b17 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Wed, 13 Jul 2022 00:25:19 +0000 Subject: [PATCH 319/465] Update tests --- .../ExampleController.rb | 48 ---------- .../ManuallyCheckHttpVerb.rb | 96 +++++++++++++++++++ .../manually-check-http-verb/NotController.rb | 17 ---- 3 files changed, 96 insertions(+), 65 deletions(-) delete mode 100644 ruby/ql/test/query-tests/experimental/manually-check-http-verb/ExampleController.rb create mode 100644 ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb delete mode 100644 ruby/ql/test/query-tests/experimental/manually-check-http-verb/NotController.rb diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ExampleController.rb b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ExampleController.rb deleted file mode 100644 index 7e4ab4a1a77..00000000000 --- a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ExampleController.rb +++ /dev/null @@ -1,48 +0,0 @@ -class ExampleController < ActionController::Base - # This function should have 6 vulnerable lines - def example_action - if request.get? - Example.find(params[:example_id]) - end - end -end - -class OtherController < ActionController::Base - def other_action - if env['REQUEST_METHOD'] == "GET" - Other.find(params[:id]) - end - end -end - -class ResourceController < ActionController::Base - # This method should have 1 vulnerable line, but is currently failing because it's not a comparison node - def resource_action - case env['REQUEST_METHOD'] - when "GET" - Resource.find(params[:id]) - when "POST" - Resource.new(params[:id], params[:details]) - end - end -end - -class SafeController < ActionController::Base - # this method should have no hits because controllers rely on conventional Rails routes - def index - Safe.find(params[:id]) - end - - def create - Safe.new(params[:id], params[:details]) - end - - def update - Safe.update(params[:id], params[:details]) - end - - def delete - s = Safe.find(params[:id]) - s.delete - end -end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb new file mode 100644 index 00000000000..aa10ebc69aa --- /dev/null +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb @@ -0,0 +1,96 @@ +class ExampleController < ActionController::Base + # Should find + def example_action + if request.get? + Resource.find(id: params[:example_id]) + end + end + + # Should find + def other_action + if request.env['REQUEST_METHOD'] == "GET" + Resource.find(id: params[:id]) + end + end + + # Should find + def foo + if request.request_method == "GET" + Resource.find(id: params[:id]) + end + end + + # Should find + def bar + if request.method == "GET" + Resource.find(id: params[:id]) + end + end + + # Should find + def baz + if request.raw_request_method == "GET" + Resource.find(id: params[:id]) + end + end + + # Should find + def foobarbaz + if request.request_method_symbol == :GET + Resource.find(id: params[:id]) + end + end + + # Should find + def resource_action + case request.env['REQUEST_METHOD'] + when "GET" + Resource.find(id: params[:id]) + when "POST" + Resource.new(id: params[:id], details: params[:details]) + end + end + + +end + +class SafeController < ActionController::Base + # this class should have no hits because controllers rely on conventional Rails routes + def index + Resource.find(id: params[:id]) + end + + def create + Resource.new(id: params[:id], details: params[:details]) + end + + def update + Resource.update(id: params[:id], details: params[:details]) + end + + def delete + s = Resource.find(id: params[:id]) + s.delete + end +end + +# There should be no hits from this class because it does not inherit from ActionController +class NotAController + def example_action + if request.get? + Resource.find(params[:example_id]) + end + end + + def resource_action + case env['REQUEST_METHOD'] + when "GET" + Resource.find(params[:id]) + when "POST" + Resource.new(params[:id], params[:details]) + end + end +end + +class Resource < ActiveRecord::Base +end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/NotController.rb b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/NotController.rb deleted file mode 100644 index 78e194245e2..00000000000 --- a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/NotController.rb +++ /dev/null @@ -1,17 +0,0 @@ -# There should be no hits from this class because it does not inherit from ActionController -class NotAController - def example_action - if request.get? - Example.find(params[:example_id]) - end - end - - def resource_action - case env['REQUEST_METHOD'] - when "GET" - Resource.find(params[:id]) - when "POST" - Resource.new(params[:id], params[:details]) - end - end -end \ No newline at end of file From 712900257342ffbfbb788c6491e955c7f10c3dc1 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Wed, 13 Jul 2022 00:33:58 +0000 Subject: [PATCH 320/465] tweak tests more --- .../ManuallyCheckHttpVerb.ql | 10 +++++++++- .../ManuallyCheckHttpVerb.rb | 15 ++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql index 5e1db6f0de7..72574e148d2 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -18,7 +18,15 @@ import codeql.ruby.frameworks.ActionController class Request extends DataFlow::CallNode { Request() { this.getMethodName() = "request" and - this.asExpr().getExpr() instanceof ActionControllerActionMethod + this.asExpr().getExpr().getEnclosingMethod() instanceof ActionControllerActionMethod + } +} + +// `request.env` +class RequestEnvMethod extends DataFlow::CallNode { + RequestEnvMethod() { + this.getMethodName() = "env" and + any(Request r).flowsTo(this.getReceiver()) } } diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb index aa10ebc69aa..ad0f5b45566 100644 --- a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb @@ -8,35 +8,40 @@ class ExampleController < ActionController::Base # Should find def other_action - if request.env['REQUEST_METHOD'] == "GET" + method = request.env['REQUEST_METHOD'] + if method == "GET" Resource.find(id: params[:id]) end end # Should find def foo - if request.request_method == "GET" + method = request.request_method + if method == "GET" Resource.find(id: params[:id]) end end # Should find def bar - if request.method == "GET" + method = request.method + if method == "GET" Resource.find(id: params[:id]) end end # Should find def baz - if request.raw_request_method == "GET" + method = request.raw_request_method + if method == "GET" Resource.find(id: params[:id]) end end # Should find def foobarbaz - if request.request_method_symbol == :GET + method = request.request_method_symbol + if method == :GET Resource.find(id: params[:id]) end end From 0dbb03f732b5b5fcbdf54555331f4f014925e92f Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Tue, 12 Jul 2022 21:49:19 -0700 Subject: [PATCH 321/465] Adding CVE information. --- .../Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp | 2 +- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 2 +- .../Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp | 2 +- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 2 +- .../Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp index e0ee017cb14..54c9a4998b4 100644 --- a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -22,7 +22,7 @@ Azure Storage Client Encryption Blog.
  • - CVE-2022-PENDING + CVE-2022-30187
  • diff --git a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index b150ca71060..eb1cb673ed2 100644 --- a/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/csharp/ql/src/experimental/Security Features/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -1,5 +1,5 @@ /** - * @name Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). + * @name Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-30187). * @description Unsafe usage of v1 version of Azure Storage client-side encryption, please refer to http://aka.ms/azstorageclientencryptionblog * @kind problem * @tags security diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp index 190ce5e25dc..b6884aed914 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -22,7 +22,7 @@ Azure Storage Client Encryption Blog.
  • - CVE-2022-PENDING + CVE-2022-30187
  • diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 5977d29f26e..ba78fa56423 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -1,5 +1,5 @@ /** - * @name Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-PENDING). + * @name Unsafe usage of v1 version of Azure Storage client-side encryption (CVE-2022-30187). * @description Unsafe usage of v1 version of Azure Storage client-side encryption, please refer to http://aka.ms/azstorageclientencryptionblog * @kind problem * @tags security diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp index eaf49f371e6..a2f9a2213c3 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.qhelp @@ -22,7 +22,7 @@ Azure Storage Client Encryption Blog.
  • - CVE-2022-PENDING + CVE-2022-30187
  • From 706d1d2eee83ed3b71545801c080e1688469b839 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Thu, 12 May 2022 15:12:18 +0100 Subject: [PATCH 322/465] Ruby: Make StringArrayInclusion more sensitive We now recognise the following pattern as a barrier guard for `x`: values = ["foo", "bar"] if values.include? x sink x end --- .../lib/codeql/ruby/controlflow/CfgNodes.qll | 3 + .../codeql/ruby/dataflow/BarrierGuards.qll | 25 +++++-- .../barrier-guards/barrier-guards.expected | 8 ++ .../dataflow/barrier-guards/barrier-guards.rb | 73 +++++++++++++++++++ 4 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected create mode 100644 ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb diff --git a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll index efb69af39eb..29668b82e70 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/CfgNodes.qll @@ -374,6 +374,9 @@ module ExprNodes { MethodCallCfgNode() { super.getExpr() instanceof MethodCall } override MethodCall getExpr() { result = super.getExpr() } + + /** Gets the name of this method call. */ + string getMethodName() { result = this.getExpr().getMethodName() } } private class CaseExprChildMapping extends ExprChildMapping, CaseExpr { diff --git a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll index d55bd9af278..506f95b5b45 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll @@ -3,6 +3,8 @@ private import ruby private import codeql.ruby.DataFlow private import codeql.ruby.CFG +private import codeql.ruby.controlflow.CfgNodes +private import codeql.ruby.dataflow.SSA private predicate stringConstCompare(CfgNodes::ExprCfgNode g, CfgNode e, boolean branch) { exists(CfgNodes::ExprNodes::ComparisonOperationCfgNode c | @@ -133,13 +135,24 @@ deprecated class StringConstArrayInclusionCall extends DataFlow::BarrierGuard, private CfgNode checkedNode; StringConstArrayInclusionCall() { - exists(ArrayLiteral aLit | - this.getExpr().getMethodName() = "include?" and - [this.getExpr().getReceiver(), this.getExpr().getReceiver().(ConstantReadAccess).getValue()] = - aLit + this.getMethodName() = "include?" and + this.getArgument(0) = checkedNode and + exists(ExprNodes::ArrayLiteralCfgNode arr | + // [...].include? + this.getReceiver() = arr + or + // C = [...] + // C.include? + this.getReceiver().(ExprNodes::ConstantReadAccessCfgNode).getExpr().getValue().getDesugared() = + arr.getExpr() + or + // x = [...] + // x.include? + exists(Ssa::WriteDefinition def | def.getARead() = this.getReceiver() and def.assigns(arr)) | - forall(Expr elem | elem = aLit.getAnElement() | elem instanceof StringLiteral) and - this.getArgument(0) = checkedNode + forall(ExprCfgNode elem | elem = arr.getAnArgument() | + elem instanceof ExprNodes::StringLiteralCfgNode + ) ) } diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected new file mode 100644 index 00000000000..dcbe2c76d80 --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected @@ -0,0 +1,8 @@ +| barrier-guards.rb:3:4:3:15 | ... == ... | barrier-guards.rb:4:5:4:7 | foo | barrier-guards.rb:3:4:3:6 | foo | true | +| barrier-guards.rb:9:4:9:24 | call to include? | barrier-guards.rb:10:5:10:7 | foo | barrier-guards.rb:9:21:9:23 | foo | true | +| barrier-guards.rb:15:4:15:15 | ... != ... | barrier-guards.rb:18:5:18:7 | foo | barrier-guards.rb:15:4:15:6 | foo | false | +| barrier-guards.rb:21:8:21:19 | ... == ... | barrier-guards.rb:24:5:24:7 | foo | barrier-guards.rb:21:8:21:10 | foo | true | +| barrier-guards.rb:27:8:27:19 | ... != ... | barrier-guards.rb:28:5:28:7 | foo | barrier-guards.rb:27:8:27:10 | foo | false | +| barrier-guards.rb:37:4:37:20 | call to include? | barrier-guards.rb:38:5:38:7 | foo | barrier-guards.rb:37:17:37:19 | foo | true | +| barrier-guards.rb:43:4:43:15 | ... == ... | barrier-guards.rb:45:9:45:11 | foo | barrier-guards.rb:43:4:43:6 | foo | true | +| barrier-guards.rb:69:4:69:21 | call to include? | barrier-guards.rb:70:5:70:7 | foo | barrier-guards.rb:69:18:69:20 | foo | true | diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb new file mode 100644 index 00000000000..78ef5e7bf19 --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb @@ -0,0 +1,73 @@ +foo = "foo" + +if foo == "foo" + foo +else + foo +end + +if ["foo"].include?(foo) + foo +else + foo +end + +if foo != "foo" + foo +else + foo +end + +unless foo == "foo" + foo +else + foo +end + +unless foo != "foo" + foo +else + foo +end + +foo + +FOO = ["foo"] + +if FOO.include?(foo) + foo +else + foo +end + +if foo == "foo" + capture { + foo # guarded + } +end + +if foo == "foo" + capture { + foo = "bar" + foo # not guarded + } +end + +if foo == "foo" + my_lambda = -> () { + foo # not guarded + } + + foo = "bar" + + my_lambda() +end + +foos = ["foo"] +bars = ["bar"] + +if foos.include?(foo) + foo +else + foo +end \ No newline at end of file From 301914d80c41db9f662740171755a391228ea448 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Thu, 12 May 2022 15:41:55 +0100 Subject: [PATCH 323/465] Ruby: Add an extra barrier guard test --- .../barrier-guards/barrier-guards.expected | 2 +- .../dataflow/barrier-guards/barrier-guards.rb | 23 +++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected index dcbe2c76d80..fcf95346a5a 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected @@ -5,4 +5,4 @@ | barrier-guards.rb:27:8:27:19 | ... != ... | barrier-guards.rb:28:5:28:7 | foo | barrier-guards.rb:27:8:27:10 | foo | false | | barrier-guards.rb:37:4:37:20 | call to include? | barrier-guards.rb:38:5:38:7 | foo | barrier-guards.rb:37:17:37:19 | foo | true | | barrier-guards.rb:43:4:43:15 | ... == ... | barrier-guards.rb:45:9:45:11 | foo | barrier-guards.rb:43:4:43:6 | foo | true | -| barrier-guards.rb:69:4:69:21 | call to include? | barrier-guards.rb:70:5:70:7 | foo | barrier-guards.rb:69:18:69:20 | foo | true | +| barrier-guards.rb:70:4:70:21 | call to include? | barrier-guards.rb:71:5:71:7 | foo | barrier-guards.rb:70:18:70:20 | foo | true | diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb index 78ef5e7bf19..a3f13b48639 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb @@ -63,11 +63,30 @@ if foo == "foo" my_lambda() end +foos = nil foos = ["foo"] -bars = ["bar"] +bars = NotAnArray.new if foos.include?(foo) foo else foo -end \ No newline at end of file +end + +if bars.include?(foo) + foo +else + foo +end + +bars = ["bar"] + +if condition + bars = nil +end + +if bars.include?(foo) + foo +else + foo +end From b5a3d3c4886dce9892ec25eacf474084a0d85463 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 23 May 2022 13:34:06 +0100 Subject: [PATCH 324/465] Ruby: Extract isArrayConstant This predicate might be useful elsewhere. --- .../lib/codeql/ruby/ast/internal/Constant.qll | 20 +++++++++++++++++++ .../codeql/ruby/dataflow/BarrierGuards.qll | 15 ++------------ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll index fb7cb3737b9..00e4472c7c1 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll @@ -509,3 +509,23 @@ private module Cached { } import Cached + +/** + * Holds if `e` is an array constructed from an array literal. + * Example: + * ```rb + * [1, 2, 3] + * C = [1, 2, 3]; C + * x = [1, 2, 3]; x + * ``` + */ +predicate isArrayConstant(ExprCfgNode e, ArrayLiteralCfgNode arr) { + // [...] + e = arr + or + // C = [...]; C + e.(ExprNodes::ConstantReadAccessCfgNode).getExpr().getValue().getDesugared() = arr.getExpr() + or + // x = [...]; x + exists(Ssa::WriteDefinition def | def.getARead() = e and def.assigns(arr)) +} diff --git a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll index 506f95b5b45..52e9c48779d 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll @@ -5,6 +5,7 @@ private import codeql.ruby.DataFlow private import codeql.ruby.CFG private import codeql.ruby.controlflow.CfgNodes private import codeql.ruby.dataflow.SSA +private import codeql.ruby.ast.internal.Constant private predicate stringConstCompare(CfgNodes::ExprCfgNode g, CfgNode e, boolean branch) { exists(CfgNodes::ExprNodes::ComparisonOperationCfgNode c | @@ -137,19 +138,7 @@ deprecated class StringConstArrayInclusionCall extends DataFlow::BarrierGuard, StringConstArrayInclusionCall() { this.getMethodName() = "include?" and this.getArgument(0) = checkedNode and - exists(ExprNodes::ArrayLiteralCfgNode arr | - // [...].include? - this.getReceiver() = arr - or - // C = [...] - // C.include? - this.getReceiver().(ExprNodes::ConstantReadAccessCfgNode).getExpr().getValue().getDesugared() = - arr.getExpr() - or - // x = [...] - // x.include? - exists(Ssa::WriteDefinition def | def.getARead() = this.getReceiver() and def.assigns(arr)) - | + exists(ExprNodes::ArrayLiteralCfgNode arr | isArrayConstant(this.getReceiver(), arr) | forall(ExprCfgNode elem | elem = arr.getAnArgument() | elem instanceof ExprNodes::StringLiteralCfgNode ) From 63dcce9a31dbd5af563b970308e3108712232bf1 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Thu, 30 Jun 2022 16:15:56 +1200 Subject: [PATCH 325/465] Ruby: Refactor isArrayConstant --- .../lib/codeql/ruby/ast/internal/Constant.qll | 37 ++++++++++++++++--- .../ast/constants/constants.expected | 16 ++++++++ .../library-tests/ast/constants/constants.ql | 3 ++ .../library-tests/ast/constants/constants.rb | 8 ++++ 4 files changed, 58 insertions(+), 6 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll index 00e4472c7c1..ae1d9f5989c 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll @@ -36,7 +36,7 @@ private import ExprNodes * constant value in some cases. */ private module Propagation { - private ExprCfgNode getSource(VariableReadAccessCfgNode read) { + ExprCfgNode getSource(VariableReadAccessCfgNode read) { exists(Ssa::WriteDefinition def | def.assigns(result) and read = def.getARead() @@ -511,7 +511,8 @@ private module Cached { import Cached /** - * Holds if `e` is an array constructed from an array literal. + * Holds if the control flow node `e` refers to an array constructed from the + * array literal `arr`. * Example: * ```rb * [1, 2, 3] @@ -523,9 +524,33 @@ predicate isArrayConstant(ExprCfgNode e, ArrayLiteralCfgNode arr) { // [...] e = arr or - // C = [...]; C - e.(ExprNodes::ConstantReadAccessCfgNode).getExpr().getValue().getDesugared() = arr.getExpr() + // e = [...]; e + isArrayConstant(getSource(e), arr) or - // x = [...]; x - exists(Ssa::WriteDefinition def | def.getARead() = e and def.assigns(arr)) + isArrayExpr(e.getExpr(), arr) +} + +/** + * Holds if the expression `e` refers to an array constructed from the array literal `arr`. + */ +predicate isArrayExpr(Expr e, ArrayLiteralCfgNode arr) { + // e = [...] + e = arr.getExpr() + or + // Like above, but handles the desugaring of array literals to Array.[] calls. + e.getDesugared() = arr.getExpr() + or + // A = [...]; A + // A = a; A + isArrayExpr(e.(ConstantReadAccess).getValue(), arr) + or + // Recurse via CFG nodes. Necessary for example in: + // a = [...] + // A = a + // A + // + // We map from A to a via ConstantReadAccess::getValue, yielding the Expr a. + // To get to [...] we need to go via getSource(ExprCfgNode e), so we find a + // CFG node for a and call `isArrayConstant`. + isArrayConstant(e.getAControlFlowNode(), arr) } diff --git a/ruby/ql/test/library-tests/ast/constants/constants.expected b/ruby/ql/test/library-tests/ast/constants/constants.expected index 89b5512921c..0fe1b324232 100644 --- a/ruby/ql/test/library-tests/ast/constants/constants.expected +++ b/ruby/ql/test/library-tests/ast/constants/constants.expected @@ -61,6 +61,13 @@ constantAccess | constants.rb:71:5:71:14 | FOURTY_SIX | write | FOURTY_SIX | ConstantAssignment | | constants.rb:73:18:73:21 | Mod3 | read | Mod3 | ConstantReadAccess | | constants.rb:73:18:73:33 | FOURTY_SIX | read | FOURTY_SIX | ConstantReadAccess | +| constants.rb:78:5:78:13 | Array | read | Array | ConstantReadAccess | +| constants.rb:79:1:79:1 | A | write | A | ConstantAssignment | +| constants.rb:79:5:79:13 | Array | read | Array | ConstantReadAccess | +| constants.rb:80:1:80:1 | B | write | B | ConstantAssignment | +| constants.rb:81:1:81:1 | C | write | C | ConstantAssignment | +| constants.rb:81:5:81:5 | A | read | A | ConstantReadAccess | +| constants.rb:82:5:82:5 | B | read | B | ConstantReadAccess | getConst | constants.rb:1:1:15:3 | ModuleA | CONST_B | constants.rb:6:15:6:23 | "const_b" | | constants.rb:1:1:15:3 | ModuleA | FOURTY_FOUR | constants.rb:53:17:53:29 | "fourty-four" | @@ -133,3 +140,12 @@ constantWriteAccessQualifiedName | constants.rb:70:3:72:5 | Mod5 | Mod3::Mod5 | | constants.rb:71:5:71:14 | FOURTY_SIX | Mod1::Mod3::Mod5::FOURTY_SIX | | constants.rb:71:5:71:14 | FOURTY_SIX | Mod3::Mod5::FOURTY_SIX | +| constants.rb:79:1:79:1 | A | A | +| constants.rb:80:1:80:1 | B | B | +| constants.rb:81:1:81:1 | C | C | +arrayConstant +| constants.rb:20:13:20:37 | call to [] | constants.rb:20:13:20:37 | call to [] | +| constants.rb:78:5:78:13 | call to [] | constants.rb:78:5:78:13 | call to [] | +| constants.rb:79:5:79:13 | call to [] | constants.rb:79:5:79:13 | call to [] | +| constants.rb:80:5:80:5 | a | constants.rb:78:5:78:13 | call to [] | +| constants.rb:81:5:81:5 | A | constants.rb:79:5:79:13 | call to [] | diff --git a/ruby/ql/test/library-tests/ast/constants/constants.ql b/ruby/ql/test/library-tests/ast/constants/constants.ql index 66c0d230d99..37140a957a3 100644 --- a/ruby/ql/test/library-tests/ast/constants/constants.ql +++ b/ruby/ql/test/library-tests/ast/constants/constants.ql @@ -1,5 +1,6 @@ import ruby import codeql.ruby.ast.internal.Module as M +import codeql.ruby.ast.internal.Constant query predicate constantAccess(ConstantAccess a, string kind, string name, string cls) { ( @@ -20,3 +21,5 @@ query predicate constantValue(ConstantReadAccess a, Expr e) { e = a.getValue() } query predicate constantWriteAccessQualifiedName(ConstantWriteAccess w, string qualifiedName) { w.getAQualifiedName() = qualifiedName } + +query predicate arrayConstant = isArrayConstant/2; diff --git a/ruby/ql/test/library-tests/ast/constants/constants.rb b/ruby/ql/test/library-tests/ast/constants/constants.rb index 08e0d4216a9..fce55bccd00 100644 --- a/ruby/ql/test/library-tests/ast/constants/constants.rb +++ b/ruby/ql/test/library-tests/ast/constants/constants.rb @@ -72,3 +72,11 @@ module Mod4 end @@fourty_six = Mod3::FOURTY_SIX end + +# Array constants + +a = [1, 2, 3] +A = [1, 2, 3] +B = a +C = A +b = B \ No newline at end of file From 5f17d8370c1b8f3b547ba290c970bd5e8691952d Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Tue, 12 Jul 2022 13:19:13 +1200 Subject: [PATCH 326/465] Ruby: Small change to isArrayExpr --- .../lib/codeql/ruby/ast/internal/Constant.qll | 7 +++++- .../ast/constants/constants.expected | 22 +++++++++++++++++++ .../library-tests/ast/constants/constants.rb | 7 +++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll index ae1d9f5989c..e7e303a9fa6 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll @@ -552,5 +552,10 @@ predicate isArrayExpr(Expr e, ArrayLiteralCfgNode arr) { // We map from A to a via ConstantReadAccess::getValue, yielding the Expr a. // To get to [...] we need to go via getSource(ExprCfgNode e), so we find a // CFG node for a and call `isArrayConstant`. - isArrayConstant(e.getAControlFlowNode(), arr) + // + // The use of `forex` is intended to ensure that a is an array constant in all + // control flow paths. + // Note(hmac): I don't think this is necessary, as `getSource` will not return + // results if the source is a phi node. + forex(ExprCfgNode n | n = e.getAControlFlowNode() | isArrayConstant(n, arr)) } diff --git a/ruby/ql/test/library-tests/ast/constants/constants.expected b/ruby/ql/test/library-tests/ast/constants/constants.expected index 0fe1b324232..3f189cc26fd 100644 --- a/ruby/ql/test/library-tests/ast/constants/constants.expected +++ b/ruby/ql/test/library-tests/ast/constants/constants.expected @@ -78,23 +78,41 @@ getConst | constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | FOURTY_ONE | constants.rb:48:18:48:19 | 41 | | constants.rb:62:3:64:5 | Mod1::Mod3 | FOURTY_FIVE | constants.rb:63:19:63:20 | 45 | | constants.rb:70:3:72:5 | Mod1::Mod3::Mod5 | FOURTY_SIX | constants.rb:71:18:71:19 | 46 | +| file://:0:0:0:0 | Object | A | constants.rb:79:5:79:13 | [...] | +| file://:0:0:0:0 | Object | B | constants.rb:80:5:80:5 | a | +| file://:0:0:0:0 | Object | C | constants.rb:81:5:81:5 | A | | file://:0:0:0:0 | Object | GREETING | constants.rb:17:12:17:64 | ... + ... | lookupConst | constants.rb:1:1:15:3 | ModuleA | CONST_B | constants.rb:6:15:6:23 | "const_b" | | constants.rb:1:1:15:3 | ModuleA | FOURTY_FOUR | constants.rb:53:17:53:29 | "fourty-four" | +| constants.rb:2:5:4:7 | ModuleA::ClassA | A | constants.rb:79:5:79:13 | [...] | +| constants.rb:2:5:4:7 | ModuleA::ClassA | B | constants.rb:80:5:80:5 | a | +| constants.rb:2:5:4:7 | ModuleA::ClassA | C | constants.rb:81:5:81:5 | A | | constants.rb:2:5:4:7 | ModuleA::ClassA | CONST_A | constants.rb:3:19:3:27 | "const_a" | | constants.rb:2:5:4:7 | ModuleA::ClassA | GREETING | constants.rb:17:12:17:64 | ... + ... | | constants.rb:8:5:14:7 | ModuleA::ModuleB | MAX_SIZE | constants.rb:39:30:39:33 | 1024 | +| constants.rb:12:9:13:11 | ModuleA::ModuleB::ClassC | A | constants.rb:79:5:79:13 | [...] | +| constants.rb:12:9:13:11 | ModuleA::ModuleB::ClassC | B | constants.rb:80:5:80:5 | a | +| constants.rb:12:9:13:11 | ModuleA::ModuleB::ClassC | C | constants.rb:81:5:81:5 | A | | constants.rb:12:9:13:11 | ModuleA::ModuleB::ClassC | GREETING | constants.rb:17:12:17:64 | ... + ... | +| constants.rb:31:1:33:3 | ModuleA::ClassD | A | constants.rb:79:5:79:13 | [...] | +| constants.rb:31:1:33:3 | ModuleA::ClassD | B | constants.rb:80:5:80:5 | a | +| constants.rb:31:1:33:3 | ModuleA::ClassD | C | constants.rb:81:5:81:5 | A | | constants.rb:31:1:33:3 | ModuleA::ClassD | CONST_A | constants.rb:3:19:3:27 | "const_a" | | constants.rb:31:1:33:3 | ModuleA::ClassD | FOURTY_TWO | constants.rb:32:16:32:17 | 42 | | constants.rb:31:1:33:3 | ModuleA::ClassD | GREETING | constants.rb:17:12:17:64 | ... + ... | | constants.rb:35:1:37:3 | ModuleA::ModuleC | FOURTY_THREE | constants.rb:36:18:36:19 | 43 | +| constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | A | constants.rb:79:5:79:13 | [...] | +| constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | B | constants.rb:80:5:80:5 | a | +| constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | C | constants.rb:81:5:81:5 | A | | constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | FOURTY_FOUR | constants.rb:56:19:56:20 | 44 | | constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | FOURTY_ONE | constants.rb:48:18:48:19 | 41 | | constants.rb:54:3:58:5 | ModuleA::ModuleB::ClassB | GREETING | constants.rb:17:12:17:64 | ... + ... | | constants.rb:62:3:64:5 | Mod1::Mod3 | FOURTY_FIVE | constants.rb:63:19:63:20 | 45 | | constants.rb:70:3:72:5 | Mod1::Mod3::Mod5 | FOURTY_SIX | constants.rb:71:18:71:19 | 46 | +| file://:0:0:0:0 | Object | A | constants.rb:79:5:79:13 | [...] | +| file://:0:0:0:0 | Object | B | constants.rb:80:5:80:5 | a | +| file://:0:0:0:0 | Object | C | constants.rb:81:5:81:5 | A | | file://:0:0:0:0 | Object | GREETING | constants.rb:17:12:17:64 | ... + ... | constantValue | constants.rb:17:22:17:45 | CONST_A | constants.rb:3:19:3:27 | "const_a" | @@ -108,6 +126,8 @@ constantValue | constants.rb:57:21:57:31 | FOURTY_FOUR | constants.rb:53:17:53:29 | "fourty-four" | | constants.rb:57:21:57:31 | FOURTY_FOUR | constants.rb:56:19:56:20 | 44 | | constants.rb:65:19:65:35 | FOURTY_FIVE | constants.rb:63:19:63:20 | 45 | +| constants.rb:81:5:81:5 | A | constants.rb:79:5:79:13 | [...] | +| constants.rb:82:5:82:5 | B | constants.rb:80:5:80:5 | a | constantWriteAccessQualifiedName | constants.rb:1:1:15:3 | ModuleA | ModuleA | | constants.rb:2:5:4:7 | ClassA | ModuleA::ClassA | @@ -149,3 +169,5 @@ arrayConstant | constants.rb:79:5:79:13 | call to [] | constants.rb:79:5:79:13 | call to [] | | constants.rb:80:5:80:5 | a | constants.rb:78:5:78:13 | call to [] | | constants.rb:81:5:81:5 | A | constants.rb:79:5:79:13 | call to [] | +| constants.rb:82:5:82:5 | B | constants.rb:78:5:78:13 | call to [] | +| constants.rb:85:7:85:7 | b | constants.rb:78:5:78:13 | call to [] | diff --git a/ruby/ql/test/library-tests/ast/constants/constants.rb b/ruby/ql/test/library-tests/ast/constants/constants.rb index fce55bccd00..359a861eb1e 100644 --- a/ruby/ql/test/library-tests/ast/constants/constants.rb +++ b/ruby/ql/test/library-tests/ast/constants/constants.rb @@ -79,4 +79,9 @@ a = [1, 2, 3] A = [1, 2, 3] B = a C = A -b = B \ No newline at end of file +b = B + +if condition + c = b +end +c # not recognised From 4cfaa86d5d4329d32455fd0c83aba6f80de1f066 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Wed, 13 Jul 2022 12:39:47 +1200 Subject: [PATCH 327/465] Ruby: Update new-style barrier-guard --- ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll index 52e9c48779d..b86f976d119 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll @@ -84,13 +84,16 @@ deprecated class StringConstCompare extends DataFlow::BarrierGuard, } private predicate stringConstArrayInclusionCall(CfgNodes::ExprCfgNode g, CfgNode e, boolean branch) { - exists(CfgNodes::ExprNodes::MethodCallCfgNode mc, ArrayLiteral aLit | + exists(CfgNodes::ExprNodes::MethodCallCfgNode mc | mc = g and mc.getExpr().getMethodName() = "include?" and - [mc.getExpr().getReceiver(), mc.getExpr().getReceiver().(ConstantReadAccess).getValue()] = aLit - | - forall(Expr elem | elem = aLit.getAnElement() | elem instanceof StringLiteral) and mc.getArgument(0) = e + | + exists(ExprNodes::ArrayLiteralCfgNode arr | isArrayConstant(mc.getReceiver(), arr) | + forall(ExprCfgNode elem | elem = arr.getAnArgument() | + elem instanceof ExprNodes::StringLiteralCfgNode + ) + ) ) and branch = true } From b9fc82a741c74b2b812cfe9a2e1ae8ae47f14931 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Wed, 13 Jul 2022 12:56:03 +1200 Subject: [PATCH 328/465] Ruby: Test both old and new-style barrier guards --- .../codeql/ruby/dataflow/BarrierGuards.qll | 24 ++----------------- .../barrier-guards/barrier-guards.expected | 11 +++++++++ .../dataflow/barrier-guards/barrier-guards.ql | 16 +++++++++++++ 3 files changed, 29 insertions(+), 22 deletions(-) create mode 100644 ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.ql diff --git a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll index b86f976d119..e32eb11fa1a 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll @@ -64,19 +64,7 @@ deprecated class StringConstCompare extends DataFlow::BarrierGuard, // The value of the condition that results in the node being validated. private boolean checkedBranch; - StringConstCompare() { - exists(CfgNodes::ExprNodes::StringLiteralCfgNode strLitNode | - this.getExpr() instanceof EqExpr and checkedBranch = true - or - this.getExpr() instanceof CaseEqExpr and checkedBranch = true - or - this.getExpr() instanceof NEExpr and checkedBranch = false - | - this.getLeftOperand() = strLitNode and this.getRightOperand() = checkedNode - or - this.getLeftOperand() = checkedNode and this.getRightOperand() = strLitNode - ) - } + StringConstCompare() { stringConstCompare(this, checkedNode, checkedBranch) } override predicate checks(CfgNode expr, boolean branch) { expr = checkedNode and branch = checkedBranch @@ -138,15 +126,7 @@ deprecated class StringConstArrayInclusionCall extends DataFlow::BarrierGuard, CfgNodes::ExprNodes::MethodCallCfgNode { private CfgNode checkedNode; - StringConstArrayInclusionCall() { - this.getMethodName() = "include?" and - this.getArgument(0) = checkedNode and - exists(ExprNodes::ArrayLiteralCfgNode arr | isArrayConstant(this.getReceiver(), arr) | - forall(ExprCfgNode elem | elem = arr.getAnArgument() | - elem instanceof ExprNodes::StringLiteralCfgNode - ) - ) - } + StringConstArrayInclusionCall() { stringConstArrayInclusionCall(this, checkedNode, _) } override predicate checks(CfgNode expr, boolean branch) { expr = checkedNode and branch = true } } diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected index fcf95346a5a..ea99ed7d669 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected @@ -1,3 +1,5 @@ +WARNING: Type BarrierGuard has been deprecated and may be removed in future (barrier-guards.ql:8,3-15) +oldStyleBarrierGuards | barrier-guards.rb:3:4:3:15 | ... == ... | barrier-guards.rb:4:5:4:7 | foo | barrier-guards.rb:3:4:3:6 | foo | true | | barrier-guards.rb:9:4:9:24 | call to include? | barrier-guards.rb:10:5:10:7 | foo | barrier-guards.rb:9:21:9:23 | foo | true | | barrier-guards.rb:15:4:15:15 | ... != ... | barrier-guards.rb:18:5:18:7 | foo | barrier-guards.rb:15:4:15:6 | foo | false | @@ -6,3 +8,12 @@ | barrier-guards.rb:37:4:37:20 | call to include? | barrier-guards.rb:38:5:38:7 | foo | barrier-guards.rb:37:17:37:19 | foo | true | | barrier-guards.rb:43:4:43:15 | ... == ... | barrier-guards.rb:45:9:45:11 | foo | barrier-guards.rb:43:4:43:6 | foo | true | | barrier-guards.rb:70:4:70:21 | call to include? | barrier-guards.rb:71:5:71:7 | foo | barrier-guards.rb:70:18:70:20 | foo | true | +newStyleBarrierGuards +| barrier-guards.rb:4:5:4:7 | foo | +| barrier-guards.rb:10:5:10:7 | foo | +| barrier-guards.rb:18:5:18:7 | foo | +| barrier-guards.rb:24:5:24:7 | foo | +| barrier-guards.rb:28:5:28:7 | foo | +| barrier-guards.rb:38:5:38:7 | foo | +| barrier-guards.rb:45:9:45:11 | foo | +| barrier-guards.rb:71:5:71:7 | foo | diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.ql b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.ql new file mode 100644 index 00000000000..84a962ade35 --- /dev/null +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.ql @@ -0,0 +1,16 @@ +import codeql.ruby.dataflow.internal.DataFlowPublic +import codeql.ruby.dataflow.BarrierGuards +import codeql.ruby.controlflow.CfgNodes +import codeql.ruby.controlflow.ControlFlowGraph +import codeql.ruby.DataFlow + +query predicate oldStyleBarrierGuards( + BarrierGuard g, DataFlow::Node guardedNode, ExprCfgNode expr, boolean branch +) { + g.checks(expr, branch) and guardedNode = g.getAGuardedNode() +} + +query predicate newStyleBarrierGuards(DataFlow::Node n) { + n instanceof StringConstCompareBarrier or + n instanceof StringConstArrayInclusionCallBarrier +} From ea95e2e1d0a65ba680b2cb3f2b8796c2633aef59 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Wed, 13 Jul 2022 18:01:06 +1200 Subject: [PATCH 329/465] Ruby: Use InclusionTests library in barrier guards --- .../lib/codeql/ruby/dataflow/BarrierGuards.qll | 18 ++++++++++-------- .../barrier-guards/barrier-guards.expected | 3 +++ .../dataflow/barrier-guards/barrier-guards.rb | 12 ++++++++++++ 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll index e32eb11fa1a..c79e4311489 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/BarrierGuards.qll @@ -6,6 +6,7 @@ private import codeql.ruby.CFG private import codeql.ruby.controlflow.CfgNodes private import codeql.ruby.dataflow.SSA private import codeql.ruby.ast.internal.Constant +private import codeql.ruby.InclusionTests private predicate stringConstCompare(CfgNodes::ExprCfgNode g, CfgNode e, boolean branch) { exists(CfgNodes::ExprNodes::ComparisonOperationCfgNode c | @@ -72,18 +73,19 @@ deprecated class StringConstCompare extends DataFlow::BarrierGuard, } private predicate stringConstArrayInclusionCall(CfgNodes::ExprCfgNode g, CfgNode e, boolean branch) { - exists(CfgNodes::ExprNodes::MethodCallCfgNode mc | - mc = g and - mc.getExpr().getMethodName() = "include?" and - mc.getArgument(0) = e + exists(InclusionTest t | + t.asExpr() = g and + e = t.getContainedNode().asExpr() and + branch = t.getPolarity() | - exists(ExprNodes::ArrayLiteralCfgNode arr | isArrayConstant(mc.getReceiver(), arr) | + exists(ExprNodes::ArrayLiteralCfgNode arr | + isArrayConstant(t.getContainerNode().asExpr(), arr) + | forall(ExprCfgNode elem | elem = arr.getAnArgument() | elem instanceof ExprNodes::StringLiteralCfgNode ) ) - ) and - branch = true + ) } /** @@ -126,7 +128,7 @@ deprecated class StringConstArrayInclusionCall extends DataFlow::BarrierGuard, CfgNodes::ExprNodes::MethodCallCfgNode { private CfgNode checkedNode; - StringConstArrayInclusionCall() { stringConstArrayInclusionCall(this, checkedNode, _) } + StringConstArrayInclusionCall() { stringConstArrayInclusionCall(this, checkedNode, true) } override predicate checks(CfgNode expr, boolean branch) { expr = checkedNode and branch = true } } diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected index ea99ed7d669..783d414dad6 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.expected @@ -8,6 +8,7 @@ oldStyleBarrierGuards | barrier-guards.rb:37:4:37:20 | call to include? | barrier-guards.rb:38:5:38:7 | foo | barrier-guards.rb:37:17:37:19 | foo | true | | barrier-guards.rb:43:4:43:15 | ... == ... | barrier-guards.rb:45:9:45:11 | foo | barrier-guards.rb:43:4:43:6 | foo | true | | barrier-guards.rb:70:4:70:21 | call to include? | barrier-guards.rb:71:5:71:7 | foo | barrier-guards.rb:70:18:70:20 | foo | true | +| barrier-guards.rb:82:4:82:25 | ... != ... | barrier-guards.rb:83:5:83:7 | foo | barrier-guards.rb:82:15:82:17 | foo | true | newStyleBarrierGuards | barrier-guards.rb:4:5:4:7 | foo | | barrier-guards.rb:10:5:10:7 | foo | @@ -17,3 +18,5 @@ newStyleBarrierGuards | barrier-guards.rb:38:5:38:7 | foo | | barrier-guards.rb:45:9:45:11 | foo | | barrier-guards.rb:71:5:71:7 | foo | +| barrier-guards.rb:83:5:83:7 | foo | +| barrier-guards.rb:91:5:91:7 | foo | diff --git a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb index a3f13b48639..47b96da22dd 100644 --- a/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb +++ b/ruby/ql/test/library-tests/dataflow/barrier-guards/barrier-guards.rb @@ -79,6 +79,18 @@ else foo end +if foos.index(foo) != nil + foo +else + foo +end + +if foos.index(foo)r == nil + foo +else + foo +end + bars = ["bar"] if condition From 49aab5189362f85d6b0c320b6b031f14eb80847d Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Wed, 13 Jul 2022 18:02:33 +1200 Subject: [PATCH 330/465] Ruby: Make helper predicate private --- ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll b/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll index e7e303a9fa6..53355695e57 100644 --- a/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll +++ b/ruby/ql/lib/codeql/ruby/ast/internal/Constant.qll @@ -533,7 +533,7 @@ predicate isArrayConstant(ExprCfgNode e, ArrayLiteralCfgNode arr) { /** * Holds if the expression `e` refers to an array constructed from the array literal `arr`. */ -predicate isArrayExpr(Expr e, ArrayLiteralCfgNode arr) { +private predicate isArrayExpr(Expr e, ArrayLiteralCfgNode arr) { // e = [...] e = arr.getExpr() or From 2850b35a04cc7c457e63369dbf9932094c36ecb5 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 25 May 2022 14:07:38 +0200 Subject: [PATCH 331/465] update, and fix, the autobuilders by using the new --also-match option --- ql/autobuilder/src/main.rs | 30 ++++++++++++++++++++---------- ruby/autobuilder/src/main.rs | 18 ++++++++++++++++-- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/ql/autobuilder/src/main.rs b/ql/autobuilder/src/main.rs index 45977b3792d..4bb03eb0ed4 100644 --- a/ql/autobuilder/src/main.rs +++ b/ql/autobuilder/src/main.rs @@ -15,29 +15,39 @@ fn main() -> std::io::Result<()> { let mut cmd = Command::new(codeql); cmd.arg("database") .arg("index-files") + .arg("--include-extension=.ql") + .arg("--include-extension=.qll") + .arg("--include-extension=.dbscheme") + .arg("--include=**/qlpack.yml") .arg("--size-limit=5m") .arg("--language=ql") .arg("--working-dir=.") .arg(db); - let mut has_include_dir = false; // TODO: This is a horrible hack, wait for the post-merge discussion in https://github.com/github/codeql/pull/7444 to be resolved + let pwd = env::current_dir()?; for line in env::var("LGTM_INDEX_FILTERS") .unwrap_or_default() .split('\n') { if let Some(stripped) = line.strip_prefix("include:") { - cmd.arg("--include").arg(stripped); - has_include_dir = true; + let path = pwd + .join(stripped) + .join("**") + .into_os_string() + .into_string() + .unwrap(); + cmd.arg("--also-match").arg(path); } else if let Some(stripped) = line.strip_prefix("exclude:") { - cmd.arg("--exclude").arg(stripped); + let path = pwd + .join(stripped) + .join("**") + .into_os_string() + .into_string() + .unwrap(); + // the same as above, but starting with "!" + cmd.arg("--also-match").arg("!".to_owned() + &path); } } - if !has_include_dir { - cmd.arg("--include-extension=.ql") - .arg("--include-extension=.qll") - .arg("--include-extension=.dbscheme") - .arg("--include=**/qlpack.yml"); - } let exit = &cmd.spawn()?.wait()?; std::process::exit(exit.code().unwrap_or(1)) } diff --git a/ruby/autobuilder/src/main.rs b/ruby/autobuilder/src/main.rs index 18892ae2d5c..6573f4cfd33 100644 --- a/ruby/autobuilder/src/main.rs +++ b/ruby/autobuilder/src/main.rs @@ -24,14 +24,28 @@ fn main() -> std::io::Result<()> { .arg("--working-dir=.") .arg(db); + let pwd = env::current_dir()?; for line in env::var("LGTM_INDEX_FILTERS") .unwrap_or_default() .split('\n') { if let Some(stripped) = line.strip_prefix("include:") { - cmd.arg("--include").arg(stripped); + let path = pwd + .join(stripped) + .join("**") + .into_os_string() + .into_string() + .unwrap(); + cmd.arg("--also-match").arg(path); } else if let Some(stripped) = line.strip_prefix("exclude:") { - cmd.arg("--exclude").arg(stripped); + let path = pwd + .join(stripped) + .join("**") + .into_os_string() + .into_string() + .unwrap(); + // the same as above, but starting with "!" + cmd.arg("--also-match").arg("!".to_owned() + &path); } } let exit = &cmd.spawn()?.wait()?; From 878168384ee82c1a00d28bb4c352c6a9a371658d Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 25 May 2022 14:07:59 +0200 Subject: [PATCH 332/465] remove tools:latest from codeql-action in QL-for-QL --- .github/workflows/ql-for-ql-build.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index 95b93dd772c..2d96fbfa797 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -19,7 +19,6 @@ jobs: uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980 with: languages: javascript # does not matter - tools: latest - name: Get CodeQL version id: get-codeql-version run: | @@ -184,7 +183,6 @@ jobs: languages: ql db-location: ${{ runner.temp }}/db config-file: ./ql-for-ql-config.yml - tools: latest - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@aa93aea877e5fb8841bcb1193f672abf6e9f2980 @@ -224,4 +222,4 @@ jobs: uses: actions/upload-artifact@v3 with: name: combined.sarif - path: combined.sarif + path: combined.sarif \ No newline at end of file From eb0340dcb6ba5154f55335e9963961e6e9becf3a Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 30 May 2022 22:18:00 +0200 Subject: [PATCH 333/465] get excludes to work properly --- ql/autobuilder/src/main.rs | 25 +++++++++---------------- ruby/autobuilder/src/main.rs | 25 +++++++++---------------- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/ql/autobuilder/src/main.rs b/ql/autobuilder/src/main.rs index 4bb03eb0ed4..7cc4900a6b7 100644 --- a/ql/autobuilder/src/main.rs +++ b/ql/autobuilder/src/main.rs @@ -24,30 +24,23 @@ fn main() -> std::io::Result<()> { .arg("--working-dir=.") .arg(db); - let pwd = env::current_dir()?; for line in env::var("LGTM_INDEX_FILTERS") .unwrap_or_default() .split('\n') { if let Some(stripped) = line.strip_prefix("include:") { - let path = pwd - .join(stripped) - .join("**") - .into_os_string() - .into_string() - .unwrap(); - cmd.arg("--also-match").arg(path); + cmd.arg("--also-match").arg(absolutelyfy(stripped)); } else if let Some(stripped) = line.strip_prefix("exclude:") { - let path = pwd - .join(stripped) - .join("**") - .into_os_string() - .into_string() - .unwrap(); - // the same as above, but starting with "!" - cmd.arg("--also-match").arg("!".to_owned() + &path); + cmd.arg("--exclude").arg(stripped); } } let exit = &cmd.spawn()?.wait()?; std::process::exit(exit.code().unwrap_or(1)) } + +// converts the relative path `stripped` to an absolute path by prepending the working directory +fn absolutelyfy(stripped: &str) -> String { + let pwd = env::current_dir().unwrap(); + + pwd.join(stripped).into_os_string().into_string().unwrap() +} diff --git a/ruby/autobuilder/src/main.rs b/ruby/autobuilder/src/main.rs index 6573f4cfd33..496c34a0594 100644 --- a/ruby/autobuilder/src/main.rs +++ b/ruby/autobuilder/src/main.rs @@ -24,30 +24,23 @@ fn main() -> std::io::Result<()> { .arg("--working-dir=.") .arg(db); - let pwd = env::current_dir()?; for line in env::var("LGTM_INDEX_FILTERS") .unwrap_or_default() .split('\n') { if let Some(stripped) = line.strip_prefix("include:") { - let path = pwd - .join(stripped) - .join("**") - .into_os_string() - .into_string() - .unwrap(); - cmd.arg("--also-match").arg(path); + cmd.arg("--also-match").arg(absolutelyfy(stripped)); } else if let Some(stripped) = line.strip_prefix("exclude:") { - let path = pwd - .join(stripped) - .join("**") - .into_os_string() - .into_string() - .unwrap(); - // the same as above, but starting with "!" - cmd.arg("--also-match").arg("!".to_owned() + &path); + cmd.arg("--exclude").arg(stripped); } } let exit = &cmd.spawn()?.wait()?; std::process::exit(exit.code().unwrap_or(1)) } + +// converts the relative path `stripped` to an absolute path by prepending the working directory +fn absolutelyfy(stripped: &str) -> String { + let pwd = env::current_dir().unwrap(); + + pwd.join(stripped).into_os_string().into_string().unwrap() +} From 047b14e310bef5eee5ce07d18b3f6dca01de38da Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Tue, 31 May 2022 10:25:48 +0000 Subject: [PATCH 334/465] get the autobuilders to work after introducing test-cases --- ql/autobuilder/src/main.rs | 11 ++--------- ruby/autobuilder/src/main.rs | 11 ++--------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/ql/autobuilder/src/main.rs b/ql/autobuilder/src/main.rs index 7cc4900a6b7..df47cc33184 100644 --- a/ql/autobuilder/src/main.rs +++ b/ql/autobuilder/src/main.rs @@ -29,18 +29,11 @@ fn main() -> std::io::Result<()> { .split('\n') { if let Some(stripped) = line.strip_prefix("include:") { - cmd.arg("--also-match").arg(absolutelyfy(stripped)); + cmd.arg("--also-match=".to_owned() + stripped); } else if let Some(stripped) = line.strip_prefix("exclude:") { - cmd.arg("--exclude").arg(stripped); + cmd.arg("--exclude=".to_owned() + stripped); } } let exit = &cmd.spawn()?.wait()?; std::process::exit(exit.code().unwrap_or(1)) } - -// converts the relative path `stripped` to an absolute path by prepending the working directory -fn absolutelyfy(stripped: &str) -> String { - let pwd = env::current_dir().unwrap(); - - pwd.join(stripped).into_os_string().into_string().unwrap() -} diff --git a/ruby/autobuilder/src/main.rs b/ruby/autobuilder/src/main.rs index 496c34a0594..8f0f1b48d0d 100644 --- a/ruby/autobuilder/src/main.rs +++ b/ruby/autobuilder/src/main.rs @@ -29,18 +29,11 @@ fn main() -> std::io::Result<()> { .split('\n') { if let Some(stripped) = line.strip_prefix("include:") { - cmd.arg("--also-match").arg(absolutelyfy(stripped)); + cmd.arg("--also-match=".to_owned() + stripped); } else if let Some(stripped) = line.strip_prefix("exclude:") { - cmd.arg("--exclude").arg(stripped); + cmd.arg("--exclude=".to_owned() + stripped); } } let exit = &cmd.spawn()?.wait()?; std::process::exit(exit.code().unwrap_or(1)) } - -// converts the relative path `stripped` to an absolute path by prepending the working directory -fn absolutelyfy(stripped: &str) -> String { - let pwd = env::current_dir().unwrap(); - - pwd.join(stripped).into_os_string().into_string().unwrap() -} From dded3af3d8ccead9e640652ce18017bd45b16025 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 13 Jul 2022 09:57:17 +0200 Subject: [PATCH 335/465] remove more false positives from the ql/missing-parameter-qldoc query --- ql/ql/src/queries/style/MissingParameterInQlDoc.ql | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql index b378803822a..c2b1e80fe53 100644 --- a/ql/ql/src/queries/style/MissingParameterInQlDoc.ql +++ b/ql/ql/src/queries/style/MissingParameterInQlDoc.ql @@ -44,7 +44,10 @@ private string getAMentionedNonParameter(Predicate p) { not result.toLowerCase() = getAParameterName(p).toLowerCase() and // keywords not result = - ["true", "false", "NaN", "this", "forall", "exists", "null", "break", "return", "not"] and + [ + "true", "false", "NaN", "this", "forall", "exists", "null", "break", "return", "not", "if", + "then", "else", "import" + ] and not result = any(Aggregate a).getKind() and // min, max, sum, count, etc. not result = getMentionedThings(p.getLocation().getFile()) and not result = any(Annotation a).getName() and // private, final, etc. @@ -66,7 +69,7 @@ private string getMentionedThings(File file) { private string getAnUndocumentedParameter(Predicate p) { result = getAParameterName(p) and not result.toLowerCase() = getADocumentedParameter(p).toLowerCase() and - not result = ["config", "conf", "cfg"] and // DataFlow configurations are often undocumented, and that's fine. + not result = ["config", "conf", "cfg", "t", "t2"] and // DataFlow configurations / type-trackers are often undocumented, and that's fine. not ( // "the given" often refers to the first parameter. p.getQLDoc().getContents().regexpMatch("(?s).*\\bthe given\\b.*") and @@ -85,7 +88,7 @@ private string getMentionedNonParameters(Predicate p) { } from Predicate p -where not p.getLocation().getFile().getBaseName() = "Aliases.qll" // these are OK +where not p.getLocation().getFile().getBaseName() in ["Aliases.qll", "TreeSitter.qll"] // these are OK select p, "The QLDoc has no documentation for " + getUndocumentedParameters(p) + ", but the QLDoc mentions " + getMentionedNonParameters(p) From c4f44bb67fbd989c61610011a12af863efd50b1b Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 13 Jul 2022 10:01:26 +0200 Subject: [PATCH 336/465] sync files --- python/ql/src/Security/CWE-020/HostnameRegexpShared.qll | 2 +- ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll b/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll index 2192951f76d..5e9bc406512 100644 --- a/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll +++ b/python/ql/src/Security/CWE-020/HostnameRegexpShared.qll @@ -53,7 +53,7 @@ predicate matchesBeginningOfString(RegExpTerm term) { } /** - * Holds if the given sequence contains top-level domain preceded by a dot, such as `.com`, + * Holds if the given sequence `seq` contains top-level domain preceded by a dot, such as `.com`, * excluding cases where this is at the very beginning of the regexp. * * `i` is bound to the index of the last child in the top-level domain part. diff --git a/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll b/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll index 2192951f76d..5e9bc406512 100644 --- a/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll +++ b/ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll @@ -53,7 +53,7 @@ predicate matchesBeginningOfString(RegExpTerm term) { } /** - * Holds if the given sequence contains top-level domain preceded by a dot, such as `.com`, + * Holds if the given sequence `seq` contains top-level domain preceded by a dot, such as `.com`, * excluding cases where this is at the very beginning of the regexp. * * `i` is bound to the index of the last child in the top-level domain part. From cd5fbe633f2206b264ebcfb7ea25eca5b08f915c Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Wed, 13 Jul 2022 10:12:52 +0200 Subject: [PATCH 337/465] update locations in test after merging in the focus-location-pr --- .../MissingParameterInQlDoc/MissingParameterInQlDoc.expected | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected index cca5b457ec4..4307178da72 100644 --- a/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected +++ b/ql/ql/test/queries/style/MissingParameterInQlDoc/MissingParameterInQlDoc.expected @@ -1,2 +1,2 @@ -| Foo.qll:5:1:5:50 | ClasslessPredicate test2 | The QLDoc has no documentation for param2, but the QLDoc mentions par2 | -| Foo.qll:14:1:14:50 | ClasslessPredicate test5 | The QLDoc has no documentation for param2, but the QLDoc mentions par2 | +| Foo.qll:5:11:5:15 | ClasslessPredicate test2 | The QLDoc has no documentation for param2, but the QLDoc mentions par2 | +| Foo.qll:14:11:14:15 | ClasslessPredicate test5 | The QLDoc has no documentation for param2, but the QLDoc mentions par2 | From fd10947ca0f1f17d42436a7173c734f2d75cd37d Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Mon, 11 Jul 2022 16:22:54 +0200 Subject: [PATCH 338/465] use small steps in TypeBackTracker correctly --- .../lib/semmle/javascript/dataflow/TypeTracking.qll | 2 +- .../UnsafeHtmlConstructionCustomizations.qll | 2 +- .../src/Security/CWE-094/ImproperCodeSanitization.ql | 2 +- .../UnsafeHtmlConstruction.expected | 12 ++++++++++++ .../Security/CWE-079/UnsafeHtmlConstruction/main.js | 8 ++++++++ 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/dataflow/TypeTracking.qll b/javascript/ql/lib/semmle/javascript/dataflow/TypeTracking.qll index 896f0177ec3..12aa8d09ed1 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/TypeTracking.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/TypeTracking.qll @@ -312,7 +312,7 @@ class TypeBackTracker extends TTypeBackTracker { * result = < some API call >.getArgument(< n >) * or * exists (DataFlow::TypeBackTracker t2 | - * t = t2.smallstep(result, myType(t2)) + * t2 = t.smallstep(result, myType(t2)) * ) * } * diff --git a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll index d594da271b8..fd549429e4a 100644 --- a/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll +++ b/javascript/ql/lib/semmle/javascript/security/dataflow/UnsafeHtmlConstructionCustomizations.qll @@ -80,7 +80,7 @@ module UnsafeHtmlConstruction { t.start() and result = sink or - exists(DataFlow::TypeBackTracker t2 | t = t2.smallstep(result, isUsedInXssSink(t2, sink))) + exists(DataFlow::TypeBackTracker t2 | t2 = t.smallstep(result, isUsedInXssSink(t2, sink))) or exists(DataFlow::TypeBackTracker t2 | t.continue() = t2 and diff --git a/javascript/ql/src/Security/CWE-094/ImproperCodeSanitization.ql b/javascript/ql/src/Security/CWE-094/ImproperCodeSanitization.ql index 886c78b0161..694e827ba41 100644 --- a/javascript/ql/src/Security/CWE-094/ImproperCodeSanitization.ql +++ b/javascript/ql/src/Security/CWE-094/ImproperCodeSanitization.ql @@ -50,7 +50,7 @@ private DataFlow::Node endsInCodeInjectionSink(DataFlow::TypeBackTracker t) { not result instanceof StringOps::ConcatenationRoot // the heuristic CodeInjection sink looks for string-concats, we are not interrested in those here. ) or - exists(DataFlow::TypeBackTracker t2 | t = t2.smallstep(result, endsInCodeInjectionSink(t2))) + exists(DataFlow::TypeBackTracker t2 | t2 = t.smallstep(result, endsInCodeInjectionSink(t2))) } /** diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected index c604f4ab2d2..94f1fe314b0 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/UnsafeHtmlConstruction.expected @@ -50,6 +50,12 @@ nodes | main.js:79:34:79:36 | val | | main.js:81:35:81:37 | val | | main.js:81:35:81:37 | val | +| main.js:89:21:89:21 | x | +| main.js:90:23:90:23 | x | +| main.js:90:23:90:23 | x | +| main.js:93:43:93:43 | x | +| main.js:93:43:93:43 | x | +| main.js:94:31:94:31 | x | | typed.ts:1:39:1:39 | s | | typed.ts:1:39:1:39 | s | | typed.ts:2:29:2:29 | s | @@ -115,6 +121,11 @@ edges | main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | | main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | | main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | +| main.js:89:21:89:21 | x | main.js:90:23:90:23 | x | +| main.js:89:21:89:21 | x | main.js:90:23:90:23 | x | +| main.js:93:43:93:43 | x | main.js:94:31:94:31 | x | +| main.js:93:43:93:43 | x | main.js:94:31:94:31 | x | +| main.js:94:31:94:31 | x | main.js:89:21:89:21 | x | | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | @@ -141,5 +152,6 @@ edges | main.js:62:19:62:31 | settings.name | main.js:56:28:56:34 | options | main.js:62:19:62:31 | settings.name | $@ based on $@ might later cause $@. | main.js:62:19:62:31 | settings.name | HTML construction | main.js:56:28:56:34 | options | library input | main.js:62:11:62:40 | "" + ... "" | cross-site scripting | | main.js:67:63:67:69 | attrVal | main.js:66:35:66:41 | attrVal | main.js:67:63:67:69 | attrVal | $@ based on $@ might later cause $@. | main.js:67:63:67:69 | attrVal | HTML construction | main.js:66:35:66:41 | attrVal | library input | main.js:67:47:67:78 | "" | cross-site scripting | | main.js:81:35:81:37 | val | main.js:79:34:79:36 | val | main.js:81:35:81:37 | val | $@ based on $@ might later cause $@. | main.js:81:35:81:37 | val | HTML construction | main.js:79:34:79:36 | val | library input | main.js:81:24:81:49 | " ... /span>" | cross-site scripting | +| main.js:90:23:90:23 | x | main.js:93:43:93:43 | x | main.js:90:23:90:23 | x | $@ based on $@ might later cause $@. | main.js:90:23:90:23 | x | HTML construction | main.js:93:43:93:43 | x | library input | main.js:94:20:94:32 | createHTML(x) | cross-site scripting | | typed.ts:2:29:2:29 | s | typed.ts:1:39:1:39 | s | typed.ts:2:29:2:29 | s | $@ based on $@ might later cause $@. | typed.ts:2:29:2:29 | s | HTML construction | typed.ts:1:39:1:39 | s | library input | typed.ts:3:31:3:34 | html | cross-site scripting | | typed.ts:8:40:8:40 | s | typed.ts:6:43:6:43 | s | typed.ts:8:40:8:40 | s | $@ based on $@ might later cause $@. | typed.ts:8:40:8:40 | s | HTML construction | typed.ts:6:43:6:43 | s | library input | typed.ts:8:29:8:52 | " ... /span>" | cross-site scripting | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/main.js b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/main.js index 1547ae86b24..2e9d344b1f3 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/main.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/UnsafeHtmlConstruction/main.js @@ -85,3 +85,11 @@ module.exports.types = function (val) { $("#foo").html("" + val + ""); // OK } } + +function createHTML(x) { + return "" + x + ""; // NOT OK +} + +module.exports.usesCreateHTML = function (x) { + $("#foo").html(createHTML(x)); +} \ No newline at end of file From 1fa214471659a6769b5ab7ba61fb6555fe9846f8 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Wed, 13 Jul 2022 21:02:08 +1200 Subject: [PATCH 339/465] Ruby: Update test fixtures --- ruby/ql/test/library-tests/ast/Ast.expected | 29 ++++++++++++ .../library-tests/ast/AstDesugar.expected | 12 +++++ .../library-tests/ast/TreeSitter.expected | 46 +++++++++++++++++++ .../test/library-tests/ast/ValueText.expected | 12 +++++ 4 files changed, 99 insertions(+) diff --git a/ruby/ql/test/library-tests/ast/Ast.expected b/ruby/ql/test/library-tests/ast/Ast.expected index ebfd53fd551..0a16654594d 100644 --- a/ruby/ql/test/library-tests/ast/Ast.expected +++ b/ruby/ql/test/library-tests/ast/Ast.expected @@ -1556,6 +1556,35 @@ constants/constants.rb: # 73| getAnOperand/getLeftOperand: [ClassVariableAccess] @@fourty_six # 73| getAnOperand/getRightOperand: [ConstantReadAccess] FOURTY_SIX # 73| getScopeExpr: [ConstantReadAccess] Mod3 +# 78| getStmt: [AssignExpr] ... = ... +# 78| getAnOperand/getLeftOperand: [LocalVariableAccess] a +# 78| getAnOperand/getRightOperand: [ArrayLiteral] [...] +# 78| getElement: [IntegerLiteral] 1 +# 78| getElement: [IntegerLiteral] 2 +# 78| getElement: [IntegerLiteral] 3 +# 79| getStmt: [AssignExpr] ... = ... +# 79| getAnOperand/getLeftOperand: [ConstantAssignment] A +# 79| getAnOperand/getRightOperand: [ArrayLiteral] [...] +# 79| getElement: [IntegerLiteral] 1 +# 79| getElement: [IntegerLiteral] 2 +# 79| getElement: [IntegerLiteral] 3 +# 80| getStmt: [AssignExpr] ... = ... +# 80| getAnOperand/getLeftOperand: [ConstantAssignment] B +# 80| getAnOperand/getRightOperand: [LocalVariableAccess] a +# 81| getStmt: [AssignExpr] ... = ... +# 81| getAnOperand/getLeftOperand: [ConstantAssignment] C +# 81| getAnOperand/getRightOperand: [ConstantReadAccess] A +# 82| getStmt: [AssignExpr] ... = ... +# 82| getAnOperand/getLeftOperand: [LocalVariableAccess] b +# 82| getAnOperand/getRightOperand: [ConstantReadAccess] B +# 84| getStmt: [IfExpr] if ... +# 84| getCondition: [MethodCall] call to condition +# 84| getReceiver: [SelfVariableAccess] self +# 84| getBranch/getThen: [StmtSequence] then ... +# 85| getStmt: [AssignExpr] ... = ... +# 85| getAnOperand/getLeftOperand: [LocalVariableAccess] c +# 85| getAnOperand/getRightOperand: [LocalVariableAccess] b +# 87| getStmt: [LocalVariableAccess] c escape_sequences/escapes.rb: # 1| [Toplevel] escapes.rb # 6| getStmt: [StringLiteral] "\'" diff --git a/ruby/ql/test/library-tests/ast/AstDesugar.expected b/ruby/ql/test/library-tests/ast/AstDesugar.expected index 0e6a0694105..956893e944f 100644 --- a/ruby/ql/test/library-tests/ast/AstDesugar.expected +++ b/ruby/ql/test/library-tests/ast/AstDesugar.expected @@ -336,6 +336,18 @@ constants/constants.rb: # 20| getComponent: [StringTextComponent] Chuck # 20| getArgument: [StringLiteral] "Dave" # 20| getComponent: [StringTextComponent] Dave +# 78| [ArrayLiteral] [...] +# 78| getDesugared: [MethodCall] call to [] +# 78| getReceiver: [ConstantReadAccess] Array +# 78| getArgument: [IntegerLiteral] 1 +# 78| getArgument: [IntegerLiteral] 2 +# 78| getArgument: [IntegerLiteral] 3 +# 79| [ArrayLiteral] [...] +# 79| getDesugared: [MethodCall] call to [] +# 79| getReceiver: [ConstantReadAccess] Array +# 79| getArgument: [IntegerLiteral] 1 +# 79| getArgument: [IntegerLiteral] 2 +# 79| getArgument: [IntegerLiteral] 3 escape_sequences/escapes.rb: # 58| [ArrayLiteral] %w(...) # 58| getDesugared: [MethodCall] call to [] diff --git a/ruby/ql/test/library-tests/ast/TreeSitter.expected b/ruby/ql/test/library-tests/ast/TreeSitter.expected index 0a2ecda8d28..67a909d9002 100644 --- a/ruby/ql/test/library-tests/ast/TreeSitter.expected +++ b/ruby/ql/test/library-tests/ast/TreeSitter.expected @@ -1656,10 +1656,56 @@ constants/constants.rb: # 73| 1: [ReservedWord] :: # 73| 2: [Constant] FOURTY_SIX # 74| 5: [ReservedWord] end +# 78| 13: [Assignment] Assignment +# 78| 0: [Identifier] a +# 78| 1: [ReservedWord] = +# 78| 2: [Array] Array +# 78| 0: [ReservedWord] [ +# 78| 1: [Integer] 1 +# 78| 2: [ReservedWord] , +# 78| 3: [Integer] 2 +# 78| 4: [ReservedWord] , +# 78| 5: [Integer] 3 +# 78| 6: [ReservedWord] ] +# 79| 14: [Assignment] Assignment +# 79| 0: [Constant] A +# 79| 1: [ReservedWord] = +# 79| 2: [Array] Array +# 79| 0: [ReservedWord] [ +# 79| 1: [Integer] 1 +# 79| 2: [ReservedWord] , +# 79| 3: [Integer] 2 +# 79| 4: [ReservedWord] , +# 79| 5: [Integer] 3 +# 79| 6: [ReservedWord] ] +# 80| 15: [Assignment] Assignment +# 80| 0: [Constant] B +# 80| 1: [ReservedWord] = +# 80| 2: [Identifier] a +# 81| 16: [Assignment] Assignment +# 81| 0: [Constant] C +# 81| 1: [ReservedWord] = +# 81| 2: [Constant] A +# 82| 17: [Assignment] Assignment +# 82| 0: [Identifier] b +# 82| 1: [ReservedWord] = +# 82| 2: [Constant] B +# 84| 18: [If] If +# 84| 0: [ReservedWord] if +# 84| 1: [Identifier] condition +# 84| 2: [Then] Then +# 85| 0: [Assignment] Assignment +# 85| 0: [Identifier] c +# 85| 1: [ReservedWord] = +# 85| 2: [Identifier] b +# 86| 3: [ReservedWord] end +# 87| 19: [Identifier] c # 26| [Comment] # A call to Kernel::Array; despite beginning with an upper-case character, # 27| [Comment] # we don't consider this to be a constant access. # 55| [Comment] # refers to ::ModuleA::FOURTY_FOUR # 57| [Comment] # refers to ::ModuleA::ModuleB::ClassB::FOURTY_FOUR +# 76| [Comment] # Array constants +# 87| [Comment] # not recognised control/cases.rb: # 1| [Program] Program # 2| 0: [Assignment] Assignment diff --git a/ruby/ql/test/library-tests/ast/ValueText.expected b/ruby/ql/test/library-tests/ast/ValueText.expected index 6225b1b2e90..ecf7399a99a 100644 --- a/ruby/ql/test/library-tests/ast/ValueText.expected +++ b/ruby/ql/test/library-tests/ast/ValueText.expected @@ -109,6 +109,12 @@ exprValue | constants/constants.rb:63:19:63:20 | 45 | 45 | int | | constants/constants.rb:65:19:65:35 | FOURTY_FIVE | 45 | int | | constants/constants.rb:71:18:71:19 | 46 | 46 | int | +| constants/constants.rb:78:6:78:6 | 1 | 1 | int | +| constants/constants.rb:78:9:78:9 | 2 | 2 | int | +| constants/constants.rb:78:12:78:12 | 3 | 3 | int | +| constants/constants.rb:79:6:79:6 | 1 | 1 | int | +| constants/constants.rb:79:9:79:9 | 2 | 2 | int | +| constants/constants.rb:79:12:79:12 | 3 | 3 | int | | control/cases.rb:2:5:2:5 | 0 | 0 | int | | control/cases.rb:3:5:3:5 | 0 | 0 | int | | control/cases.rb:4:5:4:5 | 0 | 0 | int | @@ -1004,6 +1010,12 @@ exprCfgNodeValue | constants/constants.rb:63:19:63:20 | 45 | 45 | int | | constants/constants.rb:65:19:65:35 | FOURTY_FIVE | 45 | int | | constants/constants.rb:71:18:71:19 | 46 | 46 | int | +| constants/constants.rb:78:6:78:6 | 1 | 1 | int | +| constants/constants.rb:78:9:78:9 | 2 | 2 | int | +| constants/constants.rb:78:12:78:12 | 3 | 3 | int | +| constants/constants.rb:79:6:79:6 | 1 | 1 | int | +| constants/constants.rb:79:9:79:9 | 2 | 2 | int | +| constants/constants.rb:79:12:79:12 | 3 | 3 | int | | control/cases.rb:2:5:2:5 | 0 | 0 | int | | control/cases.rb:3:5:3:5 | 0 | 0 | int | | control/cases.rb:4:5:4:5 | 0 | 0 | int | From f7dca4d70fd58016671a3a0dde5158fd3a716993 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Tue, 12 Jul 2022 17:31:02 +0200 Subject: [PATCH 340/465] Swift: trap output rework Firstly, this change reworks how inter-process races are resolved. Moreover some responsability reorganization has led to merging `TrapArena` and `TrapOutput` again into a `TrapDomain` class. A `TargetFile` class is introduced, that is successfully created only for the first process that starts processing a given trap output file. From then on `TargetFile` simply wraps around `<<` stream operations, dumping them to a temporary file. When `TargetFile::commit` is called, the temporary file is moved on to the actual target trap file. Processes that lose the race can now just ignore the unneeded extraction and go on, while previously all processes would carry out all extractions overwriting each other at the end. Some of the file system logic contained in `SwiftExtractor.cpp` has been moved to this class, and two TODOs are solved: * introducing a better inter process file collision avoidance strategy * better error handling for trap output operations: if unable to write to the trap file (or carry out other basic file operations), we just abort. The changes to `ExprVisitor` and `StmtVisitor` are due to wanting to hide the raw `TrapDomain::createLabel` from them, and bring more funcionality under the generic caching/dispatching mechanism. --- swift/codegen/schema.yml | 1 + swift/extractor/SwiftExtractor.cpp | 70 +++++------------- swift/extractor/infra/BUILD.bazel | 2 + swift/extractor/infra/SwiftDispatcher.h | 46 ++++++------ swift/extractor/infra/SwiftTagTraits.h | 2 + swift/extractor/infra/TargetFile.cpp | 73 +++++++++++++++++++ swift/extractor/infra/TargetFile.h | 40 ++++++++++ swift/extractor/trap/TrapArena.h | 23 ------ .../trap/{TrapOutput.h => TrapDomain.h} | 68 +++++++++++------ swift/extractor/visitors/ExprVisitor.cpp | 10 +-- swift/extractor/visitors/StmtVisitor.cpp | 34 ++++----- swift/extractor/visitors/StmtVisitor.h | 4 +- swift/extractor/visitors/SwiftVisitor.h | 7 +- .../codeql/swift/generated/expr/Argument.qll | 4 +- swift/ql/lib/swift.dbscheme | 6 +- .../DotSyntaxCallExpr_getArgument.expected | 4 +- 16 files changed, 238 insertions(+), 156 deletions(-) create mode 100644 swift/extractor/infra/TargetFile.cpp create mode 100644 swift/extractor/infra/TargetFile.h delete mode 100644 swift/extractor/trap/TrapArena.h rename swift/extractor/trap/{TrapOutput.h => TrapDomain.h} (56%) diff --git a/swift/codegen/schema.yml b/swift/codegen/schema.yml index 01bb0c2feba..1c76a1c7a65 100644 --- a/swift/codegen/schema.yml +++ b/swift/codegen/schema.yml @@ -319,6 +319,7 @@ AppliedPropertyWrapperExpr: _extends: Expr Argument: + _extends: Locatable label: string _children: expr: Expr diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 44d2309cb2a..88ad2152473 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -16,8 +16,9 @@ #include #include "swift/extractor/trap/generated/TrapClasses.h" -#include "swift/extractor/trap/TrapOutput.h" +#include "swift/extractor/trap/TrapDomain.h" #include "swift/extractor/visitors/SwiftVisitor.h" +#include "swift/extractor/infra/TargetFile.h" using namespace codeql; @@ -52,7 +53,7 @@ static void archiveFile(const SwiftExtractorConfiguration& config, swift::Source } } -static std::string getTrapFilename(swift::ModuleDecl& module, swift::SourceFile* primaryFile) { +static std::string getFilename(swift::ModuleDecl& module, swift::SourceFile* primaryFile) { if (primaryFile) { return primaryFile->getFilename().str(); } @@ -80,56 +81,39 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, swift::CompilerInstance& compiler, swift::ModuleDecl& module, swift::SourceFile* primaryFile = nullptr) { + auto filename = getFilename(module, primaryFile); + // The extractor can be called several times from different processes with - // the same input file(s) - // We are using PID to avoid concurrent access - // TODO: find a more robust approach to avoid collisions? - auto name = getTrapFilename(module, primaryFile); - llvm::StringRef filename(name); - std::string tempTrapName = filename.str() + '.' + std::to_string(getpid()) + ".trap"; - llvm::SmallString tempTrapPath(config.getTempTrapDir()); - llvm::sys::path::append(tempTrapPath, tempTrapName); - - llvm::StringRef tempTrapParent = llvm::sys::path::parent_path(tempTrapPath); - if (std::error_code ec = llvm::sys::fs::create_directories(tempTrapParent)) { - std::cerr << "Cannot create temp trap directory '" << tempTrapParent.str() - << "': " << ec.message() << "\n"; + // the same input file(s). Using `TargetFile` the first process will win, and the following + // will just skip the work + TargetFile trapStream{filename + ".trap", config.trapDir, config.getTempTrapDir()}; + if (!trapStream.good()) { + // another process arrived first, nothing to do for us return; } - std::ofstream trapStream(tempTrapPath.str().str()); - if (!trapStream) { - std::error_code ec; - ec.assign(errno, std::generic_category()); - std::cerr << "Cannot create temp trap file '" << tempTrapPath.str().str() - << "': " << ec.message() << "\n"; - return; - } trapStream << "/* extractor-args:\n"; - for (auto opt : config.frontendOptions) { + for (const auto& opt : config.frontendOptions) { trapStream << " " << std::quoted(opt) << " \\\n"; } trapStream << "\n*/\n"; trapStream << "/* swift-frontend-args:\n"; - for (auto opt : config.patchedFrontendOptions) { + for (const auto& opt : config.patchedFrontendOptions) { trapStream << " " << std::quoted(opt) << " \\\n"; } trapStream << "\n*/\n"; - TrapOutput trap{trapStream}; - TrapArena arena{}; + TrapDomain trap{trapStream}; // TODO: move default location emission elsewhere, possibly in a separate global trap file - auto unknownFileLabel = arena.allocateLabel(); // the following cannot conflict with actual files as those have an absolute path starting with / - trap.assignKey(unknownFileLabel, "unknown"); + auto unknownFileLabel = trap.createLabel("unknown"); + auto unknownLocationLabel = trap.createLabel("unknown"); trap.emit(FilesTrap{unknownFileLabel}); - auto unknownLocationLabel = arena.allocateLabel(); - trap.assignKey(unknownLocationLabel, "unknown"); trap.emit(LocationsTrap{unknownLocationLabel, unknownFileLabel}); - SwiftVisitor visitor(compiler.getSourceMgr(), arena, trap, module, primaryFile); + SwiftVisitor visitor(compiler.getSourceMgr(), trap, module, primaryFile); auto topLevelDecls = getTopLevelDecls(module, primaryFile); for (auto decl : topLevelDecls) { visitor.extract(decl); @@ -142,28 +126,10 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, // fact that the file was extracted llvm::SmallString name(filename); llvm::sys::fs::make_absolute(name); - auto fileLabel = arena.allocateLabel(); - trap.assignKey(fileLabel, name.str().str()); + auto fileLabel = trap.createLabel(name.str().str()); trap.emit(FilesTrap{fileLabel, name.str().str()}); } - - // TODO: Pick a better name to avoid collisions - std::string trapName = filename.str() + ".trap"; - llvm::SmallString trapPath(config.trapDir); - llvm::sys::path::append(trapPath, trapName); - - llvm::StringRef trapParent = llvm::sys::path::parent_path(trapPath); - if (std::error_code ec = llvm::sys::fs::create_directories(trapParent)) { - std::cerr << "Cannot create trap directory '" << trapParent.str() << "': " << ec.message() - << "\n"; - return; - } - - // TODO: The last process wins. Should we do better than that? - if (std::error_code ec = llvm::sys::fs::rename(tempTrapPath, trapPath)) { - std::cerr << "Cannot rename temp trap file '" << tempTrapPath.str().str() << "' -> '" - << trapPath.str().str() << "': " << ec.message() << "\n"; - } + trapStream.commit(); } static std::unordered_set collectInputFilenames(swift::CompilerInstance& compiler) { diff --git a/swift/extractor/infra/BUILD.bazel b/swift/extractor/infra/BUILD.bazel index 33098eb76a4..115fb06b745 100644 --- a/swift/extractor/infra/BUILD.bazel +++ b/swift/extractor/infra/BUILD.bazel @@ -2,9 +2,11 @@ load("//swift:rules.bzl", "swift_cc_library") swift_cc_library( name = "infra", + srcs = glob(["*.cpp"]), hdrs = glob(["*.h"]), visibility = ["//swift:__subpackages__"], deps = [ "//swift/extractor/trap", + "//swift/tools/prebuilt:swift-llvm-support", ], ) diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index c7ca43a1614..a9ecb6996ff 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -4,9 +4,8 @@ #include #include -#include "swift/extractor/trap/TrapArena.h" #include "swift/extractor/trap/TrapLabelStore.h" -#include "swift/extractor/trap/TrapOutput.h" +#include "swift/extractor/trap/TrapDomain.h" #include "swift/extractor/infra/SwiftTagTraits.h" #include "swift/extractor/trap/generated/TrapClasses.h" @@ -22,12 +21,10 @@ class SwiftDispatcher { // all references and pointers passed as parameters to this constructor are supposed to outlive // the SwiftDispatcher SwiftDispatcher(const swift::SourceManager& sourceManager, - TrapArena& arena, - TrapOutput& trap, + TrapDomain& trap, swift::ModuleDecl& currentModule, swift::SourceFile* currentPrimarySourceFile = nullptr) : sourceManager{sourceManager}, - arena{arena}, trap{trap}, currentModule{currentModule}, currentPrimarySourceFile{currentPrimarySourceFile} {} @@ -77,6 +74,7 @@ class SwiftDispatcher { } waitingForNewLabel = e; visit(e); + // TODO when everything is moved to structured C++ classes, this should be moved to createEntry if (auto l = store.get(e)) { if constexpr (!std::is_base_of_v) { attachLocation(e, *l); @@ -95,13 +93,17 @@ class SwiftDispatcher { return fetchLabelFromUnion(node); } + TrapLabel fetchLabel(const swift::StmtConditionElement& element) { + return fetchLabel(&element); + } + // Due to the lazy emission approach, we must assign a label to a corresponding AST node before // it actually gets emitted to handle recursive cases such as recursive calls, or recursive type // declarations template TrapLabelOf assignNewLabel(E* e, Args&&... args) { assert(waitingForNewLabel == Store::Handle{e} && "assignNewLabel called on wrong entity"); - auto label = createLabel>(std::forward(args)...); + auto label = trap.createLabel>(std::forward(args)...); store.insert(e, label); waitingForNewLabel = std::monostate{}; return label; @@ -118,18 +120,13 @@ class SwiftDispatcher { return TrapClassOf{assignNewLabel(&e, std::forward(args)...)}; } - template - TrapLabel createLabel() { - auto ret = arena.allocateLabel(); - trap.assignStar(ret); - return ret; - } - - template - TrapLabel createLabel(Args&&... args) { - auto ret = arena.allocateLabel(); - trap.assignKey(ret, std::forward(args)...); - return ret; + // used to create a new entry for entities that should not be cached + // an example is swift::Argument, that are created on the fly and thus have no stable pointer + template >* = nullptr> + auto createUncachedEntry(const E& e, Args&&... args) { + auto label = trap.createLabel>(std::forward(args)...); + attachLocation(&e, label); + return TrapClassOf{label}; } template @@ -213,6 +210,7 @@ class SwiftDispatcher { using Store = TrapLabelStore(filepath); + auto fileLabel = trap.createLabel(filepath); // TODO: do not emit duplicate trap entries for Files trap.emit(FilesTrap{fileLabel, filepath}); auto [startLine, startColumn] = sourceManager.getLineAndColumnInBuffer(start); auto [endLine, endColumn] = sourceManager.getLineAndColumnInBuffer(end); - auto locLabel = createLabel('{', fileLabel, "}:", startLine, ':', startColumn, ':', - endLine, ':', endColumn); + auto locLabel = trap.createLabel('{', fileLabel, "}:", startLine, ':', startColumn, + ':', endLine, ':', endColumn); trap.emit(LocationsTrap{locLabel, fileLabel, startLine, startColumn, endLine, endColumn}); trap.emit(LocatableLocationsTrap{locatableLabel, locLabel}); } @@ -275,7 +273,8 @@ class SwiftDispatcher { // which are to be introduced in follow-up PRs virtual void visit(swift::Decl* decl) = 0; virtual void visit(swift::Stmt* stmt) = 0; - virtual void visit(swift::StmtCondition* cond) = 0; + virtual void visit(const swift::StmtCondition* cond) = 0; + virtual void visit(const swift::StmtConditionElement* cond) = 0; virtual void visit(swift::CaseLabelItem* item) = 0; virtual void visit(swift::Expr* expr) = 0; virtual void visit(swift::Pattern* pattern) = 0; @@ -283,8 +282,7 @@ class SwiftDispatcher { virtual void visit(swift::TypeBase* type) = 0; const swift::SourceManager& sourceManager; - TrapArena& arena; - TrapOutput& trap; + TrapDomain& trap; Store store; Store::Handle waitingForNewLabel{std::monostate{}}; swift::ModuleDecl& currentModule; diff --git a/swift/extractor/infra/SwiftTagTraits.h b/swift/extractor/infra/SwiftTagTraits.h index 8a2e489683d..7447fa8f9b3 100644 --- a/swift/extractor/infra/SwiftTagTraits.h +++ b/swift/extractor/infra/SwiftTagTraits.h @@ -36,12 +36,14 @@ using SILBoxTypeReprTag = SilBoxTypeReprTag; MAP_TAG(Stmt); MAP_TAG(StmtCondition); +MAP_TYPE_TO_TAG(StmtConditionElement, ConditionElementTag); MAP_TAG(CaseLabelItem); #define ABSTRACT_STMT(CLASS, PARENT) MAP_SUBTAG(CLASS##Stmt, PARENT) #define STMT(CLASS, PARENT) ABSTRACT_STMT(CLASS, PARENT) #include MAP_TAG(Expr); +MAP_TAG(Argument); #define ABSTRACT_EXPR(CLASS, PARENT) MAP_SUBTAG(CLASS##Expr, PARENT) #define EXPR(CLASS, PARENT) ABSTRACT_EXPR(CLASS, PARENT) #include diff --git a/swift/extractor/infra/TargetFile.cpp b/swift/extractor/infra/TargetFile.cpp new file mode 100644 index 00000000000..5051c0c191f --- /dev/null +++ b/swift/extractor/infra/TargetFile.cpp @@ -0,0 +1,73 @@ +#include "swift/extractor/infra/TargetFile.h" + +#include +#include + +namespace codeql { +namespace { +[[noreturn]] void error(const char* action, const std::string& arg, std::error_code ec) { + std::cerr << "Unable to " << action << ": " << arg << " (" << ec.message() << ")\n"; + std::abort(); +} + +[[noreturn]] void error(const char* action, const std::string& arg) { + error(action, arg, {errno, std::system_category()}); +} + +void ensureParentDir(const std::string& path) { + auto parent = llvm::sys::path::parent_path(path); + if (auto ec = llvm::sys::fs::create_directories(parent)) { + error("create directory", parent.str(), ec); + } +} + +std::string initPath(std::string_view target, std::string_view dir) { + std::string ret{dir}; + assert(!target.empty() && "target must be a non-empty path"); + if (target[0] != '/') { + ret += '/'; + } + ret.append(target); + ensureParentDir(ret); + return ret; +} +} // namespace + +TargetFile::TargetFile(std::string_view target, + std::string_view targetDir, + std::string_view workingDir) + : workingPath{initPath(target, workingDir)}, targetPath{initPath(target, targetDir)} { + errno = 0; + // since C++17 "x" mode opens with O_EXCL (fails if file already exists) + if (auto f = std::fopen(targetPath.c_str(), "wx")) { + std::fclose(f); + out.open(workingPath); + checkOutput("open file for writing"); + } else { + if (errno != EEXIST) { + error("open file for writing", targetPath); + } + // else we just lost the race, do nothing (good() will return false to signal this) + } +} + +bool TargetFile::good() const { + return out && out.is_open(); +} + +void TargetFile::commit() { + assert(good()); + out.close(); + errno = 0; + if (std::rename(workingPath.c_str(), targetPath.c_str()) != 0) { + error("rename file", targetPath); + } +} + +void TargetFile::checkOutput(const char* action) { + if (!out) { + error(action, workingPath); + } +} + +} // namespace codeql diff --git a/swift/extractor/infra/TargetFile.h b/swift/extractor/infra/TargetFile.h new file mode 100644 index 00000000000..91a6f1651f1 --- /dev/null +++ b/swift/extractor/infra/TargetFile.h @@ -0,0 +1,40 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace codeql { + +// Only the first process trying to open an `TargetFile` for a given `target` is allowed to do +// so, all others will have an instance with `good() == false` and failing on any other operation. +// The content streamed to the `TargetFile` is written to `workingDir/target`, and is moved onto +// `targetDir/target` only when `commit()` is called +class TargetFile { + std::string workingPath; + std::string targetPath; + std::ofstream out; + + public: + TargetFile(std::string_view target, std::string_view targetDir, std::string_view workingDir); + + bool good() const; + void commit(); + + template + TargetFile& operator<<(T&& value) { + errno = 0; + out << value; + checkOutput("write to file"); + return *this; + } + + private: + void checkOutput(const char* action); +}; + +} // namespace codeql diff --git a/swift/extractor/trap/TrapArena.h b/swift/extractor/trap/TrapArena.h deleted file mode 100644 index 99d0b4a5d3b..00000000000 --- a/swift/extractor/trap/TrapArena.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "swift/extractor/trap/TrapLabel.h" - -namespace codeql { - -// TrapArena has the responsibilities to allocate distinct trap #-labels -// TODO this is now a small functionality that will be moved to code upcoming from other PRs -class TrapArena { - uint64_t id_{0}; - - public: - template - TrapLabel allocateLabel() { - return TrapLabel::unsafeCreateFromExplicitId(id_++); - } -}; - -} // namespace codeql diff --git a/swift/extractor/trap/TrapOutput.h b/swift/extractor/trap/TrapDomain.h similarity index 56% rename from swift/extractor/trap/TrapOutput.h rename to swift/extractor/trap/TrapDomain.h index 0e3f61d39e7..42aed53d499 100644 --- a/swift/extractor/trap/TrapOutput.h +++ b/swift/extractor/trap/TrapDomain.h @@ -2,18 +2,55 @@ #include #include "swift/extractor/trap/TrapLabel.h" +#include "swift/extractor/infra/TargetFile.h" namespace codeql { -// Sink for trap emissions and label assignments. This abstracts away `ofstream` operations -// like `ofstream`, an explicit bool operator is provided, that return false if something -// went wrong -// TODO better error handling -class TrapOutput { - std::ostream& out_; +// Abstracts a given trap output file, with its own universe of trap labels +class TrapDomain { + TargetFile& out_; public: - explicit TrapOutput(std::ostream& out) : out_{out} {} + explicit TrapDomain(TargetFile& out) : out_{out} {} + + template + void emit(const Entry& e) { + print(e); + } + + template + void debug(const Args&... args) { + print("/* DEBUG:"); + print(args...); + print("*/"); + } + + template + TrapLabel createLabel() { + auto ret = allocateLabel(); + assignStar(ret); + return ret; + } + + template + TrapLabel createLabel(Args&&... args) { + auto ret = allocateLabel(); + assignKey(ret, std::forward(args)...); + return ret; + } + + private: + uint64_t id_{0}; + + template + TrapLabel allocateLabel() { + return TrapLabel::unsafeCreateFromExplicitId(id_++); + } + + template + void print(const Args&... args) { + (out_ << ... << args) << '\n'; + } template void assignStar(TrapLabel label) { @@ -33,23 +70,6 @@ class TrapOutput { (oss << ... << keyParts); assignKey(label, oss.str()); } - - template - void emit(const Entry& e) { - print(e); - } - - template - void debug(const Args&... args) { - out_ << "/* DEBUG:\n"; - (out_ << ... << args) << "\n*/\n"; - } - - private: - template - void print(const Args&... args) { - (out_ << ... << args) << '\n'; - } }; } // namespace codeql diff --git a/swift/extractor/visitors/ExprVisitor.cpp b/swift/extractor/visitors/ExprVisitor.cpp index e6aabef4cea..730996a2739 100644 --- a/swift/extractor/visitors/ExprVisitor.cpp +++ b/swift/extractor/visitors/ExprVisitor.cpp @@ -611,11 +611,11 @@ void ExprVisitor::fillAbstractClosureExpr(const swift::AbstractClosureExpr& expr } TrapLabel ExprVisitor::emitArgument(const swift::Argument& arg) { - auto argLabel = dispatcher_.createLabel(); - assert(arg.getExpr() && "Argument has getExpr"); - dispatcher_.emit( - ArgumentsTrap{argLabel, arg.getLabel().str().str(), dispatcher_.fetchLabel(arg.getExpr())}); - return argLabel; + auto entry = dispatcher_.createUncachedEntry(arg); + entry.label = arg.getLabel().str().str(); + entry.expr = dispatcher_.fetchLabel(arg.getExpr()); + dispatcher_.emit(entry); + return entry.id; } void ExprVisitor::emitImplicitConversionExpr(swift::ImplicitConversionExpr* expr, diff --git a/swift/extractor/visitors/StmtVisitor.cpp b/swift/extractor/visitors/StmtVisitor.cpp index 21f93828ed7..bc8a8a30933 100644 --- a/swift/extractor/visitors/StmtVisitor.cpp +++ b/swift/extractor/visitors/StmtVisitor.cpp @@ -7,26 +7,22 @@ void StmtVisitor::visitLabeledStmt(swift::LabeledStmt* stmt) { emitLabeledStmt(stmt, label); } -void StmtVisitor::visitStmtCondition(swift::StmtCondition* cond) { - auto label = dispatcher_.assignNewLabel(cond); - dispatcher_.emit(StmtConditionsTrap{label}); - unsigned index = 0; - for (const auto& cond : *cond) { - auto condLabel = dispatcher_.createLabel(); - dispatcher_.attachLocation(cond, condLabel); - dispatcher_.emit(ConditionElementsTrap{condLabel}); - dispatcher_.emit(StmtConditionElementsTrap{label, index++, condLabel}); - if (auto boolean = cond.getBooleanOrNull()) { - auto elementLabel = dispatcher_.fetchLabel(boolean); - dispatcher_.emit(ConditionElementBooleansTrap{condLabel, elementLabel}); - } else if (auto pattern = cond.getPatternOrNull()) { - auto patternLabel = dispatcher_.fetchLabel(pattern); - auto initilizerLabel = dispatcher_.fetchLabel(cond.getInitializer()); - dispatcher_.emit(ConditionElementPatternsTrap{condLabel, patternLabel}); - dispatcher_.emit(ConditionElementInitializersTrap{condLabel, initilizerLabel}); - } - /// TODO: Implement availability +codeql::StmtCondition StmtVisitor::translateStmtCondition(const swift::StmtCondition& cond) { + auto entry = dispatcher_.createEntry(cond); + entry.elements = dispatcher_.fetchRepeatedLabels(cond); + return entry; +} + +codeql::ConditionElement StmtVisitor::translateStmtConditionElement( + const swift::StmtConditionElement& element) { + auto entry = dispatcher_.createEntry(element); + if (auto boolean = element.getBooleanOrNull()) { + entry.boolean = dispatcher_.fetchLabel(boolean); + } else if (auto pattern = element.getPatternOrNull()) { + entry.pattern = dispatcher_.fetchLabel(pattern); + entry.initializer = dispatcher_.fetchLabel(element.getInitializer()); } + return entry; } void StmtVisitor::visitLabeledConditionalStmt(swift::LabeledConditionalStmt* stmt) { diff --git a/swift/extractor/visitors/StmtVisitor.h b/swift/extractor/visitors/StmtVisitor.h index 78273366d9e..e929a364399 100644 --- a/swift/extractor/visitors/StmtVisitor.h +++ b/swift/extractor/visitors/StmtVisitor.h @@ -10,7 +10,9 @@ class StmtVisitor : public AstVisitorBase { using AstVisitorBase::AstVisitorBase; void visitLabeledStmt(swift::LabeledStmt* stmt); - void visitStmtCondition(swift::StmtCondition* cond); + codeql::StmtCondition translateStmtCondition(const swift::StmtCondition& cond); + codeql::ConditionElement translateStmtConditionElement( + const swift::StmtConditionElement& element); void visitLabeledConditionalStmt(swift::LabeledConditionalStmt* stmt); void visitCaseLabelItem(swift::CaseLabelItem* labelItem); void visitBraceStmt(swift::BraceStmt* stmt); diff --git a/swift/extractor/visitors/SwiftVisitor.h b/swift/extractor/visitors/SwiftVisitor.h index 6380390af82..a13479246f4 100644 --- a/swift/extractor/visitors/SwiftVisitor.h +++ b/swift/extractor/visitors/SwiftVisitor.h @@ -22,7 +22,12 @@ class SwiftVisitor : private SwiftDispatcher { private: void visit(swift::Decl* decl) override { declVisitor.visit(decl); } void visit(swift::Stmt* stmt) override { stmtVisitor.visit(stmt); } - void visit(swift::StmtCondition* cond) override { stmtVisitor.visitStmtCondition(cond); } + void visit(const swift::StmtCondition* cond) override { + emit(stmtVisitor.translateStmtCondition(*cond)); + } + void visit(const swift::StmtConditionElement* element) override { + emit(stmtVisitor.translateStmtConditionElement(*element)); + } void visit(swift::CaseLabelItem* item) override { stmtVisitor.visitCaseLabelItem(item); } void visit(swift::Expr* expr) override { exprVisitor.visit(expr); } void visit(swift::Pattern* pattern) override { patternVisitor.visit(pattern); } diff --git a/swift/ql/lib/codeql/swift/generated/expr/Argument.qll b/swift/ql/lib/codeql/swift/generated/expr/Argument.qll index 9f16b90e3fe..7e8d6ea0ed3 100644 --- a/swift/ql/lib/codeql/swift/generated/expr/Argument.qll +++ b/swift/ql/lib/codeql/swift/generated/expr/Argument.qll @@ -1,8 +1,8 @@ // generated by codegen/codegen.py -import codeql.swift.elements.Element import codeql.swift.elements.expr.Expr +import codeql.swift.elements.Locatable -class ArgumentBase extends @argument, Element { +class ArgumentBase extends @argument, Locatable { override string getAPrimaryQlClass() { result = "Argument" } string getLabel() { arguments(this, result, _) } diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index 83ee8412131..ae57f4e6fbb 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -13,8 +13,7 @@ sourceLocationPrefix( // from codegen/schema.yml @element = - @argument -| @callable + @callable | @file | @generic_context | @iterable_decl_context @@ -34,7 +33,8 @@ files( ); @locatable = - @ast_node + @argument +| @ast_node | @condition_element ; diff --git a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.expected b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.expected index 64bdae371b7..85102771b48 100644 --- a/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.expected +++ b/swift/ql/test/extractor-tests/generated/expr/DotSyntaxCallExpr/DotSyntaxCallExpr_getArgument.expected @@ -1,2 +1,2 @@ -| dot_syntax_call.swift:6:1:6:3 | call to foo(_:_:) | 0 | : X.Type | -| dot_syntax_call.swift:7:1:7:3 | call to bar() | 0 | : X.Type | +| dot_syntax_call.swift:6:1:6:3 | call to foo(_:_:) | 0 | dot_syntax_call.swift:6:1:6:1 | : X.Type | +| dot_syntax_call.swift:7:1:7:3 | call to bar() | 0 | dot_syntax_call.swift:7:1:7:1 | : X.Type | From 5773a734c307d656b52db8ac75e842f41821fb79 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 13 Jul 2022 11:27:50 +0200 Subject: [PATCH 341/465] Swift: slightly simplify a cppgen change --- swift/codegen/generators/cppgen.py | 38 +++++++++++++----------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/swift/codegen/generators/cppgen.py b/swift/codegen/generators/cppgen.py index 08af5fb82f9..420e82605e1 100644 --- a/swift/codegen/generators/cppgen.py +++ b/swift/codegen/generators/cppgen.py @@ -13,7 +13,6 @@ Each class in the schema gets a corresponding `struct` in `TrapClasses.h`, where import functools import pathlib -import typing from typing import Dict import inflection @@ -35,25 +34,22 @@ def _get_type(t: str) -> str: return t -def _get_fields(cls: schema.Class) -> typing.Iterable[cpp.Field]: - for p in cls.properties: - if "cpp_skip" in p.pragmas: - continue - trap_name = None - if not p.is_single: - trap_name = inflection.camelize(f"{cls.name}_{p.name}") - if not p.is_predicate: - trap_name = inflection.pluralize(trap_name) - args = dict( - field_name=p.name + ("_" if p.name in cpp.cpp_keywords else ""), - type=_get_type(p.type), - is_optional=p.is_optional, - is_repeated=p.is_repeated, - is_predicate=p.is_predicate, - trap_name=trap_name, - ) - args.update(cpp.get_field_override(p.name)) - yield cpp.Field(**args) +def _get_field(cls: schema.Class, p: schema.Property) -> cpp.Field: + trap_name = None + if not p.is_single: + trap_name = inflection.camelize(f"{cls.name}_{p.name}") + if not p.is_predicate: + trap_name = inflection.pluralize(trap_name) + args = dict( + field_name=p.name + ("_" if p.name in cpp.cpp_keywords else ""), + type=_get_type(p.type), + is_optional=p.is_optional, + is_repeated=p.is_repeated, + is_predicate=p.is_predicate, + trap_name=trap_name, + ) + args.update(cpp.get_field_override(p.name)) + return cpp.Field(**args) class Processor: @@ -69,7 +65,7 @@ class Processor: return cpp.Class( name=name, bases=[self._get_class(b) for b in cls.bases], - fields=list(_get_fields(cls)), + fields=[_get_field(cls, p) for p in cls.properties if "cpp_skip" not in p.pragmas], final=not cls.derived, trap_name=trap_name, ) From b1dd3c2d846664a7876ff06042590963c070244b Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 13 Jul 2022 13:58:36 +0100 Subject: [PATCH 342/465] Model java.util.Properties.getProperty --- .../code/java/dataflow/internal/ContainerFlow.qll | 3 +++ java/ql/lib/semmle/code/java/frameworks/Properties.qll | 4 +--- .../test/library-tests/dataflow/collections/Test.java | 10 ++++++++++ .../library-tests/dataflow/collections/flow.expected | 3 +++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll index 0f5d5e39f39..e9c457fc801 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll @@ -241,6 +241,9 @@ private class ContainerFlowSummaries extends SummaryModelCsv { "java.util;NavigableSet;true;pollLast;();;Argument[-1].Element;ReturnValue;value;manual", "java.util;NavigableSet;true;subSet;(Object,boolean,Object,boolean);;Argument[-1].Element;ReturnValue.Element;value;manual", "java.util;NavigableSet;true;tailSet;(Object,boolean);;Argument[-1].Element;ReturnValue.Element;value;manual", + "java.util;Properties;true;getProperty;(String);;Argument[-1].MapValue;ReturnValue;value;manual", + "java.util;Properties;true;getProperty;(String,String);;Argument[-1].MapValue;ReturnValue;value;manual", + "java.util;Properties;true;getProperty;(String,String);;Argument[1];ReturnValue;value;manual", "java.util;Scanner;true;next;(Pattern);;Argument[-1];ReturnValue;taint;manual", "java.util;Scanner;true;next;(String);;Argument[-1];ReturnValue;taint;manual", "java.util;SortedMap;true;headMap;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", diff --git a/java/ql/lib/semmle/code/java/frameworks/Properties.qll b/java/ql/lib/semmle/code/java/frameworks/Properties.qll index 7b749a13e05..0c7b83b2e52 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Properties.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Properties.qll @@ -10,13 +10,11 @@ class TypeProperty extends Class { } /** The `getProperty` method of the class `java.util.Properties`. */ -class PropertiesGetPropertyMethod extends ValuePreservingMethod { +class PropertiesGetPropertyMethod extends Method { PropertiesGetPropertyMethod() { getDeclaringType() instanceof TypeProperty and hasName("getProperty") } - - override predicate returnsValue(int arg) { arg = 1 } } /** The `get` method of the class `java.util.Properties`. */ diff --git a/java/ql/test/library-tests/dataflow/collections/Test.java b/java/ql/test/library-tests/dataflow/collections/Test.java index 216f373ca8c..9836070f42c 100644 --- a/java/ql/test/library-tests/dataflow/collections/Test.java +++ b/java/ql/test/library-tests/dataflow/collections/Test.java @@ -78,4 +78,14 @@ public class Test { sink(x18); // Flow }); } + + public void run4() { + Properties p = new Properties(); + p.put("key", tainted); + sink(p.getProperty("key")); // Flow + sink(p.getProperty("key", "defaultValue")); // Flow + + Properties clean = new Properties(); + sink(clean.getProperty("key", tainted)); // Flow + } } diff --git a/java/ql/test/library-tests/dataflow/collections/flow.expected b/java/ql/test/library-tests/dataflow/collections/flow.expected index 1a4bed0a6e7..875a4191722 100644 --- a/java/ql/test/library-tests/dataflow/collections/flow.expected +++ b/java/ql/test/library-tests/dataflow/collections/flow.expected @@ -11,3 +11,6 @@ | Test.java:49:20:49:26 | tainted | Test.java:60:12:60:14 | x14 | | Test.java:73:11:73:17 | tainted | Test.java:75:10:75:12 | x17 | | Test.java:73:11:73:17 | tainted | Test.java:78:12:78:14 | x18 | +| Test.java:84:18:84:24 | tainted | Test.java:85:10:85:29 | getProperty(...) | +| Test.java:84:18:84:24 | tainted | Test.java:86:10:86:45 | getProperty(...) | +| Test.java:89:35:89:41 | tainted | Test.java:89:10:89:42 | getProperty(...) | From f9da4a045624ad49c755a9f880dc7713a6729dbd Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 13 Jul 2022 14:11:31 +0100 Subject: [PATCH 343/465] Add change note --- java/ql/lib/change-notes/2022-07-13-properites.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2022-07-13-properites.md diff --git a/java/ql/lib/change-notes/2022-07-13-properites.md b/java/ql/lib/change-notes/2022-07-13-properites.md new file mode 100644 index 00000000000..2be74455704 --- /dev/null +++ b/java/ql/lib/change-notes/2022-07-13-properites.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added data-flow models for `java.util.Properites`. Additional results may be found where relevant data is stored in and then retrieved from a `Properties` instance. From f7c47b6c75f79430e75147d224ce5049352be8ee Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Wed, 13 Jul 2022 08:34:48 -0700 Subject: [PATCH 344/465] Update python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py Co-authored-by: Taus --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py index b7099b3d6c0..96aeb436a9b 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.py @@ -3,5 +3,5 @@ blob_client.require_encryption = True blob_client.key_encryption_key = kek # GOOD: Must use `encryption_version` set to `2.0` blob_client.encryption_version = '2.0' # Use Version 2.0! -with open(“decryptedcontentfile.txt”, “rb”) as stream: +with open("decryptedcontentfile.txt", "rb") as stream: blob_client.upload_blob(stream, overwrite=OVERWRITE_EXISTING) \ No newline at end of file From 2cc703387b0c42a7c260cc5e400d08e9a7c08ce2 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 14 Jul 2022 00:05:19 +0000 Subject: [PATCH 345/465] use taint config for data flow --- .../ManuallyCheckHttpVerb.ql | 48 ++++++++----------- .../ManuallyCheckHttpVerb.expected | 32 +++++++++++++ .../ManuallyCheckHttpVerb.rb | 18 ++++++- 3 files changed, 70 insertions(+), 28 deletions(-) diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql index 72574e148d2..3de3a7a03d5 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -1,7 +1,7 @@ /** * @name Manually checking http verb instead of using built in rails routes and protections * @description Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. - * @kind problem + * @kind path-problem * @problem.severity error * @security-severity 5.0 * @precision low @@ -13,6 +13,8 @@ import ruby import codeql.ruby.DataFlow import codeql.ruby.controlflow.CfgNodes import codeql.ruby.frameworks.ActionController +import codeql.ruby.TaintTracking +import DataFlow::PathGraph // any `request` calls in an action method class Request extends DataFlow::CallNode { @@ -70,32 +72,24 @@ class RequestGet extends DataFlow::CallNode { } } -// A conditional expression where the condition uses `request.method`, `request.request_method`, `request.raw_request_method`, `request.request_method_symbol`, or `request.get?` in some way. -// e.g. -// ``` -// r = request.request_method -// if r == "GET" -// ... -// ``` -class RequestMethodConditional extends DataFlow::Node { - RequestMethodConditional() { - // We have to cast the dataflow node down to a specific CFG node (`ExprNodes::ConditionalExprCfgNode`) to be able to call `getCondition()`. - // We then find the dataflow node corresponding to the condition CFG node, - // and filter for just nodes where a request method accessor value flows to them. - exists(DataFlow::Node conditionNode | - conditionNode.asExpr() = this.asExpr().(ExprNodes::ConditionalExprCfgNode).getCondition() - | - ( - any(RequestMethod r).flowsTo(conditionNode) or - any(RequestRequestMethod r).flowsTo(conditionNode) or - any(RequestRawRequestMethod r).flowsTo(conditionNode) or - any(RequestRequestMethodSymbol r).flowsTo(conditionNode) or - any(RequestGet r).flowsTo(conditionNode) - ) - ) +class HttpVerbConfig extends TaintTracking::Configuration { + HttpVerbConfig() { this = "HttpVerbConfig" } + + override predicate isSource(DataFlow::Node source) { + source instanceof RequestMethod or + source instanceof RequestRequestMethod or + source instanceof RequestEnvMethod or + source instanceof RequestRawRequestMethod or + source instanceof RequestRequestMethodSymbol or + source instanceof RequestGet + } + + override predicate isSink(DataFlow::Node sink) { + exists(ExprNodes::ConditionalExprCfgNode c | c.getCondition() = sink.asExpr()) or + exists(ExprNodes::CaseExprCfgNode c | c.getValue() = sink.asExpr()) } } -from RequestMethodConditional req -select req, - "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods." +from HttpVerbConfig config, DataFlow::Node source, DataFlow::Node sink +where config.hasFlow(source, sink) +select sink.asExpr().getExpr(), source, sink, "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods." diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected index e69de29bb2d..9102005a67e 100644 --- a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected @@ -0,0 +1,32 @@ +edges +| ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env : | ManuallyCheckHttpVerb.rb:11:14:11:42 | ...[...] : | +| ManuallyCheckHttpVerb.rb:11:14:11:42 | ...[...] : | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | +| ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method : | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | +| ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method : | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | +| ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method : | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | +| ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol : | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | +| ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env : | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | +nodes +| ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | semmle.label | call to get? | +| ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env : | semmle.label | call to env : | +| ManuallyCheckHttpVerb.rb:11:14:11:42 | ...[...] : | semmle.label | ...[...] : | +| ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method : | semmle.label | call to request_method : | +| ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method : | semmle.label | call to method : | +| ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method : | semmle.label | call to raw_request_method : | +| ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol : | semmle.label | call to request_method_symbol : | +| ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | semmle.label | ... == ... | +| ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env : | semmle.label | call to env : | +| ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | semmle.label | ...[...] | +subpaths +#select +| ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb index ad0f5b45566..055e9d98638 100644 --- a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.rb @@ -38,6 +38,14 @@ class ExampleController < ActionController::Base end end + # Should not find + def baz2 + method = request.raw_request_method + if some_other_function == "GET" + Resource.find(id: params[:id]) + end + end + # Should find def foobarbaz method = request.request_method_symbol @@ -56,7 +64,15 @@ class ExampleController < ActionController::Base end end - + # Should not find + def resource_action + case request.random_method + when "GET" + Resource.find(id: params[:id]) + when "POST" + Resource.new(id: params[:id], details: params[:details]) + end + end end class SafeController < ActionController::Base From ae634367c99f404fb3f2a92944243ccef9d50b95 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 14 Jul 2022 00:11:25 +0000 Subject: [PATCH 346/465] add qhelp file --- .../ManuallyCheckHttpVerb.qhelp | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qhelp diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qhelp b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qhelp new file mode 100644 index 00000000000..5d7378ef003 --- /dev/null +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qhelp @@ -0,0 +1,23 @@ + + + +

    + Manually checking the HTTP request verb inside of a controller method can lead to + CSRF bypass if GET or HEAD requests are handled improperly. +

    +
    + +

    + It is better to use different controller methods for each resource/http verb combination + and configure the Rails routes in your application to call them accordingly. +

    +
    + + +

    + See https://guides.rubyonrails.org/routing.html for more information. +

    +
    +
    From ee79834cc80671d5e4535969e600346e4ea6708e Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 14 Jul 2022 00:15:39 +0000 Subject: [PATCH 347/465] formatting in qhelp --- .../manually-check-http-verb/ManuallyCheckHttpVerb.qhelp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qhelp b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qhelp index 5d7378ef003..d50c7f0bf30 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qhelp +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.qhelp @@ -16,8 +16,8 @@ -

    +

  • See https://guides.rubyonrails.org/routing.html for more information. -

    +
  • From 9a186ba5d2a524bc1e04851d22fcace19f1100f6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 14 Jul 2022 00:18:56 +0000 Subject: [PATCH 348/465] Add changed framework coverage reports --- java/documentation/library-coverage/coverage.csv | 2 +- java/documentation/library-coverage/coverage.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 06ec8d978d4..ce777afae1d 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -36,7 +36,7 @@ java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12 java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,3,7, java.nio,15,,6,,13,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,6, java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,,, -java.util,44,,438,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,24,414 +java.util,44,,441,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,24,417 javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 7b45a3115b1..3e4ea1201bf 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -15,9 +15,9 @@ Java framework & library support `Apache HttpComponents `_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,136,28,,,3,,,,25 `Google Guava `_,``com.google.common.*``,,728,39,,6,,,,, `JSON-java `_,``org.json``,,236,,,,,,,, - Java Standard Library,``java.*``,3,549,130,28,,,7,,,10 + Java Standard Library,``java.*``,3,552,130,28,,,7,,,10 Java extensions,"``javax.*``, ``jakarta.*``",63,609,32,,,4,,1,1,2 `Spring `_,``org.springframework.*``,29,476,101,,,,19,14,,29 Others,"``androidx.slice``, ``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``kotlin.jvm.internal``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.logging.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jboss.logging``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",65,395,932,,,,14,18,,3 - Totals,,217,6410,1474,117,6,10,107,33,1,84 + Totals,,217,6413,1474,117,6,10,107,33,1,84 From 3dd61cadf44297f672a9e550b289781abf325839 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 14 Jul 2022 00:19:36 +0000 Subject: [PATCH 349/465] formatting query --- .../ManuallyCheckHttpVerb.ql | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql index 3de3a7a03d5..e7553b39a3d 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -74,14 +74,14 @@ class RequestGet extends DataFlow::CallNode { class HttpVerbConfig extends TaintTracking::Configuration { HttpVerbConfig() { this = "HttpVerbConfig" } - + override predicate isSource(DataFlow::Node source) { - source instanceof RequestMethod or - source instanceof RequestRequestMethod or - source instanceof RequestEnvMethod or - source instanceof RequestRawRequestMethod or - source instanceof RequestRequestMethodSymbol or - source instanceof RequestGet + source instanceof RequestMethod or + source instanceof RequestRequestMethod or + source instanceof RequestEnvMethod or + source instanceof RequestRawRequestMethod or + source instanceof RequestRequestMethodSymbol or + source instanceof RequestGet } override predicate isSink(DataFlow::Node sink) { @@ -92,4 +92,5 @@ class HttpVerbConfig extends TaintTracking::Configuration { from HttpVerbConfig config, DataFlow::Node source, DataFlow::Node sink where config.hasFlow(source, sink) -select sink.asExpr().getExpr(), source, sink, "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods." +select sink.asExpr().getExpr(), source, sink, + "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods." From 8ca7d7d775cf8540acbb7539fad7830c04eb3ed2 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 14 Jul 2022 00:22:38 +0000 Subject: [PATCH 350/465] update change note --- ruby/ql/lib/change-notes/released/0.3.1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/change-notes/released/0.3.1.md b/ruby/ql/lib/change-notes/released/0.3.1.md index 64efa15884a..392aa6f0b27 100644 --- a/ruby/ql/lib/change-notes/released/0.3.1.md +++ b/ruby/ql/lib/change-notes/released/0.3.1.md @@ -2,4 +2,4 @@ ### Minor Analysis Improvements -- Calls to `ActiveRecord::Relation#annotate` have now been added to `ActiveRecordModelClass#sqlFragmentArgument` so that it can be used as a sink for queries like rb/sql-injection. \ No newline at end of file +- Calls to `ActiveRecord::Relation#annotate` are now recognized as`SqlExecution`s so that it will be considered as a sink for queries like rb/sql-injection. \ No newline at end of file From 4c53c341f6c2fb9022b18c69c6ed6655b0a8669f Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 14 Jul 2022 05:51:45 +0200 Subject: [PATCH 351/465] Swift: make `TargetFile::good()` a class invariant Fallible initialization has been moved to a factory function, and `commit` has been moved to the destructor. --- swift/extractor/SwiftExtractor.cpp | 35 +++++++++---------- swift/extractor/infra/TargetFile.cpp | 50 ++++++++++++++++++++-------- swift/extractor/infra/TargetFile.h | 25 ++++++++------ 3 files changed, 69 insertions(+), 41 deletions(-) diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 88ad2152473..b36db1ba23b 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -77,6 +77,20 @@ static llvm::SmallVector getTopLevelDecls(swift::ModuleDecl& modul return ret; } +static void dumpArgs(TargetFile& out, const SwiftExtractorConfiguration& config) { + out << "/* extractor-args:\n"; + for (const auto& opt : config.frontendOptions) { + out << " " << std::quoted(opt) << " \\\n"; + } + out << "\n*/\n"; + + out << "/* swift-frontend-args:\n"; + for (const auto& opt : config.patchedFrontendOptions) { + out << " " << std::quoted(opt) << " \\\n"; + } + out << "\n*/\n"; +} + static void extractDeclarations(const SwiftExtractorConfiguration& config, swift::CompilerInstance& compiler, swift::ModuleDecl& module, @@ -86,25 +100,13 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, // The extractor can be called several times from different processes with // the same input file(s). Using `TargetFile` the first process will win, and the following // will just skip the work - TargetFile trapStream{filename + ".trap", config.trapDir, config.getTempTrapDir()}; - if (!trapStream.good()) { + auto trapTarget = TargetFile::create(filename + ".trap", config.trapDir, config.getTempTrapDir()); + if (!trapTarget) { // another process arrived first, nothing to do for us return; } - - trapStream << "/* extractor-args:\n"; - for (const auto& opt : config.frontendOptions) { - trapStream << " " << std::quoted(opt) << " \\\n"; - } - trapStream << "\n*/\n"; - - trapStream << "/* swift-frontend-args:\n"; - for (const auto& opt : config.patchedFrontendOptions) { - trapStream << " " << std::quoted(opt) << " \\\n"; - } - trapStream << "\n*/\n"; - - TrapDomain trap{trapStream}; + dumpArgs(*trapTarget, config); + TrapDomain trap{*trapTarget}; // TODO: move default location emission elsewhere, possibly in a separate global trap file // the following cannot conflict with actual files as those have an absolute path starting with / @@ -129,7 +131,6 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, auto fileLabel = trap.createLabel(name.str().str()); trap.emit(FilesTrap{fileLabel, name.str().str()}); } - trapStream.commit(); } static std::unordered_set collectInputFilenames(swift::CompilerInstance& compiler) { diff --git a/swift/extractor/infra/TargetFile.cpp b/swift/extractor/infra/TargetFile.cpp index 5051c0c191f..d6c4df74318 100644 --- a/swift/extractor/infra/TargetFile.cpp +++ b/swift/extractor/infra/TargetFile.cpp @@ -1,5 +1,10 @@ #include "swift/extractor/infra/TargetFile.h" +#include +#include +#include +#include + #include #include @@ -36,31 +41,49 @@ std::string initPath(std::string_view target, std::string_view dir) { TargetFile::TargetFile(std::string_view target, std::string_view targetDir, std::string_view workingDir) - : workingPath{initPath(target, workingDir)}, targetPath{initPath(target, targetDir)} { + : workingPath{initPath(target, workingDir)}, targetPath{initPath(target, targetDir)} {} + +bool TargetFile::init() { errno = 0; // since C++17 "x" mode opens with O_EXCL (fails if file already exists) if (auto f = std::fopen(targetPath.c_str(), "wx")) { std::fclose(f); out.open(workingPath); checkOutput("open file for writing"); - } else { - if (errno != EEXIST) { - error("open file for writing", targetPath); - } - // else we just lost the race, do nothing (good() will return false to signal this) + return true; } + if (errno != EEXIST) { + error("open file for writing", targetPath); + } + // else we just lost the race + return false; } -bool TargetFile::good() const { - return out && out.is_open(); +std::optional TargetFile::create(std::string_view target, + std::string_view targetDir, + std::string_view workingDir) { + TargetFile ret{target, targetDir, workingDir}; + if (ret.init()) return {std::move(ret)}; + return std::nullopt; +} + +TargetFile& TargetFile::operator=(TargetFile&& other) { + if (this != &other) { + commit(); + workingPath = std::move(other.workingPath); + targetPath = std::move(other.targetPath); + out = std::move(other.out); + } + return *this; } void TargetFile::commit() { - assert(good()); - out.close(); - errno = 0; - if (std::rename(workingPath.c_str(), targetPath.c_str()) != 0) { - error("rename file", targetPath); + if (out.is_open()) { + out.close(); + errno = 0; + if (std::rename(workingPath.c_str(), targetPath.c_str()) != 0) { + error("rename file", targetPath); + } } } @@ -69,5 +92,4 @@ void TargetFile::checkOutput(const char* action) { error(action, workingPath); } } - } // namespace codeql diff --git a/swift/extractor/infra/TargetFile.h b/swift/extractor/infra/TargetFile.h index 91a6f1651f1..551abe0bb76 100644 --- a/swift/extractor/infra/TargetFile.h +++ b/swift/extractor/infra/TargetFile.h @@ -2,28 +2,29 @@ #include #include -#include -#include +#include #include -#include -#include namespace codeql { -// Only the first process trying to open an `TargetFile` for a given `target` is allowed to do -// so, all others will have an instance with `good() == false` and failing on any other operation. +// Only the first process trying to create a `TargetFile` for a given `target` is allowed to do +// so, all others will have `create` return `std::nullopt`. // The content streamed to the `TargetFile` is written to `workingDir/target`, and is moved onto -// `targetDir/target` only when `commit()` is called +// `targetDir/target` on destruction. class TargetFile { std::string workingPath; std::string targetPath; std::ofstream out; public: - TargetFile(std::string_view target, std::string_view targetDir, std::string_view workingDir); + static std::optional create(std::string_view target, + std::string_view targetDir, + std::string_view workingDir); - bool good() const; - void commit(); + ~TargetFile() { commit(); } + + TargetFile(TargetFile&& other) = default; + TargetFile& operator=(TargetFile&& other); template TargetFile& operator<<(T&& value) { @@ -34,7 +35,11 @@ class TargetFile { } private: + TargetFile(std::string_view target, std::string_view targetDir, std::string_view workingDir); + + bool init(); void checkOutput(const char* action); + void commit(); }; } // namespace codeql From d748cb483d1ea03d6786d62eaf5a2292696bdd4b Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 14 Jul 2022 06:10:12 +0200 Subject: [PATCH 352/465] Swift: include cleanup Fix a problem with `sstream` not being transitively included on macOS. --- swift/extractor/SwiftExtractor.cpp | 4 ---- swift/extractor/trap/TrapDomain.h | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index b36db1ba23b..60ac3436fa8 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -1,11 +1,7 @@ #include "SwiftExtractor.h" -#include -#include #include -#include #include -#include #include #include diff --git a/swift/extractor/trap/TrapDomain.h b/swift/extractor/trap/TrapDomain.h index 42aed53d499..c84a3910134 100644 --- a/swift/extractor/trap/TrapDomain.h +++ b/swift/extractor/trap/TrapDomain.h @@ -1,6 +1,8 @@ #pragma once #include +#include + #include "swift/extractor/trap/TrapLabel.h" #include "swift/extractor/infra/TargetFile.h" From f1144b96720355a7c33c3b1c000e8a95bdc880be Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 14 Jul 2022 06:18:51 +0200 Subject: [PATCH 353/465] Swift: small TypeRepr visit rewording --- swift/extractor/visitors/SwiftVisitor.h | 2 +- swift/extractor/visitors/TypeVisitor.cpp | 4 ++-- swift/extractor/visitors/TypeVisitor.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/swift/extractor/visitors/SwiftVisitor.h b/swift/extractor/visitors/SwiftVisitor.h index f9464eafa46..53a259b5584 100644 --- a/swift/extractor/visitors/SwiftVisitor.h +++ b/swift/extractor/visitors/SwiftVisitor.h @@ -27,7 +27,7 @@ class SwiftVisitor : private SwiftDispatcher { void visit(swift::Pattern* pattern) override { patternVisitor.visit(pattern); } void visit(swift::TypeBase* type) override { typeVisitor.visit(type); } void visit(swift::TypeRepr* typeRepr, swift::Type type) override { - typeVisitor.visit(*typeRepr, type); + emit(typeVisitor.translateTypeRepr(*typeRepr, type)); } DeclVisitor declVisitor{*this}; diff --git a/swift/extractor/visitors/TypeVisitor.cpp b/swift/extractor/visitors/TypeVisitor.cpp index 5a1896080e0..868ce1a0db7 100644 --- a/swift/extractor/visitors/TypeVisitor.cpp +++ b/swift/extractor/visitors/TypeVisitor.cpp @@ -8,10 +8,10 @@ void TypeVisitor::visit(swift::TypeBase* type) { dispatcher_.emit(TypesTrap{label, type->getString(), canonicalLabel}); } -void TypeVisitor::visit(const swift::TypeRepr& typeRepr, swift::Type type) { +codeql::TypeRepr TypeVisitor::translateTypeRepr(const swift::TypeRepr& typeRepr, swift::Type type) { auto entry = dispatcher_.createEntry(typeRepr); entry.type = dispatcher_.fetchLabel(type); - dispatcher_.emit(entry); + return entry; } void TypeVisitor::visitProtocolType(swift::ProtocolType* type) { diff --git a/swift/extractor/visitors/TypeVisitor.h b/swift/extractor/visitors/TypeVisitor.h index b2deab60369..4fcd8a489f9 100644 --- a/swift/extractor/visitors/TypeVisitor.h +++ b/swift/extractor/visitors/TypeVisitor.h @@ -9,7 +9,7 @@ class TypeVisitor : public TypeVisitorBase { using TypeVisitorBase::TypeVisitorBase; void visit(swift::TypeBase* type); - void visit(const swift::TypeRepr& typeRepr, swift::Type type); + codeql::TypeRepr translateTypeRepr(const swift::TypeRepr& typeRepr, swift::Type type); void visitProtocolType(swift::ProtocolType* type); void visitEnumType(swift::EnumType* type); From da8123072dba05681836df5908bb1c4d110a807d Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 14 Jul 2022 09:38:10 +0200 Subject: [PATCH 354/465] Apply suggestions from doc review Co-authored-by: mc <42146119+mchammer01@users.noreply.github.com> --- .../src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp | 6 +++--- .../ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql | 2 +- .../change-notes/2022-06-27-case-sensitive-middleware.md | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp index 13e2331bc62..96bf1c18c94 100644 --- a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.qhelp @@ -7,21 +7,21 @@

    Using a case-sensitive regular expression path in a middleware route enables an attacker to bypass that middleware when accessing an endpoint with a case-insensitive path. -Paths specified using a string are case insensitive, whereas regular expressions are case sensitive by default. +Paths specified using a string are case-insensitive, whereas regular expressions are case-sensitive by default.

    When using a regular expression as a middleware path, make sure the regular expression is -case insensitive by adding the i flag. +case-insensitive by adding the i flag.

    The following example restricts access to paths in the /admin path to users logged in as -an administrator: +administrators:

    diff --git a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql index df3beecfb13..ccf659bf024 100644 --- a/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql +++ b/javascript/ql/src/Security/CWE-178/CaseSensitiveMiddlewarePath.ql @@ -1,6 +1,6 @@ /** * @name Case-sensitive middleware path - * @description Middleware with case-sensitive paths do not protect endpoints with case-insensitive paths + * @description Middleware with case-sensitive paths do not protect endpoints with case-insensitive paths. * @kind problem * @problem.severity warning * @security-severity 7.3 diff --git a/javascript/ql/src/change-notes/2022-06-27-case-sensitive-middleware.md b/javascript/ql/src/change-notes/2022-06-27-case-sensitive-middleware.md index 1593596e939..09895db1e2c 100644 --- a/javascript/ql/src/change-notes/2022-06-27-case-sensitive-middleware.md +++ b/javascript/ql/src/change-notes/2022-06-27-case-sensitive-middleware.md @@ -2,5 +2,5 @@ category: newQuery --- -- A new query "case sensitive middleware path" (`js/case-sensitive-middleware-path`) has been added. +- A new query "Case-sensitive middleware path" (`js/case-sensitive-middleware-path`) has been added. It highlights middleware routes that can be bypassed due to having a case-sensitive regular expression path. From d1aa0d7dd38cc4c9a8c0942a7e57bb367bd7ffc4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 14 Jul 2022 08:56:03 +0000 Subject: [PATCH 355/465] Release preparation for version 2.10.1 --- cpp/ql/lib/CHANGELOG.md | 6 ++++++ .../0.3.1.md} | 7 ++++--- cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 6 ++++++ .../0.3.0.md} | 7 ++++--- cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md | 2 ++ .../Solorigate/lib/change-notes/released/1.2.1.md | 1 + .../Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/CHANGELOG.md | 2 ++ .../Solorigate/src/change-notes/released/1.2.1.md | 1 + .../Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 2 ++ csharp/ql/lib/change-notes/released/0.3.1.md | 1 + csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 6 ++++++ .../0.3.0.md} | 7 ++++--- csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 2 ++ go/ql/lib/change-notes/released/0.2.1.md | 1 + go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 2 ++ go/ql/src/change-notes/released/0.2.1.md | 1 + go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 13 +++++++++++++ .../2022-05-18-android-external-storage.md | 4 ---- .../change-notes/2022-06-13-kotlin-break-loops.md | 4 ---- java/ql/lib/change-notes/2022-06-27-isInline.md | 4 ---- java/ql/lib/change-notes/2022-07-12-errortype.md | 4 ---- java/ql/lib/change-notes/2022-07-13-properites.md | 4 ---- java/ql/lib/change-notes/released/0.3.1.md | 12 ++++++++++++ java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 12 ++++++++++++ .../2022-06-29-move-contextual-queries.md | 4 ---- .../0.3.0.md} | 13 +++++++++---- java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 8 ++++++++ .../2022-06-22-sensitive-common-words copy.md | 4 ---- .../2022-06-22-sensitive-common-words.md | 4 ---- .../ql/lib/change-notes/2022-06-30-chownr.md | 4 ---- javascript/ql/lib/change-notes/released/0.2.1.md | 7 +++++++ javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 6 ++++++ .../0.3.0.md} | 7 ++++--- javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 15 +++++++++++++++ .../2022-06-22-sensitive-common-words.md | 4 ---- .../0.5.1.md} | 10 +++++++--- python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 6 ++++++ .../0.3.0.md} | 7 ++++--- python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 9 +++++++++ .../2022-06-22-sensitive-common-words.md | 4 ---- .../0.3.1.md} | 8 +++++--- ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 6 ++++++ .../0.3.0.md} | 7 ++++--- ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- 75 files changed, 204 insertions(+), 104 deletions(-) rename cpp/ql/lib/change-notes/{2022-07-12-cover-more-nullness-cases.md => released/0.3.1.md} (81%) rename cpp/ql/src/change-notes/{2022-06-29-move-contextual-queries.md => released/0.3.0.md} (77%) create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.1.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.1.md create mode 100644 csharp/ql/lib/change-notes/released/0.3.1.md rename csharp/ql/src/change-notes/{2022-06-29-move-contextual-queries.md => released/0.3.0.md} (77%) create mode 100644 go/ql/lib/change-notes/released/0.2.1.md create mode 100644 go/ql/src/change-notes/released/0.2.1.md delete mode 100644 java/ql/lib/change-notes/2022-05-18-android-external-storage.md delete mode 100644 java/ql/lib/change-notes/2022-06-13-kotlin-break-loops.md delete mode 100644 java/ql/lib/change-notes/2022-06-27-isInline.md delete mode 100644 java/ql/lib/change-notes/2022-07-12-errortype.md delete mode 100644 java/ql/lib/change-notes/2022-07-13-properites.md create mode 100644 java/ql/lib/change-notes/released/0.3.1.md delete mode 100644 java/ql/src/change-notes/2022-06-29-move-contextual-queries.md rename java/ql/src/change-notes/{2022-04-27-intent-verification.md => released/0.3.0.md} (57%) delete mode 100644 javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words copy.md delete mode 100644 javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words.md delete mode 100644 javascript/ql/lib/change-notes/2022-06-30-chownr.md create mode 100644 javascript/ql/lib/change-notes/released/0.2.1.md rename javascript/ql/src/change-notes/{2022-06-29-move-contextual-queries.md => released/0.3.0.md} (78%) delete mode 100644 python/ql/lib/change-notes/2022-06-22-sensitive-common-words.md rename python/ql/lib/change-notes/{2022-06-28-api-graph-api.md => released/0.5.1.md} (58%) rename python/ql/src/change-notes/{2022-06-29-move-contextual-queries.md => released/0.3.0.md} (77%) delete mode 100644 ruby/ql/lib/change-notes/2022-06-22-sensitive-common-words.md rename ruby/ql/lib/change-notes/{2022-07-11-command-execution.md => released/0.3.1.md} (65%) rename ruby/ql/src/change-notes/{2022-06-29-move-contextual-queries.md => released/0.3.0.md} (77%) diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index c1cefbed8f9..3e3f0b4531b 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.3.1 + +### Minor Analysis Improvements + +* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the the C++ logical and variable declarations in conditions. + ## 0.3.0 ### Deprecated APIs diff --git a/cpp/ql/lib/change-notes/2022-07-12-cover-more-nullness-cases.md b/cpp/ql/lib/change-notes/released/0.3.1.md similarity index 81% rename from cpp/ql/lib/change-notes/2022-07-12-cover-more-nullness-cases.md rename to cpp/ql/lib/change-notes/released/0.3.1.md index eef564991f5..4b9a3206c96 100644 --- a/cpp/ql/lib/change-notes/2022-07-12-cover-more-nullness-cases.md +++ b/cpp/ql/lib/change-notes/released/0.3.1.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- +## 0.3.1 + +### Minor Analysis Improvements + * `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the the C++ logical and variable declarations in conditions. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 95f6e3a0ba6..bb106b1cb63 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.0 +lastReleaseVersion: 0.3.1 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index a20077271d7..ae668b219fb 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.3.1-dev +version: 0.3.1 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 2b404ff5288..e87fc5dce39 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/cpp-all` package. + ## 0.2.0 ## 0.1.4 diff --git a/cpp/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/cpp/ql/src/change-notes/released/0.3.0.md similarity index 77% rename from cpp/ql/src/change-notes/2022-06-29-move-contextual-queries.md rename to cpp/ql/src/change-notes/released/0.3.0.md index cc5464d58b3..75d99f333c9 100644 --- a/cpp/ql/src/change-notes/2022-06-29-move-contextual-queries.md +++ b/cpp/ql/src/change-notes/released/0.3.0.md @@ -1,4 +1,5 @@ ---- -category: breaking ---- +## 0.3.0 + +### Breaking Changes + * Contextual queries and the query libraries they depend on have been moved to the `codeql/cpp-all` package. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 5274e27ed52..95f6e3a0ba6 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.0 +lastReleaseVersion: 0.3.0 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 62cac967801..1a97e24c9c7 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.2.1-dev +version: 0.3.0 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 30c583ee913..de0a7eeae4b 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.2.1 + ## 1.2.0 ## 1.1.4 diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.1.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.1.md new file mode 100644 index 00000000000..ddf8866b672 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.2.1.md @@ -0,0 +1 @@ +## 1.2.1 diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index 75430e73d1c..73dd403938c 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.2.0 +lastReleaseVersion: 1.2.1 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index bc7eaf4142c..3b56b5ac98e 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.2.1-dev +version: 1.2.1 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 30c583ee913..de0a7eeae4b 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,5 @@ +## 1.2.1 + ## 1.2.0 ## 1.1.4 diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.1.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.1.md new file mode 100644 index 00000000000..ddf8866b672 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.2.1.md @@ -0,0 +1 @@ +## 1.2.1 diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index 75430e73d1c..73dd403938c 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.2.0 +lastReleaseVersion: 1.2.1 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 00725e23666..54326ca55ad 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.2.1-dev +version: 1.2.1 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index 3f49fe5ade3..d1c89626798 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.3.1 + ## 0.3.0 ### Deprecated APIs diff --git a/csharp/ql/lib/change-notes/released/0.3.1.md b/csharp/ql/lib/change-notes/released/0.3.1.md new file mode 100644 index 00000000000..2b0719929a1 --- /dev/null +++ b/csharp/ql/lib/change-notes/released/0.3.1.md @@ -0,0 +1 @@ +## 0.3.1 diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index 95f6e3a0ba6..bb106b1cb63 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.0 +lastReleaseVersion: 0.3.1 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 3f371c01e92..6aff1d2ac68 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.3.1-dev +version: 0.3.1 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index e7ce0b0b471..bf9e8f9c41f 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/csharp-all` package. + ## 0.2.0 ### Query Metadata Changes diff --git a/csharp/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/csharp/ql/src/change-notes/released/0.3.0.md similarity index 77% rename from csharp/ql/src/change-notes/2022-06-29-move-contextual-queries.md rename to csharp/ql/src/change-notes/released/0.3.0.md index a27c68766c0..001d034c251 100644 --- a/csharp/ql/src/change-notes/2022-06-29-move-contextual-queries.md +++ b/csharp/ql/src/change-notes/released/0.3.0.md @@ -1,4 +1,5 @@ ---- -category: breaking ---- +## 0.3.0 + +### Breaking Changes + * Contextual queries and the query libraries they depend on have been moved to the `codeql/csharp-all` package. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index 5274e27ed52..95f6e3a0ba6 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.0 +lastReleaseVersion: 0.3.0 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 1002c6a56ad..b4e5b89773f 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.2.1-dev +version: 0.3.0 groups: - csharp - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 112f4fab585..23c4fc2eb4f 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.2.1 + ## 0.2.0 ### Deprecated APIs diff --git a/go/ql/lib/change-notes/released/0.2.1.md b/go/ql/lib/change-notes/released/0.2.1.md new file mode 100644 index 00000000000..c260de2a9ee --- /dev/null +++ b/go/ql/lib/change-notes/released/0.2.1.md @@ -0,0 +1 @@ +## 0.2.1 diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index 5274e27ed52..df29a726bcc 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.0 +lastReleaseVersion: 0.2.1 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 964f5d4dd13..8f46c7040bb 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.2.1-dev +version: 0.2.1 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index bed2509f5d3..1697aa9e561 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.2.1 + ## 0.2.0 ## 0.1.4 diff --git a/go/ql/src/change-notes/released/0.2.1.md b/go/ql/src/change-notes/released/0.2.1.md new file mode 100644 index 00000000000..c260de2a9ee --- /dev/null +++ b/go/ql/src/change-notes/released/0.2.1.md @@ -0,0 +1 @@ +## 0.2.1 diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index 5274e27ed52..df29a726bcc 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.0 +lastReleaseVersion: 0.2.1 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 80a4430b8da..3aff018b452 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.2.1-dev +version: 0.2.1 groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 41b23a74d1f..6b5e4ec9f09 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.3.1 + +### New Features + +* Added an `ErrorType` class. An instance of this class will be used if an extractor is unable to extract a type, or if an up/downgrade script is unable to provide a type. + +### Minor Analysis Improvements + +* Added data-flow models for `java.util.Properites`. Additional results may be found where relevant data is stored in and then retrieved from a `Properties` instance. +Added `Modifier.isInline()`. +* Removed Kotlin-specific database and QL structures for loops and `break`/`continue` statements. The Kotlin extractor was changed to reuse the Java structures for these constructs. +Added additional flow sources for uses of external storage on Android. + ## 0.3.0 ### Deprecated APIs diff --git a/java/ql/lib/change-notes/2022-05-18-android-external-storage.md b/java/ql/lib/change-notes/2022-05-18-android-external-storage.md deleted file mode 100644 index b3d5fa793b3..00000000000 --- a/java/ql/lib/change-notes/2022-05-18-android-external-storage.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -Added additional flow sources for uses of external storage on Android. \ No newline at end of file diff --git a/java/ql/lib/change-notes/2022-06-13-kotlin-break-loops.md b/java/ql/lib/change-notes/2022-06-13-kotlin-break-loops.md deleted file mode 100644 index 412cf7d5ff5..00000000000 --- a/java/ql/lib/change-notes/2022-06-13-kotlin-break-loops.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Removed Kotlin-specific database and QL structures for loops and `break`/`continue` statements. The Kotlin extractor was changed to reuse the Java structures for these constructs. diff --git a/java/ql/lib/change-notes/2022-06-27-isInline.md b/java/ql/lib/change-notes/2022-06-27-isInline.md deleted file mode 100644 index ad73ed8bf82..00000000000 --- a/java/ql/lib/change-notes/2022-06-27-isInline.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -Added `Modifier.isInline()`. diff --git a/java/ql/lib/change-notes/2022-07-12-errortype.md b/java/ql/lib/change-notes/2022-07-12-errortype.md deleted file mode 100644 index 97f851bb936..00000000000 --- a/java/ql/lib/change-notes/2022-07-12-errortype.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Added an `ErrorType` class. An instance of this class will be used if an extractor is unable to extract a type, or if an up/downgrade script is unable to provide a type. diff --git a/java/ql/lib/change-notes/2022-07-13-properites.md b/java/ql/lib/change-notes/2022-07-13-properites.md deleted file mode 100644 index 2be74455704..00000000000 --- a/java/ql/lib/change-notes/2022-07-13-properites.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added data-flow models for `java.util.Properites`. Additional results may be found where relevant data is stored in and then retrieved from a `Properties` instance. diff --git a/java/ql/lib/change-notes/released/0.3.1.md b/java/ql/lib/change-notes/released/0.3.1.md new file mode 100644 index 00000000000..8c0e3158b0b --- /dev/null +++ b/java/ql/lib/change-notes/released/0.3.1.md @@ -0,0 +1,12 @@ +## 0.3.1 + +### New Features + +* Added an `ErrorType` class. An instance of this class will be used if an extractor is unable to extract a type, or if an up/downgrade script is unable to provide a type. + +### Minor Analysis Improvements + +* Added data-flow models for `java.util.Properites`. Additional results may be found where relevant data is stored in and then retrieved from a `Properties` instance. +Added `Modifier.isInline()`. +* Removed Kotlin-specific database and QL structures for loops and `break`/`continue` statements. The Kotlin extractor was changed to reuse the Java structures for these constructs. +Added additional flow sources for uses of external storage on Android. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 95f6e3a0ba6..bb106b1cb63 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.0 +lastReleaseVersion: 0.3.1 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 541fad197e0..29b02e16b6e 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.3.1-dev +version: 0.3.1 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 1f8a00fb1ff..fc9988443b2 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/java-all` package. + +### New Queries + +* A new query "Improper verification of intent by broadcast receiver" (`java/improper-intent-verification`) has been added. +This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered +to receive system intents. + ## 0.2.0 ### Minor Analysis Improvements diff --git a/java/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/java/ql/src/change-notes/2022-06-29-move-contextual-queries.md deleted file mode 100644 index 02ff5b6d59c..00000000000 --- a/java/ql/src/change-notes/2022-06-29-move-contextual-queries.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: breaking ---- -* Contextual queries and the query libraries they depend on have been moved to the `codeql/java-all` package. diff --git a/java/ql/src/change-notes/2022-04-27-intent-verification.md b/java/ql/src/change-notes/released/0.3.0.md similarity index 57% rename from java/ql/src/change-notes/2022-04-27-intent-verification.md rename to java/ql/src/change-notes/released/0.3.0.md index e5e0e287753..48b478ec905 100644 --- a/java/ql/src/change-notes/2022-04-27-intent-verification.md +++ b/java/ql/src/change-notes/released/0.3.0.md @@ -1,6 +1,11 @@ ---- -category: newQuery ---- +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/java-all` package. + +### New Queries + * A new query "Improper verification of intent by broadcast receiver" (`java/improper-intent-verification`) has been added. This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered -to receive system intents. \ No newline at end of file +to receive system intents. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index 5274e27ed52..95f6e3a0ba6 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.0 +lastReleaseVersion: 0.3.0 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 2366eef3778..b0790498fe3 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.2.1-dev +version: 0.3.0 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index 9df72979ef3..23d54f955a7 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.2.1 + +### Minor Analysis Improvements + +* The `chownr` library is now modeled as a sink for the `js/path-injection` query. +* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). +* The `gray-matter` library is now modeled as a sink for the `js/code-injection` query. + ## 0.2.0 ### Major Analysis Improvements diff --git a/javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words copy.md b/javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words copy.md deleted file mode 100644 index 8a0151df015..00000000000 --- a/javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words copy.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `gray-matter` library is now modeled as a sink for the `js/code-injection` query. diff --git a/javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words.md b/javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words.md deleted file mode 100644 index 9102d58abdb..00000000000 --- a/javascript/ql/lib/change-notes/2022-06-22-sensitive-common-words.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). diff --git a/javascript/ql/lib/change-notes/2022-06-30-chownr.md b/javascript/ql/lib/change-notes/2022-06-30-chownr.md deleted file mode 100644 index 1ad13fb8113..00000000000 --- a/javascript/ql/lib/change-notes/2022-06-30-chownr.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `chownr` library is now modeled as a sink for the `js/path-injection` query. diff --git a/javascript/ql/lib/change-notes/released/0.2.1.md b/javascript/ql/lib/change-notes/released/0.2.1.md new file mode 100644 index 00000000000..3548bd5ad69 --- /dev/null +++ b/javascript/ql/lib/change-notes/released/0.2.1.md @@ -0,0 +1,7 @@ +## 0.2.1 + +### Minor Analysis Improvements + +* The `chownr` library is now modeled as a sink for the `js/path-injection` query. +* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). +* The `gray-matter` library is now modeled as a sink for the `js/code-injection` query. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index 5274e27ed52..df29a726bcc 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.0 +lastReleaseVersion: 0.2.1 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index b16a8912ccf..cb4b01d90b0 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.2.1-dev +version: 0.2.1 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index 68660fcbb52..baf7f9b85e0 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/javascript-all` package. + ## 0.2.0 ### Minor Analysis Improvements diff --git a/javascript/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/javascript/ql/src/change-notes/released/0.3.0.md similarity index 78% rename from javascript/ql/src/change-notes/2022-06-29-move-contextual-queries.md rename to javascript/ql/src/change-notes/released/0.3.0.md index ff190788cd4..13b4541cd4b 100644 --- a/javascript/ql/src/change-notes/2022-06-29-move-contextual-queries.md +++ b/javascript/ql/src/change-notes/released/0.3.0.md @@ -1,4 +1,5 @@ ---- -category: breaking ---- +## 0.3.0 + +### Breaking Changes + * Contextual queries and the query libraries they depend on have been moved to the `codeql/javascript-all` package. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index 5274e27ed52..95f6e3a0ba6 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.0 +lastReleaseVersion: 0.3.0 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 4f54f7dc5bc..07ac096af64 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.2.1-dev +version: 0.3.0 groups: - javascript - queries diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 83861bcf61d..83a09c70446 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,18 @@ +## 0.5.1 + +### Deprecated APIs + +- The documentation of API graphs (the `API` module) has been expanded, and some of the members predicates of `API::Node` + have been renamed as follows: + - `getAnImmediateUse` -> `asSource` + - `getARhs` -> `asSink` + - `getAUse` -> `getAValueReachableFromSource` + - `getAValueReachingRhs` -> `getAValueReachingSink` + +### Minor Analysis Improvements + +* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). + ## 0.5.0 ### Deprecated APIs diff --git a/python/ql/lib/change-notes/2022-06-22-sensitive-common-words.md b/python/ql/lib/change-notes/2022-06-22-sensitive-common-words.md deleted file mode 100644 index 9102d58abdb..00000000000 --- a/python/ql/lib/change-notes/2022-06-22-sensitive-common-words.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). diff --git a/python/ql/lib/change-notes/2022-06-28-api-graph-api.md b/python/ql/lib/change-notes/released/0.5.1.md similarity index 58% rename from python/ql/lib/change-notes/2022-06-28-api-graph-api.md rename to python/ql/lib/change-notes/released/0.5.1.md index ef6ff3d4f76..1b560c7a35a 100644 --- a/python/ql/lib/change-notes/2022-06-28-api-graph-api.md +++ b/python/ql/lib/change-notes/released/0.5.1.md @@ -1,6 +1,6 @@ ---- -category: deprecated ---- +## 0.5.1 + +### Deprecated APIs - The documentation of API graphs (the `API` module) has been expanded, and some of the members predicates of `API::Node` have been renamed as follows: @@ -8,3 +8,7 @@ category: deprecated - `getARhs` -> `asSink` - `getAUse` -> `getAValueReachableFromSource` - `getAValueReachingRhs` -> `getAValueReachingSink` + +### Minor Analysis Improvements + +* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index 30e271c5361..0bf7024c337 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.5.0 +lastReleaseVersion: 0.5.1 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 65145e40d74..7aac7c78527 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.5.1-dev +version: 0.5.1 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index 3be12c71c5f..fae4ab0dc9a 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/python-all` package. + ## 0.2.0 ### Major Analysis Improvements diff --git a/python/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/python/ql/src/change-notes/released/0.3.0.md similarity index 77% rename from python/ql/src/change-notes/2022-06-29-move-contextual-queries.md rename to python/ql/src/change-notes/released/0.3.0.md index 2e8562e66f8..7b54313449c 100644 --- a/python/ql/src/change-notes/2022-06-29-move-contextual-queries.md +++ b/python/ql/src/change-notes/released/0.3.0.md @@ -1,4 +1,5 @@ ---- -category: breaking ---- +## 0.3.0 + +### Breaking Changes + * Contextual queries and the query libraries they depend on have been moved to the `codeql/python-all` package. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index 5274e27ed52..95f6e3a0ba6 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.0 +lastReleaseVersion: 0.3.0 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index af722116e41..6d07cdc1ab3 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.2.1-dev +version: 0.3.0 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index 1b060e46141..fe8a12aa938 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.3.1 + +### Minor Analysis Improvements + +* Fixed a bug causing every expression in the database to be considered a system-command execution sink when calls to any of the following methods exist: + * The `spawn`, `fspawn`, `popen4`, `pspawn`, `system`, `_pspawn` methods and the backtick operator from the `POSIX::spawn` gem. + * The `execute_command`, `rake`, `rails_command`, and `git` methods in `Rails::Generation::Actions`. +* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). + ## 0.3.0 ### Deprecated APIs diff --git a/ruby/ql/lib/change-notes/2022-06-22-sensitive-common-words.md b/ruby/ql/lib/change-notes/2022-06-22-sensitive-common-words.md deleted file mode 100644 index 9102d58abdb..00000000000 --- a/ruby/ql/lib/change-notes/2022-06-22-sensitive-common-words.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). diff --git a/ruby/ql/lib/change-notes/2022-07-11-command-execution.md b/ruby/ql/lib/change-notes/released/0.3.1.md similarity index 65% rename from ruby/ql/lib/change-notes/2022-07-11-command-execution.md rename to ruby/ql/lib/change-notes/released/0.3.1.md index f6548719b57..59f378bbb32 100644 --- a/ruby/ql/lib/change-notes/2022-07-11-command-execution.md +++ b/ruby/ql/lib/change-notes/released/0.3.1.md @@ -1,6 +1,8 @@ ---- -category: minorAnalysis ---- +## 0.3.1 + +### Minor Analysis Improvements + * Fixed a bug causing every expression in the database to be considered a system-command execution sink when calls to any of the following methods exist: * The `spawn`, `fspawn`, `popen4`, `pspawn`, `system`, `_pspawn` methods and the backtick operator from the `POSIX::spawn` gem. * The `execute_command`, `rake`, `rails_command`, and `git` methods in `Rails::Generation::Actions`. +* Improved modeling of sensitive data sources, so common words like `certain` and `secretary` are no longer considered a certificate and a secret (respectively). diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 95f6e3a0ba6..bb106b1cb63 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.3.0 +lastReleaseVersion: 0.3.1 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 062d906c9a2..5b67e5ccd50 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.3.1-dev +version: 0.3.1 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index 0905f133d16..9f227fdc843 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.3.0 + +### Breaking Changes + +* Contextual queries and the query libraries they depend on have been moved to the `codeql/ruby-all` package. + ## 0.2.0 ### New Queries diff --git a/ruby/ql/src/change-notes/2022-06-29-move-contextual-queries.md b/ruby/ql/src/change-notes/released/0.3.0.md similarity index 77% rename from ruby/ql/src/change-notes/2022-06-29-move-contextual-queries.md rename to ruby/ql/src/change-notes/released/0.3.0.md index bc85eb9361e..717a3a27aa5 100644 --- a/ruby/ql/src/change-notes/2022-06-29-move-contextual-queries.md +++ b/ruby/ql/src/change-notes/released/0.3.0.md @@ -1,4 +1,5 @@ ---- -category: breaking ---- +## 0.3.0 + +### Breaking Changes + * Contextual queries and the query libraries they depend on have been moved to the `codeql/ruby-all` package. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index 5274e27ed52..95f6e3a0ba6 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.0 +lastReleaseVersion: 0.3.0 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 0bd19b5bdeb..6a55e6cecd3 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.2.1-dev +version: 0.3.0 groups: - ruby - queries From fe1f1bb79d0143fc3fba77a42df8e0eb219eafe2 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema <93738568+jketema@users.noreply.github.com> Date: Thu, 14 Jul 2022 11:06:14 +0200 Subject: [PATCH 356/465] Fix issues with change notes --- cpp/ql/lib/CHANGELOG.md | 2 +- cpp/ql/lib/change-notes/released/0.3.1.md | 2 +- java/ql/lib/CHANGELOG.md | 4 ++-- java/ql/lib/change-notes/released/0.3.1.md | 4 ++-- java/ql/src/CHANGELOG.md | 4 ++-- java/ql/src/change-notes/released/0.3.0.md | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 3e3f0b4531b..d954c60fb0a 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -2,7 +2,7 @@ ### Minor Analysis Improvements -* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the the C++ logical and variable declarations in conditions. +* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the the C++ logical "and", and variable declarations in conditions. ## 0.3.0 diff --git a/cpp/ql/lib/change-notes/released/0.3.1.md b/cpp/ql/lib/change-notes/released/0.3.1.md index 4b9a3206c96..235ad58d370 100644 --- a/cpp/ql/lib/change-notes/released/0.3.1.md +++ b/cpp/ql/lib/change-notes/released/0.3.1.md @@ -2,4 +2,4 @@ ### Minor Analysis Improvements -* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the the C++ logical and variable declarations in conditions. +* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the the C++ logical "and", and variable declarations in conditions. diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 6b5e4ec9f09..b5ceb823e75 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -7,9 +7,9 @@ ### Minor Analysis Improvements * Added data-flow models for `java.util.Properites`. Additional results may be found where relevant data is stored in and then retrieved from a `Properties` instance. -Added `Modifier.isInline()`. +* Added `Modifier.isInline()`. * Removed Kotlin-specific database and QL structures for loops and `break`/`continue` statements. The Kotlin extractor was changed to reuse the Java structures for these constructs. -Added additional flow sources for uses of external storage on Android. +* Added additional flow sources for uses of external storage on Android. ## 0.3.0 diff --git a/java/ql/lib/change-notes/released/0.3.1.md b/java/ql/lib/change-notes/released/0.3.1.md index 8c0e3158b0b..a453f034d5c 100644 --- a/java/ql/lib/change-notes/released/0.3.1.md +++ b/java/ql/lib/change-notes/released/0.3.1.md @@ -7,6 +7,6 @@ ### Minor Analysis Improvements * Added data-flow models for `java.util.Properites`. Additional results may be found where relevant data is stored in and then retrieved from a `Properties` instance. -Added `Modifier.isInline()`. +* Added `Modifier.isInline()`. * Removed Kotlin-specific database and QL structures for loops and `break`/`continue` statements. The Kotlin extractor was changed to reuse the Java structures for these constructs. -Added additional flow sources for uses of external storage on Android. +* Added additional flow sources for uses of external storage on Android. diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index fc9988443b2..b39e648bf04 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -7,8 +7,8 @@ ### New Queries * A new query "Improper verification of intent by broadcast receiver" (`java/improper-intent-verification`) has been added. -This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered -to receive system intents. + This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered + to receive system intents. ## 0.2.0 diff --git a/java/ql/src/change-notes/released/0.3.0.md b/java/ql/src/change-notes/released/0.3.0.md index 48b478ec905..d91c653a471 100644 --- a/java/ql/src/change-notes/released/0.3.0.md +++ b/java/ql/src/change-notes/released/0.3.0.md @@ -7,5 +7,5 @@ ### New Queries * A new query "Improper verification of intent by broadcast receiver" (`java/improper-intent-verification`) has been added. -This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered -to receive system intents. + This query finds instances of Android `BroadcastReceiver`s that don't verify the action string of received intents when registered + to receive system intents. From 9f184ec122ffed2d532e5d037db2f76b126138ad Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 14 Jul 2022 12:09:58 +0200 Subject: [PATCH 357/465] Update cpp/ql/lib/change-notes/released/0.3.1.md --- cpp/ql/lib/change-notes/released/0.3.1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/change-notes/released/0.3.1.md b/cpp/ql/lib/change-notes/released/0.3.1.md index 235ad58d370..d5b251c42ab 100644 --- a/cpp/ql/lib/change-notes/released/0.3.1.md +++ b/cpp/ql/lib/change-notes/released/0.3.1.md @@ -2,4 +2,4 @@ ### Minor Analysis Improvements -* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the the C++ logical "and", and variable declarations in conditions. +* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the C++ logical "and", and variable declarations in conditions. From dbff20a3d8854f2707a24580887ce22d544f4a86 Mon Sep 17 00:00:00 2001 From: Asger F Date: Thu, 14 Jul 2022 12:10:03 +0200 Subject: [PATCH 358/465] Update cpp/ql/lib/CHANGELOG.md --- cpp/ql/lib/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index d954c60fb0a..75a047d6f64 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -2,7 +2,7 @@ ### Minor Analysis Improvements -* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the the C++ logical "and", and variable declarations in conditions. +* `AnalysedExpr::isNullCheck` and `AnalysedExpr::isValidCheck` have been updated to handle variable accesses on the left-hand side of the C++ logical "and", and variable declarations in conditions. ## 0.3.0 From 380070f2e474912a700a41d813db04e901520517 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Thu, 14 Jul 2022 12:50:23 +0200 Subject: [PATCH 359/465] rewrite the QL-for-QL workflow to just do everything in one go --- .github/workflows/ql-for-ql-build.yml | 70 +++++---------------------- 1 file changed, 11 insertions(+), 59 deletions(-) diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index 2d96fbfa797..7d8efa9e7ca 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -10,9 +10,10 @@ env: CARGO_TERM_COLOR: always jobs: - queries: - runs-on: ubuntu-latest + all-the-things: + runs-on: ubuntu-latest-xl steps: + ### Build the queries ### - uses: actions/checkout@v3 - name: Find codeql id: find-codeql @@ -48,11 +49,7 @@ jobs: name: query-pack-zip path: ${{ runner.temp }}/query-pack.zip - extractors: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 + ### Build the extractor ### - name: Cache entire extractor id: cache-extractor uses: actions/cache@v3 @@ -96,15 +93,8 @@ jobs: ql/target/release/ql-extractor ql/target/release/ql-extractor.exe retention-days: 1 - package: - runs-on: ubuntu-latest - needs: - - extractors - - queries - - steps: - - uses: actions/checkout@v3 + ### Package the queries and extractor ### - uses: actions/download-artifact@v3 with: name: query-pack-zip @@ -132,16 +122,8 @@ jobs: name: codeql-ql-pack path: codeql-ql.zip retention-days: 1 - analyze: - runs-on: ubuntu-latest - strategy: - matrix: - folder: [cpp, csharp, java, javascript, python, ql, ruby, swift, go] - needs: - - package - - steps: + ### Run the analysis ### - name: Download pack uses: actions/download-artifact@v3 with: @@ -161,12 +143,8 @@ jobs: env: PACK: ${{ runner.temp }}/pack - - name: Checkout repository - uses: actions/checkout@v3 - name: Create CodeQL config file run: | - echo "paths:" > ${CONF} - echo " - ${FOLDER}" >> ${CONF} echo "paths-ignore:" >> ${CONF} echo " - ql/ql/test" >> ${CONF} echo "disable-default-queries: true" >> ${CONF} @@ -176,7 +154,6 @@ jobs: cat ${CONF} env: CONF: ./ql-for-ql-config.yml - FOLDER: ${{ matrix.folder }} - name: Initialize CodeQL uses: github/codeql-action/init@aa93aea877e5fb8841bcb1193f672abf6e9f2980 with: @@ -187,39 +164,14 @@ jobs: - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@aa93aea877e5fb8841bcb1193f672abf6e9f2980 with: - category: "ql-for-ql-${{ matrix.folder }}" + category: "ql-for-ql" - name: Copy sarif file to CWD - run: cp ../results/ql.sarif ./${{ matrix.folder }}.sarif + run: cp ../results/ql.sarif ./ql-for-ql.sarif - name: Fixup the $scema in sarif # Until https://github.com/microsoft/sarif-vscode-extension/pull/436/ is part in a stable release run: | - sed -i 's/\$schema.*/\$schema": "https:\/\/raw.githubusercontent.com\/oasis-tcs\/sarif-spec\/master\/Schemata\/sarif-schema-2.1.0",/' ${{ matrix.folder }}.sarif + sed -i 's/\$schema.*/\$schema": "https:\/\/raw.githubusercontent.com\/oasis-tcs\/sarif-spec\/master\/Schemata\/sarif-schema-2.1.0",/' ql-for-ql.sarif - name: Sarif as artifact uses: actions/upload-artifact@v3 with: - name: ${{ matrix.folder }}.sarif - path: ${{ matrix.folder }}.sarif - - combine: - runs-on: ubuntu-latest - needs: - - analyze - - steps: - - uses: actions/checkout@v3 - - name: Make a folder for artifacts. - run: mkdir -p results - - name: Download all sarif files - uses: actions/download-artifact@v3 - with: - path: results - - uses: actions/setup-node@v3 - with: - node-version: 16 - - name: Combine all sarif files - run: | - node ./ql/scripts/merge-sarif.js results/**/*.sarif combined.sarif - - name: Upload combined sarif file - uses: actions/upload-artifact@v3 - with: - name: combined.sarif - path: combined.sarif \ No newline at end of file + name: ql-for-ql.sarif + path: ql-for-ql.sarif From 47c9b446f0f068069f5caee83a2e1f16d3908642 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Thu, 14 Jul 2022 12:54:53 +0200 Subject: [PATCH 360/465] exclude upgrade scripts from QL-for-QL --- .github/workflows/ql-for-ql-build.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index 7d8efa9e7ca..c971d28bb2f 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -10,7 +10,7 @@ env: CARGO_TERM_COLOR: always jobs: - all-the-things: + analyze: runs-on: ubuntu-latest-xl steps: ### Build the queries ### @@ -147,6 +147,7 @@ jobs: run: | echo "paths-ignore:" >> ${CONF} echo " - ql/ql/test" >> ${CONF} + echo " - \"*/ql/lib/upgrades/\"" >> ${CONF} echo "disable-default-queries: true" >> ${CONF} echo "packs:" >> ${CONF} echo " - codeql/ql" >> ${CONF} From a7a9428dc1aed8f21563bc8fa37e8b1d148b71b4 Mon Sep 17 00:00:00 2001 From: Erik Krogh Kristensen Date: Thu, 14 Jul 2022 13:20:52 +0200 Subject: [PATCH 361/465] split the sarif file into languages --- .github/workflows/ql-for-ql-build.yml | 10 +++++++++ ql/scripts/split-sarif.js | 30 +++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 ql/scripts/split-sarif.js diff --git a/.github/workflows/ql-for-ql-build.yml b/.github/workflows/ql-for-ql-build.yml index c971d28bb2f..f5df6291b62 100644 --- a/.github/workflows/ql-for-ql-build.yml +++ b/.github/workflows/ql-for-ql-build.yml @@ -176,3 +176,13 @@ jobs: with: name: ql-for-ql.sarif path: ql-for-ql.sarif + - name: Split out the sarif file into langs + run: | + mkdir split-sarif + node ./ql/scripts/split-sarif.js ql-for-ql.sarif split-sarif + - name: Upload langs as artifacts + uses: actions/upload-artifact@v3 + with: + name: ql-for-ql-langs + path: split-sarif + retention-days: 1 \ No newline at end of file diff --git a/ql/scripts/split-sarif.js b/ql/scripts/split-sarif.js new file mode 100644 index 00000000000..d09989abf8a --- /dev/null +++ b/ql/scripts/split-sarif.js @@ -0,0 +1,30 @@ +var fs = require("fs"); + +// the .sarif file to split, and then the directory to put the split files in. +async function main(inputs) { + const sarifFile = JSON.parse(fs.readFileSync(inputs[0])); + const outFolder = inputs[1]; + + const out = {}; + + for (const result of sarifFile.runs[0].results) { + const lang = getLanguage(result); + if (!out[lang]) { + out[lang] = []; + } + out[lang].push(result); + } + + for (const lang in out) { + const outSarif = JSON.parse(JSON.stringify(sarifFile)); + outSarif.runs[0].results = out[lang]; + fs.writeFileSync(`${outFolder}/${lang}.sarif`, JSON.stringify(outSarif, null, 2)); + } +} + +function getLanguage(result) { + return result.locations[0].physicalLocation.artifactLocation.uri.split( + "/" + )[0]; +} +main(process.argv.splice(2)); From 3e06455ac1e11ceedbb5ae2b18d54ceb6bacc921 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 14 Jul 2022 15:39:36 +0200 Subject: [PATCH 362/465] Swift: delete `TargetFile`'s move assignment --- swift/extractor/infra/TargetFile.cpp | 10 ---------- swift/extractor/infra/TargetFile.h | 3 ++- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/swift/extractor/infra/TargetFile.cpp b/swift/extractor/infra/TargetFile.cpp index d6c4df74318..c2639e81bd8 100644 --- a/swift/extractor/infra/TargetFile.cpp +++ b/swift/extractor/infra/TargetFile.cpp @@ -67,16 +67,6 @@ std::optional TargetFile::create(std::string_view target, return std::nullopt; } -TargetFile& TargetFile::operator=(TargetFile&& other) { - if (this != &other) { - commit(); - workingPath = std::move(other.workingPath); - targetPath = std::move(other.targetPath); - out = std::move(other.out); - } - return *this; -} - void TargetFile::commit() { if (out.is_open()) { out.close(); diff --git a/swift/extractor/infra/TargetFile.h b/swift/extractor/infra/TargetFile.h index 551abe0bb76..5f5ca7d823c 100644 --- a/swift/extractor/infra/TargetFile.h +++ b/swift/extractor/infra/TargetFile.h @@ -24,7 +24,8 @@ class TargetFile { ~TargetFile() { commit(); } TargetFile(TargetFile&& other) = default; - TargetFile& operator=(TargetFile&& other); + // move assignment deleted as non-trivial and not needed + TargetFile& operator=(TargetFile&& other) = delete; template TargetFile& operator<<(T&& value) { From 22ff8c2c7e33e2f6bc0533a2b99ea00044fb3cc5 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 14 Jul 2022 15:40:48 +0200 Subject: [PATCH 363/465] Swift: remove redundant braces --- swift/extractor/infra/TargetFile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/extractor/infra/TargetFile.cpp b/swift/extractor/infra/TargetFile.cpp index c2639e81bd8..d9706205c90 100644 --- a/swift/extractor/infra/TargetFile.cpp +++ b/swift/extractor/infra/TargetFile.cpp @@ -63,7 +63,7 @@ std::optional TargetFile::create(std::string_view target, std::string_view targetDir, std::string_view workingDir) { TargetFile ret{target, targetDir, workingDir}; - if (ret.init()) return {std::move(ret)}; + if (ret.init()) return ret; return std::nullopt; } From d13f9d5d71e6de2e672a041f14460d5e8dd3184f Mon Sep 17 00:00:00 2001 From: Aditya Sharad <6874315+adityasharad@users.noreply.github.com> Date: Thu, 14 Jul 2022 07:29:29 -0700 Subject: [PATCH 364/465] Update docs/codeql/query-help/javascript.rst Co-authored-by: Felicity Chapman --- docs/codeql/query-help/javascript.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/query-help/javascript.rst b/docs/codeql/query-help/javascript.rst index ae85de99f7b..58fe97eb3b0 100644 --- a/docs/codeql/query-help/javascript.rst +++ b/docs/codeql/query-help/javascript.rst @@ -3,7 +3,7 @@ CodeQL query help for JavaScript .. include:: ../reusables/query-help-overview.rst -These queries are published in the CodeQL query pack ``codeql/javascript-queries`` (`changelog `__, `source `__). +These queries are published in the CodeQL query pack ``codeql/javascript-queries`` (`changelog `__, `source `__). For shorter queries that you can use as building blocks when writing your own queries, see the `example queries in the CodeQL repository `__. From 5e74df3882b1d7e1f79cb1917f04114ff1608c3e Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 13 Jul 2022 19:05:05 +0200 Subject: [PATCH 365/465] Swift: cache file paths This required a bit of a generalization of `TrapLabelStore` to not work only with pointers. --- swift/extractor/SwiftExtractor.cpp | 22 ++---- swift/extractor/infra/FilePath.h | 24 ++++++ swift/extractor/infra/SwiftDispatcher.h | 99 +++++++++++++++---------- swift/extractor/infra/SwiftTagTraits.h | 17 +++-- swift/extractor/trap/TrapLabelStore.h | 6 +- swift/extractor/trap/TrapTagTraits.h | 3 +- swift/extractor/visitors/SwiftVisitor.h | 2 +- 7 files changed, 105 insertions(+), 68 deletions(-) create mode 100644 swift/extractor/infra/FilePath.h diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 60ac3436fa8..666b7a90044 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -104,29 +104,19 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, dumpArgs(*trapTarget, config); TrapDomain trap{*trapTarget}; - // TODO: move default location emission elsewhere, possibly in a separate global trap file + // TODO: remove this and recreate it with IPA when we have that // the following cannot conflict with actual files as those have an absolute path starting with / - auto unknownFileLabel = trap.createLabel("unknown"); - auto unknownLocationLabel = trap.createLabel("unknown"); - trap.emit(FilesTrap{unknownFileLabel}); - trap.emit(LocationsTrap{unknownLocationLabel, unknownFileLabel}); + File unknownFileEntry{trap.createLabel("unknown")}; + Location unknownLocationEntry{trap.createLabel("unknown")}; + unknownLocationEntry.file = unknownFileEntry.id; + trap.emit(unknownFileEntry); + trap.emit(unknownLocationEntry); SwiftVisitor visitor(compiler.getSourceMgr(), trap, module, primaryFile); auto topLevelDecls = getTopLevelDecls(module, primaryFile); for (auto decl : topLevelDecls) { visitor.extract(decl); } - // TODO the following will be moved to the dispatcher when we start caching swift file objects - // for the moment, topLevelDecls always contains the current module, which does not have a file - // associated with it, so we need a special case when there are no top level declarations - if (topLevelDecls.size() == 1) { - // In the case of empty files, the dispatcher is not called, but we still want to 'record' the - // fact that the file was extracted - llvm::SmallString name(filename); - llvm::sys::fs::make_absolute(name); - auto fileLabel = trap.createLabel(name.str().str()); - trap.emit(FilesTrap{fileLabel, name.str().str()}); - } } static std::unordered_set collectInputFilenames(swift::CompilerInstance& compiler) { diff --git a/swift/extractor/infra/FilePath.h b/swift/extractor/infra/FilePath.h new file mode 100644 index 00000000000..48288b928e4 --- /dev/null +++ b/swift/extractor/infra/FilePath.h @@ -0,0 +1,24 @@ +#pragma once + +#include +namespace codeql { + +// wrapper around `std::string` mainly intended to unambiguously go into an `std::variant` +// TODO probably not needed once we can use `std::filesystem::path` +struct FilePath { + FilePath() = default; + FilePath(const std::string& path) : path{path} {} + FilePath(std::string&& path) : path{std::move(path)} {} + + std::string path; + + bool operator==(const FilePath& other) const { return path == other.path; } +}; +} // namespace codeql + +namespace std { +template <> +struct hash { + size_t operator()(const codeql::FilePath& value) { return hash{}(value.path); } +}; +} // namespace std diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index a9ecb6996ff..b0cc951dd31 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -8,6 +8,7 @@ #include "swift/extractor/trap/TrapDomain.h" #include "swift/extractor/infra/SwiftTagTraits.h" #include "swift/extractor/trap/generated/TrapClasses.h" +#include "swift/extractor/infra/FilePath.h" namespace codeql { @@ -17,6 +18,24 @@ namespace codeql { // Since SwiftDispatcher sees all the AST nodes, it also attaches a location to every 'locatable' // node (AST nodes that are not types: declarations, statements, expressions, etc.). class SwiftDispatcher { + // types to be supported by assignNewLabel/fetchLabel need to be listed here + using Store = TrapLabelStore; + + template + static constexpr bool IsStorable = std::is_constructible_v; + + template + static constexpr bool IsLocatable = std::is_base_of_v>; + public: // all references and pointers passed as parameters to this constructor are supposed to outlive // the SwiftDispatcher @@ -27,7 +46,12 @@ class SwiftDispatcher { : sourceManager{sourceManager}, trap{trap}, currentModule{currentModule}, - currentPrimarySourceFile{currentPrimarySourceFile} {} + currentPrimarySourceFile{currentPrimarySourceFile} { + if (currentPrimarySourceFile) { + // we make sure the file is in the trap output even if the source is empty + fetchLabel(getFilePath(currentPrimarySourceFile->getFilename())); + } + } template void emit(const Entry& entry) { @@ -61,9 +85,11 @@ class SwiftDispatcher { // This method gives a TRAP label for already emitted AST node. // If the AST node was not emitted yet, then the emission is dispatched to a corresponding // visitor (see `visit(T *)` methods below). - template - TrapLabelOf fetchLabel(E* e) { - assert(e && "trying to fetch a label on nullptr, maybe fetchOptionalLabel is to be used?"); + template >* = nullptr> + TrapLabelOf fetchLabel(const E& e) { + if constexpr (std::is_constructible_v) { + assert(e && "fetching a label on a null entity, maybe fetchOptionalLabel is to be used?"); + } // this is required so we avoid any recursive loop: a `fetchLabel` during the visit of `e` might // end up calling `fetchLabel` on `e` itself, so we want the visit of `e` to call `fetchLabel` // only after having called `assignNewLabel` on `e`. @@ -76,7 +102,7 @@ class SwiftDispatcher { visit(e); // TODO when everything is moved to structured C++ classes, this should be moved to createEntry if (auto l = store.get(e)) { - if constexpr (!std::is_base_of_v) { + if constexpr (IsLocatable) { attachLocation(e, *l); } return *l; @@ -93,15 +119,16 @@ class SwiftDispatcher { return fetchLabelFromUnion(node); } - TrapLabel fetchLabel(const swift::StmtConditionElement& element) { - return fetchLabel(&element); + template >* = nullptr> + TrapLabelOf fetchLabel(const E& e) { + return fetchLabel(&e); } // Due to the lazy emission approach, we must assign a label to a corresponding AST node before // it actually gets emitted to handle recursive cases such as recursive calls, or recursive type // declarations - template - TrapLabelOf assignNewLabel(E* e, Args&&... args) { + template >* = nullptr> + TrapLabelOf assignNewLabel(const E& e, Args&&... args) { assert(waitingForNewLabel == Store::Handle{e} && "assignNewLabel called on wrong entity"); auto label = trap.createLabel>(std::forward(args)...); store.insert(e, label); @@ -109,20 +136,20 @@ class SwiftDispatcher { return label; } - template >* = nullptr> + template >* = nullptr> TrapLabelOf assignNewLabel(const E& e, Args&&... args) { return assignNewLabel(&e, std::forward(args)...); } // convenience methods for structured C++ creation - template >* = nullptr> + template auto createEntry(const E& e, Args&&... args) { - return TrapClassOf{assignNewLabel(&e, std::forward(args)...)}; + return TrapClassOf{assignNewLabel(e, std::forward(args)...)}; } // used to create a new entry for entities that should not be cached // an example is swift::Argument, that are created on the fly and thus have no stable pointer - template >* = nullptr> + template auto createUncachedEntry(const E& e, Args&&... args) { auto label = trap.createLabel>(std::forward(args)...); attachLocation(&e, label); @@ -206,17 +233,6 @@ class SwiftDispatcher { } private: - // types to be supported by assignNewLabel/fetchLabel need to be listed here - using Store = TrapLabelStore; - void attachLocation(swift::SourceLoc start, swift::SourceLoc end, TrapLabel locatableLabel) { @@ -224,16 +240,16 @@ class SwiftDispatcher { // invalid locations seem to come from entities synthesized by the compiler return; } - std::string filepath = getFilepath(start); - auto fileLabel = trap.createLabel(filepath); - // TODO: do not emit duplicate trap entries for Files - trap.emit(FilesTrap{fileLabel, filepath}); - auto [startLine, startColumn] = sourceManager.getLineAndColumnInBuffer(start); - auto [endLine, endColumn] = sourceManager.getLineAndColumnInBuffer(end); - auto locLabel = trap.createLabel('{', fileLabel, "}:", startLine, ':', startColumn, - ':', endLine, ':', endColumn); - trap.emit(LocationsTrap{locLabel, fileLabel, startLine, startColumn, endLine, endColumn}); - trap.emit(LocatableLocationsTrap{locatableLabel, locLabel}); + auto file = getFilePath(sourceManager.getDisplayNameForLoc(start)); + Location entry{{}}; + entry.file = fetchLabel(file); + std::tie(entry.start_line, entry.start_column) = sourceManager.getLineAndColumnInBuffer(start); + std::tie(entry.end_line, entry.end_column) = sourceManager.getLineAndColumnInBuffer(end); + entry.id = trap.createLabel('{', entry.file, "}:", entry.start_line, ':', + entry.start_column, ':', entry.end_line, ':', + entry.end_column); + emit(entry); + emit(LocatableLocationsTrap{locatableLabel, entry.id}); } template @@ -256,21 +272,18 @@ class SwiftDispatcher { return false; } - std::string getFilepath(swift::SourceLoc loc) { + static FilePath getFilePath(llvm::StringRef path) { // TODO: this needs more testing // TODO: check canonicaliztion of names on a case insensitive filesystems // TODO: make symlink resolution conditional on CODEQL_PRESERVE_SYMLINKS=true - auto displayName = sourceManager.getDisplayNameForLoc(loc); llvm::SmallString realPath; - if (std::error_code ec = llvm::sys::fs::real_path(displayName, realPath)) { - std::cerr << "Cannot get real path: '" << displayName.str() << "': " << ec.message() << "\n"; + if (std::error_code ec = llvm::sys::fs::real_path(path, realPath)) { + std::cerr << "Cannot get real path: '" << path.str() << "': " << ec.message() << "\n"; return {}; } return realPath.str().str(); } - // TODO: The following methods are supposed to redirect TRAP emission to correpsonding visitors, - // which are to be introduced in follow-up PRs virtual void visit(swift::Decl* decl) = 0; virtual void visit(swift::Stmt* stmt) = 0; virtual void visit(const swift::StmtCondition* cond) = 0; @@ -281,6 +294,12 @@ class SwiftDispatcher { virtual void visit(swift::TypeRepr* type) = 0; virtual void visit(swift::TypeBase* type) = 0; + void visit(const FilePath& file) { + auto entry = createEntry(file); + entry.name = file.path; + emit(entry); + } + const swift::SourceManager& sourceManager; TrapDomain& trap; Store store; diff --git a/swift/extractor/infra/SwiftTagTraits.h b/swift/extractor/infra/SwiftTagTraits.h index 7447fa8f9b3..a4949b3ec5f 100644 --- a/swift/extractor/infra/SwiftTagTraits.h +++ b/swift/extractor/infra/SwiftTagTraits.h @@ -5,6 +5,7 @@ #include #include "swift/extractor/trap/TrapTagTraits.h" #include "swift/extractor/trap/generated/TrapTags.h" +#include "swift/extractor/infra/FilePath.h" namespace codeql { @@ -16,12 +17,12 @@ using SILFunctionTypeTag = SilFunctionTypeTag; using SILTokenTypeTag = SilTokenTypeTag; using SILBoxTypeReprTag = SilBoxTypeReprTag; -#define MAP_TYPE_TO_TAG(TYPE, TAG) \ - template <> \ - struct detail::ToTagFunctor { \ - using type = TAG; \ +#define MAP_TYPE_TO_TAG(TYPE, TAG) \ + template <> \ + struct detail::ToTagFunctor { \ + using type = TAG; \ } -#define MAP_TAG(TYPE) MAP_TYPE_TO_TAG(TYPE, TYPE##Tag) +#define MAP_TAG(TYPE) MAP_TYPE_TO_TAG(swift::TYPE, TYPE##Tag) #define MAP_SUBTAG(TYPE, PARENT) \ MAP_TAG(TYPE); \ static_assert(std::is_base_of_v, \ @@ -36,7 +37,7 @@ using SILBoxTypeReprTag = SilBoxTypeReprTag; MAP_TAG(Stmt); MAP_TAG(StmtCondition); -MAP_TYPE_TO_TAG(StmtConditionElement, ConditionElementTag); +MAP_TYPE_TO_TAG(swift::StmtConditionElement, ConditionElementTag); MAP_TAG(CaseLabelItem); #define ABSTRACT_STMT(CLASS, PARENT) MAP_SUBTAG(CLASS##Stmt, PARENT) #define STMT(CLASS, PARENT) ABSTRACT_STMT(CLASS, PARENT) @@ -63,7 +64,7 @@ MAP_TAG(TypeRepr); #define TYPEREPR(CLASS, PARENT) ABSTRACT_TYPEREPR(CLASS, PARENT) #include -MAP_TYPE_TO_TAG(TypeBase, TypeTag); +MAP_TYPE_TO_TAG(swift::TypeBase, TypeTag); #define ABSTRACT_TYPE(CLASS, PARENT) MAP_SUBTAG(CLASS##Type, PARENT) #define TYPE(CLASS, PARENT) ABSTRACT_TYPE(CLASS, PARENT) #include @@ -71,6 +72,8 @@ MAP_TYPE_TO_TAG(TypeBase, TypeTag); OVERRIDE_TAG(FuncDecl, ConcreteFuncDeclTag); OVERRIDE_TAG(VarDecl, ConcreteVarDeclTag); +MAP_TYPE_TO_TAG(FilePath, FileTag); + #undef MAP_TAG #undef MAP_SUBTAG #undef MAP_TYPE_TO_TAG diff --git a/swift/extractor/trap/TrapLabelStore.h b/swift/extractor/trap/TrapLabelStore.h index 93ca4212185..f9b0edd1753 100644 --- a/swift/extractor/trap/TrapLabelStore.h +++ b/swift/extractor/trap/TrapLabelStore.h @@ -20,10 +20,10 @@ namespace codeql { template class TrapLabelStore { public: - using Handle = std::variant; + using Handle = std::variant; template - std::optional> get(const T* e) { + std::optional> get(const T& e) { if (auto found = store_.find(e); found != store_.end()) { return TrapLabelOf::unsafeCreateFromUntyped(found->second); } @@ -31,7 +31,7 @@ class TrapLabelStore { } template - void insert(const T* e, TrapLabelOf l) { + void insert(const T& e, TrapLabelOf l) { auto [_, inserted] = store_.emplace(e, l); assert(inserted && "already inserted"); } diff --git a/swift/extractor/trap/TrapTagTraits.h b/swift/extractor/trap/TrapTagTraits.h index 9c29ff22330..f0f8c41cc8d 100644 --- a/swift/extractor/trap/TrapTagTraits.h +++ b/swift/extractor/trap/TrapTagTraits.h @@ -26,7 +26,8 @@ struct ToTrapClassFunctor; } // namespace detail template -using TrapTagOf = typename detail::ToTagOverride>::type; +using TrapTagOf = + typename detail::ToTagOverride>>::type; template using TrapLabelOf = TrapLabel>; diff --git a/swift/extractor/visitors/SwiftVisitor.h b/swift/extractor/visitors/SwiftVisitor.h index a13479246f4..d9d27f2a7ed 100644 --- a/swift/extractor/visitors/SwiftVisitor.h +++ b/swift/extractor/visitors/SwiftVisitor.h @@ -15,7 +15,7 @@ class SwiftVisitor : private SwiftDispatcher { using SwiftDispatcher::SwiftDispatcher; template - void extract(T* entity) { + void extract(const T& entity) { fetchLabel(entity); } From 0ee476129a847a52469fe639669b8ad0566f3fde Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 14 Jul 2022 14:38:49 +0000 Subject: [PATCH 366/465] Post-release preparation for codeql-cli-2.10.1 --- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index ae668b219fb..ce90251f83f 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.3.1 +version: 0.3.2-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 1a97e24c9c7..2735b4d5289 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.3.0 +version: 0.3.1-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 3b56b5ac98e..fc22389c2a8 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.2.1 +version: 1.2.2-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 54326ca55ad..a2ef81cc0e4 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.2.1 +version: 1.2.2-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index 6aff1d2ac68..0d72cfc0c65 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.3.1 +version: 0.3.2-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index b4e5b89773f..d3ceb328420 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.3.0 +version: 0.3.1-dev groups: - csharp - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 8f46c7040bb..c360e550193 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.2.1 +version: 0.2.2-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 3aff018b452..75ed3c98275 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.2.1 +version: 0.2.2-dev groups: - go - queries diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 29b02e16b6e..0de218dcd22 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.3.1 +version: 0.3.2-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index b0790498fe3..9cd3341f443 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.3.0 +version: 0.3.1-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index cb4b01d90b0..9a05a09e0b6 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.2.1 +version: 0.2.2-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 07ac096af64..5525fe8b54b 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.3.0 +version: 0.3.1-dev groups: - javascript - queries diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 7aac7c78527..f1a7c716b1e 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.5.1 +version: 0.5.2-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index 6d07cdc1ab3..155e57024e8 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.3.0 +version: 0.3.1-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 5b67e5ccd50..8216fedd9d2 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.3.1 +version: 0.3.2-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 6a55e6cecd3..6715fc61912 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.3.0 +version: 0.3.1-dev groups: - ruby - queries From 2f505491843462ca10128402d0dd39b27e9fe2d1 Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Fri, 15 Jul 2022 11:06:24 -0700 Subject: [PATCH 367/465] Move definitions.ql back to src --- go/ql/{lib => src}/definitions.ql | 0 javascript/ql/{lib => src}/definitions.ql | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename go/ql/{lib => src}/definitions.ql (100%) rename javascript/ql/{lib => src}/definitions.ql (100%) diff --git a/go/ql/lib/definitions.ql b/go/ql/src/definitions.ql similarity index 100% rename from go/ql/lib/definitions.ql rename to go/ql/src/definitions.ql diff --git a/javascript/ql/lib/definitions.ql b/javascript/ql/src/definitions.ql similarity index 100% rename from javascript/ql/lib/definitions.ql rename to javascript/ql/src/definitions.ql From b897a40228a8a9cf852680038e4b1ccc8be1ea6a Mon Sep 17 00:00:00 2001 From: Andrew Eisenberg Date: Fri, 15 Jul 2022 12:06:41 -0700 Subject: [PATCH 368/465] Move python contextual queries to lib folders This will ensure that python projects can use jump to ref/def in vscode when the core libraries are not installed. --- python/ql/{src => lib}/analysis/LocalDefinitions.ql | 0 python/ql/{src => lib}/analysis/LocalReferences.ql | 0 .../src/change-notes/2022-07-15-move-contextual-queries.md | 5 +++++ 3 files changed, 5 insertions(+) rename python/ql/{src => lib}/analysis/LocalDefinitions.ql (100%) rename python/ql/{src => lib}/analysis/LocalReferences.ql (100%) create mode 100644 python/ql/src/change-notes/2022-07-15-move-contextual-queries.md diff --git a/python/ql/src/analysis/LocalDefinitions.ql b/python/ql/lib/analysis/LocalDefinitions.ql similarity index 100% rename from python/ql/src/analysis/LocalDefinitions.ql rename to python/ql/lib/analysis/LocalDefinitions.ql diff --git a/python/ql/src/analysis/LocalReferences.ql b/python/ql/lib/analysis/LocalReferences.ql similarity index 100% rename from python/ql/src/analysis/LocalReferences.ql rename to python/ql/lib/analysis/LocalReferences.ql diff --git a/python/ql/src/change-notes/2022-07-15-move-contextual-queries.md b/python/ql/src/change-notes/2022-07-15-move-contextual-queries.md new file mode 100644 index 00000000000..25ae1b57b99 --- /dev/null +++ b/python/ql/src/change-notes/2022-07-15-move-contextual-queries.md @@ -0,0 +1,5 @@ +--- +category: breaking +--- +* Contextual queries and the query libraries they depend on have been moved to the `codeql/python-all` package. + From fe789c8aa97b95be0fb49d8151f6a8816b6463a1 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Sat, 16 Jul 2022 08:22:18 -0700 Subject: [PATCH 369/465] Update java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql Co-authored-by: yo-h <55373593+yo-h@users.noreply.github.com> --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index ba78fa56423..5fac4f2c6c9 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -51,8 +51,8 @@ predicate isCreatingAzureClientSideEncryptionObjectNewVersion(Call call, Class c * A dataflow config that tracks `EncryptedBlobClientBuilder.version` argument initialization. */ private class EncryptedBlobClientBuilderSafeEncryptionVersionConfig extends DataFlow::Configuration { - EncryptedBlobClientBuilderEncryptionVersionConfig() { - this = "EncryptedBlobClientBuilderEncryptionVersionConfig" + EncryptedBlobClientBuilderSafeEncryptionVersionConfig() { + this = "EncryptedBlobClientBuilderSafeEncryptionVersionConfig" } override predicate isSource(DataFlow::Node source) { From eefa6595038ea4eba8abc6ab4efe513598954692 Mon Sep 17 00:00:00 2001 From: Raul Garcia <42392023+raulgarciamsft@users.noreply.github.com> Date: Sat, 16 Jul 2022 08:23:59 -0700 Subject: [PATCH 370/465] Update java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql Co-authored-by: yo-h <55373593+yo-h@users.noreply.github.com> --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 5fac4f2c6c9..287a3f07a6c 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -74,7 +74,7 @@ private class EncryptedBlobClientBuilderSafeEncryptionVersionConfig extends Data */ predicate isCreatingSafeAzureClientSideEncryptionObject(Call call, Class c, Expr versionArg) { isCreatingAzureClientSideEncryptionObjectNewVersion(call, c, versionArg) and - exists(EncryptedBlobClientBuilderEncryptionVersionConfig config, DataFlow::Node sink | + exists(EncryptedBlobClientBuilderSafeEncryptionVersionConfig config, DataFlow::Node sink | sink.asExpr() = versionArg | config.hasFlow(_, sink) From 6b17890e4f0adefdd7127197fd08857bc6296131 Mon Sep 17 00:00:00 2001 From: Raul Garcia Date: Sat, 16 Jul 2022 08:30:06 -0700 Subject: [PATCH 371/465] Fixing warning on usage of a deprecated feature. --- .../CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql index 3b35f2350bd..c9687b17821 100644 --- a/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql +++ b/python/ql/src/experimental/Security/CWE-327/Azure/UnsafeUsageOfClientSideEncryptionVersion.ql @@ -33,7 +33,7 @@ predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrN .getMember("BlobClient") .getReturn() .getMember("upload_blob") and - n.getAUse().asExpr() = a and + n.getAValueReachableFromSource().asExpr() = a and astmt.getATarget() = a and a.getAFlowNode() = node and uploadBlob = @@ -60,7 +60,7 @@ predicate isUnsafeClientSideAzureStorageEncryptionViaAttributes(Call call, AttrN .getMember("BlobClient") .getReturn() .getMember("encryption_version") and - encryptionVersion.getAUse().asExpr() = a2 and + encryptionVersion.getAValueReachableFromSource().asExpr() = a2 and astmt2.getATarget() = a2 and a2.getAFlowNode() = encryptionVersionSet and encryptionVersionSet.strictlyReaches(ctrlFlowNode) From dbd660787541d5f36264052d82910207fc2d3b01 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Mon, 18 Jul 2022 08:54:58 +0100 Subject: [PATCH 372/465] Ruby: use ASCII dash in comment Co-authored-by: Harry Maclean --- ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll index e2cea924838..b6381c448ec 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/stdlib/Pathname.qll @@ -22,7 +22,7 @@ module Pathname { * puts pn.read * ``` * - * there are three `PathnameInstance`s – the call to `Pathname.new`, the + * there are three `PathnameInstance`s - the call to `Pathname.new`, the * assignment `pn = ...`, and the read access to `pn` on the second line. * * Every `PathnameInstance` is considered to be a `FileNameSource`. From 78fc356febfc28d4175b4881b664d796a8c37e94 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 18 Jul 2022 10:29:20 +0200 Subject: [PATCH 373/465] Swift: address review comments --- swift/extractor/infra/SwiftDispatcher.h | 7 ++++--- swift/extractor/visitors/ExprVisitor.cpp | 2 +- swift/extractor/visitors/ExprVisitor.h | 8 +++++--- swift/extractor/visitors/TypeVisitor.cpp | 2 ++ 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index 095ddf0a7aa..baf3bdba292 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -78,7 +78,7 @@ class SwiftDispatcher { waitingForNewLabel = e; visit(e); if (auto l = store.get(e)) { - if constexpr (std::is_base_of_v>) { + if constexpr (!std::is_base_of_v) { attachLocation(e, *l); } return *l; @@ -285,8 +285,9 @@ class SwiftDispatcher { return realPath.str().str(); } - // TODO: The following methods are supposed to redirect TRAP emission to correpsonding visitors, - // which are to be introduced in follow-up PRs + // TODO: for const correctness these should consistently be `const` (and maybe const references + // as we don't expect `nullptr` here. However `swift::ASTVisitor` and `swift::TypeVisitor` do not + // accept const pointers virtual void visit(swift::Decl* decl) = 0; virtual void visit(const swift::IfConfigClause* clause) = 0; virtual void visit(swift::Stmt* stmt) = 0; diff --git a/swift/extractor/visitors/ExprVisitor.cpp b/swift/extractor/visitors/ExprVisitor.cpp index 90ca0a168ee..e1baf3a80dc 100644 --- a/swift/extractor/visitors/ExprVisitor.cpp +++ b/swift/extractor/visitors/ExprVisitor.cpp @@ -667,11 +667,11 @@ void ExprVisitor::emitLookupExpr(const swift::LookupExpr* expr, TrapLabel { codeql::BridgeFromObjCExpr translateBridgeFromObjCExpr(const swift::BridgeFromObjCExpr& expr); codeql::DotSelfExpr translateDotSelfExpr(const swift::DotSelfExpr& expr); codeql::ErrorExpr translateErrorExpr(const swift::ErrorExpr& expr); - // following requires non-const because: - // * `swift::UnresolvedPatternExpr::getSubPattern` gives `const swift::Pattern*` on const refs + // The following function requires a non-const parameter because: + // * `swift::UnresolvedPatternExpr::getSubPattern` has a `const`-qualified overload returning + // `const swift::Pattern*` // * `swift::ASTVisitor` only visits non-const pointers - // either we accept this, or we fix constness by providing our own const visiting in VisitorBase + // either we accept this, or we fix constness, e.g. by providing `visit` on `const` pointers + // in `VisitorBase`, or by doing a `const_cast` in `SwifDispatcher::fetchLabel` codeql::UnresolvedPatternExpr translateUnresolvedPatternExpr(swift::UnresolvedPatternExpr& expr); private: diff --git a/swift/extractor/visitors/TypeVisitor.cpp b/swift/extractor/visitors/TypeVisitor.cpp index 945ef5693ce..988e16b527c 100644 --- a/swift/extractor/visitors/TypeVisitor.cpp +++ b/swift/extractor/visitors/TypeVisitor.cpp @@ -1,4 +1,5 @@ #include "swift/extractor/visitors/TypeVisitor.h" + namespace codeql { void TypeVisitor::visit(swift::TypeBase* type) { TypeVisitorBase::visit(type); @@ -367,6 +368,7 @@ codeql::BuiltinVectorType TypeVisitor::translateBuiltinVectorType( const swift::BuiltinVectorType& type) { return createTypeEntry(type); } + codeql::OpenedArchetypeType TypeVisitor::translateOpenedArchetypeType( const swift::OpenedArchetypeType& type) { auto entry = createTypeEntry(type); From c08c3955d6f5ebe824eb9570edf3d463e4fd66f4 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 18 Jul 2022 10:37:54 +0200 Subject: [PATCH 374/465] Swift: add `UnresolvedPatternExpr` test --- swift/codegen/schema.yml | 1 - .../expr/UnresolvedPatternExpr/unresolved_pattern_expr.swift | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/unresolved_pattern_expr.swift diff --git a/swift/codegen/schema.yml b/swift/codegen/schema.yml index 540f187d021..13d01fefc0e 100644 --- a/swift/codegen/schema.yml +++ b/swift/codegen/schema.yml @@ -569,7 +569,6 @@ UnresolvedMemberExpr: UnresolvedPatternExpr: _extends: Expr - _pragma: qltest_skip # we should really never extract these _children: sub_pattern: Pattern diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/unresolved_pattern_expr.swift b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/unresolved_pattern_expr.swift new file mode 100644 index 00000000000..2ca1bbb7c24 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/unresolved_pattern_expr.swift @@ -0,0 +1,5 @@ +#if FOO +if case let .some(x) = 42 { + print(x) +} +#endif From c779936ee80e68ae324c3cd0a8ba98ec530c60e7 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Mon, 18 Jul 2022 11:19:40 +0200 Subject: [PATCH 375/465] Swift: commit forgotten files --- .../UnresolvedPatternExpr.expected | 1 + .../UnresolvedPatternExpr/UnresolvedPatternExpr.ql | 10 ++++++++++ .../UnresolvedPatternExpr_getType.expected | 0 .../UnresolvedPatternExpr_getType.ql | 7 +++++++ 4 files changed, 18 insertions(+) create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.expected create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.ql create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr_getType.expected create mode 100644 swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr_getType.ql diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.expected b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.expected new file mode 100644 index 00000000000..3f348092bdb --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.expected @@ -0,0 +1 @@ +| unresolved_pattern_expr.swift:2:19:2:19 | UnresolvedPatternExpr | getSubPattern: | unresolved_pattern_expr.swift:2:19:2:19 | x | diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.ql new file mode 100644 index 00000000000..9a5f8e54490 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr.ql @@ -0,0 +1,10 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from UnresolvedPatternExpr x, Pattern getSubPattern +where + toBeTested(x) and + not x.isUnknown() and + getSubPattern = x.getSubPattern() +select x, "getSubPattern:", getSubPattern diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr_getType.expected b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr_getType.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr_getType.ql b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr_getType.ql new file mode 100644 index 00000000000..af57d0129a1 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/expr/UnresolvedPatternExpr/UnresolvedPatternExpr_getType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from UnresolvedPatternExpr x +where toBeTested(x) and not x.isUnknown() +select x, x.getType() From 39fb714ad17e91cefbb3fa9a7160836ef8f3a303 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 18 Jul 2022 12:54:35 +0100 Subject: [PATCH 376/465] Swift: Add test with substring declared differently. --- .../CWE-135/StringLengthConflation.expected | 4 ++ .../CWE-135/StringLengthConflation2.swift | 42 +++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation2.swift diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected index 1af416dad2f..e5191b6446d 100644 --- a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation.expected @@ -1,4 +1,5 @@ edges +| StringLengthConflation2.swift:37:34:37:36 | .count : | StringLengthConflation2.swift:37:34:37:44 | ... call to -(_:_:) ... | | StringLengthConflation.swift:60:47:60:50 | .length : | StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | | StringLengthConflation.swift:66:33:66:36 | .length : | StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | | StringLengthConflation.swift:93:28:93:31 | .length : | StringLengthConflation.swift:93:28:93:40 | ... call to -(_:_:) ... | @@ -15,6 +16,8 @@ edges | StringLengthConflation.swift:135:36:135:38 | .count : | StringLengthConflation.swift:135:36:135:46 | ... call to -(_:_:) ... | | StringLengthConflation.swift:141:28:141:30 | .count : | StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | nodes +| StringLengthConflation2.swift:37:34:37:36 | .count : | semmle.label | .count : | +| StringLengthConflation2.swift:37:34:37:44 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | | StringLengthConflation.swift:53:43:53:46 | .length | semmle.label | .length | | StringLengthConflation.swift:60:47:60:50 | .length : | semmle.label | .length : | | StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | semmle.label | ... call to /(_:_:) ... | @@ -50,6 +53,7 @@ nodes | StringLengthConflation.swift:141:28:141:38 | ... call to -(_:_:) ... | semmle.label | ... call to -(_:_:) ... | subpaths #select +| StringLengthConflation2.swift:37:34:37:44 | ... call to -(_:_:) ... | StringLengthConflation2.swift:37:34:37:36 | .count : | StringLengthConflation2.swift:37:34:37:44 | ... call to -(_:_:) ... | 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:60:47:60:59 | ... call to /(_:_:) ... | StringLengthConflation.swift:60:47:60:50 | .length : | StringLengthConflation.swift:60:47:60:59 | ... call to /(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | | StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | StringLengthConflation.swift:66:33:66:36 | .length : | StringLengthConflation.swift:66:33:66:45 | ... call to /(_:_:) ... | This NSString length is used in a String, but it may not be equivalent. | diff --git a/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation2.swift b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation2.swift new file mode 100644 index 00000000000..39b1456e604 --- /dev/null +++ b/swift/ql/test/query-tests/Security/CWE-135/StringLengthConflation2.swift @@ -0,0 +1,42 @@ +// this test is in a separate file, because we want to test with a slightly different library +// implementation. In this version, some of the functions of `NSString` are in fact implemented +// in a base class `NSStringBase`. + +// --- stubs --- + +func print(_ items: Any...) {} + +typealias unichar = UInt16 + +class NSObject +{ +} + +class NSStringBase : NSObject +{ + func substring(from: Int) -> String { return "" } +} + +class NSString : NSStringBase +{ + init(string: String) { length = string.count } + + func substring(to: Int) -> String { return "" } + + private(set) var length: Int +} + +// --- tests --- + +func test(s: String) { + let ns = NSString(string: s) + + let nstr1 = ns.substring(from: ns.length - 1) // GOOD + let nstr2 = ns.substring(from: s.count - 1) // BAD: String length used in NSString [NOT DETECTED] + let nstr3 = ns.substring(to: ns.length - 1) // GOOD + let nstr4 = ns.substring(to: s.count - 1) // BAD: String length used in NSString + print("substrings '\(nstr1)' '\(nstr2)' / '\(nstr3)' '\(nstr4)'") +} + +// `begin :thumbsup: end`, with thumbs up emoji and skin tone modifier +test(s: "begin \u{0001F44D}\u{0001F3FF} end") From 4854679a4010f415e80151c4f797afff3e1f2ed0 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 18 Jul 2022 13:04:20 +0100 Subject: [PATCH 377/465] Swift: Clean up isSink (1 - move common variables to an outer exists). --- .../CWE-135/StringLengthConflation.ql | 163 +++++++++--------- 1 file changed, 81 insertions(+), 82 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 398c48f01e5..fa5c5f25e9d 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -41,88 +41,87 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { } override predicate isSink(DataFlow::Node node, string flowstate) { - // arguments to method calls... - exists( - string className, string methodName, string paramName, ClassDecl c, AbstractFunctionDecl f, - CallExpr call, int arg - | - ( - // `NSRange.init` - className = "NSRange" and - methodName = "init(location:length:)" and - paramName = ["location", "length"] - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - methodName = "character(at:)" and - paramName = "at" - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - methodName = "substring(from:)" and - paramName = "from" - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - methodName = "substring(to:)" and - paramName = "to" - or - // `NSMutableString.insert` - className = "NSMutableString" and - methodName = "insert(_:at:)" and - paramName = "at" - ) and - c.getName() = className and - c.getAMember() = f and // TODO: will this even work if its defined in a parent class? - call.getFunction().(ApplyExpr).getStaticTarget() = f and - f.getName() = methodName and - f.getParam(pragma[only_bind_into](arg)).getName() = paramName and - call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and - flowstate = "String" // `String` length flowing into `NSString` - ) - or - // arguments to function calls... - exists(string funcName, string paramName, CallExpr call, int arg | - // `NSMakeRange` - funcName = "NSMakeRange(_:_:)" and - paramName = ["loc", "len"] and - call.getStaticTarget().getName() = funcName and - call.getStaticTarget().getParam(pragma[only_bind_into](arg)).getName() = paramName and - call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and - flowstate = "String" // `String` length flowing into `NSString` - ) - or - // arguments to function calls... - exists(string funcName, string paramName, CallExpr call, int arg | - ( - // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` - funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and - paramName = "k" - or - // `String.prefix`, `String.suffix` - funcName = ["prefix(_:)", "suffix(_:)"] and - paramName = "maxLength" - or - // `String.Index.init` - funcName = "init(encodedOffset:)" and - paramName = "offset" - or - // `String.index` - funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and - paramName = "n" - or - // `String.formIndex` - funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and - paramName = "distance" - ) and - call.getFunction().(ApplyExpr).getStaticTarget().getName() = funcName and - call.getFunction() - .(ApplyExpr) - .getStaticTarget() - .getParam(pragma[only_bind_into](arg)) - .getName() = paramName and - call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and - flowstate = "NSString" // `NSString` length flowing into `String` + exists(CallExpr call, string paramName, int arg | + // arguments to method calls... + exists(string className, string methodName, ClassDecl c, AbstractFunctionDecl f | + ( + // `NSRange.init` + className = "NSRange" and + methodName = "init(location:length:)" and + paramName = ["location", "length"] + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + methodName = "character(at:)" and + paramName = "at" + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + methodName = "substring(from:)" and + paramName = "from" + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + methodName = "substring(to:)" and + paramName = "to" + or + // `NSMutableString.insert` + className = "NSMutableString" and + methodName = "insert(_:at:)" and + paramName = "at" + ) and + c.getName() = className and + c.getAMember() = f and // TODO: will this even work if its defined in a parent class? + call.getFunction().(ApplyExpr).getStaticTarget() = f and + f.getName() = methodName and + f.getParam(pragma[only_bind_into](arg)).getName() = paramName and + call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and + flowstate = "String" // `String` length flowing into `NSString` + ) + or + // arguments to function calls... + exists(string funcName | + // `NSMakeRange` + funcName = "NSMakeRange(_:_:)" and + paramName = ["loc", "len"] and + call.getStaticTarget().getName() = funcName and + call.getStaticTarget().getParam(pragma[only_bind_into](arg)).getName() = paramName and + call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and + flowstate = "String" // `String` length flowing into `NSString` + ) + or + // arguments to function calls... + exists(string funcName | + ( + // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` + funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and + paramName = "k" + or + // `String.prefix`, `String.suffix` + funcName = ["prefix(_:)", "suffix(_:)"] and + paramName = "maxLength" + or + // `String.Index.init` + funcName = "init(encodedOffset:)" and + paramName = "offset" + or + // `String.index` + funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and + paramName = "n" + or + // `String.formIndex` + funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and + paramName = "distance" + ) and + call.getFunction().(ApplyExpr).getStaticTarget().getName() = funcName and + call.getFunction() + .(ApplyExpr) + .getStaticTarget() + .getParam(pragma[only_bind_into](arg)) + .getName() = paramName and + call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and + flowstate = "NSString" // `NSString` length flowing into `String` + ) ) } From 0bd94a630761b0fdf103832f8f864407755b5790 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 18 Jul 2022 13:04:57 +0100 Subject: [PATCH 378/465] Swift: Clean up isSink (2 - rename methodName -> funcName and move that out as well). --- .../CWE-135/StringLengthConflation.ql | 92 +++++++++---------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index fa5c5f25e9d..131e2b72ceb 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -41,87 +41,83 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { } override predicate isSink(DataFlow::Node node, string flowstate) { - exists(CallExpr call, string paramName, int arg | + exists(CallExpr call, string funcName, string paramName, int arg | // arguments to method calls... - exists(string className, string methodName, ClassDecl c, AbstractFunctionDecl f | + exists(string className, ClassDecl c, AbstractFunctionDecl f | ( // `NSRange.init` className = "NSRange" and - methodName = "init(location:length:)" and + funcName = "init(location:length:)" and paramName = ["location", "length"] or // `NSString.character` className = ["NSString", "NSMutableString"] and - methodName = "character(at:)" and + funcName = "character(at:)" and paramName = "at" or // `NSString.character` className = ["NSString", "NSMutableString"] and - methodName = "substring(from:)" and + funcName = "substring(from:)" and paramName = "from" or // `NSString.character` className = ["NSString", "NSMutableString"] and - methodName = "substring(to:)" and + funcName = "substring(to:)" and paramName = "to" or // `NSMutableString.insert` className = "NSMutableString" and - methodName = "insert(_:at:)" and + funcName = "insert(_:at:)" and paramName = "at" ) and c.getName() = className and c.getAMember() = f and // TODO: will this even work if its defined in a parent class? call.getFunction().(ApplyExpr).getStaticTarget() = f and - f.getName() = methodName and + f.getName() = funcName and f.getParam(pragma[only_bind_into](arg)).getName() = paramName and call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and flowstate = "String" // `String` length flowing into `NSString` ) or // arguments to function calls... - exists(string funcName | - // `NSMakeRange` - funcName = "NSMakeRange(_:_:)" and - paramName = ["loc", "len"] and - call.getStaticTarget().getName() = funcName and - call.getStaticTarget().getParam(pragma[only_bind_into](arg)).getName() = paramName and - call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and - flowstate = "String" // `String` length flowing into `NSString` - ) + // `NSMakeRange` + funcName = "NSMakeRange(_:_:)" and + paramName = ["loc", "len"] and + call.getStaticTarget().getName() = funcName and + call.getStaticTarget().getParam(pragma[only_bind_into](arg)).getName() = paramName and + call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and + flowstate = "String" // `String` length flowing into `NSString` or // arguments to function calls... - exists(string funcName | - ( - // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` - funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and - paramName = "k" - or - // `String.prefix`, `String.suffix` - funcName = ["prefix(_:)", "suffix(_:)"] and - paramName = "maxLength" - or - // `String.Index.init` - funcName = "init(encodedOffset:)" and - paramName = "offset" - or - // `String.index` - funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and - paramName = "n" - or - // `String.formIndex` - funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and - paramName = "distance" - ) and - call.getFunction().(ApplyExpr).getStaticTarget().getName() = funcName and - call.getFunction() - .(ApplyExpr) - .getStaticTarget() - .getParam(pragma[only_bind_into](arg)) - .getName() = paramName and - call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and - flowstate = "NSString" // `NSString` length flowing into `String` - ) + ( + // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` + funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and + paramName = "k" + or + // `String.prefix`, `String.suffix` + funcName = ["prefix(_:)", "suffix(_:)"] and + paramName = "maxLength" + or + // `String.Index.init` + funcName = "init(encodedOffset:)" and + paramName = "offset" + or + // `String.index` + funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and + paramName = "n" + or + // `String.formIndex` + funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and + paramName = "distance" + ) and + call.getFunction().(ApplyExpr).getStaticTarget().getName() = funcName and + call.getFunction() + .(ApplyExpr) + .getStaticTarget() + .getParam(pragma[only_bind_into](arg)) + .getName() = paramName and + call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and + flowstate = "NSString" // `NSString` length flowing into `String` ) } From b136790efd53ba3488fc3a3c4b4c0b0f9749dbe7 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 18 Jul 2022 13:06:32 +0100 Subject: [PATCH 379/465] Swift: Clean up isSink (3 - rename f -> funcDecl and move that out as well; in the other two cases this variable didn't exist, now it does). --- .../CWE-135/StringLengthConflation.ql | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 131e2b72ceb..117cbac1e27 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -41,9 +41,11 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { } override predicate isSink(DataFlow::Node node, string flowstate) { - exists(CallExpr call, string funcName, string paramName, int arg | + exists( + AbstractFunctionDecl funcDecl, CallExpr call, string funcName, string paramName, int arg + | // arguments to method calls... - exists(string className, ClassDecl c, AbstractFunctionDecl f | + exists(string className, ClassDecl c | ( // `NSRange.init` className = "NSRange" and @@ -71,10 +73,10 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { paramName = "at" ) and c.getName() = className and - c.getAMember() = f and // TODO: will this even work if its defined in a parent class? - call.getFunction().(ApplyExpr).getStaticTarget() = f and - f.getName() = funcName and - f.getParam(pragma[only_bind_into](arg)).getName() = paramName and + c.getAMember() = funcDecl and // TODO: will this even work if its defined in a parent class? + call.getFunction().(ApplyExpr).getStaticTarget() = funcDecl and + funcDecl.getName() = funcName and + funcDecl.getParam(pragma[only_bind_into](arg)).getName() = paramName and call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and flowstate = "String" // `String` length flowing into `NSString` ) @@ -83,8 +85,9 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { // `NSMakeRange` funcName = "NSMakeRange(_:_:)" and paramName = ["loc", "len"] and - call.getStaticTarget().getName() = funcName and - call.getStaticTarget().getParam(pragma[only_bind_into](arg)).getName() = paramName and + call.getStaticTarget() = funcDecl and + funcDecl.getName() = funcName and + funcDecl.getParam(pragma[only_bind_into](arg)).getName() = paramName and call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and flowstate = "String" // `String` length flowing into `NSString` or @@ -110,12 +113,9 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and paramName = "distance" ) and - call.getFunction().(ApplyExpr).getStaticTarget().getName() = funcName and - call.getFunction() - .(ApplyExpr) - .getStaticTarget() - .getParam(pragma[only_bind_into](arg)) - .getName() = paramName and + call.getFunction().(ApplyExpr).getStaticTarget() = funcDecl and + funcDecl.getName() = funcName and + funcDecl.getParam(pragma[only_bind_into](arg)).getName() = paramName and call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and flowstate = "NSString" // `NSString` length flowing into `String` ) From 9474e63faf23cda600ef3b1006dda2d4dfb31a15 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 18 Jul 2022 13:08:31 +0100 Subject: [PATCH 380/465] Swift: Clean up isSink (4 - move common code out). --- .../CWE-135/StringLengthConflation.ql | 132 +++++++++--------- 1 file changed, 64 insertions(+), 68 deletions(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 117cbac1e27..62e166487ec 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -44,80 +44,76 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { exists( AbstractFunctionDecl funcDecl, CallExpr call, string funcName, string paramName, int arg | - // arguments to method calls... - exists(string className, ClassDecl c | - ( - // `NSRange.init` - className = "NSRange" and - funcName = "init(location:length:)" and - paramName = ["location", "length"] - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - funcName = "character(at:)" and - paramName = "at" - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - funcName = "substring(from:)" and - paramName = "from" - or - // `NSString.character` - className = ["NSString", "NSMutableString"] and - funcName = "substring(to:)" and - paramName = "to" - or - // `NSMutableString.insert` - className = "NSMutableString" and - funcName = "insert(_:at:)" and - paramName = "at" - ) and - c.getName() = className and - c.getAMember() = funcDecl and // TODO: will this even work if its defined in a parent class? - call.getFunction().(ApplyExpr).getStaticTarget() = funcDecl and - funcDecl.getName() = funcName and - funcDecl.getParam(pragma[only_bind_into](arg)).getName() = paramName and - call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and - flowstate = "String" // `String` length flowing into `NSString` - ) - or - // arguments to function calls... - // `NSMakeRange` - funcName = "NSMakeRange(_:_:)" and - paramName = ["loc", "len"] and - call.getStaticTarget() = funcDecl and - funcDecl.getName() = funcName and - funcDecl.getParam(pragma[only_bind_into](arg)).getName() = paramName and - call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and - flowstate = "String" // `String` length flowing into `NSString` - or - // arguments to function calls... ( - // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` - funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and - paramName = "k" + // arguments to method calls... + exists(string className, ClassDecl c | + ( + // `NSRange.init` + className = "NSRange" and + funcName = "init(location:length:)" and + paramName = ["location", "length"] + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + funcName = "character(at:)" and + paramName = "at" + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + funcName = "substring(from:)" and + paramName = "from" + or + // `NSString.character` + className = ["NSString", "NSMutableString"] and + funcName = "substring(to:)" and + paramName = "to" + or + // `NSMutableString.insert` + className = "NSMutableString" and + funcName = "insert(_:at:)" and + paramName = "at" + ) and + c.getName() = className and + c.getAMember() = funcDecl and // TODO: will this even work if its defined in a parent class? + call.getFunction().(ApplyExpr).getStaticTarget() = funcDecl and + flowstate = "String" // `String` length flowing into `NSString` + ) or - // `String.prefix`, `String.suffix` - funcName = ["prefix(_:)", "suffix(_:)"] and - paramName = "maxLength" + // arguments to function calls... + // `NSMakeRange` + funcName = "NSMakeRange(_:_:)" and + paramName = ["loc", "len"] and + call.getStaticTarget() = funcDecl and + flowstate = "String" // `String` length flowing into `NSString` or - // `String.Index.init` - funcName = "init(encodedOffset:)" and - paramName = "offset" - or - // `String.index` - funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and - paramName = "n" - or - // `String.formIndex` - funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and - paramName = "distance" + // arguments to function calls... + ( + // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` + funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and + paramName = "k" + or + // `String.prefix`, `String.suffix` + funcName = ["prefix(_:)", "suffix(_:)"] and + paramName = "maxLength" + or + // `String.Index.init` + funcName = "init(encodedOffset:)" and + paramName = "offset" + or + // `String.index` + funcName = ["index(_:offsetBy:)", "index(_:offsetBy:limitBy:)"] and + paramName = "n" + or + // `String.formIndex` + funcName = ["formIndex(_:offsetBy:)", "formIndex(_:offsetBy:limitBy:)"] and + paramName = "distance" + ) and + call.getFunction().(ApplyExpr).getStaticTarget() = funcDecl and + flowstate = "NSString" // `NSString` length flowing into `String` ) and - call.getFunction().(ApplyExpr).getStaticTarget() = funcDecl and funcDecl.getName() = funcName and funcDecl.getParam(pragma[only_bind_into](arg)).getName() = paramName and - call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() and - flowstate = "NSString" // `NSString` length flowing into `String` + call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() ) } From 336548f746dedabeb5813821e7a4b05f7b8ce76b Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 18 Jul 2022 13:10:18 +0100 Subject: [PATCH 381/465] Swift: Improve comments. --- .../ql/src/queries/Security/CWE-135/StringLengthConflation.ql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 62e166487ec..50001985055 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -86,7 +86,7 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { call.getStaticTarget() = funcDecl and flowstate = "String" // `String` length flowing into `NSString` or - // arguments to function calls... + // arguments to method calls... ( // `String.dropFirst`, `String.dropLast`, `String.removeFirst`, `String.removeLast` funcName = ["dropFirst(_:)", "dropLast(_:)", "removeFirst(_:)", "removeLast(_:)"] and @@ -111,6 +111,7 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { call.getFunction().(ApplyExpr).getStaticTarget() = funcDecl and flowstate = "NSString" // `NSString` length flowing into `String` ) and + // match up `funcName`, `paramName`, `arg`, `node`. funcDecl.getName() = funcName and funcDecl.getParam(pragma[only_bind_into](arg)).getName() = paramName and call.getArgument(pragma[only_bind_into](arg)).getExpr() = node.asExpr() From 541df9b5505eca66b5afe8aa1c91487d77672157 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 18 Jul 2022 14:26:08 +0100 Subject: [PATCH 382/465] Swift: Remove TODO comment. We have a test for this problem now. --- swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql index 50001985055..4e78d56f7d2 100644 --- a/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql +++ b/swift/ql/src/queries/Security/CWE-135/StringLengthConflation.ql @@ -74,7 +74,7 @@ class StringLengthConflationConfiguration extends DataFlow::Configuration { paramName = "at" ) and c.getName() = className and - c.getAMember() = funcDecl and // TODO: will this even work if its defined in a parent class? + c.getAMember() = funcDecl and call.getFunction().(ApplyExpr).getStaticTarget() = funcDecl and flowstate = "String" // `String` length flowing into `NSString` ) From c9e5206396600f6ed11fec6bcd765a10696f4d8d Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Mon, 18 Jul 2022 15:26:38 +0200 Subject: [PATCH 383/465] Ruby: skip .git folder --- ruby/autobuilder/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/ruby/autobuilder/src/main.rs b/ruby/autobuilder/src/main.rs index 8f0f1b48d0d..ae4aa816190 100644 --- a/ruby/autobuilder/src/main.rs +++ b/ruby/autobuilder/src/main.rs @@ -19,6 +19,7 @@ fn main() -> std::io::Result<()> { .arg("--include-extension=.erb") .arg("--include-extension=.gemspec") .arg("--include=**/Gemfile") + .arg("--exclude=**/.git") .arg("--size-limit=5m") .arg("--language=ruby") .arg("--working-dir=.") From f9b6ca76e5d124eb1881fdc1c5d3a686523bdce6 Mon Sep 17 00:00:00 2001 From: alexet Date: Mon, 18 Jul 2022 16:28:19 +0100 Subject: [PATCH 384/465] Python: Fix binding incorrect predicate. --- .../lib/semmle/python/frameworks/internal/SubclassFinder.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll index 47521ac0b31..04b0a9e4afd 100644 --- a/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll +++ b/python/ql/lib/semmle/python/frameworks/internal/SubclassFinder.qll @@ -74,9 +74,7 @@ private module NotExposed { } /** DEPRECATED: Alias for fullyQualifiedToApiGraphPath */ - deprecated string fullyQualifiedToAPIGraphPath(string fullyQaulified) { - result = fullyQualifiedToApiGraphPath(fullyQaulified) - } + deprecated predicate fullyQualifiedToAPIGraphPath = fullyQualifiedToApiGraphPath/1; bindingset[this] abstract class FindSubclassesSpec extends string { From 7b8603c89b076fec2de4ecc474b1a43601d4ed98 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 18 Jul 2022 15:05:17 +1200 Subject: [PATCH 385/465] Ruby: Model Arel.sql --- ruby/ql/lib/codeql/ruby/Frameworks.qll | 1 + ruby/ql/lib/codeql/ruby/frameworks/Arel.qll | 31 +++++++++++++++++++ .../frameworks/arel/Arel.expected | 3 ++ .../library-tests/frameworks/arel/Arel.ql | 11 +++++++ .../library-tests/frameworks/arel/arel.rb | 14 +++++++++ 5 files changed, 60 insertions(+) create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/Arel.qll create mode 100644 ruby/ql/test/library-tests/frameworks/arel/Arel.expected create mode 100644 ruby/ql/test/library-tests/frameworks/arel/Arel.ql create mode 100644 ruby/ql/test/library-tests/frameworks/arel/arel.rb diff --git a/ruby/ql/lib/codeql/ruby/Frameworks.qll b/ruby/ql/lib/codeql/ruby/Frameworks.qll index 87b8a3f61a2..69ba758a767 100644 --- a/ruby/ql/lib/codeql/ruby/Frameworks.qll +++ b/ruby/ql/lib/codeql/ruby/Frameworks.qll @@ -10,6 +10,7 @@ private import codeql.ruby.frameworks.ActiveStorage private import codeql.ruby.frameworks.ActionView private import codeql.ruby.frameworks.ActiveSupport private import codeql.ruby.frameworks.Archive +private import codeql.ruby.frameworks.Arel private import codeql.ruby.frameworks.GraphQL private import codeql.ruby.frameworks.Rails private import codeql.ruby.frameworks.Railties diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll b/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll new file mode 100644 index 00000000000..9fa17f4e5a5 --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/Arel.qll @@ -0,0 +1,31 @@ +/** + * Provides modeling for Arel, a low level SQL library that powers ActiveRecord. + * Version: 7.0.3 + * https://api.rubyonrails.org/classes/Arel.html + */ + +private import codeql.ruby.ApiGraphs +private import codeql.ruby.dataflow.FlowSummary + +/** + * Provides modeling for Arel, a low level SQL library that powers ActiveRecord. + * Version: 7.0.3 + * https://api.rubyonrails.org/classes/Arel.html + */ +module Arel { + /** + * Flow summary for `Arel.sql`. This method wraps a SQL string, marking it as + * safe. + */ + private class SqlSummary extends SummarizedCallable { + SqlSummary() { this = "Arel.sql" } + + override MethodCall getACall() { + result = API::getTopLevelMember("Arel").getAMethodCall("sql").asExpr().getExpr() + } + + override predicate propagatesFlowExt(string input, string output, boolean preservesValue) { + input = "Argument[0]" and output = "ReturnValue" and preservesValue = false + } + } +} diff --git a/ruby/ql/test/library-tests/frameworks/arel/Arel.expected b/ruby/ql/test/library-tests/frameworks/arel/Arel.expected new file mode 100644 index 00000000000..63cd556e836 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/arel/Arel.expected @@ -0,0 +1,3 @@ +failures +#select +| arel.rb:3:8:3:18 | call to sql | arel.rb:2:7:2:14 | call to source : | arel.rb:3:8:3:18 | call to sql | $@ | arel.rb:2:7:2:14 | call to source : | call to source : | diff --git a/ruby/ql/test/library-tests/frameworks/arel/Arel.ql b/ruby/ql/test/library-tests/frameworks/arel/Arel.ql new file mode 100644 index 00000000000..197a710803e --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/arel/Arel.ql @@ -0,0 +1,11 @@ +/** + * @kind path-problem + */ + +import codeql.ruby.frameworks.Arel +import ruby +import TestUtilities.InlineFlowTest + +from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultTaintFlowConf conf +where conf.hasFlowPath(source, sink) +select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/frameworks/arel/arel.rb b/ruby/ql/test/library-tests/frameworks/arel/arel.rb new file mode 100644 index 00000000000..7e7bc51f9a8 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/arel/arel.rb @@ -0,0 +1,14 @@ +def m1 + x = source 1 + sink(Arel.sql(x)) # $hasTaintFlow=1 +end + +def m2 + x = 1 + sink(Arel.sql(x)) +end + +def m3 + x = source 1 + sink(Unrelated.method(x)) +end From 304203ad2f2cfeaafcc1dab46324937fb7415685 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Tue, 19 Jul 2022 00:25:27 +0000 Subject: [PATCH 386/465] fix path problem output --- .../ManuallyCheckHttpVerb.ql | 6 +++--- .../ManuallyCheckHttpVerb.expected | 21 +++++++++++++------ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql index e7553b39a3d..354ccf62698 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -90,7 +90,7 @@ class HttpVerbConfig extends TaintTracking::Configuration { } } -from HttpVerbConfig config, DataFlow::Node source, DataFlow::Node sink -where config.hasFlow(source, sink) -select sink.asExpr().getExpr(), source, sink, +from HttpVerbConfig config, DataFlow::PathNode source, DataFlow::PathNode sink +where config.hasFlow(source.getNode(), sink.getNode()) +select sink.getNode(), source, sink, "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods." diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected index 9102005a67e..a253c3e9313 100644 --- a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected @@ -24,9 +24,18 @@ nodes subpaths #select | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? : | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? : | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env : | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env : | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method : | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method : | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method : | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method : | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method : | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method : | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol : | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol : | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env : | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | +| ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env : | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | From 9586259706b1c855d7426a8c54aef3da8422355a Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Tue, 19 Jul 2022 00:29:30 +0000 Subject: [PATCH 387/465] style tweak for checking multiple method names --- ruby/ql/src/experimental/weak-params/WeakParams.ql | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql index 86ba72cbd91..0f36d4930d3 100644 --- a/ruby/ql/src/experimental/weak-params/WeakParams.ql +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -38,13 +38,8 @@ class ActionControllerRequest extends DataFlow::Node { class WeakParams extends DataFlow::CallNode { WeakParams() { this.getReceiver() instanceof ActionControllerRequest and - ( - this.getMethodName() = "path_parametes" or - this.getMethodName() = "query_parameters" or - this.getMethodName() = "request_parameters" or - this.getMethodName() = "GET" or - this.getMethodName() = "POST" - ) + this.getMethodName() = + ["path_parametes", "query_parameters", "request_parameters", "GET", "POST"] } } From 962155fd61596271a83003d05ae25cdc365b0488 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Tue, 19 Jul 2022 00:33:04 +0000 Subject: [PATCH 388/465] fix changenotes --- ...=> 2022-07-18-sqli-in-activerecord-relation-annotate.md} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename ruby/ql/lib/change-notes/{released/0.3.1.md => 2022-07-18-sqli-in-activerecord-relation-annotate.md} (64%) diff --git a/ruby/ql/lib/change-notes/released/0.3.1.md b/ruby/ql/lib/change-notes/2022-07-18-sqli-in-activerecord-relation-annotate.md similarity index 64% rename from ruby/ql/lib/change-notes/released/0.3.1.md rename to ruby/ql/lib/change-notes/2022-07-18-sqli-in-activerecord-relation-annotate.md index 392aa6f0b27..60ab137f8b2 100644 --- a/ruby/ql/lib/change-notes/released/0.3.1.md +++ b/ruby/ql/lib/change-notes/2022-07-18-sqli-in-activerecord-relation-annotate.md @@ -1,5 +1,5 @@ -## 0.3.1 - -### Minor Analysis Improvements +--- +category: minorAnalysis +--- - Calls to `ActiveRecord::Relation#annotate` are now recognized as`SqlExecution`s so that it will be considered as a sink for queries like rb/sql-injection. \ No newline at end of file From ec1d1eb54744cbfcd01f144be71fe3c311f3a061 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Tue, 19 Jul 2022 14:33:51 +1200 Subject: [PATCH 389/465] Ruby: Add change note --- ruby/ql/lib/change-notes/2022-07-19-arel.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ruby/ql/lib/change-notes/2022-07-19-arel.md diff --git a/ruby/ql/lib/change-notes/2022-07-19-arel.md b/ruby/ql/lib/change-notes/2022-07-19-arel.md new file mode 100644 index 00000000000..3dda3d4b1f6 --- /dev/null +++ b/ruby/ql/lib/change-notes/2022-07-19-arel.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Calls to `Arel.sql` are now recognised as propagating taint from their argument. From 0828474192694f508eb0a0b30326cf49e93b068a Mon Sep 17 00:00:00 2001 From: Henti Smith Date: Tue, 19 Jul 2022 15:34:10 +0100 Subject: [PATCH 390/465] Added Workflow::getName and Step::GetId --- javascript/ql/lib/semmle/javascript/Actions.qll | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/Actions.qll b/javascript/ql/lib/semmle/javascript/Actions.qll index f5b2c39b064..8e842c81e73 100644 --- a/javascript/ql/lib/semmle/javascript/Actions.qll +++ b/javascript/ql/lib/semmle/javascript/Actions.qll @@ -28,6 +28,9 @@ module Actions { /** Gets the `jobs` mapping from job IDs to job definitions in this workflow. */ YAMLMapping getJobs() { result = this.lookup("jobs") } + /** Gets the name of the workflow */ + string getName() { result = this.lookup("name").(YAMLString).getValue() } + /** Gets the name of the workflow file. */ string getFileName() { result = this.getFile().getBaseName() } @@ -129,6 +132,9 @@ module Actions { /** Gets the value of the `if` field in this step, if any. */ StepIf getIf() { result.getStep() = this } + + /** Gets the id of the step field, if any. */ + string getId() { result = this.lookup("id").(YAMLString).getValue() } } /** From dcc76ddf3629e8f579c68440a8aa20d67a90e656 Mon Sep 17 00:00:00 2001 From: Henti Smith <28868601+henti@users.noreply.github.com> Date: Tue, 19 Jul 2022 15:53:12 +0100 Subject: [PATCH 391/465] Apply suggestions from code review Co-authored-by: Henry Mercer --- javascript/ql/lib/semmle/javascript/Actions.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/semmle/javascript/Actions.qll b/javascript/ql/lib/semmle/javascript/Actions.qll index 8e842c81e73..8ea789c96e0 100644 --- a/javascript/ql/lib/semmle/javascript/Actions.qll +++ b/javascript/ql/lib/semmle/javascript/Actions.qll @@ -28,7 +28,7 @@ module Actions { /** Gets the `jobs` mapping from job IDs to job definitions in this workflow. */ YAMLMapping getJobs() { result = this.lookup("jobs") } - /** Gets the name of the workflow */ + /** Gets the name of the workflow. */ string getName() { result = this.lookup("name").(YAMLString).getValue() } /** Gets the name of the workflow file. */ @@ -133,7 +133,7 @@ module Actions { /** Gets the value of the `if` field in this step, if any. */ StepIf getIf() { result.getStep() = this } - /** Gets the id of the step field, if any. */ + /** Gets the ID of this step, if any. */ string getId() { result = this.lookup("id").(YAMLString).getValue() } } From 7620a6f6539dcbdf4efab6bd9a08335023c4d95a Mon Sep 17 00:00:00 2001 From: Aditya Sharad Date: Thu, 14 Jul 2022 12:08:22 -0700 Subject: [PATCH 392/465] Docs: Update supported languages page with links to CLI and pack information Include links to the CLI changelog, CLI releases, bundle releases, pack changelogs, and pack source. Clarify that this support information applies to the current version of the CLI, bundle, query packs, and library packs. --- .../supported-languages-and-frameworks.rst | 7 ++++-- docs/codeql/support/reusables/frameworks.rst | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst b/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst index 4353f9402b7..be66125846a 100644 --- a/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst +++ b/docs/codeql/codeql-overview/supported-languages-and-frameworks.rst @@ -11,14 +11,17 @@ CodeQL. Languages and compilers ####################### -CodeQL supports the following languages and compilers. +The current versions of the CodeQL CLI (`changelog `__, `releases `__), +CodeQL library packs (`source `__), +and CodeQL bundle (`releases `__) +support the following languages and compilers. .. include:: ../support/reusables/versions-compilers.rst Frameworks and libraries ######################## -The libraries and queries in the current version of CodeQL have been explicitly checked against the libraries and frameworks listed below. +The current versions of the CodeQL library and query packs (`source `__) have been explicitly checked against the libraries and frameworks listed below. .. pull-quote:: diff --git a/docs/codeql/support/reusables/frameworks.rst b/docs/codeql/support/reusables/frameworks.rst index 12bcd5af8e6..fc5410648cf 100644 --- a/docs/codeql/support/reusables/frameworks.rst +++ b/docs/codeql/support/reusables/frameworks.rst @@ -1,6 +1,10 @@ C and C++ built-in support ================================ +Provided by the current versions of the +CodeQL query pack ``codeql/cpp-queries`` (`changelog `__, `source `__) +and the CodeQL library pack ``codeql/cpp-all`` (`changelog `__, `source `__). + .. csv-table:: :header-rows: 1 :class: fullWidthTable @@ -14,6 +18,10 @@ C and C++ built-in support C# built-in support ================================ +Provided by the current versions of the +CodeQL query pack ``codeql/csharp-queries`` (`changelog `__, `source `__) +and the CodeQL library pack ``codeql/csharp-all`` (`changelog `__, `source `__). + .. csv-table:: :header-rows: 1 :class: fullWidthTable @@ -33,6 +41,10 @@ C# built-in support Go built-in support ================================ +Provided by the current versions of the +CodeQL query pack ``codeql/go-queries`` (`changelog `__, `source `__) +and the CodeQL library pack ``codeql/go-all`` (`changelog `__, `source `__). + .. csv-table:: :header-rows: 1 :class: fullWidthTable @@ -84,6 +96,10 @@ Go built-in support Java built-in support ================================== +Provided by the current versions of the +CodeQL query pack ``codeql/java-queries`` (`changelog `__, `source `__) +and the CodeQL library pack ``codeql/java-all`` (`changelog `__, `source `__). + .. csv-table:: :header-rows: 1 :class: fullWidthTable @@ -113,6 +129,10 @@ Java built-in support JavaScript and TypeScript built-in support ======================================================= +Provided by the current versions of the +CodeQL query pack ``codeql/javascript-queries`` (`changelog `__, `source `__) +and the CodeQL library pack ``codeql/javascript-all`` (`changelog `__, `source `__). + .. csv-table:: :header-rows: 1 :class: fullWidthTable @@ -156,6 +176,10 @@ JavaScript and TypeScript built-in support Python built-in support ==================================== +Provided by the current versions of the +CodeQL query pack ``codeql/python-queries`` (`changelog `__, `source `__) +and the CodeQL library pack ``codeql/python-all`` (`changelog `__, `source `__). + .. csv-table:: :header-rows: 1 :class: fullWidthTable From 3527897eff418d15ca8b0dfa6e9db996422c56ba Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 20 Jul 2022 09:13:34 +0200 Subject: [PATCH 393/465] Swift: make `type` optional in `TypeRepr` A type representation may not have a type in unresolved things, which for example pop up in inactive `#if` clauses. --- swift/codegen/schema.yml | 2 +- swift/extractor/visitors/TypeVisitor.cpp | 2 +- swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll | 4 +++- swift/ql/lib/swift.dbscheme | 7 ++++++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/swift/codegen/schema.yml b/swift/codegen/schema.yml index 525318cc09e..f810bfec636 100644 --- a/swift/codegen/schema.yml +++ b/swift/codegen/schema.yml @@ -184,7 +184,7 @@ Stmt: TypeRepr: _extends: AstNode - type: Type + type: Type? # type can be absent on unresolved entities FunctionType: _extends: AnyFunctionType diff --git a/swift/extractor/visitors/TypeVisitor.cpp b/swift/extractor/visitors/TypeVisitor.cpp index 7920b6084ef..ddc253c90a5 100644 --- a/swift/extractor/visitors/TypeVisitor.cpp +++ b/swift/extractor/visitors/TypeVisitor.cpp @@ -11,7 +11,7 @@ void TypeVisitor::visit(swift::TypeBase* type) { codeql::TypeRepr TypeVisitor::translateTypeRepr(const swift::TypeRepr& typeRepr, swift::Type type) { auto entry = dispatcher_.createEntry(typeRepr); - entry.type = dispatcher_.fetchLabel(type); + entry.type = dispatcher_.fetchOptionalLabel(type); return entry; } diff --git a/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll b/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll index 829960deda9..5cc1cc04147 100644 --- a/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll +++ b/swift/ql/lib/codeql/swift/generated/type/TypeRepr.qll @@ -7,8 +7,10 @@ class TypeReprBase extends @type_repr, AstNode { Type getType() { exists(Type x | - type_reprs(this, x) and + type_repr_types(this, x) and result = x.resolve() ) } + + predicate hasType() { exists(getType()) } } diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index d4f95d5122a..0826b2b9ef4 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -473,7 +473,12 @@ expr_types( //dir=expr ; type_reprs( //dir=type - unique int id: @type_repr, + unique int id: @type_repr +); + +#keyset[id] +type_repr_types( //dir=type + int id: @type_repr ref, int type_: @type ref ); From e9e5d948b33e8ba3f84f417aedaeb7cc3445b72a Mon Sep 17 00:00:00 2001 From: Cornelius Riemenschneider Date: Thu, 9 Sep 2021 17:21:08 +0000 Subject: [PATCH 394/465] C#: Implement proper `dotnet build` handling in the Lua tracing config. For proper C# tracing, `dotnet build` needs the parameter /p:UseSharedCompilation=false. However, we can't pass that to the other subcommands of `dotnet`, therefore we need to figure out which subcommand of `dotnet` is being invoked. --- csharp/tools/tracing-config.lua | 61 ++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/csharp/tools/tracing-config.lua b/csharp/tools/tracing-config.lua index b4ff0206b02..8aafc63e7e5 100644 --- a/csharp/tools/tracing-config.lua +++ b/csharp/tools/tracing-config.lua @@ -2,7 +2,54 @@ function RegisterExtractorPack(id) local extractor = GetPlatformToolsDirectory() .. 'Semmle.Extraction.CSharp.Driver' if OperatingSystem == 'windows' then extractor = extractor .. '.exe' end + + function DotnetMatcherBuild(compilerName, compilerPath, compilerArguments, + _languageId) + if compilerName ~= 'dotnet' and compilerName ~= 'dotnet.exe' then + return nil + end + + -- The dotnet CLI has the following usage instructions: + -- dotnet [sdk-options] [command] [command-options] [arguments] + -- we are interested in dotnet build, which has the following usage instructions: + -- dotnet [options] build [...] + -- For now, parse the command line as follows: + -- Everything that starts with `-` (or `/`) will be ignored. + -- The first non-option argument is treated as the command. + -- if that's `build`, we append `/p:UseSharedCompilation=false` to the command line, + -- otherwise we do nothing. + local match = false + local argv = compilerArguments.argv + if OperatingSystem == 'windows' then + -- let's hope that this split matches the escaping rules `dotnet` applies to command line arguments + -- or, at least, that it is close enough + argv = + NativeArgumentsToArgv(compilerArguments.nativeArgumentPointer) + end + for i, arg in ipairs(argv) do + -- dotnet options start with either - or / (both are legal) + local firstCharacter = string.sub(arg, 1, 1) + if not (firstCharacter == '-') and not (firstCharacter == '/') then + Log(1, 'Dotnet subcommand detected: %s', arg) + if arg == 'build' then match = true end + break + end + end + if match then + return { + order = ORDER_REPLACE, + invocation = BuildExtractorInvocation(id, compilerPath, + compilerPath, + compilerArguments, nil, { + '/p:UseSharedCompilation=false' + }) + } + end + return nil + end + local windowsMatchers = { + DotnetMatcherBuild, CreatePatternMatcher({'^dotnet%.exe$'}, MatchCompilerName, extractor, { prepend = {'--dotnetexec', '--cil'}, order = ORDER_BEFORE @@ -10,22 +57,21 @@ function RegisterExtractorPack(id) CreatePatternMatcher({'^csc.*%.exe$'}, MatchCompilerName, extractor, { prepend = {'--compiler', '"${compiler}"', '--cil'}, order = ORDER_BEFORE - }), CreatePatternMatcher({'^fakes.*%.exe$', 'moles.*%.exe'}, MatchCompilerName, nil, {trace = false}) } local posixMatchers = { - CreatePatternMatcher({'^mcs%.exe$', '^csc%.exe$'}, MatchCompilerName, - extractor, { - prepend = {'--compiler', '"${compiler}"', '--cil'}, - order = ORDER_BEFORE - - }), + DotnetMatcherBuild, CreatePatternMatcher({'^mono', '^dotnet$'}, MatchCompilerName, extractor, { prepend = {'--dotnetexec', '--cil'}, order = ORDER_BEFORE + }), + CreatePatternMatcher({'^mcs%.exe$', '^csc%.exe$'}, MatchCompilerName, + extractor, { + prepend = {'--compiler', '"${compiler}"', '--cil'}, + order = ORDER_BEFORE }), function(compilerName, compilerPath, compilerArguments, _languageId) if MatchCompilerName('^msbuild$', compilerName, compilerPath, compilerArguments) or @@ -49,7 +95,6 @@ function RegisterExtractorPack(id) else return posixMatchers end - end -- Return a list of minimum supported versions of the configuration file format From 694d6395d581a4f2a876754c49046606c519f368 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 20 Jul 2022 16:25:33 +0200 Subject: [PATCH 395/465] C++: Fix join-order problem in `cpp/command-line-injection` Before on Abseil Linux: ``` Evaluated relational algebra for predicate ExecTainted::ExecState#class#91000ffb#fff@41084cm7 with tuple counts: 40879811 ~0% {2} r1 = SCAN DataFlowUtil::Node::getLocation#dispred#f0820431#ff OUTPUT In.1, In.0 40879811 ~0% {2} r2 = JOIN r1 WITH Location::Location::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.1, Rhs.1 7527 ~3% {3} r3 = JOIN r2 WITH ExecTainted::interestingConcatenation#91000ffb#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.0 7527 ~0% {4} r4 = JOIN r3 WITH DataFlowUtil::Node::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Lhs.0, Rhs.1 7527 ~0% {5} r5 = JOIN r4 WITH DataFlowUtil::Node::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.2, Lhs.1, Lhs.0, Lhs.3, Rhs.1 7527 ~0% {6} r6 = JOIN r5 WITH DataFlowUtil::Node::getLocation#dispred#f0820431#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.0, Lhs.3, Lhs.4 7527 ~0% {3} r7 = JOIN r6 WITH Location::Location::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT ((((((("ExecState (" ++ Rhs.1) ++ " | ") ++ Lhs.4) ++ ", ") ++ Lhs.1) ++ " | ") ++ Lhs.5 ++ ")"), Lhs.3, Lhs.2 return r7 ``` After: ``` Evaluated relational algebra for predicate ExecTainted::ExecState#class#91000ffb#fff@1ffe61ps with tuple counts: 7527 ~0% {3} r1 = JOIN ExecTainted::interestingConcatenation#91000ffb#ff WITH DataFlowUtil::Node::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.1, Lhs.0, Rhs.1 7527 ~0% {4} r2 = JOIN r1 WITH DataFlowUtil::Node::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2, Rhs.1 7527 ~1% {5} r3 = JOIN r2 WITH DataFlowUtil::Node::getLocation#dispred#f0820431#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.0, Lhs.2, Lhs.3 7527 ~0% {5} r4 = JOIN r3 WITH Location::Location::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.3, Lhs.4, Rhs.1 7527 ~4% {6} r5 = JOIN r4 WITH DataFlowUtil::Node::getLocation#dispred#f0820431#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.0, Lhs.1, Lhs.2, Lhs.3, Lhs.4 7527 ~0% {3} r6 = JOIN r5 WITH Location::Location::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT ((((((("ExecState (" ++ Rhs.1) ++ " | ") ++ Lhs.3) ++ ", ") ++ Lhs.5) ++ " | ") ++ Lhs.4 ++ ")"), Lhs.1, Lhs.2 return r6 ``` --- cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql index 73fcf034096..7a3877f638c 100644 --- a/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql +++ b/cpp/ql/src/Security/CWE/CWE-078/ExecTainted.ql @@ -77,7 +77,7 @@ class ExecState extends DataFlow::FlowState { ExecState() { this = "ExecState (" + fst.getLocation() + " | " + fst + ", " + snd.getLocation() + " | " + snd + ")" and - interestingConcatenation(fst, snd) + interestingConcatenation(pragma[only_bind_into](fst), pragma[only_bind_into](snd)) } DataFlow::Node getFstNode() { result = fst } From 8d80e0332efafa59f80632b233de2821e5993691 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Wed, 20 Jul 2022 16:13:46 +0200 Subject: [PATCH 396/465] Ruby: update tree-sitter-ruby --- ruby/Cargo.lock | Bin 15139 -> 15139 bytes ruby/extractor/Cargo.toml | 2 +- ruby/generator/Cargo.toml | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ruby/Cargo.lock b/ruby/Cargo.lock index 1be66824a3e4184f0dabbebc3fec55848f3da549..3d7e6eb5713079c870275af07d906cca3d12cdca 100644 GIT binary patch delta 102 zcmZ2nwzzDAw^?ASxoL`liHU(pvSmt&xnW|8nT3U^L5gXznYmGtk&#)7X{wo}Nt&@T Uu?i Date: Mon, 18 Jul 2022 12:52:17 +0100 Subject: [PATCH 397/465] Kotlin: fix for-loop iterators over primitive or wildcard types Array<*> can't be queried for an argument type, and IntArray doesn't have an argument at all; both were previously causing the extractor to fail to extract the whole file due to throwing an exception. --- .../src/main/kotlin/KotlinFileExtractor.kt | 8 +++++++- .../library-tests/for-array-iterators/test.expected | 9 +++++++++ .../kotlin/library-tests/for-array-iterators/test.kt | 11 +++++++++++ .../kotlin/library-tests/for-array-iterators/test.ql | 4 ++++ 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 java/ql/test/kotlin/library-tests/for-array-iterators/test.expected create mode 100644 java/ql/test/kotlin/library-tests/for-array-iterators/test.kt create mode 100644 java/ql/test/kotlin/library-tests/for-array-iterators/test.ql diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 9bdf40fdca0..78a81fb0715 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -2124,7 +2124,13 @@ open class KotlinFileExtractor( } isFunction(target, "kotlin", "(some array type)", { isArrayType(it) }, "iterator") && c.origin == IrStatementOrigin.FOR_LOOP_ITERATOR -> { findTopLevelFunctionOrWarn("kotlin.jvm.internal.iterator", "kotlin.jvm.internal.ArrayIteratorKt", c)?.let { iteratorFn -> - extractRawMethodAccess(iteratorFn, c, callable, parent, idx, enclosingStmt, listOf(c.dispatchReceiver), null, null, listOf((c.dispatchReceiver!!.type as IrSimpleType).arguments.first().typeOrNull!!)) + val typeArgs = (c.dispatchReceiver!!.type as IrSimpleType).arguments.map { + when(it) { + is IrTypeProjection -> it.type + else -> pluginContext.irBuiltIns.anyNType + } + } + extractRawMethodAccess(iteratorFn, c, callable, parent, idx, enclosingStmt, listOf(c.dispatchReceiver), null, null, typeArgs) } } isFunction(target, "kotlin", "(some array type)", { isArrayType(it) }, "get") && c.origin == IrStatementOrigin.GET_ARRAY_ELEMENT -> { diff --git a/java/ql/test/kotlin/library-tests/for-array-iterators/test.expected b/java/ql/test/kotlin/library-tests/for-array-iterators/test.expected new file mode 100644 index 00000000000..ac5821044ff --- /dev/null +++ b/java/ql/test/kotlin/library-tests/for-array-iterators/test.expected @@ -0,0 +1,9 @@ +| test.kt:5:14:5:14 | hasNext(...) | +| test.kt:5:14:5:14 | iterator(...) | +| test.kt:5:14:5:14 | next(...) | +| test.kt:6:14:6:14 | hasNext(...) | +| test.kt:6:14:6:14 | iterator(...) | +| test.kt:6:14:6:14 | next(...) | +| test.kt:7:14:7:14 | hasNext(...) | +| test.kt:7:14:7:14 | iterator(...) | +| test.kt:7:14:7:14 | next(...) | diff --git a/java/ql/test/kotlin/library-tests/for-array-iterators/test.kt b/java/ql/test/kotlin/library-tests/for-array-iterators/test.kt new file mode 100644 index 00000000000..2da3a6e1e0e --- /dev/null +++ b/java/ql/test/kotlin/library-tests/for-array-iterators/test.kt @@ -0,0 +1,11 @@ +fun test(x: Array, y: Array<*>, z: IntArray): Int { + + var ret = 0 + + for (el in x) { ret += 1 } + for (el in y) { ret += 1 } + for (el in z) { ret += 1 } + + return ret + +} diff --git a/java/ql/test/kotlin/library-tests/for-array-iterators/test.ql b/java/ql/test/kotlin/library-tests/for-array-iterators/test.ql new file mode 100644 index 00000000000..ab60ba2525d --- /dev/null +++ b/java/ql/test/kotlin/library-tests/for-array-iterators/test.ql @@ -0,0 +1,4 @@ +import java + +from MethodAccess ma +select ma From 9593ceeda54855bf6e6edd830710542e84a54306 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 19 Jul 2022 14:48:00 +0100 Subject: [PATCH 398/465] Kotlin: Special-case String.charAt naming In the Kotlin universe this is called `get` so that Kotlin programmers can use the `[]` operator on `String`s. --- java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt | 2 ++ java/ql/test/kotlin/library-tests/string-charat/Test.java | 5 +++++ .../ql/test/kotlin/library-tests/string-charat/test.expected | 2 ++ java/ql/test/kotlin/library-tests/string-charat/test.kt | 2 ++ java/ql/test/kotlin/library-tests/string-charat/test.ql | 4 ++++ 5 files changed, 15 insertions(+) create mode 100644 java/ql/test/kotlin/library-tests/string-charat/Test.java create mode 100644 java/ql/test/kotlin/library-tests/string-charat/test.expected create mode 100644 java/ql/test/kotlin/library-tests/string-charat/test.kt create mode 100644 java/ql/test/kotlin/library-tests/string-charat/test.ql diff --git a/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt b/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt index 57a3e92e6b2..76d155f8b22 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/JvmNames.kt @@ -51,6 +51,8 @@ private val specialFunctions = mapOf( makeDescription(FqName("java.lang.Number"), "toFloat") to "floatValue", makeDescription(StandardNames.FqNames.number.toSafe(), "toDouble") to "doubleValue", makeDescription(FqName("java.lang.Number"), "toDouble") to "doubleValue", + makeDescription(StandardNames.FqNames.string.toSafe(), "get") to "charAt", + makeDescription(FqName("java.lang.String"), "get") to "charAt", ) private val specialFunctionShortNames = specialFunctions.keys.map { it.functionName }.toSet() diff --git a/java/ql/test/kotlin/library-tests/string-charat/Test.java b/java/ql/test/kotlin/library-tests/string-charat/Test.java new file mode 100644 index 00000000000..22f553216b7 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/string-charat/Test.java @@ -0,0 +1,5 @@ +public class Test { + + public char f(String s) { return s.charAt(0); } + +} diff --git a/java/ql/test/kotlin/library-tests/string-charat/test.expected b/java/ql/test/kotlin/library-tests/string-charat/test.expected new file mode 100644 index 00000000000..ab1ff9b6d5f --- /dev/null +++ b/java/ql/test/kotlin/library-tests/string-charat/test.expected @@ -0,0 +1,2 @@ +| Test.java:3:36:3:46 | charAt(...) | +| test.kt:2:20:2:23 | charAt(...) | diff --git a/java/ql/test/kotlin/library-tests/string-charat/test.kt b/java/ql/test/kotlin/library-tests/string-charat/test.kt new file mode 100644 index 00000000000..c586f3d0171 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/string-charat/test.kt @@ -0,0 +1,2 @@ + +fun f(x: String) = x[0] diff --git a/java/ql/test/kotlin/library-tests/string-charat/test.ql b/java/ql/test/kotlin/library-tests/string-charat/test.ql new file mode 100644 index 00000000000..ab60ba2525d --- /dev/null +++ b/java/ql/test/kotlin/library-tests/string-charat/test.ql @@ -0,0 +1,4 @@ +import java + +from MethodAccess ma +select ma From ad8335d6f3b498c8a70f4ffdaaae214d018acb7e Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 20 Jul 2022 20:12:39 +0200 Subject: [PATCH 399/465] C++: Fix join-order problem in `cpp/return-stack-allocated-memory` Before on Abseil: ``` Evaluated relational algebra for predicate #select#cpe#12356#fffff@3ffb21o1 with tuple counts: 1235939 ~0% {2} r1 = SCAN functions OUTPUT In.0, In.0 1235939 ~0% {2} r2 = JOIN r1 WITH functions ON FIRST 1 OUTPUT Lhs.1, Lhs.0 33500841 ~0% {2} r3 = JOIN r2 WITH DataFlowUtil::Node::getEnclosingCallable#dispred#f0820431#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1 280683 ~3% {3} r4 = JOIN r3 WITH MustFlow::MkLocalPathNode#0227f5a1#fff ON FIRST 1 OUTPUT Rhs.2, Lhs.1, Lhs.0 40970 ~2% {4} r5 = JOIN r4 WITH MustFlow::MustFlowConfiguration::hasFlowPath#dispred#f0820431#fff#cpe#23_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.0 40970 ~0% {5} r6 = JOIN r5 WITH MustFlow::MkLocalPathNode#0227f5a1#fff_20#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.3, Lhs.0 40970 ~1% {5} r7 = JOIN r6 WITH DataFlowUtil::Cached::TInstructionNode#47741e1f#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.3, Lhs.4 40970 ~1% {5} r8 = JOIN r7 WITH project#Instruction::VariableAddressInstruction#class#577b6a83#ff ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2, Lhs.3, Lhs.4 40970 ~0% {6} r9 = JOIN r8 WITH SSAConstruction::Cached::getInstructionAst#2b11997e#ff ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2, Lhs.3, Lhs.4, Rhs.1 40970 ~2% {7} r10 = JOIN r9 WITH SSAConstruction::Cached::getInstructionAst#2b11997e#ff ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2, Lhs.3, Lhs.4, Lhs.5, Rhs.1 0 ~0% {6} r11 = JOIN r10 WITH Instruction::Instruction::getEnclosingFunction#dispred#f0820431#3#ff ON FIRST 2 OUTPUT Rhs.1, Lhs.2, Lhs.3, Lhs.4, Lhs.5, Lhs.6 0 ~0% {5} r12 = JOIN r11 WITH functions ON FIRST 1 OUTPUT Lhs.5, Lhs.1, Lhs.2, Lhs.3, Lhs.4 0 ~0% {5} r13 = JOIN r12 WITH Element::ElementBase::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.1, Lhs.3, Lhs.2, Lhs.4, Rhs.1 return r13 ``` After: ``` Evaluated relational algebra for predicate #select#cpe#12356#fffff@1dbc97kv with tuple counts: 40970 ~0% {2} r1 = SCAN MustFlow::MustFlowConfiguration::hasFlowPath#dispred#f0820431#fff#cpe#23 OUTPUT In.1, In.0 40970 ~0% {3} r2 = JOIN r1 WITH MustFlow::MkLocalPathNode#0227f5a1#fff_20#join_rhs ON FIRST 1 OUTPUT Lhs.1, Lhs.0, Rhs.1 40970 ~7% {4} r3 = JOIN r2 WITH MustFlow::MkLocalPathNode#0227f5a1#fff_20#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.0, Lhs.1, Lhs.2 40970 ~2% {4} r4 = JOIN r3 WITH DataFlowUtil::Cached::TInstructionNode#47741e1f#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1, Lhs.2, Lhs.3 40970 ~2% {4} r5 = JOIN r4 WITH project#Instruction::VariableAddressInstruction#class#577b6a83#ff ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2, Lhs.3 40970 ~0% {5} r6 = JOIN r5 WITH SSAConstruction::Cached::getInstructionAst#2b11997e#ff ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2, Lhs.3, Rhs.1 40970 ~1% {6} r7 = JOIN r6 WITH SSAConstruction::Cached::getInstructionAst#2b11997e#ff ON FIRST 1 OUTPUT Lhs.0, Lhs.1, Lhs.2, Lhs.3, Lhs.4, Rhs.1 40970 ~0% {6} r8 = JOIN r7 WITH Instruction::Instruction::getEnclosingFunction#dispred#f0820431#3#ff ON FIRST 1 OUTPUT Lhs.3, Rhs.1, Lhs.1, Lhs.2, Lhs.4, Lhs.5 0 ~0% {5} r9 = JOIN r8 WITH DataFlowUtil::Node::getEnclosingCallable#dispred#f0820431#fb ON FIRST 2 OUTPUT Lhs.5, Lhs.2, Lhs.3, Lhs.0, Lhs.4 0 ~0% {5} r10 = JOIN r9 WITH Element::ElementBase::toString#dispred#f0820431#ff ON FIRST 1 OUTPUT Lhs.3, Lhs.1, Lhs.2, Lhs.4, Rhs.1 return r10 ``` --- .../Memory Management/ReturnStackAllocatedMemory.ql | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql index bd55008677c..7eab1bd03c8 100644 --- a/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql +++ b/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql @@ -74,13 +74,12 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration { from MustFlowPathNode source, MustFlowPathNode sink, VariableAddressInstruction var, - ReturnStackAllocatedMemoryConfig conf, Function f + ReturnStackAllocatedMemoryConfig conf where - conf.hasFlowPath(source, sink) and + conf.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and source.getNode().asInstruction() = var and // Only raise an alert if we're returning from the _same_ callable as the on that // declared the stack variable. - var.getEnclosingFunction() = pragma[only_bind_into](f) and - sink.getNode().getEnclosingCallable() = pragma[only_bind_into](f) + var.getEnclosingFunction() = sink.getNode().getEnclosingCallable() select sink.getNode(), source, sink, "May return stack-allocated memory from $@.", var.getAst(), var.getAst().toString() From 388c9ffb745c833929dfcf53fd38c3e464d5ccaf Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Mon, 1 Nov 2021 16:24:28 +0000 Subject: [PATCH 400/465] Ruby: separate trap-writer into its own module --- ruby/extractor/src/extractor.rs | 454 +++++++++----------------------- ruby/extractor/src/main.rs | 66 +---- ruby/extractor/src/trap.rs | 272 +++++++++++++++++++ 3 files changed, 410 insertions(+), 382 deletions(-) create mode 100644 ruby/extractor/src/trap.rs diff --git a/ruby/extractor/src/extractor.rs b/ruby/extractor/src/extractor.rs index 8cdaff1b738..6c462e11bb4 100644 --- a/ruby/extractor/src/extractor.rs +++ b/ruby/extractor/src/extractor.rs @@ -1,161 +1,112 @@ +use crate::trap; use node_types::{EntryKind, Field, NodeTypeMap, Storage, TypeName}; -use std::borrow::Cow; use std::collections::BTreeMap as Map; use std::collections::BTreeSet as Set; use std::fmt; -use std::io::Write; use std::path::Path; use tracing::{error, info, span, Level}; use tree_sitter::{Language, Node, Parser, Range, Tree}; -pub struct TrapWriter { - /// The accumulated trap entries - trap_output: Vec, - /// A counter for generating fresh labels - counter: u32, - /// cache of global keys - global_keys: std::collections::HashMap, +pub fn populate_file(writer: &mut trap::Writer, absolute_path: &Path) -> trap::Label { + let (file_label, fresh) = + writer.global_id(&trap::full_id_for_file(&normalize_path(absolute_path))); + if fresh { + writer.add_tuple( + "files", + vec![ + trap::Arg::Label(file_label), + trap::Arg::String(normalize_path(absolute_path)), + ], + ); + populate_parent_folders(writer, file_label, absolute_path.parent()); + } + file_label } -pub fn new_trap_writer() -> TrapWriter { - TrapWriter { - counter: 0, - trap_output: Vec::new(), - global_keys: std::collections::HashMap::new(), +fn populate_empty_file(writer: &mut trap::Writer) -> trap::Label { + let (file_label, fresh) = writer.global_id("empty;sourcefile"); + if fresh { + writer.add_tuple( + "files", + vec![ + trap::Arg::Label(file_label), + trap::Arg::String("".to_string()), + ], + ); } + file_label } -impl TrapWriter { - /// Gets a label that will hold the unique ID of the passed string at import time. - /// This can be used for incrementally importable TRAP files -- use globally unique - /// strings to compute a unique ID for table tuples. - /// - /// Note: You probably want to make sure that the key strings that you use are disjoint - /// for disjoint column types; the standard way of doing this is to prefix (or append) - /// the column type name to the ID. Thus, you might identify methods in Java by the - /// full ID "methods_com.method.package.DeclaringClass.method(argumentList)". +pub fn populate_empty_location(writer: &mut trap::Writer) { + let file_label = populate_empty_file(writer); + location(writer, file_label, 0, 0, 0, 0); +} - fn fresh_id(&mut self) -> Label { - let label = Label(self.counter); - self.counter += 1; - self.trap_output.push(TrapEntry::FreshId(label)); - label - } - - fn global_id(&mut self, key: &str) -> (Label, bool) { - if let Some(label) = self.global_keys.get(key) { - return (*label, false); - } - let label = Label(self.counter); - self.counter += 1; - self.global_keys.insert(key.to_owned(), label); - self.trap_output - .push(TrapEntry::MapLabelToKey(label, key.to_owned())); - (label, true) - } - - fn add_tuple(&mut self, table_name: &str, args: Vec) { - self.trap_output - .push(TrapEntry::GenericTuple(table_name.to_owned(), args)) - } - - fn populate_file(&mut self, absolute_path: &Path) -> Label { - let (file_label, fresh) = self.global_id(&full_id_for_file(absolute_path)); - if fresh { - self.add_tuple( - "files", - vec![ - Arg::Label(file_label), - Arg::String(normalize_path(absolute_path)), - ], - ); - self.populate_parent_folders(file_label, absolute_path.parent()); - } - file_label - } - - fn populate_empty_file(&mut self) -> Label { - let (file_label, fresh) = self.global_id("empty;sourcefile"); - if fresh { - self.add_tuple( - "files", - vec![Arg::Label(file_label), Arg::String("".to_string())], - ); - } - file_label - } - - pub fn populate_empty_location(&mut self) { - let file_label = self.populate_empty_file(); - self.location(file_label, 0, 0, 0, 0); - } - - fn populate_parent_folders(&mut self, child_label: Label, path: Option<&Path>) { - let mut path = path; - let mut child_label = child_label; - loop { - match path { - None => break, - Some(folder) => { - let (folder_label, fresh) = self.global_id(&full_id_for_folder(folder)); - self.add_tuple( - "containerparent", - vec![Arg::Label(folder_label), Arg::Label(child_label)], +pub fn populate_parent_folders( + writer: &mut trap::Writer, + child_label: trap::Label, + path: Option<&Path>, +) { + let mut path = path; + let mut child_label = child_label; + loop { + match path { + None => break, + Some(folder) => { + let (folder_label, fresh) = + writer.global_id(&trap::full_id_for_folder(&normalize_path(folder))); + writer.add_tuple( + "containerparent", + vec![ + trap::Arg::Label(folder_label), + trap::Arg::Label(child_label), + ], + ); + if fresh { + writer.add_tuple( + "folders", + vec![ + trap::Arg::Label(folder_label), + trap::Arg::String(normalize_path(folder)), + ], ); - if fresh { - self.add_tuple( - "folders", - vec![ - Arg::Label(folder_label), - Arg::String(normalize_path(folder)), - ], - ); - path = folder.parent(); - child_label = folder_label; - } else { - break; - } + path = folder.parent(); + child_label = folder_label; + } else { + break; } } } } +} - fn location( - &mut self, - file_label: Label, - start_line: usize, - start_column: usize, - end_line: usize, - end_column: usize, - ) -> Label { - let (loc_label, fresh) = self.global_id(&format!( - "loc,{{{}}},{},{},{},{}", - file_label, start_line, start_column, end_line, end_column - )); - if fresh { - self.add_tuple( - "locations_default", - vec![ - Arg::Label(loc_label), - Arg::Label(file_label), - Arg::Int(start_line), - Arg::Int(start_column), - Arg::Int(end_line), - Arg::Int(end_column), - ], - ); - } - loc_label - } - - fn comment(&mut self, text: String) { - self.trap_output.push(TrapEntry::Comment(text)); - } - - pub fn output(self, writer: &mut dyn Write) -> std::io::Result<()> { - write!(writer, "{}", Program(self.trap_output)) +fn location( + writer: &mut trap::Writer, + file_label: trap::Label, + start_line: usize, + start_column: usize, + end_line: usize, + end_column: usize, +) -> trap::Label { + let (loc_label, fresh) = writer.global_id(&format!( + "loc,{{{}}},{},{},{},{}", + file_label, start_line, start_column, end_line, end_column + )); + if fresh { + writer.add_tuple( + "locations_default", + vec![ + trap::Arg::Label(loc_label), + trap::Arg::Label(file_label), + trap::Arg::Int(start_line), + trap::Arg::Int(start_column), + trap::Arg::Int(end_line), + trap::Arg::Int(end_column), + ], + ); } + loc_label } /// Extracts the source file at `path`, which is assumed to be canonicalized. @@ -163,7 +114,7 @@ pub fn extract( language: Language, language_prefix: &str, schema: &NodeTypeMap, - trap_writer: &mut TrapWriter, + trap_writer: &mut trap::Writer, path: &Path, source: &[u8], ranges: &[Range], @@ -183,13 +134,13 @@ pub fn extract( parser.set_included_ranges(ranges).unwrap(); let tree = parser.parse(&source, None).expect("Failed to parse file"); trap_writer.comment(format!("Auto-generated TRAP file for {}", path.display())); - let file_label = &trap_writer.populate_file(path); + let file_label = populate_file(trap_writer, path); let mut visitor = Visitor { source, trap_writer, // TODO: should we handle path strings that are not valid UTF8 better? path: format!("{}", path.display()), - file_label: *file_label, + file_label, toplevel_child_counter: 0, stack: Vec::new(), language_prefix, @@ -201,33 +152,6 @@ pub fn extract( Ok(()) } -/// Escapes a string for use in a TRAP key, by replacing special characters with -/// HTML entities. -fn escape_key<'a, S: Into>>(key: S) -> Cow<'a, str> { - fn needs_escaping(c: char) -> bool { - matches!(c, '&' | '{' | '}' | '"' | '@' | '#') - } - - let key = key.into(); - if key.contains(needs_escaping) { - let mut escaped = String::with_capacity(2 * key.len()); - for c in key.chars() { - match c { - '&' => escaped.push_str("&"), - '{' => escaped.push_str("{"), - '}' => escaped.push_str("}"), - '"' => escaped.push_str("""), - '@' => escaped.push_str("@"), - '#' => escaped.push_str("#"), - _ => escaped.push(c), - } - } - Cow::Owned(escaped) - } else { - key - } -} - /// Normalizes the path according the common CodeQL specification. Assumes that /// `path` has already been canonicalized using `std::fs::canonicalize`. fn normalize_path(path: &Path) -> String { @@ -267,17 +191,9 @@ fn normalize_path(path: &Path) -> String { } } -fn full_id_for_file(path: &Path) -> String { - format!("{};sourcefile", escape_key(&normalize_path(path))) -} - -fn full_id_for_folder(path: &Path) -> String { - format!("{};folder", escape_key(&normalize_path(path))) -} - struct ChildNode { field_name: Option<&'static str>, - label: Label, + label: trap::Label, type_name: TypeName, } @@ -286,11 +202,11 @@ struct Visitor<'a> { path: String, /// The label to use whenever we need to refer to the `@file` entity of this /// source file. - file_label: Label, + file_label: trap::Label, /// The source code as a UTF-8 byte array source: &'a [u8], - /// A TrapWriter to accumulate trap entries - trap_writer: &'a mut TrapWriter, + /// A trap::Writer to accumulate trap entries + trap_writer: &'a mut trap::Writer, /// A counter for top-level child nodes toplevel_child_counter: usize, /// Language prefix @@ -303,7 +219,7 @@ struct Visitor<'a> { /// node the list containing the child data is popped from the stack and /// matched against the dbscheme for the node. If the expectations are met /// the corresponding row definitions are added to the trap_output. - stack: Vec<(Label, usize, Vec)>, + stack: Vec<(trap::Label, usize, Vec)>, } impl Visitor<'_> { @@ -311,19 +227,19 @@ impl Visitor<'_> { &mut self, error_message: String, full_error_message: String, - loc: Label, + loc: trap::Label, ) { error!("{}", full_error_message); let id = self.trap_writer.fresh_id(); self.trap_writer.add_tuple( "diagnostics", vec![ - Arg::Label(id), - Arg::Int(40), // severity 40 = error - Arg::String("parse_error".to_string()), - Arg::String(error_message), - Arg::String(full_error_message), - Arg::Label(loc), + trap::Arg::Label(id), + trap::Arg::Int(40), // severity 40 = error + trap::Arg::String("parse_error".to_string()), + trap::Arg::String(error_message), + trap::Arg::String(full_error_message), + trap::Arg::Label(loc), ], ); } @@ -335,7 +251,8 @@ impl Visitor<'_> { node: Node, ) { let (start_line, start_column, end_line, end_column) = location_for(self.source, node); - let loc = self.trap_writer.location( + let loc = location( + self.trap_writer, self.file_label, start_line, start_column, @@ -374,7 +291,8 @@ impl Visitor<'_> { } let (id, _, child_nodes) = self.stack.pop().expect("Vistor: empty stack"); let (start_line, start_column, end_line, end_column) = location_for(self.source, node); - let loc = self.trap_writer.location( + let loc = location( + self.trap_writer, self.file_label, start_line, start_column, @@ -404,18 +322,19 @@ impl Visitor<'_> { self.trap_writer.add_tuple( &format!("{}_ast_node_info", self.language_prefix), vec![ - Arg::Label(id), - Arg::Label(parent_id), - Arg::Int(parent_index), - Arg::Label(loc), + trap::Arg::Label(id), + trap::Arg::Label(parent_id), + trap::Arg::Int(parent_index), + trap::Arg::Label(loc), ], ); self.trap_writer.add_tuple( &format!("{}_tokeninfo", self.language_prefix), vec![ - Arg::Label(id), - Arg::Int(*kind_id), + trap::Arg::Label(id), + trap::Arg::Int(*kind_id), sliced_source_arg(self.source, node), + trap::Arg::Label(loc), ], ); } @@ -427,13 +346,13 @@ impl Visitor<'_> { self.trap_writer.add_tuple( &format!("{}_ast_node_info", self.language_prefix), vec![ - Arg::Label(id), - Arg::Label(parent_id), - Arg::Int(parent_index), - Arg::Label(loc), + trap::Arg::Label(id), + trap::Arg::Label(parent_id), + trap::Arg::Int(parent_index), + trap::Arg::Label(loc), ], ); - let mut all_args = vec![Arg::Label(id)]; + let mut all_args = vec![trap::Arg::Label(id)]; all_args.extend(args); self.trap_writer.add_tuple(table_name, all_args); } @@ -472,9 +391,9 @@ impl Visitor<'_> { node: &Node, fields: &[Field], child_nodes: &[ChildNode], - parent_id: Label, - ) -> Option> { - let mut map: Map<&Option, (&Field, Vec)> = Map::new(); + parent_id: trap::Label, + ) -> Option> { + let mut map: Map<&Option, (&Field, Vec)> = Map::new(); for field in fields { map.insert(&field.name, (field, Vec::new())); } @@ -488,9 +407,9 @@ impl Visitor<'_> { { // We can safely unwrap because type_matches checks the key is in the map. let (int_value, _) = int_mapping.get(&child_node.type_name.kind).unwrap(); - values.push(Arg::Int(*int_value)); + values.push(trap::Arg::Int(*int_value)); } else { - values.push(Arg::Label(child_node.label)); + values.push(trap::Arg::Label(child_node.label)); } } else if field.name.is_some() { let error_message = format!( @@ -569,9 +488,9 @@ impl Visitor<'_> { ); break; } - let mut args = vec![Arg::Label(parent_id)]; + let mut args = vec![trap::Arg::Label(parent_id)]; if *has_index { - args.push(Arg::Int(index)) + args.push(trap::Arg::Int(index)) } args.push(child_value.clone()); self.trap_writer.add_tuple(table_name, args); @@ -625,9 +544,9 @@ impl Visitor<'_> { } // Emit a slice of a source file as an Arg. -fn sliced_source_arg(source: &[u8], n: Node) -> Arg { +fn sliced_source_arg(source: &[u8], n: Node) -> trap::Arg { let range = n.byte_range(); - Arg::String(String::from_utf8_lossy(&source[range.start..range.end]).into_owned()) + trap::Arg::String(String::from_utf8_lossy(&source[range.start..range.end]).into_owned()) } // Emit a pair of `TrapEntry`s for the provided node, appropriately calibrated. @@ -699,59 +618,6 @@ fn traverse(tree: &Tree, visitor: &mut Visitor) { } } -pub struct Program(Vec); - -impl fmt::Display for Program { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut text = String::new(); - for trap_entry in &self.0 { - text.push_str(&format!("{}\n", trap_entry)); - } - write!(f, "{}", text) - } -} - -enum TrapEntry { - /// Maps the label to a fresh id, e.g. `#123=*`. - FreshId(Label), - /// Maps the label to a key, e.g. `#7=@"foo"`. - MapLabelToKey(Label, String), - /// foo_bar(arg*) - GenericTuple(String, Vec), - Comment(String), -} -impl fmt::Display for TrapEntry { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - TrapEntry::FreshId(label) => write!(f, "{}=*", label), - TrapEntry::MapLabelToKey(label, key) => { - write!(f, "{}=@\"{}\"", label, key.replace("\"", "\"\"")) - } - TrapEntry::GenericTuple(name, args) => { - write!(f, "{}(", name)?; - for (index, arg) in args.iter().enumerate() { - if index > 0 { - write!(f, ",")?; - } - write!(f, "{}", arg)?; - } - write!(f, ")") - } - TrapEntry::Comment(line) => write!(f, "// {}", line), - } - } -} - -#[derive(Debug, Copy, Clone)] -// Identifiers of the form #0, #1... -struct Label(u32); - -impl fmt::Display for Label { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "#{:x}", self.0) - } -} - // Numeric indices. #[derive(Debug, Copy, Clone)] struct Index(usize); @@ -761,69 +627,3 @@ impl fmt::Display for Index { write!(f, "{}", self.0) } } - -// Some untyped argument to a TrapEntry. -#[derive(Debug, Clone)] -enum Arg { - Label(Label), - Int(usize), - String(String), -} - -const MAX_STRLEN: usize = 1048576; - -impl fmt::Display for Arg { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Arg::Label(x) => write!(f, "{}", x), - Arg::Int(x) => write!(f, "{}", x), - Arg::String(x) => write!( - f, - "\"{}\"", - limit_string(x, MAX_STRLEN).replace("\"", "\"\"") - ), - } - } -} - -/// Limit the length (in bytes) of a string. If the string's length in bytes is -/// less than or equal to the limit then the entire string is returned. Otherwise -/// the string is sliced at the provided limit. If there is a multi-byte character -/// at the limit then the returned slice will be slightly shorter than the limit to -/// avoid splitting that multi-byte character. -fn limit_string(string: &str, max_size: usize) -> &str { - if string.len() <= max_size { - return string; - } - let p = string.as_bytes(); - let mut index = max_size; - // We want to clip the string at [max_size]; however, the character at that position - // may span several bytes. We need to find the first byte of the character. In UTF-8 - // encoded data any byte that matches the bit pattern 10XXXXXX is not a start byte. - // Therefore we decrement the index as long as there are bytes matching this pattern. - // This ensures we cut the string at the border between one character and another. - while index > 0 && (p[index] & 0b11000000) == 0b10000000 { - index -= 1; - } - &string[0..index] -} - -#[test] -fn limit_string_test() { - assert_eq!("hello", limit_string(&"hello world".to_owned(), 5)); - assert_eq!("hi ☹", limit_string(&"hi ☹☹".to_owned(), 6)); - assert_eq!("hi ", limit_string(&"hi ☹☹".to_owned(), 5)); -} - -#[test] -fn escape_key_test() { - assert_eq!("foo!", escape_key("foo!")); - assert_eq!("foo{}", escape_key("foo{}")); - assert_eq!("{}", escape_key("{}")); - assert_eq!("", escape_key("")); - assert_eq!("/path/to/foo.rb", escape_key("/path/to/foo.rb")); - assert_eq!( - "/path/to/foo&{}"@#.rb", - escape_key("/path/to/foo&{}\"@#.rb") - ); -} diff --git a/ruby/extractor/src/main.rs b/ruby/extractor/src/main.rs index 7e4aa973518..4fc886a50ad 100644 --- a/ruby/extractor/src/main.rs +++ b/ruby/extractor/src/main.rs @@ -1,51 +1,15 @@ mod extractor; +mod trap; extern crate num_cpus; use clap::arg; -use flate2::write::GzEncoder; use rayon::prelude::*; use std::fs; -use std::io::{BufRead, BufWriter}; +use std::io::BufRead; use std::path::{Path, PathBuf}; use tree_sitter::{Language, Parser, Range}; -enum TrapCompression { - None, - Gzip, -} - -impl TrapCompression { - fn from_env() -> TrapCompression { - match std::env::var("CODEQL_RUBY_TRAP_COMPRESSION") { - Ok(method) => match TrapCompression::from_string(&method) { - Some(c) => c, - None => { - tracing::error!("Unknown compression method '{}'; using gzip.", &method); - TrapCompression::Gzip - } - }, - // Default compression method if the env var isn't set: - Err(_) => TrapCompression::Gzip, - } - } - - fn from_string(s: &str) -> Option { - match s.to_lowercase().as_ref() { - "none" => Some(TrapCompression::None), - "gzip" => Some(TrapCompression::Gzip), - _ => None, - } - } - - fn extension(&self) -> &str { - match self { - TrapCompression::None => "trap", - TrapCompression::Gzip => "trap.gz", - } - } -} - /** * Gets the number of threads the extractor should use, by reading the * CODEQL_THREADS environment variable and using it as described in the @@ -118,7 +82,7 @@ fn main() -> std::io::Result<()> { .value_of("output-dir") .expect("missing --output-dir"); let trap_dir = PathBuf::from(trap_dir); - let trap_compression = TrapCompression::from_env(); + let trap_compression = trap::Compression::from_env("CODEQL_RUBY_TRAP_COMPRESSION"); let file_list = matches.value_of("file-list").expect("missing --file-list"); let file_list = fs::File::open(file_list)?; @@ -141,7 +105,7 @@ fn main() -> std::io::Result<()> { let src_archive_file = path_for(&src_archive_dir, &path, ""); let mut source = std::fs::read(&path)?; let code_ranges; - let mut trap_writer = extractor::new_trap_writer(); + let mut trap_writer = trap::Writer::new(); if path.extension().map_or(false, |x| x == "erb") { tracing::info!("scanning: {}", path.display()); extractor::extract( @@ -181,33 +145,25 @@ fn main() -> std::io::Result<()> { )?; std::fs::create_dir_all(&src_archive_file.parent().unwrap())?; std::fs::copy(&path, &src_archive_file)?; - write_trap(&trap_dir, path, trap_writer, &trap_compression) + write_trap(&trap_dir, path, &trap_writer, trap_compression) }) .expect("failed to extract files"); let path = PathBuf::from("extras"); - let mut trap_writer = extractor::new_trap_writer(); - trap_writer.populate_empty_location(); - write_trap(&trap_dir, path, trap_writer, &trap_compression) + let mut trap_writer = trap::Writer::new(); + extractor::populate_empty_location(&mut trap_writer); + write_trap(&trap_dir, path, &trap_writer, trap_compression) } fn write_trap( trap_dir: &Path, path: PathBuf, - trap_writer: extractor::TrapWriter, - trap_compression: &TrapCompression, + trap_writer: &trap::Writer, + trap_compression: trap::Compression, ) -> std::io::Result<()> { let trap_file = path_for(trap_dir, &path, trap_compression.extension()); std::fs::create_dir_all(&trap_file.parent().unwrap())?; - let trap_file = std::fs::File::create(&trap_file)?; - let mut trap_file = BufWriter::new(trap_file); - match trap_compression { - TrapCompression::None => trap_writer.output(&mut trap_file), - TrapCompression::Gzip => { - let mut compressed_writer = GzEncoder::new(trap_file, flate2::Compression::fast()); - trap_writer.output(&mut compressed_writer) - } - } + trap_writer.write_to_file(&trap_file, trap_compression) } fn scan_erb( diff --git a/ruby/extractor/src/trap.rs b/ruby/extractor/src/trap.rs new file mode 100644 index 00000000000..d64c520c4cc --- /dev/null +++ b/ruby/extractor/src/trap.rs @@ -0,0 +1,272 @@ +use std::borrow::Cow; +use std::fmt; +use std::io::{BufWriter, Write}; +use std::path::Path; + +use flate2::write::GzEncoder; + +pub struct Writer { + /// The accumulated trap entries + trap_output: Vec, + /// A counter for generating fresh labels + counter: u32, + /// cache of global keys + global_keys: std::collections::HashMap, +} + +impl Writer { + pub fn new() -> Writer { + Writer { + counter: 0, + trap_output: Vec::new(), + global_keys: std::collections::HashMap::new(), + } + } + + pub fn fresh_id(&mut self) -> Label { + let label = Label(self.counter); + self.counter += 1; + self.trap_output.push(Entry::FreshId(label)); + label + } + + /// Gets a label that will hold the unique ID of the passed string at import time. + /// This can be used for incrementally importable TRAP files -- use globally unique + /// strings to compute a unique ID for table tuples. + /// + /// Note: You probably want to make sure that the key strings that you use are disjoint + /// for disjoint column types; the standard way of doing this is to prefix (or append) + /// the column type name to the ID. Thus, you might identify methods in Java by the + /// full ID "methods_com.method.package.DeclaringClass.method(argumentList)". + pub fn global_id(&mut self, key: &str) -> (Label, bool) { + if let Some(label) = self.global_keys.get(key) { + return (*label, false); + } + let label = Label(self.counter); + self.counter += 1; + self.global_keys.insert(key.to_owned(), label); + self.trap_output + .push(Entry::MapLabelToKey(label, key.to_owned())); + (label, true) + } + + pub fn add_tuple(&mut self, table_name: &str, args: Vec) { + self.trap_output + .push(Entry::GenericTuple(table_name.to_owned(), args)) + } + + pub fn comment(&mut self, text: String) { + self.trap_output.push(Entry::Comment(text)); + } + + pub fn write_to_file(&self, path: &Path, compression: Compression) -> std::io::Result<()> { + let trap_file = std::fs::File::create(path)?; + let mut trap_file = BufWriter::new(trap_file); + match compression { + Compression::None => self.write_trap_entries(&mut trap_file), + Compression::Gzip => { + let mut compressed_writer = GzEncoder::new(trap_file, flate2::Compression::fast()); + self.write_trap_entries(&mut compressed_writer) + } + } + } + + fn write_trap_entries(&self, file: &mut W) -> std::io::Result<()> { + for trap_entry in &self.trap_output { + writeln!(file, "{}", trap_entry)?; + } + std::io::Result::Ok(()) + } +} + +pub enum Entry { + /// Maps the label to a fresh id, e.g. `#123=*`. + FreshId(Label), + /// Maps the label to a key, e.g. `#7=@"foo"`. + MapLabelToKey(Label, String), + /// foo_bar(arg*) + GenericTuple(String, Vec), + Comment(String), +} + +impl fmt::Display for Entry { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Entry::FreshId(label) => write!(f, "{}=*", label), + Entry::MapLabelToKey(label, key) => { + write!(f, "{}=@\"{}\"", label, key.replace("\"", "\"\"")) + } + Entry::GenericTuple(name, args) => { + write!(f, "{}(", name)?; + for (index, arg) in args.iter().enumerate() { + if index > 0 { + write!(f, ",")?; + } + write!(f, "{}", arg)?; + } + write!(f, ")") + } + Entry::Comment(line) => write!(f, "// {}", line), + } + } +} + +#[derive(Debug, Copy, Clone)] +// Identifiers of the form #0, #1... +pub struct Label(u32); + +impl fmt::Display for Label { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "#{:x}", self.0) + } +} + +// Some untyped argument to a TrapEntry. +#[derive(Debug, Clone)] +pub enum Arg { + Label(Label), + Int(usize), + String(String), +} + +const MAX_STRLEN: usize = 1048576; + +impl fmt::Display for Arg { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Arg::Label(x) => write!(f, "{}", x), + Arg::Int(x) => write!(f, "{}", x), + Arg::String(x) => write!( + f, + "\"{}\"", + limit_string(x, MAX_STRLEN).replace("\"", "\"\"") + ), + } + } +} + +pub struct Program(Vec); + +impl fmt::Display for Program { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut text = String::new(); + for trap_entry in &self.0 { + text.push_str(&format!("{}\n", trap_entry)); + } + write!(f, "{}", text) + } +} + +pub fn full_id_for_file(normalized_path: &str) -> String { + format!("{};sourcefile", escape_key(normalized_path)) +} + +pub fn full_id_for_folder(normalized_path: &str) -> String { + format!("{};folder", escape_key(normalized_path)) +} + +/// Escapes a string for use in a TRAP key, by replacing special characters with +/// HTML entities. +fn escape_key<'a, S: Into>>(key: S) -> Cow<'a, str> { + fn needs_escaping(c: char) -> bool { + matches!(c, '&' | '{' | '}' | '"' | '@' | '#') + } + + let key = key.into(); + if key.contains(needs_escaping) { + let mut escaped = String::with_capacity(2 * key.len()); + for c in key.chars() { + match c { + '&' => escaped.push_str("&"), + '{' => escaped.push_str("{"), + '}' => escaped.push_str("}"), + '"' => escaped.push_str("""), + '@' => escaped.push_str("@"), + '#' => escaped.push_str("#"), + _ => escaped.push(c), + } + } + Cow::Owned(escaped) + } else { + key + } +} + +/// Limit the length (in bytes) of a string. If the string's length in bytes is +/// less than or equal to the limit then the entire string is returned. Otherwise +/// the string is sliced at the provided limit. If there is a multi-byte character +/// at the limit then the returned slice will be slightly shorter than the limit to +/// avoid splitting that multi-byte character. +fn limit_string(string: &str, max_size: usize) -> &str { + if string.len() <= max_size { + return string; + } + let p = string.as_bytes(); + let mut index = max_size; + // We want to clip the string at [max_size]; however, the character at that position + // may span several bytes. We need to find the first byte of the character. In UTF-8 + // encoded data any byte that matches the bit pattern 10XXXXXX is not a start byte. + // Therefore we decrement the index as long as there are bytes matching this pattern. + // This ensures we cut the string at the border between one character and another. + while index > 0 && (p[index] & 0b11000000) == 0b10000000 { + index -= 1; + } + &string[0..index] +} + +#[derive(Clone, Copy)] +pub enum Compression { + None, + Gzip, +} + +impl Compression { + pub fn from_env(var_name: &str) -> Compression { + match std::env::var(var_name) { + Ok(method) => match Compression::from_string(&method) { + Some(c) => c, + None => { + tracing::error!("Unknown compression method '{}'; using gzip.", &method); + Compression::Gzip + } + }, + // Default compression method if the env var isn't set: + Err(_) => Compression::Gzip, + } + } + + pub fn from_string(s: &str) -> Option { + match s.to_lowercase().as_ref() { + "none" => Some(Compression::None), + "gzip" => Some(Compression::Gzip), + _ => None, + } + } + + pub fn extension(&self) -> &str { + match self { + Compression::None => "trap", + Compression::Gzip => "trap.gz", + } + } +} + +#[test] +fn limit_string_test() { + assert_eq!("hello", limit_string(&"hello world".to_owned(), 5)); + assert_eq!("hi ☹", limit_string(&"hi ☹☹".to_owned(), 6)); + assert_eq!("hi ", limit_string(&"hi ☹☹".to_owned(), 5)); +} + +#[test] +fn escape_key_test() { + assert_eq!("foo!", escape_key("foo!")); + assert_eq!("foo{}", escape_key("foo{}")); + assert_eq!("{}", escape_key("{}")); + assert_eq!("", escape_key("")); + assert_eq!("/path/to/foo.rb", escape_key("/path/to/foo.rb")); + assert_eq!( + "/path/to/foo&{}"@#.rb", + escape_key("/path/to/foo&{}\"@#.rb") + ); +} From 0a8ecd3cf73296779e92966682fced6793cdce33 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Mon, 1 Nov 2021 16:31:30 +0000 Subject: [PATCH 401/465] Ruby: compute path string only once --- ruby/extractor/src/extractor.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ruby/extractor/src/extractor.rs b/ruby/extractor/src/extractor.rs index 6c462e11bb4..74a8db28030 100644 --- a/ruby/extractor/src/extractor.rs +++ b/ruby/extractor/src/extractor.rs @@ -119,27 +119,28 @@ pub fn extract( source: &[u8], ranges: &[Range], ) -> std::io::Result<()> { + let path_str = format!("{}", path.display()); let span = span!( Level::TRACE, "extract", - file = %path.display() + file = %path_str ); let _enter = span.enter(); - info!("extracting: {}", path.display()); + info!("extracting: {}", path_str); let mut parser = Parser::new(); parser.set_language(language).unwrap(); parser.set_included_ranges(ranges).unwrap(); let tree = parser.parse(&source, None).expect("Failed to parse file"); - trap_writer.comment(format!("Auto-generated TRAP file for {}", path.display())); + trap_writer.comment(format!("Auto-generated TRAP file for {}", path_str)); let file_label = populate_file(trap_writer, path); let mut visitor = Visitor { source, trap_writer, // TODO: should we handle path strings that are not valid UTF8 better? - path: format!("{}", path.display()), + path: &path_str, file_label, toplevel_child_counter: 0, stack: Vec::new(), @@ -199,7 +200,7 @@ struct ChildNode { struct Visitor<'a> { /// The file path of the source code (as string) - path: String, + path: &'a str, /// The label to use whenever we need to refer to the `@file` entity of this /// source file. file_label: trap::Label, From 8dae85e1b1a249f9a2c0836eb184df26f4fadce5 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Mon, 1 Nov 2021 17:19:26 +0000 Subject: [PATCH 402/465] Ruby: avoid repeated construction of table name strings --- ruby/extractor/src/extractor.rs | 44 ++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/ruby/extractor/src/extractor.rs b/ruby/extractor/src/extractor.rs index 74a8db28030..db280634ae5 100644 --- a/ruby/extractor/src/extractor.rs +++ b/ruby/extractor/src/extractor.rs @@ -136,17 +136,15 @@ pub fn extract( let tree = parser.parse(&source, None).expect("Failed to parse file"); trap_writer.comment(format!("Auto-generated TRAP file for {}", path_str)); let file_label = populate_file(trap_writer, path); - let mut visitor = Visitor { + let mut visitor = Visitor::new( source, trap_writer, // TODO: should we handle path strings that are not valid UTF8 better? - path: &path_str, + &path_str, file_label, - toplevel_child_counter: 0, - stack: Vec::new(), language_prefix, schema, - }; + ); traverse(&tree, &mut visitor); parser.reset(); @@ -210,8 +208,10 @@ struct Visitor<'a> { trap_writer: &'a mut trap::Writer, /// A counter for top-level child nodes toplevel_child_counter: usize, - /// Language prefix - language_prefix: &'a str, + /// Language-specific name of the AST info table + ast_node_info_table_name: String, + /// Language-specific name of the tokeninfo table + tokeninfo_table_name: String, /// A lookup table from type name to node types schema: &'a NodeTypeMap, /// A stack for gathering information from child nodes. Whenever a node is @@ -223,7 +223,28 @@ struct Visitor<'a> { stack: Vec<(trap::Label, usize, Vec)>, } -impl Visitor<'_> { +impl<'a> Visitor<'a> { + fn new( + source: &'a [u8], + trap_writer: &'a mut trap::Writer, + path: &'a str, + file_label: trap::Label, + language_prefix: &str, + schema: &'a NodeTypeMap, + ) -> Visitor<'a> { + Visitor { + path, + file_label, + source, + trap_writer, + toplevel_child_counter: 0, + ast_node_info_table_name: format!("{}_ast_node_info", language_prefix), + tokeninfo_table_name: format!("{}_tokeninfo", language_prefix), + schema, + stack: Vec::new(), + } + } + fn record_parse_error( &mut self, error_message: String, @@ -321,7 +342,7 @@ impl Visitor<'_> { match &table.kind { EntryKind::Token { kind_id, .. } => { self.trap_writer.add_tuple( - &format!("{}_ast_node_info", self.language_prefix), + &self.ast_node_info_table_name, vec![ trap::Arg::Label(id), trap::Arg::Label(parent_id), @@ -330,12 +351,11 @@ impl Visitor<'_> { ], ); self.trap_writer.add_tuple( - &format!("{}_tokeninfo", self.language_prefix), + &self.tokeninfo_table_name, vec![ trap::Arg::Label(id), trap::Arg::Int(*kind_id), sliced_source_arg(self.source, node), - trap::Arg::Label(loc), ], ); } @@ -345,7 +365,7 @@ impl Visitor<'_> { } => { if let Some(args) = self.complex_node(&node, fields, &child_nodes, id) { self.trap_writer.add_tuple( - &format!("{}_ast_node_info", self.language_prefix), + &self.ast_node_info_table_name, vec![ trap::Arg::Label(id), trap::Arg::Label(parent_id), From 7be106d7bba3cb89b55653570110766e86122f06 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Mon, 18 Jul 2022 15:01:25 +0200 Subject: [PATCH 403/465] Ruby: handle magic coding: comments --- ruby/Cargo.lock | Bin 15139 -> 17026 bytes ruby/extractor/Cargo.toml | 2 + ruby/extractor/src/main.rs | 207 +++++++++++++++++- ruby/ql/test/library-tests/ast/Ast.expected | 6 + .../library-tests/ast/TreeSitter.expected | 11 + .../test/library-tests/ast/ValueText.expected | 2 + .../library-tests/ast/misc/iso-8859-15.rb | 4 + 7 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 ruby/ql/test/library-tests/ast/misc/iso-8859-15.rb diff --git a/ruby/Cargo.lock b/ruby/Cargo.lock index 1be66824a3e4184f0dabbebc3fec55848f3da549..c92ef0214a65f4bbdb4497085ba30c6a71d17e85 100644 GIT binary patch delta 1127 zcmaKrOHPzQ6oq3J`yIRO^5?&tLoOR$3Vpu=*%JBM_p~j2I-CwCq@%j@Vf!y z1~hELfh@+kKS(1F=}D#D=hSykeS7=q^QG_mi_2{+TRIv)A1u6WJCo7Yc;)`ezzxF? zpnG)X@p@vXHA2C}wL0}dfe{(7`WVe1dIV_bQ@_jA!d}6|lcbasQj?BWuYZ_{tc}Ln z-mSf)Z5p>p8{A!38Jt;rwYAe|{J)jS==HX|7+rL5(m!Ie@$U5ewTr#xbcgis>F(p| zvOA-C?C2x~KMc-CAAB9+0gHz&w!*<-3E6d_Vw zz&%cCCDJ@kXF>goSv&QkPG#xGy(bUUwcr#}DbhfQu{MTgK*1Ftl$_aOO~Sbr?E@yt zeO)0ysZM~r vR@Y}Zm~)tF_hxW&Z-4Rk((ReV;Xk!anznG*-K6)s8G@buOnYBy#X delta 25 gcmZo_Wn5gg;Ue#5VbQN5Y-u@(C8 usize { } } +lazy_static! { + static ref CP_NUMBER: regex::Regex = regex::Regex::new("cp([0-9]+)").unwrap(); +} + +fn encoding_from_name(encoding_name: &str) -> Option<&(dyn encoding::Encoding + Send + Sync)> { + match encoding::label::encoding_from_whatwg_label(&encoding_name) { + Some(e) => return Some(e), + None => { + if let Some(cap) = CP_NUMBER.captures(&encoding_name) { + return encoding::label::encoding_from_windows_code_page( + str::parse(cap.get(1).unwrap().as_str()).unwrap(), + ); + } else { + return None; + } + } + } +} + fn main() -> std::io::Result<()> { tracing_subscriber::fmt() .with_target(false) @@ -140,6 +163,7 @@ fn main() -> std::io::Result<()> { let path = PathBuf::from(line).canonicalize()?; let src_archive_file = path_for(&src_archive_dir, &path, ""); let mut source = std::fs::read(&path)?; + let mut needs_conversion = false; let code_ranges; let mut trap_writer = extractor::new_trap_writer(); if path.extension().map_or(false, |x| x == "erb") { @@ -168,6 +192,43 @@ fn main() -> std::io::Result<()> { } code_ranges = ranges; } else { + if let Some(encoding_name) = scan_coding_comment(&source) { + // If the input is already UTF-8 then there is no need to recode the source + // If the declared encoding is 'binary' or 'ascii-8bit' then it is not clear how + // to interpret characters. In this case it is probably best to leave the input + // unchanged. + if !encoding_name.eq_ignore_ascii_case("utf-8") + && !encoding_name.eq_ignore_ascii_case("ascii-8bit") + && !encoding_name.eq_ignore_ascii_case("binary") + { + if let Some(encoding) = encoding_from_name(&encoding_name) { + needs_conversion = + encoding.whatwg_name().unwrap_or_default() != "utf-8"; + if needs_conversion { + match encoding + .decode(&source, encoding::types::DecoderTrap::Replace) + { + Ok(str) => source = str.as_bytes().to_owned(), + Err(msg) => { + needs_conversion = false; + tracing::warn!( + "{}: character decoding failure: {} ({})", + &path.to_string_lossy(), + msg, + &encoding_name + ); + } + } + } + } else { + tracing::warn!( + "{}: unknown character encoding: '{}'", + &path.to_string_lossy(), + &encoding_name + ); + } + } + } code_ranges = vec![]; } extractor::extract( @@ -180,7 +241,11 @@ fn main() -> std::io::Result<()> { &code_ranges, )?; std::fs::create_dir_all(&src_archive_file.parent().unwrap())?; - std::fs::copy(&path, &src_archive_file)?; + if needs_conversion { + std::fs::write(&src_archive_file, &source)?; + } else { + std::fs::copy(&path, &src_archive_file)?; + } write_trap(&trap_dir, path, trap_writer, &trap_compression) }) .expect("failed to extract files"); @@ -299,3 +364,143 @@ fn path_for(dir: &Path, path: &Path, ext: &str) -> PathBuf { } result } + +fn skip_space(content: &[u8], index: usize) -> usize { + let mut index = index; + while index < content.len() { + let c = content[index] as char; + // white space except \n + let is_space = c == ' ' || ('\t'..='\r').contains(&c) && c != '\n'; + if !is_space { + break; + } + index += 1; + } + index +} + +fn scan_coding_comment(content: &[u8]) -> std::option::Option> { + let mut index = 0; + // skip UTF-8 BOM marker if there is one + if content.len() >= 3 && content[0] == 0xef && content[1] == 0xbb && content[2] == 0xbf { + index += 3; + } + // skip #! line if there is one + if index + 1 < content.len() + && content[index] as char == '#' + && content[index + 1] as char == '!' + { + index += 2; + while index < content.len() && content[index] as char != '\n' { + index += 1 + } + index += 1 + } + index = skip_space(content, index); + + if index >= content.len() || content[index] as char != '#' { + return None; + } + index += 1; + + const CODING: [char; 12] = ['C', 'c', 'O', 'o', 'D', 'd', 'I', 'i', 'N', 'n', 'G', 'g']; + let mut word_index = 0; + while index < content.len() && word_index < CODING.len() && content[index] as char != '\n' { + if content[index] as char == CODING[word_index] + || content[index] as char == CODING[word_index + 1] + { + word_index += 2 + } else { + word_index = 0; + } + index += 1; + } + if word_index < CODING.len() { + return None; + } + index = skip_space(content, index); + + if index < content.len() && content[index] as char != ':' && content[index] as char != '=' { + return None; + } + index += 1; + index = skip_space(content, index); + + let start = index; + while index < content.len() { + let c = content[index] as char; + if c == '-' || c == '_' || c.is_ascii_alphanumeric() { + index += 1; + } else { + break; + } + } + if index > start { + return Some(String::from_utf8_lossy(&content[start..index])); + } + None +} + +#[test] +fn test_scan_coding_comment() { + let text = "# encoding: utf-8"; + let result = scan_coding_comment(text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "#coding:utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "# foo\n# encoding: utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, None); + + let text = "# encoding: latin1 encoding: utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("latin1".into())); + + let text = "# encoding: nonsense"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("nonsense".into())); + + let text = "# coding = utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "# CODING = utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "# CoDiNg = utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "# blah blahblahcoding = utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + // unicode BOM is ignored + let text = "\u{FEFF}# encoding: utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "\u{FEFF} # encoding: utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "#! /usr/bin/env ruby\n # encoding: utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + let text = "\u{FEFF}#! /usr/bin/env ruby\n # encoding: utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + + // A #! must be the first thing on a line, otherwise it's a normal comment + let text = " #! /usr/bin/env ruby encoding = utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, Some("utf-8".into())); + let text = " #! /usr/bin/env ruby \n # encoding = utf-8"; + let result = scan_coding_comment(&text.as_bytes()); + assert_eq!(result, None); +} diff --git a/ruby/ql/test/library-tests/ast/Ast.expected b/ruby/ql/test/library-tests/ast/Ast.expected index 0a16654594d..4cb29e0f033 100644 --- a/ruby/ql/test/library-tests/ast/Ast.expected +++ b/ruby/ql/test/library-tests/ast/Ast.expected @@ -1762,6 +1762,12 @@ escape_sequences/escapes.rb: # 93| getStmt: [SymbolLiteral] :"\C-?" # 93| getComponent: [StringEscapeSequenceComponent] \C # 93| getComponent: [StringTextComponent] -? +misc/iso-8859-15.rb: +# 1| [Toplevel] iso-8859-15.rb +# 4| getStmt: [MethodCall] call to print +# 4| getReceiver: [SelfVariableAccess] self +# 4| getArgument: [StringLiteral] "EUR = €" +# 4| getComponent: [StringTextComponent] EUR = € literals/literals.rb: # 1| [Toplevel] literals.rb # 2| getStmt: [NilLiteral] nil diff --git a/ruby/ql/test/library-tests/ast/TreeSitter.expected b/ruby/ql/test/library-tests/ast/TreeSitter.expected index 67a909d9002..cb5a17ebebb 100644 --- a/ruby/ql/test/library-tests/ast/TreeSitter.expected +++ b/ruby/ql/test/library-tests/ast/TreeSitter.expected @@ -4604,6 +4604,17 @@ literals/literals.rb: # 193| cat file.txt # 193| # 195| 1: [HeredocEnd] SCRIPT +misc/iso-8859-15.rb: +# 1| [Program] Program +# 4| 0: [Call] Call +# 4| 0: [Identifier] print +# 4| 1: [ArgumentList] ArgumentList +# 4| 0: [String] String +# 4| 0: [ReservedWord] " +# 4| 1: [StringContent] EUR = € +# 4| 2: [ReservedWord] " +# 1| [Comment] #! /usr/bin/ruby +# 2| [Comment] # coding: iso-8859-15 misc/misc.erb: # 2| [Program] Program # 2| 0: [Call] Call diff --git a/ruby/ql/test/library-tests/ast/ValueText.expected b/ruby/ql/test/library-tests/ast/ValueText.expected index ecf7399a99a..e66838fbe2c 100644 --- a/ruby/ql/test/library-tests/ast/ValueText.expected +++ b/ruby/ql/test/library-tests/ast/ValueText.expected @@ -717,6 +717,7 @@ exprValue | literals/literals.rb:198:8:198:8 | 5 | 5 | int | | literals/literals.rb:199:2:199:2 | :y | :y | symbol | | literals/literals.rb:199:7:199:7 | :Z | :Z | symbol | +| misc/iso-8859-15.rb:4:7:4:17 | "EUR = \u20ac" | EUR = \u20ac | string | | misc/misc.erb:2:15:2:37 | "main_include_admin.js" | main_include_admin.js | string | | misc/misc.rb:1:7:1:11 | "bar" | bar | string | | misc/misc.rb:3:7:3:9 | foo | foo | string | @@ -1592,6 +1593,7 @@ exprCfgNodeValue | literals/literals.rb:198:8:198:8 | 5 | 5 | int | | literals/literals.rb:199:2:199:2 | :y | :y | symbol | | literals/literals.rb:199:7:199:7 | :Z | :Z | symbol | +| misc/iso-8859-15.rb:4:7:4:17 | "EUR = \u20ac" | EUR = \u20ac | string | | misc/misc.erb:2:15:2:37 | "main_include_admin.js" | main_include_admin.js | string | | misc/misc.rb:1:7:1:11 | "bar" | bar | string | | misc/misc.rb:3:7:3:9 | foo | foo | string | diff --git a/ruby/ql/test/library-tests/ast/misc/iso-8859-15.rb b/ruby/ql/test/library-tests/ast/misc/iso-8859-15.rb new file mode 100644 index 00000000000..d5fd8ae9456 --- /dev/null +++ b/ruby/ql/test/library-tests/ast/misc/iso-8859-15.rb @@ -0,0 +1,4 @@ +#! /usr/bin/ruby +# coding: iso-8859-15 + +print "EUR = " \ No newline at end of file From 5f96c92fac08025fad9098442ea370308dc78201 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Thu, 21 Jul 2022 17:38:33 +0100 Subject: [PATCH 404/465] QL: sync Ruby extractor changes --- ql/extractor/src/extractor.rs | 505 +++++++++++----------------------- ql/extractor/src/main.rs | 66 +---- ql/extractor/src/trap.rs | 272 ++++++++++++++++++ 3 files changed, 446 insertions(+), 397 deletions(-) create mode 100644 ql/extractor/src/trap.rs diff --git a/ql/extractor/src/extractor.rs b/ql/extractor/src/extractor.rs index 8cdaff1b738..db280634ae5 100644 --- a/ql/extractor/src/extractor.rs +++ b/ql/extractor/src/extractor.rs @@ -1,161 +1,112 @@ +use crate::trap; use node_types::{EntryKind, Field, NodeTypeMap, Storage, TypeName}; -use std::borrow::Cow; use std::collections::BTreeMap as Map; use std::collections::BTreeSet as Set; use std::fmt; -use std::io::Write; use std::path::Path; use tracing::{error, info, span, Level}; use tree_sitter::{Language, Node, Parser, Range, Tree}; -pub struct TrapWriter { - /// The accumulated trap entries - trap_output: Vec, - /// A counter for generating fresh labels - counter: u32, - /// cache of global keys - global_keys: std::collections::HashMap, +pub fn populate_file(writer: &mut trap::Writer, absolute_path: &Path) -> trap::Label { + let (file_label, fresh) = + writer.global_id(&trap::full_id_for_file(&normalize_path(absolute_path))); + if fresh { + writer.add_tuple( + "files", + vec![ + trap::Arg::Label(file_label), + trap::Arg::String(normalize_path(absolute_path)), + ], + ); + populate_parent_folders(writer, file_label, absolute_path.parent()); + } + file_label } -pub fn new_trap_writer() -> TrapWriter { - TrapWriter { - counter: 0, - trap_output: Vec::new(), - global_keys: std::collections::HashMap::new(), +fn populate_empty_file(writer: &mut trap::Writer) -> trap::Label { + let (file_label, fresh) = writer.global_id("empty;sourcefile"); + if fresh { + writer.add_tuple( + "files", + vec![ + trap::Arg::Label(file_label), + trap::Arg::String("".to_string()), + ], + ); } + file_label } -impl TrapWriter { - /// Gets a label that will hold the unique ID of the passed string at import time. - /// This can be used for incrementally importable TRAP files -- use globally unique - /// strings to compute a unique ID for table tuples. - /// - /// Note: You probably want to make sure that the key strings that you use are disjoint - /// for disjoint column types; the standard way of doing this is to prefix (or append) - /// the column type name to the ID. Thus, you might identify methods in Java by the - /// full ID "methods_com.method.package.DeclaringClass.method(argumentList)". +pub fn populate_empty_location(writer: &mut trap::Writer) { + let file_label = populate_empty_file(writer); + location(writer, file_label, 0, 0, 0, 0); +} - fn fresh_id(&mut self) -> Label { - let label = Label(self.counter); - self.counter += 1; - self.trap_output.push(TrapEntry::FreshId(label)); - label - } - - fn global_id(&mut self, key: &str) -> (Label, bool) { - if let Some(label) = self.global_keys.get(key) { - return (*label, false); - } - let label = Label(self.counter); - self.counter += 1; - self.global_keys.insert(key.to_owned(), label); - self.trap_output - .push(TrapEntry::MapLabelToKey(label, key.to_owned())); - (label, true) - } - - fn add_tuple(&mut self, table_name: &str, args: Vec) { - self.trap_output - .push(TrapEntry::GenericTuple(table_name.to_owned(), args)) - } - - fn populate_file(&mut self, absolute_path: &Path) -> Label { - let (file_label, fresh) = self.global_id(&full_id_for_file(absolute_path)); - if fresh { - self.add_tuple( - "files", - vec![ - Arg::Label(file_label), - Arg::String(normalize_path(absolute_path)), - ], - ); - self.populate_parent_folders(file_label, absolute_path.parent()); - } - file_label - } - - fn populate_empty_file(&mut self) -> Label { - let (file_label, fresh) = self.global_id("empty;sourcefile"); - if fresh { - self.add_tuple( - "files", - vec![Arg::Label(file_label), Arg::String("".to_string())], - ); - } - file_label - } - - pub fn populate_empty_location(&mut self) { - let file_label = self.populate_empty_file(); - self.location(file_label, 0, 0, 0, 0); - } - - fn populate_parent_folders(&mut self, child_label: Label, path: Option<&Path>) { - let mut path = path; - let mut child_label = child_label; - loop { - match path { - None => break, - Some(folder) => { - let (folder_label, fresh) = self.global_id(&full_id_for_folder(folder)); - self.add_tuple( - "containerparent", - vec![Arg::Label(folder_label), Arg::Label(child_label)], +pub fn populate_parent_folders( + writer: &mut trap::Writer, + child_label: trap::Label, + path: Option<&Path>, +) { + let mut path = path; + let mut child_label = child_label; + loop { + match path { + None => break, + Some(folder) => { + let (folder_label, fresh) = + writer.global_id(&trap::full_id_for_folder(&normalize_path(folder))); + writer.add_tuple( + "containerparent", + vec![ + trap::Arg::Label(folder_label), + trap::Arg::Label(child_label), + ], + ); + if fresh { + writer.add_tuple( + "folders", + vec![ + trap::Arg::Label(folder_label), + trap::Arg::String(normalize_path(folder)), + ], ); - if fresh { - self.add_tuple( - "folders", - vec![ - Arg::Label(folder_label), - Arg::String(normalize_path(folder)), - ], - ); - path = folder.parent(); - child_label = folder_label; - } else { - break; - } + path = folder.parent(); + child_label = folder_label; + } else { + break; } } } } +} - fn location( - &mut self, - file_label: Label, - start_line: usize, - start_column: usize, - end_line: usize, - end_column: usize, - ) -> Label { - let (loc_label, fresh) = self.global_id(&format!( - "loc,{{{}}},{},{},{},{}", - file_label, start_line, start_column, end_line, end_column - )); - if fresh { - self.add_tuple( - "locations_default", - vec![ - Arg::Label(loc_label), - Arg::Label(file_label), - Arg::Int(start_line), - Arg::Int(start_column), - Arg::Int(end_line), - Arg::Int(end_column), - ], - ); - } - loc_label - } - - fn comment(&mut self, text: String) { - self.trap_output.push(TrapEntry::Comment(text)); - } - - pub fn output(self, writer: &mut dyn Write) -> std::io::Result<()> { - write!(writer, "{}", Program(self.trap_output)) +fn location( + writer: &mut trap::Writer, + file_label: trap::Label, + start_line: usize, + start_column: usize, + end_line: usize, + end_column: usize, +) -> trap::Label { + let (loc_label, fresh) = writer.global_id(&format!( + "loc,{{{}}},{},{},{},{}", + file_label, start_line, start_column, end_line, end_column + )); + if fresh { + writer.add_tuple( + "locations_default", + vec![ + trap::Arg::Label(loc_label), + trap::Arg::Label(file_label), + trap::Arg::Int(start_line), + trap::Arg::Int(start_column), + trap::Arg::Int(end_line), + trap::Arg::Int(end_column), + ], + ); } + loc_label } /// Extracts the source file at `path`, which is assumed to be canonicalized. @@ -163,71 +114,43 @@ pub fn extract( language: Language, language_prefix: &str, schema: &NodeTypeMap, - trap_writer: &mut TrapWriter, + trap_writer: &mut trap::Writer, path: &Path, source: &[u8], ranges: &[Range], ) -> std::io::Result<()> { + let path_str = format!("{}", path.display()); let span = span!( Level::TRACE, "extract", - file = %path.display() + file = %path_str ); let _enter = span.enter(); - info!("extracting: {}", path.display()); + info!("extracting: {}", path_str); let mut parser = Parser::new(); parser.set_language(language).unwrap(); parser.set_included_ranges(ranges).unwrap(); let tree = parser.parse(&source, None).expect("Failed to parse file"); - trap_writer.comment(format!("Auto-generated TRAP file for {}", path.display())); - let file_label = &trap_writer.populate_file(path); - let mut visitor = Visitor { + trap_writer.comment(format!("Auto-generated TRAP file for {}", path_str)); + let file_label = populate_file(trap_writer, path); + let mut visitor = Visitor::new( source, trap_writer, // TODO: should we handle path strings that are not valid UTF8 better? - path: format!("{}", path.display()), - file_label: *file_label, - toplevel_child_counter: 0, - stack: Vec::new(), + &path_str, + file_label, language_prefix, schema, - }; + ); traverse(&tree, &mut visitor); parser.reset(); Ok(()) } -/// Escapes a string for use in a TRAP key, by replacing special characters with -/// HTML entities. -fn escape_key<'a, S: Into>>(key: S) -> Cow<'a, str> { - fn needs_escaping(c: char) -> bool { - matches!(c, '&' | '{' | '}' | '"' | '@' | '#') - } - - let key = key.into(); - if key.contains(needs_escaping) { - let mut escaped = String::with_capacity(2 * key.len()); - for c in key.chars() { - match c { - '&' => escaped.push_str("&"), - '{' => escaped.push_str("{"), - '}' => escaped.push_str("}"), - '"' => escaped.push_str("""), - '@' => escaped.push_str("@"), - '#' => escaped.push_str("#"), - _ => escaped.push(c), - } - } - Cow::Owned(escaped) - } else { - key - } -} - /// Normalizes the path according the common CodeQL specification. Assumes that /// `path` has already been canonicalized using `std::fs::canonicalize`. fn normalize_path(path: &Path) -> String { @@ -267,34 +190,28 @@ fn normalize_path(path: &Path) -> String { } } -fn full_id_for_file(path: &Path) -> String { - format!("{};sourcefile", escape_key(&normalize_path(path))) -} - -fn full_id_for_folder(path: &Path) -> String { - format!("{};folder", escape_key(&normalize_path(path))) -} - struct ChildNode { field_name: Option<&'static str>, - label: Label, + label: trap::Label, type_name: TypeName, } struct Visitor<'a> { /// The file path of the source code (as string) - path: String, + path: &'a str, /// The label to use whenever we need to refer to the `@file` entity of this /// source file. - file_label: Label, + file_label: trap::Label, /// The source code as a UTF-8 byte array source: &'a [u8], - /// A TrapWriter to accumulate trap entries - trap_writer: &'a mut TrapWriter, + /// A trap::Writer to accumulate trap entries + trap_writer: &'a mut trap::Writer, /// A counter for top-level child nodes toplevel_child_counter: usize, - /// Language prefix - language_prefix: &'a str, + /// Language-specific name of the AST info table + ast_node_info_table_name: String, + /// Language-specific name of the tokeninfo table + tokeninfo_table_name: String, /// A lookup table from type name to node types schema: &'a NodeTypeMap, /// A stack for gathering information from child nodes. Whenever a node is @@ -303,27 +220,48 @@ struct Visitor<'a> { /// node the list containing the child data is popped from the stack and /// matched against the dbscheme for the node. If the expectations are met /// the corresponding row definitions are added to the trap_output. - stack: Vec<(Label, usize, Vec)>, + stack: Vec<(trap::Label, usize, Vec)>, } -impl Visitor<'_> { +impl<'a> Visitor<'a> { + fn new( + source: &'a [u8], + trap_writer: &'a mut trap::Writer, + path: &'a str, + file_label: trap::Label, + language_prefix: &str, + schema: &'a NodeTypeMap, + ) -> Visitor<'a> { + Visitor { + path, + file_label, + source, + trap_writer, + toplevel_child_counter: 0, + ast_node_info_table_name: format!("{}_ast_node_info", language_prefix), + tokeninfo_table_name: format!("{}_tokeninfo", language_prefix), + schema, + stack: Vec::new(), + } + } + fn record_parse_error( &mut self, error_message: String, full_error_message: String, - loc: Label, + loc: trap::Label, ) { error!("{}", full_error_message); let id = self.trap_writer.fresh_id(); self.trap_writer.add_tuple( "diagnostics", vec![ - Arg::Label(id), - Arg::Int(40), // severity 40 = error - Arg::String("parse_error".to_string()), - Arg::String(error_message), - Arg::String(full_error_message), - Arg::Label(loc), + trap::Arg::Label(id), + trap::Arg::Int(40), // severity 40 = error + trap::Arg::String("parse_error".to_string()), + trap::Arg::String(error_message), + trap::Arg::String(full_error_message), + trap::Arg::Label(loc), ], ); } @@ -335,7 +273,8 @@ impl Visitor<'_> { node: Node, ) { let (start_line, start_column, end_line, end_column) = location_for(self.source, node); - let loc = self.trap_writer.location( + let loc = location( + self.trap_writer, self.file_label, start_line, start_column, @@ -374,7 +313,8 @@ impl Visitor<'_> { } let (id, _, child_nodes) = self.stack.pop().expect("Vistor: empty stack"); let (start_line, start_column, end_line, end_column) = location_for(self.source, node); - let loc = self.trap_writer.location( + let loc = location( + self.trap_writer, self.file_label, start_line, start_column, @@ -402,19 +342,19 @@ impl Visitor<'_> { match &table.kind { EntryKind::Token { kind_id, .. } => { self.trap_writer.add_tuple( - &format!("{}_ast_node_info", self.language_prefix), + &self.ast_node_info_table_name, vec![ - Arg::Label(id), - Arg::Label(parent_id), - Arg::Int(parent_index), - Arg::Label(loc), + trap::Arg::Label(id), + trap::Arg::Label(parent_id), + trap::Arg::Int(parent_index), + trap::Arg::Label(loc), ], ); self.trap_writer.add_tuple( - &format!("{}_tokeninfo", self.language_prefix), + &self.tokeninfo_table_name, vec![ - Arg::Label(id), - Arg::Int(*kind_id), + trap::Arg::Label(id), + trap::Arg::Int(*kind_id), sliced_source_arg(self.source, node), ], ); @@ -425,15 +365,15 @@ impl Visitor<'_> { } => { if let Some(args) = self.complex_node(&node, fields, &child_nodes, id) { self.trap_writer.add_tuple( - &format!("{}_ast_node_info", self.language_prefix), + &self.ast_node_info_table_name, vec![ - Arg::Label(id), - Arg::Label(parent_id), - Arg::Int(parent_index), - Arg::Label(loc), + trap::Arg::Label(id), + trap::Arg::Label(parent_id), + trap::Arg::Int(parent_index), + trap::Arg::Label(loc), ], ); - let mut all_args = vec![Arg::Label(id)]; + let mut all_args = vec![trap::Arg::Label(id)]; all_args.extend(args); self.trap_writer.add_tuple(table_name, all_args); } @@ -472,9 +412,9 @@ impl Visitor<'_> { node: &Node, fields: &[Field], child_nodes: &[ChildNode], - parent_id: Label, - ) -> Option> { - let mut map: Map<&Option, (&Field, Vec)> = Map::new(); + parent_id: trap::Label, + ) -> Option> { + let mut map: Map<&Option, (&Field, Vec)> = Map::new(); for field in fields { map.insert(&field.name, (field, Vec::new())); } @@ -488,9 +428,9 @@ impl Visitor<'_> { { // We can safely unwrap because type_matches checks the key is in the map. let (int_value, _) = int_mapping.get(&child_node.type_name.kind).unwrap(); - values.push(Arg::Int(*int_value)); + values.push(trap::Arg::Int(*int_value)); } else { - values.push(Arg::Label(child_node.label)); + values.push(trap::Arg::Label(child_node.label)); } } else if field.name.is_some() { let error_message = format!( @@ -569,9 +509,9 @@ impl Visitor<'_> { ); break; } - let mut args = vec![Arg::Label(parent_id)]; + let mut args = vec![trap::Arg::Label(parent_id)]; if *has_index { - args.push(Arg::Int(index)) + args.push(trap::Arg::Int(index)) } args.push(child_value.clone()); self.trap_writer.add_tuple(table_name, args); @@ -625,9 +565,9 @@ impl Visitor<'_> { } // Emit a slice of a source file as an Arg. -fn sliced_source_arg(source: &[u8], n: Node) -> Arg { +fn sliced_source_arg(source: &[u8], n: Node) -> trap::Arg { let range = n.byte_range(); - Arg::String(String::from_utf8_lossy(&source[range.start..range.end]).into_owned()) + trap::Arg::String(String::from_utf8_lossy(&source[range.start..range.end]).into_owned()) } // Emit a pair of `TrapEntry`s for the provided node, appropriately calibrated. @@ -699,59 +639,6 @@ fn traverse(tree: &Tree, visitor: &mut Visitor) { } } -pub struct Program(Vec); - -impl fmt::Display for Program { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let mut text = String::new(); - for trap_entry in &self.0 { - text.push_str(&format!("{}\n", trap_entry)); - } - write!(f, "{}", text) - } -} - -enum TrapEntry { - /// Maps the label to a fresh id, e.g. `#123=*`. - FreshId(Label), - /// Maps the label to a key, e.g. `#7=@"foo"`. - MapLabelToKey(Label, String), - /// foo_bar(arg*) - GenericTuple(String, Vec), - Comment(String), -} -impl fmt::Display for TrapEntry { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - TrapEntry::FreshId(label) => write!(f, "{}=*", label), - TrapEntry::MapLabelToKey(label, key) => { - write!(f, "{}=@\"{}\"", label, key.replace("\"", "\"\"")) - } - TrapEntry::GenericTuple(name, args) => { - write!(f, "{}(", name)?; - for (index, arg) in args.iter().enumerate() { - if index > 0 { - write!(f, ",")?; - } - write!(f, "{}", arg)?; - } - write!(f, ")") - } - TrapEntry::Comment(line) => write!(f, "// {}", line), - } - } -} - -#[derive(Debug, Copy, Clone)] -// Identifiers of the form #0, #1... -struct Label(u32); - -impl fmt::Display for Label { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "#{:x}", self.0) - } -} - // Numeric indices. #[derive(Debug, Copy, Clone)] struct Index(usize); @@ -761,69 +648,3 @@ impl fmt::Display for Index { write!(f, "{}", self.0) } } - -// Some untyped argument to a TrapEntry. -#[derive(Debug, Clone)] -enum Arg { - Label(Label), - Int(usize), - String(String), -} - -const MAX_STRLEN: usize = 1048576; - -impl fmt::Display for Arg { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - Arg::Label(x) => write!(f, "{}", x), - Arg::Int(x) => write!(f, "{}", x), - Arg::String(x) => write!( - f, - "\"{}\"", - limit_string(x, MAX_STRLEN).replace("\"", "\"\"") - ), - } - } -} - -/// Limit the length (in bytes) of a string. If the string's length in bytes is -/// less than or equal to the limit then the entire string is returned. Otherwise -/// the string is sliced at the provided limit. If there is a multi-byte character -/// at the limit then the returned slice will be slightly shorter than the limit to -/// avoid splitting that multi-byte character. -fn limit_string(string: &str, max_size: usize) -> &str { - if string.len() <= max_size { - return string; - } - let p = string.as_bytes(); - let mut index = max_size; - // We want to clip the string at [max_size]; however, the character at that position - // may span several bytes. We need to find the first byte of the character. In UTF-8 - // encoded data any byte that matches the bit pattern 10XXXXXX is not a start byte. - // Therefore we decrement the index as long as there are bytes matching this pattern. - // This ensures we cut the string at the border between one character and another. - while index > 0 && (p[index] & 0b11000000) == 0b10000000 { - index -= 1; - } - &string[0..index] -} - -#[test] -fn limit_string_test() { - assert_eq!("hello", limit_string(&"hello world".to_owned(), 5)); - assert_eq!("hi ☹", limit_string(&"hi ☹☹".to_owned(), 6)); - assert_eq!("hi ", limit_string(&"hi ☹☹".to_owned(), 5)); -} - -#[test] -fn escape_key_test() { - assert_eq!("foo!", escape_key("foo!")); - assert_eq!("foo{}", escape_key("foo{}")); - assert_eq!("{}", escape_key("{}")); - assert_eq!("", escape_key("")); - assert_eq!("/path/to/foo.rb", escape_key("/path/to/foo.rb")); - assert_eq!( - "/path/to/foo&{}"@#.rb", - escape_key("/path/to/foo&{}\"@#.rb") - ); -} diff --git a/ql/extractor/src/main.rs b/ql/extractor/src/main.rs index 7f8ab87a7ca..9584304c430 100644 --- a/ql/extractor/src/main.rs +++ b/ql/extractor/src/main.rs @@ -1,49 +1,13 @@ mod extractor; +mod trap; extern crate num_cpus; -use flate2::write::GzEncoder; use rayon::prelude::*; use std::fs; -use std::io::{BufRead, BufWriter}; +use std::io::BufRead; use std::path::{Path, PathBuf}; -enum TrapCompression { - None, - Gzip, -} - -impl TrapCompression { - fn from_env() -> TrapCompression { - match std::env::var("CODEQL_QL_TRAP_COMPRESSION") { - Ok(method) => match TrapCompression::from_string(&method) { - Some(c) => c, - None => { - tracing::error!("Unknown compression method '{}'; using gzip.", &method); - TrapCompression::Gzip - } - }, - // Default compression method if the env var isn't set: - Err(_) => TrapCompression::Gzip, - } - } - - fn from_string(s: &str) -> Option { - match s.to_lowercase().as_ref() { - "none" => Some(TrapCompression::None), - "gzip" => Some(TrapCompression::Gzip), - _ => None, - } - } - - fn extension(&self) -> &str { - match self { - TrapCompression::None => "trap", - TrapCompression::Gzip => "trap.gz", - } - } -} - /** * Gets the number of threads the extractor should use, by reading the * CODEQL_THREADS environment variable and using it as described in the @@ -115,7 +79,7 @@ fn main() -> std::io::Result<()> { .value_of("output-dir") .expect("missing --output-dir"); let trap_dir = PathBuf::from(trap_dir); - let trap_compression = TrapCompression::from_env(); + let trap_compression = trap::Compression::from_env("CODEQL_QL_TRAP_COMPRESSION"); let file_list = matches.value_of("file-list").expect("missing --file-list"); let file_list = fs::File::open(file_list)?; @@ -140,7 +104,7 @@ fn main() -> std::io::Result<()> { let src_archive_file = path_for(&src_archive_dir, &path, ""); let source = std::fs::read(&path)?; let code_ranges = vec![]; - let mut trap_writer = extractor::new_trap_writer(); + let mut trap_writer = trap::Writer::new(); extractor::extract( language, "ql", @@ -152,33 +116,25 @@ fn main() -> std::io::Result<()> { )?; std::fs::create_dir_all(&src_archive_file.parent().unwrap())?; std::fs::copy(&path, &src_archive_file)?; - write_trap(&trap_dir, path, trap_writer, &trap_compression) + write_trap(&trap_dir, path, &trap_writer, trap_compression) }) .expect("failed to extract files"); let path = PathBuf::from("extras"); - let mut trap_writer = extractor::new_trap_writer(); - trap_writer.populate_empty_location(); - write_trap(&trap_dir, path, trap_writer, &trap_compression) + let mut trap_writer = trap::Writer::new(); + extractor::populate_empty_location(&mut trap_writer); + write_trap(&trap_dir, path, &trap_writer, trap_compression) } fn write_trap( trap_dir: &Path, path: PathBuf, - trap_writer: extractor::TrapWriter, - trap_compression: &TrapCompression, + trap_writer: &trap::Writer, + trap_compression: trap::Compression, ) -> std::io::Result<()> { let trap_file = path_for(trap_dir, &path, trap_compression.extension()); std::fs::create_dir_all(&trap_file.parent().unwrap())?; - let trap_file = std::fs::File::create(&trap_file)?; - let mut trap_file = BufWriter::new(trap_file); - match trap_compression { - TrapCompression::None => trap_writer.output(&mut trap_file), - TrapCompression::Gzip => { - let mut compressed_writer = GzEncoder::new(trap_file, flate2::Compression::fast()); - trap_writer.output(&mut compressed_writer) - } - } + trap_writer.write_to_file(&trap_file, trap_compression) } fn path_for(dir: &Path, path: &Path, ext: &str) -> PathBuf { diff --git a/ql/extractor/src/trap.rs b/ql/extractor/src/trap.rs new file mode 100644 index 00000000000..d64c520c4cc --- /dev/null +++ b/ql/extractor/src/trap.rs @@ -0,0 +1,272 @@ +use std::borrow::Cow; +use std::fmt; +use std::io::{BufWriter, Write}; +use std::path::Path; + +use flate2::write::GzEncoder; + +pub struct Writer { + /// The accumulated trap entries + trap_output: Vec, + /// A counter for generating fresh labels + counter: u32, + /// cache of global keys + global_keys: std::collections::HashMap, +} + +impl Writer { + pub fn new() -> Writer { + Writer { + counter: 0, + trap_output: Vec::new(), + global_keys: std::collections::HashMap::new(), + } + } + + pub fn fresh_id(&mut self) -> Label { + let label = Label(self.counter); + self.counter += 1; + self.trap_output.push(Entry::FreshId(label)); + label + } + + /// Gets a label that will hold the unique ID of the passed string at import time. + /// This can be used for incrementally importable TRAP files -- use globally unique + /// strings to compute a unique ID for table tuples. + /// + /// Note: You probably want to make sure that the key strings that you use are disjoint + /// for disjoint column types; the standard way of doing this is to prefix (or append) + /// the column type name to the ID. Thus, you might identify methods in Java by the + /// full ID "methods_com.method.package.DeclaringClass.method(argumentList)". + pub fn global_id(&mut self, key: &str) -> (Label, bool) { + if let Some(label) = self.global_keys.get(key) { + return (*label, false); + } + let label = Label(self.counter); + self.counter += 1; + self.global_keys.insert(key.to_owned(), label); + self.trap_output + .push(Entry::MapLabelToKey(label, key.to_owned())); + (label, true) + } + + pub fn add_tuple(&mut self, table_name: &str, args: Vec) { + self.trap_output + .push(Entry::GenericTuple(table_name.to_owned(), args)) + } + + pub fn comment(&mut self, text: String) { + self.trap_output.push(Entry::Comment(text)); + } + + pub fn write_to_file(&self, path: &Path, compression: Compression) -> std::io::Result<()> { + let trap_file = std::fs::File::create(path)?; + let mut trap_file = BufWriter::new(trap_file); + match compression { + Compression::None => self.write_trap_entries(&mut trap_file), + Compression::Gzip => { + let mut compressed_writer = GzEncoder::new(trap_file, flate2::Compression::fast()); + self.write_trap_entries(&mut compressed_writer) + } + } + } + + fn write_trap_entries(&self, file: &mut W) -> std::io::Result<()> { + for trap_entry in &self.trap_output { + writeln!(file, "{}", trap_entry)?; + } + std::io::Result::Ok(()) + } +} + +pub enum Entry { + /// Maps the label to a fresh id, e.g. `#123=*`. + FreshId(Label), + /// Maps the label to a key, e.g. `#7=@"foo"`. + MapLabelToKey(Label, String), + /// foo_bar(arg*) + GenericTuple(String, Vec), + Comment(String), +} + +impl fmt::Display for Entry { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Entry::FreshId(label) => write!(f, "{}=*", label), + Entry::MapLabelToKey(label, key) => { + write!(f, "{}=@\"{}\"", label, key.replace("\"", "\"\"")) + } + Entry::GenericTuple(name, args) => { + write!(f, "{}(", name)?; + for (index, arg) in args.iter().enumerate() { + if index > 0 { + write!(f, ",")?; + } + write!(f, "{}", arg)?; + } + write!(f, ")") + } + Entry::Comment(line) => write!(f, "// {}", line), + } + } +} + +#[derive(Debug, Copy, Clone)] +// Identifiers of the form #0, #1... +pub struct Label(u32); + +impl fmt::Display for Label { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "#{:x}", self.0) + } +} + +// Some untyped argument to a TrapEntry. +#[derive(Debug, Clone)] +pub enum Arg { + Label(Label), + Int(usize), + String(String), +} + +const MAX_STRLEN: usize = 1048576; + +impl fmt::Display for Arg { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Arg::Label(x) => write!(f, "{}", x), + Arg::Int(x) => write!(f, "{}", x), + Arg::String(x) => write!( + f, + "\"{}\"", + limit_string(x, MAX_STRLEN).replace("\"", "\"\"") + ), + } + } +} + +pub struct Program(Vec); + +impl fmt::Display for Program { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut text = String::new(); + for trap_entry in &self.0 { + text.push_str(&format!("{}\n", trap_entry)); + } + write!(f, "{}", text) + } +} + +pub fn full_id_for_file(normalized_path: &str) -> String { + format!("{};sourcefile", escape_key(normalized_path)) +} + +pub fn full_id_for_folder(normalized_path: &str) -> String { + format!("{};folder", escape_key(normalized_path)) +} + +/// Escapes a string for use in a TRAP key, by replacing special characters with +/// HTML entities. +fn escape_key<'a, S: Into>>(key: S) -> Cow<'a, str> { + fn needs_escaping(c: char) -> bool { + matches!(c, '&' | '{' | '}' | '"' | '@' | '#') + } + + let key = key.into(); + if key.contains(needs_escaping) { + let mut escaped = String::with_capacity(2 * key.len()); + for c in key.chars() { + match c { + '&' => escaped.push_str("&"), + '{' => escaped.push_str("{"), + '}' => escaped.push_str("}"), + '"' => escaped.push_str("""), + '@' => escaped.push_str("@"), + '#' => escaped.push_str("#"), + _ => escaped.push(c), + } + } + Cow::Owned(escaped) + } else { + key + } +} + +/// Limit the length (in bytes) of a string. If the string's length in bytes is +/// less than or equal to the limit then the entire string is returned. Otherwise +/// the string is sliced at the provided limit. If there is a multi-byte character +/// at the limit then the returned slice will be slightly shorter than the limit to +/// avoid splitting that multi-byte character. +fn limit_string(string: &str, max_size: usize) -> &str { + if string.len() <= max_size { + return string; + } + let p = string.as_bytes(); + let mut index = max_size; + // We want to clip the string at [max_size]; however, the character at that position + // may span several bytes. We need to find the first byte of the character. In UTF-8 + // encoded data any byte that matches the bit pattern 10XXXXXX is not a start byte. + // Therefore we decrement the index as long as there are bytes matching this pattern. + // This ensures we cut the string at the border between one character and another. + while index > 0 && (p[index] & 0b11000000) == 0b10000000 { + index -= 1; + } + &string[0..index] +} + +#[derive(Clone, Copy)] +pub enum Compression { + None, + Gzip, +} + +impl Compression { + pub fn from_env(var_name: &str) -> Compression { + match std::env::var(var_name) { + Ok(method) => match Compression::from_string(&method) { + Some(c) => c, + None => { + tracing::error!("Unknown compression method '{}'; using gzip.", &method); + Compression::Gzip + } + }, + // Default compression method if the env var isn't set: + Err(_) => Compression::Gzip, + } + } + + pub fn from_string(s: &str) -> Option { + match s.to_lowercase().as_ref() { + "none" => Some(Compression::None), + "gzip" => Some(Compression::Gzip), + _ => None, + } + } + + pub fn extension(&self) -> &str { + match self { + Compression::None => "trap", + Compression::Gzip => "trap.gz", + } + } +} + +#[test] +fn limit_string_test() { + assert_eq!("hello", limit_string(&"hello world".to_owned(), 5)); + assert_eq!("hi ☹", limit_string(&"hi ☹☹".to_owned(), 6)); + assert_eq!("hi ", limit_string(&"hi ☹☹".to_owned(), 5)); +} + +#[test] +fn escape_key_test() { + assert_eq!("foo!", escape_key("foo!")); + assert_eq!("foo{}", escape_key("foo{}")); + assert_eq!("{}", escape_key("{}")); + assert_eq!("", escape_key("")); + assert_eq!("/path/to/foo.rb", escape_key("/path/to/foo.rb")); + assert_eq!( + "/path/to/foo&{}"@#.rb", + escape_key("/path/to/foo&{}\"@#.rb") + ); +} From cc958dc1711ef9b3943bb8272f0b18334ea4ca64 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 21 Jul 2022 17:19:33 -0400 Subject: [PATCH 405/465] Update ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql Co-authored-by: Harry Maclean --- .../manually-check-http-verb/ManuallyCheckHttpVerb.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql index 354ccf62698..2ddf7fe87b3 100644 --- a/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql +++ b/ruby/ql/src/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.ql @@ -91,6 +91,6 @@ class HttpVerbConfig extends TaintTracking::Configuration { } from HttpVerbConfig config, DataFlow::PathNode source, DataFlow::PathNode sink -where config.hasFlow(source.getNode(), sink.getNode()) +where config.hasFlowPath(source, sink) select sink.getNode(), source, sink, "Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods." From 8fabc06d370e88603e809d35e76bd3c13bed8495 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 21 Jul 2022 21:25:44 +0000 Subject: [PATCH 406/465] fix test assertion --- .../ManuallyCheckHttpVerb.expected | 9 --------- 1 file changed, 9 deletions(-) diff --git a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected index a253c3e9313..1fdf8045c23 100644 --- a/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected +++ b/ruby/ql/test/query-tests/experimental/manually-check-http-verb/ManuallyCheckHttpVerb.expected @@ -24,18 +24,9 @@ nodes subpaths #select | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? : | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? : | ManuallyCheckHttpVerb.rb:4:8:4:19 | call to get? : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env : | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... | ManuallyCheckHttpVerb.rb:11:14:11:24 | call to env : | ManuallyCheckHttpVerb.rb:12:8:12:22 | ... == ... : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method : | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... | ManuallyCheckHttpVerb.rb:19:14:19:35 | call to request_method : | ManuallyCheckHttpVerb.rb:20:8:20:22 | ... == ... : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method : | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... | ManuallyCheckHttpVerb.rb:27:14:27:27 | call to method : | ManuallyCheckHttpVerb.rb:28:8:28:22 | ... == ... : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method : | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... | ManuallyCheckHttpVerb.rb:35:14:35:39 | call to raw_request_method : | ManuallyCheckHttpVerb.rb:36:8:36:22 | ... == ... : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol : | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... | ManuallyCheckHttpVerb.rb:51:16:51:44 | call to request_method_symbol : | ManuallyCheckHttpVerb.rb:52:10:52:23 | ... == ... : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env : | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | -| ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] | ManuallyCheckHttpVerb.rb:59:10:59:20 | call to env : | ManuallyCheckHttpVerb.rb:59:10:59:38 | ...[...] : | Manually checking HTTP verbs is an indication that multiple requests are routed to the same controller action. This could lead to bypassing necessary authorization methods and other protections, like CSRF protection. Prefer using different controller actions for each HTTP method and relying Rails routing to handle mappting resources and verbs to specific methods. | From 486a394a7f1979a69f6a9b82f804645111b05876 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 21 Jul 2022 17:26:09 -0400 Subject: [PATCH 407/465] Update ruby/ql/src/experimental/weak-params/WeakParams.ql Co-authored-by: Harry Maclean --- ruby/ql/src/experimental/weak-params/WeakParams.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql index 0f36d4930d3..8789018e2cc 100644 --- a/ruby/ql/src/experimental/weak-params/WeakParams.ql +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -39,7 +39,7 @@ class WeakParams extends DataFlow::CallNode { WeakParams() { this.getReceiver() instanceof ActionControllerRequest and this.getMethodName() = - ["path_parametes", "query_parameters", "request_parameters", "GET", "POST"] + ["path_parameters", "query_parameters", "request_parameters", "GET", "POST"] } } From c1a6ca5f9458346453a98938b1e0616e8428f43f Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 21 Jul 2022 22:11:14 +0000 Subject: [PATCH 408/465] add change note --- ruby/ql/src/change-notes/2022-07-21-check-http-verb.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ruby/ql/src/change-notes/2022-07-21-check-http-verb.md diff --git a/ruby/ql/src/change-notes/2022-07-21-check-http-verb.md b/ruby/ql/src/change-notes/2022-07-21-check-http-verb.md new file mode 100644 index 00000000000..3d1a978953d --- /dev/null +++ b/ruby/ql/src/change-notes/2022-07-21-check-http-verb.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, rb/manually-checking-http-verb, to detect cases when the HTTP verb for an incoming request is checked and then used as part of control flow. \ No newline at end of file From 1842bde879caddebd17a3498eca3e5b33f70107d Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Thu, 21 Jul 2022 22:13:53 +0000 Subject: [PATCH 409/465] add change note --- ruby/ql/src/change-notes/2022-07-21-weak-params.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ruby/ql/src/change-notes/2022-07-21-weak-params.md diff --git a/ruby/ql/src/change-notes/2022-07-21-weak-params.md b/ruby/ql/src/change-notes/2022-07-21-weak-params.md new file mode 100644 index 00000000000..c00926492af --- /dev/null +++ b/ruby/ql/src/change-notes/2022-07-21-weak-params.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, rb/weak-params, to detect cases when the rails strong parameters pattern isn't followed and the values flow into persistent store writes \ No newline at end of file From 7e67338fb5bdf10da2b088227d7c241e774d8a8e Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 22 Jul 2022 13:34:11 +0200 Subject: [PATCH 410/465] Update swift/extractor/infra/SwiftDispatcher.h Co-authored-by: Jeroen Ketema <93738568+jketema@users.noreply.github.com> --- swift/extractor/infra/SwiftDispatcher.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index d3490b56b9f..4b604f4e00a 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -265,7 +265,7 @@ class SwiftDispatcher { bool fetchLabelFromUnionCase(const llvm::PointerUnion u, TrapLabel& output) { // we rely on the fact that when we extract `ASTNode` instances (which only happens // on `BraceStmt` elements), we cannot encounter a standalone `TypeRepr` there, so we skip - // this case, which would be problematic as we would not be able to provide the corresponding + // this case; extracting `TypeRepr`s here would be problematic as we would not be able to provide the corresponding // type if constexpr (!std::is_same_v) { if (auto e = u.template dyn_cast()) { From d44bf326f0db8e26df38c7f63024f4fb056d8720 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Fri, 22 Jul 2022 13:36:22 +0200 Subject: [PATCH 411/465] Update ruby/extractor/src/main.rs Co-authored-by: Nick Rolfe --- ruby/extractor/src/main.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/ruby/extractor/src/main.rs b/ruby/extractor/src/main.rs index a3ed7ed7933..ca1039e4e0d 100644 --- a/ruby/extractor/src/main.rs +++ b/ruby/extractor/src/main.rs @@ -48,17 +48,13 @@ lazy_static! { } fn encoding_from_name(encoding_name: &str) -> Option<&(dyn encoding::Encoding + Send + Sync)> { - match encoding::label::encoding_from_whatwg_label(&encoding_name) { - Some(e) => return Some(e), - None => { - if let Some(cap) = CP_NUMBER.captures(&encoding_name) { - return encoding::label::encoding_from_windows_code_page( - str::parse(cap.get(1).unwrap().as_str()).unwrap(), - ); - } else { - return None; - } - } + match encoding::label::encoding_from_whatwg_label(encoding_name) { + s @ Some(_) => s, + None => CP_NUMBER.captures(encoding_name).and_then(|cap| { + encoding::label::encoding_from_windows_code_page( + str::parse(cap.get(1).unwrap().as_str()).unwrap(), + ) + }), } } From 77401ded4ec353c556e2f25a124fae42aebab3f7 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 22 Jul 2022 13:54:32 +0200 Subject: [PATCH 412/465] Swift: reflow comment --- swift/extractor/infra/SwiftDispatcher.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index 4b604f4e00a..bfcefb41970 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -265,8 +265,8 @@ class SwiftDispatcher { bool fetchLabelFromUnionCase(const llvm::PointerUnion u, TrapLabel& output) { // we rely on the fact that when we extract `ASTNode` instances (which only happens // on `BraceStmt` elements), we cannot encounter a standalone `TypeRepr` there, so we skip - // this case; extracting `TypeRepr`s here would be problematic as we would not be able to provide the corresponding - // type + // this case; extracting `TypeRepr`s here would be problematic as we would not be able to + // provide the corresponding type if constexpr (!std::is_same_v) { if (auto e = u.template dyn_cast()) { output = fetchLabel(e); From 4767d5a1ba544dcd8a60e6372d545930e5096fa1 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Fri, 22 Jul 2022 15:37:53 +0100 Subject: [PATCH 413/465] Ruby/QL: speed up trap writing by putting BufWriter in front of GzEncoder --- ql/extractor/src/trap.rs | 11 +++++++---- ruby/extractor/src/trap.rs | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/ql/extractor/src/trap.rs b/ql/extractor/src/trap.rs index d64c520c4cc..35a9b69f255 100644 --- a/ql/extractor/src/trap.rs +++ b/ql/extractor/src/trap.rs @@ -61,12 +61,15 @@ impl Writer { pub fn write_to_file(&self, path: &Path, compression: Compression) -> std::io::Result<()> { let trap_file = std::fs::File::create(path)?; - let mut trap_file = BufWriter::new(trap_file); match compression { - Compression::None => self.write_trap_entries(&mut trap_file), + Compression::None => { + let mut trap_file = BufWriter::new(trap_file); + self.write_trap_entries(&mut trap_file) + } Compression::Gzip => { - let mut compressed_writer = GzEncoder::new(trap_file, flate2::Compression::fast()); - self.write_trap_entries(&mut compressed_writer) + let trap_file = GzEncoder::new(trap_file, flate2::Compression::fast()); + let mut trap_file = BufWriter::new(trap_file); + self.write_trap_entries(&mut trap_file) } } } diff --git a/ruby/extractor/src/trap.rs b/ruby/extractor/src/trap.rs index d64c520c4cc..35a9b69f255 100644 --- a/ruby/extractor/src/trap.rs +++ b/ruby/extractor/src/trap.rs @@ -61,12 +61,15 @@ impl Writer { pub fn write_to_file(&self, path: &Path, compression: Compression) -> std::io::Result<()> { let trap_file = std::fs::File::create(path)?; - let mut trap_file = BufWriter::new(trap_file); match compression { - Compression::None => self.write_trap_entries(&mut trap_file), + Compression::None => { + let mut trap_file = BufWriter::new(trap_file); + self.write_trap_entries(&mut trap_file) + } Compression::Gzip => { - let mut compressed_writer = GzEncoder::new(trap_file, flate2::Compression::fast()); - self.write_trap_entries(&mut compressed_writer) + let trap_file = GzEncoder::new(trap_file, flate2::Compression::fast()); + let mut trap_file = BufWriter::new(trap_file); + self.write_trap_entries(&mut trap_file) } } } From a9d95a94188e0f8e626f47e5cc2c63e5cd55b779 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 28 Jun 2022 16:37:11 +0200 Subject: [PATCH 414/465] C++: Remove `pragma[noinline]` from `ResolveGlobalVariable.ql` --- cpp/ql/lib/semmle/code/cpp/internal/ResolveGlobalVariable.qll | 3 --- 1 file changed, 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/internal/ResolveGlobalVariable.qll b/cpp/ql/lib/semmle/code/cpp/internal/ResolveGlobalVariable.qll index 219d45e2991..c11e1457dae 100644 --- a/cpp/ql/lib/semmle/code/cpp/internal/ResolveGlobalVariable.qll +++ b/cpp/ql/lib/semmle/code/cpp/internal/ResolveGlobalVariable.qll @@ -2,13 +2,11 @@ private predicate hasDefinition(@globalvariable g) { exists(@var_decl vd | var_decls(vd, g, _, _, _) | var_def(vd)) } -pragma[noinline] private predicate onlyOneCompleteGlobalVariableExistsWithMangledName(@mangledname name) { strictcount(@globalvariable g | hasDefinition(g) and mangled_name(g, name)) = 1 } /** Holds if `g` is a unique global variable with a definition named `name`. */ -pragma[noinline] private predicate isGlobalWithMangledNameAndWithDefinition(@mangledname name, @globalvariable g) { hasDefinition(g) and mangled_name(g, name) and @@ -16,7 +14,6 @@ private predicate isGlobalWithMangledNameAndWithDefinition(@mangledname name, @g } /** Holds if `g` is a global variable without a definition named `name`. */ -pragma[noinline] private predicate isGlobalWithMangledNameAndWithoutDefinition(@mangledname name, @globalvariable g) { not hasDefinition(g) and mangled_name(g, name) From 2c095cf16631aa5f93ec1b4eb035920a665efab5 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Fri, 22 Jul 2022 13:51:38 -0400 Subject: [PATCH 415/465] Update ruby/ql/src/change-notes/2022-07-21-weak-params.md Co-authored-by: Harry Maclean --- ruby/ql/src/change-notes/2022-07-21-weak-params.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/src/change-notes/2022-07-21-weak-params.md b/ruby/ql/src/change-notes/2022-07-21-weak-params.md index c00926492af..08b8f153989 100644 --- a/ruby/ql/src/change-notes/2022-07-21-weak-params.md +++ b/ruby/ql/src/change-notes/2022-07-21-weak-params.md @@ -1,4 +1,4 @@ --- category: newQuery --- -* Added a new query, rb/weak-params, to detect cases when the rails strong parameters pattern isn't followed and the values flow into persistent store writes \ No newline at end of file +* Added a new experimental query, `rb/weak-params`, to detect cases when the rails strong parameters pattern isn't followed and values flow into persistent store writes. \ No newline at end of file From c2710fb038003a1c29b28ba941ff0367cf42f39c Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Fri, 22 Jul 2022 13:52:00 -0400 Subject: [PATCH 416/465] Update ruby/ql/src/change-notes/2022-07-21-check-http-verb.md Co-authored-by: Harry Maclean --- ruby/ql/src/change-notes/2022-07-21-check-http-verb.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/src/change-notes/2022-07-21-check-http-verb.md b/ruby/ql/src/change-notes/2022-07-21-check-http-verb.md index 3d1a978953d..4a670ba1092 100644 --- a/ruby/ql/src/change-notes/2022-07-21-check-http-verb.md +++ b/ruby/ql/src/change-notes/2022-07-21-check-http-verb.md @@ -1,4 +1,4 @@ --- category: newQuery --- -* Added a new query, rb/manually-checking-http-verb, to detect cases when the HTTP verb for an incoming request is checked and then used as part of control flow. \ No newline at end of file +* Added a new experimental query, `rb/manually-checking-http-verb`, to detect cases when the HTTP verb for an incoming request is checked and then used as part of control flow. \ No newline at end of file From f39ca1aad227487a6f1f2d107e634d3515c75650 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Fri, 22 Jul 2022 18:36:25 +0000 Subject: [PATCH 417/465] correct cwe tagged --- ruby/ql/src/experimental/weak-params/WeakParams.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql index 8789018e2cc..e2a441fc7c9 100644 --- a/ruby/ql/src/experimental/weak-params/WeakParams.ql +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -7,7 +7,7 @@ * @precision medium * @id rb/weak-params * @tags security - * external/cwe/cwe-223 + * external/cwe/cwe-352 */ import ruby From 0c0ba925a7a28d6e76677fc76b915238300d4820 Mon Sep 17 00:00:00 2001 From: thiggy1342 Date: Fri, 22 Jul 2022 18:44:03 +0000 Subject: [PATCH 418/465] this one should have no tag --- ruby/ql/src/experimental/weak-params/WeakParams.ql | 1 - 1 file changed, 1 deletion(-) diff --git a/ruby/ql/src/experimental/weak-params/WeakParams.ql b/ruby/ql/src/experimental/weak-params/WeakParams.ql index e2a441fc7c9..0c6d9db5644 100644 --- a/ruby/ql/src/experimental/weak-params/WeakParams.ql +++ b/ruby/ql/src/experimental/weak-params/WeakParams.ql @@ -7,7 +7,6 @@ * @precision medium * @id rb/weak-params * @tags security - * external/cwe/cwe-352 */ import ruby From 715b0b3fb89030d83a1e18ec1e6c144727281dfe Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Mon, 25 Jul 2022 15:17:14 +0100 Subject: [PATCH 419/465] Accept test changes --- java/ql/test/kotlin/library-tests/reflection/PrintAst.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected b/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected index dd47be234c3..b1da7cdcee2 100644 --- a/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected +++ b/java/ql/test/kotlin/library-tests/reflection/PrintAst.expected @@ -8,7 +8,7 @@ reflection.kt: # 46| 0: [TypeAccess] String # 47| 5: [BlockStmt] { ... } # 47| 0: [ReturnStmt] return ... -# 47| 0: [MethodAccess] get(...) +# 47| 0: [MethodAccess] charAt(...) # 47| -1: [ExtensionReceiverAccess] this # 47| 0: [SubExpr] ... - ... # 47| 0: [MethodAccess] length(...) From 95db81658b4aa3176b5edb3946a76788fdaee1ac Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 26 Jul 2022 10:42:24 +0200 Subject: [PATCH 420/465] Add CSV models for java.util.Scanner --- .../java/dataflow/internal/ContainerFlow.qll | 6 + java/ql/test/library-tests/scanner/Test.java | 183 ++++++++++++++++++ .../test/library-tests/scanner/test.expected | 0 java/ql/test/library-tests/scanner/test.ql | 2 + 4 files changed, 191 insertions(+) create mode 100644 java/ql/test/library-tests/scanner/Test.java create mode 100644 java/ql/test/library-tests/scanner/test.expected create mode 100644 java/ql/test/library-tests/scanner/test.ql diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll index e9c457fc801..3acb3291911 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll @@ -244,8 +244,14 @@ private class ContainerFlowSummaries extends SummaryModelCsv { "java.util;Properties;true;getProperty;(String);;Argument[-1].MapValue;ReturnValue;value;manual", "java.util;Properties;true;getProperty;(String,String);;Argument[-1].MapValue;ReturnValue;value;manual", "java.util;Properties;true;getProperty;(String,String);;Argument[1];ReturnValue;value;manual", + "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual", "java.util;Scanner;true;next;(Pattern);;Argument[-1];ReturnValue;taint;manual", "java.util;Scanner;true;next;(String);;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;reset;;;Argument[-1];ReturnValue;value;manual", + "java.util;Scanner;true;skip;;;Argument[-1];ReturnValue;value;manual", + "java.util;Scanner;true;useDelimiter;;;Argument[-1];ReturnValue;value;manual", + "java.util;Scanner;true;useLocale;;;Argument[-1];ReturnValue;value;manual", + "java.util;Scanner;true;useRadix;;;Argument[-1];ReturnValue;value;manual", "java.util;SortedMap;true;headMap;(Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", "java.util;SortedMap;true;headMap;(Object);;Argument[-1].MapValue;ReturnValue.MapValue;value;manual", "java.util;SortedMap;true;subMap;(Object,Object);;Argument[-1].MapKey;ReturnValue.MapKey;value;manual", diff --git a/java/ql/test/library-tests/scanner/Test.java b/java/ql/test/library-tests/scanner/Test.java new file mode 100644 index 00000000000..d5bd778fe1b --- /dev/null +++ b/java/ql/test/library-tests/scanner/Test.java @@ -0,0 +1,183 @@ +package generatedtest; + +import java.io.File; +import java.io.InputStream; +import java.nio.channels.ReadableByteChannel; +import java.nio.charset.Charset; +import java.nio.file.Path; +import java.util.Scanner; +import java.util.regex.Pattern; + +// Test case generated by GenerateFlowTestCase.ql +public class Test { + + Object source() { return null; } + void sink(Object o) { } + + public void test() throws Exception { + + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + File in = (File)source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + File in = (File)source(); + out = new Scanner(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + File in = (File)source(); + out = new Scanner(in, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + InputStream in = (InputStream)source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + InputStream in = (InputStream)source(); + out = new Scanner(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + InputStream in = (InputStream)source(); + out = new Scanner(in, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + Path in = (Path)source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + Path in = (Path)source(); + out = new Scanner(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + Path in = (Path)source(); + out = new Scanner(in, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + Readable in = (Readable)source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + ReadableByteChannel in = (ReadableByteChannel)source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + ReadableByteChannel in = (ReadableByteChannel)source(); + out = new Scanner(in, (Charset)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + ReadableByteChannel in = (ReadableByteChannel)source(); + out = new Scanner(in, (String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" + Scanner out = null; + String in = (String)source(); + out = new Scanner(in); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;next;(Pattern);;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner)source(); + out = in.next((Pattern)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;next;(String);;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner)source(); + out = in.next((String)null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;reset;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.reset(); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;skip;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.skip((Pattern)null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;skip;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.skip((String)null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;useDelimiter;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.useDelimiter((Pattern)null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;useDelimiter;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.useDelimiter((String)null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;useLocale;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.useLocale(null); + sink(out); // $ hasValueFlow + } + { + // "java.util;Scanner;true;useRadix;;;Argument[-1];ReturnValue;value;manual" + Scanner out = null; + Scanner in = (Scanner)source(); + out = in.useRadix(0); + sink(out); // $ hasValueFlow + } + + } + +} \ No newline at end of file diff --git a/java/ql/test/library-tests/scanner/test.expected b/java/ql/test/library-tests/scanner/test.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/scanner/test.ql b/java/ql/test/library-tests/scanner/test.ql new file mode 100644 index 00000000000..5d91e4e8e26 --- /dev/null +++ b/java/ql/test/library-tests/scanner/test.ql @@ -0,0 +1,2 @@ +import java +import TestUtilities.InlineFlowTest From c56e0f7c0d55e5e04cd87cd4eb56c2118db15693 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 26 Jul 2022 10:50:34 +0200 Subject: [PATCH 421/465] Add change note --- java/ql/lib/change-notes/2022-07-26-scanner-models.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 java/ql/lib/change-notes/2022-07-26-scanner-models.md diff --git a/java/ql/lib/change-notes/2022-07-26-scanner-models.md b/java/ql/lib/change-notes/2022-07-26-scanner-models.md new file mode 100644 index 00000000000..6a78982d639 --- /dev/null +++ b/java/ql/lib/change-notes/2022-07-26-scanner-models.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added data flow models for `java.util.Scanner`. \ No newline at end of file From 33f5620782479ea2f449e44faa8857e6eaa59bc5 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Tue, 26 Jul 2022 11:06:11 +0200 Subject: [PATCH 422/465] Add more models --- .../java/dataflow/internal/ContainerFlow.qll | 16 +- java/ql/test/library-tests/scanner/Test.java | 229 ++++++++++++++---- 2 files changed, 201 insertions(+), 44 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll index 3acb3291911..6c4a369527c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll @@ -245,8 +245,20 @@ private class ContainerFlowSummaries extends SummaryModelCsv { "java.util;Properties;true;getProperty;(String,String);;Argument[-1].MapValue;ReturnValue;value;manual", "java.util;Properties;true;getProperty;(String,String);;Argument[1];ReturnValue;value;manual", "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual", - "java.util;Scanner;true;next;(Pattern);;Argument[-1];ReturnValue;taint;manual", - "java.util;Scanner;true;next;(String);;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;findInLine;;;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;next;;;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;nextBigDecimal;;;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;nextBigInteger;;;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;nextBoolean;;;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;nextByte;;;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;nextDouble;;;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;nextFloat;;;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;nextInt;;;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;nextLine;;;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;nextLong;;;Argument[-1];ReturnValue;taint;manual", + "java.util;Scanner;true;nextShort;;;Argument[-1];ReturnValue;taint;manual", "java.util;Scanner;true;reset;;;Argument[-1];ReturnValue;value;manual", "java.util;Scanner;true;skip;;;Argument[-1];ReturnValue;value;manual", "java.util;Scanner;true;useDelimiter;;;Argument[-1];ReturnValue;value;manual", diff --git a/java/ql/test/library-tests/scanner/Test.java b/java/ql/test/library-tests/scanner/Test.java index d5bd778fe1b..05f5b497215 100644 --- a/java/ql/test/library-tests/scanner/Test.java +++ b/java/ql/test/library-tests/scanner/Test.java @@ -2,6 +2,8 @@ package generatedtest; import java.io.File; import java.io.InputStream; +import java.math.BigDecimal; +import java.math.BigInteger; import java.nio.channels.ReadableByteChannel; import java.nio.charset.Charset; import java.nio.file.Path; @@ -11,173 +13,316 @@ import java.util.regex.Pattern; // Test case generated by GenerateFlowTestCase.ql public class Test { - Object source() { return null; } - void sink(Object o) { } + Object source() { + return null; + } + + void sink(Object o) {} public void test() throws Exception { { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - File in = (File)source(); + File in = (File) source(); out = new Scanner(in); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - File in = (File)source(); - out = new Scanner(in, (Charset)null); + File in = (File) source(); + out = new Scanner(in, (Charset) null); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - File in = (File)source(); - out = new Scanner(in, (String)null); + File in = (File) source(); + out = new Scanner(in, (String) null); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - InputStream in = (InputStream)source(); + InputStream in = (InputStream) source(); out = new Scanner(in); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - InputStream in = (InputStream)source(); - out = new Scanner(in, (Charset)null); + InputStream in = (InputStream) source(); + out = new Scanner(in, (Charset) null); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - InputStream in = (InputStream)source(); - out = new Scanner(in, (String)null); + InputStream in = (InputStream) source(); + out = new Scanner(in, (String) null); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - Path in = (Path)source(); + Path in = (Path) source(); out = new Scanner(in); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - Path in = (Path)source(); - out = new Scanner(in, (Charset)null); + Path in = (Path) source(); + out = new Scanner(in, (Charset) null); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - Path in = (Path)source(); - out = new Scanner(in, (String)null); + Path in = (Path) source(); + out = new Scanner(in, (String) null); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - Readable in = (Readable)source(); + Readable in = (Readable) source(); out = new Scanner(in); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - ReadableByteChannel in = (ReadableByteChannel)source(); + ReadableByteChannel in = (ReadableByteChannel) source(); out = new Scanner(in); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - ReadableByteChannel in = (ReadableByteChannel)source(); - out = new Scanner(in, (Charset)null); + ReadableByteChannel in = (ReadableByteChannel) source(); + out = new Scanner(in, (Charset) null); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - ReadableByteChannel in = (ReadableByteChannel)source(); - out = new Scanner(in, (String)null); + ReadableByteChannel in = (ReadableByteChannel) source(); + out = new Scanner(in, (String) null); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;Scanner;;;Argument[0];Argument[-1];taint;manual" Scanner out = null; - String in = (String)source(); + String in = (String) source(); out = new Scanner(in); sink(out); // $ hasTaintFlow } { - // "java.util;Scanner;true;next;(Pattern);;Argument[-1];ReturnValue;taint;manual" + // "java.util;Scanner;true;findInLine;;;Argument[-1];ReturnValue;taint;manual" String out = null; - Scanner in = (Scanner)source(); - out = in.next((Pattern)null); + Scanner in = (Scanner) source(); + out = in.findInLine((Pattern) null); sink(out); // $ hasTaintFlow } { - // "java.util;Scanner;true;next;(String);;Argument[-1];ReturnValue;taint;manual" + // "java.util;Scanner;true;findInLine;;;Argument[-1];ReturnValue;taint;manual" String out = null; - Scanner in = (Scanner)source(); - out = in.next((String)null); + Scanner in = (Scanner) source(); + out = in.findInLine((String) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.findWithinHorizon((Pattern) null, 0); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;findWithinHorizon;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.findWithinHorizon((String) null, 0); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;next;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.next((Pattern) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;next;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.next((String) null); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;next;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.next(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextBigDecimal;;;Argument[-1];ReturnValue;taint;manual" + BigDecimal out = null; + Scanner in = (Scanner) source(); + out = in.nextBigDecimal(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextBigInteger;;;Argument[-1];ReturnValue;taint;manual" + BigInteger out = null; + Scanner in = (Scanner) source(); + out = in.nextBigInteger(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextBigInteger;;;Argument[-1];ReturnValue;taint;manual" + BigInteger out = null; + Scanner in = (Scanner) source(); + out = in.nextBigInteger(0); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextBoolean;;;Argument[-1];ReturnValue;taint;manual" + boolean out = false; + Scanner in = (Scanner) source(); + out = in.nextBoolean(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextByte;;;Argument[-1];ReturnValue;taint;manual" + byte out = 0; + Scanner in = (Scanner) source(); + out = in.nextByte(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextByte;;;Argument[-1];ReturnValue;taint;manual" + byte out = 0; + Scanner in = (Scanner) source(); + out = in.nextByte(0); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextDouble;;;Argument[-1];ReturnValue;taint;manual" + double out = 0; + Scanner in = (Scanner) source(); + out = in.nextDouble(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextFloat;;;Argument[-1];ReturnValue;taint;manual" + float out = 0; + Scanner in = (Scanner) source(); + out = in.nextFloat(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextInt;;;Argument[-1];ReturnValue;taint;manual" + int out = 0; + Scanner in = (Scanner) source(); + out = in.nextInt(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextInt;;;Argument[-1];ReturnValue;taint;manual" + int out = 0; + Scanner in = (Scanner) source(); + out = in.nextInt(0); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextLine;;;Argument[-1];ReturnValue;taint;manual" + String out = null; + Scanner in = (Scanner) source(); + out = in.nextLine(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextLong;;;Argument[-1];ReturnValue;taint;manual" + long out = 0; + Scanner in = (Scanner) source(); + out = in.nextLong(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextLong;;;Argument[-1];ReturnValue;taint;manual" + long out = 0; + Scanner in = (Scanner) source(); + out = in.nextLong(0); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextShort;;;Argument[-1];ReturnValue;taint;manual" + short out = 0; + Scanner in = (Scanner) source(); + out = in.nextShort(); + sink(out); // $ hasTaintFlow + } + { + // "java.util;Scanner;true;nextShort;;;Argument[-1];ReturnValue;taint;manual" + short out = 0; + Scanner in = (Scanner) source(); + out = in.nextShort(0); sink(out); // $ hasTaintFlow } { // "java.util;Scanner;true;reset;;;Argument[-1];ReturnValue;value;manual" Scanner out = null; - Scanner in = (Scanner)source(); + Scanner in = (Scanner) source(); out = in.reset(); sink(out); // $ hasValueFlow } { // "java.util;Scanner;true;skip;;;Argument[-1];ReturnValue;value;manual" Scanner out = null; - Scanner in = (Scanner)source(); - out = in.skip((Pattern)null); + Scanner in = (Scanner) source(); + out = in.skip((Pattern) null); sink(out); // $ hasValueFlow } { // "java.util;Scanner;true;skip;;;Argument[-1];ReturnValue;value;manual" Scanner out = null; - Scanner in = (Scanner)source(); - out = in.skip((String)null); + Scanner in = (Scanner) source(); + out = in.skip((String) null); sink(out); // $ hasValueFlow } { // "java.util;Scanner;true;useDelimiter;;;Argument[-1];ReturnValue;value;manual" Scanner out = null; - Scanner in = (Scanner)source(); - out = in.useDelimiter((Pattern)null); + Scanner in = (Scanner) source(); + out = in.useDelimiter((Pattern) null); sink(out); // $ hasValueFlow } { // "java.util;Scanner;true;useDelimiter;;;Argument[-1];ReturnValue;value;manual" Scanner out = null; - Scanner in = (Scanner)source(); - out = in.useDelimiter((String)null); + Scanner in = (Scanner) source(); + out = in.useDelimiter((String) null); sink(out); // $ hasValueFlow } { // "java.util;Scanner;true;useLocale;;;Argument[-1];ReturnValue;value;manual" Scanner out = null; - Scanner in = (Scanner)source(); + Scanner in = (Scanner) source(); out = in.useLocale(null); sink(out); // $ hasValueFlow } { // "java.util;Scanner;true;useRadix;;;Argument[-1];ReturnValue;value;manual" Scanner out = null; - Scanner in = (Scanner)source(); + Scanner in = (Scanner) source(); out = in.useRadix(0); sink(out); // $ hasValueFlow } } -} \ No newline at end of file +} From 5086841b46ca2aa3dd2076b85da4f190661beb5a Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 26 Jul 2022 17:03:46 +0100 Subject: [PATCH 423/465] Kotlin: implement super-method calls If we only look at the dispatch receiver, these show up like `this` references rather than `super` references, preventing flow through super-calls. The super-interface case requires properly noting that interface methods with a body get a `default` modifier in order to avoid QL discarding the method as a possible callee. --- .../src/main/kotlin/KotlinFileExtractor.kt | 36 ++++++++++++++----- .../super-method-calls/test.expected | 2 ++ .../library-tests/super-method-calls/test.kt | 36 +++++++++++++++++++ .../library-tests/super-method-calls/test.ql | 18 ++++++++++ 4 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 java/ql/test/kotlin/library-tests/super-method-calls/test.expected create mode 100644 java/ql/test/kotlin/library-tests/super-method-calls/test.kt create mode 100644 java/ql/test/kotlin/library-tests/super-method-calls/test.ql diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 78a81fb0715..4100594ad35 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -888,6 +888,10 @@ open class KotlinFileExtractor( if (shortName.nameInDB != shortName.kotlinName) { tw.writeKtFunctionOriginalNames(methodId, shortName.kotlinName) } + + if (f.hasInterfaceParent() && f.body != null) { + addModifiers(id, "default") // The actual output class file may or may not have this modifier, depending on the -Xjvm-default setting. + } } tw.writeHasLocation(id, locId) @@ -1386,7 +1390,8 @@ open class KotlinFileExtractor( dispatchReceiver: IrExpression?, extensionReceiver: IrExpression?, typeArguments: List = listOf(), - extractClassTypeArguments: Boolean = false) { + extractClassTypeArguments: Boolean = false, + superQualifierSymbol: IrClassSymbol? = null) { val locId = tw.getLocation(callsite) @@ -1404,7 +1409,8 @@ open class KotlinFileExtractor( dispatchReceiver?.let { { callId -> extractExpressionExpr(dispatchReceiver, enclosingCallable, callId, -1, enclosingStmt) } }, extensionReceiver?.let { { argParent -> extractExpressionExpr(extensionReceiver, enclosingCallable, argParent, 0, enclosingStmt) } }, typeArguments, - extractClassTypeArguments + extractClassTypeArguments, + superQualifierSymbol ) } @@ -1424,7 +1430,8 @@ open class KotlinFileExtractor( extractDispatchReceiver: ((Label) -> Unit)?, extractExtensionReceiver: ((Label) -> Unit)?, typeArguments: List = listOf(), - extractClassTypeArguments: Boolean = false) { + extractClassTypeArguments: Boolean = false, + superQualifierSymbol: IrClassSymbol? = null) { val callTarget = syntacticCallTarget.target.realOverrideTarget val id = tw.getFreshIdLabel() @@ -1483,6 +1490,8 @@ open class KotlinFileExtractor( if (callTarget.shouldExtractAsStatic) { extractStaticTypeAccessQualifier(callTarget, id, locId, enclosingCallable, enclosingStmt) + } else if (superQualifierSymbol != null) { + extractSuperAccess(superQualifierSymbol.typeWith(), enclosingCallable, id, -1, enclosingStmt, locId) } else if (extractDispatchReceiver != null) { extractDispatchReceiver(id) } @@ -1744,7 +1753,7 @@ open class KotlinFileExtractor( else listOf() - extractRawMethodAccess(syntacticCallTarget, c, callable, parent, idx, enclosingStmt, (0 until c.valueArgumentsCount).map { c.getValueArgument(it) }, c.dispatchReceiver, c.extensionReceiver, typeArgs, extractClassTypeArguments) + extractRawMethodAccess(syntacticCallTarget, c, callable, parent, idx, enclosingStmt, (0 until c.valueArgumentsCount).map { c.getValueArgument(it) }, c.dispatchReceiver, c.extensionReceiver, typeArgs, extractClassTypeArguments, c.superQualifierSymbol) } fun extractSpecialEnumFunction(fnName: String){ @@ -3066,6 +3075,17 @@ open class KotlinFileExtractor( } } + private fun extractSuperAccess(irType: IrType, callable: Label, parent: Label, idx: Int, enclosingStmt: Label, locId: Label) = + tw.getFreshIdLabel().also { + val type = useType(irType) + tw.writeExprs_superaccess(it, type.javaResult.id, parent, idx) + tw.writeExprsKotlinType(it, type.kotlinResult.id) + tw.writeHasLocation(it, locId) + tw.writeCallableEnclosingExpr(it, callable) + tw.writeStatementEnclosingExpr(it, enclosingStmt) + extractTypeAccessRecursive(irType, locId, it, 0) + } + private fun extractThisAccess(e: IrGetValue, exprParent: ExprParent, callable: Label) { val containingDeclaration = declarationStack.peek() val locId = tw.getLocation(e) @@ -4020,7 +4040,7 @@ open class KotlinFileExtractor( /** * Extracts a single wildcard type access expression with no enclosing callable and statement. */ - private fun extractWildcardTypeAccess(type: TypeResults, location: Label, parent: Label, idx: Int): Label { + private fun extractWildcardTypeAccess(type: TypeResults, location: Label, parent: Label, idx: Int): Label { val id = tw.getFreshIdLabel() tw.writeExprs_wildcardtypeaccess(id, type.javaResult.id, parent, idx) tw.writeExprsKotlinType(id, type.kotlinResult.id) @@ -4031,7 +4051,7 @@ open class KotlinFileExtractor( /** * Extracts a single type access expression with no enclosing callable and statement. */ - private fun extractTypeAccess(type: TypeResults, location: Label, parent: Label, idx: Int): Label { + private fun extractTypeAccess(type: TypeResults, location: Label, parent: Label, idx: Int): Label { // TODO: elementForLocation allows us to give some sort of // location, but a proper location for the type access will // require upstream changes @@ -4057,7 +4077,7 @@ open class KotlinFileExtractor( * `extractTypeAccessRecursive` if the argument is invariant. * No enclosing callable and statement is extracted, this is useful for type access extraction in field declarations. */ - private fun extractWildcardTypeAccessRecursive(t: IrTypeArgument, location: Label, parent: Label, idx: Int) { + private fun extractWildcardTypeAccessRecursive(t: IrTypeArgument, location: Label, parent: Label, idx: Int) { val typeLabels by lazy { TypeResults(getTypeArgumentLabel(t), TypeResult(fakeKotlinType(), "TODO", "TODO")) } when (t) { is IrStarProjection -> extractWildcardTypeAccess(typeLabels, location, parent, idx) @@ -4077,7 +4097,7 @@ open class KotlinFileExtractor( * Extracts a type access expression and its child type access expressions in case of a generic type. Nested generics are also handled. * No enclosing callable and statement is extracted, this is useful for type access extraction in field declarations. */ - private fun extractTypeAccessRecursive(t: IrType, location: Label, parent: Label, idx: Int, typeContext: TypeContext = TypeContext.OTHER): Label { + private fun extractTypeAccessRecursive(t: IrType, location: Label, parent: Label, idx: Int, typeContext: TypeContext = TypeContext.OTHER): Label { val typeAccessId = extractTypeAccess(useType(t, typeContext), location, parent, idx) if (t is IrSimpleType) { t.arguments.forEachIndexed { argIdx, arg -> diff --git a/java/ql/test/kotlin/library-tests/super-method-calls/test.expected b/java/ql/test/kotlin/library-tests/super-method-calls/test.expected new file mode 100644 index 00000000000..841eb6298c7 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/super-method-calls/test.expected @@ -0,0 +1,2 @@ +| test.kt:31:17:31:24 | source(...) | test.kt:31:15:31:25 | f(...) | +| test.kt:32:17:32:24 | source(...) | test.kt:32:15:32:25 | g(...) | diff --git a/java/ql/test/kotlin/library-tests/super-method-calls/test.kt b/java/ql/test/kotlin/library-tests/super-method-calls/test.kt new file mode 100644 index 00000000000..7b3e90d7359 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/super-method-calls/test.kt @@ -0,0 +1,36 @@ +open class A { + + open fun f(x: String) = x + +} + +interface B { + + fun g(x: String) = x + +} + +interface C { + + fun g(x: String) = x + +} + +class User : A(), B, C { + + override fun f(x: String) = super.f(x) + + override fun g(x: String) = super.g(x) + + fun source() = "tainted" + + fun sink(s: String) { } + + fun test() { + + sink(this.f(source())) + sink(this.g(source())) + + } + +} diff --git a/java/ql/test/kotlin/library-tests/super-method-calls/test.ql b/java/ql/test/kotlin/library-tests/super-method-calls/test.ql new file mode 100644 index 00000000000..9a628624c91 --- /dev/null +++ b/java/ql/test/kotlin/library-tests/super-method-calls/test.ql @@ -0,0 +1,18 @@ +import java +import semmle.code.java.dataflow.DataFlow + +class Config extends DataFlow::Configuration { + Config() { this = "abc" } + + override predicate isSource(DataFlow::Node n) { + n.asExpr().(MethodAccess).getMethod().getName() = "source" + } + + override predicate isSink(DataFlow::Node n) { + n.asExpr().(Argument).getCall().getCallee().getName() = "sink" + } +} + +from Config c, DataFlow::Node n1, DataFlow::Node n2 +where c.hasFlow(n1, n2) +select n1, n2 From 30accecd8a4db51a368bb4870e16989ba8c5c8e9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 27 Jul 2022 00:19:16 +0000 Subject: [PATCH 424/465] Add changed framework coverage reports --- java/documentation/library-coverage/coverage.csv | 2 +- java/documentation/library-coverage/coverage.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index ce777afae1d..598035e03c3 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -36,7 +36,7 @@ java.lang,13,,58,,,,,,,,,,,8,,,,,4,,,1,,,,,,,,,,,,,,,46,12 java.net,10,3,7,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,3,7, java.nio,15,,6,,13,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,6, java.sql,11,,,,,,,,,4,,,,,,,,,,,,,,,,7,,,,,,,,,,,, -java.util,44,,441,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,24,417 +java.util,44,,458,,,,,,,,,,,34,,,,,,5,2,,1,2,,,,,,,,,,,,,36,422 javax.faces.context,2,7,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,7,, javax.jms,,9,57,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,57, javax.json,,,123,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,100,23 diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index 3e4ea1201bf..06101b6633d 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -15,9 +15,9 @@ Java framework & library support `Apache HttpComponents `_,"``org.apache.hc.core5.*``, ``org.apache.http``",5,136,28,,,3,,,,25 `Google Guava `_,``com.google.common.*``,,728,39,,6,,,,, `JSON-java `_,``org.json``,,236,,,,,,,, - Java Standard Library,``java.*``,3,552,130,28,,,7,,,10 + Java Standard Library,``java.*``,3,569,130,28,,,7,,,10 Java extensions,"``javax.*``, ``jakarta.*``",63,609,32,,,4,,1,1,2 `Spring `_,``org.springframework.*``,29,476,101,,,,19,14,,29 Others,"``androidx.slice``, ``cn.hutool.core.codec``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.opensymphony.xwork2.ognl``, ``com.rabbitmq.client``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``groovy.lang``, ``groovy.util``, ``jodd.json``, ``kotlin.jvm.internal``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.logging``, ``org.apache.commons.ognl``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.logging.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.hibernate``, ``org.jboss.logging``, ``org.jdbi.v3.core``, ``org.jooq``, ``org.mvel2``, ``org.scijava.log``, ``org.slf4j``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",65,395,932,,,,14,18,,3 - Totals,,217,6413,1474,117,6,10,107,33,1,84 + Totals,,217,6430,1474,117,6,10,107,33,1,84 From cc423af8f1d28ae3cc03751983f7f9a140cf19aa Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 27 Jul 2022 10:20:47 +0200 Subject: [PATCH 425/465] Java: Add support for JUnit5 assertions in the nullness queries. --- java/ql/lib/change-notes/2022-07-27-nullness-junit5.md | 5 +++++ java/ql/lib/semmle/code/java/frameworks/Assertions.qll | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 java/ql/lib/change-notes/2022-07-27-nullness-junit5.md diff --git a/java/ql/lib/change-notes/2022-07-27-nullness-junit5.md b/java/ql/lib/change-notes/2022-07-27-nullness-junit5.md new file mode 100644 index 00000000000..6cfb0949c69 --- /dev/null +++ b/java/ql/lib/change-notes/2022-07-27-nullness-junit5.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* The JUnit5 version of `AssertNotNull` is now recognized, which removes + related false positives in the nullness queries. diff --git a/java/ql/lib/semmle/code/java/frameworks/Assertions.qll b/java/ql/lib/semmle/code/java/frameworks/Assertions.qll index 3c3d090b993..ff95c71b037 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Assertions.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Assertions.qll @@ -2,7 +2,8 @@ * A library providing uniform access to various assertion frameworks. * * Currently supports `org.junit.Assert`, `junit.framework.*`, - * `com.google.common.base.Preconditions`, and `java.util.Objects`. + * `org.junit.jupiter.api.Assertions`, `com.google.common.base.Preconditions`, + * and `java.util.Objects`. */ import java @@ -17,7 +18,11 @@ private newtype AssertKind = private predicate assertionMethod(Method m, AssertKind kind) { exists(RefType junit | m.getDeclaringType() = junit and - (junit.hasQualifiedName("org.junit", "Assert") or junit.hasQualifiedName("junit.framework", _)) + ( + junit.hasQualifiedName("org.junit", "Assert") or + junit.hasQualifiedName("junit.framework", _) or + junit.hasQualifiedName("org.junit.jupiter.api", "Assertions") + ) | m.hasName("assertNotNull") and kind = AssertKindNotNull() or From ebf650c0c0e4f41c86da4ae9860465b7159706bb Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Wed, 27 Jul 2022 14:56:02 +0200 Subject: [PATCH 426/465] Control Flow: add more ordering for edges --- .../csharp/controlflow/internal/ControlFlowGraphImplShared.qll | 2 +- .../ruby/controlflow/internal/ControlFlowGraphImplShared.qll | 2 +- .../swift/controlflow/internal/ControlFlowGraphImplShared.qll | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll index 47fcd24883c..13fb796ca3d 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll @@ -916,7 +916,7 @@ module TestOutput { s order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString(), s.toString() ) ).toString() } diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll index 47fcd24883c..13fb796ca3d 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll @@ -916,7 +916,7 @@ module TestOutput { s order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString(), s.toString() ) ).toString() } diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll index 47fcd24883c..13fb796ca3d 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll @@ -916,7 +916,7 @@ module TestOutput { s order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString(), s.toString() ) ).toString() } From 7ca955a0e6ca6e4903b76f8eb2fcd7cf15de6dca Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Wed, 27 Jul 2022 17:23:10 +0200 Subject: [PATCH 427/465] Add support for XML InlineExpectationsTest --- .../InlineExpectationsTestPrivate.qll | 12 ++++++++++++ java/ql/test/library-tests/xml/Test.java | 3 +++ java/ql/test/library-tests/xml/XMLTest.expected | 0 java/ql/test/library-tests/xml/XMLTest.ql | 17 +++++++++++++++++ java/ql/test/library-tests/xml/test.xml | 4 ++++ 5 files changed, 36 insertions(+) create mode 100644 java/ql/test/library-tests/xml/Test.java create mode 100644 java/ql/test/library-tests/xml/XMLTest.expected create mode 100644 java/ql/test/library-tests/xml/XMLTest.ql create mode 100644 java/ql/test/library-tests/xml/test.xml diff --git a/java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll b/java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll index 5233f92f406..7e4a1b65f4c 100644 --- a/java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll +++ b/java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll @@ -20,3 +20,15 @@ private class KtExpectationComment extends KtComment, ExpectationComment { override string getContents() { result = this.getText().suffix(2).trim() } } + +private class XMLExpectationComment extends ExpectationComment instanceof XMLComment { + override string getContents() { result = this.(XMLComment).getText().trim() } + + override Location getLocation() { result = this.(XMLComment).getLocation() } + + override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { + this.(XMLComment).hasLocationInfo(path, sl, sc, el, ec) + } + + override string toString() { result = this.(XMLComment).toString() } +} diff --git a/java/ql/test/library-tests/xml/Test.java b/java/ql/test/library-tests/xml/Test.java new file mode 100644 index 00000000000..4566fbca2ad --- /dev/null +++ b/java/ql/test/library-tests/xml/Test.java @@ -0,0 +1,3 @@ +public class Test { + +} diff --git a/java/ql/test/library-tests/xml/XMLTest.expected b/java/ql/test/library-tests/xml/XMLTest.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/java/ql/test/library-tests/xml/XMLTest.ql b/java/ql/test/library-tests/xml/XMLTest.ql new file mode 100644 index 00000000000..e4b8b3a0361 --- /dev/null +++ b/java/ql/test/library-tests/xml/XMLTest.ql @@ -0,0 +1,17 @@ +import semmle.code.xml.XML +import TestUtilities.InlineExpectationsTest + +class XMLTest extends InlineExpectationsTest { + XMLTest() { this = "XMLTest" } + + override string getARelevantTag() { result = "hasXmlResult" } + + override predicate hasActualResult(Location location, string element, string tag, string value) { + tag = "hasXmlResult" and + exists(XMLAttribute a | + a.getLocation() = location and + element = a.toString() and + value = "" + ) + } +} diff --git a/java/ql/test/library-tests/xml/test.xml b/java/ql/test/library-tests/xml/test.xml new file mode 100644 index 00000000000..cd41bd7f36c --- /dev/null +++ b/java/ql/test/library-tests/xml/test.xml @@ -0,0 +1,4 @@ + + + Text + \ No newline at end of file From 9b26921cb67a03a6dd3958e0f42b6941523072c3 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 28 Jul 2022 09:04:12 +0200 Subject: [PATCH 428/465] Control flow: add order disambuigation customization --- .../internal/ControlFlowGraphImplShared.qll | 13 ++++++++++--- .../internal/ControlFlowGraphImplShared.qll | 13 ++++++++++--- .../internal/ControlFlowGraphImplShared.qll | 13 ++++++++++--- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll index 13fb796ca3d..7d0dd10c084 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll @@ -881,7 +881,12 @@ import Cached * graph is restricted to nodes from `RelevantNode`. */ module TestOutput { - abstract class RelevantNode extends Node { } + abstract class RelevantNode extends Node { + /** + * Gets a string used to resolve ties in node and edge ordering. + */ + string getOrderDisambuigation() { result = "" } + } query predicate nodes(RelevantNode n, string attr, string val) { attr = "semmle.order" and @@ -894,7 +899,8 @@ module TestOutput { p order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), p.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), p.toString(), + p.getOrderDisambuigation() ) ).toString() } @@ -916,7 +922,8 @@ module TestOutput { s order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString(), s.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString(), s.toString(), + s.getOrderDisambuigation() ) ).toString() } diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll index 13fb796ca3d..7d0dd10c084 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImplShared.qll @@ -881,7 +881,12 @@ import Cached * graph is restricted to nodes from `RelevantNode`. */ module TestOutput { - abstract class RelevantNode extends Node { } + abstract class RelevantNode extends Node { + /** + * Gets a string used to resolve ties in node and edge ordering. + */ + string getOrderDisambuigation() { result = "" } + } query predicate nodes(RelevantNode n, string attr, string val) { attr = "semmle.order" and @@ -894,7 +899,8 @@ module TestOutput { p order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), p.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), p.toString(), + p.getOrderDisambuigation() ) ).toString() } @@ -916,7 +922,8 @@ module TestOutput { s order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString(), s.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString(), s.toString(), + s.getOrderDisambuigation() ) ).toString() } diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll index 13fb796ca3d..7d0dd10c084 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll +++ b/swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll @@ -881,7 +881,12 @@ import Cached * graph is restricted to nodes from `RelevantNode`. */ module TestOutput { - abstract class RelevantNode extends Node { } + abstract class RelevantNode extends Node { + /** + * Gets a string used to resolve ties in node and edge ordering. + */ + string getOrderDisambuigation() { result = "" } + } query predicate nodes(RelevantNode n, string attr, string val) { attr = "semmle.order" and @@ -894,7 +899,8 @@ module TestOutput { p order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), p.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), p.toString(), + p.getOrderDisambuigation() ) ).toString() } @@ -916,7 +922,8 @@ module TestOutput { s order by l.getFile().getBaseName(), l.getFile().getAbsolutePath(), l.getStartLine(), - l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString(), s.toString() + l.getStartColumn(), l.getEndLine(), l.getEndColumn(), t.toString(), s.toString(), + s.getOrderDisambuigation() ) ).toString() } From ab1370cc8f01b7bedf6bfdbbcb9bb05ef8ca291c Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 28 Jul 2022 11:19:45 +0200 Subject: [PATCH 429/465] Swift: add `--no-cleanup` to integration tests --- swift/integration-tests/create_database_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/integration-tests/create_database_utils.py b/swift/integration-tests/create_database_utils.py index 3f2d11a39f7..38822fd70b4 100644 --- a/swift/integration-tests/create_database_utils.py +++ b/swift/integration-tests/create_database_utils.py @@ -12,7 +12,7 @@ def run_codeql_database_create(cmds, lang, keep_trap=True): codeql_root = pathlib.Path(__file__).parents[2] cmd = [ "codeql", "database", "create", - "-s", ".", "-l", "swift", "--internal-use-lua-tracing", f"--search-path={codeql_root}", + "-s", ".", "-l", "swift", "--internal-use-lua-tracing", f"--search-path={codeql_root}", "--no-cleanup", ] if keep_trap: cmd.append("--keep-trap") From 76ea63ffbe07a68686a132d3d237004d1dfad0d4 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 28 Jul 2022 12:28:52 +0200 Subject: [PATCH 430/465] Swift: deduplicate `VarDecl` Deduplication of `ConcreteVarDecl` is triggered only if its `DeclContext` is not local. This avoids a mangled name conflict. Also added more thourough tests for `ConcreteVarDecl` and `ParamDecl`. --- swift/extractor/visitors/DeclVisitor.cpp | 29 ++++++++++++------- swift/extractor/visitors/DeclVisitor.h | 4 +-- .../ConcreteVarDecl/ConcreteVarDecl.expected | 7 +++++ .../decl/ConcreteVarDecl/ConcreteVarDecl.ql | 14 +++++++++ .../ConcreteVarDecl_getAccessorDecl.expected | 13 +++++++++ .../ConcreteVarDecl_getAccessorDecl.ql | 7 +++++ ...cl_getAttachedPropertyWrapperType.expected | 1 + ...eVarDecl_getAttachedPropertyWrapperType.ql | 7 +++++ ...creteVarDecl_getParentInitializer.expected | 3 ++ .../ConcreteVarDecl_getParentInitializer.ql | 7 +++++ .../ConcreteVarDecl_getParentPattern.expected | 7 +++++ .../ConcreteVarDecl_getParentPattern.ql | 7 +++++ .../decl/ConcreteVarDecl/MISSING_SOURCE.txt | 4 --- .../decl/ConcreteVarDecl/var_decls.swift | 25 ++++++++++++++++ .../decl/ParamDecl/MISSING_SOURCE.txt | 4 --- .../decl/ParamDecl/ParamDecl.expected | 15 ++++++++++ .../generated/decl/ParamDecl/ParamDecl.ql | 14 +++++++++ .../ParamDecl_getAccessorDecl.expected | 0 .../ParamDecl/ParamDecl_getAccessorDecl.ql | 7 +++++ ...cl_getAttachedPropertyWrapperType.expected | 0 ...aramDecl_getAttachedPropertyWrapperType.ql | 7 +++++ .../ParamDecl_getParentInitializer.expected | 0 .../ParamDecl_getParentInitializer.ql | 7 +++++ .../ParamDecl_getParentPattern.expected | 0 .../ParamDecl/ParamDecl_getParentPattern.ql | 7 +++++ .../decl/ParamDecl/param_decls.swift | 15 ++++++++++ 26 files changed, 191 insertions(+), 20 deletions(-) create mode 100644 swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.ql delete mode 100644 swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/var_decls.swift delete mode 100644 swift/ql/test/extractor-tests/generated/decl/ParamDecl/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAccessorDecl.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAccessorDecl.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAttachedPropertyWrapperType.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAttachedPropertyWrapperType.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentInitializer.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentInitializer.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentPattern.expected create mode 100644 swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentPattern.ql create mode 100644 swift/ql/test/extractor-tests/generated/decl/ParamDecl/param_decls.swift diff --git a/swift/extractor/visitors/DeclVisitor.cpp b/swift/extractor/visitors/DeclVisitor.cpp index 819c959a6d2..dc693e66a0f 100644 --- a/swift/extractor/visitors/DeclVisitor.cpp +++ b/swift/extractor/visitors/DeclVisitor.cpp @@ -83,11 +83,13 @@ codeql::PrecedenceGroupDecl DeclVisitor::translatePrecedenceGroupDecl( return entry; } -codeql::ParamDecl DeclVisitor::translateParamDecl(const swift::ParamDecl& decl) { - // TODO: deduplicate - ParamDecl entry{dispatcher_.assignNewLabel(decl)}; - fillVarDecl(decl, entry); - entry.is_inout = decl.isInOut(); +std::optional DeclVisitor::translateParamDecl(const swift::ParamDecl& decl) { + auto entry = createNamedEntry(decl); + if (!entry) { + return std::nullopt; + } + fillVarDecl(decl, *entry); + entry->is_inout = decl.isInOut(); return entry; } @@ -111,11 +113,18 @@ codeql::PatternBindingDecl DeclVisitor::translatePatternBindingDecl( return entry; } -codeql::ConcreteVarDecl DeclVisitor::translateVarDecl(const swift::VarDecl& decl) { - // TODO: deduplicate all non-local variables - ConcreteVarDecl entry{dispatcher_.assignNewLabel(decl)}; - entry.introducer_int = static_cast(decl.getIntroducer()); - fillVarDecl(decl, entry); +std::optional DeclVisitor::translateVarDecl(const swift::VarDecl& decl) { + std::optional entry; + if (decl.getDeclContext()->isLocalContext()) { + entry.emplace(dispatcher_.assignNewLabel(decl)); + } else { + entry = createNamedEntry(decl); + if (!entry) { + return std::nullopt; + } + } + entry->introducer_int = static_cast(decl.getIntroducer()); + fillVarDecl(decl, *entry); return entry; } diff --git a/swift/extractor/visitors/DeclVisitor.h b/swift/extractor/visitors/DeclVisitor.h index 0d6296591a0..85e819adb5b 100644 --- a/swift/extractor/visitors/DeclVisitor.h +++ b/swift/extractor/visitors/DeclVisitor.h @@ -30,10 +30,10 @@ class DeclVisitor : public AstVisitorBase { codeql::PostfixOperatorDecl translatePostfixOperatorDecl(const swift::PostfixOperatorDecl& decl); codeql::InfixOperatorDecl translateInfixOperatorDecl(const swift::InfixOperatorDecl& decl); codeql::PrecedenceGroupDecl translatePrecedenceGroupDecl(const swift::PrecedenceGroupDecl& decl); - codeql::ParamDecl translateParamDecl(const swift::ParamDecl& decl); + std::optional translateParamDecl(const swift::ParamDecl& decl); codeql::TopLevelCodeDecl translateTopLevelCodeDecl(const swift::TopLevelCodeDecl& decl); codeql::PatternBindingDecl translatePatternBindingDecl(const swift::PatternBindingDecl& decl); - codeql::ConcreteVarDecl translateVarDecl(const swift::VarDecl& decl); + std::optional translateVarDecl(const swift::VarDecl& decl); std::variant translateStructDecl( const swift::StructDecl& decl); std::variant translateClassDecl( diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.expected new file mode 100644 index 00000000000..f50475445e5 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.expected @@ -0,0 +1,7 @@ +| var_decls.swift:4:7:4:7 | i | getInterfaceType: | Int | getName: | i | getType: | Int | getIntroducerInt: | 1 | +| var_decls.swift:7:5:7:5 | numbers | getInterfaceType: | [Int] | getName: | numbers | getType: | [Int] | getIntroducerInt: | 1 | +| var_decls.swift:10:12:10:12 | numbers | getInterfaceType: | [Int] | getName: | numbers | getType: | [Int] | getIntroducerInt: | 0 | +| var_decls.swift:15:7:15:7 | wrappedValue | getInterfaceType: | T | getName: | wrappedValue | getType: | T | getIntroducerInt: | 1 | +| var_decls.swift:20:7:20:7 | wrappedValue | getInterfaceType: | Int | getName: | wrappedValue | getType: | Int | getIntroducerInt: | 1 | +| var_decls.swift:24:15:24:15 | _wrapped | getInterfaceType: | X | getName: | _wrapped | getType: | X | getIntroducerInt: | 1 | +| var_decls.swift:24:15:24:15 | wrapped | getInterfaceType: | Int | getName: | wrapped | getType: | Int | getIntroducerInt: | 1 | diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.ql new file mode 100644 index 00000000000..55ae04af6ac --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl.ql @@ -0,0 +1,14 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ConcreteVarDecl x, Type getInterfaceType, string getName, Type getType, int getIntroducerInt +where + toBeTested(x) and + not x.isUnknown() and + getInterfaceType = x.getInterfaceType() and + getName = x.getName() and + getType = x.getType() and + getIntroducerInt = x.getIntroducerInt() +select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "getType:", getType, + "getIntroducerInt:", getIntroducerInt diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.expected new file mode 100644 index 00000000000..cfbce6fe5ef --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.expected @@ -0,0 +1,13 @@ +| var_decls.swift:10:12:10:12 | numbers | 0 | var_decls.swift:10:12:10:12 | get | +| var_decls.swift:15:7:15:7 | wrappedValue | 0 | var_decls.swift:15:7:15:7 | get | +| var_decls.swift:15:7:15:7 | wrappedValue | 1 | var_decls.swift:15:7:15:7 | set | +| var_decls.swift:15:7:15:7 | wrappedValue | 2 | var_decls.swift:15:7:15:7 | (unnamed function decl) | +| var_decls.swift:20:7:20:7 | wrappedValue | 0 | var_decls.swift:20:7:20:7 | get | +| var_decls.swift:20:7:20:7 | wrappedValue | 1 | var_decls.swift:20:7:20:7 | set | +| var_decls.swift:20:7:20:7 | wrappedValue | 2 | var_decls.swift:20:7:20:7 | (unnamed function decl) | +| var_decls.swift:24:15:24:15 | _wrapped | 0 | var_decls.swift:24:15:24:15 | get | +| var_decls.swift:24:15:24:15 | _wrapped | 1 | var_decls.swift:24:15:24:15 | set | +| var_decls.swift:24:15:24:15 | _wrapped | 2 | var_decls.swift:24:15:24:15 | (unnamed function decl) | +| var_decls.swift:24:15:24:15 | wrapped | 0 | var_decls.swift:24:15:24:15 | get | +| var_decls.swift:24:15:24:15 | wrapped | 1 | var_decls.swift:24:15:24:15 | set | +| var_decls.swift:24:15:24:15 | wrapped | 2 | var_decls.swift:24:15:24:15 | (unnamed function decl) | diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.ql new file mode 100644 index 00000000000..b25caf7bf97 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAccessorDecl.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ConcreteVarDecl x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getAccessorDecl(index) diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.expected b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.expected new file mode 100644 index 00000000000..67bff5661b0 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.expected @@ -0,0 +1 @@ +| var_decls.swift:24:15:24:15 | wrapped | X | diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.ql b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.ql new file mode 100644 index 00000000000..569c25f0602 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getAttachedPropertyWrapperType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ConcreteVarDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getAttachedPropertyWrapperType() diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.expected b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.expected new file mode 100644 index 00000000000..786b16fcab1 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.expected @@ -0,0 +1,3 @@ +| var_decls.swift:4:7:4:7 | i | var_decls.swift:4:11:4:11 | 0 | +| var_decls.swift:7:5:7:5 | numbers | var_decls.swift:7:15:7:18 | [...] | +| var_decls.swift:10:12:10:12 | numbers | var_decls.swift:10:22:10:35 | [...] | diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.ql b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.ql new file mode 100644 index 00000000000..eddfa346732 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentInitializer.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ConcreteVarDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getParentInitializer() diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.expected b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.expected new file mode 100644 index 00000000000..8e15539394a --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.expected @@ -0,0 +1,7 @@ +| var_decls.swift:4:7:4:7 | i | var_decls.swift:4:7:4:7 | i | +| var_decls.swift:7:5:7:5 | numbers | var_decls.swift:7:5:7:5 | numbers | +| var_decls.swift:10:12:10:12 | numbers | var_decls.swift:10:12:10:12 | numbers | +| var_decls.swift:15:7:15:7 | wrappedValue | var_decls.swift:15:7:15:21 | ... as ... | +| var_decls.swift:20:7:20:7 | wrappedValue | var_decls.swift:20:7:20:21 | ... as ... | +| var_decls.swift:24:15:24:15 | _wrapped | var_decls.swift:24:15:24:15 | ... as ... | +| var_decls.swift:24:15:24:15 | wrapped | var_decls.swift:24:15:24:25 | ... as ... | diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.ql b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.ql new file mode 100644 index 00000000000..2aedb61e2ae --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/ConcreteVarDecl_getParentPattern.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ConcreteVarDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getParentPattern() diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/var_decls.swift b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/var_decls.swift new file mode 100644 index 00000000000..37c145a5a42 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ConcreteVarDecl/var_decls.swift @@ -0,0 +1,25 @@ +func loop() { + for i in 1...5 { + } + var i = 0 +} + +var numbers = [42] + +struct S { +static let numbers = [42, 404, 101] +} + +@propertyWrapper +struct X { + var wrappedValue: T +} + +@propertyWrapper +struct Y { + var wrappedValue: Int +} + +struct Wrapped { + @X @Y var wrapped : Int +} diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.expected new file mode 100644 index 00000000000..8f559769407 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.expected @@ -0,0 +1,15 @@ +| param_decls.swift:1:10:1:13 | _ | getInterfaceType: | Int | getName: | _ | getType: | Int | isInout: | no | +| param_decls.swift:1:18:1:29 | y | getInterfaceType: | Double | getName: | y | getType: | Double | isInout: | yes | +| param_decls.swift:2:10:2:13 | _ | getInterfaceType: | Int | getName: | _ | getType: | Int | isInout: | no | +| param_decls.swift:2:18:2:29 | y | getInterfaceType: | Double | getName: | y | getType: | Double | isInout: | yes | +| param_decls.swift:5:5:5:5 | self | getInterfaceType: | S | getName: | self | getType: | S | isInout: | yes | +| param_decls.swift:5:15:5:15 | x | getInterfaceType: | Int | getName: | x | getType: | Int | isInout: | no | +| param_decls.swift:5:15:5:15 | x | getInterfaceType: | Int | getName: | x | getType: | Int | isInout: | no | +| param_decls.swift:5:15:5:18 | x | getInterfaceType: | Int | getName: | x | getType: | Int | isInout: | no | +| param_decls.swift:5:23:5:23 | y | getInterfaceType: | Int | getName: | y | getType: | Int | isInout: | no | +| param_decls.swift:5:23:5:23 | y | getInterfaceType: | Int | getName: | y | getType: | Int | isInout: | no | +| param_decls.swift:5:23:5:26 | y | getInterfaceType: | Int | getName: | y | getType: | Int | isInout: | no | +| param_decls.swift:7:9:7:9 | newValue | getInterfaceType: | Int? | getName: | newValue | getType: | Int? | isInout: | no | +| param_decls.swift:12:13:12:22 | s | getInterfaceType: | String | getName: | s | getType: | String | isInout: | yes | +| param_decls.swift:13:13:13:22 | s | getInterfaceType: | String | getName: | s | getType: | String | isInout: | yes | +| param_decls.swift:14:26:14:26 | $0 | getInterfaceType: | Int | getName: | $0 | getType: | Int | isInout: | no | diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.ql new file mode 100644 index 00000000000..acf3614b7b0 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl.ql @@ -0,0 +1,14 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ParamDecl x, Type getInterfaceType, string getName, Type getType, string isInout +where + toBeTested(x) and + not x.isUnknown() and + getInterfaceType = x.getInterfaceType() and + getName = x.getName() and + getType = x.getType() and + if x.isInout() then isInout = "yes" else isInout = "no" +select x, "getInterfaceType:", getInterfaceType, "getName:", getName, "getType:", getType, + "isInout:", isInout diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAccessorDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAccessorDecl.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAccessorDecl.ql b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAccessorDecl.ql new file mode 100644 index 00000000000..a751e0006cc --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAccessorDecl.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ParamDecl x, int index +where toBeTested(x) and not x.isUnknown() +select x, index, x.getAccessorDecl(index) diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAttachedPropertyWrapperType.expected b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAttachedPropertyWrapperType.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAttachedPropertyWrapperType.ql b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAttachedPropertyWrapperType.ql new file mode 100644 index 00000000000..0e71fb1cf26 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getAttachedPropertyWrapperType.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ParamDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getAttachedPropertyWrapperType() diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentInitializer.expected b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentInitializer.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentInitializer.ql b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentInitializer.ql new file mode 100644 index 00000000000..39f7e9e1b6e --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentInitializer.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ParamDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getParentInitializer() diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentPattern.expected b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentPattern.expected new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentPattern.ql b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentPattern.ql new file mode 100644 index 00000000000..17b5a06c1d5 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/ParamDecl_getParentPattern.ql @@ -0,0 +1,7 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ParamDecl x +where toBeTested(x) and not x.isUnknown() +select x, x.getParentPattern() diff --git a/swift/ql/test/extractor-tests/generated/decl/ParamDecl/param_decls.swift b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/param_decls.swift new file mode 100644 index 00000000000..72b47ed2c60 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/decl/ParamDecl/param_decls.swift @@ -0,0 +1,15 @@ +func foo(_: Int, x y: inout Double) {} +func bar(_: Int, x y: inout Double) {} + +struct S { + subscript(x: Int, y: Int) -> Int? { + get { nil } + set {} + } +} + +func closures() { + let x = {(s: inout String) -> String in s} + let y = {(s: inout String) -> String in ""} + let z : (Int) -> Int = { $0 + 1 } +} From 7d7966e71135785aa59fbd255a9df730121df482 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 28 Jul 2022 12:43:30 +0200 Subject: [PATCH 431/465] Swift: make trap key prefixes readable This replaces numeric tag-based prefixes with the actual tag name. While this means in general slightly larger trap files, it aids debugging them for a human. In the future we can make this conditional on some kind of trap debug option, but for the moment it does not seem detrimental. --- swift/codegen/generators/trapgen.py | 3 +-- swift/codegen/lib/cpp.py | 1 - swift/codegen/templates/trap_tags_h.mustache | 2 +- swift/codegen/test/test_cpp.py | 4 ++-- swift/codegen/test/test_trapgen.py | 20 ++++++++++---------- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/swift/codegen/generators/trapgen.py b/swift/codegen/generators/trapgen.py index eb701b629ef..22c46e6e146 100755 --- a/swift/codegen/generators/trapgen.py +++ b/swift/codegen/generators/trapgen.py @@ -86,11 +86,10 @@ def generate(opts, renderer): renderer.render(cpp.TrapList(entries, opts.dbscheme), out / dir / "TrapEntries") tags = [] - for index, tag in enumerate(toposort_flatten(tag_graph)): + for tag in toposort_flatten(tag_graph): tags.append(cpp.Tag( name=get_tag_name(tag), bases=[get_tag_name(b) for b in sorted(tag_graph[tag])], - index=index, id=tag, )) renderer.render(cpp.TagList(tags, opts.dbscheme), out / "TrapTags") diff --git a/swift/codegen/lib/cpp.py b/swift/codegen/lib/cpp.py index 9eb5f78af58..3542efcdee9 100644 --- a/swift/codegen/lib/cpp.py +++ b/swift/codegen/lib/cpp.py @@ -83,7 +83,6 @@ class TagBase: class Tag: name: str bases: List[TagBase] - index: int id: str def __post_init__(self): diff --git a/swift/codegen/templates/trap_tags_h.mustache b/swift/codegen/templates/trap_tags_h.mustache index feac64ff92a..c444d28afcb 100644 --- a/swift/codegen/templates/trap_tags_h.mustache +++ b/swift/codegen/templates/trap_tags_h.mustache @@ -7,7 +7,7 @@ namespace codeql { // {{id}} struct {{name}}Tag {{#has_bases}}: {{#bases}}{{^first}}, {{/first}}{{base}}Tag{{/bases}} {{/has_bases}}{ - static constexpr const char* prefix = "{{index}}"; + static constexpr const char* prefix = "{{name}}"; }; {{/tags}} } diff --git a/swift/codegen/test/test_cpp.py b/swift/codegen/test/test_cpp.py index e6cd4f81305..d04877e38c4 100644 --- a/swift/codegen/test/test_cpp.py +++ b/swift/codegen/test/test_cpp.py @@ -65,7 +65,7 @@ def test_trap_has_first_field_marked(): def test_tag_has_first_base_marked(): bases = ["a", "b", "c"] expected = [cpp.TagBase("a", first=True), cpp.TagBase("b"), cpp.TagBase("c")] - t = cpp.Tag("name", bases, 0, "id") + t = cpp.Tag("name", bases, "id") assert t.bases == expected @@ -75,7 +75,7 @@ def test_tag_has_first_base_marked(): (["a", "b"], True) ]) def test_tag_has_bases(bases, expected): - t = cpp.Tag("name", bases, 0, "id") + t = cpp.Tag("name", bases, "id") assert t.has_bases is expected diff --git a/swift/codegen/test/test_trapgen.py b/swift/codegen/test/test_trapgen.py index 376f69c43a3..c8121ce48ba 100644 --- a/swift/codegen/test/test_trapgen.py +++ b/swift/codegen/test/test_trapgen.py @@ -162,10 +162,10 @@ def test_one_union_tags(generate_tags): assert generate_tags([ dbscheme.Union(lhs="@left_hand_side", rhs=["@b", "@a", "@c"]), ]) == [ - cpp.Tag(name="LeftHandSide", bases=[], index=0, id="@left_hand_side"), - cpp.Tag(name="A", bases=["LeftHandSide"], index=1, id="@a"), - cpp.Tag(name="B", bases=["LeftHandSide"], index=2, id="@b"), - cpp.Tag(name="C", bases=["LeftHandSide"], index=3, id="@c"), + cpp.Tag(name="LeftHandSide", bases=[], id="@left_hand_side"), + cpp.Tag(name="A", bases=["LeftHandSide"], id="@a"), + cpp.Tag(name="B", bases=["LeftHandSide"], id="@b"), + cpp.Tag(name="C", bases=["LeftHandSide"], id="@c"), ] @@ -175,12 +175,12 @@ def test_multiple_union_tags(generate_tags): dbscheme.Union(lhs="@a", rhs=["@b", "@c"]), dbscheme.Union(lhs="@e", rhs=["@c", "@f"]), ]) == [ - cpp.Tag(name="D", bases=[], index=0, id="@d"), - cpp.Tag(name="E", bases=[], index=1, id="@e"), - cpp.Tag(name="A", bases=["D"], index=2, id="@a"), - cpp.Tag(name="F", bases=["E"], index=3, id="@f"), - cpp.Tag(name="B", bases=["A"], index=4, id="@b"), - cpp.Tag(name="C", bases=["A", "E"], index=5, id="@c"), + cpp.Tag(name="D", bases=[], id="@d"), + cpp.Tag(name="E", bases=[], id="@e"), + cpp.Tag(name="A", bases=["D"], id="@a"), + cpp.Tag(name="F", bases=["E"], id="@f"), + cpp.Tag(name="B", bases=["A"], id="@b"), + cpp.Tag(name="C", bases=["A", "E"], id="@c"), ] From d547a417c93a8b26e66f985c71e64271e5fc97c0 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 28 Jul 2022 12:57:12 +0200 Subject: [PATCH 432/465] Swift: accept new test results --- .../posix-only/cross-references/VarDecls.expected | 1 - 1 file changed, 1 deletion(-) diff --git a/swift/integration-tests/posix-only/cross-references/VarDecls.expected b/swift/integration-tests/posix-only/cross-references/VarDecls.expected index 104271d5384..6fab086e7dd 100644 --- a/swift/integration-tests/posix-only/cross-references/VarDecls.expected +++ b/swift/integration-tests/posix-only/cross-references/VarDecls.expected @@ -1,5 +1,4 @@ | Sources/cross-references/lib.swift:10:5:10:5 | X | -| Sources/cross-references/lib.swift:10:5:10:5 | X | | Sources/cross-references/lib.swift:17:16:17:19 | v | | Sources/cross-references/lib.swift:22:16:22:19 | v | | Sources/cross-references/lib.swift:27:8:27:13 | lhs | From e7f275382e7e152b965467e7d405a018cec43765 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 14 Jul 2022 11:14:27 +0100 Subject: [PATCH 433/465] Add test for Java wildcard substitution --- .../wildcard-substitution/Lib.java | 17 ++++++ .../wildcard-substitution/User.java | 12 +++++ .../wildcard-substitution/test.expected | 54 +++++++++++++++++++ .../wildcard-substitution/test.ql | 7 +++ 4 files changed, 90 insertions(+) create mode 100644 java/ql/test/library-tests/wildcard-substitution/Lib.java create mode 100644 java/ql/test/library-tests/wildcard-substitution/User.java create mode 100644 java/ql/test/library-tests/wildcard-substitution/test.expected create mode 100644 java/ql/test/library-tests/wildcard-substitution/test.ql diff --git a/java/ql/test/library-tests/wildcard-substitution/Lib.java b/java/ql/test/library-tests/wildcard-substitution/Lib.java new file mode 100644 index 00000000000..9bd84a9218c --- /dev/null +++ b/java/ql/test/library-tests/wildcard-substitution/Lib.java @@ -0,0 +1,17 @@ +import java.util.List; + +public class Lib { + + public void takesVar(T t) { } + public void takesInvar(List lt) { } + public void takesUnbound(List lt) { } + public void takesExtends(List lt) { } + public void takesSuper(List lt) { } + + public T returnsVar() { return null; } + public List returnsInvar() { return null; } + public List returnsUnbound() { return null; } + public List returnsExtends() { return null; } + public List returnsSuper() { return null; } + +} diff --git a/java/ql/test/library-tests/wildcard-substitution/User.java b/java/ql/test/library-tests/wildcard-substitution/User.java new file mode 100644 index 00000000000..5f4b7fac21a --- /dev/null +++ b/java/ql/test/library-tests/wildcard-substitution/User.java @@ -0,0 +1,12 @@ +public class User { + + public static void test(Lib invarLib, Lib extendsLib, Lib superLib, Lib unboundLib) { + + invarLib.takesVar(null); + extendsLib.takesVar(null); + superLib.takesVar(null); + unboundLib.takesVar(null); + + } + +} diff --git a/java/ql/test/library-tests/wildcard-substitution/test.expected b/java/ql/test/library-tests/wildcard-substitution/test.expected new file mode 100644 index 00000000000..85af393c21e --- /dev/null +++ b/java/ql/test/library-tests/wildcard-substitution/test.expected @@ -0,0 +1,54 @@ +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsVar | CharSequence | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesVar | | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsVar | Object | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesVar | CharSequence | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsVar | Object | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesVar | | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsVar | CharSequence | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesExtends | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesInvar | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesSuper | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesUnbound | List | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesVar | CharSequence | +| Lib.java:3:14:3:16 | Lib | Lib.java:5:15:5:22 | takesVar | T | +| Lib.java:3:14:3:16 | Lib | Lib.java:6:15:6:24 | takesInvar | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:7:15:7:26 | takesUnbound | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:8:15:8:26 | takesExtends | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:9:15:9:24 | takesSuper | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:11:12:11:21 | returnsVar | T | +| Lib.java:3:14:3:16 | Lib | Lib.java:12:18:12:29 | returnsInvar | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:13:18:13:31 | returnsUnbound | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:14:28:14:41 | returnsExtends | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:15:26:15:37 | returnsSuper | List | +| User.java:1:14:1:17 | User | User.java:3:22:3:25 | test | Lib | +| User.java:1:14:1:17 | User | User.java:3:22:3:25 | test | Lib | +| User.java:1:14:1:17 | User | User.java:3:22:3:25 | test | Lib | +| User.java:1:14:1:17 | User | User.java:3:22:3:25 | test | Lib | diff --git a/java/ql/test/library-tests/wildcard-substitution/test.ql b/java/ql/test/library-tests/wildcard-substitution/test.ql new file mode 100644 index 00000000000..3fdf1c00a55 --- /dev/null +++ b/java/ql/test/library-tests/wildcard-substitution/test.ql @@ -0,0 +1,7 @@ +import java + +Type notVoid(Type t) { result = t and not result instanceof VoidType } + +from Callable c +where c.getSourceDeclaration().fromSource() +select c.getDeclaringType(), c, notVoid([c.getAParamType(), c.getReturnType()]).toString() From 7475f84ea5a69c5572e3cd0b954cb2c8ca9fdbc4 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 14 Jul 2022 15:19:05 +0100 Subject: [PATCH 434/465] Fix type-parameter-out-of-scope test --- java/ql/consistency-queries/typeParametersInScope.ql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/ql/consistency-queries/typeParametersInScope.ql b/java/ql/consistency-queries/typeParametersInScope.ql index f78bf2d42a4..2f1fd651278 100644 --- a/java/ql/consistency-queries/typeParametersInScope.ql +++ b/java/ql/consistency-queries/typeParametersInScope.ql @@ -12,6 +12,8 @@ Type getAMentionedType(RefType type) { result = getAMentionedType(type).(InstantiatedType).getATypeArgument() or result = getAMentionedType(type).(NestedType).getEnclosingType() + or + result = getAMentionedType(type).(Wildcard).getATypeBound().getType() } Type getATypeUsedInClass(RefType type) { From 8cd2aeb65dbc9768dda5056478dcd871df6df0f6 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 14 Jul 2022 15:19:33 +0100 Subject: [PATCH 435/465] Accept test changes --- .../generic-instance-methods/test.expected | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/java/ql/test/kotlin/library-tests/generic-instance-methods/test.expected b/java/ql/test/kotlin/library-tests/generic-instance-methods/test.expected index 13c5c19bd68..b80b1311a64 100644 --- a/java/ql/test/kotlin/library-tests/generic-instance-methods/test.expected +++ b/java/ql/test/kotlin/library-tests/generic-instance-methods/test.expected @@ -14,8 +14,8 @@ calls | test.kt:22:15:22:33 | setter(...) | test.kt:12:1:25:1 | user | test.kt:0:0:0:0 | TestKt | file:///!unknown-binary-location/Generic.class:0:0:0:0 | setter | file:///!unknown-binary-location/Generic.class:0:0:0:0 | Generic | | test.kt:23:15:23:22 | getter(...) | test.kt:12:1:25:1 | user | test.kt:0:0:0:0 | TestKt | file:///!unknown-binary-location/Generic.class:0:0:0:0 | getter | file:///!unknown-binary-location/Generic.class:0:0:0:0 | Generic | constructors -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | Generic2 | Generic2(java.lang.String) | ? extends String | void | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | Generic2 | Generic2(java.lang.Object) | ? super String | void | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | Generic2 | Generic2() | | void | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | Generic2 | Generic2(java.lang.String) | String | void | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | | Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | Generic2 | Generic2(java.lang.String) | String | void | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | Generic2(java.lang.Object) | T | void | Test.java:1:7:1:14 | Generic2 | Test.java:3:10:3:17 | Generic2 | | Test.java:14:14:14:17 | Test | Test.java:14:14:14:17 | Test | Test() | No parameters | void | Test.java:14:14:14:17 | Test | Test.java:14:14:14:17 | Test | @@ -34,14 +34,14 @@ refTypes | test.kt:1:1:10:1 | Generic | | test.kt:1:15:1:15 | T | #select -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | getter | getter() | No parameters | ? extends String | Test.java:1:7:1:14 | Generic2 | Test.java:9:5:9:10 | getter | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity | identity(java.lang.String) | ? extends String | ? extends String | Test.java:1:7:1:14 | Generic2 | Test.java:8:5:8:12 | identity | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity2 | identity2(java.lang.String) | ? extends String | ? extends String | Test.java:1:7:1:14 | Generic2 | Test.java:7:5:7:13 | identity2 | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | setter | setter(java.lang.String) | ? extends String | void | Test.java:1:7:1:14 | Generic2 | Test.java:10:8:10:13 | setter | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | getter | getter() | No parameters | ? super String | Test.java:1:7:1:14 | Generic2 | Test.java:9:5:9:10 | getter | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity | identity(java.lang.Object) | ? super String | ? super String | Test.java:1:7:1:14 | Generic2 | Test.java:8:5:8:12 | identity | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity2 | identity2(java.lang.Object) | ? super String | ? super String | Test.java:1:7:1:14 | Generic2 | Test.java:7:5:7:13 | identity2 | -| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | setter | setter(java.lang.Object) | ? super String | void | Test.java:1:7:1:14 | Generic2 | Test.java:10:8:10:13 | setter | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | getter | getter() | No parameters | String | Test.java:1:7:1:14 | Generic2 | Test.java:9:5:9:10 | getter | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity | identity() | | String | Test.java:1:7:1:14 | Generic2 | Test.java:8:5:8:12 | identity | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity2 | identity2() | | String | Test.java:1:7:1:14 | Generic2 | Test.java:7:5:7:13 | identity2 | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | setter | setter() | | void | Test.java:1:7:1:14 | Generic2 | Test.java:10:8:10:13 | setter | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | getter | getter() | No parameters | Object | Test.java:1:7:1:14 | Generic2 | Test.java:9:5:9:10 | getter | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity | identity(java.lang.String) | String | Object | Test.java:1:7:1:14 | Generic2 | Test.java:8:5:8:12 | identity | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity2 | identity2(java.lang.String) | String | Object | Test.java:1:7:1:14 | Generic2 | Test.java:7:5:7:13 | identity2 | +| Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | setter | setter(java.lang.String) | String | void | Test.java:1:7:1:14 | Generic2 | Test.java:10:8:10:13 | setter | | Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | getter | getter() | No parameters | String | Test.java:1:7:1:14 | Generic2 | Test.java:9:5:9:10 | getter | | Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity | identity(java.lang.String) | String | String | Test.java:1:7:1:14 | Generic2 | Test.java:8:5:8:12 | identity | | Generic2.class:0:0:0:0 | Generic2 | Generic2.class:0:0:0:0 | identity2 | identity2(java.lang.String) | String | String | Test.java:1:7:1:14 | Generic2 | Test.java:7:5:7:13 | identity2 | From 1737ed50ba8dd02c81167746393bd440b4d83c67 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 20 Jul 2022 10:09:50 +0100 Subject: [PATCH 436/465] Add test cases for wildcard lowering of array types --- .../test/library-tests/wildcard-substitution/Lib.java | 3 +++ .../library-tests/wildcard-substitution/test.expected | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/java/ql/test/library-tests/wildcard-substitution/Lib.java b/java/ql/test/library-tests/wildcard-substitution/Lib.java index 9bd84a9218c..0647410b692 100644 --- a/java/ql/test/library-tests/wildcard-substitution/Lib.java +++ b/java/ql/test/library-tests/wildcard-substitution/Lib.java @@ -14,4 +14,7 @@ public class Lib { public List returnsExtends() { return null; } public List returnsSuper() { return null; } + public void takesArray(T[] ts) { } + public T[] returnsArray() { return null; } + } diff --git a/java/ql/test/library-tests/wildcard-substitution/test.expected b/java/ql/test/library-tests/wildcard-substitution/test.expected index 85af393c21e..91a1cc43cb0 100644 --- a/java/ql/test/library-tests/wildcard-substitution/test.expected +++ b/java/ql/test/library-tests/wildcard-substitution/test.expected @@ -1,38 +1,46 @@ +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsArray | CharSequence[] | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsExtends | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsInvar | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsSuper | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsUnbound | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsVar | CharSequence | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesArray | [] | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesExtends | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesInvar | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesSuper | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesUnbound | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesVar | | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsArray | Object[] | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsExtends | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsInvar | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsSuper | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsUnbound | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsVar | Object | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesArray | CharSequence[] | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesExtends | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesInvar | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesSuper | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesUnbound | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesVar | CharSequence | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsArray | Object[] | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsExtends | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsInvar | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsSuper | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsUnbound | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsVar | Object | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesArray | [] | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesExtends | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesInvar | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesSuper | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesUnbound | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesVar | | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsArray | CharSequence[] | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsExtends | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsInvar | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsSuper | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsUnbound | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | returnsVar | CharSequence | +| Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesArray | CharSequence[] | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesExtends | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesInvar | List | | Lib.class:0:0:0:0 | Lib | Lib.class:0:0:0:0 | takesSuper | List | @@ -48,6 +56,8 @@ | Lib.java:3:14:3:16 | Lib | Lib.java:13:18:13:31 | returnsUnbound | List | | Lib.java:3:14:3:16 | Lib | Lib.java:14:28:14:41 | returnsExtends | List | | Lib.java:3:14:3:16 | Lib | Lib.java:15:26:15:37 | returnsSuper | List | +| Lib.java:3:14:3:16 | Lib | Lib.java:17:15:17:24 | takesArray | T[] | +| Lib.java:3:14:3:16 | Lib | Lib.java:18:14:18:25 | returnsArray | T[] | | User.java:1:14:1:17 | User | User.java:3:22:3:25 | test | Lib | | User.java:1:14:1:17 | User | User.java:3:22:3:25 | test | Lib | | User.java:1:14:1:17 | User | User.java:3:22:3:25 | test | Lib | From 985237ab2d3070edfc91c8d5c41596ec14362cdf Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Thu, 28 Jul 2022 17:05:52 +0200 Subject: [PATCH 437/465] Swift: small dispatcher fixes File extraction was not using named trap keys, and `emitDebugInfo` was using `std::forward` when it should not. --- swift/extractor/infra/SwiftDispatcher.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swift/extractor/infra/SwiftDispatcher.h b/swift/extractor/infra/SwiftDispatcher.h index 60d20273655..d564673c976 100644 --- a/swift/extractor/infra/SwiftDispatcher.h +++ b/swift/extractor/infra/SwiftDispatcher.h @@ -215,7 +215,7 @@ class SwiftDispatcher { template void emitDebugInfo(const Args&... args) { - trap.debug(std::forward(args)...); + trap.debug(args...); } // In order to not emit duplicated entries for declarations, we restrict emission to only @@ -315,7 +315,7 @@ class SwiftDispatcher { virtual void visit(swift::TypeBase* type) = 0; void visit(const FilePath& file) { - auto entry = createEntry(file); + auto entry = createEntry(file, file.path); entry.name = file.path; emit(entry); } From c4283dd23f8de6f3a1501090f5a83e65cb3cb253 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 Jul 2022 11:31:50 +0200 Subject: [PATCH 438/465] C++: Support `__is_assignable` builtin While here fix the documentation of `__is_trivially_assignable` and `__is_nothrow_assignable`. --- .../code/cpp/exprs/BuiltInOperations.qll | 29 ++++++++++++++----- cpp/ql/lib/semmlecode.cpp.dbscheme | 2 ++ .../builtins/type_traits/expr.expected | 9 ++++++ .../library-tests/builtins/type_traits/ms.cpp | 5 +++- 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll index 309d98cd694..c794b574045 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll @@ -612,13 +612,10 @@ class BuiltInOperationIsTriviallyDestructible extends BuiltInOperation, @istrivi * The `__is_trivially_assignable` built-in operation (used by some * implementations of the `` header). * - * Returns `true` if the assignment operator `C::operator =(const C& c)` is - * trivial. + * Returns `true` if the assignment operator `C::operator =(const D& d)` is + * trivial (i.e., it will not call any operation that is non-trivial). * ``` - * template - * struct is_trivially_assignable - * : public integral_constant - * { }; + * bool v = __is_trivially_assignable(MyType1, MyType2); * ``` */ class BuiltInOperationIsTriviallyAssignable extends BuiltInOperation, @istriviallyassignableexpr { @@ -631,10 +628,10 @@ class BuiltInOperationIsTriviallyAssignable extends BuiltInOperation, @istrivial * The `__is_nothrow_assignable` built-in operation (used by some * implementations of the `` header). * - * Returns true if there exists a `C::operator =(const C& c) nothrow` + * Returns true if there exists a `C::operator =(const D& d) nothrow` * assignment operator (i.e, with an empty exception specification). * ``` - * bool v = __is_nothrow_assignable(MyType); + * bool v = __is_nothrow_assignable(MyType1, MyType2); * ``` */ class BuiltInOperationIsNothrowAssignable extends BuiltInOperation, @isnothrowassignableexpr { @@ -643,6 +640,22 @@ class BuiltInOperationIsNothrowAssignable extends BuiltInOperation, @isnothrowas override string getAPrimaryQlClass() { result = "BuiltInOperationIsNothrowAssignable" } } +/** + * The `__is_assignable` built-in operation (used by some implementations + * of the `` header). + * + * Returns true if there exists a `C::operator =(const D& d)` assignment + * operator. + * ``` + * bool v = __is_assignable(MyType1, MyType2); + * ``` + */ +class BuiltInOperationIsAssignable extends BuiltInOperation, @isassignable { + override string toString() { result = "__is_assignable" } + + override string getAPrimaryQlClass() { result = "BuiltInOperationIsAssignable" } +} + /** * The `__is_standard_layout` built-in operation (used by some implementations * of the `` header). diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index 19e31bf071f..f214ac4d338 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -1650,6 +1650,7 @@ case @expr.kind of | 327 = @co_await | 328 = @co_yield | 329 = @temp_init +| 330 = @isassignable ; @var_args_expr = @vastartexpr @@ -1711,6 +1712,7 @@ case @expr.kind of | @isfinalexpr | @builtinchooseexpr | @builtincomplex + | @isassignable ; new_allocated_type( diff --git a/cpp/ql/test/library-tests/builtins/type_traits/expr.expected b/cpp/ql/test/library-tests/builtins/type_traits/expr.expected index 47918496198..4d59a3341f0 100644 --- a/cpp/ql/test/library-tests/builtins/type_traits/expr.expected +++ b/cpp/ql/test/library-tests/builtins/type_traits/expr.expected @@ -296,3 +296,12 @@ | ms.cpp:255:24:255:43 | a_struct | | | | ms.cpp:256:24:256:49 | __is_final | a_final_struct | 1 | | ms.cpp:256:24:256:49 | a_final_struct | | | +| ms.cpp:258:29:258:62 | __is_assignable | a_struct,a_struct | 1 | +| ms.cpp:258:29:258:62 | a_struct | | | +| ms.cpp:258:29:258:62 | a_struct | | | +| ms.cpp:259:29:259:59 | __is_assignable | a_struct,empty | 0 | +| ms.cpp:259:29:259:59 | a_struct | | | +| ms.cpp:259:29:259:59 | empty | | | +| ms.cpp:260:29:260:57 | __is_assignable | a_struct,int | 0 | +| ms.cpp:260:29:260:57 | a_struct | | | +| ms.cpp:260:29:260:57 | int | | | diff --git a/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp b/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp index 742f95faf07..aacd74e578a 100644 --- a/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp +++ b/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp @@ -254,5 +254,8 @@ void f(void) { bool b_is_final1 = __is_final(a_struct); bool b_is_final2 = __is_final(a_final_struct); -} + bool b_is_assignable1 = __is_assignable(a_struct,a_struct); + bool b_is_assignable2 = __is_assignable(a_struct,empty); + bool b_is_assignable3 = __is_assignable(a_struct,int); +} From 0c039354373f7005fe1aa7269ee861aa2978d241 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 Jul 2022 12:34:47 +0200 Subject: [PATCH 439/465] C++: Support `__is_aggregate` builtin Fix some whitespace issues while here. --- .../code/cpp/exprs/BuiltInOperations.qll | 36 +++++++++++++------ cpp/ql/lib/semmlecode.cpp.dbscheme | 2 ++ .../builtins/type_traits/expr.expected | 4 +++ .../library-tests/builtins/type_traits/ms.cpp | 3 ++ 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll index c794b574045..44550e13335 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll @@ -173,7 +173,7 @@ class BuiltInOperationHasAssign extends BuiltInOperation, @hasassignexpr { * * Returns `true` if the type has a copy constructor. * ``` - * std::integral_constant< bool, __has_copy(_Tp)> hc; + * std::integral_constant hc; * ``` */ class BuiltInOperationHasCopy extends BuiltInOperation, @hascopyexpr { @@ -189,7 +189,7 @@ class BuiltInOperationHasCopy extends BuiltInOperation, @hascopyexpr { * Returns `true` if a copy assignment operator has an empty exception * specification. * ``` - * std::integral_constant< bool, __has_nothrow_assign(_Tp)> hnta; + * std::integral_constant hnta; * ``` */ class BuiltInOperationHasNoThrowAssign extends BuiltInOperation, @hasnothrowassign { @@ -220,7 +220,7 @@ class BuiltInOperationHasNoThrowConstructor extends BuiltInOperation, @hasnothro * * Returns `true` if the copy constructor has an empty exception specification. * ``` - * std::integral_constant< bool, __has_nothrow_copy(MyType) >; + * std::integral_constant; * ``` */ class BuiltInOperationHasNoThrowCopy extends BuiltInOperation, @hasnothrowcopy { @@ -266,7 +266,7 @@ class BuiltInOperationHasTrivialConstructor extends BuiltInOperation, @hastrivia * * Returns true if the type has a trivial copy constructor. * ``` - * std::integral_constant< bool, __has_trivial_copy(MyType) > htc; + * std::integral_constant htc; * ``` */ class BuiltInOperationHasTrivialCopy extends BuiltInOperation, @hastrivialcopy { @@ -468,7 +468,7 @@ class BuiltInOperationIsUnion extends BuiltInOperation, @isunionexpr { * ``` * template * struct types_compatible - * : public integral_constant + * : public integral_constant * { }; * ``` */ @@ -547,7 +547,7 @@ class BuiltInOperationBuiltInAddressOf extends UnaryOperation, BuiltInOperation, * ``` * template * struct is_trivially_constructible - * : public integral_constant + * : public integral_constant * { }; * ``` */ @@ -701,7 +701,7 @@ class BuiltInOperationIsTriviallyCopyable extends BuiltInOperation, @istrivially * * ``` * template - * std::integral_constant< bool, __is_literal_type(_Tp)> ilt; + * std::integral_constant ilt; * ``` */ class BuiltInOperationIsLiteralType extends BuiltInOperation, @isliteraltypeexpr { @@ -718,7 +718,7 @@ class BuiltInOperationIsLiteralType extends BuiltInOperation, @isliteraltypeexpr * compiler, with semantics of the `memcpy` operation. * ``` * template - * std::integral_constant< bool, __has_trivial_move_constructor(_Tp)> htmc; + * std::integral_constant htmc; * ``` */ class BuiltInOperationHasTrivialMoveConstructor extends BuiltInOperation, @@ -736,7 +736,7 @@ class BuiltInOperationHasTrivialMoveConstructor extends BuiltInOperation, * ``` * template * struct has_trivial_move_assign - * : public integral_constant + * : public integral_constant * { }; * ``` */ @@ -771,7 +771,7 @@ class BuiltInOperationHasNothrowMoveAssign extends BuiltInOperation, @hasnothrow * ``` * template * struct is_constructible - * : public integral_constant + * : public integral_constant * { }; * ``` */ @@ -935,7 +935,7 @@ class BuiltInOperationIsValueClass extends BuiltInOperation, @isvalueclassexpr { * ``` * template * struct is_final - * : public integral_constant + * : public integral_constant * { }; * ``` */ @@ -991,3 +991,17 @@ class BuiltInComplexOperation extends BuiltInOperation, @builtincomplex { /** Gets the operand corresponding to the imaginary part of the complex number. */ Expr getImaginaryOperand() { this.hasChild(result, 1) } } + +/** + * A C++ `__is_aggregate` built-in operation (used by some implementations of the + * `` header). + * + * Returns `true` if the type has is an aggregate type. + * ``` + * std::integral_constant ia; + * ``` */ +class BuiltInOperationIsAggregate extends BuiltInOperation, @isaggregate { + override string toString() { result = "__is_aggregate" } + + override string getAPrimaryQlClass() { result = "BuiltInOperationIsAggregate" } +} diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index f214ac4d338..d438935e5ef 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -1651,6 +1651,7 @@ case @expr.kind of | 328 = @co_yield | 329 = @temp_init | 330 = @isassignable +| 331 = @isaggregate ; @var_args_expr = @vastartexpr @@ -1713,6 +1714,7 @@ case @expr.kind of | @builtinchooseexpr | @builtincomplex | @isassignable + | @isaggregate ; new_allocated_type( diff --git a/cpp/ql/test/library-tests/builtins/type_traits/expr.expected b/cpp/ql/test/library-tests/builtins/type_traits/expr.expected index 4d59a3341f0..10db02f8450 100644 --- a/cpp/ql/test/library-tests/builtins/type_traits/expr.expected +++ b/cpp/ql/test/library-tests/builtins/type_traits/expr.expected @@ -305,3 +305,7 @@ | ms.cpp:260:29:260:57 | __is_assignable | a_struct,int | 0 | | ms.cpp:260:29:260:57 | a_struct | | | | ms.cpp:260:29:260:57 | int | | | +| ms.cpp:262:28:262:51 | __is_aggregate | a_struct | 1 | +| ms.cpp:262:28:262:51 | a_struct | | | +| ms.cpp:263:28:263:46 | __is_aggregate | int | 0 | +| ms.cpp:263:28:263:46 | int | | | diff --git a/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp b/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp index aacd74e578a..6d8ea3c6161 100644 --- a/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp +++ b/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp @@ -258,4 +258,7 @@ void f(void) { bool b_is_assignable1 = __is_assignable(a_struct,a_struct); bool b_is_assignable2 = __is_assignable(a_struct,empty); bool b_is_assignable3 = __is_assignable(a_struct,int); + + bool b_is_aggregate1 = __is_aggregate(a_struct); + bool b_is_aggregate2 = __is_aggregate(int); } From a85d3f9b7f09656b327d8f7a44e24a4f7399a9b3 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 Jul 2022 12:46:35 +0200 Subject: [PATCH 440/465] C++: Support `__has_unique_object_representations` builtin --- .../code/cpp/exprs/BuiltInOperations.qll | 20 ++++++++++++++++++- cpp/ql/lib/semmlecode.cpp.dbscheme | 2 ++ .../builtins/type_traits/expr.expected | 4 ++++ .../library-tests/builtins/type_traits/ms.cpp | 3 +++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll index 44550e13335..cd361d0ac8f 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll @@ -999,9 +999,27 @@ class BuiltInComplexOperation extends BuiltInOperation, @builtincomplex { * Returns `true` if the type has is an aggregate type. * ``` * std::integral_constant ia; - * ``` */ + * ``` + */ class BuiltInOperationIsAggregate extends BuiltInOperation, @isaggregate { override string toString() { result = "__is_aggregate" } override string getAPrimaryQlClass() { result = "BuiltInOperationIsAggregate" } } + +/** + * A C++ `__has_unique_object_representations` built-in operation (used by some + * implementations of the `` header). + * + * Returns `true` if the type is trivially copyable and if the object representation + * is unique for two objects with the same value. + * ``` + * bool v = __has_unique_object_representations(MyType); + * ``` + */ +class BuiltInOperationHasUniqueObjectRepresentations extends BuiltInOperation, + @hasuniqueobjectrepresentations { + override string toString() { result = "__has_unique_object_representations" } + + override string getAPrimaryQlClass() { result = "BuiltInOperationHasUniqueObjectRepresentations" } +} diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index d438935e5ef..7fb82ddb3e3 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -1652,6 +1652,7 @@ case @expr.kind of | 329 = @temp_init | 330 = @isassignable | 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations ; @var_args_expr = @vastartexpr @@ -1715,6 +1716,7 @@ case @expr.kind of | @builtincomplex | @isassignable | @isaggregate + | @hasuniqueobjectrepresentations ; new_allocated_type( diff --git a/cpp/ql/test/library-tests/builtins/type_traits/expr.expected b/cpp/ql/test/library-tests/builtins/type_traits/expr.expected index 10db02f8450..a19d917aaac 100644 --- a/cpp/ql/test/library-tests/builtins/type_traits/expr.expected +++ b/cpp/ql/test/library-tests/builtins/type_traits/expr.expected @@ -309,3 +309,7 @@ | ms.cpp:262:28:262:51 | a_struct | | | | ms.cpp:263:28:263:46 | __is_aggregate | int | 0 | | ms.cpp:263:28:263:46 | int | | | +| ms.cpp:265:49:265:88 | __has_unique_object_representations | int | 1 | +| ms.cpp:265:49:265:88 | int | | | +| ms.cpp:266:49:266:90 | __has_unique_object_representations | float | 0 | +| ms.cpp:266:49:266:90 | float | | | diff --git a/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp b/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp index 6d8ea3c6161..91d6245cc35 100644 --- a/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp +++ b/cpp/ql/test/library-tests/builtins/type_traits/ms.cpp @@ -261,4 +261,7 @@ void f(void) { bool b_is_aggregate1 = __is_aggregate(a_struct); bool b_is_aggregate2 = __is_aggregate(int); + + bool b_has_unique_object_representations1 = __has_unique_object_representations(int); + bool b_has_unique_object_representations2 = __has_unique_object_representations(float); } From 81e687ea9854334ca8e85340033c664e91221043 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 Jul 2022 13:12:57 +0200 Subject: [PATCH 441/465] C++: Support `__builtin_bit_cast` builtin --- .../semmle/code/cpp/exprs/BuiltInOperations.qll | 15 +++++++++++++++ cpp/ql/lib/semmlecode.cpp.dbscheme | 2 ++ cpp/ql/test/library-tests/builtins/edg/edg.c | 5 ++++- .../test/library-tests/builtins/edg/expr.expected | 3 +++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll index cd361d0ac8f..6e413c64d7f 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll @@ -1023,3 +1023,18 @@ class BuiltInOperationHasUniqueObjectRepresentations extends BuiltInOperation, override string getAPrimaryQlClass() { result = "BuiltInOperationHasUniqueObjectRepresentations" } } + +/** + * A C/C++ `__builtin_bit_cast` built-in operation (used by some implementations + * of `std::bit_cast`). + * + * Performs a bit cast from a value to a type. + * ``` + * __builtin_bit_cast(Type, value); + * ``` + */ +class BuiltInBitCast extends BuiltInOperation, @builtinbitcast { + override string toString() { result = "__builtin_bit_cast" } + + override string getAPrimaryQlClass() { result = "BuiltInBitCast" } +} diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index 7fb82ddb3e3..f350bfc257f 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -1653,6 +1653,7 @@ case @expr.kind of | 330 = @isassignable | 331 = @isaggregate | 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast ; @var_args_expr = @vastartexpr @@ -1717,6 +1718,7 @@ case @expr.kind of | @isassignable | @isaggregate | @hasuniqueobjectrepresentations + | @builtinbitcast ; new_allocated_type( diff --git a/cpp/ql/test/library-tests/builtins/edg/edg.c b/cpp/ql/test/library-tests/builtins/edg/edg.c index d1a78435317..f1f0f0f1375 100644 --- a/cpp/ql/test/library-tests/builtins/edg/edg.c +++ b/cpp/ql/test/library-tests/builtins/edg/edg.c @@ -1,4 +1,4 @@ - +// semmle-extractor-options: --clang struct mystruct { int f1; int f2; @@ -13,3 +13,6 @@ void f(void) { int i2 = edg_offsetof(struct mystruct,f2); } +void g(void) { + double f = __builtin_bit_cast(double,42l); +} diff --git a/cpp/ql/test/library-tests/builtins/edg/expr.expected b/cpp/ql/test/library-tests/builtins/edg/expr.expected index 0969dc1e217..5ab0747ecc7 100644 --- a/cpp/ql/test/library-tests/builtins/edg/expr.expected +++ b/cpp/ql/test/library-tests/builtins/edg/expr.expected @@ -13,3 +13,6 @@ | edg.c:13:14:13:45 | (size_t)... | 0 | 0 | | edg.c:13:14:13:45 | __INTADDR__ | 1 | 1 | | edg.c:13:43:13:44 | f2 | 0 | 0 | +| edg.c:17:16:17:45 | __builtin_bit_cast | 1 | 1 | +| edg.c:17:16:17:45 | double | 0 | 0 | +| edg.c:17:42:17:44 | 42 | 1 | 1 | From 20b66eaf34fc2fa2b972610c39ac4b6afcb4fba9 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 Jul 2022 13:59:30 +0200 Subject: [PATCH 442/465] C++: Support `__builtin_shuffle` builtin While here write gcc instead of GNU, which is more accurate. --- .../code/cpp/exprs/BuiltInOperations.qll | 21 +++++++++++++++++-- cpp/ql/lib/semmlecode.cpp.dbscheme | 2 ++ .../vector_types/builtin_ops.expected | 2 ++ .../vector_types/variables.expected | 6 ++++++ .../vector_types/vector_types2.cpp | 12 +++++++++++ 5 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 cpp/ql/test/library-tests/vector_types/vector_types2.cpp diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll index 6e413c64d7f..866ed3c314a 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll @@ -121,7 +121,7 @@ class BuiltInNoOp extends BuiltInOperation, @noopexpr { /** * A C/C++ `__builtin_offsetof` built-in operation (used by some implementations * of `offsetof`). The operation retains its semantics even in the presence - * of an overloaded `operator &`). This is a GNU/Clang extension. + * of an overloaded `operator &`). This is a gcc/clang extension. * ``` * struct S { * int a, b; @@ -494,6 +494,23 @@ class BuiltInOperationBuiltInShuffleVector extends BuiltInOperation, @builtinshu override string getAPrimaryQlClass() { result = "BuiltInOperationBuiltInShuffleVector" } } +/** + * A gcc `__builtin_shuffle` expression. + * + * It outputs a permutation of elements from one or two input vectors. + * Please see https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html + * for more information. + * ``` + * // Concatenate every other element of 4-element vectors V1 and V2. + * V3 = __builtin_shufflevector(V1, V2, {0, 2, 4, 6}); + * ``` + */ +class BuiltInOperationBuiltInShuffle extends BuiltInOperation, @builtinshuffle { + override string toString() { result = "__builtin_shuffle" } + + override string getAPrimaryQlClass() { result = "BuiltInOperationBuiltInShuffle" } +} + /** * A clang `__builtin_convertvector` expression. * @@ -946,7 +963,7 @@ class BuiltInOperationIsFinal extends BuiltInOperation, @isfinalexpr { } /** - * The `__builtin_choose_expr` expression. This is a GNU/Clang extension. + * The `__builtin_choose_expr` expression. This is a gcc/clang extension. * * The expression functions similarly to the ternary `?:` operator, except * that it is evaluated at compile-time. diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index f350bfc257f..23f7cbb88a4 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -1654,6 +1654,7 @@ case @expr.kind of | 331 = @isaggregate | 332 = @hasuniqueobjectrepresentations | 333 = @builtinbitcast +| 334 = @builtinshuffle ; @var_args_expr = @vastartexpr @@ -1719,6 +1720,7 @@ case @expr.kind of | @isaggregate | @hasuniqueobjectrepresentations | @builtinbitcast + | @builtinshuffle ; new_allocated_type( diff --git a/cpp/ql/test/library-tests/vector_types/builtin_ops.expected b/cpp/ql/test/library-tests/vector_types/builtin_ops.expected index 2c0dd9d0017..756ca2f1c17 100644 --- a/cpp/ql/test/library-tests/vector_types/builtin_ops.expected +++ b/cpp/ql/test/library-tests/vector_types/builtin_ops.expected @@ -1,2 +1,4 @@ +| vector_types2.cpp:10:15:10:42 | __builtin_shuffle | +| vector_types2.cpp:11:15:11:45 | __builtin_shuffle | | vector_types.cpp:31:13:31:49 | __builtin_shufflevector | | vector_types.cpp:58:10:58:52 | __builtin_convertvector | diff --git a/cpp/ql/test/library-tests/vector_types/variables.expected b/cpp/ql/test/library-tests/vector_types/variables.expected index 2494f192e9a..52fa98dd3f0 100644 --- a/cpp/ql/test/library-tests/vector_types/variables.expected +++ b/cpp/ql/test/library-tests/vector_types/variables.expected @@ -13,6 +13,12 @@ | file://:0:0:0:0 | gp_offset | gp_offset | file://:0:0:0:0 | unsigned int | 4 | | file://:0:0:0:0 | overflow_arg_area | overflow_arg_area | file://:0:0:0:0 | void * | 8 | | file://:0:0:0:0 | reg_save_area | reg_save_area | file://:0:0:0:0 | void * | 8 | +| vector_types2.cpp:5:7:5:7 | a | a | vector_types2.cpp:2:13:2:15 | v4i | 16 | +| vector_types2.cpp:6:7:6:7 | b | b | vector_types2.cpp:2:13:2:15 | v4i | 16 | +| vector_types2.cpp:7:7:7:12 | mask_1 | mask_1 | vector_types2.cpp:2:13:2:15 | v4i | 16 | +| vector_types2.cpp:8:7:8:12 | mask_2 | mask_2 | vector_types2.cpp:2:13:2:15 | v4i | 16 | +| vector_types2.cpp:10:7:10:11 | res_1 | res_1 | vector_types2.cpp:2:13:2:15 | v4i | 16 | +| vector_types2.cpp:11:7:11:11 | res_2 | res_2 | vector_types2.cpp:2:13:2:15 | v4i | 16 | | vector_types.cpp:9:21:9:21 | x | x | vector_types.cpp:6:15:6:17 | v4f | 16 | | vector_types.cpp:14:18:14:20 | lhs | lhs | vector_types.cpp:6:15:6:17 | v4f | 16 | | vector_types.cpp:14:27:14:29 | rhs | rhs | vector_types.cpp:6:15:6:17 | v4f | 16 | diff --git a/cpp/ql/test/library-tests/vector_types/vector_types2.cpp b/cpp/ql/test/library-tests/vector_types/vector_types2.cpp new file mode 100644 index 00000000000..d4233b28890 --- /dev/null +++ b/cpp/ql/test/library-tests/vector_types/vector_types2.cpp @@ -0,0 +1,12 @@ +// semmle-extractor-options: --gnu --gnu_version 80000 +typedef int v4i __attribute__((vector_size (16))); + +void f() { + v4i a = {1,2,3,4}; + v4i b = {5,6,7,8}; + v4i mask_1 = {3,0,1,2}; + v4i mask_2 = {3,5,4,2}; + + v4i res_1 = __builtin_shuffle(a, mask_1); + v4i res_2 = __builtin_shuffle(a, b, mask_2); +} From 1806b8933f9271ebb47a7ee9783f19aece21e3d1 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 Jul 2022 16:26:40 +0200 Subject: [PATCH 443/465] C++: Add change note for newly added builtins --- .../lib/change-notes/2022-07-26-additional-builtin-support.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/lib/change-notes/2022-07-26-additional-builtin-support.md diff --git a/cpp/ql/lib/change-notes/2022-07-26-additional-builtin-support.md b/cpp/ql/lib/change-notes/2022-07-26-additional-builtin-support.md new file mode 100644 index 00000000000..2e4d7db69a5 --- /dev/null +++ b/cpp/ql/lib/change-notes/2022-07-26-additional-builtin-support.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Added subclasses of `BuiltInOperations` for `__builtin_bit_cast`, `__builtin_shuffle`, `__has_unique_object_representations`, `__is_aggregate`, and `__is_assignable`. From 295ecbb4016253db5943ea25a65f038ba81fd53f Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 Jul 2022 16:53:34 +0200 Subject: [PATCH 444/465] C++: Add upgrade and downgrade scripts for new builtins --- .../exprs.ql | 17 + .../old.dbscheme | 2125 +++++++++++++++++ .../semmlecode.cpp.dbscheme | 2115 ++++++++++++++++ .../upgrade.properties | 3 + .../old.dbscheme | 2115 ++++++++++++++++ .../semmlecode.cpp.dbscheme | 2125 +++++++++++++++++ .../upgrade.properties | 2 + 7 files changed, 8502 insertions(+) create mode 100644 cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/exprs.ql create mode 100644 cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/old.dbscheme create mode 100644 cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/semmlecode.cpp.dbscheme create mode 100644 cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/upgrade.properties create mode 100644 cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/old.dbscheme create mode 100644 cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/semmlecode.cpp.dbscheme create mode 100644 cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/upgrade.properties diff --git a/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/exprs.ql b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/exprs.ql new file mode 100644 index 00000000000..d00685e7cc6 --- /dev/null +++ b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/exprs.ql @@ -0,0 +1,17 @@ +class Expr extends @expr { + string toString() { none() } +} + +class Location extends @location_expr { + string toString() { none() } +} + +predicate isExprWithNewBuiltin(Expr expr) { + exists(int kind | exprs(expr, kind, _) | 330 <= kind and kind <= 334) +} + +from Expr expr, int kind, int kind_new, Location location +where + exprs(expr, kind, location) and + if isExprWithNewBuiltin(expr) then kind_new = 0 else kind_new = kind +select expr, kind_new, location diff --git a/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/old.dbscheme b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/old.dbscheme new file mode 100644 index 00000000000..23f7cbb88a4 --- /dev/null +++ b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/old.dbscheme @@ -0,0 +1,2125 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/semmlecode.cpp.dbscheme b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..19e31bf071f --- /dev/null +++ b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/semmlecode.cpp.dbscheme @@ -0,0 +1,2115 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/upgrade.properties b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/upgrade.properties new file mode 100644 index 00000000000..d697a16a42f --- /dev/null +++ b/cpp/downgrades/23f7cbb88a4eb29f30c3490363dc201bc054c5ff/upgrade.properties @@ -0,0 +1,3 @@ +description: Add new builtin operations +compatibility: partial +exprs.rel: run exprs.qlo diff --git a/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/old.dbscheme b/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/old.dbscheme new file mode 100644 index 00000000000..19e31bf071f --- /dev/null +++ b/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/old.dbscheme @@ -0,0 +1,2115 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/semmlecode.cpp.dbscheme new file mode 100644 index 00000000000..23f7cbb88a4 --- /dev/null +++ b/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/semmlecode.cpp.dbscheme @@ -0,0 +1,2125 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +/* + case @macroinvocations.kind of + 1 = macro expansion + | 2 = other macro reference + ; +*/ +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* + case @function.kind of + 1 = normal + | 2 = constructor + | 3 = destructor + | 4 = conversion + | 5 = operator + | 6 = builtin // GCC built-in functions, e.g. __builtin___memcpy_chk + ; +*/ +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point(int id: @function ref, unique int entry_point: @stmt ref); + +function_return_type(int id: @function ref, int return_type: @type ref); + +/** If `function` is a coroutine, then this gives the + std::experimental::resumable_traits instance associated with it, + and the variables representing the `handle` and `promise` for it. */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type(unique int id: @function ref, int this_type: @type ref); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides(int new: @function ref, int old: @function ref); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/* + Built-in types are the fundamental types, e.g., integral, floating, and void. + + case @builtintype.kind of + 1 = error + | 2 = unknown + | 3 = void + | 4 = boolean + | 5 = char + | 6 = unsigned_char + | 7 = signed_char + | 8 = short + | 9 = unsigned_short + | 10 = signed_short + | 11 = int + | 12 = unsigned_int + | 13 = signed_int + | 14 = long + | 15 = unsigned_long + | 16 = signed_long + | 17 = long_long + | 18 = unsigned_long_long + | 19 = signed_long_long + | 20 = __int8 // Microsoft-specific + | 21 = __int16 // Microsoft-specific + | 22 = __int32 // Microsoft-specific + | 23 = __int64 // Microsoft-specific + | 24 = float + | 25 = double + | 26 = long_double + | 27 = _Complex_float // C99-specific + | 28 = _Complex_double // C99-specific + | 29 = _Complex_long double // C99-specific + | 30 = _Imaginary_float // C99-specific + | 31 = _Imaginary_double // C99-specific + | 32 = _Imaginary_long_double // C99-specific + | 33 = wchar_t // Microsoft-specific + | 34 = decltype_nullptr // C++11 + | 35 = __int128 + | 36 = unsigned___int128 + | 37 = signed___int128 + | 38 = __float128 + | 39 = _Complex___float128 + | 40 = _Decimal32 + | 41 = _Decimal64 + | 42 = _Decimal128 + | 43 = char16_t + | 44 = char32_t + | 45 = _Float32 + | 46 = _Float32x + | 47 = _Float64 + | 48 = _Float64x + | 49 = _Float128 + | 50 = _Float128x + | 51 = char8_t + ; +*/ +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/* + Derived types are types that are directly derived from existing types and + point to, refer to, transform type data to return a new type. + + case @derivedtype.kind of + 1 = pointer + | 2 = reference + | 3 = type_with_specifiers + | 4 = array + | 5 = gnu_vector + | 6 = routineptr + | 7 = routinereference + | 8 = rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated + | 10 = block + ; +*/ +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* + case @usertype.kind of + 1 = struct + | 2 = class + | 3 = union + | 4 = enum + | 5 = typedef // classic C: typedef typedef type name + | 6 = template + | 7 = template_parameter + | 8 = template_template_parameter + | 9 = proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated + | 13 = scoped_enum + | 14 = using_alias // a using name = type style typedef + ; +*/ +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the EDG frontend. See symbol_ref.h there. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall(unique int caller: @funbindexpr ref, int kind: int ref); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // EDG internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. + */ +#keyset[aggregate, field] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. + */ +#keyset[aggregate, element_index] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string URI: string ref, + int fileid: @file ref +); + +xmlHasNs( + int elementId: @xmlnamespaceable ref, + int nsId: @xmlnamespace ref, + int fileid: @file ref +); + +xmlComments( + unique int id: @xmlcomment, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string text: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int isCDATA: int ref, + int fileid: @file ref +); + +@xmlparent = @file | @xmlelement; +@xmlnamespaceable = @xmlelement | @xmlattribute; + +xmllocations( + int xmlElement: @xmllocatable ref, + int location: @location_default ref +); + +@xmllocatable = @xmlcharacters + | @xmlelement + | @xmlcomment + | @xmlattribute + | @xmldtd + | @file + | @xmlnamespace; diff --git a/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/upgrade.properties b/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/upgrade.properties new file mode 100644 index 00000000000..db0e7e92d0e --- /dev/null +++ b/cpp/ql/lib/upgrades/19e31bf071f588bb7efd1e4d5a185ce4f6fbbd84/upgrade.properties @@ -0,0 +1,2 @@ +description: Add new builtin operations +compatibility: backwards From afdd21eab7acbac11975ec20c5f09b4ed041ca05 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 26 Jul 2022 20:52:36 +0200 Subject: [PATCH 445/465] C++: Update DB scheme stats file --- cpp/ql/lib/semmlecode.cpp.dbscheme.stats | 5604 +++++++++++----------- 1 file changed, 2707 insertions(+), 2897 deletions(-) diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats index e439c5ac624..35eb9c7e6de 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats @@ -2,79 +2,79 @@ @compilation - 9980 + 9978 @externalDataElement 65 - - @svnentry - 575525 - @external_package 4 + + @svnentry + 575525 + @location_stmt - 3805462 + 3805465 @diagnostic - 582773 + 72312 @file - 124189 + 124196 @folder 15994 - @location_expr - 13128112 + @location_default + 30132211 - @location_default - 30128761 + @location_expr + 13128120 @macroinvocation - 33894981 + 33889080 @function - 4726273 + 4726519 @fun_decl - 5096962 + 5097227 @type_decl - 3283977 + 3284148 @namespace_decl - 306972 + 306973 @using - 374921 + 374941 @static_assert - 130417 + 130418 @var_decl - 8543232 + 8543677 @parameter - 6660155 + 6660502 @membervariable @@ -82,7 +82,7 @@ @globalvariable - 300708 + 318724 @localvariable @@ -94,55 +94,55 @@ @builtintype - 22109 + 22110 @derivedtype - 4413446 + 4413676 @decltype - 31047 + 31049 @usertype - 5342989 + 5343268 @mangledname - 1728010 + 1975901 @type_mention - 4011508 + 4011511 @routinetype - 546982 + 546661 @ptrtomember - 38103 + 38105 @specifier - 24932 + 24933 @gnuattribute - 664228 + 664262 @stdattribute - 468982 + 469081 @alignas - 8937 + 8938 @declspec - 238544 + 238545 @msattribute @@ -150,11 +150,11 @@ @attribute_arg_token - 25402 + 25403 @attribute_arg_constant - 326469 + 326486 @attribute_arg_type @@ -166,15 +166,15 @@ @derivation - 402388 + 402152 @frienddecl - 715075 + 714656 @comment - 8781270 + 8783134 @namespace @@ -186,23 +186,23 @@ @namequalifier - 1618961 + 1618866 @value - 10646146 + 10646153 @initialiser - 1731824 + 1732353 @lambdacapture - 28224 + 28226 @stmt_expr - 1480414 + 1480415 @stmt_if @@ -210,23 +210,23 @@ @stmt_while - 30207 + 30201 @stmt_label - 53046 + 53044 @stmt_return - 1306346 + 1306414 @stmt_block - 1446530 + 1446605 @stmt_end_test_while - 148604 + 148599 @stmt_for @@ -234,7 +234,7 @@ @stmt_switch_case - 191408 + 191399 @stmt_switch @@ -242,11 +242,11 @@ @stmt_try_block - 42701 + 42699 @stmt_decl - 608508 + 608387 @stmt_empty @@ -258,7 +258,7 @@ @stmt_break - 102231 + 102232 @stmt_range_based_for @@ -266,15 +266,15 @@ @stmt_handler - 59432 + 59429 @stmt_constexpr_if - 52551 + 52562 @stmt_goto - 110490 + 110487 @stmt_asm @@ -310,43 +310,43 @@ @ctordirectinit - 112813 + 112747 @ctorvirtualinit - 6534 + 6532 @ctorfieldinit - 200789 + 200671 @ctordelegatinginit - 3347 + 3345 @dtordirectdestruct - 41715 + 41690 @dtorvirtualdestruct - 4122 + 4119 @dtorfielddestruct - 41644 + 41620 @static_cast - 211821 + 211675 @reinterpret_cast - 30776 + 30783 @const_cast - 35278 + 35285 @dynamic_cast @@ -354,19 +354,19 @@ @c_style_cast - 4209393 + 4209396 @lambdaexpr - 21639 + 21640 @param_ref - 375289 + 375271 @errorexpr - 46823 + 46796 @address_of @@ -374,27 +374,27 @@ @reference_to - 1596143 + 1596067 @indirect - 292115 + 292106 @ref_indirect - 1934537 + 1938685 @array_to_pointer - 1424883 + 1424884 @vacuous_destructor_call - 8138 + 8133 @parexpr - 3572547 + 3572549 @arithnegexpr @@ -402,11 +402,11 @@ @complementexpr - 27787 + 27786 @notexpr - 277992 + 277993 @postincrexpr @@ -446,11 +446,11 @@ @remexpr - 15819 + 15810 @paddexpr - 86505 + 86502 @psubexpr @@ -458,7 +458,7 @@ @pdiffexpr - 35487 + 35495 @lshiftexpr @@ -490,11 +490,11 @@ @gtexpr - 100669 + 100674 @ltexpr - 106314 + 106319 @geexpr @@ -502,11 +502,11 @@ @leexpr - 212141 + 212134 @assignexpr - 933419 + 933420 @assignaddexpr @@ -518,7 +518,7 @@ @assignmulexpr - 7170 + 7168 @assigndivexpr @@ -546,7 +546,7 @@ @assignxorexpr - 21804 + 21803 @assignpaddexpr @@ -554,7 +554,7 @@ @andlogicalexpr - 249008 + 249009 @orlogicalexpr @@ -562,7 +562,7 @@ @commaexpr - 181539 + 181530 @subscriptexpr @@ -570,7 +570,7 @@ @callexpr - 309063 + 309079 @vastartexpr @@ -586,27 +586,27 @@ @varaccess - 6006364 + 6006368 @thisaccess - 1125914 + 1125919 @new_expr - 47598 + 47571 @delete_expr - 11732 + 11725 @throw_expr - 21765 + 21760 @condition_decl - 38595 + 38593 @braced_init_list @@ -614,7 +614,7 @@ @type_id - 36430 + 36408 @runtime_sizeof @@ -622,15 +622,15 @@ @runtime_alignof - 48550 + 48521 @sizeof_pack - 5644 + 5645 @routineexpr - 3047613 + 3047738 @type_operand @@ -642,7 +642,7 @@ @ispodexpr - 636 + 635 @hastrivialdestructor @@ -666,23 +666,23 @@ @isconstructibleexpr - 2721 + 2722 @isfinalexpr - 2093 + 2094 @noexceptexpr - 23574 + 23573 @builtinaddressof - 13282 + 13274 @temp_init - 760683 + 760646 @assume @@ -826,7 +826,7 @@ @typescompexpr - 562415 + 562416 @intaddrexpr @@ -846,7 +846,7 @@ @istriviallyconstructibleexpr - 2826 + 2827 @isdestructibleexpr @@ -866,7 +866,7 @@ @isnothrowassignableexpr - 2093 + 2094 @isstandardlayoutexpr @@ -890,7 +890,7 @@ @isnothrowconstructibleexpr - 4815 + 4816 @hasfinalizerexpr @@ -956,45 +956,65 @@ @co_yield 1 + + @isassignable + 2617 + + + @isaggregate + 2 + + + @hasuniqueobjectrepresentations + 2 + + + @builtinbitcast + 1 + + + @builtinshuffle + 1965 + @ppd_if - 672225 + 672260 @ppd_ifdef - 265314 + 265328 @ppd_ifndef - 268607 + 268621 @ppd_elif - 25402 + 25403 @ppd_else - 210746 + 210757 @ppd_endif - 1206147 + 1206210 @ppd_plain_include - 313767 + 313784 @ppd_define - 2435252 + 2435769 @ppd_undef - 262021 + 262035 @ppd_pragma - 312270 + 312337 @ppd_include_next @@ -1048,11 +1068,11 @@ compilations - 9980 + 9978 id - 9980 + 9978 cwd @@ -1070,7 +1090,7 @@ 1 2 - 9980 + 9978 @@ -1644,7 +1664,7 @@ seconds - 12490 + 9586 @@ -1725,48 +1745,48 @@ 3 4 - 198 + 715 4 5 - 795 + 278 - 5 - 9 + 6 + 8 159 - 9 + 8 + 10 + 159 + + + 10 11 - 119 + 79 11 12 - 198 - - - 13 - 18 159 - 18 - 22 + 17 + 19 + 159 + + + 20 + 27 + 159 + + + 40 + 77 119 - - 22 - 46 - 159 - - - 60 - 104 - 79 - @@ -1833,12 +1853,12 @@ 3 4 - 556 + 835 4 5 - 1233 + 914 5 @@ -1848,32 +1868,27 @@ 6 7 - 119 + 437 7 8 - 318 + 79 8 9 - 119 + 278 9 - 11 + 26 278 - 11 - 31 - 278 - - - 40 - 95 - 159 + 26 + 92 + 238 @@ -1919,18 +1934,23 @@ 12 - 4 - 5 - 79 - - - 152 - 153 + 3 + 4 39 - 160 - 161 + 4 + 5 + 39 + + + 112 + 113 + 39 + + + 129 + 130 39 @@ -1947,22 +1967,27 @@ 1 2 - 7875 + 5449 2 3 - 2704 + 1670 3 4 - 1312 + 1272 4 - 45 - 596 + 5 + 676 + + + 5 + 42 + 517 @@ -1978,27 +2003,32 @@ 1 2 - 6682 + 5091 2 3 - 3142 + 1392 3 4 - 1431 - - - 4 - 6 954 - 6 - 65 - 278 + 4 + 5 + 875 + + + 5 + 7 + 795 + + + 7 + 67 + 477 @@ -2014,12 +2044,12 @@ 1 2 - 12251 + 9307 2 3 - 238 + 278 @@ -2029,23 +2059,23 @@ diagnostic_for - 1031027 + 891808 diagnostic - 582773 + 72312 compilation - 1988 + 9585 file_number - 104 + 11 file_number_diagnostic_number - 104788 + 6856 @@ -2059,27 +2089,17 @@ 1 2 - 362937 + 9631 2 3 - 92540 + 59836 - 3 - 4 - 70033 - - - 4 - 6 - 47421 - - - 6 - 9 - 9840 + 254 + 825 + 2844 @@ -2095,7 +2115,7 @@ 1 2 - 582773 + 72312 @@ -2111,22 +2131,7 @@ 1 2 - 475263 - - - 2 - 3 - 50143 - - - 3 - 6 - 53702 - - - 6 - 7 - 3663 + 72312 @@ -2135,222 +2140,6 @@ compilation diagnostic - - - 12 - - - 32 - 33 - 104 - - - 37 - 38 - 104 - - - 77 - 78 - 104 - - - 78 - 79 - 104 - - - 155 - 156 - 104 - - - 359 - 360 - 104 - - - 418 - 419 - 104 - - - 436 - 437 - 104 - - - 509 - 510 - 104 - - - 571 - 572 - 104 - - - 639 - 640 - 104 - - - 756 - 757 - 628 - - - 1001 - 1002 - 209 - - - - - - - compilation - file_number - - - 12 - - - 1 - 2 - 1988 - - - - - - - compilation - file_number_diagnostic_number - - - 12 - - - 32 - 33 - 104 - - - 37 - 38 - 104 - - - 77 - 78 - 104 - - - 78 - 79 - 104 - - - 155 - 156 - 104 - - - 359 - 360 - 104 - - - 418 - 419 - 104 - - - 436 - 437 - 104 - - - 509 - 510 - 104 - - - 571 - 572 - 104 - - - 639 - 640 - 104 - - - 756 - 757 - 628 - - - 1001 - 1002 - 209 - - - - - - - file_number - diagnostic - - - 12 - - - 5567 - 5568 - 104 - - - - - - - file_number - compilation - - - 12 - - - 19 - 20 - 104 - - - - - - - file_number - file_number_diagnostic_number - - - 12 - - - 1001 - 1002 - 104 - - - - - - - file_number_diagnostic_number - diagnostic 12 @@ -2358,37 +2147,193 @@ 2 3 - 25647 + 57 7 8 - 10991 + 6093 8 9 - 13085 + 497 - 9 - 10 - 13608 + 247 + 248 + 1965 - 10 - 11 - 27741 + 263 + 444 + 763 - 11 - 12 - 5652 + 446 + 594 + 208 + + + + + + + compilation + file_number + + + 12 + + + 1 + 2 + 9585 + + + + + + + compilation + file_number_diagnostic_number + + + 12 + + + 2 + 3 + 57 - 12 - 15 - 8060 + 7 + 8 + 6093 + + + 8 + 9 + 497 + + + 247 + 248 + 1965 + + + 263 + 444 + 763 + + + 446 + 594 + 208 + + + + + + + file_number + diagnostic + + + 12 + + + 6254 + 6255 + 11 + + + + + + + file_number + compilation + + + 12 + + + 829 + 830 + 11 + + + + + + + file_number + file_number_diagnostic_number + + + 12 + + + 593 + 594 + 11 + + + + + + + file_number_diagnostic_number + diagnostic + + + 12 + + + 1 + 2 + 2821 + + + 2 + 5 + 601 + + + 5 + 6 + 1017 + + + 7 + 14 + 543 + + + 15 + 16 + 57 + + + 17 + 18 + 601 + + + 18 + 23 + 462 + + + 26 + 40 + 555 + + + 42 + 830 + 196 @@ -2402,49 +2347,54 @@ 12 - 2 - 3 - 25647 - - - 8 + 4 9 - 12247 - - - 9 - 10 - 7118 + 589 10 11 - 6490 - - - 11 - 13 - 9526 - - - 13 - 14 - 6176 + 1005 14 - 15 - 21355 + 27 + 543 - 15 - 16 - 8060 + 30 + 31 + 57 - 16 - 20 - 8165 + 34 + 35 + 601 + + + 36 + 45 + 462 + + + 52 + 79 + 555 + + + 84 + 85 + 185 + + + 254 + 255 + 2763 + + + 297 + 830 + 92 @@ -2460,7 +2410,7 @@ 1 2 - 104788 + 6856 @@ -2470,19 +2420,19 @@ compilation_finished - 9980 + 9978 id - 9980 + 9978 cpu_seconds - 7956 + 7850 elapsed_seconds - 138 + 161 @@ -2496,7 +2446,7 @@ 1 2 - 9980 + 9978 @@ -2512,7 +2462,7 @@ 1 2 - 9980 + 9978 @@ -2528,17 +2478,17 @@ 1 2 - 6777 + 6498 2 3 - 786 + 1005 3 - 17 - 393 + 15 + 346 @@ -2554,12 +2504,12 @@ 1 2 - 7505 + 7423 2 3 - 451 + 427 @@ -2572,10 +2522,15 @@ 12 + + 1 + 2 + 23 + 2 3 - 23 + 11 3 @@ -2583,43 +2538,43 @@ 23 - 9 - 10 + 8 + 9 + 23 + + + 11 + 12 11 - 14 - 15 + 24 + 25 11 - 22 - 23 + 49 + 50 11 - 37 - 38 + 104 + 105 11 - 144 - 145 + 155 + 156 11 - 162 - 163 + 239 + 240 11 - 222 - 223 - 11 - - - 243 - 244 + 255 + 256 11 @@ -2633,10 +2588,15 @@ 12 + + 1 + 2 + 23 + 2 3 - 23 + 11 3 @@ -2644,43 +2604,43 @@ 23 - 9 - 10 + 8 + 9 + 23 + + + 11 + 12 11 - 14 - 15 + 24 + 25 11 - 22 - 23 + 49 + 50 11 - 36 - 37 + 104 + 105 11 - 118 - 119 + 111 + 112 11 - 123 - 124 + 174 + 175 11 - 177 - 178 - 11 - - - 218 - 219 + 217 + 218 11 @@ -4405,31 +4365,31 @@ locations_default - 30128761 + 30132211 id - 30128761 + 30132211 container - 140184 + 140191 startLine - 2114992 + 2115102 startColumn - 37162 + 37164 endLine - 2117814 + 2117925 endColumn - 48452 + 48455 @@ -4443,7 +4403,7 @@ 1 2 - 30128761 + 30132211 @@ -4459,7 +4419,7 @@ 1 2 - 30128761 + 30132211 @@ -4475,7 +4435,7 @@ 1 2 - 30128761 + 30132211 @@ -4491,7 +4451,7 @@ 1 2 - 30128761 + 30132211 @@ -4507,7 +4467,7 @@ 1 2 - 30128761 + 30132211 @@ -4523,67 +4483,67 @@ 1 2 - 16464 + 16465 2 12 - 10819 + 10820 13 20 - 11760 + 11761 21 36 - 11289 + 11290 36 55 - 11289 + 11290 55 77 - 10819 + 10820 77 102 - 10819 + 10820 102 149 - 10819 + 10820 149 227 - 11289 + 11290 228 350 - 11289 + 10820 - 358 - 628 - 10819 + 351 + 604 + 10820 - 671 - 1926 - 10819 + 627 + 1479 + 10820 - 2168 + 1925 2380 - 1881 + 2352 @@ -4599,62 +4559,62 @@ 1 2 - 16464 + 16465 2 9 - 10819 + 10820 9 16 - 11760 + 11761 16 25 - 11289 + 11290 25 40 - 10819 + 10820 40 57 - 10819 + 10820 58 72 - 10819 + 10820 73 103 - 11289 + 11290 106 141 - 11760 + 11761 148 226 - 11289 + 11290 226 373 - 10819 + 10820 381 1456 - 10819 + 10820 1464 @@ -4675,62 +4635,62 @@ 1 2 - 16464 + 16465 2 4 - 8937 + 8938 4 5 - 7526 + 7527 5 6 - 7526 + 7527 6 8 - 11760 + 11761 8 13 - 12230 + 12231 13 17 - 10819 + 10820 17 25 - 11289 + 11290 25 31 - 11760 + 11761 31 38 - 10819 + 10820 38 52 - 10819 + 10820 52 64 - 10819 + 10820 65 @@ -4751,62 +4711,62 @@ 1 2 - 16464 + 16465 2 9 - 10819 + 10820 9 16 - 11760 + 11761 16 25 - 11289 + 11290 25 40 - 10819 + 10820 40 57 - 10819 + 10820 58 71 - 10819 + 10820 72 98 - 10819 + 10820 101 140 - 11760 + 11761 140 224 - 10819 + 10820 224 360 - 10819 + 10820 364 1185 - 10819 + 10820 1254 @@ -4827,27 +4787,27 @@ 1 2 - 16464 + 16465 2 10 - 11289 + 11290 10 14 - 10819 + 10820 14 21 - 11289 + 11290 22 31 - 11289 + 11290 31 @@ -4857,27 +4817,27 @@ 39 48 - 12230 + 12231 48 56 - 11760 + 11761 56 64 - 11760 + 11761 64 72 - 10819 + 10820 72 77 - 11289 + 11290 77 @@ -4898,47 +4858,47 @@ 1 2 - 581905 + 581935 2 3 - 318001 + 318018 3 4 - 199456 + 199466 4 6 - 160882 + 160890 6 10 - 190048 + 190058 10 16 - 166057 + 166065 16 25 - 168879 + 168888 25 46 - 163704 + 163713 46 169 - 159000 + 159009 170 @@ -4959,42 +4919,42 @@ 1 2 - 869799 + 869845 2 3 - 280838 + 280853 3 5 - 191459 + 191469 5 8 - 181110 + 181119 8 12 - 162293 + 162302 12 18 - 166527 + 166536 18 39 - 159941 + 159949 39 299 - 103021 + 103026 @@ -5010,47 +4970,47 @@ 1 2 - 612482 + 612514 2 3 - 313297 + 313313 3 4 - 202749 + 202760 4 6 - 184403 + 184412 6 9 - 180639 + 180649 9 13 - 166997 + 167006 13 19 - 173583 + 173592 19 29 - 167468 + 167476 29 52 - 113370 + 113376 @@ -5066,22 +5026,22 @@ 1 2 - 1545788 + 1545868 2 3 - 351401 + 351419 3 5 - 164645 + 164654 5 16 - 53157 + 53159 @@ -5097,47 +5057,47 @@ 1 2 - 586609 + 586639 2 3 - 318942 + 318958 3 4 - 201808 + 201819 4 6 - 167468 + 167476 6 9 - 160412 + 160420 9 14 - 178287 + 178297 14 21 - 176406 + 176415 21 32 - 163234 + 163243 32 61 - 159000 + 159009 61 @@ -5212,7 +5172,7 @@ 819 - 1546 + 1548 2822 @@ -5244,7 +5204,7 @@ 23 35 - 3292 + 3293 38 @@ -5263,23 +5223,23 @@ 73 - 83 - 2822 + 84 + 3293 - 83 - 95 - 2822 + 84 + 97 + 3293 - 96 + 98 101 - 3292 + 2352 101 105 - 3292 + 3293 106 @@ -5369,7 +5329,7 @@ 587 - 831 + 832 2822 @@ -5482,12 +5442,12 @@ 7 11 - 3292 + 3293 11 16 - 3292 + 3293 16 @@ -5502,7 +5462,7 @@ 24 27 - 3292 + 3293 28 @@ -5512,7 +5472,7 @@ 33 40 - 3292 + 3293 40 @@ -5553,52 +5513,52 @@ 1 2 - 589902 + 589932 2 3 - 312356 + 312372 3 4 - 198986 + 198996 4 6 - 161352 + 161361 6 10 - 189577 + 189587 10 16 - 163704 + 163713 16 25 - 171231 + 170770 25 45 - 159471 + 159949 45 160 - 159941 + 159949 160 299 - 11289 + 11290 @@ -5614,47 +5574,47 @@ 1 2 - 881560 + 881606 2 3 - 270019 + 270033 3 4 - 123249 + 123255 4 6 - 142065 + 142073 6 10 - 195693 + 195703 10 15 - 168409 + 168417 15 26 - 165586 + 165595 26 120 - 159471 + 159479 121 299 - 11760 + 11761 @@ -5670,22 +5630,22 @@ 1 2 - 1538732 + 1538812 2 3 - 349048 + 349067 3 5 - 172172 + 172181 5 10 - 57861 + 57864 @@ -5701,47 +5661,47 @@ 1 2 - 621890 + 621922 2 3 - 304359 + 304375 3 4 - 204631 + 204641 4 6 - 186755 + 186765 6 9 - 177817 + 177826 9 13 - 169349 + 169358 13 19 - 174524 + 174533 19 29 - 162764 + 162772 29 52 - 115722 + 115728 @@ -5757,47 +5717,47 @@ 1 2 - 596488 + 596519 2 3 - 311415 + 311431 3 4 - 198986 + 198996 4 6 - 171701 + 171710 6 9 - 157589 + 157597 9 14 - 173583 + 173592 14 21 - 180169 + 180178 21 32 - 165116 + 165124 32 60 - 159000 + 159009 60 @@ -5862,7 +5822,7 @@ 879 - 1081 + 1082 3763 @@ -5871,7 +5831,7 @@ 3763 - 1309 + 1310 1590 3763 @@ -5894,7 +5854,7 @@ 1 2 - 5644 + 5645 2 @@ -5970,7 +5930,7 @@ 1 2 - 5644 + 5645 2 @@ -6009,7 +5969,7 @@ 575 - 628 + 627 3763 @@ -6081,7 +6041,7 @@ 35 39 - 3292 + 3293 39 @@ -6122,7 +6082,7 @@ 1 2 - 5644 + 5645 2 @@ -6192,11 +6152,11 @@ locations_stmt - 3805462 + 3805465 id - 3805462 + 3805465 container @@ -6230,7 +6190,7 @@ 1 2 - 3805462 + 3805465 @@ -6246,7 +6206,7 @@ 1 2 - 3805462 + 3805465 @@ -6262,7 +6222,7 @@ 1 2 - 3805462 + 3805465 @@ -6278,7 +6238,7 @@ 1 2 - 3805462 + 3805465 @@ -6294,7 +6254,7 @@ 1 2 - 3805462 + 3805465 @@ -6958,7 +6918,7 @@ 10 11 - 10500 + 10501 11 @@ -8174,11 +8134,11 @@ locations_expr - 13128112 + 13128120 id - 13128112 + 13128120 container @@ -8212,7 +8172,7 @@ 1 2 - 13128112 + 13128120 @@ -8228,7 +8188,7 @@ 1 2 - 13128112 + 13128120 @@ -8244,7 +8204,7 @@ 1 2 - 13128112 + 13128120 @@ -8260,7 +8220,7 @@ 1 2 - 13128112 + 13128120 @@ -8276,7 +8236,7 @@ 1 2 - 13128112 + 13128120 @@ -10096,23 +10056,23 @@ numlines - 1406545 + 1406618 element_id - 1399488 + 1399561 num_lines - 102550 + 102556 num_code - 85615 + 85620 num_comment - 60213 + 60216 @@ -10126,7 +10086,7 @@ 1 2 - 1392432 + 1392505 2 @@ -10147,7 +10107,7 @@ 1 2 - 1393373 + 1393446 2 @@ -10168,7 +10128,7 @@ 1 2 - 1399488 + 1399561 @@ -10184,17 +10144,17 @@ 1 2 - 68680 + 68684 2 3 - 12230 + 12231 3 4 - 7526 + 7527 4 @@ -10220,12 +10180,12 @@ 1 2 - 71032 + 71036 2 3 - 12230 + 12231 3 @@ -10256,22 +10216,22 @@ 1 2 - 70092 + 70095 2 3 - 15053 + 15054 3 4 - 10819 + 10820 4 7 - 6585 + 6586 @@ -10287,22 +10247,22 @@ 1 2 - 53157 + 53159 2 3 - 14582 + 14583 3 5 - 6585 + 6586 5 42 - 6585 + 6586 44 @@ -10323,12 +10283,12 @@ 1 2 - 53157 + 53159 2 3 - 16934 + 16935 3 @@ -10338,7 +10298,7 @@ 5 8 - 6585 + 6586 8 @@ -10359,7 +10319,7 @@ 1 2 - 53627 + 53630 2 @@ -10369,7 +10329,7 @@ 3 5 - 7526 + 7527 5 @@ -10379,7 +10339,7 @@ 7 10 - 3292 + 3293 @@ -10395,7 +10355,7 @@ 1 2 - 34810 + 34812 2 @@ -10436,7 +10396,7 @@ 1 2 - 34810 + 34812 2 @@ -10477,7 +10437,7 @@ 1 2 - 34810 + 34812 2 @@ -10512,31 +10472,31 @@ diagnostics - 582773 + 72312 id - 582773 + 72312 severity - 209 + 23 error_tag - 7851 + 80 error_message - 56215 + 127 full_error_message - 582040 + 62738 location - 369218 + 150 @@ -10550,7 +10510,7 @@ 1 2 - 582773 + 72312 @@ -10566,7 +10526,7 @@ 1 2 - 582773 + 72312 @@ -10582,7 +10542,7 @@ 1 2 - 582773 + 72312 @@ -10598,7 +10558,7 @@ 1 2 - 582773 + 72312 @@ -10614,7 +10574,7 @@ 1 2 - 582773 + 72312 @@ -10628,14 +10588,14 @@ 12 - 254 - 255 - 104 + 4 + 5 + 11 - 5313 - 5314 - 104 + 6250 + 6251 + 11 @@ -10649,14 +10609,14 @@ 12 - 5 - 6 - 104 + 1 + 2 + 11 - 70 - 71 - 104 + 6 + 7 + 11 @@ -10669,508 +10629,388 @@ 12 - - 7 - 8 - 104 - - - 530 - 531 - 104 - - - - - - - severity - full_error_message - - - 12 - - - 254 - 255 - 104 - - - 5306 - 5307 - 104 - - - - - - - severity - location - - - 12 - - - 174 - 175 - 104 - - - 3429 - 3430 - 104 - - - - - - - error_tag - id - - - 12 - - - 1 - 2 - 1046 - - - 2 - 3 - 942 - 3 4 - 523 - - - 4 - 5 - 523 - - - 5 - 7 - 628 - - - 7 - 11 - 628 - - - 11 - 16 - 628 - - - 16 - 21 - 628 - - - 21 - 32 - 628 - - - 44 - 72 - 628 - - - 112 - 540 - 628 - - - 595 - 1254 - 418 - - - - - - - error_tag - severity - - - 12 - - - 1 - 2 - 7851 - - - - - - - error_tag - error_message - - - 12 - - - 1 - 2 - 5443 - - - 2 - 3 - 418 - - - 3 - 4 - 523 - - - 4 - 6 - 628 - - - 7 - 35 - 628 - - - 59 - 294 - 209 - - - - - - - error_tag - full_error_message - - - 12 - - - 1 - 2 - 1151 - - - 2 - 3 - 942 - - - 3 - 4 - 523 - - - 4 - 5 - 523 - - - 5 - 7 - 628 - - - 7 - 12 - 628 - - - 13 - 16 - 523 - - - 16 - 21 - 628 - - - 21 - 32 - 628 - - - 44 - 72 - 628 - - - 112 - 540 - 628 - - - 595 - 1254 - 418 - - - - - - - error_tag - location - - - 12 - - - 1 - 2 - 1674 - - - 2 - 3 - 942 - - - 3 - 4 - 418 - - - 4 - 5 - 523 - - - 5 - 6 - 523 - - - 6 - 7 - 523 - - - 7 - 15 - 628 - - - 15 - 20 - 628 - - - 23 - 44 - 628 - - - 44 - 95 - 628 - - - 139 - 630 - 628 - - - 764 - 765 - 104 - - - - - - - error_message - id - - - 12 - - - 1 - 2 - 24809 - - - 2 - 3 - 13608 - - - 3 - 4 - 4187 - - - 4 - 6 - 4606 - - - 6 - 14 - 4292 - - - 14 - 227 - 4292 - - - 405 - 1254 - 418 - - - - - - - error_message - severity - - - 12 - - - 1 - 2 - 56215 - - - - - - - error_message - error_tag - - - 12 - - - 1 - 2 - 56215 - - - - - - - error_message - full_error_message - - - 12 - - - 1 - 2 - 24914 - - - 2 - 3 - 13608 - - - 3 - 4 - 4187 - - - 4 - 6 - 4606 - - - 6 - 15 - 4396 - - - 15 - 540 - 4292 - - - 595 - 1254 - 209 - - - - - - - error_message - location - - - 12 - - - 1 - 2 - 36011 - - - 2 - 3 - 6909 - - - 3 - 5 - 4710 - - - 5 - 12 - 4292 - - - 12 - 765 - 4292 - - - - - - - full_error_message - id - - - 12 - - - 1 - 2 - 581935 + 11 8 9 - 104 + 11 + + + + + + + severity + full_error_message + + + 12 + + + 4 + 5 + 11 + + + 5422 + 5423 + 11 + + + + + + + severity + location + + + 12 + + + 4 + 5 + 11 + + + 9 + 10 + 11 + + + + + + + error_tag + id + + + 12 + + + 1 + 2 + 11 + + + 2 + 3 + 11 + + + 4 + 5 + 11 + + + 5 + 6 + 11 + + + 417 + 418 + 11 + + + 829 + 830 + 11 + + + 4996 + 4997 + 11 + + + + + + + error_tag + severity + + + 12 + + + 1 + 2 + 80 + + + + + + + error_tag + error_message + + + 12 + + + 1 + 2 + 57 + + + 3 + 4 + 23 + + + + + + + error_tag + full_error_message + + + 12 + + + 1 + 2 + 23 + + + 2 + 3 + 11 + + + 4 + 5 + 11 + + + 5 + 6 + 11 + + + 417 + 418 + 11 + + + 4996 + 4997 + 11 + + + + + + + error_tag + location + + + 12 + + + 1 + 2 + 46 + + + 2 + 3 + 11 + + + 4 + 5 + 11 + + + 5 + 6 + 11 + + + + + + + error_message + id + + + 12 + + + 1 + 2 + 34 + + + 2 + 3 + 23 + + + 5 + 6 + 11 + + + 10 + 11 + 11 + + + 75 + 76 + 11 + + + 332 + 333 + 11 + + + 829 + 830 + 11 + + + 4996 + 4997 + 11 + + + + + + + error_message + severity + + + 12 + + + 1 + 2 + 127 + + + + + + + error_message + error_tag + + + 12 + + + 1 + 2 + 127 + + + + + + + error_message + full_error_message + + + 12 + + + 1 + 2 + 46 + + + 2 + 3 + 23 + + + 5 + 6 + 11 + + + 10 + 11 + 11 + + + 75 + 76 + 11 + + + 332 + 333 + 11 + + + 4996 + 4997 + 11 + + + + + + + error_message + location + + + 12 + + + 1 + 2 + 92 + + + 2 + 3 + 23 + + + 5 + 6 + 11 + + + + + + + full_error_message + id + + + 12 + + + 1 + 2 + 62726 + + + 829 + 830 + 11 @@ -11186,7 +11026,7 @@ 1 2 - 582040 + 62738 @@ -11202,7 +11042,7 @@ 1 2 - 582040 + 62738 @@ -11218,7 +11058,7 @@ 1 2 - 582040 + 62738 @@ -11234,7 +11074,7 @@ 1 2 - 582040 + 62738 @@ -11250,17 +11090,12 @@ 1 2 - 206959 + 138 - 2 - 3 - 135774 - - - 3 - 13 - 26484 + 6242 + 6243 + 11 @@ -11276,12 +11111,7 @@ 1 2 - 361262 - - - 2 - 3 - 7955 + 150 @@ -11297,12 +11127,12 @@ 1 2 - 354458 + 138 - 2 - 6 - 14760 + 3 + 4 + 11 @@ -11318,12 +11148,12 @@ 1 2 - 353830 + 138 - 2 + 5 6 - 15388 + 11 @@ -11339,17 +11169,12 @@ 1 2 - 207063 + 138 - 2 - 3 - 135774 - - - 3 - 13 - 26380 + 5414 + 5415 + 11 @@ -11359,15 +11184,15 @@ files - 124189 + 124196 id - 124189 + 124196 name - 124189 + 124196 @@ -11381,7 +11206,7 @@ 1 2 - 124189 + 124196 @@ -11397,7 +11222,7 @@ 1 2 - 124189 + 124196 @@ -11455,7 +11280,7 @@ containerparent - 139243 + 139250 parent @@ -11463,7 +11288,7 @@ child - 139243 + 139250 @@ -11482,7 +11307,7 @@ 2 3 - 3292 + 3293 3 @@ -11518,7 +11343,7 @@ 1 2 - 139243 + 139250 @@ -11528,11 +11353,11 @@ fileannotations - 5254886 + 5253841 id - 5019 + 5018 kind @@ -11540,11 +11365,11 @@ name - 56112 + 56101 value - 47173 + 47163 @@ -11563,7 +11388,7 @@ 2 3 - 4845 + 4844 @@ -11624,7 +11449,7 @@ 936 937 - 1457 + 1456 1083 @@ -11690,7 +11515,7 @@ 1501 1502 - 1457 + 1456 1504 @@ -11779,12 +11604,12 @@ 1 2 - 9078 + 9076 2 3 - 6372 + 6370 3 @@ -11794,12 +11619,12 @@ 5 9 - 4371 + 4370 9 14 - 4082 + 4081 14 @@ -11809,27 +11634,27 @@ 18 20 - 4834 + 4833 20 34 - 4325 + 4324 34 128 - 4614 + 4613 128 229 - 4221 + 4220 229 387 - 4348 + 4347 387 @@ -11850,7 +11675,7 @@ 1 2 - 56112 + 56101 @@ -11866,17 +11691,17 @@ 1 2 - 9089 + 9088 2 3 - 8257 + 8255 3 4 - 2625 + 2624 4 @@ -11886,37 +11711,37 @@ 6 9 - 4232 + 4231 9 14 - 4313 + 4312 14 17 - 4232 + 4231 17 22 - 4706 + 4705 22 41 - 4313 + 4312 41 82 - 4267 + 4266 82 157 - 4209 + 4208 158 @@ -11937,7 +11762,7 @@ 1 2 - 7332 + 7330 2 @@ -11947,7 +11772,7 @@ 5 8 - 3411 + 3410 8 @@ -11957,22 +11782,22 @@ 15 17 - 2602 + 2601 17 19 - 4244 + 4243 19 34 - 3411 + 3410 34 189 - 3712 + 3711 189 @@ -11987,12 +11812,12 @@ 266 321 - 3770 + 3769 322 399 - 4047 + 4046 399 @@ -12013,7 +11838,7 @@ 1 2 - 47161 + 47152 2 @@ -12034,17 +11859,17 @@ 1 2 - 7355 + 7353 2 5 - 2648 + 2647 5 8 - 3596 + 3595 8 @@ -12059,17 +11884,17 @@ 17 19 - 3677 + 3676 19 29 - 3596 + 3595 29 39 - 3758 + 3757 39 @@ -12079,7 +11904,7 @@ 48 74 - 3654 + 3653 74 @@ -12089,7 +11914,7 @@ 102 119 - 3689 + 3688 119 @@ -12104,15 +11929,15 @@ inmacroexpansion - 109313317 + 109313388 id - 17941916 + 17941927 inv - 2682068 + 2682069 @@ -12126,32 +11951,32 @@ 1 3 - 1566018 + 1566019 3 5 - 1071344 + 1071345 5 6 - 1179814 + 1179815 6 7 - 4800000 + 4800003 7 8 - 6359380 + 6359384 8 9 - 2595248 + 2595250 9 @@ -12172,12 +11997,12 @@ 1 2 - 371855 + 371856 2 3 - 540116 + 540113 3 @@ -12212,7 +12037,7 @@ 11 337 - 223911 + 223913 339 @@ -12232,15 +12057,15 @@ affectedbymacroexpansion - 35540532 + 35540555 id - 5135277 + 5135280 inv - 2773181 + 2773183 @@ -12254,7 +12079,7 @@ 1 2 - 2804212 + 2804214 2 @@ -12279,7 +12104,7 @@ 12 50 - 405705 + 405706 50 @@ -12305,7 +12130,7 @@ 4 7 - 230823 + 230824 7 @@ -12315,7 +12140,7 @@ 9 12 - 250042 + 250043 12 @@ -12345,7 +12170,7 @@ 17 18 - 146328 + 146329 18 @@ -12370,19 +12195,19 @@ macroinvocations - 33894981 + 33889080 id - 33894981 + 33889080 macro_id - 81381 + 81423 location - 778557 + 778830 kind @@ -12400,7 +12225,7 @@ 1 2 - 33894981 + 33889080 @@ -12416,7 +12241,7 @@ 1 2 - 33894981 + 33889080 @@ -12432,7 +12257,7 @@ 1 2 - 33894981 + 33889080 @@ -12448,12 +12273,12 @@ 1 2 - 17578 + 17575 2 3 - 16977 + 16973 3 @@ -12463,42 +12288,42 @@ 4 5 - 4880 + 4879 5 8 - 6048 + 6047 8 14 - 6406 + 6440 14 29 - 6291 + 6313 29 - 72 - 6106 + 73 + 6220 - 72 - 247 - 6129 + 73 + 257 + 6139 - 248 - 4166 - 6106 + 257 + 5769 + 6116 - 4220 + 6272 168296 - 1156 + 1017 @@ -12514,32 +12339,32 @@ 1 2 - 43506 + 43498 2 3 - 10651 + 10649 3 4 - 5285 + 5284 4 6 - 6985 + 7018 6 13 - 6626 + 6636 13 66 - 6140 + 6151 66 @@ -12560,12 +12385,12 @@ 1 2 - 75553 + 75538 2 3 - 5828 + 5885 @@ -12581,37 +12406,37 @@ 1 2 - 320982 + 321115 2 3 - 177751 + 177878 3 4 - 47300 + 47313 4 5 - 59605 + 59616 5 9 - 68533 + 68542 9 23 - 58425 + 58414 23 244365 - 45958 + 45949 @@ -12627,12 +12452,12 @@ 1 2 - 731280 + 731563 2 350 - 47277 + 47267 @@ -12648,7 +12473,7 @@ 1 2 - 778557 + 778830 @@ -12662,13 +12487,13 @@ 12 - 20414 - 20415 + 20464 + 20465 11 - 2910446 - 2910447 + 2910469 + 2910470 11 @@ -12683,13 +12508,13 @@ 12 - 2123 - 2124 + 2128 + 2129 11 - 5418 - 5419 + 5423 + 5424 11 @@ -12704,13 +12529,13 @@ 12 - 6291 - 6292 + 6315 + 6316 11 - 61030 - 61031 + 61043 + 61044 11 @@ -12721,15 +12546,15 @@ macroparent - 30455592 + 30449647 id - 30455592 + 30449647 parent_id - 23698199 + 23693599 @@ -12743,7 +12568,7 @@ 1 2 - 30455592 + 30449647 @@ -12759,17 +12584,17 @@ 1 2 - 18307171 + 18303643 2 3 - 4540062 + 4539159 3 88 - 850965 + 850796 @@ -12779,15 +12604,15 @@ macrolocationbind - 3984640 + 3984515 id - 2778886 + 2778799 location - 1988454 + 1988392 @@ -12801,22 +12626,22 @@ 1 2 - 2183104 + 2183036 2 3 - 336443 + 336432 3 7 - 229815 + 229808 7 57 - 29523 + 29522 @@ -12832,22 +12657,22 @@ 1 2 - 1589588 + 1589539 2 3 - 169647 + 169641 3 8 - 154233 + 154228 8 723 - 74984 + 74982 @@ -12857,11 +12682,11 @@ macro_argument_unexpanded - 86176782 + 86159621 invocation - 26568343 + 26563044 argument_index @@ -12869,7 +12694,7 @@ text - 326094 + 326029 @@ -12883,22 +12708,22 @@ 1 2 - 7436793 + 7435302 2 3 - 10861692 + 10859530 3 4 - 6256808 + 6255563 4 67 - 2013048 + 2012648 @@ -12914,22 +12739,22 @@ 1 2 - 7508010 + 7506504 2 3 - 11011561 + 11009369 3 4 - 6087232 + 6086021 4 67 - 1961538 + 1961148 @@ -12954,7 +12779,7 @@ 715085 - 2297335 + 2297334 34 @@ -12997,57 +12822,57 @@ 1 2 - 40858 + 40850 2 3 - 65607 + 65594 3 4 - 15184 + 15181 4 5 - 45102 + 45093 5 8 - 25569 + 25576 8 12 - 16075 + 16060 12 16 - 22297 + 22292 16 23 - 26518 + 26512 23 43 - 24748 + 24743 43 164 - 24459 + 24454 164 521384 - 19671 + 19667 @@ -13063,17 +12888,17 @@ 1 2 - 235830 + 235783 2 3 - 79728 + 79712 3 9 - 10535 + 10533 @@ -13083,11 +12908,11 @@ macro_argument_expanded - 86176782 + 86159621 invocation - 26568343 + 26563044 argument_index @@ -13095,7 +12920,7 @@ text - 197597 + 197580 @@ -13109,22 +12934,22 @@ 1 2 - 7436793 + 7435302 2 3 - 10861692 + 10859530 3 4 - 6256808 + 6255563 4 67 - 2013048 + 2012648 @@ -13140,22 +12965,22 @@ 1 2 - 10747743 + 10745593 2 3 - 9374139 + 9372273 3 4 - 5306998 + 5305941 4 9 - 1139462 + 1139235 @@ -13180,7 +13005,7 @@ 715085 - 2297335 + 2297334 34 @@ -13206,7 +13031,7 @@ 870 - 13877 + 13879 46 @@ -13223,62 +13048,62 @@ 1 2 - 24552 + 24547 2 3 - 41147 + 41151 3 4 - 6927 + 6925 4 5 - 16364 + 16361 5 6 - 2995 + 2994 6 7 - 23291 + 23286 7 9 - 15982 + 15991 9 15 - 16699 + 16696 15 31 - 15589 + 15586 31 97 - 15080 + 15077 97 775 - 15485 + 15482 775 - 1052916 - 3481 + 1052906 + 3480 @@ -13294,17 +13119,17 @@ 1 2 - 99989 + 99992 2 3 - 82850 + 82834 3 66 - 14756 + 14753 @@ -13314,19 +13139,19 @@ functions - 4726273 + 4726519 id - 4726273 + 4726519 name - 1934352 + 1934453 kind - 3292 + 3293 @@ -13340,7 +13165,7 @@ 1 2 - 4726273 + 4726519 @@ -13356,7 +13181,7 @@ 1 2 - 4726273 + 4726519 @@ -13372,22 +13197,22 @@ 1 2 - 1516622 + 1516701 2 3 - 154296 + 154304 3 5 - 151003 + 151011 5 1724 - 112429 + 112435 @@ -13403,7 +13228,7 @@ 1 2 - 1933881 + 1933982 2 @@ -13510,15 +13335,15 @@ function_entry_point - 1176981 + 1177043 id - 1167103 + 1167163 entry_point - 1176981 + 1177043 @@ -13532,12 +13357,12 @@ 1 2 - 1157224 + 1157284 2 3 - 9878 + 9879 @@ -13553,7 +13378,7 @@ 1 2 - 1176981 + 1177043 @@ -13563,15 +13388,15 @@ function_return_type - 4734741 + 4734987 id - 4726273 + 4726519 return_type - 1016569 + 1016622 @@ -13585,7 +13410,7 @@ 1 2 - 4719217 + 4719463 2 @@ -13606,22 +13431,22 @@ 1 2 - 523103 + 523130 2 3 - 390445 + 390465 3 11 - 78559 + 78563 11 2516 - 24461 + 24462 @@ -13639,7 +13464,7 @@ traits - 1 + 2 handle @@ -13707,9 +13532,9 @@ 12 - 2 - 3 - 1 + 1 + 2 + 2 @@ -13723,9 +13548,9 @@ 12 - 2 - 3 - 1 + 1 + 2 + 2 @@ -13739,9 +13564,9 @@ 12 - 2 - 3 - 1 + 1 + 2 + 2 @@ -13943,48 +13768,48 @@ purefunctions - 99446 + 99447 id - 99446 + 99447 function_deleted - 140654 + 140661 id - 140654 + 140661 function_defaulted - 74325 + 74329 id - 74325 + 74329 member_function_this_type - 553641 + 553316 id - 553641 + 553316 this_type - 189690 + 189579 @@ -13998,7 +13823,7 @@ 1 2 - 553641 + 553316 @@ -14014,32 +13839,32 @@ 1 2 - 68526 + 68486 2 3 - 45414 + 45387 3 4 - 30475 + 30458 4 5 - 15537 + 15528 5 7 - 15607 + 15598 7 66 - 14128 + 14119 @@ -14049,27 +13874,27 @@ fun_decls - 5102136 + 5102402 id - 5096962 + 5097227 function - 4578563 + 4578801 type_id - 1013276 + 1013329 name - 1836035 + 1836130 location - 3461324 + 3461504 @@ -14083,7 +13908,7 @@ 1 2 - 5096962 + 5097227 @@ -14099,7 +13924,7 @@ 1 2 - 5091787 + 5092052 2 @@ -14120,7 +13945,7 @@ 1 2 - 5096962 + 5097227 @@ -14136,7 +13961,7 @@ 1 2 - 5096962 + 5097227 @@ -14152,17 +13977,17 @@ 1 2 - 4141075 + 4141291 2 3 - 363161 + 363180 3 7 - 74325 + 74329 @@ -14178,12 +14003,12 @@ 1 2 - 4536696 + 4536932 2 5 - 41867 + 41869 @@ -14199,7 +14024,7 @@ 1 2 - 4578563 + 4578801 @@ -14215,12 +14040,12 @@ 1 2 - 4197996 + 4198214 2 4 - 379155 + 379175 4 @@ -14241,22 +14066,22 @@ 1 2 - 445954 + 445977 2 3 - 453481 + 453505 3 9 - 79500 + 79504 9 2768 - 34340 + 34342 @@ -14272,22 +14097,22 @@ 1 2 - 530629 + 530657 2 3 - 381978 + 381998 3 11 - 77148 + 77152 11 2477 - 23520 + 23522 @@ -14303,17 +14128,17 @@ 1 2 - 883912 + 883958 2 5 - 90319 + 90324 5 822 - 39044 + 39046 @@ -14329,22 +14154,22 @@ 1 2 - 779480 + 779520 2 3 - 133127 + 133134 3 11 - 78089 + 78093 11 2030 - 22579 + 22581 @@ -14360,27 +14185,27 @@ 1 2 - 1245192 + 1245257 2 3 - 269548 + 269562 3 4 - 80441 + 80445 4 6 - 138772 + 138780 6 1758 - 102080 + 102085 @@ -14396,22 +14221,22 @@ 1 2 - 1425832 + 1425906 2 3 - 153355 + 153363 3 5 - 145358 + 145366 5 1708 - 111488 + 111494 @@ -14427,17 +14252,17 @@ 1 2 - 1615880 + 1615964 2 4 - 135009 + 135016 4 954 - 85145 + 85149 @@ -14453,27 +14278,27 @@ 1 2 - 1266831 + 1266897 2 3 - 296362 + 296377 3 4 - 79500 + 79504 4 8 - 139243 + 139250 8 664 - 54097 + 54100 @@ -14489,17 +14314,17 @@ 1 2 - 2995611 + 2995767 2 4 - 302007 + 302023 4 55 - 163704 + 163713 @@ -14515,17 +14340,17 @@ 1 2 - 3063351 + 3063511 2 6 - 268607 + 268621 6 55 - 129364 + 129371 @@ -14541,12 +14366,12 @@ 1 2 - 3245873 + 3246042 2 27 - 215450 + 215461 @@ -14562,12 +14387,12 @@ 1 2 - 3285388 + 3285559 2 13 - 175935 + 175944 @@ -14577,22 +14402,22 @@ fun_def - 1963988 + 1964090 id - 1963988 + 1964090 fun_specialized - 26343 + 26344 id - 26343 + 26344 @@ -14610,11 +14435,11 @@ fun_decl_specifiers - 2937280 + 2937433 id - 1710904 + 1710993 name @@ -14632,17 +14457,17 @@ 1 2 - 503345 + 503371 2 3 - 1188742 + 1188804 3 4 - 18816 + 18817 @@ -14814,26 +14639,26 @@ fun_decl_empty_throws - 1978101 + 1978204 fun_decl - 1978101 + 1978204 fun_decl_noexcept - 61239 + 61252 fun_decl - 61239 + 61252 constant - 61135 + 61148 @@ -14847,7 +14672,7 @@ 1 2 - 61239 + 61252 @@ -14863,7 +14688,7 @@ 1 2 - 61030 + 61043 2 @@ -14878,11 +14703,11 @@ fun_decl_empty_noexcept - 888146 + 888192 fun_decl - 888146 + 888192 @@ -14987,11 +14812,11 @@ param_decl_bind - 7472094 + 7472483 id - 7472094 + 7472483 index @@ -14999,7 +14824,7 @@ fun_decl - 4286434 + 4286657 @@ -15013,7 +14838,7 @@ 1 2 - 7472094 + 7472483 @@ -15029,7 +14854,7 @@ 1 2 - 7472094 + 7472483 @@ -15207,22 +15032,22 @@ 1 2 - 2409002 + 2409127 2 3 - 1071608 + 1071664 3 4 - 506638 + 506664 4 18 - 299184 + 299200 @@ -15238,22 +15063,22 @@ 1 2 - 2409002 + 2409127 2 3 - 1071608 + 1071664 3 4 - 506638 + 506664 4 18 - 299184 + 299200 @@ -15263,27 +15088,27 @@ var_decls - 8611913 + 8612362 id - 8543232 + 8543677 variable - 7520077 + 7520468 type_id - 2430641 + 2430768 name - 672695 + 672730 location - 5365099 + 5365378 @@ -15297,7 +15122,7 @@ 1 2 - 8543232 + 8543677 @@ -15313,12 +15138,12 @@ 1 2 - 8474552 + 8474993 2 3 - 68680 + 68684 @@ -15334,7 +15159,7 @@ 1 2 - 8543232 + 8543677 @@ -15350,7 +15175,7 @@ 1 2 - 8543232 + 8543677 @@ -15366,17 +15191,17 @@ 1 2 - 6658274 + 6658620 2 3 - 707035 + 707072 3 7 - 154767 + 154775 @@ -15392,12 +15217,12 @@ 1 2 - 7346963 + 7347346 2 4 - 173113 + 173122 @@ -15413,12 +15238,12 @@ 1 2 - 7402943 + 7403328 2 3 - 117133 + 117139 @@ -15434,12 +15259,12 @@ 1 2 - 6967337 + 6967700 2 4 - 552739 + 552768 @@ -15455,27 +15280,27 @@ 1 2 - 1505802 + 1505881 2 3 - 516046 + 516073 3 4 - 98787 + 98792 4 7 - 188636 + 188646 7 780 - 121367 + 121373 @@ -15491,22 +15316,22 @@ 1 2 - 1640342 + 1640427 2 3 - 491114 + 491140 3 7 - 188166 + 188176 7 742 - 111018 + 111024 @@ -15522,17 +15347,17 @@ 1 2 - 1918828 + 1918928 2 3 - 388563 + 388584 3 128 - 123249 + 123255 @@ -15548,22 +15373,22 @@ 1 2 - 1743833 + 1743924 2 3 - 406910 + 406931 3 8 - 190048 + 190058 8 595 - 89849 + 89854 @@ -15579,37 +15404,37 @@ 1 2 - 343874 + 343892 2 3 - 87497 + 87502 3 4 - 48923 + 48925 4 6 - 52216 + 52218 6 12 - 52686 + 52689 12 33 - 50804 + 50807 34 3281 - 36692 + 36694 @@ -15625,37 +15450,37 @@ 1 2 - 371628 + 371648 2 3 - 78559 + 78563 3 4 - 45630 + 45632 4 6 - 49864 + 49866 6 14 - 53627 + 53630 14 56 - 51275 + 51278 56 3198 - 22109 + 22110 @@ -15671,27 +15496,27 @@ 1 2 - 460537 + 460561 2 3 - 94553 + 94558 3 5 - 47041 + 47044 5 19 - 51275 + 51278 19 1979 - 19287 + 19288 @@ -15707,32 +15532,32 @@ 1 2 - 381978 + 381998 2 3 - 91260 + 91265 3 5 - 60213 + 60216 5 9 - 51745 + 51748 9 21 - 50804 + 50807 21 1020 - 36692 + 36694 @@ -15748,17 +15573,17 @@ 1 2 - 4535755 + 4535991 2 3 - 550387 + 550415 3 1783 - 278956 + 278971 @@ -15774,17 +15599,17 @@ 1 2 - 4939842 + 4940100 2 17 - 414436 + 414458 17 1779 - 10819 + 10820 @@ -15800,12 +15625,12 @@ 1 2 - 5016520 + 5016782 2 1561 - 348578 + 348596 @@ -15821,7 +15646,7 @@ 1 2 - 5360865 + 5361144 2 @@ -15836,22 +15661,22 @@ var_def - 4083685 + 4083897 id - 4083685 + 4083897 var_decl_specifiers - 334936 + 334953 id - 334936 + 334953 name @@ -15869,7 +15694,7 @@ 1 2 - 334936 + 334953 @@ -15916,19 +15741,19 @@ type_decls - 3283977 + 3284148 id - 3283977 + 3284148 type_id - 3233172 + 3233340 location - 3204006 + 3204173 @@ -15942,7 +15767,7 @@ 1 2 - 3283977 + 3284148 @@ -15958,7 +15783,7 @@ 1 2 - 3283977 + 3284148 @@ -15974,12 +15799,12 @@ 1 2 - 3191305 + 3191471 2 5 - 41867 + 41869 @@ -15995,12 +15820,12 @@ 1 2 - 3191305 + 3191471 2 5 - 41867 + 41869 @@ -16016,12 +15841,12 @@ 1 2 - 3163080 + 3163244 2 20 - 40926 + 40928 @@ -16037,12 +15862,12 @@ 1 2 - 3163080 + 3163244 2 20 - 40926 + 40928 @@ -16052,33 +15877,33 @@ type_def - 2660675 + 2660813 id - 2660675 + 2660813 type_decl_top - 755959 + 755998 type_decl - 755959 + 755998 namespace_decls - 306972 + 306973 id - 306972 + 306973 namespace_id @@ -16086,11 +15911,11 @@ location - 306972 + 306973 bodylocation - 306972 + 306973 @@ -16104,7 +15929,7 @@ 1 2 - 306972 + 306973 @@ -16120,7 +15945,7 @@ 1 2 - 306972 + 306973 @@ -16136,7 +15961,7 @@ 1 2 - 306972 + 306973 @@ -16350,7 +16175,7 @@ 1 2 - 306972 + 306973 @@ -16366,7 +16191,7 @@ 1 2 - 306972 + 306973 @@ -16382,7 +16207,7 @@ 1 2 - 306972 + 306973 @@ -16398,7 +16223,7 @@ 1 2 - 306972 + 306973 @@ -16414,7 +16239,7 @@ 1 2 - 306972 + 306973 @@ -16430,7 +16255,7 @@ 1 2 - 306972 + 306973 @@ -16440,19 +16265,19 @@ usings - 374921 + 374941 id - 374921 + 374941 element_id - 318471 + 318488 location - 249791 + 249804 @@ -16466,7 +16291,7 @@ 1 2 - 374921 + 374941 @@ -16482,7 +16307,7 @@ 1 2 - 374921 + 374941 @@ -16498,12 +16323,12 @@ 1 2 - 263903 + 263917 2 3 - 53157 + 53159 3 @@ -16524,12 +16349,12 @@ 1 2 - 263903 + 263917 2 3 - 53157 + 53159 3 @@ -16550,22 +16375,22 @@ 1 2 - 203690 + 203700 2 4 - 11289 + 11290 4 5 - 31517 + 31519 5 11 - 3292 + 3293 @@ -16581,22 +16406,22 @@ 1 2 - 203690 + 203700 2 4 - 11289 + 11290 4 5 - 31517 + 31519 5 11 - 3292 + 3293 @@ -16606,15 +16431,15 @@ using_container - 478195 + 478100 parent - 11298 + 11296 child - 303207 + 303147 @@ -16684,17 +16509,17 @@ 1 2 - 223629 + 223585 2 3 - 52990 + 52979 3 11 - 24401 + 24396 13 @@ -16709,15 +16534,15 @@ static_asserts - 130417 + 130418 id - 130417 + 130418 condition - 130417 + 130418 message @@ -16743,7 +16568,7 @@ 1 2 - 130417 + 130418 @@ -16759,7 +16584,7 @@ 1 2 - 130417 + 130418 @@ -16775,7 +16600,7 @@ 1 2 - 130417 + 130418 @@ -16791,7 +16616,7 @@ 1 2 - 130417 + 130418 @@ -16807,7 +16632,7 @@ 1 2 - 130417 + 130418 @@ -16823,7 +16648,7 @@ 1 2 - 130417 + 130418 @@ -16839,7 +16664,7 @@ 1 2 - 130417 + 130418 @@ -16855,7 +16680,7 @@ 1 2 - 130417 + 130418 @@ -17327,15 +17152,15 @@ params - 6825742 + 6826097 id - 6660155 + 6660502 function - 3940208 + 3940413 index @@ -17343,7 +17168,7 @@ type_id - 2234478 + 2234594 @@ -17357,7 +17182,7 @@ 1 2 - 6660155 + 6660502 @@ -17373,7 +17198,7 @@ 1 2 - 6660155 + 6660502 @@ -17389,12 +17214,12 @@ 1 2 - 6535025 + 6535365 2 4 - 125130 + 125137 @@ -17410,22 +17235,22 @@ 1 2 - 2303158 + 2303278 2 3 - 960590 + 960640 3 4 - 433253 + 433276 4 18 - 243205 + 243217 @@ -17441,22 +17266,22 @@ 1 2 - 2303158 + 2303278 2 3 - 960590 + 960640 3 4 - 433253 + 433276 4 18 - 243205 + 243217 @@ -17472,22 +17297,22 @@ 1 2 - 2605636 + 2605772 2 3 - 831225 + 831269 3 4 - 349519 + 349537 4 12 - 153826 + 153834 @@ -17741,22 +17566,22 @@ 1 2 - 1525560 + 1525639 2 3 - 446425 + 446448 3 8 - 171701 + 171710 8 522 - 90790 + 90795 @@ -17772,22 +17597,22 @@ 1 2 - 1749008 + 1749099 2 3 - 250731 + 250745 3 9 - 169820 + 169829 9 506 - 64917 + 64920 @@ -17803,17 +17628,17 @@ 1 2 - 1801694 + 1801788 2 3 - 353282 + 353301 3 13 - 79500 + 79504 @@ -17823,7 +17648,7 @@ overrides - 159823 + 159824 new @@ -17919,7 +17744,7 @@ type_id - 326293 + 326294 name @@ -17937,7 +17762,7 @@ 1 2 - 1048372 + 1048373 2 @@ -18087,19 +17912,19 @@ globalvariables - 300716 + 318724 id - 300708 + 318724 type_id - 1405 + 7852 name - 294738 + 86905 @@ -18113,12 +17938,7 @@ 1 2 - 300700 - - - 2 - 3 - 8 + 318724 @@ -18134,7 +17954,7 @@ 1 2 - 300708 + 318724 @@ -18150,27 +17970,32 @@ 1 2 - 977 + 5130 2 3 - 159 + 209 3 - 7 - 114 + 4 + 628 - 7 - 77 - 106 + 4 + 9 + 628 - 83 - 169397 - 49 + 18 + 31 + 628 + + + 35 + 1226 + 628 @@ -18186,27 +18011,32 @@ 1 2 - 1010 + 5130 2 3 - 135 + 209 3 - 7 - 112 + 4 + 628 - 7 - 105 - 106 + 4 + 9 + 628 - 106 - 168448 - 42 + 14 + 25 + 628 + + + 35 + 209 + 628 @@ -18222,12 +18052,17 @@ 1 2 - 290989 + 75911 2 - 33 - 3749 + 11 + 6596 + + + 11 + 449 + 4397 @@ -18243,12 +18078,12 @@ 1 2 - 294142 + 76644 2 - 12 - 596 + 3 + 10261 @@ -18266,7 +18101,7 @@ type_id - 37905 + 37909 name @@ -18326,7 +18161,7 @@ 3 4 - 2479 + 2483 4 @@ -18336,12 +18171,12 @@ 7 18 - 2878 + 2874 18 15847 - 2513 + 2517 @@ -18367,7 +18202,7 @@ 3 5 - 2946 + 2950 5 @@ -18449,11 +18284,11 @@ autoderivation - 149488 + 149519 var - 149488 + 149519 derivation_type @@ -18471,7 +18306,7 @@ 1 2 - 149488 + 149519 @@ -18537,7 +18372,7 @@ name - 240334 + 240335 location @@ -19272,7 +19107,7 @@ 1 2 - 240334 + 240335 @@ -19288,7 +19123,7 @@ 1 2 - 240334 + 240335 @@ -19414,23 +19249,23 @@ builtintypes - 22109 + 22110 id - 22109 + 22110 name - 22109 + 22110 kind - 22109 + 22110 size - 3292 + 3293 sign @@ -19452,7 +19287,7 @@ 1 2 - 22109 + 22110 @@ -19468,7 +19303,7 @@ 1 2 - 22109 + 22110 @@ -19484,7 +19319,7 @@ 1 2 - 22109 + 22110 @@ -19500,7 +19335,7 @@ 1 2 - 22109 + 22110 @@ -19516,7 +19351,7 @@ 1 2 - 22109 + 22110 @@ -19532,7 +19367,7 @@ 1 2 - 22109 + 22110 @@ -19548,7 +19383,7 @@ 1 2 - 22109 + 22110 @@ -19564,7 +19399,7 @@ 1 2 - 22109 + 22110 @@ -19580,7 +19415,7 @@ 1 2 - 22109 + 22110 @@ -19596,7 +19431,7 @@ 1 2 - 22109 + 22110 @@ -19612,7 +19447,7 @@ 1 2 - 22109 + 22110 @@ -19628,7 +19463,7 @@ 1 2 - 22109 + 22110 @@ -19644,7 +19479,7 @@ 1 2 - 22109 + 22110 @@ -19660,7 +19495,7 @@ 1 2 - 22109 + 22110 @@ -19676,7 +19511,7 @@ 1 2 - 22109 + 22110 @@ -20126,15 +19961,15 @@ derivedtypes - 4413446 + 4413676 id - 4413446 + 4413676 name - 2205312 + 2205427 kind @@ -20142,7 +19977,7 @@ type_id - 2729356 + 2729498 @@ -20156,7 +19991,7 @@ 1 2 - 4413446 + 4413676 @@ -20172,7 +20007,7 @@ 1 2 - 4413446 + 4413676 @@ -20188,7 +20023,7 @@ 1 2 - 4413446 + 4413676 @@ -20204,17 +20039,17 @@ 1 2 - 1935763 + 1935864 2 5 - 171231 + 171240 5 1173 - 98317 + 98322 @@ -20230,7 +20065,7 @@ 1 2 - 2204371 + 2204486 2 @@ -20251,17 +20086,17 @@ 1 2 - 1935763 + 1935864 2 5 - 171231 + 171240 5 1155 - 98317 + 98322 @@ -20400,22 +20235,22 @@ 1 2 - 1685972 + 1686060 2 3 - 568733 + 568763 3 4 - 367395 + 367414 4 54 - 107254 + 107260 @@ -20431,22 +20266,22 @@ 1 2 - 1697262 + 1697350 2 3 - 561206 + 561236 3 4 - 364572 + 364591 4 54 - 106314 + 106319 @@ -20462,22 +20297,22 @@ 1 2 - 1690206 + 1690294 2 3 - 572496 + 572526 3 4 - 366454 + 366473 4 6 - 100198 + 100203 @@ -20487,11 +20322,11 @@ pointerishsize - 3314342 + 3312399 id - 3314342 + 3312399 size @@ -20513,7 +20348,7 @@ 1 2 - 3314342 + 3312399 @@ -20529,7 +20364,7 @@ 1 2 - 3314342 + 3312399 @@ -20603,19 +20438,19 @@ arraysizes - 71503 + 71507 id - 71503 + 71507 num_elements - 23520 + 23522 bytesize - 26343 + 26344 alignment @@ -20633,7 +20468,7 @@ 1 2 - 71503 + 71507 @@ -20649,7 +20484,7 @@ 1 2 - 71503 + 71507 @@ -20665,7 +20500,7 @@ 1 2 - 71503 + 71507 @@ -20686,7 +20521,7 @@ 2 3 - 15053 + 15054 3 @@ -20722,7 +20557,7 @@ 1 2 - 18346 + 18347 2 @@ -20753,7 +20588,7 @@ 1 2 - 18346 + 18347 2 @@ -20789,12 +20624,12 @@ 2 3 - 16934 + 16935 3 4 - 3292 + 3293 4 @@ -20820,12 +20655,12 @@ 1 2 - 21639 + 21640 2 3 - 3292 + 3293 3 @@ -20846,12 +20681,12 @@ 1 2 - 22109 + 22110 2 3 - 3292 + 3293 4 @@ -20954,15 +20789,15 @@ typedefbase - 1724181 + 1736730 id - 1724181 + 1736730 type_id - 803746 + 810523 @@ -20976,7 +20811,7 @@ 1 2 - 1724181 + 1736730 @@ -20992,22 +20827,22 @@ 1 2 - 623380 + 629130 2 3 - 84307 + 85019 3 6 - 64497 + 64576 6 5443 - 31560 + 31797 @@ -21017,19 +20852,19 @@ decltypes - 355640 + 355894 id - 23953 + 23951 expr - 355640 + 355894 base_type - 17181 + 17180 parentheses_would_change_meaning @@ -21047,12 +20882,12 @@ 1 2 - 5961 + 5960 2 3 - 7492 + 7491 3 @@ -21067,12 +20902,12 @@ 7 18 - 1999 + 1980 18 42 - 2017 + 2035 42 @@ -21093,7 +20928,7 @@ 1 2 - 23953 + 23951 @@ -21109,7 +20944,7 @@ 1 2 - 23953 + 23951 @@ -21125,7 +20960,7 @@ 1 2 - 355640 + 355894 @@ -21141,7 +20976,7 @@ 1 2 - 355640 + 355894 @@ -21157,7 +20992,7 @@ 1 2 - 355640 + 355894 @@ -21204,7 +21039,7 @@ 2 3 - 7348 + 7347 3 @@ -21245,7 +21080,7 @@ 1 2 - 17181 + 17180 @@ -21275,8 +21110,8 @@ 12 - 19747 - 19748 + 19762 + 19763 18 @@ -21303,15 +21138,15 @@ usertypes - 5342989 + 5343268 id - 5342989 + 5343268 name - 1383024 + 1383096 kind @@ -21329,7 +21164,7 @@ 1 2 - 5342989 + 5343268 @@ -21345,7 +21180,7 @@ 1 2 - 5342989 + 5343268 @@ -21361,27 +21196,27 @@ 1 2 - 1001986 + 1002039 2 3 - 161352 + 161361 3 7 - 107725 + 107730 7 80 - 104432 + 104437 80 885 - 7526 + 7527 @@ -21397,17 +21232,17 @@ 1 2 - 1240488 + 1240552 2 3 - 127012 + 127019 3 7 - 15523 + 15524 @@ -21549,11 +21384,11 @@ usertypesize - 1755594 + 1755685 id - 1755594 + 1755685 size @@ -21575,7 +21410,7 @@ 1 2 - 1755594 + 1755685 @@ -21591,7 +21426,7 @@ 1 2 - 1755594 + 1755685 @@ -21607,7 +21442,7 @@ 1 2 - 3292 + 3293 2 @@ -21755,11 +21590,11 @@ usertype_final - 9526 + 9528 id - 9526 + 9528 @@ -21819,15 +21654,15 @@ mangled_name - 5264430 + 5301398 id - 5264430 + 5301398 mangled_name - 1235313 + 1272072 @@ -21841,7 +21676,7 @@ 1 2 - 5264430 + 5301398 @@ -21857,32 +21692,32 @@ 1 2 - 731027 + 767759 2 3 - 178287 + 178297 3 4 - 84674 + 84679 4 - 6 - 86086 + 7 + 114787 - 6 - 13 - 93142 + 7 + 25 + 95499 - 13 + 25 885 - 62094 + 31049 @@ -21892,59 +21727,59 @@ is_pod_class - 554326 + 554216 id - 554326 + 554216 is_standard_layout_class - 1295997 + 1296064 id - 1295997 + 1296064 is_complete - 1694439 + 1694528 id - 1694439 + 1694528 is_class_template - 405028 + 405049 id - 405028 + 405049 class_instantiation - 1121943 + 1122001 to - 1121943 + 1122001 from - 170761 + 170770 @@ -21958,7 +21793,7 @@ 1 2 - 1121943 + 1122001 @@ -21974,42 +21809,42 @@ 1 2 - 58802 + 58805 2 3 - 30106 + 30108 3 4 - 16464 + 16465 4 5 - 14582 + 14583 5 7 - 15523 + 15524 7 13 - 13171 + 13172 13 29 - 13171 + 13172 30 84 - 8937 + 8938 @@ -22019,11 +21854,11 @@ class_template_argument - 2978113 + 2977520 type_id - 1355713 + 1355443 index @@ -22031,7 +21866,7 @@ arg_type - 863386 + 863214 @@ -22045,27 +21880,27 @@ 1 2 - 551562 + 551453 2 3 - 411593 + 411511 3 4 - 246019 + 245970 4 7 - 122356 + 122331 7 113 - 24182 + 24177 @@ -22081,22 +21916,22 @@ 1 2 - 577421 + 577306 2 3 - 424939 + 424854 3 4 - 257884 + 257833 4 113 - 95467 + 95448 @@ -22117,7 +21952,7 @@ 2 3 - 821 + 820 3 @@ -22163,7 +21998,7 @@ 2 3 - 821 + 820 3 @@ -22204,27 +22039,27 @@ 1 2 - 535649 + 535542 2 3 - 181070 + 181034 3 4 - 52573 + 52563 4 10 - 65688 + 65675 10 11334 - 28403 + 28397 @@ -22240,17 +22075,17 @@ 1 2 - 755682 + 755532 2 3 - 85741 + 85724 3 22 - 21961 + 21957 @@ -22260,11 +22095,11 @@ class_template_argument_value - 508520 + 508546 type_id - 316590 + 316606 index @@ -22272,7 +22107,7 @@ arg_value - 508520 + 508546 @@ -22286,12 +22121,12 @@ 1 2 - 261081 + 261094 2 3 - 53627 + 53630 3 @@ -22312,17 +22147,17 @@ 1 2 - 200397 + 200407 2 3 - 81852 + 81856 3 5 - 29165 + 29167 5 @@ -22405,7 +22240,7 @@ 1 2 - 508520 + 508546 @@ -22421,7 +22256,7 @@ 1 2 - 508520 + 508546 @@ -22431,15 +22266,15 @@ is_proxy_class_for - 65387 + 65391 id - 65387 + 65391 templ_param_id - 65387 + 65391 @@ -22453,7 +22288,7 @@ 1 2 - 65387 + 65391 @@ -22469,7 +22304,7 @@ 1 2 - 65387 + 65391 @@ -22479,11 +22314,11 @@ type_mentions - 4011508 + 4011511 id - 4011508 + 4011511 type_id @@ -22491,7 +22326,7 @@ location - 3978135 + 3978138 kind @@ -22509,7 +22344,7 @@ 1 2 - 4011508 + 4011511 @@ -22525,7 +22360,7 @@ 1 2 - 4011508 + 4011511 @@ -22541,7 +22376,7 @@ 1 2 - 4011508 + 4011511 @@ -22675,7 +22510,7 @@ 1 2 - 3944762 + 3944765 2 @@ -22696,7 +22531,7 @@ 1 2 - 3944762 + 3944765 2 @@ -22717,7 +22552,7 @@ 1 2 - 3978135 + 3978138 @@ -22775,26 +22610,26 @@ is_function_template - 1413601 + 1413674 id - 1413601 + 1413674 function_instantiation - 906422 + 905891 to - 906422 + 905891 from - 146002 + 145917 @@ -22808,7 +22643,7 @@ 1 2 - 906422 + 905891 @@ -22824,27 +22659,27 @@ 1 2 - 101152 + 101092 2 3 - 14480 + 14472 3 6 - 12014 + 12007 6 21 - 12049 + 12042 22 869 - 6306 + 6302 @@ -22854,11 +22689,11 @@ function_template_argument - 2339815 + 2338443 function_id - 1318394 + 1317621 index @@ -22866,7 +22701,7 @@ arg_type - 305041 + 304862 @@ -22880,22 +22715,22 @@ 1 2 - 679667 + 679268 2 3 - 388084 + 387856 3 4 - 179966 + 179861 4 15 - 70676 + 70634 @@ -22911,22 +22746,22 @@ 1 2 - 694852 + 694445 2 3 - 393404 + 393173 3 4 - 150970 + 150882 4 9 - 79167 + 79120 @@ -23074,32 +22909,32 @@ 1 2 - 186978 + 186868 2 3 - 44850 + 44824 3 5 - 23218 + 23204 5 16 - 23535 + 23521 16 107 - 23006 + 22993 108 955 - 3452 + 3450 @@ -23115,17 +22950,17 @@ 1 2 - 274918 + 274756 2 4 - 26001 + 25986 4 17 - 4122 + 4119 @@ -23135,11 +22970,11 @@ function_template_argument_value - 362998 + 362786 function_id - 181340 + 181234 index @@ -23147,7 +22982,7 @@ arg_value - 360356 + 360145 @@ -23161,12 +22996,12 @@ 1 2 - 171969 + 171868 2 8 - 9371 + 9366 @@ -23182,17 +23017,17 @@ 1 2 - 151428 + 151339 2 3 - 20681 + 20669 3 97 - 9230 + 9225 @@ -23330,12 +23165,12 @@ 1 2 - 357714 + 357504 2 3 - 2642 + 2640 @@ -23351,7 +23186,7 @@ 1 2 - 360356 + 360145 @@ -23361,26 +23196,26 @@ is_variable_template - 42082 + 47326 id - 42082 + 47326 variable_instantiation - 49201 + 258309 to - 49201 + 258309 from - 25019 + 26281 @@ -23394,7 +23229,7 @@ 1 2 - 49201 + 258309 @@ -23410,22 +23245,42 @@ 1 2 - 14236 + 11203 2 3 - 7746 + 3559 3 + 4 + 1675 + + + 4 + 6 + 1884 + + + 6 8 - 1988 + 1884 8 14 - 1046 + 2408 + + + 15 + 26 + 1989 + + + 32 + 371 + 1675 @@ -23435,11 +23290,11 @@ variable_template_argument - 329648 + 448035 variable_id - 26380 + 247943 index @@ -23447,7 +23302,7 @@ arg_type - 217532 + 217578 @@ -23461,22 +23316,22 @@ 1 2 - 16121 + 119469 2 3 - 5652 + 99889 3 4 - 3873 + 18218 4 17 - 732 + 10365 @@ -23492,52 +23347,22 @@ 1 2 - 5757 + 129206 2 3 - 5234 + 91408 3 - 4 - 2093 - - - 4 5 - 1256 + 22825 5 - 6 - 2407 - - - 6 - 8 - 2303 - - - 8 - 11 - 2198 - - - 11 - 18 - 2303 - - - 18 - 50 - 1988 - - - 66 - 516 - 837 + 17 + 4502 @@ -23551,43 +23376,53 @@ 12 - 1 - 2 + 11 + 12 104 - 2 - 3 + 22 + 23 628 - 3 - 4 - 418 - - - 5 - 6 - 209 - - - 27 - 28 + 29 + 30 104 - 42 - 43 + 30 + 31 + 314 + + + 44 + 45 104 - 79 - 80 + 93 + 94 104 - 248 - 249 + 222 + 223 + 104 + + + 588 + 589 + 104 + + + 1090 + 1091 + 104 + + + 1974 + 1975 104 @@ -23665,17 +23500,22 @@ 1 2 - 180579 + 171403 2 3 - 21878 + 25024 3 - 38 - 15074 + 8 + 17067 + + + 8 + 94 + 4083 @@ -23691,12 +23531,12 @@ 1 2 - 200259 + 200302 2 5 - 16854 + 16857 5 @@ -23711,11 +23551,11 @@ variable_template_argument_value - 15597 + 15810 variable_id - 2826 + 6596 index @@ -23723,7 +23563,7 @@ arg_value - 12038 + 12041 @@ -23737,12 +23577,12 @@ 1 2 - 2617 + 5968 2 3 - 209 + 628 @@ -23756,45 +23596,25 @@ 12 - 2 - 3 - 418 + 1 + 2 + 314 - 3 - 4 - 104 + 2 + 3 + 5235 4 5 - 1360 - - - 5 - 6 - 209 - - - 6 - 7 - 209 + 837 8 9 209 - - 12 - 17 - 209 - - - 20 - 21 - 104 - @@ -23806,24 +23626,24 @@ 12 - - 2 - 3 - 104 - 6 7 104 - 8 - 9 + 19 + 20 104 - 13 - 14 + 20 + 21 + 104 + + + 24 + 25 104 @@ -23871,12 +23691,12 @@ 1 2 - 8479 + 8271 2 3 - 3559 + 3769 @@ -23892,7 +23712,7 @@ 1 2 - 12038 + 12041 @@ -23902,15 +23722,15 @@ routinetypes - 546982 + 546661 id - 546982 + 546661 return_type - 285945 + 285778 @@ -23924,7 +23744,7 @@ 1 2 - 546982 + 546661 @@ -23940,17 +23760,17 @@ 1 2 - 249233 + 249087 2 3 - 21315 + 21303 3 3594 - 15396 + 15387 @@ -23960,11 +23780,11 @@ routinetypeargs - 993519 + 993571 routine - 429019 + 429042 index @@ -23972,7 +23792,7 @@ type_id - 229563 + 229575 @@ -23986,27 +23806,27 @@ 1 2 - 155707 + 155715 2 3 - 135479 + 135486 3 4 - 63976 + 63979 4 5 - 46100 + 46103 5 18 - 27754 + 27756 @@ -24022,27 +23842,27 @@ 1 2 - 185814 + 185824 2 3 - 135009 + 135016 3 4 - 59272 + 59275 4 5 - 33869 + 33871 5 11 - 15053 + 15054 @@ -24200,27 +24020,27 @@ 1 2 - 148651 + 148659 2 3 - 31047 + 31049 3 5 - 16934 + 16935 5 12 - 18346 + 18347 12 113 - 14582 + 14583 @@ -24236,17 +24056,17 @@ 1 2 - 174994 + 175004 2 3 - 31047 + 31049 3 6 - 18816 + 18817 6 @@ -24261,19 +24081,19 @@ ptrtomembers - 38103 + 38105 id - 38103 + 38105 type_id - 38103 + 38105 class_id - 15523 + 15524 @@ -24287,7 +24107,7 @@ 1 2 - 38103 + 38105 @@ -24303,7 +24123,7 @@ 1 2 - 38103 + 38105 @@ -24319,7 +24139,7 @@ 1 2 - 38103 + 38105 @@ -24335,7 +24155,7 @@ 1 2 - 38103 + 38105 @@ -24397,15 +24217,15 @@ specifiers - 24932 + 24933 id - 24932 + 24933 str - 24932 + 24933 @@ -24419,7 +24239,7 @@ 1 2 - 24932 + 24933 @@ -24435,7 +24255,7 @@ 1 2 - 24932 + 24933 @@ -24445,11 +24265,11 @@ typespecifiers - 1317166 + 1317234 type_id - 1298819 + 1298887 spec_id @@ -24467,12 +24287,12 @@ 1 2 - 1280473 + 1280540 2 3 - 18346 + 18347 @@ -24533,11 +24353,11 @@ funspecifiers - 13049498 + 13041848 func_id - 3975160 + 3972829 spec_id @@ -24555,27 +24375,27 @@ 1 2 - 314977 + 314792 2 3 - 544551 + 544231 3 4 - 1145438 + 1144767 4 5 - 1732127 + 1731112 5 8 - 238064 + 237925 @@ -24691,11 +24511,11 @@ varspecifiers - 2347848 + 2347970 var_id - 1255071 + 1255136 spec_id @@ -24713,22 +24533,22 @@ 1 2 - 735731 + 735769 2 3 - 203219 + 203230 3 4 - 58802 + 58805 4 5 - 257317 + 257331 @@ -24789,11 +24609,11 @@ attributes - 696354 + 696502 id - 696354 + 696502 kind @@ -24801,7 +24621,7 @@ name - 1674 + 1675 name_space @@ -24809,7 +24629,7 @@ location - 483847 + 483949 @@ -24823,7 +24643,7 @@ 1 2 - 696354 + 696502 @@ -24839,7 +24659,7 @@ 1 2 - 696354 + 696502 @@ -24855,7 +24675,7 @@ 1 2 - 696354 + 696502 @@ -24871,7 +24691,7 @@ 1 2 - 696354 + 696502 @@ -25088,7 +24908,7 @@ 1 2 - 1674 + 1675 @@ -25264,17 +25084,17 @@ 1 2 - 442497 + 442591 2 9 - 36848 + 36856 9 201 - 4501 + 4502 @@ -25290,7 +25110,7 @@ 1 2 - 483847 + 483949 @@ -25306,7 +25126,7 @@ 1 2 - 479555 + 479656 2 @@ -25327,7 +25147,7 @@ 1 2 - 483847 + 483949 @@ -25337,11 +25157,11 @@ attribute_args - 352341 + 352360 id - 352341 + 352360 kind @@ -25349,7 +25169,7 @@ attribute - 270489 + 270503 index @@ -25357,7 +25177,7 @@ location - 329291 + 329308 @@ -25371,7 +25191,7 @@ 1 2 - 352341 + 352360 @@ -25387,7 +25207,7 @@ 1 2 - 352341 + 352360 @@ -25403,7 +25223,7 @@ 1 2 - 352341 + 352360 @@ -25419,7 +25239,7 @@ 1 2 - 352341 + 352360 @@ -25534,12 +25354,12 @@ 1 2 - 204631 + 204641 2 3 - 49864 + 49866 3 @@ -25560,7 +25380,7 @@ 1 2 - 260140 + 260153 2 @@ -25581,12 +25401,12 @@ 1 2 - 204631 + 204641 2 3 - 49864 + 49866 3 @@ -25607,12 +25427,12 @@ 1 2 - 204631 + 204641 2 3 - 49864 + 49866 3 @@ -25732,12 +25552,12 @@ 1 2 - 315179 + 315195 2 16 - 14112 + 14113 @@ -25753,7 +25573,7 @@ 1 2 - 316590 + 316606 2 @@ -25774,12 +25594,12 @@ 1 2 - 315179 + 315195 2 16 - 14112 + 14113 @@ -25795,7 +25615,7 @@ 1 2 - 329291 + 329308 @@ -25805,15 +25625,15 @@ attribute_arg_value - 351871 + 351889 arg - 351871 + 351889 value - 34810 + 34812 @@ -25827,7 +25647,7 @@ 1 2 - 351871 + 351889 @@ -25843,12 +25663,12 @@ 1 2 - 16934 + 16935 2 3 - 12230 + 12231 3 @@ -25969,15 +25789,15 @@ typeattributes - 62496 + 62509 type_id - 62077 + 62090 spec_id - 62496 + 62509 @@ -25991,7 +25811,7 @@ 1 2 - 61658 + 61671 2 @@ -26012,7 +25832,7 @@ 1 2 - 62496 + 62509 @@ -26022,15 +25842,15 @@ funcattributes - 635532 + 635565 func_id - 447366 + 447389 spec_id - 635532 + 635565 @@ -26044,17 +25864,17 @@ 1 2 - 341522 + 341540 2 3 - 64917 + 64920 3 6 - 39985 + 39987 6 @@ -26075,7 +25895,7 @@ 1 2 - 635532 + 635565 @@ -26143,15 +25963,15 @@ stmtattributes - 1006 + 1005 stmt_id - 1006 + 1005 spec_id - 1006 + 1005 @@ -26165,7 +25985,7 @@ 1 2 - 1006 + 1005 @@ -26181,7 +26001,7 @@ 1 2 - 1006 + 1005 @@ -26191,15 +26011,15 @@ unspecifiedtype - 10352924 + 10353463 type_id - 10352924 + 10353463 unspecified_type_id - 6956047 + 6956409 @@ -26213,7 +26033,7 @@ 1 2 - 10352924 + 10353463 @@ -26229,17 +26049,17 @@ 1 2 - 4675939 + 4676182 2 3 - 2037843 + 2037950 3 147 - 242264 + 242277 @@ -26249,19 +26069,19 @@ member - 5134480 + 5131470 parent - 689567 + 689163 index - 8808 + 8802 child - 5070710 + 5067737 @@ -26275,42 +26095,42 @@ 1 3 - 18884 + 18873 3 4 - 390691 + 390462 4 5 - 39072 + 39049 5 7 - 53059 + 53028 7 10 - 52848 + 52817 10 16 - 57569 + 57535 16 30 - 52954 + 52923 30 251 - 24486 + 24472 @@ -26326,42 +26146,42 @@ 1 3 - 18884 + 18873 3 4 - 390656 + 390427 4 5 - 39107 + 39084 5 7 - 53165 + 53134 7 10 - 53165 + 53134 10 16 - 57323 + 57289 16 29 - 52742 + 52711 29 253 - 24521 + 24507 @@ -26377,17 +26197,17 @@ 1 2 - 1409 + 1408 2 3 - 810 + 809 3 4 - 951 + 950 5 @@ -26448,7 +26268,7 @@ 1 2 - 810 + 809 2 @@ -26458,7 +26278,7 @@ 3 4 - 1162 + 1161 4 @@ -26503,7 +26323,7 @@ 2770 19253 - 458 + 457 @@ -26519,7 +26339,7 @@ 1 2 - 5070710 + 5067737 @@ -26535,12 +26355,12 @@ 1 2 - 5008419 + 5005483 2 8 - 62290 + 62254 @@ -26550,15 +26370,15 @@ enclosingfunction - 121743 + 121719 child - 121743 + 121719 parent - 69504 + 69490 @@ -26572,7 +26392,7 @@ 1 2 - 121743 + 121719 @@ -26588,22 +26408,22 @@ 1 2 - 36695 + 36687 2 3 - 21591 + 21587 3 4 - 6106 + 6105 4 45 - 5111 + 5110 @@ -26613,15 +26433,15 @@ derivations - 402388 + 402152 derivation - 402388 + 402152 sub - 381883 + 381659 index @@ -26629,11 +26449,11 @@ super - 206461 + 206340 location - 38156 + 38134 @@ -26647,7 +26467,7 @@ 1 2 - 402388 + 402152 @@ -26663,7 +26483,7 @@ 1 2 - 402388 + 402152 @@ -26679,7 +26499,7 @@ 1 2 - 402388 + 402152 @@ -26695,7 +26515,7 @@ 1 2 - 402388 + 402152 @@ -26711,12 +26531,12 @@ 1 2 - 366733 + 366518 2 7 - 15149 + 15141 @@ -26732,12 +26552,12 @@ 1 2 - 366733 + 366518 2 7 - 15149 + 15141 @@ -26753,12 +26573,12 @@ 1 2 - 366733 + 366518 2 7 - 15149 + 15141 @@ -26774,12 +26594,12 @@ 1 2 - 366733 + 366518 2 7 - 15149 + 15141 @@ -26924,12 +26744,12 @@ 1 2 - 199133 + 199016 2 1225 - 7328 + 7324 @@ -26945,12 +26765,12 @@ 1 2 - 199133 + 199016 2 1225 - 7328 + 7324 @@ -26966,12 +26786,12 @@ 1 2 - 206003 + 205882 2 4 - 458 + 457 @@ -26987,12 +26807,12 @@ 1 2 - 202867 + 202748 2 108 - 3593 + 3591 @@ -27008,22 +26828,22 @@ 1 2 - 28326 + 28310 2 5 - 3135 + 3133 5 16 - 2994 + 2992 17 133 - 2994 + 2992 142 @@ -27044,22 +26864,22 @@ 1 2 - 28326 + 28310 2 5 - 3135 + 3133 5 16 - 2994 + 2992 17 133 - 2994 + 2992 142 @@ -27080,7 +26900,7 @@ 1 2 - 38156 + 38134 @@ -27096,22 +26916,22 @@ 1 2 - 30757 + 30739 2 5 - 3417 + 3415 5 55 - 2889 + 2887 60 420 - 1092 + 1091 @@ -27121,11 +26941,11 @@ derspecifiers - 404291 + 404054 der_id - 402001 + 401765 spec_id @@ -27143,12 +26963,12 @@ 1 2 - 399710 + 399476 2 3 - 2290 + 2288 @@ -27189,11 +27009,11 @@ direct_base_offsets - 373110 + 372891 der_id - 373110 + 372891 offset @@ -27211,7 +27031,7 @@ 1 2 - 373110 + 372891 @@ -27262,11 +27082,11 @@ virtual_base_offsets - 6661 + 6660 sub - 3677 + 3676 super @@ -27288,7 +27108,7 @@ 1 2 - 2891 + 2890 2 @@ -27319,7 +27139,7 @@ 1 2 - 3099 + 3098 2 @@ -27553,23 +27373,23 @@ frienddecls - 715075 + 714656 id - 715075 + 714656 type_id - 42384 + 42359 decl_id - 70182 + 70141 location - 6341 + 6338 @@ -27583,7 +27403,7 @@ 1 2 - 715075 + 714656 @@ -27599,7 +27419,7 @@ 1 2 - 715075 + 714656 @@ -27615,7 +27435,7 @@ 1 2 - 715075 + 714656 @@ -27631,47 +27451,47 @@ 1 2 - 6200 + 6197 2 3 - 13212 + 13204 3 6 - 2959 + 2957 6 10 - 3206 + 3204 10 17 - 3276 + 3274 17 24 - 3347 + 3345 25 36 - 3311 + 3309 37 55 - 3241 + 3239 55 103 - 3628 + 3626 @@ -27687,47 +27507,47 @@ 1 2 - 6200 + 6197 2 3 - 13212 + 13204 3 6 - 2959 + 2957 6 10 - 3206 + 3204 10 17 - 3276 + 3274 17 24 - 3347 + 3345 25 36 - 3311 + 3309 37 55 - 3241 + 3239 55 103 - 3628 + 3626 @@ -27743,12 +27563,12 @@ 1 2 - 40939 + 40915 2 13 - 1444 + 1443 @@ -27764,37 +27584,37 @@ 1 2 - 40481 + 40458 2 3 - 5883 + 5880 3 8 - 6024 + 6021 8 15 - 5425 + 5422 15 32 - 5284 + 5281 32 71 - 5284 + 5281 72 160 - 1796 + 1795 @@ -27810,37 +27630,37 @@ 1 2 - 40481 + 40458 2 3 - 5883 + 5880 3 8 - 6024 + 6021 8 15 - 5425 + 5422 15 32 - 5284 + 5281 32 71 - 5284 + 5281 72 160 - 1796 + 1795 @@ -27856,7 +27676,7 @@ 1 2 - 69513 + 69472 2 @@ -27877,7 +27697,7 @@ 1 2 - 5954 + 5950 2 @@ -27898,7 +27718,7 @@ 1 2 - 6200 + 6197 2 @@ -27919,7 +27739,7 @@ 1 2 - 5989 + 5985 2 @@ -27934,19 +27754,19 @@ comments - 8781270 + 8783134 id - 8781270 + 8783134 contents - 3342962 + 3343672 location - 8781270 + 8783134 @@ -27960,7 +27780,7 @@ 1 2 - 8781270 + 8783134 @@ -27976,7 +27796,7 @@ 1 2 - 8781270 + 8783134 @@ -27992,17 +27812,17 @@ 1 2 - 3058223 + 3058872 2 7 - 251135 + 251189 7 32784 - 33603 + 33610 @@ -28018,17 +27838,17 @@ 1 2 - 3058223 + 3058872 2 7 - 251135 + 251189 7 32784 - 33603 + 33610 @@ -28044,7 +27864,7 @@ 1 2 - 8781270 + 8783134 @@ -28060,7 +27880,7 @@ 1 2 - 8781270 + 8783134 @@ -28070,15 +27890,15 @@ commentbinding - 3145674 + 3145838 id - 2490384 + 2490514 element - 3068526 + 3068686 @@ -28092,12 +27912,12 @@ 1 2 - 2408061 + 2408187 2 97 - 82322 + 82327 @@ -28113,12 +27933,12 @@ 1 2 - 2991378 + 2991533 2 3 - 77148 + 77152 @@ -28128,15 +27948,15 @@ exprconv - 7003750 + 7003755 converted - 7003750 + 7003755 conversion - 7003750 + 7003755 @@ -28150,7 +27970,7 @@ 1 2 - 7003750 + 7003755 @@ -28166,7 +27986,7 @@ 1 2 - 7003750 + 7003755 @@ -28176,22 +27996,22 @@ compgenerated - 8494343 + 8493976 id - 8494343 + 8493976 synthetic_destructor_call - 133110 + 133104 element - 103484 + 103479 i @@ -28199,7 +28019,7 @@ destructor_call - 117766 + 117760 @@ -28213,12 +28033,12 @@ 1 2 - 85546 + 85542 2 3 - 11832 + 11831 3 @@ -28239,12 +28059,12 @@ 1 2 - 85546 + 85542 2 3 - 11832 + 11831 3 @@ -28417,7 +28237,7 @@ 1 2 - 115749 + 115743 2 @@ -28438,7 +28258,7 @@ 1 2 - 117766 + 117760 @@ -28486,7 +28306,7 @@ 1 2 - 8937 + 8938 2 @@ -28517,15 +28337,15 @@ namespacembrs - 2463100 + 2463228 parentid - 10819 + 10820 memberid - 2463100 + 2463228 @@ -28605,7 +28425,7 @@ 1 2 - 2463100 + 2463228 @@ -28615,11 +28435,11 @@ exprparents - 14152882 + 14152891 expr_id - 14152882 + 14152891 child_index @@ -28627,7 +28447,7 @@ parent_id - 9417999 + 9418005 @@ -28641,7 +28461,7 @@ 1 2 - 14152882 + 14152891 @@ -28657,7 +28477,7 @@ 1 2 - 14152882 + 14152891 @@ -28775,12 +28595,12 @@ 1 2 - 5388939 + 5388942 2 3 - 3692597 + 3692599 3 @@ -28801,12 +28621,12 @@ 1 2 - 5388939 + 5388942 2 3 - 3692597 + 3692599 3 @@ -28821,22 +28641,22 @@ expr_isload - 4981779 + 4981688 expr_id - 4981779 + 4981688 conversionkinds - 4220621 + 4220624 expr_id - 4220621 + 4220624 kind @@ -28854,7 +28674,7 @@ 1 2 - 4220621 + 4220624 @@ -28883,8 +28703,8 @@ 1 - 26289 - 26290 + 26287 + 26288 1 @@ -28893,8 +28713,8 @@ 1 - 4131029 - 4131030 + 4131034 + 4131035 1 @@ -28905,11 +28725,11 @@ iscall - 3078157 + 3078281 caller - 3078157 + 3078281 kind @@ -28927,7 +28747,7 @@ 1 2 - 3078157 + 3078281 @@ -28951,8 +28771,8 @@ 18 - 167025 - 167026 + 167040 + 167041 18 @@ -28963,11 +28783,11 @@ numtemplatearguments - 543303 + 543548 expr_id - 543303 + 543548 num @@ -28985,7 +28805,7 @@ 1 2 - 543303 + 543548 @@ -29014,8 +28834,8 @@ 18 - 29893 - 29894 + 29908 + 29909 18 @@ -29074,23 +28894,23 @@ namequalifiers - 1618961 + 1618866 id - 1618961 + 1618866 qualifiableelement - 1618961 + 1618866 qualifyingelement - 79675 + 79653 location - 282719 + 282705 @@ -29104,7 +28924,7 @@ 1 2 - 1618961 + 1618866 @@ -29120,7 +28940,7 @@ 1 2 - 1618961 + 1618866 @@ -29136,7 +28956,7 @@ 1 2 - 1618961 + 1618866 @@ -29152,7 +28972,7 @@ 1 2 - 1618961 + 1618866 @@ -29168,7 +28988,7 @@ 1 2 - 1618961 + 1618866 @@ -29184,7 +29004,7 @@ 1 2 - 1618961 + 1618866 @@ -29200,12 +29020,12 @@ 1 2 - 45546 + 45526 2 3 - 17163 + 17162 3 @@ -29236,12 +29056,12 @@ 1 2 - 45546 + 45526 2 3 - 17163 + 17162 3 @@ -29272,7 +29092,7 @@ 1 2 - 49725 + 49704 2 @@ -29308,32 +29128,32 @@ 1 2 - 91742 + 91737 2 3 - 25646 + 25644 3 4 - 42179 + 42177 4 6 - 12895 + 12894 6 7 - 89869 + 89865 7 2135 - 20387 + 20386 @@ -29349,32 +29169,32 @@ 1 2 - 91742 + 91737 2 3 - 25646 + 25644 3 4 - 42179 + 42177 4 6 - 12895 + 12894 6 7 - 89869 + 89865 7 2135 - 20387 + 20386 @@ -29390,17 +29210,17 @@ 1 2 - 125168 + 125162 2 3 - 52354 + 52352 3 4 - 96622 + 96618 4 @@ -29415,11 +29235,11 @@ varbind - 6006364 + 6006368 expr - 6006364 + 6006368 var @@ -29437,7 +29257,7 @@ 1 2 - 6006364 + 6006368 @@ -29508,15 +29328,15 @@ funbind - 3080553 + 3080676 expr - 3076933 + 3077056 fun - 514055 + 514013 @@ -29530,7 +29350,7 @@ 1 2 - 3073313 + 3073437 2 @@ -29551,32 +29371,32 @@ 1 2 - 306582 + 306531 2 3 - 78775 + 78789 3 4 - 37226 + 37224 4 7 - 43475 + 43473 7 38 - 38703 + 38701 38 4943 - 9293 + 9292 @@ -29586,11 +29406,11 @@ expr_allocator - 46541 + 46514 expr - 46541 + 46514 func @@ -29612,7 +29432,7 @@ 1 2 - 46541 + 46514 @@ -29628,7 +29448,7 @@ 1 2 - 46541 + 46514 @@ -29712,11 +29532,11 @@ expr_deallocator - 55314 + 55282 expr - 55314 + 55282 func @@ -29738,7 +29558,7 @@ 1 2 - 55314 + 55282 @@ -29754,7 +29574,7 @@ 1 2 - 55314 + 55282 @@ -29907,15 +29727,15 @@ expr_cond_true - 654499 + 654500 cond - 654499 + 654500 true - 654499 + 654500 @@ -29929,7 +29749,7 @@ 1 2 - 654499 + 654500 @@ -29945,7 +29765,7 @@ 1 2 - 654499 + 654500 @@ -30003,11 +29823,11 @@ values - 10646146 + 10646153 id - 10646146 + 10646153 str @@ -30025,7 +29845,7 @@ 1 2 - 10646146 + 10646153 @@ -30071,15 +29891,15 @@ valuetext - 4756729 + 4756702 id - 4756729 + 4756702 text - 703924 + 703921 @@ -30093,7 +29913,7 @@ 1 2 - 4756729 + 4756702 @@ -30114,17 +29934,17 @@ 2 3 - 102489 + 102490 3 7 - 56759 + 56757 7 425881 - 17147 + 17145 @@ -30134,15 +29954,15 @@ valuebind - 11083050 + 11083057 val - 10646146 + 10646153 expr - 11083050 + 11083057 @@ -30156,7 +29976,7 @@ 1 2 - 10232022 + 10232029 2 @@ -30177,7 +29997,7 @@ 1 2 - 11083050 + 11083057 @@ -30388,11 +30208,11 @@ bitfield - 20936 + 20941 id - 20936 + 20941 bits @@ -30414,7 +30234,7 @@ 1 2 - 20936 + 20941 @@ -30430,7 +30250,7 @@ 1 2 - 20936 + 20941 @@ -30574,23 +30394,23 @@ initialisers - 1731824 + 1732353 init - 1731824 + 1732353 var - 717748 + 721222 expr - 1731824 + 1732353 location - 390436 + 390438 @@ -30604,7 +30424,7 @@ 1 2 - 1731824 + 1732353 @@ -30620,7 +30440,7 @@ 1 2 - 1731824 + 1732353 @@ -30636,7 +30456,7 @@ 1 2 - 1731824 + 1732353 @@ -30652,22 +30472,17 @@ 1 2 - 629392 + 632463 2 16 - 31625 + 32109 16 25 - 56686 - - - 25 - 112 - 44 + 56649 @@ -30683,22 +30498,17 @@ 1 2 - 629392 + 632463 2 16 - 31625 + 32109 16 25 - 56686 - - - 25 - 112 - 44 + 56649 @@ -30714,12 +30524,12 @@ 1 2 - 717666 + 721215 2 - 4 - 81 + 3 + 6 @@ -30735,7 +30545,7 @@ 1 2 - 1731824 + 1732353 @@ -30751,7 +30561,7 @@ 1 2 - 1731824 + 1732353 @@ -30767,7 +30577,7 @@ 1 2 - 1731824 + 1732353 @@ -30783,7 +30593,7 @@ 1 2 - 317956 + 317957 2 @@ -30798,7 +30608,7 @@ 15 111459 - 17855 + 17856 @@ -30814,17 +30624,17 @@ 1 2 - 340955 + 340698 2 4 - 35579 + 35642 4 12738 - 13901 + 14096 @@ -30840,7 +30650,7 @@ 1 2 - 317956 + 317957 2 @@ -30855,7 +30665,7 @@ 15 111459 - 17855 + 17856 @@ -30876,15 +30686,15 @@ expr_ancestor - 121674 + 121668 exp - 121674 + 121668 ancestor - 84880 + 84876 @@ -30898,7 +30708,7 @@ 1 2 - 121674 + 121668 @@ -30914,12 +30724,12 @@ 1 2 - 61377 + 61374 2 3 - 16785 + 16784 3 @@ -30939,19 +30749,19 @@ exprs - 18300140 + 18300152 id - 18300140 + 18300152 kind - 3382 + 3380 location - 3561673 + 3559831 @@ -30965,7 +30775,7 @@ 1 2 - 18300140 + 18300152 @@ -30981,7 +30791,7 @@ 1 2 - 18300140 + 18300152 @@ -31050,13 +30860,13 @@ 281 - 6591 - 63491 + 6528 + 63599 281 - 78915 - 109590 + 79044 + 109592 70 @@ -31127,11 +30937,11 @@ 1051 - 14609 + 14618 281 - 16974 + 16981 32757 140 @@ -31149,32 +30959,32 @@ 1 2 - 1936933 + 1935551 2 3 - 816932 + 816946 3 4 - 247260 + 247397 4 8 - 280872 + 280461 8 - 136 - 267131 + 137 + 267010 - 136 + 137 54140 - 12542 + 12464 @@ -31190,22 +31000,22 @@ 1 2 - 2363808 + 2362352 2 3 - 873691 + 873426 3 6 - 307261 + 307151 6 25 - 16911 + 16901 @@ -31215,15 +31025,15 @@ expr_types - 18357789 + 18357798 id - 18300140 + 18300152 typeid - 829282 + 829243 value_category @@ -31241,12 +31051,12 @@ 1 2 - 18242562 + 18242577 2 5 - 57577 + 57574 @@ -31262,7 +31072,7 @@ 1 2 - 18300140 + 18300152 @@ -31278,42 +31088,42 @@ 1 2 - 293470 + 292376 2 3 - 160720 + 161054 3 4 - 69824 + 70343 4 5 - 60801 + 60978 5 7 - 66996 + 66993 7 12 - 65321 + 65336 12 35 - 62638 + 62653 35 - 78674 - 49509 + 78689 + 49506 @@ -31329,12 +31139,12 @@ 1 2 - 716180 + 715462 2 3 - 102314 + 102993 3 @@ -31353,18 +31163,18 @@ 12 - 11828 - 11829 + 11826 + 11827 18 - 253738 - 253739 + 253755 + 253756 18 - 750551 - 750552 + 750585 + 750586 18 @@ -31379,18 +31189,18 @@ 12 - 1446 - 1447 + 1484 + 1485 18 - 11978 - 11979 + 11980 + 11981 18 - 39501 - 39502 + 39499 + 39500 18 @@ -31401,15 +31211,15 @@ new_allocated_type - 47598 + 47571 expr - 47598 + 47571 type_id - 28150 + 28134 @@ -31423,7 +31233,7 @@ 1 2 - 47598 + 47571 @@ -31439,17 +31249,17 @@ 1 2 - 11767 + 11760 2 3 - 14903 + 14894 3 19 - 1479 + 1478 @@ -32069,15 +31879,15 @@ condition_decl_bind - 38595 + 38593 expr - 38595 + 38593 decl - 38595 + 38593 @@ -32091,7 +31901,7 @@ 1 2 - 38595 + 38593 @@ -32107,7 +31917,7 @@ 1 2 - 38595 + 38593 @@ -32117,15 +31927,15 @@ typeid_bind - 36430 + 36408 expr - 36430 + 36408 type_id - 16383 + 16373 @@ -32139,7 +31949,7 @@ 1 2 - 36430 + 36408 @@ -32155,7 +31965,7 @@ 1 2 - 15960 + 15950 3 @@ -32354,11 +32164,11 @@ lambdas - 21639 + 21640 expr - 21639 + 21640 default_capture @@ -32380,7 +32190,7 @@ 1 2 - 21639 + 21640 @@ -32396,7 +32206,7 @@ 1 2 - 21639 + 21640 @@ -32470,15 +32280,15 @@ lambda_capture - 28224 + 28226 id - 28224 + 28226 lambda - 20698 + 20699 index @@ -32486,7 +32296,7 @@ field - 28224 + 28226 captured_by_reference @@ -32512,7 +32322,7 @@ 1 2 - 28224 + 28226 @@ -32528,7 +32338,7 @@ 1 2 - 28224 + 28226 @@ -32544,7 +32354,7 @@ 1 2 - 28224 + 28226 @@ -32560,7 +32370,7 @@ 1 2 - 28224 + 28226 @@ -32576,7 +32386,7 @@ 1 2 - 28224 + 28226 @@ -32592,7 +32402,7 @@ 1 2 - 28224 + 28226 @@ -32608,12 +32418,12 @@ 1 2 - 13171 + 13172 2 3 - 7526 + 7527 @@ -32629,12 +32439,12 @@ 1 2 - 13171 + 13172 2 3 - 7526 + 7527 @@ -32650,12 +32460,12 @@ 1 2 - 13171 + 13172 2 3 - 7526 + 7527 @@ -32671,7 +32481,7 @@ 1 2 - 20698 + 20699 @@ -32687,7 +32497,7 @@ 1 2 - 20698 + 20699 @@ -32703,12 +32513,12 @@ 1 2 - 13171 + 13172 2 3 - 7526 + 7527 @@ -32840,7 +32650,7 @@ 1 2 - 28224 + 28226 @@ -32856,7 +32666,7 @@ 1 2 - 28224 + 28226 @@ -32872,7 +32682,7 @@ 1 2 - 28224 + 28226 @@ -32888,7 +32698,7 @@ 1 2 - 28224 + 28226 @@ -32904,7 +32714,7 @@ 1 2 - 28224 + 28226 @@ -32920,7 +32730,7 @@ 1 2 - 28224 + 28226 @@ -33349,19 +33159,19 @@ stmts - 4660299 + 4661289 id - 4660299 + 4661289 kind - 1988 + 1989 location - 2286915 + 2287401 @@ -33375,7 +33185,7 @@ 1 2 - 4660299 + 4661289 @@ -33391,7 +33201,7 @@ 1 2 - 4660299 + 4661289 @@ -33619,22 +33429,22 @@ 1 2 - 1892154 + 1892555 2 4 - 175972 + 176010 4 12 - 176182 + 176219 12 699 - 42606 + 42615 @@ -33650,12 +33460,12 @@ 1 2 - 2229653 + 2230127 2 8 - 57261 + 57274 @@ -33953,15 +33763,15 @@ constexpr_if_then - 52551 + 52562 constexpr_if_stmt - 52551 + 52562 then_id - 52551 + 52562 @@ -33975,7 +33785,7 @@ 1 2 - 52551 + 52562 @@ -33991,7 +33801,7 @@ 1 2 - 52551 + 52562 @@ -34001,15 +33811,15 @@ constexpr_if_else - 30881 + 30888 constexpr_if_stmt - 30881 + 30888 else_id - 30881 + 30888 @@ -34023,7 +33833,7 @@ 1 2 - 30881 + 30888 @@ -34039,7 +33849,7 @@ 1 2 - 30881 + 30888 @@ -34049,15 +33859,15 @@ while_body - 30207 + 30201 while_stmt - 30207 + 30201 body_id - 30207 + 30201 @@ -34071,7 +33881,7 @@ 1 2 - 30207 + 30201 @@ -34087,7 +33897,7 @@ 1 2 - 30207 + 30201 @@ -34097,15 +33907,15 @@ do_body - 148604 + 148599 do_stmt - 148604 + 148599 body_id - 148604 + 148599 @@ -34119,7 +33929,7 @@ 1 2 - 148604 + 148599 @@ -34135,7 +33945,7 @@ 1 2 - 148604 + 148599 @@ -34193,7 +34003,7 @@ switch_case - 191408 + 191399 switch_stmt @@ -34205,7 +34015,7 @@ case_id - 191408 + 191399 @@ -34361,7 +34171,7 @@ 32 33 - 1909 + 1908 33 @@ -34402,7 +34212,7 @@ 32 33 - 1909 + 1908 33 @@ -34433,7 +34243,7 @@ 1 2 - 191408 + 191399 @@ -34449,7 +34259,7 @@ 1 2 - 191408 + 191399 @@ -34699,19 +34509,19 @@ stmtparents - 4052305 + 4052323 id - 4052305 + 4052323 index - 12209 + 12210 parent - 1719463 + 1719470 @@ -34725,7 +34535,7 @@ 1 2 - 4052305 + 4052323 @@ -34741,7 +34551,7 @@ 1 2 - 4052305 + 4052323 @@ -34879,12 +34689,12 @@ 1 2 - 987317 + 987321 2 3 - 372963 + 372965 3 @@ -34894,7 +34704,7 @@ 4 6 - 111241 + 111242 6 @@ -34920,12 +34730,12 @@ 1 2 - 987317 + 987321 2 3 - 372963 + 372965 3 @@ -34935,7 +34745,7 @@ 4 6 - 111241 + 111242 6 @@ -34955,11 +34765,11 @@ ishandler - 59432 + 59429 block - 59432 + 59429 @@ -35528,15 +35338,15 @@ blockscope - 1438063 + 1438137 block - 1438063 + 1438137 enclosing - 1321870 + 1321939 @@ -35550,7 +35360,7 @@ 1 2 - 1438063 + 1438137 @@ -35566,12 +35376,12 @@ 1 2 - 1256011 + 1256077 2 13 - 65858 + 65861 @@ -35581,19 +35391,19 @@ jumpinfo - 253995 + 253987 id - 253995 + 253987 str - 21152 + 21151 target - 53046 + 53044 @@ -35607,7 +35417,7 @@ 1 2 - 253995 + 253987 @@ -35623,7 +35433,7 @@ 1 2 - 253995 + 253987 @@ -35685,7 +35495,7 @@ 1 2 - 16717 + 16716 2 @@ -35721,7 +35531,7 @@ 2 3 - 26428 + 26427 3 @@ -35736,7 +35546,7 @@ 5 8 - 4691 + 4690 8 @@ -35757,7 +35567,7 @@ 1 2 - 53046 + 53044 @@ -35767,19 +35577,19 @@ preprocdirects - 4431252 + 4432193 id - 4431252 + 4432193 kind - 1046 + 1047 location - 4428739 + 4429680 @@ -35793,7 +35603,7 @@ 1 2 - 4431252 + 4432193 @@ -35809,7 +35619,7 @@ 1 2 - 4431252 + 4432193 @@ -35947,7 +35757,7 @@ 1 2 - 4428635 + 4429575 25 @@ -35968,7 +35778,7 @@ 1 2 - 4428739 + 4429680 @@ -35978,15 +35788,15 @@ preprocpair - 1442296 + 1442371 begin - 1206147 + 1206210 elseelifend - 1442296 + 1442371 @@ -36000,12 +35810,12 @@ 1 2 - 985992 + 986044 2 3 - 209805 + 209816 3 @@ -36026,7 +35836,7 @@ 1 2 - 1442296 + 1442371 @@ -36036,41 +35846,41 @@ preproctrue - 782302 + 783284 branch - 782302 + 783284 preprocfalse - 327409 + 326956 branch - 327409 + 326956 preproctext - 3572638 + 3573396 id - 3572638 + 3573396 head - 2591544 + 2592094 body - 1515816 + 1516138 @@ -36084,7 +35894,7 @@ 1 2 - 3572638 + 3573396 @@ -36100,7 +35910,7 @@ 1 2 - 3572638 + 3573396 @@ -36116,12 +35926,12 @@ 1 2 - 2444464 + 2444983 2 740 - 147080 + 147111 @@ -36137,12 +35947,12 @@ 1 2 - 2529362 + 2529899 2 5 - 62181 + 62195 @@ -36158,17 +35968,17 @@ 1 2 - 1372191 + 1372482 2 6 - 113686 + 113710 6 11572 - 29939 + 29945 @@ -36184,17 +35994,17 @@ 1 2 - 1375227 + 1375519 2 7 - 114000 + 114024 7 2959 - 26589 + 26595 @@ -36204,15 +36014,15 @@ includes - 315649 + 315665 id - 315649 + 315665 included - 118074 + 118080 @@ -36226,7 +36036,7 @@ 1 2 - 315649 + 315665 @@ -36242,12 +36052,12 @@ 1 2 - 61624 + 61627 2 3 - 22109 + 22110 3 @@ -36262,7 +36072,7 @@ 6 14 - 8937 + 8938 14 @@ -36325,11 +36135,11 @@ link_parent - 40143068 + 40119536 element - 5115983 + 5112984 link_target @@ -36347,17 +36157,17 @@ 1 2 - 701934 + 701522 2 9 - 44146 + 44120 9 10 - 4369903 + 4367341 From bce253920c0ebda146bb9879f01604cefbc2d9fd Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 27 Jul 2022 10:16:55 +0200 Subject: [PATCH 446/465] C++: Fix `__builtin_shuffle` qldoc --- cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll index 866ed3c314a..d18f4bdcb66 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll @@ -502,7 +502,8 @@ class BuiltInOperationBuiltInShuffleVector extends BuiltInOperation, @builtinshu * for more information. * ``` * // Concatenate every other element of 4-element vectors V1 and V2. - * V3 = __builtin_shufflevector(V1, V2, {0, 2, 4, 6}); + * M = {0, 2, 4, 6}; + * V3 = __builtin_shuffle(V1, V2, M); * ``` */ class BuiltInOperationBuiltInShuffle extends BuiltInOperation, @builtinshuffle { From 5a59354d73ac1e643aafb5c31bb02b9d37776f2f Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 27 Jul 2022 10:21:40 +0200 Subject: [PATCH 447/465] C++: Minor clean up of the builtin operations qldoc --- .../code/cpp/exprs/BuiltInOperations.qll | 58 +++++++++---------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll index d18f4bdcb66..979c9c03940 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/BuiltInOperations.qll @@ -1,5 +1,5 @@ /** - * Provides classes for modeling built-in operations. Built-in operations are + * Provides classes for modeling built-in operations. Built-in operations are * typically compiler specific and are used by libraries and generated code. */ @@ -120,8 +120,8 @@ class BuiltInNoOp extends BuiltInOperation, @noopexpr { /** * A C/C++ `__builtin_offsetof` built-in operation (used by some implementations - * of `offsetof`). The operation retains its semantics even in the presence - * of an overloaded `operator &`). This is a gcc/clang extension. + * of `offsetof`). The operation retains its semantics even in the presence + * of an overloaded `operator &`). This is a gcc/clang extension. * ``` * struct S { * int a, b; @@ -137,8 +137,8 @@ class BuiltInOperationBuiltInOffsetOf extends BuiltInOperation, @offsetofexpr { /** * A C/C++ `__INTADDR__` built-in operation (used by some implementations - * of `offsetof`). The operation retains its semantics even in the presence - * of an overloaded `operator &`). This is an EDG extension. + * of `offsetof`). The operation retains its semantics even in the presence + * of an overloaded `operator &`). This is an EDG extension. * ``` * struct S { * int a, b; @@ -479,8 +479,7 @@ class BuiltInOperationBuiltInTypesCompatibleP extends BuiltInOperation, @typesco /** * A clang `__builtin_shufflevector` expression. * - * It outputs a permutation of elements from one or two input vectors. - * Please see + * It outputs a permutation of elements from one or two input vectors. See * https://releases.llvm.org/3.7.0/tools/clang/docs/LanguageExtensions.html#langext-builtin-shufflevector * for more information. * ``` @@ -498,7 +497,7 @@ class BuiltInOperationBuiltInShuffleVector extends BuiltInOperation, @builtinshu * A gcc `__builtin_shuffle` expression. * * It outputs a permutation of elements from one or two input vectors. - * Please see https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html + * See https://gcc.gnu.org/onlinedocs/gcc/Vector-Extensions.html * for more information. * ``` * // Concatenate every other element of 4-element vectors V1 and V2. @@ -516,7 +515,7 @@ class BuiltInOperationBuiltInShuffle extends BuiltInOperation, @builtinshuffle { * A clang `__builtin_convertvector` expression. * * Allows for conversion of vectors of equal element count and compatible - * element types. Please see + * element types. See * https://releases.llvm.org/3.7.0/tools/clang/docs/LanguageExtensions.html#builtin-convertvector * for more information. * ``` @@ -679,10 +678,9 @@ class BuiltInOperationIsAssignable extends BuiltInOperation, @isassignable { * of the `` header). * * Returns `true` if the type is a primitive type, or a `class`, `struct` or - * `union` WITHOUT (1) virtual functions or base classes, (2) reference member - * variable or (3) multiple occurrences of base `class` objects, among other - * restrictions. Please see - * https://en.cppreference.com/w/cpp/named_req/StandardLayoutType + * `union` without (1) virtual functions or base classes, (2) reference member + * variable, or (3) multiple occurrences of base `class` objects, among other + * restrictions. See https://en.cppreference.com/w/cpp/named_req/StandardLayoutType * for more information. * ``` * bool v = __is_standard_layout(MyType); @@ -699,7 +697,7 @@ class BuiltInOperationIsStandardLayout extends BuiltInOperation, @isstandardlayo * implementations of the `` header). * * Returns `true` if instances of this type can be copied by trivial - * means. The copying is done in a manner similar to the `memcpy` + * means. The copying is done in a manner similar to the `memcpy` * function. */ class BuiltInOperationIsTriviallyCopyable extends BuiltInOperation, @istriviallycopyableexpr { @@ -713,7 +711,7 @@ class BuiltInOperationIsTriviallyCopyable extends BuiltInOperation, @istrivially * the `` header). * * Returns `true` if the type is a scalar type, a reference type or an array of - * literal types, among others. Please see + * literal types, among others. See * https://en.cppreference.com/w/cpp/named_req/LiteralType * for more information. * @@ -816,7 +814,7 @@ class BuiltInOperationIsNothrowConstructible extends BuiltInOperation, @isnothro } /** - * The `__has_finalizer` built-in operation. This is a Microsoft extension. + * The `__has_finalizer` built-in operation. This is a Microsoft extension. * * Returns `true` if the type defines a _finalizer_ `C::!C(void)`, to be called * from either the regular destructor or the garbage collector. @@ -831,10 +829,10 @@ class BuiltInOperationHasFinalizer extends BuiltInOperation, @hasfinalizerexpr { } /** - * The `__is_delegate` built-in operation. This is a Microsoft extension. + * The `__is_delegate` built-in operation. This is a Microsoft extension. * * Returns `true` if the function has been declared as a `delegate`, used in - * message forwarding. Please see + * message forwarding. See * https://docs.microsoft.com/en-us/cpp/extensions/delegate-cpp-component-extensions * for more information. */ @@ -845,9 +843,9 @@ class BuiltInOperationIsDelegate extends BuiltInOperation, @isdelegateexpr { } /** - * The `__is_interface_class` built-in operation. This is a Microsoft extension. + * The `__is_interface_class` built-in operation. This is a Microsoft extension. * - * Returns `true` if the type has been declared as an `interface`. Please see + * Returns `true` if the type has been declared as an `interface`. See * https://docs.microsoft.com/en-us/cpp/extensions/interface-class-cpp-component-extensions * for more information. */ @@ -858,9 +856,9 @@ class BuiltInOperationIsInterfaceClass extends BuiltInOperation, @isinterfacecla } /** - * The `__is_ref_array` built-in operation. This is a Microsoft extension. + * The `__is_ref_array` built-in operation. This is a Microsoft extension. * - * Returns `true` if the object passed in is a _platform array_. Please see + * Returns `true` if the object passed in is a _platform array_. See * https://docs.microsoft.com/en-us/cpp/extensions/arrays-cpp-component-extensions * for more information. * ``` @@ -875,9 +873,9 @@ class BuiltInOperationIsRefArray extends BuiltInOperation, @isrefarrayexpr { } /** - * The `__is_ref_class` built-in operation. This is a Microsoft extension. + * The `__is_ref_class` built-in operation. This is a Microsoft extension. * - * Returns `true` if the type is a _reference class_. Please see + * Returns `true` if the type is a _reference class_. See * https://docs.microsoft.com/en-us/cpp/extensions/classes-and-structs-cpp-component-extensions * for more information. * ``` @@ -892,10 +890,10 @@ class BuiltInOperationIsRefClass extends BuiltInOperation, @isrefclassexpr { } /** - * The `__is_sealed` built-in operation. This is a Microsoft extension. + * The `__is_sealed` built-in operation. This is a Microsoft extension. * * Returns `true` if a given class or virtual function is marked as `sealed`, - * meaning that it cannot be extended or overridden. The `sealed` keyword + * meaning that it cannot be extended or overridden. The `sealed` keyword * is similar to the C++11 `final` keyword. * ``` * ref class X sealed { @@ -910,7 +908,7 @@ class BuiltInOperationIsSealed extends BuiltInOperation, @issealedexpr { } /** - * The `__is_simple_value_class` built-in operation. This is a Microsoft extension. + * The `__is_simple_value_class` built-in operation. This is a Microsoft extension. * * Returns `true` if passed a value type that contains no references to the * garbage-collected heap. @@ -929,9 +927,9 @@ class BuiltInOperationIsSimpleValueClass extends BuiltInOperation, @issimplevalu } /** - * The `__is_value_class` built-in operation. This is a Microsoft extension. + * The `__is_value_class` built-in operation. This is a Microsoft extension. * - * Returns `true` if passed a value type. Please see + * Returns `true` if passed a value type. See * https://docs.microsoft.com/en-us/cpp/extensions/classes-and-structs-cpp-component-extensions * For more information. * ``` @@ -964,7 +962,7 @@ class BuiltInOperationIsFinal extends BuiltInOperation, @isfinalexpr { } /** - * The `__builtin_choose_expr` expression. This is a gcc/clang extension. + * The `__builtin_choose_expr` expression. This is a gcc/clang extension. * * The expression functions similarly to the ternary `?:` operator, except * that it is evaluated at compile-time. From a27b1ee33a897e4641d6b2d660ab284c4dc5298d Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Wed, 27 Jul 2022 10:27:43 +0200 Subject: [PATCH 448/465] C++: Improve `ErrorExpr` documentation to match current practise --- cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll index 55a59cc9588..68973293425 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll @@ -596,9 +596,12 @@ class ParenthesisExpr extends Conversion, @parexpr { } /** - * A C/C++ expression that has not been resolved. + * A C/C++ expression that could not be resolved, or that can no longer be + * represented due to a database upgrade or downgrade. * - * It is assigned `ErroneousType` as its type. + * If the expression could not be resolved, it has type `ErroneousType`. In the + * case of a database upgrade or downgrade, the original type from before the + * upgrade or downgrade is kept if that type can be represented. */ class ErrorExpr extends Expr, @errorexpr { override string toString() { result = "" } From 50e1ffda645610ff7b8dcf924b630d558ff58350 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Fri, 29 Jul 2022 10:19:13 +0200 Subject: [PATCH 449/465] Swift: put all the PCM traps into the same place --- swift/extractor/SwiftExtractor.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 666b7a90044..8ad2fe128ac 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -17,6 +17,7 @@ #include "swift/extractor/infra/TargetFile.h" using namespace codeql; +using namespace std::string_literals; static void archiveFile(const SwiftExtractorConfiguration& config, swift::SourceFile& file) { if (std::error_code ec = llvm::sys::fs::create_directories(config.trapDir)) { @@ -53,12 +54,16 @@ static std::string getFilename(swift::ModuleDecl& module, swift::SourceFile* pri if (primaryFile) { return primaryFile->getFilename().str(); } - // Several modules with different name might come from .pcm (clang module) files - // In this case we want to differentiate them - std::string filename = module.getModuleFilename().str(); - filename += "-"; - filename += module.getName().str(); - return filename; + // PCM clang module + if (module.isNonSwiftModule()) { + // Several modules with different name might come from .pcm (clang module) files + // In this case we want to differentiate them + std::string filename = "/pcms/"s + llvm::sys::path::filename(module.getModuleFilename()).str(); + filename += "-"; + filename += module.getName().str(); + return filename; + } + return module.getModuleFilename().str(); } static llvm::SmallVector getTopLevelDecls(swift::ModuleDecl& module, From 065fecc57e9a962c97d488ac121df2816f680082 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 29 Jul 2022 10:55:26 +0200 Subject: [PATCH 450/465] Swift: extract precompiled swiftmodule files Previously we were not extracting any `swiftmodule` file that was not a system or a built-in one. This was done to avoid re-extracting `swiftmodule` files that were built previously in the same build, but it turned out to be too eager, as there are legitimate cases where a non-system, non-built-in precompiled swift module can be used. An example of that is the `PackageDescription` module used in Swift Package Manager manifest files (`Package.swift`). We now relax the test and trigger module extraction on all loaded modules that do not have source files (we trigger source file extraction for those). The catch, is that we also create empty trap files for current output `swiftmodule` files (including possible alias locations set up by XCode). This means that if a following extractor run loads a previously built `swiftmodule` file, although it will trigger module extraction, this will however be skipped as it will find its target file already present (this is done via the `TargetFile` semantics). --- swift/extractor/SwiftExtractor.cpp | 37 ++++++++++++------- swift/extractor/SwiftExtractorConfiguration.h | 4 ++ swift/extractor/SwiftOutputRewrite.cpp | 12 +++++- swift/extractor/SwiftOutputRewrite.h | 5 ++- swift/extractor/main.cpp | 1 + .../partial-modules/Modules.expected | 1 + swift/integration-tests/runner.py | 2 + 7 files changed, 46 insertions(+), 16 deletions(-) diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 666b7a90044..bbf2a2551fd 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -165,22 +165,31 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, auto inputFiles = collectInputFilenames(compiler); auto modules = collectModules(compiler); + // we want to make sure any following extractor run will not try to extract things from + // the swiftmodule files we are creating in this run, as those things will already have been + // extracted from source with more information. We do this by creating empty trap files. + // TargetFile semantics will ensure any following run trying to extract that swiftmodule will just + // skip doing it + auto outputModuleTrapSuffix = "-" + compiler.getMainModule()->getName().str().str() + ".trap"; + for (const auto& output : config.outputSwiftModules) { + TargetFile::create(output + outputModuleTrapSuffix, config.trapDir, config.getTempTrapDir()); + } for (auto& module : modules) { - // We only extract system and builtin modules here as the other "user" modules can be built - // during the build process and then re-used at a later stage. In this case, we extract the - // user code twice: once during the module build in a form of a source file, and then as - // a pre-built module during building of the dependent source files. - if (module->isSystemModule() || module->isBuiltinModule()) { - extractDeclarations(config, compiler, *module); - } else { - for (auto file : module->getFiles()) { - auto sourceFile = llvm::dyn_cast(file); - if (!sourceFile || inputFiles.count(sourceFile->getFilename().str()) == 0) { - continue; - } - archiveFile(config, *sourceFile); - extractDeclarations(config, compiler, *module, sourceFile); + bool isFromSourceFile = false; + for (auto file : module->getFiles()) { + auto sourceFile = llvm::dyn_cast(file); + if (!sourceFile) { + continue; } + isFromSourceFile = true; + if (inputFiles.count(sourceFile->getFilename().str()) == 0) { + continue; + } + archiveFile(config, *sourceFile); + extractDeclarations(config, compiler, *module, sourceFile); + } + if (!isFromSourceFile) { + extractDeclarations(config, compiler, *module); } } } diff --git a/swift/extractor/SwiftExtractorConfiguration.h b/swift/extractor/SwiftExtractorConfiguration.h index 3365da5f268..eec73e7dc21 100644 --- a/swift/extractor/SwiftExtractorConfiguration.h +++ b/swift/extractor/SwiftExtractorConfiguration.h @@ -32,5 +32,9 @@ struct SwiftExtractorConfiguration { // A temporary directory that contains build artifacts generated by the extractor during the // overall extraction process. std::string getTempArtifactDir() const { return scratchDir + "/swift-extraction-artifacts"; } + + // Output swiftmodule files. This also includes possible locations where XCode internally moves + // modules + std::vector outputSwiftModules; }; } // namespace codeql diff --git a/swift/extractor/SwiftOutputRewrite.cpp b/swift/extractor/SwiftOutputRewrite.cpp index 35a38512ff8..f85290f5beb 100644 --- a/swift/extractor/SwiftOutputRewrite.cpp +++ b/swift/extractor/SwiftOutputRewrite.cpp @@ -163,7 +163,7 @@ static std::vector computeModuleAliases(llvm::StringRef modulePath, namespace codeql { std::unordered_map rewriteOutputsInPlace( - SwiftExtractorConfiguration& config, + const SwiftExtractorConfiguration& config, std::vector& CLIArgs) { std::unordered_map remapping; @@ -323,5 +323,15 @@ std::vector collectVFSFiles(const SwiftExtractorConfiguration& conf return overlays; } +std::vector getOutputSwiftModules( + const std::unordered_map& remapping) { + std::vector ret; + for (const auto& [oldPath, newPath] : remapping) { + if (llvm::StringRef(oldPath).endswith(".swiftmodule")) { + ret.push_back(oldPath); + } + } + return ret; +} } // namespace codeql diff --git a/swift/extractor/SwiftOutputRewrite.h b/swift/extractor/SwiftOutputRewrite.h index b7ee7fa3829..61ef2d98ea6 100644 --- a/swift/extractor/SwiftOutputRewrite.h +++ b/swift/extractor/SwiftOutputRewrite.h @@ -13,7 +13,7 @@ struct SwiftExtractorConfiguration; // artifacts produced by the actual Swift compiler. // Returns the map containing remapping oldpath -> newPath. std::unordered_map rewriteOutputsInPlace( - SwiftExtractorConfiguration& config, + const SwiftExtractorConfiguration& config, std::vector& CLIArgs); // Create directories for all the redirected new paths as the Swift compiler expects them to exist. @@ -29,4 +29,7 @@ void storeRemappingForVFS(const SwiftExtractorConfiguration& config, // This is separate from storeRemappingForVFS as we also collect files produced by other processes. std::vector collectVFSFiles(const SwiftExtractorConfiguration& config); +// Returns a list of output remapped swift module files +std::vector getOutputSwiftModules( + const std::unordered_map& remapping); } // namespace codeql diff --git a/swift/extractor/main.cpp b/swift/extractor/main.cpp index bde37b0ccb5..d9ad3475477 100644 --- a/swift/extractor/main.cpp +++ b/swift/extractor/main.cpp @@ -68,6 +68,7 @@ int main(int argc, char** argv) { codeql::rewriteOutputsInPlace(configuration, configuration.patchedFrontendOptions); codeql::ensureDirectoriesForNewPathsExist(remapping); codeql::storeRemappingForVFS(configuration, remapping); + configuration.outputSwiftModules = codeql::getOutputSwiftModules(remapping); std::vector args; for (auto& arg : configuration.patchedFrontendOptions) { diff --git a/swift/integration-tests/posix-only/partial-modules/Modules.expected b/swift/integration-tests/posix-only/partial-modules/Modules.expected index 4c738975f34..3cdcff9b980 100644 --- a/swift/integration-tests/posix-only/partial-modules/Modules.expected +++ b/swift/integration-tests/posix-only/partial-modules/Modules.expected @@ -1,4 +1,5 @@ | file://:0:0:0:0 | A | | file://:0:0:0:0 | B | +| file://:0:0:0:0 | PackageDescription | | file://:0:0:0:0 | main | | file://:0:0:0:0 | partial_modules | diff --git a/swift/integration-tests/runner.py b/swift/integration-tests/runner.py index b9e39325fd9..77a62bfb81b 100755 --- a/swift/integration-tests/runner.py +++ b/swift/integration-tests/runner.py @@ -62,6 +62,8 @@ def main(opts): ] if opts.check_databases: cmd.append("--check-databases") + else: + cmd.append("--no-check-databases") if opts.learn: cmd.append("--learn") cmd.extend(str(t.parent) for t in succesful_db_creation) From 604328ea5f69aeedc84ad63eebfc7d8eef769e0c Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 29 Jul 2022 12:25:11 +0200 Subject: [PATCH 451/465] Swift: strip suffix from swiftmodule trap files --- swift/extractor/SwiftExtractor.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 9d19d31c646..46204ee597e 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -56,8 +56,10 @@ static std::string getFilename(swift::ModuleDecl& module, swift::SourceFile* pri } // PCM clang module if (module.isNonSwiftModule()) { - // Several modules with different name might come from .pcm (clang module) files + // Several modules with different names might come from .pcm (clang module) files // In this case we want to differentiate them + // Moreover, pcm files may come from caches located in different directories, but are + // unambiguously identified by the base file name, so we can discard the absolute directory std::string filename = "/pcms/"s + llvm::sys::path::filename(module.getModuleFilename()).str(); filename += "-"; filename += module.getName().str(); @@ -175,9 +177,8 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, // extracted from source with more information. We do this by creating empty trap files. // TargetFile semantics will ensure any following run trying to extract that swiftmodule will just // skip doing it - auto outputModuleTrapSuffix = "-" + compiler.getMainModule()->getName().str().str() + ".trap"; for (const auto& output : config.outputSwiftModules) { - TargetFile::create(output + outputModuleTrapSuffix, config.trapDir, config.getTempTrapDir()); + TargetFile::create(output, config.trapDir, config.getTempTrapDir()); } for (auto& module : modules) { bool isFromSourceFile = false; From 099ab0e0c2e6e3b4d64718b05339661f9290466e Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 29 Jul 2022 12:26:33 +0200 Subject: [PATCH 452/465] Swift: readd .trap suffix to swiftmodule trap files --- swift/extractor/SwiftExtractor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index 46204ee597e..debbc5c99af 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -178,7 +178,7 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, // TargetFile semantics will ensure any following run trying to extract that swiftmodule will just // skip doing it for (const auto& output : config.outputSwiftModules) { - TargetFile::create(output, config.trapDir, config.getTempTrapDir()); + TargetFile::create(output + ".trap", config.trapDir, config.getTempTrapDir()); } for (auto& module : modules) { bool isFromSourceFile = false; From 6091f0dbce4da7e8f653e3d2eb4479819cbed00c Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Fri, 29 Jul 2022 13:44:11 +0200 Subject: [PATCH 453/465] Use camelCase for XML acronym --- java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll | 2 +- java/ql/test/library-tests/xml/XMLTest.expected | 2 ++ java/ql/test/library-tests/xml/XMLTest.ql | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll b/java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll index 7e4a1b65f4c..e61d3dabe70 100644 --- a/java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll +++ b/java/ql/test/TestUtilities/InlineExpectationsTestPrivate.qll @@ -21,7 +21,7 @@ private class KtExpectationComment extends KtComment, ExpectationComment { override string getContents() { result = this.getText().suffix(2).trim() } } -private class XMLExpectationComment extends ExpectationComment instanceof XMLComment { +private class XmlExpectationComment extends ExpectationComment instanceof XMLComment { override string getContents() { result = this.(XMLComment).getText().trim() } override Location getLocation() { result = this.(XMLComment).getLocation() } diff --git a/java/ql/test/library-tests/xml/XMLTest.expected b/java/ql/test/library-tests/xml/XMLTest.expected index e69de29bb2d..61d3c801963 100644 --- a/java/ql/test/library-tests/xml/XMLTest.expected +++ b/java/ql/test/library-tests/xml/XMLTest.expected @@ -0,0 +1,2 @@ +| test.xml:4:5:4:32 | attribute=value | Unexpected result: hasXmlResult= | +| test.xml:5:29:5:52 | $ hasXmlResult | Missing result:hasXmlResult= | \ No newline at end of file diff --git a/java/ql/test/library-tests/xml/XMLTest.ql b/java/ql/test/library-tests/xml/XMLTest.ql index e4b8b3a0361..fb51e0a1506 100644 --- a/java/ql/test/library-tests/xml/XMLTest.ql +++ b/java/ql/test/library-tests/xml/XMLTest.ql @@ -1,8 +1,8 @@ import semmle.code.xml.XML import TestUtilities.InlineExpectationsTest -class XMLTest extends InlineExpectationsTest { - XMLTest() { this = "XMLTest" } +class XmlTest extends InlineExpectationsTest { + XmlTest() { this = "XmlTest" } override string getARelevantTag() { result = "hasXmlResult" } From ec03ebbbfca2e7b5bce8cf0875cbe8c0b0628d95 Mon Sep 17 00:00:00 2001 From: Tony Torralba Date: Fri, 29 Jul 2022 13:44:25 +0200 Subject: [PATCH 454/465] Add spurious and missing test cases --- java/ql/test/library-tests/xml/test.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/java/ql/test/library-tests/xml/test.xml b/java/ql/test/library-tests/xml/test.xml index cd41bd7f36c..f0d9262f09f 100644 --- a/java/ql/test/library-tests/xml/test.xml +++ b/java/ql/test/library-tests/xml/test.xml @@ -1,4 +1,6 @@ Text + Text + Text \ No newline at end of file From 5b1fe56d5f03abdec92ba85e850bd9f8ecd2370c Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Fri, 29 Jul 2022 14:04:32 +0200 Subject: [PATCH 455/465] Swift: do not deduplicate PCM variables (as the mangler crashes there sometimes) --- swift/extractor/visitors/DeclVisitor.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/swift/extractor/visitors/DeclVisitor.cpp b/swift/extractor/visitors/DeclVisitor.cpp index dc693e66a0f..0a889fb42e1 100644 --- a/swift/extractor/visitors/DeclVisitor.cpp +++ b/swift/extractor/visitors/DeclVisitor.cpp @@ -115,7 +115,9 @@ codeql::PatternBindingDecl DeclVisitor::translatePatternBindingDecl( std::optional DeclVisitor::translateVarDecl(const swift::VarDecl& decl) { std::optional entry; - if (decl.getDeclContext()->isLocalContext()) { + // We do not deduplicate variables from non-swift (PCM, clang modules) modules as the mangler + // crashes sometimes + if (decl.getDeclContext()->isLocalContext() || decl.getModuleContext()->isNonSwiftModule()) { entry.emplace(dispatcher_.assignNewLabel(decl)); } else { entry = createNamedEntry(decl); From 34edb2537fd700451dece7fd76d48deb8fc14ab8 Mon Sep 17 00:00:00 2001 From: Alex Denisov Date: Fri, 29 Jul 2022 10:33:55 +0200 Subject: [PATCH 456/465] Swift: mangle TypeAliasDecls differently --- swift/extractor/visitors/DeclVisitor.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/swift/extractor/visitors/DeclVisitor.cpp b/swift/extractor/visitors/DeclVisitor.cpp index dc693e66a0f..05392711a54 100644 --- a/swift/extractor/visitors/DeclVisitor.cpp +++ b/swift/extractor/visitors/DeclVisitor.cpp @@ -296,6 +296,14 @@ std::string DeclVisitor::mangledName(const swift::ValueDecl& decl) { if (decl.getKind() == swift::DeclKind::Module) { return static_cast(decl).getRealName().str().str(); } + // In cases like this (when coming from PCM) + // typealias CFXMLTree = CFTree + // typealias CFXMLTreeRef = CFXMLTree + // mangleAnyDecl mangles both CFXMLTree and CFXMLTreeRef into 'So12CFXMLTreeRefa' + // which is not correct and causes inconsistencies. mangleEntity makes these two distinct + if (decl.getKind() == swift::DeclKind::TypeAlias) { + return mangler.mangleEntity(&decl); + } // prefix adds a couple of special symbols, we don't necessary need them return mangler.mangleAnyDecl(&decl, /* prefix = */ false); } From daf1fa3c31df2d21aa3cea0c812fc68c26614479 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 29 Jul 2022 16:27:55 +0200 Subject: [PATCH 457/465] Swift: lock built swiftmodule traps in main This should cover `-merge-modules` mode. Dumping of the configuration to the target files was moved to a separate pair of header/source files, as now it is also done in `SwiftOutputRewrite.cpp`. --- swift/extractor/BUILD.bazel | 12 +++------ swift/extractor/SwiftExtractor.cpp | 27 ++----------------- swift/extractor/SwiftExtractorConfiguration.h | 7 +++-- swift/extractor/SwiftOutputRewrite.cpp | 14 ++++++---- swift/extractor/SwiftOutputRewrite.h | 6 ++--- swift/extractor/TargetTrapFile.cpp | 23 ++++++++++++++++ swift/extractor/TargetTrapFile.h | 11 ++++++++ swift/extractor/main.cpp | 2 +- 8 files changed, 56 insertions(+), 46 deletions(-) create mode 100644 swift/extractor/TargetTrapFile.cpp create mode 100644 swift/extractor/TargetTrapFile.h diff --git a/swift/extractor/BUILD.bazel b/swift/extractor/BUILD.bazel index b22841ca819..bf5c9e65d52 100644 --- a/swift/extractor/BUILD.bazel +++ b/swift/extractor/BUILD.bazel @@ -2,14 +2,10 @@ load("//swift:rules.bzl", "swift_cc_binary") swift_cc_binary( name = "extractor", - srcs = [ - "SwiftOutputRewrite.cpp", - "SwiftOutputRewrite.h", - "SwiftExtractor.cpp", - "SwiftExtractor.h", - "SwiftExtractorConfiguration.h", - "main.cpp", - ], + srcs = glob([ + "*.h", + "*.cpp", + ]), visibility = ["//swift:__pkg__"], deps = [ "//swift/extractor/infra", diff --git a/swift/extractor/SwiftExtractor.cpp b/swift/extractor/SwiftExtractor.cpp index debbc5c99af..22f4f01a470 100644 --- a/swift/extractor/SwiftExtractor.cpp +++ b/swift/extractor/SwiftExtractor.cpp @@ -14,7 +14,7 @@ #include "swift/extractor/trap/generated/TrapClasses.h" #include "swift/extractor/trap/TrapDomain.h" #include "swift/extractor/visitors/SwiftVisitor.h" -#include "swift/extractor/infra/TargetFile.h" +#include "swift/extractor/TargetTrapFile.h" using namespace codeql; using namespace std::string_literals; @@ -80,20 +80,6 @@ static llvm::SmallVector getTopLevelDecls(swift::ModuleDecl& modul return ret; } -static void dumpArgs(TargetFile& out, const SwiftExtractorConfiguration& config) { - out << "/* extractor-args:\n"; - for (const auto& opt : config.frontendOptions) { - out << " " << std::quoted(opt) << " \\\n"; - } - out << "\n*/\n"; - - out << "/* swift-frontend-args:\n"; - for (const auto& opt : config.patchedFrontendOptions) { - out << " " << std::quoted(opt) << " \\\n"; - } - out << "\n*/\n"; -} - static void extractDeclarations(const SwiftExtractorConfiguration& config, swift::CompilerInstance& compiler, swift::ModuleDecl& module, @@ -103,12 +89,11 @@ static void extractDeclarations(const SwiftExtractorConfiguration& config, // The extractor can be called several times from different processes with // the same input file(s). Using `TargetFile` the first process will win, and the following // will just skip the work - auto trapTarget = TargetFile::create(filename + ".trap", config.trapDir, config.getTempTrapDir()); + auto trapTarget = createTargetTrapFile(config, filename); if (!trapTarget) { // another process arrived first, nothing to do for us return; } - dumpArgs(*trapTarget, config); TrapDomain trap{*trapTarget}; // TODO: remove this and recreate it with IPA when we have that @@ -172,14 +157,6 @@ void codeql::extractSwiftFiles(const SwiftExtractorConfiguration& config, auto inputFiles = collectInputFilenames(compiler); auto modules = collectModules(compiler); - // we want to make sure any following extractor run will not try to extract things from - // the swiftmodule files we are creating in this run, as those things will already have been - // extracted from source with more information. We do this by creating empty trap files. - // TargetFile semantics will ensure any following run trying to extract that swiftmodule will just - // skip doing it - for (const auto& output : config.outputSwiftModules) { - TargetFile::create(output + ".trap", config.trapDir, config.getTempTrapDir()); - } for (auto& module : modules) { bool isFromSourceFile = false; for (auto file : module->getFiles()) { diff --git a/swift/extractor/SwiftExtractorConfiguration.h b/swift/extractor/SwiftExtractorConfiguration.h index eec73e7dc21..cd4ed51cdcd 100644 --- a/swift/extractor/SwiftExtractorConfiguration.h +++ b/swift/extractor/SwiftExtractorConfiguration.h @@ -3,6 +3,8 @@ #include #include +#include "swift/extractor/infra/TargetFile.h" + namespace codeql { struct SwiftExtractorConfiguration { // The location for storing TRAP files to be imported by CodeQL engine. @@ -32,9 +34,6 @@ struct SwiftExtractorConfiguration { // A temporary directory that contains build artifacts generated by the extractor during the // overall extraction process. std::string getTempArtifactDir() const { return scratchDir + "/swift-extraction-artifacts"; } - - // Output swiftmodule files. This also includes possible locations where XCode internally moves - // modules - std::vector outputSwiftModules; }; + } // namespace codeql diff --git a/swift/extractor/SwiftOutputRewrite.cpp b/swift/extractor/SwiftOutputRewrite.cpp index f85290f5beb..b09a558d187 100644 --- a/swift/extractor/SwiftOutputRewrite.cpp +++ b/swift/extractor/SwiftOutputRewrite.cpp @@ -1,5 +1,6 @@ #include "SwiftOutputRewrite.h" #include "swift/extractor/SwiftExtractorConfiguration.h" +#include "swift/extractor/TargetTrapFile.h" #include #include @@ -323,15 +324,18 @@ std::vector collectVFSFiles(const SwiftExtractorConfiguration& conf return overlays; } -std::vector getOutputSwiftModules( - const std::unordered_map& remapping) { - std::vector ret; + +void lockOutputSwiftModuleTraps(const SwiftExtractorConfiguration& config, + const std::unordered_map& remapping) { for (const auto& [oldPath, newPath] : remapping) { if (llvm::StringRef(oldPath).endswith(".swiftmodule")) { - ret.push_back(oldPath); + if (auto target = createTargetTrapFile(config, oldPath)) { + *target << "// trap file deliberately empty\n" + "// this swiftmodule was created during the build, so its entities must have" + " been extracted directly from source files"; + } } } - return ret; } } // namespace codeql diff --git a/swift/extractor/SwiftOutputRewrite.h b/swift/extractor/SwiftOutputRewrite.h index 61ef2d98ea6..94f1eeb6aaa 100644 --- a/swift/extractor/SwiftOutputRewrite.h +++ b/swift/extractor/SwiftOutputRewrite.h @@ -29,7 +29,7 @@ void storeRemappingForVFS(const SwiftExtractorConfiguration& config, // This is separate from storeRemappingForVFS as we also collect files produced by other processes. std::vector collectVFSFiles(const SwiftExtractorConfiguration& config); -// Returns a list of output remapped swift module files -std::vector getOutputSwiftModules( - const std::unordered_map& remapping); +// Creates empty trap files for output swiftmodule files +void lockOutputSwiftModuleTraps(const SwiftExtractorConfiguration& config, + const std::unordered_map& remapping); } // namespace codeql diff --git a/swift/extractor/TargetTrapFile.cpp b/swift/extractor/TargetTrapFile.cpp new file mode 100644 index 00000000000..2275575ecfa --- /dev/null +++ b/swift/extractor/TargetTrapFile.cpp @@ -0,0 +1,23 @@ +#include "swift/extractor/TargetTrapFile.h" +#include +namespace codeql { +std::optional createTargetTrapFile(const SwiftExtractorConfiguration& configuration, + std::string_view target) { + std::string trap{target}; + trap += ".trap"; + auto ret = TargetFile::create(trap, configuration.trapDir, configuration.getTempTrapDir()); + if (ret) { + *ret << "/* extractor-args:\n"; + for (const auto& opt : configuration.frontendOptions) { + *ret << " " << std::quoted(opt) << " \\\n"; + } + *ret << "\n*/\n" + "/* swift-frontend-args:\n"; + for (const auto& opt : configuration.patchedFrontendOptions) { + *ret << " " << std::quoted(opt) << " \\\n"; + } + *ret << "\n*/\n"; + } + return ret; +} +} // namespace codeql diff --git a/swift/extractor/TargetTrapFile.h b/swift/extractor/TargetTrapFile.h new file mode 100644 index 00000000000..eb8de4c206f --- /dev/null +++ b/swift/extractor/TargetTrapFile.h @@ -0,0 +1,11 @@ +#pragma once + +#include "swift/extractor/infra/TargetFile.h" +#include "swift/extractor/SwiftExtractorConfiguration.h" + +namespace codeql { + +std::optional createTargetTrapFile(const SwiftExtractorConfiguration& configuration, + std::string_view target); + +} // namespace codeql diff --git a/swift/extractor/main.cpp b/swift/extractor/main.cpp index d9ad3475477..5f9afef4e81 100644 --- a/swift/extractor/main.cpp +++ b/swift/extractor/main.cpp @@ -68,7 +68,7 @@ int main(int argc, char** argv) { codeql::rewriteOutputsInPlace(configuration, configuration.patchedFrontendOptions); codeql::ensureDirectoriesForNewPathsExist(remapping); codeql::storeRemappingForVFS(configuration, remapping); - configuration.outputSwiftModules = codeql::getOutputSwiftModules(remapping); + codeql::lockOutputSwiftModuleTraps(configuration, remapping); std::vector args; for (auto& arg : configuration.patchedFrontendOptions) { From 45e14c96f2c984d67da7f321c7c729ef7a3c6c38 Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 29 Jul 2022 16:36:08 +0200 Subject: [PATCH 458/465] Swift: extract `ModuleType` --- swift/codegen/schema.yml | 1 + swift/extractor/visitors/TypeVisitor.cpp | 10 ++++++++++ swift/extractor/visitors/TypeVisitor.h | 7 ++++--- .../lib/codeql/swift/generated/type/ModuleType.qll | 8 ++++++++ swift/ql/lib/swift.dbscheme | 3 ++- swift/ql/test/TestUtils.qll | 6 +++++- .../generated/decl/ModuleDecl/ModuleDecl.expected | 1 + .../decl/ModuleDecl/default_module_name.swift | 0 .../generated/type/ModuleType/MISSING_SOURCE.txt | 4 ---- .../generated/type/ModuleType/ModuleType.expected | 2 ++ .../generated/type/ModuleType/ModuleType.ql | 12 ++++++++++++ .../type/ModuleType/default_module_name.swift | 0 .../generated/type/ModuleType/modules.swift | 1 + 13 files changed, 46 insertions(+), 9 deletions(-) create mode 100644 swift/ql/test/extractor-tests/generated/decl/ModuleDecl/default_module_name.swift delete mode 100644 swift/ql/test/extractor-tests/generated/type/ModuleType/MISSING_SOURCE.txt create mode 100644 swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.expected create mode 100644 swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.ql create mode 100644 swift/ql/test/extractor-tests/generated/type/ModuleType/default_module_name.swift create mode 100644 swift/ql/test/extractor-tests/generated/type/ModuleType/modules.swift diff --git a/swift/codegen/schema.yml b/swift/codegen/schema.yml index f810bfec636..83e2c87ef4e 100644 --- a/swift/codegen/schema.yml +++ b/swift/codegen/schema.yml @@ -112,6 +112,7 @@ LValueType: ModuleType: _extends: Type + module: ModuleDecl PlaceholderType: _extends: Type diff --git a/swift/extractor/visitors/TypeVisitor.cpp b/swift/extractor/visitors/TypeVisitor.cpp index ddc253c90a5..d1c499a9a96 100644 --- a/swift/extractor/visitors/TypeVisitor.cpp +++ b/swift/extractor/visitors/TypeVisitor.cpp @@ -381,4 +381,14 @@ codeql::OpenedArchetypeType TypeVisitor::translateOpenedArchetypeType( fillArchetypeType(type, entry); return entry; } + +codeql::ModuleType TypeVisitor::translateModuleType(const swift::ModuleType& type) { + auto key = type.getModule()->getRealName().str().str(); + if (type.getModule()->isNonSwiftModule()) { + key += "|clang"; + } + auto entry = createTypeEntry(type, key); + entry.module = dispatcher_.fetchLabel(type.getModule()); + return entry; +} } // namespace codeql diff --git a/swift/extractor/visitors/TypeVisitor.h b/swift/extractor/visitors/TypeVisitor.h index 38e9e71b32f..21cbd96d24d 100644 --- a/swift/extractor/visitors/TypeVisitor.h +++ b/swift/extractor/visitors/TypeVisitor.h @@ -71,6 +71,7 @@ class TypeVisitor : public TypeVisitorBase { const swift::BuiltinUnsafeValueBufferType& type); codeql::BuiltinVectorType translateBuiltinVectorType(const swift::BuiltinVectorType& type); codeql::OpenedArchetypeType translateOpenedArchetypeType(const swift::OpenedArchetypeType& type); + codeql::ModuleType translateModuleType(const swift::ModuleType& type); private: void fillType(const swift::TypeBase& type, codeql::Type& entry); @@ -83,9 +84,9 @@ class TypeVisitor : public TypeVisitorBase { void emitBoundGenericType(swift::BoundGenericType* type, TrapLabel label); void emitAnyGenericType(swift::AnyGenericType* type, TrapLabel label); - template - auto createTypeEntry(const T& type) { - auto entry = dispatcher_.createEntry(type); + template + auto createTypeEntry(const T& type, const Args&... args) { + auto entry = dispatcher_.createEntry(type, args...); fillType(type, entry); return entry; } diff --git a/swift/ql/lib/codeql/swift/generated/type/ModuleType.qll b/swift/ql/lib/codeql/swift/generated/type/ModuleType.qll index 91da39854d7..866598ad431 100644 --- a/swift/ql/lib/codeql/swift/generated/type/ModuleType.qll +++ b/swift/ql/lib/codeql/swift/generated/type/ModuleType.qll @@ -1,6 +1,14 @@ // generated by codegen/codegen.py +import codeql.swift.elements.decl.ModuleDecl import codeql.swift.elements.type.Type class ModuleTypeBase extends @module_type, Type { override string getAPrimaryQlClass() { result = "ModuleType" } + + ModuleDecl getModule() { + exists(ModuleDecl x | + module_types(this, x) and + result = x.resolve() + ) + } } diff --git a/swift/ql/lib/swift.dbscheme b/swift/ql/lib/swift.dbscheme index 0826b2b9ef4..7c102d30524 100644 --- a/swift/ql/lib/swift.dbscheme +++ b/swift/ql/lib/swift.dbscheme @@ -264,7 +264,8 @@ l_value_types( //dir=type ); module_types( //dir=type - unique int id: @module_type + unique int id: @module_type, + int module: @module_decl ref ); placeholder_types( //dir=type diff --git a/swift/ql/test/TestUtils.qll b/swift/ql/test/TestUtils.qll index 0c04fcb5989..265513b4f4a 100644 --- a/swift/ql/test/TestUtils.qll +++ b/swift/ql/test/TestUtils.qll @@ -4,7 +4,11 @@ cached predicate toBeTested(Element e) { e instanceof File or - exists(ModuleDecl m | m = e and not m.isBuiltinModule() and not m.isSystemModule()) + exists(ModuleDecl m | + not m.isBuiltinModule() and + not m.isSystemModule() and + (m = e or m.getInterfaceType() = e) + ) or exists(Locatable loc | loc.getLocation().getFile().getName().matches("%swift/ql/test%") and diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.expected b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.expected index ef50edbe828..cfae187857a 100644 --- a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.expected +++ b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/ModuleDecl.expected @@ -1 +1,2 @@ | file://:0:0:0:0 | Foo | getInterfaceType: | module | getName: | Foo | isBuiltinModule: | no | isSystemModule: | no | +| file://:0:0:0:0 | default_module_name | getInterfaceType: | module | getName: | default_module_name | isBuiltinModule: | no | isSystemModule: | no | diff --git a/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/default_module_name.swift b/swift/ql/test/extractor-tests/generated/decl/ModuleDecl/default_module_name.swift new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/type/ModuleType/MISSING_SOURCE.txt b/swift/ql/test/extractor-tests/generated/type/ModuleType/MISSING_SOURCE.txt deleted file mode 100644 index 0d319d9a669..00000000000 --- a/swift/ql/test/extractor-tests/generated/type/ModuleType/MISSING_SOURCE.txt +++ /dev/null @@ -1,4 +0,0 @@ -// generated by codegen/codegen.py - -After a swift source file is added in this directory and codegen/codegen.py is run again, test queries -will appear and this file will be deleted diff --git a/swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.expected b/swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.expected new file mode 100644 index 00000000000..3a688c7fbd6 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.expected @@ -0,0 +1,2 @@ +| module | getName: | module | getCanonicalType: | module | getModule: | file://:0:0:0:0 | Foo | +| module | getName: | module | getCanonicalType: | module | getModule: | file://:0:0:0:0 | default_module_name | diff --git a/swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.ql b/swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.ql new file mode 100644 index 00000000000..aa070b52e34 --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ModuleType/ModuleType.ql @@ -0,0 +1,12 @@ +// generated by codegen/codegen.py +import codeql.swift.elements +import TestUtils + +from ModuleType x, string getName, Type getCanonicalType, ModuleDecl getModule +where + toBeTested(x) and + not x.isUnknown() and + getName = x.getName() and + getCanonicalType = x.getCanonicalType() and + getModule = x.getModule() +select x, "getName:", getName, "getCanonicalType:", getCanonicalType, "getModule:", getModule diff --git a/swift/ql/test/extractor-tests/generated/type/ModuleType/default_module_name.swift b/swift/ql/test/extractor-tests/generated/type/ModuleType/default_module_name.swift new file mode 100644 index 00000000000..e69de29bb2d diff --git a/swift/ql/test/extractor-tests/generated/type/ModuleType/modules.swift b/swift/ql/test/extractor-tests/generated/type/ModuleType/modules.swift new file mode 100644 index 00000000000..bb12ed63ddd --- /dev/null +++ b/swift/ql/test/extractor-tests/generated/type/ModuleType/modules.swift @@ -0,0 +1 @@ +//codeql-extractor-options: -module-name Foo From 4ce100f9a38b0f319fdf642d8c28051d4042226b Mon Sep 17 00:00:00 2001 From: Paolo Tranquilli Date: Fri, 29 Jul 2022 16:51:49 +0200 Subject: [PATCH 459/465] Swift: append clang module names in trap keys We have found out there can be separate declarations (`VarDecl` or `AccessorDecl`) which are effectively the same (with equal mangled name) but come from different clang modules. This is the case for example for glibc constants like `L_SET` that appear in both `SwiftGlibc` and `CDispatch`. In this patch, we simply avoid full deduplication in that case by appending the module name to the trap key for non-swift modules. A more solid solution should be found in the future. --- swift/extractor/visitors/DeclVisitor.cpp | 31 ++++++++++++++++-------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/swift/extractor/visitors/DeclVisitor.cpp b/swift/extractor/visitors/DeclVisitor.cpp index 2b3775171e9..fce28e504dd 100644 --- a/swift/extractor/visitors/DeclVisitor.cpp +++ b/swift/extractor/visitors/DeclVisitor.cpp @@ -295,19 +295,30 @@ std::string DeclVisitor::mangledName(const swift::ValueDecl& decl) { // ASTMangler::mangleAnyDecl crashes when called on `ModuleDecl` // TODO find a more unique string working also when different modules are compiled with the same // name + std::ostringstream ret; if (decl.getKind() == swift::DeclKind::Module) { - return static_cast(decl).getRealName().str().str(); + ret << static_cast(decl).getRealName().str().str(); + } else if (decl.getKind() == swift::DeclKind::TypeAlias) { + // In cases like this (when coming from PCM) + // typealias CFXMLTree = CFTree + // typealias CFXMLTreeRef = CFXMLTree + // mangleAnyDecl mangles both CFXMLTree and CFXMLTreeRef into 'So12CFXMLTreeRefa' + // which is not correct and causes inconsistencies. mangleEntity makes these two distinct + // prefix adds a couple of special symbols, we don't necessary need them + ret << mangler.mangleEntity(&decl); + } else { + // prefix adds a couple of special symbols, we don't necessary need them + ret << mangler.mangleAnyDecl(&decl, /* prefix = */ false); } - // In cases like this (when coming from PCM) - // typealias CFXMLTree = CFTree - // typealias CFXMLTreeRef = CFXMLTree - // mangleAnyDecl mangles both CFXMLTree and CFXMLTreeRef into 'So12CFXMLTreeRefa' - // which is not correct and causes inconsistencies. mangleEntity makes these two distinct - if (decl.getKind() == swift::DeclKind::TypeAlias) { - return mangler.mangleEntity(&decl); + // there can be separate declarations (`VarDecl` or `AccessorDecl`) which are effectively the same + // (with equal mangled name) but come from different clang modules. This is the case for example + // for glibc constants like `L_SET` that appear in both `SwiftGlibc` and `CDispatch`. + // For the moment, we sidestep the problem by making them separate entities in the DB + // TODO find a more solid solution + if (decl.getModuleContext()->isNonSwiftModule()) { + ret << '_' << decl.getModuleContext()->getRealName().str().str(); } - // prefix adds a couple of special symbols, we don't necessary need them - return mangler.mangleAnyDecl(&decl, /* prefix = */ false); + return ret.str(); } void DeclVisitor::fillAbstractFunctionDecl(const swift::AbstractFunctionDecl& decl, From bc05cdaa4d916362d9de5ff3965ead70ea1207c7 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Mon, 1 Aug 2022 11:56:51 +0200 Subject: [PATCH 460/465] Implement fetch-codeql using 'gh codeql' --- .github/actions/fetch-codeql/action.yml | 18 ++++-------------- .github/workflows/check-qldoc.yml | 15 +++++---------- 2 files changed, 9 insertions(+), 24 deletions(-) diff --git a/.github/actions/fetch-codeql/action.yml b/.github/actions/fetch-codeql/action.yml index 13b91525237..d1f48f40047 100644 --- a/.github/actions/fetch-codeql/action.yml +++ b/.github/actions/fetch-codeql/action.yml @@ -3,22 +3,12 @@ description: Fetches the latest version of CodeQL runs: using: composite steps: - - name: Select platform - Linux - if: runner.os == 'Linux' - shell: bash - run: echo "GA_CODEQL_CLI_PLATFORM=linux64" >> $GITHUB_ENV - - - name: Select platform - MacOS - if: runner.os == 'MacOS' - shell: bash - run: echo "GA_CODEQL_CLI_PLATFORM=osx64" >> $GITHUB_ENV - - name: Fetch CodeQL shell: bash run: | - LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1) - gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-$GA_CODEQL_CLI_PLATFORM.zip "$LATEST" - unzip -q -d "${RUNNER_TEMP}" codeql-$GA_CODEQL_CLI_PLATFORM.zip - echo "${RUNNER_TEMP}/codeql" >> "${GITHUB_PATH}" + gh extension install github/gh-codeql + gh codeql set-channel release + gh codeql version + gh codeql version --format=json | jq -r .unpackedLocation >> "${GITHUB_PATH}" env: GITHUB_TOKEN: ${{ github.token }} diff --git a/.github/workflows/check-qldoc.yml b/.github/workflows/check-qldoc.yml index 77f524b73e7..f0256b1758a 100644 --- a/.github/workflows/check-qldoc.yml +++ b/.github/workflows/check-qldoc.yml @@ -14,18 +14,13 @@ jobs: runs-on: ubuntu-latest steps: - - name: Install CodeQL - run: | - gh extension install github/gh-codeql - gh codeql set-channel nightly - gh codeql version - env: - GITHUB_TOKEN: ${{ github.token }} - - uses: actions/checkout@v3 with: fetch-depth: 2 + - name: Install CodeQL + uses: ./.github/actions/fetch-codeql + - name: Check QLdoc coverage shell: bash run: | @@ -34,7 +29,7 @@ jobs: changed_lib_packs="$(git diff --name-only --diff-filter=ACMRT HEAD^ HEAD | { grep -Po '^(?!swift)[a-z]*/ql/lib' || true; } | sort -u)" for pack_dir in ${changed_lib_packs}; do lang="${pack_dir%/ql/lib}" - gh codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-current.txt" --dir="${pack_dir}" + codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-current.txt" --dir="${pack_dir}" done git checkout HEAD^ for pack_dir in ${changed_lib_packs}; do @@ -42,7 +37,7 @@ jobs: # In this case the right thing to do is to skip the check. [[ ! -d "${pack_dir}" ]] && continue lang="${pack_dir%/ql/lib}" - gh codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-baseline.txt" --dir="${pack_dir}" + codeql generate library-doc-coverage --output="${RUNNER_TEMP}/${lang}-baseline.txt" --dir="${pack_dir}" awk -F, '{gsub(/"/,""); if ($4==0 && $6=="public") print "\""$3"\"" }' "${RUNNER_TEMP}/${lang}-current.txt" | sort -u > "${RUNNER_TEMP}/current-undocumented.txt" awk -F, '{gsub(/"/,""); if ($4==0 && $6=="public") print "\""$3"\"" }' "${RUNNER_TEMP}/${lang}-baseline.txt" | sort -u > "${RUNNER_TEMP}/baseline-undocumented.txt" UNDOCUMENTED="$(grep -f <(comm -13 "${RUNNER_TEMP}/baseline-undocumented.txt" "${RUNNER_TEMP}/current-undocumented.txt") "${RUNNER_TEMP}/${lang}-current.txt" || true)" From 3b8eeb09bf4a3521c6022768e71bf4cc3b5d5544 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Mon, 1 Aug 2022 12:16:15 +0200 Subject: [PATCH 461/465] Add fetch-codeql path to Actions triggers --- .github/workflows/check-qldoc.yml | 1 + .github/workflows/csv-coverage-metrics.yml | 1 + .github/workflows/js-ml-tests.yml | 2 ++ .github/workflows/mad_regenerate-models.yml | 1 + .github/workflows/query-list.yml | 1 + .github/workflows/ruby-qltest.yml | 2 ++ .github/workflows/swift-codegen.yml | 1 + .github/workflows/swift-integration-tests.yml | 1 + .github/workflows/swift-qltest.yml | 1 + .github/workflows/validate-change-notes.yml | 2 ++ 10 files changed, 13 insertions(+) diff --git a/.github/workflows/check-qldoc.yml b/.github/workflows/check-qldoc.yml index f0256b1758a..be986d5ecf6 100644 --- a/.github/workflows/check-qldoc.yml +++ b/.github/workflows/check-qldoc.yml @@ -5,6 +5,7 @@ on: paths: - "*/ql/lib/**" - .github/workflows/check-qldoc.yml + - .github/actions/fetch-codeql branches: - main - "rc/*" diff --git a/.github/workflows/csv-coverage-metrics.yml b/.github/workflows/csv-coverage-metrics.yml index 7778221dc2f..e263572398e 100644 --- a/.github/workflows/csv-coverage-metrics.yml +++ b/.github/workflows/csv-coverage-metrics.yml @@ -12,6 +12,7 @@ on: - main paths: - ".github/workflows/csv-coverage-metrics.yml" + - ".github/actions/fetch-codeql" jobs: publish-java: diff --git a/.github/workflows/js-ml-tests.yml b/.github/workflows/js-ml-tests.yml index 65db215d8c3..0b23f91ed48 100644 --- a/.github/workflows/js-ml-tests.yml +++ b/.github/workflows/js-ml-tests.yml @@ -5,6 +5,7 @@ on: paths: - "javascript/ql/experimental/adaptivethreatmodeling/**" - .github/workflows/js-ml-tests.yml + - .github/actions/fetch-codeql - codeql-workspace.yml branches: - main @@ -13,6 +14,7 @@ on: paths: - "javascript/ql/experimental/adaptivethreatmodeling/**" - .github/workflows/js-ml-tests.yml + - .github/actions/fetch-codeql - codeql-workspace.yml workflow_dispatch: diff --git a/.github/workflows/mad_regenerate-models.yml b/.github/workflows/mad_regenerate-models.yml index d1d7e6e3791..9f16c223ec6 100644 --- a/.github/workflows/mad_regenerate-models.yml +++ b/.github/workflows/mad_regenerate-models.yml @@ -9,6 +9,7 @@ on: - main paths: - ".github/workflows/mad_regenerate-models.yml" + - ".github/actions/fetch-codeql" jobs: regenerate-models: diff --git a/.github/workflows/query-list.yml b/.github/workflows/query-list.yml index 9416b740c99..56604b17cdc 100644 --- a/.github/workflows/query-list.yml +++ b/.github/workflows/query-list.yml @@ -10,6 +10,7 @@ on: pull_request: paths: - '.github/workflows/query-list.yml' + - '.github/actions/fetch-codeql' - 'misc/scripts/generate-code-scanning-query-list.py' jobs: diff --git a/.github/workflows/ruby-qltest.yml b/.github/workflows/ruby-qltest.yml index 0cf8860d8f1..e5eb7e05ecd 100644 --- a/.github/workflows/ruby-qltest.yml +++ b/.github/workflows/ruby-qltest.yml @@ -5,6 +5,7 @@ on: paths: - "ruby/**" - .github/workflows/ruby-qltest.yml + - .github/actions/fetch-codeql - codeql-workspace.yml branches: - main @@ -13,6 +14,7 @@ on: paths: - "ruby/**" - .github/workflows/ruby-qltest.yml + - .github/actions/fetch-codeql - codeql-workspace.yml branches: - main diff --git a/.github/workflows/swift-codegen.yml b/.github/workflows/swift-codegen.yml index 46a27709717..665ee55a247 100644 --- a/.github/workflows/swift-codegen.yml +++ b/.github/workflows/swift-codegen.yml @@ -5,6 +5,7 @@ on: paths: - "swift/**" - .github/workflows/swift-codegen.yml + - .github/actions/fetch-codeql branches: - main diff --git a/.github/workflows/swift-integration-tests.yml b/.github/workflows/swift-integration-tests.yml index 591ea2b12f7..cc365809c73 100644 --- a/.github/workflows/swift-integration-tests.yml +++ b/.github/workflows/swift-integration-tests.yml @@ -5,6 +5,7 @@ on: paths: - "swift/**" - .github/workflows/swift-integration-tests.yml + - .github/actions/fetch-codeql - codeql-workspace.yml branches: - main diff --git a/.github/workflows/swift-qltest.yml b/.github/workflows/swift-qltest.yml index 915e1f331a5..76a21b0bd8a 100644 --- a/.github/workflows/swift-qltest.yml +++ b/.github/workflows/swift-qltest.yml @@ -5,6 +5,7 @@ on: paths: - "swift/**" - .github/workflows/swift-qltest.yml + - .github/actions/fetch-codeql - codeql-workspace.yml branches: - main diff --git a/.github/workflows/validate-change-notes.yml b/.github/workflows/validate-change-notes.yml index 798913746be..b06167ea905 100644 --- a/.github/workflows/validate-change-notes.yml +++ b/.github/workflows/validate-change-notes.yml @@ -5,6 +5,7 @@ on: paths: - "*/ql/*/change-notes/**/*" - ".github/workflows/validate-change-notes.yml" + - ".github/actions/fetch-codeql" branches: - main - "rc/*" @@ -12,6 +13,7 @@ on: paths: - "*/ql/*/change-notes/**/*" - ".github/workflows/validate-change-notes.yml" + - ".github/actions/fetch-codeql" jobs: check-change-note: From 2bbd2f36c9e070594a75b0f9475b987537bb0ded Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Mon, 1 Aug 2022 12:26:03 +0200 Subject: [PATCH 462/465] Fix .github/workflows/query-list.yml --- .github/workflows/query-list.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/query-list.yml b/.github/workflows/query-list.yml index 56604b17cdc..0cf1cf30422 100644 --- a/.github/workflows/query-list.yml +++ b/.github/workflows/query-list.yml @@ -30,8 +30,6 @@ jobs: - name: Download CodeQL CLI # Look under the `codeql` directory, as this is where we checked out the `github/codeql` repo uses: ./codeql/.github/actions/fetch-codeql - - name: Unzip CodeQL CLI - run: unzip -d codeql-cli codeql-linux64.zip - name: Build code scanning query list run: | python codeql/misc/scripts/generate-code-scanning-query-list.py > code-scanning-query-list.csv From 29381dc26413c30be85985e30f358e60ce1568c6 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Mon, 1 Aug 2022 12:38:59 +0200 Subject: [PATCH 463/465] Use fetch-codeql in more places --- .../workflows/csv-coverage-pr-artifacts.yml | 163 +++++++------- .github/workflows/csv-coverage-timeseries.yml | 57 +++-- .github/workflows/csv-coverage-update.yml | 52 ++--- .github/workflows/csv-coverage.yml | 65 +++--- .github/workflows/go-tests.yml | 198 +++++++----------- .github/workflows/ruby-build.yml | 31 +-- 6 files changed, 242 insertions(+), 324 deletions(-) diff --git a/.github/workflows/csv-coverage-pr-artifacts.yml b/.github/workflows/csv-coverage-pr-artifacts.yml index 379b3c5aad8..b63d85534b4 100644 --- a/.github/workflows/csv-coverage-pr-artifacts.yml +++ b/.github/workflows/csv-coverage-pr-artifacts.yml @@ -3,18 +3,20 @@ name: Check framework coverage changes on: pull_request: paths: - - '.github/workflows/csv-coverage-pr-comment.yml' - - '*/ql/src/**/*.ql' - - '*/ql/src/**/*.qll' - - '*/ql/lib/**/*.ql' - - '*/ql/lib/**/*.qll' - - 'misc/scripts/library-coverage/*.py' + - ".github/workflows/csv-coverage-pr-comment.yml" + - ".github/workflows/csv-coverage-pr-artifacts.yml" + - ".github/actions/fetch-codeql" + - "*/ql/src/**/*.ql" + - "*/ql/src/**/*.qll" + - "*/ql/lib/**/*.ql" + - "*/ql/lib/**/*.qll" + - "misc/scripts/library-coverage/*.py" # input data files - - '*/documentation/library-coverage/cwe-sink.csv' - - '*/documentation/library-coverage/frameworks.csv' + - "*/documentation/library-coverage/cwe-sink.csv" + - "*/documentation/library-coverage/frameworks.csv" branches: - main - - 'rc/*' + - "rc/*" jobs: generate: @@ -23,77 +25,72 @@ jobs: runs-on: ubuntu-latest steps: - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJSON(github.event) }} - run: echo "$GITHUB_CONTEXT" - - name: Clone self (github/codeql) - MERGE - uses: actions/checkout@v3 - with: - path: merge - - name: Clone self (github/codeql) - BASE - uses: actions/checkout@v3 - with: - fetch-depth: 2 - path: base - - run: | - git checkout HEAD^1 - git log -1 --format='%H' - working-directory: base - - name: Set up Python 3.8 - uses: actions/setup-python@v4 - with: - python-version: 3.8 - - name: Download CodeQL CLI - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip" - - name: Unzip CodeQL CLI - run: unzip -d codeql-cli codeql-linux64.zip - - name: Generate CSV files on merge commit of the PR - run: | - echo "Running generator on merge" - PATH="$PATH:codeql-cli/codeql" python merge/misc/scripts/library-coverage/generate-report.py ci merge merge - mkdir out_merge - cp framework-coverage-*.csv out_merge/ - cp framework-coverage-*.rst out_merge/ - - name: Generate CSV files on base commit of the PR - run: | - echo "Running generator on base" - PATH="$PATH:codeql-cli/codeql" python base/misc/scripts/library-coverage/generate-report.py ci base base - mkdir out_base - cp framework-coverage-*.csv out_base/ - cp framework-coverage-*.rst out_base/ - - name: Generate diff of coverage reports - run: | - python base/misc/scripts/library-coverage/compare-folders.py out_base out_merge comparison.md - - name: Upload CSV package list - uses: actions/upload-artifact@v3 - with: - name: csv-framework-coverage-merge - path: | - out_merge/framework-coverage-*.csv - out_merge/framework-coverage-*.rst - - name: Upload CSV package list - uses: actions/upload-artifact@v3 - with: - name: csv-framework-coverage-base - path: | - out_base/framework-coverage-*.csv - out_base/framework-coverage-*.rst - - name: Upload comparison results - uses: actions/upload-artifact@v3 - with: - name: comparison - path: | - comparison.md - - name: Save PR number - run: | - mkdir -p pr - echo ${{ github.event.pull_request.number }} > pr/NR - - name: Upload PR number - uses: actions/upload-artifact@v3 - with: - name: pr - path: pr/ + - name: Dump GitHub context + env: + GITHUB_CONTEXT: ${{ toJSON(github.event) }} + run: echo "$GITHUB_CONTEXT" + - name: Clone self (github/codeql) - MERGE + uses: actions/checkout@v3 + with: + path: merge + - name: Clone self (github/codeql) - BASE + uses: actions/checkout@v3 + with: + fetch-depth: 2 + path: base + - run: | + git checkout HEAD^1 + git log -1 --format='%H' + working-directory: base + - name: Set up Python 3.8 + uses: actions/setup-python@v4 + with: + python-version: 3.8 + - name: Download CodeQL CLI + uses: ./merge/.github/actions/fetch-codeql + - name: Generate CSV files on merge commit of the PR + run: | + echo "Running generator on merge" + PATH="$PATH:codeql-cli/codeql" python merge/misc/scripts/library-coverage/generate-report.py ci merge merge + mkdir out_merge + cp framework-coverage-*.csv out_merge/ + cp framework-coverage-*.rst out_merge/ + - name: Generate CSV files on base commit of the PR + run: | + echo "Running generator on base" + PATH="$PATH:codeql-cli/codeql" python base/misc/scripts/library-coverage/generate-report.py ci base base + mkdir out_base + cp framework-coverage-*.csv out_base/ + cp framework-coverage-*.rst out_base/ + - name: Generate diff of coverage reports + run: | + python base/misc/scripts/library-coverage/compare-folders.py out_base out_merge comparison.md + - name: Upload CSV package list + uses: actions/upload-artifact@v3 + with: + name: csv-framework-coverage-merge + path: | + out_merge/framework-coverage-*.csv + out_merge/framework-coverage-*.rst + - name: Upload CSV package list + uses: actions/upload-artifact@v3 + with: + name: csv-framework-coverage-base + path: | + out_base/framework-coverage-*.csv + out_base/framework-coverage-*.rst + - name: Upload comparison results + uses: actions/upload-artifact@v3 + with: + name: comparison + path: | + comparison.md + - name: Save PR number + run: | + mkdir -p pr + echo ${{ github.event.pull_request.number }} > pr/NR + - name: Upload PR number + uses: actions/upload-artifact@v3 + with: + name: pr + path: pr/ diff --git a/.github/workflows/csv-coverage-timeseries.yml b/.github/workflows/csv-coverage-timeseries.yml index 95b084ea215..2eb9d0cdf84 100644 --- a/.github/workflows/csv-coverage-timeseries.yml +++ b/.github/workflows/csv-coverage-timeseries.yml @@ -5,38 +5,31 @@ on: jobs: build: - runs-on: ubuntu-latest steps: - - name: Clone self (github/codeql) - uses: actions/checkout@v3 - with: - path: script - - name: Clone self (github/codeql) for analysis - uses: actions/checkout@v3 - with: - path: codeqlModels - fetch-depth: 0 - - name: Set up Python 3.8 - uses: actions/setup-python@v4 - with: - python-version: 3.8 - - name: Download CodeQL CLI - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip" - - name: Unzip CodeQL CLI - run: unzip -d codeql-cli codeql-linux64.zip - - name: Build modeled package list - run: | - CLI=$(realpath "codeql-cli/codeql") - echo $CLI - PATH="$PATH:$CLI" python script/misc/scripts/library-coverage/generate-timeseries.py codeqlModels - - name: Upload timeseries CSV - uses: actions/upload-artifact@v3 - with: - name: framework-coverage-timeseries - path: framework-coverage-timeseries-*.csv - + - name: Clone self (github/codeql) + uses: actions/checkout@v3 + with: + path: script + - name: Clone self (github/codeql) for analysis + uses: actions/checkout@v3 + with: + path: codeqlModels + fetch-depth: 0 + - name: Set up Python 3.8 + uses: actions/setup-python@v4 + with: + python-version: 3.8 + - name: Download CodeQL CLI + uses: ./.github/actions/fetch-codeql + - name: Build modeled package list + run: | + CLI=$(realpath "codeql-cli/codeql") + echo $CLI + PATH="$PATH:$CLI" python script/misc/scripts/library-coverage/generate-timeseries.py codeqlModels + - name: Upload timeseries CSV + uses: actions/upload-artifact@v3 + with: + name: framework-coverage-timeseries + path: framework-coverage-timeseries-*.csv diff --git a/.github/workflows/csv-coverage-update.yml b/.github/workflows/csv-coverage-update.yml index c57056b6de1..58e60cc363e 100644 --- a/.github/workflows/csv-coverage-update.yml +++ b/.github/workflows/csv-coverage-update.yml @@ -12,33 +12,27 @@ jobs: runs-on: ubuntu-latest steps: - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJSON(github.event) }} - run: echo "$GITHUB_CONTEXT" - - name: Clone self (github/codeql) - uses: actions/checkout@v3 - with: - path: ql - fetch-depth: 0 - - name: Set up Python 3.8 - uses: actions/setup-python@v4 - with: - python-version: 3.8 - - name: Download CodeQL CLI - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip" - - name: Unzip CodeQL CLI - run: unzip -d codeql-cli codeql-linux64.zip + - name: Dump GitHub context + env: + GITHUB_CONTEXT: ${{ toJSON(github.event) }} + run: echo "$GITHUB_CONTEXT" + - name: Clone self (github/codeql) + uses: actions/checkout@v3 + with: + path: ql + fetch-depth: 0 + - name: Set up Python 3.8 + uses: actions/setup-python@v4 + with: + python-version: 3.8 + - name: Download CodeQL CLI + uses: ./.github/actions/fetch-codeql + - name: Generate coverage files + run: | + PATH="$PATH:codeql-cli/codeql" python ql/misc/scripts/library-coverage/generate-report.py ci ql ql - - name: Generate coverage files - run: | - PATH="$PATH:codeql-cli/codeql" python ql/misc/scripts/library-coverage/generate-report.py ci ql ql - - - name: Create pull request with changes - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - python ql/misc/scripts/library-coverage/create-pr.py ql "$GITHUB_REPOSITORY" + - name: Create pull request with changes + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + python ql/misc/scripts/library-coverage/create-pr.py ql "$GITHUB_REPOSITORY" diff --git a/.github/workflows/csv-coverage.yml b/.github/workflows/csv-coverage.yml index 9a308d50265..dfce019451e 100644 --- a/.github/workflows/csv-coverage.yml +++ b/.github/workflows/csv-coverage.yml @@ -4,46 +4,39 @@ on: workflow_dispatch: inputs: qlModelShaOverride: - description: 'github/codeql repo SHA used for looking up the CSV models' + description: "github/codeql repo SHA used for looking up the CSV models" required: false jobs: build: - runs-on: ubuntu-latest steps: - - name: Clone self (github/codeql) - uses: actions/checkout@v3 - with: - path: script - - name: Clone self (github/codeql) for analysis - uses: actions/checkout@v3 - with: - path: codeqlModels - ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }} - - name: Set up Python 3.8 - uses: actions/setup-python@v4 - with: - python-version: 3.8 - - name: Download CodeQL CLI - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - gh release download --repo "github/codeql-cli-binaries" --pattern "codeql-linux64.zip" - - name: Unzip CodeQL CLI - run: unzip -d codeql-cli codeql-linux64.zip - - name: Build modeled package list - run: | - PATH="$PATH:codeql-cli/codeql" python script/misc/scripts/library-coverage/generate-report.py ci codeqlModels script - - name: Upload CSV package list - uses: actions/upload-artifact@v3 - with: - name: framework-coverage-csv - path: framework-coverage-*.csv - - name: Upload RST package list - uses: actions/upload-artifact@v3 - with: - name: framework-coverage-rst - path: framework-coverage-*.rst - + - name: Clone self (github/codeql) + uses: actions/checkout@v3 + with: + path: script + - name: Clone self (github/codeql) for analysis + uses: actions/checkout@v3 + with: + path: codeqlModels + ref: ${{ github.event.inputs.qlModelShaOverride || github.ref }} + - name: Set up Python 3.8 + uses: actions/setup-python@v4 + with: + python-version: 3.8 + - name: Download CodeQL CLI + uses: ./.github/actions/fetch-codeql + - name: Build modeled package list + run: | + PATH="$PATH:codeql-cli/codeql" python script/misc/scripts/library-coverage/generate-report.py ci codeqlModels script + - name: Upload CSV package list + uses: actions/upload-artifact@v3 + with: + name: framework-coverage-csv + path: framework-coverage-*.csv + - name: Upload RST package list + uses: actions/upload-artifact@v3 + with: + name: framework-coverage-rst + path: framework-coverage-*.rst diff --git a/.github/workflows/go-tests.yml b/.github/workflows/go-tests.yml index ca126d1a3ee..6001a18aad1 100644 --- a/.github/workflows/go-tests.yml +++ b/.github/workflows/go-tests.yml @@ -4,159 +4,111 @@ on: paths: - "go/**" - .github/workflows/go-tests.yml + - .github/actions/fetch-codeql - codeql-workspace.yml jobs: - test-linux: name: Test Linux (Ubuntu) runs-on: ubuntu-latest steps: + - name: Set up Go 1.18.1 + uses: actions/setup-go@v3 + with: + go-version: 1.18.1 + id: go - - name: Set up Go 1.18.1 - uses: actions/setup-go@v3 - with: - go-version: 1.18.1 - id: go + - name: Check out code + uses: actions/checkout@v2 - - name: Set up CodeQL CLI - run: | - echo "Removing old CodeQL Directory..." - rm -rf $HOME/codeql - echo "Done" - cd $HOME - echo "Downloading CodeQL CLI..." - LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | grep -v beta | tail -1) - gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$LATEST" - echo "Done" - echo "Unpacking CodeQL CLI..." - unzip -q codeql-linux64.zip - rm -f codeql-linux64.zip - echo "Done" - env: - GITHUB_TOKEN: ${{ github.token }} + - name: Set up CodeQL CLI + uses: ./.github/actions/fetch-codeql - - name: Check out code - uses: actions/checkout@v2 + - name: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - name: Enable problem matchers in repository - shell: bash - run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' + - name: Build + run: | + cd go + env make - - name: Build - run: | - cd go - env PATH=$PATH:$HOME/codeql make + - name: Check that all QL and Go code is autoformatted + run: | + cd go + env make check-formatting - - name: Check that all QL and Go code is autoformatted - run: | - cd go - env PATH=$PATH:$HOME/codeql make check-formatting + - name: Compile qhelp files to markdown + run: | + cd go + env QHELP_OUT_DIR=qhelp-out make qhelp-to-markdown - - name: Compile qhelp files to markdown - run: | - cd go - env PATH=$PATH:$HOME/codeql QHELP_OUT_DIR=qhelp-out make qhelp-to-markdown + - name: Upload qhelp markdown + uses: actions/upload-artifact@v2 + with: + name: qhelp-markdown + path: go/qhelp-out/**/*.md - - name: Upload qhelp markdown - uses: actions/upload-artifact@v2 - with: - name: qhelp-markdown - path: go/qhelp-out/**/*.md - - - name: Test - run: | - cd go - env PATH=$PATH:$HOME/codeql make test + - name: Test + run: | + cd go + env make test test-mac: name: Test MacOS - runs-on: macOS-latest + runs-on: macos-latest steps: - - name: Set up Go 1.18.1 - uses: actions/setup-go@v3 - with: - go-version: 1.18.1 - id: go + - name: Set up Go 1.18.1 + uses: actions/setup-go@v3 + with: + go-version: 1.18.1 + id: go - - name: Set up CodeQL CLI - run: | - echo "Removing old CodeQL Directory..." - rm -rf $HOME/codeql - echo "Done" - cd $HOME - echo "Downloading CodeQL CLI..." - LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | grep -v beta | tail -1) - gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-osx64.zip "$LATEST" - echo "Done" - echo "Unpacking CodeQL CLI..." - unzip -q codeql-osx64.zip - rm -f codeql-osx64.zip - echo "Done" - env: - GITHUB_TOKEN: ${{ github.token }} + - name: Check out code + uses: actions/checkout@v2 - - name: Check out code - uses: actions/checkout@v2 + - name: Set up CodeQL CLI + uses: ./.github/actions/fetch-codeql - - name: Enable problem matchers in repository - shell: bash - run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' + - name: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - name: Build - run: | - cd go - env PATH=$PATH:$HOME/codeql make + - name: Build + run: | + cd go + make - - name: Test - run: | - cd go - env PATH=$PATH:$HOME/codeql make test + - name: Test + run: | + cd go + make test test-win: name: Test Windows runs-on: windows-2019 steps: - - name: Set up Go 1.18.1 - uses: actions/setup-go@v3 - with: - go-version: 1.18.1 - id: go + - name: Set up Go 1.18.1 + uses: actions/setup-go@v3 + with: + go-version: 1.18.1 + id: go - - name: Set up CodeQL CLI - run: | - echo "Removing old CodeQL Directory..." - rm -rf $HOME/codeql - echo "Done" - cd "$HOME" - echo "Downloading CodeQL CLI..." - LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | sort --version-sort | grep -v beta | tail -1) - gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-win64.zip "$LATEST" - echo "Done" - echo "Unpacking CodeQL CLI..." - unzip -q -o codeql-win64.zip - unzip -q -o codeql-win64.zip codeql/codeql.exe - rm -f codeql-win64.zip - echo "Done" - env: - GITHUB_TOKEN: ${{ github.token }} - shell: - bash + - name: Check out code + uses: actions/checkout@v2 - - name: Check out code - uses: actions/checkout@v2 + - name: Set up CodeQL CLI + uses: ./.github/actions/fetch-codeql - - name: Enable problem matchers in repository - shell: bash - run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' + - name: Enable problem matchers in repository + shell: bash + run: 'find .github/problem-matchers -name \*.json -exec echo "::add-matcher::{}" \;' - - name: Build - run: | - $Env:Path += ";$HOME\codeql" - cd go - make + - name: Build + run: | + cd go + make - - name: Test - run: | - $Env:Path += ";$HOME\codeql" - cd go - make test + - name: Test + run: | + cd go + make test diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index c402312db0e..0322408e58f 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -90,19 +90,14 @@ jobs: steps: - uses: actions/checkout@v3 - name: Fetch CodeQL - run: | - LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1) - gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip "$LATEST" - unzip -q codeql-linux64.zip - env: - GITHUB_TOKEN: ${{ github.token }} + uses: ./.github/actions/fetch-codeql - name: Build Query Pack run: | - codeql/codeql pack create ql/lib --output target/packs - codeql/codeql pack install ql/src - codeql/codeql pack create ql/src --output target/packs + codeql pack create ql/lib --output target/packs + codeql pack install ql/src + codeql pack create ql/src --output target/packs PACK_FOLDER=$(readlink -f target/packs/codeql/ruby-queries/*) - codeql/codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src + codeql generate query-help --format=sarifv2.1.0 --output="${PACK_FOLDER}/rules.sarif" ql/src (cd ql/src; find queries \( -name '*.qhelp' -o -name '*.rb' -o -name '*.erb' \) -exec bash -c 'mkdir -p "'"${PACK_FOLDER}"'/$(dirname "{}")"' \; -exec cp "{}" "${PACK_FOLDER}/{}" \;) - uses: actions/upload-artifact@v3 with: @@ -184,14 +179,8 @@ jobs: repository: Shopify/example-ruby-app ref: 67a0decc5eb550f3a9228eda53925c3afd40dfe9 - name: Fetch CodeQL - shell: bash - run: | - LATEST=$(gh release list --repo https://github.com/github/codeql-cli-binaries | cut -f 1 | grep -v beta | sort --version-sort | tail -1) - gh release download --repo https://github.com/github/codeql-cli-binaries --pattern codeql.zip "$LATEST" - unzip -q codeql.zip - env: - GITHUB_TOKEN: ${{ github.token }} - working-directory: ${{ runner.temp }} + uses: ./.github/actions/fetch-codeql + - name: Download Ruby bundle uses: actions/download-artifact@v3 with: @@ -215,12 +204,12 @@ jobs: - name: Run QL test shell: bash run: | - "${{ runner.temp }}/codeql/codeql" test run --search-path "${{ runner.temp }}/ruby-bundle" --additional-packs "${{ runner.temp }}/ruby-bundle" . + codeql test run --search-path "${{ runner.temp }}/ruby-bundle" --additional-packs "${{ runner.temp }}/ruby-bundle" . - name: Create database shell: bash run: | - "${{ runner.temp }}/codeql/codeql" database create --search-path "${{ runner.temp }}/ruby-bundle" --language ruby --source-root . ../database + codeql database create --search-path "${{ runner.temp }}/ruby-bundle" --language ruby --source-root . ../database - name: Analyze database shell: bash run: | - "${{ runner.temp }}/codeql/codeql" database analyze --search-path "${{ runner.temp }}/ruby-bundle" --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls + codeql database analyze --search-path "${{ runner.temp }}/ruby-bundle" --format=sarifv2.1.0 --output=out.sarif ../database ruby-code-scanning.qls From 4d35d8da48fd03cda237c67ab162755b71080e83 Mon Sep 17 00:00:00 2001 From: Arthur Baars Date: Mon, 1 Aug 2022 13:36:05 +0200 Subject: [PATCH 464/465] CI: fix Ruby build job --- .github/workflows/ruby-build.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ruby-build.yml b/.github/workflows/ruby-build.yml index 0322408e58f..2f7464e47b3 100644 --- a/.github/workflows/ruby-build.yml +++ b/.github/workflows/ruby-build.yml @@ -5,6 +5,7 @@ on: paths: - "ruby/**" - .github/workflows/ruby-build.yml + - .github/actions/fetch-codeql - codeql-workspace.yml branches: - main @@ -13,6 +14,7 @@ on: paths: - "ruby/**" - .github/workflows/ruby-build.yml + - .github/actions/fetch-codeql - codeql-workspace.yml branches: - main @@ -174,12 +176,14 @@ jobs: runs-on: ${{ matrix.os }} needs: [package] steps: + - uses: actions/checkout@v3 + - name: Fetch CodeQL + uses: ./.github/actions/fetch-codeql + - uses: actions/checkout@v3 with: repository: Shopify/example-ruby-app ref: 67a0decc5eb550f3a9228eda53925c3afd40dfe9 - - name: Fetch CodeQL - uses: ./.github/actions/fetch-codeql - name: Download Ruby bundle uses: actions/download-artifact@v3 From e3cb7cf9fed80c2eade636208da9d14895275440 Mon Sep 17 00:00:00 2001 From: Mathias Vorreiter Pedersen Date: Mon, 1 Aug 2022 17:30:23 +0100 Subject: [PATCH 465/465] C++: Remove internal 'microsoft' tags from queries. --- .../Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.ql | 1 - cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql | 3 +-- .../Likely Bugs/Likely Typos/inconsistentLoopDirection.ql | 1 - cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql | 5 ----- cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql | 1 - cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql | 1 - .../src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql | 1 - 7 files changed, 1 insertion(+), 12 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.ql b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.ql index 30664869adc..9c0230d7514 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.ql +++ b/cpp/ql/src/Likely Bugs/Likely Typos/IncorrectNotOperatorUsage.ql @@ -10,7 +10,6 @@ * @precision medium * @tags security * external/cwe/cwe-480 - * external/microsoft/c6317 */ import cpp diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql b/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql index 074c82bc03b..8770d249497 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql +++ b/cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql @@ -7,8 +7,7 @@ * @problem.severity error * @precision high * @id cpp/string-copy-return-value-as-boolean - * @tags external/microsoft/C6324 - * correctness + * @tags correctness */ import cpp diff --git a/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql b/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql index 5e3af347821..9646d8b3adf 100644 --- a/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql +++ b/cpp/ql/src/Likely Bugs/Likely Typos/inconsistentLoopDirection.ql @@ -7,7 +7,6 @@ * @id cpp/inconsistent-loop-direction * @tags correctness * external/cwe/cwe-835 - * external/microsoft/6293 * @msrc.severity important */ diff --git a/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql b/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql index 67ba5b0c45b..eb746e2d1d2 100644 --- a/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql @@ -8,11 +8,6 @@ * @precision high * @tags security * external/cwe/cwe-253 - * external/microsoft/C6214 - * external/microsoft/C6215 - * external/microsoft/C6216 - * external/microsoft/C6217 - * external/microsoft/C6230 */ import cpp diff --git a/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql b/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql index 7c540e9d313..ff8e85cecec 100644 --- a/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql +++ b/cpp/ql/src/Security/CWE/CWE-428/UnsafeCreateProcessCall.ql @@ -9,7 +9,6 @@ * @msrc.severity important * @tags security * external/cwe/cwe-428 - * external/microsoft/C6277 */ import cpp diff --git a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql index 65551a1f138..aee4f3c8405 100644 --- a/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql +++ b/cpp/ql/src/Security/CWE/CWE-704/WcharCharConversion.ql @@ -10,7 +10,6 @@ * @precision high * @tags security * external/cwe/cwe-704 - * external/microsoft/c/c6276 */ import cpp diff --git a/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql b/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql index 81998bda450..482b5daf992 100644 --- a/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql +++ b/cpp/ql/src/Security/CWE/CWE-732/UnsafeDaclSecurityDescriptor.ql @@ -11,7 +11,6 @@ * @precision high * @tags security * external/cwe/cwe-732 - * external/microsoft/C6248 */ import cpp