diff --git a/config/identical-files.json b/config/identical-files.json index 214fc402c4f..f814b0f1f81 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -55,15 +55,6 @@ "ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", "swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll" ], - "DataFlow Java/C++/C#/Python/Ruby/Swift Consistency checks": [ - "java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll", - "cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll", - "cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll", - "csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll", - "python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll", - "ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplConsistency.qll", - "swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll" - ], "DataFlow Java/C#/Go/Ruby/Python/Swift Flow Summaries": [ "java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll", "csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll", @@ -561,4 +552,4 @@ "python/ql/test/experimental/dataflow/model-summaries/InlineTaintTest.ext.yml", "python/ql/test/experimental/dataflow/model-summaries/NormalDataflowTest.ext.yml" ] -} +} \ No newline at end of file diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj index abf4f358a24..0c9f70c6d6d 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp.Tests/Semmle.Autobuild.Cpp.Tests.csproj @@ -11,12 +11,12 @@ - - + + all runtime; build; native; contentfiles; analyzers - + diff --git a/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj b/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj index 5e0d40cdfe2..f8f5c285074 100644 --- a/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj +++ b/cpp/autobuilder/Semmle.Autobuild.Cpp/Semmle.Autobuild.Cpp.csproj @@ -17,7 +17,7 @@ - + diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index 2bdc935dfac..58c1d800b3d 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,18 @@ +## 0.9.2 + +### Deprecated APIs + +* `getAllocatorCall` on `DeleteExpr` and `DeleteArrayExpr` has been deprecated. `getDeallocatorCall` should be used instead. + +### New Features + +* Added `DeleteOrDeleteArrayExpr` as a super type of `DeleteExpr` and `DeleteArrayExpr` + +### Minor Analysis Improvements + +* `delete` and `delete[]` are now modeled as calls to the relevant `operator delete` in the IR. In the case of a dynamic delete call a new instruction `VirtualDeleteFunctionAddress` is used to represent a function that dispatches to the correct delete implementation. +* Only the 2 level indirection of `argv` (corresponding to `**argv`) is consided for `FlowSource`. + ## 0.9.1 No user-facing changes. diff --git a/cpp/ql/lib/change-notes/2023-08-24-no-taint-argv-indirections.md b/cpp/ql/lib/change-notes/2023-08-24-no-taint-argv-indirections.md deleted file mode 100644 index 4baf9b770d6..00000000000 --- a/cpp/ql/lib/change-notes/2023-08-24-no-taint-argv-indirections.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Only the 2 level indirection of `argv` (corresponding to `**argv`) is consided for `FlowSource`. diff --git a/cpp/ql/lib/change-notes/2023-08-25-delete-or-delete-array.md b/cpp/ql/lib/change-notes/2023-08-25-delete-or-delete-array.md deleted file mode 100644 index f3f3a59e8f0..00000000000 --- a/cpp/ql/lib/change-notes/2023-08-25-delete-or-delete-array.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Added `DeleteOrDeleteArrayExpr` as a super type of `DeleteExpr` and `DeleteArrayExpr` \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/2023-08-25-getAllocatorCall-deprecated.md b/cpp/ql/lib/change-notes/2023-08-25-getAllocatorCall-deprecated.md deleted file mode 100644 index b9bb1fada5b..00000000000 --- a/cpp/ql/lib/change-notes/2023-08-25-getAllocatorCall-deprecated.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: deprecated ---- -* `getAllocatorCall` on `DeleteExpr` and `DeleteArrayExpr` has been deprecated. `getDeallocatorCall` should be used instead. \ No newline at end of file diff --git a/cpp/ql/lib/change-notes/released/0.9.2.md b/cpp/ql/lib/change-notes/released/0.9.2.md new file mode 100644 index 00000000000..93b36c8e40a --- /dev/null +++ b/cpp/ql/lib/change-notes/released/0.9.2.md @@ -0,0 +1,14 @@ +## 0.9.2 + +### Deprecated APIs + +* `getAllocatorCall` on `DeleteExpr` and `DeleteArrayExpr` has been deprecated. `getDeallocatorCall` should be used instead. + +### New Features + +* Added `DeleteOrDeleteArrayExpr` as a super type of `DeleteExpr` and `DeleteArrayExpr` + +### Minor Analysis Improvements + +* `delete` and `delete[]` are now modeled as calls to the relevant `operator delete` in the IR. In the case of a dynamic delete call a new instruction `VirtualDeleteFunctionAddress` is used to represent a function that dispatches to the correct delete implementation. +* Only the 2 level indirection of `argv` (corresponding to `**argv`) is consided for `FlowSource`. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index 6789dcd18b7..e1eda519435 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.9.1 +lastReleaseVersion: 0.9.2 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 1a8ab0be7bb..6c56393b656 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 0.9.2-dev +version: 0.9.2 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll index e154491f795..229031e0149 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplConsistency.qll @@ -3,297 +3,25 @@ * data-flow classes and predicates. */ -private import DataFlowImplSpecific::Private -private import DataFlowImplSpecific::Public -private import tainttracking1.TaintTrackingParameter::Private -private import tainttracking1.TaintTrackingParameter::Public +private import cpp +private import DataFlowImplSpecific +private import TaintTrackingImplSpecific +private import codeql.dataflow.internal.DataFlowImplConsistency -module Consistency { - private newtype TConsistencyConfiguration = MkConsistencyConfiguration() - - /** A class for configuring the consistency queries. */ - class ConsistencyConfiguration extends TConsistencyConfiguration { - string toString() { none() } - - /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */ - predicate uniqueEnclosingCallableExclude(Node n) { none() } - - /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */ - predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() } - - /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */ - predicate uniqueNodeLocationExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `missingLocation`. */ - predicate missingLocationExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */ - predicate postWithInFlowExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */ - predicate argHasPostUpdateExclude(ArgumentNode n) { none() } - - /** Holds if `n` should be excluded from the consistency test `reverseRead`. */ - predicate reverseReadExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */ - predicate postHasUniquePreExclude(PostUpdateNode n) { none() } - - /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */ - predicate uniquePostUpdateExclude(Node n) { none() } - - /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */ - predicate viableImplInCallContextTooLargeExclude( - DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable - ) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */ - predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */ - predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */ - predicate identityLocalStepExclude(Node n) { none() } - } - - private class RelevantNode extends Node { - RelevantNode() { - this instanceof ArgumentNode or - this instanceof ParameterNode or - this instanceof ReturnNode or - this = getAnOutNode(_, _) or - simpleLocalFlowStep(this, _) or - simpleLocalFlowStep(_, this) or - jumpStep(this, _) or - jumpStep(_, this) or - storeStep(this, _, _) or - storeStep(_, _, this) or - readStep(this, _, _) or - readStep(_, _, this) or - defaultAdditionalTaintStep(this, _) or - defaultAdditionalTaintStep(_, this) - } - } - - query predicate uniqueEnclosingCallable(Node n, string msg) { - exists(int c | - n instanceof RelevantNode and - c = count(nodeGetEnclosingCallable(n)) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and - msg = "Node should have one enclosing callable but has " + c + "." - ) - } - - query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) { - exists(int c | - c = count(call.getEnclosingCallable()) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and - msg = "Call should have one enclosing callable but has " + c + "." - ) - } - - query predicate uniqueType(Node n, string msg) { - exists(int c | - n instanceof RelevantNode and - c = count(getNodeType(n)) and - c != 1 and - msg = "Node should have one type but has " + c + "." - ) - } - - query predicate uniqueNodeLocation(Node n, string msg) { - exists(int c | - c = - count(string filepath, int startline, int startcolumn, int endline, int endcolumn | - n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - ) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and - msg = "Node should have one location but has " + c + "." - ) - } - - query predicate missingLocation(string msg) { - exists(int c | - c = - strictcount(Node n | - not n.hasLocationInfo(_, _, _, _, _) and - not any(ConsistencyConfiguration conf).missingLocationExclude(n) - ) and - msg = "Nodes without location: " + c - ) - } - - query predicate uniqueNodeToString(Node n, string msg) { - exists(int c | - c = count(n.toString()) and - c != 1 and - msg = "Node should have one toString but has " + c + "." - ) - } - - query predicate missingToString(string msg) { - exists(int c | - c = strictcount(Node n | not exists(n.toString())) and - msg = "Nodes without toString: " + c - ) - } - - query predicate parameterCallable(ParameterNode p, string msg) { - exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and - msg = "Callable mismatch for parameter." - } - - query predicate localFlowIsLocal(Node n1, Node n2, string msg) { - simpleLocalFlowStep(n1, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Local flow step does not preserve enclosing callable." - } - - query predicate readStepIsLocal(Node n1, Node n2, string msg) { - readStep(n1, _, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Read step does not preserve enclosing callable." - } - - query predicate storeStepIsLocal(Node n1, Node n2, string msg) { - storeStep(n1, _, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Store step does not preserve enclosing callable." - } - - private DataFlowType typeRepr() { result = getNodeType(_) } - - query predicate compatibleTypesReflexive(DataFlowType t, string msg) { - t = typeRepr() and - not compatibleTypes(t, t) and - msg = "Type compatibility predicate is not reflexive." - } - - query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) { - isUnreachableInCall(n, call) and - exists(DataFlowCallable c | - c = nodeGetEnclosingCallable(n) and - not viableCallable(call) = c - ) and - msg = "Call context for isUnreachableInCall is inconsistent with call graph." - } - - query predicate localCallNodes(DataFlowCall call, Node n, string msg) { - ( - n = getAnOutNode(call, _) and - msg = "OutNode and call does not share enclosing callable." - or - n.(ArgumentNode).argumentOf(call, _) and - msg = "ArgumentNode and call does not share enclosing callable." - ) and - nodeGetEnclosingCallable(n) != call.getEnclosingCallable() - } - - // This predicate helps the compiler forget that in some languages - // it is impossible for a result of `getPreUpdateNode` to be an - // instance of `PostUpdateNode`. - private Node getPre(PostUpdateNode n) { - result = n.getPreUpdateNode() +private module Input implements InputSig { + predicate argHasPostUpdateExclude(Private::ArgumentNode n) { + // Is the null pointer (or something that's not really a pointer) + exists(n.asExpr().getValue()) or - none() - } - - query predicate postIsNotPre(PostUpdateNode n, string msg) { - getPre(n) = n and - msg = "PostUpdateNode should not equal its pre-update node." - } - - query predicate postHasUniquePre(PostUpdateNode n, string msg) { - not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and - exists(int c | - c = count(n.getPreUpdateNode()) and - c != 1 and - msg = "PostUpdateNode should have one pre-update node but has " + c + "." + // Isn't a pointer or is a pointer to const + forall(DerivedType dt | dt = n.asExpr().getActualType() | + dt.getBaseType().isConst() + or + dt.getBaseType() instanceof RoutineType ) - } - - query predicate uniquePostUpdate(Node n, string msg) { - not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and - 1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and - msg = "Node has multiple PostUpdateNodes." - } - - query predicate postIsInSameCallable(PostUpdateNode n, string msg) { - nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and - msg = "PostUpdateNode does not share callable with its pre-update node." - } - - private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) } - - query predicate reverseRead(Node n, string msg) { - exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and - not any(ConsistencyConfiguration conf).reverseReadExclude(n) and - msg = "Origin of readStep is missing a PostUpdateNode." - } - - query predicate argHasPostUpdate(ArgumentNode n, string msg) { - not hasPost(n) and - not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and - msg = "ArgumentNode is missing PostUpdateNode." - } - - // This predicate helps the compiler forget that in some languages - // it is impossible for a `PostUpdateNode` to be the target of - // `simpleLocalFlowStep`. - private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() } - - query predicate postWithInFlow(Node n, string msg) { - isPostUpdateNode(n) and - not clearsContent(n, _) and - simpleLocalFlowStep(_, n) and - not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and - msg = "PostUpdateNode should not be the target of local flow." - } - - query predicate viableImplInCallContextTooLarge( - DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable - ) { - callable = viableImplInCallContext(call, ctx) and - not callable = viableCallable(call) and - not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable) - } - - query predicate uniqueParameterNodeAtPosition( - DataFlowCallable c, ParameterPosition pos, Node p, string msg - ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and - isParameterNode(p, c, pos) and - not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and - msg = "Parameters with overlapping positions." - } - - query predicate uniqueParameterNodePosition( - DataFlowCallable c, ParameterPosition pos, Node p, string msg - ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and - isParameterNode(p, c, pos) and - not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and - msg = "Parameter node with multiple positions." - } - - query predicate uniqueContentApprox(Content c, string msg) { - not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and - msg = "Non-unique content approximation." - } - - query predicate identityLocalStep(Node n, string msg) { - simpleLocalFlowStep(n, n) and - not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and - msg = "Node steps to itself" + // The above list of cases isn't exhaustive, but it narrows down the + // consistency alerts enough that most of them are interesting. } } + +module Consistency = MakeConsistency; diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll index a6f00f30b27..00eca92b3e4 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowPrivate.qll @@ -2,7 +2,6 @@ private import cpp private import DataFlowUtil private import DataFlowDispatch private import FlowVar -private import DataFlowImplConsistency private import codeql.util.Unit /** Gets the callable in which this node occurs. */ @@ -297,22 +296,6 @@ class ContentApprox = Unit; pragma[inline] ContentApprox getContentApprox(Content c) { any() } -private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration { - override predicate argHasPostUpdateExclude(ArgumentNode n) { - // Is the null pointer (or something that's not really a pointer) - exists(n.asExpr().getValue()) - or - // Isn't a pointer or is a pointer to const - forall(DerivedType dt | dt = n.asExpr().getActualType() | - dt.getBaseType().isConst() - or - dt.getBaseType() instanceof RoutineType - ) - // The above list of cases isn't exhaustive, but it narrows down the - // consistency alerts enough that most of them are interesting. - } -} - /** * Gets an additional term that is added to the `join` and `branch` computations to reflect * an additional forward or backwards branching factor that is not taken into account diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll index e154491f795..c32f63a619d 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImplConsistency.qll @@ -3,297 +3,17 @@ * data-flow classes and predicates. */ -private import DataFlowImplSpecific::Private -private import DataFlowImplSpecific::Public -private import tainttracking1.TaintTrackingParameter::Private -private import tainttracking1.TaintTrackingParameter::Public +private import cpp +private import DataFlowImplSpecific +private import TaintTrackingImplSpecific +private import codeql.dataflow.internal.DataFlowImplConsistency -module Consistency { - private newtype TConsistencyConfiguration = MkConsistencyConfiguration() - - /** A class for configuring the consistency queries. */ - class ConsistencyConfiguration extends TConsistencyConfiguration { - string toString() { none() } - - /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */ - predicate uniqueEnclosingCallableExclude(Node n) { none() } - - /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */ - predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() } - - /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */ - predicate uniqueNodeLocationExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `missingLocation`. */ - predicate missingLocationExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */ - predicate postWithInFlowExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */ - predicate argHasPostUpdateExclude(ArgumentNode n) { none() } - - /** Holds if `n` should be excluded from the consistency test `reverseRead`. */ - predicate reverseReadExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */ - predicate postHasUniquePreExclude(PostUpdateNode n) { none() } - - /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */ - predicate uniquePostUpdateExclude(Node n) { none() } - - /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */ - predicate viableImplInCallContextTooLargeExclude( - DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable - ) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */ - predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */ - predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */ - predicate identityLocalStepExclude(Node n) { none() } - } - - private class RelevantNode extends Node { - RelevantNode() { - this instanceof ArgumentNode or - this instanceof ParameterNode or - this instanceof ReturnNode or - this = getAnOutNode(_, _) or - simpleLocalFlowStep(this, _) or - simpleLocalFlowStep(_, this) or - jumpStep(this, _) or - jumpStep(_, this) or - storeStep(this, _, _) or - storeStep(_, _, this) or - readStep(this, _, _) or - readStep(_, _, this) or - defaultAdditionalTaintStep(this, _) or - defaultAdditionalTaintStep(_, this) - } - } - - query predicate uniqueEnclosingCallable(Node n, string msg) { - exists(int c | - n instanceof RelevantNode and - c = count(nodeGetEnclosingCallable(n)) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and - msg = "Node should have one enclosing callable but has " + c + "." - ) - } - - query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) { - exists(int c | - c = count(call.getEnclosingCallable()) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and - msg = "Call should have one enclosing callable but has " + c + "." - ) - } - - query predicate uniqueType(Node n, string msg) { - exists(int c | - n instanceof RelevantNode and - c = count(getNodeType(n)) and - c != 1 and - msg = "Node should have one type but has " + c + "." - ) - } - - query predicate uniqueNodeLocation(Node n, string msg) { - exists(int c | - c = - count(string filepath, int startline, int startcolumn, int endline, int endcolumn | - n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - ) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and - msg = "Node should have one location but has " + c + "." - ) - } - - query predicate missingLocation(string msg) { - exists(int c | - c = - strictcount(Node n | - not n.hasLocationInfo(_, _, _, _, _) and - not any(ConsistencyConfiguration conf).missingLocationExclude(n) - ) and - msg = "Nodes without location: " + c - ) - } - - query predicate uniqueNodeToString(Node n, string msg) { - exists(int c | - c = count(n.toString()) and - c != 1 and - msg = "Node should have one toString but has " + c + "." - ) - } - - query predicate missingToString(string msg) { - exists(int c | - c = strictcount(Node n | not exists(n.toString())) and - msg = "Nodes without toString: " + c - ) - } - - query predicate parameterCallable(ParameterNode p, string msg) { - exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and - msg = "Callable mismatch for parameter." - } - - query predicate localFlowIsLocal(Node n1, Node n2, string msg) { - simpleLocalFlowStep(n1, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Local flow step does not preserve enclosing callable." - } - - query predicate readStepIsLocal(Node n1, Node n2, string msg) { - readStep(n1, _, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Read step does not preserve enclosing callable." - } - - query predicate storeStepIsLocal(Node n1, Node n2, string msg) { - storeStep(n1, _, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Store step does not preserve enclosing callable." - } - - private DataFlowType typeRepr() { result = getNodeType(_) } - - query predicate compatibleTypesReflexive(DataFlowType t, string msg) { - t = typeRepr() and - not compatibleTypes(t, t) and - msg = "Type compatibility predicate is not reflexive." - } - - query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) { - isUnreachableInCall(n, call) and - exists(DataFlowCallable c | - c = nodeGetEnclosingCallable(n) and - not viableCallable(call) = c - ) and - msg = "Call context for isUnreachableInCall is inconsistent with call graph." - } - - query predicate localCallNodes(DataFlowCall call, Node n, string msg) { - ( - n = getAnOutNode(call, _) and - msg = "OutNode and call does not share enclosing callable." - or - n.(ArgumentNode).argumentOf(call, _) and - msg = "ArgumentNode and call does not share enclosing callable." - ) and - nodeGetEnclosingCallable(n) != call.getEnclosingCallable() - } - - // This predicate helps the compiler forget that in some languages - // it is impossible for a result of `getPreUpdateNode` to be an - // instance of `PostUpdateNode`. - private Node getPre(PostUpdateNode n) { - result = n.getPreUpdateNode() - or - none() - } - - query predicate postIsNotPre(PostUpdateNode n, string msg) { - getPre(n) = n and - msg = "PostUpdateNode should not equal its pre-update node." - } - - query predicate postHasUniquePre(PostUpdateNode n, string msg) { - not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and - exists(int c | - c = count(n.getPreUpdateNode()) and - c != 1 and - msg = "PostUpdateNode should have one pre-update node but has " + c + "." - ) - } - - query predicate uniquePostUpdate(Node n, string msg) { - not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and - 1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and - msg = "Node has multiple PostUpdateNodes." - } - - query predicate postIsInSameCallable(PostUpdateNode n, string msg) { - nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and - msg = "PostUpdateNode does not share callable with its pre-update node." - } - - private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) } - - query predicate reverseRead(Node n, string msg) { - exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and - not any(ConsistencyConfiguration conf).reverseReadExclude(n) and - msg = "Origin of readStep is missing a PostUpdateNode." - } - - query predicate argHasPostUpdate(ArgumentNode n, string msg) { - not hasPost(n) and - not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and - msg = "ArgumentNode is missing PostUpdateNode." - } - - // This predicate helps the compiler forget that in some languages - // it is impossible for a `PostUpdateNode` to be the target of - // `simpleLocalFlowStep`. - private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() } - - query predicate postWithInFlow(Node n, string msg) { - isPostUpdateNode(n) and - not clearsContent(n, _) and - simpleLocalFlowStep(_, n) and - not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and - msg = "PostUpdateNode should not be the target of local flow." - } - - query predicate viableImplInCallContextTooLarge( - DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable - ) { - callable = viableImplInCallContext(call, ctx) and - not callable = viableCallable(call) and - not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable) - } - - query predicate uniqueParameterNodeAtPosition( - DataFlowCallable c, ParameterPosition pos, Node p, string msg - ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and - isParameterNode(p, c, pos) and - not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and - msg = "Parameters with overlapping positions." - } - - query predicate uniqueParameterNodePosition( - DataFlowCallable c, ParameterPosition pos, Node p, string msg - ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and - isParameterNode(p, c, pos) and - not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and - msg = "Parameter node with multiple positions." - } - - query predicate uniqueContentApprox(Content c, string msg) { - not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and - msg = "Non-unique content approximation." - } - - query predicate identityLocalStep(Node n, string msg) { - simpleLocalFlowStep(n, n) and - not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and - msg = "Node steps to itself" +private module Input implements InputSig { + predicate argHasPostUpdateExclude(Private::ArgumentNode n) { + // The rules for whether an IR argument gets a post-update node are too + // complex to model here. + any() } } + +module Consistency = MakeConsistency; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 329164e0fd0..7e4b87e3853 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -2,7 +2,6 @@ private import cpp as Cpp private import DataFlowUtil private import semmle.code.cpp.ir.IR private import DataFlowDispatch -private import DataFlowImplConsistency private import semmle.code.cpp.ir.internal.IRCppLanguage private import SsaInternals as Ssa private import DataFlowImplCommon as DataFlowImplCommon @@ -220,9 +219,10 @@ private module IndirectOperands { int indirectionIndex; IndirectOperandFromIRRepr() { - exists(Operand repr | - repr = Ssa::getIRRepresentationOfIndirectOperand(operand, indirectionIndex) and - nodeHasOperand(this, repr, indirectionIndex - 1) + exists(Operand repr, int indirectionIndexRepr | + Ssa::hasIRRepresentationOfIndirectOperand(operand, indirectionIndex, repr, + indirectionIndexRepr) and + nodeHasOperand(this, repr, indirectionIndexRepr) ) } @@ -262,9 +262,10 @@ private module IndirectInstructions { int indirectionIndex; IndirectInstructionFromIRRepr() { - exists(Instruction repr | - repr = Ssa::getIRRepresentationOfIndirectInstruction(instr, indirectionIndex) and - nodeHasInstruction(this, repr, indirectionIndex - 1) + exists(Instruction repr, int indirectionIndexRepr | + Ssa::hasIRRepresentationOfIndirectInstruction(instr, indirectionIndex, repr, + indirectionIndexRepr) and + nodeHasInstruction(this, repr, indirectionIndexRepr) ) } @@ -690,7 +691,7 @@ predicate storeStep(Node node1, ContentSet c, Node node2) { storeStepImpl(node1, private predicate numberOfLoadsFromOperandRec( Operand operandFrom, Operand operandTo, int ind, boolean certain ) { - exists(Instruction load | Ssa::isDereference(load, operandFrom) | + exists(Instruction load | Ssa::isDereference(load, operandFrom, _) | operandTo = operandFrom and ind = 0 and certain = true or numberOfLoadsFromOperand(load.getAUse(), operandTo, ind - 1, certain) @@ -714,7 +715,7 @@ private predicate numberOfLoadsFromOperand( ) { numberOfLoadsFromOperandRec(operandFrom, operandTo, n, certain) or - not Ssa::isDereference(_, operandFrom) and + not Ssa::isDereference(_, operandFrom, _) and not conversionFlow(operandFrom, _, _, _) and operandFrom = operandTo and n = 0 and @@ -1011,14 +1012,6 @@ ContentApprox getContentApprox(Content c) { ) } -private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration { - override predicate argHasPostUpdateExclude(ArgumentNode n) { - // The rules for whether an IR argument gets a post-update node are too - // complex to model here. - any() - } -} - /** * A local flow relation that includes both local steps, read steps and * argument-to-return flow through summarized functions. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index 4e9a90dc0a1..844633ad8d7 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -74,7 +74,7 @@ predicate hasRawIndirectOperand(Operand op, int indirectionIndex) { type = getLanguageType(op) and m = countIndirectionsForCppType(type) and indirectionIndex = [1 .. m] and - not exists(getIRRepresentationOfIndirectOperand(op, indirectionIndex)) + not hasIRRepresentationOfIndirectOperand(op, indirectionIndex, _, _) ) } @@ -88,7 +88,7 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) { type = getResultLanguageType(instr) and m = countIndirectionsForCppType(type) and indirectionIndex = [1 .. m] and - not exists(getIRRepresentationOfIndirectInstruction(instr, indirectionIndex)) + not hasIRRepresentationOfIndirectInstruction(instr, indirectionIndex, _, _) ) } @@ -108,7 +108,7 @@ private newtype TDefOrUseImpl = } or TUseImpl(BaseSourceVariableInstruction base, Operand operand, int indirectionIndex) { isUse(_, operand, base, _, indirectionIndex) and - not isDef(_, _, operand, _, _, _) + not isDef(true, _, operand, _, _, _) } or TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) { // Represents a final "use" of a global variable to ensure that @@ -610,7 +610,7 @@ private predicate indirectConversionFlowStep(Node nFrom, Node nTo) { hasOperandAndIndex(nFrom, op1, pragma[only_bind_into](indirectionIndex)) and hasOperandAndIndex(nTo, op2, indirectionIndex - 1) and instr = op2.getDef() and - isDereference(instr, op1) + isDereference(instr, op1, _) ) ) } @@ -638,12 +638,24 @@ private predicate adjustForPointerArith(PostUpdateNode pun, UseOrPhi use) { ) } +/** + * Holds if `nodeFrom` flows to `nodeTo` because there is `def-use` or + * `use-use` flow from `defOrUse` to `use`. + * + * `uncertain` is `true` if the `defOrUse` is an uncertain definition. + */ +private predicate localSsaFlow( + SsaDefOrUse defOrUse, Node nodeFrom, UseOrPhi use, Node nodeTo, boolean uncertain +) { + nodeToDefOrUse(nodeFrom, defOrUse, uncertain) and + adjacentDefRead(defOrUse, use) and + useToNode(use, nodeTo) and + nodeFrom != nodeTo +} + private predicate ssaFlowImpl(SsaDefOrUse defOrUse, Node nodeFrom, Node nodeTo, boolean uncertain) { exists(UseOrPhi use | - nodeToDefOrUse(nodeFrom, defOrUse, uncertain) and - adjacentDefRead(defOrUse, use) and - useToNode(use, nodeTo) and - nodeFrom != nodeTo + localSsaFlow(defOrUse, nodeFrom, use, nodeTo, uncertain) or // Initial global variable value to a first use nodeFrom.(InitialGlobalValue).getGlobalDef() = defOrUse and @@ -684,19 +696,99 @@ predicate ssaFlow(Node nodeFrom, Node nodeTo) { ) } -private predicate isArgumentOfCallable(DataFlowCall call, ArgumentNode arg) { - arg.argumentOf(call, _) +private predicate isArgumentOfCallableInstruction(DataFlowCall call, Instruction instr) { + isArgumentOfCallableOperand(call, unique( | | getAUse(instr))) } -/** Holds if there is def-use or use-use flow from `pun` to `nodeTo`. */ -predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) { - exists(UseOrPhi use, Node preUpdate | +private predicate isArgumentOfCallableOperand(DataFlowCall call, Operand operand) { + operand.(ArgumentOperand).getCall() = call + or + exists(FieldAddressInstruction fai | + fai.getObjectAddressOperand() = operand and + isArgumentOfCallableInstruction(call, fai) + ) + or + exists(Instruction deref | + isArgumentOfCallableInstruction(call, deref) and + isDereference(deref, operand, _) + ) + or + exists(Instruction instr | + isArgumentOfCallableInstruction(call, instr) and + conversionFlow(operand, instr, _, _) + ) +} + +private predicate isArgumentOfCallable(DataFlowCall call, Node n) { + isArgumentOfCallableOperand(call, n.asOperand()) + or + exists(Operand op | + n.(IndirectOperand).hasOperandAndIndirectionIndex(op, _) and + isArgumentOfCallableOperand(call, op) + ) + or + exists(Instruction instr | + n.(IndirectInstruction).hasInstructionAndIndirectionIndex(instr, _) and + isArgumentOfCallableInstruction(call, instr) + ) +} + +/** + * Holds if there is use-use flow from `pun`'s pre-update node to `n`. + */ +private predicate postUpdateNodeToFirstUse(PostUpdateNode pun, Node n) { + exists(UseOrPhi use | adjustForPointerArith(pun, use) and - useToNode(use, nodeTo) and + useToNode(use, n) + ) +} + +private predicate stepUntilNotInCall(DataFlowCall call, Node n1, Node n2) { + isArgumentOfCallable(call, n1) and + exists(Node mid | localSsaFlow(_, n1, _, mid, _) | + isArgumentOfCallable(call, mid) and + stepUntilNotInCall(call, mid, n2) + or + not isArgumentOfCallable(call, mid) and + mid = n2 + ) +} + +bindingset[n1, n2] +pragma[inline_late] +private predicate isArgumentOfSameCall(DataFlowCall call, Node n1, Node n2) { + isArgumentOfCallable(call, n1) and isArgumentOfCallable(call, n2) +} + +/** + * Holds if there is def-use or use-use flow from `pun` to `nodeTo`. + * + * Note: This is more complex than it sounds. Consider a call such as: + * ```cpp + * write_first_argument(x, x); + * sink(x); + * ``` + * Assume flow comes out of the first argument to `write_first_argument`. We + * don't want flow to go to the `x` that's also an argument to + * `write_first_argument` (because we just flowed out of that function, and we + * don't want to flow back into it again). + * + * We do, however, want flow from the output argument to `x` on the next line, and + * similarly we want flow from the second argument of `write_first_argument` to `x` + * on the next line. + */ +predicate postUpdateFlow(PostUpdateNode pun, Node nodeTo) { + exists(Node preUpdate, Node mid | preUpdate = pun.getPreUpdateNode() and - not exists(DataFlowCall call | - isArgumentOfCallable(call, preUpdate) and isArgumentOfCallable(call, nodeTo) + postUpdateNodeToFirstUse(pun, mid) + | + exists(DataFlowCall call | + isArgumentOfSameCall(call, preUpdate, mid) and + stepUntilNotInCall(call, mid, nodeTo) ) + or + not isArgumentOfSameCall(_, preUpdate, mid) and + nodeTo = mid ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll index 4410e2e9e69..27948d68913 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll @@ -320,10 +320,20 @@ private module IteratorIndirections { } } -predicate isDereference(Instruction deref, Operand address) { - any(Indirection ind).isAdditionalDereference(deref, address) +/** + * Holds if `deref` is the result of loading the value at the address + * represented by `address`. + * + * If `additional = true` then the dereference comes from an `Indirection` + * class (such as a call to an iterator's `operator*`), and if + * `additional = false` the dereference is a `LoadInstruction`. + */ +predicate isDereference(Instruction deref, Operand address, boolean additional) { + any(Indirection ind).isAdditionalDereference(deref, address) and + additional = true or - deref.(LoadInstruction).getSourceAddressOperand() = address + deref.(LoadInstruction).getSourceAddressOperand() = address and + additional = false } predicate isWrite(Node0Impl value, Operand address, boolean certain) { @@ -545,7 +555,7 @@ private module Cached { isDef(_, value, iteratorDerefAddress, iteratorBase, numberOfLoads + 2, 0) and isUse(_, iteratorAddress, iteratorBase, numberOfLoads + 1, 0) and iteratorBase.getResultType() instanceof Interfaces::Iterator and - isDereference(iteratorAddress.getDef(), read.getArgumentDef().getAUse()) and + isDereference(iteratorAddress.getDef(), read.getArgumentDef().getAUse(), _) and memory = read.getSideEffectOperand().getAnyDef() ) } @@ -781,11 +791,14 @@ private module Cached { * instead associated with the operand returned by this predicate. */ cached - Operand getIRRepresentationOfIndirectOperand(Operand operand, int indirectionIndex) { + predicate hasIRRepresentationOfIndirectOperand( + Operand operand, int indirectionIndex, Operand operandRepr, int indirectionIndexRepr + ) { + indirectionIndex = [1 .. countIndirectionsForCppType(getLanguageType(operand))] and exists(Instruction load | - isDereference(load, operand) and - result = unique( | | getAUse(load)) and - isUseImpl(operand, _, indirectionIndex - 1) + isDereference(load, operand, false) and + operandRepr = unique( | | getAUse(load)) and + indirectionIndexRepr = indirectionIndex - 1 ) } @@ -797,12 +810,15 @@ private module Cached { * instead associated with the instruction returned by this predicate. */ cached - Instruction getIRRepresentationOfIndirectInstruction(Instruction instr, int indirectionIndex) { + predicate hasIRRepresentationOfIndirectInstruction( + Instruction instr, int indirectionIndex, Instruction instrRepr, int indirectionIndexRepr + ) { + indirectionIndex = [1 .. countIndirectionsForCppType(getResultLanguageType(instr))] and exists(Instruction load, Operand address | address.getDef() = instr and - isDereference(load, address) and - isUseImpl(address, _, indirectionIndex - 1) and - result = load + isDereference(load, address, false) and + instrRepr = load and + indirectionIndexRepr = indirectionIndex - 1 ) } @@ -823,7 +839,7 @@ private module Cached { or exists(int ind0 | exists(Operand address | - isDereference(operand.getDef(), address) and + isDereference(operand.getDef(), address, _) and isUseImpl(address, base, ind0) ) or @@ -893,7 +909,7 @@ private module Cached { ) or exists(Operand address, boolean certain0 | - isDereference(operand.getDef(), address) and + isDereference(operand.getDef(), address, _) and isDefImpl(address, base, ind - 1, certain0) | if isCertainAddress(operand) then certain = certain0 else certain = false diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll index 50e45e3081d..fd4169edd7d 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll @@ -57,7 +57,7 @@ private predicate operandToInstructionTaintStep(Operand opFrom, Instruction inst ) or // Taint flow from an address to its dereference. - Ssa::isDereference(instrTo, opFrom) + Ssa::isDereference(instrTo, opFrom, _) or // Unary instructions tend to preserve enough information in practice that we // want taint to flow through. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll index a9ecdf46984..c473969467d 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll @@ -55,6 +55,7 @@ private newtype TOpcode = TVariableAddress() or TFieldAddress() or TFunctionAddress() or + TVirtualDeleteFunctionAddress() or TElementsAddress() or TConstant() or TStringConstant() or @@ -887,6 +888,15 @@ module Opcode { final override string toString() { result = "FunctionAddress" } } + /** + * The `Opcode` for a `VirtualDeleteFunctionAddress`. + * + * See the `VirtualDeleteFunctionAddressInstruction` documentation for more details. + */ + class VirtualDeleteFunctionAddress extends Opcode, TVirtualDeleteFunctionAddress { + final override string toString() { result = "VirtualDeleteFunctionAddress" } + } + /** * The `Opcode` for a `ConstantInstruction`. * diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index 1b5ea432946..2a3a6d3407a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -576,6 +576,22 @@ class FunctionAddressInstruction extends FunctionInstruction { FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress } } +/** + * An instruction that returns the address of a "virtual" delete function. + * + * This function, which does not actually exist in the source code, is used to + * delete objects of a class with a virtual destructor. In that case the deacllocation + * function is selected at runtime based on the dynamic type of the object. So this + * function dynamically dispatches to the correct deallocation function. + * It also should pass in the required extra arguments to the deallocation function + * which may differ dynamically depending on the type of the object. + */ +class VirtualDeleteFunctionAddressInstruction extends Instruction { + VirtualDeleteFunctionAddressInstruction() { + this.getOpcode() instanceof Opcode::VirtualDeleteFunctionAddress + } +} + /** * An instruction that initializes a parameter of the enclosing function with the value of the * corresponding argument passed by the caller. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll index 1b5ea432946..2a3a6d3407a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -576,6 +576,22 @@ class FunctionAddressInstruction extends FunctionInstruction { FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress } } +/** + * An instruction that returns the address of a "virtual" delete function. + * + * This function, which does not actually exist in the source code, is used to + * delete objects of a class with a virtual destructor. In that case the deacllocation + * function is selected at runtime based on the dynamic type of the object. So this + * function dynamically dispatches to the correct deallocation function. + * It also should pass in the required extra arguments to the deallocation function + * which may differ dynamically depending on the type of the object. + */ +class VirtualDeleteFunctionAddressInstruction extends Instruction { + VirtualDeleteFunctionAddressInstruction() { + this.getOpcode() instanceof Opcode::VirtualDeleteFunctionAddress + } +} + /** * An instruction that initializes a parameter of the enclosing function with the value of the * corresponding argument passed by the caller. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll index 684aa4f14f2..187cde6e700 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/SideEffects.qll @@ -120,9 +120,9 @@ private predicate hasDefaultSideEffect(Call call, ParameterIndex i, boolean buff } /** - * A `Call` or `NewOrNewArrayExpr`. + * A `Call` or `NewOrNewArrayExpr` or `DeleteOrDeleteArrayExpr`. * - * Both kinds of expression invoke a function as part of their evaluation. This class provides a + * All kinds of expression invoke a function as part of their evaluation. This class provides a * way to treat both kinds of function similarly, and to get the invoked `Function`. */ class CallOrAllocationExpr extends Expr { @@ -130,6 +130,8 @@ class CallOrAllocationExpr extends Expr { this instanceof Call or this instanceof NewOrNewArrayExpr + or + this instanceof DeleteOrDeleteArrayExpr } /** Gets the `Function` invoked by this expression, if known. */ @@ -137,6 +139,8 @@ class CallOrAllocationExpr extends Expr { result = this.(Call).getTarget() or result = this.(NewOrNewArrayExpr).getAllocator() + or + result = this.(DeleteOrDeleteArrayExpr).getDeallocator() } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index 68f7a5fbdb4..7079354f098 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -350,6 +350,9 @@ class TranslatedCallSideEffects extends TranslatedSideEffects, TTranslatedCallSi or expr instanceof NewOrNewArrayExpr and result = getTranslatedAllocatorCall(expr).getInstruction(CallTag()) + or + expr instanceof DeleteOrDeleteArrayExpr and + result = getTranslatedDeleteOrDeleteArray(expr).getInstruction(CallTag()) } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 0efc7e7af3a..409d76f4fd5 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -77,17 +77,17 @@ private predicate ignoreExprAndDescendants(Expr expr) { newExpr.getInitializer().getFullyConverted() = expr ) or + exists(DeleteOrDeleteArrayExpr deleteExpr | + // Ignore the deallocator call, because we always synthesize it. + deleteExpr.getDeallocatorCall() = expr + ) + or // Do not translate input/output variables in GNU asm statements // getRealParent(expr) instanceof AsmStmt // or ignoreExprAndDescendants(getRealParent(expr)) // recursive case or - // We do not yet translate destructors properly, so for now we ignore any - // custom deallocator call, if present. - exists(DeleteExpr deleteExpr | deleteExpr.getDeallocatorCall() = expr) - or - exists(DeleteArrayExpr deleteArrayExpr | deleteArrayExpr.getDeallocatorCall() = expr) - or + // va_start doesn't evaluate its argument, so we don't need to translate it. exists(BuiltInVarArgsStart vaStartExpr | vaStartExpr.getLastNamedParameter().getFullyConverted() = expr ) @@ -104,6 +104,12 @@ private predicate ignoreExprOnly(Expr expr) { newExpr.getAllocatorCall() = expr ) or + exists(DeleteOrDeleteArrayExpr deleteExpr | + // Ignore the destructor call as we don't model it yet. Don't ignore + // its arguments, though, as they are the arguments to the deallocator. + deleteExpr.getDestructorCall() = expr + ) + or // The extractor deliberately emits an `ErrorExpr` as the first argument to // the allocator call, if any, of a `NewOrNewArrayExpr`. That `ErrorExpr` // should not be translated. @@ -111,13 +117,6 @@ private predicate ignoreExprOnly(Expr expr) { or not translateFunction(getEnclosingFunction(expr)) and not Raw::varHasIRFunc(getEnclosingVariable(expr)) - or - // We do not yet translate destructors properly, so for now we ignore the - // destructor call. We do, however, translate the expression being - // destructed, and that expression can be a child of the destructor call. - exists(DeleteExpr deleteExpr | deleteExpr.getDestructorCall() = expr) - or - exists(DeleteArrayExpr deleteArrayExpr | deleteArrayExpr.getDestructorCall() = expr) } /** @@ -416,7 +415,9 @@ predicate hasTranslatedLoad(Expr expr) { not ignoreExpr(expr) and not isNativeCondition(expr) and not isFlexibleCondition(expr) and - not ignoreLoad(expr) + not ignoreLoad(expr) and + // don't insert a load since we'll just substitute the constant value. + not isIRConstant(expr) } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index 4f93f5d3702..5589786ce39 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -2017,6 +2017,66 @@ TranslatedAllocatorCall getTranslatedAllocatorCall(NewOrNewArrayExpr newExpr) { result.getAst() = newExpr } +/** + * The IR translation of a `delete` or `delete[]` + * expression. + */ +class TranslatedDeleteOrDeleteArrayExpr extends TranslatedNonConstantExpr, TranslatedCall { + override DeleteOrDeleteArrayExpr expr; + + final override Instruction getFirstCallTargetInstruction() { + result = this.getInstruction(CallTargetTag()) + } + + final override Instruction getCallTargetResult() { result = this.getInstruction(CallTargetTag()) } + + override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { + TranslatedCall.super.hasInstruction(opcode, tag, resultType) + or + tag = CallTargetTag() and + resultType = getFunctionGLValueType() and + if exists(expr.getDeallocator()) + then opcode instanceof Opcode::FunctionAddress + else opcode instanceof Opcode::VirtualDeleteFunctionAddress + } + + override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { + result = TranslatedCall.super.getInstructionSuccessor(tag, kind) + or + tag = CallTargetTag() and + kind instanceof GotoEdge and + result = this.getFirstArgumentOrCallInstruction() + } + + override Function getInstructionFunction(InstructionTag tag) { + tag = CallTargetTag() and result = expr.getDeallocator() + } + + final override Type getCallResultType() { result = expr.getType() } + + final override TranslatedExpr getQualifier() { none() } + + final override predicate hasArguments() { + // All deallocator calls have at least one argument. + any() + } + + final override int getNumberOfArguments() { + // We ignore the other arguments for now as we would have to synthesize them. + result = 1 + } + + final override TranslatedExpr getArgument(int index) { + // The only argument we define is the pointer to be deallocated. + index = 0 and + result = getTranslatedExpr(expr.getExpr().getFullyConverted()) + } +} + +TranslatedDeleteOrDeleteArrayExpr getTranslatedDeleteOrDeleteArray(DeleteOrDeleteArrayExpr newExpr) { + result.getAst() = newExpr +} + /** * Abstract class implemented by any `TranslatedElement` that has a child * expression that is a call to a constructor or destructor, in order to @@ -2954,78 +3014,6 @@ class TranslatedNewArrayExpr extends TranslatedNewOrNewArrayExpr { } } -/** - * A placeholder for the translation of a `delete[]` expression. - * - * Proper translation is not yet implemented, but this stub implementation - * ensures that code following a `delete[]` is not unreachable. - */ -class TranslatedDeleteArrayExprPlaceHolder extends TranslatedSingleInstructionExpr { - override DeleteArrayExpr expr; - - final override Instruction getFirstInstruction() { - result = this.getOperand().getFirstInstruction() - } - - final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() } - - final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { - tag = OnlyInstructionTag() and - result = this.getParent().getChildSuccessor(this) and - kind instanceof GotoEdge - } - - final override Instruction getChildSuccessor(TranslatedElement child) { - child = this.getOperand() and result = this.getInstruction(OnlyInstructionTag()) - } - - final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { - none() - } - - final override Opcode getOpcode() { result instanceof Opcode::NoOp } - - private TranslatedExpr getOperand() { - result = getTranslatedExpr(expr.getExpr().getFullyConverted()) - } -} - -/** - * A placeholder for the translation of a `delete` expression. - * - * Proper translation is not yet implemented, but this stub implementation - * ensures that code following a `delete` is not unreachable. - */ -class TranslatedDeleteExprPlaceHolder extends TranslatedSingleInstructionExpr { - override DeleteExpr expr; - - final override Instruction getFirstInstruction() { - result = this.getOperand().getFirstInstruction() - } - - final override TranslatedElement getChild(int id) { id = 0 and result = this.getOperand() } - - final override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { - tag = OnlyInstructionTag() and - result = this.getParent().getChildSuccessor(this) and - kind instanceof GotoEdge - } - - final override Instruction getChildSuccessor(TranslatedElement child) { - child = this.getOperand() and result = this.getInstruction(OnlyInstructionTag()) - } - - final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { - none() - } - - final override Opcode getOpcode() { result instanceof Opcode::NoOp } - - private TranslatedExpr getOperand() { - result = getTranslatedExpr(expr.getExpr().getFullyConverted()) - } -} - /** * The IR translation of a `ConditionDeclExpr`, which represents the value of the declared variable * after conversion to `bool` in code such as: diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index 1b5ea432946..2a3a6d3407a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -576,6 +576,22 @@ class FunctionAddressInstruction extends FunctionInstruction { FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress } } +/** + * An instruction that returns the address of a "virtual" delete function. + * + * This function, which does not actually exist in the source code, is used to + * delete objects of a class with a virtual destructor. In that case the deacllocation + * function is selected at runtime based on the dynamic type of the object. So this + * function dynamically dispatches to the correct deallocation function. + * It also should pass in the required extra arguments to the deallocation function + * which may differ dynamically depending on the type of the object. + */ +class VirtualDeleteFunctionAddressInstruction extends Instruction { + VirtualDeleteFunctionAddressInstruction() { + this.getOpcode() instanceof Opcode::VirtualDeleteFunctionAddress + } +} + /** * An instruction that initializes a parameter of the enclosing function with the value of the * corresponding argument passed by the caller. diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index f3d5cd46f66..6edc055a334 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,15 @@ +## 0.7.4 + +### New Queries + +* Added a new query, `cpp/invalid-pointer-deref`, to detect out-of-bounds pointer reads and writes. + +### Minor Analysis Improvements + +* The "Comparison where assignment was intended" query (`cpp/compare-where-assign-meant`) no longer reports comparisons that appear in macro expansions. +* Some queries that had repeated results corresponding to different levels of indirection for `argv` now only have a single result. +* The `cpp/non-constant-format` query no longer considers an assignment on the right-hand side of another assignment to be a source of non-constant format strings. As a result, the query may now produce fewer results. + ## 0.7.3 No user-facing changes. diff --git a/cpp/ql/src/change-notes/2023-08-21-invalid-pointer-deref.md b/cpp/ql/src/change-notes/2023-08-21-invalid-pointer-deref.md deleted file mode 100644 index d8207a75604..00000000000 --- a/cpp/ql/src/change-notes/2023-08-21-invalid-pointer-deref.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: newQuery ---- -* Added a new query, `cpp/invalid-pointer-deref`, to detect out-of-bounds pointer reads and writes. diff --git a/cpp/ql/src/change-notes/2023-08-24-no-taint-argv-indirections.md b/cpp/ql/src/change-notes/2023-08-24-no-taint-argv-indirections.md deleted file mode 100644 index 74b8e6910da..00000000000 --- a/cpp/ql/src/change-notes/2023-08-24-no-taint-argv-indirections.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Some queries that had repeated results corresponding to different levels of indirection for `argv` now only have a single result. diff --git a/cpp/ql/src/change-notes/2023-08-24-remove-non-constant-assign-sources.md b/cpp/ql/src/change-notes/2023-08-24-remove-non-constant-assign-sources.md deleted file mode 100644 index f4dcc011a29..00000000000 --- a/cpp/ql/src/change-notes/2023-08-24-remove-non-constant-assign-sources.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The `cpp/non-constant-format` query no longer considers an assignment on the right-hand side of another assignment to be a source of non-constant format strings. As a result, the query may now produce fewer results. diff --git a/cpp/ql/src/change-notes/2023-08-25-compare-where-assign-meant.md b/cpp/ql/src/change-notes/2023-08-25-compare-where-assign-meant.md deleted file mode 100644 index 8872ba413fb..00000000000 --- a/cpp/ql/src/change-notes/2023-08-25-compare-where-assign-meant.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The "Comparison where assignment was intended" query (`cpp/compare-where-assign-meant`) no longer reports comparisons that appear in macro expansions. diff --git a/cpp/ql/src/change-notes/released/0.7.4.md b/cpp/ql/src/change-notes/released/0.7.4.md new file mode 100644 index 00000000000..bdec41d4f69 --- /dev/null +++ b/cpp/ql/src/change-notes/released/0.7.4.md @@ -0,0 +1,11 @@ +## 0.7.4 + +### New Queries + +* Added a new query, `cpp/invalid-pointer-deref`, to detect out-of-bounds pointer reads and writes. + +### Minor Analysis Improvements + +* The "Comparison where assignment was intended" query (`cpp/compare-where-assign-meant`) no longer reports comparisons that appear in macro expansions. +* Some queries that had repeated results corresponding to different levels of indirection for `argv` now only have a single result. +* The `cpp/non-constant-format` query no longer considers an assignment on the right-hand side of another assignment to be a source of non-constant format strings. As a result, the query may now produce fewer results. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index a4ea9c8de17..e388f34b4ec 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.3 +lastReleaseVersion: 0.7.4 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index fd076044593..0fe920a9439 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 0.7.4-dev +version: 0.7.4 groups: - cpp - queries diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected index dbd71611d81..15a601b27f0 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected @@ -9,44 +9,35 @@ edges | test.cpp:22:5:22:7 | arr indirection [p] | test.cpp:19:9:19:16 | mk_array indirection [p] | | test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:31:9:31:11 | arr indirection [p] | | test.cpp:28:19:28:26 | call to mk_array [p] | test.cpp:35:9:35:11 | arr indirection [p] | -| test.cpp:31:9:31:11 | arr indirection [p] | test.cpp:31:13:31:13 | p indirection | -| test.cpp:31:13:31:13 | p indirection | test.cpp:31:13:31:13 | p | -| test.cpp:35:9:35:11 | arr indirection [p] | test.cpp:35:13:35:13 | p indirection | -| test.cpp:35:13:35:13 | p indirection | test.cpp:35:13:35:13 | p | +| test.cpp:31:9:31:11 | arr indirection [p] | test.cpp:31:13:31:13 | p | +| test.cpp:35:9:35:11 | arr indirection [p] | test.cpp:35:13:35:13 | p | | test.cpp:39:27:39:29 | arr [p] | test.cpp:41:9:41:11 | arr indirection [p] | | test.cpp:39:27:39:29 | arr [p] | test.cpp:45:9:45:11 | arr indirection [p] | -| test.cpp:41:9:41:11 | arr indirection [p] | test.cpp:41:13:41:13 | p indirection | -| test.cpp:41:13:41:13 | p indirection | test.cpp:41:13:41:13 | p | -| test.cpp:45:9:45:11 | arr indirection [p] | test.cpp:45:13:45:13 | p indirection | -| test.cpp:45:13:45:13 | p indirection | test.cpp:45:13:45:13 | p | +| test.cpp:41:9:41:11 | arr indirection [p] | test.cpp:41:13:41:13 | p | +| test.cpp:45:9:45:11 | arr indirection [p] | test.cpp:45:13:45:13 | p | | test.cpp:50:18:50:25 | call to mk_array [p] | test.cpp:39:27:39:29 | arr [p] | | test.cpp:55:5:55:24 | ... = ... | test.cpp:55:9:55:9 | arr indirection [post update] [p] | | test.cpp:55:9:55:9 | arr indirection [post update] [p] | test.cpp:56:5:56:7 | arr indirection [p] | | test.cpp:55:13:55:18 | call to malloc | test.cpp:55:5:55:24 | ... = ... | | test.cpp:56:5:56:7 | arr indirection [p] | test.cpp:59:9:59:11 | arr indirection [p] | | test.cpp:56:5:56:7 | arr indirection [p] | test.cpp:63:9:63:11 | arr indirection [p] | -| test.cpp:59:9:59:11 | arr indirection [p] | test.cpp:59:13:59:13 | p indirection | -| test.cpp:59:13:59:13 | p indirection | test.cpp:59:13:59:13 | p | -| test.cpp:63:9:63:11 | arr indirection [p] | test.cpp:63:13:63:13 | p indirection | -| test.cpp:63:13:63:13 | p indirection | test.cpp:63:13:63:13 | p | +| test.cpp:59:9:59:11 | arr indirection [p] | test.cpp:59:13:59:13 | p | +| test.cpp:63:9:63:11 | arr indirection [p] | test.cpp:63:13:63:13 | p | | test.cpp:67:10:67:19 | mk_array_p indirection [p] | test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | | test.cpp:67:10:67:19 | mk_array_p indirection [p] | test.cpp:98:18:98:27 | call to mk_array_p indirection [p] | | test.cpp:69:5:69:25 | ... = ... | test.cpp:69:10:69:10 | arr indirection [post update] [p] | | test.cpp:69:10:69:10 | arr indirection [post update] [p] | test.cpp:70:5:70:7 | arr indirection [p] | | test.cpp:69:14:69:19 | call to malloc | test.cpp:69:5:69:25 | ... = ... | | test.cpp:70:5:70:7 | arr indirection [p] | test.cpp:67:10:67:19 | mk_array_p indirection [p] | +| test.cpp:70:5:70:7 | arr indirection [p] | test.cpp:70:5:70:7 | arr indirection [p] | | test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:79:9:79:11 | arr indirection [p] | | test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | test.cpp:83:9:83:11 | arr indirection [p] | -| test.cpp:79:9:79:11 | arr indirection [p] | test.cpp:79:14:79:14 | p indirection | -| test.cpp:79:14:79:14 | p indirection | test.cpp:79:14:79:14 | p | -| test.cpp:83:9:83:11 | arr indirection [p] | test.cpp:83:14:83:14 | p indirection | -| test.cpp:83:14:83:14 | p indirection | test.cpp:83:14:83:14 | p | +| test.cpp:79:9:79:11 | arr indirection [p] | test.cpp:79:14:79:14 | p | +| test.cpp:83:9:83:11 | arr indirection [p] | test.cpp:83:14:83:14 | p | | test.cpp:87:28:87:30 | arr indirection [p] | test.cpp:89:9:89:11 | arr indirection [p] | | test.cpp:87:28:87:30 | arr indirection [p] | test.cpp:93:9:93:11 | arr indirection [p] | -| test.cpp:89:9:89:11 | arr indirection [p] | test.cpp:89:14:89:14 | p indirection | -| test.cpp:89:14:89:14 | p indirection | test.cpp:89:14:89:14 | p | -| test.cpp:93:9:93:11 | arr indirection [p] | test.cpp:93:14:93:14 | p indirection | -| test.cpp:93:14:93:14 | p indirection | test.cpp:93:14:93:14 | p | +| test.cpp:89:9:89:11 | arr indirection [p] | test.cpp:89:14:89:14 | p | +| test.cpp:93:9:93:11 | arr indirection [p] | test.cpp:93:14:93:14 | p | | test.cpp:98:18:98:27 | call to mk_array_p indirection [p] | test.cpp:87:28:87:30 | arr indirection [p] | nodes | test.cpp:4:17:4:22 | call to malloc | semmle.label | call to malloc | @@ -60,17 +51,13 @@ nodes | test.cpp:28:19:28:26 | call to mk_array [p] | semmle.label | call to mk_array [p] | | test.cpp:31:9:31:11 | arr indirection [p] | semmle.label | arr indirection [p] | | test.cpp:31:13:31:13 | p | semmle.label | p | -| test.cpp:31:13:31:13 | p indirection | semmle.label | p indirection | | test.cpp:35:9:35:11 | arr indirection [p] | semmle.label | arr indirection [p] | | test.cpp:35:13:35:13 | p | semmle.label | p | -| test.cpp:35:13:35:13 | p indirection | semmle.label | p indirection | | test.cpp:39:27:39:29 | arr [p] | semmle.label | arr [p] | | test.cpp:41:9:41:11 | arr indirection [p] | semmle.label | arr indirection [p] | | test.cpp:41:13:41:13 | p | semmle.label | p | -| test.cpp:41:13:41:13 | p indirection | semmle.label | p indirection | | test.cpp:45:9:45:11 | arr indirection [p] | semmle.label | arr indirection [p] | | test.cpp:45:13:45:13 | p | semmle.label | p | -| test.cpp:45:13:45:13 | p indirection | semmle.label | p indirection | | test.cpp:50:18:50:25 | call to mk_array [p] | semmle.label | call to mk_array [p] | | test.cpp:55:5:55:24 | ... = ... | semmle.label | ... = ... | | test.cpp:55:9:55:9 | arr indirection [post update] [p] | semmle.label | arr indirection [post update] [p] | @@ -78,10 +65,8 @@ nodes | test.cpp:56:5:56:7 | arr indirection [p] | semmle.label | arr indirection [p] | | test.cpp:59:9:59:11 | arr indirection [p] | semmle.label | arr indirection [p] | | test.cpp:59:13:59:13 | p | semmle.label | p | -| test.cpp:59:13:59:13 | p indirection | semmle.label | p indirection | | test.cpp:63:9:63:11 | arr indirection [p] | semmle.label | arr indirection [p] | | test.cpp:63:13:63:13 | p | semmle.label | p | -| test.cpp:63:13:63:13 | p indirection | semmle.label | p indirection | | test.cpp:67:10:67:19 | mk_array_p indirection [p] | semmle.label | mk_array_p indirection [p] | | test.cpp:69:5:69:25 | ... = ... | semmle.label | ... = ... | | test.cpp:69:10:69:10 | arr indirection [post update] [p] | semmle.label | arr indirection [post update] [p] | @@ -90,17 +75,13 @@ nodes | test.cpp:76:20:76:29 | call to mk_array_p indirection [p] | semmle.label | call to mk_array_p indirection [p] | | test.cpp:79:9:79:11 | arr indirection [p] | semmle.label | arr indirection [p] | | test.cpp:79:14:79:14 | p | semmle.label | p | -| test.cpp:79:14:79:14 | p indirection | semmle.label | p indirection | | test.cpp:83:9:83:11 | arr indirection [p] | semmle.label | arr indirection [p] | | test.cpp:83:14:83:14 | p | semmle.label | p | -| test.cpp:83:14:83:14 | p indirection | semmle.label | p indirection | | test.cpp:87:28:87:30 | arr indirection [p] | semmle.label | arr indirection [p] | | test.cpp:89:9:89:11 | arr indirection [p] | semmle.label | arr indirection [p] | | test.cpp:89:14:89:14 | p | semmle.label | p | -| test.cpp:89:14:89:14 | p indirection | semmle.label | p indirection | | test.cpp:93:9:93:11 | arr indirection [p] | semmle.label | arr indirection [p] | | test.cpp:93:14:93:14 | p | semmle.label | p | -| test.cpp:93:14:93:14 | p indirection | semmle.label | p indirection | | test.cpp:98:18:98:27 | call to mk_array_p indirection [p] | semmle.label | call to mk_array_p indirection [p] | subpaths #select diff --git a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected index 4cac8898022..fe5eed1b916 100644 --- a/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected +++ b/cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/annotate_sinks_only/tainted.expected @@ -1,4 +1,4 @@ WARNING: Module TaintedWithPath has been deprecated and may be removed in future (tainted.ql:10,8-47) WARNING: Predicate tainted has been deprecated and may be removed in future (tainted.ql:21,3-28) -failures testFailures +failures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_argument_flow.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_argument_flow.cpp new file mode 100644 index 00000000000..f3d135cce60 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_argument_flow.cpp @@ -0,0 +1,14 @@ +namespace { + struct Foo { + char string[10]; + }; + + void acquire(char*); + + Foo* test_self_argument_flow() { + Foo *info; + acquire(info->string); // clean + + return info; + } +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp index c49d9092cd7..c5f7ffcf160 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -788,4 +788,12 @@ void test_sometimes_calls_sink_switch() { sometimes_calls_sink_switch(source(), 1); sometimes_calls_sink_switch(0, 0); sometimes_calls_sink_switch(source(), 0); +} + +void intPointerSource(int *ref_source, const int* another_arg); + +void test() { + MyStruct a; + intPointerSource(a.content, a.content); + indirect_sink(a.content); // $ ast ir } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected index 0260ed62b05..d4756e8d808 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.expected @@ -5,5 +5,5 @@ WARNING: Module DataFlow has been deprecated and may be removed in future (test. WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:40,25-33) WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:42,17-25) WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:46,20-28) -failures testFailures +failures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.expected new file mode 100644 index 00000000000..8ec8033d086 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.expected @@ -0,0 +1,2 @@ +testFailures +failures diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.ql b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.ql new file mode 100644 index 00000000000..95f992f39f5 --- /dev/null +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test_self_argument_flow.ql @@ -0,0 +1,33 @@ +import cpp +import semmle.code.cpp.dataflow.new.DataFlow +import TestUtilities.InlineExpectationsTest + +module TestConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + source.getLocation().getFile().getBaseName() = "self_argument_flow.cpp" and + source.asDefiningArgument() = + any(Call call | call.getTarget().hasName("acquire")).getAnArgument() + } + + predicate isSink(DataFlow::Node sink) { + sink.asIndirectArgument() = any(Call call | call.getTarget().hasName("acquire")).getAnArgument() + } +} + +import DataFlow::Global + +module TestSelfArgumentFlow implements TestSig { + string getARelevantTag() { result = "self-arg-flow" } + + predicate hasActualResult(Location location, string element, string tag, string value) { + exists(DataFlow::Node sink | + flowTo(sink) and + location = sink.getLocation() and + element = sink.toString() and + tag = "self-arg-flow" and + value = "" + ) + } +} + +import MakeTest diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected index b40148f4950..72290967857 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/uninitialized.expected @@ -14,6 +14,8 @@ | ref.cpp:120:17:120:18 | x3 | ref.cpp:129:10:129:11 | x3 | | ref.cpp:120:21:120:22 | x4 | ref.cpp:131:15:131:16 | x4 | | ref.cpp:120:21:120:22 | x4 | ref.cpp:132:10:132:11 | x4 | +| self_argument_flow.cpp:9:10:9:13 | info | self_argument_flow.cpp:10:13:10:16 | info | +| self_argument_flow.cpp:9:10:9:13 | info | self_argument_flow.cpp:12:12:12:15 | info | | test.cpp:75:7:75:8 | u1 | test.cpp:76:8:76:9 | u1 | | test.cpp:83:7:83:8 | u2 | test.cpp:84:13:84:14 | u2 | | test.cpp:83:7:83:8 | u2 | test.cpp:85:8:85:9 | u2 | @@ -44,3 +46,6 @@ | test.cpp:595:8:595:9 | xs | test.cpp:597:9:597:10 | xs | | test.cpp:733:7:733:7 | x | test.cpp:734:41:734:41 | x | | test.cpp:733:7:733:7 | x | test.cpp:735:8:735:8 | x | +| test.cpp:796:12:796:12 | a | test.cpp:797:20:797:20 | a | +| test.cpp:796:12:796:12 | a | test.cpp:797:31:797:31 | a | +| test.cpp:796:12:796:12 | a | test.cpp:798:17:798:17 | a | diff --git a/cpp/ql/test/library-tests/dataflow/fields/flow.expected b/cpp/ql/test/library-tests/dataflow/fields/flow.expected index 48de9172b36..8ec8033d086 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/flow.expected @@ -1,2 +1,2 @@ -failures testFailures +failures diff --git a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected index 6dce17b97bf..bde0ebd2586 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected @@ -5,9 +5,7 @@ edges | A.cpp:27:22:27:32 | ... = ... | A.cpp:27:28:27:28 | this indirection [post update] [c] | | A.cpp:28:8:28:10 | this indirection [c] | A.cpp:28:23:28:26 | this indirection [c] | | A.cpp:28:23:28:26 | this indirection [c] | A.cpp:28:29:28:29 | c | -| A.cpp:28:23:28:26 | this indirection [c] | A.cpp:28:29:28:29 | c indirection | | A.cpp:28:29:28:29 | c | A.cpp:28:8:28:10 | get indirection | -| A.cpp:28:29:28:29 | c indirection | A.cpp:28:8:28:10 | get indirection | | A.cpp:29:23:29:23 | c | A.cpp:31:20:31:20 | c | | A.cpp:31:14:31:21 | call to B [c] | A.cpp:29:15:29:18 | make indirection [c] | | A.cpp:31:20:31:20 | c | A.cpp:23:10:23:10 | c | @@ -21,9 +19,7 @@ edges | A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c | | A.cpp:48:20:48:20 | c | A.cpp:48:12:48:18 | call to make indirection [c] | | A.cpp:49:10:49:10 | b indirection [c] | A.cpp:49:10:49:13 | c | -| A.cpp:49:10:49:10 | b indirection [c] | A.cpp:49:13:49:13 | c indirection | -| A.cpp:49:13:49:13 | c indirection | A.cpp:49:10:49:13 | c | -| A.cpp:49:13:49:13 | c indirection | A.cpp:49:13:49:13 | c | +| A.cpp:49:10:49:10 | b indirection [c] | A.cpp:49:13:49:13 | c | | A.cpp:55:5:55:5 | set output argument [c] | A.cpp:56:10:56:10 | b indirection [c] | | A.cpp:55:12:55:19 | new | A.cpp:27:17:27:17 | c | | A.cpp:55:12:55:19 | new | A.cpp:55:5:55:5 | set output argument [c] | @@ -41,17 +37,13 @@ edges | A.cpp:64:21:64:28 | new | A.cpp:64:21:64:28 | new | | A.cpp:64:21:64:28 | new | A.cpp:85:26:85:26 | c | | A.cpp:66:10:66:11 | b2 indirection [c] | A.cpp:66:10:66:14 | c | -| A.cpp:66:10:66:11 | b2 indirection [c] | A.cpp:66:14:66:14 | c indirection | -| A.cpp:66:14:66:14 | c indirection | A.cpp:66:10:66:14 | c | -| A.cpp:66:14:66:14 | c indirection | A.cpp:66:14:66:14 | c | +| A.cpp:66:10:66:11 | b2 indirection [c] | A.cpp:66:14:66:14 | c | | A.cpp:73:10:73:19 | call to setOnBWrap indirection [c] | A.cpp:75:10:75:11 | b2 indirection [c] | | A.cpp:73:25:73:32 | new | A.cpp:73:10:73:19 | call to setOnBWrap indirection [c] | | A.cpp:73:25:73:32 | new | A.cpp:73:25:73:32 | new | | A.cpp:73:25:73:32 | new | A.cpp:78:27:78:27 | c | | A.cpp:75:10:75:11 | b2 indirection [c] | A.cpp:75:10:75:14 | c | -| A.cpp:75:10:75:11 | b2 indirection [c] | A.cpp:75:14:75:14 | c indirection | -| A.cpp:75:14:75:14 | c indirection | A.cpp:75:10:75:14 | c | -| A.cpp:75:14:75:14 | c indirection | A.cpp:75:14:75:14 | c | +| A.cpp:75:10:75:11 | b2 indirection [c] | A.cpp:75:14:75:14 | c | | A.cpp:78:27:78:27 | c | A.cpp:81:21:81:21 | c | | A.cpp:81:10:81:15 | call to setOnB indirection [c] | A.cpp:78:6:78:15 | setOnBWrap indirection [c] | | A.cpp:81:21:81:21 | c | A.cpp:81:10:81:15 | call to setOnB indirection [c] | @@ -67,22 +59,16 @@ edges | A.cpp:103:14:103:14 | c indirection [a] | A.cpp:107:12:107:13 | c1 indirection [a] | | A.cpp:103:14:103:14 | c indirection [a] | A.cpp:120:12:120:13 | c1 indirection [a] | | A.cpp:107:12:107:13 | c1 indirection [a] | A.cpp:107:12:107:16 | a | -| A.cpp:107:12:107:13 | c1 indirection [a] | A.cpp:107:16:107:16 | a indirection | -| A.cpp:107:16:107:16 | a indirection | A.cpp:107:12:107:16 | a | -| A.cpp:107:16:107:16 | a indirection | A.cpp:107:16:107:16 | a | +| A.cpp:107:12:107:13 | c1 indirection [a] | A.cpp:107:16:107:16 | a | | A.cpp:120:12:120:13 | c1 indirection [a] | A.cpp:120:12:120:16 | a | -| A.cpp:120:12:120:13 | c1 indirection [a] | A.cpp:120:16:120:16 | a indirection | -| A.cpp:120:16:120:16 | a indirection | A.cpp:120:12:120:16 | a | -| A.cpp:120:16:120:16 | a indirection | A.cpp:120:16:120:16 | a | +| A.cpp:120:12:120:13 | c1 indirection [a] | A.cpp:120:16:120:16 | a | | A.cpp:126:5:126:5 | set output argument [c] | A.cpp:131:8:131:8 | f7 output argument [c] | | A.cpp:126:12:126:18 | new | A.cpp:27:17:27:17 | c | | A.cpp:126:12:126:18 | new | A.cpp:126:5:126:5 | set output argument [c] | | A.cpp:126:12:126:18 | new | A.cpp:126:12:126:18 | new | | A.cpp:131:8:131:8 | f7 output argument [c] | A.cpp:132:10:132:10 | b indirection [c] | | A.cpp:132:10:132:10 | b indirection [c] | A.cpp:132:10:132:13 | c | -| A.cpp:132:10:132:10 | b indirection [c] | A.cpp:132:13:132:13 | c indirection | -| A.cpp:132:13:132:13 | c indirection | A.cpp:132:10:132:13 | c | -| A.cpp:132:13:132:13 | c indirection | A.cpp:132:13:132:13 | c | +| A.cpp:132:10:132:10 | b indirection [c] | A.cpp:132:13:132:13 | c | | A.cpp:140:13:140:13 | b | A.cpp:143:7:143:31 | ... = ... | | A.cpp:142:7:142:20 | ... = ... | A.cpp:142:10:142:10 | b indirection [post update] [c] | | A.cpp:142:10:142:10 | b indirection [post update] [c] | A.cpp:143:7:143:31 | ... = ... indirection [c] | @@ -101,20 +87,13 @@ edges | A.cpp:151:18:151:18 | b | A.cpp:140:13:140:13 | b | | A.cpp:151:18:151:18 | b | A.cpp:151:12:151:24 | call to D [b] | | A.cpp:152:10:152:10 | d indirection [b] | A.cpp:152:10:152:13 | b | -| A.cpp:152:10:152:10 | d indirection [b] | A.cpp:152:13:152:13 | b indirection | -| A.cpp:152:13:152:13 | b indirection | A.cpp:152:10:152:13 | b | -| A.cpp:152:13:152:13 | b indirection | A.cpp:152:13:152:13 | b | -| A.cpp:153:10:153:10 | d indirection [b indirection, c] | A.cpp:153:13:153:13 | b indirection [c] | +| A.cpp:152:10:152:10 | d indirection [b] | A.cpp:152:13:152:13 | b | | A.cpp:153:10:153:10 | d indirection [b indirection, c] | A.cpp:153:13:153:13 | b indirection [c] | | A.cpp:153:13:153:13 | b indirection [c] | A.cpp:153:10:153:16 | c | | A.cpp:153:13:153:13 | b indirection [c] | A.cpp:153:13:153:13 | b indirection [c] | -| A.cpp:153:13:153:13 | b indirection [c] | A.cpp:153:16:153:16 | c indirection | -| A.cpp:153:16:153:16 | c indirection | A.cpp:153:10:153:16 | c | -| A.cpp:153:16:153:16 | c indirection | A.cpp:153:16:153:16 | c | +| A.cpp:153:13:153:13 | b indirection [c] | A.cpp:153:16:153:16 | c | | A.cpp:154:10:154:10 | b indirection [c] | A.cpp:154:10:154:13 | c | -| A.cpp:154:10:154:10 | b indirection [c] | A.cpp:154:13:154:13 | c indirection | -| A.cpp:154:13:154:13 | c indirection | A.cpp:154:10:154:13 | c | -| A.cpp:154:13:154:13 | c indirection | A.cpp:154:13:154:13 | c | +| A.cpp:154:10:154:10 | b indirection [c] | A.cpp:154:13:154:13 | c | | A.cpp:159:12:159:18 | new | A.cpp:160:29:160:29 | b | | A.cpp:160:18:160:60 | call to MyList [head] | A.cpp:161:38:161:39 | l1 indirection [head] | | A.cpp:160:29:160:29 | b | A.cpp:160:18:160:60 | call to MyList [head] | @@ -127,27 +106,17 @@ edges | A.cpp:162:38:162:39 | l2 indirection [next indirection, head] | A.cpp:162:18:162:40 | call to MyList [next indirection, next indirection, head] | | A.cpp:162:38:162:39 | l2 indirection [next indirection, head] | A.cpp:181:32:181:35 | next indirection [next indirection, head] | | A.cpp:165:10:165:11 | l3 indirection [next indirection, next indirection, head] | A.cpp:165:14:165:17 | next indirection [next indirection, head] | -| A.cpp:165:10:165:11 | l3 indirection [next indirection, next indirection, head] | A.cpp:165:14:165:17 | next indirection [next indirection, head] | | A.cpp:165:14:165:17 | next indirection [next indirection, head] | A.cpp:165:14:165:17 | next indirection [next indirection, head] | | A.cpp:165:14:165:17 | next indirection [next indirection, head] | A.cpp:165:20:165:23 | next indirection [head] | -| A.cpp:165:14:165:17 | next indirection [next indirection, head] | A.cpp:165:20:165:23 | next indirection [head] | | A.cpp:165:20:165:23 | next indirection [head] | A.cpp:165:10:165:29 | head | | A.cpp:165:20:165:23 | next indirection [head] | A.cpp:165:20:165:23 | next indirection [head] | -| A.cpp:165:20:165:23 | next indirection [head] | A.cpp:165:26:165:29 | head indirection | -| A.cpp:165:26:165:29 | head indirection | A.cpp:165:10:165:29 | head | -| A.cpp:165:26:165:29 | head indirection | A.cpp:165:26:165:29 | head | -| A.cpp:167:44:167:44 | l indirection [next indirection, head] | A.cpp:167:47:167:50 | next indirection [head] | +| A.cpp:165:20:165:23 | next indirection [head] | A.cpp:165:26:165:29 | head | | A.cpp:167:44:167:44 | l indirection [next indirection, head] | A.cpp:167:47:167:50 | next indirection [head] | | A.cpp:167:44:167:44 | l indirection [next indirection, next indirection, head] | A.cpp:167:47:167:50 | next indirection [next indirection, head] | -| A.cpp:167:44:167:44 | l indirection [next indirection, next indirection, head] | A.cpp:167:47:167:50 | next indirection [next indirection, head] | | A.cpp:167:47:167:50 | next indirection [head] | A.cpp:169:12:169:12 | l indirection [head] | -| A.cpp:167:47:167:50 | next indirection [head] | A.cpp:169:12:169:12 | l indirection [head] | -| A.cpp:167:47:167:50 | next indirection [next indirection, head] | A.cpp:167:44:167:44 | l indirection [next indirection, head] | | A.cpp:167:47:167:50 | next indirection [next indirection, head] | A.cpp:167:44:167:44 | l indirection [next indirection, head] | | A.cpp:169:12:169:12 | l indirection [head] | A.cpp:169:12:169:18 | head | -| A.cpp:169:12:169:12 | l indirection [head] | A.cpp:169:15:169:18 | head indirection | -| A.cpp:169:15:169:18 | head indirection | A.cpp:169:12:169:18 | head | -| A.cpp:169:15:169:18 | head indirection | A.cpp:169:15:169:18 | head | +| A.cpp:169:12:169:12 | l indirection [head] | A.cpp:169:15:169:18 | head | | A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:20 | ... = ... | | A.cpp:181:32:181:35 | next indirection [head] | A.cpp:184:7:184:23 | ... = ... indirection [head] | | A.cpp:181:32:181:35 | next indirection [next indirection, head] | A.cpp:184:7:184:23 | ... = ... indirection [next indirection, head] | @@ -162,12 +131,9 @@ edges | B.cpp:8:25:8:26 | b1 indirection [elem1] | B.cpp:8:16:8:27 | call to Box2 [box1 indirection, elem1] | | B.cpp:8:25:8:26 | b1 indirection [elem1] | B.cpp:44:16:44:17 | b1 indirection [elem1] | | B.cpp:9:10:9:11 | b2 indirection [box1 indirection, elem1] | B.cpp:9:14:9:17 | box1 indirection [elem1] | -| B.cpp:9:10:9:11 | b2 indirection [box1 indirection, elem1] | B.cpp:9:14:9:17 | box1 indirection [elem1] | | B.cpp:9:14:9:17 | box1 indirection [elem1] | B.cpp:9:10:9:24 | elem1 | | B.cpp:9:14:9:17 | box1 indirection [elem1] | B.cpp:9:14:9:17 | box1 indirection [elem1] | -| B.cpp:9:14:9:17 | box1 indirection [elem1] | B.cpp:9:20:9:24 | elem1 indirection | -| B.cpp:9:20:9:24 | elem1 indirection | B.cpp:9:10:9:24 | elem1 | -| B.cpp:9:20:9:24 | elem1 indirection | B.cpp:9:20:9:24 | elem1 | +| B.cpp:9:14:9:17 | box1 indirection [elem1] | B.cpp:9:20:9:24 | elem1 | | B.cpp:15:15:15:27 | new | B.cpp:16:37:16:37 | e | | B.cpp:16:16:16:38 | call to Box1 [elem2] | B.cpp:17:25:17:26 | b1 indirection [elem2] | | B.cpp:16:37:16:37 | e | B.cpp:16:16:16:38 | call to Box1 [elem2] | @@ -176,12 +142,9 @@ edges | B.cpp:17:25:17:26 | b1 indirection [elem2] | B.cpp:17:16:17:27 | call to Box2 [box1 indirection, elem2] | | B.cpp:17:25:17:26 | b1 indirection [elem2] | B.cpp:44:16:44:17 | b1 indirection [elem2] | | B.cpp:19:10:19:11 | b2 indirection [box1 indirection, elem2] | B.cpp:19:14:19:17 | box1 indirection [elem2] | -| B.cpp:19:10:19:11 | b2 indirection [box1 indirection, elem2] | B.cpp:19:14:19:17 | box1 indirection [elem2] | | B.cpp:19:14:19:17 | box1 indirection [elem2] | B.cpp:19:10:19:24 | elem2 | | B.cpp:19:14:19:17 | box1 indirection [elem2] | B.cpp:19:14:19:17 | box1 indirection [elem2] | -| B.cpp:19:14:19:17 | box1 indirection [elem2] | B.cpp:19:20:19:24 | elem2 indirection | -| B.cpp:19:20:19:24 | elem2 indirection | B.cpp:19:10:19:24 | elem2 | -| B.cpp:19:20:19:24 | elem2 indirection | B.cpp:19:20:19:24 | elem2 | +| B.cpp:19:14:19:17 | box1 indirection [elem2] | B.cpp:19:20:19:24 | elem2 | | B.cpp:33:16:33:17 | e1 | B.cpp:35:7:35:22 | ... = ... | | B.cpp:33:26:33:27 | e2 | B.cpp:36:7:36:22 | ... = ... | | B.cpp:35:7:35:22 | ... = ... | B.cpp:35:13:35:17 | this indirection [post update] [elem1] | @@ -202,23 +165,15 @@ edges | C.cpp:24:16:24:25 | new | C.cpp:24:5:24:25 | ... = ... | | C.cpp:27:8:27:11 | this indirection [s1] | C.cpp:29:10:29:11 | this indirection [s1] | | C.cpp:27:8:27:11 | this indirection [s3] | C.cpp:31:10:31:11 | this indirection [s3] | -| C.cpp:29:10:29:11 | s1 indirection | C.cpp:29:10:29:11 | s1 | | C.cpp:29:10:29:11 | this indirection [s1] | C.cpp:29:10:29:11 | s1 | -| C.cpp:29:10:29:11 | this indirection [s1] | C.cpp:29:10:29:11 | s1 indirection | -| C.cpp:31:10:31:11 | s3 indirection | C.cpp:31:10:31:11 | s3 | | C.cpp:31:10:31:11 | this indirection [s3] | C.cpp:31:10:31:11 | s3 | -| C.cpp:31:10:31:11 | this indirection [s3] | C.cpp:31:10:31:11 | s3 indirection | | D.cpp:10:11:10:17 | this indirection [elem] | D.cpp:10:30:10:33 | this indirection [elem] | | D.cpp:10:30:10:33 | elem | D.cpp:10:11:10:17 | getElem indirection | -| D.cpp:10:30:10:33 | elem indirection | D.cpp:10:11:10:17 | getElem indirection | | D.cpp:10:30:10:33 | this indirection [elem] | D.cpp:10:30:10:33 | elem | -| D.cpp:10:30:10:33 | this indirection [elem] | D.cpp:10:30:10:33 | elem indirection | | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:36 | ... = ... | | D.cpp:11:29:11:36 | ... = ... | D.cpp:11:29:11:32 | this indirection [post update] [elem] | | D.cpp:17:11:17:17 | this indirection [box indirection, elem] | D.cpp:17:30:17:32 | this indirection [box indirection, elem] | | D.cpp:17:30:17:32 | box indirection [elem] | D.cpp:17:11:17:17 | getBox1 indirection [elem] | -| D.cpp:17:30:17:32 | box indirection [elem] | D.cpp:17:11:17:17 | getBox1 indirection [elem] | -| D.cpp:17:30:17:32 | this indirection [box indirection, elem] | D.cpp:17:30:17:32 | box indirection [elem] | | D.cpp:17:30:17:32 | this indirection [box indirection, elem] | D.cpp:17:30:17:32 | box indirection [elem] | | D.cpp:21:30:21:31 | b2 indirection [box indirection, elem] | D.cpp:22:10:22:11 | b2 indirection [box indirection, elem] | | D.cpp:22:10:22:11 | b2 indirection [box indirection, elem] | D.cpp:17:11:17:17 | this indirection [box indirection, elem] | @@ -256,20 +211,16 @@ edges | D.cpp:63:8:63:10 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] | | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | D.cpp:64:20:64:22 | box indirection [elem] | -| D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | D.cpp:64:20:64:22 | box indirection [elem] | -| D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | | D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | | D.cpp:64:20:64:22 | box indirection [elem] | D.cpp:64:10:64:28 | elem | | D.cpp:64:20:64:22 | box indirection [elem] | D.cpp:64:20:64:22 | box indirection [elem] | -| D.cpp:64:20:64:22 | box indirection [elem] | D.cpp:64:25:64:28 | elem indirection | -| D.cpp:64:25:64:28 | elem indirection | D.cpp:64:10:64:28 | elem | -| D.cpp:64:25:64:28 | elem indirection | D.cpp:64:25:64:28 | elem | +| D.cpp:64:20:64:22 | box indirection [elem] | D.cpp:64:25:64:28 | elem | | E.cpp:19:27:19:27 | p indirection [data, buffer indirection] | E.cpp:21:10:21:10 | p indirection [data, buffer indirection] | | E.cpp:21:10:21:10 | p indirection [data, buffer indirection] | E.cpp:21:13:21:16 | data indirection [buffer indirection] | | E.cpp:21:13:21:16 | data indirection [buffer indirection] | E.cpp:21:18:21:23 | buffer indirection | | E.cpp:21:13:21:16 | data indirection [buffer indirection] | E.cpp:21:18:21:23 | buffer indirection | | E.cpp:21:18:21:23 | buffer indirection | E.cpp:21:18:21:23 | buffer indirection | -| E.cpp:28:21:28:23 | argument_source output argument | E.cpp:31:10:31:12 | raw indirection | +| E.cpp:21:18:21:23 | buffer indirection | E.cpp:21:18:21:23 | buffer indirection | | E.cpp:28:21:28:23 | argument_source output argument | E.cpp:31:10:31:12 | raw indirection | | E.cpp:29:21:29:29 | argument_source output argument | E.cpp:29:24:29:29 | b indirection [post update] [buffer indirection] | | E.cpp:29:24:29:29 | b indirection [post update] [buffer indirection] | E.cpp:32:10:32:10 | b indirection [buffer indirection] | @@ -279,6 +230,7 @@ edges | E.cpp:32:10:32:10 | b indirection [buffer indirection] | E.cpp:32:13:32:18 | buffer indirection | | E.cpp:32:10:32:10 | b indirection [buffer indirection] | E.cpp:32:13:32:18 | buffer indirection | | E.cpp:32:13:32:18 | buffer indirection | E.cpp:32:13:32:18 | buffer indirection | +| E.cpp:32:13:32:18 | buffer indirection | E.cpp:32:13:32:18 | buffer indirection | | E.cpp:33:18:33:19 | & ... indirection [data, buffer indirection] | E.cpp:19:27:19:27 | p indirection [data, buffer indirection] | | aliasing.cpp:9:3:9:22 | ... = ... | aliasing.cpp:9:6:9:7 | s indirection [post update] [m1] | | aliasing.cpp:9:6:9:7 | s indirection [post update] [m1] | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | @@ -289,25 +241,17 @@ edges | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | aliasing.cpp:29:8:29:9 | s1 indirection [m1] | | aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | aliasing.cpp:30:8:30:9 | s2 indirection [m1] | | aliasing.cpp:29:8:29:9 | s1 indirection [m1] | aliasing.cpp:29:11:29:12 | m1 | -| aliasing.cpp:29:8:29:9 | s1 indirection [m1] | aliasing.cpp:29:11:29:12 | m1 indirection | -| aliasing.cpp:29:11:29:12 | m1 indirection | aliasing.cpp:29:11:29:12 | m1 | | aliasing.cpp:30:8:30:9 | s2 indirection [m1] | aliasing.cpp:30:11:30:12 | m1 | -| aliasing.cpp:30:8:30:9 | s2 indirection [m1] | aliasing.cpp:30:11:30:12 | m1 indirection | -| aliasing.cpp:30:11:30:12 | m1 indirection | aliasing.cpp:30:11:30:12 | m1 | | aliasing.cpp:60:3:60:22 | ... = ... | aliasing.cpp:60:6:60:7 | s2 indirection [post update] [m1] | | aliasing.cpp:60:6:60:7 | s2 indirection [post update] [m1] | aliasing.cpp:62:8:62:12 | copy2 indirection [m1] | | aliasing.cpp:60:11:60:20 | call to user_input | aliasing.cpp:60:3:60:22 | ... = ... | | aliasing.cpp:62:8:62:12 | copy2 indirection [m1] | aliasing.cpp:62:14:62:15 | m1 | -| aliasing.cpp:62:8:62:12 | copy2 indirection [m1] | aliasing.cpp:62:14:62:15 | m1 indirection | -| aliasing.cpp:62:14:62:15 | m1 indirection | aliasing.cpp:62:14:62:15 | m1 | | aliasing.cpp:92:3:92:23 | ... = ... | aliasing.cpp:92:7:92:8 | s indirection [post update] [m1] | | aliasing.cpp:92:5:92:5 | w indirection [post update] [s, m1] | aliasing.cpp:93:8:93:8 | w indirection [s, m1] | | aliasing.cpp:92:7:92:8 | s indirection [post update] [m1] | aliasing.cpp:92:5:92:5 | w indirection [post update] [s, m1] | | aliasing.cpp:92:12:92:21 | call to user_input | aliasing.cpp:92:3:92:23 | ... = ... | | aliasing.cpp:93:8:93:8 | w indirection [s, m1] | aliasing.cpp:93:10:93:10 | s indirection [m1] | | aliasing.cpp:93:10:93:10 | s indirection [m1] | aliasing.cpp:93:12:93:13 | m1 | -| aliasing.cpp:93:10:93:10 | s indirection [m1] | aliasing.cpp:93:12:93:13 | m1 indirection | -| aliasing.cpp:93:12:93:13 | m1 indirection | aliasing.cpp:93:12:93:13 | m1 | | aliasing.cpp:98:3:98:21 | ... = ... | aliasing.cpp:98:5:98:6 | s indirection [post update] [m1] | | aliasing.cpp:98:5:98:6 | s indirection [post update] [m1] | aliasing.cpp:101:14:101:19 | s_copy indirection [m1] | | aliasing.cpp:98:10:98:19 | call to user_input | aliasing.cpp:98:3:98:21 | ... = ... | @@ -331,41 +275,29 @@ edges | aliasing.cpp:141:17:141:20 | s indirection [post update] [data indirection] | aliasing.cpp:143:8:143:8 | s indirection [data indirection] | | aliasing.cpp:141:17:141:20 | taint_a_ptr output argument | aliasing.cpp:141:17:141:20 | s indirection [post update] [data indirection] | | aliasing.cpp:143:8:143:8 | s indirection [data indirection] | aliasing.cpp:143:8:143:16 | access to array | -| aliasing.cpp:143:8:143:8 | s indirection [data indirection] | aliasing.cpp:143:8:143:16 | access to array indirection | | aliasing.cpp:143:8:143:8 | s indirection [data indirection] | aliasing.cpp:143:10:143:13 | data indirection | -| aliasing.cpp:143:8:143:16 | access to array indirection | aliasing.cpp:143:8:143:16 | access to array | | aliasing.cpp:143:10:143:13 | data indirection | aliasing.cpp:143:8:143:16 | access to array | | aliasing.cpp:158:15:158:20 | taint_a_ptr output argument | aliasing.cpp:158:17:158:20 | s indirection [post update] [data] | | aliasing.cpp:158:17:158:20 | s indirection [post update] [data] | aliasing.cpp:159:9:159:9 | s indirection [data] | | aliasing.cpp:159:9:159:9 | s indirection [data] | aliasing.cpp:159:8:159:14 | * ... | -| aliasing.cpp:159:9:159:9 | s indirection [data] | aliasing.cpp:159:9:159:14 | data indirection | -| aliasing.cpp:159:9:159:14 | data indirection | aliasing.cpp:159:8:159:14 | * ... | | aliasing.cpp:164:15:164:20 | taint_a_ptr output argument | aliasing.cpp:164:17:164:20 | s indirection [post update] [data] | | aliasing.cpp:164:17:164:20 | s indirection [post update] [data] | aliasing.cpp:165:8:165:8 | s indirection [data] | | aliasing.cpp:165:8:165:8 | s indirection [data] | aliasing.cpp:165:8:165:16 | access to array | -| aliasing.cpp:165:8:165:8 | s indirection [data] | aliasing.cpp:165:8:165:16 | access to array indirection | -| aliasing.cpp:165:8:165:16 | access to array indirection | aliasing.cpp:165:8:165:16 | access to array | | aliasing.cpp:175:15:175:22 | taint_a_ptr output argument | aliasing.cpp:175:21:175:22 | s indirection [post update] [m1] | | aliasing.cpp:175:19:175:19 | s2 indirection [post update] [s, m1] | aliasing.cpp:176:8:176:9 | s2 indirection [s, m1] | | aliasing.cpp:175:21:175:22 | s indirection [post update] [m1] | aliasing.cpp:175:19:175:19 | s2 indirection [post update] [s, m1] | | aliasing.cpp:176:8:176:9 | s2 indirection [s, m1] | aliasing.cpp:176:11:176:11 | s indirection [m1] | | aliasing.cpp:176:11:176:11 | s indirection [m1] | aliasing.cpp:176:13:176:14 | m1 | -| aliasing.cpp:176:11:176:11 | s indirection [m1] | aliasing.cpp:176:13:176:14 | m1 indirection | -| aliasing.cpp:176:13:176:14 | m1 indirection | aliasing.cpp:176:13:176:14 | m1 | | aliasing.cpp:187:15:187:22 | taint_a_ptr output argument | aliasing.cpp:187:21:187:22 | s indirection [post update] [m1] | | aliasing.cpp:187:19:187:19 | s2 indirection [post update] [s, m1] | aliasing.cpp:189:8:189:11 | s2_2 indirection [s, m1] | | aliasing.cpp:187:21:187:22 | s indirection [post update] [m1] | aliasing.cpp:187:19:187:19 | s2 indirection [post update] [s, m1] | | aliasing.cpp:189:8:189:11 | s2_2 indirection [s, m1] | aliasing.cpp:189:13:189:13 | s indirection [m1] | | aliasing.cpp:189:13:189:13 | s indirection [m1] | aliasing.cpp:189:15:189:16 | m1 | -| aliasing.cpp:189:13:189:13 | s indirection [m1] | aliasing.cpp:189:15:189:16 | m1 indirection | -| aliasing.cpp:189:15:189:16 | m1 indirection | aliasing.cpp:189:15:189:16 | m1 | | aliasing.cpp:200:15:200:24 | taint_a_ptr output argument | aliasing.cpp:200:23:200:24 | s indirection [post update] [m1] | | aliasing.cpp:200:21:200:21 | ps2 indirection [post update] [s, m1] | aliasing.cpp:201:8:201:10 | ps2 indirection [s, m1] | | aliasing.cpp:200:23:200:24 | s indirection [post update] [m1] | aliasing.cpp:200:21:200:21 | ps2 indirection [post update] [s, m1] | | aliasing.cpp:201:8:201:10 | ps2 indirection [s, m1] | aliasing.cpp:201:13:201:13 | s indirection [m1] | | aliasing.cpp:201:13:201:13 | s indirection [m1] | aliasing.cpp:201:15:201:16 | m1 | -| aliasing.cpp:201:13:201:13 | s indirection [m1] | aliasing.cpp:201:15:201:16 | m1 indirection | -| aliasing.cpp:201:15:201:16 | m1 indirection | aliasing.cpp:201:15:201:16 | m1 | | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:7:8:7:13 | access to array | | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:8:8:8:13 | access to array | | arrays.cpp:6:12:6:21 | call to user_input | arrays.cpp:9:8:9:11 | * ... | @@ -380,14 +312,10 @@ edges | arrays.cpp:36:26:36:35 | call to user_input | arrays.cpp:36:3:36:37 | ... = ... | | arrays.cpp:37:8:37:8 | o indirection [nested, arr, data] | arrays.cpp:37:10:37:15 | nested indirection [arr, data] | | arrays.cpp:37:8:37:22 | access to array indirection [data] | arrays.cpp:37:24:37:27 | data | -| arrays.cpp:37:8:37:22 | access to array indirection [data] | arrays.cpp:37:24:37:27 | data indirection | | arrays.cpp:37:10:37:15 | nested indirection [arr, data] | arrays.cpp:37:8:37:22 | access to array indirection [data] | -| arrays.cpp:37:24:37:27 | data indirection | arrays.cpp:37:24:37:27 | data | | arrays.cpp:38:8:38:8 | o indirection [nested, arr, data] | arrays.cpp:38:10:38:15 | nested indirection [arr, data] | | arrays.cpp:38:8:38:22 | access to array indirection [data] | arrays.cpp:38:24:38:27 | data | -| arrays.cpp:38:8:38:22 | access to array indirection [data] | arrays.cpp:38:24:38:27 | data indirection | | arrays.cpp:38:10:38:15 | nested indirection [arr, data] | arrays.cpp:38:8:38:22 | access to array indirection [data] | -| arrays.cpp:38:24:38:27 | data indirection | arrays.cpp:38:24:38:27 | data | | arrays.cpp:42:3:42:40 | ... = ... | arrays.cpp:42:22:42:25 | access to array indirection [post update] [data] | | arrays.cpp:42:5:42:12 | o indirection [post update] [indirect indirection, arr, data] | arrays.cpp:43:8:43:8 | o indirection [indirect indirection, arr, data] | | arrays.cpp:42:5:42:12 | o indirection [post update] [indirect indirection, arr, data] | arrays.cpp:44:8:44:8 | o indirection [indirect indirection, arr, data] | @@ -395,19 +323,13 @@ edges | arrays.cpp:42:22:42:25 | access to array indirection [post update] [data] | arrays.cpp:42:15:42:17 | indirect indirection [post update] [arr, data] | | arrays.cpp:42:29:42:38 | call to user_input | arrays.cpp:42:3:42:40 | ... = ... | | arrays.cpp:43:8:43:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | -| arrays.cpp:43:8:43:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | | arrays.cpp:43:8:43:25 | access to array indirection [data] | arrays.cpp:43:27:43:30 | data | -| arrays.cpp:43:8:43:25 | access to array indirection [data] | arrays.cpp:43:27:43:30 | data indirection | | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | arrays.cpp:43:8:43:25 | access to array indirection [data] | | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | -| arrays.cpp:43:27:43:30 | data indirection | arrays.cpp:43:27:43:30 | data | -| arrays.cpp:44:8:44:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | | arrays.cpp:44:8:44:8 | o indirection [indirect indirection, arr, data] | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | | arrays.cpp:44:8:44:25 | access to array indirection [data] | arrays.cpp:44:27:44:30 | data | -| arrays.cpp:44:8:44:25 | access to array indirection [data] | arrays.cpp:44:27:44:30 | data indirection | | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | arrays.cpp:44:8:44:25 | access to array indirection [data] | | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | -| arrays.cpp:44:27:44:30 | data indirection | arrays.cpp:44:27:44:30 | data | | arrays.cpp:48:3:48:40 | ... = ... | arrays.cpp:48:22:48:25 | access to array indirection [post update] [data] | | arrays.cpp:48:5:48:12 | o indirection [post update] [indirect indirection, ptr indirection, data] | arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] | | arrays.cpp:48:5:48:12 | o indirection [post update] [indirect indirection, ptr indirection, data] | arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] | @@ -415,23 +337,17 @@ edges | arrays.cpp:48:22:48:25 | access to array indirection [post update] [data] | arrays.cpp:48:15:48:17 | indirect indirection [post update] [ptr indirection, data] | | arrays.cpp:48:29:48:38 | call to user_input | arrays.cpp:48:3:48:40 | ... = ... | | arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | -| arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | | arrays.cpp:49:8:49:25 | access to array indirection [data] | arrays.cpp:49:27:49:30 | data | -| arrays.cpp:49:8:49:25 | access to array indirection [data] | arrays.cpp:49:27:49:30 | data indirection | | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:8:49:25 | access to array indirection [data] | | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | arrays.cpp:49:20:49:22 | ptr indirection [data] | | arrays.cpp:49:20:49:22 | ptr indirection [data] | arrays.cpp:49:8:49:25 | access to array indirection [data] | -| arrays.cpp:49:27:49:30 | data indirection | arrays.cpp:49:27:49:30 | data | -| arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | | arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | | arrays.cpp:50:8:50:25 | access to array indirection [data] | arrays.cpp:50:27:50:30 | data | -| arrays.cpp:50:8:50:25 | access to array indirection [data] | arrays.cpp:50:27:50:30 | data indirection | | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:8:50:25 | access to array indirection [data] | | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | arrays.cpp:50:20:50:22 | ptr indirection [data] | | arrays.cpp:50:20:50:22 | ptr indirection [data] | arrays.cpp:50:8:50:25 | access to array indirection [data] | -| arrays.cpp:50:27:50:30 | data indirection | arrays.cpp:50:27:50:30 | data | | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | ... = ... | | by_reference.cpp:12:5:12:16 | ... = ... | by_reference.cpp:12:8:12:8 | s indirection [post update] [a] | | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:19 | ... = ... | @@ -444,14 +360,10 @@ edges | by_reference.cpp:24:25:24:29 | value | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] | | by_reference.cpp:31:46:31:46 | s indirection [a] | by_reference.cpp:32:12:32:12 | s indirection [a] | | by_reference.cpp:32:12:32:12 | s indirection [a] | by_reference.cpp:32:15:32:15 | a | -| by_reference.cpp:32:12:32:12 | s indirection [a] | by_reference.cpp:32:15:32:15 | a indirection | | by_reference.cpp:32:15:32:15 | a | by_reference.cpp:31:16:31:28 | nonMemberGetA indirection | -| by_reference.cpp:32:15:32:15 | a indirection | by_reference.cpp:31:16:31:28 | nonMemberGetA indirection | | by_reference.cpp:35:9:35:19 | this indirection [a] | by_reference.cpp:36:12:36:15 | this indirection [a] | | by_reference.cpp:36:12:36:15 | this indirection [a] | by_reference.cpp:36:18:36:18 | a | -| by_reference.cpp:36:12:36:15 | this indirection [a] | by_reference.cpp:36:18:36:18 | a indirection | | by_reference.cpp:36:18:36:18 | a | by_reference.cpp:35:9:35:19 | getDirectly indirection | -| by_reference.cpp:36:18:36:18 | a indirection | by_reference.cpp:35:9:35:19 | getDirectly indirection | | by_reference.cpp:39:9:39:21 | this indirection [a] | by_reference.cpp:40:12:40:15 | this indirection [a] | | by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:35:9:35:19 | this indirection [a] | | by_reference.cpp:40:12:40:15 | this indirection [a] | by_reference.cpp:40:18:40:28 | call to getDirectly | @@ -512,30 +424,16 @@ edges | by_reference.cpp:108:24:108:24 | pouter indirection [post update] [a] | by_reference.cpp:116:8:116:13 | pouter indirection [a] | | by_reference.cpp:110:8:110:12 | outer indirection [inner_nested, a] | by_reference.cpp:110:14:110:25 | inner_nested indirection [a] | | by_reference.cpp:110:14:110:25 | inner_nested indirection [a] | by_reference.cpp:110:27:110:27 | a | -| by_reference.cpp:110:14:110:25 | inner_nested indirection [a] | by_reference.cpp:110:27:110:27 | a indirection | -| by_reference.cpp:110:27:110:27 | a indirection | by_reference.cpp:110:27:110:27 | a | -| by_reference.cpp:111:8:111:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | | by_reference.cpp:111:8:111:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | by_reference.cpp:111:25:111:25 | a | -| by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | by_reference.cpp:111:25:111:25 | a indirection | -| by_reference.cpp:111:25:111:25 | a indirection | by_reference.cpp:111:25:111:25 | a | | by_reference.cpp:112:8:112:12 | outer indirection [a] | by_reference.cpp:112:14:112:14 | a | -| by_reference.cpp:112:8:112:12 | outer indirection [a] | by_reference.cpp:112:14:112:14 | a indirection | -| by_reference.cpp:112:14:112:14 | a indirection | by_reference.cpp:112:14:112:14 | a | | by_reference.cpp:114:8:114:13 | pouter indirection [inner_nested, a] | by_reference.cpp:114:16:114:27 | inner_nested indirection [a] | | by_reference.cpp:114:16:114:27 | inner_nested indirection [a] | by_reference.cpp:114:29:114:29 | a | -| by_reference.cpp:114:16:114:27 | inner_nested indirection [a] | by_reference.cpp:114:29:114:29 | a indirection | -| by_reference.cpp:114:29:114:29 | a indirection | by_reference.cpp:114:29:114:29 | a | -| by_reference.cpp:115:8:115:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | | by_reference.cpp:115:8:115:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | by_reference.cpp:115:27:115:27 | a | -| by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | by_reference.cpp:115:27:115:27 | a indirection | -| by_reference.cpp:115:27:115:27 | a indirection | by_reference.cpp:115:27:115:27 | a | | by_reference.cpp:116:8:116:13 | pouter indirection [a] | by_reference.cpp:116:16:116:16 | a | -| by_reference.cpp:116:8:116:13 | pouter indirection [a] | by_reference.cpp:116:16:116:16 | a indirection | -| by_reference.cpp:116:16:116:16 | a indirection | by_reference.cpp:116:16:116:16 | a | | by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | by_reference.cpp:122:27:122:38 | outer indirection [post update] [inner_nested, a] | | by_reference.cpp:122:27:122:38 | outer indirection [post update] [inner_nested, a] | by_reference.cpp:130:8:130:12 | outer indirection [inner_nested, a] | | by_reference.cpp:123:21:123:36 | taint_inner_a_ref output argument [a] | by_reference.cpp:123:28:123:36 | outer indirection [post update] [inner_ptr indirection, a] | @@ -550,39 +448,21 @@ edges | by_reference.cpp:128:23:128:23 | pouter indirection [post update] [a] | by_reference.cpp:136:8:136:13 | pouter indirection [a] | | by_reference.cpp:130:8:130:12 | outer indirection [inner_nested, a] | by_reference.cpp:130:14:130:25 | inner_nested indirection [a] | | by_reference.cpp:130:14:130:25 | inner_nested indirection [a] | by_reference.cpp:130:27:130:27 | a | -| by_reference.cpp:130:14:130:25 | inner_nested indirection [a] | by_reference.cpp:130:27:130:27 | a indirection | -| by_reference.cpp:130:27:130:27 | a indirection | by_reference.cpp:130:27:130:27 | a | -| by_reference.cpp:131:8:131:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | | by_reference.cpp:131:8:131:12 | outer indirection [inner_ptr indirection, a] | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | by_reference.cpp:131:25:131:25 | a | -| by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | by_reference.cpp:131:25:131:25 | a indirection | -| by_reference.cpp:131:25:131:25 | a indirection | by_reference.cpp:131:25:131:25 | a | | by_reference.cpp:132:8:132:12 | outer indirection [a] | by_reference.cpp:132:14:132:14 | a | -| by_reference.cpp:132:8:132:12 | outer indirection [a] | by_reference.cpp:132:14:132:14 | a indirection | -| by_reference.cpp:132:14:132:14 | a indirection | by_reference.cpp:132:14:132:14 | a | | by_reference.cpp:134:8:134:13 | pouter indirection [inner_nested, a] | by_reference.cpp:134:16:134:27 | inner_nested indirection [a] | | by_reference.cpp:134:16:134:27 | inner_nested indirection [a] | by_reference.cpp:134:29:134:29 | a | -| by_reference.cpp:134:16:134:27 | inner_nested indirection [a] | by_reference.cpp:134:29:134:29 | a indirection | -| by_reference.cpp:134:29:134:29 | a indirection | by_reference.cpp:134:29:134:29 | a | -| by_reference.cpp:135:8:135:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | | by_reference.cpp:135:8:135:13 | pouter indirection [inner_ptr indirection, a] | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | by_reference.cpp:135:27:135:27 | a | -| by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | by_reference.cpp:135:27:135:27 | a indirection | -| by_reference.cpp:135:27:135:27 | a indirection | by_reference.cpp:135:27:135:27 | a | | by_reference.cpp:136:8:136:13 | pouter indirection [a] | by_reference.cpp:136:16:136:16 | a | -| by_reference.cpp:136:8:136:13 | pouter indirection [a] | by_reference.cpp:136:16:136:16 | a indirection | -| by_reference.cpp:136:16:136:16 | a indirection | by_reference.cpp:136:16:136:16 | a | | clearning.cpp:32:3:32:25 | ... = ... | clearning.cpp:32:6:32:6 | s indirection [post update] [x indirection] | | clearning.cpp:32:6:32:6 | s indirection [post update] [x indirection] | clearning.cpp:33:5:33:5 | s indirection [x indirection] | | clearning.cpp:32:10:32:19 | call to user_input | clearning.cpp:32:3:32:25 | ... = ... | | clearning.cpp:33:5:33:5 | s indirection [x indirection] | clearning.cpp:34:9:34:9 | s indirection [x indirection] | | clearning.cpp:34:9:34:9 | s indirection [x indirection] | clearning.cpp:34:8:34:11 | * ... | -| clearning.cpp:34:9:34:9 | s indirection [x indirection] | clearning.cpp:34:11:34:11 | x indirection | -| clearning.cpp:34:9:34:9 | s indirection [x indirection] | clearning.cpp:34:11:34:11 | x indirection | -| clearning.cpp:34:11:34:11 | x indirection | clearning.cpp:34:8:34:11 | * ... | -| clearning.cpp:34:11:34:11 | x indirection | clearning.cpp:34:8:34:11 | * ... | | clearning.cpp:53:3:53:25 | ... = ... | clearning.cpp:53:6:53:6 | s indirection [post update] [x indirection] | | clearning.cpp:53:6:53:6 | s indirection [post update] [x indirection] | clearning.cpp:54:3:54:3 | s indirection [x indirection] | | clearning.cpp:53:10:53:19 | call to user_input | clearning.cpp:53:3:53:25 | ... = ... | @@ -596,6 +476,7 @@ edges | clearning.cpp:55:8:55:8 | s indirection [x indirection] | clearning.cpp:55:10:55:10 | x indirection | | clearning.cpp:55:8:55:8 | s indirection [x indirection] | clearning.cpp:55:10:55:10 | x indirection | | clearning.cpp:55:10:55:10 | x indirection | clearning.cpp:55:10:55:10 | x indirection | +| clearning.cpp:55:10:55:10 | x indirection | clearning.cpp:55:10:55:10 | x indirection | | clearning.cpp:60:3:60:22 | ... = ... | clearning.cpp:60:7:60:7 | s indirection [post update] [x indirection] | | clearning.cpp:60:7:60:7 | s indirection [post update] [x indirection] | clearning.cpp:61:3:61:3 | s indirection [x indirection] | | clearning.cpp:60:11:60:20 | call to user_input | clearning.cpp:60:3:60:22 | ... = ... | @@ -609,13 +490,10 @@ edges | clearning.cpp:62:8:62:8 | s indirection [x indirection] | clearning.cpp:62:10:62:10 | x indirection | | clearning.cpp:62:8:62:8 | s indirection [x indirection] | clearning.cpp:62:10:62:10 | x indirection | | clearning.cpp:62:10:62:10 | x indirection | clearning.cpp:62:10:62:10 | x indirection | +| clearning.cpp:62:10:62:10 | x indirection | clearning.cpp:62:10:62:10 | x indirection | | clearning.cpp:74:20:74:22 | argument_source output argument | clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] | | clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] | clearning.cpp:76:8:76:8 | s indirection [val indirection] | | clearning.cpp:76:8:76:8 | s indirection [val indirection] | clearning.cpp:76:7:76:12 | * ... | -| clearning.cpp:76:8:76:8 | s indirection [val indirection] | clearning.cpp:76:10:76:12 | val indirection | -| clearning.cpp:76:8:76:8 | s indirection [val indirection] | clearning.cpp:76:10:76:12 | val indirection | -| clearning.cpp:76:10:76:12 | val indirection | clearning.cpp:76:7:76:12 | * ... | -| clearning.cpp:76:10:76:12 | val indirection | clearning.cpp:76:7:76:12 | * ... | | clearning.cpp:81:20:81:22 | argument_source output argument | clearning.cpp:81:20:81:22 | s indirection [post update] [val indirection] | | clearning.cpp:81:20:81:22 | s indirection [post update] [val indirection] | clearning.cpp:83:13:83:13 | s indirection [val indirection] | | clearning.cpp:83:5:83:21 | ... = ... indirection | clearning.cpp:83:7:83:9 | s indirection [post update] [val indirection] | @@ -625,10 +503,6 @@ edges | clearning.cpp:83:13:83:21 | ... + ... indirection | clearning.cpp:83:5:83:21 | ... = ... indirection | | clearning.cpp:83:15:83:17 | val indirection | clearning.cpp:83:5:83:21 | ... = ... indirection | | clearning.cpp:84:8:84:8 | s indirection [val indirection] | clearning.cpp:84:7:84:12 | * ... | -| clearning.cpp:84:8:84:8 | s indirection [val indirection] | clearning.cpp:84:10:84:12 | val indirection | -| clearning.cpp:84:8:84:8 | s indirection [val indirection] | clearning.cpp:84:10:84:12 | val indirection | -| clearning.cpp:84:10:84:12 | val indirection | clearning.cpp:84:7:84:12 | * ... | -| clearning.cpp:84:10:84:12 | val indirection | clearning.cpp:84:7:84:12 | * ... | | clearning.cpp:89:20:89:22 | argument_source output argument | clearning.cpp:89:20:89:22 | s indirection [post update] [val indirection] | | clearning.cpp:89:20:89:22 | s indirection [post update] [val indirection] | clearning.cpp:90:3:90:3 | s indirection [val indirection] | | clearning.cpp:90:3:90:3 | s indirection [val indirection] | clearning.cpp:90:3:90:9 | ... ++ indirection | @@ -639,10 +513,6 @@ edges | clearning.cpp:90:5:90:7 | s indirection [post update] [val indirection] | clearning.cpp:91:8:91:8 | s indirection [val indirection] | | clearning.cpp:90:5:90:7 | val indirection | clearning.cpp:90:3:90:9 | ... ++ indirection | | clearning.cpp:91:8:91:8 | s indirection [val indirection] | clearning.cpp:91:7:91:12 | * ... | -| clearning.cpp:91:8:91:8 | s indirection [val indirection] | clearning.cpp:91:10:91:12 | val indirection | -| clearning.cpp:91:8:91:8 | s indirection [val indirection] | clearning.cpp:91:10:91:12 | val indirection | -| clearning.cpp:91:10:91:12 | val indirection | clearning.cpp:91:7:91:12 | * ... | -| clearning.cpp:91:10:91:12 | val indirection | clearning.cpp:91:7:91:12 | * ... | | clearning.cpp:96:20:96:22 | argument_source output argument | clearning.cpp:96:20:96:22 | s indirection [post update] [val indirection] | | clearning.cpp:96:20:96:22 | s indirection [post update] [val indirection] | clearning.cpp:97:10:97:10 | s indirection [val indirection] | | clearning.cpp:97:2:97:18 | ... = ... indirection | clearning.cpp:97:4:97:6 | s indirection [post update] [val indirection] | @@ -652,10 +522,6 @@ edges | clearning.cpp:97:10:97:18 | ... + ... indirection | clearning.cpp:97:2:97:18 | ... = ... indirection | | clearning.cpp:97:12:97:14 | val indirection | clearning.cpp:97:2:97:18 | ... = ... indirection | | clearning.cpp:98:8:98:8 | s indirection [val indirection] | clearning.cpp:98:7:98:12 | * ... | -| clearning.cpp:98:8:98:8 | s indirection [val indirection] | clearning.cpp:98:10:98:12 | val indirection | -| clearning.cpp:98:8:98:8 | s indirection [val indirection] | clearning.cpp:98:10:98:12 | val indirection | -| clearning.cpp:98:10:98:12 | val indirection | clearning.cpp:98:7:98:12 | * ... | -| clearning.cpp:98:10:98:12 | val indirection | clearning.cpp:98:7:98:12 | * ... | | clearning.cpp:103:20:103:22 | argument_source output argument | clearning.cpp:103:20:103:22 | s indirection [post update] [val indirection] | | clearning.cpp:103:20:103:22 | s indirection [post update] [val indirection] | clearning.cpp:104:2:104:2 | s indirection [val indirection] | | clearning.cpp:104:2:104:2 | s indirection [val indirection] | clearning.cpp:104:2:104:8 | ... ++ indirection | @@ -666,10 +532,6 @@ edges | clearning.cpp:104:4:104:6 | s indirection [post update] [val indirection] | clearning.cpp:105:8:105:8 | s indirection [val indirection] | | clearning.cpp:104:4:104:6 | val indirection | clearning.cpp:104:2:104:8 | ... ++ indirection | | clearning.cpp:105:8:105:8 | s indirection [val indirection] | clearning.cpp:105:7:105:12 | * ... | -| clearning.cpp:105:8:105:8 | s indirection [val indirection] | clearning.cpp:105:10:105:12 | val indirection | -| clearning.cpp:105:8:105:8 | s indirection [val indirection] | clearning.cpp:105:10:105:12 | val indirection | -| clearning.cpp:105:10:105:12 | val indirection | clearning.cpp:105:7:105:12 | * ... | -| clearning.cpp:105:10:105:12 | val indirection | clearning.cpp:105:7:105:12 | * ... | | clearning.cpp:110:20:110:22 | argument_source output argument | clearning.cpp:110:20:110:22 | s indirection [post update] [val indirection] | | clearning.cpp:110:20:110:22 | s indirection [post update] [val indirection] | clearning.cpp:111:4:111:4 | s indirection [val indirection] | | clearning.cpp:111:2:111:8 | ++ ... indirection | clearning.cpp:111:2:111:8 | ++ ... indirection | @@ -680,10 +542,6 @@ edges | clearning.cpp:111:6:111:8 | s indirection [post update] [val indirection] | clearning.cpp:112:8:112:8 | s indirection [val indirection] | | clearning.cpp:111:6:111:8 | val indirection | clearning.cpp:111:2:111:8 | ++ ... indirection | | clearning.cpp:112:8:112:8 | s indirection [val indirection] | clearning.cpp:112:7:112:12 | * ... | -| clearning.cpp:112:8:112:8 | s indirection [val indirection] | clearning.cpp:112:10:112:12 | val indirection | -| clearning.cpp:112:8:112:8 | s indirection [val indirection] | clearning.cpp:112:10:112:12 | val indirection | -| clearning.cpp:112:10:112:12 | val indirection | clearning.cpp:112:7:112:12 | * ... | -| clearning.cpp:112:10:112:12 | val indirection | clearning.cpp:112:7:112:12 | * ... | | clearning.cpp:117:20:117:22 | argument_source output argument | clearning.cpp:117:20:117:22 | s indirection [post update] [val indirection] | | clearning.cpp:117:20:117:22 | s indirection [post update] [val indirection] | clearning.cpp:118:2:118:2 | s indirection [val indirection] | | clearning.cpp:118:2:118:2 | s indirection [val indirection] | clearning.cpp:118:2:118:11 | ... += ... indirection | @@ -694,26 +552,16 @@ edges | clearning.cpp:118:4:118:6 | s indirection [post update] [val indirection] | clearning.cpp:119:8:119:8 | s indirection [val indirection] | | clearning.cpp:118:4:118:6 | val indirection | clearning.cpp:118:2:118:11 | ... += ... indirection | | clearning.cpp:119:8:119:8 | s indirection [val indirection] | clearning.cpp:119:7:119:12 | * ... | -| clearning.cpp:119:8:119:8 | s indirection [val indirection] | clearning.cpp:119:10:119:12 | val indirection | -| clearning.cpp:119:8:119:8 | s indirection [val indirection] | clearning.cpp:119:10:119:12 | val indirection | -| clearning.cpp:119:10:119:12 | val indirection | clearning.cpp:119:7:119:12 | * ... | -| clearning.cpp:119:10:119:12 | val indirection | clearning.cpp:119:7:119:12 | * ... | | clearning.cpp:151:3:151:22 | ... = ... | clearning.cpp:151:5:151:7 | s indirection [post update] [val] | | clearning.cpp:151:5:151:7 | s indirection [post update] [val] | clearning.cpp:152:8:152:8 | s indirection [val] | | clearning.cpp:151:11:151:20 | call to user_input | clearning.cpp:151:3:151:22 | ... = ... | | clearning.cpp:152:8:152:8 | s indirection [val] | clearning.cpp:152:10:152:12 | val | -| clearning.cpp:152:8:152:8 | s indirection [val] | clearning.cpp:152:10:152:12 | val indirection | -| clearning.cpp:152:10:152:12 | val indirection | clearning.cpp:152:10:152:12 | val | | complex.cpp:9:7:9:7 | this indirection [a_] | complex.cpp:9:20:9:21 | this indirection [a_] | | complex.cpp:9:20:9:21 | a_ | complex.cpp:9:7:9:7 | a indirection | -| complex.cpp:9:20:9:21 | a_ indirection | complex.cpp:9:7:9:7 | a indirection | | complex.cpp:9:20:9:21 | this indirection [a_] | complex.cpp:9:20:9:21 | a_ | -| complex.cpp:9:20:9:21 | this indirection [a_] | complex.cpp:9:20:9:21 | a_ indirection | | complex.cpp:10:7:10:7 | this indirection [b_] | complex.cpp:10:20:10:21 | this indirection [b_] | | complex.cpp:10:20:10:21 | b_ | complex.cpp:10:7:10:7 | b indirection | -| complex.cpp:10:20:10:21 | b_ indirection | complex.cpp:10:7:10:7 | b indirection | | complex.cpp:10:20:10:21 | this indirection [b_] | complex.cpp:10:20:10:21 | b_ | -| complex.cpp:10:20:10:21 | this indirection [b_] | complex.cpp:10:20:10:21 | b_ indirection | | complex.cpp:11:17:11:17 | a | complex.cpp:11:22:11:27 | ... = ... | | complex.cpp:11:22:11:27 | ... = ... | complex.cpp:11:22:11:23 | this indirection [post update] [a_] | | complex.cpp:12:17:12:17 | b | complex.cpp:12:22:12:27 | ... = ... | @@ -772,55 +620,36 @@ edges | conflated.cpp:10:7:10:7 | ra indirection [post update] [p indirection] | conflated.cpp:11:9:11:10 | ra indirection [p indirection] | | conflated.cpp:10:11:10:20 | call to user_input | conflated.cpp:10:3:10:22 | ... = ... | | conflated.cpp:11:9:11:10 | ra indirection [p indirection] | conflated.cpp:11:8:11:12 | * ... | -| conflated.cpp:11:9:11:10 | ra indirection [p indirection] | conflated.cpp:11:12:11:12 | p indirection | -| conflated.cpp:11:9:11:10 | ra indirection [p indirection] | conflated.cpp:11:12:11:12 | p indirection | -| conflated.cpp:11:12:11:12 | p indirection | conflated.cpp:11:8:11:12 | * ... | -| conflated.cpp:11:12:11:12 | p indirection | conflated.cpp:11:8:11:12 | * ... | -| conflated.cpp:19:19:19:21 | argument_source output argument | conflated.cpp:20:8:20:10 | raw indirection | | conflated.cpp:19:19:19:21 | argument_source output argument | conflated.cpp:20:8:20:10 | raw indirection | | conflated.cpp:19:19:19:21 | argument_source output argument | conflated.cpp:20:8:20:10 | raw indirection | | conflated.cpp:29:3:29:22 | ... = ... | conflated.cpp:29:7:29:7 | pa indirection [post update] [x] | | conflated.cpp:29:7:29:7 | pa indirection [post update] [x] | conflated.cpp:30:8:30:9 | pa indirection [x] | | conflated.cpp:29:11:29:20 | call to user_input | conflated.cpp:29:3:29:22 | ... = ... | | conflated.cpp:30:8:30:9 | pa indirection [x] | conflated.cpp:30:12:30:12 | x | -| conflated.cpp:30:8:30:9 | pa indirection [x] | conflated.cpp:30:12:30:12 | x indirection | -| conflated.cpp:30:12:30:12 | x indirection | conflated.cpp:30:12:30:12 | x | | conflated.cpp:36:3:36:22 | ... = ... | conflated.cpp:36:7:36:7 | pa indirection [post update] [x] | | conflated.cpp:36:7:36:7 | pa indirection [post update] [x] | conflated.cpp:37:8:37:9 | pa indirection [x] | | conflated.cpp:36:11:36:20 | call to user_input | conflated.cpp:36:3:36:22 | ... = ... | | conflated.cpp:37:8:37:9 | pa indirection [x] | conflated.cpp:37:12:37:12 | x | -| conflated.cpp:37:8:37:9 | pa indirection [x] | conflated.cpp:37:12:37:12 | x indirection | -| conflated.cpp:37:12:37:12 | x indirection | conflated.cpp:37:12:37:12 | x | | conflated.cpp:54:3:54:28 | ... = ... | conflated.cpp:54:13:54:13 | next indirection [post update] [y] | | conflated.cpp:54:7:54:10 | ll indirection [post update] [next indirection, y] | conflated.cpp:55:8:55:9 | ll indirection [next indirection, y] | | conflated.cpp:54:13:54:13 | next indirection [post update] [y] | conflated.cpp:54:7:54:10 | ll indirection [post update] [next indirection, y] | | conflated.cpp:54:17:54:26 | call to user_input | conflated.cpp:54:3:54:28 | ... = ... | | conflated.cpp:55:8:55:9 | ll indirection [next indirection, y] | conflated.cpp:55:12:55:15 | next indirection [y] | -| conflated.cpp:55:8:55:9 | ll indirection [next indirection, y] | conflated.cpp:55:12:55:15 | next indirection [y] | | conflated.cpp:55:12:55:15 | next indirection [y] | conflated.cpp:55:12:55:15 | next indirection [y] | | conflated.cpp:55:12:55:15 | next indirection [y] | conflated.cpp:55:18:55:18 | y | -| conflated.cpp:55:12:55:15 | next indirection [y] | conflated.cpp:55:18:55:18 | y indirection | -| conflated.cpp:55:18:55:18 | y indirection | conflated.cpp:55:18:55:18 | y | | conflated.cpp:60:3:60:28 | ... = ... | conflated.cpp:60:13:60:13 | next indirection [post update] [y] | | conflated.cpp:60:7:60:10 | ll indirection [post update] [next indirection, y] | conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] | | conflated.cpp:60:13:60:13 | next indirection [post update] [y] | conflated.cpp:60:7:60:10 | ll indirection [post update] [next indirection, y] | | conflated.cpp:60:17:60:26 | call to user_input | conflated.cpp:60:3:60:28 | ... = ... | | conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] | conflated.cpp:61:12:61:15 | next indirection [y] | -| conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] | conflated.cpp:61:12:61:15 | next indirection [y] | | conflated.cpp:61:12:61:15 | next indirection [y] | conflated.cpp:61:12:61:15 | next indirection [y] | | conflated.cpp:61:12:61:15 | next indirection [y] | conflated.cpp:61:18:61:18 | y | -| conflated.cpp:61:12:61:15 | next indirection [y] | conflated.cpp:61:18:61:18 | y indirection | -| conflated.cpp:61:18:61:18 | y indirection | conflated.cpp:61:18:61:18 | y | | constructors.cpp:18:9:18:9 | this indirection [a_] | constructors.cpp:18:22:18:23 | this indirection [a_] | | constructors.cpp:18:22:18:23 | a_ | constructors.cpp:18:9:18:9 | a indirection | -| constructors.cpp:18:22:18:23 | a_ indirection | constructors.cpp:18:9:18:9 | a indirection | | constructors.cpp:18:22:18:23 | this indirection [a_] | constructors.cpp:18:22:18:23 | a_ | -| constructors.cpp:18:22:18:23 | this indirection [a_] | constructors.cpp:18:22:18:23 | a_ indirection | | constructors.cpp:19:9:19:9 | this indirection [b_] | constructors.cpp:19:22:19:23 | this indirection [b_] | | constructors.cpp:19:22:19:23 | b_ | constructors.cpp:19:9:19:9 | b indirection | -| constructors.cpp:19:22:19:23 | b_ indirection | constructors.cpp:19:9:19:9 | b indirection | | constructors.cpp:19:22:19:23 | this indirection [b_] | constructors.cpp:19:22:19:23 | b_ | -| constructors.cpp:19:22:19:23 | this indirection [b_] | constructors.cpp:19:22:19:23 | b_ indirection | | constructors.cpp:23:13:23:13 | a | constructors.cpp:23:28:23:28 | a | | constructors.cpp:23:20:23:20 | b | constructors.cpp:23:35:23:35 | b | | constructors.cpp:23:28:23:28 | a | constructors.cpp:23:25:23:29 | this indirection [post update] [a_] | @@ -858,61 +687,43 @@ edges | qualifiers.cpp:22:23:22:23 | call to getInner indirection [post update] [a] | qualifiers.cpp:22:5:22:9 | getInner output argument [inner indirection, a] | | qualifiers.cpp:22:27:22:36 | call to user_input | qualifiers.cpp:22:5:22:38 | ... = ... | | qualifiers.cpp:23:10:23:14 | outer indirection [inner indirection, a] | qualifiers.cpp:23:16:23:20 | inner indirection [a] | -| qualifiers.cpp:23:10:23:14 | outer indirection [inner indirection, a] | qualifiers.cpp:23:16:23:20 | inner indirection [a] | | qualifiers.cpp:23:16:23:20 | inner indirection [a] | qualifiers.cpp:23:16:23:20 | inner indirection [a] | | qualifiers.cpp:23:16:23:20 | inner indirection [a] | qualifiers.cpp:23:23:23:23 | a | -| qualifiers.cpp:23:16:23:20 | inner indirection [a] | qualifiers.cpp:23:23:23:23 | a indirection | -| qualifiers.cpp:23:23:23:23 | a indirection | qualifiers.cpp:23:23:23:23 | a | | qualifiers.cpp:27:5:27:9 | getInner output argument [inner indirection, a] | qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] | | qualifiers.cpp:27:11:27:18 | setA output argument [a] | qualifiers.cpp:27:5:27:9 | getInner output argument [inner indirection, a] | | qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value | | qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:27:11:27:18 | setA output argument [a] | | qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] | qualifiers.cpp:28:16:28:20 | inner indirection [a] | -| qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] | qualifiers.cpp:28:16:28:20 | inner indirection [a] | | qualifiers.cpp:28:16:28:20 | inner indirection [a] | qualifiers.cpp:28:16:28:20 | inner indirection [a] | | qualifiers.cpp:28:16:28:20 | inner indirection [a] | qualifiers.cpp:28:23:28:23 | a | -| qualifiers.cpp:28:16:28:20 | inner indirection [a] | qualifiers.cpp:28:23:28:23 | a indirection | -| qualifiers.cpp:28:23:28:23 | a indirection | qualifiers.cpp:28:23:28:23 | a | | qualifiers.cpp:32:17:32:21 | getInner output argument [inner indirection, a] | qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] | | qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] | qualifiers.cpp:32:17:32:21 | getInner output argument [inner indirection, a] | | qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value | | qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] | | qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] | qualifiers.cpp:33:16:33:20 | inner indirection [a] | -| qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] | qualifiers.cpp:33:16:33:20 | inner indirection [a] | | qualifiers.cpp:33:16:33:20 | inner indirection [a] | qualifiers.cpp:33:16:33:20 | inner indirection [a] | | qualifiers.cpp:33:16:33:20 | inner indirection [a] | qualifiers.cpp:33:23:33:23 | a | -| qualifiers.cpp:33:16:33:20 | inner indirection [a] | qualifiers.cpp:33:23:33:23 | a indirection | -| qualifiers.cpp:33:23:33:23 | a indirection | qualifiers.cpp:33:23:33:23 | a | | qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] | qualifiers.cpp:37:20:37:24 | getInner output argument [inner indirection, a] | | qualifiers.cpp:37:20:37:24 | getInner output argument [inner indirection, a] | qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] | | qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value | | qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] | | qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] | qualifiers.cpp:38:16:38:20 | inner indirection [a] | -| qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] | qualifiers.cpp:38:16:38:20 | inner indirection [a] | | qualifiers.cpp:38:16:38:20 | inner indirection [a] | qualifiers.cpp:38:16:38:20 | inner indirection [a] | | qualifiers.cpp:38:16:38:20 | inner indirection [a] | qualifiers.cpp:38:23:38:23 | a | -| qualifiers.cpp:38:16:38:20 | inner indirection [a] | qualifiers.cpp:38:23:38:23 | a indirection | -| qualifiers.cpp:38:23:38:23 | a indirection | qualifiers.cpp:38:23:38:23 | a | | qualifiers.cpp:42:5:42:40 | ... = ... | qualifiers.cpp:42:25:42:25 | * ... indirection [post update] [a] | | qualifiers.cpp:42:7:42:11 | getInner output argument [inner indirection, a] | qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] | | qualifiers.cpp:42:25:42:25 | * ... indirection [post update] [a] | qualifiers.cpp:42:7:42:11 | getInner output argument [inner indirection, a] | | qualifiers.cpp:42:29:42:38 | call to user_input | qualifiers.cpp:42:5:42:40 | ... = ... | | qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] | qualifiers.cpp:43:16:43:20 | inner indirection [a] | -| qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] | qualifiers.cpp:43:16:43:20 | inner indirection [a] | | qualifiers.cpp:43:16:43:20 | inner indirection [a] | qualifiers.cpp:43:16:43:20 | inner indirection [a] | | qualifiers.cpp:43:16:43:20 | inner indirection [a] | qualifiers.cpp:43:23:43:23 | a | -| qualifiers.cpp:43:16:43:20 | inner indirection [a] | qualifiers.cpp:43:23:43:23 | a indirection | -| qualifiers.cpp:43:23:43:23 | a indirection | qualifiers.cpp:43:23:43:23 | a | | qualifiers.cpp:47:5:47:42 | ... = ... | qualifiers.cpp:47:27:47:27 | call to getInner indirection [post update] [a] | | qualifiers.cpp:47:6:47:11 | getInner output argument [inner indirection, a] | qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] | | qualifiers.cpp:47:27:47:27 | call to getInner indirection [post update] [a] | qualifiers.cpp:47:6:47:11 | getInner output argument [inner indirection, a] | | qualifiers.cpp:47:31:47:40 | call to user_input | qualifiers.cpp:47:5:47:42 | ... = ... | | qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] | qualifiers.cpp:48:16:48:20 | inner indirection [a] | -| qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] | qualifiers.cpp:48:16:48:20 | inner indirection [a] | | qualifiers.cpp:48:16:48:20 | inner indirection [a] | qualifiers.cpp:48:16:48:20 | inner indirection [a] | | qualifiers.cpp:48:16:48:20 | inner indirection [a] | qualifiers.cpp:48:23:48:23 | a | -| qualifiers.cpp:48:16:48:20 | inner indirection [a] | qualifiers.cpp:48:23:48:23 | a indirection | -| qualifiers.cpp:48:23:48:23 | a indirection | qualifiers.cpp:48:23:48:23 | a | | realistic.cpp:53:9:53:66 | ... = ... | realistic.cpp:53:35:53:43 | userInput indirection [post update] [bufferLen] | | realistic.cpp:53:13:53:15 | foo indirection [post update] [bar, baz indirection, userInput, bufferLen] | realistic.cpp:61:21:61:23 | foo indirection [bar, baz indirection, userInput, bufferLen] | | realistic.cpp:53:20:53:22 | access to array indirection [post update] [baz indirection, userInput, bufferLen] | realistic.cpp:53:13:53:15 | foo indirection [post update] [bar, baz indirection, userInput, bufferLen] | @@ -922,23 +733,16 @@ edges | realistic.cpp:53:55:53:64 | call to user_input | realistic.cpp:53:9:53:66 | ... = ... | | realistic.cpp:61:21:61:23 | foo indirection [bar, baz indirection, userInput, bufferLen] | realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] | | realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | -| realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] | | realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] | realistic.cpp:61:14:61:55 | bufferLen | -| realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] | realistic.cpp:61:47:61:55 | bufferLen indirection | -| realistic.cpp:61:47:61:55 | bufferLen indirection | realistic.cpp:61:14:61:55 | bufferLen | -| realistic.cpp:61:47:61:55 | bufferLen indirection | realistic.cpp:61:47:61:55 | bufferLen | +| realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] | realistic.cpp:61:47:61:55 | bufferLen | | simple.cpp:18:9:18:9 | this indirection [a_] | simple.cpp:18:22:18:23 | this indirection [a_] | | simple.cpp:18:22:18:23 | a_ | simple.cpp:18:9:18:9 | a indirection | -| simple.cpp:18:22:18:23 | a_ indirection | simple.cpp:18:9:18:9 | a indirection | | simple.cpp:18:22:18:23 | this indirection [a_] | simple.cpp:18:22:18:23 | a_ | -| simple.cpp:18:22:18:23 | this indirection [a_] | simple.cpp:18:22:18:23 | a_ indirection | | simple.cpp:19:9:19:9 | this indirection [b_] | simple.cpp:19:22:19:23 | this indirection [b_] | | simple.cpp:19:22:19:23 | b_ | simple.cpp:19:9:19:9 | b indirection | -| simple.cpp:19:22:19:23 | b_ indirection | simple.cpp:19:9:19:9 | b indirection | | simple.cpp:19:22:19:23 | this indirection [b_] | simple.cpp:19:22:19:23 | b_ | -| simple.cpp:19:22:19:23 | this indirection [b_] | simple.cpp:19:22:19:23 | b_ indirection | | simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:29 | ... = ... | | simple.cpp:20:24:20:29 | ... = ... | simple.cpp:20:24:20:25 | this indirection [post update] [a_] | | simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:29 | ... = ... | @@ -969,14 +773,10 @@ edges | simple.cpp:65:7:65:7 | a indirection [post update] [i] | simple.cpp:67:10:67:11 | a2 indirection [i] | | simple.cpp:65:11:65:20 | call to user_input | simple.cpp:65:5:65:22 | ... = ... | | simple.cpp:67:10:67:11 | a2 indirection [i] | simple.cpp:67:13:67:13 | i | -| simple.cpp:67:10:67:11 | a2 indirection [i] | simple.cpp:67:13:67:13 | i indirection | -| simple.cpp:67:13:67:13 | i indirection | simple.cpp:67:13:67:13 | i | | simple.cpp:78:9:78:15 | this indirection [f2, f1] | simple.cpp:79:16:79:17 | this indirection [f2, f1] | | simple.cpp:79:16:79:17 | f2 indirection [f1] | simple.cpp:79:19:79:20 | f1 | -| simple.cpp:79:16:79:17 | f2 indirection [f1] | simple.cpp:79:19:79:20 | f1 indirection | | simple.cpp:79:16:79:17 | this indirection [f2, f1] | simple.cpp:79:16:79:17 | f2 indirection [f1] | | simple.cpp:79:19:79:20 | f1 | simple.cpp:78:9:78:15 | getf2f1 indirection | -| simple.cpp:79:19:79:20 | f1 indirection | simple.cpp:78:9:78:15 | getf2f1 indirection | | simple.cpp:83:9:83:10 | this indirection [post update] [f2, f1] | simple.cpp:84:14:84:20 | this indirection [f2, f1] | | simple.cpp:83:9:83:28 | ... = ... | simple.cpp:83:12:83:13 | f2 indirection [post update] [f1] | | simple.cpp:83:12:83:13 | f2 indirection [post update] [f1] | simple.cpp:83:9:83:10 | this indirection [post update] [f2, f1] | @@ -987,12 +787,8 @@ edges | simple.cpp:92:7:92:7 | a indirection [post update] [i] | simple.cpp:94:10:94:11 | a2 indirection [i] | | simple.cpp:92:11:92:20 | call to user_input | simple.cpp:92:5:92:22 | ... = ... | | simple.cpp:94:10:94:11 | a2 indirection [i] | simple.cpp:94:13:94:13 | i | -| simple.cpp:94:10:94:11 | a2 indirection [i] | simple.cpp:94:13:94:13 | i indirection | -| simple.cpp:94:13:94:13 | i indirection | simple.cpp:94:13:94:13 | i | | struct_init.c:14:24:14:25 | ab indirection [a] | struct_init.c:15:8:15:9 | ab indirection [a] | | struct_init.c:15:8:15:9 | ab indirection [a] | struct_init.c:15:12:15:12 | a | -| struct_init.c:15:8:15:9 | ab indirection [a] | struct_init.c:15:12:15:12 | a indirection | -| struct_init.c:15:12:15:12 | a indirection | struct_init.c:15:12:15:12 | a | | struct_init.c:20:13:20:14 | definition of ab indirection [a] | struct_init.c:22:8:22:9 | ab indirection [a] | | struct_init.c:20:13:20:14 | definition of ab indirection [a] | struct_init.c:24:10:24:12 | & ... indirection [a] | | struct_init.c:20:13:20:14 | definition of ab indirection [a] | struct_init.c:28:5:28:7 | & ... indirection [a] | @@ -1000,8 +796,6 @@ edges | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:20:17:20:36 | definition of ab indirection [post update] [a] | | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:20:20:20:29 | call to user_input | | struct_init.c:22:8:22:9 | ab indirection [a] | struct_init.c:22:11:22:11 | a | -| struct_init.c:22:8:22:9 | ab indirection [a] | struct_init.c:22:11:22:11 | a indirection | -| struct_init.c:22:11:22:11 | a indirection | struct_init.c:22:11:22:11 | a | | struct_init.c:24:10:24:12 | & ... indirection [a] | struct_init.c:14:24:14:25 | ab indirection [a] | | struct_init.c:26:16:26:20 | definition of outer indirection [nestedAB, a] | struct_init.c:31:8:31:12 | outer indirection [nestedAB, a] | | struct_init.c:26:16:26:20 | definition of outer indirection [nestedAB, a] | struct_init.c:36:11:36:15 | outer indirection [nestedAB, a] | @@ -1015,14 +809,9 @@ edges | struct_init.c:28:5:28:7 | & ... indirection [a] | struct_init.c:26:23:29:3 | definition of outer indirection [post update] [pointerAB indirection, a] | | struct_init.c:31:8:31:12 | outer indirection [nestedAB, a] | struct_init.c:31:14:31:21 | nestedAB indirection [a] | | struct_init.c:31:14:31:21 | nestedAB indirection [a] | struct_init.c:31:23:31:23 | a | -| struct_init.c:31:14:31:21 | nestedAB indirection [a] | struct_init.c:31:23:31:23 | a indirection | -| struct_init.c:31:23:31:23 | a indirection | struct_init.c:31:23:31:23 | a | -| struct_init.c:33:8:33:12 | outer indirection [pointerAB indirection, a] | struct_init.c:33:14:33:22 | pointerAB indirection [a] | | struct_init.c:33:8:33:12 | outer indirection [pointerAB indirection, a] | struct_init.c:33:14:33:22 | pointerAB indirection [a] | | struct_init.c:33:14:33:22 | pointerAB indirection [a] | struct_init.c:33:14:33:22 | pointerAB indirection [a] | | struct_init.c:33:14:33:22 | pointerAB indirection [a] | struct_init.c:33:25:33:25 | a | -| struct_init.c:33:14:33:22 | pointerAB indirection [a] | struct_init.c:33:25:33:25 | a indirection | -| struct_init.c:33:25:33:25 | a indirection | struct_init.c:33:25:33:25 | a | | struct_init.c:36:10:36:24 | & ... indirection [a] | struct_init.c:14:24:14:25 | ab indirection [a] | | struct_init.c:36:11:36:15 | outer indirection [nestedAB, a] | struct_init.c:36:10:36:24 | & ... indirection [a] | | struct_init.c:40:13:40:14 | definition of ab indirection [a] | struct_init.c:43:5:43:7 | & ... indirection [a] | @@ -1032,7 +821,6 @@ edges | struct_init.c:41:23:44:3 | definition of outer indirection [post update] [pointerAB indirection, a] | struct_init.c:46:10:46:14 | outer indirection [pointerAB indirection, a] | | struct_init.c:43:5:43:7 | & ... indirection [a] | struct_init.c:41:23:44:3 | definition of outer indirection [post update] [pointerAB indirection, a] | | struct_init.c:46:10:46:14 | outer indirection [pointerAB indirection, a] | struct_init.c:46:16:46:24 | pointerAB indirection [a] | -| struct_init.c:46:10:46:14 | outer indirection [pointerAB indirection, a] | struct_init.c:46:16:46:24 | pointerAB indirection [a] | | struct_init.c:46:16:46:24 | pointerAB indirection [a] | struct_init.c:14:24:14:25 | ab indirection [a] | | struct_init.c:46:16:46:24 | pointerAB indirection [a] | struct_init.c:46:16:46:24 | pointerAB indirection [a] | nodes @@ -1046,7 +834,6 @@ nodes | A.cpp:28:8:28:10 | this indirection [c] | semmle.label | this indirection [c] | | A.cpp:28:23:28:26 | this indirection [c] | semmle.label | this indirection [c] | | A.cpp:28:29:28:29 | c | semmle.label | c | -| A.cpp:28:29:28:29 | c indirection | semmle.label | c indirection | | A.cpp:29:15:29:18 | make indirection [c] | semmle.label | make indirection [c] | | A.cpp:29:23:29:23 | c | semmle.label | c | | A.cpp:31:14:31:21 | call to B [c] | semmle.label | call to B [c] | @@ -1061,7 +848,6 @@ nodes | A.cpp:49:10:49:10 | b indirection [c] | semmle.label | b indirection [c] | | A.cpp:49:10:49:13 | c | semmle.label | c | | A.cpp:49:13:49:13 | c | semmle.label | c | -| A.cpp:49:13:49:13 | c indirection | semmle.label | c indirection | | A.cpp:55:5:55:5 | set output argument [c] | semmle.label | set output argument [c] | | A.cpp:55:12:55:19 | new | semmle.label | new | | A.cpp:55:12:55:19 | new | semmle.label | new | @@ -1078,14 +864,12 @@ nodes | A.cpp:66:10:66:11 | b2 indirection [c] | semmle.label | b2 indirection [c] | | A.cpp:66:10:66:14 | c | semmle.label | c | | A.cpp:66:14:66:14 | c | semmle.label | c | -| A.cpp:66:14:66:14 | c indirection | semmle.label | c indirection | | A.cpp:73:10:73:19 | call to setOnBWrap indirection [c] | semmle.label | call to setOnBWrap indirection [c] | | A.cpp:73:25:73:32 | new | semmle.label | new | | A.cpp:73:25:73:32 | new | semmle.label | new | | A.cpp:75:10:75:11 | b2 indirection [c] | semmle.label | b2 indirection [c] | | A.cpp:75:10:75:14 | c | semmle.label | c | | A.cpp:75:14:75:14 | c | semmle.label | c | -| A.cpp:75:14:75:14 | c indirection | semmle.label | c indirection | | A.cpp:78:6:78:15 | setOnBWrap indirection [c] | semmle.label | setOnBWrap indirection [c] | | A.cpp:78:27:78:27 | c | semmle.label | c | | A.cpp:81:10:81:15 | call to setOnB indirection [c] | semmle.label | call to setOnB indirection [c] | @@ -1102,11 +886,9 @@ nodes | A.cpp:107:12:107:13 | c1 indirection [a] | semmle.label | c1 indirection [a] | | A.cpp:107:12:107:16 | a | semmle.label | a | | A.cpp:107:16:107:16 | a | semmle.label | a | -| A.cpp:107:16:107:16 | a indirection | semmle.label | a indirection | | A.cpp:120:12:120:13 | c1 indirection [a] | semmle.label | c1 indirection [a] | | A.cpp:120:12:120:16 | a | semmle.label | a | | A.cpp:120:16:120:16 | a | semmle.label | a | -| A.cpp:120:16:120:16 | a indirection | semmle.label | a indirection | | A.cpp:126:5:126:5 | set output argument [c] | semmle.label | set output argument [c] | | A.cpp:126:12:126:18 | new | semmle.label | new | | A.cpp:126:12:126:18 | new | semmle.label | new | @@ -1114,7 +896,6 @@ nodes | A.cpp:132:10:132:10 | b indirection [c] | semmle.label | b indirection [c] | | A.cpp:132:10:132:13 | c | semmle.label | c | | A.cpp:132:13:132:13 | c | semmle.label | c | -| A.cpp:132:13:132:13 | c indirection | semmle.label | c indirection | | A.cpp:140:13:140:13 | b | semmle.label | b | | A.cpp:142:7:142:20 | ... = ... | semmle.label | ... = ... | | A.cpp:142:10:142:10 | b indirection [post update] [c] | semmle.label | b indirection [post update] [c] | @@ -1134,17 +915,13 @@ nodes | A.cpp:152:10:152:10 | d indirection [b] | semmle.label | d indirection [b] | | A.cpp:152:10:152:13 | b | semmle.label | b | | A.cpp:152:13:152:13 | b | semmle.label | b | -| A.cpp:152:13:152:13 | b indirection | semmle.label | b indirection | | A.cpp:153:10:153:10 | d indirection [b indirection, c] | semmle.label | d indirection [b indirection, c] | | A.cpp:153:10:153:16 | c | semmle.label | c | | A.cpp:153:13:153:13 | b indirection [c] | semmle.label | b indirection [c] | -| A.cpp:153:13:153:13 | b indirection [c] | semmle.label | b indirection [c] | | A.cpp:153:16:153:16 | c | semmle.label | c | -| A.cpp:153:16:153:16 | c indirection | semmle.label | c indirection | | A.cpp:154:10:154:10 | b indirection [c] | semmle.label | b indirection [c] | | A.cpp:154:10:154:13 | c | semmle.label | c | | A.cpp:154:13:154:13 | c | semmle.label | c | -| A.cpp:154:13:154:13 | c indirection | semmle.label | c indirection | | A.cpp:159:12:159:18 | new | semmle.label | new | | A.cpp:160:18:160:60 | call to MyList [head] | semmle.label | call to MyList [head] | | A.cpp:160:29:160:29 | b | semmle.label | b | @@ -1155,21 +932,15 @@ nodes | A.cpp:165:10:165:11 | l3 indirection [next indirection, next indirection, head] | semmle.label | l3 indirection [next indirection, next indirection, head] | | A.cpp:165:10:165:29 | head | semmle.label | head | | A.cpp:165:14:165:17 | next indirection [next indirection, head] | semmle.label | next indirection [next indirection, head] | -| A.cpp:165:14:165:17 | next indirection [next indirection, head] | semmle.label | next indirection [next indirection, head] | -| A.cpp:165:20:165:23 | next indirection [head] | semmle.label | next indirection [head] | | A.cpp:165:20:165:23 | next indirection [head] | semmle.label | next indirection [head] | | A.cpp:165:26:165:29 | head | semmle.label | head | -| A.cpp:165:26:165:29 | head indirection | semmle.label | head indirection | | A.cpp:167:44:167:44 | l indirection [next indirection, head] | semmle.label | l indirection [next indirection, head] | | A.cpp:167:44:167:44 | l indirection [next indirection, next indirection, head] | semmle.label | l indirection [next indirection, next indirection, head] | | A.cpp:167:47:167:50 | next indirection [head] | semmle.label | next indirection [head] | -| A.cpp:167:47:167:50 | next indirection [head] | semmle.label | next indirection [head] | -| A.cpp:167:47:167:50 | next indirection [next indirection, head] | semmle.label | next indirection [next indirection, head] | | A.cpp:167:47:167:50 | next indirection [next indirection, head] | semmle.label | next indirection [next indirection, head] | | A.cpp:169:12:169:12 | l indirection [head] | semmle.label | l indirection [head] | | A.cpp:169:12:169:18 | head | semmle.label | head | | A.cpp:169:15:169:18 | head | semmle.label | head | -| A.cpp:169:15:169:18 | head indirection | semmle.label | head indirection | | A.cpp:181:15:181:21 | newHead | semmle.label | newHead | | A.cpp:181:32:181:35 | next indirection [head] | semmle.label | next indirection [head] | | A.cpp:181:32:181:35 | next indirection [next indirection, head] | semmle.label | next indirection [next indirection, head] | @@ -1187,9 +958,7 @@ nodes | B.cpp:9:10:9:11 | b2 indirection [box1 indirection, elem1] | semmle.label | b2 indirection [box1 indirection, elem1] | | B.cpp:9:10:9:24 | elem1 | semmle.label | elem1 | | B.cpp:9:14:9:17 | box1 indirection [elem1] | semmle.label | box1 indirection [elem1] | -| B.cpp:9:14:9:17 | box1 indirection [elem1] | semmle.label | box1 indirection [elem1] | | B.cpp:9:20:9:24 | elem1 | semmle.label | elem1 | -| B.cpp:9:20:9:24 | elem1 indirection | semmle.label | elem1 indirection | | B.cpp:15:15:15:27 | new | semmle.label | new | | B.cpp:16:16:16:38 | call to Box1 [elem2] | semmle.label | call to Box1 [elem2] | | B.cpp:16:37:16:37 | e | semmle.label | e | @@ -1198,9 +967,7 @@ nodes | B.cpp:19:10:19:11 | b2 indirection [box1 indirection, elem2] | semmle.label | b2 indirection [box1 indirection, elem2] | | B.cpp:19:10:19:24 | elem2 | semmle.label | elem2 | | B.cpp:19:14:19:17 | box1 indirection [elem2] | semmle.label | box1 indirection [elem2] | -| B.cpp:19:14:19:17 | box1 indirection [elem2] | semmle.label | box1 indirection [elem2] | | B.cpp:19:20:19:24 | elem2 | semmle.label | elem2 | -| B.cpp:19:20:19:24 | elem2 indirection | semmle.label | elem2 indirection | | B.cpp:33:16:33:17 | e1 | semmle.label | e1 | | B.cpp:33:26:33:27 | e2 | semmle.label | e2 | | B.cpp:35:7:35:22 | ... = ... | semmle.label | ... = ... | @@ -1226,15 +993,12 @@ nodes | C.cpp:27:8:27:11 | this indirection [s1] | semmle.label | this indirection [s1] | | C.cpp:27:8:27:11 | this indirection [s3] | semmle.label | this indirection [s3] | | C.cpp:29:10:29:11 | s1 | semmle.label | s1 | -| C.cpp:29:10:29:11 | s1 indirection | semmle.label | s1 indirection | | C.cpp:29:10:29:11 | this indirection [s1] | semmle.label | this indirection [s1] | | C.cpp:31:10:31:11 | s3 | semmle.label | s3 | -| C.cpp:31:10:31:11 | s3 indirection | semmle.label | s3 indirection | | C.cpp:31:10:31:11 | this indirection [s3] | semmle.label | this indirection [s3] | | D.cpp:10:11:10:17 | getElem indirection | semmle.label | getElem indirection | | D.cpp:10:11:10:17 | this indirection [elem] | semmle.label | this indirection [elem] | | D.cpp:10:30:10:33 | elem | semmle.label | elem | -| D.cpp:10:30:10:33 | elem indirection | semmle.label | elem indirection | | D.cpp:10:30:10:33 | this indirection [elem] | semmle.label | this indirection [elem] | | D.cpp:11:24:11:24 | e | semmle.label | e | | D.cpp:11:29:11:32 | this indirection [post update] [elem] | semmle.label | this indirection [post update] [elem] | @@ -1242,7 +1006,6 @@ nodes | D.cpp:17:11:17:17 | getBox1 indirection [elem] | semmle.label | getBox1 indirection [elem] | | D.cpp:17:11:17:17 | this indirection [box indirection, elem] | semmle.label | this indirection [box indirection, elem] | | D.cpp:17:30:17:32 | box indirection [elem] | semmle.label | box indirection [elem] | -| D.cpp:17:30:17:32 | box indirection [elem] | semmle.label | box indirection [elem] | | D.cpp:17:30:17:32 | this indirection [box indirection, elem] | semmle.label | this indirection [box indirection, elem] | | D.cpp:21:30:21:31 | b2 indirection [box indirection, elem] | semmle.label | b2 indirection [box indirection, elem] | | D.cpp:22:10:22:11 | b2 indirection [box indirection, elem] | semmle.label | b2 indirection [box indirection, elem] | @@ -1276,13 +1039,10 @@ nodes | D.cpp:59:5:59:7 | this indirection [boxfield indirection, box indirection, elem] | semmle.label | this indirection [boxfield indirection, box indirection, elem] | | D.cpp:63:8:63:10 | this indirection [boxfield indirection, box indirection, elem] | semmle.label | this indirection [boxfield indirection, box indirection, elem] | | D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | semmle.label | boxfield indirection [box indirection, elem] | -| D.cpp:64:10:64:17 | boxfield indirection [box indirection, elem] | semmle.label | boxfield indirection [box indirection, elem] | | D.cpp:64:10:64:17 | this indirection [boxfield indirection, box indirection, elem] | semmle.label | this indirection [boxfield indirection, box indirection, elem] | | D.cpp:64:10:64:28 | elem | semmle.label | elem | | D.cpp:64:20:64:22 | box indirection [elem] | semmle.label | box indirection [elem] | -| D.cpp:64:20:64:22 | box indirection [elem] | semmle.label | box indirection [elem] | | D.cpp:64:25:64:28 | elem | semmle.label | elem | -| D.cpp:64:25:64:28 | elem indirection | semmle.label | elem indirection | | E.cpp:19:27:19:27 | p indirection [data, buffer indirection] | semmle.label | p indirection [data, buffer indirection] | | E.cpp:21:10:21:10 | p indirection [data, buffer indirection] | semmle.label | p indirection [data, buffer indirection] | | E.cpp:21:13:21:16 | data indirection [buffer indirection] | semmle.label | data indirection [buffer indirection] | @@ -1295,7 +1055,6 @@ nodes | E.cpp:30:23:30:26 | p indirection [post update] [data, buffer indirection] | semmle.label | p indirection [post update] [data, buffer indirection] | | E.cpp:30:28:30:33 | data indirection [post update] [buffer indirection] | semmle.label | data indirection [post update] [buffer indirection] | | E.cpp:31:10:31:12 | raw indirection | semmle.label | raw indirection | -| E.cpp:31:10:31:12 | raw indirection | semmle.label | raw indirection | | E.cpp:32:10:32:10 | b indirection [buffer indirection] | semmle.label | b indirection [buffer indirection] | | E.cpp:32:13:32:18 | buffer indirection | semmle.label | buffer indirection | | E.cpp:32:13:32:18 | buffer indirection | semmle.label | buffer indirection | @@ -1310,16 +1069,13 @@ nodes | aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | semmle.label | referenceSetter output argument [m1] | | aliasing.cpp:29:8:29:9 | s1 indirection [m1] | semmle.label | s1 indirection [m1] | | aliasing.cpp:29:11:29:12 | m1 | semmle.label | m1 | -| aliasing.cpp:29:11:29:12 | m1 indirection | semmle.label | m1 indirection | | aliasing.cpp:30:8:30:9 | s2 indirection [m1] | semmle.label | s2 indirection [m1] | | aliasing.cpp:30:11:30:12 | m1 | semmle.label | m1 | -| aliasing.cpp:30:11:30:12 | m1 indirection | semmle.label | m1 indirection | | aliasing.cpp:60:3:60:22 | ... = ... | semmle.label | ... = ... | | aliasing.cpp:60:6:60:7 | s2 indirection [post update] [m1] | semmle.label | s2 indirection [post update] [m1] | | aliasing.cpp:60:11:60:20 | call to user_input | semmle.label | call to user_input | | aliasing.cpp:62:8:62:12 | copy2 indirection [m1] | semmle.label | copy2 indirection [m1] | | aliasing.cpp:62:14:62:15 | m1 | semmle.label | m1 | -| aliasing.cpp:62:14:62:15 | m1 indirection | semmle.label | m1 indirection | | aliasing.cpp:92:3:92:23 | ... = ... | semmle.label | ... = ... | | aliasing.cpp:92:5:92:5 | w indirection [post update] [s, m1] | semmle.label | w indirection [post update] [s, m1] | | aliasing.cpp:92:7:92:8 | s indirection [post update] [m1] | semmle.label | s indirection [post update] [m1] | @@ -1327,7 +1083,6 @@ nodes | aliasing.cpp:93:8:93:8 | w indirection [s, m1] | semmle.label | w indirection [s, m1] | | aliasing.cpp:93:10:93:10 | s indirection [m1] | semmle.label | s indirection [m1] | | aliasing.cpp:93:12:93:13 | m1 | semmle.label | m1 | -| aliasing.cpp:93:12:93:13 | m1 indirection | semmle.label | m1 indirection | | aliasing.cpp:98:3:98:21 | ... = ... | semmle.label | ... = ... | | aliasing.cpp:98:5:98:6 | s indirection [post update] [m1] | semmle.label | s indirection [post update] [m1] | | aliasing.cpp:98:10:98:19 | call to user_input | semmle.label | call to user_input | @@ -1348,39 +1103,33 @@ nodes | aliasing.cpp:141:17:141:20 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument | | aliasing.cpp:143:8:143:8 | s indirection [data indirection] | semmle.label | s indirection [data indirection] | | aliasing.cpp:143:8:143:16 | access to array | semmle.label | access to array | -| aliasing.cpp:143:8:143:16 | access to array indirection | semmle.label | access to array indirection | | aliasing.cpp:143:10:143:13 | data indirection | semmle.label | data indirection | | aliasing.cpp:158:15:158:20 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument | | aliasing.cpp:158:17:158:20 | s indirection [post update] [data] | semmle.label | s indirection [post update] [data] | | aliasing.cpp:159:8:159:14 | * ... | semmle.label | * ... | | aliasing.cpp:159:9:159:9 | s indirection [data] | semmle.label | s indirection [data] | -| aliasing.cpp:159:9:159:14 | data indirection | semmle.label | data indirection | | aliasing.cpp:164:15:164:20 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument | | aliasing.cpp:164:17:164:20 | s indirection [post update] [data] | semmle.label | s indirection [post update] [data] | | aliasing.cpp:165:8:165:8 | s indirection [data] | semmle.label | s indirection [data] | | aliasing.cpp:165:8:165:16 | access to array | semmle.label | access to array | -| aliasing.cpp:165:8:165:16 | access to array indirection | semmle.label | access to array indirection | | aliasing.cpp:175:15:175:22 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument | | aliasing.cpp:175:19:175:19 | s2 indirection [post update] [s, m1] | semmle.label | s2 indirection [post update] [s, m1] | | aliasing.cpp:175:21:175:22 | s indirection [post update] [m1] | semmle.label | s indirection [post update] [m1] | | aliasing.cpp:176:8:176:9 | s2 indirection [s, m1] | semmle.label | s2 indirection [s, m1] | | aliasing.cpp:176:11:176:11 | s indirection [m1] | semmle.label | s indirection [m1] | | aliasing.cpp:176:13:176:14 | m1 | semmle.label | m1 | -| aliasing.cpp:176:13:176:14 | m1 indirection | semmle.label | m1 indirection | | aliasing.cpp:187:15:187:22 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument | | aliasing.cpp:187:19:187:19 | s2 indirection [post update] [s, m1] | semmle.label | s2 indirection [post update] [s, m1] | | aliasing.cpp:187:21:187:22 | s indirection [post update] [m1] | semmle.label | s indirection [post update] [m1] | | aliasing.cpp:189:8:189:11 | s2_2 indirection [s, m1] | semmle.label | s2_2 indirection [s, m1] | | aliasing.cpp:189:13:189:13 | s indirection [m1] | semmle.label | s indirection [m1] | | aliasing.cpp:189:15:189:16 | m1 | semmle.label | m1 | -| aliasing.cpp:189:15:189:16 | m1 indirection | semmle.label | m1 indirection | | aliasing.cpp:200:15:200:24 | taint_a_ptr output argument | semmle.label | taint_a_ptr output argument | | aliasing.cpp:200:21:200:21 | ps2 indirection [post update] [s, m1] | semmle.label | ps2 indirection [post update] [s, m1] | | aliasing.cpp:200:23:200:24 | s indirection [post update] [m1] | semmle.label | s indirection [post update] [m1] | | aliasing.cpp:201:8:201:10 | ps2 indirection [s, m1] | semmle.label | ps2 indirection [s, m1] | | aliasing.cpp:201:13:201:13 | s indirection [m1] | semmle.label | s indirection [m1] | | aliasing.cpp:201:15:201:16 | m1 | semmle.label | m1 | -| aliasing.cpp:201:15:201:16 | m1 indirection | semmle.label | m1 indirection | | arrays.cpp:6:12:6:21 | call to user_input | semmle.label | call to user_input | | arrays.cpp:7:8:7:13 | access to array | semmle.label | access to array | | arrays.cpp:8:8:8:13 | access to array | semmle.label | access to array | @@ -1398,12 +1147,10 @@ nodes | arrays.cpp:37:8:37:22 | access to array indirection [data] | semmle.label | access to array indirection [data] | | arrays.cpp:37:10:37:15 | nested indirection [arr, data] | semmle.label | nested indirection [arr, data] | | arrays.cpp:37:24:37:27 | data | semmle.label | data | -| arrays.cpp:37:24:37:27 | data indirection | semmle.label | data indirection | | arrays.cpp:38:8:38:8 | o indirection [nested, arr, data] | semmle.label | o indirection [nested, arr, data] | | arrays.cpp:38:8:38:22 | access to array indirection [data] | semmle.label | access to array indirection [data] | | arrays.cpp:38:10:38:15 | nested indirection [arr, data] | semmle.label | nested indirection [arr, data] | | arrays.cpp:38:24:38:27 | data | semmle.label | data | -| arrays.cpp:38:24:38:27 | data indirection | semmle.label | data indirection | | arrays.cpp:42:3:42:40 | ... = ... | semmle.label | ... = ... | | arrays.cpp:42:5:42:12 | o indirection [post update] [indirect indirection, arr, data] | semmle.label | o indirection [post update] [indirect indirection, arr, data] | | arrays.cpp:42:15:42:17 | indirect indirection [post update] [arr, data] | semmle.label | indirect indirection [post update] [arr, data] | @@ -1412,15 +1159,11 @@ nodes | arrays.cpp:43:8:43:8 | o indirection [indirect indirection, arr, data] | semmle.label | o indirection [indirect indirection, arr, data] | | arrays.cpp:43:8:43:25 | access to array indirection [data] | semmle.label | access to array indirection [data] | | arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | semmle.label | indirect indirection [arr, data] | -| arrays.cpp:43:10:43:17 | indirect indirection [arr, data] | semmle.label | indirect indirection [arr, data] | | arrays.cpp:43:27:43:30 | data | semmle.label | data | -| arrays.cpp:43:27:43:30 | data indirection | semmle.label | data indirection | | arrays.cpp:44:8:44:8 | o indirection [indirect indirection, arr, data] | semmle.label | o indirection [indirect indirection, arr, data] | | arrays.cpp:44:8:44:25 | access to array indirection [data] | semmle.label | access to array indirection [data] | | arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | semmle.label | indirect indirection [arr, data] | -| arrays.cpp:44:10:44:17 | indirect indirection [arr, data] | semmle.label | indirect indirection [arr, data] | | arrays.cpp:44:27:44:30 | data | semmle.label | data | -| arrays.cpp:44:27:44:30 | data indirection | semmle.label | data indirection | | arrays.cpp:48:3:48:40 | ... = ... | semmle.label | ... = ... | | arrays.cpp:48:5:48:12 | o indirection [post update] [indirect indirection, ptr indirection, data] | semmle.label | o indirection [post update] [indirect indirection, ptr indirection, data] | | arrays.cpp:48:15:48:17 | indirect indirection [post update] [ptr indirection, data] | semmle.label | indirect indirection [post update] [ptr indirection, data] | @@ -1429,17 +1172,13 @@ nodes | arrays.cpp:49:8:49:8 | o indirection [indirect indirection, ptr indirection, data] | semmle.label | o indirection [indirect indirection, ptr indirection, data] | | arrays.cpp:49:8:49:25 | access to array indirection [data] | semmle.label | access to array indirection [data] | | arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | semmle.label | indirect indirection [ptr indirection, data] | -| arrays.cpp:49:10:49:17 | indirect indirection [ptr indirection, data] | semmle.label | indirect indirection [ptr indirection, data] | | arrays.cpp:49:20:49:22 | ptr indirection [data] | semmle.label | ptr indirection [data] | | arrays.cpp:49:27:49:30 | data | semmle.label | data | -| arrays.cpp:49:27:49:30 | data indirection | semmle.label | data indirection | | arrays.cpp:50:8:50:8 | o indirection [indirect indirection, ptr indirection, data] | semmle.label | o indirection [indirect indirection, ptr indirection, data] | | arrays.cpp:50:8:50:25 | access to array indirection [data] | semmle.label | access to array indirection [data] | | arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | semmle.label | indirect indirection [ptr indirection, data] | -| arrays.cpp:50:10:50:17 | indirect indirection [ptr indirection, data] | semmle.label | indirect indirection [ptr indirection, data] | | arrays.cpp:50:20:50:22 | ptr indirection [data] | semmle.label | ptr indirection [data] | | arrays.cpp:50:27:50:30 | data | semmle.label | data | -| arrays.cpp:50:27:50:30 | data indirection | semmle.label | data indirection | | by_reference.cpp:11:48:11:52 | value | semmle.label | value | | by_reference.cpp:12:5:12:16 | ... = ... | semmle.label | ... = ... | | by_reference.cpp:12:8:12:8 | s indirection [post update] [a] | semmle.label | s indirection [post update] [a] | @@ -1456,12 +1195,10 @@ nodes | by_reference.cpp:31:46:31:46 | s indirection [a] | semmle.label | s indirection [a] | | by_reference.cpp:32:12:32:12 | s indirection [a] | semmle.label | s indirection [a] | | by_reference.cpp:32:15:32:15 | a | semmle.label | a | -| by_reference.cpp:32:15:32:15 | a indirection | semmle.label | a indirection | | by_reference.cpp:35:9:35:19 | getDirectly indirection | semmle.label | getDirectly indirection | | by_reference.cpp:35:9:35:19 | this indirection [a] | semmle.label | this indirection [a] | | by_reference.cpp:36:12:36:15 | this indirection [a] | semmle.label | this indirection [a] | | by_reference.cpp:36:18:36:18 | a | semmle.label | a | -| by_reference.cpp:36:18:36:18 | a indirection | semmle.label | a indirection | | by_reference.cpp:39:9:39:21 | getIndirectly indirection | semmle.label | getIndirectly indirection | | by_reference.cpp:39:9:39:21 | this indirection [a] | semmle.label | this indirection [a] | | by_reference.cpp:40:12:40:15 | this indirection [a] | semmle.label | this indirection [a] | @@ -1511,27 +1248,19 @@ nodes | by_reference.cpp:110:8:110:12 | outer indirection [inner_nested, a] | semmle.label | outer indirection [inner_nested, a] | | by_reference.cpp:110:14:110:25 | inner_nested indirection [a] | semmle.label | inner_nested indirection [a] | | by_reference.cpp:110:27:110:27 | a | semmle.label | a | -| by_reference.cpp:110:27:110:27 | a indirection | semmle.label | a indirection | | by_reference.cpp:111:8:111:12 | outer indirection [inner_ptr indirection, a] | semmle.label | outer indirection [inner_ptr indirection, a] | | by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] | -| by_reference.cpp:111:14:111:22 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] | | by_reference.cpp:111:25:111:25 | a | semmle.label | a | -| by_reference.cpp:111:25:111:25 | a indirection | semmle.label | a indirection | | by_reference.cpp:112:8:112:12 | outer indirection [a] | semmle.label | outer indirection [a] | | by_reference.cpp:112:14:112:14 | a | semmle.label | a | -| by_reference.cpp:112:14:112:14 | a indirection | semmle.label | a indirection | | by_reference.cpp:114:8:114:13 | pouter indirection [inner_nested, a] | semmle.label | pouter indirection [inner_nested, a] | | by_reference.cpp:114:16:114:27 | inner_nested indirection [a] | semmle.label | inner_nested indirection [a] | | by_reference.cpp:114:29:114:29 | a | semmle.label | a | -| by_reference.cpp:114:29:114:29 | a indirection | semmle.label | a indirection | | by_reference.cpp:115:8:115:13 | pouter indirection [inner_ptr indirection, a] | semmle.label | pouter indirection [inner_ptr indirection, a] | | by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] | -| by_reference.cpp:115:16:115:24 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] | | by_reference.cpp:115:27:115:27 | a | semmle.label | a | -| by_reference.cpp:115:27:115:27 | a indirection | semmle.label | a indirection | | by_reference.cpp:116:8:116:13 | pouter indirection [a] | semmle.label | pouter indirection [a] | | by_reference.cpp:116:16:116:16 | a | semmle.label | a | -| by_reference.cpp:116:16:116:16 | a indirection | semmle.label | a indirection | | by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] | | by_reference.cpp:122:27:122:38 | outer indirection [post update] [inner_nested, a] | semmle.label | outer indirection [post update] [inner_nested, a] | | by_reference.cpp:123:21:123:36 | taint_inner_a_ref output argument [a] | semmle.label | taint_inner_a_ref output argument [a] | @@ -1547,35 +1276,25 @@ nodes | by_reference.cpp:130:8:130:12 | outer indirection [inner_nested, a] | semmle.label | outer indirection [inner_nested, a] | | by_reference.cpp:130:14:130:25 | inner_nested indirection [a] | semmle.label | inner_nested indirection [a] | | by_reference.cpp:130:27:130:27 | a | semmle.label | a | -| by_reference.cpp:130:27:130:27 | a indirection | semmle.label | a indirection | | by_reference.cpp:131:8:131:12 | outer indirection [inner_ptr indirection, a] | semmle.label | outer indirection [inner_ptr indirection, a] | | by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] | -| by_reference.cpp:131:14:131:22 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] | | by_reference.cpp:131:25:131:25 | a | semmle.label | a | -| by_reference.cpp:131:25:131:25 | a indirection | semmle.label | a indirection | | by_reference.cpp:132:8:132:12 | outer indirection [a] | semmle.label | outer indirection [a] | | by_reference.cpp:132:14:132:14 | a | semmle.label | a | -| by_reference.cpp:132:14:132:14 | a indirection | semmle.label | a indirection | | by_reference.cpp:134:8:134:13 | pouter indirection [inner_nested, a] | semmle.label | pouter indirection [inner_nested, a] | | by_reference.cpp:134:16:134:27 | inner_nested indirection [a] | semmle.label | inner_nested indirection [a] | | by_reference.cpp:134:29:134:29 | a | semmle.label | a | -| by_reference.cpp:134:29:134:29 | a indirection | semmle.label | a indirection | | by_reference.cpp:135:8:135:13 | pouter indirection [inner_ptr indirection, a] | semmle.label | pouter indirection [inner_ptr indirection, a] | | by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] | -| by_reference.cpp:135:16:135:24 | inner_ptr indirection [a] | semmle.label | inner_ptr indirection [a] | | by_reference.cpp:135:27:135:27 | a | semmle.label | a | -| by_reference.cpp:135:27:135:27 | a indirection | semmle.label | a indirection | | by_reference.cpp:136:8:136:13 | pouter indirection [a] | semmle.label | pouter indirection [a] | | by_reference.cpp:136:16:136:16 | a | semmle.label | a | -| by_reference.cpp:136:16:136:16 | a indirection | semmle.label | a indirection | | clearning.cpp:32:3:32:25 | ... = ... | semmle.label | ... = ... | | clearning.cpp:32:6:32:6 | s indirection [post update] [x indirection] | semmle.label | s indirection [post update] [x indirection] | | clearning.cpp:32:10:32:19 | call to user_input | semmle.label | call to user_input | | clearning.cpp:33:5:33:5 | s indirection [x indirection] | semmle.label | s indirection [x indirection] | | clearning.cpp:34:8:34:11 | * ... | semmle.label | * ... | | clearning.cpp:34:9:34:9 | s indirection [x indirection] | semmle.label | s indirection [x indirection] | -| clearning.cpp:34:11:34:11 | x indirection | semmle.label | x indirection | -| clearning.cpp:34:11:34:11 | x indirection | semmle.label | x indirection | | clearning.cpp:53:3:53:25 | ... = ... | semmle.label | ... = ... | | clearning.cpp:53:6:53:6 | s indirection [post update] [x indirection] | semmle.label | s indirection [post update] [x indirection] | | clearning.cpp:53:10:53:19 | call to user_input | semmle.label | call to user_input | @@ -1602,8 +1321,6 @@ nodes | clearning.cpp:74:20:74:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] | | clearning.cpp:76:7:76:12 | * ... | semmle.label | * ... | | clearning.cpp:76:8:76:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] | -| clearning.cpp:76:10:76:12 | val indirection | semmle.label | val indirection | -| clearning.cpp:76:10:76:12 | val indirection | semmle.label | val indirection | | clearning.cpp:81:20:81:22 | argument_source output argument | semmle.label | argument_source output argument | | clearning.cpp:81:20:81:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] | | clearning.cpp:83:5:83:21 | ... = ... indirection | semmle.label | ... = ... indirection | @@ -1613,8 +1330,6 @@ nodes | clearning.cpp:83:15:83:17 | val indirection | semmle.label | val indirection | | clearning.cpp:84:7:84:12 | * ... | semmle.label | * ... | | clearning.cpp:84:8:84:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] | -| clearning.cpp:84:10:84:12 | val indirection | semmle.label | val indirection | -| clearning.cpp:84:10:84:12 | val indirection | semmle.label | val indirection | | clearning.cpp:89:20:89:22 | argument_source output argument | semmle.label | argument_source output argument | | clearning.cpp:89:20:89:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] | | clearning.cpp:90:3:90:3 | s indirection [val indirection] | semmle.label | s indirection [val indirection] | @@ -1624,8 +1339,6 @@ nodes | clearning.cpp:90:5:90:7 | val indirection | semmle.label | val indirection | | clearning.cpp:91:7:91:12 | * ... | semmle.label | * ... | | clearning.cpp:91:8:91:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] | -| clearning.cpp:91:10:91:12 | val indirection | semmle.label | val indirection | -| clearning.cpp:91:10:91:12 | val indirection | semmle.label | val indirection | | clearning.cpp:96:20:96:22 | argument_source output argument | semmle.label | argument_source output argument | | clearning.cpp:96:20:96:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] | | clearning.cpp:97:2:97:18 | ... = ... indirection | semmle.label | ... = ... indirection | @@ -1635,8 +1348,6 @@ nodes | clearning.cpp:97:12:97:14 | val indirection | semmle.label | val indirection | | clearning.cpp:98:7:98:12 | * ... | semmle.label | * ... | | clearning.cpp:98:8:98:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] | -| clearning.cpp:98:10:98:12 | val indirection | semmle.label | val indirection | -| clearning.cpp:98:10:98:12 | val indirection | semmle.label | val indirection | | clearning.cpp:103:20:103:22 | argument_source output argument | semmle.label | argument_source output argument | | clearning.cpp:103:20:103:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] | | clearning.cpp:104:2:104:2 | s indirection [val indirection] | semmle.label | s indirection [val indirection] | @@ -1646,8 +1357,6 @@ nodes | clearning.cpp:104:4:104:6 | val indirection | semmle.label | val indirection | | clearning.cpp:105:7:105:12 | * ... | semmle.label | * ... | | clearning.cpp:105:8:105:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] | -| clearning.cpp:105:10:105:12 | val indirection | semmle.label | val indirection | -| clearning.cpp:105:10:105:12 | val indirection | semmle.label | val indirection | | clearning.cpp:110:20:110:22 | argument_source output argument | semmle.label | argument_source output argument | | clearning.cpp:110:20:110:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] | | clearning.cpp:111:2:111:8 | ++ ... indirection | semmle.label | ++ ... indirection | @@ -1657,8 +1366,6 @@ nodes | clearning.cpp:111:6:111:8 | val indirection | semmle.label | val indirection | | clearning.cpp:112:7:112:12 | * ... | semmle.label | * ... | | clearning.cpp:112:8:112:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] | -| clearning.cpp:112:10:112:12 | val indirection | semmle.label | val indirection | -| clearning.cpp:112:10:112:12 | val indirection | semmle.label | val indirection | | clearning.cpp:117:20:117:22 | argument_source output argument | semmle.label | argument_source output argument | | clearning.cpp:117:20:117:22 | s indirection [post update] [val indirection] | semmle.label | s indirection [post update] [val indirection] | | clearning.cpp:118:2:118:2 | s indirection [val indirection] | semmle.label | s indirection [val indirection] | @@ -1668,23 +1375,18 @@ nodes | clearning.cpp:118:4:118:6 | val indirection | semmle.label | val indirection | | clearning.cpp:119:7:119:12 | * ... | semmle.label | * ... | | clearning.cpp:119:8:119:8 | s indirection [val indirection] | semmle.label | s indirection [val indirection] | -| clearning.cpp:119:10:119:12 | val indirection | semmle.label | val indirection | -| clearning.cpp:119:10:119:12 | val indirection | semmle.label | val indirection | | clearning.cpp:151:3:151:22 | ... = ... | semmle.label | ... = ... | | clearning.cpp:151:5:151:7 | s indirection [post update] [val] | semmle.label | s indirection [post update] [val] | | clearning.cpp:151:11:151:20 | call to user_input | semmle.label | call to user_input | | clearning.cpp:152:8:152:8 | s indirection [val] | semmle.label | s indirection [val] | | clearning.cpp:152:10:152:12 | val | semmle.label | val | -| clearning.cpp:152:10:152:12 | val indirection | semmle.label | val indirection | | complex.cpp:9:7:9:7 | a indirection | semmle.label | a indirection | | complex.cpp:9:7:9:7 | this indirection [a_] | semmle.label | this indirection [a_] | | complex.cpp:9:20:9:21 | a_ | semmle.label | a_ | -| complex.cpp:9:20:9:21 | a_ indirection | semmle.label | a_ indirection | | complex.cpp:9:20:9:21 | this indirection [a_] | semmle.label | this indirection [a_] | | complex.cpp:10:7:10:7 | b indirection | semmle.label | b indirection | | complex.cpp:10:7:10:7 | this indirection [b_] | semmle.label | this indirection [b_] | | complex.cpp:10:20:10:21 | b_ | semmle.label | b_ | -| complex.cpp:10:20:10:21 | b_ indirection | semmle.label | b_ indirection | | complex.cpp:10:20:10:21 | this indirection [b_] | semmle.label | this indirection [b_] | | complex.cpp:11:17:11:17 | a | semmle.label | a | | complex.cpp:11:22:11:23 | this indirection [post update] [a_] | semmle.label | this indirection [post update] [a_] | @@ -1735,51 +1437,40 @@ nodes | conflated.cpp:10:11:10:20 | call to user_input | semmle.label | call to user_input | | conflated.cpp:11:8:11:12 | * ... | semmle.label | * ... | | conflated.cpp:11:9:11:10 | ra indirection [p indirection] | semmle.label | ra indirection [p indirection] | -| conflated.cpp:11:12:11:12 | p indirection | semmle.label | p indirection | -| conflated.cpp:11:12:11:12 | p indirection | semmle.label | p indirection | | conflated.cpp:19:19:19:21 | argument_source output argument | semmle.label | argument_source output argument | | conflated.cpp:20:8:20:10 | raw indirection | semmle.label | raw indirection | | conflated.cpp:20:8:20:10 | raw indirection | semmle.label | raw indirection | -| conflated.cpp:20:8:20:10 | raw indirection | semmle.label | raw indirection | | conflated.cpp:29:3:29:22 | ... = ... | semmle.label | ... = ... | | conflated.cpp:29:7:29:7 | pa indirection [post update] [x] | semmle.label | pa indirection [post update] [x] | | conflated.cpp:29:11:29:20 | call to user_input | semmle.label | call to user_input | | conflated.cpp:30:8:30:9 | pa indirection [x] | semmle.label | pa indirection [x] | | conflated.cpp:30:12:30:12 | x | semmle.label | x | -| conflated.cpp:30:12:30:12 | x indirection | semmle.label | x indirection | | conflated.cpp:36:3:36:22 | ... = ... | semmle.label | ... = ... | | conflated.cpp:36:7:36:7 | pa indirection [post update] [x] | semmle.label | pa indirection [post update] [x] | | conflated.cpp:36:11:36:20 | call to user_input | semmle.label | call to user_input | | conflated.cpp:37:8:37:9 | pa indirection [x] | semmle.label | pa indirection [x] | | conflated.cpp:37:12:37:12 | x | semmle.label | x | -| conflated.cpp:37:12:37:12 | x indirection | semmle.label | x indirection | | conflated.cpp:54:3:54:28 | ... = ... | semmle.label | ... = ... | | conflated.cpp:54:7:54:10 | ll indirection [post update] [next indirection, y] | semmle.label | ll indirection [post update] [next indirection, y] | | conflated.cpp:54:13:54:13 | next indirection [post update] [y] | semmle.label | next indirection [post update] [y] | | conflated.cpp:54:17:54:26 | call to user_input | semmle.label | call to user_input | | conflated.cpp:55:8:55:9 | ll indirection [next indirection, y] | semmle.label | ll indirection [next indirection, y] | | conflated.cpp:55:12:55:15 | next indirection [y] | semmle.label | next indirection [y] | -| conflated.cpp:55:12:55:15 | next indirection [y] | semmle.label | next indirection [y] | | conflated.cpp:55:18:55:18 | y | semmle.label | y | -| conflated.cpp:55:18:55:18 | y indirection | semmle.label | y indirection | | conflated.cpp:60:3:60:28 | ... = ... | semmle.label | ... = ... | | conflated.cpp:60:7:60:10 | ll indirection [post update] [next indirection, y] | semmle.label | ll indirection [post update] [next indirection, y] | | conflated.cpp:60:13:60:13 | next indirection [post update] [y] | semmle.label | next indirection [post update] [y] | | conflated.cpp:60:17:60:26 | call to user_input | semmle.label | call to user_input | | conflated.cpp:61:8:61:9 | ll indirection [next indirection, y] | semmle.label | ll indirection [next indirection, y] | | conflated.cpp:61:12:61:15 | next indirection [y] | semmle.label | next indirection [y] | -| conflated.cpp:61:12:61:15 | next indirection [y] | semmle.label | next indirection [y] | | conflated.cpp:61:18:61:18 | y | semmle.label | y | -| conflated.cpp:61:18:61:18 | y indirection | semmle.label | y indirection | | constructors.cpp:18:9:18:9 | a indirection | semmle.label | a indirection | | constructors.cpp:18:9:18:9 | this indirection [a_] | semmle.label | this indirection [a_] | | constructors.cpp:18:22:18:23 | a_ | semmle.label | a_ | -| constructors.cpp:18:22:18:23 | a_ indirection | semmle.label | a_ indirection | | constructors.cpp:18:22:18:23 | this indirection [a_] | semmle.label | this indirection [a_] | | constructors.cpp:19:9:19:9 | b indirection | semmle.label | b indirection | | constructors.cpp:19:9:19:9 | this indirection [b_] | semmle.label | this indirection [b_] | | constructors.cpp:19:22:19:23 | b_ | semmle.label | b_ | -| constructors.cpp:19:22:19:23 | b_ indirection | semmle.label | b_ indirection | | constructors.cpp:19:22:19:23 | this indirection [b_] | semmle.label | this indirection [b_] | | constructors.cpp:23:13:23:13 | a | semmle.label | a | | constructors.cpp:23:20:23:20 | b | semmle.label | b | @@ -1820,51 +1511,39 @@ nodes | qualifiers.cpp:22:27:22:36 | call to user_input | semmle.label | call to user_input | | qualifiers.cpp:23:10:23:14 | outer indirection [inner indirection, a] | semmle.label | outer indirection [inner indirection, a] | | qualifiers.cpp:23:16:23:20 | inner indirection [a] | semmle.label | inner indirection [a] | -| qualifiers.cpp:23:16:23:20 | inner indirection [a] | semmle.label | inner indirection [a] | | qualifiers.cpp:23:23:23:23 | a | semmle.label | a | -| qualifiers.cpp:23:23:23:23 | a indirection | semmle.label | a indirection | | qualifiers.cpp:27:5:27:9 | getInner output argument [inner indirection, a] | semmle.label | getInner output argument [inner indirection, a] | | qualifiers.cpp:27:11:27:18 | setA output argument [a] | semmle.label | setA output argument [a] | | qualifiers.cpp:27:28:27:37 | call to user_input | semmle.label | call to user_input | | qualifiers.cpp:28:10:28:14 | outer indirection [inner indirection, a] | semmle.label | outer indirection [inner indirection, a] | | qualifiers.cpp:28:16:28:20 | inner indirection [a] | semmle.label | inner indirection [a] | -| qualifiers.cpp:28:16:28:20 | inner indirection [a] | semmle.label | inner indirection [a] | | qualifiers.cpp:28:23:28:23 | a | semmle.label | a | -| qualifiers.cpp:28:23:28:23 | a indirection | semmle.label | a indirection | | qualifiers.cpp:32:17:32:21 | getInner output argument [inner indirection, a] | semmle.label | getInner output argument [inner indirection, a] | | qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] | semmle.label | pointerSetA output argument [a] | | qualifiers.cpp:32:35:32:44 | call to user_input | semmle.label | call to user_input | | qualifiers.cpp:33:10:33:14 | outer indirection [inner indirection, a] | semmle.label | outer indirection [inner indirection, a] | | qualifiers.cpp:33:16:33:20 | inner indirection [a] | semmle.label | inner indirection [a] | -| qualifiers.cpp:33:16:33:20 | inner indirection [a] | semmle.label | inner indirection [a] | | qualifiers.cpp:33:23:33:23 | a | semmle.label | a | -| qualifiers.cpp:33:23:33:23 | a indirection | semmle.label | a indirection | | qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] | semmle.label | referenceSetA output argument [a] | | qualifiers.cpp:37:20:37:24 | getInner output argument [inner indirection, a] | semmle.label | getInner output argument [inner indirection, a] | | qualifiers.cpp:37:38:37:47 | call to user_input | semmle.label | call to user_input | | qualifiers.cpp:38:10:38:14 | outer indirection [inner indirection, a] | semmle.label | outer indirection [inner indirection, a] | | qualifiers.cpp:38:16:38:20 | inner indirection [a] | semmle.label | inner indirection [a] | -| qualifiers.cpp:38:16:38:20 | inner indirection [a] | semmle.label | inner indirection [a] | | qualifiers.cpp:38:23:38:23 | a | semmle.label | a | -| qualifiers.cpp:38:23:38:23 | a indirection | semmle.label | a indirection | | qualifiers.cpp:42:5:42:40 | ... = ... | semmle.label | ... = ... | | qualifiers.cpp:42:7:42:11 | getInner output argument [inner indirection, a] | semmle.label | getInner output argument [inner indirection, a] | | qualifiers.cpp:42:25:42:25 | * ... indirection [post update] [a] | semmle.label | * ... indirection [post update] [a] | | qualifiers.cpp:42:29:42:38 | call to user_input | semmle.label | call to user_input | | qualifiers.cpp:43:10:43:14 | outer indirection [inner indirection, a] | semmle.label | outer indirection [inner indirection, a] | | qualifiers.cpp:43:16:43:20 | inner indirection [a] | semmle.label | inner indirection [a] | -| qualifiers.cpp:43:16:43:20 | inner indirection [a] | semmle.label | inner indirection [a] | | qualifiers.cpp:43:23:43:23 | a | semmle.label | a | -| qualifiers.cpp:43:23:43:23 | a indirection | semmle.label | a indirection | | qualifiers.cpp:47:5:47:42 | ... = ... | semmle.label | ... = ... | | qualifiers.cpp:47:6:47:11 | getInner output argument [inner indirection, a] | semmle.label | getInner output argument [inner indirection, a] | | qualifiers.cpp:47:27:47:27 | call to getInner indirection [post update] [a] | semmle.label | call to getInner indirection [post update] [a] | | qualifiers.cpp:47:31:47:40 | call to user_input | semmle.label | call to user_input | | qualifiers.cpp:48:10:48:14 | outer indirection [inner indirection, a] | semmle.label | outer indirection [inner indirection, a] | | qualifiers.cpp:48:16:48:20 | inner indirection [a] | semmle.label | inner indirection [a] | -| qualifiers.cpp:48:16:48:20 | inner indirection [a] | semmle.label | inner indirection [a] | | qualifiers.cpp:48:23:48:23 | a | semmle.label | a | -| qualifiers.cpp:48:23:48:23 | a indirection | semmle.label | a indirection | | realistic.cpp:53:9:53:66 | ... = ... | semmle.label | ... = ... | | realistic.cpp:53:13:53:15 | foo indirection [post update] [bar, baz indirection, userInput, bufferLen] | semmle.label | foo indirection [post update] [bar, baz indirection, userInput, bufferLen] | | realistic.cpp:53:20:53:22 | access to array indirection [post update] [baz indirection, userInput, bufferLen] | semmle.label | access to array indirection [post update] [baz indirection, userInput, bufferLen] | @@ -1876,19 +1555,15 @@ nodes | realistic.cpp:61:21:61:23 | foo indirection [bar, baz indirection, userInput, bufferLen] | semmle.label | foo indirection [bar, baz indirection, userInput, bufferLen] | | realistic.cpp:61:21:61:30 | access to array indirection [baz indirection, userInput, bufferLen] | semmle.label | access to array indirection [baz indirection, userInput, bufferLen] | | realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | semmle.label | baz indirection [userInput, bufferLen] | -| realistic.cpp:61:32:61:34 | baz indirection [userInput, bufferLen] | semmle.label | baz indirection [userInput, bufferLen] | | realistic.cpp:61:37:61:45 | userInput indirection [bufferLen] | semmle.label | userInput indirection [bufferLen] | | realistic.cpp:61:47:61:55 | bufferLen | semmle.label | bufferLen | -| realistic.cpp:61:47:61:55 | bufferLen indirection | semmle.label | bufferLen indirection | | simple.cpp:18:9:18:9 | a indirection | semmle.label | a indirection | | simple.cpp:18:9:18:9 | this indirection [a_] | semmle.label | this indirection [a_] | | simple.cpp:18:22:18:23 | a_ | semmle.label | a_ | -| simple.cpp:18:22:18:23 | a_ indirection | semmle.label | a_ indirection | | simple.cpp:18:22:18:23 | this indirection [a_] | semmle.label | this indirection [a_] | | simple.cpp:19:9:19:9 | b indirection | semmle.label | b indirection | | simple.cpp:19:9:19:9 | this indirection [b_] | semmle.label | this indirection [b_] | | simple.cpp:19:22:19:23 | b_ | semmle.label | b_ | -| simple.cpp:19:22:19:23 | b_ indirection | semmle.label | b_ indirection | | simple.cpp:19:22:19:23 | this indirection [b_] | semmle.label | this indirection [b_] | | simple.cpp:20:19:20:19 | a | semmle.label | a | | simple.cpp:20:24:20:25 | this indirection [post update] [a_] | semmle.label | this indirection [post update] [a_] | @@ -1919,13 +1594,11 @@ nodes | simple.cpp:65:11:65:20 | call to user_input | semmle.label | call to user_input | | simple.cpp:67:10:67:11 | a2 indirection [i] | semmle.label | a2 indirection [i] | | simple.cpp:67:13:67:13 | i | semmle.label | i | -| simple.cpp:67:13:67:13 | i indirection | semmle.label | i indirection | | simple.cpp:78:9:78:15 | getf2f1 indirection | semmle.label | getf2f1 indirection | | simple.cpp:78:9:78:15 | this indirection [f2, f1] | semmle.label | this indirection [f2, f1] | | simple.cpp:79:16:79:17 | f2 indirection [f1] | semmle.label | f2 indirection [f1] | | simple.cpp:79:16:79:17 | this indirection [f2, f1] | semmle.label | this indirection [f2, f1] | | simple.cpp:79:19:79:20 | f1 | semmle.label | f1 | -| simple.cpp:79:19:79:20 | f1 indirection | semmle.label | f1 indirection | | simple.cpp:83:9:83:10 | this indirection [post update] [f2, f1] | semmle.label | this indirection [post update] [f2, f1] | | simple.cpp:83:9:83:28 | ... = ... | semmle.label | ... = ... | | simple.cpp:83:12:83:13 | f2 indirection [post update] [f1] | semmle.label | f2 indirection [post update] [f1] | @@ -1937,18 +1610,15 @@ nodes | simple.cpp:92:11:92:20 | call to user_input | semmle.label | call to user_input | | simple.cpp:94:10:94:11 | a2 indirection [i] | semmle.label | a2 indirection [i] | | simple.cpp:94:13:94:13 | i | semmle.label | i | -| simple.cpp:94:13:94:13 | i indirection | semmle.label | i indirection | | struct_init.c:14:24:14:25 | ab indirection [a] | semmle.label | ab indirection [a] | | struct_init.c:15:8:15:9 | ab indirection [a] | semmle.label | ab indirection [a] | | struct_init.c:15:12:15:12 | a | semmle.label | a | -| struct_init.c:15:12:15:12 | a indirection | semmle.label | a indirection | | struct_init.c:20:13:20:14 | definition of ab indirection [a] | semmle.label | definition of ab indirection [a] | | struct_init.c:20:17:20:36 | definition of ab indirection [post update] [a] | semmle.label | definition of ab indirection [post update] [a] | | struct_init.c:20:20:20:29 | call to user_input | semmle.label | call to user_input | | struct_init.c:20:20:20:29 | call to user_input | semmle.label | call to user_input | | struct_init.c:22:8:22:9 | ab indirection [a] | semmle.label | ab indirection [a] | | struct_init.c:22:11:22:11 | a | semmle.label | a | -| struct_init.c:22:11:22:11 | a indirection | semmle.label | a indirection | | struct_init.c:24:10:24:12 | & ... indirection [a] | semmle.label | & ... indirection [a] | | struct_init.c:26:16:26:20 | definition of outer indirection [nestedAB, a] | semmle.label | definition of outer indirection [nestedAB, a] | | struct_init.c:26:23:29:3 | definition of outer indirection [post update] [nestedAB, a] | semmle.label | definition of outer indirection [post update] [nestedAB, a] | @@ -1961,12 +1631,9 @@ nodes | struct_init.c:31:8:31:12 | outer indirection [nestedAB, a] | semmle.label | outer indirection [nestedAB, a] | | struct_init.c:31:14:31:21 | nestedAB indirection [a] | semmle.label | nestedAB indirection [a] | | struct_init.c:31:23:31:23 | a | semmle.label | a | -| struct_init.c:31:23:31:23 | a indirection | semmle.label | a indirection | | struct_init.c:33:8:33:12 | outer indirection [pointerAB indirection, a] | semmle.label | outer indirection [pointerAB indirection, a] | | struct_init.c:33:14:33:22 | pointerAB indirection [a] | semmle.label | pointerAB indirection [a] | -| struct_init.c:33:14:33:22 | pointerAB indirection [a] | semmle.label | pointerAB indirection [a] | | struct_init.c:33:25:33:25 | a | semmle.label | a | -| struct_init.c:33:25:33:25 | a indirection | semmle.label | a indirection | | struct_init.c:36:10:36:24 | & ... indirection [a] | semmle.label | & ... indirection [a] | | struct_init.c:36:11:36:15 | outer indirection [nestedAB, a] | semmle.label | outer indirection [nestedAB, a] | | struct_init.c:40:13:40:14 | definition of ab indirection [a] | semmle.label | definition of ab indirection [a] | @@ -1977,7 +1644,6 @@ nodes | struct_init.c:43:5:43:7 | & ... indirection [a] | semmle.label | & ... indirection [a] | | struct_init.c:46:10:46:14 | outer indirection [pointerAB indirection, a] | semmle.label | outer indirection [pointerAB indirection, a] | | struct_init.c:46:16:46:24 | pointerAB indirection [a] | semmle.label | pointerAB indirection [a] | -| struct_init.c:46:16:46:24 | pointerAB indirection [a] | semmle.label | pointerAB indirection [a] | subpaths | A.cpp:31:20:31:20 | c | A.cpp:23:10:23:10 | c | A.cpp:25:13:25:13 | this indirection [post update] [c] | A.cpp:31:14:31:21 | call to B [c] | | A.cpp:48:20:48:20 | c | A.cpp:29:23:29:23 | c | A.cpp:29:15:29:18 | make indirection [c] | A.cpp:48:12:48:18 | call to make indirection [c] | @@ -2084,7 +1750,6 @@ subpaths | D.cpp:64:25:64:28 | elem | D.cpp:56:15:56:24 | new | D.cpp:64:25:64:28 | elem | elem flows from $@ | D.cpp:56:15:56:24 | new | new | | E.cpp:21:18:21:23 | buffer indirection | E.cpp:30:21:30:33 | argument_source output argument | E.cpp:21:18:21:23 | buffer indirection | buffer indirection flows from $@ | E.cpp:30:21:30:33 | argument_source output argument | argument_source output argument | | E.cpp:31:10:31:12 | raw indirection | E.cpp:28:21:28:23 | argument_source output argument | E.cpp:31:10:31:12 | raw indirection | raw indirection flows from $@ | E.cpp:28:21:28:23 | argument_source output argument | argument_source output argument | -| E.cpp:31:10:31:12 | raw indirection | E.cpp:28:21:28:23 | argument_source output argument | E.cpp:31:10:31:12 | raw indirection | raw indirection flows from $@ | E.cpp:28:21:28:23 | argument_source output argument | argument_source output argument | | E.cpp:32:13:32:18 | buffer indirection | E.cpp:29:21:29:29 | argument_source output argument | E.cpp:32:13:32:18 | buffer indirection | buffer indirection flows from $@ | E.cpp:29:21:29:29 | argument_source output argument | argument_source output argument | | aliasing.cpp:29:11:29:12 | m1 | aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:29:11:29:12 | m1 | m1 flows from $@ | aliasing.cpp:9:11:9:20 | call to user_input | call to user_input | | aliasing.cpp:30:11:30:12 | m1 | aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:30:11:30:12 | m1 | m1 flows from $@ | aliasing.cpp:13:10:13:19 | call to user_input | call to user_input | @@ -2147,7 +1812,6 @@ subpaths | conflated.cpp:11:8:11:12 | * ... | conflated.cpp:10:11:10:20 | call to user_input | conflated.cpp:11:8:11:12 | * ... | * ... flows from $@ | conflated.cpp:10:11:10:20 | call to user_input | call to user_input | | conflated.cpp:20:8:20:10 | raw indirection | conflated.cpp:19:19:19:21 | argument_source output argument | conflated.cpp:20:8:20:10 | raw indirection | raw indirection flows from $@ | conflated.cpp:19:19:19:21 | argument_source output argument | argument_source output argument | | conflated.cpp:20:8:20:10 | raw indirection | conflated.cpp:19:19:19:21 | argument_source output argument | conflated.cpp:20:8:20:10 | raw indirection | raw indirection flows from $@ | conflated.cpp:19:19:19:21 | argument_source output argument | argument_source output argument | -| conflated.cpp:20:8:20:10 | raw indirection | conflated.cpp:19:19:19:21 | argument_source output argument | conflated.cpp:20:8:20:10 | raw indirection | raw indirection flows from $@ | conflated.cpp:19:19:19:21 | argument_source output argument | argument_source output argument | | conflated.cpp:30:12:30:12 | x | conflated.cpp:29:11:29:20 | call to user_input | conflated.cpp:30:12:30:12 | x | x flows from $@ | conflated.cpp:29:11:29:20 | call to user_input | call to user_input | | conflated.cpp:37:12:37:12 | x | conflated.cpp:36:11:36:20 | call to user_input | conflated.cpp:37:12:37:12 | x | x flows from $@ | conflated.cpp:36:11:36:20 | call to user_input | call to user_input | | conflated.cpp:55:18:55:18 | y | conflated.cpp:54:17:54:26 | call to user_input | conflated.cpp:55:18:55:18 | y | y flows from $@ | conflated.cpp:54:17:54:26 | call to user_input | call to user_input | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 97e2352000a..0065ae75d21 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -3,5 +3,5 @@ WARNING: Module DataFlow has been deprecated and may be removed in future (taint WARNING: Module DataFlow has been deprecated and may be removed in future (taint.ql:61,22-30) WARNING: Module DataFlow has been deprecated and may be removed in future (taint.ql:68,25-33) WARNING: Module TaintTracking has been deprecated and may be removed in future (taint.ql:73,20-33) -failures testFailures +failures diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 02e9045bcdb..9c261125c2f 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -15553,6 +15553,193 @@ ir.cpp: # 2030| Type = [IntType] int # 2030| ValueCategory = prvalue # 2031| getStmt(2): [ReturnStmt] return ... +# 2033| [TopLevelFunction] void NewDeleteMem() +# 2033| : +# 2033| getEntryPoint(): [BlockStmt] { ... } +# 2034| getStmt(0): [DeclStmt] declaration +# 2034| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2034| Type = [IntPointerType] int * +# 2034| getVariable().getInitializer(): [Initializer] initializer for x +# 2034| getExpr(): [NewExpr] new +# 2034| Type = [IntPointerType] int * +# 2034| ValueCategory = prvalue +# 2035| getStmt(1): [ExprStmt] ExprStmt +# 2035| getExpr(): [AssignExpr] ... = ... +# 2035| Type = [IntType] int +# 2035| ValueCategory = lvalue +# 2035| getLValue(): [PointerDereferenceExpr] * ... +# 2035| Type = [IntType] int +# 2035| ValueCategory = lvalue +# 2035| getOperand(): [VariableAccess] x +# 2035| Type = [IntPointerType] int * +# 2035| ValueCategory = prvalue(load) +# 2035| getRValue(): [Literal] 6 +# 2035| Type = [IntType] int +# 2035| Value = [Literal] 6 +# 2035| ValueCategory = prvalue +# 2036| getStmt(2): [ExprStmt] ExprStmt +# 2036| getExpr(): [DeleteExpr] delete +# 2036| Type = [VoidType] void +# 2036| ValueCategory = prvalue +# 2036| getExpr(): [VariableAccess] x +# 2036| Type = [IntPointerType] int * +# 2036| ValueCategory = prvalue(load) +# 2037| getStmt(3): [ReturnStmt] return ... +# 2039| [CopyAssignmentOperator] Base2& Base2::operator=(Base2 const&) +# 2039| : +#-----| getParameter(0): [Parameter] (unnamed parameter 0) +#-----| Type = [LValueReferenceType] const Base2 & +# 2039| [Constructor] void Base2::Base2() +# 2039| : +# 2039| : +# 2039| getEntryPoint(): [BlockStmt] { ... } +# 2039| getStmt(0): [ReturnStmt] return ... +# 2039| [CopyConstructor] void Base2::Base2(Base2 const&) +# 2039| : +#-----| getParameter(0): [Parameter] (unnamed parameter 0) +#-----| Type = [LValueReferenceType] const Base2 & +# 2041| [MemberFunction] void Base2::operator delete(void*) +# 2041| : +# 2041| getParameter(0): [Parameter] p +# 2041| Type = [VoidPointerType] void * +# 2041| getEntryPoint(): [BlockStmt] { ... } +# 2042| getStmt(0): [ReturnStmt] return ... +# 2043| [Destructor,VirtualFunction] void Base2::~Base2() +# 2043| : +# 2043| getEntryPoint(): [BlockStmt] { ... } +# 2043| getStmt(0): [ReturnStmt] return ... +# 2043| : +# 2046| [CopyAssignmentOperator] Derived2& Derived2::operator=(Derived2 const&) +# 2046| : +#-----| getParameter(0): [Parameter] (unnamed parameter 0) +#-----| Type = [LValueReferenceType] const Derived2 & +# 2046| [Constructor] void Derived2::Derived2() +# 2046| : +# 2046| : +# 2046| getInitializer(0): [ConstructorDirectInit] call to Base2 +# 2046| Type = [VoidType] void +# 2046| ValueCategory = prvalue +# 2046| getEntryPoint(): [BlockStmt] { ... } +# 2046| getStmt(0): [ReturnStmt] return ... +# 2046| [CopyConstructor] void Derived2::Derived2(Derived2 const&) +# 2046| : +#-----| getParameter(0): [Parameter] (unnamed parameter 0) +#-----| Type = [LValueReferenceType] const Derived2 & +# 2049| [Destructor,VirtualFunction] void Derived2::~Derived2() +# 2049| : +# 2049| getEntryPoint(): [BlockStmt] { ... } +# 2049| getStmt(0): [ReturnStmt] return ... +# 2049| : +# 2049| getDestruction(0): [DestructorDirectDestruction] call to ~Base2 +# 2049| Type = [VoidType] void +# 2049| ValueCategory = prvalue +# 2051| [MemberFunction] void Derived2::operator delete(void*) +# 2051| : +# 2051| getParameter(0): [Parameter] p +# 2051| Type = [VoidPointerType] void * +# 2051| getEntryPoint(): [BlockStmt] { ... } +# 2052| getStmt(0): [ReturnStmt] return ... +# 2056| [TopLevelFunction] int virtual_delete() +# 2056| : +# 2057| getEntryPoint(): [BlockStmt] { ... } +# 2058| getStmt(0): [DeclStmt] declaration +# 2058| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b1 +# 2058| Type = [PointerType] Base2 * +# 2058| getVariable().getInitializer(): [Initializer] initializer for b1 +# 2058| getExpr(): [NewExpr] new +# 2058| Type = [PointerType] Base2 * +# 2058| ValueCategory = prvalue +# 2058| getInitializer(): [ConstructorCall] call to Base2 +# 2058| Type = [VoidType] void +# 2058| ValueCategory = prvalue +# 2059| getStmt(1): [ExprStmt] ExprStmt +# 2059| getExpr(): [DeleteExpr] delete +# 2059| Type = [VoidType] void +# 2059| ValueCategory = prvalue +# 2059| getDeallocatorCall(): [FunctionCall] call to operator delete +# 2059| Type = [VoidType] void +# 2059| ValueCategory = prvalue +# 2059| getDestructorCall(): [DestructorCall] call to ~Base2 +# 2059| Type = [VoidType] void +# 2059| ValueCategory = prvalue +# 2059| getQualifier(): [VariableAccess] b1 +# 2059| Type = [PointerType] Base2 * +# 2059| ValueCategory = prvalue(load) +# 2061| getStmt(2): [DeclStmt] declaration +# 2061| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b2 +# 2061| Type = [PointerType] Base2 * +# 2061| getVariable().getInitializer(): [Initializer] initializer for b2 +# 2061| getExpr(): [NewExpr] new +# 2061| Type = [PointerType] Derived2 * +# 2061| ValueCategory = prvalue +# 2061| getInitializer(): [ConstructorCall] call to Derived2 +# 2061| Type = [VoidType] void +# 2061| ValueCategory = prvalue +# 2061| getExpr().getFullyConverted(): [CStyleCast] (Base2 *)... +# 2061| Conversion = [BaseClassConversion] base class conversion +# 2061| Type = [PointerType] Base2 * +# 2061| ValueCategory = prvalue +# 2062| getStmt(3): [ExprStmt] ExprStmt +# 2062| getExpr(): [DeleteExpr] delete +# 2062| Type = [VoidType] void +# 2062| ValueCategory = prvalue +# 2062| getDeallocatorCall(): [FunctionCall] call to operator delete +# 2062| Type = [VoidType] void +# 2062| ValueCategory = prvalue +# 2062| getDestructorCall(): [DestructorCall] call to ~Base2 +# 2062| Type = [VoidType] void +# 2062| ValueCategory = prvalue +# 2062| getQualifier(): [VariableAccess] b2 +# 2062| Type = [PointerType] Base2 * +# 2062| ValueCategory = prvalue(load) +# 2064| getStmt(4): [DeclStmt] declaration +# 2064| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d +# 2064| Type = [PointerType] Derived2 * +# 2064| getVariable().getInitializer(): [Initializer] initializer for d +# 2064| getExpr(): [NewExpr] new +# 2064| Type = [PointerType] Derived2 * +# 2064| ValueCategory = prvalue +# 2064| getInitializer(): [ConstructorCall] call to Derived2 +# 2064| Type = [VoidType] void +# 2064| ValueCategory = prvalue +# 2065| getStmt(5): [ExprStmt] ExprStmt +# 2065| getExpr(): [DeleteExpr] delete +# 2065| Type = [VoidType] void +# 2065| ValueCategory = prvalue +# 2065| getDeallocatorCall(): [FunctionCall] call to operator delete +# 2065| Type = [VoidType] void +# 2065| ValueCategory = prvalue +# 2065| getDestructorCall(): [DestructorCall] call to ~Derived2 +# 2065| Type = [VoidType] void +# 2065| ValueCategory = prvalue +# 2065| getQualifier(): [VariableAccess] d +# 2065| Type = [PointerType] Derived2 * +# 2065| ValueCategory = prvalue(load) +# 2066| getStmt(6): [ReturnStmt] return ... +# 2068| [TopLevelFunction] void test_constant_folding_use(int) +# 2068| : +# 2068| getParameter(0): [Parameter] (unnamed parameter 0) +# 2068| Type = [IntType] int +# 2070| [TopLevelFunction] void test_constant_folding() +# 2070| : +# 2070| getEntryPoint(): [BlockStmt] { ... } +# 2071| getStmt(0): [DeclStmt] declaration +# 2071| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x +# 2071| Type = [SpecifiedType] const int +# 2071| getVariable().getInitializer(): [Initializer] initializer for x +# 2071| getExpr(): [Literal] 116 +# 2071| Type = [IntType] int +# 2071| Value = [Literal] 116 +# 2071| ValueCategory = prvalue +# 2072| getStmt(1): [ExprStmt] ExprStmt +# 2072| getExpr(): [FunctionCall] call to test_constant_folding_use +# 2072| Type = [VoidType] void +# 2072| ValueCategory = prvalue +# 2072| getArgument(0): [VariableAccess] x +# 2072| Type = [IntType] int +# 2072| Value = [VariableAccess] 116 +# 2072| ValueCategory = prvalue(load) +# 2073| getStmt(2): [ReturnStmt] return ... perf-regression.cpp: # 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&) # 4| : diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index 44f88d23166..e3de7919375 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -2030,4 +2030,46 @@ unsigned int CommaTest(unsigned int x) { (CommaTestHelper(x), 10); } +void NewDeleteMem() { + int* x = new int; // No constructor + *x = 6; + delete x; +} + +class Base2 { +public: + void operator delete(void* p) { + } + virtual ~Base2() {}; +}; + +class Derived2 : public Base2 { + int i; +public: + ~Derived2() {}; + + void operator delete(void* p) { + } +}; + +// Delete is kind-of virtual in these cases +int virtual_delete() +{ + Base2* b1 = new Base2{}; + delete b1; + + Base2* b2 = new Derived2{}; + delete b2; + + Derived2* d = new Derived2{}; + delete d; +} + +void test_constant_folding_use(int); + +void test_constant_folding() { + const int x = 116; + test_constant_folding_use(x); +} + // semmle-extractor-options: -std=c++17 --clang diff --git a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected index bfe31bbefe7..e8a8d7e06b7 100644 --- a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected +++ b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected @@ -4887,10 +4887,60 @@ | ir.cpp:1011:12:1011:12 | Unary | r1011_3 | | ir.cpp:1015:6:1015:19 | ChiPartial | partial:m1015_3 | | ir.cpp:1015:6:1015:19 | ChiTotal | total:m1015_2 | -| ir.cpp:1015:6:1015:19 | SideEffect | m1015_3 | +| ir.cpp:1015:6:1015:19 | SideEffect | ~m1020_5 | +| ir.cpp:1016:3:1016:35 | CallTarget | func:r1016_1 | +| ir.cpp:1016:3:1016:35 | ChiPartial | partial:m1016_4 | +| ir.cpp:1016:3:1016:35 | ChiTotal | total:m1015_4 | +| ir.cpp:1016:3:1016:35 | SideEffect | ~m1015_4 | +| ir.cpp:1016:10:1016:35 | Arg(0) | 0:r1016_2 | +| ir.cpp:1017:3:1017:38 | CallTarget | func:r1017_1 | +| ir.cpp:1017:3:1017:38 | ChiPartial | partial:m1017_4 | +| ir.cpp:1017:3:1017:38 | ChiTotal | total:m1016_5 | +| ir.cpp:1017:3:1017:38 | SideEffect | ~m1016_5 | +| ir.cpp:1017:10:1017:38 | Arg(0) | 0:r1017_2 | +| ir.cpp:1018:3:1018:44 | CallTarget | func:r1018_1 | +| ir.cpp:1018:3:1018:44 | ChiPartial | partial:m1018_4 | +| ir.cpp:1018:3:1018:44 | ChiTotal | total:m1017_5 | +| ir.cpp:1018:3:1018:44 | SideEffect | ~m1017_5 | +| ir.cpp:1018:10:1018:44 | Arg(0) | 0:r1018_2 | +| ir.cpp:1019:3:1019:43 | CallTarget | func:r1019_1 | +| ir.cpp:1019:3:1019:43 | ChiPartial | partial:m1019_4 | +| ir.cpp:1019:3:1019:43 | ChiTotal | total:m1018_5 | +| ir.cpp:1019:3:1019:43 | SideEffect | ~m1018_5 | +| ir.cpp:1019:10:1019:43 | Arg(0) | 0:r1019_2 | +| ir.cpp:1020:3:1020:47 | CallTarget | func:r1020_1 | +| ir.cpp:1020:3:1020:47 | ChiPartial | partial:m1020_4 | +| ir.cpp:1020:3:1020:47 | ChiTotal | total:m1019_5 | +| ir.cpp:1020:3:1020:47 | SideEffect | ~m1019_5 | +| ir.cpp:1020:10:1020:47 | Arg(0) | 0:r1020_2 | | ir.cpp:1024:6:1024:24 | ChiPartial | partial:m1024_3 | | ir.cpp:1024:6:1024:24 | ChiTotal | total:m1024_2 | -| ir.cpp:1024:6:1024:24 | SideEffect | m1024_3 | +| ir.cpp:1024:6:1024:24 | SideEffect | ~m1029_5 | +| ir.cpp:1025:3:1025:37 | CallTarget | func:r1025_1 | +| ir.cpp:1025:3:1025:37 | ChiPartial | partial:m1025_4 | +| ir.cpp:1025:3:1025:37 | ChiTotal | total:m1024_4 | +| ir.cpp:1025:3:1025:37 | SideEffect | ~m1024_4 | +| ir.cpp:1025:12:1025:37 | Arg(0) | 0:r1025_2 | +| ir.cpp:1026:3:1026:40 | CallTarget | func:r1026_1 | +| ir.cpp:1026:3:1026:40 | ChiPartial | partial:m1026_4 | +| ir.cpp:1026:3:1026:40 | ChiTotal | total:m1025_5 | +| ir.cpp:1026:3:1026:40 | SideEffect | ~m1025_5 | +| ir.cpp:1026:12:1026:40 | Arg(0) | 0:r1026_2 | +| ir.cpp:1027:3:1027:46 | CallTarget | func:r1027_1 | +| ir.cpp:1027:3:1027:46 | ChiPartial | partial:m1027_4 | +| ir.cpp:1027:3:1027:46 | ChiTotal | total:m1026_5 | +| ir.cpp:1027:3:1027:46 | SideEffect | ~m1026_5 | +| ir.cpp:1027:12:1027:46 | Arg(0) | 0:r1027_2 | +| ir.cpp:1028:3:1028:45 | CallTarget | func:r1028_1 | +| ir.cpp:1028:3:1028:45 | ChiPartial | partial:m1028_4 | +| ir.cpp:1028:3:1028:45 | ChiTotal | total:m1027_5 | +| ir.cpp:1028:3:1028:45 | SideEffect | ~m1027_5 | +| ir.cpp:1028:12:1028:45 | Arg(0) | 0:r1028_2 | +| ir.cpp:1029:3:1029:49 | CallTarget | func:r1029_1 | +| ir.cpp:1029:3:1029:49 | ChiPartial | partial:m1029_4 | +| ir.cpp:1029:3:1029:49 | ChiTotal | total:m1028_5 | +| ir.cpp:1029:3:1029:49 | SideEffect | ~m1028_5 | +| ir.cpp:1029:12:1029:49 | Arg(0) | 0:r1029_2 | | ir.cpp:1034:6:1034:20 | ChiPartial | partial:m1034_3 | | ir.cpp:1034:6:1034:20 | ChiTotal | total:m1034_2 | | ir.cpp:1034:6:1034:20 | SideEffect | m1034_3 | @@ -9576,6 +9626,186 @@ | ir.cpp:2030:22:2030:22 | Arg(0) | 0:r2030_3 | | ir.cpp:2030:22:2030:22 | Load | m2026_6 | | ir.cpp:2030:26:2030:27 | Unary | r2030_7 | +| ir.cpp:2033:6:2033:17 | ChiPartial | partial:m2033_3 | +| ir.cpp:2033:6:2033:17 | ChiTotal | total:m2033_2 | +| ir.cpp:2033:6:2033:17 | SideEffect | ~m2036_6 | +| ir.cpp:2034:8:2034:8 | Address | &:r2034_1 | +| ir.cpp:2034:12:2034:18 | Address | &:r2034_4 | +| ir.cpp:2034:12:2034:18 | Arg(0) | 0:r2034_3 | +| ir.cpp:2034:12:2034:18 | CallTarget | func:r2034_2 | +| ir.cpp:2034:12:2034:18 | ChiPartial | partial:m2034_5 | +| ir.cpp:2034:12:2034:18 | ChiTotal | total:m2033_4 | +| ir.cpp:2034:12:2034:18 | SideEffect | ~m2033_4 | +| ir.cpp:2034:12:2034:18 | StoreValue | r2034_8 | +| ir.cpp:2034:12:2034:18 | Unary | r2034_4 | +| ir.cpp:2035:3:2035:4 | Address | &:r2035_4 | +| ir.cpp:2035:3:2035:8 | ChiPartial | partial:m2035_5 | +| ir.cpp:2035:3:2035:8 | ChiTotal | total:m2034_7 | +| ir.cpp:2035:4:2035:4 | Address | &:r2035_2 | +| ir.cpp:2035:4:2035:4 | Load | m2034_9 | +| ir.cpp:2035:4:2035:4 | Unary | r2035_3 | +| ir.cpp:2035:8:2035:8 | StoreValue | r2035_1 | +| ir.cpp:2036:3:2036:10 | CallTarget | func:r2036_1 | +| ir.cpp:2036:3:2036:10 | ChiPartial | partial:m2036_5 | +| ir.cpp:2036:3:2036:10 | ChiTotal | total:m2034_6 | +| ir.cpp:2036:3:2036:10 | SideEffect | ~m2034_6 | +| ir.cpp:2036:10:2036:10 | Address | &:r2036_2 | +| ir.cpp:2036:10:2036:10 | Arg(0) | 0:r2036_3 | +| ir.cpp:2036:10:2036:10 | Load | m2034_9 | +| ir.cpp:2039:7:2039:7 | Address | &:r2039_5 | +| ir.cpp:2039:7:2039:7 | Address | &:r2039_5 | +| ir.cpp:2039:7:2039:7 | Address | &:r2039_7 | +| ir.cpp:2039:7:2039:7 | Address | &:r2039_7 | +| ir.cpp:2039:7:2039:7 | ChiPartial | partial:m2039_3 | +| ir.cpp:2039:7:2039:7 | ChiTotal | total:m2039_2 | +| ir.cpp:2039:7:2039:7 | Load | m2039_6 | +| ir.cpp:2039:7:2039:7 | SideEffect | m2039_3 | +| ir.cpp:2039:7:2039:7 | SideEffect | m2039_8 | +| ir.cpp:2041:10:2041:24 | ChiPartial | partial:m2041_3 | +| ir.cpp:2041:10:2041:24 | ChiTotal | total:m2041_2 | +| ir.cpp:2041:10:2041:24 | SideEffect | m2041_3 | +| ir.cpp:2041:32:2041:32 | Address | &:r2041_5 | +| ir.cpp:2041:32:2041:32 | Address | &:r2041_5 | +| ir.cpp:2041:32:2041:32 | Address | &:r2041_7 | +| ir.cpp:2041:32:2041:32 | Address | &:r2041_7 | +| ir.cpp:2041:32:2041:32 | Load | m2041_6 | +| ir.cpp:2041:32:2041:32 | SideEffect | m2041_8 | +| ir.cpp:2043:13:2043:18 | Address | &:r2043_5 | +| ir.cpp:2043:13:2043:18 | Address | &:r2043_5 | +| ir.cpp:2043:13:2043:18 | Address | &:r2043_7 | +| ir.cpp:2043:13:2043:18 | Address | &:r2043_7 | +| ir.cpp:2043:13:2043:18 | ChiPartial | partial:m2043_3 | +| ir.cpp:2043:13:2043:18 | ChiTotal | total:m2043_2 | +| ir.cpp:2043:13:2043:18 | Load | m2043_6 | +| ir.cpp:2043:13:2043:18 | SideEffect | m2043_3 | +| ir.cpp:2043:13:2043:18 | SideEffect | m2043_8 | +| ir.cpp:2046:7:2046:7 | Address | &:r2046_5 | +| ir.cpp:2046:7:2046:7 | Address | &:r2046_5 | +| ir.cpp:2046:7:2046:7 | Address | &:r2046_7 | +| ir.cpp:2046:7:2046:7 | Address | &:r2046_7 | +| ir.cpp:2046:7:2046:7 | Address | &:r2046_9 | +| ir.cpp:2046:7:2046:7 | Arg(this) | this:r2046_9 | +| ir.cpp:2046:7:2046:7 | CallTarget | func:r2046_10 | +| ir.cpp:2046:7:2046:7 | ChiPartial | partial:m2046_3 | +| ir.cpp:2046:7:2046:7 | ChiPartial | partial:m2046_12 | +| ir.cpp:2046:7:2046:7 | ChiPartial | partial:m2046_14 | +| ir.cpp:2046:7:2046:7 | ChiTotal | total:m2046_2 | +| ir.cpp:2046:7:2046:7 | ChiTotal | total:m2046_4 | +| ir.cpp:2046:7:2046:7 | ChiTotal | total:m2046_8 | +| ir.cpp:2046:7:2046:7 | Load | m2046_6 | +| ir.cpp:2046:7:2046:7 | SideEffect | m2046_15 | +| ir.cpp:2046:7:2046:7 | SideEffect | ~m2046_4 | +| ir.cpp:2046:7:2046:7 | SideEffect | ~m2046_13 | +| ir.cpp:2046:7:2046:7 | Unary | m2046_6 | +| ir.cpp:2049:5:2049:13 | Address | &:r2049_5 | +| ir.cpp:2049:5:2049:13 | Address | &:r2049_5 | +| ir.cpp:2049:5:2049:13 | Address | &:r2049_7 | +| ir.cpp:2049:5:2049:13 | Address | &:r2049_7 | +| ir.cpp:2049:5:2049:13 | ChiPartial | partial:m2049_3 | +| ir.cpp:2049:5:2049:13 | ChiTotal | total:m2049_2 | +| ir.cpp:2049:5:2049:13 | Load | m2049_6 | +| ir.cpp:2049:5:2049:13 | SideEffect | m2049_8 | +| ir.cpp:2049:5:2049:13 | SideEffect | ~m2049_14 | +| ir.cpp:2049:5:2049:13 | Unary | m2049_6 | +| ir.cpp:2049:18:2049:18 | Arg(this) | this:r2049_10 | +| ir.cpp:2049:18:2049:18 | CallTarget | func:r2049_11 | +| ir.cpp:2049:18:2049:18 | ChiPartial | partial:m2049_13 | +| ir.cpp:2049:18:2049:18 | ChiTotal | total:m2049_4 | +| ir.cpp:2049:18:2049:18 | SideEffect | ~m2049_4 | +| ir.cpp:2051:10:2051:24 | ChiPartial | partial:m2051_3 | +| ir.cpp:2051:10:2051:24 | ChiTotal | total:m2051_2 | +| ir.cpp:2051:10:2051:24 | SideEffect | m2051_3 | +| ir.cpp:2051:32:2051:32 | Address | &:r2051_5 | +| ir.cpp:2051:32:2051:32 | Address | &:r2051_5 | +| ir.cpp:2051:32:2051:32 | Address | &:r2051_7 | +| ir.cpp:2051:32:2051:32 | Address | &:r2051_7 | +| ir.cpp:2051:32:2051:32 | Load | m2051_6 | +| ir.cpp:2051:32:2051:32 | SideEffect | m2051_8 | +| ir.cpp:2056:5:2056:18 | ChiPartial | partial:m2056_3 | +| ir.cpp:2056:5:2056:18 | ChiTotal | total:m2056_2 | +| ir.cpp:2058:12:2058:13 | Address | &:r2058_1 | +| ir.cpp:2058:17:2058:27 | Address | &:r2058_4 | +| ir.cpp:2058:17:2058:27 | Address | &:r2058_8 | +| ir.cpp:2058:17:2058:27 | Arg(0) | 0:r2058_3 | +| ir.cpp:2058:17:2058:27 | Arg(this) | this:r2058_8 | +| ir.cpp:2058:17:2058:27 | CallTarget | func:r2058_2 | +| ir.cpp:2058:17:2058:27 | CallTarget | func:r2058_9 | +| ir.cpp:2058:17:2058:27 | ChiPartial | partial:m2058_5 | +| ir.cpp:2058:17:2058:27 | ChiPartial | partial:m2058_11 | +| ir.cpp:2058:17:2058:27 | ChiPartial | partial:m2058_13 | +| ir.cpp:2058:17:2058:27 | ChiTotal | total:m2056_4 | +| ir.cpp:2058:17:2058:27 | ChiTotal | total:m2058_6 | +| ir.cpp:2058:17:2058:27 | ChiTotal | total:m2058_7 | +| ir.cpp:2058:17:2058:27 | SideEffect | ~m2056_4 | +| ir.cpp:2058:17:2058:27 | SideEffect | ~m2058_6 | +| ir.cpp:2058:17:2058:27 | StoreValue | r2058_8 | +| ir.cpp:2058:17:2058:27 | Unary | r2058_4 | +| ir.cpp:2059:5:2059:13 | CallTarget | func:r2059_1 | +| ir.cpp:2059:5:2059:13 | ChiPartial | partial:m2059_5 | +| ir.cpp:2059:5:2059:13 | ChiTotal | total:m2058_12 | +| ir.cpp:2059:5:2059:13 | SideEffect | ~m2058_12 | +| ir.cpp:2059:12:2059:13 | Address | &:r2059_2 | +| ir.cpp:2059:12:2059:13 | Arg(0) | 0:r2059_3 | +| ir.cpp:2059:12:2059:13 | Load | m2058_15 | +| ir.cpp:2061:12:2061:13 | Address | &:r2061_1 | +| ir.cpp:2061:17:2061:30 | Address | &:r2061_4 | +| ir.cpp:2061:17:2061:30 | Address | &:r2061_8 | +| ir.cpp:2061:17:2061:30 | Arg(0) | 0:r2061_3 | +| ir.cpp:2061:17:2061:30 | Arg(this) | this:r2061_8 | +| ir.cpp:2061:17:2061:30 | CallTarget | func:r2061_2 | +| ir.cpp:2061:17:2061:30 | CallTarget | func:r2061_9 | +| ir.cpp:2061:17:2061:30 | ChiPartial | partial:m2061_5 | +| ir.cpp:2061:17:2061:30 | ChiPartial | partial:m2061_11 | +| ir.cpp:2061:17:2061:30 | ChiPartial | partial:m2061_13 | +| ir.cpp:2061:17:2061:30 | ChiTotal | total:m2059_6 | +| ir.cpp:2061:17:2061:30 | ChiTotal | total:m2061_6 | +| ir.cpp:2061:17:2061:30 | ChiTotal | total:m2061_7 | +| ir.cpp:2061:17:2061:30 | SideEffect | ~m2059_6 | +| ir.cpp:2061:17:2061:30 | SideEffect | ~m2061_6 | +| ir.cpp:2061:17:2061:30 | StoreValue | r2061_15 | +| ir.cpp:2061:17:2061:30 | Unary | r2061_4 | +| ir.cpp:2061:17:2061:30 | Unary | r2061_8 | +| ir.cpp:2062:5:2062:13 | CallTarget | func:r2062_1 | +| ir.cpp:2062:5:2062:13 | ChiPartial | partial:m2062_5 | +| ir.cpp:2062:5:2062:13 | ChiTotal | total:m2061_12 | +| ir.cpp:2062:5:2062:13 | SideEffect | ~m2061_12 | +| ir.cpp:2062:12:2062:13 | Address | &:r2062_2 | +| ir.cpp:2062:12:2062:13 | Arg(0) | 0:r2062_3 | +| ir.cpp:2062:12:2062:13 | Load | m2061_16 | +| ir.cpp:2064:15:2064:15 | Address | &:r2064_1 | +| ir.cpp:2064:19:2064:32 | Address | &:r2064_4 | +| ir.cpp:2064:19:2064:32 | Address | &:r2064_8 | +| ir.cpp:2064:19:2064:32 | Arg(0) | 0:r2064_3 | +| ir.cpp:2064:19:2064:32 | Arg(this) | this:r2064_8 | +| ir.cpp:2064:19:2064:32 | CallTarget | func:r2064_2 | +| ir.cpp:2064:19:2064:32 | CallTarget | func:r2064_9 | +| ir.cpp:2064:19:2064:32 | ChiPartial | partial:m2064_5 | +| ir.cpp:2064:19:2064:32 | ChiPartial | partial:m2064_11 | +| ir.cpp:2064:19:2064:32 | ChiPartial | partial:m2064_13 | +| ir.cpp:2064:19:2064:32 | ChiTotal | total:m2062_6 | +| ir.cpp:2064:19:2064:32 | ChiTotal | total:m2064_6 | +| ir.cpp:2064:19:2064:32 | ChiTotal | total:m2064_7 | +| ir.cpp:2064:19:2064:32 | SideEffect | ~m2062_6 | +| ir.cpp:2064:19:2064:32 | SideEffect | ~m2064_6 | +| ir.cpp:2064:19:2064:32 | StoreValue | r2064_8 | +| ir.cpp:2064:19:2064:32 | Unary | r2064_4 | +| ir.cpp:2065:5:2065:12 | CallTarget | func:r2065_1 | +| ir.cpp:2065:5:2065:12 | ChiPartial | partial:m2065_5 | +| ir.cpp:2065:5:2065:12 | ChiTotal | total:m2064_12 | +| ir.cpp:2065:5:2065:12 | SideEffect | ~m2064_12 | +| ir.cpp:2065:12:2065:12 | Address | &:r2065_2 | +| ir.cpp:2065:12:2065:12 | Arg(0) | 0:r2065_3 | +| ir.cpp:2065:12:2065:12 | Load | m2064_15 | +| ir.cpp:2070:6:2070:26 | ChiPartial | partial:m2070_3 | +| ir.cpp:2070:6:2070:26 | ChiTotal | total:m2070_2 | +| ir.cpp:2070:6:2070:26 | SideEffect | ~m2072_5 | +| ir.cpp:2071:13:2071:13 | Address | &:r2071_1 | +| ir.cpp:2071:16:2071:19 | StoreValue | r2071_2 | +| ir.cpp:2072:3:2072:27 | CallTarget | func:r2072_1 | +| ir.cpp:2072:3:2072:27 | ChiPartial | partial:m2072_4 | +| ir.cpp:2072:3:2072:27 | ChiTotal | total:m2070_4 | +| ir.cpp:2072:3:2072:27 | SideEffect | ~m2070_4 | +| ir.cpp:2072:29:2072:29 | Arg(0) | 0:r2072_2 | | perf-regression.cpp:6:3:6:5 | Address | &:r6_5 | | perf-regression.cpp:6:3:6:5 | Address | &:r6_5 | | perf-regression.cpp:6:3:6:5 | Address | &:r6_7 | diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 019199d980d..8bb7c6dde6a 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -5663,43 +5663,63 @@ ir.cpp: # 1015| void OperatorDelete() # 1015| Block 0 -# 1015| v1015_1(void) = EnterFunction : -# 1015| mu1015_2(unknown) = AliasedDefinition : -# 1015| mu1015_3(unknown) = InitializeNonLocal : -# 1016| r1016_1(int *) = Constant[0] : -# 1016| v1016_2(void) = NoOp : -# 1017| r1017_1(String *) = Constant[0] : -# 1017| v1017_2(void) = NoOp : -# 1018| r1018_1(SizedDealloc *) = Constant[0] : -# 1018| v1018_2(void) = NoOp : -# 1019| r1019_1(Overaligned *) = Constant[0] : -# 1019| v1019_2(void) = NoOp : -# 1020| r1020_1(PolymorphicBase *) = Constant[0] : -# 1020| v1020_2(void) = NoOp : -# 1021| v1021_1(void) = NoOp : -# 1015| v1015_4(void) = ReturnVoid : -# 1015| v1015_5(void) = AliasedUse : ~m? -# 1015| v1015_6(void) = ExitFunction : +# 1015| v1015_1(void) = EnterFunction : +# 1015| mu1015_2(unknown) = AliasedDefinition : +# 1015| mu1015_3(unknown) = InitializeNonLocal : +# 1016| r1016_1(glval) = FunctionAddress[operator delete] : +# 1016| r1016_2(int *) = Constant[0] : +# 1016| v1016_3(void) = Call[operator delete] : func:r1016_1, 0:r1016_2 +# 1016| mu1016_4(unknown) = ^CallSideEffect : ~m? +# 1017| r1017_1(glval) = FunctionAddress[operator delete] : +# 1017| r1017_2(String *) = Constant[0] : +# 1017| v1017_3(void) = Call[operator delete] : func:r1017_1, 0:r1017_2 +# 1017| mu1017_4(unknown) = ^CallSideEffect : ~m? +# 1018| r1018_1(glval) = FunctionAddress[operator delete] : +# 1018| r1018_2(SizedDealloc *) = Constant[0] : +# 1018| v1018_3(void) = Call[operator delete] : func:r1018_1, 0:r1018_2 +# 1018| mu1018_4(unknown) = ^CallSideEffect : ~m? +# 1019| r1019_1(glval) = FunctionAddress[operator delete] : +# 1019| r1019_2(Overaligned *) = Constant[0] : +# 1019| v1019_3(void) = Call[operator delete] : func:r1019_1, 0:r1019_2 +# 1019| mu1019_4(unknown) = ^CallSideEffect : ~m? +# 1020| r1020_1(glval) = VirtualDeleteFunctionAddress : +# 1020| r1020_2(PolymorphicBase *) = Constant[0] : +# 1020| v1020_3(void) = Call[?] : func:r1020_1, 0:r1020_2 +# 1020| mu1020_4(unknown) = ^CallSideEffect : ~m? +# 1021| v1021_1(void) = NoOp : +# 1015| v1015_4(void) = ReturnVoid : +# 1015| v1015_5(void) = AliasedUse : ~m? +# 1015| v1015_6(void) = ExitFunction : # 1024| void OperatorDeleteArray() # 1024| Block 0 -# 1024| v1024_1(void) = EnterFunction : -# 1024| mu1024_2(unknown) = AliasedDefinition : -# 1024| mu1024_3(unknown) = InitializeNonLocal : -# 1025| r1025_1(int *) = Constant[0] : -# 1025| v1025_2(void) = NoOp : -# 1026| r1026_1(String *) = Constant[0] : -# 1026| v1026_2(void) = NoOp : -# 1027| r1027_1(SizedDealloc *) = Constant[0] : -# 1027| v1027_2(void) = NoOp : -# 1028| r1028_1(Overaligned *) = Constant[0] : -# 1028| v1028_2(void) = NoOp : -# 1029| r1029_1(PolymorphicBase *) = Constant[0] : -# 1029| v1029_2(void) = NoOp : -# 1030| v1030_1(void) = NoOp : -# 1024| v1024_4(void) = ReturnVoid : -# 1024| v1024_5(void) = AliasedUse : ~m? -# 1024| v1024_6(void) = ExitFunction : +# 1024| v1024_1(void) = EnterFunction : +# 1024| mu1024_2(unknown) = AliasedDefinition : +# 1024| mu1024_3(unknown) = InitializeNonLocal : +# 1025| r1025_1(glval) = FunctionAddress[operator delete[]] : +# 1025| r1025_2(int *) = Constant[0] : +# 1025| v1025_3(void) = Call[operator delete[]] : func:r1025_1, 0:r1025_2 +# 1025| mu1025_4(unknown) = ^CallSideEffect : ~m? +# 1026| r1026_1(glval) = FunctionAddress[operator delete[]] : +# 1026| r1026_2(String *) = Constant[0] : +# 1026| v1026_3(void) = Call[operator delete[]] : func:r1026_1, 0:r1026_2 +# 1026| mu1026_4(unknown) = ^CallSideEffect : ~m? +# 1027| r1027_1(glval) = FunctionAddress[operator delete[]] : +# 1027| r1027_2(SizedDealloc *) = Constant[0] : +# 1027| v1027_3(void) = Call[operator delete[]] : func:r1027_1, 0:r1027_2 +# 1027| mu1027_4(unknown) = ^CallSideEffect : ~m? +# 1028| r1028_1(glval) = FunctionAddress[operator delete[]] : +# 1028| r1028_2(Overaligned *) = Constant[0] : +# 1028| v1028_3(void) = Call[operator delete[]] : func:r1028_1, 0:r1028_2 +# 1028| mu1028_4(unknown) = ^CallSideEffect : ~m? +# 1029| r1029_1(glval) = FunctionAddress[operator delete[]] : +# 1029| r1029_2(PolymorphicBase *) = Constant[0] : +# 1029| v1029_3(void) = Call[operator delete[]] : func:r1029_1, 0:r1029_2 +# 1029| mu1029_4(unknown) = ^CallSideEffect : ~m? +# 1030| v1030_1(void) = NoOp : +# 1024| v1024_4(void) = ReturnVoid : +# 1024| v1024_5(void) = AliasedUse : ~m? +# 1024| v1024_6(void) = ExitFunction : # 1034| void EmptyStructInit() # 1034| Block 0 @@ -11091,6 +11111,215 @@ ir.cpp: # 2028| mu2028_13(unsigned int) = Store[#temp2028:7] : &:r2028_12, r2030_8 #-----| Goto -> Block 2 +# 2033| void NewDeleteMem() +# 2033| Block 0 +# 2033| v2033_1(void) = EnterFunction : +# 2033| mu2033_2(unknown) = AliasedDefinition : +# 2033| mu2033_3(unknown) = InitializeNonLocal : +# 2034| r2034_1(glval) = VariableAddress[x] : +# 2034| r2034_2(glval) = FunctionAddress[operator new] : +# 2034| r2034_3(unsigned long) = Constant[4] : +# 2034| r2034_4(void *) = Call[operator new] : func:r2034_2, 0:r2034_3 +# 2034| mu2034_5(unknown) = ^CallSideEffect : ~m? +# 2034| mu2034_6(unknown) = ^InitializeDynamicAllocation : &:r2034_4 +# 2034| r2034_7(int *) = Convert : r2034_4 +# 2034| mu2034_8(int *) = Store[x] : &:r2034_1, r2034_7 +# 2035| r2035_1(int) = Constant[6] : +# 2035| r2035_2(glval) = VariableAddress[x] : +# 2035| r2035_3(int *) = Load[x] : &:r2035_2, ~m? +# 2035| r2035_4(glval) = CopyValue : r2035_3 +# 2035| mu2035_5(int) = Store[?] : &:r2035_4, r2035_1 +# 2036| r2036_1(glval) = FunctionAddress[operator delete] : +# 2036| r2036_2(glval) = VariableAddress[x] : +# 2036| r2036_3(int *) = Load[x] : &:r2036_2, ~m? +# 2036| v2036_4(void) = Call[operator delete] : func:r2036_1, 0:r2036_3 +# 2036| mu2036_5(unknown) = ^CallSideEffect : ~m? +# 2037| v2037_1(void) = NoOp : +# 2033| v2033_4(void) = ReturnVoid : +# 2033| v2033_5(void) = AliasedUse : ~m? +# 2033| v2033_6(void) = ExitFunction : + +# 2039| void Base2::Base2() +# 2039| Block 0 +# 2039| v2039_1(void) = EnterFunction : +# 2039| mu2039_2(unknown) = AliasedDefinition : +# 2039| mu2039_3(unknown) = InitializeNonLocal : +# 2039| r2039_4(glval) = VariableAddress[#this] : +# 2039| mu2039_5(glval) = InitializeParameter[#this] : &:r2039_4 +# 2039| r2039_6(glval) = Load[#this] : &:r2039_4, ~m? +# 2039| mu2039_7(Base2) = InitializeIndirection[#this] : &:r2039_6 +# 2039| v2039_8(void) = NoOp : +# 2039| v2039_9(void) = ReturnIndirection[#this] : &:r2039_6, ~m? +# 2039| v2039_10(void) = ReturnVoid : +# 2039| v2039_11(void) = AliasedUse : ~m? +# 2039| v2039_12(void) = ExitFunction : + +# 2041| void Base2::operator delete(void*) +# 2041| Block 0 +# 2041| v2041_1(void) = EnterFunction : +# 2041| mu2041_2(unknown) = AliasedDefinition : +# 2041| mu2041_3(unknown) = InitializeNonLocal : +# 2041| r2041_4(glval) = VariableAddress[p] : +# 2041| mu2041_5(void *) = InitializeParameter[p] : &:r2041_4 +# 2041| r2041_6(void *) = Load[p] : &:r2041_4, ~m? +# 2041| mu2041_7(unknown) = InitializeIndirection[p] : &:r2041_6 +# 2042| v2042_1(void) = NoOp : +# 2041| v2041_8(void) = ReturnIndirection[p] : &:r2041_6, ~m? +# 2041| v2041_9(void) = ReturnVoid : +# 2041| v2041_10(void) = AliasedUse : ~m? +# 2041| v2041_11(void) = ExitFunction : + +# 2043| void Base2::~Base2() +# 2043| Block 0 +# 2043| v2043_1(void) = EnterFunction : +# 2043| mu2043_2(unknown) = AliasedDefinition : +# 2043| mu2043_3(unknown) = InitializeNonLocal : +# 2043| r2043_4(glval) = VariableAddress[#this] : +# 2043| mu2043_5(glval) = InitializeParameter[#this] : &:r2043_4 +# 2043| r2043_6(glval) = Load[#this] : &:r2043_4, ~m? +# 2043| mu2043_7(Base2) = InitializeIndirection[#this] : &:r2043_6 +# 2043| v2043_8(void) = NoOp : +# 2043| v2043_9(void) = ReturnIndirection[#this] : &:r2043_6, ~m? +# 2043| v2043_10(void) = ReturnVoid : +# 2043| v2043_11(void) = AliasedUse : ~m? +# 2043| v2043_12(void) = ExitFunction : + +# 2046| void Derived2::Derived2() +# 2046| Block 0 +# 2046| v2046_1(void) = EnterFunction : +# 2046| mu2046_2(unknown) = AliasedDefinition : +# 2046| mu2046_3(unknown) = InitializeNonLocal : +# 2046| r2046_4(glval) = VariableAddress[#this] : +# 2046| mu2046_5(glval) = InitializeParameter[#this] : &:r2046_4 +# 2046| r2046_6(glval) = Load[#this] : &:r2046_4, ~m? +# 2046| mu2046_7(Derived2) = InitializeIndirection[#this] : &:r2046_6 +# 2046| r2046_8(glval) = ConvertToNonVirtualBase[Derived2 : Base2] : mu2046_5 +# 2046| r2046_9(glval) = FunctionAddress[Base2] : +# 2046| v2046_10(void) = Call[Base2] : func:r2046_9, this:r2046_8 +# 2046| mu2046_11(unknown) = ^CallSideEffect : ~m? +# 2046| mu2046_12(Base2) = ^IndirectMayWriteSideEffect[-1] : &:r2046_8 +# 2046| v2046_13(void) = NoOp : +# 2046| v2046_14(void) = ReturnIndirection[#this] : &:r2046_6, ~m? +# 2046| v2046_15(void) = ReturnVoid : +# 2046| v2046_16(void) = AliasedUse : ~m? +# 2046| v2046_17(void) = ExitFunction : + +# 2049| void Derived2::~Derived2() +# 2049| Block 0 +# 2049| v2049_1(void) = EnterFunction : +# 2049| mu2049_2(unknown) = AliasedDefinition : +# 2049| mu2049_3(unknown) = InitializeNonLocal : +# 2049| r2049_4(glval) = VariableAddress[#this] : +# 2049| mu2049_5(glval) = InitializeParameter[#this] : &:r2049_4 +# 2049| r2049_6(glval) = Load[#this] : &:r2049_4, ~m? +# 2049| mu2049_7(Derived2) = InitializeIndirection[#this] : &:r2049_6 +# 2049| v2049_8(void) = NoOp : +# 2049| r2049_9(glval) = ConvertToNonVirtualBase[Derived2 : Base2] : mu2049_5 +# 2049| r2049_10(glval) = FunctionAddress[~Base2] : +# 2049| v2049_11(void) = Call[~Base2] : func:r2049_10, this:r2049_9 +# 2049| mu2049_12(unknown) = ^CallSideEffect : ~m? +# 2049| v2049_13(void) = ReturnIndirection[#this] : &:r2049_6, ~m? +# 2049| v2049_14(void) = ReturnVoid : +# 2049| v2049_15(void) = AliasedUse : ~m? +# 2049| v2049_16(void) = ExitFunction : + +# 2051| void Derived2::operator delete(void*) +# 2051| Block 0 +# 2051| v2051_1(void) = EnterFunction : +# 2051| mu2051_2(unknown) = AliasedDefinition : +# 2051| mu2051_3(unknown) = InitializeNonLocal : +# 2051| r2051_4(glval) = VariableAddress[p] : +# 2051| mu2051_5(void *) = InitializeParameter[p] : &:r2051_4 +# 2051| r2051_6(void *) = Load[p] : &:r2051_4, ~m? +# 2051| mu2051_7(unknown) = InitializeIndirection[p] : &:r2051_6 +# 2052| v2052_1(void) = NoOp : +# 2051| v2051_8(void) = ReturnIndirection[p] : &:r2051_6, ~m? +# 2051| v2051_9(void) = ReturnVoid : +# 2051| v2051_10(void) = AliasedUse : ~m? +# 2051| v2051_11(void) = ExitFunction : + +# 2056| int virtual_delete() +# 2056| Block 0 +# 2056| v2056_1(void) = EnterFunction : +# 2056| mu2056_2(unknown) = AliasedDefinition : +# 2056| mu2056_3(unknown) = InitializeNonLocal : +# 2058| r2058_1(glval) = VariableAddress[b1] : +# 2058| r2058_2(glval) = FunctionAddress[operator new] : +# 2058| r2058_3(unsigned long) = Constant[8] : +# 2058| r2058_4(void *) = Call[operator new] : func:r2058_2, 0:r2058_3 +# 2058| mu2058_5(unknown) = ^CallSideEffect : ~m? +# 2058| mu2058_6(unknown) = ^InitializeDynamicAllocation : &:r2058_4 +# 2058| r2058_7(Base2 *) = Convert : r2058_4 +# 2058| r2058_8(glval) = FunctionAddress[Base2] : +# 2058| v2058_9(void) = Call[Base2] : func:r2058_8, this:r2058_7 +# 2058| mu2058_10(unknown) = ^CallSideEffect : ~m? +# 2058| mu2058_11(Base2) = ^IndirectMayWriteSideEffect[-1] : &:r2058_7 +# 2058| mu2058_12(Base2 *) = Store[b1] : &:r2058_1, r2058_7 +# 2059| r2059_1(glval) = VirtualDeleteFunctionAddress : +# 2059| r2059_2(glval) = VariableAddress[b1] : +# 2059| r2059_3(Base2 *) = Load[b1] : &:r2059_2, ~m? +# 2059| v2059_4(void) = Call[?] : func:r2059_1, 0:r2059_3 +# 2059| mu2059_5(unknown) = ^CallSideEffect : ~m? +# 2061| r2061_1(glval) = VariableAddress[b2] : +# 2061| r2061_2(glval) = FunctionAddress[operator new] : +# 2061| r2061_3(unsigned long) = Constant[16] : +# 2061| r2061_4(void *) = Call[operator new] : func:r2061_2, 0:r2061_3 +# 2061| mu2061_5(unknown) = ^CallSideEffect : ~m? +# 2061| mu2061_6(unknown) = ^InitializeDynamicAllocation : &:r2061_4 +# 2061| r2061_7(Derived2 *) = Convert : r2061_4 +# 2061| r2061_8(glval) = FunctionAddress[Derived2] : +# 2061| v2061_9(void) = Call[Derived2] : func:r2061_8, this:r2061_7 +# 2061| mu2061_10(unknown) = ^CallSideEffect : ~m? +# 2061| mu2061_11(Derived2) = ^IndirectMayWriteSideEffect[-1] : &:r2061_7 +# 2061| r2061_12(Base2 *) = ConvertToNonVirtualBase[Derived2 : Base2] : r2061_7 +# 2061| mu2061_13(Base2 *) = Store[b2] : &:r2061_1, r2061_12 +# 2062| r2062_1(glval) = VirtualDeleteFunctionAddress : +# 2062| r2062_2(glval) = VariableAddress[b2] : +# 2062| r2062_3(Base2 *) = Load[b2] : &:r2062_2, ~m? +# 2062| v2062_4(void) = Call[?] : func:r2062_1, 0:r2062_3 +# 2062| mu2062_5(unknown) = ^CallSideEffect : ~m? +# 2064| r2064_1(glval) = VariableAddress[d] : +# 2064| r2064_2(glval) = FunctionAddress[operator new] : +# 2064| r2064_3(unsigned long) = Constant[16] : +# 2064| r2064_4(void *) = Call[operator new] : func:r2064_2, 0:r2064_3 +# 2064| mu2064_5(unknown) = ^CallSideEffect : ~m? +# 2064| mu2064_6(unknown) = ^InitializeDynamicAllocation : &:r2064_4 +# 2064| r2064_7(Derived2 *) = Convert : r2064_4 +# 2064| r2064_8(glval) = FunctionAddress[Derived2] : +# 2064| v2064_9(void) = Call[Derived2] : func:r2064_8, this:r2064_7 +# 2064| mu2064_10(unknown) = ^CallSideEffect : ~m? +# 2064| mu2064_11(Derived2) = ^IndirectMayWriteSideEffect[-1] : &:r2064_7 +# 2064| mu2064_12(Derived2 *) = Store[d] : &:r2064_1, r2064_7 +# 2065| r2065_1(glval) = VirtualDeleteFunctionAddress : +# 2065| r2065_2(glval) = VariableAddress[d] : +# 2065| r2065_3(Derived2 *) = Load[d] : &:r2065_2, ~m? +# 2065| v2065_4(void) = Call[?] : func:r2065_1, 0:r2065_3 +# 2065| mu2065_5(unknown) = ^CallSideEffect : ~m? +# 2066| v2066_1(void) = Unreached : + +# 2056| Block 1 +# 2056| r2056_4(glval) = VariableAddress[#return] : +# 2056| v2056_5(void) = ReturnValue : &:r2056_4, ~m? +# 2056| v2056_6(void) = AliasedUse : ~m? +# 2056| v2056_7(void) = ExitFunction : + +# 2070| void test_constant_folding() +# 2070| Block 0 +# 2070| v2070_1(void) = EnterFunction : +# 2070| mu2070_2(unknown) = AliasedDefinition : +# 2070| mu2070_3(unknown) = InitializeNonLocal : +# 2071| r2071_1(glval) = VariableAddress[x] : +# 2071| r2071_2(int) = Constant[116] : +# 2071| mu2071_3(int) = Store[x] : &:r2071_1, r2071_2 +# 2072| r2072_1(glval) = FunctionAddress[test_constant_folding_use] : +# 2072| r2072_2(int) = Constant[116] : +# 2072| v2072_3(void) = Call[test_constant_folding_use] : func:r2072_1, 0:r2072_2 +# 2072| mu2072_4(unknown) = ^CallSideEffect : ~m? +# 2073| v2073_1(void) = NoOp : +# 2070| v2070_4(void) = ReturnVoid : +# 2070| v2070_5(void) = AliasedUse : ~m? +# 2070| v2070_6(void) = ExitFunction : + perf-regression.cpp: # 6| void Big::Big() # 6| Block 0 diff --git a/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp b/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp index dfdb90ee690..8f3c2c1faef 100644 --- a/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp +++ b/cpp/ql/test/library-tests/ir/modulus-analysis/test.cpp @@ -10,7 +10,7 @@ void m(int i, bool cond, int x, int y) { int seven = 7; if (mul % c2 == seven) { - mod(mul); // congruent 3 mod 42, 7 mod 43 + mod(mul); // $ mod=0,3,42 } int j = cond @@ -19,13 +19,11 @@ void m(int i, bool cond, int x, int y) { mod(j); // $ mod=0,3,4 if (x % c1 == 3 && y % c1 == 7) { - // Need implies_v2 - mod(x + y); // $ MISSING: 0,10,42 + mod(x + y); // $ mod=0,10,42 } if (x % c1 == 3 && y % c1 == 7) { - // Need implies_v2 - mod(x - y); // $ MISSING: mod=0,38,42 + mod(x - y); // $ mod=0,38,42 } if (cond) { diff --git a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp index df29578409b..825e02b8616 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/SimpleRangeAnalysis_tests.cpp @@ -1008,12 +1008,12 @@ label: void test_overflow() { const int x = 2147483647; // 2^31-1 - range(x); + range(x); // $ range===2147483647 const int y = 256; - range(y); + range(y); // $ range===256 if ((x + y) <= 512) { - range(x); - range(y); + range(x); // $ range===2147483647 + range(y); // $ range===256 range(x + y); // $ range===-2147483393 } } diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/DoubleFree.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/DoubleFree.expected index bfc99021d27..cfe71545293 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/DoubleFree.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/DoubleFree.expected @@ -18,6 +18,7 @@ edges | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | +| test_free.cpp:83:12:83:12 | a | test_free.cpp:85:12:85:12 | a | | test_free.cpp:101:10:101:10 | a | test_free.cpp:103:10:103:10 | a | | test_free.cpp:128:10:128:11 | * ... | test_free.cpp:129:10:129:11 | * ... | | test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a | @@ -28,6 +29,8 @@ edges | test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a | | test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a | | test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a | +| test_free.cpp:252:7:252:7 | p | test_free.cpp:255:10:255:10 | p | +| test_free.cpp:260:9:260:9 | p | test_free.cpp:263:12:263:12 | p | nodes | test_free.cpp:11:10:11:10 | a | semmle.label | a | | test_free.cpp:11:10:11:10 | a | semmle.label | a | @@ -51,6 +54,8 @@ nodes | test_free.cpp:69:10:69:10 | a | semmle.label | a | | test_free.cpp:72:14:72:14 | a | semmle.label | a | | test_free.cpp:72:14:72:14 | a | semmle.label | a | +| test_free.cpp:83:12:83:12 | a | semmle.label | a | +| test_free.cpp:85:12:85:12 | a | semmle.label | a | | test_free.cpp:101:10:101:10 | a | semmle.label | a | | test_free.cpp:103:10:103:10 | a | semmle.label | a | | test_free.cpp:128:10:128:11 | * ... | semmle.label | * ... | @@ -63,6 +68,10 @@ nodes | test_free.cpp:207:10:207:10 | a | semmle.label | a | | test_free.cpp:209:10:209:10 | a | semmle.label | a | | test_free.cpp:209:10:209:10 | a | semmle.label | a | +| test_free.cpp:252:7:252:7 | p | semmle.label | p | +| test_free.cpp:255:10:255:10 | p | semmle.label | p | +| test_free.cpp:260:9:260:9 | p | semmle.label | p | +| test_free.cpp:263:12:263:12 | p | semmle.label | p | subpaths #select | test_free.cpp:14:10:14:10 | a | test_free.cpp:11:10:11:10 | a | test_free.cpp:14:10:14:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free | @@ -84,6 +93,7 @@ subpaths | test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free | | test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free | | test_free.cpp:72:14:72:14 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:72:14:72:14 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free | +| test_free.cpp:85:12:85:12 | a | test_free.cpp:83:12:83:12 | a | test_free.cpp:85:12:85:12 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:83:5:83:13 | delete | delete | | test_free.cpp:103:10:103:10 | a | test_free.cpp:101:10:101:10 | a | test_free.cpp:103:10:103:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:101:5:101:8 | call to free | call to free | | test_free.cpp:129:10:129:11 | * ... | test_free.cpp:128:10:128:11 | * ... | test_free.cpp:129:10:129:11 | * ... | Memory pointed to by '* ...' may already have been freed by $@. | test_free.cpp:128:5:128:8 | call to free | call to free | | test_free.cpp:154:10:154:10 | a | test_free.cpp:152:27:152:27 | a | test_free.cpp:154:10:154:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:152:22:152:25 | call to free | call to free | @@ -94,3 +104,5 @@ subpaths | test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:207:5:207:8 | call to free | call to free | | test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:207:5:207:8 | call to free | call to free | | test_free.cpp:209:10:209:10 | a | test_free.cpp:207:10:207:10 | a | test_free.cpp:209:10:209:10 | a | Memory pointed to by 'a' may already have been freed by $@. | test_free.cpp:207:5:207:8 | call to free | call to free | +| test_free.cpp:255:10:255:10 | p | test_free.cpp:252:7:252:7 | p | test_free.cpp:255:10:255:10 | p | Memory pointed to by 'p' may already have been freed by $@. | test_free.cpp:252:2:252:5 | call to free | call to free | +| test_free.cpp:263:12:263:12 | p | test_free.cpp:260:9:260:9 | p | test_free.cpp:263:12:263:12 | p | Memory pointed to by 'p' may already have been freed by $@. | test_free.cpp:260:2:260:9 | delete | delete | diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected index 4eb9bb35587..a9aa883efad 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected @@ -92,6 +92,10 @@ | test_free.cpp:233:14:233:15 | * ... | | test_free.cpp:239:14:239:15 | * ... | | test_free.cpp:245:10:245:11 | * ... | +| test_free.cpp:252:7:252:7 | p | +| test_free.cpp:255:10:255:10 | p | +| test_free.cpp:260:9:260:9 | p | +| test_free.cpp:263:12:263:12 | p | | virtual.cpp:18:10:18:10 | a | | virtual.cpp:19:10:19:10 | c | | virtual.cpp:38:10:38:10 | b | diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected index 827c207b659..298e86c37e3 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryNeverFreed.expected @@ -12,3 +12,5 @@ | test.cpp:157:3:157:26 | new[] | This memory is never freed. | | test.cpp:169:14:169:19 | call to strdup | This memory is never freed. | | test_free.cpp:167:15:167:21 | call to realloc | This memory is never freed. | +| test_free.cpp:253:14:253:19 | call to malloc | This memory is never freed. | +| test_free.cpp:261:6:261:12 | new | This memory is never freed. | diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected index 16e74b982c1..6b125a106af 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected @@ -9,6 +9,7 @@ edges | test_free.cpp:44:27:44:27 | a | test_free.cpp:45:5:45:5 | a | | test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a | | test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a | +| test_free.cpp:83:12:83:12 | a | test_free.cpp:84:5:84:5 | a | | test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a | | test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a | | test_free.cpp:95:10:95:10 | a | test_free.cpp:96:9:96:9 | a | @@ -27,6 +28,8 @@ edges | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | +| test_free.cpp:252:7:252:7 | p | test_free.cpp:254:6:254:6 | p | +| test_free.cpp:260:9:260:9 | p | test_free.cpp:262:6:262:6 | p | nodes | test_free.cpp:11:10:11:10 | a | semmle.label | a | | test_free.cpp:11:10:11:10 | a | semmle.label | a | @@ -41,6 +44,8 @@ nodes | test_free.cpp:69:10:69:10 | a | semmle.label | a | | test_free.cpp:69:10:69:10 | a | semmle.label | a | | test_free.cpp:71:9:71:9 | a | semmle.label | a | +| test_free.cpp:83:12:83:12 | a | semmle.label | a | +| test_free.cpp:84:5:84:5 | a | semmle.label | a | | test_free.cpp:90:10:90:10 | a | semmle.label | a | | test_free.cpp:90:10:90:10 | a | semmle.label | a | | test_free.cpp:91:5:91:5 | a | semmle.label | a | @@ -63,6 +68,10 @@ nodes | test_free.cpp:245:10:245:11 | * ... | semmle.label | * ... | | test_free.cpp:246:9:246:10 | * ... | semmle.label | * ... | | test_free.cpp:246:9:246:10 | * ... | semmle.label | * ... | +| test_free.cpp:252:7:252:7 | p | semmle.label | p | +| test_free.cpp:254:6:254:6 | p | semmle.label | p | +| test_free.cpp:260:9:260:9 | p | semmle.label | p | +| test_free.cpp:262:6:262:6 | p | semmle.label | p | subpaths #select | test_free.cpp:12:5:12:5 | a | test_free.cpp:11:10:11:10 | a | test_free.cpp:12:5:12:5 | a | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free | @@ -75,6 +84,7 @@ subpaths | test_free.cpp:45:5:45:5 | a | test_free.cpp:44:27:44:27 | a | test_free.cpp:45:5:45:5 | a | Memory may have been previously freed by $@. | test_free.cpp:44:22:44:25 | call to free | call to free | | test_free.cpp:71:9:71:9 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a | Memory may have been previously freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free | | test_free.cpp:71:9:71:9 | a | test_free.cpp:69:10:69:10 | a | test_free.cpp:71:9:71:9 | a | Memory may have been previously freed by $@. | test_free.cpp:69:5:69:8 | call to free | call to free | +| test_free.cpp:84:5:84:5 | a | test_free.cpp:83:12:83:12 | a | test_free.cpp:84:5:84:5 | a | Memory may have been previously freed by $@. | test_free.cpp:83:5:83:13 | delete | delete | | test_free.cpp:91:5:91:5 | a | test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a | Memory may have been previously freed by $@. | test_free.cpp:90:5:90:8 | call to free | call to free | | test_free.cpp:91:5:91:5 | a | test_free.cpp:90:10:90:10 | a | test_free.cpp:91:5:91:5 | a | Memory may have been previously freed by $@. | test_free.cpp:90:5:90:8 | call to free | call to free | | test_free.cpp:96:9:96:9 | a | test_free.cpp:95:10:95:10 | a | test_free.cpp:96:9:96:9 | a | Memory may have been previously freed by $@. | test_free.cpp:95:5:95:8 | call to free | call to free | @@ -93,3 +103,5 @@ subpaths | test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free | | test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free | | test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free | +| test_free.cpp:254:6:254:6 | p | test_free.cpp:252:7:252:7 | p | test_free.cpp:254:6:254:6 | p | Memory may have been previously freed by $@. | test_free.cpp:252:2:252:5 | call to free | call to free | +| test_free.cpp:262:6:262:6 | p | test_free.cpp:260:9:260:9 | p | test_free.cpp:262:6:262:6 | p | Memory may have been previously freed by $@. | test_free.cpp:260:2:260:9 | delete | delete | diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp b/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp index 8ea72edd64c..3aaefb1e416 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp @@ -81,8 +81,8 @@ public: void test_new1() { A *a = new A(); delete(a); - a->f(); // BAD [NOT DETECTED] - delete(a); // BAD [NOT DETECTED] + a->f(); // BAD + delete(a); // BAD } void test_dereference1(A *a) { @@ -244,4 +244,21 @@ void test_loop3(char ** a, char ** b) { void test_deref(char **a) { free(*a); use(*a); // GOOD [FALSE POSITIVE] +} + +// Refs + +void test_ref(char *&p) { + free(p); + p = (char *)malloc(sizeof(char)*10); + use(p); // GOOD [FALSE POSITIVE] + free(p); // GOOD [FALSE POSITIVE] +} + + +void test_ref_delete(int *&p) { + delete p; + p = new int; + use(p); // GOOD [FALSE POSITIVE] + delete p; // GOOD [FALSE POSITIVE] } \ No newline at end of file diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected index 7a1b76f7632..ae8073cf09f 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected @@ -2,9 +2,11 @@ edges | test.cpp:15:27:15:30 | argv indirection | test.cpp:22:45:22:52 | userName indirection | | test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | command1 indirection | | test.cpp:22:45:22:52 | userName indirection | test.cpp:22:13:22:20 | sprintf output argument | +| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:45:22:52 | userName indirection | | test.cpp:47:21:47:26 | call to getenv indirection | test.cpp:50:35:50:43 | envCflags indirection | | test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | command indirection | | test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:11:50:17 | sprintf output argument | +| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:35:50:43 | envCflags indirection | | test.cpp:62:9:62:16 | fread output argument | test.cpp:64:20:64:27 | filename indirection | | test.cpp:64:11:64:17 | strncat output argument | test.cpp:65:10:65:16 | command indirection | | test.cpp:64:20:64:27 | filename indirection | test.cpp:64:11:64:17 | strncat output argument | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected index e1665c23315..56297693056 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected @@ -4,38 +4,29 @@ edges | test.cpp:18:10:18:15 | str indirection [post update] [string] | test.cpp:19:5:19:7 | str indirection [string] | | test.cpp:18:19:18:24 | call to malloc | test.cpp:18:5:18:30 | ... = ... | | test.cpp:19:5:19:7 | str indirection [string] | test.cpp:16:11:16:21 | mk_string_t indirection [string] | +| test.cpp:19:5:19:7 | str indirection [string] | test.cpp:19:5:19:7 | str indirection [string] | | test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:42:13:42:15 | str indirection [string] | | test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:72:17:72:19 | str indirection [string] | | test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | test.cpp:80:17:80:19 | str indirection [string] | | test.cpp:42:13:42:15 | str indirection [string] | test.cpp:42:18:42:23 | string | -| test.cpp:42:13:42:15 | str indirection [string] | test.cpp:42:18:42:23 | string indirection | -| test.cpp:42:18:42:23 | string indirection | test.cpp:42:18:42:23 | string | | test.cpp:72:17:72:19 | str indirection [string] | test.cpp:72:22:72:27 | string | -| test.cpp:72:17:72:19 | str indirection [string] | test.cpp:72:22:72:27 | string indirection | -| test.cpp:72:22:72:27 | string indirection | test.cpp:72:22:72:27 | string | | test.cpp:80:17:80:19 | str indirection [string] | test.cpp:80:22:80:27 | string | -| test.cpp:80:17:80:19 | str indirection [string] | test.cpp:80:22:80:27 | string indirection | -| test.cpp:80:22:80:27 | string indirection | test.cpp:80:22:80:27 | string | | test.cpp:88:11:88:30 | mk_string_t_plus_one indirection [string] | test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | | test.cpp:90:5:90:34 | ... = ... | test.cpp:90:10:90:15 | str indirection [post update] [string] | | test.cpp:90:10:90:15 | str indirection [post update] [string] | test.cpp:91:5:91:7 | str indirection [string] | | test.cpp:90:19:90:24 | call to malloc | test.cpp:90:5:90:34 | ... = ... | | test.cpp:91:5:91:7 | str indirection [string] | test.cpp:88:11:88:30 | mk_string_t_plus_one indirection [string] | +| test.cpp:91:5:91:7 | str indirection [string] | test.cpp:91:5:91:7 | str indirection [string] | | test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:99:13:99:15 | str indirection [string] | | test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:129:17:129:19 | str indirection [string] | | test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | test.cpp:137:17:137:19 | str indirection [string] | | test.cpp:99:13:99:15 | str indirection [string] | test.cpp:99:18:99:23 | string | -| test.cpp:99:13:99:15 | str indirection [string] | test.cpp:99:18:99:23 | string indirection | -| test.cpp:99:18:99:23 | string indirection | test.cpp:99:18:99:23 | string | | test.cpp:129:17:129:19 | str indirection [string] | test.cpp:129:22:129:27 | string | -| test.cpp:129:17:129:19 | str indirection [string] | test.cpp:129:22:129:27 | string indirection | -| test.cpp:129:22:129:27 | string indirection | test.cpp:129:22:129:27 | string | | test.cpp:137:17:137:19 | str indirection [string] | test.cpp:137:22:137:27 | string | -| test.cpp:137:17:137:19 | str indirection [string] | test.cpp:137:22:137:27 | string indirection | -| test.cpp:137:22:137:27 | string indirection | test.cpp:137:22:137:27 | string | | test.cpp:147:5:147:34 | ... = ... | test.cpp:147:10:147:15 | str indirection [post update] [string] | | test.cpp:147:10:147:15 | str indirection [post update] [string] | test.cpp:148:5:148:7 | str indirection [string] | | test.cpp:147:19:147:24 | call to malloc | test.cpp:147:5:147:34 | ... = ... | +| test.cpp:148:5:148:7 | str indirection [string] | test.cpp:148:5:148:7 | str indirection [string] | | test.cpp:148:5:148:7 | str indirection [string] | test.cpp:152:13:152:15 | str indirection [string] | | test.cpp:148:5:148:7 | str indirection [string] | test.cpp:154:13:154:15 | str indirection [string] | | test.cpp:148:5:148:7 | str indirection [string] | test.cpp:156:13:156:15 | str indirection [string] | @@ -46,32 +37,14 @@ edges | test.cpp:148:5:148:7 | str indirection [string] | test.cpp:203:17:203:19 | str indirection [string] | | test.cpp:148:5:148:7 | str indirection [string] | test.cpp:207:17:207:19 | str indirection [string] | | test.cpp:152:13:152:15 | str indirection [string] | test.cpp:152:18:152:23 | string | -| test.cpp:152:13:152:15 | str indirection [string] | test.cpp:152:18:152:23 | string indirection | -| test.cpp:152:18:152:23 | string indirection | test.cpp:152:18:152:23 | string | | test.cpp:154:13:154:15 | str indirection [string] | test.cpp:154:18:154:23 | string | -| test.cpp:154:13:154:15 | str indirection [string] | test.cpp:154:18:154:23 | string indirection | -| test.cpp:154:18:154:23 | string indirection | test.cpp:154:18:154:23 | string | | test.cpp:156:13:156:15 | str indirection [string] | test.cpp:156:18:156:23 | string | -| test.cpp:156:13:156:15 | str indirection [string] | test.cpp:156:18:156:23 | string indirection | -| test.cpp:156:18:156:23 | string indirection | test.cpp:156:18:156:23 | string | | test.cpp:175:17:175:19 | str indirection [string] | test.cpp:175:22:175:27 | string | -| test.cpp:175:17:175:19 | str indirection [string] | test.cpp:175:22:175:27 | string indirection | -| test.cpp:175:22:175:27 | string indirection | test.cpp:175:22:175:27 | string | | test.cpp:187:17:187:19 | str indirection [string] | test.cpp:187:22:187:27 | string | -| test.cpp:187:17:187:19 | str indirection [string] | test.cpp:187:22:187:27 | string indirection | -| test.cpp:187:22:187:27 | string indirection | test.cpp:187:22:187:27 | string | | test.cpp:195:17:195:19 | str indirection [string] | test.cpp:195:22:195:27 | string | -| test.cpp:195:17:195:19 | str indirection [string] | test.cpp:195:22:195:27 | string indirection | -| test.cpp:195:22:195:27 | string indirection | test.cpp:195:22:195:27 | string | | test.cpp:199:17:199:19 | str indirection [string] | test.cpp:199:22:199:27 | string | -| test.cpp:199:17:199:19 | str indirection [string] | test.cpp:199:22:199:27 | string indirection | -| test.cpp:199:22:199:27 | string indirection | test.cpp:199:22:199:27 | string | | test.cpp:203:17:203:19 | str indirection [string] | test.cpp:203:22:203:27 | string | -| test.cpp:203:17:203:19 | str indirection [string] | test.cpp:203:22:203:27 | string indirection | -| test.cpp:203:22:203:27 | string indirection | test.cpp:203:22:203:27 | string | | test.cpp:207:17:207:19 | str indirection [string] | test.cpp:207:22:207:27 | string | -| test.cpp:207:17:207:19 | str indirection [string] | test.cpp:207:22:207:27 | string indirection | -| test.cpp:207:22:207:27 | string indirection | test.cpp:207:22:207:27 | string | | test.cpp:214:24:214:24 | p | test.cpp:216:10:216:10 | p | | test.cpp:220:43:220:48 | call to malloc | test.cpp:222:15:222:20 | buffer | | test.cpp:222:15:222:20 | buffer | test.cpp:214:24:214:24 | p | @@ -83,8 +56,6 @@ edges | test.cpp:242:22:242:27 | buffer | test.cpp:235:40:235:45 | buffer | | test.cpp:242:22:242:27 | buffer | test.cpp:242:16:242:19 | set_string output argument [string] | | test.cpp:243:12:243:14 | str indirection [string] | test.cpp:243:12:243:21 | string | -| test.cpp:243:12:243:14 | str indirection [string] | test.cpp:243:16:243:21 | string indirection | -| test.cpp:243:16:243:21 | string indirection | test.cpp:243:12:243:21 | string | | test.cpp:249:20:249:27 | call to my_alloc | test.cpp:250:12:250:12 | p | | test.cpp:256:17:256:22 | call to malloc | test.cpp:257:12:257:12 | p | | test.cpp:262:22:262:27 | call to malloc | test.cpp:266:12:266:12 | p | @@ -98,13 +69,10 @@ nodes | test.cpp:39:21:39:31 | call to mk_string_t indirection [string] | semmle.label | call to mk_string_t indirection [string] | | test.cpp:42:13:42:15 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:42:18:42:23 | string | semmle.label | string | -| test.cpp:42:18:42:23 | string indirection | semmle.label | string indirection | | test.cpp:72:17:72:19 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:72:22:72:27 | string | semmle.label | string | -| test.cpp:72:22:72:27 | string indirection | semmle.label | string indirection | | test.cpp:80:17:80:19 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:80:22:80:27 | string | semmle.label | string | -| test.cpp:80:22:80:27 | string indirection | semmle.label | string indirection | | test.cpp:88:11:88:30 | mk_string_t_plus_one indirection [string] | semmle.label | mk_string_t_plus_one indirection [string] | | test.cpp:90:5:90:34 | ... = ... | semmle.label | ... = ... | | test.cpp:90:10:90:15 | str indirection [post update] [string] | semmle.label | str indirection [post update] [string] | @@ -113,44 +81,32 @@ nodes | test.cpp:96:21:96:40 | call to mk_string_t_plus_one indirection [string] | semmle.label | call to mk_string_t_plus_one indirection [string] | | test.cpp:99:13:99:15 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:99:18:99:23 | string | semmle.label | string | -| test.cpp:99:18:99:23 | string indirection | semmle.label | string indirection | | test.cpp:129:17:129:19 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:129:22:129:27 | string | semmle.label | string | -| test.cpp:129:22:129:27 | string indirection | semmle.label | string indirection | | test.cpp:137:17:137:19 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:137:22:137:27 | string | semmle.label | string | -| test.cpp:137:22:137:27 | string indirection | semmle.label | string indirection | | test.cpp:147:5:147:34 | ... = ... | semmle.label | ... = ... | | test.cpp:147:10:147:15 | str indirection [post update] [string] | semmle.label | str indirection [post update] [string] | | test.cpp:147:19:147:24 | call to malloc | semmle.label | call to malloc | | test.cpp:148:5:148:7 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:152:13:152:15 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:152:18:152:23 | string | semmle.label | string | -| test.cpp:152:18:152:23 | string indirection | semmle.label | string indirection | | test.cpp:154:13:154:15 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:154:18:154:23 | string | semmle.label | string | -| test.cpp:154:18:154:23 | string indirection | semmle.label | string indirection | | test.cpp:156:13:156:15 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:156:18:156:23 | string | semmle.label | string | -| test.cpp:156:18:156:23 | string indirection | semmle.label | string indirection | | test.cpp:175:17:175:19 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:175:22:175:27 | string | semmle.label | string | -| test.cpp:175:22:175:27 | string indirection | semmle.label | string indirection | | test.cpp:187:17:187:19 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:187:22:187:27 | string | semmle.label | string | -| test.cpp:187:22:187:27 | string indirection | semmle.label | string indirection | | test.cpp:195:17:195:19 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:195:22:195:27 | string | semmle.label | string | -| test.cpp:195:22:195:27 | string indirection | semmle.label | string indirection | | test.cpp:199:17:199:19 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:199:22:199:27 | string | semmle.label | string | -| test.cpp:199:22:199:27 | string indirection | semmle.label | string indirection | | test.cpp:203:17:203:19 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:203:22:203:27 | string | semmle.label | string | -| test.cpp:203:22:203:27 | string indirection | semmle.label | string indirection | | test.cpp:207:17:207:19 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:207:22:207:27 | string | semmle.label | string | -| test.cpp:207:22:207:27 | string indirection | semmle.label | string indirection | | test.cpp:214:24:214:24 | p | semmle.label | p | | test.cpp:216:10:216:10 | p | semmle.label | p | | test.cpp:220:43:220:48 | call to malloc | semmle.label | call to malloc | @@ -165,7 +121,6 @@ nodes | test.cpp:242:22:242:27 | buffer | semmle.label | buffer | | test.cpp:243:12:243:14 | str indirection [string] | semmle.label | str indirection [string] | | test.cpp:243:12:243:21 | string | semmle.label | string | -| test.cpp:243:16:243:21 | string indirection | semmle.label | string indirection | | test.cpp:249:20:249:27 | call to my_alloc | semmle.label | call to my_alloc | | test.cpp:250:12:250:12 | p | semmle.label | p | | test.cpp:256:17:256:22 | call to malloc | semmle.label | call to malloc | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected index b18019c0b49..82049fc9229 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected @@ -2,16 +2,13 @@ edges | main.cpp:6:27:6:30 | argv indirection | main.cpp:7:33:7:36 | argv indirection | | main.cpp:7:33:7:36 | argv indirection | overflowdestination.cpp:23:45:23:48 | argv indirection | | overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | -| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | | overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src indirection | | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:9:53:12 | memcpy output argument | | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:15:53:17 | src indirection | -| overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:53:15:53:17 | src indirection | | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:54:9:54:12 | memcpy output argument | | overflowdestination.cpp:53:9:53:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument | | overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:54:9:54:12 | memcpy output argument | | overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:64:16:64:19 | src2 indirection | -| overflowdestination.cpp:57:52:57:54 | src indirection | overflowdestination.cpp:64:16:64:19 | src2 indirection | | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:75:30:75:32 | src indirection | | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:76:30:76:32 | src indirection | | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | overflowdestination.cpp:76:30:76:32 | src indirection | @@ -23,17 +20,14 @@ nodes | main.cpp:7:33:7:36 | argv indirection | semmle.label | argv indirection | | overflowdestination.cpp:23:45:23:48 | argv indirection | semmle.label | argv indirection | | overflowdestination.cpp:30:17:30:20 | arg1 indirection | semmle.label | arg1 indirection | -| overflowdestination.cpp:30:17:30:20 | arg1 indirection | semmle.label | arg1 indirection | | overflowdestination.cpp:43:8:43:10 | fgets output argument | semmle.label | fgets output argument | | overflowdestination.cpp:46:15:46:17 | src indirection | semmle.label | src indirection | | overflowdestination.cpp:50:52:50:54 | src indirection | semmle.label | src indirection | | overflowdestination.cpp:53:9:53:12 | memcpy output argument | semmle.label | memcpy output argument | | overflowdestination.cpp:53:15:53:17 | src indirection | semmle.label | src indirection | -| overflowdestination.cpp:53:15:53:17 | src indirection | semmle.label | src indirection | | overflowdestination.cpp:54:9:54:12 | memcpy output argument | semmle.label | memcpy output argument | | overflowdestination.cpp:57:52:57:54 | src indirection | semmle.label | src indirection | | overflowdestination.cpp:64:16:64:19 | src2 indirection | semmle.label | src2 indirection | -| overflowdestination.cpp:64:16:64:19 | src2 indirection | semmle.label | src2 indirection | | overflowdestination.cpp:73:8:73:10 | fgets output argument | semmle.label | fgets output argument | | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | semmle.label | overflowdest_test2 output argument | | overflowdestination.cpp:75:30:75:32 | src indirection | semmle.label | src indirection | @@ -43,9 +37,6 @@ subpaths | overflowdestination.cpp:75:30:75:32 | src indirection | overflowdestination.cpp:50:52:50:54 | src indirection | overflowdestination.cpp:54:9:54:12 | memcpy output argument | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | #select | overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | -| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | | overflowdestination.cpp:46:2:46:7 | call to memcpy | overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | | overflowdestination.cpp:53:2:53:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:53:15:53:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | -| overflowdestination.cpp:53:2:53:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:53:15:53:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | -| overflowdestination.cpp:64:2:64:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:64:16:64:19 | src2 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | | overflowdestination.cpp:64:2:64:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:64:16:64:19 | src2 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected index 065c900c71f..272327331f8 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextBufferWrite.expected @@ -1,13 +1,10 @@ edges | test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection | -| test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection | nodes | test2.cpp:110:3:110:6 | call to gets indirection | semmle.label | call to gets indirection | | test.cpp:53:27:53:30 | argv indirection | semmle.label | argv indirection | | test.cpp:58:25:58:29 | input indirection | semmle.label | input indirection | -| test.cpp:58:25:58:29 | input indirection | semmle.label | input indirection | subpaths #select | test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets indirection | test2.cpp:110:3:110:6 | call to gets indirection | This write into buffer 'password' may contain unencrypted data from $@. | test2.cpp:110:3:110:6 | call to gets indirection | user input (string read by gets) | | test.cpp:58:3:58:9 | call to sprintf | test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:53:27:53:30 | argv indirection | user input (a command-line argument) | -| test.cpp:58:3:58:9 | call to sprintf | test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:53:27:53:30 | argv indirection | user input (a command-line argument) | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/UseOfHttp.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/UseOfHttp.expected index d5a39f2465c..ba2e1dc5834 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/UseOfHttp.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/UseOfHttp.expected @@ -1,6 +1,5 @@ edges | test.cpp:11:26:11:28 | url indirection | test.cpp:15:30:15:32 | url indirection | -| test.cpp:11:26:11:28 | url indirection | test.cpp:15:30:15:32 | url indirection | | test.cpp:24:13:24:17 | url_g indirection | test.cpp:38:11:38:15 | url_g indirection | | test.cpp:24:21:24:40 | http://example.com indirection | test.cpp:24:13:24:17 | url_g indirection | | test.cpp:24:21:24:40 | http://example.com indirection | test.cpp:24:13:24:17 | url_g indirection | @@ -23,7 +22,6 @@ edges nodes | test.cpp:11:26:11:28 | url indirection | semmle.label | url indirection | | test.cpp:15:30:15:32 | url indirection | semmle.label | url indirection | -| test.cpp:15:30:15:32 | url indirection | semmle.label | url indirection | | test.cpp:24:13:24:17 | url_g indirection | semmle.label | url_g indirection | | test.cpp:24:21:24:40 | http://example.com indirection | semmle.label | http://example.com indirection | | test.cpp:24:21:24:40 | http://example.com indirection | semmle.label | http://example.com indirection | @@ -47,27 +45,14 @@ subpaths #select | test.cpp:24:21:24:40 | http://example.com | test.cpp:24:21:24:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | | test.cpp:24:21:24:40 | http://example.com | test.cpp:24:21:24:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | -| test.cpp:24:21:24:40 | http://example.com | test.cpp:24:21:24:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | -| test.cpp:24:21:24:40 | http://example.com | test.cpp:24:21:24:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | -| test.cpp:28:10:28:29 | http://example.com | test.cpp:28:10:28:29 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | -| test.cpp:28:10:28:29 | http://example.com | test.cpp:28:10:28:29 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | | test.cpp:28:10:28:29 | http://example.com | test.cpp:28:10:28:29 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | | test.cpp:28:10:28:29 | http://example.com | test.cpp:28:10:28:29 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | | test.cpp:35:23:35:42 | http://example.com | test.cpp:35:23:35:42 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | | test.cpp:35:23:35:42 | http://example.com | test.cpp:35:23:35:42 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | -| test.cpp:35:23:35:42 | http://example.com | test.cpp:35:23:35:42 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | -| test.cpp:35:23:35:42 | http://example.com | test.cpp:35:23:35:42 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | -| test.cpp:36:26:36:45 | http://example.com | test.cpp:36:26:36:45 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | -| test.cpp:36:26:36:45 | http://example.com | test.cpp:36:26:36:45 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | | test.cpp:36:26:36:45 | http://example.com | test.cpp:36:26:36:45 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | | test.cpp:36:26:36:45 | http://example.com | test.cpp:36:26:36:45 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | | test.cpp:46:18:46:26 | http:// | test.cpp:46:18:46:26 | http:// indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | | test.cpp:46:18:46:26 | http:// | test.cpp:46:18:46:26 | http:// indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | -| test.cpp:46:18:46:26 | http:// | test.cpp:46:18:46:26 | http:// indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | -| test.cpp:46:18:46:26 | http:// | test.cpp:46:18:46:26 | http:// indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | -| test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | -| test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | -| test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | | test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | | test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | | test.cpp:110:21:110:40 | http://example.com | test.cpp:110:21:110:40 | http://example.com indirection | test.cpp:15:30:15:32 | url indirection | This URL may be constructed with the HTTP protocol. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseAfterFree.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseAfterFree.expected index e95af7ceb10..200db037129 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseAfterFree.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/UseAfterFree.expected @@ -11,6 +11,9 @@ edges | test.cpp:127:7:127:10 | data | test.cpp:130:6:130:9 | data | | test.cpp:138:7:138:10 | data | test.cpp:141:6:141:9 | data | | test.cpp:138:7:138:10 | data | test.cpp:141:6:141:9 | data | +| test.cpp:164:9:164:9 | c | test.cpp:165:2:165:2 | c | +| test.cpp:164:9:164:9 | c | test.cpp:166:3:166:4 | * ... | +| test.cpp:164:9:164:9 | c | test.cpp:166:4:166:4 | c | | test.cpp:181:7:181:10 | data | test.cpp:186:6:186:9 | data | | test.cpp:181:7:181:10 | data | test.cpp:186:6:186:9 | data | | test.cpp:192:7:192:10 | data | test.cpp:197:6:197:9 | data | @@ -19,6 +22,7 @@ edges | test.cpp:203:7:203:10 | data | test.cpp:209:6:209:9 | data | | test.cpp:207:8:207:11 | data | test.cpp:209:6:209:9 | data | | test.cpp:207:8:207:11 | data | test.cpp:209:6:209:9 | data | +| test.cpp:216:9:216:9 | x | test.cpp:217:6:217:6 | x | nodes | test.cpp:39:7:39:10 | data | semmle.label | data | | test.cpp:39:7:39:10 | data | semmle.label | data | @@ -38,6 +42,10 @@ nodes | test.cpp:138:7:138:10 | data | semmle.label | data | | test.cpp:138:7:138:10 | data | semmle.label | data | | test.cpp:141:6:141:9 | data | semmle.label | data | +| test.cpp:164:9:164:9 | c | semmle.label | c | +| test.cpp:165:2:165:2 | c | semmle.label | c | +| test.cpp:166:3:166:4 | * ... | semmle.label | * ... | +| test.cpp:166:4:166:4 | c | semmle.label | c | | test.cpp:181:7:181:10 | data | semmle.label | data | | test.cpp:181:7:181:10 | data | semmle.label | data | | test.cpp:186:6:186:9 | data | semmle.label | data | @@ -50,6 +58,8 @@ nodes | test.cpp:207:8:207:11 | data | semmle.label | data | | test.cpp:209:6:209:9 | data | semmle.label | data | | test.cpp:209:6:209:9 | data | semmle.label | data | +| test.cpp:216:9:216:9 | x | semmle.label | x | +| test.cpp:217:6:217:6 | x | semmle.label | x | subpaths #select | test.cpp:41:6:41:9 | data | test.cpp:39:7:39:10 | data | test.cpp:41:6:41:9 | data | Memory may have been previously freed by $@. | test.cpp:39:2:39:5 | call to free | call to free | @@ -64,6 +74,9 @@ subpaths | test.cpp:130:6:130:9 | data | test.cpp:127:7:127:10 | data | test.cpp:130:6:130:9 | data | Memory may have been previously freed by $@. | test.cpp:127:2:127:5 | call to free | call to free | | test.cpp:141:6:141:9 | data | test.cpp:138:7:138:10 | data | test.cpp:141:6:141:9 | data | Memory may have been previously freed by $@. | test.cpp:138:2:138:5 | call to free | call to free | | test.cpp:141:6:141:9 | data | test.cpp:138:7:138:10 | data | test.cpp:141:6:141:9 | data | Memory may have been previously freed by $@. | test.cpp:138:2:138:5 | call to free | call to free | +| test.cpp:165:2:165:2 | c | test.cpp:164:9:164:9 | c | test.cpp:165:2:165:2 | c | Memory may have been previously freed by $@. | test.cpp:164:2:164:10 | delete | delete | +| test.cpp:166:3:166:4 | * ... | test.cpp:164:9:164:9 | c | test.cpp:166:3:166:4 | * ... | Memory may have been previously freed by $@. | test.cpp:164:2:164:10 | delete | delete | +| test.cpp:166:4:166:4 | c | test.cpp:164:9:164:9 | c | test.cpp:166:4:166:4 | c | Memory may have been previously freed by $@. | test.cpp:164:2:164:10 | delete | delete | | test.cpp:186:6:186:9 | data | test.cpp:181:7:181:10 | data | test.cpp:186:6:186:9 | data | Memory may have been previously freed by $@. | test.cpp:181:2:181:5 | call to free | call to free | | test.cpp:186:6:186:9 | data | test.cpp:181:7:181:10 | data | test.cpp:186:6:186:9 | data | Memory may have been previously freed by $@. | test.cpp:181:2:181:5 | call to free | call to free | | test.cpp:197:6:197:9 | data | test.cpp:192:7:192:10 | data | test.cpp:197:6:197:9 | data | Memory may have been previously freed by $@. | test.cpp:192:2:192:5 | call to free | call to free | @@ -72,3 +85,4 @@ subpaths | test.cpp:209:6:209:9 | data | test.cpp:203:7:203:10 | data | test.cpp:209:6:209:9 | data | Memory may have been previously freed by $@. | test.cpp:203:2:203:5 | call to free | call to free | | test.cpp:209:6:209:9 | data | test.cpp:207:8:207:11 | data | test.cpp:209:6:209:9 | data | Memory may have been previously freed by $@. | test.cpp:207:3:207:6 | call to free | call to free | | test.cpp:209:6:209:9 | data | test.cpp:207:8:207:11 | data | test.cpp:209:6:209:9 | data | Memory may have been previously freed by $@. | test.cpp:207:3:207:6 | call to free | call to free | +| test.cpp:217:6:217:6 | x | test.cpp:216:9:216:9 | x | test.cpp:217:6:217:6 | x | Memory may have been previously freed by $@. | test.cpp:216:2:216:9 | delete | delete | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/ExposedSystemData.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/ExposedSystemData.expected index a675c3a99d5..da20718ac12 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/ExposedSystemData.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/ExposedSystemData.expected @@ -1,6 +1,5 @@ edges | tests2.cpp:50:13:50:19 | global1 indirection | tests2.cpp:82:14:82:20 | global1 indirection | -| tests2.cpp:50:13:50:19 | global1 indirection | tests2.cpp:82:14:82:20 | global1 indirection | | tests2.cpp:50:23:50:43 | call to mysql_get_client_info indirection | tests2.cpp:50:13:50:19 | global1 indirection | | tests2.cpp:63:13:63:18 | call to getenv indirection | tests2.cpp:63:13:63:26 | call to getenv indirection | | tests2.cpp:64:13:64:18 | call to getenv indirection | tests2.cpp:64:13:64:26 | call to getenv indirection | @@ -8,29 +7,24 @@ edges | tests2.cpp:66:13:66:18 | call to getenv indirection | tests2.cpp:66:13:66:34 | call to getenv indirection | | tests2.cpp:78:18:78:38 | call to mysql_get_client_info indirection | tests2.cpp:81:14:81:19 | buffer indirection | | tests2.cpp:91:42:91:45 | str1 indirection | tests2.cpp:93:14:93:17 | str1 indirection | -| tests2.cpp:91:42:91:45 | str1 indirection | tests2.cpp:93:14:93:17 | str1 indirection | -| tests2.cpp:101:8:101:15 | call to getpwuid indirection | tests2.cpp:102:14:102:15 | pw indirection | | tests2.cpp:101:8:101:15 | call to getpwuid indirection | tests2.cpp:102:14:102:15 | pw indirection | | tests2.cpp:109:3:109:36 | ... = ... indirection | tests2.cpp:109:6:109:8 | c1 indirection [post update] [ptr indirection] | | tests2.cpp:109:6:109:8 | c1 indirection [post update] [ptr indirection] | tests2.cpp:111:14:111:15 | c1 indirection [ptr indirection] | | tests2.cpp:109:12:109:17 | call to getenv indirection | tests2.cpp:109:3:109:36 | ... = ... indirection | | tests2.cpp:111:14:111:15 | c1 indirection [ptr indirection] | tests2.cpp:111:14:111:19 | ptr indirection | | tests2.cpp:111:14:111:15 | c1 indirection [ptr indirection] | tests2.cpp:111:17:111:19 | ptr indirection | +| tests2.cpp:111:14:111:15 | c1 indirection [ptr indirection] | tests2.cpp:111:17:111:19 | ptr indirection | | tests2.cpp:111:17:111:19 | ptr indirection | tests2.cpp:111:14:111:19 | ptr indirection | | tests2.cpp:111:17:111:19 | ptr indirection | tests2.cpp:111:17:111:19 | ptr indirection | +| tests2.cpp:111:17:111:19 | ptr indirection | tests2.cpp:111:17:111:19 | ptr indirection | | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:39:19:39:22 | path indirection | | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:39:19:39:22 | path indirection | -| tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:39:19:39:22 | path indirection | -| tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:43:20:43:23 | path indirection | | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:43:20:43:23 | path indirection | | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:43:20:43:23 | path indirection | | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:76:19:76:22 | path indirection | | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:76:19:76:22 | path indirection | -| tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:76:19:76:22 | path indirection | | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:80:20:80:23 | path indirection | | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:80:20:80:23 | path indirection | -| tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:80:20:80:23 | path indirection | -| tests_sysconf.cpp:36:21:36:27 | confstr output argument | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | | tests_sysconf.cpp:36:21:36:27 | confstr output argument | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | | tests_sysconf.cpp:36:21:36:27 | confstr output argument | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | nodes @@ -52,13 +46,10 @@ nodes | tests2.cpp:80:14:80:34 | call to mysql_get_client_info indirection | semmle.label | call to mysql_get_client_info indirection | | tests2.cpp:81:14:81:19 | buffer indirection | semmle.label | buffer indirection | | tests2.cpp:82:14:82:20 | global1 indirection | semmle.label | global1 indirection | -| tests2.cpp:82:14:82:20 | global1 indirection | semmle.label | global1 indirection | | tests2.cpp:91:42:91:45 | str1 indirection | semmle.label | str1 indirection | | tests2.cpp:93:14:93:17 | str1 indirection | semmle.label | str1 indirection | -| tests2.cpp:93:14:93:17 | str1 indirection | semmle.label | str1 indirection | | tests2.cpp:101:8:101:15 | call to getpwuid indirection | semmle.label | call to getpwuid indirection | | tests2.cpp:102:14:102:15 | pw indirection | semmle.label | pw indirection | -| tests2.cpp:102:14:102:15 | pw indirection | semmle.label | pw indirection | | tests2.cpp:109:3:109:36 | ... = ... indirection | semmle.label | ... = ... indirection | | tests2.cpp:109:6:109:8 | c1 indirection [post update] [ptr indirection] | semmle.label | c1 indirection [post update] [ptr indirection] | | tests2.cpp:109:12:109:17 | call to getenv indirection | semmle.label | call to getenv indirection | @@ -69,21 +60,16 @@ nodes | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | semmle.label | call to getenv indirection | | tests_sockets.cpp:39:19:39:22 | path indirection | semmle.label | path indirection | | tests_sockets.cpp:39:19:39:22 | path indirection | semmle.label | path indirection | -| tests_sockets.cpp:39:19:39:22 | path indirection | semmle.label | path indirection | -| tests_sockets.cpp:43:20:43:23 | path indirection | semmle.label | path indirection | | tests_sockets.cpp:43:20:43:23 | path indirection | semmle.label | path indirection | | tests_sockets.cpp:43:20:43:23 | path indirection | semmle.label | path indirection | | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | semmle.label | call to getenv indirection | | tests_sockets.cpp:76:19:76:22 | path indirection | semmle.label | path indirection | | tests_sockets.cpp:76:19:76:22 | path indirection | semmle.label | path indirection | -| tests_sockets.cpp:76:19:76:22 | path indirection | semmle.label | path indirection | -| tests_sockets.cpp:80:20:80:23 | path indirection | semmle.label | path indirection | | tests_sockets.cpp:80:20:80:23 | path indirection | semmle.label | path indirection | | tests_sockets.cpp:80:20:80:23 | path indirection | semmle.label | path indirection | | tests_sysconf.cpp:36:21:36:27 | confstr output argument | semmle.label | confstr output argument | | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | semmle.label | pathbuf indirection | | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | semmle.label | pathbuf indirection | -| tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | semmle.label | pathbuf indirection | subpaths #select | tests2.cpp:63:13:63:18 | call to getenv indirection | tests2.cpp:63:13:63:18 | call to getenv indirection | tests2.cpp:63:13:63:18 | call to getenv indirection | This operation exposes system data from $@. | tests2.cpp:63:13:63:18 | call to getenv indirection | call to getenv indirection | @@ -97,25 +83,17 @@ subpaths | tests2.cpp:80:14:80:34 | call to mysql_get_client_info indirection | tests2.cpp:80:14:80:34 | call to mysql_get_client_info indirection | tests2.cpp:80:14:80:34 | call to mysql_get_client_info indirection | This operation exposes system data from $@. | tests2.cpp:80:14:80:34 | call to mysql_get_client_info indirection | call to mysql_get_client_info indirection | | tests2.cpp:81:14:81:19 | buffer indirection | tests2.cpp:78:18:78:38 | call to mysql_get_client_info indirection | tests2.cpp:81:14:81:19 | buffer indirection | This operation exposes system data from $@. | tests2.cpp:78:18:78:38 | call to mysql_get_client_info indirection | call to mysql_get_client_info indirection | | tests2.cpp:82:14:82:20 | global1 indirection | tests2.cpp:50:23:50:43 | call to mysql_get_client_info indirection | tests2.cpp:82:14:82:20 | global1 indirection | This operation exposes system data from $@. | tests2.cpp:50:23:50:43 | call to mysql_get_client_info indirection | call to mysql_get_client_info indirection | -| tests2.cpp:82:14:82:20 | global1 indirection | tests2.cpp:50:23:50:43 | call to mysql_get_client_info indirection | tests2.cpp:82:14:82:20 | global1 indirection | This operation exposes system data from $@. | tests2.cpp:50:23:50:43 | call to mysql_get_client_info indirection | call to mysql_get_client_info indirection | | tests2.cpp:93:14:93:17 | str1 indirection | tests2.cpp:91:42:91:45 | str1 indirection | tests2.cpp:93:14:93:17 | str1 indirection | This operation exposes system data from $@. | tests2.cpp:91:42:91:45 | str1 indirection | str1 indirection | -| tests2.cpp:93:14:93:17 | str1 indirection | tests2.cpp:91:42:91:45 | str1 indirection | tests2.cpp:93:14:93:17 | str1 indirection | This operation exposes system data from $@. | tests2.cpp:91:42:91:45 | str1 indirection | str1 indirection | -| tests2.cpp:102:14:102:15 | pw indirection | tests2.cpp:101:8:101:15 | call to getpwuid indirection | tests2.cpp:102:14:102:15 | pw indirection | This operation exposes system data from $@. | tests2.cpp:101:8:101:15 | call to getpwuid indirection | call to getpwuid indirection | | tests2.cpp:102:14:102:15 | pw indirection | tests2.cpp:101:8:101:15 | call to getpwuid indirection | tests2.cpp:102:14:102:15 | pw indirection | This operation exposes system data from $@. | tests2.cpp:101:8:101:15 | call to getpwuid indirection | call to getpwuid indirection | | tests2.cpp:111:14:111:19 | ptr indirection | tests2.cpp:109:12:109:17 | call to getenv indirection | tests2.cpp:111:14:111:19 | ptr indirection | This operation exposes system data from $@. | tests2.cpp:109:12:109:17 | call to getenv indirection | call to getenv indirection | | tests2.cpp:111:17:111:19 | ptr indirection | tests2.cpp:109:12:109:17 | call to getenv indirection | tests2.cpp:111:17:111:19 | ptr indirection | This operation exposes system data from $@. | tests2.cpp:109:12:109:17 | call to getenv indirection | call to getenv indirection | | tests_sockets.cpp:39:19:39:22 | path indirection | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:39:19:39:22 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | call to getenv indirection | | tests_sockets.cpp:39:19:39:22 | path indirection | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:39:19:39:22 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | call to getenv indirection | -| tests_sockets.cpp:39:19:39:22 | path indirection | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:39:19:39:22 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | call to getenv indirection | -| tests_sockets.cpp:43:20:43:23 | path indirection | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:43:20:43:23 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | call to getenv indirection | | tests_sockets.cpp:43:20:43:23 | path indirection | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:43:20:43:23 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | call to getenv indirection | | tests_sockets.cpp:43:20:43:23 | path indirection | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | tests_sockets.cpp:43:20:43:23 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:26:15:26:20 | call to getenv indirection | call to getenv indirection | | tests_sockets.cpp:76:19:76:22 | path indirection | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:76:19:76:22 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | call to getenv indirection | | tests_sockets.cpp:76:19:76:22 | path indirection | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:76:19:76:22 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | call to getenv indirection | -| tests_sockets.cpp:76:19:76:22 | path indirection | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:76:19:76:22 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | call to getenv indirection | -| tests_sockets.cpp:80:20:80:23 | path indirection | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:80:20:80:23 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | call to getenv indirection | | tests_sockets.cpp:80:20:80:23 | path indirection | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:80:20:80:23 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | call to getenv indirection | | tests_sockets.cpp:80:20:80:23 | path indirection | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | tests_sockets.cpp:80:20:80:23 | path indirection | This operation exposes system data from $@. | tests_sockets.cpp:63:15:63:20 | call to getenv indirection | call to getenv indirection | | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | tests_sysconf.cpp:36:21:36:27 | confstr output argument | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | This operation exposes system data from $@. | tests_sysconf.cpp:36:21:36:27 | confstr output argument | confstr output argument | | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | tests_sysconf.cpp:36:21:36:27 | confstr output argument | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | This operation exposes system data from $@. | tests_sysconf.cpp:36:21:36:27 | confstr output argument | confstr output argument | -| tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | tests_sysconf.cpp:36:21:36:27 | confstr output argument | tests_sysconf.cpp:39:19:39:25 | pathbuf indirection | This operation exposes system data from $@. | tests_sysconf.cpp:36:21:36:27 | confstr output argument | confstr output argument | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected index 4c37d69d3d6..79d0c0c8921 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected @@ -6,20 +6,15 @@ edges | tests.cpp:58:41:58:46 | call to getenv indirection | tests.cpp:58:41:58:62 | call to getenv indirection | | tests.cpp:59:43:59:48 | call to getenv indirection | tests.cpp:59:43:59:64 | call to getenv indirection | | tests.cpp:62:7:62:18 | global_token indirection | tests.cpp:71:27:71:38 | global_token indirection | -| tests.cpp:62:7:62:18 | global_token indirection | tests.cpp:71:27:71:38 | global_token indirection | -| tests.cpp:62:7:62:18 | global_token indirection | tests.cpp:73:27:73:31 | maybe indirection | | tests.cpp:62:7:62:18 | global_token indirection | tests.cpp:73:27:73:31 | maybe indirection | | tests.cpp:62:22:62:27 | call to getenv indirection | tests.cpp:62:7:62:18 | global_token indirection | | tests.cpp:86:29:86:31 | msg indirection | tests.cpp:88:15:88:17 | msg indirection | -| tests.cpp:86:29:86:31 | msg indirection | tests.cpp:88:15:88:17 | msg indirection | | tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:97:13:97:34 | call to getenv indirection | | tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:97:13:97:34 | call to getenv indirection | | tests.cpp:97:13:97:34 | call to getenv indirection | tests.cpp:86:29:86:31 | msg indirection | | tests.cpp:107:30:107:32 | msg indirection | tests.cpp:111:15:111:17 | tmp indirection | -| tests.cpp:107:30:107:32 | msg indirection | tests.cpp:111:15:111:17 | tmp indirection | | tests.cpp:114:30:114:32 | msg indirection | tests.cpp:119:7:119:12 | buffer indirection | | tests.cpp:122:30:122:32 | msg indirection | tests.cpp:124:15:124:17 | msg indirection | -| tests.cpp:122:30:122:32 | msg indirection | tests.cpp:124:15:124:17 | msg indirection | | tests.cpp:131:14:131:19 | call to getenv indirection | tests.cpp:131:14:131:35 | call to getenv indirection | | tests.cpp:131:14:131:35 | call to getenv indirection | tests.cpp:107:30:107:32 | msg indirection | | tests.cpp:132:14:132:19 | call to getenv indirection | tests.cpp:132:14:132:35 | call to getenv indirection | @@ -28,8 +23,6 @@ edges | tests.cpp:133:14:133:19 | call to getenv indirection | tests.cpp:133:14:133:35 | call to getenv indirection | | tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:122:30:122:32 | msg indirection | | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection | -| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection | -| tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection | | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection | nodes | tests.cpp:48:15:48:20 | call to getenv indirection | semmle.label | call to getenv indirection | @@ -53,24 +46,19 @@ nodes | tests.cpp:62:7:62:18 | global_token indirection | semmle.label | global_token indirection | | tests.cpp:62:22:62:27 | call to getenv indirection | semmle.label | call to getenv indirection | | tests.cpp:71:27:71:38 | global_token indirection | semmle.label | global_token indirection | -| tests.cpp:71:27:71:38 | global_token indirection | semmle.label | global_token indirection | -| tests.cpp:73:27:73:31 | maybe indirection | semmle.label | maybe indirection | | tests.cpp:73:27:73:31 | maybe indirection | semmle.label | maybe indirection | | tests.cpp:86:29:86:31 | msg indirection | semmle.label | msg indirection | | tests.cpp:88:15:88:17 | msg indirection | semmle.label | msg indirection | -| tests.cpp:88:15:88:17 | msg indirection | semmle.label | msg indirection | | tests.cpp:97:13:97:18 | call to getenv indirection | semmle.label | call to getenv indirection | | tests.cpp:97:13:97:18 | call to getenv indirection | semmle.label | call to getenv indirection | | tests.cpp:97:13:97:34 | call to getenv indirection | semmle.label | call to getenv indirection | | tests.cpp:97:13:97:34 | call to getenv indirection | semmle.label | call to getenv indirection | | tests.cpp:107:30:107:32 | msg indirection | semmle.label | msg indirection | | tests.cpp:111:15:111:17 | tmp indirection | semmle.label | tmp indirection | -| tests.cpp:111:15:111:17 | tmp indirection | semmle.label | tmp indirection | | tests.cpp:114:30:114:32 | msg indirection | semmle.label | msg indirection | | tests.cpp:119:7:119:12 | buffer indirection | semmle.label | buffer indirection | | tests.cpp:122:30:122:32 | msg indirection | semmle.label | msg indirection | | tests.cpp:124:15:124:17 | msg indirection | semmle.label | msg indirection | -| tests.cpp:124:15:124:17 | msg indirection | semmle.label | msg indirection | | tests.cpp:131:14:131:19 | call to getenv indirection | semmle.label | call to getenv indirection | | tests.cpp:131:14:131:35 | call to getenv indirection | semmle.label | call to getenv indirection | | tests.cpp:132:14:132:19 | call to getenv indirection | semmle.label | call to getenv indirection | @@ -81,8 +69,6 @@ nodes | tests.cpp:133:14:133:35 | call to getenv indirection | semmle.label | call to getenv indirection | | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | semmle.label | call to getpwnam indirection | | tests_passwd.cpp:18:29:18:31 | pwd indirection | semmle.label | pwd indirection | -| tests_passwd.cpp:18:29:18:31 | pwd indirection | semmle.label | pwd indirection | -| tests_passwd.cpp:19:26:19:28 | pwd indirection | semmle.label | pwd indirection | | tests_passwd.cpp:19:26:19:28 | pwd indirection | semmle.label | pwd indirection | subpaths #select @@ -99,21 +85,14 @@ subpaths | tests.cpp:59:43:59:48 | call to getenv indirection | tests.cpp:59:43:59:48 | call to getenv indirection | tests.cpp:59:43:59:48 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:59:43:59:48 | call to getenv indirection | call to getenv indirection | | tests.cpp:59:43:59:64 | call to getenv indirection | tests.cpp:59:43:59:48 | call to getenv indirection | tests.cpp:59:43:59:64 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:59:43:59:48 | call to getenv indirection | call to getenv indirection | | tests.cpp:71:27:71:38 | global_token indirection | tests.cpp:62:22:62:27 | call to getenv indirection | tests.cpp:71:27:71:38 | global_token indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:62:22:62:27 | call to getenv indirection | call to getenv indirection | -| tests.cpp:71:27:71:38 | global_token indirection | tests.cpp:62:22:62:27 | call to getenv indirection | tests.cpp:71:27:71:38 | global_token indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:62:22:62:27 | call to getenv indirection | call to getenv indirection | | tests.cpp:73:27:73:31 | maybe indirection | tests.cpp:62:22:62:27 | call to getenv indirection | tests.cpp:73:27:73:31 | maybe indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:62:22:62:27 | call to getenv indirection | call to getenv indirection | -| tests.cpp:73:27:73:31 | maybe indirection | tests.cpp:62:22:62:27 | call to getenv indirection | tests.cpp:73:27:73:31 | maybe indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:62:22:62:27 | call to getenv indirection | call to getenv indirection | -| tests.cpp:88:15:88:17 | msg indirection | tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:88:15:88:17 | msg indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:97:13:97:18 | call to getenv indirection | call to getenv indirection | | tests.cpp:88:15:88:17 | msg indirection | tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:88:15:88:17 | msg indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:97:13:97:18 | call to getenv indirection | call to getenv indirection | | tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:97:13:97:18 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:97:13:97:18 | call to getenv indirection | call to getenv indirection | | tests.cpp:97:13:97:34 | call to getenv indirection | tests.cpp:97:13:97:18 | call to getenv indirection | tests.cpp:97:13:97:34 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:97:13:97:18 | call to getenv indirection | call to getenv indirection | | tests.cpp:111:15:111:17 | tmp indirection | tests.cpp:131:14:131:19 | call to getenv indirection | tests.cpp:111:15:111:17 | tmp indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:131:14:131:19 | call to getenv indirection | call to getenv indirection | -| tests.cpp:111:15:111:17 | tmp indirection | tests.cpp:131:14:131:19 | call to getenv indirection | tests.cpp:111:15:111:17 | tmp indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:131:14:131:19 | call to getenv indirection | call to getenv indirection | | tests.cpp:119:7:119:12 | buffer indirection | tests.cpp:132:14:132:19 | call to getenv indirection | tests.cpp:119:7:119:12 | buffer indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:132:14:132:19 | call to getenv indirection | call to getenv indirection | | tests.cpp:124:15:124:17 | msg indirection | tests.cpp:133:14:133:19 | call to getenv indirection | tests.cpp:124:15:124:17 | msg indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:19 | call to getenv indirection | call to getenv indirection | -| tests.cpp:124:15:124:17 | msg indirection | tests.cpp:133:14:133:19 | call to getenv indirection | tests.cpp:124:15:124:17 | msg indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:19 | call to getenv indirection | call to getenv indirection | | tests.cpp:133:14:133:19 | call to getenv indirection | tests.cpp:133:14:133:19 | call to getenv indirection | tests.cpp:133:14:133:19 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:19 | call to getenv indirection | call to getenv indirection | | tests.cpp:133:14:133:35 | call to getenv indirection | tests.cpp:133:14:133:19 | call to getenv indirection | tests.cpp:133:14:133:35 | call to getenv indirection | This operation potentially exposes sensitive system data from $@. | tests.cpp:133:14:133:19 | call to getenv indirection | call to getenv indirection | | tests_passwd.cpp:18:29:18:31 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection | -| tests_passwd.cpp:18:29:18:31 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:18:29:18:31 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection | -| tests_passwd.cpp:19:26:19:28 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection | | tests_passwd.cpp:19:26:19:28 | pwd indirection | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | tests_passwd.cpp:19:26:19:28 | pwd indirection | This operation potentially exposes sensitive system data from $@. | tests_passwd.cpp:16:8:16:15 | call to getpwnam indirection | call to getpwnam indirection | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected index 7acab8885ed..275e9e1fae9 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected @@ -1,38 +1,25 @@ edges | tests2.cpp:20:17:20:31 | call to SAXParser | tests2.cpp:22:2:22:2 | p indirection | -| tests2.cpp:20:17:20:31 | call to SAXParser | tests2.cpp:22:2:22:2 | p indirection | -| tests2.cpp:33:17:33:31 | call to SAXParser | tests2.cpp:37:2:37:2 | p indirection | | tests2.cpp:33:17:33:31 | call to SAXParser | tests2.cpp:37:2:37:2 | p indirection | | tests2.cpp:49:12:49:12 | call to SAXParser | tests2.cpp:51:2:51:2 | p indirection | | tests3.cpp:23:21:23:53 | call to createXMLReader indirection | tests3.cpp:25:2:25:2 | p indirection | -| tests3.cpp:23:21:23:53 | call to createXMLReader indirection | tests3.cpp:25:2:25:2 | p indirection | -| tests3.cpp:35:16:35:20 | p_3_3 indirection | tests3.cpp:38:2:38:6 | p_3_3 indirection | | tests3.cpp:35:16:35:20 | p_3_3 indirection | tests3.cpp:38:2:38:6 | p_3_3 indirection | | tests3.cpp:35:24:35:56 | call to createXMLReader indirection | tests3.cpp:35:16:35:20 | p_3_3 indirection | | tests3.cpp:48:16:48:20 | p_3_5 indirection | tests3.cpp:56:2:56:6 | p_3_5 indirection | -| tests3.cpp:48:16:48:20 | p_3_5 indirection | tests3.cpp:56:2:56:6 | p_3_5 indirection | | tests3.cpp:48:24:48:56 | call to createXMLReader indirection | tests3.cpp:48:16:48:20 | p_3_5 indirection | | tests3.cpp:60:21:60:53 | call to createXMLReader indirection | tests3.cpp:63:2:63:2 | p indirection | -| tests3.cpp:60:21:60:53 | call to createXMLReader indirection | tests3.cpp:63:2:63:2 | p indirection | -| tests3.cpp:67:21:67:53 | call to createXMLReader indirection | tests3.cpp:70:2:70:2 | p indirection | | tests3.cpp:67:21:67:53 | call to createXMLReader indirection | tests3.cpp:70:2:70:2 | p indirection | | tests5.cpp:27:25:27:38 | call to createLSParser indirection | tests5.cpp:29:2:29:2 | p indirection | -| tests5.cpp:27:25:27:38 | call to createLSParser indirection | tests5.cpp:29:2:29:2 | p indirection | -| tests5.cpp:40:25:40:38 | call to createLSParser indirection | tests5.cpp:43:2:43:2 | p indirection | | tests5.cpp:40:25:40:38 | call to createLSParser indirection | tests5.cpp:43:2:43:2 | p indirection | | tests5.cpp:55:25:55:38 | call to createLSParser indirection | tests5.cpp:59:2:59:2 | p indirection | -| tests5.cpp:55:25:55:38 | call to createLSParser indirection | tests5.cpp:59:2:59:2 | p indirection | -| tests5.cpp:63:21:63:24 | g_p2 indirection | tests5.cpp:77:2:77:5 | g_p2 indirection | | tests5.cpp:63:21:63:24 | g_p2 indirection | tests5.cpp:77:2:77:5 | g_p2 indirection | | tests5.cpp:70:17:70:30 | call to createLSParser indirection | tests5.cpp:63:21:63:24 | g_p2 indirection | | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:83:2:83:2 | p indirection | | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:83:2:83:2 | p indirection | -| tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:83:2:83:2 | p indirection | | tests5.cpp:83:2:83:2 | p indirection | tests5.cpp:85:2:85:2 | p indirection | | tests5.cpp:85:2:85:2 | p indirection | tests5.cpp:86:2:86:2 | p indirection | | tests5.cpp:86:2:86:2 | p indirection | tests5.cpp:88:2:88:2 | p indirection | | tests5.cpp:88:2:88:2 | p indirection | tests5.cpp:89:2:89:2 | p indirection | -| tests5.cpp:88:2:88:2 | p indirection | tests5.cpp:89:2:89:2 | p indirection | | tests.cpp:15:23:15:43 | call to XercesDOMParser | tests.cpp:17:2:17:2 | p indirection | | tests.cpp:28:23:28:43 | call to XercesDOMParser | tests.cpp:31:2:31:2 | p indirection | | tests.cpp:35:23:35:43 | call to XercesDOMParser | tests.cpp:35:23:35:43 | new indirection | @@ -63,29 +50,22 @@ edges nodes | tests2.cpp:20:17:20:31 | call to SAXParser | semmle.label | call to SAXParser | | tests2.cpp:22:2:22:2 | p indirection | semmle.label | p indirection | -| tests2.cpp:22:2:22:2 | p indirection | semmle.label | p indirection | | tests2.cpp:33:17:33:31 | call to SAXParser | semmle.label | call to SAXParser | | tests2.cpp:37:2:37:2 | p indirection | semmle.label | p indirection | -| tests2.cpp:37:2:37:2 | p indirection | semmle.label | p indirection | | tests2.cpp:49:12:49:12 | call to SAXParser | semmle.label | call to SAXParser | | tests2.cpp:51:2:51:2 | p indirection | semmle.label | p indirection | | tests3.cpp:23:21:23:53 | call to createXMLReader indirection | semmle.label | call to createXMLReader indirection | | tests3.cpp:25:2:25:2 | p indirection | semmle.label | p indirection | -| tests3.cpp:25:2:25:2 | p indirection | semmle.label | p indirection | | tests3.cpp:35:16:35:20 | p_3_3 indirection | semmle.label | p_3_3 indirection | | tests3.cpp:35:24:35:56 | call to createXMLReader indirection | semmle.label | call to createXMLReader indirection | | tests3.cpp:38:2:38:6 | p_3_3 indirection | semmle.label | p_3_3 indirection | -| tests3.cpp:38:2:38:6 | p_3_3 indirection | semmle.label | p_3_3 indirection | | tests3.cpp:48:16:48:20 | p_3_5 indirection | semmle.label | p_3_5 indirection | | tests3.cpp:48:24:48:56 | call to createXMLReader indirection | semmle.label | call to createXMLReader indirection | | tests3.cpp:56:2:56:6 | p_3_5 indirection | semmle.label | p_3_5 indirection | -| tests3.cpp:56:2:56:6 | p_3_5 indirection | semmle.label | p_3_5 indirection | | tests3.cpp:60:21:60:53 | call to createXMLReader indirection | semmle.label | call to createXMLReader indirection | | tests3.cpp:63:2:63:2 | p indirection | semmle.label | p indirection | -| tests3.cpp:63:2:63:2 | p indirection | semmle.label | p indirection | | tests3.cpp:67:21:67:53 | call to createXMLReader indirection | semmle.label | call to createXMLReader indirection | | tests3.cpp:70:2:70:2 | p indirection | semmle.label | p indirection | -| tests3.cpp:70:2:70:2 | p indirection | semmle.label | p indirection | | tests4.cpp:26:34:26:48 | XML_PARSE_NOENT | semmle.label | XML_PARSE_NOENT | | tests4.cpp:36:34:36:50 | XML_PARSE_DTDLOAD | semmle.label | XML_PARSE_DTDLOAD | | tests4.cpp:46:34:46:68 | ... \| ... | semmle.label | ... \| ... | @@ -93,26 +73,20 @@ nodes | tests4.cpp:130:39:130:55 | XML_PARSE_DTDLOAD | semmle.label | XML_PARSE_DTDLOAD | | tests5.cpp:27:25:27:38 | call to createLSParser indirection | semmle.label | call to createLSParser indirection | | tests5.cpp:29:2:29:2 | p indirection | semmle.label | p indirection | -| tests5.cpp:29:2:29:2 | p indirection | semmle.label | p indirection | | tests5.cpp:40:25:40:38 | call to createLSParser indirection | semmle.label | call to createLSParser indirection | | tests5.cpp:43:2:43:2 | p indirection | semmle.label | p indirection | -| tests5.cpp:43:2:43:2 | p indirection | semmle.label | p indirection | | tests5.cpp:55:25:55:38 | call to createLSParser indirection | semmle.label | call to createLSParser indirection | | tests5.cpp:59:2:59:2 | p indirection | semmle.label | p indirection | -| tests5.cpp:59:2:59:2 | p indirection | semmle.label | p indirection | | tests5.cpp:63:21:63:24 | g_p2 indirection | semmle.label | g_p2 indirection | | tests5.cpp:70:17:70:30 | call to createLSParser indirection | semmle.label | call to createLSParser indirection | | tests5.cpp:77:2:77:5 | g_p2 indirection | semmle.label | g_p2 indirection | -| tests5.cpp:77:2:77:5 | g_p2 indirection | semmle.label | g_p2 indirection | | tests5.cpp:81:25:81:38 | call to createLSParser indirection | semmle.label | call to createLSParser indirection | | tests5.cpp:83:2:83:2 | p indirection | semmle.label | p indirection | | tests5.cpp:83:2:83:2 | p indirection | semmle.label | p indirection | -| tests5.cpp:83:2:83:2 | p indirection | semmle.label | p indirection | | tests5.cpp:85:2:85:2 | p indirection | semmle.label | p indirection | | tests5.cpp:86:2:86:2 | p indirection | semmle.label | p indirection | | tests5.cpp:88:2:88:2 | p indirection | semmle.label | p indirection | | tests5.cpp:89:2:89:2 | p indirection | semmle.label | p indirection | -| tests5.cpp:89:2:89:2 | p indirection | semmle.label | p indirection | | tests.cpp:15:23:15:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser | | tests.cpp:17:2:17:2 | p indirection | semmle.label | p indirection | | tests.cpp:28:23:28:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser | @@ -152,19 +126,12 @@ nodes subpaths #select | tests2.cpp:22:2:22:2 | p indirection | tests2.cpp:20:17:20:31 | call to SAXParser | tests2.cpp:22:2:22:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests2.cpp:20:17:20:31 | call to SAXParser | XML parser | -| tests2.cpp:22:2:22:2 | p indirection | tests2.cpp:20:17:20:31 | call to SAXParser | tests2.cpp:22:2:22:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests2.cpp:20:17:20:31 | call to SAXParser | XML parser | -| tests2.cpp:37:2:37:2 | p indirection | tests2.cpp:33:17:33:31 | call to SAXParser | tests2.cpp:37:2:37:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests2.cpp:33:17:33:31 | call to SAXParser | XML parser | | tests2.cpp:37:2:37:2 | p indirection | tests2.cpp:33:17:33:31 | call to SAXParser | tests2.cpp:37:2:37:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests2.cpp:33:17:33:31 | call to SAXParser | XML parser | | tests2.cpp:51:2:51:2 | p indirection | tests2.cpp:49:12:49:12 | call to SAXParser | tests2.cpp:51:2:51:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests2.cpp:49:12:49:12 | call to SAXParser | XML parser | | tests3.cpp:25:2:25:2 | p indirection | tests3.cpp:23:21:23:53 | call to createXMLReader indirection | tests3.cpp:25:2:25:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:23:21:23:53 | call to createXMLReader indirection | XML parser | -| tests3.cpp:25:2:25:2 | p indirection | tests3.cpp:23:21:23:53 | call to createXMLReader indirection | tests3.cpp:25:2:25:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:23:21:23:53 | call to createXMLReader indirection | XML parser | -| tests3.cpp:38:2:38:6 | p_3_3 indirection | tests3.cpp:35:24:35:56 | call to createXMLReader indirection | tests3.cpp:38:2:38:6 | p_3_3 indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:35:24:35:56 | call to createXMLReader indirection | XML parser | | tests3.cpp:38:2:38:6 | p_3_3 indirection | tests3.cpp:35:24:35:56 | call to createXMLReader indirection | tests3.cpp:38:2:38:6 | p_3_3 indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:35:24:35:56 | call to createXMLReader indirection | XML parser | | tests3.cpp:56:2:56:6 | p_3_5 indirection | tests3.cpp:48:24:48:56 | call to createXMLReader indirection | tests3.cpp:56:2:56:6 | p_3_5 indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:48:24:48:56 | call to createXMLReader indirection | XML parser | -| tests3.cpp:56:2:56:6 | p_3_5 indirection | tests3.cpp:48:24:48:56 | call to createXMLReader indirection | tests3.cpp:56:2:56:6 | p_3_5 indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:48:24:48:56 | call to createXMLReader indirection | XML parser | | tests3.cpp:63:2:63:2 | p indirection | tests3.cpp:60:21:60:53 | call to createXMLReader indirection | tests3.cpp:63:2:63:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:60:21:60:53 | call to createXMLReader indirection | XML parser | -| tests3.cpp:63:2:63:2 | p indirection | tests3.cpp:60:21:60:53 | call to createXMLReader indirection | tests3.cpp:63:2:63:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:60:21:60:53 | call to createXMLReader indirection | XML parser | -| tests3.cpp:70:2:70:2 | p indirection | tests3.cpp:67:21:67:53 | call to createXMLReader indirection | tests3.cpp:70:2:70:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:67:21:67:53 | call to createXMLReader indirection | XML parser | | tests3.cpp:70:2:70:2 | p indirection | tests3.cpp:67:21:67:53 | call to createXMLReader indirection | tests3.cpp:70:2:70:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests3.cpp:67:21:67:53 | call to createXMLReader indirection | XML parser | | tests4.cpp:26:34:26:48 | XML_PARSE_NOENT | tests4.cpp:26:34:26:48 | XML_PARSE_NOENT | tests4.cpp:26:34:26:48 | XML_PARSE_NOENT | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests4.cpp:26:34:26:48 | XML_PARSE_NOENT | XML parser | | tests4.cpp:36:34:36:50 | XML_PARSE_DTDLOAD | tests4.cpp:36:34:36:50 | XML_PARSE_DTDLOAD | tests4.cpp:36:34:36:50 | XML_PARSE_DTDLOAD | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests4.cpp:36:34:36:50 | XML_PARSE_DTDLOAD | XML parser | @@ -172,16 +139,10 @@ subpaths | tests4.cpp:77:34:77:38 | flags | tests4.cpp:77:34:77:38 | flags | tests4.cpp:77:34:77:38 | flags | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests4.cpp:77:34:77:38 | flags | XML parser | | tests4.cpp:130:39:130:55 | XML_PARSE_DTDLOAD | tests4.cpp:130:39:130:55 | XML_PARSE_DTDLOAD | tests4.cpp:130:39:130:55 | XML_PARSE_DTDLOAD | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests4.cpp:130:39:130:55 | XML_PARSE_DTDLOAD | XML parser | | tests5.cpp:29:2:29:2 | p indirection | tests5.cpp:27:25:27:38 | call to createLSParser indirection | tests5.cpp:29:2:29:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:27:25:27:38 | call to createLSParser indirection | XML parser | -| tests5.cpp:29:2:29:2 | p indirection | tests5.cpp:27:25:27:38 | call to createLSParser indirection | tests5.cpp:29:2:29:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:27:25:27:38 | call to createLSParser indirection | XML parser | -| tests5.cpp:43:2:43:2 | p indirection | tests5.cpp:40:25:40:38 | call to createLSParser indirection | tests5.cpp:43:2:43:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:40:25:40:38 | call to createLSParser indirection | XML parser | | tests5.cpp:43:2:43:2 | p indirection | tests5.cpp:40:25:40:38 | call to createLSParser indirection | tests5.cpp:43:2:43:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:40:25:40:38 | call to createLSParser indirection | XML parser | | tests5.cpp:59:2:59:2 | p indirection | tests5.cpp:55:25:55:38 | call to createLSParser indirection | tests5.cpp:59:2:59:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:55:25:55:38 | call to createLSParser indirection | XML parser | -| tests5.cpp:59:2:59:2 | p indirection | tests5.cpp:55:25:55:38 | call to createLSParser indirection | tests5.cpp:59:2:59:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:55:25:55:38 | call to createLSParser indirection | XML parser | -| tests5.cpp:77:2:77:5 | g_p2 indirection | tests5.cpp:70:17:70:30 | call to createLSParser indirection | tests5.cpp:77:2:77:5 | g_p2 indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:70:17:70:30 | call to createLSParser indirection | XML parser | | tests5.cpp:77:2:77:5 | g_p2 indirection | tests5.cpp:70:17:70:30 | call to createLSParser indirection | tests5.cpp:77:2:77:5 | g_p2 indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:70:17:70:30 | call to createLSParser indirection | XML parser | | tests5.cpp:83:2:83:2 | p indirection | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:83:2:83:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:81:25:81:38 | call to createLSParser indirection | XML parser | -| tests5.cpp:83:2:83:2 | p indirection | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:83:2:83:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:81:25:81:38 | call to createLSParser indirection | XML parser | -| tests5.cpp:89:2:89:2 | p indirection | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:89:2:89:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:81:25:81:38 | call to createLSParser indirection | XML parser | | tests5.cpp:89:2:89:2 | p indirection | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:89:2:89:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:81:25:81:38 | call to createLSParser indirection | XML parser | | tests.cpp:17:2:17:2 | p indirection | tests.cpp:15:23:15:43 | call to XercesDOMParser | tests.cpp:17:2:17:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:15:23:15:43 | call to XercesDOMParser | XML parser | | tests.cpp:31:2:31:2 | p indirection | tests.cpp:28:23:28:43 | call to XercesDOMParser | tests.cpp:31:2:31:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:28:23:28:43 | call to XercesDOMParser | XML parser | diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj index ecc67fa5695..590c03738b0 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp.Tests/Semmle.Autobuild.CSharp.Tests.csproj @@ -8,12 +8,12 @@ - - + + all runtime; build; native; contentfiles; analyzers - + diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj index 6edc9fdcd97..1083564dd26 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/Semmle.Autobuild.CSharp.csproj @@ -3,9 +3,9 @@ net7.0 Semmle.Autobuild.CSharp Semmle.Autobuild.CSharp - + Exe - + false win-x64;linux-x64;osx-x64 enable @@ -14,8 +14,8 @@ - - + + diff --git a/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj b/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj index 83c53552cc0..7a1f537fe75 100644 --- a/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj +++ b/csharp/autobuilder/Semmle.Autobuild.Shared/Semmle.Autobuild.Shared.csproj @@ -11,7 +11,7 @@ - + diff --git a/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj b/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj index c37242cd890..5bf70a9346b 100644 --- a/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj +++ b/csharp/extractor/Semmle.Extraction.CIL/Semmle.Extraction.CIL.csproj @@ -24,7 +24,7 @@ - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index d6a19b9cd1a..f7b4ec3263b 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -85,11 +85,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching } } - if (options.UseMscorlib) - { - UseReference(typeof(object).Assembly.Location); - } - if (options.UseNuGet) { dllDirNames.Add(packageDirectory.DirInfo.FullName); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyOptions.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyOptions.cs index bf5800edb46..c669e649aee 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyOptions.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyOptions.cs @@ -40,11 +40,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// bool ScanNetFrameworkDlls { get; } - /// - /// Whether to use mscorlib as a reference. - /// - bool UseMscorlib { get; } - /// /// Determine whether the given path should be excluded. /// @@ -74,8 +69,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching public bool ScanNetFrameworkDlls { get; set; } = true; - public bool UseMscorlib { get; set; } = true; - public bool ExcludesFile(string path) => Excludes.Any(path.Contains); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotnetVersion.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotnetVersion.cs index 9ad268fde31..6d52b410412 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotnetVersion.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotnetVersion.cs @@ -10,16 +10,44 @@ namespace Semmle.Extraction.CSharp.DependencyFetching private readonly Version? preReleaseVersion; private readonly string? preReleaseVersionType; private bool IsPreRelease => preReleaseVersionType is not null && preReleaseVersion is not null; - public string FullPath + + private string FullVersion { get { var preRelease = IsPreRelease ? $"-{preReleaseVersionType}.{preReleaseVersion}" : ""; - var version = this.version + preRelease; - return Path.Combine(dir, version); + return this.version + preRelease; } } + public string FullPath => Path.Combine(dir, FullVersion); + + /** + * The full path to the reference assemblies for this runtime. + * This is the same as FullPath, except that we assume that the + * reference assemblies are in a directory called "packs" and + * the reference assemblies themselves are in a directory called + * ".Ref/ref". + * Example: + * FullPath: /usr/share/dotnet/shared/Microsoft.NETCore.App/7.0.2 + * FullPathReferenceAssemblies: /usr/share/dotnet/packs/Microsoft.NETCore.App.Ref/7.0.2/ref + */ + public string? FullPathReferenceAssemblies + { + get + { + var directories = dir.Split(Path.DirectorySeparatorChar); + if (directories.Length >= 2) + { + directories[^2] = "packs"; + directories[^1] = $"{directories[^1]}.Ref"; + return Path.Combine(string.Join(Path.DirectorySeparatorChar, directories), FullVersion, "ref"); + } + return null; + } + } + + public DotnetVersion(string dir, string version, string preReleaseVersionType, string preReleaseVersion) { this.dir = dir; diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Runtime.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Runtime.cs index cc7f77f5aac..9d1c6054d9b 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Runtime.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/Runtime.cs @@ -94,6 +94,18 @@ namespace Semmle.Extraction.CSharp.DependencyFetching } } + private string? GetVersion(string framework) + { + if (NewestRuntimes.TryGetValue(framework, out var version)) + { + var refAssemblies = version.FullPathReferenceAssemblies; + return Directory.Exists(refAssemblies) + ? refAssemblies + : version.FullPath; + } + return null; + } + /// /// Gets the .NET runtime location to use for extraction. /// @@ -105,9 +117,9 @@ namespace Semmle.Extraction.CSharp.DependencyFetching } // Location of the newest .NET Core Runtime. - if (NewestRuntimes.TryGetValue(netCoreApp, out var netCoreVersion)) + if (GetVersion(netCoreApp) is string path) { - return netCoreVersion.FullPath; + return path; } if (DesktopRuntimes.Any()) @@ -122,14 +134,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching /// /// Gets the ASP.NET runtime location to use for extraction, if one exists. /// - public string? GetAspRuntime() - { - // Location of the newest ASP.NET Core Runtime. - if (NewestRuntimes.TryGetValue(aspNetCoreApp, out var aspNetCoreVersion)) - { - return aspNetCoreVersion.FullPath; - } - return null; - } + public string? GetAspRuntime() => GetVersion(aspNetCoreApp); } } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Options.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Options.cs index 451998396ed..1965296681a 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Options.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Options.cs @@ -29,9 +29,6 @@ namespace Semmle.Extraction.CSharp.Standalone case "all-references": AnalyseCsProjFiles = !value; return true; - case "stdlib": - dependencies.UseMscorlib = value; - return true; case "skip-dotnet": dependencies.ScanNetFrameworkDlls = !value; return true; @@ -110,7 +107,7 @@ namespace Semmle.Extraction.CSharp.Standalone /// /// Outputs the command line options to the console. /// - public static void ShowHelp(System.IO.TextWriter output) + public static void ShowHelp(TextWriter output) { output.WriteLine("C# standalone extractor\n\nExtracts a C# project in the current directory without performing a build.\n"); output.WriteLine("Additional options:\n"); @@ -121,7 +118,6 @@ namespace Semmle.Extraction.CSharp.Standalone output.WriteLine(" --dry-run Stop before extraction"); output.WriteLine(" --skip-nuget Do not download nuget packages"); output.WriteLine(" --all-references Use all references (default is to only use references in .csproj files)"); - output.WriteLine(" --nostdlib Do not link mscorlib.dll (use only for extracting mscorlib itself)"); output.WriteLine(" --threads:nnn Specify number of threads (default=CPU cores)"); output.WriteLine(" --verbose Produce more output"); output.WriteLine(" --pdb Cross-reference information from PDBs where available"); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj index 38ba70ce285..525b1081bff 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/Semmle.Extraction.CSharp.Standalone.csproj @@ -6,7 +6,7 @@ Semmle.Extraction.CSharp.Standalone false false - + win-x64;linux-x64;osx-x64 enable @@ -19,7 +19,7 @@ - + diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj b/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj index 4227a1df710..a06a1df38f2 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj +++ b/csharp/extractor/Semmle.Extraction.CSharp/Semmle.Extraction.CSharp.csproj @@ -18,7 +18,7 @@ - - + + \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.Tests/Options.cs b/csharp/extractor/Semmle.Extraction.Tests/Options.cs index 8b6704b95f9..226af193eb1 100644 --- a/csharp/extractor/Semmle.Extraction.Tests/Options.cs +++ b/csharp/extractor/Semmle.Extraction.Tests/Options.cs @@ -135,9 +135,8 @@ namespace Semmle.Extraction.Tests public void StandaloneDefaults() { standaloneOptions = CSharp.Standalone.Options.Create(Array.Empty()); - Assert.Equal(0, standaloneOptions.Dependencies.DllDirs.Count); + Assert.Empty(standaloneOptions.Dependencies.DllDirs); Assert.True(standaloneOptions.Dependencies.UseNuGet); - Assert.True(standaloneOptions.Dependencies.UseMscorlib); Assert.False(standaloneOptions.SkipExtraction); Assert.Null(standaloneOptions.Dependencies.SolutionFile); Assert.True(standaloneOptions.Dependencies.ScanNetFrameworkDlls); @@ -147,12 +146,11 @@ namespace Semmle.Extraction.Tests [Fact] public void StandaloneOptions() { - standaloneOptions = CSharp.Standalone.Options.Create(new string[] { "--references:foo", "--silent", "--skip-nuget", "--skip-dotnet", "--exclude", "bar", "--nostdlib" }); + standaloneOptions = CSharp.Standalone.Options.Create(new string[] { "--references:foo", "--silent", "--skip-nuget", "--skip-dotnet", "--exclude", "bar" }); Assert.Equal("foo", standaloneOptions.Dependencies.DllDirs[0]); Assert.Equal("bar", standaloneOptions.Dependencies.Excludes[0]); Assert.Equal(Verbosity.Off, standaloneOptions.Verbosity); Assert.False(standaloneOptions.Dependencies.UseNuGet); - Assert.False(standaloneOptions.Dependencies.UseMscorlib); Assert.False(standaloneOptions.Dependencies.ScanNetFrameworkDlls); Assert.False(standaloneOptions.Errors); Assert.False(standaloneOptions.Help); diff --git a/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj b/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj index 4e04bafc638..92bf46deb44 100644 --- a/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj +++ b/csharp/extractor/Semmle.Extraction.Tests/Semmle.Extraction.Tests.csproj @@ -8,12 +8,12 @@ - - + + all runtime; build; native; contentfiles; analyzers - + diff --git a/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj b/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj index 1c15b614ce4..433bb15ab1f 100644 --- a/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj +++ b/csharp/extractor/Semmle.Extraction/Semmle.Extraction.csproj @@ -12,9 +12,9 @@ TRACE;DEBUG;DEBUG_LABELS - - - + + + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj b/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj index cb362f6df33..384555bf18c 100644 --- a/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj +++ b/csharp/extractor/Semmle.Util.Tests/Semmle.Util.Tests.csproj @@ -6,12 +6,12 @@ enable - - + + all runtime; build; native; contentfiles; analyzers - + diff --git a/csharp/extractor/Semmle.Util/Semmle.Util.csproj b/csharp/extractor/Semmle.Util/Semmle.Util.csproj index b2f15484886..894488f9f84 100644 --- a/csharp/extractor/Semmle.Util/Semmle.Util.csproj +++ b/csharp/extractor/Semmle.Util/Semmle.Util.csproj @@ -15,7 +15,7 @@ - + diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 887b20471da..e17f85e34d1 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.4 + +No user-facing changes. + ## 1.6.3 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.6.4.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.6.4.md new file mode 100644 index 00000000000..5c811dc4638 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.6.4.md @@ -0,0 +1,3 @@ +## 1.6.4 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index 00b51441d88..1910e09d6a6 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.6.3 +lastReleaseVersion: 1.6.4 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 5719e05afcf..c60da3557a0 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.6.4-dev +version: 1.6.4 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 887b20471da..e17f85e34d1 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.6.4 + +No user-facing changes. + ## 1.6.3 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.6.4.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.6.4.md new file mode 100644 index 00000000000..5c811dc4638 --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.6.4.md @@ -0,0 +1,3 @@ +## 1.6.4 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index 00b51441d88..1910e09d6a6 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.6.3 +lastReleaseVersion: 1.6.4 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 2a3524ece6d..22e9e2f575b 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.6.4-dev +version: 1.6.4 groups: - csharp - solorigate diff --git a/csharp/ql/consistency-queries/DataFlowConsistency.ql b/csharp/ql/consistency-queries/DataFlowConsistency.ql index 4ac709fd366..3fcda210961 100644 --- a/csharp/ql/consistency-queries/DataFlowConsistency.ql +++ b/csharp/ql/consistency-queries/DataFlowConsistency.ql @@ -1,12 +1,13 @@ import csharp import cil -import semmle.code.csharp.dataflow.internal.DataFlowPrivate -import semmle.code.csharp.dataflow.internal.DataFlowPublic -import semmle.code.csharp.dataflow.internal.DataFlowDispatch -import semmle.code.csharp.dataflow.internal.DataFlowImplConsistency::Consistency +private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific +private import semmle.code.csharp.dataflow.internal.TaintTrackingImplSpecific +private import codeql.dataflow.internal.DataFlowImplConsistency -private class MyConsistencyConfiguration extends ConsistencyConfiguration { - override predicate uniqueEnclosingCallableExclude(Node n) { +private module Input implements InputSig { + private import CsharpDataFlow + + predicate uniqueEnclosingCallableExclude(Node n) { // TODO: Remove once static initializers are folded into the // static constructors exists(ControlFlow::Node cfn | @@ -15,7 +16,7 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration { ) } - override predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { + predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { // TODO: Remove once static initializers are folded into the // static constructors exists(ControlFlow::Node cfn | @@ -24,25 +25,25 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration { ) } - override predicate uniqueNodeLocationExclude(Node n) { + predicate uniqueNodeLocationExclude(Node n) { // Methods with multiple implementations n instanceof ParameterNode or - this.missingLocationExclude(n) + missingLocationExclude(n) } - override predicate missingLocationExclude(Node n) { + predicate missingLocationExclude(Node n) { // Some CIL methods are missing locations n.asParameter() instanceof CIL::Parameter } - override predicate postWithInFlowExclude(Node n) { + predicate postWithInFlowExclude(Node n) { n instanceof FlowSummaryNode or n.asExpr().(ObjectCreation).hasInitializer() } - override predicate argHasPostUpdateExclude(ArgumentNode n) { + predicate argHasPostUpdateExclude(ArgumentNode n) { n instanceof FlowSummaryNode or not exists(LocalFlow::getAPostUpdateNodeForArg(n.getControlFlowNode())) @@ -54,7 +55,7 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration { n.asExpr() instanceof CIL::Expr } - override predicate postHasUniquePreExclude(PostUpdateNode n) { + predicate postHasUniquePreExclude(PostUpdateNode n) { exists(ControlFlow::Nodes::ExprNode e, ControlFlow::Nodes::ExprNode arg | e = LocalFlow::getAPostUpdateNodeForArg(arg) and e != arg and @@ -62,7 +63,7 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration { ) } - override predicate uniquePostUpdateExclude(Node n) { + predicate uniquePostUpdateExclude(Node n) { exists(ControlFlow::Nodes::ExprNode e, ControlFlow::Nodes::ExprNode arg | e = LocalFlow::getAPostUpdateNodeForArg(arg) and e != arg and @@ -70,12 +71,12 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration { ) } - override predicate reverseReadExclude(Node n) { n.asExpr() = any(AwaitExpr ae).getExpr() } - - override predicate identityLocalStepExclude(Node n) { none() } + predicate reverseReadExclude(Node n) { n.asExpr() = any(AwaitExpr ae).getExpr() } } -query predicate multipleToString(Node n, string s) { +import MakeConsistency + +query predicate multipleToString(DataFlow::Node n, string s) { s = strictconcat(n.toString(), ",") and strictcount(n.toString()) > 1 } diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj b/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj index 5ea4974db7f..968726df756 100644 --- a/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj +++ b/csharp/ql/integration-tests/posix-only/dotnet_test/dotnet_test.csproj @@ -8,10 +8,10 @@ - + - - + + diff --git a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj index dfa6909c44b..95c7586e04e 100644 --- a/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj +++ b/csharp/ql/integration-tests/posix-only/dotnet_test_mstest/dotnet_test_mstest.csproj @@ -10,10 +10,10 @@ - - - - + + + + diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index c96f22b5aa8..b16907bd011 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.7.4 + +### Minor Analysis Improvements + +* The `--nostdlib` extractor option for the standalone extractor has been removed. + ## 0.7.3 ### Minor Analysis Improvements diff --git a/csharp/ql/lib/change-notes/released/0.7.4.md b/csharp/ql/lib/change-notes/released/0.7.4.md new file mode 100644 index 00000000000..9665706305a --- /dev/null +++ b/csharp/ql/lib/change-notes/released/0.7.4.md @@ -0,0 +1,5 @@ +## 0.7.4 + +### Minor Analysis Improvements + +* The `--nostdlib` extractor option for the standalone extractor has been removed. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index a4ea9c8de17..e388f34b4ec 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.3 +lastReleaseVersion: 0.7.4 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index ba47a23065f..6bc467079d9 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 0.7.4-dev +version: 0.7.4 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/lib/semmle/code/cil/Stubs.qll b/csharp/ql/lib/semmle/code/cil/Stubs.qll index afe95d3ae77..7617119e617 100644 --- a/csharp/ql/lib/semmle/code/cil/Stubs.qll +++ b/csharp/ql/lib/semmle/code/cil/Stubs.qll @@ -32,12 +32,12 @@ private module Cached { exists(Assembly asm | asm = mi.getLocation() and (assemblyIsStubImpl(asm) implies asm.getFile().extractedQlTest()) and - not exists(MethodImplementation better | mi.getMethod() = better.getMethod() | - mi.getNumberOfInstructions() < better.getNumberOfInstructions() - or - mi.getNumberOfInstructions() = better.getNumberOfInstructions() and - asm.getFile().toString() > better.getLocation().getFile().toString() - ) and + mi = + max(MethodImplementation impl | + mi.getMethod() = impl.getMethod() + | + impl order by impl.getNumberOfInstructions(), impl.getLocation().getFile().toString() desc + ) and exists(mi.getAnInstruction()) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll index 9f6ff2ce17f..0c57c2cea3b 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowDispatch.qll @@ -109,8 +109,8 @@ private module Cached { TExplicitDelegateLikeCall(ControlFlow::Nodes::ElementNode cfn, DelegateLikeCall dc) { cfn.getAstNode() = dc } or - TTransitiveCapturedCall(ControlFlow::Nodes::ElementNode cfn, Callable target) { - transitiveCapturedCallTarget(cfn, target) + TTransitiveCapturedCall(ControlFlow::Nodes::ElementNode cfn) { + transitiveCapturedCallTarget(cfn, _) } or TCilCall(CIL::Call call) { // No need to include calls that are compiled from source @@ -389,11 +389,12 @@ class ExplicitDelegateLikeDataFlowCall extends DelegateDataFlowCall, TExplicitDe */ class TransitiveCapturedDataFlowCall extends DataFlowCall, TTransitiveCapturedCall { private ControlFlow::Nodes::ElementNode cfn; - private Callable target; - TransitiveCapturedDataFlowCall() { this = TTransitiveCapturedCall(cfn, target) } + TransitiveCapturedDataFlowCall() { this = TTransitiveCapturedCall(cfn) } - override DataFlowCallable getARuntimeTarget() { result.asCallable() = target } + override DataFlowCallable getARuntimeTarget() { + transitiveCapturedCallTarget(cfn, result.asCallable()) + } override ControlFlow::Nodes::ElementNode getControlFlowNode() { result = cfn } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index e7c11557a4c..308df381a12 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -1564,7 +1564,7 @@ private module OutNodes { additionalCalls = false and call = csharpCall(_, cfn) or additionalCalls = true and - call = TTransitiveCapturedCall(cfn, n.getEnclosingCallable()) + call = TTransitiveCapturedCall(cfn) ) } diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index 0d165e05a25..0326272c6d8 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.4 + +No user-facing changes. + ## 0.7.3 No user-facing changes. diff --git a/csharp/ql/src/change-notes/released/0.7.4.md b/csharp/ql/src/change-notes/released/0.7.4.md new file mode 100644 index 00000000000..1b33df9cb1e --- /dev/null +++ b/csharp/ql/src/change-notes/released/0.7.4.md @@ -0,0 +1,3 @@ +## 0.7.4 + +No user-facing changes. diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index a4ea9c8de17..e388f34b4ec 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.3 +lastReleaseVersion: 0.7.4 diff --git a/csharp/ql/src/experimental/ir/implementation/Opcode.qll b/csharp/ql/src/experimental/ir/implementation/Opcode.qll index a9ecdf46984..c473969467d 100644 --- a/csharp/ql/src/experimental/ir/implementation/Opcode.qll +++ b/csharp/ql/src/experimental/ir/implementation/Opcode.qll @@ -55,6 +55,7 @@ private newtype TOpcode = TVariableAddress() or TFieldAddress() or TFunctionAddress() or + TVirtualDeleteFunctionAddress() or TElementsAddress() or TConstant() or TStringConstant() or @@ -887,6 +888,15 @@ module Opcode { final override string toString() { result = "FunctionAddress" } } + /** + * The `Opcode` for a `VirtualDeleteFunctionAddress`. + * + * See the `VirtualDeleteFunctionAddressInstruction` documentation for more details. + */ + class VirtualDeleteFunctionAddress extends Opcode, TVirtualDeleteFunctionAddress { + final override string toString() { result = "VirtualDeleteFunctionAddress" } + } + /** * The `Opcode` for a `ConstantInstruction`. * diff --git a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll index 1b5ea432946..2a3a6d3407a 100644 --- a/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/raw/Instruction.qll @@ -576,6 +576,22 @@ class FunctionAddressInstruction extends FunctionInstruction { FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress } } +/** + * An instruction that returns the address of a "virtual" delete function. + * + * This function, which does not actually exist in the source code, is used to + * delete objects of a class with a virtual destructor. In that case the deacllocation + * function is selected at runtime based on the dynamic type of the object. So this + * function dynamically dispatches to the correct deallocation function. + * It also should pass in the required extra arguments to the deallocation function + * which may differ dynamically depending on the type of the object. + */ +class VirtualDeleteFunctionAddressInstruction extends Instruction { + VirtualDeleteFunctionAddressInstruction() { + this.getOpcode() instanceof Opcode::VirtualDeleteFunctionAddress + } +} + /** * An instruction that initializes a parameter of the enclosing function with the value of the * corresponding argument passed by the caller. diff --git a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll index 1b5ea432946..2a3a6d3407a 100644 --- a/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll +++ b/csharp/ql/src/experimental/ir/implementation/unaliased_ssa/Instruction.qll @@ -576,6 +576,22 @@ class FunctionAddressInstruction extends FunctionInstruction { FunctionAddressInstruction() { this.getOpcode() instanceof Opcode::FunctionAddress } } +/** + * An instruction that returns the address of a "virtual" delete function. + * + * This function, which does not actually exist in the source code, is used to + * delete objects of a class with a virtual destructor. In that case the deacllocation + * function is selected at runtime based on the dynamic type of the object. So this + * function dynamically dispatches to the correct deallocation function. + * It also should pass in the required extra arguments to the deallocation function + * which may differ dynamically depending on the type of the object. + */ +class VirtualDeleteFunctionAddressInstruction extends Instruction { + VirtualDeleteFunctionAddressInstruction() { + this.getOpcode() instanceof Opcode::VirtualDeleteFunctionAddress + } +} + /** * An instruction that initializes a parameter of the enclosing function with the value of the * corresponding argument passed by the caller. diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index a9d4c81c0f1..857555c05d8 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 0.7.4-dev +version: 0.7.4 groups: - csharp - queries diff --git a/docs/codeql/reusables/supported-versions-compilers.rst b/docs/codeql/reusables/supported-versions-compilers.rst index 6ed36237e4c..1065d12e9f3 100644 --- a/docs/codeql/reusables/supported-versions-compilers.rst +++ b/docs/codeql/reusables/supported-versions-compilers.rst @@ -25,7 +25,7 @@ Python [8]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11",Not applicable,``.py`` Ruby [9]_,"up to 3.2",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``" Swift [10]_,"Swift 5.4-5.8.1","Swift compiler","``.swift``" - TypeScript [11]_,"2.6-5.1",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``" + TypeScript [11]_,"2.6-5.2",Standard TypeScript compiler,"``.ts``, ``.tsx``, ``.mts``, ``.cts``" .. container:: footnote-group diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index fb9e1f49e54..136789c4419 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.6.4 + +### Minor Analysis Improvements + +* Added [http.Error](https://pkg.go.dev/net/http#Error) to XSS sanitzers. + ## 0.6.3 No user-facing changes. diff --git a/go/ql/lib/change-notes/released/0.6.4.md b/go/ql/lib/change-notes/released/0.6.4.md new file mode 100644 index 00000000000..6c561f82177 --- /dev/null +++ b/go/ql/lib/change-notes/released/0.6.4.md @@ -0,0 +1,5 @@ +## 0.6.4 + +### Minor Analysis Improvements + +* Added [http.Error](https://pkg.go.dev/net/http#Error) to XSS sanitzers. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index b7dafe32c5d..ced8cf94614 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.3 +lastReleaseVersion: 0.6.4 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index d3765da2f89..6fa1f846bdd 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 0.6.4-dev +version: 0.6.4 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/lib/semmle/go/security/Xss.qll b/go/ql/lib/semmle/go/security/Xss.qll index 9003b766416..3310c7a420d 100644 --- a/go/ql/lib/semmle/go/security/Xss.qll +++ b/go/ql/lib/semmle/go/security/Xss.qll @@ -109,6 +109,18 @@ module SharedXss { } } + /** + * A http.Error function returns with the ContentType of text/plain, and is not a valid XSS sink + */ + class ErrorSanitizer extends Sanitizer { + ErrorSanitizer() { + exists(Function f, DataFlow::CallNode call | call = f.getACall() | + f.hasQualifiedName("net/http", "Error") and + call.getArgument(1) = this + ) + } + } + /** * A regexp replacement involving an HTML meta-character, or a call to an escape * function, viewed as a sanitizer for XSS vulnerabilities. diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index cfe3163c6e9..7e8335b6aff 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4 + +No user-facing changes. + ## 0.6.3 No user-facing changes. diff --git a/go/ql/src/change-notes/released/0.6.4.md b/go/ql/src/change-notes/released/0.6.4.md new file mode 100644 index 00000000000..7e98b0159fc --- /dev/null +++ b/go/ql/src/change-notes/released/0.6.4.md @@ -0,0 +1,3 @@ +## 0.6.4 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index b7dafe32c5d..ced8cf94614 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.3 +lastReleaseVersion: 0.6.4 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index a625c40a9c8..cd538178553 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 0.6.4-dev +version: 0.6.4 groups: - go - queries diff --git a/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go b/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go index a6f311e8458..d1ea413c3b9 100644 --- a/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go +++ b/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go @@ -25,9 +25,9 @@ func ServeJsonDirect(w http.ResponseWriter, r http.Request) { func ErrTest(w http.ResponseWriter, r http.Request) { cookie, err := r.Cookie("somecookie") - w.Write([]byte(fmt.Sprintf("Cookie result: %v", cookie))) // BAD: Cookie's value is user-controlled - w.Write([]byte(fmt.Sprintf("Cookie check error: %v", err))) // GOOD: Cookie's err return is harmless - + w.Write([]byte(fmt.Sprintf("Cookie result: %v", cookie))) // BAD: Cookie's value is user-controlled + w.Write([]byte(fmt.Sprintf("Cookie check error: %v", err))) // GOOD: Cookie's err return is harmless + http.Error(w, fmt.Sprintf("Cookie result: %v", cookie), 500) // Good: only plain text is written. file, header, err := r.FormFile("someFile") content, err2 := ioutil.ReadAll(file) w.Write([]byte(fmt.Sprintf("File content: %v", content))) // BAD: file content is user-controlled diff --git a/java/kotlin-extractor/build.py b/java/kotlin-extractor/build.py index 009017b0073..c639209a930 100755 --- a/java/kotlin-extractor/build.py +++ b/java/kotlin-extractor/build.py @@ -92,6 +92,7 @@ def compile_to_dir(build_dir, srcs, classpath, java_classpath, output): kotlin_arg_file = build_dir + '/kotlin.args' kotlin_args = ['-Werror', '-opt-in=kotlin.RequiresOptIn', + '-opt-in=org.jetbrains.kotlin.ir.symbols.IrSymbolInternals', '-d', output, '-module-name', 'codeql-kotlin-extractor', '-no-reflect', '-no-stdlib', @@ -168,7 +169,7 @@ def compile(jars, java_jars, dependency_folder, transform_to_embeddable, output, shutil.rmtree(tmp_src_dir) shutil.copytree('src', tmp_src_dir) - include_version_folder = tmp_src_dir + '/main/kotlin/utils/versions/to_include' + include_version_folder = tmp_src_dir + '/main/kotlin/utils/this_version' os.makedirs(include_version_folder) resource_dir = tmp_src_dir + '/main/resources/com/github/codeql' @@ -192,11 +193,7 @@ def compile(jars, java_jars, dependency_folder, transform_to_embeddable, output, shutil.copytree(d, include_version_folder, dirs_exist_ok=True) # remove all version folders: - for version in kotlin_plugin_versions.many_versions: - d = tmp_src_dir + '/main/kotlin/utils/versions/v_' + \ - version.replace('.', '_') - if os.path.exists(d): - shutil.rmtree(d) + shutil.rmtree(tmp_src_dir + '/main/kotlin/utils/versions') srcs = find_sources(tmp_src_dir) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt b/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt index c766d70df33..0e9524a8e43 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt @@ -20,6 +20,7 @@ import java.nio.file.Files import java.nio.file.Paths import java.util.zip.GZIPInputStream import java.util.zip.GZIPOutputStream +import com.github.codeql.utils.versions.usesK2 import com.semmle.util.files.FileUtil import kotlin.system.exitProcess @@ -97,6 +98,7 @@ class KotlinExtractorExtension( private fun runExtractor(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) { val startTimeMs = System.currentTimeMillis() + val usesK2 = usesK2(pluginContext) // This default should be kept in sync with com.semmle.extractor.java.interceptors.KotlinInterceptor.initializeExtractionContext val trapDir = File(System.getenv("CODEQL_EXTRACTOR_JAVA_TRAP_DIR").takeUnless { it.isNullOrEmpty() } ?: "kotlin-extractor/trap") val compression_env_var = "CODEQL_EXTRACTOR_JAVA_OPTION_TRAP_COMPRESSION" @@ -134,6 +136,7 @@ class KotlinExtractorExtension( tw.writeCompilation_info(compilation, "Kotlin Compiler Version", KotlinCompilerVersion.getVersion() ?: "") val extractor_name = this::class.java.getResource("extractor.name")?.readText() ?: "" tw.writeCompilation_info(compilation, "Kotlin Extractor Name", extractor_name) + tw.writeCompilation_info(compilation, "Uses Kotlin 2", usesK2.toString()) if (compilationStartTime != null) { tw.writeCompilation_compiler_times(compilation, -1.0, (System.currentTimeMillis()-compilationStartTime)/1000.0) } diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 55ec8c44dbb..022b71ca562 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -107,7 +107,7 @@ open class KotlinFileExtractor( fun extractFileContents(file: IrFile, id: Label) { with("file", file) { val locId = tw.getWholeFileLocation() - val pkg = file.fqName.asString() + val pkg = file.packageFqName.asString() val pkgId = extractPackage(pkg) tw.writeHasLocation(id, locId) tw.writeCupackage(id, pkgId) @@ -1901,8 +1901,9 @@ open class KotlinFileExtractor( verboseln("No match as didn't find target package") return false } - if (targetPkg.fqName.asString() != pName) { - verboseln("No match as package name is ${targetPkg.fqName.asString()}") + val targetName = targetPkg.packageFqName.asString() + if (targetName != pName) { + verboseln("No match as package name is $targetName") return false } verboseln("Match") @@ -2556,8 +2557,9 @@ open class KotlinFileExtractor( verboseln("No match as didn't find target package") return false } - if (targetPkg.fqName.asString() != pkgName) { - verboseln("No match as package name is ${targetPkg.fqName.asString()} not $pkgName") + val targetName = targetPkg.packageFqName.asString() + if (targetName != pkgName) { + verboseln("No match as package name is $targetName not $pkgName") return false } verboseln("Match") diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt index 9c8f289eb0a..6d12d28cf9e 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinUsesExtractor.kt @@ -5,6 +5,7 @@ import com.github.codeql.utils.versions.codeQlWithHasQuestionMark import com.github.codeql.utils.versions.getFileClassFqName import com.github.codeql.utils.versions.getKotlinType import com.github.codeql.utils.versions.isRawType +import com.github.codeql.utils.versions.packageFqName import com.semmle.extractor.java.OdasaOutput import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext import org.jetbrains.kotlin.backend.common.ir.* @@ -83,7 +84,7 @@ open class KotlinUsesExtractor( ) fun extractFileClass(f: IrFile): Label { - val pkg = f.fqName.asString() + val pkg = f.packageFqName.asString() val jvmName = getFileClassName(f) val id = extractFileClass(pkg, jvmName) if (tw.lm.fileClassLocationsExtracted.add(f)) { @@ -848,7 +849,7 @@ open class KotlinUsesExtractor( when(dp) { is IrFile -> if(canBeTopLevel) { - usePackage(dp.fqName.asString()) + usePackage(dp.packageFqName.asString()) } else { extractFileClass(dp) } diff --git a/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt b/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt index 5fdf073813d..7cf1439b56a 100644 --- a/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt +++ b/java/kotlin-extractor/src/main/kotlin/MetaAnnotationSupport.kt @@ -276,8 +276,8 @@ class MetaAnnotationSupport(private val logger: FileLogger, private val pluginCo run { logger.warnElement("Expected property's parent class to have a receiver parameter", parentClass); return } val newParam = copyParameterToFunction(thisReceiever, this) dispatchReceiverParameter = newParam - body = factory.createBlockBody( - UNDEFINED_OFFSET, UNDEFINED_OFFSET, listOf( + body = factory.createBlockBody(UNDEFINED_OFFSET, UNDEFINED_OFFSET).apply({ + this.statements.add( IrReturnImpl( UNDEFINED_OFFSET, UNDEFINED_OFFSET, pluginContext.irBuiltIns.nothingType, @@ -294,7 +294,7 @@ class MetaAnnotationSupport(private val logger: FileLogger, private val pluginCo ) ) ) - ) + }) } } diff --git a/java/kotlin-extractor/src/main/kotlin/PrimitiveTypeInfo.kt b/java/kotlin-extractor/src/main/kotlin/PrimitiveTypeInfo.kt index a14b0c138db..738d44c7adf 100644 --- a/java/kotlin-extractor/src/main/kotlin/PrimitiveTypeInfo.kt +++ b/java/kotlin-extractor/src/main/kotlin/PrimitiveTypeInfo.kt @@ -8,11 +8,12 @@ import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.name.FqName import com.github.codeql.utils.* +import com.github.codeql.utils.versions.packageFqName class PrimitiveTypeMapping(val logger: Logger, val pluginContext: IrPluginContext) { fun getPrimitiveInfo(s: IrSimpleType) = s.classOrNull?.let { - if ((it.owner.parent as? IrPackageFragment)?.fqName == StandardNames.BUILT_INS_PACKAGE_FQ_NAME) + if ((it.owner.parent as? IrPackageFragment)?.packageFqName == StandardNames.BUILT_INS_PACKAGE_FQ_NAME) mapping[it.owner.name] else null diff --git a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt index ad4aaf60936..6a6b67b20aa 100644 --- a/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/comments/CommentExtractor.kt @@ -3,8 +3,8 @@ package com.github.codeql.comments import com.github.codeql.* import com.github.codeql.utils.IrVisitorLookup import com.github.codeql.utils.isLocalFunction +import com.github.codeql.utils.Psi2IrFacade import com.github.codeql.utils.versions.getPsi2Ir -import com.github.codeql.utils.versions.Psi2IrFacade import com.intellij.psi.PsiComment import com.intellij.psi.PsiElement import org.jetbrains.kotlin.config.KotlinCompilerVersion diff --git a/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt b/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt index 927d579ec34..30325af4b0f 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/ClassNames.kt @@ -2,6 +2,7 @@ package com.github.codeql import com.github.codeql.utils.getJvmName import com.github.codeql.utils.versions.getFileClassFqName +import com.github.codeql.utils.versions.packageFqName import com.intellij.openapi.vfs.StandardFileSystems import org.jetbrains.kotlin.load.java.sources.JavaSourceElement import org.jetbrains.kotlin.load.java.structure.impl.classFiles.BinaryJavaClass @@ -33,7 +34,7 @@ fun getFileClassName(f: IrFile) = fun getIrElementBinaryName(that: IrElement): String { if (that is IrFile) { val shortName = getFileClassName(that) - val pkg = that.fqName.asString() + val pkg = that.packageFqName.asString() return if (pkg.isEmpty()) shortName else "$pkg.$shortName" } @@ -59,7 +60,7 @@ fun getIrElementBinaryName(that: IrElement): String { .forEach { when (it) { is IrClass -> internalName.insert(0, getName(it) + "$") - is IrPackageFragment -> it.fqName.asString().takeIf { fqName -> fqName.isNotEmpty() }?.let { fqName -> internalName.insert(0, "$fqName.") } + is IrPackageFragment -> it.packageFqName.asString().takeIf { fqName -> fqName.isNotEmpty() }?.let { fqName -> internalName.insert(0, "$fqName.") } } } return internalName.toString() diff --git a/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt b/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt index d7da222442b..970c03da9cb 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/IrVisitorLookup.kt @@ -1,6 +1,6 @@ package com.github.codeql.utils -import com.github.codeql.utils.versions.Psi2IrFacade +import com.github.codeql.utils.Psi2IrFacade import com.intellij.psi.PsiElement import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrDeclaration diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/Psi2IrFacade.kt b/java/kotlin-extractor/src/main/kotlin/utils/Psi2IrFacade.kt similarity index 88% rename from java/kotlin-extractor/src/main/kotlin/utils/versions/Psi2IrFacade.kt rename to java/kotlin-extractor/src/main/kotlin/utils/Psi2IrFacade.kt index 2c9e5f65e94..c9845b46895 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/Psi2IrFacade.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/Psi2IrFacade.kt @@ -1,4 +1,4 @@ -package com.github.codeql.utils.versions +package com.github.codeql.utils import com.intellij.psi.PsiElement import org.jetbrains.kotlin.ir.IrElement @@ -8,4 +8,4 @@ import org.jetbrains.kotlin.psi.KtFile interface Psi2IrFacade { fun getKtFile(irFile: IrFile): KtFile? fun findPsiElement(irElement: IrElement, irFile: IrFile): PsiElement? -} \ No newline at end of file +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/IrSymbolInternals.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/IrSymbolInternals.kt new file mode 100644 index 00000000000..b4f55b07cfd --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/IrSymbolInternals.kt @@ -0,0 +1,4 @@ +package org.jetbrains.kotlin.ir.symbols + +@RequiresOptIn(level = RequiresOptIn.Level.WARNING) +annotation class IrSymbolInternals 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 80120107478..2046b507bf8 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,3 +1,5 @@ package com.github.codeql.utils.versions +import com.github.codeql.utils.Psi2IrFacade + fun getPsi2Ir(): Psi2IrFacade? = null diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/UsesK2.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/UsesK2.kt new file mode 100644 index 00000000000..39219d77730 --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/UsesK2.kt @@ -0,0 +1,7 @@ +package com.github.codeql.utils.versions + +import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext + +fun usesK2(@Suppress("UNUSED_PARAMETER") pluginContext: IrPluginContext): Boolean { + return false +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/packageFqName.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/packageFqName.kt new file mode 100644 index 00000000000..87e67cd8368 --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_4_32/packageFqName.kt @@ -0,0 +1,10 @@ +package com.github.codeql.utils.versions + +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.name.FqName + +val IrFile.packageFqName: FqName + get() = this.fqName + +val IrPackageFragment.packageFqName: FqName + get() = this.fqName diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt index 73987106c55..dcd1c26afd2 100644 --- a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_5_20/Psi2Ir.kt @@ -6,6 +6,7 @@ import org.jetbrains.kotlin.backend.jvm.ir.getKtFile import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.psi.KtFile +import com.github.codeql.utils.Psi2IrFacade fun getPsi2Ir(): Psi2IrFacade? = Psi2Ir() diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_0-Beta/UsesK2.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_0-Beta/UsesK2.kt new file mode 100644 index 00000000000..8d5e3345565 --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_0-Beta/UsesK2.kt @@ -0,0 +1,7 @@ +package com.github.codeql.utils.versions + +import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext + +fun usesK2(pluginContext: IrPluginContext): Boolean { + return pluginContext.languageVersionSettings.languageVersion.usesK2 +} diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_255/IrSymbolInternals.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_255/IrSymbolInternals.kt new file mode 100644 index 00000000000..48829cc30c5 --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_255/IrSymbolInternals.kt @@ -0,0 +1,4 @@ +package com.github.codeql + +// The compiler provides the annotation class, so we don't need to do +// anything diff --git a/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_255/packageFqName.kt b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_255/packageFqName.kt new file mode 100644 index 00000000000..613d51c7cbf --- /dev/null +++ b/java/kotlin-extractor/src/main/kotlin/utils/versions/v_1_9_255/packageFqName.kt @@ -0,0 +1,3 @@ +package com.github.codeql + +// The compiler provides packageFqName, so we don't need to do anything diff --git a/java/ql/automodel/src/CHANGELOG.md b/java/ql/automodel/src/CHANGELOG.md new file mode 100644 index 00000000000..af7864fc7d5 --- /dev/null +++ b/java/ql/automodel/src/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.3 + +No user-facing changes. diff --git a/java/ql/automodel/src/change-notes/released/0.0.3.md b/java/ql/automodel/src/change-notes/released/0.0.3.md new file mode 100644 index 00000000000..af7864fc7d5 --- /dev/null +++ b/java/ql/automodel/src/change-notes/released/0.0.3.md @@ -0,0 +1,3 @@ +## 0.0.3 + +No user-facing changes. diff --git a/java/ql/automodel/src/codeql-pack.release.yml b/java/ql/automodel/src/codeql-pack.release.yml new file mode 100644 index 00000000000..a24b693d1e7 --- /dev/null +++ b/java/ql/automodel/src/codeql-pack.release.yml @@ -0,0 +1,2 @@ +--- +lastReleaseVersion: 0.0.3 diff --git a/java/ql/automodel/src/qlpack.yml b/java/ql/automodel/src/qlpack.yml index 851dbe69e82..514ab9d0896 100644 --- a/java/ql/automodel/src/qlpack.yml +++ b/java/ql/automodel/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-automodel-queries -version: 0.0.3-dev +version: 0.0.3 groups: - java - automodel diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.expected b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.expected new file mode 100644 index 00000000000..b7d6dd6e972 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.expected @@ -0,0 +1,7 @@ +| Number of files with extension jar | 1 | +| Number of files with extension kt | 1 | +| Number of lines of code | 2 | +| Number of lines of code with extension kt | 2 | +| Total number of lines | 3 | +| Total number of lines with extension kt | 3 | +| Uses Kotlin 2: false | 1 | diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.ext.yml b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.ext.yml new file mode 100644 index 00000000000..3b6ffa4a377 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.ext.yml @@ -0,0 +1,13 @@ +extensions: + - addsTo: + pack: codeql/java-queries + extensible: extractorInformationSkipKey + data: + # These will have unstable values, as they are dependent on the + # JDK that the test is run with, so filter them out: + - ["Number of files"] + - ["Number of files with extension class"] + # These depend on the Kotlin version you have installed + - ["Kotlin Compiler Version: %"] + - ["Kotlin Extractor Name: %"] + diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.qlref b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.qlref new file mode 100644 index 00000000000..ff57e78a9d7 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/ExtractorInformation.qlref @@ -0,0 +1 @@ +Telemetry/ExtractorInformation.ql \ No newline at end of file diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/SomeClass.kt b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/SomeClass.kt new file mode 100644 index 00000000000..80fb3d3af6a --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/SomeClass.kt @@ -0,0 +1,2 @@ +class SomeClass { +} diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/test.py b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/test.py new file mode 100755 index 00000000000..4a0fa4efd23 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin1/test.py @@ -0,0 +1,3 @@ +from create_database_utils import * + +run_codeql_database_create(["kotlinc SomeClass.kt"], lang="java") diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.expected b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.expected new file mode 100644 index 00000000000..e1fe4c6ee39 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.expected @@ -0,0 +1,3 @@ +| Number of files with extension jar | 1 | +| Number of files with extension kt | 1 | +| Uses Kotlin 2: true | 1 | diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.ext.yml b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.ext.yml new file mode 100644 index 00000000000..be02d9554f8 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.ext.yml @@ -0,0 +1,17 @@ +extensions: + - addsTo: + pack: codeql/java-queries + extensible: extractorInformationSkipKey + data: + # These will have unstable values, as they are dependent on the + # JDK that the test is run with, so filter them out: + - ["Number of files"] + - ["Number of files with extension class"] + # These depend on the Kotlin version you have installed + - ["Kotlin Compiler Version: %"] + - ["Kotlin Extractor Name: %"] + # Currently we get some diagnostics as Kotlin 2 support isn't complete. + # Ignore these, as the number probably isn't stable. + - ["Number of diagnostics from CodeQL Kotlin extractor with severity %"] + - ["Total number of diagnostics from CodeQL Kotlin extractor"] + diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.qlref b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.qlref new file mode 100644 index 00000000000..ff57e78a9d7 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/ExtractorInformation.qlref @@ -0,0 +1 @@ +Telemetry/ExtractorInformation.ql \ No newline at end of file diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/SomeClass.kt b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/SomeClass.kt new file mode 100644 index 00000000000..80fb3d3af6a --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/SomeClass.kt @@ -0,0 +1,2 @@ +class SomeClass { +} diff --git a/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/test.py b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/test.py new file mode 100755 index 00000000000..c61bbf88860 --- /dev/null +++ b/java/ql/integration-tests/all-platforms/kotlin/extractor_information_kotlin2/test.py @@ -0,0 +1,3 @@ +from create_database_utils import * + +run_codeql_database_create(["kotlinc -language-version 2.0 SomeClass.kt"], lang="java") diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index 42a5c07e826..eaec0383f13 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,16 @@ +## 0.7.4 + +### New Features + +* Kotlin versions up to 1.9.10 are now supported. + +### Minor Analysis Improvements + +* Fixed the MaD signature specifications to use proper nested type names. +* Added new sanitizer to Java command injection model +* Added more dataflow models for JAX-RS. +* The predicate `JaxWsEndpoint::getARemoteMethod` no longer requires the result to be annotated with `@WebMethod`. Instead, the requirements listed in the JAX-RPC Specification 1.1 for required parameter and return types are used. Applications using JAX-RS may see an increase in results. + ## 0.7.3 ### Major Analysis Improvements diff --git a/java/ql/lib/change-notes/2023-08-07-jaxrs-new-models.md b/java/ql/lib/change-notes/2023-08-07-jaxrs-new-models.md deleted file mode 100644 index 8b34698758b..00000000000 --- a/java/ql/lib/change-notes/2023-08-07-jaxrs-new-models.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added more dataflow models for JAX-RS. diff --git a/java/ql/lib/change-notes/2023-08-21-java-command-injection-sanitizer.md b/java/ql/lib/change-notes/2023-08-21-java-command-injection-sanitizer.md deleted file mode 100644 index ca183d5d065..00000000000 --- a/java/ql/lib/change-notes/2023-08-21-java-command-injection-sanitizer.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added new sanitizer to Java command injection model \ No newline at end of file diff --git a/java/ql/lib/change-notes/2023-08-23-mad-nestednames.md b/java/ql/lib/change-notes/2023-08-23-mad-nestednames.md deleted file mode 100644 index 0a804f1866f..00000000000 --- a/java/ql/lib/change-notes/2023-08-23-mad-nestednames.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Fixed the MaD signature specifications to use proper nested type names. diff --git a/java/ql/lib/change-notes/2023-08-24-kotlin-1.9.10.md b/java/ql/lib/change-notes/2023-08-24-kotlin-1.9.10.md deleted file mode 100644 index ee878bb11af..00000000000 --- a/java/ql/lib/change-notes/2023-08-24-kotlin-1.9.10.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* Kotlin versions up to 1.9.10 are now supported. diff --git a/java/ql/lib/change-notes/2023-08-07-jaxrs-webmethod-improvements.md b/java/ql/lib/change-notes/released/0.7.4.md similarity index 50% rename from java/ql/lib/change-notes/2023-08-07-jaxrs-webmethod-improvements.md rename to java/ql/lib/change-notes/released/0.7.4.md index be19599c865..78491df85eb 100644 --- a/java/ql/lib/change-notes/2023-08-07-jaxrs-webmethod-improvements.md +++ b/java/ql/lib/change-notes/released/0.7.4.md @@ -1,4 +1,12 @@ ---- -category: minorAnalysis ---- +## 0.7.4 + +### New Features + +* Kotlin versions up to 1.9.10 are now supported. + +### Minor Analysis Improvements + +* Fixed the MaD signature specifications to use proper nested type names. +* Added new sanitizer to Java command injection model +* Added more dataflow models for JAX-RS. * The predicate `JaxWsEndpoint::getARemoteMethod` no longer requires the result to be annotated with `@WebMethod`. Instead, the requirements listed in the JAX-RPC Specification 1.1 for required parameter and return types are used. Applications using JAX-RS may see an increase in results. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index a4ea9c8de17..e388f34b4ec 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.3 +lastReleaseVersion: 0.7.4 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index e708ee160f2..f4c8b284176 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 0.7.4-dev +version: 0.7.4 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll index e154491f795..1dfa24fffac 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll @@ -3,297 +3,15 @@ * data-flow classes and predicates. */ -private import DataFlowImplSpecific::Private -private import DataFlowImplSpecific::Public -private import tainttracking1.TaintTrackingParameter::Private -private import tainttracking1.TaintTrackingParameter::Public +private import java +private import DataFlowImplSpecific +private import TaintTrackingImplSpecific +private import codeql.dataflow.internal.DataFlowImplConsistency -module Consistency { - private newtype TConsistencyConfiguration = MkConsistencyConfiguration() - - /** A class for configuring the consistency queries. */ - class ConsistencyConfiguration extends TConsistencyConfiguration { - string toString() { none() } - - /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */ - predicate uniqueEnclosingCallableExclude(Node n) { none() } - - /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */ - predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() } - - /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */ - predicate uniqueNodeLocationExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `missingLocation`. */ - predicate missingLocationExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */ - predicate postWithInFlowExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */ - predicate argHasPostUpdateExclude(ArgumentNode n) { none() } - - /** Holds if `n` should be excluded from the consistency test `reverseRead`. */ - predicate reverseReadExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */ - predicate postHasUniquePreExclude(PostUpdateNode n) { none() } - - /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */ - predicate uniquePostUpdateExclude(Node n) { none() } - - /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */ - predicate viableImplInCallContextTooLargeExclude( - DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable - ) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */ - predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */ - predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */ - predicate identityLocalStepExclude(Node n) { none() } - } - - private class RelevantNode extends Node { - RelevantNode() { - this instanceof ArgumentNode or - this instanceof ParameterNode or - this instanceof ReturnNode or - this = getAnOutNode(_, _) or - simpleLocalFlowStep(this, _) or - simpleLocalFlowStep(_, this) or - jumpStep(this, _) or - jumpStep(_, this) or - storeStep(this, _, _) or - storeStep(_, _, this) or - readStep(this, _, _) or - readStep(_, _, this) or - defaultAdditionalTaintStep(this, _) or - defaultAdditionalTaintStep(_, this) - } - } - - query predicate uniqueEnclosingCallable(Node n, string msg) { - exists(int c | - n instanceof RelevantNode and - c = count(nodeGetEnclosingCallable(n)) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and - msg = "Node should have one enclosing callable but has " + c + "." - ) - } - - query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) { - exists(int c | - c = count(call.getEnclosingCallable()) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and - msg = "Call should have one enclosing callable but has " + c + "." - ) - } - - query predicate uniqueType(Node n, string msg) { - exists(int c | - n instanceof RelevantNode and - c = count(getNodeType(n)) and - c != 1 and - msg = "Node should have one type but has " + c + "." - ) - } - - query predicate uniqueNodeLocation(Node n, string msg) { - exists(int c | - c = - count(string filepath, int startline, int startcolumn, int endline, int endcolumn | - n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - ) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and - msg = "Node should have one location but has " + c + "." - ) - } - - query predicate missingLocation(string msg) { - exists(int c | - c = - strictcount(Node n | - not n.hasLocationInfo(_, _, _, _, _) and - not any(ConsistencyConfiguration conf).missingLocationExclude(n) - ) and - msg = "Nodes without location: " + c - ) - } - - query predicate uniqueNodeToString(Node n, string msg) { - exists(int c | - c = count(n.toString()) and - c != 1 and - msg = "Node should have one toString but has " + c + "." - ) - } - - query predicate missingToString(string msg) { - exists(int c | - c = strictcount(Node n | not exists(n.toString())) and - msg = "Nodes without toString: " + c - ) - } - - query predicate parameterCallable(ParameterNode p, string msg) { - exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and - msg = "Callable mismatch for parameter." - } - - query predicate localFlowIsLocal(Node n1, Node n2, string msg) { - simpleLocalFlowStep(n1, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Local flow step does not preserve enclosing callable." - } - - query predicate readStepIsLocal(Node n1, Node n2, string msg) { - readStep(n1, _, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Read step does not preserve enclosing callable." - } - - query predicate storeStepIsLocal(Node n1, Node n2, string msg) { - storeStep(n1, _, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Store step does not preserve enclosing callable." - } - - private DataFlowType typeRepr() { result = getNodeType(_) } - - query predicate compatibleTypesReflexive(DataFlowType t, string msg) { - t = typeRepr() and - not compatibleTypes(t, t) and - msg = "Type compatibility predicate is not reflexive." - } - - query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) { - isUnreachableInCall(n, call) and - exists(DataFlowCallable c | - c = nodeGetEnclosingCallable(n) and - not viableCallable(call) = c - ) and - msg = "Call context for isUnreachableInCall is inconsistent with call graph." - } - - query predicate localCallNodes(DataFlowCall call, Node n, string msg) { - ( - n = getAnOutNode(call, _) and - msg = "OutNode and call does not share enclosing callable." - or - n.(ArgumentNode).argumentOf(call, _) and - msg = "ArgumentNode and call does not share enclosing callable." - ) and - nodeGetEnclosingCallable(n) != call.getEnclosingCallable() - } - - // This predicate helps the compiler forget that in some languages - // it is impossible for a result of `getPreUpdateNode` to be an - // instance of `PostUpdateNode`. - private Node getPre(PostUpdateNode n) { - result = n.getPreUpdateNode() - or - none() - } - - query predicate postIsNotPre(PostUpdateNode n, string msg) { - getPre(n) = n and - msg = "PostUpdateNode should not equal its pre-update node." - } - - query predicate postHasUniquePre(PostUpdateNode n, string msg) { - not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and - exists(int c | - c = count(n.getPreUpdateNode()) and - c != 1 and - msg = "PostUpdateNode should have one pre-update node but has " + c + "." - ) - } - - query predicate uniquePostUpdate(Node n, string msg) { - not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and - 1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and - msg = "Node has multiple PostUpdateNodes." - } - - query predicate postIsInSameCallable(PostUpdateNode n, string msg) { - nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and - msg = "PostUpdateNode does not share callable with its pre-update node." - } - - private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) } - - query predicate reverseRead(Node n, string msg) { - exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and - not any(ConsistencyConfiguration conf).reverseReadExclude(n) and - msg = "Origin of readStep is missing a PostUpdateNode." - } - - query predicate argHasPostUpdate(ArgumentNode n, string msg) { - not hasPost(n) and - not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and - msg = "ArgumentNode is missing PostUpdateNode." - } - - // This predicate helps the compiler forget that in some languages - // it is impossible for a `PostUpdateNode` to be the target of - // `simpleLocalFlowStep`. - private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() } - - query predicate postWithInFlow(Node n, string msg) { - isPostUpdateNode(n) and - not clearsContent(n, _) and - simpleLocalFlowStep(_, n) and - not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and - msg = "PostUpdateNode should not be the target of local flow." - } - - query predicate viableImplInCallContextTooLarge( - DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable - ) { - callable = viableImplInCallContext(call, ctx) and - not callable = viableCallable(call) and - not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable) - } - - query predicate uniqueParameterNodeAtPosition( - DataFlowCallable c, ParameterPosition pos, Node p, string msg - ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and - isParameterNode(p, c, pos) and - not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and - msg = "Parameters with overlapping positions." - } - - query predicate uniqueParameterNodePosition( - DataFlowCallable c, ParameterPosition pos, Node p, string msg - ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and - isParameterNode(p, c, pos) and - not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and - msg = "Parameter node with multiple positions." - } - - query predicate uniqueContentApprox(Content c, string msg) { - not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and - msg = "Non-unique content approximation." - } - - query predicate identityLocalStep(Node n, string msg) { - simpleLocalFlowStep(n, n) and - not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and - msg = "Node steps to itself" +private module Input implements InputSig { + predicate argHasPostUpdateExclude(JavaDataFlow::ArgumentNode n) { + n.getType() instanceof ImmutableType or n instanceof Public::ImplicitVarargsArray } } + +module Consistency = MakeConsistency; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index 212232e077a..556baa60f96 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -8,7 +8,6 @@ private import ContainerFlow private import semmle.code.java.dataflow.FlowSteps private import semmle.code.java.dataflow.FlowSummary private import FlowSummaryImpl as FlowSummaryImpl -private import DataFlowImplConsistency private import DataFlowNodes private import codeql.dataflow.VariableCapture as VariableCapture import DataFlowNodes::Private @@ -113,11 +112,6 @@ private module CaptureInput implements VariableCapture::InputSig { VariableWrite() { super.getDestVar() = v } CapturedVariable getVariable() { result = v } - - Expr getSource() { - result = this.(VariableAssign).getSource() or - result = this.(AssignOp) - } } class VariableRead extends Expr instanceof RValue { @@ -155,14 +149,27 @@ class CapturedParameter = CaptureInput::CapturedParameter; module CaptureFlow = VariableCapture::Flow; private CaptureFlow::ClosureNode asClosureNode(Node n) { - result = n.(CaptureNode).getSynthesizedCaptureNode() or - result.(CaptureFlow::ExprNode).getExpr() = n.asExpr() or + result = n.(CaptureNode).getSynthesizedCaptureNode() + or + result.(CaptureFlow::ExprNode).getExpr() = n.asExpr() + or result.(CaptureFlow::ExprPostUpdateNode).getExpr() = - n.(PostUpdateNode).getPreUpdateNode().asExpr() or - result.(CaptureFlow::ParameterNode).getParameter() = n.asParameter() or - result.(CaptureFlow::ThisParameterNode).getCallable() = n.(InstanceParameterNode).getCallable() or + n.(PostUpdateNode).getPreUpdateNode().asExpr() + or + result.(CaptureFlow::ParameterNode).getParameter() = n.asParameter() + or + result.(CaptureFlow::ThisParameterNode).getCallable() = n.(InstanceParameterNode).getCallable() + or exprNode(result.(CaptureFlow::MallocNode).getClosureExpr()).(PostUpdateNode).getPreUpdateNode() = n + or + exists(CaptureInput::VariableWrite write | + result.(CaptureFlow::VariableWriteSourceNode).getVariableWrite() = write + | + n.asExpr() = write.(VariableAssign).getSource() + or + n.asExpr() = write.(AssignOp) + ) } private predicate captureStoreStep(Node node1, CapturedVariableContent c, Node node2) { @@ -572,12 +579,6 @@ ContentApprox getContentApprox(Content c) { c instanceof SyntheticFieldContent and result = TSyntheticFieldApproxContent() } -private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration { - override predicate argHasPostUpdateExclude(ArgumentNode n) { - n.getType() instanceof ImmutableType or n instanceof ImplicitVarargsArray - } -} - /** * Holds if the the content `c` is a container. */ diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 4c5b963ada7..76cd01f48eb 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.7.4 + +### New Queries + +* Added the `java/trust-boundary-violation` query to detect trust boundary violations between HTTP requests and the HTTP session. Also added the `trust-boundary-violation` sink kind for sinks which may cross a trust boundary, such as calls to the `HttpSession#setAttribute` method. + +### Minor Analysis Improvements + +* The queries "Resolving XML external entity in user-controlled data" (`java/xxe`) and "Resolving XML external entity in user-controlled data from local source" (`java/xxe-local`) now recognize sinks in the MDHT library. + ## 0.7.3 No user-facing changes. diff --git a/java/ql/src/Telemetry/ExtractorInformation.ql b/java/ql/src/Telemetry/ExtractorInformation.ql index 51990878a34..24cd705eee7 100644 --- a/java/ql/src/Telemetry/ExtractorInformation.ql +++ b/java/ql/src/Telemetry/ExtractorInformation.ql @@ -87,7 +87,7 @@ predicate extractorTotalDiagnostics(string key, int value) { from string key, int value where - not extractorInformationSkipKey(key) and + not exists(string pattern | extractorInformationSkipKey(pattern) and key.matches(pattern)) and ( compilationInfo(key, value) or fileCount(key, value) or diff --git a/java/ql/src/change-notes/2023-07-19-xxe-new-sinks.md b/java/ql/src/change-notes/2023-07-19-xxe-new-sinks.md deleted file mode 100644 index 6f062a63e81..00000000000 --- a/java/ql/src/change-notes/2023-07-19-xxe-new-sinks.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The queries "Resolving XML external entity in user-controlled data" (`java/xxe`) and "Resolving XML external entity in user-controlled data from local source" (`java/xxe-local`) now recognize sinks in the MDHT library. diff --git a/java/ql/src/change-notes/2023-07-25-trust-boundary-violation-query.md b/java/ql/src/change-notes/released/0.7.4.md similarity index 50% rename from java/ql/src/change-notes/2023-07-25-trust-boundary-violation-query.md rename to java/ql/src/change-notes/released/0.7.4.md index 802e367bf10..c214e52bd23 100644 --- a/java/ql/src/change-notes/2023-07-25-trust-boundary-violation-query.md +++ b/java/ql/src/change-notes/released/0.7.4.md @@ -1,5 +1,9 @@ ---- -category: newQuery ---- +## 0.7.4 + +### New Queries + * Added the `java/trust-boundary-violation` query to detect trust boundary violations between HTTP requests and the HTTP session. Also added the `trust-boundary-violation` sink kind for sinks which may cross a trust boundary, such as calls to the `HttpSession#setAttribute` method. +### Minor Analysis Improvements + +* The queries "Resolving XML external entity in user-controlled data" (`java/xxe`) and "Resolving XML external entity in user-controlled data from local source" (`java/xxe-local`) now recognize sinks in the MDHT library. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index a4ea9c8de17..e388f34b4ec 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.3 +lastReleaseVersion: 0.7.4 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index b2a297894fa..8fadb6cf148 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 0.7.4-dev +version: 0.7.4 groups: - java - queries diff --git a/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/old.dbscheme b/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/old.dbscheme new file mode 100644 index 00000000000..c88c69174bd --- /dev/null +++ b/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/old.dbscheme @@ -0,0 +1,1190 @@ +/*** Standard fragments ***/ + +/*- Files and folders -*/ + +/** + * The location of an element. + * 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( + 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 +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Lines of code -*/ + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +/*- External data -*/ + +/** + * 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 +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- JavaScript-specific part -*/ + +@location = @location_default + +@sourceline = @locatable; + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +is_externs (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url +| 4 = @template_toplevel; + +is_module (int tl: @toplevel ref); +is_nodejs (int tl: @toplevel ref); +is_es2015_module (int tl: @toplevel ref); +is_closure_module (int tl: @toplevel ref); + +@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag; +toplevel_parent_xml_node( + unique int toplevel: @toplevel ref, + int xmlnode: @xml_node_with_code ref); + +xml_element_parent_expression( + unique int xmlnode: @xmlelement ref, + int expression: @expr ref, + int index: int ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmt_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmt_containers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jump_targets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer; +@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration; + +case @stmt.kind of + 0 = @empty_stmt +| 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @labeled_stmt +| 5 = @break_stmt +| 6 = @continue_stmt +| 7 = @with_stmt +| 8 = @switch_stmt +| 9 = @return_stmt +| 10 = @throw_stmt +| 11 = @try_stmt +| 12 = @while_stmt +| 13 = @do_while_stmt +| 14 = @for_stmt +| 15 = @for_in_stmt +| 16 = @debugger_stmt +| 17 = @function_decl_stmt +| 18 = @var_decl_stmt +| 19 = @case +| 20 = @catch_clause +| 21 = @for_of_stmt +| 22 = @const_decl_stmt +| 23 = @let_stmt +| 24 = @legacy_let_stmt +| 25 = @for_each_stmt +| 26 = @class_decl_stmt +| 27 = @import_declaration +| 28 = @export_all_declaration +| 29 = @export_default_declaration +| 30 = @export_named_declaration +| 31 = @namespace_declaration +| 32 = @import_equals_declaration +| 33 = @export_assign_declaration +| 34 = @interface_declaration +| 35 = @type_alias_declaration +| 36 = @enum_declaration +| 37 = @external_module_declaration +| 38 = @export_as_namespace_declaration +| 39 = @global_augmentation_declaration +| 40 = @using_decl_stmt +; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt | @using_decl_stmt; + +@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration; + +@namespace_definition = @namespace_declaration | @enum_declaration; +@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member; + +is_instantiated(unique int decl: @namespace_declaration ref); + +@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field; +has_declare_keyword(unique int stmt: @declarable_node ref); + +is_for_await_of(unique int forof: @for_of_stmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @expr_or_type ref); + +enclosing_stmt (unique int expr: @expr_or_type ref, + int stmt: @stmt ref); + +expr_containers (unique int expr: @expr_or_type ref, + int container: @stmt_container ref); + +array_size (unique int ae: @arraylike ref, + int sz: int ref); + +is_delegating (int yield: @yield_expr ref); + +@expr_or_stmt = @expr | @stmt; +@expr_or_type = @expr | @typeexpr; +@expr_parent = @expr_or_stmt | @property | @function_typeexpr; +@arraylike = @array_expr | @array_pattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; +@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel; + +case @expr.kind of + 0 = @label +| 1 = @null_literal +| 2 = @boolean_literal +| 3 = @number_literal +| 4 = @string_literal +| 5 = @regexp_literal +| 6 = @this_expr +| 7 = @array_expr +| 8 = @obj_expr +| 9 = @function_expr +| 10 = @seq_expr +| 11 = @conditional_expr +| 12 = @new_expr +| 13 = @call_expr +| 14 = @dot_expr +| 15 = @index_expr +| 16 = @neg_expr +| 17 = @plus_expr +| 18 = @log_not_expr +| 19 = @bit_not_expr +| 20 = @typeof_expr +| 21 = @void_expr +| 22 = @delete_expr +| 23 = @eq_expr +| 24 = @neq_expr +| 25 = @eqq_expr +| 26 = @neqq_expr +| 27 = @lt_expr +| 28 = @le_expr +| 29 = @gt_expr +| 30 = @ge_expr +| 31 = @lshift_expr +| 32 = @rshift_expr +| 33 = @urshift_expr +| 34 = @add_expr +| 35 = @sub_expr +| 36 = @mul_expr +| 37 = @div_expr +| 38 = @mod_expr +| 39 = @bitor_expr +| 40 = @xor_expr +| 41 = @bitand_expr +| 42 = @in_expr +| 43 = @instanceof_expr +| 44 = @logand_expr +| 45 = @logor_expr +| 47 = @assign_expr +| 48 = @assign_add_expr +| 49 = @assign_sub_expr +| 50 = @assign_mul_expr +| 51 = @assign_div_expr +| 52 = @assign_mod_expr +| 53 = @assign_lshift_expr +| 54 = @assign_rshift_expr +| 55 = @assign_urshift_expr +| 56 = @assign_or_expr +| 57 = @assign_xor_expr +| 58 = @assign_and_expr +| 59 = @preinc_expr +| 60 = @postinc_expr +| 61 = @predec_expr +| 62 = @postdec_expr +| 63 = @par_expr +| 64 = @var_declarator +| 65 = @arrow_function_expr +| 66 = @spread_element +| 67 = @array_pattern +| 68 = @object_pattern +| 69 = @yield_expr +| 70 = @tagged_template_expr +| 71 = @template_literal +| 72 = @template_element +| 73 = @array_comprehension_expr +| 74 = @generator_expr +| 75 = @for_in_comprehension_block +| 76 = @for_of_comprehension_block +| 77 = @legacy_letexpr +| 78 = @var_decl +| 79 = @proper_varaccess +| 80 = @class_expr +| 81 = @super_expr +| 82 = @newtarget_expr +| 83 = @named_import_specifier +| 84 = @import_default_specifier +| 85 = @import_namespace_specifier +| 86 = @named_export_specifier +| 87 = @exp_expr +| 88 = @assign_exp_expr +| 89 = @jsx_element +| 90 = @jsx_qualified_name +| 91 = @jsx_empty_expr +| 92 = @await_expr +| 93 = @function_sent_expr +| 94 = @decorator +| 95 = @export_default_specifier +| 96 = @export_namespace_specifier +| 97 = @bind_expr +| 98 = @external_module_reference +| 99 = @dynamic_import +| 100 = @expression_with_type_arguments +| 101 = @prefix_type_assertion +| 102 = @as_type_assertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigint_literal +| 107 = @nullishcoalescing_expr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @import_meta_expr +| 116 = @assignlogandexpr +| 117 = @assignlogorexpr +| 118 = @assignnullishcoalescingexpr +| 119 = @template_pipe_ref +| 120 = @generated_code_expr +| 121 = @satisfies_expr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @var_decl | @varaccess; + +@identifier = @label | @varref | @type_identifier; + +@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal; + +@propaccess = @dot_expr | @index_expr; + +@invokeexpr = @new_expr | @call_expr; + +@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element; + +@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr; + +@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr; + +@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr; + +@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr; + +@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr; + +@pattern = @varref | @array_pattern | @object_pattern; + +@comprehension_expr = @array_comprehension_expr | @generator_expr; + +@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block; + +@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier; + +@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier; + +@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier; + +@type_assertion = @as_type_assertion | @prefix_type_assertion; + +@class_definition = @class_decl_stmt | @class_expr; +@interface_definition = @interface_declaration | @interface_typeexpr; +@class_or_interface = @class_definition | @interface_definition; + +@lexical_decl = @var_decl | @type_decl; +@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +expr_contains_template_tag_location( + int expr: @expr ref, + int location: @location ref +); + +@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file; + +template_placeholder_tag_info( + unique int node: @template_placeholder_tag, + int parentNode: @template_placeholder_tag_parent ref, + varchar(900) raw: string ref +); + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @global_scope +| 1 = @function_scope +| 2 = @catch_scope +| 3 = @module_scope +| 4 = @block_scope +| 5 = @for_scope +| 6 = @for_in_scope // for-of scopes work the same as for-in scopes +| 7 = @comprehension_block_scope +| 8 = @class_expr_scope +| 9 = @namespace_scope +| 10 = @class_decl_scope +| 11 = @interface_scope +| 12 = @type_alias_scope +| 13 = @mapped_type_scope +| 14 = @enum_scope +| 15 = @external_module_scope +| 16 = @conditional_type_scope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @function_decl_stmt | @function_expr | @arrow_function_expr; + +@parameterized = @function | @catch_clause; +@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr; + +is_generator (int fun: @function ref); +has_rest_parameter (int fun: @function ref); +is_async (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +is_arguments_object (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @local_var_type_access; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @var_decl ref, + int decl: @variable ref); + +@typebind_id = @local_type_access | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @type_decl | @var_decl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @var_decl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @local_namespace_access | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +| 10 = @static_initializer +; + +@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @var_declarator; + +is_computed (int id: @property ref); +is_method (int id: @property ref); +is_static (int id: @property ref); +is_abstract_member (int id: @property ref); +is_const_enum (int id: @enum_declaration ref); +is_abstract_class (int id: @class_decl_stmt ref); + +has_public_keyword (int id: @property ref); +has_private_keyword (int id: @property ref); +has_protected_keyword (int id: @property ref); +has_readonly_keyword (int id: @property ref); +has_type_keyword (int id: @type_keyword_operand ref); +is_optional_member (int id: @property ref); +has_definite_assignment_assertion (int id: @field_or_vardeclarator ref); +is_optional_parameter_declaration (unique int parameter: @pattern ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @function_expr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @local_type_access +| 1 = @type_decl +| 2 = @keyword_typeexpr +| 3 = @string_literal_typeexpr +| 4 = @number_literal_typeexpr +| 5 = @boolean_literal_typeexpr +| 6 = @array_typeexpr +| 7 = @union_typeexpr +| 8 = @indexed_access_typeexpr +| 9 = @intersection_typeexpr +| 10 = @parenthesized_typeexpr +| 11 = @tuple_typeexpr +| 12 = @keyof_typeexpr +| 13 = @qualified_type_access +| 14 = @generic_typeexpr +| 15 = @type_label +| 16 = @typeof_typeexpr +| 17 = @local_var_type_access +| 18 = @qualified_var_type_access +| 19 = @this_var_type_access +| 20 = @predicate_typeexpr +| 21 = @interface_typeexpr +| 22 = @type_parameter +| 23 = @plain_function_typeexpr +| 24 = @constructor_typeexpr +| 25 = @local_namespace_access +| 26 = @qualified_namespace_access +| 27 = @mapped_typeexpr +| 28 = @conditional_typeexpr +| 29 = @infer_typeexpr +| 30 = @import_type_access +| 31 = @import_namespace_access +| 32 = @import_var_type_access +| 33 = @optional_typeexpr +| 34 = @rest_typeexpr +| 35 = @bigint_literal_typeexpr +| 36 = @readonly_typeexpr +| 37 = @template_literal_typeexpr +; + +@typeref = @typeaccess | @type_decl; +@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr; +@typeaccess = @local_type_access | @qualified_type_access | @import_type_access; +@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access; +@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access; +@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access; + +@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @any_type +| 1 = @string_type +| 2 = @number_type +| 3 = @union_type +| 4 = @true_type +| 5 = @false_type +| 6 = @type_reference +| 7 = @object_type +| 8 = @canonical_type_variable_type +| 9 = @typeof_type +| 10 = @void_type +| 11 = @undefined_type +| 12 = @null_type +| 13 = @never_type +| 14 = @plain_symbol_type +| 15 = @unique_symbol_type +| 16 = @objectkeyword_type +| 17 = @intersection_type +| 18 = @tuple_type +| 19 = @lexical_type_variable_type +| 20 = @this_type +| 21 = @number_literal_type +| 22 = @string_literal_type +| 23 = @unknown_type +| 24 = @bigint_type +| 25 = @bigint_literal_type +; + +@boolean_literal_type = @true_type | @false_type; +@symbol_type = @plain_symbol_type | @unique_symbol_type; +@union_or_intersection_type = @union_type | @intersection_type; +@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type; + +has_asserts_keyword(int node: @predicate_typeexpr ref); + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type; +@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference | @external_module_declaration; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +type_alias( + unique int aliasType: @type ref, + int underlyingType: @type ref); + +@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type; +@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +is_abstract_signature( + unique int sig: @signature_type ref +); + +signature_rest_parameter( + unique int sig: @signature_type ref, + int rest_param_arra_type: @type ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @type_reference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest_index( + unique int typ: @type ref, + int index: int ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslash_comment +| 1 = @slashstar_comment +| 2 = @doc_comment +| 3 = @html_comment_start +| 4 = @htmlcommentend; + +@html_comment = @html_comment_start | @htmlcommentend; +@line_comment = @slashslash_comment | @html_comment; +@block_comment = @slashstar_comment | @doc_comment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +js_parse_errors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexp_literal | @string_literal | @add_expr; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_constant +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexp_parse_errors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_constant | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; +@regexp_anchor = @regexp_dollar | @regexp_caret; + +is_greedy (int id: @regexp_quantifier ref); +range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref); +range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref); +is_capture (unique int id: @regexp_group ref, int number: int ref); +is_named_capture (unique int id: @regexp_group ref, string name: string ref); +is_inverted (int id: @regexp_char_class ref); +regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref); +char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +named_backref (unique int id: @regexp_backref ref, string name: string ref); +unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable + | @template_placeholder_tag; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @expr_parent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +jsdoc_type_exprs (unique int id: @jsdoc_type_expr, + int kind: int ref, + int parent: @jsdoc_type_expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** +* Non-timing related data for the extraction of a single file. +* This table contains non-deterministic content. +*/ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- 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; diff --git a/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/semmlecode.javascript.dbscheme b/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/semmlecode.javascript.dbscheme new file mode 100644 index 00000000000..8accf0f930b --- /dev/null +++ b/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/semmlecode.javascript.dbscheme @@ -0,0 +1,1189 @@ +/*** Standard fragments ***/ + +/*- Files and folders -*/ + +/** + * The location of an element. + * 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( + 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 +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Lines of code -*/ + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +/*- External data -*/ + +/** + * 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 +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- JavaScript-specific part -*/ + +@location = @location_default + +@sourceline = @locatable; + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +is_externs (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url +| 4 = @template_toplevel; + +is_module (int tl: @toplevel ref); +is_nodejs (int tl: @toplevel ref); +is_es2015_module (int tl: @toplevel ref); +is_closure_module (int tl: @toplevel ref); + +@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag; +toplevel_parent_xml_node( + unique int toplevel: @toplevel ref, + int xmlnode: @xml_node_with_code ref); + +xml_element_parent_expression( + unique int xmlnode: @xmlelement ref, + int expression: @expr ref, + int index: int ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmt_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmt_containers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jump_targets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer; +@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration; + +case @stmt.kind of + 0 = @empty_stmt +| 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @labeled_stmt +| 5 = @break_stmt +| 6 = @continue_stmt +| 7 = @with_stmt +| 8 = @switch_stmt +| 9 = @return_stmt +| 10 = @throw_stmt +| 11 = @try_stmt +| 12 = @while_stmt +| 13 = @do_while_stmt +| 14 = @for_stmt +| 15 = @for_in_stmt +| 16 = @debugger_stmt +| 17 = @function_decl_stmt +| 18 = @var_decl_stmt +| 19 = @case +| 20 = @catch_clause +| 21 = @for_of_stmt +| 22 = @const_decl_stmt +| 23 = @let_stmt +| 24 = @legacy_let_stmt +| 25 = @for_each_stmt +| 26 = @class_decl_stmt +| 27 = @import_declaration +| 28 = @export_all_declaration +| 29 = @export_default_declaration +| 30 = @export_named_declaration +| 31 = @namespace_declaration +| 32 = @import_equals_declaration +| 33 = @export_assign_declaration +| 34 = @interface_declaration +| 35 = @type_alias_declaration +| 36 = @enum_declaration +| 37 = @external_module_declaration +| 38 = @export_as_namespace_declaration +| 39 = @global_augmentation_declaration +; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt; + +@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration; + +@namespace_definition = @namespace_declaration | @enum_declaration; +@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member; + +is_instantiated(unique int decl: @namespace_declaration ref); + +@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field; +has_declare_keyword(unique int stmt: @declarable_node ref); + +is_for_await_of(unique int forof: @for_of_stmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @expr_or_type ref); + +enclosing_stmt (unique int expr: @expr_or_type ref, + int stmt: @stmt ref); + +expr_containers (unique int expr: @expr_or_type ref, + int container: @stmt_container ref); + +array_size (unique int ae: @arraylike ref, + int sz: int ref); + +is_delegating (int yield: @yield_expr ref); + +@expr_or_stmt = @expr | @stmt; +@expr_or_type = @expr | @typeexpr; +@expr_parent = @expr_or_stmt | @property | @function_typeexpr; +@arraylike = @array_expr | @array_pattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; +@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel; + +case @expr.kind of + 0 = @label +| 1 = @null_literal +| 2 = @boolean_literal +| 3 = @number_literal +| 4 = @string_literal +| 5 = @regexp_literal +| 6 = @this_expr +| 7 = @array_expr +| 8 = @obj_expr +| 9 = @function_expr +| 10 = @seq_expr +| 11 = @conditional_expr +| 12 = @new_expr +| 13 = @call_expr +| 14 = @dot_expr +| 15 = @index_expr +| 16 = @neg_expr +| 17 = @plus_expr +| 18 = @log_not_expr +| 19 = @bit_not_expr +| 20 = @typeof_expr +| 21 = @void_expr +| 22 = @delete_expr +| 23 = @eq_expr +| 24 = @neq_expr +| 25 = @eqq_expr +| 26 = @neqq_expr +| 27 = @lt_expr +| 28 = @le_expr +| 29 = @gt_expr +| 30 = @ge_expr +| 31 = @lshift_expr +| 32 = @rshift_expr +| 33 = @urshift_expr +| 34 = @add_expr +| 35 = @sub_expr +| 36 = @mul_expr +| 37 = @div_expr +| 38 = @mod_expr +| 39 = @bitor_expr +| 40 = @xor_expr +| 41 = @bitand_expr +| 42 = @in_expr +| 43 = @instanceof_expr +| 44 = @logand_expr +| 45 = @logor_expr +| 47 = @assign_expr +| 48 = @assign_add_expr +| 49 = @assign_sub_expr +| 50 = @assign_mul_expr +| 51 = @assign_div_expr +| 52 = @assign_mod_expr +| 53 = @assign_lshift_expr +| 54 = @assign_rshift_expr +| 55 = @assign_urshift_expr +| 56 = @assign_or_expr +| 57 = @assign_xor_expr +| 58 = @assign_and_expr +| 59 = @preinc_expr +| 60 = @postinc_expr +| 61 = @predec_expr +| 62 = @postdec_expr +| 63 = @par_expr +| 64 = @var_declarator +| 65 = @arrow_function_expr +| 66 = @spread_element +| 67 = @array_pattern +| 68 = @object_pattern +| 69 = @yield_expr +| 70 = @tagged_template_expr +| 71 = @template_literal +| 72 = @template_element +| 73 = @array_comprehension_expr +| 74 = @generator_expr +| 75 = @for_in_comprehension_block +| 76 = @for_of_comprehension_block +| 77 = @legacy_letexpr +| 78 = @var_decl +| 79 = @proper_varaccess +| 80 = @class_expr +| 81 = @super_expr +| 82 = @newtarget_expr +| 83 = @named_import_specifier +| 84 = @import_default_specifier +| 85 = @import_namespace_specifier +| 86 = @named_export_specifier +| 87 = @exp_expr +| 88 = @assign_exp_expr +| 89 = @jsx_element +| 90 = @jsx_qualified_name +| 91 = @jsx_empty_expr +| 92 = @await_expr +| 93 = @function_sent_expr +| 94 = @decorator +| 95 = @export_default_specifier +| 96 = @export_namespace_specifier +| 97 = @bind_expr +| 98 = @external_module_reference +| 99 = @dynamic_import +| 100 = @expression_with_type_arguments +| 101 = @prefix_type_assertion +| 102 = @as_type_assertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigint_literal +| 107 = @nullishcoalescing_expr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @import_meta_expr +| 116 = @assignlogandexpr +| 117 = @assignlogorexpr +| 118 = @assignnullishcoalescingexpr +| 119 = @template_pipe_ref +| 120 = @generated_code_expr +| 121 = @satisfies_expr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @var_decl | @varaccess; + +@identifier = @label | @varref | @type_identifier; + +@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal; + +@propaccess = @dot_expr | @index_expr; + +@invokeexpr = @new_expr | @call_expr; + +@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element; + +@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr; + +@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr; + +@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr; + +@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr; + +@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr; + +@pattern = @varref | @array_pattern | @object_pattern; + +@comprehension_expr = @array_comprehension_expr | @generator_expr; + +@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block; + +@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier; + +@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier; + +@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier; + +@type_assertion = @as_type_assertion | @prefix_type_assertion; + +@class_definition = @class_decl_stmt | @class_expr; +@interface_definition = @interface_declaration | @interface_typeexpr; +@class_or_interface = @class_definition | @interface_definition; + +@lexical_decl = @var_decl | @type_decl; +@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +expr_contains_template_tag_location( + int expr: @expr ref, + int location: @location ref +); + +@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file; + +template_placeholder_tag_info( + unique int node: @template_placeholder_tag, + int parentNode: @template_placeholder_tag_parent ref, + varchar(900) raw: string ref +); + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @global_scope +| 1 = @function_scope +| 2 = @catch_scope +| 3 = @module_scope +| 4 = @block_scope +| 5 = @for_scope +| 6 = @for_in_scope // for-of scopes work the same as for-in scopes +| 7 = @comprehension_block_scope +| 8 = @class_expr_scope +| 9 = @namespace_scope +| 10 = @class_decl_scope +| 11 = @interface_scope +| 12 = @type_alias_scope +| 13 = @mapped_type_scope +| 14 = @enum_scope +| 15 = @external_module_scope +| 16 = @conditional_type_scope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @function_decl_stmt | @function_expr | @arrow_function_expr; + +@parameterized = @function | @catch_clause; +@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr; + +is_generator (int fun: @function ref); +has_rest_parameter (int fun: @function ref); +is_async (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +is_arguments_object (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @local_var_type_access; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @var_decl ref, + int decl: @variable ref); + +@typebind_id = @local_type_access | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @type_decl | @var_decl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @var_decl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @local_namespace_access | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +| 10 = @static_initializer +; + +@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @var_declarator; + +is_computed (int id: @property ref); +is_method (int id: @property ref); +is_static (int id: @property ref); +is_abstract_member (int id: @property ref); +is_const_enum (int id: @enum_declaration ref); +is_abstract_class (int id: @class_decl_stmt ref); + +has_public_keyword (int id: @property ref); +has_private_keyword (int id: @property ref); +has_protected_keyword (int id: @property ref); +has_readonly_keyword (int id: @property ref); +has_type_keyword (int id: @type_keyword_operand ref); +is_optional_member (int id: @property ref); +has_definite_assignment_assertion (int id: @field_or_vardeclarator ref); +is_optional_parameter_declaration (unique int parameter: @pattern ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @function_expr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @local_type_access +| 1 = @type_decl +| 2 = @keyword_typeexpr +| 3 = @string_literal_typeexpr +| 4 = @number_literal_typeexpr +| 5 = @boolean_literal_typeexpr +| 6 = @array_typeexpr +| 7 = @union_typeexpr +| 8 = @indexed_access_typeexpr +| 9 = @intersection_typeexpr +| 10 = @parenthesized_typeexpr +| 11 = @tuple_typeexpr +| 12 = @keyof_typeexpr +| 13 = @qualified_type_access +| 14 = @generic_typeexpr +| 15 = @type_label +| 16 = @typeof_typeexpr +| 17 = @local_var_type_access +| 18 = @qualified_var_type_access +| 19 = @this_var_type_access +| 20 = @predicate_typeexpr +| 21 = @interface_typeexpr +| 22 = @type_parameter +| 23 = @plain_function_typeexpr +| 24 = @constructor_typeexpr +| 25 = @local_namespace_access +| 26 = @qualified_namespace_access +| 27 = @mapped_typeexpr +| 28 = @conditional_typeexpr +| 29 = @infer_typeexpr +| 30 = @import_type_access +| 31 = @import_namespace_access +| 32 = @import_var_type_access +| 33 = @optional_typeexpr +| 34 = @rest_typeexpr +| 35 = @bigint_literal_typeexpr +| 36 = @readonly_typeexpr +| 37 = @template_literal_typeexpr +; + +@typeref = @typeaccess | @type_decl; +@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr; +@typeaccess = @local_type_access | @qualified_type_access | @import_type_access; +@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access; +@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access; +@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access; + +@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @any_type +| 1 = @string_type +| 2 = @number_type +| 3 = @union_type +| 4 = @true_type +| 5 = @false_type +| 6 = @type_reference +| 7 = @object_type +| 8 = @canonical_type_variable_type +| 9 = @typeof_type +| 10 = @void_type +| 11 = @undefined_type +| 12 = @null_type +| 13 = @never_type +| 14 = @plain_symbol_type +| 15 = @unique_symbol_type +| 16 = @objectkeyword_type +| 17 = @intersection_type +| 18 = @tuple_type +| 19 = @lexical_type_variable_type +| 20 = @this_type +| 21 = @number_literal_type +| 22 = @string_literal_type +| 23 = @unknown_type +| 24 = @bigint_type +| 25 = @bigint_literal_type +; + +@boolean_literal_type = @true_type | @false_type; +@symbol_type = @plain_symbol_type | @unique_symbol_type; +@union_or_intersection_type = @union_type | @intersection_type; +@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type; + +has_asserts_keyword(int node: @predicate_typeexpr ref); + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type; +@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference | @external_module_declaration; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +type_alias( + unique int aliasType: @type ref, + int underlyingType: @type ref); + +@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type; +@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +is_abstract_signature( + unique int sig: @signature_type ref +); + +signature_rest_parameter( + unique int sig: @signature_type ref, + int rest_param_arra_type: @type ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @type_reference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest_index( + unique int typ: @type ref, + int index: int ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslash_comment +| 1 = @slashstar_comment +| 2 = @doc_comment +| 3 = @html_comment_start +| 4 = @htmlcommentend; + +@html_comment = @html_comment_start | @htmlcommentend; +@line_comment = @slashslash_comment | @html_comment; +@block_comment = @slashstar_comment | @doc_comment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +js_parse_errors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexp_literal | @string_literal | @add_expr; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_constant +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexp_parse_errors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_constant | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; +@regexp_anchor = @regexp_dollar | @regexp_caret; + +is_greedy (int id: @regexp_quantifier ref); +range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref); +range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref); +is_capture (unique int id: @regexp_group ref, int number: int ref); +is_named_capture (unique int id: @regexp_group ref, string name: string ref); +is_inverted (int id: @regexp_char_class ref); +regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref); +char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +named_backref (unique int id: @regexp_backref ref, string name: string ref); +unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable + | @template_placeholder_tag; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @expr_parent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +jsdoc_type_exprs (unique int id: @jsdoc_type_expr, + int kind: int ref, + int parent: @jsdoc_type_expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** +* Non-timing related data for the extraction of a single file. +* This table contains non-deterministic content. +*/ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- 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; diff --git a/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/upgrade.properties b/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/upgrade.properties new file mode 100644 index 00000000000..e4f4275eac4 --- /dev/null +++ b/javascript/downgrades/c88c69174bd0dd4e95f1bcfbada68a2505e812c3/upgrade.properties @@ -0,0 +1,2 @@ +description: Add @using_decl_stmt +compatibility: backwards diff --git a/javascript/extractor/lib/typescript/package-lock.json b/javascript/extractor/lib/typescript/package-lock.json new file mode 100644 index 00000000000..9384d286b79 --- /dev/null +++ b/javascript/extractor/lib/typescript/package-lock.json @@ -0,0 +1,35 @@ +{ + "name": "typescript-parser-wrapper", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "typescript-parser-wrapper", + "dependencies": { + "typescript": "5.2.2" + }, + "devDependencies": { + "@types/node": "18.15.3" + } + }, + "node_modules/@types/node": { + "version": "18.15.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.3.tgz", + "integrity": "sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + } + } +} diff --git a/javascript/extractor/lib/typescript/package.json b/javascript/extractor/lib/typescript/package.json index 3190b683d34..e043afa01db 100644 --- a/javascript/extractor/lib/typescript/package.json +++ b/javascript/extractor/lib/typescript/package.json @@ -2,7 +2,7 @@ "name": "typescript-parser-wrapper", "private": true, "dependencies": { - "typescript": "5.1.3" + "typescript": "5.2.2" }, "scripts": { "build": "tsc --project tsconfig.json", diff --git a/javascript/extractor/lib/typescript/src/main.ts b/javascript/extractor/lib/typescript/src/main.ts index 2594f4e35f5..e9849f42f5c 100644 --- a/javascript/extractor/lib/typescript/src/main.ts +++ b/javascript/extractor/lib/typescript/src/main.ts @@ -361,7 +361,10 @@ function handleParseCommand(command: ParseCommand, checkPending = true) { let filename = command.filename; let expectedFilename = state.pendingFiles[state.pendingFileIndex]; if (expectedFilename !== filename && checkPending) { - throw new Error("File requested out of order. Expected '" + expectedFilename + "' but got '" + filename + "'"); + // File was requested out of order. This happens in rare cases because the Java process decided against extracting it, + // for example because it was too large. Just recover and accept that some work was wasted. + state.pendingResponse = null; + state.pendingFileIndex = state.pendingFiles.indexOf(filename); } ++state.pendingFileIndex; let response = state.pendingResponse || extractFile(command.filename); diff --git a/javascript/extractor/lib/typescript/yarn.lock b/javascript/extractor/lib/typescript/yarn.lock index 355c257cf69..d72f714a4fb 100644 --- a/javascript/extractor/lib/typescript/yarn.lock +++ b/javascript/extractor/lib/typescript/yarn.lock @@ -4,10 +4,10 @@ "@types/node@18.15.3": version "18.15.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.3.tgz#f0b991c32cfc6a4e7f3399d6cb4b8cf9a0315014" + resolved "https://registry.npmjs.org/@types/node/-/node-18.15.3.tgz" integrity sha512-p6ua9zBxz5otCmbpb5D3U4B5Nanw6Pk3PPyX05xnxbB/fRv71N7CPmORg7uAD5P70T0xmx1pzAx/FUfa5X+3cw== -typescript@5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.3.tgz#8d84219244a6b40b6fb2b33cc1c062f715b9e826" - integrity sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw== +typescript@5.2.2: + version "5.2.2" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== diff --git a/javascript/extractor/src/com/semmle/jcorn/Parser.java b/javascript/extractor/src/com/semmle/jcorn/Parser.java index aac1c425e77..b7325021b72 100644 --- a/javascript/extractor/src/com/semmle/jcorn/Parser.java +++ b/javascript/extractor/src/com/semmle/jcorn/Parser.java @@ -2674,17 +2674,42 @@ public class Parser { // - 'async /*foo*/ function' is OK. // - 'async /*\n*/ function' is invalid. boolean isAsyncFunction() { + return isAsyncKeyword("async", "function"); + } + + boolean isAwaitUsing() { + return isAsyncKeyword("await", "using"); + } + + // check 'pre [no LineTerminator here] keyword' + // e.g. `await using" or `async function`. + // is only used for async/await parsing, so it requires ecmaVersion >= 8. + boolean isAsyncKeyword(String pre, String keyword) { if (this.type != TokenType.name || this.options.ecmaVersion() < 8 - || !this.value.equals("async")) return false; + || !this.value.equals(pre)) return false; + + Matcher m = Whitespace.skipWhiteSpace.matcher(this.input); + m.find(this.pos); + int next = m.end(); + int len = keyword.length(); + return !Whitespace.lineBreakG.matcher(inputSubstring(this.pos, next)).matches() + && inputSubstring(next, next + len).equals(keyword) + && (next + len == this.input.length() + || !Identifiers.isIdentifierChar(this.input.codePointAt(next + len), false)); + } + + // matches "using [identifier]" + boolean isUsingDecl() { + if (this.type != TokenType.name + || this.options.ecmaVersion() < 8 + || !this.value.equals("using")) return false; Matcher m = Whitespace.skipWhiteSpace.matcher(this.input); m.find(this.pos); int next = m.end(); return !Whitespace.lineBreakG.matcher(inputSubstring(this.pos, next)).matches() - && inputSubstring(next, next + 8).equals("function") - && (next + 8 == this.input.length() - || !Identifiers.isIdentifierChar(this.input.codePointAt(next + 8), false)); + && Identifiers.isIdentifierChar(this.input.codePointAt(next), false); } /** @@ -2737,7 +2762,7 @@ public class Parser { return this.parseThrowStatement(startLoc); } else if (starttype == TokenType._try) { return this.parseTryStatement(startLoc); - } else if (starttype == TokenType._const || starttype == TokenType._var) { + } else if (starttype == TokenType._const || starttype == TokenType._var || this.isUsingDecl()) { if (kind == null) kind = String.valueOf(this.value); if (!declaration && !kind.equals("var")) this.unexpected(); return this.parseVarStatement(startLoc, kind); @@ -2761,6 +2786,10 @@ public class Parser { : this.parseExport(startLoc, exports); } else { + if (this.isAwaitUsing() && (this.inAsync || options.esnext() && !this.inFunction)) { + this.next(); + return this.parseVarStatement(startLoc, "using"); + } if (this.isAsyncFunction() && declaration) { this.next(); return this.parseFunctionStatement(startLoc, true); @@ -2840,7 +2869,10 @@ public class Parser { this.expect(TokenType.parenL); if (this.type == TokenType.semi) return this.parseFor(startLoc, null); boolean isLet = this.isLet(); - if (this.type == TokenType._var || this.type == TokenType._const || isLet) { + if (this.isAwaitUsing() && this.inAsync) { + this.next(); // just skip the await and treat it as a `using` statement + } + if (this.type == TokenType._var || this.type == TokenType._const || isLet || (this.type == TokenType.name && this.value.equals("using"))) { Position initStartLoc = this.startLoc; String kind = isLet ? "let" : String.valueOf(this.value); this.next(); @@ -3122,7 +3154,7 @@ public class Parser { Expression init = null; if (this.eat(TokenType.eq)) { init = this.parseMaybeAssign(isFor, null, null); - } else if (kind.equals("const") + } else if ((kind.equals("const") || kind.equals("using")) && !(this.type == TokenType._in || (this.options.ecmaVersion() >= 6 && this.isContextual("of")))) { this.raiseRecoverable( diff --git a/javascript/extractor/src/com/semmle/js/ast/VariableDeclaration.java b/javascript/extractor/src/com/semmle/js/ast/VariableDeclaration.java index ffe5d13b296..b86d8e8e0e2 100644 --- a/javascript/extractor/src/com/semmle/js/ast/VariableDeclaration.java +++ b/javascript/extractor/src/com/semmle/js/ast/VariableDeclaration.java @@ -28,8 +28,8 @@ public class VariableDeclaration extends Statement { } /** - * The kind of this variable declaration statement; one of "var", "let" - * or "const". + * The kind of this variable declaration statement; one of "var", "let", + * "const", or "using". */ public String getKind() { return kind; @@ -42,6 +42,7 @@ public class VariableDeclaration extends Statement { */ public boolean isBlockScoped(ECMAVersion ecmaVersion) { return "let".equals(kind) + || "using".equals(kind) || ecmaVersion.compareTo(ECMAVersion.ECMA2015) >= 0 && "const".equals(kind); } diff --git a/javascript/extractor/src/com/semmle/js/extractor/Main.java b/javascript/extractor/src/com/semmle/js/extractor/Main.java index 2a188676924..72156e94927 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/Main.java +++ b/javascript/extractor/src/com/semmle/js/extractor/Main.java @@ -41,7 +41,7 @@ public class Main { * A version identifier that should be updated every time the extractor changes in such a way that * it may produce different tuples for the same file under the same {@link ExtractorConfig}. */ - public static final String EXTRACTOR_VERSION = "2023-04-19"; + public static final String EXTRACTOR_VERSION = "2023-08-10"; public static final Pattern NEWLINE = Pattern.compile("\n"); diff --git a/javascript/extractor/src/com/semmle/js/extractor/StmtKinds.java b/javascript/extractor/src/com/semmle/js/extractor/StmtKinds.java index db9982ba152..b4e540c3a0b 100644 --- a/javascript/extractor/src/com/semmle/js/extractor/StmtKinds.java +++ b/javascript/extractor/src/com/semmle/js/extractor/StmtKinds.java @@ -58,6 +58,7 @@ public class StmtKinds { declKinds.put("var", 18); declKinds.put("const", 22); declKinds.put("let", 23); + declKinds.put("using", 40); } public static int getStmtKind(final Statement stmt) { diff --git a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java index 7b68106bb3f..bf48c3fd7c9 100644 --- a/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java +++ b/javascript/extractor/src/com/semmle/ts/extractor/TypeScriptASTConverter.java @@ -2683,10 +2683,13 @@ public class TypeScriptASTConverter { } /** - * Gets the declaration kind of the given node, which is one of {@code "var"}, {@code "let"} or - * {@code "const"}. + * Gets the declaration kind of the given node, which is one of {@code "var"}, {@code "let"}, + * {@code "const"}, or {@code "using"}. */ private String getDeclarationKind(JsonObject declarationList) { + if (hasFlag(declarationList, "Using")) { + return "using"; + } return declarationList.get("$declarationKind").getAsString(); } } diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index ad0301e9c7b..13a56f3dcda 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.7.4 + +### Major Analysis Improvements + +* Added support for TypeScript 5.2. + ## 0.7.3 No user-facing changes. diff --git a/javascript/ql/lib/change-notes/released/0.7.4.md b/javascript/ql/lib/change-notes/released/0.7.4.md new file mode 100644 index 00000000000..7608c571bdf --- /dev/null +++ b/javascript/ql/lib/change-notes/released/0.7.4.md @@ -0,0 +1,5 @@ +## 0.7.4 + +### Major Analysis Improvements + +* Added support for TypeScript 5.2. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index a4ea9c8de17..e388f34b4ec 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.3 +lastReleaseVersion: 0.7.4 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index d65eefd366c..bb8abe793e6 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 0.7.4-dev +version: 0.7.4 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/lib/semmle/javascript/PrintAst.qll b/javascript/ql/lib/semmle/javascript/PrintAst.qll index 0defda1dc6b..2d3e0d26074 100644 --- a/javascript/ql/lib/semmle/javascript/PrintAst.qll +++ b/javascript/ql/lib/semmle/javascript/PrintAst.qll @@ -246,13 +246,15 @@ private module PrintJavaScript { } /** - * Gets "var" or "const" or "let" depending on what type of declaration `decl` is. + * Gets "var" or "const" or "let" or "using" depending on what type of declaration `decl` is. */ private string getDeclarationKeyword(DeclStmt decl) { decl instanceof VarDeclStmt and result = "var" or decl instanceof ConstDeclStmt and result = "const" or + decl instanceof UsingDeclStmt and result = "using" + or decl instanceof LetStmt and result = "let" } } diff --git a/javascript/ql/lib/semmle/javascript/Stmt.qll b/javascript/ql/lib/semmle/javascript/Stmt.qll index 24a901a0dcc..ae59c0b81eb 100644 --- a/javascript/ql/lib/semmle/javascript/Stmt.qll +++ b/javascript/ql/lib/semmle/javascript/Stmt.qll @@ -1041,6 +1041,17 @@ class VarDeclStmt extends @var_decl_stmt, DeclStmt { } */ class ConstDeclStmt extends @const_decl_stmt, DeclStmt { } +/** + * A `using` declaration statement. + * + * Example: + * + * ``` + * using file = new TextFile("file.txt"); + * ``` + */ +class UsingDeclStmt extends @using_decl_stmt, DeclStmt { } + /** * A `let` declaration statement. * diff --git a/javascript/ql/lib/semmlecode.javascript.dbscheme b/javascript/ql/lib/semmlecode.javascript.dbscheme index 8accf0f930b..c88c69174bd 100644 --- a/javascript/ql/lib/semmlecode.javascript.dbscheme +++ b/javascript/ql/lib/semmlecode.javascript.dbscheme @@ -162,9 +162,10 @@ case @stmt.kind of | 37 = @external_module_declaration | 38 = @export_as_namespace_declaration | 39 = @global_augmentation_declaration +| 40 = @using_decl_stmt ; -@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt; +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt | @using_decl_stmt; @export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration; diff --git a/javascript/ql/lib/semmlecode.javascript.dbscheme.stats b/javascript/ql/lib/semmlecode.javascript.dbscheme.stats index c198daf9e67..97ba6f9bcc3 100644 --- a/javascript/ql/lib/semmlecode.javascript.dbscheme.stats +++ b/javascript/ql/lib/semmlecode.javascript.dbscheme.stats @@ -170,6 +170,10 @@ 5 +@using_decl_stmt +5 + + @export_default_declaration 5 diff --git a/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/old.dbscheme b/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/old.dbscheme new file mode 100644 index 00000000000..8accf0f930b --- /dev/null +++ b/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/old.dbscheme @@ -0,0 +1,1189 @@ +/*** Standard fragments ***/ + +/*- Files and folders -*/ + +/** + * The location of an element. + * 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( + 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 +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Lines of code -*/ + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +/*- External data -*/ + +/** + * 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 +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- JavaScript-specific part -*/ + +@location = @location_default + +@sourceline = @locatable; + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +is_externs (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url +| 4 = @template_toplevel; + +is_module (int tl: @toplevel ref); +is_nodejs (int tl: @toplevel ref); +is_es2015_module (int tl: @toplevel ref); +is_closure_module (int tl: @toplevel ref); + +@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag; +toplevel_parent_xml_node( + unique int toplevel: @toplevel ref, + int xmlnode: @xml_node_with_code ref); + +xml_element_parent_expression( + unique int xmlnode: @xmlelement ref, + int expression: @expr ref, + int index: int ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmt_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmt_containers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jump_targets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer; +@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration; + +case @stmt.kind of + 0 = @empty_stmt +| 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @labeled_stmt +| 5 = @break_stmt +| 6 = @continue_stmt +| 7 = @with_stmt +| 8 = @switch_stmt +| 9 = @return_stmt +| 10 = @throw_stmt +| 11 = @try_stmt +| 12 = @while_stmt +| 13 = @do_while_stmt +| 14 = @for_stmt +| 15 = @for_in_stmt +| 16 = @debugger_stmt +| 17 = @function_decl_stmt +| 18 = @var_decl_stmt +| 19 = @case +| 20 = @catch_clause +| 21 = @for_of_stmt +| 22 = @const_decl_stmt +| 23 = @let_stmt +| 24 = @legacy_let_stmt +| 25 = @for_each_stmt +| 26 = @class_decl_stmt +| 27 = @import_declaration +| 28 = @export_all_declaration +| 29 = @export_default_declaration +| 30 = @export_named_declaration +| 31 = @namespace_declaration +| 32 = @import_equals_declaration +| 33 = @export_assign_declaration +| 34 = @interface_declaration +| 35 = @type_alias_declaration +| 36 = @enum_declaration +| 37 = @external_module_declaration +| 38 = @export_as_namespace_declaration +| 39 = @global_augmentation_declaration +; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt; + +@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration; + +@namespace_definition = @namespace_declaration | @enum_declaration; +@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member; + +is_instantiated(unique int decl: @namespace_declaration ref); + +@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field; +has_declare_keyword(unique int stmt: @declarable_node ref); + +is_for_await_of(unique int forof: @for_of_stmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @expr_or_type ref); + +enclosing_stmt (unique int expr: @expr_or_type ref, + int stmt: @stmt ref); + +expr_containers (unique int expr: @expr_or_type ref, + int container: @stmt_container ref); + +array_size (unique int ae: @arraylike ref, + int sz: int ref); + +is_delegating (int yield: @yield_expr ref); + +@expr_or_stmt = @expr | @stmt; +@expr_or_type = @expr | @typeexpr; +@expr_parent = @expr_or_stmt | @property | @function_typeexpr; +@arraylike = @array_expr | @array_pattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; +@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel; + +case @expr.kind of + 0 = @label +| 1 = @null_literal +| 2 = @boolean_literal +| 3 = @number_literal +| 4 = @string_literal +| 5 = @regexp_literal +| 6 = @this_expr +| 7 = @array_expr +| 8 = @obj_expr +| 9 = @function_expr +| 10 = @seq_expr +| 11 = @conditional_expr +| 12 = @new_expr +| 13 = @call_expr +| 14 = @dot_expr +| 15 = @index_expr +| 16 = @neg_expr +| 17 = @plus_expr +| 18 = @log_not_expr +| 19 = @bit_not_expr +| 20 = @typeof_expr +| 21 = @void_expr +| 22 = @delete_expr +| 23 = @eq_expr +| 24 = @neq_expr +| 25 = @eqq_expr +| 26 = @neqq_expr +| 27 = @lt_expr +| 28 = @le_expr +| 29 = @gt_expr +| 30 = @ge_expr +| 31 = @lshift_expr +| 32 = @rshift_expr +| 33 = @urshift_expr +| 34 = @add_expr +| 35 = @sub_expr +| 36 = @mul_expr +| 37 = @div_expr +| 38 = @mod_expr +| 39 = @bitor_expr +| 40 = @xor_expr +| 41 = @bitand_expr +| 42 = @in_expr +| 43 = @instanceof_expr +| 44 = @logand_expr +| 45 = @logor_expr +| 47 = @assign_expr +| 48 = @assign_add_expr +| 49 = @assign_sub_expr +| 50 = @assign_mul_expr +| 51 = @assign_div_expr +| 52 = @assign_mod_expr +| 53 = @assign_lshift_expr +| 54 = @assign_rshift_expr +| 55 = @assign_urshift_expr +| 56 = @assign_or_expr +| 57 = @assign_xor_expr +| 58 = @assign_and_expr +| 59 = @preinc_expr +| 60 = @postinc_expr +| 61 = @predec_expr +| 62 = @postdec_expr +| 63 = @par_expr +| 64 = @var_declarator +| 65 = @arrow_function_expr +| 66 = @spread_element +| 67 = @array_pattern +| 68 = @object_pattern +| 69 = @yield_expr +| 70 = @tagged_template_expr +| 71 = @template_literal +| 72 = @template_element +| 73 = @array_comprehension_expr +| 74 = @generator_expr +| 75 = @for_in_comprehension_block +| 76 = @for_of_comprehension_block +| 77 = @legacy_letexpr +| 78 = @var_decl +| 79 = @proper_varaccess +| 80 = @class_expr +| 81 = @super_expr +| 82 = @newtarget_expr +| 83 = @named_import_specifier +| 84 = @import_default_specifier +| 85 = @import_namespace_specifier +| 86 = @named_export_specifier +| 87 = @exp_expr +| 88 = @assign_exp_expr +| 89 = @jsx_element +| 90 = @jsx_qualified_name +| 91 = @jsx_empty_expr +| 92 = @await_expr +| 93 = @function_sent_expr +| 94 = @decorator +| 95 = @export_default_specifier +| 96 = @export_namespace_specifier +| 97 = @bind_expr +| 98 = @external_module_reference +| 99 = @dynamic_import +| 100 = @expression_with_type_arguments +| 101 = @prefix_type_assertion +| 102 = @as_type_assertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigint_literal +| 107 = @nullishcoalescing_expr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @import_meta_expr +| 116 = @assignlogandexpr +| 117 = @assignlogorexpr +| 118 = @assignnullishcoalescingexpr +| 119 = @template_pipe_ref +| 120 = @generated_code_expr +| 121 = @satisfies_expr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @var_decl | @varaccess; + +@identifier = @label | @varref | @type_identifier; + +@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal; + +@propaccess = @dot_expr | @index_expr; + +@invokeexpr = @new_expr | @call_expr; + +@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element; + +@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr; + +@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr; + +@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr; + +@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr; + +@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr; + +@pattern = @varref | @array_pattern | @object_pattern; + +@comprehension_expr = @array_comprehension_expr | @generator_expr; + +@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block; + +@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier; + +@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier; + +@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier; + +@type_assertion = @as_type_assertion | @prefix_type_assertion; + +@class_definition = @class_decl_stmt | @class_expr; +@interface_definition = @interface_declaration | @interface_typeexpr; +@class_or_interface = @class_definition | @interface_definition; + +@lexical_decl = @var_decl | @type_decl; +@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +expr_contains_template_tag_location( + int expr: @expr ref, + int location: @location ref +); + +@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file; + +template_placeholder_tag_info( + unique int node: @template_placeholder_tag, + int parentNode: @template_placeholder_tag_parent ref, + varchar(900) raw: string ref +); + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @global_scope +| 1 = @function_scope +| 2 = @catch_scope +| 3 = @module_scope +| 4 = @block_scope +| 5 = @for_scope +| 6 = @for_in_scope // for-of scopes work the same as for-in scopes +| 7 = @comprehension_block_scope +| 8 = @class_expr_scope +| 9 = @namespace_scope +| 10 = @class_decl_scope +| 11 = @interface_scope +| 12 = @type_alias_scope +| 13 = @mapped_type_scope +| 14 = @enum_scope +| 15 = @external_module_scope +| 16 = @conditional_type_scope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @function_decl_stmt | @function_expr | @arrow_function_expr; + +@parameterized = @function | @catch_clause; +@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr; + +is_generator (int fun: @function ref); +has_rest_parameter (int fun: @function ref); +is_async (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +is_arguments_object (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @local_var_type_access; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @var_decl ref, + int decl: @variable ref); + +@typebind_id = @local_type_access | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @type_decl | @var_decl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @var_decl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @local_namespace_access | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +| 10 = @static_initializer +; + +@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @var_declarator; + +is_computed (int id: @property ref); +is_method (int id: @property ref); +is_static (int id: @property ref); +is_abstract_member (int id: @property ref); +is_const_enum (int id: @enum_declaration ref); +is_abstract_class (int id: @class_decl_stmt ref); + +has_public_keyword (int id: @property ref); +has_private_keyword (int id: @property ref); +has_protected_keyword (int id: @property ref); +has_readonly_keyword (int id: @property ref); +has_type_keyword (int id: @type_keyword_operand ref); +is_optional_member (int id: @property ref); +has_definite_assignment_assertion (int id: @field_or_vardeclarator ref); +is_optional_parameter_declaration (unique int parameter: @pattern ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @function_expr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @local_type_access +| 1 = @type_decl +| 2 = @keyword_typeexpr +| 3 = @string_literal_typeexpr +| 4 = @number_literal_typeexpr +| 5 = @boolean_literal_typeexpr +| 6 = @array_typeexpr +| 7 = @union_typeexpr +| 8 = @indexed_access_typeexpr +| 9 = @intersection_typeexpr +| 10 = @parenthesized_typeexpr +| 11 = @tuple_typeexpr +| 12 = @keyof_typeexpr +| 13 = @qualified_type_access +| 14 = @generic_typeexpr +| 15 = @type_label +| 16 = @typeof_typeexpr +| 17 = @local_var_type_access +| 18 = @qualified_var_type_access +| 19 = @this_var_type_access +| 20 = @predicate_typeexpr +| 21 = @interface_typeexpr +| 22 = @type_parameter +| 23 = @plain_function_typeexpr +| 24 = @constructor_typeexpr +| 25 = @local_namespace_access +| 26 = @qualified_namespace_access +| 27 = @mapped_typeexpr +| 28 = @conditional_typeexpr +| 29 = @infer_typeexpr +| 30 = @import_type_access +| 31 = @import_namespace_access +| 32 = @import_var_type_access +| 33 = @optional_typeexpr +| 34 = @rest_typeexpr +| 35 = @bigint_literal_typeexpr +| 36 = @readonly_typeexpr +| 37 = @template_literal_typeexpr +; + +@typeref = @typeaccess | @type_decl; +@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr; +@typeaccess = @local_type_access | @qualified_type_access | @import_type_access; +@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access; +@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access; +@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access; + +@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @any_type +| 1 = @string_type +| 2 = @number_type +| 3 = @union_type +| 4 = @true_type +| 5 = @false_type +| 6 = @type_reference +| 7 = @object_type +| 8 = @canonical_type_variable_type +| 9 = @typeof_type +| 10 = @void_type +| 11 = @undefined_type +| 12 = @null_type +| 13 = @never_type +| 14 = @plain_symbol_type +| 15 = @unique_symbol_type +| 16 = @objectkeyword_type +| 17 = @intersection_type +| 18 = @tuple_type +| 19 = @lexical_type_variable_type +| 20 = @this_type +| 21 = @number_literal_type +| 22 = @string_literal_type +| 23 = @unknown_type +| 24 = @bigint_type +| 25 = @bigint_literal_type +; + +@boolean_literal_type = @true_type | @false_type; +@symbol_type = @plain_symbol_type | @unique_symbol_type; +@union_or_intersection_type = @union_type | @intersection_type; +@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type; + +has_asserts_keyword(int node: @predicate_typeexpr ref); + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type; +@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference | @external_module_declaration; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +type_alias( + unique int aliasType: @type ref, + int underlyingType: @type ref); + +@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type; +@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +is_abstract_signature( + unique int sig: @signature_type ref +); + +signature_rest_parameter( + unique int sig: @signature_type ref, + int rest_param_arra_type: @type ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @type_reference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest_index( + unique int typ: @type ref, + int index: int ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslash_comment +| 1 = @slashstar_comment +| 2 = @doc_comment +| 3 = @html_comment_start +| 4 = @htmlcommentend; + +@html_comment = @html_comment_start | @htmlcommentend; +@line_comment = @slashslash_comment | @html_comment; +@block_comment = @slashstar_comment | @doc_comment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +js_parse_errors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexp_literal | @string_literal | @add_expr; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_constant +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexp_parse_errors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_constant | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; +@regexp_anchor = @regexp_dollar | @regexp_caret; + +is_greedy (int id: @regexp_quantifier ref); +range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref); +range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref); +is_capture (unique int id: @regexp_group ref, int number: int ref); +is_named_capture (unique int id: @regexp_group ref, string name: string ref); +is_inverted (int id: @regexp_char_class ref); +regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref); +char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +named_backref (unique int id: @regexp_backref ref, string name: string ref); +unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable + | @template_placeholder_tag; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @expr_parent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +jsdoc_type_exprs (unique int id: @jsdoc_type_expr, + int kind: int ref, + int parent: @jsdoc_type_expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** +* Non-timing related data for the extraction of a single file. +* This table contains non-deterministic content. +*/ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- 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; diff --git a/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/semmlecode.javascript.dbscheme b/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/semmlecode.javascript.dbscheme new file mode 100644 index 00000000000..c88c69174bd --- /dev/null +++ b/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/semmlecode.javascript.dbscheme @@ -0,0 +1,1190 @@ +/*** Standard fragments ***/ + +/*- Files and folders -*/ + +/** + * The location of an element. + * 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( + 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 +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @file | @folder + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +/*- Lines of code -*/ + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +/*- External data -*/ + +/** + * 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 +); + +/*- Source location prefix -*/ + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/*- JavaScript-specific part -*/ + +@location = @location_default + +@sourceline = @locatable; + +filetype( + int file: @file ref, + string filetype: string ref +) + +// top-level code fragments +toplevels (unique int id: @toplevel, + int kind: int ref); + +is_externs (int toplevel: @toplevel ref); + +case @toplevel.kind of + 0 = @script +| 1 = @inline_script +| 2 = @event_handler +| 3 = @javascript_url +| 4 = @template_toplevel; + +is_module (int tl: @toplevel ref); +is_nodejs (int tl: @toplevel ref); +is_es2015_module (int tl: @toplevel ref); +is_closure_module (int tl: @toplevel ref); + +@xml_node_with_code = @xmlelement | @xmlattribute | @template_placeholder_tag; +toplevel_parent_xml_node( + unique int toplevel: @toplevel ref, + int xmlnode: @xml_node_with_code ref); + +xml_element_parent_expression( + unique int xmlnode: @xmlelement ref, + int expression: @expr ref, + int index: int ref); + +// statements +#keyset[parent, idx] +stmts (unique int id: @stmt, + int kind: int ref, + int parent: @stmt_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +stmt_containers (unique int stmt: @stmt ref, + int container: @stmt_container ref); + +jump_targets (unique int jump: @stmt ref, + int target: @stmt ref); + +@stmt_parent = @stmt | @toplevel | @function_expr | @arrow_function_expr | @static_initializer; +@stmt_container = @toplevel | @function | @namespace_declaration | @external_module_declaration | @global_augmentation_declaration; + +case @stmt.kind of + 0 = @empty_stmt +| 1 = @block_stmt +| 2 = @expr_stmt +| 3 = @if_stmt +| 4 = @labeled_stmt +| 5 = @break_stmt +| 6 = @continue_stmt +| 7 = @with_stmt +| 8 = @switch_stmt +| 9 = @return_stmt +| 10 = @throw_stmt +| 11 = @try_stmt +| 12 = @while_stmt +| 13 = @do_while_stmt +| 14 = @for_stmt +| 15 = @for_in_stmt +| 16 = @debugger_stmt +| 17 = @function_decl_stmt +| 18 = @var_decl_stmt +| 19 = @case +| 20 = @catch_clause +| 21 = @for_of_stmt +| 22 = @const_decl_stmt +| 23 = @let_stmt +| 24 = @legacy_let_stmt +| 25 = @for_each_stmt +| 26 = @class_decl_stmt +| 27 = @import_declaration +| 28 = @export_all_declaration +| 29 = @export_default_declaration +| 30 = @export_named_declaration +| 31 = @namespace_declaration +| 32 = @import_equals_declaration +| 33 = @export_assign_declaration +| 34 = @interface_declaration +| 35 = @type_alias_declaration +| 36 = @enum_declaration +| 37 = @external_module_declaration +| 38 = @export_as_namespace_declaration +| 39 = @global_augmentation_declaration +| 40 = @using_decl_stmt +; + +@decl_stmt = @var_decl_stmt | @const_decl_stmt | @let_stmt | @legacy_let_stmt | @using_decl_stmt; + +@export_declaration = @export_all_declaration | @export_default_declaration | @export_named_declaration; + +@namespace_definition = @namespace_declaration | @enum_declaration; +@type_definition = @class_definition | @interface_declaration | @enum_declaration | @type_alias_declaration | @enum_member; + +is_instantiated(unique int decl: @namespace_declaration ref); + +@declarable_node = @decl_stmt | @namespace_declaration | @class_decl_stmt | @function_decl_stmt | @enum_declaration | @external_module_declaration | @global_augmentation_declaration | @field; +has_declare_keyword(unique int stmt: @declarable_node ref); + +is_for_await_of(unique int forof: @for_of_stmt ref); + +// expressions +#keyset[parent, idx] +exprs (unique int id: @expr, + int kind: int ref, + int parent: @expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @expr_or_type ref); + +enclosing_stmt (unique int expr: @expr_or_type ref, + int stmt: @stmt ref); + +expr_containers (unique int expr: @expr_or_type ref, + int container: @stmt_container ref); + +array_size (unique int ae: @arraylike ref, + int sz: int ref); + +is_delegating (int yield: @yield_expr ref); + +@expr_or_stmt = @expr | @stmt; +@expr_or_type = @expr | @typeexpr; +@expr_parent = @expr_or_stmt | @property | @function_typeexpr; +@arraylike = @array_expr | @array_pattern; +@type_annotation = @typeexpr | @jsdoc_type_expr; +@node_in_stmt_container = @cfg_node | @type_annotation | @toplevel; + +case @expr.kind of + 0 = @label +| 1 = @null_literal +| 2 = @boolean_literal +| 3 = @number_literal +| 4 = @string_literal +| 5 = @regexp_literal +| 6 = @this_expr +| 7 = @array_expr +| 8 = @obj_expr +| 9 = @function_expr +| 10 = @seq_expr +| 11 = @conditional_expr +| 12 = @new_expr +| 13 = @call_expr +| 14 = @dot_expr +| 15 = @index_expr +| 16 = @neg_expr +| 17 = @plus_expr +| 18 = @log_not_expr +| 19 = @bit_not_expr +| 20 = @typeof_expr +| 21 = @void_expr +| 22 = @delete_expr +| 23 = @eq_expr +| 24 = @neq_expr +| 25 = @eqq_expr +| 26 = @neqq_expr +| 27 = @lt_expr +| 28 = @le_expr +| 29 = @gt_expr +| 30 = @ge_expr +| 31 = @lshift_expr +| 32 = @rshift_expr +| 33 = @urshift_expr +| 34 = @add_expr +| 35 = @sub_expr +| 36 = @mul_expr +| 37 = @div_expr +| 38 = @mod_expr +| 39 = @bitor_expr +| 40 = @xor_expr +| 41 = @bitand_expr +| 42 = @in_expr +| 43 = @instanceof_expr +| 44 = @logand_expr +| 45 = @logor_expr +| 47 = @assign_expr +| 48 = @assign_add_expr +| 49 = @assign_sub_expr +| 50 = @assign_mul_expr +| 51 = @assign_div_expr +| 52 = @assign_mod_expr +| 53 = @assign_lshift_expr +| 54 = @assign_rshift_expr +| 55 = @assign_urshift_expr +| 56 = @assign_or_expr +| 57 = @assign_xor_expr +| 58 = @assign_and_expr +| 59 = @preinc_expr +| 60 = @postinc_expr +| 61 = @predec_expr +| 62 = @postdec_expr +| 63 = @par_expr +| 64 = @var_declarator +| 65 = @arrow_function_expr +| 66 = @spread_element +| 67 = @array_pattern +| 68 = @object_pattern +| 69 = @yield_expr +| 70 = @tagged_template_expr +| 71 = @template_literal +| 72 = @template_element +| 73 = @array_comprehension_expr +| 74 = @generator_expr +| 75 = @for_in_comprehension_block +| 76 = @for_of_comprehension_block +| 77 = @legacy_letexpr +| 78 = @var_decl +| 79 = @proper_varaccess +| 80 = @class_expr +| 81 = @super_expr +| 82 = @newtarget_expr +| 83 = @named_import_specifier +| 84 = @import_default_specifier +| 85 = @import_namespace_specifier +| 86 = @named_export_specifier +| 87 = @exp_expr +| 88 = @assign_exp_expr +| 89 = @jsx_element +| 90 = @jsx_qualified_name +| 91 = @jsx_empty_expr +| 92 = @await_expr +| 93 = @function_sent_expr +| 94 = @decorator +| 95 = @export_default_specifier +| 96 = @export_namespace_specifier +| 97 = @bind_expr +| 98 = @external_module_reference +| 99 = @dynamic_import +| 100 = @expression_with_type_arguments +| 101 = @prefix_type_assertion +| 102 = @as_type_assertion +| 103 = @export_varaccess +| 104 = @decorator_list +| 105 = @non_null_assertion +| 106 = @bigint_literal +| 107 = @nullishcoalescing_expr +| 108 = @e4x_xml_anyname +| 109 = @e4x_xml_static_attribute_selector +| 110 = @e4x_xml_dynamic_attribute_selector +| 111 = @e4x_xml_filter_expression +| 112 = @e4x_xml_static_qualident +| 113 = @e4x_xml_dynamic_qualident +| 114 = @e4x_xml_dotdotexpr +| 115 = @import_meta_expr +| 116 = @assignlogandexpr +| 117 = @assignlogorexpr +| 118 = @assignnullishcoalescingexpr +| 119 = @template_pipe_ref +| 120 = @generated_code_expr +| 121 = @satisfies_expr +; + +@varaccess = @proper_varaccess | @export_varaccess; +@varref = @var_decl | @varaccess; + +@identifier = @label | @varref | @type_identifier; + +@literal = @null_literal | @boolean_literal | @number_literal | @string_literal | @regexp_literal | @bigint_literal; + +@propaccess = @dot_expr | @index_expr; + +@invokeexpr = @new_expr | @call_expr; + +@unaryexpr = @neg_expr | @plus_expr | @log_not_expr | @bit_not_expr | @typeof_expr | @void_expr | @delete_expr | @spread_element; + +@equality_test = @eq_expr | @neq_expr | @eqq_expr | @neqq_expr; + +@comparison = @equality_test | @lt_expr | @le_expr | @gt_expr | @ge_expr; + +@binaryexpr = @comparison | @lshift_expr | @rshift_expr | @urshift_expr | @add_expr | @sub_expr | @mul_expr | @div_expr | @mod_expr | @exp_expr | @bitor_expr | @xor_expr | @bitand_expr | @in_expr | @instanceof_expr | @logand_expr | @logor_expr | @nullishcoalescing_expr; + +@assignment = @assign_expr | @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr | @assign_mod_expr | @assign_exp_expr | @assign_lshift_expr | @assign_rshift_expr | @assign_urshift_expr | @assign_or_expr | @assign_xor_expr | @assign_and_expr | @assignlogandexpr | @assignlogorexpr | @assignnullishcoalescingexpr; + +@updateexpr = @preinc_expr | @postinc_expr | @predec_expr | @postdec_expr; + +@pattern = @varref | @array_pattern | @object_pattern; + +@comprehension_expr = @array_comprehension_expr | @generator_expr; + +@comprehension_block = @for_in_comprehension_block | @for_of_comprehension_block; + +@import_specifier = @named_import_specifier | @import_default_specifier | @import_namespace_specifier; + +@exportspecifier = @named_export_specifier | @export_default_specifier | @export_namespace_specifier; + +@type_keyword_operand = @import_declaration | @export_declaration | @import_specifier; + +@type_assertion = @as_type_assertion | @prefix_type_assertion; + +@class_definition = @class_decl_stmt | @class_expr; +@interface_definition = @interface_declaration | @interface_typeexpr; +@class_or_interface = @class_definition | @interface_definition; + +@lexical_decl = @var_decl | @type_decl; +@lexical_access = @varaccess | @local_type_access | @local_var_type_access | @local_namespace_access; +@lexical_ref = @lexical_decl | @lexical_access; + +@e4x_xml_attribute_selector = @e4x_xml_static_attribute_selector | @e4x_xml_dynamic_attribute_selector; +@e4x_xml_qualident = @e4x_xml_static_qualident | @e4x_xml_dynamic_qualident; + +expr_contains_template_tag_location( + int expr: @expr ref, + int location: @location ref +); + +@template_placeholder_tag_parent = @xmlelement | @xmlattribute | @file; + +template_placeholder_tag_info( + unique int node: @template_placeholder_tag, + int parentNode: @template_placeholder_tag_parent ref, + varchar(900) raw: string ref +); + +// scopes +scopes (unique int id: @scope, + int kind: int ref); + +case @scope.kind of + 0 = @global_scope +| 1 = @function_scope +| 2 = @catch_scope +| 3 = @module_scope +| 4 = @block_scope +| 5 = @for_scope +| 6 = @for_in_scope // for-of scopes work the same as for-in scopes +| 7 = @comprehension_block_scope +| 8 = @class_expr_scope +| 9 = @namespace_scope +| 10 = @class_decl_scope +| 11 = @interface_scope +| 12 = @type_alias_scope +| 13 = @mapped_type_scope +| 14 = @enum_scope +| 15 = @external_module_scope +| 16 = @conditional_type_scope; + +scopenodes (unique int node: @ast_node ref, + int scope: @scope ref); + +scopenesting (unique int inner: @scope ref, + int outer: @scope ref); + +// functions +@function = @function_decl_stmt | @function_expr | @arrow_function_expr; + +@parameterized = @function | @catch_clause; +@type_parameterized = @function | @class_or_interface | @type_alias_declaration | @mapped_typeexpr | @infer_typeexpr; + +is_generator (int fun: @function ref); +has_rest_parameter (int fun: @function ref); +is_async (int fun: @function ref); + +// variables and lexically scoped type names +#keyset[scope, name] +variables (unique int id: @variable, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_type_names (unique int id: @local_type_name, + varchar(900) name: string ref, + int scope: @scope ref); + +#keyset[scope, name] +local_namespace_names (unique int id: @local_namespace_name, + varchar(900) name: string ref, + int scope: @scope ref); + +is_arguments_object (int id: @variable ref); + +@lexical_name = @variable | @local_type_name | @local_namespace_name; + +@bind_id = @varaccess | @local_var_type_access; +bind (unique int id: @bind_id ref, + int decl: @variable ref); + +decl (unique int id: @var_decl ref, + int decl: @variable ref); + +@typebind_id = @local_type_access | @export_varaccess; +typebind (unique int id: @typebind_id ref, + int decl: @local_type_name ref); + +@typedecl_id = @type_decl | @var_decl; +typedecl (unique int id: @typedecl_id ref, + int decl: @local_type_name ref); + +namespacedecl (unique int id: @var_decl ref, + int decl: @local_namespace_name ref); + +@namespacebind_id = @local_namespace_access | @export_varaccess; +namespacebind (unique int id: @namespacebind_id ref, + int decl: @local_namespace_name ref); + + +// properties in object literals, property patterns in object patterns, and method declarations in classes +#keyset[parent, index] +properties (unique int id: @property, + int parent: @property_parent ref, + int index: int ref, + int kind: int ref, + varchar(900) tostring: string ref); + +case @property.kind of + 0 = @value_property +| 1 = @property_getter +| 2 = @property_setter +| 3 = @jsx_attribute +| 4 = @function_call_signature +| 5 = @constructor_call_signature +| 6 = @index_signature +| 7 = @enum_member +| 8 = @proper_field +| 9 = @parameter_field +| 10 = @static_initializer +; + +@property_parent = @obj_expr | @object_pattern | @class_definition | @jsx_element | @interface_definition | @enum_declaration; +@property_accessor = @property_getter | @property_setter; +@call_signature = @function_call_signature | @constructor_call_signature; +@field = @proper_field | @parameter_field; +@field_or_vardeclarator = @field | @var_declarator; + +is_computed (int id: @property ref); +is_method (int id: @property ref); +is_static (int id: @property ref); +is_abstract_member (int id: @property ref); +is_const_enum (int id: @enum_declaration ref); +is_abstract_class (int id: @class_decl_stmt ref); + +has_public_keyword (int id: @property ref); +has_private_keyword (int id: @property ref); +has_protected_keyword (int id: @property ref); +has_readonly_keyword (int id: @property ref); +has_type_keyword (int id: @type_keyword_operand ref); +is_optional_member (int id: @property ref); +has_definite_assignment_assertion (int id: @field_or_vardeclarator ref); +is_optional_parameter_declaration (unique int parameter: @pattern ref); + +#keyset[constructor, param_index] +parameter_fields( + unique int field: @parameter_field ref, + int constructor: @function_expr ref, + int param_index: int ref +); + +// types +#keyset[parent, idx] +typeexprs ( + unique int id: @typeexpr, + int kind: int ref, + int parent: @typeexpr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref +); + +case @typeexpr.kind of + 0 = @local_type_access +| 1 = @type_decl +| 2 = @keyword_typeexpr +| 3 = @string_literal_typeexpr +| 4 = @number_literal_typeexpr +| 5 = @boolean_literal_typeexpr +| 6 = @array_typeexpr +| 7 = @union_typeexpr +| 8 = @indexed_access_typeexpr +| 9 = @intersection_typeexpr +| 10 = @parenthesized_typeexpr +| 11 = @tuple_typeexpr +| 12 = @keyof_typeexpr +| 13 = @qualified_type_access +| 14 = @generic_typeexpr +| 15 = @type_label +| 16 = @typeof_typeexpr +| 17 = @local_var_type_access +| 18 = @qualified_var_type_access +| 19 = @this_var_type_access +| 20 = @predicate_typeexpr +| 21 = @interface_typeexpr +| 22 = @type_parameter +| 23 = @plain_function_typeexpr +| 24 = @constructor_typeexpr +| 25 = @local_namespace_access +| 26 = @qualified_namespace_access +| 27 = @mapped_typeexpr +| 28 = @conditional_typeexpr +| 29 = @infer_typeexpr +| 30 = @import_type_access +| 31 = @import_namespace_access +| 32 = @import_var_type_access +| 33 = @optional_typeexpr +| 34 = @rest_typeexpr +| 35 = @bigint_literal_typeexpr +| 36 = @readonly_typeexpr +| 37 = @template_literal_typeexpr +; + +@typeref = @typeaccess | @type_decl; +@type_identifier = @type_decl | @local_type_access | @type_label | @local_var_type_access | @local_namespace_access; +@typeexpr_parent = @expr | @stmt | @property | @typeexpr; +@literal_typeexpr = @string_literal_typeexpr | @number_literal_typeexpr | @boolean_literal_typeexpr | @bigint_literal_typeexpr; +@typeaccess = @local_type_access | @qualified_type_access | @import_type_access; +@vartypeaccess = @local_var_type_access | @qualified_var_type_access | @this_var_type_access | @import_var_type_access; +@namespace_access = @local_namespace_access | @qualified_namespace_access | @import_namespace_access; +@import_typeexpr = @import_type_access | @import_namespace_access | @import_var_type_access; + +@function_typeexpr = @plain_function_typeexpr | @constructor_typeexpr; + +// types +types ( + unique int id: @type, + int kind: int ref, + varchar(900) tostring: string ref +); + +#keyset[parent, idx] +type_child ( + int child: @type ref, + int parent: @type ref, + int idx: int ref +); + +case @type.kind of + 0 = @any_type +| 1 = @string_type +| 2 = @number_type +| 3 = @union_type +| 4 = @true_type +| 5 = @false_type +| 6 = @type_reference +| 7 = @object_type +| 8 = @canonical_type_variable_type +| 9 = @typeof_type +| 10 = @void_type +| 11 = @undefined_type +| 12 = @null_type +| 13 = @never_type +| 14 = @plain_symbol_type +| 15 = @unique_symbol_type +| 16 = @objectkeyword_type +| 17 = @intersection_type +| 18 = @tuple_type +| 19 = @lexical_type_variable_type +| 20 = @this_type +| 21 = @number_literal_type +| 22 = @string_literal_type +| 23 = @unknown_type +| 24 = @bigint_type +| 25 = @bigint_literal_type +; + +@boolean_literal_type = @true_type | @false_type; +@symbol_type = @plain_symbol_type | @unique_symbol_type; +@union_or_intersection_type = @union_type | @intersection_type; +@typevariable_type = @canonical_type_variable_type | @lexical_type_variable_type; + +has_asserts_keyword(int node: @predicate_typeexpr ref); + +@typed_ast_node = @expr | @typeexpr | @function; +ast_node_type( + unique int node: @typed_ast_node ref, + int typ: @type ref); + +declared_function_signature( + unique int node: @function ref, + int sig: @signature_type ref +); + +invoke_expr_signature( + unique int node: @invokeexpr ref, + int sig: @signature_type ref +); + +invoke_expr_overload_index( + unique int node: @invokeexpr ref, + int index: int ref +); + +symbols ( + unique int id: @symbol, + int kind: int ref, + varchar(900) name: string ref +); + +symbol_parent ( + unique int symbol: @symbol ref, + int parent: @symbol ref +); + +symbol_module ( + int symbol: @symbol ref, + varchar(900) moduleName: string ref +); + +symbol_global ( + int symbol: @symbol ref, + varchar(900) globalName: string ref +); + +case @symbol.kind of + 0 = @root_symbol +| 1 = @member_symbol +| 2 = @other_symbol +; + +@type_with_symbol = @type_reference | @typevariable_type | @typeof_type | @unique_symbol_type; +@ast_node_with_symbol = @type_definition | @namespace_definition | @toplevel | @typeaccess | @namespace_access | @var_decl | @function | @invokeexpr | @import_declaration | @external_module_reference | @external_module_declaration; + +ast_node_symbol( + unique int node: @ast_node_with_symbol ref, + int symbol: @symbol ref); + +type_symbol( + unique int typ: @type_with_symbol ref, + int symbol: @symbol ref); + +#keyset[typ, name] +type_property( + int typ: @type ref, + varchar(900) name: string ref, + int propertyType: @type ref); + +type_alias( + unique int aliasType: @type ref, + int underlyingType: @type ref); + +@literal_type = @string_literal_type | @number_literal_type | @boolean_literal_type | @bigint_literal_type; +@type_with_literal_value = @string_literal_type | @number_literal_type | @bigint_literal_type; +type_literal_value( + unique int typ: @type_with_literal_value ref, + varchar(900) value: string ref); + +signature_types ( + unique int id: @signature_type, + int kind: int ref, + varchar(900) tostring: string ref, + int type_parameters: int ref, + int required_params: int ref +); + +is_abstract_signature( + unique int sig: @signature_type ref +); + +signature_rest_parameter( + unique int sig: @signature_type ref, + int rest_param_arra_type: @type ref +); + +case @signature_type.kind of + 0 = @function_signature_type +| 1 = @constructor_signature_type +; + +#keyset[typ, kind, index] +type_contains_signature ( + int typ: @type ref, + int kind: int ref, // constructor/call/index + int index: int ref, // ordering of overloaded signatures + int sig: @signature_type ref +); + +#keyset[parent, index] +signature_contains_type ( + int child: @type ref, + int parent: @signature_type ref, + int index: int ref +); + +#keyset[sig, index] +signature_parameter_name ( + int sig: @signature_type ref, + int index: int ref, + varchar(900) name: string ref +); + +number_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +string_index_type ( + unique int baseType: @type ref, + int propertyType: @type ref +); + +base_type_names( + int typeName: @symbol ref, + int baseTypeName: @symbol ref +); + +self_types( + int typeName: @symbol ref, + int selfType: @type_reference ref +); + +tuple_type_min_length( + unique int typ: @type ref, + int minLength: int ref +); + +tuple_type_rest_index( + unique int typ: @type ref, + int index: int ref +); + +// comments +comments (unique int id: @comment, + int kind: int ref, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(900) tostring: string ref); + +case @comment.kind of + 0 = @slashslash_comment +| 1 = @slashstar_comment +| 2 = @doc_comment +| 3 = @html_comment_start +| 4 = @htmlcommentend; + +@html_comment = @html_comment_start | @htmlcommentend; +@line_comment = @slashslash_comment | @html_comment; +@block_comment = @slashstar_comment | @doc_comment; + +// source lines +lines (unique int id: @line, + int toplevel: @toplevel ref, + varchar(900) text: string ref, + varchar(2) terminator: string ref); +indentation (int file: @file ref, + int lineno: int ref, + varchar(1) indentChar: string ref, + int indentDepth: int ref); + +// JavaScript parse errors +js_parse_errors (unique int id: @js_parse_error, + int toplevel: @toplevel ref, + varchar(900) message: string ref, + varchar(900) line: string ref); + +// regular expressions +#keyset[parent, idx] +regexpterm (unique int id: @regexpterm, + int kind: int ref, + int parent: @regexpparent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +@regexpparent = @regexpterm | @regexp_literal | @string_literal | @add_expr; + +case @regexpterm.kind of + 0 = @regexp_alt +| 1 = @regexp_seq +| 2 = @regexp_caret +| 3 = @regexp_dollar +| 4 = @regexp_wordboundary +| 5 = @regexp_nonwordboundary +| 6 = @regexp_positive_lookahead +| 7 = @regexp_negative_lookahead +| 8 = @regexp_star +| 9 = @regexp_plus +| 10 = @regexp_opt +| 11 = @regexp_range +| 12 = @regexp_dot +| 13 = @regexp_group +| 14 = @regexp_normal_constant +| 15 = @regexp_hex_escape +| 16 = @regexp_unicode_escape +| 17 = @regexp_dec_escape +| 18 = @regexp_oct_escape +| 19 = @regexp_ctrl_escape +| 20 = @regexp_char_class_escape +| 21 = @regexp_id_escape +| 22 = @regexp_backref +| 23 = @regexp_char_class +| 24 = @regexp_char_range +| 25 = @regexp_positive_lookbehind +| 26 = @regexp_negative_lookbehind +| 27 = @regexp_unicode_property_escape; + +regexp_parse_errors (unique int id: @regexp_parse_error, + int regexp: @regexpterm ref, + varchar(900) message: string ref); + +@regexp_quantifier = @regexp_star | @regexp_plus | @regexp_opt | @regexp_range; +@regexp_escape = @regexp_char_escape | @regexp_char_class_escape | @regexp_unicode_property_escape; +@regexp_char_escape = @regexp_hex_escape | @regexp_unicode_escape | @regexp_dec_escape | @regexp_oct_escape | @regexp_ctrl_escape | @regexp_id_escape; +@regexp_constant = @regexp_normal_constant | @regexp_char_escape; +@regexp_lookahead = @regexp_positive_lookahead | @regexp_negative_lookahead; +@regexp_lookbehind = @regexp_positive_lookbehind | @regexp_negative_lookbehind; +@regexp_subpattern = @regexp_lookahead | @regexp_lookbehind; +@regexp_anchor = @regexp_dollar | @regexp_caret; + +is_greedy (int id: @regexp_quantifier ref); +range_quantifier_lower_bound (unique int id: @regexp_range ref, int lo: int ref); +range_quantifier_upper_bound (unique int id: @regexp_range ref, int hi: int ref); +is_capture (unique int id: @regexp_group ref, int number: int ref); +is_named_capture (unique int id: @regexp_group ref, string name: string ref); +is_inverted (int id: @regexp_char_class ref); +regexp_const_value (unique int id: @regexp_constant ref, varchar(1) value: string ref); +char_class_escape (unique int id: @regexp_char_class_escape ref, varchar(1) value: string ref); +backref (unique int id: @regexp_backref ref, int value: int ref); +named_backref (unique int id: @regexp_backref ref, string name: string ref); +unicode_property_escapename (unique int id: @regexp_unicode_property_escape ref, string name: string ref); +unicode_property_escapevalue (unique int id: @regexp_unicode_property_escape ref, string value: string ref); + +// tokens +#keyset[toplevel, idx] +tokeninfo (unique int id: @token, + int kind: int ref, + int toplevel: @toplevel ref, + int idx: int ref, + varchar(900) value: string ref); + +case @token.kind of + 0 = @token_eof +| 1 = @token_null_literal +| 2 = @token_boolean_literal +| 3 = @token_numeric_literal +| 4 = @token_string_literal +| 5 = @token_regular_expression +| 6 = @token_identifier +| 7 = @token_keyword +| 8 = @token_punctuator; + +// associate comments with the token immediately following them (which may be EOF) +next_token (int comment: @comment ref, int token: @token ref); + +// JSON +#keyset[parent, idx] +json (unique int id: @json_value, + int kind: int ref, + int parent: @json_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); + +json_literals (varchar(900) value: string ref, + varchar(900) raw: string ref, + unique int expr: @json_value ref); + +json_properties (int obj: @json_object ref, + varchar(900) property: string ref, + int value: @json_value ref); + +json_errors (unique int id: @json_parse_error, + varchar(900) message: string ref); + +json_locations(unique int locatable: @json_locatable ref, + int location: @location_default ref); + +case @json_value.kind of + 0 = @json_null +| 1 = @json_boolean +| 2 = @json_number +| 3 = @json_string +| 4 = @json_array +| 5 = @json_object; + +@json_parent = @json_object | @json_array | @file; + +@json_locatable = @json_value | @json_parse_error; + +// locations +@ast_node = @toplevel | @stmt | @expr | @property | @typeexpr; + +@locatable = @file + | @ast_node + | @comment + | @line + | @js_parse_error | @regexp_parse_error + | @regexpterm + | @json_locatable + | @token + | @cfg_node + | @jsdoc | @jsdoc_type_expr | @jsdoc_tag + | @yaml_locatable + | @xmllocatable + | @configLocatable + | @template_placeholder_tag; + +hasLocation (unique int locatable: @locatable ref, + int location: @location ref); + +// CFG +entry_cfg_node (unique int id: @entry_node, int container: @stmt_container ref); +exit_cfg_node (unique int id: @exit_node, int container: @stmt_container ref); +guard_node (unique int id: @guard_node, int kind: int ref, int test: @expr ref); +case @guard_node.kind of + 0 = @falsy_guard +| 1 = @truthy_guard; +@condition_guard = @falsy_guard | @truthy_guard; + +@synthetic_cfg_node = @entry_node | @exit_node | @guard_node; +@cfg_node = @synthetic_cfg_node | @expr_parent; + +successor (int pred: @cfg_node ref, int succ: @cfg_node ref); + +// JSDoc comments +jsdoc (unique int id: @jsdoc, varchar(900) description: string ref, int comment: @comment ref); +#keyset[parent, idx] +jsdoc_tags (unique int id: @jsdoc_tag, varchar(900) title: string ref, + int parent: @jsdoc ref, int idx: int ref, varchar(900) tostring: string ref); +jsdoc_tag_descriptions (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); +jsdoc_tag_names (unique int tag: @jsdoc_tag ref, varchar(900) text: string ref); + +#keyset[parent, idx] +jsdoc_type_exprs (unique int id: @jsdoc_type_expr, + int kind: int ref, + int parent: @jsdoc_type_expr_parent ref, + int idx: int ref, + varchar(900) tostring: string ref); +case @jsdoc_type_expr.kind of + 0 = @jsdoc_any_type_expr +| 1 = @jsdoc_null_type_expr +| 2 = @jsdoc_undefined_type_expr +| 3 = @jsdoc_unknown_type_expr +| 4 = @jsdoc_void_type_expr +| 5 = @jsdoc_named_type_expr +| 6 = @jsdoc_applied_type_expr +| 7 = @jsdoc_nullable_type_expr +| 8 = @jsdoc_non_nullable_type_expr +| 9 = @jsdoc_record_type_expr +| 10 = @jsdoc_array_type_expr +| 11 = @jsdoc_union_type_expr +| 12 = @jsdoc_function_type_expr +| 13 = @jsdoc_optional_type_expr +| 14 = @jsdoc_rest_type_expr +; + +#keyset[id, idx] +jsdoc_record_field_name (int id: @jsdoc_record_type_expr ref, int idx: int ref, varchar(900) name: string ref); +jsdoc_prefix_qualifier (int id: @jsdoc_type_expr ref); +jsdoc_has_new_parameter (int fn: @jsdoc_function_type_expr ref); + +@jsdoc_type_expr_parent = @jsdoc_type_expr | @jsdoc_tag; + +jsdoc_errors (unique int id: @jsdoc_error, int tag: @jsdoc_tag ref, varchar(900) message: string ref, varchar(900) tostring: string ref); + +@dataflownode = @expr | @function_decl_stmt | @class_decl_stmt | @namespace_declaration | @enum_declaration | @property; + +@optionalchainable = @call_expr | @propaccess; + +isOptionalChaining(int id: @optionalchainable ref); + +/** + * The time taken for the extraction of a file. + * This table contains non-deterministic content. + * + * The sum of the `time` column for each (`file`, `timerKind`) pair + * is the total time taken for extraction of `file`. The `extractionPhase` + * column provides a granular view of the extraction time of the file. + */ +extraction_time( + int file : @file ref, + // see `com.semmle.js.extractor.ExtractionMetrics.ExtractionPhase`. + int extractionPhase: int ref, + // 0 for the elapsed CPU time in nanoseconds, 1 for the elapsed wallclock time in nanoseconds + int timerKind: int ref, + float time: float ref +) + +/** +* Non-timing related data for the extraction of a single file. +* This table contains non-deterministic content. +*/ +extraction_data( + int file : @file ref, + // the absolute path to the cache file + varchar(900) cacheFile: string ref, + boolean fromCache: boolean ref, + int length: int ref +) + +/*- YAML -*/ + +#keyset[parent, idx] +yaml (unique int id: @yaml_node, + int kind: int ref, + int parent: @yaml_node_parent ref, + int idx: int ref, + string tag: string ref, + string tostring: string ref); + +case @yaml_node.kind of + 0 = @yaml_scalar_node +| 1 = @yaml_mapping_node +| 2 = @yaml_sequence_node +| 3 = @yaml_alias_node +; + +@yaml_collection_node = @yaml_mapping_node | @yaml_sequence_node; + +@yaml_node_parent = @yaml_collection_node | @file; + +yaml_anchors (unique int node: @yaml_node ref, + string anchor: string ref); + +yaml_aliases (unique int alias: @yaml_alias_node ref, + string target: string ref); + +yaml_scalars (unique int scalar: @yaml_scalar_node ref, + int style: int ref, + string value: string ref); + +yaml_errors (unique int id: @yaml_error, + string message: string ref); + +yaml_locations(unique int locatable: @yaml_locatable ref, + int location: @location_default ref); + +@yaml_locatable = @yaml_node | @yaml_error; + +/*- 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; diff --git a/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/upgrade.properties b/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/upgrade.properties new file mode 100644 index 00000000000..2937b1f0cc2 --- /dev/null +++ b/javascript/ql/lib/upgrades/8accf0f930bcb8b42d69fd7ef7b4372604f551ed/upgrade.properties @@ -0,0 +1,2 @@ +description: add support for TypeScript 5.2 +compatibility: backwards diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index d77e565ad90..3cf78549f64 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,14 @@ +## 0.7.4 + +### Minor Analysis Improvements + +* Files larger than 10 MB are no longer be extracted or analyzed. +* Imports can now be resolved in more cases, where a non-constant string expression is passed to a `require()` call. + +### Bug Fixes + +* Fixed an extractor crash that would occur in rare cases when a TypeScript file contains a self-referential namespace alias. + ## 0.7.3 No user-facing changes. diff --git a/javascript/ql/src/Declarations/AssignmentToConst.ql b/javascript/ql/src/Declarations/AssignmentToConst.ql index e9efb03fd83..f2a24832c6a 100644 --- a/javascript/ql/src/Declarations/AssignmentToConst.ql +++ b/javascript/ql/src/Declarations/AssignmentToConst.ql @@ -13,8 +13,9 @@ import javascript import semmle.javascript.RestrictedLocations -from ConstDeclStmt cds, VariableDeclarator decl, VarDef def, Variable v +from DeclStmt cds, VariableDeclarator decl, VarDef def, Variable v where + (cds instanceof ConstDeclStmt or cds instanceof UsingDeclStmt) and decl = cds.getADecl() and def.getAVariable() = v and decl.getBindingPattern().getAVariable() = v and diff --git a/javascript/ql/src/Statements/UselessConditional.ql b/javascript/ql/src/Statements/UselessConditional.ql index 600fff5fb1c..cc70defa7b2 100644 --- a/javascript/ql/src/Statements/UselessConditional.ql +++ b/javascript/ql/src/Statements/UselessConditional.ql @@ -39,6 +39,8 @@ predicate isSymbolicConstant(Variable v) { exists(VarDef vd | vd = getSingleDef(v) | vd.(VariableDeclarator).getDeclStmt() instanceof ConstDeclStmt or + vd.(VariableDeclarator).getDeclStmt() instanceof UsingDeclStmt + or isConstant(vd.getSource()) ) } diff --git a/javascript/ql/src/change-notes/2023-08-23-fix-cyclic-alias-extraction.md b/javascript/ql/src/change-notes/2023-08-23-fix-cyclic-alias-extraction.md deleted file mode 100644 index 66769f2b8fa..00000000000 --- a/javascript/ql/src/change-notes/2023-08-23-fix-cyclic-alias-extraction.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: fix ---- -* Fixed an extractor crash that would occur in rare cases when a TypeScript file contains a self-referential namespace alias. diff --git a/javascript/ql/src/change-notes/2023-08-23-ignore-huge-files.md b/javascript/ql/src/change-notes/2023-08-23-ignore-huge-files.md deleted file mode 100644 index fc82b3b5a3f..00000000000 --- a/javascript/ql/src/change-notes/2023-08-23-ignore-huge-files.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Files larger than 10 MB are no longer be extracted or analyzed. diff --git a/javascript/ql/src/change-notes/2023-08-23-import-path-string.md b/javascript/ql/src/change-notes/2023-08-23-import-path-string.md deleted file mode 100644 index 64a70c1fe10..00000000000 --- a/javascript/ql/src/change-notes/2023-08-23-import-path-string.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Imports can now be resolved in more cases, where a non-constant string expression is passed to a `require()` call. diff --git a/javascript/ql/src/change-notes/2023-09-08-tolerate-out-of-order-requests.md b/javascript/ql/src/change-notes/2023-09-08-tolerate-out-of-order-requests.md new file mode 100644 index 00000000000..e6104889ba6 --- /dev/null +++ b/javascript/ql/src/change-notes/2023-09-08-tolerate-out-of-order-requests.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed an extractor crash that could occur in projects containing TypeScript files larger than 10 MB. diff --git a/javascript/ql/src/change-notes/released/0.7.4.md b/javascript/ql/src/change-notes/released/0.7.4.md new file mode 100644 index 00000000000..55118b12535 --- /dev/null +++ b/javascript/ql/src/change-notes/released/0.7.4.md @@ -0,0 +1,10 @@ +## 0.7.4 + +### Minor Analysis Improvements + +* Files larger than 10 MB are no longer be extracted or analyzed. +* Imports can now be resolved in more cases, where a non-constant string expression is passed to a `require()` call. + +### Bug Fixes + +* Fixed an extractor crash that would occur in rare cases when a TypeScript file contains a self-referential namespace alias. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index a4ea9c8de17..e388f34b4ec 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.3 +lastReleaseVersion: 0.7.4 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 04ee9ae6135..343d34fce46 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 0.7.4-dev +version: 0.7.4 groups: - javascript - queries diff --git a/javascript/ql/test/library-tests/AST/ExplicitResource/printAst.expected b/javascript/ql/test/library-tests/AST/ExplicitResource/printAst.expected new file mode 100644 index 00000000000..48ecc28df26 --- /dev/null +++ b/javascript/ql/test/library-tests/AST/ExplicitResource/printAst.expected @@ -0,0 +1,193 @@ +nodes +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| tst.js:1:1:10:1 | [FunctionDeclStmt] functio ... } } | semmle.label | [FunctionDeclStmt] functio ... } } | +| tst.js:1:1:10:1 | [FunctionDeclStmt] functio ... } } | semmle.order | 1 | +| tst.js:1:10:1:10 | [VarDecl] g | semmle.label | [VarDecl] g | +| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | semmle.label | [BlockStmt] { u ... } } | +| tst.js:2:5:2:33 | [DeclStmt] using stream = ... | semmle.label | [DeclStmt] using stream = ... | +| tst.js:2:11:2:16 | [VarDecl] stream | semmle.label | [VarDecl] stream | +| tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | semmle.label | [VariableDeclarator] stream ... ource() | +| tst.js:2:20:2:30 | [VarRef] getResource | semmle.label | [VarRef] getResource | +| tst.js:2:20:2:32 | [CallExpr] getResource() | semmle.label | [CallExpr] getResource() | +| tst.js:4:5:4:7 | [VarRef] let | semmle.label | [VarRef] let | +| tst.js:4:5:4:19 | [CallExpr] let (test = 20) | semmle.label | [CallExpr] let (test = 20) | +| tst.js:4:5:4:20 | [ExprStmt] let (test = 20); | semmle.label | [ExprStmt] let (test = 20); | +| tst.js:4:10:4:13 | [VarRef] test | semmle.label | [VarRef] test | +| tst.js:4:10:4:18 | [AssignExpr] test = 20 | semmle.label | [AssignExpr] test = 20 | +| tst.js:4:17:4:18 | [Literal] 20 | semmle.label | [Literal] 20 | +| tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | semmle.label | [ForStmt] for (us ... ; } | +| tst.js:6:10:6:38 | [DeclStmt] using stream2 = ... | semmle.label | [DeclStmt] using stream2 = ... | +| tst.js:6:16:6:22 | [VarDecl] stream2 | semmle.label | [VarDecl] stream2 | +| tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | semmle.label | [VariableDeclarator] stream2 ... ource() | +| tst.js:6:26:6:36 | [VarRef] getResource | semmle.label | [VarRef] getResource | +| tst.js:6:26:6:38 | [CallExpr] getResource() | semmle.label | [CallExpr] getResource() | +| tst.js:6:45:9:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } | +| tst.js:8:9:8:14 | [BreakStmt] break; | semmle.label | [BreakStmt] break; | +| tst.js:12:1:21:1 | [FunctionDeclStmt] async f ... nd"); } | semmle.label | [FunctionDeclStmt] async f ... nd"); } | +| tst.js:12:1:21:1 | [FunctionDeclStmt] async f ... nd"); } | semmle.order | 2 | +| tst.js:12:16:12:16 | [VarDecl] h | semmle.label | [VarDecl] h | +| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | semmle.label | [BlockStmt] { a ... nd"); } | +| tst.js:13:5:13:39 | [DeclStmt] using stream = ... | semmle.label | [DeclStmt] using stream = ... | +| tst.js:13:17:13:22 | [VarDecl] stream | semmle.label | [VarDecl] stream | +| tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | semmle.label | [VariableDeclarator] stream ... ource() | +| tst.js:13:26:13:36 | [VarRef] getResource | semmle.label | [VarRef] getResource | +| tst.js:13:26:13:38 | [CallExpr] getResource() | semmle.label | [CallExpr] getResource() | +| tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | semmle.label | [ForStmt] for (aw ... ; } | +| tst.js:15:16:15:44 | [DeclStmt] using stream2 = ... | semmle.label | [DeclStmt] using stream2 = ... | +| tst.js:15:22:15:28 | [VarDecl] stream2 | semmle.label | [VarDecl] stream2 | +| tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | semmle.label | [VariableDeclarator] stream2 ... ource() | +| tst.js:15:32:15:42 | [VarRef] getResource | semmle.label | [VarRef] getResource | +| tst.js:15:32:15:44 | [CallExpr] getResource() | semmle.label | [CallExpr] getResource() | +| tst.js:15:51:18:5 | [BlockStmt] { ... ; } | semmle.label | [BlockStmt] { ... ; } | +| tst.js:17:9:17:14 | [BreakStmt] break; | semmle.label | [BreakStmt] break; | +| tst.js:20:5:20:11 | [VarRef] console | semmle.label | [VarRef] console | +| tst.js:20:5:20:15 | [DotExpr] console.log | semmle.label | [DotExpr] console.log | +| tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | semmle.label | [MethodCallExpr] console.log("end") | +| tst.js:20:5:20:23 | [ExprStmt] console.log("end"); | semmle.label | [ExprStmt] console.log("end"); | +| tst.js:20:13:20:15 | [Label] log | semmle.label | [Label] log | +| tst.js:20:17:20:21 | [Literal] "end" | semmle.label | [Literal] "end" | +| tst.js:23:1:29:1 | [FunctionDeclStmt] functio ... ing); } | semmle.label | [FunctionDeclStmt] functio ... ing); } | +| tst.js:23:1:29:1 | [FunctionDeclStmt] functio ... ing); } | semmle.order | 3 | +| tst.js:23:10:23:18 | [VarDecl] usesUsing | semmle.label | [VarDecl] usesUsing | +| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | semmle.label | [BlockStmt] { u ... ing); } | +| tst.js:24:5:24:9 | [VarRef] using | semmle.label | [VarRef] using | +| tst.js:24:5:24:16 | [CallExpr] using("foo") | semmle.label | [CallExpr] using("foo") | +| tst.js:24:5:24:17 | [ExprStmt] using("foo"); | semmle.label | [ExprStmt] using("foo"); | +| tst.js:24:11:24:15 | [Literal] "foo" | semmle.label | [Literal] "foo" | +| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | semmle.label | [FunctionDeclStmt] functio ... . } | +| tst.js:25:14:25:18 | [VarDecl] using | semmle.label | [VarDecl] using | +| tst.js:25:20:25:22 | [SimpleParameter] foo | semmle.label | [SimpleParameter] foo | +| tst.js:25:25:27:5 | [BlockStmt] { ... . } | semmle.label | [BlockStmt] { ... . } | +| tst.js:28:5:28:9 | [VarRef] using | semmle.label | [VarRef] using | +| tst.js:28:5:28:16 | [CallExpr] using(using) | semmle.label | [CallExpr] using(using) | +| tst.js:28:5:28:17 | [ExprStmt] using(using); | semmle.label | [ExprStmt] using(using); | +| tst.js:28:11:28:15 | [VarRef] using | semmle.label | [VarRef] using | +edges +| file://:0:0:0:0 | (Arguments) | tst.js:4:10:4:18 | [AssignExpr] test = 20 | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | tst.js:4:10:4:18 | [AssignExpr] test = 20 | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | tst.js:20:17:20:21 | [Literal] "end" | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | tst.js:20:17:20:21 | [Literal] "end" | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | tst.js:24:11:24:15 | [Literal] "foo" | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | tst.js:24:11:24:15 | [Literal] "foo" | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | tst.js:28:11:28:15 | [VarRef] using | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | tst.js:28:11:28:15 | [VarRef] using | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tst.js:25:20:25:22 | [SimpleParameter] foo | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tst.js:25:20:25:22 | [SimpleParameter] foo | semmle.order | 0 | +| tst.js:1:1:10:1 | [FunctionDeclStmt] functio ... } } | tst.js:1:10:1:10 | [VarDecl] g | semmle.label | 0 | +| tst.js:1:1:10:1 | [FunctionDeclStmt] functio ... } } | tst.js:1:10:1:10 | [VarDecl] g | semmle.order | 0 | +| tst.js:1:1:10:1 | [FunctionDeclStmt] functio ... } } | tst.js:1:14:10:1 | [BlockStmt] { u ... } } | semmle.label | 5 | +| tst.js:1:1:10:1 | [FunctionDeclStmt] functio ... } } | tst.js:1:14:10:1 | [BlockStmt] { u ... } } | semmle.order | 5 | +| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | tst.js:2:5:2:33 | [DeclStmt] using stream = ... | semmle.label | 1 | +| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | tst.js:2:5:2:33 | [DeclStmt] using stream = ... | semmle.order | 1 | +| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | tst.js:4:5:4:20 | [ExprStmt] let (test = 20); | semmle.label | 2 | +| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | tst.js:4:5:4:20 | [ExprStmt] let (test = 20); | semmle.order | 2 | +| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | semmle.label | 3 | +| tst.js:1:14:10:1 | [BlockStmt] { u ... } } | tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | semmle.order | 3 | +| tst.js:2:5:2:33 | [DeclStmt] using stream = ... | tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | semmle.label | 1 | +| tst.js:2:5:2:33 | [DeclStmt] using stream = ... | tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | semmle.order | 1 | +| tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | tst.js:2:11:2:16 | [VarDecl] stream | semmle.label | 1 | +| tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | tst.js:2:11:2:16 | [VarDecl] stream | semmle.order | 1 | +| tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | tst.js:2:20:2:32 | [CallExpr] getResource() | semmle.label | 2 | +| tst.js:2:11:2:32 | [VariableDeclarator] stream ... ource() | tst.js:2:20:2:32 | [CallExpr] getResource() | semmle.order | 2 | +| tst.js:2:20:2:32 | [CallExpr] getResource() | tst.js:2:20:2:30 | [VarRef] getResource | semmle.label | 0 | +| tst.js:2:20:2:32 | [CallExpr] getResource() | tst.js:2:20:2:30 | [VarRef] getResource | semmle.order | 0 | +| tst.js:4:5:4:19 | [CallExpr] let (test = 20) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| tst.js:4:5:4:19 | [CallExpr] let (test = 20) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| tst.js:4:5:4:19 | [CallExpr] let (test = 20) | tst.js:4:5:4:7 | [VarRef] let | semmle.label | 0 | +| tst.js:4:5:4:19 | [CallExpr] let (test = 20) | tst.js:4:5:4:7 | [VarRef] let | semmle.order | 0 | +| tst.js:4:5:4:20 | [ExprStmt] let (test = 20); | tst.js:4:5:4:19 | [CallExpr] let (test = 20) | semmle.label | 1 | +| tst.js:4:5:4:20 | [ExprStmt] let (test = 20); | tst.js:4:5:4:19 | [CallExpr] let (test = 20) | semmle.order | 1 | +| tst.js:4:10:4:18 | [AssignExpr] test = 20 | tst.js:4:10:4:13 | [VarRef] test | semmle.label | 1 | +| tst.js:4:10:4:18 | [AssignExpr] test = 20 | tst.js:4:10:4:13 | [VarRef] test | semmle.order | 1 | +| tst.js:4:10:4:18 | [AssignExpr] test = 20 | tst.js:4:17:4:18 | [Literal] 20 | semmle.label | 2 | +| tst.js:4:10:4:18 | [AssignExpr] test = 20 | tst.js:4:17:4:18 | [Literal] 20 | semmle.order | 2 | +| tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | tst.js:6:10:6:38 | [DeclStmt] using stream2 = ... | semmle.label | 1 | +| tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | tst.js:6:10:6:38 | [DeclStmt] using stream2 = ... | semmle.order | 1 | +| tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | tst.js:6:45:9:5 | [BlockStmt] { ... ; } | semmle.label | 2 | +| tst.js:6:5:9:5 | [ForStmt] for (us ... ; } | tst.js:6:45:9:5 | [BlockStmt] { ... ; } | semmle.order | 2 | +| tst.js:6:10:6:38 | [DeclStmt] using stream2 = ... | tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | semmle.label | 1 | +| tst.js:6:10:6:38 | [DeclStmt] using stream2 = ... | tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | semmle.order | 1 | +| tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | tst.js:6:16:6:22 | [VarDecl] stream2 | semmle.label | 1 | +| tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | tst.js:6:16:6:22 | [VarDecl] stream2 | semmle.order | 1 | +| tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | tst.js:6:26:6:38 | [CallExpr] getResource() | semmle.label | 2 | +| tst.js:6:16:6:38 | [VariableDeclarator] stream2 ... ource() | tst.js:6:26:6:38 | [CallExpr] getResource() | semmle.order | 2 | +| tst.js:6:26:6:38 | [CallExpr] getResource() | tst.js:6:26:6:36 | [VarRef] getResource | semmle.label | 0 | +| tst.js:6:26:6:38 | [CallExpr] getResource() | tst.js:6:26:6:36 | [VarRef] getResource | semmle.order | 0 | +| tst.js:6:45:9:5 | [BlockStmt] { ... ; } | tst.js:8:9:8:14 | [BreakStmt] break; | semmle.label | 1 | +| tst.js:6:45:9:5 | [BlockStmt] { ... ; } | tst.js:8:9:8:14 | [BreakStmt] break; | semmle.order | 1 | +| tst.js:12:1:21:1 | [FunctionDeclStmt] async f ... nd"); } | tst.js:12:16:12:16 | [VarDecl] h | semmle.label | 0 | +| tst.js:12:1:21:1 | [FunctionDeclStmt] async f ... nd"); } | tst.js:12:16:12:16 | [VarDecl] h | semmle.order | 0 | +| tst.js:12:1:21:1 | [FunctionDeclStmt] async f ... nd"); } | tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | semmle.label | 5 | +| tst.js:12:1:21:1 | [FunctionDeclStmt] async f ... nd"); } | tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | semmle.order | 5 | +| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | tst.js:13:5:13:39 | [DeclStmt] using stream = ... | semmle.label | 1 | +| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | tst.js:13:5:13:39 | [DeclStmt] using stream = ... | semmle.order | 1 | +| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | semmle.label | 2 | +| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | semmle.order | 2 | +| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | tst.js:20:5:20:23 | [ExprStmt] console.log("end"); | semmle.label | 3 | +| tst.js:12:20:21:1 | [BlockStmt] { a ... nd"); } | tst.js:20:5:20:23 | [ExprStmt] console.log("end"); | semmle.order | 3 | +| tst.js:13:5:13:39 | [DeclStmt] using stream = ... | tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | semmle.label | 1 | +| tst.js:13:5:13:39 | [DeclStmt] using stream = ... | tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | semmle.order | 1 | +| tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | tst.js:13:17:13:22 | [VarDecl] stream | semmle.label | 1 | +| tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | tst.js:13:17:13:22 | [VarDecl] stream | semmle.order | 1 | +| tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | tst.js:13:26:13:38 | [CallExpr] getResource() | semmle.label | 2 | +| tst.js:13:17:13:38 | [VariableDeclarator] stream ... ource() | tst.js:13:26:13:38 | [CallExpr] getResource() | semmle.order | 2 | +| tst.js:13:26:13:38 | [CallExpr] getResource() | tst.js:13:26:13:36 | [VarRef] getResource | semmle.label | 0 | +| tst.js:13:26:13:38 | [CallExpr] getResource() | tst.js:13:26:13:36 | [VarRef] getResource | semmle.order | 0 | +| tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | tst.js:15:16:15:44 | [DeclStmt] using stream2 = ... | semmle.label | 1 | +| tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | tst.js:15:16:15:44 | [DeclStmt] using stream2 = ... | semmle.order | 1 | +| tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | tst.js:15:51:18:5 | [BlockStmt] { ... ; } | semmle.label | 2 | +| tst.js:15:5:18:5 | [ForStmt] for (aw ... ; } | tst.js:15:51:18:5 | [BlockStmt] { ... ; } | semmle.order | 2 | +| tst.js:15:16:15:44 | [DeclStmt] using stream2 = ... | tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | semmle.label | 1 | +| tst.js:15:16:15:44 | [DeclStmt] using stream2 = ... | tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | semmle.order | 1 | +| tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | tst.js:15:22:15:28 | [VarDecl] stream2 | semmle.label | 1 | +| tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | tst.js:15:22:15:28 | [VarDecl] stream2 | semmle.order | 1 | +| tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | tst.js:15:32:15:44 | [CallExpr] getResource() | semmle.label | 2 | +| tst.js:15:22:15:44 | [VariableDeclarator] stream2 ... ource() | tst.js:15:32:15:44 | [CallExpr] getResource() | semmle.order | 2 | +| tst.js:15:32:15:44 | [CallExpr] getResource() | tst.js:15:32:15:42 | [VarRef] getResource | semmle.label | 0 | +| tst.js:15:32:15:44 | [CallExpr] getResource() | tst.js:15:32:15:42 | [VarRef] getResource | semmle.order | 0 | +| tst.js:15:51:18:5 | [BlockStmt] { ... ; } | tst.js:17:9:17:14 | [BreakStmt] break; | semmle.label | 1 | +| tst.js:15:51:18:5 | [BlockStmt] { ... ; } | tst.js:17:9:17:14 | [BreakStmt] break; | semmle.order | 1 | +| tst.js:20:5:20:15 | [DotExpr] console.log | tst.js:20:5:20:11 | [VarRef] console | semmle.label | 1 | +| tst.js:20:5:20:15 | [DotExpr] console.log | tst.js:20:5:20:11 | [VarRef] console | semmle.order | 1 | +| tst.js:20:5:20:15 | [DotExpr] console.log | tst.js:20:13:20:15 | [Label] log | semmle.label | 2 | +| tst.js:20:5:20:15 | [DotExpr] console.log | tst.js:20:13:20:15 | [Label] log | semmle.order | 2 | +| tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | tst.js:20:5:20:15 | [DotExpr] console.log | semmle.label | 0 | +| tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | tst.js:20:5:20:15 | [DotExpr] console.log | semmle.order | 0 | +| tst.js:20:5:20:23 | [ExprStmt] console.log("end"); | tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | semmle.label | 1 | +| tst.js:20:5:20:23 | [ExprStmt] console.log("end"); | tst.js:20:5:20:22 | [MethodCallExpr] console.log("end") | semmle.order | 1 | +| tst.js:23:1:29:1 | [FunctionDeclStmt] functio ... ing); } | tst.js:23:10:23:18 | [VarDecl] usesUsing | semmle.label | 0 | +| tst.js:23:1:29:1 | [FunctionDeclStmt] functio ... ing); } | tst.js:23:10:23:18 | [VarDecl] usesUsing | semmle.order | 0 | +| tst.js:23:1:29:1 | [FunctionDeclStmt] functio ... ing); } | tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | semmle.label | 5 | +| tst.js:23:1:29:1 | [FunctionDeclStmt] functio ... ing); } | tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | semmle.order | 5 | +| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | tst.js:24:5:24:17 | [ExprStmt] using("foo"); | semmle.label | 1 | +| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | tst.js:24:5:24:17 | [ExprStmt] using("foo"); | semmle.order | 1 | +| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | semmle.label | 2 | +| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | semmle.order | 2 | +| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | tst.js:28:5:28:17 | [ExprStmt] using(using); | semmle.label | 3 | +| tst.js:23:22:29:1 | [BlockStmt] { u ... ing); } | tst.js:28:5:28:17 | [ExprStmt] using(using); | semmle.order | 3 | +| tst.js:24:5:24:16 | [CallExpr] using("foo") | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| tst.js:24:5:24:16 | [CallExpr] using("foo") | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| tst.js:24:5:24:16 | [CallExpr] using("foo") | tst.js:24:5:24:9 | [VarRef] using | semmle.label | 0 | +| tst.js:24:5:24:16 | [CallExpr] using("foo") | tst.js:24:5:24:9 | [VarRef] using | semmle.order | 0 | +| tst.js:24:5:24:17 | [ExprStmt] using("foo"); | tst.js:24:5:24:16 | [CallExpr] using("foo") | semmle.label | 1 | +| tst.js:24:5:24:17 | [ExprStmt] using("foo"); | tst.js:24:5:24:16 | [CallExpr] using("foo") | semmle.order | 1 | +| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | tst.js:25:14:25:18 | [VarDecl] using | semmle.label | 0 | +| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | tst.js:25:14:25:18 | [VarDecl] using | semmle.order | 0 | +| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | tst.js:25:25:27:5 | [BlockStmt] { ... . } | semmle.label | 5 | +| tst.js:25:5:27:5 | [FunctionDeclStmt] functio ... . } | tst.js:25:25:27:5 | [BlockStmt] { ... . } | semmle.order | 5 | +| tst.js:28:5:28:16 | [CallExpr] using(using) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| tst.js:28:5:28:16 | [CallExpr] using(using) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| tst.js:28:5:28:16 | [CallExpr] using(using) | tst.js:28:5:28:9 | [VarRef] using | semmle.label | 0 | +| tst.js:28:5:28:16 | [CallExpr] using(using) | tst.js:28:5:28:9 | [VarRef] using | semmle.order | 0 | +| tst.js:28:5:28:17 | [ExprStmt] using(using); | tst.js:28:5:28:16 | [CallExpr] using(using) | semmle.label | 1 | +| tst.js:28:5:28:17 | [ExprStmt] using(using); | tst.js:28:5:28:16 | [CallExpr] using(using) | semmle.order | 1 | +graphProperties +| semmle.graphKind | tree | diff --git a/javascript/ql/test/library-tests/AST/ExplicitResource/printAst.ql b/javascript/ql/test/library-tests/AST/ExplicitResource/printAst.ql new file mode 100644 index 00000000000..248ea7ad396 --- /dev/null +++ b/javascript/ql/test/library-tests/AST/ExplicitResource/printAst.ql @@ -0,0 +1,2 @@ +import javascript +import semmle.javascript.PrintAst diff --git a/javascript/ql/test/library-tests/AST/ExplicitResource/tst.js b/javascript/ql/test/library-tests/AST/ExplicitResource/tst.js new file mode 100644 index 00000000000..ef5c7f0e679 --- /dev/null +++ b/javascript/ql/test/library-tests/AST/ExplicitResource/tst.js @@ -0,0 +1,29 @@ +function g() { + using stream = getResource(); + + let (test = 20); // <- I didn't know this was a thing + + for (using stream2 = getResource(); ; ) { + // ... + break; + } +} + +async function h() { + await using stream = getResource(); + + for (await using stream2 = getResource(); ; ) { + // ... + break; + } + + console.log("end"); +} + +function usesUsing() { + using("foo"); + function using(foo) { + // ... + } + using(using); +} \ No newline at end of file diff --git a/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.expected b/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.expected index aead5092430..09fa88a9b37 100644 --- a/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.expected +++ b/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.expected @@ -1,3 +1,15 @@ +#select | tst.tsx:1:10:1:10 | f | | tst.tsx:1:12:1:12 | o | | tst.tsx:2:14:2:14 | v | +| tst.tsx:6:10:6:10 | v | +| tst.tsx:7:11:7:13 | foo | +| tst.tsx:9:11:9:13 | bar | +| tst.tsx:12:16:12:16 | b | +| tst.tsx:13:17:13:19 | foo | +consts +| tst.tsx:2:3:2:26 | const { ... } = o; | +| tst.tsx:9:5:9:26 | const b ... efined; | +usings +| tst.tsx:7:5:7:28 | using f ... as any; | +| tst.tsx:13:5:13:34 | await u ... as any; | diff --git a/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.ql b/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.ql index 7039e6fa812..87cbba8b1b4 100644 --- a/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.ql +++ b/javascript/ql/test/library-tests/TypeScript/BindingPattern/VarDecl.ql @@ -2,3 +2,7 @@ import javascript from VarDecl decl select decl + +query ConstDeclStmt consts() { any() } + +query UsingDeclStmt usings() { any() } diff --git a/javascript/ql/test/library-tests/TypeScript/BindingPattern/tst.tsx b/javascript/ql/test/library-tests/TypeScript/BindingPattern/tst.tsx index db332181280..8e368671e60 100644 --- a/javascript/ql/test/library-tests/TypeScript/BindingPattern/tst.tsx +++ b/javascript/ql/test/library-tests/TypeScript/BindingPattern/tst.tsx @@ -2,3 +2,13 @@ function f(o) { const { p: v = [] } = o; return v; } + +function v() { + using foo = null as any; + + const bar = undefined; +} + +async function b() { + await using foo = null as any; +} \ No newline at end of file diff --git a/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected b/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected index cd001b3689a..a8406a01260 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/printAst.expected @@ -109,6 +109,8 @@ nodes | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | +| file://:0:0:0:0 | (Arguments) | semmle.label | (Arguments) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | @@ -151,6 +153,8 @@ nodes | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | | file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (Parameters) | semmle.label | (Parameters) | +| file://:0:0:0:0 | (TypeParameters) | semmle.label | (TypeParameters) | | file://:0:0:0:0 | (TypeParameters) | semmle.label | (TypeParameters) | | file://:0:0:0:0 | (TypeParameters) | semmle.label | (TypeParameters) | | file://:0:0:0:0 | (TypeParameters) | semmle.label | (TypeParameters) | @@ -1692,8 +1696,56 @@ nodes | tst.ts:467:15:467:17 | [VarRef] foo | semmle.label | [VarRef] foo | | tst.ts:467:15:467:20 | [IndexExpr] foo[1] | semmle.label | [IndexExpr] foo[1] | | tst.ts:467:19:467:19 | [Literal] 1 | semmle.label | [Literal] 1 | +| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | semmle.label | [NamespaceDeclaration] module ... ng>); } | +| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | semmle.order | 87 | +| tst.ts:472:8:472:11 | [VarDecl] TS52 | semmle.label | [VarDecl] TS52 | +| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | semmle.label | [ClassDefinition,TypeDefinition] class S ... ; } | +| tst.ts:473:11:473:19 | [VarDecl] SomeClass | semmle.label | [VarDecl] SomeClass | +| tst.ts:473:21:473:20 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | +| tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} | +| tst.ts:473:21:473:20 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} | +| tst.ts:473:21:473:20 | [Label] constructor | semmle.label | [Label] constructor | +| tst.ts:474:9:474:36 | [Decorator] @((_tar ... => {}) | semmle.label | [Decorator] @((_tar ... => {}) | +| tst.ts:474:10:474:36 | [ParExpr] ((_targ ... => {}) | semmle.label | [ParExpr] ((_targ ... => {}) | +| tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | semmle.label | [ArrowFunctionExpr] (_targe ... ) => {} | +| tst.ts:474:12:474:18 | [SimpleParameter] _target | semmle.label | [SimpleParameter] _target | +| tst.ts:474:21:474:28 | [SimpleParameter] _context | semmle.label | [SimpleParameter] _context | +| tst.ts:474:34:474:35 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | +| tst.ts:475:9:475:11 | [Label] foo | semmle.label | [Label] foo | +| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | semmle.label | [FieldDeclaration] foo = 123; | +| tst.ts:475:15:475:17 | [Literal] 123 | semmle.label | [Literal] 123 | +| tst.ts:478:5:478:11 | [VarRef] console | semmle.label | [VarRef] console | +| tst.ts:478:5:478:15 | [DotExpr] console.log | semmle.label | [DotExpr] console.log | +| tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | semmle.label | [MethodCallExpr] console ... adata]) | +| tst.ts:478:5:478:44 | [ExprStmt] console ... data]); | semmle.label | [ExprStmt] console ... data]); | +| tst.ts:478:13:478:15 | [Label] log | semmle.label | [Label] log | +| tst.ts:478:17:478:25 | [VarRef] SomeClass | semmle.label | [VarRef] SomeClass | +| tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | semmle.label | [IndexExpr] SomeCla ... tadata] | +| tst.ts:478:27:478:32 | [VarRef] Symbol | semmle.label | [VarRef] Symbol | +| tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | semmle.label | [DotExpr] Symbol.metadata | +| tst.ts:478:34:478:41 | [Label] metadata | semmle.label | [Label] metadata | +| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | +| tst.ts:481:10:481:14 | [Identifier] Pair3 | semmle.label | [Identifier] Pair3 | +| tst.ts:481:16:481:16 | [Identifier] T | semmle.label | [Identifier] T | +| tst.ts:481:16:481:16 | [TypeParameter] T | semmle.label | [TypeParameter] T | +| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | semmle.label | [TupleTypeExpr] [first: T, T] | +| tst.ts:481:22:481:26 | [Identifier] first | semmle.label | [Identifier] first | +| tst.ts:481:29:481:29 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | +| tst.ts:481:32:481:32 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | +| tst.ts:483:5:483:11 | [VarRef] console | semmle.label | [VarRef] console | +| tst.ts:483:5:483:15 | [DotExpr] console.log | semmle.label | [DotExpr] console.log | +| tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | semmle.label | [MethodCallExpr] console ... tring>) | +| tst.ts:483:5:483:60 | [ExprStmt] console ... ring>); | semmle.label | [ExprStmt] console ... ring>); | +| tst.ts:483:13:483:15 | [Label] log | semmle.label | [Label] log | +| tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | semmle.label | [ArrayExpr] ["hello", "world"] | +| tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | semmle.label | [SatisfiesExpr] ["hello ... string> | +| tst.ts:483:18:483:24 | [Literal] "hello" | semmle.label | [Literal] "hello" | +| tst.ts:483:27:483:33 | [Literal] "world" | semmle.label | [Literal] "world" | +| tst.ts:483:46:483:50 | [LocalTypeAccess] Pair3 | semmle.label | [LocalTypeAccess] Pair3 | +| tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | semmle.label | [GenericTypeExpr] Pair3 | +| tst.ts:483:52:483:57 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | | tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.label | [ExportDeclaration] export ... 'b'; } | -| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 87 | +| tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 88 | | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | [FunctionDeclStmt] functio ... 'b'; } | | tstModuleCJS.cts:1:17:1:28 | [VarDecl] tstModuleCJS | semmle.label | [VarDecl] tstModuleCJS | | tstModuleCJS.cts:1:33:1:35 | [LiteralTypeExpr] 'a' | semmle.label | [LiteralTypeExpr] 'a' | @@ -1711,7 +1763,7 @@ nodes | tstModuleCJS.cts:2:34:2:36 | [Literal] 'a' | semmle.label | [Literal] 'a' | | tstModuleCJS.cts:2:40:2:42 | [Literal] 'b' | semmle.label | [Literal] 'b' | | tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.label | [ExportDeclaration] export ... 'b'; } | -| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 88 | +| tstModuleES.mts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | semmle.order | 89 | | tstModuleES.mts:1:16:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | [FunctionDeclStmt] functio ... 'b'; } | | tstModuleES.mts:1:25:1:35 | [VarDecl] tstModuleES | semmle.label | [VarDecl] tstModuleES | | tstModuleES.mts:1:40:1:42 | [LiteralTypeExpr] 'a' | semmle.label | [LiteralTypeExpr] 'a' | @@ -1729,7 +1781,7 @@ nodes | tstModuleES.mts:2:34:2:36 | [Literal] 'a' | semmle.label | [Literal] 'a' | | tstModuleES.mts:2:40:2:42 | [Literal] 'b' | semmle.label | [Literal] 'b' | | tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } | -| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 89 | +| tstSuffixA.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 90 | | tstSuffixA.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } | | tstSuffixA.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile | | tstSuffixA.ts:1:33:1:47 | [LiteralTypeExpr] 'tstSuffixA.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixA.ts' | @@ -1737,7 +1789,7 @@ nodes | tstSuffixA.ts:2:5:2:27 | [ReturnStmt] return ... xA.ts'; | semmle.label | [ReturnStmt] return ... xA.ts'; | | tstSuffixA.ts:2:12:2:26 | [Literal] 'tstSuffixA.ts' | semmle.label | [Literal] 'tstSuffixA.ts' | | tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } | -| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 90 | +| tstSuffixB.ios.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 91 | | tstSuffixB.ios.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } | | tstSuffixB.ios.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile | | tstSuffixB.ios.ts:1:33:1:51 | [LiteralTypeExpr] 'tstSuffixB.ios.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixB.ios.ts' | @@ -1745,7 +1797,7 @@ nodes | tstSuffixB.ios.ts:2:5:2:31 | [ReturnStmt] return ... os.ts'; | semmle.label | [ReturnStmt] return ... os.ts'; | | tstSuffixB.ios.ts:2:12:2:30 | [Literal] 'tstSuffixB.ios.ts' | semmle.label | [Literal] 'tstSuffixB.ios.ts' | | tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.label | [ExportDeclaration] export ... .ts'; } | -| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 91 | +| tstSuffixB.ts:1:1:3:1 | [ExportDeclaration] export ... .ts'; } | semmle.order | 92 | | tstSuffixB.ts:1:8:3:1 | [FunctionDeclStmt] functio ... .ts'; } | semmle.label | [FunctionDeclStmt] functio ... .ts'; } | | tstSuffixB.ts:1:17:1:28 | [VarDecl] resolvedFile | semmle.label | [VarDecl] resolvedFile | | tstSuffixB.ts:1:33:1:47 | [LiteralTypeExpr] 'tstSuffixB.ts' | semmle.label | [LiteralTypeExpr] 'tstSuffixB.ts' | @@ -1753,16 +1805,16 @@ nodes | tstSuffixB.ts:2:5:2:27 | [ReturnStmt] return ... xB.ts'; | semmle.label | [ReturnStmt] return ... xB.ts'; | | tstSuffixB.ts:2:12:2:26 | [Literal] 'tstSuffixB.ts' | semmle.label | [Literal] 'tstSuffixB.ts' | | type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | -| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 92 | +| type_alias.ts:1:1:1:17 | [TypeAliasDeclaration,TypeDefinition] type B = boolean; | semmle.order | 93 | | type_alias.ts:1:6:1:6 | [Identifier] B | semmle.label | [Identifier] B | | type_alias.ts:1:10:1:16 | [KeywordTypeExpr] boolean | semmle.label | [KeywordTypeExpr] boolean | | type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.label | [DeclStmt] var b = ... | -| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 93 | +| type_alias.ts:3:1:3:9 | [DeclStmt] var b = ... | semmle.order | 94 | | type_alias.ts:3:5:3:5 | [VarDecl] b | semmle.label | [VarDecl] b | | type_alias.ts:3:5:3:8 | [VariableDeclarator] b: B | semmle.label | [VariableDeclarator] b: B | | type_alias.ts:3:8:3:8 | [LocalTypeAccess] B | semmle.label | [LocalTypeAccess] B | | type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | -| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.order | 94 | +| type_alias.ts:5:1:5:50 | [TypeAliasDeclaration,TypeDefinition] type Va ... ay>; | semmle.order | 95 | | type_alias.ts:5:6:5:17 | [Identifier] ValueOrArray | semmle.label | [Identifier] ValueOrArray | | type_alias.ts:5:19:5:19 | [Identifier] T | semmle.label | [Identifier] T | | type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.label | [TypeParameter] T | @@ -1774,14 +1826,14 @@ nodes | type_alias.ts:5:34:5:48 | [GenericTypeExpr] ValueOrArray | semmle.label | [GenericTypeExpr] ValueOrArray | | type_alias.ts:5:47:5:47 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | | type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.label | [DeclStmt] var c = ... | -| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 95 | +| type_alias.ts:7:1:7:28 | [DeclStmt] var c = ... | semmle.order | 96 | | type_alias.ts:7:5:7:5 | [VarDecl] c | semmle.label | [VarDecl] c | | type_alias.ts:7:5:7:27 | [VariableDeclarator] c: Valu ... number> | semmle.label | [VariableDeclarator] c: Valu ... number> | | type_alias.ts:7:8:7:19 | [LocalTypeAccess] ValueOrArray | semmle.label | [LocalTypeAccess] ValueOrArray | | type_alias.ts:7:8:7:27 | [GenericTypeExpr] ValueOrArray | semmle.label | [GenericTypeExpr] ValueOrArray | | type_alias.ts:7:21:7:26 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | | type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | -| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 96 | +| type_alias.ts:9:1:15:13 | [TypeAliasDeclaration,TypeDefinition] type Js ... Json[]; | semmle.order | 97 | | type_alias.ts:9:6:9:9 | [Identifier] Json | semmle.label | [Identifier] Json | | type_alias.ts:10:5:15:12 | [UnionTypeExpr] \| strin ... Json[] | semmle.label | [UnionTypeExpr] \| strin ... Json[] | | type_alias.ts:10:7:10:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | @@ -1797,12 +1849,12 @@ nodes | type_alias.ts:15:7:15:10 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json | | type_alias.ts:15:7:15:12 | [ArrayTypeExpr] Json[] | semmle.label | [ArrayTypeExpr] Json[] | | type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.label | [DeclStmt] var json = ... | -| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 97 | +| type_alias.ts:17:1:17:15 | [DeclStmt] var json = ... | semmle.order | 98 | | type_alias.ts:17:5:17:8 | [VarDecl] json | semmle.label | [VarDecl] json | | type_alias.ts:17:5:17:14 | [VariableDeclarator] json: Json | semmle.label | [VariableDeclarator] json: Json | | type_alias.ts:17:11:17:14 | [LocalTypeAccess] Json | semmle.label | [LocalTypeAccess] Json | | type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | -| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 98 | +| type_alias.ts:19:1:21:57 | [TypeAliasDeclaration,TypeDefinition] type Vi ... ode[]]; | semmle.order | 99 | | type_alias.ts:19:6:19:16 | [Identifier] VirtualNode | semmle.label | [Identifier] VirtualNode | | type_alias.ts:20:5:21:56 | [UnionTypeExpr] \| strin ... Node[]] | semmle.label | [UnionTypeExpr] \| strin ... Node[]] | | type_alias.ts:20:7:20:12 | [KeywordTypeExpr] string | semmle.label | [KeywordTypeExpr] string | @@ -1818,7 +1870,7 @@ nodes | type_alias.ts:21:43:21:53 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode | | type_alias.ts:21:43:21:55 | [ArrayTypeExpr] VirtualNode[] | semmle.label | [ArrayTypeExpr] VirtualNode[] | | type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.label | [DeclStmt] const myNode = ... | -| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 99 | +| type_alias.ts:23:1:27:6 | [DeclStmt] const myNode = ... | semmle.order | 100 | | type_alias.ts:23:7:23:12 | [VarDecl] myNode | semmle.label | [VarDecl] myNode | | type_alias.ts:23:7:27:5 | [VariableDeclarator] myNode: ... ] ] | semmle.label | [VariableDeclarator] myNode: ... ] ] | | type_alias.ts:23:15:23:25 | [LocalTypeAccess] VirtualNode | semmle.label | [LocalTypeAccess] VirtualNode | @@ -1843,12 +1895,12 @@ nodes | type_alias.ts:26:23:26:36 | [Literal] "second-child" | semmle.label | [Literal] "second-child" | | type_alias.ts:26:41:26:62 | [Literal] "I'm the second child" | semmle.label | [Literal] "I'm the second child" | | type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; | -| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 100 | +| type_definition_objects.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 101 | | type_definition_objects.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy | | type_definition_objects.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy | | type_definition_objects.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" | | type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.label | [ExportDeclaration] export class C {} | -| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 101 | +| type_definition_objects.ts:3:1:3:17 | [ExportDeclaration] export class C {} | semmle.order | 102 | | type_definition_objects.ts:3:8:3:17 | [ClassDefinition,TypeDefinition] class C {} | semmle.label | [ClassDefinition,TypeDefinition] class C {} | | type_definition_objects.ts:3:14:3:14 | [VarDecl] C | semmle.label | [VarDecl] C | | type_definition_objects.ts:3:16:3:15 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | @@ -1856,36 +1908,36 @@ nodes | type_definition_objects.ts:3:16:3:15 | [FunctionExpr] () {} | semmle.label | [FunctionExpr] () {} | | type_definition_objects.ts:3:16:3:15 | [Label] constructor | semmle.label | [Label] constructor | | type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.label | [DeclStmt] let classObj = ... | -| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 102 | +| type_definition_objects.ts:4:1:4:17 | [DeclStmt] let classObj = ... | semmle.order | 103 | | type_definition_objects.ts:4:5:4:12 | [VarDecl] classObj | semmle.label | [VarDecl] classObj | | type_definition_objects.ts:4:5:4:16 | [VariableDeclarator] classObj = C | semmle.label | [VariableDeclarator] classObj = C | | type_definition_objects.ts:4:16:4:16 | [VarRef] C | semmle.label | [VarRef] C | | type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.label | [ExportDeclaration] export enum E {} | -| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 103 | +| type_definition_objects.ts:6:1:6:16 | [ExportDeclaration] export enum E {} | semmle.order | 104 | | type_definition_objects.ts:6:8:6:16 | [EnumDeclaration,TypeDefinition] enum E {} | semmle.label | [EnumDeclaration,TypeDefinition] enum E {} | | type_definition_objects.ts:6:13:6:13 | [VarDecl] E | semmle.label | [VarDecl] E | | type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.label | [DeclStmt] let enumObj = ... | -| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 104 | +| type_definition_objects.ts:7:1:7:16 | [DeclStmt] let enumObj = ... | semmle.order | 105 | | type_definition_objects.ts:7:5:7:11 | [VarDecl] enumObj | semmle.label | [VarDecl] enumObj | | type_definition_objects.ts:7:5:7:15 | [VariableDeclarator] enumObj = E | semmle.label | [VariableDeclarator] enumObj = E | | type_definition_objects.ts:7:15:7:15 | [VarRef] E | semmle.label | [VarRef] E | | type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.label | [ExportDeclaration] export ... e N {;} | -| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 105 | +| type_definition_objects.ts:9:1:9:22 | [ExportDeclaration] export ... e N {;} | semmle.order | 106 | | type_definition_objects.ts:9:8:9:22 | [NamespaceDeclaration] namespace N {;} | semmle.label | [NamespaceDeclaration] namespace N {;} | | type_definition_objects.ts:9:18:9:18 | [VarDecl] N | semmle.label | [VarDecl] N | | type_definition_objects.ts:9:21:9:21 | [EmptyStmt] ; | semmle.label | [EmptyStmt] ; | | type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.label | [DeclStmt] let namespaceObj = ... | -| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 106 | +| type_definition_objects.ts:10:1:10:21 | [DeclStmt] let namespaceObj = ... | semmle.order | 107 | | type_definition_objects.ts:10:5:10:16 | [VarDecl] namespaceObj | semmle.label | [VarDecl] namespaceObj | | type_definition_objects.ts:10:5:10:20 | [VariableDeclarator] namespaceObj = N | semmle.label | [VariableDeclarator] namespaceObj = N | | type_definition_objects.ts:10:20:10:20 | [VarRef] N | semmle.label | [VarRef] N | | type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.label | [ImportDeclaration] import ... dummy"; | -| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 107 | +| type_definitions.ts:1:1:1:33 | [ImportDeclaration] import ... dummy"; | semmle.order | 108 | | type_definitions.ts:1:8:1:17 | [ImportSpecifier] * as dummy | semmle.label | [ImportSpecifier] * as dummy | | type_definitions.ts:1:13:1:17 | [VarDecl] dummy | semmle.label | [VarDecl] dummy | | type_definitions.ts:1:24:1:32 | [Literal] "./dummy" | semmle.label | [Literal] "./dummy" | | type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.label | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | -| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 108 | +| type_definitions.ts:3:1:5:1 | [InterfaceDeclaration,TypeDefinition] interfa ... x: S; } | semmle.order | 109 | | type_definitions.ts:3:11:3:11 | [Identifier] I | semmle.label | [Identifier] I | | type_definitions.ts:3:13:3:13 | [Identifier] S | semmle.label | [Identifier] S | | type_definitions.ts:3:13:3:13 | [TypeParameter] S | semmle.label | [TypeParameter] S | @@ -1893,14 +1945,14 @@ nodes | type_definitions.ts:4:3:4:7 | [FieldDeclaration] x: S; | semmle.label | [FieldDeclaration] x: S; | | type_definitions.ts:4:6:4:6 | [LocalTypeAccess] S | semmle.label | [LocalTypeAccess] S | | type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.label | [DeclStmt] let i = ... | -| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 109 | +| type_definitions.ts:6:1:6:16 | [DeclStmt] let i = ... | semmle.order | 110 | | type_definitions.ts:6:5:6:5 | [VarDecl] i | semmle.label | [VarDecl] i | | type_definitions.ts:6:5:6:16 | [VariableDeclarator] i: I | semmle.label | [VariableDeclarator] i: I | | type_definitions.ts:6:8:6:8 | [LocalTypeAccess] I | semmle.label | [LocalTypeAccess] I | | type_definitions.ts:6:8:6:16 | [GenericTypeExpr] I | semmle.label | [GenericTypeExpr] I | | type_definitions.ts:6:10:6:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | | type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.label | [ClassDefinition,TypeDefinition] class C ... x: T } | -| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 110 | +| type_definitions.ts:8:1:10:1 | [ClassDefinition,TypeDefinition] class C ... x: T } | semmle.order | 111 | | type_definitions.ts:8:7:8:7 | [VarDecl] C | semmle.label | [VarDecl] C | | type_definitions.ts:8:8:8:7 | [BlockStmt] {} | semmle.label | [BlockStmt] {} | | type_definitions.ts:8:8:8:7 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | [ClassInitializedMember,ConstructorDefinition] constructor() {} | @@ -1912,14 +1964,14 @@ nodes | type_definitions.ts:9:3:9:6 | [FieldDeclaration] x: T | semmle.label | [FieldDeclaration] x: T | | type_definitions.ts:9:6:9:6 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | | type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.label | [DeclStmt] let c = ... | -| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 111 | +| type_definitions.ts:11:1:11:17 | [DeclStmt] let c = ... | semmle.order | 112 | | type_definitions.ts:11:5:11:5 | [VarDecl] c | semmle.label | [VarDecl] c | | type_definitions.ts:11:5:11:16 | [VariableDeclarator] c: C | semmle.label | [VariableDeclarator] c: C | | type_definitions.ts:11:8:11:8 | [LocalTypeAccess] C | semmle.label | [LocalTypeAccess] C | | type_definitions.ts:11:8:11:16 | [GenericTypeExpr] C | semmle.label | [GenericTypeExpr] C | | type_definitions.ts:11:10:11:15 | [KeywordTypeExpr] number | semmle.label | [KeywordTypeExpr] number | | type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.label | [EnumDeclaration,TypeDefinition] enum Co ... blue } | -| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 112 | +| type_definitions.ts:13:1:15:1 | [EnumDeclaration,TypeDefinition] enum Co ... blue } | semmle.order | 113 | | type_definitions.ts:13:6:13:10 | [VarDecl] Color | semmle.label | [VarDecl] Color | | type_definitions.ts:14:3:14:5 | [EnumMember,TypeDefinition] red | semmle.label | [EnumMember,TypeDefinition] red | | type_definitions.ts:14:3:14:5 | [VarDecl] red | semmle.label | [VarDecl] red | @@ -1928,29 +1980,29 @@ nodes | type_definitions.ts:14:15:14:18 | [EnumMember,TypeDefinition] blue | semmle.label | [EnumMember,TypeDefinition] blue | | type_definitions.ts:14:15:14:18 | [VarDecl] blue | semmle.label | [VarDecl] blue | | type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.label | [DeclStmt] let color = ... | -| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 113 | +| type_definitions.ts:16:1:16:17 | [DeclStmt] let color = ... | semmle.order | 114 | | type_definitions.ts:16:5:16:9 | [VarDecl] color | semmle.label | [VarDecl] color | | type_definitions.ts:16:5:16:16 | [VariableDeclarator] color: Color | semmle.label | [VariableDeclarator] color: Color | | type_definitions.ts:16:12:16:16 | [LocalTypeAccess] Color | semmle.label | [LocalTypeAccess] Color | | type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.label | [EnumDeclaration,TypeDefinition] enum En ... ember } | -| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 114 | +| type_definitions.ts:18:1:18:33 | [EnumDeclaration,TypeDefinition] enum En ... ember } | semmle.order | 115 | | type_definitions.ts:18:6:18:22 | [VarDecl] EnumWithOneMember | semmle.label | [VarDecl] EnumWithOneMember | | type_definitions.ts:18:26:18:31 | [EnumMember,TypeDefinition] member | semmle.label | [EnumMember,TypeDefinition] member | | type_definitions.ts:18:26:18:31 | [VarDecl] member | semmle.label | [VarDecl] member | | type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.label | [DeclStmt] let e = ... | -| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 115 | +| type_definitions.ts:19:1:19:25 | [DeclStmt] let e = ... | semmle.order | 116 | | type_definitions.ts:19:5:19:5 | [VarDecl] e | semmle.label | [VarDecl] e | | type_definitions.ts:19:5:19:24 | [VariableDeclarator] e: EnumWithOneMember | semmle.label | [VariableDeclarator] e: EnumWithOneMember | | type_definitions.ts:19:8:19:24 | [LocalTypeAccess] EnumWithOneMember | semmle.label | [LocalTypeAccess] EnumWithOneMember | | type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.label | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | -| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.order | 116 | +| type_definitions.ts:21:1:21:20 | [TypeAliasDeclaration,TypeDefinition] type Alias = T[]; | semmle.order | 117 | | type_definitions.ts:21:6:21:10 | [Identifier] Alias | semmle.label | [Identifier] Alias | | type_definitions.ts:21:12:21:12 | [Identifier] T | semmle.label | [Identifier] T | | type_definitions.ts:21:12:21:12 | [TypeParameter] T | semmle.label | [TypeParameter] T | | type_definitions.ts:21:17:21:17 | [LocalTypeAccess] T | semmle.label | [LocalTypeAccess] T | | type_definitions.ts:21:17:21:19 | [ArrayTypeExpr] T[] | semmle.label | [ArrayTypeExpr] T[] | | type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.label | [DeclStmt] let aliasForNumberArray = ... | -| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 117 | +| type_definitions.ts:22:1:22:39 | [DeclStmt] let aliasForNumberArray = ... | semmle.order | 118 | | type_definitions.ts:22:5:22:23 | [VarDecl] aliasForNumberArray | semmle.label | [VarDecl] aliasForNumberArray | | type_definitions.ts:22:5:22:38 | [VariableDeclarator] aliasFo ... number> | semmle.label | [VariableDeclarator] aliasFo ... number> | | type_definitions.ts:22:26:22:30 | [LocalTypeAccess] Alias | semmle.label | [LocalTypeAccess] Alias | @@ -2129,6 +2181,10 @@ edges | file://:0:0:0:0 | (Arguments) | tst.ts:460:26:460:31 | [Literal] "John" | semmle.order | 0 | | file://:0:0:0:0 | (Arguments) | tst.ts:465:35:465:49 | [ArrayExpr] ["a", "b" ,"c"] | semmle.label | 0 | | file://:0:0:0:0 | (Arguments) | tst.ts:465:35:465:49 | [ArrayExpr] ["a", "b" ,"c"] | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | semmle.order | 0 | +| file://:0:0:0:0 | (Arguments) | tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | semmle.label | 0 | +| file://:0:0:0:0 | (Arguments) | tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:14:17:14:17 | [SimpleParameter] x | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:14:17:14:17 | [SimpleParameter] x | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:14:28:14:28 | [SimpleParameter] y | semmle.label | 1 | @@ -2223,6 +2279,10 @@ edges | file://:0:0:0:0 | (Parameters) | tst.ts:449:21:449:24 | [SimpleParameter] name | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:462:75:462:78 | [SimpleParameter] args | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | tst.ts:462:75:462:78 | [SimpleParameter] args | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:474:12:474:18 | [SimpleParameter] _target | semmle.label | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:474:12:474:18 | [SimpleParameter] _target | semmle.order | 0 | +| file://:0:0:0:0 | (Parameters) | tst.ts:474:21:474:28 | [SimpleParameter] _context | semmle.label | 1 | +| file://:0:0:0:0 | (Parameters) | tst.ts:474:21:474:28 | [SimpleParameter] _context | semmle.order | 1 | | file://:0:0:0:0 | (Parameters) | type_alias.ts:14:10:14:17 | [SimpleParameter] property | semmle.label | 0 | | file://:0:0:0:0 | (Parameters) | type_alias.ts:14:10:14:17 | [SimpleParameter] property | semmle.order | 0 | | file://:0:0:0:0 | (Parameters) | type_alias.ts:21:19:21:21 | [SimpleParameter] key | semmle.label | 0 | @@ -2253,6 +2313,8 @@ edges | file://:0:0:0:0 | (TypeParameters) | tst.ts:431:53:431:58 | [TypeParameter] Return | semmle.order | 2 | | file://:0:0:0:0 | (TypeParameters) | tst.ts:462:40:462:72 | [TypeParameter] const T ... tring[] | semmle.label | 0 | | file://:0:0:0:0 | (TypeParameters) | tst.ts:462:40:462:72 | [TypeParameter] const T ... tring[] | semmle.order | 0 | +| file://:0:0:0:0 | (TypeParameters) | tst.ts:481:16:481:16 | [TypeParameter] T | semmle.label | 0 | +| file://:0:0:0:0 | (TypeParameters) | tst.ts:481:16:481:16 | [TypeParameter] T | semmle.order | 0 | | file://:0:0:0:0 | (TypeParameters) | type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.label | 0 | | file://:0:0:0:0 | (TypeParameters) | type_alias.ts:5:19:5:19 | [TypeParameter] T | semmle.order | 0 | | file://:0:0:0:0 | (TypeParameters) | type_definitions.ts:3:13:3:13 | [TypeParameter] S | semmle.label | 0 | @@ -4999,6 +5061,96 @@ edges | tst.ts:467:15:467:20 | [IndexExpr] foo[1] | tst.ts:467:15:467:17 | [VarRef] foo | semmle.order | 1 | | tst.ts:467:15:467:20 | [IndexExpr] foo[1] | tst.ts:467:19:467:19 | [Literal] 1 | semmle.label | 2 | | tst.ts:467:15:467:20 | [IndexExpr] foo[1] | tst.ts:467:19:467:19 | [Literal] 1 | semmle.order | 2 | +| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:472:8:472:11 | [VarDecl] TS52 | semmle.label | 1 | +| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:472:8:472:11 | [VarDecl] TS52 | semmle.order | 1 | +| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | semmle.label | 2 | +| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | semmle.order | 2 | +| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:478:5:478:44 | [ExprStmt] console ... data]); | semmle.label | 3 | +| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:478:5:478:44 | [ExprStmt] console ... data]); | semmle.order | 3 | +| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | semmle.label | 4 | +| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | semmle.order | 4 | +| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:483:5:483:60 | [ExprStmt] console ... ring>); | semmle.label | 5 | +| tst.ts:472:1:484:1 | [NamespaceDeclaration] module ... ng>); } | tst.ts:483:5:483:60 | [ExprStmt] console ... ring>); | semmle.order | 5 | +| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | tst.ts:473:11:473:19 | [VarDecl] SomeClass | semmle.label | 1 | +| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | tst.ts:473:11:473:19 | [VarDecl] SomeClass | semmle.order | 1 | +| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.label | 2 | +| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | semmle.order | 2 | +| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | semmle.label | 3 | +| tst.ts:473:5:476:5 | [ClassDefinition,TypeDefinition] class S ... ; } | tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | semmle.order | 3 | +| tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:473:21:473:20 | [FunctionExpr] () {} | semmle.label | 2 | +| tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:473:21:473:20 | [FunctionExpr] () {} | semmle.order | 2 | +| tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:473:21:473:20 | [Label] constructor | semmle.label | 1 | +| tst.ts:473:21:473:20 | [ClassInitializedMember,ConstructorDefinition] constructor() {} | tst.ts:473:21:473:20 | [Label] constructor | semmle.order | 1 | +| tst.ts:473:21:473:20 | [FunctionExpr] () {} | tst.ts:473:21:473:20 | [BlockStmt] {} | semmle.label | 5 | +| tst.ts:473:21:473:20 | [FunctionExpr] () {} | tst.ts:473:21:473:20 | [BlockStmt] {} | semmle.order | 5 | +| tst.ts:474:9:474:36 | [Decorator] @((_tar ... => {}) | tst.ts:474:10:474:36 | [ParExpr] ((_targ ... => {}) | semmle.label | 1 | +| tst.ts:474:9:474:36 | [Decorator] @((_tar ... => {}) | tst.ts:474:10:474:36 | [ParExpr] ((_targ ... => {}) | semmle.order | 1 | +| tst.ts:474:10:474:36 | [ParExpr] ((_targ ... => {}) | tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | semmle.label | 1 | +| tst.ts:474:10:474:36 | [ParExpr] ((_targ ... => {}) | tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | semmle.order | 1 | +| tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | file://:0:0:0:0 | (Parameters) | semmle.label | 1 | +| tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | file://:0:0:0:0 | (Parameters) | semmle.order | 1 | +| tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | tst.ts:474:34:474:35 | [BlockStmt] {} | semmle.label | 5 | +| tst.ts:474:11:474:35 | [ArrowFunctionExpr] (_targe ... ) => {} | tst.ts:474:34:474:35 | [BlockStmt] {} | semmle.order | 5 | +| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | tst.ts:474:9:474:36 | [Decorator] @((_tar ... => {}) | semmle.label | 1 | +| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | tst.ts:474:9:474:36 | [Decorator] @((_tar ... => {}) | semmle.order | 1 | +| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | tst.ts:475:9:475:11 | [Label] foo | semmle.label | 2 | +| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | tst.ts:475:9:475:11 | [Label] foo | semmle.order | 2 | +| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | tst.ts:475:15:475:17 | [Literal] 123 | semmle.label | 3 | +| tst.ts:475:9:475:18 | [FieldDeclaration] foo = 123; | tst.ts:475:15:475:17 | [Literal] 123 | semmle.order | 3 | +| tst.ts:478:5:478:15 | [DotExpr] console.log | tst.ts:478:5:478:11 | [VarRef] console | semmle.label | 1 | +| tst.ts:478:5:478:15 | [DotExpr] console.log | tst.ts:478:5:478:11 | [VarRef] console | semmle.order | 1 | +| tst.ts:478:5:478:15 | [DotExpr] console.log | tst.ts:478:13:478:15 | [Label] log | semmle.label | 2 | +| tst.ts:478:5:478:15 | [DotExpr] console.log | tst.ts:478:13:478:15 | [Label] log | semmle.order | 2 | +| tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | tst.ts:478:5:478:15 | [DotExpr] console.log | semmle.label | 0 | +| tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | tst.ts:478:5:478:15 | [DotExpr] console.log | semmle.order | 0 | +| tst.ts:478:5:478:44 | [ExprStmt] console ... data]); | tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | semmle.label | 1 | +| tst.ts:478:5:478:44 | [ExprStmt] console ... data]); | tst.ts:478:5:478:43 | [MethodCallExpr] console ... adata]) | semmle.order | 1 | +| tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | tst.ts:478:17:478:25 | [VarRef] SomeClass | semmle.label | 1 | +| tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | tst.ts:478:17:478:25 | [VarRef] SomeClass | semmle.order | 1 | +| tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | semmle.label | 2 | +| tst.ts:478:17:478:42 | [IndexExpr] SomeCla ... tadata] | tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | semmle.order | 2 | +| tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | tst.ts:478:27:478:32 | [VarRef] Symbol | semmle.label | 1 | +| tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | tst.ts:478:27:478:32 | [VarRef] Symbol | semmle.order | 1 | +| tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | tst.ts:478:34:478:41 | [Label] metadata | semmle.label | 2 | +| tst.ts:478:27:478:41 | [DotExpr] Symbol.metadata | tst.ts:478:34:478:41 | [Label] metadata | semmle.order | 2 | +| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | file://:0:0:0:0 | (TypeParameters) | semmle.label | -100 | +| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | file://:0:0:0:0 | (TypeParameters) | semmle.order | -100 | +| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | tst.ts:481:10:481:14 | [Identifier] Pair3 | semmle.label | 1 | +| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | tst.ts:481:10:481:14 | [Identifier] Pair3 | semmle.order | 1 | +| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | semmle.label | 3 | +| tst.ts:481:5:481:34 | [TypeAliasDeclaration,TypeDefinition] type Pa ... T, T]; | tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | semmle.order | 3 | +| tst.ts:481:16:481:16 | [TypeParameter] T | tst.ts:481:16:481:16 | [Identifier] T | semmle.label | 1 | +| tst.ts:481:16:481:16 | [TypeParameter] T | tst.ts:481:16:481:16 | [Identifier] T | semmle.order | 1 | +| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | tst.ts:481:22:481:26 | [Identifier] first | semmle.label | 1 | +| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | tst.ts:481:22:481:26 | [Identifier] first | semmle.order | 1 | +| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | tst.ts:481:29:481:29 | [LocalTypeAccess] T | semmle.label | 2 | +| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | tst.ts:481:29:481:29 | [LocalTypeAccess] T | semmle.order | 2 | +| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | tst.ts:481:32:481:32 | [LocalTypeAccess] T | semmle.label | 3 | +| tst.ts:481:21:481:33 | [TupleTypeExpr] [first: T, T] | tst.ts:481:32:481:32 | [LocalTypeAccess] T | semmle.order | 3 | +| tst.ts:483:5:483:15 | [DotExpr] console.log | tst.ts:483:5:483:11 | [VarRef] console | semmle.label | 1 | +| tst.ts:483:5:483:15 | [DotExpr] console.log | tst.ts:483:5:483:11 | [VarRef] console | semmle.order | 1 | +| tst.ts:483:5:483:15 | [DotExpr] console.log | tst.ts:483:13:483:15 | [Label] log | semmle.label | 2 | +| tst.ts:483:5:483:15 | [DotExpr] console.log | tst.ts:483:13:483:15 | [Label] log | semmle.order | 2 | +| tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | file://:0:0:0:0 | (Arguments) | semmle.label | 1 | +| tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | file://:0:0:0:0 | (Arguments) | semmle.order | 1 | +| tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | tst.ts:483:5:483:15 | [DotExpr] console.log | semmle.label | 0 | +| tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | tst.ts:483:5:483:15 | [DotExpr] console.log | semmle.order | 0 | +| tst.ts:483:5:483:60 | [ExprStmt] console ... ring>); | tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | semmle.label | 1 | +| tst.ts:483:5:483:60 | [ExprStmt] console ... ring>); | tst.ts:483:5:483:59 | [MethodCallExpr] console ... tring>) | semmle.order | 1 | +| tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | tst.ts:483:18:483:24 | [Literal] "hello" | semmle.label | 1 | +| tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | tst.ts:483:18:483:24 | [Literal] "hello" | semmle.order | 1 | +| tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | tst.ts:483:27:483:33 | [Literal] "world" | semmle.label | 2 | +| tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | tst.ts:483:27:483:33 | [Literal] "world" | semmle.order | 2 | +| tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | semmle.label | 1 | +| tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | tst.ts:483:17:483:34 | [ArrayExpr] ["hello", "world"] | semmle.order | 1 | +| tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | semmle.label | 2 | +| tst.ts:483:17:483:58 | [SatisfiesExpr] ["hello ... string> | tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | semmle.order | 2 | +| tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | tst.ts:483:46:483:50 | [LocalTypeAccess] Pair3 | semmle.label | 1 | +| tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | tst.ts:483:46:483:50 | [LocalTypeAccess] Pair3 | semmle.order | 1 | +| tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | tst.ts:483:52:483:57 | [KeywordTypeExpr] string | semmle.label | 2 | +| tst.ts:483:46:483:58 | [GenericTypeExpr] Pair3 | tst.ts:483:52:483:57 | [KeywordTypeExpr] string | semmle.order | 2 | | tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.label | 1 | | tstModuleCJS.cts:1:1:3:1 | [ExportDeclaration] export ... 'b'; } | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | semmle.order | 1 | | tstModuleCJS.cts:1:8:3:1 | [FunctionDeclStmt] functio ... 'b'; } | tstModuleCJS.cts:1:17:1:28 | [VarDecl] tstModuleCJS | semmle.label | 0 | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected index 206a634640e..e31ed6be412 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/tests.expected +++ b/javascript/ql/test/library-tests/TypeScript/Types/tests.expected @@ -633,6 +633,31 @@ getExprType | tst.ts:467:15:467:17 | foo | readonly ["a", "b", "c"] | | tst.ts:467:15:467:20 | foo[1] | "b" | | tst.ts:467:19:467:19 | 1 | 1 | +| tst.ts:472:8:472:11 | TS52 | typeof TS52 in library-tests/TypeScript/Types/tst.ts | +| tst.ts:473:11:473:19 | SomeClass | SomeClass | +| tst.ts:474:10:474:36 | ((_targ ... => {}) | (_target: undefined, _context: ClassFieldDecora... | +| tst.ts:474:11:474:35 | (_targe ... ) => {} | (_target: undefined, _context: ClassFieldDecora... | +| tst.ts:474:12:474:18 | _target | undefined | +| tst.ts:474:21:474:28 | _context | ClassFieldDecoratorContext &... | +| tst.ts:475:9:475:11 | foo | number | +| tst.ts:475:15:475:17 | 123 | 123 | +| tst.ts:478:5:478:11 | console | Console | +| tst.ts:478:5:478:15 | console.log | (...data: any[]) => void | +| tst.ts:478:5:478:43 | console ... adata]) | void | +| tst.ts:478:13:478:15 | log | (...data: any[]) => void | +| tst.ts:478:17:478:25 | SomeClass | typeof SomeClass in tst.ts:472 | +| tst.ts:478:17:478:42 | SomeCla ... tadata] | DecoratorMetadataObject | +| tst.ts:478:27:478:32 | Symbol | SymbolConstructor | +| tst.ts:478:27:478:41 | Symbol.metadata | typeof metadata | +| tst.ts:478:34:478:41 | metadata | typeof metadata | +| tst.ts:483:5:483:11 | console | Console | +| tst.ts:483:5:483:15 | console.log | (...data: any[]) => void | +| tst.ts:483:5:483:59 | console ... tring>) | void | +| tst.ts:483:13:483:15 | log | (...data: any[]) => void | +| tst.ts:483:17:483:34 | ["hello", "world"] | Pair3 | +| tst.ts:483:17:483:58 | ["hello ... string> | [first: string, string] | +| tst.ts:483:18:483:24 | "hello" | "hello" | +| tst.ts:483:27:483:33 | "world" | "world" | | tstModuleCJS.cts:1:17:1:28 | tstModuleCJS | () => "a" \| "b" | | tstModuleCJS.cts:2:12:2:15 | Math | Math | | tstModuleCJS.cts:2:12:2:22 | Math.random | () => number | @@ -744,6 +769,8 @@ getTypeDefinitionType | tst.ts:408:3:410:3 | interfa ... er;\\n } | HSVObj | | tst.ts:419:3:425:3 | class P ... }\\n } | Person | | tst.ts:447:5:458:5 | class P ... }\\n } | Person | +| tst.ts:473:5:476:5 | class S ... ;\\n } | SomeClass | +| tst.ts:481:5:481:34 | type Pa ... T, T]; | Pair3 | | type_alias.ts:1:1:1:17 | type B = boolean; | boolean | | type_alias.ts:5:1:5:50 | type Va ... ay>; | ValueOrArray | | type_alias.ts:9:1:15:13 | type Js ... Json[]; | Json | @@ -1093,6 +1120,15 @@ getTypeExprType | tst.ts:462:65:462:72 | string[] | readonly string[] | | tst.ts:462:81:462:81 | T | T | | tst.ts:462:85:462:85 | T | T | +| tst.ts:481:10:481:14 | Pair3 | Pair3 | +| tst.ts:481:16:481:16 | T | T | +| tst.ts:481:21:481:33 | [first: T, T] | [first: T, T] | +| tst.ts:481:22:481:26 | first | any | +| tst.ts:481:29:481:29 | T | T | +| tst.ts:481:32:481:32 | T | T | +| tst.ts:483:46:483:50 | Pair3 | Pair3 | +| tst.ts:483:46:483:58 | Pair3 | Pair3 | +| tst.ts:483:52:483:57 | string | string | | tstModuleCJS.cts:1:33:1:35 | 'a' | "a" | | tstModuleCJS.cts:1:33:1:41 | 'a' \| 'b' | "a" \| "b" | | tstModuleCJS.cts:1:39:1:41 | 'b' | "b" | @@ -1196,12 +1232,15 @@ referenceDefinition | MyUnion | tst.ts:65:1:65:54 | type My ... true}; | | MyUnion2 | tst.ts:68:1:68:49 | type My ... true}; | | NonAbstractDummy | tst.ts:54:1:56:1 | interfa ... mber;\\n} | +| Pair3 | tst.ts:481:5:481:34 | type Pa ... T, T]; | +| Pair3 | tst.ts:481:5:481:34 | type Pa ... T, T]; | | Person | tst.ts:222:3:234:3 | class P ... }\\n } | | Person | tst.ts:419:3:425:3 | class P ... }\\n } | | Person | tst.ts:447:5:458:5 | class P ... }\\n } | | RGB | tst.ts:393:3:393:56 | type RG ... umber]; | | RGBObj | tst.ts:404:3:406:3 | interfa ... er;\\n } | | Shape | tst.ts:140:3:142:47 | type Sh ... mber }; | +| SomeClass | tst.ts:473:5:476:5 | class S ... ;\\n } | | State | tst.ts:342:1:345:1 | interfa ... void;\\n} | | State | tst.ts:342:1:345:1 | interfa ... void;\\n} | | Sub | tst.ts:97:3:101:3 | class S ... }\\n } | @@ -1275,6 +1314,8 @@ tupleTypes | tst.ts:467:15:467:17 | foo | readonly ["a", "b", "c"] | 0 | "a" | 3 | no-rest | | tst.ts:467:15:467:17 | foo | readonly ["a", "b", "c"] | 1 | "b" | 3 | no-rest | | tst.ts:467:15:467:17 | foo | readonly ["a", "b", "c"] | 2 | "c" | 3 | no-rest | +| tst.ts:483:17:483:58 | ["hello ... string> | [first: string, string] | 0 | string | 2 | no-rest | +| tst.ts:483:17:483:58 | ["hello ... string> | [first: string, string] | 1 | string | 2 | no-rest | unknownType | tst.ts:40:5:40:15 | unknownType | unknown | | tst.ts:47:8:47:8 | e | unknown | @@ -1355,6 +1396,7 @@ unionIndex | number | 1 | string \| number | | number | 1 | string \| number \| boolean | | number | 1 | string \| number \| boolean \| { [property: string... | +| number | 1 | string \| number \| symbol | | number | 1 | string \| number \| true | | string | 0 | VirtualNode \| { [key: string]: any; } | | string | 0 | string \| Error | @@ -1363,10 +1405,12 @@ unionIndex | string | 0 | string \| number | | string | 0 | string \| number \| boolean | | string | 0 | string \| number \| boolean \| { [property: string... | +| string | 0 | string \| number \| symbol | | string | 0 | string \| number \| true | | string | 0 | string \| symbol | | string | 0 | string \| { [key: string]: any; } | | symbol | 1 | string \| symbol | +| symbol | 2 | string \| number \| symbol | | true | 1 | boolean | | true | 1 | boolean \| Promise | | true | 2 | number \| boolean | diff --git a/javascript/ql/test/library-tests/TypeScript/Types/tst.ts b/javascript/ql/test/library-tests/TypeScript/Types/tst.ts index aafe82aeb13..27ee7357c36 100644 --- a/javascript/ql/test/library-tests/TypeScript/Types/tst.ts +++ b/javascript/ql/test/library-tests/TypeScript/Types/tst.ts @@ -465,4 +465,20 @@ module TS50 { const foo = myConstIdFunction(["a", "b" ,"c"]); const b = foo[1]; // <- "b" +} + +///////////////// + +module TS52 { + class SomeClass { + @((_target, _context) => {}) + foo = 123; + } + + console.log(SomeClass[Symbol.metadata]); // <- has type DecoratorMetadataObject + + // named and anonymous tuple elements. + type Pair3 = [first: T, T]; + + console.log(["hello", "world"] satisfies Pair3); } \ No newline at end of file diff --git a/misc/scripts/accept-expected-changes-from-ci.py b/misc/scripts/accept-expected-changes-from-ci.py index 47a6bec76ab..1e03b426e7b 100755 --- a/misc/scripts/accept-expected-changes-from-ci.py +++ b/misc/scripts/accept-expected-changes-from-ci.py @@ -114,7 +114,7 @@ def make_patches_from_log_file(log_file_lines) -> List[Patch]: while True: next_line = parse_log_line(next(lines)) # it can be the case that - if next_line[0] in (" ", "-", "+", "@"): + if next_line and next_line[0] in (" ", "-", "+", "@"): lines_changed.append(next_line) if "FAILED" in next_line: break diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index 0abf0d49317..ab0e65b02b1 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.4 + +No user-facing changes. + ## 0.6.3 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/0.6.4.md b/misc/suite-helpers/change-notes/released/0.6.4.md new file mode 100644 index 00000000000..7e98b0159fc --- /dev/null +++ b/misc/suite-helpers/change-notes/released/0.6.4.md @@ -0,0 +1,3 @@ +## 0.6.4 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index b7dafe32c5d..ced8cf94614 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.3 +lastReleaseVersion: 0.6.4 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 0c423deb64d..79c9cad4f4e 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 0.6.4-dev +version: 0.6.4 groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index d3b291f4b48..fcef91e98a4 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.10.4 + +### Minor Analysis Improvements + +* Regular expressions containing multiple parse mode flags are now interpretted correctly. For example `"(?is)abc.*"` with both the `i` and `s` flags. +* Added `shlex.quote` as a sanitizer for the `py/shell-command-constructed-from-input` query. + ## 0.10.3 ### Minor Analysis Improvements diff --git a/python/ql/lib/change-notes/2023-07-20-regex-parse-modes.md b/python/ql/lib/change-notes/released/0.10.4.md similarity index 52% rename from python/ql/lib/change-notes/2023-07-20-regex-parse-modes.md rename to python/ql/lib/change-notes/released/0.10.4.md index 2d676227491..7f93237c621 100644 --- a/python/ql/lib/change-notes/2023-07-20-regex-parse-modes.md +++ b/python/ql/lib/change-notes/released/0.10.4.md @@ -1,4 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.10.4 + +### Minor Analysis Improvements + * Regular expressions containing multiple parse mode flags are now interpretted correctly. For example `"(?is)abc.*"` with both the `i` and `s` flags. +* Added `shlex.quote` as a sanitizer for the `py/shell-command-constructed-from-input` query. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index c6c21ef7d6c..0e1088e51a9 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.10.3 +lastReleaseVersion: 0.10.4 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index cac5d51e2e4..bb4f49e84e8 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 0.10.4-dev +version: 0.10.4 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll index e154491f795..2513a4aa3bd 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImplConsistency.qll @@ -3,297 +3,50 @@ * data-flow classes and predicates. */ -private import DataFlowImplSpecific::Private -private import DataFlowImplSpecific::Public -private import tainttracking1.TaintTrackingParameter::Private -private import tainttracking1.TaintTrackingParameter::Public +private import python +private import DataFlowImplSpecific +private import TaintTrackingImplSpecific +private import codeql.dataflow.internal.DataFlowImplConsistency -module Consistency { - private newtype TConsistencyConfiguration = MkConsistencyConfiguration() +private module Input implements InputSig { + private import Private + private import Public - /** A class for configuring the consistency queries. */ - class ConsistencyConfiguration extends TConsistencyConfiguration { - string toString() { none() } - - /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */ - predicate uniqueEnclosingCallableExclude(Node n) { none() } - - /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */ - predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() } - - /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */ - predicate uniqueNodeLocationExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `missingLocation`. */ - predicate missingLocationExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */ - predicate postWithInFlowExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */ - predicate argHasPostUpdateExclude(ArgumentNode n) { none() } - - /** Holds if `n` should be excluded from the consistency test `reverseRead`. */ - predicate reverseReadExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */ - predicate postHasUniquePreExclude(PostUpdateNode n) { none() } - - /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */ - predicate uniquePostUpdateExclude(Node n) { none() } - - /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */ - predicate viableImplInCallContextTooLargeExclude( - DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable - ) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */ - predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */ - predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */ - predicate identityLocalStepExclude(Node n) { none() } - } - - private class RelevantNode extends Node { - RelevantNode() { - this instanceof ArgumentNode or - this instanceof ParameterNode or - this instanceof ReturnNode or - this = getAnOutNode(_, _) or - simpleLocalFlowStep(this, _) or - simpleLocalFlowStep(_, this) or - jumpStep(this, _) or - jumpStep(_, this) or - storeStep(this, _, _) or - storeStep(_, _, this) or - readStep(this, _, _) or - readStep(_, _, this) or - defaultAdditionalTaintStep(this, _) or - defaultAdditionalTaintStep(_, this) - } - } - - query predicate uniqueEnclosingCallable(Node n, string msg) { - exists(int c | - n instanceof RelevantNode and - c = count(nodeGetEnclosingCallable(n)) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and - msg = "Node should have one enclosing callable but has " + c + "." - ) - } - - query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) { - exists(int c | - c = count(call.getEnclosingCallable()) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and - msg = "Call should have one enclosing callable but has " + c + "." - ) - } - - query predicate uniqueType(Node n, string msg) { - exists(int c | - n instanceof RelevantNode and - c = count(getNodeType(n)) and - c != 1 and - msg = "Node should have one type but has " + c + "." - ) - } - - query predicate uniqueNodeLocation(Node n, string msg) { - exists(int c | - c = - count(string filepath, int startline, int startcolumn, int endline, int endcolumn | - n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - ) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and - msg = "Node should have one location but has " + c + "." - ) - } - - query predicate missingLocation(string msg) { - exists(int c | - c = - strictcount(Node n | - not n.hasLocationInfo(_, _, _, _, _) and - not any(ConsistencyConfiguration conf).missingLocationExclude(n) - ) and - msg = "Nodes without location: " + c - ) - } - - query predicate uniqueNodeToString(Node n, string msg) { - exists(int c | - c = count(n.toString()) and - c != 1 and - msg = "Node should have one toString but has " + c + "." - ) - } - - query predicate missingToString(string msg) { - exists(int c | - c = strictcount(Node n | not exists(n.toString())) and - msg = "Nodes without toString: " + c - ) - } - - query predicate parameterCallable(ParameterNode p, string msg) { - exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and - msg = "Callable mismatch for parameter." - } - - query predicate localFlowIsLocal(Node n1, Node n2, string msg) { - simpleLocalFlowStep(n1, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Local flow step does not preserve enclosing callable." - } - - query predicate readStepIsLocal(Node n1, Node n2, string msg) { - readStep(n1, _, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Read step does not preserve enclosing callable." - } - - query predicate storeStepIsLocal(Node n1, Node n2, string msg) { - storeStep(n1, _, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Store step does not preserve enclosing callable." - } - - private DataFlowType typeRepr() { result = getNodeType(_) } - - query predicate compatibleTypesReflexive(DataFlowType t, string msg) { - t = typeRepr() and - not compatibleTypes(t, t) and - msg = "Type compatibility predicate is not reflexive." - } - - query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) { - isUnreachableInCall(n, call) and - exists(DataFlowCallable c | - c = nodeGetEnclosingCallable(n) and - not viableCallable(call) = c - ) and - msg = "Call context for isUnreachableInCall is inconsistent with call graph." - } - - query predicate localCallNodes(DataFlowCall call, Node n, string msg) { - ( - n = getAnOutNode(call, _) and - msg = "OutNode and call does not share enclosing callable." - or - n.(ArgumentNode).argumentOf(call, _) and - msg = "ArgumentNode and call does not share enclosing callable." - ) and - nodeGetEnclosingCallable(n) != call.getEnclosingCallable() - } - - // This predicate helps the compiler forget that in some languages - // it is impossible for a result of `getPreUpdateNode` to be an - // instance of `PostUpdateNode`. - private Node getPre(PostUpdateNode n) { - result = n.getPreUpdateNode() + predicate argHasPostUpdateExclude(ArgumentNode n) { + exists(ArgumentPosition apos | n.argumentOf(_, apos) and apos.isStarArgs(_)) or - none() + exists(ArgumentPosition apos | n.argumentOf(_, apos) and apos.isDictSplat()) } - query predicate postIsNotPre(PostUpdateNode n, string msg) { - getPre(n) = n and - msg = "PostUpdateNode should not equal its pre-update node." + predicate reverseReadExclude(Node n) { + // since `self`/`cls` parameters can be marked as implicit argument to `super()`, + // they will have PostUpdateNodes. We have a read-step from the synthetic `**kwargs` + // parameter, but dataflow-consistency queries should _not_ complain about there not + // being a post-update node for the synthetic `**kwargs` parameter. + n instanceof SynthDictSplatParameterNode } - query predicate postHasUniquePre(PostUpdateNode n, string msg) { - not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and - exists(int c | - c = count(n.getPreUpdateNode()) and - c != 1 and - msg = "PostUpdateNode should have one pre-update node but has " + c + "." + predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { + // For normal parameters that can both be passed as positional arguments or keyword + // arguments, we currently have parameter positions for both cases.. + // + // TODO: Figure out how bad breaking this consistency check is + exists(Function func, Parameter param | + c.getScope() = func and + p = parameterNode(param) and + c.getParameter(pos) = p and + param = func.getArg(_) and + param = func.getArgByName(_) ) } - query predicate uniquePostUpdate(Node n, string msg) { - not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and - 1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and - msg = "Node has multiple PostUpdateNodes." + predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { + not exists(call.getLocation().getFile().getRelativePath()) } - query predicate postIsInSameCallable(PostUpdateNode n, string msg) { - nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and - msg = "PostUpdateNode does not share callable with its pre-update node." - } - - private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) } - - query predicate reverseRead(Node n, string msg) { - exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and - not any(ConsistencyConfiguration conf).reverseReadExclude(n) and - msg = "Origin of readStep is missing a PostUpdateNode." - } - - query predicate argHasPostUpdate(ArgumentNode n, string msg) { - not hasPost(n) and - not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and - msg = "ArgumentNode is missing PostUpdateNode." - } - - // This predicate helps the compiler forget that in some languages - // it is impossible for a `PostUpdateNode` to be the target of - // `simpleLocalFlowStep`. - private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() } - - query predicate postWithInFlow(Node n, string msg) { - isPostUpdateNode(n) and - not clearsContent(n, _) and - simpleLocalFlowStep(_, n) and - not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and - msg = "PostUpdateNode should not be the target of local flow." - } - - query predicate viableImplInCallContextTooLarge( - DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable - ) { - callable = viableImplInCallContext(call, ctx) and - not callable = viableCallable(call) and - not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable) - } - - query predicate uniqueParameterNodeAtPosition( - DataFlowCallable c, ParameterPosition pos, Node p, string msg - ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and - isParameterNode(p, c, pos) and - not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and - msg = "Parameters with overlapping positions." - } - - query predicate uniqueParameterNodePosition( - DataFlowCallable c, ParameterPosition pos, Node p, string msg - ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and - isParameterNode(p, c, pos) and - not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and - msg = "Parameter node with multiple positions." - } - - query predicate uniqueContentApprox(Content c, string msg) { - not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and - msg = "Non-unique content approximation." - } - - query predicate identityLocalStep(Node n, string msg) { - simpleLocalFlowStep(n, n) and - not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and - msg = "Node steps to itself" + predicate identityLocalStepExclude(Node n) { + not exists(n.getLocation().getFile().getRelativePath()) } } + +module Consistency = MakeConsistency; diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll index 390c9738cc3..a39ffc27e87 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionCustomizations.qll @@ -9,6 +9,7 @@ private import semmle.python.dataflow.new.DataFlow private import semmle.python.dataflow.new.TaintTracking private import CommandInjectionCustomizations::CommandInjection as CommandInjection private import semmle.python.Concepts as Concepts +private import semmle.python.ApiGraphs /** * Module containing sources, sinks, and sanitizers for shell command constructed from library input. @@ -17,6 +18,9 @@ module UnsafeShellCommandConstruction { /** A source for shell command constructed from library input vulnerabilities. */ abstract class Source extends DataFlow::Node { } + /** A sanitizer for shell command constructed from library input vulnerabilities. */ + abstract class Sanitizer extends DataFlow::Node { } + private import semmle.python.frameworks.Setuptools /** An input parameter to a gem seen as a source. */ @@ -156,4 +160,13 @@ module UnsafeShellCommandConstruction { override DataFlow::Node getStringConstruction() { result = formatCall } } + + /** + * A call to `shlex.quote`, considered as a sanitizer. + */ + class ShlexQuoteAsSanitizer extends Sanitizer, DataFlow::Node { + ShlexQuoteAsSanitizer() { + this = API::moduleImport("shlex").getMember("quote").getACall().getArg(0) + } + } } diff --git a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll index 0d9ebb8a472..80781a97ac6 100644 --- a/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll +++ b/python/ql/lib/semmle/python/security/dataflow/UnsafeShellCommandConstructionQuery.qll @@ -24,7 +24,8 @@ class Configuration extends TaintTracking::Configuration { override predicate isSink(DataFlow::Node sink) { sink instanceof Sink } override predicate isSanitizer(DataFlow::Node node) { - node instanceof CommandInjection::Sanitizer // using all sanitizers from `rb/command-injection` + node instanceof Sanitizer or + node instanceof CommandInjection::Sanitizer // using all sanitizers from `py/command-injection` } // override to require the path doesn't have unmatched return steps diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index d8bc409ff86..2cd732792f6 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.8.4 + +### Minor Analysis Improvements + +* Improved _Reflected server-side cross-site scripting_ (`py/reflective-xss`) query to not alert on data passed to `flask.jsonify`. Since these HTTP responses are returned with mime-type `application/json`, they do not pose a security risk for XSS. +* Updated path explanations for `@kind path-problem` queries to always include left hand side of assignments, making paths easier to understand. + ## 0.8.3 No user-facing changes. diff --git a/python/ql/src/change-notes/2023-08-17-improved-path-graph.md b/python/ql/src/change-notes/2023-08-17-improved-path-graph.md deleted file mode 100644 index a2545d362e9..00000000000 --- a/python/ql/src/change-notes/2023-08-17-improved-path-graph.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Updated path explanations for `@kind path-problem` queries to always include left hand side of assignments, making paths easier to understand. diff --git a/python/ql/src/change-notes/2023-08-29-fixed-jsonify-xss-fp.md b/python/ql/src/change-notes/released/0.8.4.md similarity index 56% rename from python/ql/src/change-notes/2023-08-29-fixed-jsonify-xss-fp.md rename to python/ql/src/change-notes/released/0.8.4.md index 8268f296606..223f2a83361 100644 --- a/python/ql/src/change-notes/2023-08-29-fixed-jsonify-xss-fp.md +++ b/python/ql/src/change-notes/released/0.8.4.md @@ -1,4 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.8.4 + +### Minor Analysis Improvements + * Improved _Reflected server-side cross-site scripting_ (`py/reflective-xss`) query to not alert on data passed to `flask.jsonify`. Since these HTTP responses are returned with mime-type `application/json`, they do not pose a security risk for XSS. +* Updated path explanations for `@kind path-problem` queries to always include left hand side of assignments, making paths easier to understand. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index b6e46394f37..32eff3dc9f3 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.8.3 +lastReleaseVersion: 0.8.4 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index f7ff3ff2348..37fb0ca7969 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 0.8.4-dev +version: 0.8.4 groups: - python - queries diff --git a/python/ql/test/experimental/dataflow/TestUtil/DataFlowConsistency.qll b/python/ql/test/experimental/dataflow/TestUtil/DataFlowConsistency.qll index fd56070f86b..76ddc3643f1 100644 --- a/python/ql/test/experimental/dataflow/TestUtil/DataFlowConsistency.qll +++ b/python/ql/test/experimental/dataflow/TestUtil/DataFlowConsistency.qll @@ -1,46 +1,6 @@ +// TODO: this should be promoted to be a REAL consistency query by being placed in +// `python/ql/consistency-queries`. For for now it resides here. import python import semmle.python.dataflow.new.DataFlow::DataFlow import semmle.python.dataflow.new.internal.DataFlowPrivate import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency - -// TODO: this should be promoted to be a REAL consistency query by being placed in -// `python/ql/consistency-queries`. For for now it resides here. -private class MyConsistencyConfiguration extends ConsistencyConfiguration { - override predicate argHasPostUpdateExclude(ArgumentNode n) { - exists(ArgumentPosition apos | n.argumentOf(_, apos) and apos.isStarArgs(_)) - or - exists(ArgumentPosition apos | n.argumentOf(_, apos) and apos.isDictSplat()) - } - - override predicate reverseReadExclude(Node n) { - // since `self`/`cls` parameters can be marked as implicit argument to `super()`, - // they will have PostUpdateNodes. We have a read-step from the synthetic `**kwargs` - // parameter, but dataflow-consistency queries should _not_ complain about there not - // being a post-update node for the synthetic `**kwargs` parameter. - n instanceof SynthDictSplatParameterNode - } - - override predicate uniqueParameterNodePositionExclude( - DataFlowCallable c, ParameterPosition pos, Node p - ) { - // For normal parameters that can both be passed as positional arguments or keyword - // arguments, we currently have parameter positions for both cases.. - // - // TODO: Figure out how bad breaking this consistency check is - exists(Function func, Parameter param | - c.getScope() = func and - p = parameterNode(param) and - c.getParameter(pos) = p and - param = func.getArg(_) and - param = func.getArgByName(_) - ) - } - - override predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { - not exists(call.getLocation().getFile().getRelativePath()) - } - - override predicate identityLocalStepExclude(Node n) { - not exists(n.getLocation().getFile().getRelativePath()) - } -} diff --git a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/src/unsafe_shell_test.py b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/src/unsafe_shell_test.py index 1b4bc708c45..f491b93583d 100644 --- a/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/src/unsafe_shell_test.py +++ b/python/ql/test/query-tests/Security/CWE-078-UnsafeShellCommandConstruction/src/unsafe_shell_test.py @@ -46,4 +46,8 @@ def subprocess_flag (name): subprocess.Popen("ping " + name, shell=unknownValue) # OK - shell assumed to be False def intentional(command): - os.system("fish -ic " + command) # $result=OK - intentional \ No newline at end of file + os.system("fish -ic " + command) # $result=OK - intentional + +import shlex +def unsafe_shell_sanitized(name): + os.system("ping " + shlex.quote(name)) # $result=OK - sanitized \ No newline at end of file diff --git a/ql/Cargo.lock b/ql/Cargo.lock index c6d82f879f3..8d97ef2bcac 100644 Binary files a/ql/Cargo.lock and b/ql/Cargo.lock differ diff --git a/ql/buramu/Cargo.toml b/ql/buramu/Cargo.toml index 0f70891bade..2e3a662303a 100644 --- a/ql/buramu/Cargo.toml +++ b/ql/buramu/Cargo.toml @@ -7,6 +7,6 @@ edition = "2018" [dependencies] lazy_static = "1.4.0" -chrono = "0.4.27" +chrono = "0.4.28" rayon = "1.7.0" -regex = "1.9.3" +regex = "1.9.5" diff --git a/ql/extractor/Cargo.toml b/ql/extractor/Cargo.toml index f082d00f6f0..b90fc7ff61e 100644 --- a/ql/extractor/Cargo.toml +++ b/ql/extractor/Cargo.toml @@ -16,5 +16,5 @@ clap = { version = "4.2", features = ["derive"] } tracing = "0.1" tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } rayon = "1.7.0" -regex = "1.9.3" +regex = "1.9.5" codeql-extractor = { path = "../../shared/tree-sitter-extractor" } diff --git a/ruby/ql/consistency-queries/DataFlowConsistency.ql b/ruby/ql/consistency-queries/DataFlowConsistency.ql index 46384305f7a..6cf0fe9a282 100644 --- a/ruby/ql/consistency-queries/DataFlowConsistency.ql +++ b/ruby/ql/consistency-queries/DataFlowConsistency.ql @@ -1,13 +1,16 @@ -import codeql.ruby.AST -import codeql.ruby.CFG -import codeql.ruby.DataFlow::DataFlow -import codeql.ruby.dataflow.internal.DataFlowPrivate -import codeql.ruby.dataflow.internal.DataFlowImplConsistency::Consistency +import codeql.ruby.DataFlow::DataFlow as DataFlow +private import codeql.ruby.AST +private import codeql.ruby.CFG +private import codeql.ruby.dataflow.internal.DataFlowImplSpecific +private import codeql.ruby.dataflow.internal.TaintTrackingImplSpecific +private import codeql.dataflow.internal.DataFlowImplConsistency -private class MyConsistencyConfiguration extends ConsistencyConfiguration { - override predicate postWithInFlowExclude(Node n) { n instanceof FlowSummaryNode } +private module Input implements InputSig { + private import RubyDataFlow - override predicate argHasPostUpdateExclude(ArgumentNode n) { + predicate postWithInFlowExclude(Node n) { n instanceof FlowSummaryNode } + + predicate argHasPostUpdateExclude(ArgumentNode n) { n instanceof BlockArgumentNode or n instanceof FlowSummaryNode @@ -17,7 +20,7 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration { not isNonConstantExpr(getAPostUpdateNodeForArg(n.asExpr())) } - override predicate postHasUniquePreExclude(PostUpdateNode n) { + predicate postHasUniquePreExclude(PostUpdateNode n) { exists(CfgNodes::ExprCfgNode e, CfgNodes::ExprCfgNode arg | e = getAPostUpdateNodeForArg(arg) and e != arg and @@ -25,7 +28,7 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration { ) } - override predicate uniquePostUpdateExclude(Node n) { + predicate uniquePostUpdateExclude(Node n) { exists(CfgNodes::ExprCfgNode e, CfgNodes::ExprCfgNode arg | e = getAPostUpdateNodeForArg(arg) and e != arg and @@ -34,7 +37,9 @@ private class MyConsistencyConfiguration extends ConsistencyConfiguration { } } -query predicate multipleToString(Node n, string s) { +import MakeConsistency + +query predicate multipleToString(DataFlow::Node n, string s) { s = strictconcat(n.toString(), ",") and strictcount(n.toString()) > 1 } diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index ae92859730f..c9c03626ec3 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.7.4 + +No user-facing changes. + ## 0.7.3 ### Minor Analysis Improvements diff --git a/ruby/ql/lib/change-notes/released/0.7.4.md b/ruby/ql/lib/change-notes/released/0.7.4.md new file mode 100644 index 00000000000..1b33df9cb1e --- /dev/null +++ b/ruby/ql/lib/change-notes/released/0.7.4.md @@ -0,0 +1,3 @@ +## 0.7.4 + +No user-facing changes. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index a4ea9c8de17..e388f34b4ec 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.3 +lastReleaseVersion: 0.7.4 diff --git a/ruby/ql/lib/codeql/ruby/controlflow/ControlFlowGraph.qll b/ruby/ql/lib/codeql/ruby/controlflow/ControlFlowGraph.qll index 9a386369e91..3ff85f5553d 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/ControlFlowGraph.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/ControlFlowGraph.qll @@ -73,16 +73,14 @@ module SuccessorTypes { } /** - * A conditional control flow successor. Either a Boolean successor (`BooleanSuccessor`), - * an emptiness successor (`EmptinessSuccessor`), or a matching successor - * (`MatchingSuccessor`) + * A conditional control flow successor. Either a Boolean successor (`BooleanSuccessor`) + * or a matching successor (`MatchingSuccessor`) */ class ConditionalSuccessor extends SuccessorType { boolean value; ConditionalSuccessor() { this = CfgImpl::TBooleanSuccessor(value) or - this = CfgImpl::TEmptinessSuccessor(value) or this = CfgImpl::TMatchingSuccessor(value) } @@ -109,41 +107,6 @@ module SuccessorTypes { */ class BooleanSuccessor extends ConditionalSuccessor, CfgImpl::TBooleanSuccessor { } - /** - * An emptiness control flow successor. - * - * For example, this program fragment: - * - * ```rb - * for arg in args do - * puts arg - * end - * puts "done"; - * ``` - * - * has a control flow graph containing emptiness successors: - * - * ``` - * args - * | - * for------<----- - * / \ \ - * / \ | - * / \ | - * / \ | - * empty non-empty | - * | \ | - * puts "done" \ | - * arg | - * | | - * puts arg | - * \___/ - * ``` - */ - class EmptinessSuccessor extends ConditionalSuccessor, CfgImpl::TEmptinessSuccessor { - override string toString() { if value = true then result = "empty" else result = "non-empty" } - } - /** * A matching control flow successor. * diff --git a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll index c7a3b27afc8..0aa93e573eb 100644 --- a/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll +++ b/ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll @@ -1513,7 +1513,6 @@ private module Cached { newtype TSuccessorType = TSuccessorSuccessor() or TBooleanSuccessor(boolean b) { b in [false, true] } or - TEmptinessSuccessor(boolean isEmpty) { isEmpty in [false, true] } or TMatchingSuccessor(boolean isMatch) { isMatch in [false, true] } or TReturnSuccessor() or TBreakSuccessor() or diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplConsistency.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplConsistency.qll deleted file mode 100644 index e154491f795..00000000000 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplConsistency.qll +++ /dev/null @@ -1,299 +0,0 @@ -/** - * Provides consistency queries for checking invariants in the language-specific - * data-flow classes and predicates. - */ - -private import DataFlowImplSpecific::Private -private import DataFlowImplSpecific::Public -private import tainttracking1.TaintTrackingParameter::Private -private import tainttracking1.TaintTrackingParameter::Public - -module Consistency { - private newtype TConsistencyConfiguration = MkConsistencyConfiguration() - - /** A class for configuring the consistency queries. */ - class ConsistencyConfiguration extends TConsistencyConfiguration { - string toString() { none() } - - /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */ - predicate uniqueEnclosingCallableExclude(Node n) { none() } - - /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */ - predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() } - - /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */ - predicate uniqueNodeLocationExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `missingLocation`. */ - predicate missingLocationExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */ - predicate postWithInFlowExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */ - predicate argHasPostUpdateExclude(ArgumentNode n) { none() } - - /** Holds if `n` should be excluded from the consistency test `reverseRead`. */ - predicate reverseReadExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */ - predicate postHasUniquePreExclude(PostUpdateNode n) { none() } - - /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */ - predicate uniquePostUpdateExclude(Node n) { none() } - - /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */ - predicate viableImplInCallContextTooLargeExclude( - DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable - ) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */ - predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */ - predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */ - predicate identityLocalStepExclude(Node n) { none() } - } - - private class RelevantNode extends Node { - RelevantNode() { - this instanceof ArgumentNode or - this instanceof ParameterNode or - this instanceof ReturnNode or - this = getAnOutNode(_, _) or - simpleLocalFlowStep(this, _) or - simpleLocalFlowStep(_, this) or - jumpStep(this, _) or - jumpStep(_, this) or - storeStep(this, _, _) or - storeStep(_, _, this) or - readStep(this, _, _) or - readStep(_, _, this) or - defaultAdditionalTaintStep(this, _) or - defaultAdditionalTaintStep(_, this) - } - } - - query predicate uniqueEnclosingCallable(Node n, string msg) { - exists(int c | - n instanceof RelevantNode and - c = count(nodeGetEnclosingCallable(n)) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and - msg = "Node should have one enclosing callable but has " + c + "." - ) - } - - query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) { - exists(int c | - c = count(call.getEnclosingCallable()) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and - msg = "Call should have one enclosing callable but has " + c + "." - ) - } - - query predicate uniqueType(Node n, string msg) { - exists(int c | - n instanceof RelevantNode and - c = count(getNodeType(n)) and - c != 1 and - msg = "Node should have one type but has " + c + "." - ) - } - - query predicate uniqueNodeLocation(Node n, string msg) { - exists(int c | - c = - count(string filepath, int startline, int startcolumn, int endline, int endcolumn | - n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - ) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and - msg = "Node should have one location but has " + c + "." - ) - } - - query predicate missingLocation(string msg) { - exists(int c | - c = - strictcount(Node n | - not n.hasLocationInfo(_, _, _, _, _) and - not any(ConsistencyConfiguration conf).missingLocationExclude(n) - ) and - msg = "Nodes without location: " + c - ) - } - - query predicate uniqueNodeToString(Node n, string msg) { - exists(int c | - c = count(n.toString()) and - c != 1 and - msg = "Node should have one toString but has " + c + "." - ) - } - - query predicate missingToString(string msg) { - exists(int c | - c = strictcount(Node n | not exists(n.toString())) and - msg = "Nodes without toString: " + c - ) - } - - query predicate parameterCallable(ParameterNode p, string msg) { - exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and - msg = "Callable mismatch for parameter." - } - - query predicate localFlowIsLocal(Node n1, Node n2, string msg) { - simpleLocalFlowStep(n1, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Local flow step does not preserve enclosing callable." - } - - query predicate readStepIsLocal(Node n1, Node n2, string msg) { - readStep(n1, _, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Read step does not preserve enclosing callable." - } - - query predicate storeStepIsLocal(Node n1, Node n2, string msg) { - storeStep(n1, _, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Store step does not preserve enclosing callable." - } - - private DataFlowType typeRepr() { result = getNodeType(_) } - - query predicate compatibleTypesReflexive(DataFlowType t, string msg) { - t = typeRepr() and - not compatibleTypes(t, t) and - msg = "Type compatibility predicate is not reflexive." - } - - query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) { - isUnreachableInCall(n, call) and - exists(DataFlowCallable c | - c = nodeGetEnclosingCallable(n) and - not viableCallable(call) = c - ) and - msg = "Call context for isUnreachableInCall is inconsistent with call graph." - } - - query predicate localCallNodes(DataFlowCall call, Node n, string msg) { - ( - n = getAnOutNode(call, _) and - msg = "OutNode and call does not share enclosing callable." - or - n.(ArgumentNode).argumentOf(call, _) and - msg = "ArgumentNode and call does not share enclosing callable." - ) and - nodeGetEnclosingCallable(n) != call.getEnclosingCallable() - } - - // This predicate helps the compiler forget that in some languages - // it is impossible for a result of `getPreUpdateNode` to be an - // instance of `PostUpdateNode`. - private Node getPre(PostUpdateNode n) { - result = n.getPreUpdateNode() - or - none() - } - - query predicate postIsNotPre(PostUpdateNode n, string msg) { - getPre(n) = n and - msg = "PostUpdateNode should not equal its pre-update node." - } - - query predicate postHasUniquePre(PostUpdateNode n, string msg) { - not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and - exists(int c | - c = count(n.getPreUpdateNode()) and - c != 1 and - msg = "PostUpdateNode should have one pre-update node but has " + c + "." - ) - } - - query predicate uniquePostUpdate(Node n, string msg) { - not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and - 1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and - msg = "Node has multiple PostUpdateNodes." - } - - query predicate postIsInSameCallable(PostUpdateNode n, string msg) { - nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and - msg = "PostUpdateNode does not share callable with its pre-update node." - } - - private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) } - - query predicate reverseRead(Node n, string msg) { - exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and - not any(ConsistencyConfiguration conf).reverseReadExclude(n) and - msg = "Origin of readStep is missing a PostUpdateNode." - } - - query predicate argHasPostUpdate(ArgumentNode n, string msg) { - not hasPost(n) and - not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and - msg = "ArgumentNode is missing PostUpdateNode." - } - - // This predicate helps the compiler forget that in some languages - // it is impossible for a `PostUpdateNode` to be the target of - // `simpleLocalFlowStep`. - private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() } - - query predicate postWithInFlow(Node n, string msg) { - isPostUpdateNode(n) and - not clearsContent(n, _) and - simpleLocalFlowStep(_, n) and - not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and - msg = "PostUpdateNode should not be the target of local flow." - } - - query predicate viableImplInCallContextTooLarge( - DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable - ) { - callable = viableImplInCallContext(call, ctx) and - not callable = viableCallable(call) and - not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable) - } - - query predicate uniqueParameterNodeAtPosition( - DataFlowCallable c, ParameterPosition pos, Node p, string msg - ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and - isParameterNode(p, c, pos) and - not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and - msg = "Parameters with overlapping positions." - } - - query predicate uniqueParameterNodePosition( - DataFlowCallable c, ParameterPosition pos, Node p, string msg - ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and - isParameterNode(p, c, pos) and - not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and - msg = "Parameter node with multiple positions." - } - - query predicate uniqueContentApprox(Content c, string msg) { - not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and - msg = "Non-unique content approximation." - } - - query predicate identityLocalStep(Node n, string msg) { - simpleLocalFlowStep(n, n) and - not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and - msg = "Node steps to itself" - } -} diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index e50377dfb13..7f512644e8d 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 0.7.4-dev +version: 0.7.4 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index 9e85e2317d3..2bc373cd332 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.7.4 + +### New Queries + +* Added a new experimental query, `rb/improper-ldap-auth`, to detect cases where user input is used during LDAP authentication without proper validation or sanitization, potentially leading to authentication bypass. + ## 0.7.3 No user-facing changes. diff --git a/ruby/ql/src/change-notes/2023-05-29-improper-ldap-auth-query.md b/ruby/ql/src/change-notes/released/0.7.4.md similarity index 88% rename from ruby/ql/src/change-notes/2023-05-29-improper-ldap-auth-query.md rename to ruby/ql/src/change-notes/released/0.7.4.md index 13c5a89c808..228683b8a68 100644 --- a/ruby/ql/src/change-notes/2023-05-29-improper-ldap-auth-query.md +++ b/ruby/ql/src/change-notes/released/0.7.4.md @@ -1,4 +1,5 @@ ---- -category: newQuery ---- +## 0.7.4 + +### New Queries + * Added a new experimental query, `rb/improper-ldap-auth`, to detect cases where user input is used during LDAP authentication without proper validation or sanitization, potentially leading to authentication bypass. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index a4ea9c8de17..e388f34b4ec 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.7.3 +lastReleaseVersion: 0.7.4 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 441effac827..92a6a245e19 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 0.7.4-dev +version: 0.7.4 groups: - ruby - queries diff --git a/shared/controlflow/CHANGELOG.md b/shared/controlflow/CHANGELOG.md index aab63b11f75..b6f5cd028e2 100644 --- a/shared/controlflow/CHANGELOG.md +++ b/shared/controlflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.3 + +No user-facing changes. + ## 0.0.2 No user-facing changes. diff --git a/shared/controlflow/change-notes/released/0.0.3.md b/shared/controlflow/change-notes/released/0.0.3.md new file mode 100644 index 00000000000..af7864fc7d5 --- /dev/null +++ b/shared/controlflow/change-notes/released/0.0.3.md @@ -0,0 +1,3 @@ +## 0.0.3 + +No user-facing changes. diff --git a/shared/controlflow/codeql-pack.release.yml b/shared/controlflow/codeql-pack.release.yml index 55dc06fbd76..a24b693d1e7 100644 --- a/shared/controlflow/codeql-pack.release.yml +++ b/shared/controlflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.2 +lastReleaseVersion: 0.0.3 diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index 90520957d85..08806425df6 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 0.0.3-dev +version: 0.0.3 groups: shared library: true dependencies: diff --git a/shared/dataflow/CHANGELOG.md b/shared/dataflow/CHANGELOG.md index 1a5f4d38663..7ab03105cb7 100644 --- a/shared/dataflow/CHANGELOG.md +++ b/shared/dataflow/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.0.3 + +### New Features + +* The various inline flow test libraries have been consolidated as a shared library part in the dataflow qlpack. + +### Minor Analysis Improvements + +* The shared taint-tracking library is now part of the dataflow qlpack. + ## 0.0.2 ### Major Analysis Improvements diff --git a/shared/dataflow/change-notes/2023-08-04-taint-tracking.md b/shared/dataflow/change-notes/2023-08-04-taint-tracking.md deleted file mode 100644 index 000d7ea265c..00000000000 --- a/shared/dataflow/change-notes/2023-08-04-taint-tracking.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The shared taint-tracking library is now part of the dataflow qlpack. diff --git a/shared/dataflow/change-notes/2023-08-24-inline-flow-test.md b/shared/dataflow/change-notes/2023-08-24-inline-flow-test.md deleted file mode 100644 index 4f879df3fd3..00000000000 --- a/shared/dataflow/change-notes/2023-08-24-inline-flow-test.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: feature ---- -* The various inline flow test libraries have been consolidated as a shared library part in the dataflow qlpack. diff --git a/shared/dataflow/change-notes/released/0.0.3.md b/shared/dataflow/change-notes/released/0.0.3.md new file mode 100644 index 00000000000..4b6ac03adc1 --- /dev/null +++ b/shared/dataflow/change-notes/released/0.0.3.md @@ -0,0 +1,9 @@ +## 0.0.3 + +### New Features + +* The various inline flow test libraries have been consolidated as a shared library part in the dataflow qlpack. + +### Minor Analysis Improvements + +* The shared taint-tracking library is now part of the dataflow qlpack. diff --git a/shared/dataflow/codeql-pack.release.yml b/shared/dataflow/codeql-pack.release.yml index 55dc06fbd76..a24b693d1e7 100644 --- a/shared/dataflow/codeql-pack.release.yml +++ b/shared/dataflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.2 +lastReleaseVersion: 0.0.3 diff --git a/shared/dataflow/codeql/dataflow/VariableCapture.qll b/shared/dataflow/codeql/dataflow/VariableCapture.qll index c94e06b8731..4a68f0563bc 100644 --- a/shared/dataflow/codeql/dataflow/VariableCapture.qll +++ b/shared/dataflow/codeql/dataflow/VariableCapture.qll @@ -95,9 +95,6 @@ signature module InputSig { /** Gets the variable that is the target of this write. */ CapturedVariable getVariable(); - /** Gets the expression that is the source of this write. */ - Expr getSource(); - /** Gets the location of this write. */ Location getLocation(); @@ -210,6 +207,22 @@ signature module OutputSig { I::ClosureExpr getClosureExpr(); } + /** + * A node representing the incoming value about to be written at the given assignment. + * + * The captured-variable library will generate flows out of this node, and assume that other + * parts of the language implementation produce the relevant data flows into this node. + * + * For ordinary assignments, this could be mapped to the right-hand side of the assignment. + * + * For more general cases, where an lvalue has no direct corresponding rvalue, this can be mapped + * to a data-flow node that wraps the lvalue, with language-specific incoming data flows. + */ + class VariableWriteSourceNode extends ClosureNode { + /** Gets the variable write for which this node is the incoming value being written to the variable. */ + I::VariableWrite getVariableWrite(); + } + /** Holds if `post` is a `PostUpdateNode` for `pre`. */ predicate capturePostUpdateNode(SynthesizedCaptureNode post, SynthesizedCaptureNode pre); @@ -239,7 +252,6 @@ module Flow implements OutputSig { private class RelevantExpr extends FinalExpr { RelevantExpr() { this instanceof VariableRead or - any(VariableWrite vw).getSource() = this or this instanceof ClosureExpr or any(ClosureExpr ce).hasAliasedAccess(this) } @@ -353,14 +365,6 @@ module Flow implements OutputSig { query predicate uniqueWriteTarget(string msg) { uniqueWriteTarget(_, msg) } - private predicate uniqueWriteSource(VariableWrite vw, string msg) { - msg = "VariableWrite has no source expression" and not exists(vw.getSource()) - or - msg = "VariableWrite has multiple source expressions" and 2 <= strictcount(vw.getSource()) - } - - query predicate uniqueWriteSource(string msg) { uniqueWriteSource(_, msg) } - private predicate uniqueWriteCfgNode(VariableWrite vw, string msg) { msg = "VariableWrite has no cfg node" and not vw.hasCfgNode(_, _) or @@ -370,17 +374,6 @@ module Flow implements OutputSig { query predicate uniqueWriteCfgNode(string msg) { uniqueWriteCfgNode(_, msg) } - private predicate localWriteStep(VariableWrite vw, string msg) { - exists(BasicBlock bb1, BasicBlock bb2 | - vw.hasCfgNode(bb1, _) and - vw.getSource().hasCfgNode(bb2, _) and - bb1.getEnclosingCallable() != bb2.getEnclosingCallable() and - msg = "VariableWrite is not a local step" - ) - } - - query predicate localWriteStep(string msg) { localWriteStep(_, msg) } - query predicate uniqueReadVariable(VariableRead vr, string msg) { msg = "VariableRead has no source variable" and not exists(vr.getVariable()) or @@ -436,9 +429,7 @@ module Flow implements OutputSig { n = strictcount(Expr e | uniqueLocation(e, msg)) or n = strictcount(Expr e | uniqueCfgNode(e, msg)) or n = strictcount(VariableWrite vw | uniqueWriteTarget(vw, msg)) or - n = strictcount(VariableWrite vw | uniqueWriteSource(vw, msg)) or n = strictcount(VariableWrite vw | uniqueWriteCfgNode(vw, msg)) or - n = strictcount(VariableWrite vw | localWriteStep(vw, msg)) or n = strictcount(VariableRead vr | uniqueReadVariable(vr, msg)) or n = strictcount(ClosureExpr ce | closureMustHaveBody(ce, msg)) or n = strictcount(ClosureExpr ce, Expr access | closureAliasMustBeInSameScope(ce, access, msg)) or @@ -719,13 +710,12 @@ module Flow implements OutputSig { TExprNode(Expr expr, boolean isPost) { expr instanceof VariableRead and isPost = [false, true] or - exists(VariableWrite vw | expr = vw.getSource() and isPost = false) - or synthRead(_, _, _, _, expr) and isPost = [false, true] } or TParamNode(CapturedParameter p) or TThisParamNode(Callable c) { captureAccess(_, c) } or - TMallocNode(ClosureExpr ce) { hasConstructorCapture(ce, _) } + TMallocNode(ClosureExpr ce) { hasConstructorCapture(ce, _) } or + TVariableWriteSourceNode(VariableWrite write) class ClosureNode extends TClosureNode { /** Gets a textual representation of this node. */ @@ -751,6 +741,11 @@ module Flow implements OutputSig { result = "this" and this = TThisParamNode(_) or result = "malloc" and this = TMallocNode(_) + or + exists(VariableWrite write | + this = TVariableWriteSourceNode(write) and + result = "Source of write to " + write.getVariable().toString() + ) } /** Gets the location of this node. */ @@ -778,6 +773,10 @@ module Flow implements OutputSig { exists(Callable c | this = TThisParamNode(c) and result = c.getLocation()) or exists(ClosureExpr ce | this = TMallocNode(ce) and result = ce.getLocation()) + or + exists(VariableWrite write | + this = TVariableWriteSourceNode(write) and result = write.getLocation() + ) } } @@ -837,6 +836,10 @@ module Flow implements OutputSig { ClosureExpr getClosureExpr() { this = TMallocNode(result) } } + class VariableWriteSourceNode extends ClosureNode, TVariableWriteSourceNode { + VariableWrite getVariableWrite() { this = TVariableWriteSourceNode(result) } + } + predicate capturePostUpdateNode(SynthesizedCaptureNode post, SynthesizedCaptureNode pre) { exists(CapturedVariable v, BasicBlock bb, int i | pre = TSynthRead(v, bb, i, false) and post = TSynthRead(v, bb, i, true) @@ -881,7 +884,7 @@ module Flow implements OutputSig { or exists(VariableWrite vw, CapturedVariable v | captureWrite(v, bb, i, true, vw) and - n = TExprNode(vw.getSource(), false) and + n = TVariableWriteSourceNode(vw) and isPost = false and cc = TVariable(v) ) @@ -928,7 +931,7 @@ module Flow implements OutputSig { // write to v inside the closure body exists(BasicBlock bb, int i, VariableWrite vw | captureWrite(v, bb, i, false, vw) and - node1 = TExprNode(vw.getSource(), false) and + node1 = TVariableWriteSourceNode(vw) and node2 = TSynthThisQualifier(bb, i, true) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll b/shared/dataflow/codeql/dataflow/internal/DataFlowImplConsistency.qll similarity index 60% rename from csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll rename to shared/dataflow/codeql/dataflow/internal/DataFlowImplConsistency.qll index e154491f795..a24f8ab794a 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplConsistency.qll +++ b/shared/dataflow/codeql/dataflow/internal/DataFlowImplConsistency.qll @@ -3,67 +3,73 @@ * data-flow classes and predicates. */ -private import DataFlowImplSpecific::Private -private import DataFlowImplSpecific::Public -private import tainttracking1.TaintTrackingParameter::Private -private import tainttracking1.TaintTrackingParameter::Public +private import codeql.dataflow.DataFlow as DF +private import codeql.dataflow.TaintTracking as TT -module Consistency { - private newtype TConsistencyConfiguration = MkConsistencyConfiguration() +signature module InputSig { + /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */ + default predicate uniqueEnclosingCallableExclude(DataFlowLang::Node n) { none() } - /** A class for configuring the consistency queries. */ - class ConsistencyConfiguration extends TConsistencyConfiguration { - string toString() { none() } + /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */ + default predicate uniqueCallEnclosingCallableExclude(DataFlowLang::DataFlowCall call) { none() } - /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */ - predicate uniqueEnclosingCallableExclude(Node n) { none() } + /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */ + default predicate uniqueNodeLocationExclude(DataFlowLang::Node n) { none() } - /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */ - predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() } + /** Holds if `n` should be excluded from the consistency test `missingLocation`. */ + default predicate missingLocationExclude(DataFlowLang::Node n) { none() } - /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */ - predicate uniqueNodeLocationExclude(Node n) { none() } + /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */ + default predicate postWithInFlowExclude(DataFlowLang::Node n) { none() } - /** Holds if `n` should be excluded from the consistency test `missingLocation`. */ - predicate missingLocationExclude(Node n) { none() } + /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */ + default predicate argHasPostUpdateExclude(DataFlowLang::ArgumentNode n) { none() } - /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */ - predicate postWithInFlowExclude(Node n) { none() } + /** Holds if `n` should be excluded from the consistency test `reverseRead`. */ + default predicate reverseReadExclude(DataFlowLang::Node n) { none() } - /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */ - predicate argHasPostUpdateExclude(ArgumentNode n) { none() } + /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */ + default predicate postHasUniquePreExclude(DataFlowLang::PostUpdateNode n) { none() } - /** Holds if `n` should be excluded from the consistency test `reverseRead`. */ - predicate reverseReadExclude(Node n) { none() } + /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */ + default predicate uniquePostUpdateExclude(DataFlowLang::Node n) { none() } - /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */ - predicate postHasUniquePreExclude(PostUpdateNode n) { none() } - - /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */ - predicate uniquePostUpdateExclude(Node n) { none() } - - /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */ - predicate viableImplInCallContextTooLargeExclude( - DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable - ) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */ - predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */ - predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */ - predicate identityLocalStepExclude(Node n) { none() } + /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */ + default predicate viableImplInCallContextTooLargeExclude( + DataFlowLang::DataFlowCall call, DataFlowLang::DataFlowCall ctx, + DataFlowLang::DataFlowCallable callable + ) { + none() } - private class RelevantNode extends Node { + /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */ + default predicate uniqueParameterNodeAtPositionExclude( + DataFlowLang::DataFlowCallable c, DataFlowLang::ParameterPosition pos, DataFlowLang::Node p + ) { + none() + } + + /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */ + default predicate uniqueParameterNodePositionExclude( + DataFlowLang::DataFlowCallable c, DataFlowLang::ParameterPosition pos, DataFlowLang::Node p + ) { + none() + } + + /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */ + default predicate identityLocalStepExclude(DataFlowLang::Node n) { none() } +} + +module MakeConsistency< + DF::InputSig DataFlowLang, TT::InputSig TaintTrackingLang, + InputSig Input> +{ + private import DataFlowLang + private import TaintTrackingLang + + final private class NodeFinal = Node; + + private class RelevantNode extends NodeFinal { RelevantNode() { this instanceof ArgumentNode or this instanceof ParameterNode or @@ -87,7 +93,7 @@ module Consistency { n instanceof RelevantNode and c = count(nodeGetEnclosingCallable(n)) and c != 1 and - not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and + not Input::uniqueEnclosingCallableExclude(n) and msg = "Node should have one enclosing callable but has " + c + "." ) } @@ -96,7 +102,7 @@ module Consistency { exists(int c | c = count(call.getEnclosingCallable()) and c != 1 and - not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and + not Input::uniqueCallEnclosingCallableExclude(call) and msg = "Call should have one enclosing callable but has " + c + "." ) } @@ -117,7 +123,7 @@ module Consistency { n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) ) and c != 1 and - not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and + not Input::uniqueNodeLocationExclude(n) and msg = "Node should have one location but has " + c + "." ) } @@ -127,7 +133,7 @@ module Consistency { c = strictcount(Node n | not n.hasLocationInfo(_, _, _, _, _) and - not any(ConsistencyConfiguration conf).missingLocationExclude(n) + not Input::missingLocationExclude(n) ) and msg = "Nodes without location: " + c ) @@ -193,28 +199,19 @@ module Consistency { n = getAnOutNode(call, _) and msg = "OutNode and call does not share enclosing callable." or - n.(ArgumentNode).argumentOf(call, _) and + isArgumentNode(n, call, _) and msg = "ArgumentNode and call does not share enclosing callable." ) and nodeGetEnclosingCallable(n) != call.getEnclosingCallable() } - // This predicate helps the compiler forget that in some languages - // it is impossible for a result of `getPreUpdateNode` to be an - // instance of `PostUpdateNode`. - private Node getPre(PostUpdateNode n) { - result = n.getPreUpdateNode() - or - none() - } - query predicate postIsNotPre(PostUpdateNode n, string msg) { - getPre(n) = n and + n = n.getPreUpdateNode() and msg = "PostUpdateNode should not equal its pre-update node." } query predicate postHasUniquePre(PostUpdateNode n, string msg) { - not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and + not Input::postHasUniquePreExclude(n) and exists(int c | c = count(n.getPreUpdateNode()) and c != 1 and @@ -223,7 +220,7 @@ module Consistency { } query predicate uniquePostUpdate(Node n, string msg) { - not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and + not Input::uniquePostUpdateExclude(n) and 1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and msg = "Node has multiple PostUpdateNodes." } @@ -237,26 +234,20 @@ module Consistency { query predicate reverseRead(Node n, string msg) { exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and - not any(ConsistencyConfiguration conf).reverseReadExclude(n) and + not Input::reverseReadExclude(n) and msg = "Origin of readStep is missing a PostUpdateNode." } query predicate argHasPostUpdate(ArgumentNode n, string msg) { not hasPost(n) and - not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and + not Input::argHasPostUpdateExclude(n) and msg = "ArgumentNode is missing PostUpdateNode." } - // This predicate helps the compiler forget that in some languages - // it is impossible for a `PostUpdateNode` to be the target of - // `simpleLocalFlowStep`. - private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() } - - query predicate postWithInFlow(Node n, string msg) { - isPostUpdateNode(n) and + query predicate postWithInFlow(PostUpdateNode n, string msg) { not clearsContent(n, _) and simpleLocalFlowStep(_, n) and - not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and + not Input::postWithInFlowExclude(n) and msg = "PostUpdateNode should not be the target of local flow." } @@ -265,13 +256,13 @@ module Consistency { ) { callable = viableImplInCallContext(call, ctx) and not callable = viableCallable(call) and - not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable) + not Input::viableImplInCallContextTooLargeExclude(call, ctx, callable) } query predicate uniqueParameterNodeAtPosition( DataFlowCallable c, ParameterPosition pos, Node p, string msg ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and + not Input::uniqueParameterNodeAtPositionExclude(c, pos, p) and isParameterNode(p, c, pos) and not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and msg = "Parameters with overlapping positions." @@ -280,7 +271,7 @@ module Consistency { query predicate uniqueParameterNodePosition( DataFlowCallable c, ParameterPosition pos, Node p, string msg ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and + not Input::uniqueParameterNodePositionExclude(c, pos, p) and isParameterNode(p, c, pos) and not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and msg = "Parameter node with multiple positions." @@ -293,7 +284,7 @@ module Consistency { query predicate identityLocalStep(Node n, string msg) { simpleLocalFlowStep(n, n) and - not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and + not Input::identityLocalStepExclude(n) and msg = "Node steps to itself" } } diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 62a35f1ccc8..0a15dee3ec6 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 0.0.3-dev +version: 0.0.3 groups: shared library: true dependencies: diff --git a/shared/mad/CHANGELOG.md b/shared/mad/CHANGELOG.md index 4c7b7dd6878..2bfa7916b94 100644 --- a/shared/mad/CHANGELOG.md +++ b/shared/mad/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.4 + +No user-facing changes. + ## 0.1.3 No user-facing changes. diff --git a/shared/mad/change-notes/released/0.1.4.md b/shared/mad/change-notes/released/0.1.4.md new file mode 100644 index 00000000000..a77c429adba --- /dev/null +++ b/shared/mad/change-notes/released/0.1.4.md @@ -0,0 +1,3 @@ +## 0.1.4 + +No user-facing changes. diff --git a/shared/mad/codeql-pack.release.yml b/shared/mad/codeql-pack.release.yml index b79d8f9d00a..e8ee3af8ef9 100644 --- a/shared/mad/codeql-pack.release.yml +++ b/shared/mad/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.3 +lastReleaseVersion: 0.1.4 diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index cf6c9c6ea7d..711f69baef6 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 0.1.4-dev +version: 0.1.4 groups: shared library: true dependencies: diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index 8cd409f9735..bcf4cdb469c 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.4 + +No user-facing changes. + ## 0.1.3 No user-facing changes. diff --git a/shared/regex/change-notes/released/0.1.4.md b/shared/regex/change-notes/released/0.1.4.md new file mode 100644 index 00000000000..a77c429adba --- /dev/null +++ b/shared/regex/change-notes/released/0.1.4.md @@ -0,0 +1,3 @@ +## 0.1.4 + +No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index b79d8f9d00a..e8ee3af8ef9 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.3 +lastReleaseVersion: 0.1.4 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index a30e17c4d96..9ae2aebd903 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 0.1.4-dev +version: 0.1.4 groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index 466f3f45326..175ecab1b6e 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.4 + +No user-facing changes. + ## 0.1.3 No user-facing changes. diff --git a/shared/ssa/change-notes/released/0.1.4.md b/shared/ssa/change-notes/released/0.1.4.md new file mode 100644 index 00000000000..a77c429adba --- /dev/null +++ b/shared/ssa/change-notes/released/0.1.4.md @@ -0,0 +1,3 @@ +## 0.1.4 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index b79d8f9d00a..e8ee3af8ef9 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.3 +lastReleaseVersion: 0.1.4 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 0db56594e86..22ca03d8047 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 0.1.4-dev +version: 0.1.4 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md index 0474ebe6865..01c61a97e76 100644 --- a/shared/tutorial/CHANGELOG.md +++ b/shared/tutorial/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.4 + +No user-facing changes. + ## 0.1.3 No user-facing changes. diff --git a/shared/tutorial/change-notes/released/0.1.4.md b/shared/tutorial/change-notes/released/0.1.4.md new file mode 100644 index 00000000000..a77c429adba --- /dev/null +++ b/shared/tutorial/change-notes/released/0.1.4.md @@ -0,0 +1,3 @@ +## 0.1.4 + +No user-facing changes. diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml index b79d8f9d00a..e8ee3af8ef9 100644 --- a/shared/tutorial/codeql-pack.release.yml +++ b/shared/tutorial/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.3 +lastReleaseVersion: 0.1.4 diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index 4beadd85122..520077ea1d5 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,6 +1,6 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 0.1.4-dev +version: 0.1.4 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md index ee0d1b59186..6a11a27cd0c 100644 --- a/shared/typetracking/CHANGELOG.md +++ b/shared/typetracking/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.4 + +No user-facing changes. + ## 0.1.3 No user-facing changes. diff --git a/shared/typetracking/change-notes/released/0.1.4.md b/shared/typetracking/change-notes/released/0.1.4.md new file mode 100644 index 00000000000..a77c429adba --- /dev/null +++ b/shared/typetracking/change-notes/released/0.1.4.md @@ -0,0 +1,3 @@ +## 0.1.4 + +No user-facing changes. diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml index b79d8f9d00a..e8ee3af8ef9 100644 --- a/shared/typetracking/codeql-pack.release.yml +++ b/shared/typetracking/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.3 +lastReleaseVersion: 0.1.4 diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 3505e8f33f1..e50be8d7635 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 0.1.4-dev +version: 0.1.4 groups: shared library: true dependencies: diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index a8f556aa029..675cc520f94 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.4 + +No user-facing changes. + ## 0.1.3 No user-facing changes. diff --git a/shared/typos/change-notes/released/0.1.4.md b/shared/typos/change-notes/released/0.1.4.md new file mode 100644 index 00000000000..a77c429adba --- /dev/null +++ b/shared/typos/change-notes/released/0.1.4.md @@ -0,0 +1,3 @@ +## 0.1.4 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index b79d8f9d00a..e8ee3af8ef9 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.3 +lastReleaseVersion: 0.1.4 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index ec757b0242c..2c8585faa48 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 0.1.4-dev +version: 0.1.4 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md index cf58b4ea37c..b42b17238e5 100644 --- a/shared/util/CHANGELOG.md +++ b/shared/util/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.4 + +No user-facing changes. + ## 0.1.3 No user-facing changes. diff --git a/shared/util/change-notes/released/0.1.4.md b/shared/util/change-notes/released/0.1.4.md new file mode 100644 index 00000000000..a77c429adba --- /dev/null +++ b/shared/util/change-notes/released/0.1.4.md @@ -0,0 +1,3 @@ +## 0.1.4 + +No user-facing changes. diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml index b79d8f9d00a..e8ee3af8ef9 100644 --- a/shared/util/codeql-pack.release.yml +++ b/shared/util/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.3 +lastReleaseVersion: 0.1.4 diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 24020172913..75eb3bf288a 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 0.1.4-dev +version: 0.1.4 groups: shared library: true dependencies: diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md index e41dc84c7c8..72ed00d14e3 100644 --- a/shared/yaml/CHANGELOG.md +++ b/shared/yaml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.4 + +No user-facing changes. + ## 0.1.3 ### New Features diff --git a/shared/yaml/change-notes/released/0.1.4.md b/shared/yaml/change-notes/released/0.1.4.md new file mode 100644 index 00000000000..a77c429adba --- /dev/null +++ b/shared/yaml/change-notes/released/0.1.4.md @@ -0,0 +1,3 @@ +## 0.1.4 + +No user-facing changes. diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml index b79d8f9d00a..e8ee3af8ef9 100644 --- a/shared/yaml/codeql-pack.release.yml +++ b/shared/yaml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.3 +lastReleaseVersion: 0.1.4 diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 58627ae3db8..e68ccfec57d 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 0.1.4-dev +version: 0.1.4 groups: shared library: true warnOnImplicitThis: true diff --git a/swift/BUILD.bazel b/swift/BUILD.bazel index 83dff3f8033..57b828ef350 100644 --- a/swift/BUILD.bazel +++ b/swift/BUILD.bazel @@ -1,4 +1,4 @@ -load("@rules_pkg//:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files", "strip_prefix") +load("@rules_pkg//:mappings.bzl", "pkg_filegroup", "pkg_files", "strip_prefix") load("@rules_pkg//:install.bzl", "pkg_install") load("//:defs.bzl", "codeql_platform") load("//misc/bazel:pkg_runfiles.bzl", "pkg_runfiles") @@ -57,8 +57,8 @@ pkg_filegroup( ) pkg_runfiles( - name = "xcode-autobuilder", - srcs = ["//swift/xcode-autobuilder"], + name = "swift-autobuilder", + srcs = ["//swift/swift-autobuilder"], prefix = "tools/" + codeql_platform, ) @@ -93,7 +93,7 @@ pkg_filegroup( ], }) + select({ "@platforms//os:macos": [ - ":xcode-autobuilder", + ":swift-autobuilder", ], "//conditions:default": [ ":diagnostics", @@ -130,7 +130,7 @@ generate_cmake( "//swift/logging/tests/assertion-diagnostics:assert-false", ] + select({ "@platforms//os:linux": ["//swift/tools/diagnostics:autobuilder-incompatible-os"], - "@platforms//os:macos": ["//swift/xcode-autobuilder"], + "@platforms//os:macos": ["//swift/swift-autobuilder"], }), visibility = ["//visibility:public"], ) diff --git a/swift/extractor/translators/ExprTranslator.cpp b/swift/extractor/translators/ExprTranslator.cpp index 22c0c7bf797..3274c49675e 100644 --- a/swift/extractor/translators/ExprTranslator.cpp +++ b/swift/extractor/translators/ExprTranslator.cpp @@ -460,7 +460,17 @@ codeql::UnresolvedMemberExpr ExprTranslator::translateUnresolvedMemberExpr( codeql::SequenceExpr ExprTranslator::translateSequenceExpr(const swift::SequenceExpr& expr) { auto entry = createExprEntry(expr); - entry.elements = dispatcher.fetchRepeatedLabels(expr.getElements()); + // SequenceExpr represents a flat tree of expressions with elements at odd indices being the + // parents of the elements with even indices, so we only extract the "parent" elements here. In + // case there is a single child, we extract it as a parent. See + // https://github.com/github/codeql/pull/14119 and commit message for more details. + if (expr.getNumElements() == 1) { + entry.elements = dispatcher.fetchRepeatedLabels(expr.getElements()); + } else { + for (int i = 1; i < expr.getNumElements(); i += 2) { + entry.elements.emplace_back(dispatcher.fetchLabel(expr.getElement(i))); + } + } return entry; } diff --git a/swift/ql/lib/CHANGELOG.md b/swift/ql/lib/CHANGELOG.md index ad443f621cb..b59991858c6 100644 --- a/swift/ql/lib/CHANGELOG.md +++ b/swift/ql/lib/CHANGELOG.md @@ -1,3 +1,10 @@ +## 0.2.4 + +### Minor Analysis Improvements + +* Flow through optional chaining and forced unwrapping in keypaths is now supported by the data flow library. +* Added flow models of collection `.withContiguous[Mutable]StorageIfAvailable`, `.withUnsafe[Mutable]BufferPointer` and `.withUnsafe[Mutable]Bytes` methods. + ## 0.2.3 ### Major Analysis Improvements diff --git a/swift/ql/lib/change-notes/2023-08-21-keypath-optionals.md b/swift/ql/lib/change-notes/2023-08-21-keypath-optionals.md deleted file mode 100644 index 9e2d3bd0e25..00000000000 --- a/swift/ql/lib/change-notes/2023-08-21-keypath-optionals.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- - -* Flow through optional chaining and forced unwrapping in keypaths is now supported by the data flow library. diff --git a/swift/ql/lib/change-notes/2023-08-04-closure-models.md b/swift/ql/lib/change-notes/released/0.2.4.md similarity index 50% rename from swift/ql/lib/change-notes/2023-08-04-closure-models.md rename to swift/ql/lib/change-notes/released/0.2.4.md index ba655f59774..b7e6c5dcc0f 100644 --- a/swift/ql/lib/change-notes/2023-08-04-closure-models.md +++ b/swift/ql/lib/change-notes/released/0.2.4.md @@ -1,5 +1,6 @@ ---- -category: minorAnalysis ---- +## 0.2.4 +### Minor Analysis Improvements + +* Flow through optional chaining and forced unwrapping in keypaths is now supported by the data flow library. * Added flow models of collection `.withContiguous[Mutable]StorageIfAvailable`, `.withUnsafe[Mutable]BufferPointer` and `.withUnsafe[Mutable]Bytes` methods. diff --git a/swift/ql/lib/codeql-pack.release.yml b/swift/ql/lib/codeql-pack.release.yml index 0b605901b42..7f1e3841dcd 100644 --- a/swift/ql/lib/codeql-pack.release.yml +++ b/swift/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.3 +lastReleaseVersion: 0.2.4 diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll index e154491f795..e9de11852a6 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImplConsistency.qll @@ -3,297 +3,11 @@ * data-flow classes and predicates. */ -private import DataFlowImplSpecific::Private -private import DataFlowImplSpecific::Public -private import tainttracking1.TaintTrackingParameter::Private -private import tainttracking1.TaintTrackingParameter::Public +private import swift +private import DataFlowImplSpecific +private import TaintTrackingImplSpecific +private import codeql.dataflow.internal.DataFlowImplConsistency -module Consistency { - private newtype TConsistencyConfiguration = MkConsistencyConfiguration() +private module Input implements InputSig { } - /** A class for configuring the consistency queries. */ - class ConsistencyConfiguration extends TConsistencyConfiguration { - string toString() { none() } - - /** Holds if `n` should be excluded from the consistency test `uniqueEnclosingCallable`. */ - predicate uniqueEnclosingCallableExclude(Node n) { none() } - - /** Holds if `call` should be excluded from the consistency test `uniqueCallEnclosingCallable`. */ - predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) { none() } - - /** Holds if `n` should be excluded from the consistency test `uniqueNodeLocation`. */ - predicate uniqueNodeLocationExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `missingLocation`. */ - predicate missingLocationExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `postWithInFlow`. */ - predicate postWithInFlowExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `argHasPostUpdate`. */ - predicate argHasPostUpdateExclude(ArgumentNode n) { none() } - - /** Holds if `n` should be excluded from the consistency test `reverseRead`. */ - predicate reverseReadExclude(Node n) { none() } - - /** Holds if `n` should be excluded from the consistency test `postHasUniquePre`. */ - predicate postHasUniquePreExclude(PostUpdateNode n) { none() } - - /** Holds if `n` should be excluded from the consistency test `uniquePostUpdate`. */ - predicate uniquePostUpdateExclude(Node n) { none() } - - /** Holds if `(call, ctx)` should be excluded from the consistency test `viableImplInCallContextTooLargeExclude`. */ - predicate viableImplInCallContextTooLargeExclude( - DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable - ) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodeAtPosition`. */ - predicate uniqueParameterNodeAtPositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `(c, pos, p)` should be excluded from the consistency test `uniqueParameterNodePosition`. */ - predicate uniqueParameterNodePositionExclude(DataFlowCallable c, ParameterPosition pos, Node p) { - none() - } - - /** Holds if `n` should be excluded from the consistency test `identityLocalStep`. */ - predicate identityLocalStepExclude(Node n) { none() } - } - - private class RelevantNode extends Node { - RelevantNode() { - this instanceof ArgumentNode or - this instanceof ParameterNode or - this instanceof ReturnNode or - this = getAnOutNode(_, _) or - simpleLocalFlowStep(this, _) or - simpleLocalFlowStep(_, this) or - jumpStep(this, _) or - jumpStep(_, this) or - storeStep(this, _, _) or - storeStep(_, _, this) or - readStep(this, _, _) or - readStep(_, _, this) or - defaultAdditionalTaintStep(this, _) or - defaultAdditionalTaintStep(_, this) - } - } - - query predicate uniqueEnclosingCallable(Node n, string msg) { - exists(int c | - n instanceof RelevantNode and - c = count(nodeGetEnclosingCallable(n)) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueEnclosingCallableExclude(n) and - msg = "Node should have one enclosing callable but has " + c + "." - ) - } - - query predicate uniqueCallEnclosingCallable(DataFlowCall call, string msg) { - exists(int c | - c = count(call.getEnclosingCallable()) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueCallEnclosingCallableExclude(call) and - msg = "Call should have one enclosing callable but has " + c + "." - ) - } - - query predicate uniqueType(Node n, string msg) { - exists(int c | - n instanceof RelevantNode and - c = count(getNodeType(n)) and - c != 1 and - msg = "Node should have one type but has " + c + "." - ) - } - - query predicate uniqueNodeLocation(Node n, string msg) { - exists(int c | - c = - count(string filepath, int startline, int startcolumn, int endline, int endcolumn | - n.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) - ) and - c != 1 and - not any(ConsistencyConfiguration conf).uniqueNodeLocationExclude(n) and - msg = "Node should have one location but has " + c + "." - ) - } - - query predicate missingLocation(string msg) { - exists(int c | - c = - strictcount(Node n | - not n.hasLocationInfo(_, _, _, _, _) and - not any(ConsistencyConfiguration conf).missingLocationExclude(n) - ) and - msg = "Nodes without location: " + c - ) - } - - query predicate uniqueNodeToString(Node n, string msg) { - exists(int c | - c = count(n.toString()) and - c != 1 and - msg = "Node should have one toString but has " + c + "." - ) - } - - query predicate missingToString(string msg) { - exists(int c | - c = strictcount(Node n | not exists(n.toString())) and - msg = "Nodes without toString: " + c - ) - } - - query predicate parameterCallable(ParameterNode p, string msg) { - exists(DataFlowCallable c | isParameterNode(p, c, _) and c != nodeGetEnclosingCallable(p)) and - msg = "Callable mismatch for parameter." - } - - query predicate localFlowIsLocal(Node n1, Node n2, string msg) { - simpleLocalFlowStep(n1, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Local flow step does not preserve enclosing callable." - } - - query predicate readStepIsLocal(Node n1, Node n2, string msg) { - readStep(n1, _, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Read step does not preserve enclosing callable." - } - - query predicate storeStepIsLocal(Node n1, Node n2, string msg) { - storeStep(n1, _, n2) and - nodeGetEnclosingCallable(n1) != nodeGetEnclosingCallable(n2) and - msg = "Store step does not preserve enclosing callable." - } - - private DataFlowType typeRepr() { result = getNodeType(_) } - - query predicate compatibleTypesReflexive(DataFlowType t, string msg) { - t = typeRepr() and - not compatibleTypes(t, t) and - msg = "Type compatibility predicate is not reflexive." - } - - query predicate unreachableNodeCCtx(Node n, DataFlowCall call, string msg) { - isUnreachableInCall(n, call) and - exists(DataFlowCallable c | - c = nodeGetEnclosingCallable(n) and - not viableCallable(call) = c - ) and - msg = "Call context for isUnreachableInCall is inconsistent with call graph." - } - - query predicate localCallNodes(DataFlowCall call, Node n, string msg) { - ( - n = getAnOutNode(call, _) and - msg = "OutNode and call does not share enclosing callable." - or - n.(ArgumentNode).argumentOf(call, _) and - msg = "ArgumentNode and call does not share enclosing callable." - ) and - nodeGetEnclosingCallable(n) != call.getEnclosingCallable() - } - - // This predicate helps the compiler forget that in some languages - // it is impossible for a result of `getPreUpdateNode` to be an - // instance of `PostUpdateNode`. - private Node getPre(PostUpdateNode n) { - result = n.getPreUpdateNode() - or - none() - } - - query predicate postIsNotPre(PostUpdateNode n, string msg) { - getPre(n) = n and - msg = "PostUpdateNode should not equal its pre-update node." - } - - query predicate postHasUniquePre(PostUpdateNode n, string msg) { - not any(ConsistencyConfiguration conf).postHasUniquePreExclude(n) and - exists(int c | - c = count(n.getPreUpdateNode()) and - c != 1 and - msg = "PostUpdateNode should have one pre-update node but has " + c + "." - ) - } - - query predicate uniquePostUpdate(Node n, string msg) { - not any(ConsistencyConfiguration conf).uniquePostUpdateExclude(n) and - 1 < strictcount(PostUpdateNode post | post.getPreUpdateNode() = n) and - msg = "Node has multiple PostUpdateNodes." - } - - query predicate postIsInSameCallable(PostUpdateNode n, string msg) { - nodeGetEnclosingCallable(n) != nodeGetEnclosingCallable(n.getPreUpdateNode()) and - msg = "PostUpdateNode does not share callable with its pre-update node." - } - - private predicate hasPost(Node n) { exists(PostUpdateNode post | post.getPreUpdateNode() = n) } - - query predicate reverseRead(Node n, string msg) { - exists(Node n2 | readStep(n, _, n2) and hasPost(n2) and not hasPost(n)) and - not any(ConsistencyConfiguration conf).reverseReadExclude(n) and - msg = "Origin of readStep is missing a PostUpdateNode." - } - - query predicate argHasPostUpdate(ArgumentNode n, string msg) { - not hasPost(n) and - not any(ConsistencyConfiguration c).argHasPostUpdateExclude(n) and - msg = "ArgumentNode is missing PostUpdateNode." - } - - // This predicate helps the compiler forget that in some languages - // it is impossible for a `PostUpdateNode` to be the target of - // `simpleLocalFlowStep`. - private predicate isPostUpdateNode(Node n) { n instanceof PostUpdateNode or none() } - - query predicate postWithInFlow(Node n, string msg) { - isPostUpdateNode(n) and - not clearsContent(n, _) and - simpleLocalFlowStep(_, n) and - not any(ConsistencyConfiguration c).postWithInFlowExclude(n) and - msg = "PostUpdateNode should not be the target of local flow." - } - - query predicate viableImplInCallContextTooLarge( - DataFlowCall call, DataFlowCall ctx, DataFlowCallable callable - ) { - callable = viableImplInCallContext(call, ctx) and - not callable = viableCallable(call) and - not any(ConsistencyConfiguration c).viableImplInCallContextTooLargeExclude(call, ctx, callable) - } - - query predicate uniqueParameterNodeAtPosition( - DataFlowCallable c, ParameterPosition pos, Node p, string msg - ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodeAtPositionExclude(c, pos, p) and - isParameterNode(p, c, pos) and - not exists(unique(Node p0 | isParameterNode(p0, c, pos))) and - msg = "Parameters with overlapping positions." - } - - query predicate uniqueParameterNodePosition( - DataFlowCallable c, ParameterPosition pos, Node p, string msg - ) { - not any(ConsistencyConfiguration conf).uniqueParameterNodePositionExclude(c, pos, p) and - isParameterNode(p, c, pos) and - not exists(unique(ParameterPosition pos0 | isParameterNode(p, c, pos0))) and - msg = "Parameter node with multiple positions." - } - - query predicate uniqueContentApprox(Content c, string msg) { - not exists(unique(ContentApprox approx | approx = getContentApprox(c))) and - msg = "Non-unique content approximation." - } - - query predicate identityLocalStep(Node n, string msg) { - simpleLocalFlowStep(n, n) and - not any(ConsistencyConfiguration c).identityLocalStepExclude(n) and - msg = "Node steps to itself" - } -} +module Consistency = MakeConsistency; diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index cd9b209ffae..b079f1b600d 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 0.2.4-dev +version: 0.2.4 groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/CHANGELOG.md b/swift/ql/src/CHANGELOG.md index 71fec278599..7f1e54070bc 100644 --- a/swift/ql/src/CHANGELOG.md +++ b/swift/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.2.4 + +### New Queries + +* Added new query "Incomplete regular expression for hostnames" (`swift/incomplete-hostname-regexp`). This query finds regular expressions matching a URL or hostname that may match more hostnames than expected. + ## 0.2.3 No user-facing changes. diff --git a/swift/ql/src/change-notes/2023-08-23-incomplete-hostname-regex.md b/swift/ql/src/change-notes/released/0.2.4.md similarity index 88% rename from swift/ql/src/change-notes/2023-08-23-incomplete-hostname-regex.md rename to swift/ql/src/change-notes/released/0.2.4.md index d70dfce16f7..12170e4fdf6 100644 --- a/swift/ql/src/change-notes/2023-08-23-incomplete-hostname-regex.md +++ b/swift/ql/src/change-notes/released/0.2.4.md @@ -1,5 +1,5 @@ ---- -category: newQuery ---- +## 0.2.4 + +### New Queries * Added new query "Incomplete regular expression for hostnames" (`swift/incomplete-hostname-regexp`). This query finds regular expressions matching a URL or hostname that may match more hostnames than expected. diff --git a/swift/ql/src/codeql-pack.release.yml b/swift/ql/src/codeql-pack.release.yml index 0b605901b42..7f1e3841dcd 100644 --- a/swift/ql/src/codeql-pack.release.yml +++ b/swift/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.2.3 +lastReleaseVersion: 0.2.4 diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 87c3fb14701..96c455c5ce8 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 0.2.4-dev +version: 0.2.4 groups: - swift - queries diff --git a/swift/xcode-autobuilder/BUILD.bazel b/swift/swift-autobuilder/BUILD.bazel similarity index 92% rename from swift/xcode-autobuilder/BUILD.bazel rename to swift/swift-autobuilder/BUILD.bazel index 13d6e9818ff..951b0c243f2 100644 --- a/swift/xcode-autobuilder/BUILD.bazel +++ b/swift/swift-autobuilder/BUILD.bazel @@ -1,7 +1,7 @@ load("//swift:rules.bzl", "swift_cc_binary") swift_cc_binary( - name = "xcode-autobuilder", + name = "swift-autobuilder", srcs = glob([ "*.cpp", "*.h", diff --git a/swift/xcode-autobuilder/XcodeBuildRunner.cpp b/swift/swift-autobuilder/BuildRunner.cpp similarity index 97% rename from swift/xcode-autobuilder/XcodeBuildRunner.cpp rename to swift/swift-autobuilder/BuildRunner.cpp index 831d7e1f94e..cf0521bf789 100644 --- a/swift/xcode-autobuilder/XcodeBuildRunner.cpp +++ b/swift/swift-autobuilder/BuildRunner.cpp @@ -1,4 +1,4 @@ -#include "swift/xcode-autobuilder/XcodeBuildRunner.h" +#include "swift/swift-autobuilder/BuildRunner.h" #include #include @@ -6,7 +6,7 @@ #include "absl/strings/str_join.h" #include "swift/logging/SwiftLogging.h" -#include "swift/xcode-autobuilder/CustomizingBuildLink.h" +#include "swift/swift-autobuilder/CustomizingBuildLink.h" constexpr codeql::SwiftDiagnostic buildCommandFailed{ .id = "build-command-failed", diff --git a/swift/xcode-autobuilder/XcodeBuildRunner.h b/swift/swift-autobuilder/BuildRunner.h similarity index 70% rename from swift/xcode-autobuilder/XcodeBuildRunner.h rename to swift/swift-autobuilder/BuildRunner.h index ab86a00c767..404e74d4319 100644 --- a/swift/xcode-autobuilder/XcodeBuildRunner.h +++ b/swift/swift-autobuilder/BuildRunner.h @@ -1,7 +1,7 @@ #pragma once -#include "swift/xcode-autobuilder/XcodeTarget.h" -#include "swift/xcode-autobuilder/XcodeProjectParser.h" +#include "swift/swift-autobuilder/XcodeTarget.h" +#include "swift/swift-autobuilder/ProjectParser.h" #include void installDependencies(const ProjectStructure& target, bool dryRun); diff --git a/swift/xcode-autobuilder/CFHelpers.cpp b/swift/swift-autobuilder/CFHelpers.cpp similarity index 95% rename from swift/xcode-autobuilder/CFHelpers.cpp rename to swift/swift-autobuilder/CFHelpers.cpp index 7ca19c7b2b2..aba37e982dc 100644 --- a/swift/xcode-autobuilder/CFHelpers.cpp +++ b/swift/swift-autobuilder/CFHelpers.cpp @@ -1,4 +1,4 @@ -#include "swift/xcode-autobuilder/CFHelpers.h" +#include "swift/swift-autobuilder/CFHelpers.h" #include diff --git a/swift/xcode-autobuilder/CFHelpers.h b/swift/swift-autobuilder/CFHelpers.h similarity index 100% rename from swift/xcode-autobuilder/CFHelpers.h rename to swift/swift-autobuilder/CFHelpers.h diff --git a/swift/xcode-autobuilder/CustomizingBuildLink.h b/swift/swift-autobuilder/CustomizingBuildLink.h similarity index 100% rename from swift/xcode-autobuilder/CustomizingBuildLink.h rename to swift/swift-autobuilder/CustomizingBuildLink.h diff --git a/swift/xcode-autobuilder/XcodeProjectParser.cpp b/swift/swift-autobuilder/ProjectParser.cpp similarity index 98% rename from swift/xcode-autobuilder/XcodeProjectParser.cpp rename to swift/swift-autobuilder/ProjectParser.cpp index 072bcaeeee2..fce29e5b70b 100644 --- a/swift/xcode-autobuilder/XcodeProjectParser.cpp +++ b/swift/swift-autobuilder/ProjectParser.cpp @@ -1,4 +1,4 @@ -#include "swift/xcode-autobuilder/XcodeProjectParser.h" +#include "swift/swift-autobuilder/ProjectParser.h" #include #include @@ -8,8 +8,8 @@ #include #include -#include "swift/xcode-autobuilder/XcodeWorkspaceParser.h" -#include "swift/xcode-autobuilder/CFHelpers.h" +#include "swift/swift-autobuilder/XcodeWorkspaceParser.h" +#include "swift/swift-autobuilder/CFHelpers.h" namespace fs = std::filesystem; diff --git a/swift/xcode-autobuilder/XcodeProjectParser.h b/swift/swift-autobuilder/ProjectParser.h similarity index 90% rename from swift/xcode-autobuilder/XcodeProjectParser.h rename to swift/swift-autobuilder/ProjectParser.h index 56958f2b97e..d7e9cdb5eb9 100644 --- a/swift/xcode-autobuilder/XcodeProjectParser.h +++ b/swift/swift-autobuilder/ProjectParser.h @@ -1,6 +1,6 @@ #pragma once -#include "swift/xcode-autobuilder/XcodeTarget.h" +#include "swift/swift-autobuilder/XcodeTarget.h" #include #include #include diff --git a/swift/xcode-autobuilder/XcodeTarget.h b/swift/swift-autobuilder/XcodeTarget.h similarity index 100% rename from swift/xcode-autobuilder/XcodeTarget.h rename to swift/swift-autobuilder/XcodeTarget.h diff --git a/swift/xcode-autobuilder/XcodeWorkspaceParser.cpp b/swift/swift-autobuilder/XcodeWorkspaceParser.cpp similarity index 96% rename from swift/xcode-autobuilder/XcodeWorkspaceParser.cpp rename to swift/swift-autobuilder/XcodeWorkspaceParser.cpp index c315ba3831b..8fd9fee7a2e 100644 --- a/swift/xcode-autobuilder/XcodeWorkspaceParser.cpp +++ b/swift/swift-autobuilder/XcodeWorkspaceParser.cpp @@ -1,7 +1,7 @@ #include #include #include -#include "swift/xcode-autobuilder/XcodeWorkspaceParser.h" +#include "swift/swift-autobuilder/XcodeWorkspaceParser.h" /* Extracts FileRef locations from an XML of the following form: diff --git a/swift/xcode-autobuilder/XcodeWorkspaceParser.h b/swift/swift-autobuilder/XcodeWorkspaceParser.h similarity index 100% rename from swift/xcode-autobuilder/XcodeWorkspaceParser.h rename to swift/swift-autobuilder/XcodeWorkspaceParser.h diff --git a/swift/xcode-autobuilder/xcode-autobuilder.cpp b/swift/swift-autobuilder/swift-autobuilder.cpp similarity index 92% rename from swift/xcode-autobuilder/xcode-autobuilder.cpp rename to swift/swift-autobuilder/swift-autobuilder.cpp index fd73d30b0ad..cbf7f217c75 100644 --- a/swift/xcode-autobuilder/xcode-autobuilder.cpp +++ b/swift/swift-autobuilder/swift-autobuilder.cpp @@ -1,11 +1,11 @@ #include #include #include -#include "swift/xcode-autobuilder/XcodeTarget.h" -#include "swift/xcode-autobuilder/XcodeBuildRunner.h" -#include "swift/xcode-autobuilder/XcodeProjectParser.h" +#include "swift/swift-autobuilder/XcodeTarget.h" +#include "swift/swift-autobuilder/BuildRunner.h" +#include "swift/swift-autobuilder/ProjectParser.h" #include "swift/logging/SwiftLogging.h" -#include "swift/xcode-autobuilder/CustomizingBuildLink.h" +#include "swift/swift-autobuilder/CustomizingBuildLink.h" static constexpr std::string_view uiTest = "com.apple.product-type.bundle.ui-testing"; static constexpr std::string_view unitTest = "com.apple.product-type.bundle.unit-test"; @@ -79,8 +79,9 @@ static bool autobuild(const CLIArgs& args) { "contain no Swift source files, or are tests."); return false; } else if (!structure.xcodeEncountered && swiftPackages.empty()) { - DIAGNOSE_ERROR(noProjectFound, - "`autobuild` detected neither an Xcode project or workspace, nor a Swift package"); + DIAGNOSE_ERROR( + noProjectFound, + "`autobuild` detected neither an Xcode project or workspace, nor a Swift package"); return false; } else if (!xcodeTargets.empty()) { LOG_INFO("Building Xcode target: {}", xcodeTargets.front()); diff --git a/swift/xcode-autobuilder/tests/.gitignore b/swift/swift-autobuilder/tests/.gitignore similarity index 100% rename from swift/xcode-autobuilder/tests/.gitignore rename to swift/swift-autobuilder/tests/.gitignore diff --git a/swift/xcode-autobuilder/tests/BUILD.bazel b/swift/swift-autobuilder/tests/BUILD.bazel similarity index 83% rename from swift/xcode-autobuilder/tests/BUILD.bazel rename to swift/swift-autobuilder/tests/BUILD.bazel index 3013dd47a10..f9a2b8eb178 100644 --- a/swift/xcode-autobuilder/tests/BUILD.bazel +++ b/swift/swift-autobuilder/tests/BUILD.bazel @@ -4,11 +4,11 @@ size = "small", srcs = ["autobuild_tester.py"], args = [ - "$(location //swift/xcode-autobuilder)", + "$(location //swift/swift-autobuilder)", "$(location %s)" % test_dir, ], data = [ - "//swift/xcode-autobuilder", + "//swift/swift-autobuilder", test_dir, ] + glob([test_dir + "/**/*"]), main = "autobuild_tester.py", diff --git a/swift/xcode-autobuilder/tests/autobuild_tester.py b/swift/swift-autobuilder/tests/autobuild_tester.py similarity index 100% rename from swift/xcode-autobuilder/tests/autobuild_tester.py rename to swift/swift-autobuilder/tests/autobuild_tester.py diff --git a/swift/xcode-autobuilder/tests/hello-autobuilder/commands.expected b/swift/swift-autobuilder/tests/hello-autobuilder/commands.expected similarity index 100% rename from swift/xcode-autobuilder/tests/hello-autobuilder/commands.expected rename to swift/swift-autobuilder/tests/hello-autobuilder/commands.expected diff --git a/swift/xcode-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.pbxproj b/swift/swift-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.pbxproj similarity index 100% rename from swift/xcode-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.pbxproj rename to swift/swift-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.pbxproj diff --git a/swift/xcode-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/swift-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from swift/xcode-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to swift/swift-autobuilder/tests/hello-autobuilder/hello-autobuilder.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/swift/xcode-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.pbxproj b/swift/swift-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.pbxproj similarity index 100% rename from swift/xcode-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.pbxproj rename to swift/swift-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.pbxproj diff --git a/swift/xcode-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/swift-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from swift/xcode-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to swift/swift-autobuilder/tests/hello-targets-with-tests-suffix/Foo.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/swift/xcode-autobuilder/tests/hello-targets-with-tests-suffix/commands.expected b/swift/swift-autobuilder/tests/hello-targets-with-tests-suffix/commands.expected similarity index 100% rename from swift/xcode-autobuilder/tests/hello-targets-with-tests-suffix/commands.expected rename to swift/swift-autobuilder/tests/hello-targets-with-tests-suffix/commands.expected diff --git a/swift/xcode-autobuilder/tests/hello-tests/commands.expected b/swift/swift-autobuilder/tests/hello-tests/commands.expected similarity index 100% rename from swift/xcode-autobuilder/tests/hello-tests/commands.expected rename to swift/swift-autobuilder/tests/hello-tests/commands.expected diff --git a/swift/xcode-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.pbxproj b/swift/swift-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.pbxproj similarity index 100% rename from swift/xcode-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.pbxproj rename to swift/swift-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.pbxproj diff --git a/swift/xcode-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/swift-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from swift/xcode-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to swift/swift-autobuilder/tests/hello-tests/hello-tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/swift/xcode-autobuilder/tests/hello-workspace/Hello.xcworkspace/contents.xcworkspacedata b/swift/swift-autobuilder/tests/hello-workspace/Hello.xcworkspace/contents.xcworkspacedata similarity index 100% rename from swift/xcode-autobuilder/tests/hello-workspace/Hello.xcworkspace/contents.xcworkspacedata rename to swift/swift-autobuilder/tests/hello-workspace/Hello.xcworkspace/contents.xcworkspacedata diff --git a/swift/xcode-autobuilder/tests/hello-workspace/commands.expected b/swift/swift-autobuilder/tests/hello-workspace/commands.expected similarity index 100% rename from swift/xcode-autobuilder/tests/hello-workspace/commands.expected rename to swift/swift-autobuilder/tests/hello-workspace/commands.expected diff --git a/swift/xcode-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.pbxproj b/swift/swift-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.pbxproj similarity index 100% rename from swift/xcode-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.pbxproj rename to swift/swift-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.pbxproj diff --git a/swift/xcode-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/swift/swift-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from swift/xcode-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to swift/swift-autobuilder/tests/hello-workspace/hello-workspace.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/swift/tools/autobuild.sh b/swift/tools/autobuild.sh index bd7ded9e486..89bf3c12435 100755 --- a/swift/tools/autobuild.sh +++ b/swift/tools/autobuild.sh @@ -3,7 +3,7 @@ if [[ "$OSTYPE" == "darwin"* ]]; then export CODEQL_SWIFT_CARTHAGE_EXEC=`which carthage` export CODEQL_SWIFT_POD_EXEC=`which pod` - exec "${CODEQL_EXTRACTOR_SWIFT_ROOT}/tools/${CODEQL_PLATFORM}/xcode-autobuilder" + exec "${CODEQL_EXTRACTOR_SWIFT_ROOT}/tools/${CODEQL_PLATFORM}/swift-autobuilder" else exec "${CODEQL_EXTRACTOR_SWIFT_ROOT}/tools/${CODEQL_PLATFORM}/autobuilder-incompatible-os" fi