Merge branch 'main' into threat-models

This commit is contained in:
Rasmus Wriedt Larsen
2024-09-26 11:44:24 +02:00
305 changed files with 11499 additions and 5937 deletions

View File

@@ -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")

View File

@@ -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"
] ]
} }

View File

@@ -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.
*/ */

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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()
) )
} }

View File

@@ -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() }

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* C#: The indexer and `Add` method on `System.Web.UI.AttributeCollection` is no longer considered an HTML sink.

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)
)
}

View File

@@ -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 {

View File

@@ -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"
}

View File

@@ -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)
}

View File

@@ -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.

View File

@@ -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 |

View File

@@ -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)

View File

@@ -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 | <%= ... %> |

View File

@@ -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" }
} }

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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>

View File

@@ -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>

View File

@@ -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``"

View File

@@ -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)$"

View File

@@ -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:") {

View File

@@ -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)

View File

@@ -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
} }

View 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)
}
}

View File

@@ -10,3 +10,7 @@ func test() {
header.Version = 4 header.Version = 4
} }
func PublicFunction() int {
return 1
}

View 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)
}
}

View File

@@ -0,0 +1,2 @@
all:
go get

View File

@@ -0,0 +1,3 @@
go 1.14
module testsample

View 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=

View File

@@ -0,0 +1,5 @@
package testsample
func PublicFunction() int { return 1 }
func privateFunction() int { return 2 }

View File

@@ -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)
}
}

View File

@@ -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)
}
}

View File

@@ -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

View File

@@ -0,0 +1,4 @@
import os
def test(codeql, go):
codeql.database.create(source_root="src", extractor_option = ["extract_tests=true"])

View 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) }

View File

@@ -0,0 +1,2 @@
all:
go get

View File

@@ -0,0 +1,3 @@
go 1.14
module testsample

View 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=

View File

@@ -0,0 +1,5 @@
package testsample
func PublicFunction() int { return 1 }
func privateFunction() int { return 2 }

View File

@@ -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)
}
}

View File

@@ -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)
}
}

View File

@@ -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

View File

@@ -0,0 +1,4 @@
import os
def test(codeql, go):
codeql.database.create(source_root="src", command="go test -c")

View 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) }

View File

@@ -0,0 +1,2 @@
all:
go get

View File

@@ -0,0 +1,3 @@
go 1.14
module testsample

View 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=

View File

@@ -0,0 +1,5 @@
package testsample
func PublicFunction() int { return 1 }
func privateFunction() int { return 2 }

View File

@@ -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)
}
}

View 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)
}
}

View File

@@ -0,0 +1,4 @@
#select
| src/testme.go:0:0:0:0 | src/testme.go |
calls
extractionErrors

View File

@@ -0,0 +1,4 @@
import os
def test(codeql, go):
codeql.database.create(source_root="src", command="go build")

View 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) }

View File

@@ -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" }

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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.

View File

@@ -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 |

View File

@@ -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 | |

View File

@@ -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

View File

@@ -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

View File

@@ -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 |

View File

@@ -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 |

View File

@@ -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,,,,,,,,,,,
1 package sink source summary sink:bean-validation sink:command-injection sink:credentials-key sink:credentials-password sink:credentials-username sink:encryption-iv sink:encryption-salt sink:environment-injection sink:file-content-store sink:fragment-injection sink:groovy-injection sink:hostname-verification sink:html-injection sink:information-leak sink:intent-redirection sink:jexl-injection sink:jndi-injection sink:js-injection sink:ldap-injection sink:log-injection sink:mvel-injection sink:notification sink:ognl-injection sink:path-injection sink:pending-intents sink:regex-use sink:regex-use[-1] sink:regex-use[0] sink:regex-use[] sink:regex-use[f-1] sink:regex-use[f1] sink:regex-use[f] sink:request-forgery sink:response-splitting sink:sql-injection sink:template-injection sink:trust-boundary-violation sink:url-forward sink:url-redirection sink:xpath-injection sink:xslt-injection source:android-external-storage-dir source:contentprovider source:database source:environment source:file source:remote summary:taint summary:value
233 org.springframework.boot.jdbc 1 1
234 org.springframework.cache 13 13
235 org.springframework.context 3 3
236 org.springframework.core.io 17 5 6 16 1 5 6
237 org.springframework.data.repository 1 1
238 org.springframework.http 14 77 14 67 10
239 org.springframework.jdbc.core 19 19
248 org.springframework.validation 13 13
249 org.springframework.web.client 13 3 13 3
250 org.springframework.web.context.request 8 8
251 org.springframework.web.multipart 12 13 12 12 13 12
252 org.springframework.web.portlet 2 2
253 org.springframework.web.reactive.function.client 2 2
254 org.springframework.web.servlet 2 2

View File

@@ -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

View File

@@ -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

Binary file not shown.

Binary file not shown.

BIN
java/kotlin-extractor/deps/kotlin-stdlib-2.1.0-Beta1.jar (Stored with Git LFS) Normal file

Binary file not shown.

View File

@@ -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>?,

View File

@@ -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(

View File

@@ -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

View File

@@ -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

View File

@@ -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.*

View File

@@ -0,0 +1,5 @@
package com.github.codeql.utils.versions
import org.jetbrains.kotlin.ir.expressions.IrConst
typealias CodeQLIrConst<T> = IrConst<T>

View File

@@ -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