mirror of
https://github.com/github/codeql.git
synced 2025-12-22 11:46:32 +01:00
C++: Port implementation to CPP.
This commit is contained in:
@@ -13,8 +13,8 @@
|
|||||||
*
|
*
|
||||||
* The interpretation of a row is similar to API-graphs with a left-to-right
|
* The interpretation of a row is similar to API-graphs with a left-to-right
|
||||||
* reading.
|
* reading.
|
||||||
* 1. The `namespace` column selects a package.
|
* 1. The `namespace` column selects a namespace.
|
||||||
* 2. The `type` column selects a type within that package.
|
* 2. The `type` column selects a type within that namespace.
|
||||||
* 3. The `subtypes` is a boolean that indicates whether to jump to an
|
* 3. The `subtypes` is a boolean that indicates whether to jump to an
|
||||||
* arbitrary subtype of that type. Set this to `false` if leaving the `type`
|
* arbitrary subtype of that type. Set this to `false` if leaving the `type`
|
||||||
* blank (for example, a free function).
|
* blank (for example, a free function).
|
||||||
@@ -65,16 +65,14 @@
|
|||||||
* globally applicable value-preserving step.
|
* globally applicable value-preserving step.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import swift
|
import cpp
|
||||||
private import internal.DataFlowDispatch
|
private import new.DataFlow
|
||||||
private import internal.DataFlowPrivate
|
|
||||||
private import internal.DataFlowPublic
|
|
||||||
private import internal.FlowSummaryImpl
|
private import internal.FlowSummaryImpl
|
||||||
private import internal.FlowSummaryImpl::Public
|
private import internal.FlowSummaryImpl::Public
|
||||||
private import internal.FlowSummaryImpl::Private
|
private import internal.FlowSummaryImpl::Private
|
||||||
private import internal.FlowSummaryImpl::Private::External
|
private import internal.FlowSummaryImpl::Private::External
|
||||||
private import FlowSummary as FlowSummary
|
|
||||||
private import codeql.mad.ModelValidation as SharedModelVal
|
private import codeql.mad.ModelValidation as SharedModelVal
|
||||||
|
private import codeql.util.Unit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A unit class for adding additional source model rows.
|
* A unit class for adding additional source model rows.
|
||||||
@@ -354,13 +352,13 @@ private predicate elementSpec(
|
|||||||
private string paramsStringPart(Function c, int i) {
|
private string paramsStringPart(Function c, int i) {
|
||||||
i = -1 and result = "(" and exists(c)
|
i = -1 and result = "(" and exists(c)
|
||||||
or
|
or
|
||||||
exists(int n, string p | c.getParam(n).getType().toString() = p |
|
exists(int n, string p | c.getParameter(n).getType().toString() = p |
|
||||||
i = 2 * n and result = p
|
i = 2 * n and result = p
|
||||||
or
|
or
|
||||||
i = 2 * n - 1 and result = "," and n != 0
|
i = 2 * n - 1 and result = "," and n != 0
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
i = 2 * c.getNumberOfParams() and result = ")"
|
i = 2 * c.getNumberOfParameters() and result = ")"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -401,42 +399,42 @@ private Element interpretElement0(
|
|||||||
type = "" and
|
type = "" and
|
||||||
matchesSignature(func, signature) and
|
matchesSignature(func, signature) and
|
||||||
subtypes = false and
|
subtypes = false and
|
||||||
not result instanceof Method and
|
not exists(func.getDeclaringType()) and
|
||||||
result = func
|
result = func
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
// Member functions
|
// Member functions
|
||||||
exists(NominalTypeDecl namedTypeDecl, Decl declWithMethod, Method method |
|
exists(Class namedClass, Class classWithMethod, Function method |
|
||||||
method.getName() = name and
|
method.getName() = name and
|
||||||
method = declWithMethod.getAMember() and
|
method = classWithMethod.getAMember() and
|
||||||
namedTypeDecl.getFullName() = type and
|
namedClass.getName() = type and
|
||||||
matchesSignature(method, signature) and
|
matchesSignature(method, signature) and
|
||||||
result = method
|
result = method
|
||||||
|
|
|
|
||||||
// member declared in the named type or a subtype of it (or an extension of any)
|
// member declared in the named type or a subtype of it
|
||||||
subtypes = true and
|
subtypes = true and
|
||||||
declWithMethod.asNominalTypeDecl() = namedTypeDecl.getADerivedTypeDecl*()
|
classWithMethod = namedClass.getADerivedClass*()
|
||||||
or
|
or
|
||||||
// member declared directly in the named type (or an extension of it)
|
// member declared directly in the named type
|
||||||
subtypes = false and
|
subtypes = false and
|
||||||
declWithMethod.asNominalTypeDecl() = namedTypeDecl
|
classWithMethod = namedClass
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
// Fields
|
// Member variables
|
||||||
signature = "" and
|
signature = "" and
|
||||||
exists(NominalTypeDecl namedTypeDecl, Decl declWithField, FieldDecl field |
|
exists(Class namedClass, Class classWithMember, MemberVariable member |
|
||||||
field.getName() = name and
|
member.getName() = name and
|
||||||
field = declWithField.getAMember() and
|
member = classWithMember.getAMember() and
|
||||||
namedTypeDecl.getFullName() = type and
|
namedClass.getName() = type and
|
||||||
result = field
|
result = member
|
||||||
|
|
|
|
||||||
// field declared in the named type or a subtype of it (or an extension of any)
|
// field declared in the named type or a subtype of it (or an extension of any)
|
||||||
subtypes = true and
|
subtypes = true and
|
||||||
declWithField.asNominalTypeDecl() = namedTypeDecl.getADerivedTypeDecl*()
|
classWithMember = namedClass.getADerivedClass*()
|
||||||
or
|
or
|
||||||
// field declared directly in the named type (or an extension of it)
|
// field declared directly in the named type (or an extension of it)
|
||||||
subtypes = false and
|
subtypes = false and
|
||||||
declWithField.asNominalTypeDecl() = namedTypeDecl
|
classWithMember = namedClass
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -451,44 +449,6 @@ Element interpretElement(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
deprecated private predicate parseField(AccessPathToken c, Content::FieldContent f) {
|
|
||||||
exists(string fieldRegex, string name |
|
|
||||||
c.getName() = "Field" and
|
|
||||||
fieldRegex = "^([^.]+)$" and
|
|
||||||
name = c.getAnArgument().regexpCapture(fieldRegex, 1) and
|
|
||||||
f.getField().getName() = name
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
deprecated private predicate parseTuple(AccessPathToken c, Content::TupleContent t) {
|
|
||||||
c.getName() = "TupleElement" and
|
|
||||||
t.getIndex() = c.getAnArgument().toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
deprecated private predicate parseEnum(AccessPathToken c, Content::EnumContent e) {
|
|
||||||
c.getName() = "EnumElement" and
|
|
||||||
c.getAnArgument() = e.getSignature()
|
|
||||||
or
|
|
||||||
c.getName() = "OptionalSome" and
|
|
||||||
e.getSignature() = "some:0"
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Holds if the specification component parses as a `Content`. */
|
|
||||||
deprecated predicate parseContent(AccessPathToken component, Content content) {
|
|
||||||
parseField(component, content)
|
|
||||||
or
|
|
||||||
parseTuple(component, content)
|
|
||||||
or
|
|
||||||
parseEnum(component, content)
|
|
||||||
or
|
|
||||||
// map legacy "ArrayElement" specification components to `CollectionContent`
|
|
||||||
component.getName() = "ArrayElement" and
|
|
||||||
content instanceof Content::CollectionContent
|
|
||||||
or
|
|
||||||
component.getName() = "CollectionElement" and
|
|
||||||
content instanceof Content::CollectionContent
|
|
||||||
}
|
|
||||||
|
|
||||||
cached
|
cached
|
||||||
private module Cached {
|
private module Cached {
|
||||||
/**
|
/**
|
||||||
@@ -496,7 +456,7 @@ private module Cached {
|
|||||||
* model.
|
* model.
|
||||||
*/
|
*/
|
||||||
cached
|
cached
|
||||||
predicate sourceNode(Node node, string kind) {
|
predicate sourceNode(DataFlow::Node node, string kind) {
|
||||||
exists(SourceSinkInterpretationInput::InterpretNode n |
|
exists(SourceSinkInterpretationInput::InterpretNode n |
|
||||||
isSourceNode(n, kind) and n.asNode() = node
|
isSourceNode(n, kind) and n.asNode() = node
|
||||||
)
|
)
|
||||||
@@ -507,7 +467,7 @@ private module Cached {
|
|||||||
* model.
|
* model.
|
||||||
*/
|
*/
|
||||||
cached
|
cached
|
||||||
predicate sinkNode(Node node, string kind) {
|
predicate sinkNode(DataFlow::Node node, string kind) {
|
||||||
exists(SourceSinkInterpretationInput::InterpretNode n |
|
exists(SourceSinkInterpretationInput::InterpretNode n |
|
||||||
isSinkNode(n, kind) and n.asNode() = node
|
isSinkNode(n, kind) and n.asNode() = node
|
||||||
)
|
)
|
||||||
@@ -567,7 +527,7 @@ private class NeutralCallableAdapter extends NeutralCallable {
|
|||||||
string provenance_;
|
string provenance_;
|
||||||
|
|
||||||
NeutralCallableAdapter() {
|
NeutralCallableAdapter() {
|
||||||
// Neutral models have not been implemented for Swift.
|
// Neutral models have not been implemented for CPP.
|
||||||
none() and
|
none() and
|
||||||
exists(this) and
|
exists(this) and
|
||||||
exists(kind) and
|
exists(kind) and
|
||||||
|
|||||||
@@ -2,21 +2,20 @@
|
|||||||
* Provides classes and predicates for defining flow summaries.
|
* Provides classes and predicates for defining flow summaries.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private import swift
|
private import cpp
|
||||||
private import codeql.dataflow.internal.FlowSummaryImpl
|
private import codeql.dataflow.internal.FlowSummaryImpl
|
||||||
private import codeql.dataflow.internal.AccessPathSyntax as AccessPath
|
private import codeql.dataflow.internal.AccessPathSyntax as AccessPath
|
||||||
private import DataFlowImplSpecific as DataFlowImplSpecific
|
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
|
||||||
private import DataFlowImplSpecific::Private
|
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||||
private import DataFlowImplSpecific::Public
|
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific as DataFlowImplSpecific
|
||||||
private import DataFlowImplCommon
|
private import semmle.code.cpp.dataflow.ExternalFlow
|
||||||
private import codeql.swift.dataflow.ExternalFlow
|
|
||||||
|
|
||||||
module Input implements InputSig<DataFlowImplSpecific::SwiftDataFlow> {
|
module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
|
||||||
class SummarizedCallableBase = Function;
|
class SummarizedCallableBase = Function;
|
||||||
|
|
||||||
ArgumentPosition callbackSelfParameterPosition() { result instanceof ThisArgumentPosition }
|
ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) }
|
||||||
|
|
||||||
ReturnKind getStandardReturnValueKind() { result instanceof NormalReturnKind }
|
ReturnKind getStandardReturnValueKind() { result.(NormalReturnKind).getIndirectionIndex() = 0 }
|
||||||
|
|
||||||
string encodeParameterPosition(ParameterPosition pos) { result = pos.toString() }
|
string encodeParameterPosition(ParameterPosition pos) { result = pos.toString() }
|
||||||
|
|
||||||
@@ -29,37 +28,40 @@ module Input implements InputSig<DataFlowImplSpecific::SwiftDataFlow> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
string encodeContent(ContentSet cs, string arg) {
|
string encodeContent(ContentSet cs, string arg) {
|
||||||
exists(Content::FieldContent c |
|
exists(FieldContent c |
|
||||||
cs.isSingleton(c) and
|
cs.isSingleton(c) and
|
||||||
result = "Field" and
|
result = "Field" and
|
||||||
arg = c.getField().getName()
|
arg = c.getField().getName()
|
||||||
)
|
)
|
||||||
or
|
/*
|
||||||
exists(Content::TupleContent c |
|
* or
|
||||||
cs.isSingleton(c) and
|
* exists(Content::TupleContent c |
|
||||||
result = "TupleElement" and
|
* cs.isSingleton(c) and
|
||||||
arg = c.getIndex().toString()
|
* result = "TupleElement" and
|
||||||
)
|
* arg = c.getIndex().toString()
|
||||||
or
|
* )
|
||||||
exists(Content::EnumContent c, string sig |
|
* or
|
||||||
cs.isSingleton(c) and
|
* exists(Content::EnumContent c, string sig |
|
||||||
sig = c.getSignature()
|
* cs.isSingleton(c) and
|
||||||
|
|
* sig = c.getSignature()
|
||||||
if sig = "some:0"
|
* |
|
||||||
then
|
* if sig = "some:0"
|
||||||
result = "OptionalSome" and
|
* then
|
||||||
arg = ""
|
* result = "OptionalSome" and
|
||||||
else (
|
* arg = ""
|
||||||
result = "EnumElement" and
|
* else (
|
||||||
arg = sig
|
* result = "EnumElement" and
|
||||||
)
|
* arg = sig
|
||||||
)
|
* )
|
||||||
or
|
* )
|
||||||
exists(Content::CollectionContent c |
|
* or
|
||||||
cs.isSingleton(c) and
|
* exists(Content::CollectionContent c |
|
||||||
result = "CollectionElement" and
|
* cs.isSingleton(c) and
|
||||||
arg = ""
|
* result = "CollectionElement" and
|
||||||
)
|
* arg = ""
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string encodeWithoutContent(ContentSet c, string arg) {
|
string encodeWithoutContent(ContentSet c, string arg) {
|
||||||
@@ -68,24 +70,12 @@ module Input implements InputSig<DataFlowImplSpecific::SwiftDataFlow> {
|
|||||||
|
|
||||||
string encodeWithContent(ContentSet c, string arg) { result = "WithContent" + c and arg = "" }
|
string encodeWithContent(ContentSet c, string arg) { result = "WithContent" + c and arg = "" }
|
||||||
|
|
||||||
bindingset[token]
|
|
||||||
ContentSet decodeUnknownContent(AccessPath::AccessPathTokenBase token) {
|
|
||||||
// map legacy "ArrayElement" specification components to `CollectionContent`
|
|
||||||
token.getName() = "ArrayElement" and
|
|
||||||
result.isSingleton(any(Content::CollectionContent c))
|
|
||||||
or
|
|
||||||
token.getName() = "CollectionElement" and
|
|
||||||
result.isSingleton(any(Content::CollectionContent c))
|
|
||||||
}
|
|
||||||
|
|
||||||
bindingset[token]
|
bindingset[token]
|
||||||
ParameterPosition decodeUnknownParameterPosition(AccessPath::AccessPathTokenBase token) {
|
ParameterPosition decodeUnknownParameterPosition(AccessPath::AccessPathTokenBase token) {
|
||||||
// needed to support `Argument[x..y]` ranges and `Argument[-1]`
|
// needed to support `Argument[x..y]` ranges and `Argument[-1]`
|
||||||
token.getName() = "Argument" and
|
token.getName() = "Argument" and
|
||||||
exists(int pos | pos = AccessPath::parseInt(token.getAnArgument()) |
|
exists(int pos | pos = AccessPath::parseInt(token.getAnArgument()) |
|
||||||
result.(PositionalParameterPosition).getIndex() = pos
|
result = TDirectPosition(pos)
|
||||||
or
|
|
||||||
pos = -1 and result instanceof ThisParameterPosition
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,24 +84,21 @@ module Input implements InputSig<DataFlowImplSpecific::SwiftDataFlow> {
|
|||||||
// needed to support `Parameter[x..y]` ranges and `Parameter[-1]`
|
// needed to support `Parameter[x..y]` ranges and `Parameter[-1]`
|
||||||
token.getName() = "Parameter" and
|
token.getName() = "Parameter" and
|
||||||
exists(int pos | pos = AccessPath::parseInt(token.getAnArgument()) |
|
exists(int pos | pos = AccessPath::parseInt(token.getAnArgument()) |
|
||||||
result.(PositionalArgumentPosition).getIndex() = pos
|
result = TDirectPosition(pos)
|
||||||
or
|
|
||||||
pos = -1 and
|
|
||||||
result instanceof ThisArgumentPosition
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private import Make<DataFlowImplSpecific::SwiftDataFlow, Input> as Impl
|
/*private*/ import Make<DataFlowImplSpecific::CppDataFlow, Input> as Impl
|
||||||
|
|
||||||
private module StepsInput implements Impl::Private::StepsInputSig {
|
private module StepsInput implements Impl::Private::StepsInputSig {
|
||||||
DataFlowCall getACall(Public::SummarizedCallable sc) { result.asCall().getStaticTarget() = sc }
|
DataFlowCall getACall(Public::SummarizedCallable sc) { result.getStaticCallTarget() = sc }
|
||||||
}
|
}
|
||||||
|
|
||||||
module SourceSinkInterpretationInput implements
|
module SourceSinkInterpretationInput implements
|
||||||
Impl::Private::External::SourceSinkInterpretationInputSig<Location>
|
Impl::Private::External::SourceSinkInterpretationInputSig<Location>
|
||||||
{
|
{
|
||||||
class Element = AstNode;
|
class Element = Element;
|
||||||
|
|
||||||
class SourceOrSinkElement = Element;
|
class SourceOrSinkElement = Element;
|
||||||
|
|
||||||
@@ -158,10 +145,12 @@ module SourceSinkInterpretationInput implements
|
|||||||
DataFlowCall asCall() { this = TDataFlowCall_(result) }
|
DataFlowCall asCall() { this = TDataFlowCall_(result) }
|
||||||
|
|
||||||
/** Gets the callable that this node corresponds to, if any. */
|
/** Gets the callable that this node corresponds to, if any. */
|
||||||
DataFlowCallable asCallable() { result.getUnderlyingCallable() = this.asElement() }
|
DataFlowCallable asCallable() { result.(Function) = this.asElement() }
|
||||||
|
|
||||||
/** Gets the target of this call, if any. */
|
/** Gets the target of this call, if any. */
|
||||||
Element getCallTarget() { result = this.asCall().asCall().getStaticTarget() }
|
Element getCallTarget() {
|
||||||
|
result = this.asNode().asExpr().(Call).getTarget()
|
||||||
|
}
|
||||||
|
|
||||||
/** Gets a textual representation of this node. */
|
/** Gets a textual representation of this node. */
|
||||||
string toString() {
|
string toString() {
|
||||||
@@ -186,31 +175,31 @@ module SourceSinkInterpretationInput implements
|
|||||||
bindingset[c]
|
bindingset[c]
|
||||||
predicate interpretOutput(string c, InterpretNode mid, InterpretNode node) {
|
predicate interpretOutput(string c, InterpretNode mid, InterpretNode node) {
|
||||||
// Allow fields to be picked as output nodes.
|
// Allow fields to be picked as output nodes.
|
||||||
exists(Node n, AstNode ast |
|
exists(Node n, Element ast |
|
||||||
n = node.asNode() and
|
n = node.asNode() and
|
||||||
ast = mid.asElement()
|
ast = mid.asElement()
|
||||||
|
|
|
|
||||||
c = "" and
|
c = "" and
|
||||||
n.asExpr().(MemberRefExpr).getMember() = ast
|
n.asExpr().(VariableAccess).getTarget() = ast
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Provides additional source specification logic. */
|
/** Provides additional source specification logic. */
|
||||||
bindingset[c]
|
bindingset[c]
|
||||||
predicate interpretInput(string c, InterpretNode mid, InterpretNode node) {
|
predicate interpretInput(string c, InterpretNode mid, InterpretNode node) {
|
||||||
exists(Node n, AstNode ast, MemberRefExpr e |
|
exists(Node n, Element ast, VariableAccess e |
|
||||||
n = node.asNode() and
|
n = node.asNode() and
|
||||||
ast = mid.asElement() and
|
ast = mid.asElement() and
|
||||||
e.getMember() = ast
|
e.getTarget() = ast
|
||||||
|
|
|
|
||||||
// Allow fields to be picked as input nodes.
|
// Allow fields to be picked as input nodes.
|
||||||
c = "" and
|
c = "" and
|
||||||
e.getBase() = n.asExpr()
|
e.getQualifier() = n.asExpr()
|
||||||
or
|
or
|
||||||
// Allow post update nodes to be picked as input nodes when the `input` column
|
// Allow post update nodes to be picked as input nodes when the `input` column
|
||||||
// of the row is `PostUpdate`.
|
// of the row is `PostUpdate`.
|
||||||
c = "PostUpdate" and
|
c = "PostUpdate" and
|
||||||
e.getBase() = n.(PostUpdateNode).getPreUpdateNode().asExpr()
|
e.getQualifier() = n.(PostUpdateNode).getPreUpdateNode().asExpr()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -458,11 +458,13 @@ class ReturnKind extends TReturnKind {
|
|||||||
abstract string toString();
|
abstract string toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NormalReturnKind extends ReturnKind, TNormalReturnKind {
|
class NormalReturnKind extends ReturnKind, TNormalReturnKind {
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
NormalReturnKind() { this = TNormalReturnKind(index) }
|
NormalReturnKind() { this = TNormalReturnKind(index) }
|
||||||
|
|
||||||
|
int getIndirectionIndex() { result = index }
|
||||||
|
|
||||||
override string toString() { result = "indirect return" }
|
override string toString() { result = "indirect return" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2330,6 +2330,12 @@ class UnionContent extends Content, TUnionContent {
|
|||||||
* stored into (`getAStoreContent`) or read from (`getAReadContent`).
|
* stored into (`getAStoreContent`) or read from (`getAReadContent`).
|
||||||
*/
|
*/
|
||||||
class ContentSet instanceof Content {
|
class ContentSet instanceof Content {
|
||||||
|
/**
|
||||||
|
* Holds if this content set is the singleton `{c}`. At present, this is
|
||||||
|
* the only kind of content set supported in C/C++.
|
||||||
|
*/
|
||||||
|
predicate isSingleton(Content c) { this = c }
|
||||||
|
|
||||||
/** Gets a content that may be stored into when storing into this set. */
|
/** Gets a content that may be stored into when storing into this set. */
|
||||||
Content getAStoreContent() { result = this }
|
Content getAStoreContent() { result = this }
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
import cpp
|
import cpp
|
||||||
import FunctionInputsAndOutputs
|
import FunctionInputsAndOutputs
|
||||||
import semmle.code.cpp.models.Models
|
import semmle.code.cpp.models.Models
|
||||||
|
import semmle.code.cpp.dataflow.ExternalFlow
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A library function that returns data that may be read from a network connection.
|
* A library function that returns data that may be read from a network connection.
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ abstract class RemoteFlowSource extends FlowSource { }
|
|||||||
/** A data flow source of local user input. */
|
/** A data flow source of local user input. */
|
||||||
abstract class LocalFlowSource extends FlowSource { }
|
abstract class LocalFlowSource extends FlowSource { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A remote data flow source that is defined through a `RemoteFlowSourceFunction` model.
|
||||||
|
*/
|
||||||
private class RemoteModelSource extends RemoteFlowSource {
|
private class RemoteModelSource extends RemoteFlowSource {
|
||||||
string sourceType;
|
string sourceType;
|
||||||
|
|
||||||
@@ -34,6 +37,9 @@ private class RemoteModelSource extends RemoteFlowSource {
|
|||||||
override string getSourceType() { result = sourceType }
|
override string getSourceType() { result = sourceType }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A local data flow source that is defined through a `LocalFlowSourceFunction` model.
|
||||||
|
*/
|
||||||
private class LocalModelSource extends LocalFlowSource {
|
private class LocalModelSource extends LocalFlowSource {
|
||||||
string sourceType;
|
string sourceType;
|
||||||
|
|
||||||
@@ -48,6 +54,9 @@ private class LocalModelSource extends LocalFlowSource {
|
|||||||
override string getSourceType() { result = sourceType }
|
override string getSourceType() { result = sourceType }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A local data flow source that the `argv` parameter to `main`.
|
||||||
|
*/
|
||||||
private class ArgvSource extends LocalFlowSource {
|
private class ArgvSource extends LocalFlowSource {
|
||||||
ArgvSource() {
|
ArgvSource() {
|
||||||
exists(Function main, Parameter argv |
|
exists(Function main, Parameter argv |
|
||||||
@@ -60,6 +69,24 @@ private class ArgvSource extends LocalFlowSource {
|
|||||||
override string getSourceType() { result = "a command-line argument" }
|
override string getSourceType() { result = "a command-line argument" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A remote data flow source that is defined through 'models as data'.
|
||||||
|
*/
|
||||||
|
private class ExternalRemoteFlowSource extends RemoteFlowSource {
|
||||||
|
ExternalRemoteFlowSource() { sourceNode(this, "remote") }
|
||||||
|
|
||||||
|
override string getSourceType() { result = "external" }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A local data flow source that is defined through 'models as data'.
|
||||||
|
*/
|
||||||
|
private class ExternalLocalFlowSource extends LocalFlowSource {
|
||||||
|
ExternalLocalFlowSource() { sourceNode(this, "local") }
|
||||||
|
|
||||||
|
override string getSourceType() { result = "external" }
|
||||||
|
}
|
||||||
|
|
||||||
/** A remote data flow sink. */
|
/** A remote data flow sink. */
|
||||||
abstract class RemoteFlowSink extends DataFlow::Node {
|
abstract class RemoteFlowSink extends DataFlow::Node {
|
||||||
/** Gets a string that describes the type of this flow sink. */
|
/** Gets a string that describes the type of this flow sink. */
|
||||||
|
|||||||
@@ -1588,7 +1588,8 @@ module Make<DF::InputSig DataFlowLang, InputSig<DataFlowLang> Input> {
|
|||||||
SourceSinkAccessPath output, int n, InterpretNode ref, InterpretNode node
|
SourceSinkAccessPath output, int n, InterpretNode ref, InterpretNode node
|
||||||
) {
|
) {
|
||||||
sourceElementRef(ref, output, _) and
|
sourceElementRef(ref, output, _) and
|
||||||
n = 0 and
|
//n = 0 and
|
||||||
|
n = [0,1] and // TODO: fix this, there's no good reason for it.
|
||||||
(
|
(
|
||||||
if output = ""
|
if output = ""
|
||||||
then
|
then
|
||||||
|
|||||||
Reference in New Issue
Block a user