mirror of
https://github.com/github/codeql.git
synced 2025-12-18 01:33:15 +01:00
Merge branch 'main' into threat-models
This commit is contained in:
@@ -128,6 +128,7 @@ use_repo(
|
|||||||
"kotlin-compiler-1.9.20-Beta",
|
"kotlin-compiler-1.9.20-Beta",
|
||||||
"kotlin-compiler-2.0.0-RC1",
|
"kotlin-compiler-2.0.0-RC1",
|
||||||
"kotlin-compiler-2.0.20-Beta2",
|
"kotlin-compiler-2.0.20-Beta2",
|
||||||
|
"kotlin-compiler-2.1.0-Beta1",
|
||||||
"kotlin-compiler-embeddable-1.5.0",
|
"kotlin-compiler-embeddable-1.5.0",
|
||||||
"kotlin-compiler-embeddable-1.5.10",
|
"kotlin-compiler-embeddable-1.5.10",
|
||||||
"kotlin-compiler-embeddable-1.5.20",
|
"kotlin-compiler-embeddable-1.5.20",
|
||||||
@@ -141,6 +142,7 @@ use_repo(
|
|||||||
"kotlin-compiler-embeddable-1.9.20-Beta",
|
"kotlin-compiler-embeddable-1.9.20-Beta",
|
||||||
"kotlin-compiler-embeddable-2.0.0-RC1",
|
"kotlin-compiler-embeddable-2.0.0-RC1",
|
||||||
"kotlin-compiler-embeddable-2.0.20-Beta2",
|
"kotlin-compiler-embeddable-2.0.20-Beta2",
|
||||||
|
"kotlin-compiler-embeddable-2.1.0-Beta1",
|
||||||
"kotlin-stdlib-1.5.0",
|
"kotlin-stdlib-1.5.0",
|
||||||
"kotlin-stdlib-1.5.10",
|
"kotlin-stdlib-1.5.10",
|
||||||
"kotlin-stdlib-1.5.20",
|
"kotlin-stdlib-1.5.20",
|
||||||
@@ -154,6 +156,7 @@ use_repo(
|
|||||||
"kotlin-stdlib-1.9.20-Beta",
|
"kotlin-stdlib-1.9.20-Beta",
|
||||||
"kotlin-stdlib-2.0.0-RC1",
|
"kotlin-stdlib-2.0.0-RC1",
|
||||||
"kotlin-stdlib-2.0.20-Beta2",
|
"kotlin-stdlib-2.0.20-Beta2",
|
||||||
|
"kotlin-stdlib-2.1.0-Beta1",
|
||||||
)
|
)
|
||||||
|
|
||||||
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
|
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
|
||||||
|
|||||||
@@ -57,10 +57,6 @@
|
|||||||
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
|
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
|
||||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
|
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll"
|
||||||
],
|
],
|
||||||
"Model as Data Generation Java/C# - CaptureModels": [
|
|
||||||
"java/ql/src/utils/modelgenerator/internal/CaptureModels.qll",
|
|
||||||
"csharp/ql/src/utils/modelgenerator/internal/CaptureModels.qll"
|
|
||||||
],
|
|
||||||
"Sign Java/C#": [
|
"Sign Java/C#": [
|
||||||
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/Sign.qll",
|
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/Sign.qll",
|
||||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/Sign.qll"
|
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/Sign.qll"
|
||||||
@@ -355,5 +351,9 @@
|
|||||||
"Python model summaries test extension": [
|
"Python model summaries test extension": [
|
||||||
"python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml",
|
"python/ql/test/library-tests/dataflow/model-summaries/InlineTaintTest.ext.yml",
|
||||||
"python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml"
|
"python/ql/test/library-tests/dataflow/model-summaries/NormalDataflowTest.ext.yml"
|
||||||
|
],
|
||||||
|
"Diagnostics.qll": [
|
||||||
|
"ruby/ql/lib/codeql/ruby/Diagnostics.qll",
|
||||||
|
"rust/ql/lib/codeql/rust/Diagnostics.qll"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ class Type extends Locatable, @type {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a specifier of this type, recursively looking through `typedef` and
|
* Gets a specifier of this type, recursively looking through `typedef` and
|
||||||
* `decltype`. For example, in the context of `typedef const int *restrict
|
* `decltype`. For example, in the context of `typedef const int *restrict t`,
|
||||||
* t`, the type `volatile t` has specifiers `volatile` and `restrict` but not
|
* the type `volatile t` has specifiers `volatile` and `restrict` but not
|
||||||
* `const` since the `const` is attached to the type being pointed to rather
|
* `const` since the `const` is attached to the type being pointed to rather
|
||||||
* than the pointer itself.
|
* than the pointer itself.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -546,7 +546,7 @@ module ProductFlow {
|
|||||||
Flow1::PathGraph::edges(pred1, succ1, _, _) and
|
Flow1::PathGraph::edges(pred1, succ1, _, _) and
|
||||||
exists(ReturnKindExt returnKind |
|
exists(ReturnKindExt returnKind |
|
||||||
succ1.getNode() = returnKind.getAnOutNode(call) and
|
succ1.getNode() = returnKind.getAnOutNode(call) and
|
||||||
paramReturnNode(_, pred1.asParameterReturnNode(), _, returnKind)
|
returnKind = getParamReturnPosition(_, pred1.asParameterReturnNode()).getKind()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,7 +574,7 @@ module ProductFlow {
|
|||||||
Flow2::PathGraph::edges(pred2, succ2, _, _) and
|
Flow2::PathGraph::edges(pred2, succ2, _, _) and
|
||||||
exists(ReturnKindExt returnKind |
|
exists(ReturnKindExt returnKind |
|
||||||
succ2.getNode() = returnKind.getAnOutNode(call) and
|
succ2.getNode() = returnKind.getAnOutNode(call) and
|
||||||
paramReturnNode(_, pred2.asParameterReturnNode(), _, returnKind)
|
returnKind = getParamReturnPosition(_, pred2.asParameterReturnNode()).getKind()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -160,6 +160,26 @@ private module InvalidPointerToDerefBarrier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BEWARE: This configuration uses an unrestricted sink, so accessing its full
|
||||||
|
* flow computation or any stages beyond the first 2 will likely diverge.
|
||||||
|
* Stage 1 will still be fast and we use it to restrict the subsequent sink
|
||||||
|
* computation.
|
||||||
|
*/
|
||||||
|
private module InvalidPointerReachesConfig implements DataFlow::ConfigSig {
|
||||||
|
predicate isSource(DataFlow::Node source) { invalidPointerToDerefSource(_, _, source) }
|
||||||
|
|
||||||
|
predicate isSink(DataFlow::Node sink) { any() }
|
||||||
|
|
||||||
|
predicate isBarrier(DataFlow::Node node) { InvalidPointerToDerefConfig::isBarrier(node) }
|
||||||
|
|
||||||
|
int fieldFlowBranchLimit() { result = invalidPointerToDereferenceFieldFlowBranchLimit() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private module InvalidPointerReachesFlow = DataFlow::Global<InvalidPointerReachesConfig>;
|
||||||
|
|
||||||
|
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A configuration to track flow from a pointer-arithmetic operation found
|
* A configuration to track flow from a pointer-arithmetic operation found
|
||||||
* by `AllocToInvalidPointerConfig` to a dereference of the pointer.
|
* by `AllocToInvalidPointerConfig` to a dereference of the pointer.
|
||||||
@@ -173,8 +193,13 @@ private module InvalidPointerToDerefConfig implements DataFlow::StateConfigSig {
|
|||||||
invalidPointerToDerefSource(_, pai, source)
|
invalidPointerToDerefSource(_, pai, source)
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma[inline]
|
predicate isSink(DataFlow::Node sink) {
|
||||||
predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _, _, _) }
|
exists(DataFlowImplCommon::NodeEx n |
|
||||||
|
InvalidPointerReachesFlow::Stages::Stage1::sinkNode(n, _) and
|
||||||
|
n.asNode() = sink and
|
||||||
|
isInvalidPointerDerefSink(sink, _, _, _, _)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
predicate isSink(DataFlow::Node sink, FlowState pai) { none() }
|
predicate isSink(DataFlow::Node sink, FlowState pai) { none() }
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,6 @@ module FlowFromFree<FlowFromFreeParamSig P> {
|
|||||||
|
|
||||||
predicate isSource(DataFlow::Node node, FlowState state) { isFree(node, _, state, _) }
|
predicate isSource(DataFlow::Node node, FlowState state) { isFree(node, _, state, _) }
|
||||||
|
|
||||||
pragma[inline]
|
|
||||||
predicate isSink(DataFlow::Node sink, FlowState state) {
|
predicate isSink(DataFlow::Node sink, FlowState state) {
|
||||||
exists(Expr e, DataFlow::Node source, DeallocationExpr dealloc |
|
exists(Expr e, DataFlow::Node source, DeallocationExpr dealloc |
|
||||||
P::isSink(sink, e) and
|
P::isSink(sink, e) and
|
||||||
|
|||||||
@@ -61,8 +61,3 @@ query predicate preBasicBlockConsistency(ControlFlowElement cfe1, ControlFlowEle
|
|||||||
bbIntraSuccInconsistency(cfe1, cfe2) and
|
bbIntraSuccInconsistency(cfe1, cfe2) and
|
||||||
s = "intra succ inconsistency"
|
s = "intra succ inconsistency"
|
||||||
}
|
}
|
||||||
|
|
||||||
query predicate multipleToString(Node n, string s) {
|
|
||||||
s = strictconcat(n.toString(), ",") and
|
|
||||||
strictcount(n.toString()) > 1
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -56,10 +56,9 @@ class HtmlTextWriterSink extends HtmlSink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An expression that is used as an argument to an HTML sink method on
|
* DEPRECATED: Attribute collections are no longer considered HTML sinks.
|
||||||
* `AttributeCollection`.
|
|
||||||
*/
|
*/
|
||||||
class AttributeCollectionSink extends HtmlSink {
|
deprecated class AttributeCollectionSink extends DataFlow::ExprNode {
|
||||||
AttributeCollectionSink() {
|
AttributeCollectionSink() {
|
||||||
exists(SystemWebUIAttributeCollectionClass ac, Parameter p |
|
exists(SystemWebUIAttributeCollectionClass ac, Parameter p |
|
||||||
p = ac.getAddMethod().getParameter(1) or
|
p = ac.getAddMethod().getParameter(1) or
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* C#: The indexer and `Add` method on `System.Web.UI.AttributeCollection` is no longer considered an HTML sink.
|
||||||
@@ -9,5 +9,5 @@
|
|||||||
import internal.CaptureModels
|
import internal.CaptureModels
|
||||||
|
|
||||||
from DataFlowSummaryTargetApi api, string flow
|
from DataFlowSummaryTargetApi api, string flow
|
||||||
where flow = captureContentFlow(api)
|
where flow = ContentSensitive::captureFlow(api)
|
||||||
select flow order by flow
|
select flow order by flow
|
||||||
|
|||||||
@@ -6,9 +6,7 @@
|
|||||||
* @tags modelgenerator
|
* @tags modelgenerator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
|
||||||
import internal.CaptureModels
|
import internal.CaptureModels
|
||||||
import internal.CaptureSummaryFlowQuery
|
|
||||||
|
|
||||||
from DataFlowSummaryTargetApi api, string noflow
|
from DataFlowSummaryTargetApi api, string noflow
|
||||||
where noflow = captureNoFlow(api)
|
where noflow = captureNoFlow(api)
|
||||||
|
|||||||
@@ -6,9 +6,7 @@
|
|||||||
* @tags modelgenerator
|
* @tags modelgenerator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
|
||||||
import internal.CaptureModels
|
import internal.CaptureModels
|
||||||
import internal.CaptureSummaryFlowQuery
|
|
||||||
|
|
||||||
from DataFlowSummaryTargetApi api, string flow
|
from DataFlowSummaryTargetApi api, string flow
|
||||||
where flow = captureFlow(api)
|
where flow = captureFlow(api)
|
||||||
|
|||||||
@@ -1,635 +1,351 @@
|
|||||||
/**
|
private import csharp as CS
|
||||||
* Provides classes and predicates related to capturing summary, source,
|
private import semmle.code.csharp.commons.Util as Util
|
||||||
* and sink models of the Standard or a 3rd party library.
|
private import semmle.code.csharp.commons.Collections as Collections
|
||||||
*/
|
private import semmle.code.csharp.commons.QualifiedName as QualifiedName
|
||||||
|
private import semmle.code.csharp.dataflow.internal.DataFlowDispatch
|
||||||
|
private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||||
|
private import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate as TaintTrackingPrivate
|
||||||
|
private import semmle.code.csharp.dataflow.internal.ExternalFlow as ExternalFlow
|
||||||
|
private import semmle.code.csharp.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon
|
||||||
|
private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific
|
||||||
|
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate as DataFlowPrivate
|
||||||
|
private import semmle.code.csharp.dataflow.internal.TaintTrackingImplSpecific
|
||||||
|
private import semmle.code.csharp.frameworks.system.linq.Expressions
|
||||||
|
private import semmle.code.csharp.frameworks.System
|
||||||
|
private import semmle.code.csharp.Location
|
||||||
|
private import codeql.mad.modelgenerator.internal.ModelGeneratorImpl
|
||||||
|
|
||||||
private import CaptureModelsSpecific
|
module ModelGeneratorInput implements ModelGeneratorInputSig<Location, CsharpDataFlow> {
|
||||||
private import CaptureModelsPrinting
|
class Type = CS::Type;
|
||||||
|
|
||||||
/**
|
class Parameter = CS::Parameter;
|
||||||
* A node from which flow can return to the caller. This is either a regular
|
|
||||||
* `ReturnNode` or a `PostUpdateNode` corresponding to the value of a parameter.
|
|
||||||
*/
|
|
||||||
private class ReturnNodeExt extends DataFlow::Node {
|
|
||||||
private DataFlowImplCommon::ReturnKindExt kind;
|
|
||||||
|
|
||||||
ReturnNodeExt() {
|
class Callable = CS::Callable;
|
||||||
kind = DataFlowImplCommon::getValueReturnPosition(this).getKind() or
|
|
||||||
kind = DataFlowImplCommon::getParamReturnPosition(this, _).getKind()
|
class NodeExtended extends CS::DataFlow::Node {
|
||||||
|
Callable getAsExprEnclosingCallable() { result = this.asExpr().getEnclosingCallable() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the kind of the return node.
|
* Holds if any of the parameters of `api` are `System.Func<>`.
|
||||||
*/
|
*/
|
||||||
DataFlowImplCommon::ReturnKindExt getKind() { result = kind }
|
private predicate isHigherOrder(Callable api) {
|
||||||
}
|
exists(Type t | t = api.getAParameter().getType().getUnboundDeclaration() |
|
||||||
|
t instanceof SystemLinqExpressions::DelegateExtType
|
||||||
bindingset[c]
|
|
||||||
private signature string printCallableParamSig(Callable c, ParameterPosition p);
|
|
||||||
|
|
||||||
private module PrintReturnNodeExt<printCallableParamSig/2 printCallableParam> {
|
|
||||||
string getOutput(ReturnNodeExt node) {
|
|
||||||
node.getKind() instanceof DataFlowImplCommon::ValueReturnKind and
|
|
||||||
result = "ReturnValue"
|
|
||||||
or
|
|
||||||
exists(ParameterPosition pos |
|
|
||||||
pos = node.getKind().(DataFlowImplCommon::ParamUpdateReturnKind).getPosition() and
|
|
||||||
result = printCallableParam(returnNodeEnclosingCallable(node), pos)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string getOutput(ReturnNodeExt node) {
|
|
||||||
result = PrintReturnNodeExt<paramReturnNodeAsOutput/2>::getOutput(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
string getContentOutput(ReturnNodeExt node) {
|
|
||||||
result = PrintReturnNodeExt<paramReturnNodeAsContentOutput/2>::getOutput(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
class DataFlowSummaryTargetApi extends SummaryTargetApi {
|
|
||||||
DataFlowSummaryTargetApi() { not isUninterestingForDataFlowModels(this) }
|
|
||||||
}
|
|
||||||
|
|
||||||
class DataFlowSourceTargetApi = SourceTargetApi;
|
|
||||||
|
|
||||||
class DataFlowSinkTargetApi = SinkTargetApi;
|
|
||||||
|
|
||||||
private module ModelPrintingInput implements ModelPrintingSig {
|
|
||||||
class SummaryApi = DataFlowSummaryTargetApi;
|
|
||||||
|
|
||||||
class SourceOrSinkApi = SourceOrSinkTargetApi;
|
|
||||||
|
|
||||||
string getProvenance() { result = "df-generated" }
|
|
||||||
}
|
|
||||||
|
|
||||||
module Printing = ModelPrinting<ModelPrintingInput>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `c` is a relevant content kind, where the underlying type is relevant.
|
|
||||||
*/
|
|
||||||
private predicate isRelevantTypeInContent(DataFlow::ContentSet c) {
|
|
||||||
isRelevantType(getUnderlyingContentType(c))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if data can flow from `node1` to `node2` either via a read or a write of an intermediate field `f`.
|
|
||||||
*/
|
|
||||||
private predicate isRelevantTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
|
||||||
exists(DataFlow::ContentSet f |
|
|
||||||
DataFlowPrivate::readStep(node1, f, node2) and
|
|
||||||
// Partially restrict the content types used for intermediate steps.
|
|
||||||
(not exists(getUnderlyingContentType(f)) or isRelevantTypeInContent(f))
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(DataFlow::ContentSet f | DataFlowPrivate::storeStep(node1, f, node2) | containerContent(f))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if content `c` is either a field, a synthetic field or language specific
|
|
||||||
* content of a relevant type or a container like content.
|
|
||||||
*/
|
|
||||||
pragma[nomagic]
|
|
||||||
private predicate isRelevantContent0(DataFlow::ContentSet c) {
|
|
||||||
isRelevantTypeInContent(c) or
|
|
||||||
containerContent(c)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MaD string representation of the parameter node `p`.
|
|
||||||
*/
|
|
||||||
string parameterNodeAsInput(DataFlow::ParameterNode p) {
|
|
||||||
result = parameterAccess(p.asParameter())
|
|
||||||
or
|
|
||||||
result = qualifierString() and p instanceof InstanceParameterNode
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MaD string representation of the parameter `p`
|
|
||||||
* when used in content flow.
|
|
||||||
*/
|
|
||||||
string parameterNodeAsContentInput(DataFlow::ParameterNode p) {
|
|
||||||
result = parameterContentAccess(p.asParameter())
|
|
||||||
or
|
|
||||||
result = qualifierString() and p instanceof InstanceParameterNode
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MaD input string representation of `source`.
|
|
||||||
*/
|
|
||||||
string asInputArgument(DataFlow::Node source) { result = asInputArgumentSpecific(source) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the summary model of `api`, if it follows the `fluent` programming pattern (returns `this`).
|
|
||||||
*/
|
|
||||||
string captureQualifierFlow(DataFlowSummaryTargetApi api) {
|
|
||||||
exists(ReturnNodeExt ret |
|
|
||||||
api = returnNodeEnclosingCallable(ret) and
|
|
||||||
isOwnInstanceAccessNode(ret)
|
|
||||||
) and
|
|
||||||
result = Printing::asLiftedValueModel(api, qualifierString(), "ReturnValue")
|
|
||||||
}
|
|
||||||
|
|
||||||
private int accessPathLimit0() { result = 2 }
|
|
||||||
|
|
||||||
private newtype TTaintState =
|
|
||||||
TTaintRead(int n) { n in [0 .. accessPathLimit0()] } or
|
|
||||||
TTaintStore(int n) { n in [1 .. accessPathLimit0()] }
|
|
||||||
|
|
||||||
abstract private class TaintState extends TTaintState {
|
|
||||||
abstract string toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A FlowState representing a tainted read.
|
|
||||||
*/
|
|
||||||
private class TaintRead extends TaintState, TTaintRead {
|
|
||||||
private int step;
|
|
||||||
|
|
||||||
TaintRead() { this = TTaintRead(step) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the flow state step number.
|
|
||||||
*/
|
|
||||||
int getStep() { result = step }
|
|
||||||
|
|
||||||
override string toString() { result = "TaintRead(" + step + ")" }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A FlowState representing a tainted write.
|
|
||||||
*/
|
|
||||||
private class TaintStore extends TaintState, TTaintStore {
|
|
||||||
private int step;
|
|
||||||
|
|
||||||
TaintStore() { this = TTaintStore(step) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the flow state step number.
|
|
||||||
*/
|
|
||||||
int getStep() { result = step }
|
|
||||||
|
|
||||||
override string toString() { result = "TaintStore(" + step + ")" }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A data-flow configuration for tracking flow through APIs.
|
|
||||||
* The sources are the parameters of an API and the sinks are the return values (excluding `this`) and parameters.
|
|
||||||
*
|
|
||||||
* This can be used to generate Flow summaries for APIs from parameter to return.
|
|
||||||
*/
|
|
||||||
module PropagateFlowConfig implements DataFlow::StateConfigSig {
|
|
||||||
class FlowState = TaintState;
|
|
||||||
|
|
||||||
predicate isSource(DataFlow::Node source, FlowState state) {
|
|
||||||
source instanceof DataFlow::ParameterNode and
|
|
||||||
source.getEnclosingCallable() instanceof DataFlowSummaryTargetApi and
|
|
||||||
state.(TaintRead).getStep() = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate isSink(DataFlow::Node sink, FlowState state) {
|
|
||||||
sink instanceof ReturnNodeExt and
|
|
||||||
not isOwnInstanceAccessNode(sink) and
|
|
||||||
not exists(captureQualifierFlow(sink.asExpr().getEnclosingCallable())) and
|
|
||||||
(state instanceof TaintRead or state instanceof TaintStore)
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate isAdditionalFlowStep(
|
|
||||||
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
|
|
||||||
) {
|
|
||||||
exists(DataFlow::ContentSet c |
|
|
||||||
DataFlowImplCommon::store(node1, c.getAStoreContent(), node2, _, _) and
|
|
||||||
isRelevantContent0(c) and
|
|
||||||
(
|
|
||||||
state1 instanceof TaintRead and state2.(TaintStore).getStep() = 1
|
|
||||||
or
|
|
||||||
state1.(TaintStore).getStep() + 1 = state2.(TaintStore).getStep()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(DataFlow::ContentSet c |
|
|
||||||
DataFlowPrivate::readStep(node1, c, node2) and
|
|
||||||
isRelevantContent0(c) and
|
|
||||||
state1.(TaintRead).getStep() + 1 = state2.(TaintRead).getStep()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isBarrier(DataFlow::Node n) {
|
private predicate irrelevantAccessor(CS::Accessor a) {
|
||||||
exists(Type t | t = n.getType() and not isRelevantType(t))
|
a.getDeclaration().(CS::Property).isReadWrite()
|
||||||
}
|
}
|
||||||
|
|
||||||
DataFlow::FlowFeature getAFeature() {
|
private predicate isUninterestingForModels(Callable api) {
|
||||||
result instanceof DataFlow::FeatureEqualSourceSinkCallContext
|
api.getDeclaringType().getNamespace().getFullName() = ""
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module PropagateFlow = TaintTracking::GlobalWithState<PropagateFlowConfig>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter.
|
|
||||||
*/
|
|
||||||
string captureThroughFlow0(
|
|
||||||
DataFlowSummaryTargetApi api, DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt
|
|
||||||
) {
|
|
||||||
exists(string input, string output |
|
|
||||||
p.getEnclosingCallable() = api and
|
|
||||||
returnNodeExt.(DataFlow::Node).getEnclosingCallable() = api and
|
|
||||||
input = parameterNodeAsInput(p) and
|
|
||||||
output = getOutput(returnNodeExt) and
|
|
||||||
input != output and
|
|
||||||
result = Printing::asLiftedTaintModel(api, input, output)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the summary model(s) of `api`, if there is flow from parameters to return value or parameter.
|
|
||||||
*/
|
|
||||||
string captureThroughFlow(DataFlowSummaryTargetApi api) {
|
|
||||||
exists(DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt |
|
|
||||||
PropagateFlow::flow(p, returnNodeExt) and
|
|
||||||
result = captureThroughFlow0(api, p, returnNodeExt)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private module PropagateContentFlowConfig implements ContentDataFlow::ConfigSig {
|
|
||||||
predicate isSource(DataFlow::Node source) {
|
|
||||||
source instanceof DataFlow::ParameterNode and
|
|
||||||
source.getEnclosingCallable() instanceof DataFlowSummaryTargetApi
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate isSink(DataFlow::Node sink) {
|
|
||||||
sink instanceof ReturnNodeExt and
|
|
||||||
sink.getEnclosingCallable() instanceof DataFlowSummaryTargetApi
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate isAdditionalFlowStep = isAdditionalContentFlowStep/2;
|
|
||||||
|
|
||||||
predicate isBarrier(DataFlow::Node n) {
|
|
||||||
exists(Type t | t = n.getType() and not isRelevantType(t))
|
|
||||||
}
|
|
||||||
|
|
||||||
int accessPathLimit() { result = 2 }
|
|
||||||
|
|
||||||
predicate isRelevantContent(DataFlow::ContentSet s) { isRelevantContent0(s) }
|
|
||||||
|
|
||||||
DataFlow::FlowFeature getAFeature() {
|
|
||||||
result instanceof DataFlow::FeatureEqualSourceSinkCallContext
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private module PropagateContentFlow = ContentDataFlow::Global<PropagateContentFlowConfig>;
|
|
||||||
|
|
||||||
private string getContent(PropagateContentFlow::AccessPath ap, int i) {
|
|
||||||
exists(ContentSet head, PropagateContentFlow::AccessPath tail |
|
|
||||||
head = ap.getHead() and
|
|
||||||
tail = ap.getTail()
|
|
||||||
|
|
|
||||||
i = 0 and
|
|
||||||
result = "." + printContent(head)
|
|
||||||
or
|
or
|
||||||
i > 0 and result = getContent(tail, i - 1)
|
api instanceof CS::ConversionOperator
|
||||||
)
|
or
|
||||||
}
|
api instanceof Util::MainMethod
|
||||||
|
or
|
||||||
/**
|
api instanceof CS::Destructor
|
||||||
* Gets the MaD string representation of a store step access path.
|
or
|
||||||
*/
|
api instanceof CS::AnonymousFunctionExpr
|
||||||
private string printStoreAccessPath(PropagateContentFlow::AccessPath ap) {
|
or
|
||||||
result = concat(int i | | getContent(ap, i), "" order by i)
|
api.(CS::Constructor).isParameterless()
|
||||||
}
|
or
|
||||||
|
exists(Type decl | decl = api.getDeclaringType() |
|
||||||
/**
|
decl instanceof SystemObjectClass or
|
||||||
* Gets the MaD string representation of a read step access path.
|
decl instanceof SystemValueTypeClass
|
||||||
*/
|
|
||||||
private string printReadAccessPath(PropagateContentFlow::AccessPath ap) {
|
|
||||||
result = concat(int i | | getContent(ap, i), "" order by i desc)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the access path `ap` contains a field or synthetic field access.
|
|
||||||
*/
|
|
||||||
private predicate mentionsField(PropagateContentFlow::AccessPath ap) {
|
|
||||||
exists(ContentSet head, PropagateContentFlow::AccessPath tail |
|
|
||||||
head = ap.getHead() and
|
|
||||||
tail = ap.getTail()
|
|
||||||
|
|
|
||||||
mentionsField(tail) or isField(head)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate apiFlow(
|
|
||||||
DataFlowSummaryTargetApi api, DataFlow::ParameterNode p, PropagateContentFlow::AccessPath reads,
|
|
||||||
ReturnNodeExt returnNodeExt, PropagateContentFlow::AccessPath stores, boolean preservesValue
|
|
||||||
) {
|
|
||||||
PropagateContentFlow::flow(p, reads, returnNodeExt, stores, preservesValue) and
|
|
||||||
returnNodeExt.getEnclosingCallable() = api and
|
|
||||||
p.getEnclosingCallable() = api
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class of APIs relevant for modeling using content flow.
|
|
||||||
* The following heuristic is applied:
|
|
||||||
* Content flow is only relevant for an API, if
|
|
||||||
* #content flow <= 2 * #parameters + 3
|
|
||||||
* If an API produces more content flow, it is likely that
|
|
||||||
* 1. Types are not sufficiently constrained leading to a combinatorial
|
|
||||||
* explosion in dispatch and thus in the generated summaries.
|
|
||||||
* 2. It is a reasonable approximation to use the non-content based flow
|
|
||||||
* detection instead, as reads and stores would use a significant
|
|
||||||
* part of an objects internal state.
|
|
||||||
*/
|
|
||||||
private class ContentDataFlowSummaryTargetApi extends DataFlowSummaryTargetApi {
|
|
||||||
ContentDataFlowSummaryTargetApi() {
|
|
||||||
count(string input, string output |
|
|
||||||
exists(
|
|
||||||
DataFlow::ParameterNode p, PropagateContentFlow::AccessPath reads,
|
|
||||||
ReturnNodeExt returnNodeExt, PropagateContentFlow::AccessPath stores
|
|
||||||
|
|
|
||||||
apiFlow(this, p, reads, returnNodeExt, stores, _) and
|
|
||||||
input = parameterNodeAsContentInput(p) + printReadAccessPath(reads) and
|
|
||||||
output = getContentOutput(returnNodeExt) + printStoreAccessPath(stores)
|
|
||||||
)
|
|
||||||
) <= 2 * this.getNumberOfParameters() + 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma[nomagic]
|
|
||||||
private predicate apiContentFlow(
|
|
||||||
ContentDataFlowSummaryTargetApi api, DataFlow::ParameterNode p,
|
|
||||||
PropagateContentFlow::AccessPath reads, ReturnNodeExt returnNodeExt,
|
|
||||||
PropagateContentFlow::AccessPath stores, boolean preservesValue
|
|
||||||
) {
|
|
||||||
PropagateContentFlow::flow(p, reads, returnNodeExt, stores, preservesValue) and
|
|
||||||
returnNodeExt.getEnclosingCallable() = api and
|
|
||||||
p.getEnclosingCallable() = api
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if any of the content sets in `path` translates into a synthetic field.
|
|
||||||
*/
|
|
||||||
private predicate hasSyntheticContent(PropagateContentFlow::AccessPath path) {
|
|
||||||
exists(PropagateContentFlow::AccessPath tail, ContentSet head |
|
|
||||||
head = path.getHead() and
|
|
||||||
tail = path.getTail()
|
|
||||||
|
|
|
||||||
exists(getSyntheticName(head)) or
|
|
||||||
hasSyntheticContent(tail)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A module containing predicates for validating access paths containing content sets
|
|
||||||
* that translates into synthetic fields, when used for generated summary models.
|
|
||||||
*/
|
|
||||||
private module AccessPathSyntheticValidation {
|
|
||||||
/**
|
|
||||||
* Holds if there exists an API that has content flow from `read` (on type `t1`)
|
|
||||||
* to `store` (on type `t2`).
|
|
||||||
*/
|
|
||||||
private predicate step(
|
|
||||||
Type t1, PropagateContentFlow::AccessPath read, Type t2, PropagateContentFlow::AccessPath store
|
|
||||||
) {
|
|
||||||
exists(DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt |
|
|
||||||
p.getType() = t1 and
|
|
||||||
returnNodeExt.getType() = t2 and
|
|
||||||
apiContentFlow(_, p, read, returnNodeExt, store, _)
|
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if there exists an API that has content flow from `read` (on type `t1`)
|
|
||||||
* to `store` (on type `t2`), where `read` does not have synthetic content and `store` does.
|
|
||||||
*
|
|
||||||
* Step A -> Synth.
|
|
||||||
*/
|
|
||||||
private predicate synthPathEntry(
|
|
||||||
Type t1, PropagateContentFlow::AccessPath read, Type t2, PropagateContentFlow::AccessPath store
|
|
||||||
) {
|
|
||||||
not hasSyntheticContent(read) and
|
|
||||||
hasSyntheticContent(store) and
|
|
||||||
step(t1, read, t2, store)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if there exists an API that has content flow from `read` (on type `t1`)
|
|
||||||
* to `store` (on type `t2`), where `read` has synthetic content
|
|
||||||
* and `store` does not.
|
|
||||||
*
|
|
||||||
* Step Synth -> A.
|
|
||||||
*/
|
|
||||||
private predicate synthPathExit(
|
|
||||||
Type t1, PropagateContentFlow::AccessPath read, Type t2, PropagateContentFlow::AccessPath store
|
|
||||||
) {
|
|
||||||
hasSyntheticContent(read) and
|
|
||||||
not hasSyntheticContent(store) and
|
|
||||||
step(t1, read, t2, store)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if there exists a path of steps from `read` to an exit.
|
|
||||||
*
|
|
||||||
* read ->* Synth -> A
|
|
||||||
*/
|
|
||||||
private predicate reachesSynthExit(Type t, PropagateContentFlow::AccessPath read) {
|
|
||||||
synthPathExit(t, read, _, _)
|
|
||||||
or
|
or
|
||||||
hasSyntheticContent(read) and
|
// Disregard properties that have both a get and a set accessor,
|
||||||
exists(PropagateContentFlow::AccessPath mid, Type midType |
|
// which implicitly means auto implemented properties.
|
||||||
hasSyntheticContent(mid) and
|
irrelevantAccessor(api)
|
||||||
step(t, read, midType, mid) and
|
}
|
||||||
reachesSynthExit(midType, mid.reverse())
|
|
||||||
)
|
private predicate relevant(Callable api) {
|
||||||
|
[api.(CS::Modifiable), api.(CS::Accessor).getDeclaration()].isEffectivelyPublic() and
|
||||||
|
api.fromSource() and
|
||||||
|
api.isUnboundDeclaration() and
|
||||||
|
not isUninterestingForModels(api)
|
||||||
|
}
|
||||||
|
|
||||||
|
private Callable getARelevantOverrideeOrImplementee(Overridable m) {
|
||||||
|
m.overridesOrImplements(result) and relevant(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if there exists a path of steps from an entry to `store`.
|
* Gets the super implementation of `api` if it is relevant.
|
||||||
*
|
* If such a super implementation does not exist, returns `api` if it is relevant.
|
||||||
* A -> Synth ->* store
|
|
||||||
*/
|
*/
|
||||||
private predicate synthEntryReaches(Type t, PropagateContentFlow::AccessPath store) {
|
private Callable liftedImpl(Callable api) {
|
||||||
synthPathEntry(_, _, t, store)
|
(
|
||||||
or
|
result = getARelevantOverrideeOrImplementee(api)
|
||||||
hasSyntheticContent(store) and
|
|
||||||
exists(PropagateContentFlow::AccessPath mid, Type midType |
|
|
||||||
hasSyntheticContent(mid) and
|
|
||||||
step(midType, mid, t, store) and
|
|
||||||
synthEntryReaches(midType, mid.reverse())
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if at least one of the access paths `read` (on type `t1`) and `store` (on type `t2`)
|
|
||||||
* contain content that will be translated into a synthetic field, when being used in
|
|
||||||
* a MaD summary model, and if there is a range of APIs, such that
|
|
||||||
* when chaining their flow access paths, there exists access paths `A` and `B` where
|
|
||||||
* A ->* read -> store ->* B and where `A` and `B` do not contain content that will
|
|
||||||
* be translated into a synthetic field.
|
|
||||||
*
|
|
||||||
* This is needed because we don't want to include summaries that reads from or
|
|
||||||
* stores into a "dead" synthetic field.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
* Assume we have a type `t` (in this case `t1` = `t2`) with methods `getX` and
|
|
||||||
* `setX`, which gets and sets a private field `X` on `t`.
|
|
||||||
* This would lead to the following content flows
|
|
||||||
* getX : Argument[this].SyntheticField[t.X] -> ReturnValue.
|
|
||||||
* setX : Argument[0] -> Argument[this].SyntheticField[t.X]
|
|
||||||
* As the reads and stores are on synthetic fields we should only make summaries
|
|
||||||
* if both of these methods exist.
|
|
||||||
*/
|
|
||||||
pragma[nomagic]
|
|
||||||
predicate acceptReadStore(
|
|
||||||
Type t1, PropagateContentFlow::AccessPath read, Type t2, PropagateContentFlow::AccessPath store
|
|
||||||
) {
|
|
||||||
synthPathEntry(t1, read, t2, store) and reachesSynthExit(t2, store.reverse())
|
|
||||||
or
|
|
||||||
exists(PropagateContentFlow::AccessPath store0 | store0.reverse() = read |
|
|
||||||
synthEntryReaches(t1, store0) and synthPathExit(t1, read, t2, store)
|
|
||||||
or
|
or
|
||||||
synthEntryReaches(t1, store0) and
|
result = api and relevant(api)
|
||||||
step(t1, read, t2, store) and
|
) and
|
||||||
reachesSynthExit(t2, store.reverse())
|
not exists(getARelevantOverrideeOrImplementee(result))
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
private predicate hasManualSummaryModel(Callable api) {
|
||||||
* Holds, if the API `api` has relevant flow from `read` on `p` to `store` on `returnNodeExt`.
|
api = any(FlowSummaryImpl::Public::SummarizedCallable sc | sc.applyManualModel()) or
|
||||||
* Flow is considered relevant,
|
api = any(FlowSummaryImpl::Public::NeutralSummaryCallable sc | sc.hasManualModel())
|
||||||
* 1. If `read` or `store` do not contain a content set that translates into a synthetic field.
|
}
|
||||||
* 2. If `read` or `store` contain a content set that translates into a synthetic field, and if
|
|
||||||
* the synthetic content is "live" on the relevant declaring type.
|
|
||||||
*/
|
|
||||||
private predicate apiRelevantContentFlow(
|
|
||||||
ContentDataFlowSummaryTargetApi api, DataFlow::ParameterNode p,
|
|
||||||
PropagateContentFlow::AccessPath read, ReturnNodeExt returnNodeExt,
|
|
||||||
PropagateContentFlow::AccessPath store, boolean preservesValue
|
|
||||||
) {
|
|
||||||
apiContentFlow(api, p, read, returnNodeExt, store, preservesValue) and
|
|
||||||
(
|
|
||||||
not hasSyntheticContent(read) and not hasSyntheticContent(store)
|
|
||||||
or
|
|
||||||
AccessPathSyntheticValidation::acceptReadStore(p.getType(), read, returnNodeExt.getType(), store)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma[nomagic]
|
private predicate hasManualSourceModel(Callable api) {
|
||||||
private predicate captureContentFlow0(
|
api = any(ExternalFlow::SourceCallable sc | sc.hasManualModel()) or
|
||||||
ContentDataFlowSummaryTargetApi api, string input, string output, boolean preservesValue,
|
api = any(FlowSummaryImpl::Public::NeutralSourceCallable sc | sc.hasManualModel())
|
||||||
boolean lift
|
}
|
||||||
) {
|
|
||||||
exists(
|
|
||||||
DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt, PropagateContentFlow::AccessPath reads,
|
|
||||||
PropagateContentFlow::AccessPath stores
|
|
||||||
|
|
|
||||||
apiRelevantContentFlow(api, p, reads, returnNodeExt, stores, preservesValue) and
|
|
||||||
input = parameterNodeAsContentInput(p) + printReadAccessPath(reads) and
|
|
||||||
output = getContentOutput(returnNodeExt) + printStoreAccessPath(stores) and
|
|
||||||
input != output and
|
|
||||||
(if mentionsField(reads) or mentionsField(stores) then lift = false else lift = true)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
private predicate hasManualSinkModel(Callable api) {
|
||||||
* Gets the content based summary model(s) of the API `api` (if there is flow from a parameter to
|
api = any(ExternalFlow::SinkCallable sc | sc.hasManualModel()) or
|
||||||
* the return value or a parameter).
|
api = any(FlowSummaryImpl::Public::NeutralSinkCallable sc | sc.hasManualModel())
|
||||||
*
|
}
|
||||||
* Models are lifted to the best type in case the read and store access paths do not
|
|
||||||
* contain a field or synthetic field access.
|
|
||||||
*/
|
|
||||||
string captureContentFlow(ContentDataFlowSummaryTargetApi api) {
|
|
||||||
exists(string input, string output, boolean lift, boolean preservesValue |
|
|
||||||
captureContentFlow0(api, input, output, _, lift) and
|
|
||||||
preservesValue = max(boolean p | captureContentFlow0(api, input, output, p, lift)) and
|
|
||||||
result = Printing::asModel(api, input, output, preservesValue, lift)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
predicate isUninterestingForDataFlowModels(Callable api) { isHigherOrder(api) }
|
||||||
* A dataflow configuration used for finding new sources.
|
|
||||||
* The sources are the already known existing sources and the sinks are the API return nodes.
|
class SourceOrSinkTargetApi extends Callable {
|
||||||
*
|
SourceOrSinkTargetApi() { relevant(this) }
|
||||||
* This can be used to generate Source summaries for an API, if the API expose an already known source
|
}
|
||||||
* via its return (then the API itself becomes a source).
|
|
||||||
*/
|
class SinkTargetApi extends SourceOrSinkTargetApi {
|
||||||
module PropagateFromSourceConfig implements DataFlow::ConfigSig {
|
SinkTargetApi() { not hasManualSinkModel(this) }
|
||||||
predicate isSource(DataFlow::Node source) {
|
}
|
||||||
exists(string kind |
|
|
||||||
isRelevantSourceKind(kind) and
|
class SourceTargetApi extends SourceOrSinkTargetApi {
|
||||||
ExternalFlow::sourceNode(source, kind)
|
SourceTargetApi() {
|
||||||
|
not hasManualSourceModel(this) and
|
||||||
|
// Do not generate source models for overridable callables
|
||||||
|
// as virtual dispatch implies that too many methods
|
||||||
|
// will be considered sources.
|
||||||
|
not this.(Overridable).overridesOrImplements(_)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class SummaryTargetApi extends Callable {
|
||||||
|
private Callable lift;
|
||||||
|
|
||||||
|
SummaryTargetApi() {
|
||||||
|
lift = liftedImpl(this) and
|
||||||
|
not hasManualSummaryModel(lift)
|
||||||
|
}
|
||||||
|
|
||||||
|
Callable lift() { result = lift }
|
||||||
|
|
||||||
|
predicate isRelevant() { relevant(this) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `t` is a type that is generally used for bulk data in collection types.
|
||||||
|
* Eg. char[] is roughly equivalent to string and thus a highly
|
||||||
|
* relevant type for model generation.
|
||||||
|
*/
|
||||||
|
private predicate isPrimitiveTypeUsedForBulkData(CS::Type t) {
|
||||||
|
t instanceof CS::ByteType or
|
||||||
|
t instanceof CS::CharType
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if the collection type `ct` is irrelevant for model generation.
|
||||||
|
* Collection types where the type of the elements are
|
||||||
|
* (1) unknown - are considered relevant.
|
||||||
|
* (2) known - at least one the child types should be relevant (a non-simple type
|
||||||
|
* or a type used for bulk data)
|
||||||
|
*/
|
||||||
|
private predicate irrelevantCollectionType(CS::Type ct) {
|
||||||
|
Collections::isCollectionType(ct) and
|
||||||
|
forex(CS::Type child | child = ct.getAChild() |
|
||||||
|
child instanceof CS::SimpleType and
|
||||||
|
not isPrimitiveTypeUsedForBulkData(child)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isSink(DataFlow::Node sink) {
|
predicate isRelevantType(CS::Type t) {
|
||||||
sink instanceof ReturnNodeExt and
|
not t instanceof CS::SimpleType and
|
||||||
sink.getEnclosingCallable() instanceof DataFlowSourceTargetApi
|
not t instanceof CS::Enum and
|
||||||
|
not t instanceof SystemDateTimeStruct and
|
||||||
|
not t instanceof SystemTypeClass and
|
||||||
|
not irrelevantCollectionType(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSinkCallContext }
|
/**
|
||||||
|
* Gets the underlying type of the content `c`.
|
||||||
predicate isBarrier(DataFlow::Node n) {
|
*/
|
||||||
exists(Type t | t = n.getType() and not isRelevantType(t))
|
private CS::Type getUnderlyingContType(DataFlow::Content c) {
|
||||||
|
result = c.(DataFlow::FieldContent).getField().getType() or
|
||||||
|
result = c.(DataFlow::SyntheticFieldContent).getField().getType()
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
Type getUnderlyingContentType(DataFlow::ContentSet c) {
|
||||||
isRelevantTaintStep(node1, node2)
|
exists(DataFlow::Content cont |
|
||||||
}
|
c.isSingleton(cont) and
|
||||||
}
|
result = getUnderlyingContType(cont)
|
||||||
|
)
|
||||||
private module PropagateFromSource = TaintTracking::Global<PropagateFromSourceConfig>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the source model(s) of `api`, if there is flow from an existing known source to the return of `api`.
|
|
||||||
*/
|
|
||||||
string captureSource(DataFlowSourceTargetApi api) {
|
|
||||||
exists(DataFlow::Node source, ReturnNodeExt sink, string kind |
|
|
||||||
PropagateFromSource::flow(source, sink) and
|
|
||||||
ExternalFlow::sourceNode(source, kind) and
|
|
||||||
api = sink.getEnclosingCallable() and
|
|
||||||
not irrelevantSourceSinkApi(source.getEnclosingCallable(), api) and
|
|
||||||
result = Printing::asSourceModel(api, getOutput(sink), kind)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A dataflow configuration used for finding new sinks.
|
|
||||||
* The sources are the parameters of the API and the fields of the enclosing type.
|
|
||||||
*
|
|
||||||
* This can be used to generate Sink summaries for APIs, if the API propagates a parameter (or enclosing type field)
|
|
||||||
* into an existing known sink (then the API itself becomes a sink).
|
|
||||||
*/
|
|
||||||
module PropagateToSinkConfig implements DataFlow::ConfigSig {
|
|
||||||
predicate isSource(DataFlow::Node source) {
|
|
||||||
apiSource(source) and source.getEnclosingCallable() instanceof DataFlowSinkTargetApi
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate isSink(DataFlow::Node sink) {
|
|
||||||
exists(string kind | isRelevantSinkKind(kind) and ExternalFlow::sinkNode(sink, kind))
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate isBarrier(DataFlow::Node node) {
|
|
||||||
exists(Type t | t = node.getType() and not isRelevantType(t))
|
|
||||||
or
|
or
|
||||||
sinkModelSanitizer(node)
|
exists(CS::Property p |
|
||||||
|
c.isProperty(p) and
|
||||||
|
result = p.getType()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
DataFlow::FlowFeature getAFeature() { result instanceof DataFlow::FeatureHasSourceCallContext }
|
string qualifierString() { result = "Argument[this]" }
|
||||||
|
|
||||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
string parameterAccess(CS::Parameter p) {
|
||||||
isRelevantTaintStep(node1, node2)
|
if Collections::isCollectionType(p.getType())
|
||||||
|
then result = "Argument[" + p.getPosition() + "].Element"
|
||||||
|
else result = "Argument[" + p.getPosition() + "]"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string parameterContentAccess(CS::Parameter p) { result = "Argument[" + p.getPosition() + "]" }
|
||||||
|
|
||||||
|
class InstanceParameterNode = DataFlowPrivate::InstanceParameterNode;
|
||||||
|
|
||||||
|
private signature string parameterAccessSig(Parameter p);
|
||||||
|
|
||||||
|
private module ParamReturnNodeAsOutput<parameterAccessSig/1 getParamAccess> {
|
||||||
|
bindingset[c]
|
||||||
|
string paramReturnNodeAsOutput(CS::Callable c, ParameterPosition pos) {
|
||||||
|
result = getParamAccess(c.getParameter(pos.getPosition()))
|
||||||
|
or
|
||||||
|
pos.isThisParameter() and
|
||||||
|
result = qualifierString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingset[c]
|
||||||
|
string paramReturnNodeAsOutput(CS::Callable c, ParameterPosition pos) {
|
||||||
|
result = ParamReturnNodeAsOutput<parameterAccess/1>::paramReturnNodeAsOutput(c, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingset[c]
|
||||||
|
string paramReturnNodeAsContentOutput(Callable c, ParameterPosition pos) {
|
||||||
|
result = ParamReturnNodeAsOutput<parameterContentAccess/1>::paramReturnNodeAsOutput(c, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
Callable returnNodeEnclosingCallable(DataFlow::Node ret) {
|
||||||
|
result = DataFlowImplCommon::getNodeEnclosingCallable(ret).asCallable(_)
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate isOwnInstanceAccessNode(DataFlowPrivate::ReturnNode node) {
|
||||||
|
node.asExpr() instanceof CS::ThisAccess
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate isRelevantMemberAccess(DataFlow::Node node) {
|
||||||
|
exists(CS::MemberAccess access | access = node.asExpr() |
|
||||||
|
access.hasThisQualifier() and
|
||||||
|
access.getTarget().isEffectivelyPublic() and
|
||||||
|
(
|
||||||
|
access instanceof CS::FieldAccess
|
||||||
|
or
|
||||||
|
access.getTarget().(CS::Property).getSetter().isPublic()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate sinkModelSanitizer(DataFlow::Node node) { none() }
|
||||||
|
|
||||||
|
predicate apiSource(DataFlow::Node source) {
|
||||||
|
isRelevantMemberAccess(source) or source instanceof DataFlow::ParameterNode
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate uniquelyCalls(DataFlowCallable dc1, DataFlowCallable dc2) {
|
||||||
|
exists(DataFlowCall call |
|
||||||
|
dc1 = call.getEnclosingCallable() and
|
||||||
|
dc2 = unique(DataFlowCallable dc0 | dc0 = viableCallable(call) | dc0)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingset[dc1, dc2]
|
||||||
|
private predicate uniquelyCallsPlus(DataFlowCallable dc1, DataFlowCallable dc2) =
|
||||||
|
fastTC(uniquelyCalls/2)(dc1, dc2)
|
||||||
|
|
||||||
|
bindingset[sourceEnclosing, api]
|
||||||
|
predicate irrelevantSourceSinkApi(Callable sourceEnclosing, SourceTargetApi api) {
|
||||||
|
not exists(DataFlowCallable dc1, DataFlowCallable dc2 |
|
||||||
|
uniquelyCallsPlus(dc1, dc2) or dc1 = dc2
|
||||||
|
|
|
||||||
|
dc1.getUnderlyingCallable() = api and
|
||||||
|
dc2.getUnderlyingCallable() = sourceEnclosing
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
string getInputArgument(DataFlow::Node source) {
|
||||||
|
exists(int pos |
|
||||||
|
pos = source.(DataFlow::ParameterNode).getParameter().getPosition() and
|
||||||
|
result = "Argument[" + pos + "]"
|
||||||
|
)
|
||||||
|
or
|
||||||
|
source.asExpr() instanceof DataFlowPrivate::FieldOrPropertyAccess and
|
||||||
|
result = qualifierString()
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingset[kind]
|
||||||
|
predicate isRelevantSinkKind(string kind) { any() }
|
||||||
|
|
||||||
|
bindingset[kind]
|
||||||
|
predicate isRelevantSourceKind(string kind) { any() }
|
||||||
|
|
||||||
|
predicate containerContent(DataFlow::ContentSet c) { c.isElement() }
|
||||||
|
|
||||||
|
predicate isAdditionalContentFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||||
|
TaintTrackingPrivate::defaultAdditionalTaintStep(nodeFrom, nodeTo, _) and
|
||||||
|
not nodeTo.asExpr() instanceof CS::ElementAccess and
|
||||||
|
not exists(DataFlow::ContentSet c |
|
||||||
|
DataFlowPrivate::readStep(nodeFrom, c, nodeTo) and containerContent(c)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
bindingset[d]
|
||||||
|
private string getFullyQualifiedName(Declaration d) {
|
||||||
|
exists(string qualifier, string name |
|
||||||
|
d.hasFullyQualifiedName(qualifier, name) and
|
||||||
|
result = QualifiedName::getQualifiedName(qualifier, name)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate isField(DataFlow::ContentSet c) {
|
||||||
|
c.isField(_) or c.isSyntheticField(_) or c.isProperty(_)
|
||||||
|
}
|
||||||
|
|
||||||
|
string getSyntheticName(DataFlow::ContentSet c) {
|
||||||
|
exists(CS::Field f |
|
||||||
|
not f.isEffectivelyPublic() and
|
||||||
|
c.isField(f) and
|
||||||
|
result = getFullyQualifiedName(f)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
exists(CS::Property p |
|
||||||
|
not p.isEffectivelyPublic() and
|
||||||
|
c.isProperty(p) and
|
||||||
|
result = getFullyQualifiedName(p)
|
||||||
|
)
|
||||||
|
or
|
||||||
|
c.isSyntheticField(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
string printContent(DataFlow::ContentSet c) {
|
||||||
|
exists(CS::Field f, string name | name = getFullyQualifiedName(f) |
|
||||||
|
c.isField(f) and
|
||||||
|
f.isEffectivelyPublic() and
|
||||||
|
result = "Field[" + name + "]"
|
||||||
|
)
|
||||||
|
or
|
||||||
|
exists(CS::Property p, string name | name = getFullyQualifiedName(p) |
|
||||||
|
c.isProperty(p) and
|
||||||
|
p.isEffectivelyPublic() and
|
||||||
|
result = "Property[" + name + "]"
|
||||||
|
)
|
||||||
|
or
|
||||||
|
result = "SyntheticField[" + getSyntheticName(c) + "]"
|
||||||
|
or
|
||||||
|
c.isElement() and
|
||||||
|
result = "Element"
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate partialModel = ExternalFlow::partialModel/6;
|
||||||
|
|
||||||
|
predicate sourceNode = ExternalFlow::sourceNode/2;
|
||||||
|
|
||||||
|
predicate sinkNode = ExternalFlow::sinkNode/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
private module PropagateToSink = TaintTracking::Global<PropagateToSinkConfig>;
|
import MakeModelGenerator<Location, CsharpDataFlow, CsharpTaintTracking, ModelGeneratorInput>
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the sink model(s) of `api`, if there is flow from a parameter to an existing known sink.
|
|
||||||
*/
|
|
||||||
string captureSink(DataFlowSinkTargetApi api) {
|
|
||||||
exists(DataFlow::Node src, DataFlow::Node sink, string kind |
|
|
||||||
PropagateToSink::flow(src, sink) and
|
|
||||||
ExternalFlow::sinkNode(sink, kind) and
|
|
||||||
api = src.getEnclosingCallable() and
|
|
||||||
result = Printing::asSinkModel(api, asInputArgument(src), kind)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
private import csharp as CS
|
private import csharp as CS
|
||||||
private import codeql.mad.modelgenerator.ModelPrinting
|
private import codeql.mad.modelgenerator.internal.ModelPrinting
|
||||||
private import semmle.code.csharp.dataflow.internal.ExternalFlow as ExternalFlow
|
private import semmle.code.csharp.dataflow.internal.ExternalFlow as ExternalFlow
|
||||||
|
|
||||||
private module ModelPrintingLang implements ModelPrintingLangSig {
|
private module ModelPrintingLang implements ModelPrintingLangSig {
|
||||||
|
|||||||
@@ -1,436 +0,0 @@
|
|||||||
/**
|
|
||||||
* Provides predicates related to capturing summary models of the Standard or a 3rd party library.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private import csharp as CS
|
|
||||||
private import semmle.code.csharp.commons.Util as Util
|
|
||||||
private import semmle.code.csharp.commons.Collections as Collections
|
|
||||||
private import semmle.code.csharp.commons.QualifiedName as QualifiedName
|
|
||||||
private import semmle.code.csharp.dataflow.internal.DataFlowDispatch
|
|
||||||
private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
|
||||||
private import semmle.code.csharp.frameworks.system.linq.Expressions
|
|
||||||
private import semmle.code.csharp.frameworks.System
|
|
||||||
private import semmle.code.csharp.dataflow.internal.TaintTrackingPrivate as TaintTrackingPrivate
|
|
||||||
import semmle.code.csharp.dataflow.internal.ExternalFlow as ExternalFlow
|
|
||||||
import semmle.code.csharp.dataflow.internal.ContentDataFlow as ContentDataFlow
|
|
||||||
import semmle.code.csharp.dataflow.internal.DataFlowImplCommon as DataFlowImplCommon
|
|
||||||
import semmle.code.csharp.dataflow.internal.DataFlowPrivate as DataFlowPrivate
|
|
||||||
import semmle.code.csharp.dataflow.internal.DataFlowDispatch as DataFlowDispatch
|
|
||||||
|
|
||||||
module DataFlow = CS::DataFlow;
|
|
||||||
|
|
||||||
module TaintTracking = CS::TaintTracking;
|
|
||||||
|
|
||||||
class Type = CS::Type;
|
|
||||||
|
|
||||||
class Callable = CS::Callable;
|
|
||||||
|
|
||||||
class ContentSet = DataFlow::ContentSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if any of the parameters of `api` are `System.Func<>`.
|
|
||||||
*/
|
|
||||||
private predicate isHigherOrder(Callable api) {
|
|
||||||
exists(Type t | t = api.getAParameter().getType().getUnboundDeclaration() |
|
|
||||||
t instanceof SystemLinqExpressions::DelegateExtType
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate irrelevantAccessor(CS::Accessor a) {
|
|
||||||
a.getDeclaration().(CS::Property).isReadWrite()
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate isUninterestingForModels(Callable api) {
|
|
||||||
api.getDeclaringType().getNamespace().getFullName() = ""
|
|
||||||
or
|
|
||||||
api instanceof CS::ConversionOperator
|
|
||||||
or
|
|
||||||
api instanceof Util::MainMethod
|
|
||||||
or
|
|
||||||
api instanceof CS::Destructor
|
|
||||||
or
|
|
||||||
api instanceof CS::AnonymousFunctionExpr
|
|
||||||
or
|
|
||||||
api.(CS::Constructor).isParameterless()
|
|
||||||
or
|
|
||||||
exists(Type decl | decl = api.getDeclaringType() |
|
|
||||||
decl instanceof SystemObjectClass or
|
|
||||||
decl instanceof SystemValueTypeClass
|
|
||||||
)
|
|
||||||
or
|
|
||||||
// Disregard properties that have both a get and a set accessor,
|
|
||||||
// which implicitly means auto implemented properties.
|
|
||||||
irrelevantAccessor(api)
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate relevant(Callable api) {
|
|
||||||
[api.(CS::Modifiable), api.(CS::Accessor).getDeclaration()].isEffectivelyPublic() and
|
|
||||||
api.fromSource() and
|
|
||||||
api.isUnboundDeclaration() and
|
|
||||||
not isUninterestingForModels(api)
|
|
||||||
}
|
|
||||||
|
|
||||||
private Callable getARelevantOverrideeOrImplementee(Overridable m) {
|
|
||||||
m.overridesOrImplements(result) and relevant(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the super implementation of `api` if it is relevant.
|
|
||||||
* If such a super implementation does not exist, returns `api` if it is relevant.
|
|
||||||
*/
|
|
||||||
private Callable liftedImpl(Callable api) {
|
|
||||||
(
|
|
||||||
result = getARelevantOverrideeOrImplementee(api)
|
|
||||||
or
|
|
||||||
result = api and relevant(api)
|
|
||||||
) and
|
|
||||||
not exists(getARelevantOverrideeOrImplementee(result))
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate hasManualSummaryModel(Callable api) {
|
|
||||||
api = any(FlowSummaryImpl::Public::SummarizedCallable sc | sc.applyManualModel()) or
|
|
||||||
api = any(FlowSummaryImpl::Public::NeutralSummaryCallable sc | sc.hasManualModel())
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate hasManualSourceModel(Callable api) {
|
|
||||||
api = any(ExternalFlow::SourceCallable sc | sc.hasManualModel()) or
|
|
||||||
api = any(FlowSummaryImpl::Public::NeutralSourceCallable sc | sc.hasManualModel())
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate hasManualSinkModel(Callable api) {
|
|
||||||
api = any(ExternalFlow::SinkCallable sc | sc.hasManualModel()) or
|
|
||||||
api = any(FlowSummaryImpl::Public::NeutralSinkCallable sc | sc.hasManualModel())
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if it is irrelevant to generate models for `api` based on data flow analysis.
|
|
||||||
*
|
|
||||||
* This serves as an extra filter for the `relevant` predicate.
|
|
||||||
*/
|
|
||||||
predicate isUninterestingForDataFlowModels(CS::Callable api) { isHigherOrder(api) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if it is irrelevant to generate models for `api` based on type-based analysis.
|
|
||||||
*
|
|
||||||
* This serves as an extra filter for the `relevant` predicate.
|
|
||||||
*/
|
|
||||||
predicate isUninterestingForTypeBasedFlowModels(CS::Callable api) { none() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class of callables that are potentially relevant for generating source or
|
|
||||||
* sink models.
|
|
||||||
*/
|
|
||||||
class SourceOrSinkTargetApi extends Callable {
|
|
||||||
SourceOrSinkTargetApi() { relevant(this) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class of callables that are potentially relevant for generating sink models.
|
|
||||||
*/
|
|
||||||
class SinkTargetApi extends SourceOrSinkTargetApi {
|
|
||||||
SinkTargetApi() { not hasManualSinkModel(this) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class of callables that are potentially relevant for generating source models.
|
|
||||||
*/
|
|
||||||
class SourceTargetApi extends SourceOrSinkTargetApi {
|
|
||||||
SourceTargetApi() {
|
|
||||||
not hasManualSourceModel(this) and
|
|
||||||
// Do not generate source models for overridable callables
|
|
||||||
// as virtual dispatch implies that too many methods
|
|
||||||
// will be considered sources.
|
|
||||||
not this.(Overridable).overridesOrImplements(_)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class of callables that are potentially relevant for generating summary or
|
|
||||||
* neutral models.
|
|
||||||
*
|
|
||||||
* In the Standard library and 3rd party libraries it is the callables (or callables that have a
|
|
||||||
* super implementation) that can be called from outside the library itself.
|
|
||||||
*/
|
|
||||||
class SummaryTargetApi extends Callable {
|
|
||||||
private Callable lift;
|
|
||||||
|
|
||||||
SummaryTargetApi() {
|
|
||||||
lift = liftedImpl(this) and
|
|
||||||
not hasManualSummaryModel(lift)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the callable that a model will be lifted to.
|
|
||||||
*
|
|
||||||
* The lifted callable is relevant in terms of model
|
|
||||||
* generation (this is ensured by `liftedImpl`).
|
|
||||||
*/
|
|
||||||
Callable lift() { result = lift }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `this` is relevant in terms of model generation.
|
|
||||||
*/
|
|
||||||
predicate isRelevant() { relevant(this) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `t` is a type that is generally used for bulk data in collection types.
|
|
||||||
* Eg. char[] is roughly equivalent to string and thus a highly
|
|
||||||
* relevant type for model generation.
|
|
||||||
*/
|
|
||||||
private predicate isPrimitiveTypeUsedForBulkData(CS::Type t) {
|
|
||||||
t instanceof CS::ByteType or
|
|
||||||
t instanceof CS::CharType
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the collection type `ct` is irrelevant for model generation.
|
|
||||||
* Collection types where the type of the elements are
|
|
||||||
* (1) unknown - are considered relevant.
|
|
||||||
* (2) known - at least one the child types should be relevant (a non-simple type
|
|
||||||
* or a type used for bulk data)
|
|
||||||
*/
|
|
||||||
private predicate irrelevantCollectionType(CS::Type ct) {
|
|
||||||
Collections::isCollectionType(ct) and
|
|
||||||
forex(CS::Type child | child = ct.getAChild() |
|
|
||||||
child instanceof CS::SimpleType and
|
|
||||||
not isPrimitiveTypeUsedForBulkData(child)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds for type `t` for fields that are relevant as an intermediate
|
|
||||||
* read or write step in the data flow analysis.
|
|
||||||
* That is, flow through any data-flow node that does not have a relevant type
|
|
||||||
* will be excluded.
|
|
||||||
*/
|
|
||||||
predicate isRelevantType(CS::Type t) {
|
|
||||||
not t instanceof CS::SimpleType and
|
|
||||||
not t instanceof CS::Enum and
|
|
||||||
not t instanceof SystemDateTimeStruct and
|
|
||||||
not t instanceof SystemTypeClass and
|
|
||||||
not irrelevantCollectionType(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the underlying type of the content `c`.
|
|
||||||
*/
|
|
||||||
private CS::Type getUnderlyingContType(DataFlow::Content c) {
|
|
||||||
result = c.(DataFlow::FieldContent).getField().getType() or
|
|
||||||
result = c.(DataFlow::SyntheticFieldContent).getField().getType()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the underlying type of the content `c`.
|
|
||||||
*/
|
|
||||||
CS::Type getUnderlyingContentType(DataFlow::ContentSet c) {
|
|
||||||
exists(DataFlow::Content cont |
|
|
||||||
c.isSingleton(cont) and
|
|
||||||
result = getUnderlyingContType(cont)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(CS::Property p |
|
|
||||||
c.isProperty(p) and
|
|
||||||
result = p.getType()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MaD string representation of the qualifier.
|
|
||||||
*/
|
|
||||||
string qualifierString() { result = "Argument[this]" }
|
|
||||||
|
|
||||||
string parameterAccess(CS::Parameter p) {
|
|
||||||
if Collections::isCollectionType(p.getType())
|
|
||||||
then result = "Argument[" + p.getPosition() + "].Element"
|
|
||||||
else result = "Argument[" + p.getPosition() + "]"
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MaD string representation of the parameter `p`
|
|
||||||
* when used in content flow.
|
|
||||||
*/
|
|
||||||
string parameterContentAccess(CS::Parameter p) { result = "Argument[" + p.getPosition() + "]" }
|
|
||||||
|
|
||||||
class InstanceParameterNode = DataFlowPrivate::InstanceParameterNode;
|
|
||||||
|
|
||||||
class ParameterPosition = DataFlowDispatch::ParameterPosition;
|
|
||||||
|
|
||||||
private signature string parameterAccessSig(Parameter p);
|
|
||||||
|
|
||||||
module ParamReturnNodeAsOutput<parameterAccessSig/1 getParamAccess> {
|
|
||||||
bindingset[c]
|
|
||||||
string paramReturnNodeAsOutput(CS::Callable c, ParameterPosition pos) {
|
|
||||||
result = getParamAccess(c.getParameter(pos.getPosition()))
|
|
||||||
or
|
|
||||||
pos.isThisParameter() and
|
|
||||||
result = qualifierString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MaD string representation of return through parameter at position
|
|
||||||
* `pos` of callable `c`.
|
|
||||||
*/
|
|
||||||
bindingset[c]
|
|
||||||
string paramReturnNodeAsOutput(CS::Callable c, ParameterPosition pos) {
|
|
||||||
result = ParamReturnNodeAsOutput<parameterAccess/1>::paramReturnNodeAsOutput(c, pos)
|
|
||||||
}
|
|
||||||
|
|
||||||
bindingset[c]
|
|
||||||
string paramReturnNodeAsContentOutput(Callable c, ParameterPosition pos) {
|
|
||||||
result = ParamReturnNodeAsOutput<parameterContentAccess/1>::paramReturnNodeAsOutput(c, pos)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the enclosing callable of `ret`.
|
|
||||||
*/
|
|
||||||
Callable returnNodeEnclosingCallable(DataFlow::Node ret) {
|
|
||||||
result = DataFlowImplCommon::getNodeEnclosingCallable(ret).asCallable(_)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `node` is an own instance access.
|
|
||||||
*/
|
|
||||||
predicate isOwnInstanceAccessNode(DataFlowPrivate::ReturnNode node) {
|
|
||||||
node.asExpr() instanceof CS::ThisAccess
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate isRelevantMemberAccess(DataFlow::Node node) {
|
|
||||||
exists(CS::MemberAccess access | access = node.asExpr() |
|
|
||||||
access.hasThisQualifier() and
|
|
||||||
access.getTarget().isEffectivelyPublic() and
|
|
||||||
(
|
|
||||||
access instanceof CS::FieldAccess
|
|
||||||
or
|
|
||||||
access.getTarget().(CS::Property).getSetter().isPublic()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate sinkModelSanitizer(DataFlow::Node node) { none() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `source` is an api entrypoint relevant for creating sink models.
|
|
||||||
*/
|
|
||||||
predicate apiSource(DataFlow::Node source) {
|
|
||||||
isRelevantMemberAccess(source) or source instanceof DataFlow::ParameterNode
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate uniquelyCalls(DataFlowCallable dc1, DataFlowCallable dc2) {
|
|
||||||
exists(DataFlowCall call |
|
|
||||||
dc1 = call.getEnclosingCallable() and
|
|
||||||
dc2 = unique(DataFlowCallable dc0 | dc0 = viableCallable(call) | dc0)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
bindingset[dc1, dc2]
|
|
||||||
private predicate uniquelyCallsPlus(DataFlowCallable dc1, DataFlowCallable dc2) =
|
|
||||||
fastTC(uniquelyCalls/2)(dc1, dc2)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if it is not relevant to generate a source model for `api`, even
|
|
||||||
* if flow is detected from a node within `source` to a sink within `api`.
|
|
||||||
*/
|
|
||||||
bindingset[sourceEnclosing, api]
|
|
||||||
predicate irrelevantSourceSinkApi(Callable sourceEnclosing, SourceTargetApi api) {
|
|
||||||
not exists(DataFlowCallable dc1, DataFlowCallable dc2 | uniquelyCallsPlus(dc1, dc2) or dc1 = dc2 |
|
|
||||||
dc1.getUnderlyingCallable() = api and
|
|
||||||
dc2.getUnderlyingCallable() = sourceEnclosing
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MaD input string representation of `source`.
|
|
||||||
*/
|
|
||||||
string asInputArgumentSpecific(DataFlow::Node source) {
|
|
||||||
exists(int pos |
|
|
||||||
pos = source.(DataFlow::ParameterNode).getParameter().getPosition() and
|
|
||||||
result = "Argument[" + pos + "]"
|
|
||||||
)
|
|
||||||
or
|
|
||||||
source.asExpr() instanceof DataFlowPrivate::FieldOrPropertyAccess and
|
|
||||||
result = qualifierString()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `kind` is a relevant sink kind for creating sink models.
|
|
||||||
*/
|
|
||||||
bindingset[kind]
|
|
||||||
predicate isRelevantSinkKind(string kind) { any() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `kind` is a relevant source kind for creating source models.
|
|
||||||
*/
|
|
||||||
bindingset[kind]
|
|
||||||
predicate isRelevantSourceKind(string kind) { any() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the the content `c` is a container.
|
|
||||||
*/
|
|
||||||
predicate containerContent(DataFlow::ContentSet c) { c.isElement() }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if there is a taint step from `node1` to `node2` in content flow.
|
|
||||||
*/
|
|
||||||
predicate isAdditionalContentFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
|
||||||
TaintTrackingPrivate::defaultAdditionalTaintStep(nodeFrom, nodeTo, _) and
|
|
||||||
not nodeTo.asExpr() instanceof CS::ElementAccess and
|
|
||||||
not exists(DataFlow::ContentSet c |
|
|
||||||
DataFlowPrivate::readStep(nodeFrom, c, nodeTo) and containerContent(c)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
bindingset[d]
|
|
||||||
private string getFullyQualifiedName(Declaration d) {
|
|
||||||
exists(string qualifier, string name |
|
|
||||||
d.hasFullyQualifiedName(qualifier, name) and
|
|
||||||
result = QualifiedName::getQualifiedName(qualifier, name)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if the content set `c` is a field, property or synthetic field.
|
|
||||||
*/
|
|
||||||
predicate isField(ContentSet c) { c.isField(_) or c.isSyntheticField(_) or c.isProperty(_) }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MaD synthetic name string representation for the content set `c`, if any.
|
|
||||||
*/
|
|
||||||
string getSyntheticName(DataFlow::ContentSet c) {
|
|
||||||
exists(CS::Field f |
|
|
||||||
not f.isEffectivelyPublic() and
|
|
||||||
c.isField(f) and
|
|
||||||
result = getFullyQualifiedName(f)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(CS::Property p |
|
|
||||||
not p.isEffectivelyPublic() and
|
|
||||||
c.isProperty(p) and
|
|
||||||
result = getFullyQualifiedName(p)
|
|
||||||
)
|
|
||||||
or
|
|
||||||
c.isSyntheticField(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the MaD string representation of the content set `c`.
|
|
||||||
*/
|
|
||||||
string printContent(DataFlow::ContentSet c) {
|
|
||||||
exists(CS::Field f, string name | name = getFullyQualifiedName(f) |
|
|
||||||
c.isField(f) and
|
|
||||||
f.isEffectivelyPublic() and
|
|
||||||
result = "Field[" + name + "]"
|
|
||||||
)
|
|
||||||
or
|
|
||||||
exists(CS::Property p, string name | name = getFullyQualifiedName(p) |
|
|
||||||
c.isProperty(p) and
|
|
||||||
p.isEffectivelyPublic() and
|
|
||||||
result = "Property[" + name + "]"
|
|
||||||
)
|
|
||||||
or
|
|
||||||
result = "SyntheticField[" + getSyntheticName(c) + "]"
|
|
||||||
or
|
|
||||||
c.isElement() and
|
|
||||||
result = "Element"
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
private import CaptureModels
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Capture fluent APIs that return `this`.
|
|
||||||
* Example of a fluent API:
|
|
||||||
* ```csharp
|
|
||||||
* public class BasicFlow {
|
|
||||||
* public BasicFlow ReturnThis(object input)
|
|
||||||
* {
|
|
||||||
* // some side effect
|
|
||||||
* return this;
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
* Captured Model:
|
|
||||||
* ```Summaries;BasicFlow;false;ReturnThis;(System.Object);Argument[this];ReturnValue;value;df-generated```
|
|
||||||
* Capture APIs that transfer taint from an input parameter to an output return
|
|
||||||
* value or parameter.
|
|
||||||
* Allows a sequence of read steps followed by a sequence of store steps.
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
*
|
|
||||||
* ```csharp
|
|
||||||
* public class BasicFlow {
|
|
||||||
* private string tainted;
|
|
||||||
*
|
|
||||||
* public String ReturnField()
|
|
||||||
* {
|
|
||||||
* return tainted;
|
|
||||||
* }
|
|
||||||
*
|
|
||||||
* public void AssignFieldToArray(object[] target)
|
|
||||||
* {
|
|
||||||
* target[0] = tainted;
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
* Captured Models:
|
|
||||||
* ```
|
|
||||||
* Summaries;BasicFlow;false;ReturnField;();Argument[this];ReturnValue;taint;df-generated |
|
|
||||||
* Summaries;BasicFlow;false;AssignFieldToArray;(System.Object[]);Argument[this];Argument[0].Element;taint;df-generated
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* ```csharp
|
|
||||||
* public class BasicFlow {
|
|
||||||
* private string tainted;
|
|
||||||
*
|
|
||||||
* public void SetField(string s)
|
|
||||||
* {
|
|
||||||
* tainted = s;
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
* Captured Model:
|
|
||||||
* ```Summaries;BasicFlow;false;SetField;(System.String);Argument[0];Argument[this];taint;df-generated```
|
|
||||||
*
|
|
||||||
* ```csharp
|
|
||||||
* public class BasicFlow {
|
|
||||||
* public void ReturnSubstring(string s)
|
|
||||||
* {
|
|
||||||
* return s.Substring(0, 1);
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
* Captured Model:
|
|
||||||
* ```Summaries;BasicFlow;false;ReturnSubstring;(System.String);Argument[0];ReturnValue;taint;df-generated```
|
|
||||||
*
|
|
||||||
* ```csharp
|
|
||||||
* public class BasicFlow {
|
|
||||||
* public void AssignToArray(int data, int[] target)
|
|
||||||
* {
|
|
||||||
* target[0] = data;
|
|
||||||
* }
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
* Captured Model:
|
|
||||||
* ```Summaries;BasicFlow;false;AssignToArray;(System.Int32,System.Int32[]);Argument[0];Argument[1].Element;taint;df-generated```
|
|
||||||
*/
|
|
||||||
string captureFlow(DataFlowSummaryTargetApi api) {
|
|
||||||
result = captureQualifierFlow(api) or
|
|
||||||
result = captureThroughFlow(api)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the neutral summary model for `api`, if any.
|
|
||||||
* A neutral summary model is generated, if we are not generating
|
|
||||||
* a summary model that applies to `api` and if it relevant to generate
|
|
||||||
* a model for `api`.
|
|
||||||
*/
|
|
||||||
string captureNoFlow(DataFlowSummaryTargetApi api) {
|
|
||||||
not exists(DataFlowSummaryTargetApi api0 | exists(captureFlow(api0)) and api0.lift() = api.lift()) and
|
|
||||||
api.isRelevant() and
|
|
||||||
result = Printing::asNeutralSummaryModel(api)
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@ private import csharp
|
|||||||
private import semmle.code.csharp.frameworks.system.collections.Generic as GenericCollections
|
private import semmle.code.csharp.frameworks.system.collections.Generic as GenericCollections
|
||||||
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
|
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
|
||||||
private import semmle.code.csharp.frameworks.system.linq.Expressions
|
private import semmle.code.csharp.frameworks.system.linq.Expressions
|
||||||
private import CaptureModelsSpecific as Specific
|
private import CaptureModels::ModelGeneratorInput as ModelGeneratorInput
|
||||||
private import CaptureModelsPrinting
|
private import CaptureModelsPrinting
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,7 +38,7 @@ private predicate localTypeParameter(Callable callable, TypeParameter tp) {
|
|||||||
*/
|
*/
|
||||||
private predicate parameter(Callable callable, string input, TypeParameter tp) {
|
private predicate parameter(Callable callable, string input, TypeParameter tp) {
|
||||||
exists(Parameter p |
|
exists(Parameter p |
|
||||||
input = Specific::parameterAccess(p) and
|
input = ModelGeneratorInput::parameterAccess(p) and
|
||||||
p = callable.getAParameter() and
|
p = callable.getAParameter() and
|
||||||
(
|
(
|
||||||
// Parameter of type tp
|
// Parameter of type tp
|
||||||
@@ -69,7 +69,7 @@ private string implicit(Callable callable, TypeParameter tp) {
|
|||||||
then access = ".Element"
|
then access = ".Element"
|
||||||
else access = getSyntheticField(tp)
|
else access = getSyntheticField(tp)
|
||||||
|
|
|
|
||||||
result = Specific::qualifierString() + access
|
result = ModelGeneratorInput::qualifierString() + access
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,9 +191,7 @@ private module Printing = ModelPrinting<ModelPrintingInput>;
|
|||||||
* A class of callables that are relevant generating summaries for based
|
* A class of callables that are relevant generating summaries for based
|
||||||
* on the Theorems for Free approach.
|
* on the Theorems for Free approach.
|
||||||
*/
|
*/
|
||||||
class TypeBasedFlowTargetApi extends Specific::SummaryTargetApi {
|
class TypeBasedFlowTargetApi extends ModelGeneratorInput::SummaryTargetApi {
|
||||||
TypeBasedFlowTargetApi() { not Specific::isUninterestingForTypeBasedFlowModels(this) }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the string representation of all type based summaries for `this`
|
* Gets the string representation of all type based summaries for `this`
|
||||||
* inspired by the Theorems for Free approach.
|
* inspired by the Theorems for Free approach.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
| script.aspx:4:1:4:23 | <%= ... %> | XSS.cs:115:16:115:29 | someJavascript |
|
| script.aspx:4:1:4:23 | <%= ... %> | XSS.cs:120:16:120:29 | someJavascript |
|
||||||
| script.aspx:8:1:8:12 | <%= ... %> | XSS.cs:122:24:122:28 | Field |
|
| script.aspx:8:1:8:12 | <%= ... %> | XSS.cs:127:24:127:28 | Field |
|
||||||
| script.aspx:12:1:12:14 | <%= ... %> | <outside test directory> | Request |
|
| script.aspx:12:1:12:14 | <%= ... %> | <outside test directory> | Request |
|
||||||
| script.aspx:16:1:16:34 | <%= ... %> | <outside test directory> | QueryString |
|
| script.aspx:16:1:16:34 | <%= ... %> | <outside test directory> | QueryString |
|
||||||
| script.aspx:20:1:20:41 | <%= ... %> | <outside test directory> | QueryString |
|
| script.aspx:20:1:20:41 | <%= ... %> | <outside test directory> | QueryString |
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ namespace Test
|
|||||||
Table table;
|
Table table;
|
||||||
Label label;
|
Label label;
|
||||||
string connectionString;
|
string connectionString;
|
||||||
|
public Button button;
|
||||||
|
|
||||||
public void WebUIXSS()
|
public void WebUIXSS()
|
||||||
{
|
{
|
||||||
@@ -100,6 +101,10 @@ namespace Test
|
|||||||
// GOOD: HTML encoding
|
// GOOD: HTML encoding
|
||||||
string name = context.Request.QueryString["name"];
|
string name = context.Request.QueryString["name"];
|
||||||
new StringContent(HttpUtility.HtmlEncode(name));
|
new StringContent(HttpUtility.HtmlEncode(name));
|
||||||
|
|
||||||
|
// GOOD: Implicit HTML encoding
|
||||||
|
string html = context.Request.QueryString["html"];
|
||||||
|
button.Attributes.Add("data-href", html);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UrlEncoded(HttpContextBase context)
|
public void UrlEncoded(HttpContextBase context)
|
||||||
|
|||||||
@@ -1,50 +1,50 @@
|
|||||||
#select
|
#select
|
||||||
| XSS.cs:26:32:26:51 | call to method ToString | XSS.cs:25:48:25:62 | access to field categoryTextBox : TextBox | XSS.cs:26:32:26:51 | call to method ToString | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:25:48:25:62 | access to field categoryTextBox : TextBox | User-provided value |
|
| XSS.cs:27:32:27:51 | call to method ToString | XSS.cs:26:48:26:62 | access to field categoryTextBox : TextBox | XSS.cs:27:32:27:51 | call to method ToString | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:26:48:26:62 | access to field categoryTextBox : TextBox | User-provided value |
|
||||||
| XSS.cs:27:29:27:48 | call to method ToString | XSS.cs:25:48:25:62 | access to field categoryTextBox : TextBox | XSS.cs:27:29:27:48 | call to method ToString | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:25:48:25:62 | access to field categoryTextBox : TextBox | User-provided value |
|
| XSS.cs:28:29:28:48 | call to method ToString | XSS.cs:26:48:26:62 | access to field categoryTextBox : TextBox | XSS.cs:28:29:28:48 | call to method ToString | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:26:48:26:62 | access to field categoryTextBox : TextBox | User-provided value |
|
||||||
| XSS.cs:28:26:28:45 | call to method ToString | XSS.cs:25:48:25:62 | access to field categoryTextBox : TextBox | XSS.cs:28:26:28:45 | call to method ToString | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:25:48:25:62 | access to field categoryTextBox : TextBox | User-provided value |
|
| XSS.cs:29:26:29:45 | call to method ToString | XSS.cs:26:48:26:62 | access to field categoryTextBox : TextBox | XSS.cs:29:26:29:45 | call to method ToString | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:26:48:26:62 | access to field categoryTextBox : TextBox | User-provided value |
|
||||||
| XSS.cs:38:36:38:39 | access to local variable name | XSS.cs:37:27:37:53 | access to property QueryString : NameValueCollection | XSS.cs:38:36:38:39 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:37:27:37:53 | access to property QueryString : NameValueCollection | User-provided value |
|
| XSS.cs:39:36:39:39 | access to local variable name | XSS.cs:38:27:38:53 | access to property QueryString : NameValueCollection | XSS.cs:39:36:39:39 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:38:27:38:53 | access to property QueryString : NameValueCollection | User-provided value |
|
||||||
| XSS.cs:59:22:59:25 | access to local variable name | XSS.cs:57:27:57:65 | access to property QueryString : NameValueCollection | XSS.cs:59:22:59:25 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:57:27:57:65 | access to property QueryString : NameValueCollection | User-provided value |
|
| XSS.cs:60:22:60:25 | access to local variable name | XSS.cs:58:27:58:65 | access to property QueryString : NameValueCollection | XSS.cs:60:22:60:25 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:58:27:58:65 | access to property QueryString : NameValueCollection | User-provided value |
|
||||||
| XSS.cs:76:36:76:39 | access to local variable name | XSS.cs:75:27:75:53 | access to property QueryString : NameValueCollection | XSS.cs:76:36:76:39 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:75:27:75:53 | access to property QueryString : NameValueCollection | User-provided value |
|
| XSS.cs:77:36:77:39 | access to local variable name | XSS.cs:76:27:76:53 | access to property QueryString : NameValueCollection | XSS.cs:77:36:77:39 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:76:27:76:53 | access to property QueryString : NameValueCollection | User-provided value |
|
||||||
| XSS.cs:79:36:79:40 | access to local variable name2 | XSS.cs:78:28:78:42 | access to property Request : HttpRequestBase | XSS.cs:79:36:79:40 | access to local variable name2 | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:78:28:78:42 | access to property Request : HttpRequestBase | User-provided value |
|
| XSS.cs:80:36:80:40 | access to local variable name2 | XSS.cs:79:28:79:42 | access to property Request : HttpRequestBase | XSS.cs:80:36:80:40 | access to local variable name2 | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:79:28:79:42 | access to property Request : HttpRequestBase | User-provided value |
|
||||||
| XSS.cs:86:28:86:31 | access to local variable name | XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | XSS.cs:86:28:86:31 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | User-provided value |
|
| XSS.cs:87:28:87:31 | access to local variable name | XSS.cs:86:27:86:53 | access to property QueryString : NameValueCollection | XSS.cs:87:28:87:31 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:86:27:86:53 | access to property QueryString : NameValueCollection | User-provided value |
|
||||||
| XSS.cs:87:31:87:34 | access to local variable name | XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | XSS.cs:87:31:87:34 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | User-provided value |
|
| XSS.cs:88:31:88:34 | access to local variable name | XSS.cs:86:27:86:53 | access to property QueryString : NameValueCollection | XSS.cs:88:31:88:34 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:86:27:86:53 | access to property QueryString : NameValueCollection | User-provided value |
|
||||||
| XSS.cs:95:31:95:34 | access to local variable name | XSS.cs:94:27:94:53 | access to property QueryString : NameValueCollection | XSS.cs:95:31:95:34 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:94:27:94:53 | access to property QueryString : NameValueCollection | User-provided value |
|
| XSS.cs:96:31:96:34 | access to local variable name | XSS.cs:95:27:95:53 | access to property QueryString : NameValueCollection | XSS.cs:96:31:96:34 | access to local variable name | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:95:27:95:53 | access to property QueryString : NameValueCollection | User-provided value |
|
||||||
| XSS.cs:135:20:135:33 | access to property RawUrl | XSS.cs:135:20:135:33 | access to property RawUrl | XSS.cs:135:20:135:33 | access to property RawUrl | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:135:20:135:33 | access to property RawUrl | User-provided value |
|
| XSS.cs:140:20:140:33 | access to property RawUrl | XSS.cs:140:20:140:33 | access to property RawUrl | XSS.cs:140:20:140:33 | access to property RawUrl | $@ flows to here and is written to HTML or JavaScript. | XSS.cs:140:20:140:33 | access to property RawUrl | User-provided value |
|
||||||
| script.aspx:12:1:12:14 | <%= ... %> | script.aspx:12:1:12:14 | <%= ... %> | script.aspx:12:1:12:14 | <%= ... %> | $@ flows to here and is a remote source accessed inline in an ASPX page. | script.aspx:12:1:12:14 | <%= ... %> | User-provided value |
|
| script.aspx:12:1:12:14 | <%= ... %> | script.aspx:12:1:12:14 | <%= ... %> | script.aspx:12:1:12:14 | <%= ... %> | $@ flows to here and is a remote source accessed inline in an ASPX page. | script.aspx:12:1:12:14 | <%= ... %> | User-provided value |
|
||||||
| script.aspx:16:1:16:34 | <%= ... %> | script.aspx:16:1:16:34 | <%= ... %> | script.aspx:16:1:16:34 | <%= ... %> | $@ flows to here and is a remote source accessed inline in an ASPX page. | script.aspx:16:1:16:34 | <%= ... %> | User-provided value |
|
| script.aspx:16:1:16:34 | <%= ... %> | script.aspx:16:1:16:34 | <%= ... %> | script.aspx:16:1:16:34 | <%= ... %> | $@ flows to here and is a remote source accessed inline in an ASPX page. | script.aspx:16:1:16:34 | <%= ... %> | User-provided value |
|
||||||
| script.aspx:20:1:20:41 | <%= ... %> | script.aspx:20:1:20:41 | <%= ... %> | script.aspx:20:1:20:41 | <%= ... %> | $@ flows to here and is a remote source accessed inline in an ASPX page. | script.aspx:20:1:20:41 | <%= ... %> | User-provided value |
|
| script.aspx:20:1:20:41 | <%= ... %> | script.aspx:20:1:20:41 | <%= ... %> | script.aspx:20:1:20:41 | <%= ... %> | $@ flows to here and is a remote source accessed inline in an ASPX page. | script.aspx:20:1:20:41 | <%= ... %> | User-provided value |
|
||||||
edges
|
edges
|
||||||
| XSS.cs:25:13:25:21 | [post] access to local variable userInput : StringBuilder | XSS.cs:26:32:26:40 | access to local variable userInput : StringBuilder | provenance | |
|
| XSS.cs:26:13:26:21 | [post] access to local variable userInput : StringBuilder | XSS.cs:27:32:27:40 | access to local variable userInput : StringBuilder | provenance | |
|
||||||
| XSS.cs:25:13:25:21 | [post] access to local variable userInput : StringBuilder | XSS.cs:27:29:27:37 | access to local variable userInput : StringBuilder | provenance | |
|
| XSS.cs:26:13:26:21 | [post] access to local variable userInput : StringBuilder | XSS.cs:28:29:28:37 | access to local variable userInput : StringBuilder | provenance | |
|
||||||
| XSS.cs:25:13:25:21 | [post] access to local variable userInput : StringBuilder | XSS.cs:28:26:28:34 | access to local variable userInput : StringBuilder | provenance | |
|
| XSS.cs:26:13:26:21 | [post] access to local variable userInput : StringBuilder | XSS.cs:29:26:29:34 | access to local variable userInput : StringBuilder | provenance | |
|
||||||
| XSS.cs:25:48:25:62 | access to field categoryTextBox : TextBox | XSS.cs:25:48:25:67 | access to property Text : String | provenance | MaD:4 |
|
| XSS.cs:26:48:26:62 | access to field categoryTextBox : TextBox | XSS.cs:26:48:26:67 | access to property Text : String | provenance | MaD:4 |
|
||||||
| XSS.cs:25:48:25:67 | access to property Text : String | XSS.cs:25:13:25:21 | [post] access to local variable userInput : StringBuilder | provenance | MaD:2 |
|
| XSS.cs:26:48:26:67 | access to property Text : String | XSS.cs:26:13:26:21 | [post] access to local variable userInput : StringBuilder | provenance | MaD:2 |
|
||||||
| XSS.cs:26:32:26:40 | access to local variable userInput : StringBuilder | XSS.cs:26:32:26:51 | call to method ToString | provenance | MaD:3 |
|
| XSS.cs:27:32:27:40 | access to local variable userInput : StringBuilder | XSS.cs:27:32:27:51 | call to method ToString | provenance | MaD:3 |
|
||||||
| XSS.cs:27:29:27:37 | access to local variable userInput : StringBuilder | XSS.cs:27:29:27:48 | call to method ToString | provenance | MaD:3 |
|
| XSS.cs:28:29:28:37 | access to local variable userInput : StringBuilder | XSS.cs:28:29:28:48 | call to method ToString | provenance | MaD:3 |
|
||||||
| XSS.cs:28:26:28:34 | access to local variable userInput : StringBuilder | XSS.cs:28:26:28:45 | call to method ToString | provenance | MaD:3 |
|
| XSS.cs:29:26:29:34 | access to local variable userInput : StringBuilder | XSS.cs:29:26:29:45 | call to method ToString | provenance | MaD:3 |
|
||||||
| XSS.cs:37:20:37:23 | access to local variable name : String | XSS.cs:38:36:38:39 | access to local variable name | provenance | Sink:MaD:5 |
|
| XSS.cs:38:20:38:23 | access to local variable name : String | XSS.cs:39:36:39:39 | access to local variable name | provenance | Sink:MaD:5 |
|
||||||
| XSS.cs:37:27:37:53 | access to property QueryString : NameValueCollection | XSS.cs:37:20:37:23 | access to local variable name : String | provenance | |
|
| XSS.cs:38:27:38:53 | access to property QueryString : NameValueCollection | XSS.cs:38:20:38:23 | access to local variable name : String | provenance | |
|
||||||
| XSS.cs:37:27:37:53 | access to property QueryString : NameValueCollection | XSS.cs:37:27:37:61 | access to indexer : String | provenance | MaD:6 |
|
| XSS.cs:38:27:38:53 | access to property QueryString : NameValueCollection | XSS.cs:38:27:38:61 | access to indexer : String | provenance | MaD:6 |
|
||||||
| XSS.cs:37:27:37:61 | access to indexer : String | XSS.cs:37:20:37:23 | access to local variable name : String | provenance | |
|
| XSS.cs:38:27:38:61 | access to indexer : String | XSS.cs:38:20:38:23 | access to local variable name : String | provenance | |
|
||||||
| XSS.cs:57:20:57:23 | access to local variable name : String | XSS.cs:59:22:59:25 | access to local variable name | provenance | |
|
| XSS.cs:58:20:58:23 | access to local variable name : String | XSS.cs:60:22:60:25 | access to local variable name | provenance | |
|
||||||
| XSS.cs:57:27:57:65 | access to property QueryString : NameValueCollection | XSS.cs:57:20:57:23 | access to local variable name : String | provenance | |
|
| XSS.cs:58:27:58:65 | access to property QueryString : NameValueCollection | XSS.cs:58:20:58:23 | access to local variable name : String | provenance | |
|
||||||
| XSS.cs:57:27:57:65 | access to property QueryString : NameValueCollection | XSS.cs:57:27:57:73 | access to indexer : String | provenance | MaD:6 |
|
| XSS.cs:58:27:58:65 | access to property QueryString : NameValueCollection | XSS.cs:58:27:58:73 | access to indexer : String | provenance | MaD:6 |
|
||||||
| XSS.cs:57:27:57:73 | access to indexer : String | XSS.cs:57:20:57:23 | access to local variable name : String | provenance | |
|
| XSS.cs:58:27:58:73 | access to indexer : String | XSS.cs:58:20:58:23 | access to local variable name : String | provenance | |
|
||||||
| XSS.cs:75:20:75:23 | access to local variable name : String | XSS.cs:76:36:76:39 | access to local variable name | provenance | |
|
| XSS.cs:76:20:76:23 | access to local variable name : String | XSS.cs:77:36:77:39 | access to local variable name | provenance | |
|
||||||
| XSS.cs:75:27:75:53 | access to property QueryString : NameValueCollection | XSS.cs:75:20:75:23 | access to local variable name : String | provenance | |
|
| XSS.cs:76:27:76:53 | access to property QueryString : NameValueCollection | XSS.cs:76:20:76:23 | access to local variable name : String | provenance | |
|
||||||
| XSS.cs:75:27:75:53 | access to property QueryString : NameValueCollection | XSS.cs:75:27:75:61 | access to indexer : String | provenance | MaD:6 |
|
| XSS.cs:76:27:76:53 | access to property QueryString : NameValueCollection | XSS.cs:76:27:76:61 | access to indexer : String | provenance | MaD:6 |
|
||||||
| XSS.cs:75:27:75:61 | access to indexer : String | XSS.cs:75:20:75:23 | access to local variable name : String | provenance | |
|
| XSS.cs:76:27:76:61 | access to indexer : String | XSS.cs:76:20:76:23 | access to local variable name : String | provenance | |
|
||||||
| XSS.cs:78:20:78:24 | access to local variable name2 : String | XSS.cs:79:36:79:40 | access to local variable name2 | provenance | |
|
| XSS.cs:79:20:79:24 | access to local variable name2 : String | XSS.cs:80:36:80:40 | access to local variable name2 | provenance | |
|
||||||
| XSS.cs:78:28:78:42 | access to property Request : HttpRequestBase | XSS.cs:78:20:78:24 | access to local variable name2 : String | provenance | |
|
| XSS.cs:79:28:79:42 | access to property Request : HttpRequestBase | XSS.cs:79:20:79:24 | access to local variable name2 : String | provenance | |
|
||||||
| XSS.cs:85:20:85:23 | access to local variable name : String | XSS.cs:86:28:86:31 | access to local variable name | provenance | |
|
| XSS.cs:86:20:86:23 | access to local variable name : String | XSS.cs:87:28:87:31 | access to local variable name | provenance | |
|
||||||
| XSS.cs:85:20:85:23 | access to local variable name : String | XSS.cs:87:31:87:34 | access to local variable name | provenance | |
|
| XSS.cs:86:20:86:23 | access to local variable name : String | XSS.cs:88:31:88:34 | access to local variable name | provenance | |
|
||||||
| XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | XSS.cs:85:20:85:23 | access to local variable name : String | provenance | |
|
| XSS.cs:86:27:86:53 | access to property QueryString : NameValueCollection | XSS.cs:86:20:86:23 | access to local variable name : String | provenance | |
|
||||||
| XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | XSS.cs:85:27:85:61 | access to indexer : String | provenance | MaD:6 |
|
| XSS.cs:86:27:86:53 | access to property QueryString : NameValueCollection | XSS.cs:86:27:86:61 | access to indexer : String | provenance | MaD:6 |
|
||||||
| XSS.cs:85:27:85:61 | access to indexer : String | XSS.cs:85:20:85:23 | access to local variable name : String | provenance | |
|
| XSS.cs:86:27:86:61 | access to indexer : String | XSS.cs:86:20:86:23 | access to local variable name : String | provenance | |
|
||||||
| XSS.cs:94:20:94:23 | access to local variable name : String | XSS.cs:95:31:95:34 | access to local variable name | provenance | Sink:MaD:1 |
|
| XSS.cs:95:20:95:23 | access to local variable name : String | XSS.cs:96:31:96:34 | access to local variable name | provenance | Sink:MaD:1 |
|
||||||
| XSS.cs:94:27:94:53 | access to property QueryString : NameValueCollection | XSS.cs:94:20:94:23 | access to local variable name : String | provenance | |
|
| XSS.cs:95:27:95:53 | access to property QueryString : NameValueCollection | XSS.cs:95:20:95:23 | access to local variable name : String | provenance | |
|
||||||
| XSS.cs:94:27:94:53 | access to property QueryString : NameValueCollection | XSS.cs:94:27:94:61 | access to indexer : String | provenance | MaD:6 |
|
| XSS.cs:95:27:95:53 | access to property QueryString : NameValueCollection | XSS.cs:95:27:95:61 | access to indexer : String | provenance | MaD:6 |
|
||||||
| XSS.cs:94:27:94:61 | access to indexer : String | XSS.cs:94:20:94:23 | access to local variable name : String | provenance | |
|
| XSS.cs:95:27:95:61 | access to indexer : String | XSS.cs:95:20:95:23 | access to local variable name : String | provenance | |
|
||||||
| script.aspx:12:1:12:14 | <%= ... %> | script.aspx:12:1:12:14 | <%= ... %> | provenance | |
|
| script.aspx:12:1:12:14 | <%= ... %> | script.aspx:12:1:12:14 | <%= ... %> | provenance | |
|
||||||
| script.aspx:16:1:16:34 | <%= ... %> | script.aspx:16:1:16:34 | <%= ... %> | provenance | |
|
| script.aspx:16:1:16:34 | <%= ... %> | script.aspx:16:1:16:34 | <%= ... %> | provenance | |
|
||||||
| script.aspx:20:1:20:41 | <%= ... %> | script.aspx:20:1:20:41 | <%= ... %> | provenance | |
|
| script.aspx:20:1:20:41 | <%= ... %> | script.aspx:20:1:20:41 | <%= ... %> | provenance | |
|
||||||
@@ -56,40 +56,40 @@ models
|
|||||||
| 5 | Sink: System.Web; HttpResponse; false; Write; ; ; Argument[0]; html-injection; manual |
|
| 5 | Sink: System.Web; HttpResponse; false; Write; ; ; Argument[0]; html-injection; manual |
|
||||||
| 6 | Summary: System.Collections.Specialized; NameValueCollection; false; get_Item; (System.String); ; Argument[this]; ReturnValue; taint; df-generated |
|
| 6 | Summary: System.Collections.Specialized; NameValueCollection; false; get_Item; (System.String); ; Argument[this]; ReturnValue; taint; df-generated |
|
||||||
nodes
|
nodes
|
||||||
| XSS.cs:25:13:25:21 | [post] access to local variable userInput : StringBuilder | semmle.label | [post] access to local variable userInput : StringBuilder |
|
| XSS.cs:26:13:26:21 | [post] access to local variable userInput : StringBuilder | semmle.label | [post] access to local variable userInput : StringBuilder |
|
||||||
| XSS.cs:25:48:25:62 | access to field categoryTextBox : TextBox | semmle.label | access to field categoryTextBox : TextBox |
|
| XSS.cs:26:48:26:62 | access to field categoryTextBox : TextBox | semmle.label | access to field categoryTextBox : TextBox |
|
||||||
| XSS.cs:25:48:25:67 | access to property Text : String | semmle.label | access to property Text : String |
|
| XSS.cs:26:48:26:67 | access to property Text : String | semmle.label | access to property Text : String |
|
||||||
| XSS.cs:26:32:26:40 | access to local variable userInput : StringBuilder | semmle.label | access to local variable userInput : StringBuilder |
|
| XSS.cs:27:32:27:40 | access to local variable userInput : StringBuilder | semmle.label | access to local variable userInput : StringBuilder |
|
||||||
| XSS.cs:26:32:26:51 | call to method ToString | semmle.label | call to method ToString |
|
| XSS.cs:27:32:27:51 | call to method ToString | semmle.label | call to method ToString |
|
||||||
| XSS.cs:27:29:27:37 | access to local variable userInput : StringBuilder | semmle.label | access to local variable userInput : StringBuilder |
|
| XSS.cs:28:29:28:37 | access to local variable userInput : StringBuilder | semmle.label | access to local variable userInput : StringBuilder |
|
||||||
| XSS.cs:27:29:27:48 | call to method ToString | semmle.label | call to method ToString |
|
| XSS.cs:28:29:28:48 | call to method ToString | semmle.label | call to method ToString |
|
||||||
| XSS.cs:28:26:28:34 | access to local variable userInput : StringBuilder | semmle.label | access to local variable userInput : StringBuilder |
|
| XSS.cs:29:26:29:34 | access to local variable userInput : StringBuilder | semmle.label | access to local variable userInput : StringBuilder |
|
||||||
| XSS.cs:28:26:28:45 | call to method ToString | semmle.label | call to method ToString |
|
| XSS.cs:29:26:29:45 | call to method ToString | semmle.label | call to method ToString |
|
||||||
| XSS.cs:37:20:37:23 | access to local variable name : String | semmle.label | access to local variable name : String |
|
| XSS.cs:38:20:38:23 | access to local variable name : String | semmle.label | access to local variable name : String |
|
||||||
| XSS.cs:37:27:37:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
| XSS.cs:38:27:38:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||||
| XSS.cs:37:27:37:61 | access to indexer : String | semmle.label | access to indexer : String |
|
| XSS.cs:38:27:38:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||||
| XSS.cs:38:36:38:39 | access to local variable name | semmle.label | access to local variable name |
|
| XSS.cs:39:36:39:39 | access to local variable name | semmle.label | access to local variable name |
|
||||||
| XSS.cs:57:20:57:23 | access to local variable name : String | semmle.label | access to local variable name : String |
|
| XSS.cs:58:20:58:23 | access to local variable name : String | semmle.label | access to local variable name : String |
|
||||||
| XSS.cs:57:27:57:65 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
| XSS.cs:58:27:58:65 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||||
| XSS.cs:57:27:57:73 | access to indexer : String | semmle.label | access to indexer : String |
|
| XSS.cs:58:27:58:73 | access to indexer : String | semmle.label | access to indexer : String |
|
||||||
| XSS.cs:59:22:59:25 | access to local variable name | semmle.label | access to local variable name |
|
| XSS.cs:60:22:60:25 | access to local variable name | semmle.label | access to local variable name |
|
||||||
| XSS.cs:75:20:75:23 | access to local variable name : String | semmle.label | access to local variable name : String |
|
| XSS.cs:76:20:76:23 | access to local variable name : String | semmle.label | access to local variable name : String |
|
||||||
| XSS.cs:75:27:75:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
| XSS.cs:76:27:76:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||||
| XSS.cs:75:27:75:61 | access to indexer : String | semmle.label | access to indexer : String |
|
| XSS.cs:76:27:76:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||||
| XSS.cs:76:36:76:39 | access to local variable name | semmle.label | access to local variable name |
|
| XSS.cs:77:36:77:39 | access to local variable name | semmle.label | access to local variable name |
|
||||||
| XSS.cs:78:20:78:24 | access to local variable name2 : String | semmle.label | access to local variable name2 : String |
|
| XSS.cs:79:20:79:24 | access to local variable name2 : String | semmle.label | access to local variable name2 : String |
|
||||||
| XSS.cs:78:28:78:42 | access to property Request : HttpRequestBase | semmle.label | access to property Request : HttpRequestBase |
|
| XSS.cs:79:28:79:42 | access to property Request : HttpRequestBase | semmle.label | access to property Request : HttpRequestBase |
|
||||||
| XSS.cs:79:36:79:40 | access to local variable name2 | semmle.label | access to local variable name2 |
|
| XSS.cs:80:36:80:40 | access to local variable name2 | semmle.label | access to local variable name2 |
|
||||||
| XSS.cs:85:20:85:23 | access to local variable name : String | semmle.label | access to local variable name : String |
|
| XSS.cs:86:20:86:23 | access to local variable name : String | semmle.label | access to local variable name : String |
|
||||||
| XSS.cs:85:27:85:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
| XSS.cs:86:27:86:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||||
| XSS.cs:85:27:85:61 | access to indexer : String | semmle.label | access to indexer : String |
|
| XSS.cs:86:27:86:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||||
| XSS.cs:86:28:86:31 | access to local variable name | semmle.label | access to local variable name |
|
| XSS.cs:87:28:87:31 | access to local variable name | semmle.label | access to local variable name |
|
||||||
| XSS.cs:87:31:87:34 | access to local variable name | semmle.label | access to local variable name |
|
| XSS.cs:88:31:88:34 | access to local variable name | semmle.label | access to local variable name |
|
||||||
| XSS.cs:94:20:94:23 | access to local variable name : String | semmle.label | access to local variable name : String |
|
| XSS.cs:95:20:95:23 | access to local variable name : String | semmle.label | access to local variable name : String |
|
||||||
| XSS.cs:94:27:94:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
| XSS.cs:95:27:95:53 | access to property QueryString : NameValueCollection | semmle.label | access to property QueryString : NameValueCollection |
|
||||||
| XSS.cs:94:27:94:61 | access to indexer : String | semmle.label | access to indexer : String |
|
| XSS.cs:95:27:95:61 | access to indexer : String | semmle.label | access to indexer : String |
|
||||||
| XSS.cs:95:31:95:34 | access to local variable name | semmle.label | access to local variable name |
|
| XSS.cs:96:31:96:34 | access to local variable name | semmle.label | access to local variable name |
|
||||||
| XSS.cs:135:20:135:33 | access to property RawUrl | semmle.label | access to property RawUrl |
|
| XSS.cs:140:20:140:33 | access to property RawUrl | semmle.label | access to property RawUrl |
|
||||||
| script.aspx:12:1:12:14 | <%= ... %> | semmle.label | <%= ... %> |
|
| script.aspx:12:1:12:14 | <%= ... %> | semmle.label | <%= ... %> |
|
||||||
| script.aspx:16:1:16:34 | <%= ... %> | semmle.label | <%= ... %> |
|
| script.aspx:16:1:16:34 | <%= ... %> | semmle.label | <%= ... %> |
|
||||||
| script.aspx:20:1:20:41 | <%= ... %> | semmle.label | <%= ... %> |
|
| script.aspx:20:1:20:41 | <%= ... %> | semmle.label | <%= ... %> |
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import utils.modelgenerator.internal.CaptureModels
|
|||||||
import TestUtilities.InlineMadTest
|
import TestUtilities.InlineMadTest
|
||||||
|
|
||||||
module InlineMadTestConfig implements InlineMadTestConfigSig {
|
module InlineMadTestConfig implements InlineMadTestConfigSig {
|
||||||
string getCapturedModel(Callable c) { result = captureContentFlow(c) }
|
string getCapturedModel(Callable c) { result = ContentSensitive::captureFlow(c) }
|
||||||
|
|
||||||
string getKind() { result = "contentbased-summary" }
|
string getKind() { result = "contentbased-summary" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import csharp
|
import csharp
|
||||||
import utils.modelgenerator.internal.CaptureSummaryFlowQuery
|
import utils.modelgenerator.internal.CaptureModels
|
||||||
import TestUtilities.InlineMadTest
|
import TestUtilities.InlineMadTest
|
||||||
|
|
||||||
module InlineMadTestConfig implements InlineMadTestConfigSig {
|
module InlineMadTestConfig implements InlineMadTestConfigSig {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import csharp
|
import csharp
|
||||||
import utils.modelgenerator.internal.CaptureSummaryFlowQuery
|
import utils.modelgenerator.internal.CaptureModels
|
||||||
import TestUtilities.InlineMadTest
|
import TestUtilities.InlineMadTest
|
||||||
|
|
||||||
module InlineMadTestConfig implements InlineMadTestConfigSig {
|
module InlineMadTestConfig implements InlineMadTestConfigSig {
|
||||||
|
|||||||
@@ -60,22 +60,22 @@
|
|||||||
<div class="dropdown-caret"></div>
|
<div class="dropdown-caret"></div>
|
||||||
</summary>
|
</summary>
|
||||||
<ul class="dropdown-menu dropdown-menu-se dropdown-menu-dark">
|
<ul class="dropdown-menu dropdown-menu-se dropdown-menu-dark">
|
||||||
<li><a class="dropdown-item" href="codeql-overview">CodeQL overview</a></li>
|
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-overview">CodeQL overview</a></li>
|
||||||
<li class="dropdown-divider" role="separator"></li>
|
<li class="dropdown-divider" role="separator"></li>
|
||||||
<div class="dropdown-header">
|
<div class="dropdown-header">
|
||||||
CodeQL guides
|
CodeQL guides
|
||||||
</div>
|
</div>
|
||||||
<li><a class="dropdown-item" href="writing-codeql-queries">Writing CodeQL queries</a></li>
|
<li><a class="dropdown-item" href="https://codeql.github.com/docs/writing-codeql-queries">Writing CodeQL queries</a></li>
|
||||||
<li><a class="dropdown-item" href="codeql-language-guides">CodeQL language guides</a>
|
<li><a class="dropdown-item" href="https://codeql.github.com/docs/codeql-language-guides">CodeQL language guides</a>
|
||||||
<li class="dropdown-divider" role="separator"></li>
|
<li class="dropdown-divider" role="separator"></li>
|
||||||
<div class="dropdown-header">
|
<div class="dropdown-header">
|
||||||
Reference docs
|
Reference docs
|
||||||
</div>
|
</div>
|
||||||
<li><a class="dropdown-item" href="ql-language-reference/">QL language
|
<li><a class="dropdown-item" href="https://codeql.github.com/docs/ql-language-reference/">QL language
|
||||||
reference</a>
|
reference</a>
|
||||||
<li><a class="dropdown-item" href="../codeql-standard-libraries">CodeQL
|
<li><a class="dropdown-item" href="https://codeql.github.com/codeql-standard-libraries">CodeQL
|
||||||
standard-libraries</a>
|
standard-libraries</a>
|
||||||
<li><a class="dropdown-item" href="../codeql-query-help">CodeQL
|
<li><a class="dropdown-item" href="https://codeql.github.com/codeql-query-help">CodeQL
|
||||||
query help</a>
|
query help</a>
|
||||||
<li class="dropdown-divider" role="separator"></li>
|
<li class="dropdown-divider" role="separator"></li>
|
||||||
<div class="dropdown-header">
|
<div class="dropdown-header">
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
<div class="dropdown-header">
|
<div class="dropdown-header">
|
||||||
Academic
|
Academic
|
||||||
</div>
|
</div>
|
||||||
<li><a class="dropdown-item" href="../publications">QL publications</a>
|
<li><a class="dropdown-item" href="https://codeql.github.com/publications">QL publications</a>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@
|
|||||||
latest release of CodeQL...</div>
|
latest release of CodeQL...</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="Subhead border-0">
|
<div class="Subhead border-0">
|
||||||
<a href="codeql-overview/about-codeql">
|
<a href="codeql-overview/codeql-changelog/">
|
||||||
<div class="Subhead-heading f4 text-center">Change logs</div>
|
<div class="Subhead-heading f4 text-center">Change logs</div>
|
||||||
</a>
|
</a>
|
||||||
<div class="Subhead-description">Read about the improvements to the queries, libraries, and tooling in each release...</div>
|
<div class="Subhead-description">Read about the improvements to the queries, libraries, and tooling in each release...</div>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
Java,"Java 7 to 22 [5]_","javac (OpenJDK and Oracle JDK),
|
Java,"Java 7 to 22 [5]_","javac (OpenJDK and Oracle JDK),
|
||||||
|
|
||||||
Eclipse compiler for Java (ECJ) [6]_",``.java``
|
Eclipse compiler for Java (ECJ) [6]_",``.java``
|
||||||
Kotlin,"Kotlin 1.5.0 to 2.0.2\ *x*","kotlinc",``.kt``
|
Kotlin,"Kotlin 1.5.0 to 2.1.0\ *x*","kotlinc",``.kt``
|
||||||
JavaScript,ECMAScript 2022 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [7]_"
|
JavaScript,ECMAScript 2022 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhtm``, ``.xhtml``, ``.vue``, ``.hbs``, ``.ejs``, ``.njk``, ``.json``, ``.yaml``, ``.yml``, ``.raml``, ``.xml`` [7]_"
|
||||||
Python [8]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12",Not applicable,``.py``
|
Python [8]_,"2.7, 3.5, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12",Not applicable,``.py``
|
||||||
Ruby [9]_,"up to 3.3",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``"
|
Ruby [9]_,"up to 3.3",Not applicable,"``.rb``, ``.erb``, ``.gemspec``, ``Gemfile``"
|
||||||
|
|||||||
@@ -19,3 +19,11 @@ file_types:
|
|||||||
extensions:
|
extensions:
|
||||||
- .go
|
- .go
|
||||||
legacy_qltest_extraction: true
|
legacy_qltest_extraction: true
|
||||||
|
options:
|
||||||
|
extract_tests:
|
||||||
|
title: Whether to include Go test files in the CodeQL database.
|
||||||
|
description: >
|
||||||
|
A value indicating whether Go test files should be included in the CodeQL database.
|
||||||
|
The default is 'false'.
|
||||||
|
type: string
|
||||||
|
pattern: "^(false|true)$"
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ func usage() {
|
|||||||
fmt.Fprintf(os.Stderr, "--help Print this help.\n")
|
fmt.Fprintf(os.Stderr, "--help Print this help.\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseFlags(args []string, mimic bool) ([]string, []string) {
|
// extractTests is set (a) if we were manually commanded to extract tests via the relevant
|
||||||
|
// environment variable / extractor option, or (b) we're mimicking a `go test` command.
|
||||||
|
func parseFlags(args []string, mimic bool, extractTests bool) ([]string, []string, bool) {
|
||||||
i := 0
|
i := 0
|
||||||
buildFlags := []string{}
|
buildFlags := []string{}
|
||||||
for ; i < len(args) && strings.HasPrefix(args[i], "-"); i++ {
|
for ; i < len(args) && strings.HasPrefix(args[i], "-"); i++ {
|
||||||
@@ -44,9 +46,9 @@ func parseFlags(args []string, mimic bool) ([]string, []string) {
|
|||||||
if i+1 < len(args) {
|
if i+1 < len(args) {
|
||||||
i++
|
i++
|
||||||
command := args[i]
|
command := args[i]
|
||||||
if command == "build" || command == "install" || command == "run" {
|
if command == "build" || command == "install" || command == "run" || command == "test" {
|
||||||
log.Printf("Intercepting build")
|
log.Printf("Intercepting build for %s command", command)
|
||||||
return parseFlags(args[i+1:], true)
|
return parseFlags(args[i+1:], true, command == "test")
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Non-build command '%s'; skipping", strings.Join(args[1:], " "))
|
log.Printf("Non-build command '%s'; skipping", strings.Join(args[1:], " "))
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
@@ -63,12 +65,12 @@ func parseFlags(args []string, mimic bool) ([]string, []string) {
|
|||||||
|
|
||||||
// parse go build flags
|
// parse go build flags
|
||||||
switch args[i] {
|
switch args[i] {
|
||||||
// skip `-o output` and `-i`, if applicable
|
// skip `-o output`, `-i` and `-c`, if applicable
|
||||||
case "-o":
|
case "-o":
|
||||||
if i+1 < len(args) {
|
if i+1 < len(args) {
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
case "-i":
|
case "-i", "-c":
|
||||||
case "-p", "-asmflags", "-buildmode", "-compiler", "-gccgoflags", "-gcflags", "-installsuffix",
|
case "-p", "-asmflags", "-buildmode", "-compiler", "-gccgoflags", "-gcflags", "-installsuffix",
|
||||||
"-ldflags", "-mod", "-modfile", "-pkgdir", "-tags", "-toolexec", "-overlay":
|
"-ldflags", "-mod", "-modfile", "-pkgdir", "-tags", "-toolexec", "-overlay":
|
||||||
if i+1 < len(args) {
|
if i+1 < len(args) {
|
||||||
@@ -90,11 +92,12 @@ func parseFlags(args []string, mimic bool) ([]string, []string) {
|
|||||||
cpuprofile = os.Getenv("CODEQL_EXTRACTOR_GO_CPU_PROFILE")
|
cpuprofile = os.Getenv("CODEQL_EXTRACTOR_GO_CPU_PROFILE")
|
||||||
memprofile = os.Getenv("CODEQL_EXTRACTOR_GO_MEM_PROFILE")
|
memprofile = os.Getenv("CODEQL_EXTRACTOR_GO_MEM_PROFILE")
|
||||||
|
|
||||||
return buildFlags, args[i:]
|
return buildFlags, args[i:], extractTests
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
buildFlags, patterns := parseFlags(os.Args[1:], false)
|
extractTestsDefault := os.Getenv("CODEQL_EXTRACTOR_GO_OPTION_EXTRACT_TESTS") == "true"
|
||||||
|
buildFlags, patterns, extractTests := parseFlags(os.Args[1:], false, extractTestsDefault)
|
||||||
|
|
||||||
if cpuprofile != "" {
|
if cpuprofile != "" {
|
||||||
f, err := os.Create(cpuprofile)
|
f, err := os.Create(cpuprofile)
|
||||||
@@ -114,7 +117,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Build flags: '%s'; patterns: '%s'\n", strings.Join(buildFlags, " "), strings.Join(patterns, " "))
|
log.Printf("Build flags: '%s'; patterns: '%s'\n", strings.Join(buildFlags, " "), strings.Join(patterns, " "))
|
||||||
err := extractor.ExtractWithFlags(buildFlags, patterns)
|
err := extractor.ExtractWithFlags(buildFlags, patterns, extractTests)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errString := err.Error()
|
errString := err.Error()
|
||||||
if strings.Contains(errString, "unexpected directory layout:") {
|
if strings.Contains(errString, "unexpected directory layout:") {
|
||||||
|
|||||||
@@ -59,11 +59,11 @@ func init() {
|
|||||||
|
|
||||||
// Extract extracts the packages specified by the given patterns
|
// Extract extracts the packages specified by the given patterns
|
||||||
func Extract(patterns []string) error {
|
func Extract(patterns []string) error {
|
||||||
return ExtractWithFlags(nil, patterns)
|
return ExtractWithFlags(nil, patterns, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExtractWithFlags extracts the packages specified by the given patterns and build flags
|
// ExtractWithFlags extracts the packages specified by the given patterns and build flags
|
||||||
func ExtractWithFlags(buildFlags []string, patterns []string) error {
|
func ExtractWithFlags(buildFlags []string, patterns []string, extractTests bool) error {
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
|
|
||||||
extraction := NewExtraction(buildFlags, patterns)
|
extraction := NewExtraction(buildFlags, patterns)
|
||||||
@@ -81,7 +81,14 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Running packages.Load.")
|
testMessage := ""
|
||||||
|
if extractTests {
|
||||||
|
testMessage = " (test extraction enabled)"
|
||||||
|
}
|
||||||
|
log.Printf("Running packages.Load%s.", testMessage)
|
||||||
|
|
||||||
|
// This includes test packages if either we're tracing a `go test` command,
|
||||||
|
// or if CODEQL_EXTRACTOR_GO_OPTION_EXTRACT_TESTS is set to "true".
|
||||||
cfg := &packages.Config{
|
cfg := &packages.Config{
|
||||||
Mode: packages.NeedName | packages.NeedFiles |
|
Mode: packages.NeedName | packages.NeedFiles |
|
||||||
packages.NeedCompiledGoFiles |
|
packages.NeedCompiledGoFiles |
|
||||||
@@ -89,6 +96,7 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error {
|
|||||||
packages.NeedTypes | packages.NeedTypesSizes |
|
packages.NeedTypes | packages.NeedTypesSizes |
|
||||||
packages.NeedTypesInfo | packages.NeedSyntax,
|
packages.NeedTypesInfo | packages.NeedSyntax,
|
||||||
BuildFlags: buildFlags,
|
BuildFlags: buildFlags,
|
||||||
|
Tests: extractTests,
|
||||||
}
|
}
|
||||||
pkgs, err := packages.Load(cfg, patterns...)
|
pkgs, err := packages.Load(cfg, patterns...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -123,7 +131,7 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error {
|
|||||||
if os.Getenv("CODEQL_EXTRACTOR_GO_FAST_PACKAGE_INFO") != "false" {
|
if os.Getenv("CODEQL_EXTRACTOR_GO_FAST_PACKAGE_INFO") != "false" {
|
||||||
log.Printf("Running go list to resolve package and module directories.")
|
log.Printf("Running go list to resolve package and module directories.")
|
||||||
// get all packages information
|
// get all packages information
|
||||||
pkgInfos, err = toolchain.GetPkgsInfo(patterns, true, modFlags...)
|
pkgInfos, err = toolchain.GetPkgsInfo(patterns, true, extractTests, modFlags...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error getting dependency package or module directories: %v.", err)
|
log.Fatalf("Error getting dependency package or module directories: %v.", err)
|
||||||
}
|
}
|
||||||
@@ -132,8 +140,36 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error {
|
|||||||
|
|
||||||
pkgsNotFound := make([]string, 0, len(pkgs))
|
pkgsNotFound := make([]string, 0, len(pkgs))
|
||||||
|
|
||||||
|
// Build a map from package paths to their longest IDs--
|
||||||
|
// in the context of a `go test -c` compilation, we will see the same package more than
|
||||||
|
// once, with IDs like "abc.com/pkgname [abc.com/pkgname.test]" to distinguish the version
|
||||||
|
// that contains and is used by test code.
|
||||||
|
// For our purposes it is simplest to just ignore the non-test version, since the test
|
||||||
|
// version seems to be a superset of it.
|
||||||
|
longestPackageIds := make(map[string]string)
|
||||||
|
packages.Visit(pkgs, nil, func(pkg *packages.Package) {
|
||||||
|
if longestIDSoFar, present := longestPackageIds[pkg.PkgPath]; present {
|
||||||
|
if len(pkg.ID) > len(longestIDSoFar) {
|
||||||
|
longestPackageIds[pkg.PkgPath] = pkg.ID
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
longestPackageIds[pkg.PkgPath] = pkg.ID
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// Do a post-order traversal and extract the package scope of each package
|
// Do a post-order traversal and extract the package scope of each package
|
||||||
packages.Visit(pkgs, nil, func(pkg *packages.Package) {
|
packages.Visit(pkgs, nil, func(pkg *packages.Package) {
|
||||||
|
// Note that if test extraction is enabled, we will encounter a package twice here:
|
||||||
|
// once as the main package, and once as the test package (with a package ID like
|
||||||
|
// "abc.com/pkgname [abc.com/pkgname.test]").
|
||||||
|
//
|
||||||
|
// We will extract it both times however, because we need to visit the packages
|
||||||
|
// in the right order in order to visit used types before their users, and the
|
||||||
|
// ordering determined by packages.Visit for the main and the test package may differ.
|
||||||
|
//
|
||||||
|
// This should only cause some wasted time and not inconsistency because the names for
|
||||||
|
// objects seen in this process should be the same each time.
|
||||||
|
|
||||||
log.Printf("Processing package %s.", pkg.PkgPath)
|
log.Printf("Processing package %s.", pkg.PkgPath)
|
||||||
|
|
||||||
if _, ok := pkgInfos[pkg.PkgPath]; !ok {
|
if _, ok := pkgInfos[pkg.PkgPath]; !ok {
|
||||||
@@ -210,6 +246,19 @@ func ExtractWithFlags(buildFlags []string, patterns []string) error {
|
|||||||
|
|
||||||
// extract AST information for all packages
|
// extract AST information for all packages
|
||||||
packages.Visit(pkgs, nil, func(pkg *packages.Package) {
|
packages.Visit(pkgs, nil, func(pkg *packages.Package) {
|
||||||
|
|
||||||
|
// If this is a variant of a package that also occurs with a longer ID, skip it;
|
||||||
|
// otherwise we would extract the same file more than once including extracting the
|
||||||
|
// body of methods twice, causing database inconsistencies.
|
||||||
|
//
|
||||||
|
// We prefer the version with the longest ID because that is (so far as I know) always
|
||||||
|
// the version that defines more entities -- the only case I'm aware of being a test
|
||||||
|
// variant of a package, which includes test-only functions in addition to the complete
|
||||||
|
// contents of the main variant.
|
||||||
|
if pkg.ID != longestPackageIds[pkg.PkgPath] {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for root := range wantedRoots {
|
for root := range wantedRoots {
|
||||||
pkgInfo := pkgInfos[pkg.PkgPath]
|
pkgInfo := pkgInfos[pkg.PkgPath]
|
||||||
relDir, err := filepath.Rel(root, pkgInfo.PkgDir)
|
relDir, err := filepath.Rel(root, pkgInfo.PkgDir)
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ type PkgInfo struct {
|
|||||||
// GetPkgsInfo gets the absolute module and package root directories for the packages matched by the
|
// GetPkgsInfo gets the absolute module and package root directories for the packages matched by the
|
||||||
// patterns `patterns`. It passes to `go list` the flags specified by `flags`. If `includingDeps`
|
// patterns `patterns`. It passes to `go list` the flags specified by `flags`. If `includingDeps`
|
||||||
// is true, all dependencies will also be included.
|
// is true, all dependencies will also be included.
|
||||||
func GetPkgsInfo(patterns []string, includingDeps bool, flags ...string) (map[string]PkgInfo, error) {
|
func GetPkgsInfo(patterns []string, includingDeps bool, extractTests bool, flags ...string) (map[string]PkgInfo, error) {
|
||||||
// enable module mode so that we can find a module root if it exists, even if go module support is
|
// enable module mode so that we can find a module root if it exists, even if go module support is
|
||||||
// disabled by a build
|
// disabled by a build
|
||||||
if includingDeps {
|
if includingDeps {
|
||||||
@@ -231,6 +231,11 @@ func GetPkgsInfo(patterns []string, includingDeps bool, flags ...string) (map[st
|
|||||||
flags = append(flags, "-deps")
|
flags = append(flags, "-deps")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if extractTests {
|
||||||
|
// Without the `-test` flag, test packages would be omitted from the `go list` output.
|
||||||
|
flags = append(flags, "-test")
|
||||||
|
}
|
||||||
|
|
||||||
// using -json overrides -f format
|
// using -json overrides -f format
|
||||||
output, err := RunList("", patterns, append(flags, "-json")...)
|
output, err := RunList("", patterns, append(flags, "-json")...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -272,6 +277,12 @@ func GetPkgsInfo(patterns []string, includingDeps bool, flags ...string) (map[st
|
|||||||
PkgDir: pkgAbsDir,
|
PkgDir: pkgAbsDir,
|
||||||
ModDir: modAbsDir,
|
ModDir: modAbsDir,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if extractTests && strings.Contains(pkgInfo.ImportPath, " [") {
|
||||||
|
// Assume " [" is the start of a qualifier, and index the package by its base name
|
||||||
|
baseImportPath := strings.Split(pkgInfo.ImportPath, " [")[0]
|
||||||
|
pkgInfoMapping[baseImportPath] = pkgInfoMapping[pkgInfo.ImportPath]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return pkgInfoMapping, nil
|
return pkgInfoMapping, nil
|
||||||
}
|
}
|
||||||
|
|||||||
16
go/ql/integration-tests/go-mod-sample/src/blackbox_test.go
Normal file
16
go/ql/integration-tests/go-mod-sample/src/blackbox_test.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package makesample_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"makesample"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Note because this is a test we do NOT expect this to be extracted.
|
||||||
|
func TestTestMe(t *testing.T) {
|
||||||
|
|
||||||
|
publicResult := makesample.PublicFunction()
|
||||||
|
if publicResult != 1 {
|
||||||
|
t.Errorf("Expected 1, got %d", publicResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,3 +10,7 @@ func test() {
|
|||||||
header.Version = 4
|
header.Version = 4
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func PublicFunction() int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|||||||
15
go/ql/integration-tests/go-mod-sample/src/test_test.go
Normal file
15
go/ql/integration-tests/go-mod-sample/src/test_test.go
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package makesample
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTestMe(t *testing.T) {
|
||||||
|
|
||||||
|
// Note because this is a test we do NOT expect this to be extracted.
|
||||||
|
publicResult := PublicFunction()
|
||||||
|
if publicResult != 1 {
|
||||||
|
t.Errorf("Expected 1, got %d", publicResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
all:
|
||||||
|
go get
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
go 1.14
|
||||||
|
|
||||||
|
module testsample
|
||||||
45
go/ql/integration-tests/test-extraction-autobuild/src/go.sum
Normal file
45
go/ql/integration-tests/test-extraction-autobuild/src/go.sum
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
|
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
|
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||||
|
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||||
|
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
|
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package testsample
|
||||||
|
|
||||||
|
func PublicFunction() int { return 1 }
|
||||||
|
|
||||||
|
func privateFunction() int { return 2 }
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package testsample_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"testsample"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTestMe(t *testing.T) {
|
||||||
|
|
||||||
|
publicResult := testsample.PublicFunction()
|
||||||
|
if publicResult != 1 {
|
||||||
|
t.Errorf("Expected 1, got %d", publicResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package testsample
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTestMe(t *testing.T) {
|
||||||
|
|
||||||
|
publicResult := PublicFunction()
|
||||||
|
if publicResult != 1 {
|
||||||
|
t.Errorf("Expected 1, got %d", publicResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
privateResult := privateFunction()
|
||||||
|
if privateResult != 2 {
|
||||||
|
t.Errorf("Expected 2, got %d", privateResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#select
|
||||||
|
| src/testme.go:0:0:0:0 | src/testme.go |
|
||||||
|
| src/testme_blackbox_test.go:0:0:0:0 | src/testme_blackbox_test.go |
|
||||||
|
| src/testme_test.go:0:0:0:0 | src/testme_test.go |
|
||||||
|
calls
|
||||||
|
| src/testme_blackbox_test.go:10:18:10:44 | call to PublicFunction | src/testme.go:3:1:3:38 | function declaration |
|
||||||
|
| src/testme_test.go:9:18:9:33 | call to PublicFunction | src/testme.go:3:1:3:38 | function declaration |
|
||||||
|
| src/testme_test.go:14:19:14:35 | call to privateFunction | src/testme.go:5:1:5:39 | function declaration |
|
||||||
|
extractionErrors
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
def test(codeql, go):
|
||||||
|
codeql.database.create(source_root="src", extractor_option = ["extract_tests=true"])
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import go
|
||||||
|
import semmle.go.DiagnosticsReporting
|
||||||
|
|
||||||
|
from GoFile f
|
||||||
|
select f
|
||||||
|
|
||||||
|
query predicate calls(CallExpr ce, FuncDecl f) { f = ce.getTarget().getFuncDecl() }
|
||||||
|
|
||||||
|
query predicate extractionErrors(string msg, int sev) { reportableDiagnostics(_, msg, sev) }
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
all:
|
||||||
|
go get
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
go 1.14
|
||||||
|
|
||||||
|
module testsample
|
||||||
45
go/ql/integration-tests/test-extraction-traced/src/go.sum
Normal file
45
go/ql/integration-tests/test-extraction-traced/src/go.sum
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
|
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
|
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||||
|
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||||
|
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
|
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package testsample
|
||||||
|
|
||||||
|
func PublicFunction() int { return 1 }
|
||||||
|
|
||||||
|
func privateFunction() int { return 2 }
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package testsample_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"testsample"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTestMe(t *testing.T) {
|
||||||
|
|
||||||
|
publicResult := testsample.PublicFunction()
|
||||||
|
if publicResult != 1 {
|
||||||
|
t.Errorf("Expected 1, got %d", publicResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package testsample
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTestMe(t *testing.T) {
|
||||||
|
|
||||||
|
publicResult := PublicFunction()
|
||||||
|
if publicResult != 1 {
|
||||||
|
t.Errorf("Expected 1, got %d", publicResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
privateResult := privateFunction()
|
||||||
|
if privateResult != 2 {
|
||||||
|
t.Errorf("Expected 2, got %d", privateResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#select
|
||||||
|
| src/testme.go:0:0:0:0 | src/testme.go |
|
||||||
|
| src/testme_blackbox_test.go:0:0:0:0 | src/testme_blackbox_test.go |
|
||||||
|
| src/testme_test.go:0:0:0:0 | src/testme_test.go |
|
||||||
|
calls
|
||||||
|
| src/testme_blackbox_test.go:10:18:10:44 | call to PublicFunction | src/testme.go:3:1:3:38 | function declaration |
|
||||||
|
| src/testme_test.go:9:18:9:33 | call to PublicFunction | src/testme.go:3:1:3:38 | function declaration |
|
||||||
|
| src/testme_test.go:14:19:14:35 | call to privateFunction | src/testme.go:5:1:5:39 | function declaration |
|
||||||
|
extractionErrors
|
||||||
4
go/ql/integration-tests/test-extraction-traced/test.py
Normal file
4
go/ql/integration-tests/test-extraction-traced/test.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
def test(codeql, go):
|
||||||
|
codeql.database.create(source_root="src", command="go test -c")
|
||||||
9
go/ql/integration-tests/test-extraction-traced/test.ql
Normal file
9
go/ql/integration-tests/test-extraction-traced/test.ql
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import go
|
||||||
|
import semmle.go.DiagnosticsReporting
|
||||||
|
|
||||||
|
from GoFile f
|
||||||
|
select f
|
||||||
|
|
||||||
|
query predicate calls(CallExpr ce, FuncDecl f) { f = ce.getTarget().getFuncDecl() }
|
||||||
|
|
||||||
|
query predicate extractionErrors(string msg, int sev) { reportableDiagnostics(_, msg, sev) }
|
||||||
2
go/ql/integration-tests/traced-extraction/src/Makefile
Normal file
2
go/ql/integration-tests/traced-extraction/src/Makefile
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
all:
|
||||||
|
go get
|
||||||
3
go/ql/integration-tests/traced-extraction/src/go.mod
Normal file
3
go/ql/integration-tests/traced-extraction/src/go.mod
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
go 1.14
|
||||||
|
|
||||||
|
module testsample
|
||||||
45
go/ql/integration-tests/traced-extraction/src/go.sum
Normal file
45
go/ql/integration-tests/traced-extraction/src/go.sum
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||||
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
|
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||||
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
|
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||||
|
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
|
golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||||
|
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||||
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||||
|
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||||
|
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||||
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
|
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||||
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
5
go/ql/integration-tests/traced-extraction/src/testme.go
Normal file
5
go/ql/integration-tests/traced-extraction/src/testme.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package testsample
|
||||||
|
|
||||||
|
func PublicFunction() int { return 1 }
|
||||||
|
|
||||||
|
func privateFunction() int { return 2 }
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package testsample_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"testsample"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTestMe(t *testing.T) {
|
||||||
|
|
||||||
|
// Note because this is a test we do NOT expect it to be extracted
|
||||||
|
publicResult := testsample.PublicFunction()
|
||||||
|
if publicResult != 1 {
|
||||||
|
t.Errorf("Expected 1, got %d", publicResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
20
go/ql/integration-tests/traced-extraction/src/testme_test.go
Normal file
20
go/ql/integration-tests/traced-extraction/src/testme_test.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package testsample
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTestMe(t *testing.T) {
|
||||||
|
|
||||||
|
// Note because this is a test we do NOT expect it to be extracted
|
||||||
|
publicResult := PublicFunction()
|
||||||
|
if publicResult != 1 {
|
||||||
|
t.Errorf("Expected 1, got %d", publicResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
privateResult := privateFunction()
|
||||||
|
if privateResult != 2 {
|
||||||
|
t.Errorf("Expected 2, got %d", privateResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
4
go/ql/integration-tests/traced-extraction/test.expected
Normal file
4
go/ql/integration-tests/traced-extraction/test.expected
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#select
|
||||||
|
| src/testme.go:0:0:0:0 | src/testme.go |
|
||||||
|
calls
|
||||||
|
extractionErrors
|
||||||
4
go/ql/integration-tests/traced-extraction/test.py
Normal file
4
go/ql/integration-tests/traced-extraction/test.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
def test(codeql, go):
|
||||||
|
codeql.database.create(source_root="src", command="go build")
|
||||||
9
go/ql/integration-tests/traced-extraction/test.ql
Normal file
9
go/ql/integration-tests/traced-extraction/test.ql
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import go
|
||||||
|
import semmle.go.DiagnosticsReporting
|
||||||
|
|
||||||
|
from GoFile f
|
||||||
|
select f
|
||||||
|
|
||||||
|
query predicate calls(CallExpr ce, FuncDecl f) { f = ce.getTarget().getFuncDecl() }
|
||||||
|
|
||||||
|
query predicate extractionErrors(string msg, int sev) { reportableDiagnostics(_, msg, sev) }
|
||||||
@@ -922,8 +922,19 @@ class SignatureType extends @signaturetype, CompositeType {
|
|||||||
language[monotonicAggregates]
|
language[monotonicAggregates]
|
||||||
override string pp() {
|
override string pp() {
|
||||||
result =
|
result =
|
||||||
"func(" + concat(int i, Type tp | tp = this.getParameterType(i) | tp.pp(), ", " order by i) +
|
"func(" +
|
||||||
") " + concat(int i, Type tp | tp = this.getResultType(i) | tp.pp(), ", " order by i)
|
concat(int i, Type tp, string prefix |
|
||||||
|
if i = this.getNumParameter() - 1 and this.isVariadic()
|
||||||
|
then
|
||||||
|
tp = this.getParameterType(i).(SliceType).getElementType() and
|
||||||
|
prefix = "..."
|
||||||
|
else (
|
||||||
|
tp = this.getParameterType(i) and
|
||||||
|
prefix = ""
|
||||||
|
)
|
||||||
|
|
|
||||||
|
prefix + tp.pp(), ", " order by i
|
||||||
|
) + ") " + concat(int i, Type tp | tp = this.getResultType(i) | tp.pp(), ", " order by i)
|
||||||
}
|
}
|
||||||
|
|
||||||
override string toString() { result = "signature type" }
|
override string toString() { result = "signature type" }
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ deprecated private module Config implements FullStateConfigSig {
|
|||||||
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
|
||||||
|
|
||||||
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
predicate includeHiddenNodes() { any(Configuration config).includeHiddenNodes() }
|
||||||
|
|
||||||
|
predicate observeDiffInformedIncrementalMode() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private import Impl<Config> as I
|
deprecated private import Impl<Config> as I
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
* @tags security
|
* @tags security
|
||||||
* external/cwe/cwe-190
|
* external/cwe/cwe-190
|
||||||
* external/cwe/cwe-681
|
* external/cwe/cwe-681
|
||||||
* @precision very-high
|
* @precision high
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import go
|
import go
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: queryMetadata
|
||||||
|
---
|
||||||
|
* The precision of the `go/incorrect-integer-conversion-query` query was decreased from `very-high` to `high`, since there is at least one known class of false positives involving dynamic bounds checking.
|
||||||
@@ -25,12 +25,9 @@ edges
|
|||||||
| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:76:24:76:32 | untrusted | provenance | Src:MaD:1 |
|
| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:76:24:76:32 | untrusted | provenance | Src:MaD:1 |
|
||||||
| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:80:22:80:30 | untrusted | provenance | Src:MaD:1 |
|
| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:80:22:80:30 | untrusted | provenance | Src:MaD:1 |
|
||||||
| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:81:25:81:33 | untrusted | provenance | Src:MaD:1 |
|
| LDAPInjection.go:57:15:57:29 | call to UserAgent | LDAPInjection.go:81:25:81:33 | untrusted | provenance | Src:MaD:1 |
|
||||||
| LDAPInjection.go:62:3:62:33 | slice literal [array] | LDAPInjection.go:62:3:62:33 | slice literal | provenance | |
|
| LDAPInjection.go:62:24:62:32 | untrusted | LDAPInjection.go:62:3:62:33 | slice literal | provenance | |
|
||||||
| LDAPInjection.go:62:24:62:32 | untrusted | LDAPInjection.go:62:3:62:33 | slice literal [array] | provenance | |
|
| LDAPInjection.go:69:24:69:32 | untrusted | LDAPInjection.go:69:3:69:33 | slice literal | provenance | |
|
||||||
| LDAPInjection.go:69:3:69:33 | slice literal [array] | LDAPInjection.go:69:3:69:33 | slice literal | provenance | |
|
| LDAPInjection.go:76:24:76:32 | untrusted | LDAPInjection.go:76:3:76:33 | slice literal | provenance | |
|
||||||
| LDAPInjection.go:69:24:69:32 | untrusted | LDAPInjection.go:69:3:69:33 | slice literal [array] | provenance | |
|
|
||||||
| LDAPInjection.go:76:3:76:33 | slice literal [array] | LDAPInjection.go:76:3:76:33 | slice literal | provenance | |
|
|
||||||
| LDAPInjection.go:76:24:76:32 | untrusted | LDAPInjection.go:76:3:76:33 | slice literal [array] | provenance | |
|
|
||||||
models
|
models
|
||||||
| 1 | Source: net/http; Request; true; UserAgent; ; ; ReturnValue; remote; manual |
|
| 1 | Source: net/http; Request; true; UserAgent; ; ; ReturnValue; remote; manual |
|
||||||
nodes
|
nodes
|
||||||
@@ -38,17 +35,14 @@ nodes
|
|||||||
| LDAPInjection.go:59:3:59:11 | untrusted | semmle.label | untrusted |
|
| LDAPInjection.go:59:3:59:11 | untrusted | semmle.label | untrusted |
|
||||||
| LDAPInjection.go:61:3:61:51 | ...+... | semmle.label | ...+... |
|
| LDAPInjection.go:61:3:61:51 | ...+... | semmle.label | ...+... |
|
||||||
| LDAPInjection.go:62:3:62:33 | slice literal | semmle.label | slice literal |
|
| LDAPInjection.go:62:3:62:33 | slice literal | semmle.label | slice literal |
|
||||||
| LDAPInjection.go:62:3:62:33 | slice literal [array] | semmle.label | slice literal [array] |
|
|
||||||
| LDAPInjection.go:62:24:62:32 | untrusted | semmle.label | untrusted |
|
| LDAPInjection.go:62:24:62:32 | untrusted | semmle.label | untrusted |
|
||||||
| LDAPInjection.go:66:3:66:11 | untrusted | semmle.label | untrusted |
|
| LDAPInjection.go:66:3:66:11 | untrusted | semmle.label | untrusted |
|
||||||
| LDAPInjection.go:68:3:68:51 | ...+... | semmle.label | ...+... |
|
| LDAPInjection.go:68:3:68:51 | ...+... | semmle.label | ...+... |
|
||||||
| LDAPInjection.go:69:3:69:33 | slice literal | semmle.label | slice literal |
|
| LDAPInjection.go:69:3:69:33 | slice literal | semmle.label | slice literal |
|
||||||
| LDAPInjection.go:69:3:69:33 | slice literal [array] | semmle.label | slice literal [array] |
|
|
||||||
| LDAPInjection.go:69:24:69:32 | untrusted | semmle.label | untrusted |
|
| LDAPInjection.go:69:24:69:32 | untrusted | semmle.label | untrusted |
|
||||||
| LDAPInjection.go:73:3:73:11 | untrusted | semmle.label | untrusted |
|
| LDAPInjection.go:73:3:73:11 | untrusted | semmle.label | untrusted |
|
||||||
| LDAPInjection.go:75:3:75:51 | ...+... | semmle.label | ...+... |
|
| LDAPInjection.go:75:3:75:51 | ...+... | semmle.label | ...+... |
|
||||||
| LDAPInjection.go:76:3:76:33 | slice literal | semmle.label | slice literal |
|
| LDAPInjection.go:76:3:76:33 | slice literal | semmle.label | slice literal |
|
||||||
| LDAPInjection.go:76:3:76:33 | slice literal [array] | semmle.label | slice literal [array] |
|
|
||||||
| LDAPInjection.go:76:24:76:32 | untrusted | semmle.label | untrusted |
|
| LDAPInjection.go:76:24:76:32 | untrusted | semmle.label | untrusted |
|
||||||
| LDAPInjection.go:80:22:80:30 | untrusted | semmle.label | untrusted |
|
| LDAPInjection.go:80:22:80:30 | untrusted | semmle.label | untrusted |
|
||||||
| LDAPInjection.go:81:25:81:33 | untrusted | semmle.label | untrusted |
|
| LDAPInjection.go:81:25:81:33 | untrusted | semmle.label | untrusted |
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ edges
|
|||||||
| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:21:15:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:21:15:21 | c | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:15:21:15:21 | c | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:15:21:15:21 | c | CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:15:21:15:21 | c | CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
||||||
@@ -24,6 +25,8 @@ edges
|
|||||||
| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | |
|
||||||
@@ -42,6 +45,8 @@ edges
|
|||||||
| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | |
|
||||||
@@ -60,6 +65,8 @@ edges
|
|||||||
| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | |
|
||||||
@@ -78,6 +85,8 @@ edges
|
|||||||
| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:55:2:55:4 | definition of val | CookieWithoutHttpOnly.go:59:13:59:15 | val | provenance | |
|
| CookieWithoutHttpOnly.go:55:2:55:4 | definition of val | CookieWithoutHttpOnly.go:59:13:59:15 | val | provenance | |
|
||||||
@@ -98,6 +107,8 @@ edges
|
|||||||
| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:65:2:65:4 | definition of val | CookieWithoutHttpOnly.go:69:13:69:15 | val | provenance | |
|
| CookieWithoutHttpOnly.go:65:2:65:4 | definition of val | CookieWithoutHttpOnly.go:69:13:69:15 | val | provenance | |
|
||||||
@@ -118,6 +129,8 @@ edges
|
|||||||
| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:75:2:75:4 | definition of val | CookieWithoutHttpOnly.go:80:15:80:17 | val | provenance | |
|
| CookieWithoutHttpOnly.go:75:2:75:4 | definition of val | CookieWithoutHttpOnly.go:80:15:80:17 | val | provenance | |
|
||||||
@@ -138,6 +151,8 @@ edges
|
|||||||
| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:85:2:85:4 | definition of val | CookieWithoutHttpOnly.go:90:15:90:17 | val | provenance | |
|
| CookieWithoutHttpOnly.go:85:2:85:4 | definition of val | CookieWithoutHttpOnly.go:90:15:90:17 | val | provenance | |
|
||||||
@@ -158,6 +173,8 @@ edges
|
|||||||
| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | |
|
||||||
@@ -168,6 +185,7 @@ edges
|
|||||||
| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:21:100:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:21:100:21 | c | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:100:21:100:21 | c | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:100:21:100:21 | c | CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:100:21:100:21 | c | CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:104:10:104:18 | "session" | CookieWithoutHttpOnly.go:106:10:106:13 | name | provenance | |
|
| CookieWithoutHttpOnly.go:104:10:104:18 | "session" | CookieWithoutHttpOnly.go:106:10:106:13 | name | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | |
|
||||||
@@ -186,6 +204,8 @@ edges
|
|||||||
| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:114:13:114:24 | "login_name" | CookieWithoutHttpOnly.go:116:10:116:16 | session | provenance | |
|
| CookieWithoutHttpOnly.go:114:13:114:24 | "login_name" | CookieWithoutHttpOnly.go:116:10:116:16 | session | provenance | |
|
||||||
@@ -205,6 +225,8 @@ edges
|
|||||||
| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | |
|
| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | |
|
| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | |
|
||||||
|
| CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | provenance | |
|
| CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | provenance | |
|
||||||
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | |
|
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | |
|
||||||
|
|||||||
@@ -53,10 +53,10 @@ input.go:
|
|||||||
# 20| 0: [CallExpr] call to Println
|
# 20| 0: [CallExpr] call to Println
|
||||||
# 20| Type = (int, error)
|
# 20| Type = (int, error)
|
||||||
# 20| 0: [FunctionName, SelectorExpr] selection of Println
|
# 20| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 20| Type = func([]interface { }) int, error
|
# 20| Type = func(...interface { }) int, error
|
||||||
# 20| 0: [Ident, PackageName] fmt
|
# 20| 0: [Ident, PackageName] fmt
|
||||||
# 20| 1: [FunctionName, Ident] Println
|
# 20| 1: [FunctionName, Ident] Println
|
||||||
# 20| Type = func([]interface { }) int, error
|
# 20| Type = func(...interface { }) int, error
|
||||||
# 20| 1: [StringLit] "Hi"
|
# 20| 1: [StringLit] "Hi"
|
||||||
# 20| Type = string
|
# 20| Type = string
|
||||||
# 20| Value = [StringLit] Hi
|
# 20| Value = [StringLit] Hi
|
||||||
@@ -203,10 +203,10 @@ input.go:
|
|||||||
# 52| 0: [CallExpr] call to Println
|
# 52| 0: [CallExpr] call to Println
|
||||||
# 52| Type = (int, error)
|
# 52| Type = (int, error)
|
||||||
# 52| 0: [FunctionName, SelectorExpr] selection of Println
|
# 52| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 52| Type = func([]interface { }) int, error
|
# 52| Type = func(...interface { }) int, error
|
||||||
# 52| 0: [Ident, PackageName] fmt
|
# 52| 0: [Ident, PackageName] fmt
|
||||||
# 52| 1: [FunctionName, Ident] Println
|
# 52| 1: [FunctionName, Ident] Println
|
||||||
# 52| Type = func([]interface { }) int, error
|
# 52| Type = func(...interface { }) int, error
|
||||||
# 52| 1: [StringLit] "Heard from ch1"
|
# 52| 1: [StringLit] "Heard from ch1"
|
||||||
# 52| Type = string
|
# 52| Type = string
|
||||||
# 52| Value = [StringLit] Heard from ch1
|
# 52| Value = [StringLit] Heard from ch1
|
||||||
@@ -229,20 +229,20 @@ input.go:
|
|||||||
# 54| 0: [CallExpr] call to Println
|
# 54| 0: [CallExpr] call to Println
|
||||||
# 54| Type = (int, error)
|
# 54| Type = (int, error)
|
||||||
# 54| 0: [FunctionName, SelectorExpr] selection of Println
|
# 54| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 54| Type = func([]interface { }) int, error
|
# 54| Type = func(...interface { }) int, error
|
||||||
# 54| 0: [Ident, PackageName] fmt
|
# 54| 0: [Ident, PackageName] fmt
|
||||||
# 54| 1: [FunctionName, Ident] Println
|
# 54| 1: [FunctionName, Ident] Println
|
||||||
# 54| Type = func([]interface { }) int, error
|
# 54| Type = func(...interface { }) int, error
|
||||||
# 54| 1: [Ident, VariableName] a
|
# 54| 1: [Ident, VariableName] a
|
||||||
# 54| Type = [1]float32
|
# 54| Type = [1]float32
|
||||||
# 55| 2: [ExprStmt] expression statement
|
# 55| 2: [ExprStmt] expression statement
|
||||||
# 55| 0: [CallExpr] call to Println
|
# 55| 0: [CallExpr] call to Println
|
||||||
# 55| Type = (int, error)
|
# 55| Type = (int, error)
|
||||||
# 55| 0: [FunctionName, SelectorExpr] selection of Println
|
# 55| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 55| Type = func([]interface { }) int, error
|
# 55| Type = func(...interface { }) int, error
|
||||||
# 55| 0: [Ident, PackageName] fmt
|
# 55| 0: [Ident, PackageName] fmt
|
||||||
# 55| 1: [FunctionName, Ident] Println
|
# 55| 1: [FunctionName, Ident] Println
|
||||||
# 55| Type = func([]interface { }) int, error
|
# 55| Type = func(...interface { }) int, error
|
||||||
# 55| 1: [Ident, VariableName] w
|
# 55| 1: [Ident, VariableName] w
|
||||||
# 55| Type = bool
|
# 55| Type = bool
|
||||||
# 56| 2: [CommClause] comm clause
|
# 56| 2: [CommClause] comm clause
|
||||||
@@ -250,10 +250,10 @@ input.go:
|
|||||||
# 57| 0: [CallExpr] call to Println
|
# 57| 0: [CallExpr] call to Println
|
||||||
# 57| Type = (int, error)
|
# 57| Type = (int, error)
|
||||||
# 57| 0: [FunctionName, SelectorExpr] selection of Println
|
# 57| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 57| Type = func([]interface { }) int, error
|
# 57| Type = func(...interface { }) int, error
|
||||||
# 57| 0: [Ident, PackageName] fmt
|
# 57| 0: [Ident, PackageName] fmt
|
||||||
# 57| 1: [FunctionName, Ident] Println
|
# 57| 1: [FunctionName, Ident] Println
|
||||||
# 57| Type = func([]interface { }) int, error
|
# 57| Type = func(...interface { }) int, error
|
||||||
# 58| 3: [CommClause] comm clause
|
# 58| 3: [CommClause] comm clause
|
||||||
# 58| 0: [SendStmt] send statement
|
# 58| 0: [SendStmt] send statement
|
||||||
# 58| 0: [Ident, VariableName] ch1
|
# 58| 0: [Ident, VariableName] ch1
|
||||||
@@ -297,10 +297,10 @@ input.go:
|
|||||||
# 67| 0: [CallExpr] call to Println
|
# 67| 0: [CallExpr] call to Println
|
||||||
# 67| Type = (int, error)
|
# 67| Type = (int, error)
|
||||||
# 67| 0: [FunctionName, SelectorExpr] selection of Println
|
# 67| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 67| Type = func([]interface { }) int, error
|
# 67| Type = func(...interface { }) int, error
|
||||||
# 67| 0: [Ident, PackageName] fmt
|
# 67| 0: [Ident, PackageName] fmt
|
||||||
# 67| 1: [FunctionName, Ident] Println
|
# 67| 1: [FunctionName, Ident] Println
|
||||||
# 67| Type = func([]interface { }) int, error
|
# 67| Type = func(...interface { }) int, error
|
||||||
# 67| 1: [Ident, VariableName] x
|
# 67| 1: [Ident, VariableName] x
|
||||||
# 67| Type = int
|
# 67| Type = int
|
||||||
# 68| 2: [BlockStmt] block statement
|
# 68| 2: [BlockStmt] block statement
|
||||||
@@ -316,10 +316,10 @@ input.go:
|
|||||||
# 69| 0: [CallExpr] call to Println
|
# 69| 0: [CallExpr] call to Println
|
||||||
# 69| Type = (int, error)
|
# 69| Type = (int, error)
|
||||||
# 69| 0: [FunctionName, SelectorExpr] selection of Println
|
# 69| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 69| Type = func([]interface { }) int, error
|
# 69| Type = func(...interface { }) int, error
|
||||||
# 69| 0: [Ident, PackageName] fmt
|
# 69| 0: [Ident, PackageName] fmt
|
||||||
# 69| 1: [FunctionName, Ident] Println
|
# 69| 1: [FunctionName, Ident] Println
|
||||||
# 69| Type = func([]interface { }) int, error
|
# 69| Type = func(...interface { }) int, error
|
||||||
# 69| 1: [MinusExpr] -...
|
# 69| 1: [MinusExpr] -...
|
||||||
# 69| Type = int
|
# 69| Type = int
|
||||||
# 69| 0: [Ident, VariableName] x
|
# 69| 0: [Ident, VariableName] x
|
||||||
@@ -474,10 +474,10 @@ input.go:
|
|||||||
# 115| 0: [CallExpr] call to Println
|
# 115| 0: [CallExpr] call to Println
|
||||||
# 115| Type = (int, error)
|
# 115| Type = (int, error)
|
||||||
# 115| 0: [FunctionName, SelectorExpr] selection of Println
|
# 115| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 115| Type = func([]interface { }) int, error
|
# 115| Type = func(...interface { }) int, error
|
||||||
# 115| 0: [Ident, PackageName] fmt
|
# 115| 0: [Ident, PackageName] fmt
|
||||||
# 115| 1: [FunctionName, Ident] Println
|
# 115| 1: [FunctionName, Ident] Println
|
||||||
# 115| Type = func([]interface { }) int, error
|
# 115| Type = func(...interface { }) int, error
|
||||||
# 115| 1: [Ident, VariableName] y
|
# 115| 1: [Ident, VariableName] y
|
||||||
# 115| Type = interface { }
|
# 115| Type = interface { }
|
||||||
# 116| 1: [CaseClause] case clause
|
# 116| 1: [CaseClause] case clause
|
||||||
@@ -566,10 +566,10 @@ input.go:
|
|||||||
# 138| 0: [CallExpr] call to Print
|
# 138| 0: [CallExpr] call to Print
|
||||||
# 138| Type = (int, error)
|
# 138| Type = (int, error)
|
||||||
# 138| 0: [FunctionName, SelectorExpr] selection of Print
|
# 138| 0: [FunctionName, SelectorExpr] selection of Print
|
||||||
# 138| Type = func([]interface { }) int, error
|
# 138| Type = func(...interface { }) int, error
|
||||||
# 138| 0: [Ident, PackageName] fmt
|
# 138| 0: [Ident, PackageName] fmt
|
||||||
# 138| 1: [FunctionName, Ident] Print
|
# 138| 1: [FunctionName, Ident] Print
|
||||||
# 138| Type = func([]interface { }) int, error
|
# 138| Type = func(...interface { }) int, error
|
||||||
# 138| 1: [Ident, VariableName] x
|
# 138| 1: [Ident, VariableName] x
|
||||||
# 138| Type = int
|
# 138| Type = int
|
||||||
# 141| 1: [RangeStmt] range statement
|
# 141| 1: [RangeStmt] range statement
|
||||||
@@ -584,10 +584,10 @@ input.go:
|
|||||||
# 142| 0: [CallExpr] call to Print
|
# 142| 0: [CallExpr] call to Print
|
||||||
# 142| Type = (int, error)
|
# 142| Type = (int, error)
|
||||||
# 142| 0: [FunctionName, SelectorExpr] selection of Print
|
# 142| 0: [FunctionName, SelectorExpr] selection of Print
|
||||||
# 142| Type = func([]interface { }) int, error
|
# 142| Type = func(...interface { }) int, error
|
||||||
# 142| 0: [Ident, PackageName] fmt
|
# 142| 0: [Ident, PackageName] fmt
|
||||||
# 142| 1: [FunctionName, Ident] Print
|
# 142| 1: [FunctionName, Ident] Print
|
||||||
# 142| Type = func([]interface { }) int, error
|
# 142| Type = func(...interface { }) int, error
|
||||||
# 142| 1: [Ident, VariableName] i
|
# 142| 1: [Ident, VariableName] i
|
||||||
# 142| Type = int
|
# 142| Type = int
|
||||||
# 142| 2: [Ident, VariableName] v
|
# 142| 2: [Ident, VariableName] v
|
||||||
|
|||||||
@@ -33,10 +33,10 @@ input.go:
|
|||||||
# 20| 0: [CallExpr] call to Println
|
# 20| 0: [CallExpr] call to Println
|
||||||
# 20| Type = (int, error)
|
# 20| Type = (int, error)
|
||||||
# 20| 0: [FunctionName, SelectorExpr] selection of Println
|
# 20| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 20| Type = func([]interface { }) int, error
|
# 20| Type = func(...interface { }) int, error
|
||||||
# 20| 0: [Ident, PackageName] fmt
|
# 20| 0: [Ident, PackageName] fmt
|
||||||
# 20| 1: [FunctionName, Ident] Println
|
# 20| 1: [FunctionName, Ident] Println
|
||||||
# 20| Type = func([]interface { }) int, error
|
# 20| Type = func(...interface { }) int, error
|
||||||
# 20| 1: [StringLit] "Hi"
|
# 20| 1: [StringLit] "Hi"
|
||||||
# 20| Type = string
|
# 20| Type = string
|
||||||
# 20| Value = [StringLit] Hi
|
# 20| Value = [StringLit] Hi
|
||||||
@@ -183,10 +183,10 @@ input.go:
|
|||||||
# 52| 0: [CallExpr] call to Println
|
# 52| 0: [CallExpr] call to Println
|
||||||
# 52| Type = (int, error)
|
# 52| Type = (int, error)
|
||||||
# 52| 0: [FunctionName, SelectorExpr] selection of Println
|
# 52| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 52| Type = func([]interface { }) int, error
|
# 52| Type = func(...interface { }) int, error
|
||||||
# 52| 0: [Ident, PackageName] fmt
|
# 52| 0: [Ident, PackageName] fmt
|
||||||
# 52| 1: [FunctionName, Ident] Println
|
# 52| 1: [FunctionName, Ident] Println
|
||||||
# 52| Type = func([]interface { }) int, error
|
# 52| Type = func(...interface { }) int, error
|
||||||
# 52| 1: [StringLit] "Heard from ch1"
|
# 52| 1: [StringLit] "Heard from ch1"
|
||||||
# 52| Type = string
|
# 52| Type = string
|
||||||
# 52| Value = [StringLit] Heard from ch1
|
# 52| Value = [StringLit] Heard from ch1
|
||||||
@@ -209,20 +209,20 @@ input.go:
|
|||||||
# 54| 0: [CallExpr] call to Println
|
# 54| 0: [CallExpr] call to Println
|
||||||
# 54| Type = (int, error)
|
# 54| Type = (int, error)
|
||||||
# 54| 0: [FunctionName, SelectorExpr] selection of Println
|
# 54| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 54| Type = func([]interface { }) int, error
|
# 54| Type = func(...interface { }) int, error
|
||||||
# 54| 0: [Ident, PackageName] fmt
|
# 54| 0: [Ident, PackageName] fmt
|
||||||
# 54| 1: [FunctionName, Ident] Println
|
# 54| 1: [FunctionName, Ident] Println
|
||||||
# 54| Type = func([]interface { }) int, error
|
# 54| Type = func(...interface { }) int, error
|
||||||
# 54| 1: [Ident, VariableName] a
|
# 54| 1: [Ident, VariableName] a
|
||||||
# 54| Type = [1]float32
|
# 54| Type = [1]float32
|
||||||
# 55| 2: [ExprStmt] expression statement
|
# 55| 2: [ExprStmt] expression statement
|
||||||
# 55| 0: [CallExpr] call to Println
|
# 55| 0: [CallExpr] call to Println
|
||||||
# 55| Type = (int, error)
|
# 55| Type = (int, error)
|
||||||
# 55| 0: [FunctionName, SelectorExpr] selection of Println
|
# 55| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 55| Type = func([]interface { }) int, error
|
# 55| Type = func(...interface { }) int, error
|
||||||
# 55| 0: [Ident, PackageName] fmt
|
# 55| 0: [Ident, PackageName] fmt
|
||||||
# 55| 1: [FunctionName, Ident] Println
|
# 55| 1: [FunctionName, Ident] Println
|
||||||
# 55| Type = func([]interface { }) int, error
|
# 55| Type = func(...interface { }) int, error
|
||||||
# 55| 1: [Ident, VariableName] w
|
# 55| 1: [Ident, VariableName] w
|
||||||
# 55| Type = bool
|
# 55| Type = bool
|
||||||
# 56| 2: [CommClause] comm clause
|
# 56| 2: [CommClause] comm clause
|
||||||
@@ -230,10 +230,10 @@ input.go:
|
|||||||
# 57| 0: [CallExpr] call to Println
|
# 57| 0: [CallExpr] call to Println
|
||||||
# 57| Type = (int, error)
|
# 57| Type = (int, error)
|
||||||
# 57| 0: [FunctionName, SelectorExpr] selection of Println
|
# 57| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 57| Type = func([]interface { }) int, error
|
# 57| Type = func(...interface { }) int, error
|
||||||
# 57| 0: [Ident, PackageName] fmt
|
# 57| 0: [Ident, PackageName] fmt
|
||||||
# 57| 1: [FunctionName, Ident] Println
|
# 57| 1: [FunctionName, Ident] Println
|
||||||
# 57| Type = func([]interface { }) int, error
|
# 57| Type = func(...interface { }) int, error
|
||||||
# 58| 3: [CommClause] comm clause
|
# 58| 3: [CommClause] comm clause
|
||||||
# 58| 0: [SendStmt] send statement
|
# 58| 0: [SendStmt] send statement
|
||||||
# 58| 0: [Ident, VariableName] ch1
|
# 58| 0: [Ident, VariableName] ch1
|
||||||
@@ -277,10 +277,10 @@ input.go:
|
|||||||
# 67| 0: [CallExpr] call to Println
|
# 67| 0: [CallExpr] call to Println
|
||||||
# 67| Type = (int, error)
|
# 67| Type = (int, error)
|
||||||
# 67| 0: [FunctionName, SelectorExpr] selection of Println
|
# 67| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 67| Type = func([]interface { }) int, error
|
# 67| Type = func(...interface { }) int, error
|
||||||
# 67| 0: [Ident, PackageName] fmt
|
# 67| 0: [Ident, PackageName] fmt
|
||||||
# 67| 1: [FunctionName, Ident] Println
|
# 67| 1: [FunctionName, Ident] Println
|
||||||
# 67| Type = func([]interface { }) int, error
|
# 67| Type = func(...interface { }) int, error
|
||||||
# 67| 1: [Ident, VariableName] x
|
# 67| 1: [Ident, VariableName] x
|
||||||
# 67| Type = int
|
# 67| Type = int
|
||||||
# 68| 2: [BlockStmt] block statement
|
# 68| 2: [BlockStmt] block statement
|
||||||
@@ -296,10 +296,10 @@ input.go:
|
|||||||
# 69| 0: [CallExpr] call to Println
|
# 69| 0: [CallExpr] call to Println
|
||||||
# 69| Type = (int, error)
|
# 69| Type = (int, error)
|
||||||
# 69| 0: [FunctionName, SelectorExpr] selection of Println
|
# 69| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 69| Type = func([]interface { }) int, error
|
# 69| Type = func(...interface { }) int, error
|
||||||
# 69| 0: [Ident, PackageName] fmt
|
# 69| 0: [Ident, PackageName] fmt
|
||||||
# 69| 1: [FunctionName, Ident] Println
|
# 69| 1: [FunctionName, Ident] Println
|
||||||
# 69| Type = func([]interface { }) int, error
|
# 69| Type = func(...interface { }) int, error
|
||||||
# 69| 1: [MinusExpr] -...
|
# 69| 1: [MinusExpr] -...
|
||||||
# 69| Type = int
|
# 69| Type = int
|
||||||
# 69| 0: [Ident, VariableName] x
|
# 69| 0: [Ident, VariableName] x
|
||||||
@@ -454,10 +454,10 @@ input.go:
|
|||||||
# 115| 0: [CallExpr] call to Println
|
# 115| 0: [CallExpr] call to Println
|
||||||
# 115| Type = (int, error)
|
# 115| Type = (int, error)
|
||||||
# 115| 0: [FunctionName, SelectorExpr] selection of Println
|
# 115| 0: [FunctionName, SelectorExpr] selection of Println
|
||||||
# 115| Type = func([]interface { }) int, error
|
# 115| Type = func(...interface { }) int, error
|
||||||
# 115| 0: [Ident, PackageName] fmt
|
# 115| 0: [Ident, PackageName] fmt
|
||||||
# 115| 1: [FunctionName, Ident] Println
|
# 115| 1: [FunctionName, Ident] Println
|
||||||
# 115| Type = func([]interface { }) int, error
|
# 115| Type = func(...interface { }) int, error
|
||||||
# 115| 1: [Ident, VariableName] y
|
# 115| 1: [Ident, VariableName] y
|
||||||
# 115| Type = interface { }
|
# 115| Type = interface { }
|
||||||
# 116| 1: [CaseClause] case clause
|
# 116| 1: [CaseClause] case clause
|
||||||
@@ -546,10 +546,10 @@ input.go:
|
|||||||
# 138| 0: [CallExpr] call to Print
|
# 138| 0: [CallExpr] call to Print
|
||||||
# 138| Type = (int, error)
|
# 138| Type = (int, error)
|
||||||
# 138| 0: [FunctionName, SelectorExpr] selection of Print
|
# 138| 0: [FunctionName, SelectorExpr] selection of Print
|
||||||
# 138| Type = func([]interface { }) int, error
|
# 138| Type = func(...interface { }) int, error
|
||||||
# 138| 0: [Ident, PackageName] fmt
|
# 138| 0: [Ident, PackageName] fmt
|
||||||
# 138| 1: [FunctionName, Ident] Print
|
# 138| 1: [FunctionName, Ident] Print
|
||||||
# 138| Type = func([]interface { }) int, error
|
# 138| Type = func(...interface { }) int, error
|
||||||
# 138| 1: [Ident, VariableName] x
|
# 138| 1: [Ident, VariableName] x
|
||||||
# 138| Type = int
|
# 138| Type = int
|
||||||
# 141| 1: [RangeStmt] range statement
|
# 141| 1: [RangeStmt] range statement
|
||||||
@@ -564,10 +564,10 @@ input.go:
|
|||||||
# 142| 0: [CallExpr] call to Print
|
# 142| 0: [CallExpr] call to Print
|
||||||
# 142| Type = (int, error)
|
# 142| Type = (int, error)
|
||||||
# 142| 0: [FunctionName, SelectorExpr] selection of Print
|
# 142| 0: [FunctionName, SelectorExpr] selection of Print
|
||||||
# 142| Type = func([]interface { }) int, error
|
# 142| Type = func(...interface { }) int, error
|
||||||
# 142| 0: [Ident, PackageName] fmt
|
# 142| 0: [Ident, PackageName] fmt
|
||||||
# 142| 1: [FunctionName, Ident] Print
|
# 142| 1: [FunctionName, Ident] Print
|
||||||
# 142| Type = func([]interface { }) int, error
|
# 142| Type = func(...interface { }) int, error
|
||||||
# 142| 1: [Ident, VariableName] i
|
# 142| 1: [Ident, VariableName] i
|
||||||
# 142| Type = int
|
# 142| Type = int
|
||||||
# 142| 2: [Ident, VariableName] v
|
# 142| 2: [Ident, VariableName] v
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ edges
|
|||||||
| test.go:45:22:45:31 | &... [pointer] | test.go:45:22:45:31 | &... | provenance | |
|
| test.go:45:22:45:31 | &... [pointer] | test.go:45:22:45:31 | &... | provenance | |
|
||||||
| test.go:45:22:45:31 | &... [pointer] | test.go:45:22:45:31 | &... | provenance | |
|
| test.go:45:22:45:31 | &... [pointer] | test.go:45:22:45:31 | &... | provenance | |
|
||||||
| test.go:45:22:45:31 | &... [pointer] | test.go:45:23:45:31 | cleanNode | provenance | |
|
| test.go:45:22:45:31 | &... [pointer] | test.go:45:23:45:31 | cleanNode | provenance | |
|
||||||
|
| test.go:45:23:45:31 | cleanNode | test.go:45:22:45:31 | &... | provenance | |
|
||||||
| test.go:45:23:45:31 | cleanNode | test.go:45:22:45:31 | &... [pointer] | provenance | |
|
| test.go:45:23:45:31 | cleanNode | test.go:45:22:45:31 | &... [pointer] | provenance | |
|
||||||
| test.go:47:6:47:15 | definition of cleanNode2 | test.go:50:22:50:32 | &... | provenance | |
|
| test.go:47:6:47:15 | definition of cleanNode2 | test.go:50:22:50:32 | &... | provenance | |
|
||||||
| test.go:47:6:47:15 | definition of cleanNode2 | test.go:50:22:50:32 | &... | provenance | |
|
| test.go:47:6:47:15 | definition of cleanNode2 | test.go:50:22:50:32 | &... | provenance | |
|
||||||
@@ -65,6 +66,7 @@ edges
|
|||||||
| test.go:50:22:50:32 | &... [pointer] | test.go:50:22:50:32 | &... | provenance | |
|
| test.go:50:22:50:32 | &... [pointer] | test.go:50:22:50:32 | &... | provenance | |
|
||||||
| test.go:50:22:50:32 | &... [pointer] | test.go:50:22:50:32 | &... | provenance | |
|
| test.go:50:22:50:32 | &... [pointer] | test.go:50:22:50:32 | &... | provenance | |
|
||||||
| test.go:50:22:50:32 | &... [pointer] | test.go:50:23:50:32 | cleanNode2 | provenance | |
|
| test.go:50:22:50:32 | &... [pointer] | test.go:50:23:50:32 | cleanNode2 | provenance | |
|
||||||
|
| test.go:50:23:50:32 | cleanNode2 | test.go:50:22:50:32 | &... | provenance | |
|
||||||
| test.go:50:23:50:32 | cleanNode2 | test.go:50:22:50:32 | &... [pointer] | provenance | |
|
| test.go:50:23:50:32 | cleanNode2 | test.go:50:22:50:32 | &... [pointer] | provenance | |
|
||||||
models
|
models
|
||||||
| 1 | Summary: golang.org/x/net/html; ; false; NewTokenizer; ; ; Argument[0]; ReturnValue; taint; manual |
|
| 1 | Summary: golang.org/x/net/html; ; false; NewTokenizer; ; ; Argument[0]; ReturnValue; taint; manual |
|
||||||
|
|||||||
@@ -59,8 +59,7 @@ edges
|
|||||||
| SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | provenance | |
|
| SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | provenance | |
|
||||||
| SanitizingDoubleDash.go:13:25:13:31 | tainted | SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | provenance | |
|
| SanitizingDoubleDash.go:13:25:13:31 | tainted | SanitizingDoubleDash.go:13:15:13:32 | array literal [array] | provenance | |
|
||||||
| SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | SanitizingDoubleDash.go:14:23:14:33 | slice element node | provenance | |
|
| SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | SanitizingDoubleDash.go:14:23:14:33 | slice element node | provenance | |
|
||||||
| SanitizingDoubleDash.go:14:23:14:33 | slice element node | SanitizingDoubleDash.go:14:23:14:33 | slice expression [array] | provenance | |
|
| SanitizingDoubleDash.go:14:23:14:33 | slice element node | SanitizingDoubleDash.go:14:23:14:33 | slice expression | provenance | |
|
||||||
| SanitizingDoubleDash.go:14:23:14:33 | slice expression [array] | SanitizingDoubleDash.go:14:23:14:33 | slice expression | provenance | |
|
|
||||||
| SanitizingDoubleDash.go:39:14:39:44 | []type{args} [array] | SanitizingDoubleDash.go:39:14:39:44 | call to append | provenance | MaD:3 |
|
| SanitizingDoubleDash.go:39:14:39:44 | []type{args} [array] | SanitizingDoubleDash.go:39:14:39:44 | call to append | provenance | MaD:3 |
|
||||||
| SanitizingDoubleDash.go:39:14:39:44 | []type{args} [array] | SanitizingDoubleDash.go:39:14:39:44 | call to append [array] | provenance | MaD:3 |
|
| SanitizingDoubleDash.go:39:14:39:44 | []type{args} [array] | SanitizingDoubleDash.go:39:14:39:44 | call to append [array] | provenance | MaD:3 |
|
||||||
| SanitizingDoubleDash.go:39:14:39:44 | call to append | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | provenance | |
|
| SanitizingDoubleDash.go:39:14:39:44 | call to append | SanitizingDoubleDash.go:40:23:40:30 | arrayLit | provenance | |
|
||||||
@@ -102,13 +101,11 @@ edges
|
|||||||
| SanitizingDoubleDash.go:95:15:95:32 | array literal [array] | SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | provenance | |
|
| SanitizingDoubleDash.go:95:15:95:32 | array literal [array] | SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | provenance | |
|
||||||
| SanitizingDoubleDash.go:95:25:95:31 | tainted | SanitizingDoubleDash.go:95:15:95:32 | array literal [array] | provenance | |
|
| SanitizingDoubleDash.go:95:25:95:31 | tainted | SanitizingDoubleDash.go:95:15:95:32 | array literal [array] | provenance | |
|
||||||
| SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | SanitizingDoubleDash.go:96:24:96:34 | slice element node | provenance | |
|
| SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | SanitizingDoubleDash.go:96:24:96:34 | slice element node | provenance | |
|
||||||
| SanitizingDoubleDash.go:96:24:96:34 | slice element node | SanitizingDoubleDash.go:96:24:96:34 | slice expression [array] | provenance | |
|
| SanitizingDoubleDash.go:96:24:96:34 | slice element node | SanitizingDoubleDash.go:96:24:96:34 | slice expression | provenance | |
|
||||||
| SanitizingDoubleDash.go:96:24:96:34 | slice expression [array] | SanitizingDoubleDash.go:96:24:96:34 | slice expression | provenance | |
|
|
||||||
| SanitizingDoubleDash.go:100:15:100:38 | array literal [array] | SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | provenance | |
|
| SanitizingDoubleDash.go:100:15:100:38 | array literal [array] | SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | provenance | |
|
||||||
| SanitizingDoubleDash.go:100:31:100:37 | tainted | SanitizingDoubleDash.go:100:15:100:38 | array literal [array] | provenance | |
|
| SanitizingDoubleDash.go:100:31:100:37 | tainted | SanitizingDoubleDash.go:100:15:100:38 | array literal [array] | provenance | |
|
||||||
| SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | SanitizingDoubleDash.go:101:24:101:34 | slice element node | provenance | |
|
| SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | SanitizingDoubleDash.go:101:24:101:34 | slice element node | provenance | |
|
||||||
| SanitizingDoubleDash.go:101:24:101:34 | slice element node | SanitizingDoubleDash.go:101:24:101:34 | slice expression [array] | provenance | |
|
| SanitizingDoubleDash.go:101:24:101:34 | slice element node | SanitizingDoubleDash.go:101:24:101:34 | slice expression | provenance | |
|
||||||
| SanitizingDoubleDash.go:101:24:101:34 | slice expression [array] | SanitizingDoubleDash.go:101:24:101:34 | slice expression | provenance | |
|
|
||||||
| SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | provenance | |
|
| SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | SanitizingDoubleDash.go:106:24:106:31 | arrayLit | provenance | |
|
||||||
| SanitizingDoubleDash.go:105:30:105:36 | tainted | SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | provenance | |
|
| SanitizingDoubleDash.go:105:30:105:36 | tainted | SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | provenance | |
|
||||||
| SanitizingDoubleDash.go:111:14:111:44 | []type{args} [array] | SanitizingDoubleDash.go:111:14:111:44 | call to append | provenance | MaD:3 |
|
| SanitizingDoubleDash.go:111:14:111:44 | []type{args} [array] | SanitizingDoubleDash.go:111:14:111:44 | call to append | provenance | MaD:3 |
|
||||||
@@ -190,7 +187,6 @@ nodes
|
|||||||
| SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | semmle.label | arrayLit [array] |
|
| SanitizingDoubleDash.go:14:23:14:30 | arrayLit [array] | semmle.label | arrayLit [array] |
|
||||||
| SanitizingDoubleDash.go:14:23:14:33 | slice element node | semmle.label | slice element node |
|
| SanitizingDoubleDash.go:14:23:14:33 | slice element node | semmle.label | slice element node |
|
||||||
| SanitizingDoubleDash.go:14:23:14:33 | slice expression | semmle.label | slice expression |
|
| SanitizingDoubleDash.go:14:23:14:33 | slice expression | semmle.label | slice expression |
|
||||||
| SanitizingDoubleDash.go:14:23:14:33 | slice expression [array] | semmle.label | slice expression [array] |
|
|
||||||
| SanitizingDoubleDash.go:39:14:39:44 | []type{args} [array] | semmle.label | []type{args} [array] |
|
| SanitizingDoubleDash.go:39:14:39:44 | []type{args} [array] | semmle.label | []type{args} [array] |
|
||||||
| SanitizingDoubleDash.go:39:14:39:44 | call to append | semmle.label | call to append |
|
| SanitizingDoubleDash.go:39:14:39:44 | call to append | semmle.label | call to append |
|
||||||
| SanitizingDoubleDash.go:39:14:39:44 | call to append [array] | semmle.label | call to append [array] |
|
| SanitizingDoubleDash.go:39:14:39:44 | call to append [array] | semmle.label | call to append [array] |
|
||||||
@@ -220,13 +216,11 @@ nodes
|
|||||||
| SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | semmle.label | arrayLit [array] |
|
| SanitizingDoubleDash.go:96:24:96:31 | arrayLit [array] | semmle.label | arrayLit [array] |
|
||||||
| SanitizingDoubleDash.go:96:24:96:34 | slice element node | semmle.label | slice element node |
|
| SanitizingDoubleDash.go:96:24:96:34 | slice element node | semmle.label | slice element node |
|
||||||
| SanitizingDoubleDash.go:96:24:96:34 | slice expression | semmle.label | slice expression |
|
| SanitizingDoubleDash.go:96:24:96:34 | slice expression | semmle.label | slice expression |
|
||||||
| SanitizingDoubleDash.go:96:24:96:34 | slice expression [array] | semmle.label | slice expression [array] |
|
|
||||||
| SanitizingDoubleDash.go:100:15:100:38 | array literal [array] | semmle.label | array literal [array] |
|
| SanitizingDoubleDash.go:100:15:100:38 | array literal [array] | semmle.label | array literal [array] |
|
||||||
| SanitizingDoubleDash.go:100:31:100:37 | tainted | semmle.label | tainted |
|
| SanitizingDoubleDash.go:100:31:100:37 | tainted | semmle.label | tainted |
|
||||||
| SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | semmle.label | arrayLit [array] |
|
| SanitizingDoubleDash.go:101:24:101:31 | arrayLit [array] | semmle.label | arrayLit [array] |
|
||||||
| SanitizingDoubleDash.go:101:24:101:34 | slice element node | semmle.label | slice element node |
|
| SanitizingDoubleDash.go:101:24:101:34 | slice element node | semmle.label | slice element node |
|
||||||
| SanitizingDoubleDash.go:101:24:101:34 | slice expression | semmle.label | slice expression |
|
| SanitizingDoubleDash.go:101:24:101:34 | slice expression | semmle.label | slice expression |
|
||||||
| SanitizingDoubleDash.go:101:24:101:34 | slice expression [array] | semmle.label | slice expression [array] |
|
|
||||||
| SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | semmle.label | slice literal [array] |
|
| SanitizingDoubleDash.go:105:15:105:37 | slice literal [array] | semmle.label | slice literal [array] |
|
||||||
| SanitizingDoubleDash.go:105:30:105:36 | tainted | semmle.label | tainted |
|
| SanitizingDoubleDash.go:105:30:105:36 | tainted | semmle.label | tainted |
|
||||||
| SanitizingDoubleDash.go:106:24:106:31 | arrayLit | semmle.label | arrayLit |
|
| SanitizingDoubleDash.go:106:24:106:31 | arrayLit | semmle.label | arrayLit |
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ org.springframework.beans,,,30,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3
|
|||||||
org.springframework.boot.jdbc,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,
|
org.springframework.boot.jdbc,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,,,,,,,,
|
||||||
org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13
|
org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13
|
||||||
org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
|
org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,
|
||||||
org.springframework.core.io,17,,5,,,,,,,,,,,,,,,,,,,,,,,,16,,,,,,,,,1,,,,,,,,,,,,,,,5,
|
org.springframework.core.io,17,,6,,,,,,,,,,,,,,,,,,,,,,,,16,,,,,,,,,1,,,,,,,,,,,,,,,6,
|
||||||
org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
|
org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
|
||||||
org.springframework.http,14,,77,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,67,10
|
org.springframework.http,14,,77,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,14,,,,,,,,,,,,,,,67,10
|
||||||
org.springframework.jdbc.core,19,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,,,,,,,
|
org.springframework.jdbc.core,19,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,,,,,,,
|
||||||
@@ -248,7 +248,7 @@ org.springframework.util,10,,142,,,,,,,,,,,,,,,,,,,,,,,,10,,,,,,,,,,,,,,,,,,,,,,
|
|||||||
org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,
|
org.springframework.validation,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,
|
||||||
org.springframework.web.client,13,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,3,,
|
org.springframework.web.client,13,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13,,,,,,,,,,,,,,3,,
|
||||||
org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,,
|
org.springframework.web.context.request,,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,,
|
||||||
org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,13,
|
org.springframework.web.multipart,,12,12,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,12,12,
|
||||||
org.springframework.web.portlet,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,
|
org.springframework.web.portlet,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,
|
||||||
org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,
|
org.springframework.web.reactive.function.client,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,,,,,,
|
||||||
org.springframework.web.servlet,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,
|
org.springframework.web.servlet,2,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,,,,,,,,,,,
|
||||||
|
|||||||
|
@@ -0,0 +1,15 @@
|
|||||||
|
class Field extends @field {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
class Type extends @type {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
class RefType extends @reftype {
|
||||||
|
string toString() { none() }
|
||||||
|
}
|
||||||
|
|
||||||
|
from Field f, string name, Type t, RefType parent
|
||||||
|
where fields(f, name, t, parent)
|
||||||
|
select f, name, t, parent, f
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
|||||||
|
description: Remove fields.sourceid
|
||||||
|
compatibility: full
|
||||||
|
fields.rel: run fields.qlo
|
||||||
BIN
java/kotlin-extractor/deps/kotlin-compiler-2.1.0-Beta1.jar
(Stored with Git LFS)
Normal file
BIN
java/kotlin-extractor/deps/kotlin-compiler-2.1.0-Beta1.jar
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
java/kotlin-extractor/deps/kotlin-compiler-embeddable-2.1.0-Beta1.jar
(Stored with Git LFS)
Normal file
BIN
java/kotlin-extractor/deps/kotlin-compiler-embeddable-2.1.0-Beta1.jar
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
java/kotlin-extractor/deps/kotlin-stdlib-2.1.0-Beta1.jar
(Stored with Git LFS)
Normal file
BIN
java/kotlin-extractor/deps/kotlin-stdlib-2.1.0-Beta1.jar
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -27,30 +27,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
|
|||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
|
||||||
import org.jetbrains.kotlin.ir.util.companionObject
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.util.constructors
|
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
|
||||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
|
||||||
import org.jetbrains.kotlin.ir.util.hasInterfaceParent
|
|
||||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
|
||||||
import org.jetbrains.kotlin.ir.util.isAnonymousObject
|
|
||||||
import org.jetbrains.kotlin.ir.util.isFakeOverride
|
|
||||||
import org.jetbrains.kotlin.ir.util.isFunctionOrKFunction
|
|
||||||
import org.jetbrains.kotlin.ir.util.isInterface
|
|
||||||
import org.jetbrains.kotlin.ir.util.isLocal
|
|
||||||
import org.jetbrains.kotlin.ir.util.isNonCompanionObject
|
|
||||||
import org.jetbrains.kotlin.ir.util.isObject
|
|
||||||
import org.jetbrains.kotlin.ir.util.isSuspend
|
|
||||||
import org.jetbrains.kotlin.ir.util.isSuspendFunctionOrKFunction
|
|
||||||
import org.jetbrains.kotlin.ir.util.isVararg
|
|
||||||
import org.jetbrains.kotlin.ir.util.kotlinFqName
|
|
||||||
import org.jetbrains.kotlin.ir.util.packageFqName
|
|
||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
|
||||||
import org.jetbrains.kotlin.ir.util.parentClassOrNull
|
|
||||||
import org.jetbrains.kotlin.ir.util.parents
|
|
||||||
import org.jetbrains.kotlin.ir.util.primaryConstructor
|
|
||||||
import org.jetbrains.kotlin.ir.util.render
|
|
||||||
import org.jetbrains.kotlin.ir.util.target
|
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
import org.jetbrains.kotlin.load.java.NOT_NULL_ANNOTATIONS
|
import org.jetbrains.kotlin.load.java.NOT_NULL_ANNOTATIONS
|
||||||
import org.jetbrains.kotlin.load.java.NULLABLE_ANNOTATIONS
|
import org.jetbrains.kotlin.load.java.NULLABLE_ANNOTATIONS
|
||||||
@@ -826,7 +803,7 @@ open class KotlinFileExtractor(
|
|||||||
fun exprId() = tw.getLabelFor<DbExpr>("@\"annotationExpr;{$parent};$idx\"")
|
fun exprId() = tw.getLabelFor<DbExpr>("@\"annotationExpr;{$parent};$idx\"")
|
||||||
|
|
||||||
return when (v) {
|
return when (v) {
|
||||||
is IrConst<*> -> {
|
is CodeQLIrConst<*> -> {
|
||||||
extractConstant(v, parent, idx, null, null, overrideId = exprId())
|
extractConstant(v, parent, idx, null, null, overrideId = exprId())
|
||||||
}
|
}
|
||||||
is IrGetEnumValue -> {
|
is IrGetEnumValue -> {
|
||||||
@@ -1020,7 +997,7 @@ open class KotlinFileExtractor(
|
|||||||
// here.
|
// here.
|
||||||
val instance = useObjectClassInstance(c)
|
val instance = useObjectClassInstance(c)
|
||||||
val type = useSimpleTypeClass(c, emptyList(), false)
|
val type = useSimpleTypeClass(c, emptyList(), false)
|
||||||
tw.writeFields(instance.id, instance.name, type.javaResult.id, id, instance.id)
|
tw.writeFields(instance.id, instance.name, type.javaResult.id, id)
|
||||||
tw.writeFieldsKotlinType(instance.id, type.kotlinResult.id)
|
tw.writeFieldsKotlinType(instance.id, type.kotlinResult.id)
|
||||||
tw.writeHasLocation(instance.id, locId)
|
tw.writeHasLocation(instance.id, locId)
|
||||||
addModifiers(instance.id, "public", "static", "final")
|
addModifiers(instance.id, "public", "static", "final")
|
||||||
@@ -1237,8 +1214,7 @@ open class KotlinFileExtractor(
|
|||||||
instance.id,
|
instance.id,
|
||||||
instance.name,
|
instance.name,
|
||||||
type.javaResult.id,
|
type.javaResult.id,
|
||||||
parentId,
|
parentId
|
||||||
instance.id
|
|
||||||
)
|
)
|
||||||
tw.writeFieldsKotlinType(instance.id, type.kotlinResult.id)
|
tw.writeFieldsKotlinType(instance.id, type.kotlinResult.id)
|
||||||
tw.writeHasLocation(instance.id, innerLocId)
|
tw.writeHasLocation(instance.id, innerLocId)
|
||||||
@@ -2600,7 +2576,7 @@ open class KotlinFileExtractor(
|
|||||||
isStatic: Boolean
|
isStatic: Boolean
|
||||||
): Label<out DbField> {
|
): Label<out DbField> {
|
||||||
val t = useType(type)
|
val t = useType(type)
|
||||||
tw.writeFields(id, name, t.javaResult.id, parentId, id)
|
tw.writeFields(id, name, t.javaResult.id, parentId)
|
||||||
tw.writeFieldsKotlinType(id, t.kotlinResult.id)
|
tw.writeFieldsKotlinType(id, t.kotlinResult.id)
|
||||||
tw.writeHasLocation(id, locId)
|
tw.writeHasLocation(id, locId)
|
||||||
|
|
||||||
@@ -2757,7 +2733,7 @@ open class KotlinFileExtractor(
|
|||||||
DeclarationStackAdjuster(ee).use {
|
DeclarationStackAdjuster(ee).use {
|
||||||
val id = useEnumEntry(ee)
|
val id = useEnumEntry(ee)
|
||||||
val type = getEnumEntryType(ee) ?: return
|
val type = getEnumEntryType(ee) ?: return
|
||||||
tw.writeFields(id, ee.name.asString(), type.javaResult.id, parentId, id)
|
tw.writeFields(id, ee.name.asString(), type.javaResult.id, parentId)
|
||||||
tw.writeFieldsKotlinType(id, type.kotlinResult.id)
|
tw.writeFieldsKotlinType(id, type.kotlinResult.id)
|
||||||
val locId = tw.getLocation(ee)
|
val locId = tw.getLocation(ee)
|
||||||
tw.writeHasLocation(id, locId)
|
tw.writeHasLocation(id, locId)
|
||||||
@@ -5999,7 +5975,7 @@ open class KotlinFileExtractor(
|
|||||||
extractExpressionExpr(a, callable, id, i, exprParent.enclosingStmt)
|
extractExpressionExpr(a, callable, id, i, exprParent.enclosingStmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is IrConst<*> -> {
|
is CodeQLIrConst<*> -> {
|
||||||
val exprParent = parent.expr(e, callable)
|
val exprParent = parent.expr(e, callable)
|
||||||
extractConstant(
|
extractConstant(
|
||||||
e,
|
e,
|
||||||
@@ -6211,9 +6187,9 @@ open class KotlinFileExtractor(
|
|||||||
if (
|
if (
|
||||||
(isAndAnd || isOrOr) &&
|
(isAndAnd || isOrOr) &&
|
||||||
e.branches.size == 2 &&
|
e.branches.size == 2 &&
|
||||||
(e.branches[1].condition as? IrConst<*>)?.value == true &&
|
(e.branches[1].condition as? CodeQLIrConst<*>)?.value == true &&
|
||||||
(e.branches[if (e.origin == IrStatementOrigin.ANDAND) 1 else 0].result
|
(e.branches[if (e.origin == IrStatementOrigin.ANDAND) 1 else 0].result
|
||||||
as? IrConst<*>)
|
as? CodeQLIrConst<*>)
|
||||||
?.value == isOrOr
|
?.value == isOrOr
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@@ -6869,7 +6845,7 @@ open class KotlinFileExtractor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun extractConstant(
|
private fun extractConstant(
|
||||||
e: IrConst<*>,
|
e: CodeQLIrConst<*>,
|
||||||
parent: Label<out DbExprparent>,
|
parent: Label<out DbExprparent>,
|
||||||
idx: Int,
|
idx: Int,
|
||||||
enclosingCallable: Label<out DbCallable>?,
|
enclosingCallable: Label<out DbCallable>?,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import com.github.codeql.utils.versions.*
|
|||||||
import com.semmle.extractor.java.OdasaOutput
|
import com.semmle.extractor.java.OdasaOutput
|
||||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||||
import org.jetbrains.kotlin.backend.common.ir.*
|
import org.jetbrains.kotlin.backend.common.ir.*
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.propertyIfAccessor
|
import org.jetbrains.kotlin.backend.jvm.ir.*
|
||||||
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
import org.jetbrains.kotlin.codegen.JvmCodegenUtil
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.load.kotlin.getJvmModuleNameForDeserializedDescripto
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.NameUtils
|
import org.jetbrains.kotlin.name.NameUtils
|
||||||
import org.jetbrains.kotlin.name.SpecialNames
|
import org.jetbrains.kotlin.name.SpecialNames
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
@@ -84,7 +85,7 @@ open class KotlinUsesExtractor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun extractFileClass(fqName: FqName): Label<out DbClassorinterface> {
|
private fun extractFileClass(fqName: FqName): Label<out DbClassorinterface> {
|
||||||
val pkg = if (fqName.isRoot()) "" else fqName.parent().asString()
|
val pkg = if (fqName.codeQlIsRoot()) "" else fqName.parent().asString()
|
||||||
val jvmName = fqName.shortName().asString()
|
val jvmName = fqName.shortName().asString()
|
||||||
return extractFileClass(pkg, jvmName)
|
return extractFileClass(pkg, jvmName)
|
||||||
}
|
}
|
||||||
@@ -779,7 +780,7 @@ open class KotlinUsesExtractor(
|
|||||||
// array.length
|
// array.length
|
||||||
val length = tw.getLabelFor<DbField>("@\"field;{$it};length\"")
|
val length = tw.getLabelFor<DbField>("@\"field;{$it};length\"")
|
||||||
val intTypeIds = useType(pluginContext.irBuiltIns.intType)
|
val intTypeIds = useType(pluginContext.irBuiltIns.intType)
|
||||||
tw.writeFields(length, "length", intTypeIds.javaResult.id, it, length)
|
tw.writeFields(length, "length", intTypeIds.javaResult.id, it)
|
||||||
tw.writeFieldsKotlinType(length, intTypeIds.kotlinResult.id)
|
tw.writeFieldsKotlinType(length, intTypeIds.kotlinResult.id)
|
||||||
addModifiers(length, "public", "final")
|
addModifiers(length, "public", "final")
|
||||||
|
|
||||||
@@ -906,7 +907,7 @@ open class KotlinUsesExtractor(
|
|||||||
return arrayInfo.componentTypeResults
|
return arrayInfo.componentTypeResults
|
||||||
}
|
}
|
||||||
owner is IrClass -> {
|
owner is IrClass -> {
|
||||||
val args = if (s.isRawType()) null else s.arguments
|
val args = if (s.codeQlIsRawType()) null else s.arguments
|
||||||
|
|
||||||
return useSimpleTypeClass(owner, args, s.isNullable())
|
return useSimpleTypeClass(owner, args, s.isNullable())
|
||||||
}
|
}
|
||||||
@@ -1232,9 +1233,10 @@ open class KotlinUsesExtractor(
|
|||||||
// false if it has `@JvmSuppressWildcards(false)`,
|
// false if it has `@JvmSuppressWildcards(false)`,
|
||||||
// and null if the annotation is not present.
|
// and null if the annotation is not present.
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
private fun getWildcardSuppressionDirective(t: IrAnnotationContainer) =
|
private fun getWildcardSuppressionDirective(t: IrAnnotationContainer): Boolean? =
|
||||||
t.getAnnotation(jvmWildcardSuppressionAnnotation)?.let {
|
t.getAnnotation(jvmWildcardSuppressionAnnotation)?.let {
|
||||||
(it.getValueArgument(0) as? IrConst<Boolean>)?.value ?: true
|
@Suppress("USELESS_CAST") // `as? Boolean` is not needed for Kotlin < 2.1
|
||||||
|
(it.getValueArgument(0) as? CodeQLIrConst<Boolean>)?.value as? Boolean ?: true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addJavaLoweringArgumentWildcards(
|
private fun addJavaLoweringArgumentWildcards(
|
||||||
|
|||||||
@@ -27,13 +27,7 @@ import org.jetbrains.kotlin.ir.expressions.IrClassReference
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrGetEnumValue
|
import org.jetbrains.kotlin.ir.expressions.IrGetEnumValue
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrVararg
|
import org.jetbrains.kotlin.ir.expressions.IrVararg
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetEnumValueImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.typeWith
|
import org.jetbrains.kotlin.ir.types.typeWith
|
||||||
import org.jetbrains.kotlin.ir.util.constructedClass
|
import org.jetbrains.kotlin.ir.util.constructedClass
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
package com.github.codeql.utils
|
package com.github.codeql.utils
|
||||||
|
|
||||||
import com.github.codeql.utils.versions.allOverriddenIncludingSelf
|
import com.github.codeql.utils.versions.allOverriddenIncludingSelf
|
||||||
|
import com.github.codeql.utils.versions.CodeQLIrConst
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer
|
import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||||
@@ -82,7 +82,7 @@ fun getJvmName(container: IrAnnotationContainer): String? {
|
|||||||
if (owner is IrClass) {
|
if (owner is IrClass) {
|
||||||
val aPkg = owner.packageFqName?.asString()
|
val aPkg = owner.packageFqName?.asString()
|
||||||
val name = owner.name.asString()
|
val name = owner.name.asString()
|
||||||
if (aPkg == "kotlin.jvm" && name == "JvmName" && v is IrConst<*>) {
|
if (aPkg == "kotlin.jvm" && name == "JvmName" && v is CodeQLIrConst<*>) {
|
||||||
val value = v.value
|
val value = v.value
|
||||||
if (value is String) {
|
if (value is String) {
|
||||||
return value
|
return value
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer
|
|||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
|
import org.jetbrains.kotlin.ir.symbols.impl.DescriptorlessExternalPackageFragmentSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.github.codeql.utils.versions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||||
|
|
||||||
|
typealias CodeQLIrConst<T> = IrConst<T>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.github.codeql.utils.versions
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
|
fun FqName.codeQlIsRoot() = this.isRoot()
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user