зеркало из https://github.com/github/codeql.git
Merge pull request #13901 from hvitved/dataflow/refactor
Data flow: Refactor shared library
This commit is contained in:
Коммит
2126ab0dde
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImpl
|
||||
private import codeql.dataflow.internal.DataFlowImpl
|
||||
import MakeImpl<CppOldDataFlow>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImplCommon
|
||||
private import codeql.dataflow.internal.DataFlowImplCommon
|
||||
import MakeImplCommon<CppOldDataFlow>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Provides C++-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
private import codeql.dataflow.DataFlowParameter
|
||||
private import codeql.dataflow.DataFlow
|
||||
|
||||
module Private {
|
||||
import DataFlowPrivate
|
||||
|
@ -13,7 +13,7 @@ module Public {
|
|||
import DataFlowUtil
|
||||
}
|
||||
|
||||
module CppOldDataFlow implements DataFlowParameter {
|
||||
module CppOldDataFlow implements InputSig {
|
||||
import Private
|
||||
import Public
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImpl
|
||||
private import codeql.dataflow.internal.DataFlowImpl
|
||||
import MakeImpl<CppDataFlow>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImplCommon
|
||||
private import codeql.dataflow.internal.DataFlowImplCommon
|
||||
import MakeImplCommon<CppDataFlow>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Provides IR-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
private import codeql.dataflow.DataFlowParameter
|
||||
private import codeql.dataflow.DataFlow
|
||||
|
||||
module Private {
|
||||
import DataFlowPrivate
|
||||
|
@ -13,7 +13,7 @@ module Public {
|
|||
import DataFlowUtil
|
||||
}
|
||||
|
||||
module CppDataFlow implements DataFlowParameter {
|
||||
module CppDataFlow implements InputSig {
|
||||
import Private
|
||||
import Public
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImpl
|
||||
private import codeql.dataflow.internal.DataFlowImpl
|
||||
import MakeImpl<CsharpDataFlow>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImplCommon
|
||||
private import codeql.dataflow.internal.DataFlowImplCommon
|
||||
import MakeImplCommon<CsharpDataFlow>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Provides C#-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
private import codeql.dataflow.DataFlowParameter
|
||||
private import codeql.dataflow.DataFlow
|
||||
|
||||
module Private {
|
||||
import DataFlowPrivate
|
||||
|
@ -13,7 +13,7 @@ module Public {
|
|||
import DataFlowPublic
|
||||
}
|
||||
|
||||
module CsharpDataFlow implements DataFlowParameter {
|
||||
module CsharpDataFlow implements InputSig {
|
||||
import Private
|
||||
import Public
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImpl
|
||||
private import codeql.dataflow.internal.DataFlowImpl
|
||||
import MakeImpl<GoDataFlow>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImplCommon
|
||||
private import codeql.dataflow.internal.DataFlowImplCommon
|
||||
import MakeImplCommon<GoDataFlow>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Provides Go-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
private import codeql.dataflow.DataFlowParameter
|
||||
private import codeql.dataflow.DataFlow
|
||||
|
||||
module Private {
|
||||
import DataFlowPrivate
|
||||
|
@ -13,7 +13,7 @@ module Public {
|
|||
import DataFlowUtil
|
||||
}
|
||||
|
||||
module GoDataFlow implements DataFlowParameter {
|
||||
module GoDataFlow implements InputSig {
|
||||
import Private
|
||||
import Public
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImpl
|
||||
private import codeql.dataflow.internal.DataFlowImpl
|
||||
import MakeImpl<JavaDataFlow>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImplCommon
|
||||
private import codeql.dataflow.internal.DataFlowImplCommon
|
||||
import MakeImplCommon<JavaDataFlow>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Provides Java-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
private import codeql.dataflow.DataFlowParameter
|
||||
private import codeql.dataflow.DataFlow
|
||||
|
||||
module Private {
|
||||
import DataFlowPrivate
|
||||
|
@ -13,7 +13,7 @@ module Public {
|
|||
import DataFlowUtil
|
||||
}
|
||||
|
||||
module JavaDataFlow implements DataFlowParameter {
|
||||
module JavaDataFlow implements InputSig {
|
||||
import Private
|
||||
import Public
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImpl
|
||||
private import codeql.dataflow.internal.DataFlowImpl
|
||||
import MakeImpl<PythonDataFlow>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImplCommon
|
||||
private import codeql.dataflow.internal.DataFlowImplCommon
|
||||
import MakeImplCommon<PythonDataFlow>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Provides Python-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
private import codeql.dataflow.DataFlowParameter
|
||||
private import codeql.dataflow.DataFlow
|
||||
// we need to export `Unit` for the DataFlowImpl* files
|
||||
private import python as Python
|
||||
|
||||
|
@ -15,7 +15,7 @@ module Public {
|
|||
import DataFlowUtil
|
||||
}
|
||||
|
||||
module PythonDataFlow implements DataFlowParameter {
|
||||
module PythonDataFlow implements InputSig {
|
||||
import Private
|
||||
import Public
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImpl
|
||||
private import codeql.dataflow.internal.DataFlowImpl
|
||||
import MakeImpl<RubyDataFlow>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImplCommon
|
||||
private import codeql.dataflow.internal.DataFlowImplCommon
|
||||
import MakeImplCommon<RubyDataFlow>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Provides Ruby-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
private import codeql.dataflow.DataFlowParameter
|
||||
private import codeql.dataflow.DataFlow
|
||||
|
||||
module Private {
|
||||
import DataFlowPrivate
|
||||
|
@ -13,7 +13,7 @@ module Public {
|
|||
import DataFlowPublic
|
||||
}
|
||||
|
||||
module RubyDataFlow implements DataFlowParameter {
|
||||
module RubyDataFlow implements InputSig {
|
||||
import Private
|
||||
import Public
|
||||
|
||||
|
|
|
@ -1,15 +1,234 @@
|
|||
/**
|
||||
* Provides an implementation of global (interprocedural) data flow. This file
|
||||
* re-exports the local (intraprocedural) data flow analysis from
|
||||
* `DataFlowImplSpecific::Public` and adds a global analysis, mainly exposed
|
||||
* through the `Global` and `GlobalWithState` modules.
|
||||
* adds a global analysis, mainly exposed through the `Global` and `GlobalWithState`
|
||||
* modules.
|
||||
*/
|
||||
|
||||
import DataFlowParameter
|
||||
/** Provides language-specific data flow parameters. */
|
||||
signature module InputSig {
|
||||
class Node {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
|
||||
module Configs<DataFlowParameter Lang> {
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
);
|
||||
}
|
||||
|
||||
class ParameterNode extends Node;
|
||||
|
||||
class ArgumentNode extends Node;
|
||||
|
||||
class ReturnNode extends Node {
|
||||
ReturnKind getKind();
|
||||
}
|
||||
|
||||
class OutNode extends Node;
|
||||
|
||||
class PostUpdateNode extends Node {
|
||||
Node getPreUpdateNode();
|
||||
}
|
||||
|
||||
class CastNode extends Node;
|
||||
|
||||
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos);
|
||||
|
||||
predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos);
|
||||
|
||||
DataFlowCallable nodeGetEnclosingCallable(Node node);
|
||||
|
||||
DataFlowType getNodeType(Node node);
|
||||
|
||||
predicate nodeIsHidden(Node node);
|
||||
|
||||
class DataFlowExpr;
|
||||
|
||||
/** Gets the node corresponding to `e`. */
|
||||
Node exprNode(DataFlowExpr e);
|
||||
|
||||
class DataFlowCall {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
|
||||
DataFlowCallable getEnclosingCallable();
|
||||
}
|
||||
|
||||
class DataFlowCallable {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
}
|
||||
|
||||
class ReturnKind {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
}
|
||||
|
||||
/** Gets a viable implementation of the target of the given `Call`. */
|
||||
DataFlowCallable viableCallable(DataFlowCall c);
|
||||
|
||||
/**
|
||||
* Holds if the set of viable implementations that can be called by `call`
|
||||
* might be improved by knowing the call context.
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c);
|
||||
|
||||
/**
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference.
|
||||
*/
|
||||
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx);
|
||||
|
||||
/**
|
||||
* Gets a node that can read the value returned from `call` with return kind
|
||||
* `kind`.
|
||||
*/
|
||||
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind);
|
||||
|
||||
class DataFlowType {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
}
|
||||
|
||||
string ppReprType(DataFlowType t);
|
||||
|
||||
bindingset[t1, t2]
|
||||
predicate compatibleTypes(DataFlowType t1, DataFlowType t2);
|
||||
|
||||
predicate typeStrongerThan(DataFlowType t1, DataFlowType t2);
|
||||
|
||||
class Content {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
}
|
||||
|
||||
predicate forceHighPrecision(Content c);
|
||||
|
||||
/**
|
||||
* An entity that represents a set of `Content`s.
|
||||
*
|
||||
* The set may be interpreted differently depending on whether it is
|
||||
* stored into (`getAStoreContent`) or read from (`getAReadContent`).
|
||||
*/
|
||||
class ContentSet {
|
||||
/** Gets a content that may be stored into when storing into this set. */
|
||||
Content getAStoreContent();
|
||||
|
||||
/** Gets a content that may be read from when reading from this set. */
|
||||
Content getAReadContent();
|
||||
}
|
||||
|
||||
class ContentApprox {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
}
|
||||
|
||||
ContentApprox getContentApprox(Content c);
|
||||
|
||||
class ParameterPosition {
|
||||
/** Gets a textual representation of this element. */
|
||||
bindingset[this]
|
||||
string toString();
|
||||
}
|
||||
|
||||
class ArgumentPosition {
|
||||
/** Gets a textual representation of this element. */
|
||||
bindingset[this]
|
||||
string toString();
|
||||
}
|
||||
|
||||
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos);
|
||||
|
||||
predicate simpleLocalFlowStep(Node node1, Node node2);
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` through a non-local step
|
||||
* that does not follow a call edge. For example, a step through a global
|
||||
* variable.
|
||||
*/
|
||||
predicate jumpStep(Node node1, Node node2);
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` via a read of `c`. Thus,
|
||||
* `node1` references an object with a content `c.getAReadContent()` whose
|
||||
* value ends up in `node2`.
|
||||
*/
|
||||
predicate readStep(Node node1, ContentSet c, Node node2);
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` via a store into `c`. Thus,
|
||||
* `node2` references an object with a content `c.getAStoreContent()` that
|
||||
* contains the value of `node1`.
|
||||
*/
|
||||
predicate storeStep(Node node1, ContentSet c, Node node2);
|
||||
|
||||
/**
|
||||
* Holds if values stored inside content `c` are cleared at node `n`. For example,
|
||||
* any value stored inside `f` is cleared at the pre-update node associated with `x`
|
||||
* in `x.f = newValue`.
|
||||
*/
|
||||
predicate clearsContent(Node n, ContentSet c);
|
||||
|
||||
/**
|
||||
* Holds if the value that is being tracked is expected to be stored inside content `c`
|
||||
* at node `n`.
|
||||
*/
|
||||
predicate expectsContent(Node n, ContentSet c);
|
||||
|
||||
/**
|
||||
* Holds if the node `n` is unreachable when the call context is `call`.
|
||||
*/
|
||||
predicate isUnreachableInCall(Node n, DataFlowCall call);
|
||||
|
||||
default int accessPathLimit() { result = 5 }
|
||||
|
||||
/**
|
||||
* Holds if flow is allowed to pass from parameter `p` and back to itself as a
|
||||
* side-effect, resulting in a summary from `p` to itself.
|
||||
*
|
||||
* One example would be to allow flow like `p.foo = p.bar;`, which is disallowed
|
||||
* by default as a heuristic.
|
||||
*/
|
||||
predicate allowParameterReturnInSelf(ParameterNode p);
|
||||
|
||||
class LambdaCallKind;
|
||||
|
||||
/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */
|
||||
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c);
|
||||
|
||||
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
|
||||
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver);
|
||||
|
||||
/** Extra data-flow steps needed for lambda flow analysis. */
|
||||
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue);
|
||||
|
||||
/**
|
||||
* Holds if `n` should never be skipped over in the `PathGraph` and in path
|
||||
* explanations.
|
||||
*/
|
||||
default predicate neverSkipInPathGraph(Node n) { none() }
|
||||
|
||||
/**
|
||||
* Gets an additional term that is added to the `join` and `branch` computations to reflect
|
||||
* an additional forward or backwards branching factor that is not taken into account
|
||||
* when calculating the (virtual) dispatch cost.
|
||||
*
|
||||
* Argument `arg` is part of a path from a source to a sink, and `p` is the target parameter.
|
||||
*/
|
||||
int getAdditionalFlowIntoCallNodeTerm(ArgumentNode arg, ParameterNode p);
|
||||
|
||||
predicate golangSpecificParamArgFilter(DataFlowCall call, ParameterNode p, ArgumentNode arg);
|
||||
}
|
||||
|
||||
module Configs<InputSig Lang> {
|
||||
private import Lang
|
||||
private import DataFlowImplCommon::MakeImplCommon<Lang>
|
||||
private import internal.DataFlowImplCommon::MakeImplCommon<Lang>
|
||||
import DataFlowImplCommonPublic
|
||||
|
||||
/** An input configuration for data flow. */
|
||||
|
@ -211,9 +430,9 @@ module Configs<DataFlowParameter Lang> {
|
|||
}
|
||||
}
|
||||
|
||||
module DataFlowMake<DataFlowParameter Lang> {
|
||||
module DataFlowMake<InputSig Lang> {
|
||||
private import Lang
|
||||
private import DataFlowImpl::MakeImpl<Lang>
|
||||
private import internal.DataFlowImpl::MakeImpl<Lang>
|
||||
import Configs<Lang>
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,220 +0,0 @@
|
|||
signature module DataFlowParameter {
|
||||
class Node {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
);
|
||||
}
|
||||
|
||||
class ParameterNode extends Node;
|
||||
|
||||
class ArgumentNode extends Node;
|
||||
|
||||
class ReturnNode extends Node {
|
||||
ReturnKind getKind();
|
||||
}
|
||||
|
||||
class OutNode extends Node;
|
||||
|
||||
class PostUpdateNode extends Node {
|
||||
Node getPreUpdateNode();
|
||||
}
|
||||
|
||||
class CastNode extends Node;
|
||||
|
||||
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos);
|
||||
|
||||
predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos);
|
||||
|
||||
DataFlowCallable nodeGetEnclosingCallable(Node node);
|
||||
|
||||
DataFlowType getNodeType(Node node);
|
||||
|
||||
predicate nodeIsHidden(Node node);
|
||||
|
||||
class DataFlowExpr;
|
||||
|
||||
/** Gets the node corresponding to `e`. */
|
||||
Node exprNode(DataFlowExpr e);
|
||||
|
||||
class DataFlowCall {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
|
||||
DataFlowCallable getEnclosingCallable();
|
||||
}
|
||||
|
||||
class DataFlowCallable {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
}
|
||||
|
||||
class ReturnKind {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
}
|
||||
|
||||
/** Gets a viable implementation of the target of the given `Call`. */
|
||||
DataFlowCallable viableCallable(DataFlowCall c);
|
||||
|
||||
/**
|
||||
* Holds if the set of viable implementations that can be called by `call`
|
||||
* might be improved by knowing the call context.
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c);
|
||||
|
||||
/**
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference.
|
||||
*/
|
||||
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx);
|
||||
|
||||
/**
|
||||
* Gets a node that can read the value returned from `call` with return kind
|
||||
* `kind`.
|
||||
*/
|
||||
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind);
|
||||
|
||||
class DataFlowType {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
}
|
||||
|
||||
string ppReprType(DataFlowType t);
|
||||
|
||||
bindingset[t1, t2]
|
||||
predicate compatibleTypes(DataFlowType t1, DataFlowType t2);
|
||||
|
||||
predicate typeStrongerThan(DataFlowType t1, DataFlowType t2);
|
||||
|
||||
class Content {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
}
|
||||
|
||||
predicate forceHighPrecision(Content c);
|
||||
|
||||
/**
|
||||
* An entity that represents a set of `Content`s.
|
||||
*
|
||||
* The set may be interpreted differently depending on whether it is
|
||||
* stored into (`getAStoreContent`) or read from (`getAReadContent`).
|
||||
*/
|
||||
class ContentSet {
|
||||
/** Gets a content that may be stored into when storing into this set. */
|
||||
Content getAStoreContent();
|
||||
|
||||
/** Gets a content that may be read from when reading from this set. */
|
||||
Content getAReadContent();
|
||||
}
|
||||
|
||||
class ContentApprox {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString();
|
||||
}
|
||||
|
||||
ContentApprox getContentApprox(Content c);
|
||||
|
||||
class ParameterPosition {
|
||||
/** Gets a textual representation of this element. */
|
||||
bindingset[this]
|
||||
string toString();
|
||||
}
|
||||
|
||||
class ArgumentPosition {
|
||||
/** Gets a textual representation of this element. */
|
||||
bindingset[this]
|
||||
string toString();
|
||||
}
|
||||
|
||||
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos);
|
||||
|
||||
predicate simpleLocalFlowStep(Node node1, Node node2);
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` through a non-local step
|
||||
* that does not follow a call edge. For example, a step through a global
|
||||
* variable.
|
||||
*/
|
||||
predicate jumpStep(Node node1, Node node2);
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` via a read of `c`. Thus,
|
||||
* `node1` references an object with a content `c.getAReadContent()` whose
|
||||
* value ends up in `node2`.
|
||||
*/
|
||||
predicate readStep(Node node1, ContentSet c, Node node2);
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` via a store into `c`. Thus,
|
||||
* `node2` references an object with a content `c.getAStoreContent()` that
|
||||
* contains the value of `node1`.
|
||||
*/
|
||||
predicate storeStep(Node node1, ContentSet c, Node node2);
|
||||
|
||||
/**
|
||||
* Holds if values stored inside content `c` are cleared at node `n`. For example,
|
||||
* any value stored inside `f` is cleared at the pre-update node associated with `x`
|
||||
* in `x.f = newValue`.
|
||||
*/
|
||||
predicate clearsContent(Node n, ContentSet c);
|
||||
|
||||
/**
|
||||
* Holds if the value that is being tracked is expected to be stored inside content `c`
|
||||
* at node `n`.
|
||||
*/
|
||||
predicate expectsContent(Node n, ContentSet c);
|
||||
|
||||
/**
|
||||
* Holds if the node `n` is unreachable when the call context is `call`.
|
||||
*/
|
||||
predicate isUnreachableInCall(Node n, DataFlowCall call);
|
||||
|
||||
default int accessPathLimit() { result = 5 }
|
||||
|
||||
/**
|
||||
* Holds if flow is allowed to pass from parameter `p` and back to itself as a
|
||||
* side-effect, resulting in a summary from `p` to itself.
|
||||
*
|
||||
* One example would be to allow flow like `p.foo = p.bar;`, which is disallowed
|
||||
* by default as a heuristic.
|
||||
*/
|
||||
predicate allowParameterReturnInSelf(ParameterNode p);
|
||||
|
||||
class LambdaCallKind;
|
||||
|
||||
/** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */
|
||||
predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c);
|
||||
|
||||
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
|
||||
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver);
|
||||
|
||||
/** Extra data-flow steps needed for lambda flow analysis. */
|
||||
predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue);
|
||||
|
||||
/**
|
||||
* Holds if `n` should never be skipped over in the `PathGraph` and in path
|
||||
* explanations.
|
||||
*/
|
||||
default predicate neverSkipInPathGraph(Node n) { none() }
|
||||
|
||||
/**
|
||||
* Gets an additional term that is added to the `join` and `branch` computations to reflect
|
||||
* an additional forward or backwards branching factor that is not taken into account
|
||||
* when calculating the (virtual) dispatch cost.
|
||||
*
|
||||
* Argument `arg` is part of a path from a source to a sink, and `p` is the target parameter.
|
||||
*/
|
||||
int getAdditionalFlowIntoCallNodeTerm(ArgumentNode arg, ParameterNode p);
|
||||
|
||||
predicate golangSpecificParamArgFilter(DataFlowCall call, ParameterNode p, ArgumentNode arg);
|
||||
}
|
|
@ -6,11 +6,11 @@
|
|||
|
||||
private import codeql.util.Unit
|
||||
private import codeql.util.Option
|
||||
import DataFlowParameter
|
||||
private import codeql.dataflow.DataFlow
|
||||
|
||||
module MakeImpl<DataFlowParameter Lang> {
|
||||
module MakeImpl<InputSig Lang> {
|
||||
private import Lang
|
||||
private import DataFlow::DataFlowMake<Lang>
|
||||
private import DataFlowMake<Lang>
|
||||
private import DataFlowImplCommon::MakeImplCommon<Lang>
|
||||
private import DataFlowImplCommonPublic
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import DataFlowParameter
|
||||
private import codeql.dataflow.DataFlow
|
||||
|
||||
module MakeImplCommon<DataFlowParameter Lang> {
|
||||
module MakeImplCommon<InputSig Lang> {
|
||||
private import Lang
|
||||
import Cached
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImpl
|
||||
private import codeql.dataflow.internal.DataFlowImpl
|
||||
import MakeImpl<SwiftDataFlow>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
private import DataFlowImplSpecific
|
||||
private import codeql.dataflow.DataFlowImplCommon
|
||||
private import codeql.dataflow.internal.DataFlowImplCommon
|
||||
import MakeImplCommon<SwiftDataFlow>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* Provides Swift-specific definitions for use in the data flow library.
|
||||
*/
|
||||
|
||||
private import codeql.dataflow.DataFlowParameter
|
||||
private import codeql.dataflow.DataFlow
|
||||
// we need to export `Unit` for the DataFlowImpl* files
|
||||
private import swift as Swift
|
||||
|
||||
|
@ -15,7 +15,7 @@ module Public {
|
|||
import DataFlowPublic
|
||||
}
|
||||
|
||||
module SwiftDataFlow implements DataFlowParameter {
|
||||
module SwiftDataFlow implements InputSig {
|
||||
import Private
|
||||
import Public
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче