mirror of
https://github.com/github/codeql.git
synced 2025-12-23 04:06:37 +01:00
cached stages iteration 2
This commit is contained in:
@@ -9,6 +9,7 @@
|
|||||||
// Importing python under the `py` namespace to avoid importing `CallNode` from `Flow.qll` and thereby having a naming conflict with `API::CallNode`.
|
// Importing python under the `py` namespace to avoid importing `CallNode` from `Flow.qll` and thereby having a naming conflict with `API::CallNode`.
|
||||||
private import python as py
|
private import python as py
|
||||||
import semmle.python.dataflow.new.DataFlow
|
import semmle.python.dataflow.new.DataFlow
|
||||||
|
private import semmle.python.internal.CachedStages
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides classes and predicates for working with APIs used in a database.
|
* Provides classes and predicates for working with APIs used in a database.
|
||||||
@@ -683,6 +684,7 @@ module API {
|
|||||||
*/
|
*/
|
||||||
cached
|
cached
|
||||||
DataFlow::LocalSourceNode trackUseNode(DataFlow::LocalSourceNode src) {
|
DataFlow::LocalSourceNode trackUseNode(DataFlow::LocalSourceNode src) {
|
||||||
|
Stages::TypeTracking::ref() and
|
||||||
result = trackUseNode(src, DataFlow::TypeTracker::end()) and
|
result = trackUseNode(src, DataFlow::TypeTracker::end()) and
|
||||||
not result instanceof DataFlow::ModuleVariableNode
|
not result instanceof DataFlow::ModuleVariableNode
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import python
|
import python
|
||||||
|
private import semmle.python.internal.CachedStages
|
||||||
|
|
||||||
/** A syntactic node (Class, Function, Module, Expr, Stmt or Comprehension) corresponding to a flow node */
|
/** A syntactic node (Class, Function, Module, Expr, Stmt or Comprehension) corresponding to a flow node */
|
||||||
abstract class AstNode extends AstNode_ {
|
abstract class AstNode extends AstNode_ {
|
||||||
@@ -20,6 +21,7 @@ abstract class AstNode extends AstNode_ {
|
|||||||
ControlFlowNode getAFlowNode() { py_flow_bb_node(result, this, _, _) }
|
ControlFlowNode getAFlowNode() { py_flow_bb_node(result, this, _, _) }
|
||||||
|
|
||||||
/** Gets the location for this AST node */
|
/** Gets the location for this AST node */
|
||||||
|
cached
|
||||||
Location getLocation() { none() }
|
Location getLocation() { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,7 +108,10 @@ class Comprehension extends Comprehension_, AstNode {
|
|||||||
|
|
||||||
override string toString() { result = "Comprehension" }
|
override string toString() { result = "Comprehension" }
|
||||||
|
|
||||||
override Location getLocation() { result = Comprehension_.super.getLocation() }
|
override Location getLocation() {
|
||||||
|
Stages::SSA::ref() and
|
||||||
|
result = Comprehension_.super.getLocation()
|
||||||
|
}
|
||||||
|
|
||||||
override AstNode getAChildNode() { result = this.getASubExpression() }
|
override AstNode getAChildNode() { result = this.getASubExpression() }
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import python
|
import python
|
||||||
private import semmle.python.pointsto.PointsTo
|
private import semmle.python.pointsto.PointsTo
|
||||||
private import semmle.python.objects.ObjectInternal
|
private import semmle.python.objects.ObjectInternal
|
||||||
|
private import semmle.python.internal.CachedStages
|
||||||
|
|
||||||
/** An expression */
|
/** An expression */
|
||||||
class Expr extends Expr_, AstNode {
|
class Expr extends Expr_, AstNode {
|
||||||
@@ -8,7 +9,11 @@ class Expr extends Expr_, AstNode {
|
|||||||
override Scope getScope() { py_scopes(this, result) }
|
override Scope getScope() { py_scopes(this, result) }
|
||||||
|
|
||||||
/** Gets a textual representation of this element. */
|
/** Gets a textual representation of this element. */
|
||||||
override string toString() { result = "Expression" }
|
cached
|
||||||
|
override string toString() {
|
||||||
|
Stages::SSA::ref() and
|
||||||
|
result = "Expression"
|
||||||
|
}
|
||||||
|
|
||||||
/** Gets the module in which this expression occurs */
|
/** Gets the module in which this expression occurs */
|
||||||
Module getEnclosingModule() { result = this.getScope().getEnclosingModule() }
|
Module getEnclosingModule() { result = this.getScope().getEnclosingModule() }
|
||||||
|
|||||||
@@ -1001,12 +1001,16 @@ class BasicBlock extends @py_flow_node {
|
|||||||
string toString() { result = "BasicBlock" }
|
string toString() { result = "BasicBlock" }
|
||||||
|
|
||||||
/** Whether this basic block strictly dominates the other */
|
/** Whether this basic block strictly dominates the other */
|
||||||
pragma[nomagic]
|
cached
|
||||||
predicate strictlyDominates(BasicBlock other) { other.getImmediateDominator+() = this }
|
predicate strictlyDominates(BasicBlock other) {
|
||||||
|
Stages::SSA::ref() and
|
||||||
|
other.getImmediateDominator+() = this
|
||||||
|
}
|
||||||
|
|
||||||
/** Whether this basic block dominates the other */
|
/** Whether this basic block dominates the other */
|
||||||
pragma[nomagic]
|
cached
|
||||||
predicate dominates(BasicBlock other) {
|
predicate dominates(BasicBlock other) {
|
||||||
|
Stages::SSA::ref() and
|
||||||
this = other
|
this = other
|
||||||
or
|
or
|
||||||
this.strictlyDominates(other)
|
this.strictlyDominates(other)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import python
|
import python
|
||||||
private import semmle.python.objects.ObjectAPI
|
private import semmle.python.objects.ObjectAPI
|
||||||
private import semmle.python.objects.Modules
|
private import semmle.python.objects.Modules
|
||||||
|
private import semmle.python.internal.CachedStages
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A module. This is the top level element in an AST, corresponding to a source file.
|
* A module. This is the top level element in an AST, corresponding to a source file.
|
||||||
@@ -221,7 +222,9 @@ private predicate transitively_imported_from_entry_point(File file) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cached
|
||||||
string moduleNameFromFile(Container file) {
|
string moduleNameFromFile(Container file) {
|
||||||
|
Stages::SSA::ref() and
|
||||||
exists(string basename |
|
exists(string basename |
|
||||||
basename = moduleNameFromBase(file) and
|
basename = moduleNameFromBase(file) and
|
||||||
legalShortName(basename)
|
legalShortName(basename)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/** Step Summaries and Type Tracking */
|
/** Step Summaries and Type Tracking */
|
||||||
|
|
||||||
private import TypeTrackerSpecific
|
private import TypeTrackerSpecific
|
||||||
|
private import semmle.python.internal.CachedStages
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A string that may appear as the name of a piece of content. This will usually include things like:
|
* A string that may appear as the name of a piece of content. This will usually include things like:
|
||||||
@@ -40,6 +41,7 @@ private module Cached {
|
|||||||
/** Gets the summary resulting from appending `step` to type-tracking summary `tt`. */
|
/** Gets the summary resulting from appending `step` to type-tracking summary `tt`. */
|
||||||
cached
|
cached
|
||||||
TypeTracker append(TypeTracker tt, StepSummary step) {
|
TypeTracker append(TypeTracker tt, StepSummary step) {
|
||||||
|
Stages::TypeTracking::ref() and
|
||||||
exists(Boolean hasCall, OptionalContentName content | tt = MkTypeTracker(hasCall, content) |
|
exists(Boolean hasCall, OptionalContentName content | tt = MkTypeTracker(hasCall, content) |
|
||||||
step = LevelStep() and result = tt
|
step = LevelStep() and result = tt
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ module Stages {
|
|||||||
*/
|
*/
|
||||||
cached
|
cached
|
||||||
module SSA {
|
module SSA {
|
||||||
|
// TODO: This is more a "basic AST", not a "SSA" stage.
|
||||||
/**
|
/**
|
||||||
* Always holds.
|
* Always holds.
|
||||||
* Ensures that a predicate is evaluated as part of the Ast stage.
|
* Ensures that a predicate is evaluated as part of the Ast stage.
|
||||||
@@ -47,6 +48,10 @@ module Stages {
|
|||||||
private import semmle.python.essa.SsaDefinitions as SsaDefinitions
|
private import semmle.python.essa.SsaDefinitions as SsaDefinitions
|
||||||
private import semmle.python.essa.SsaCompute as SsaCompute
|
private import semmle.python.essa.SsaCompute as SsaCompute
|
||||||
private import semmle.python.essa.Essa as Essa
|
private import semmle.python.essa.Essa as Essa
|
||||||
|
private import semmle.python.Module as PyModule
|
||||||
|
private import semmle.python.Exprs as Exprs
|
||||||
|
private import semmle.python.AstExtended as AstExtended
|
||||||
|
private import semmle.python.Flow as PyFlow
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DONT USE!
|
* DONT USE!
|
||||||
@@ -61,6 +66,47 @@ module Stages {
|
|||||||
SsaCompute::SsaDefinitions::reachesEndOfBlock(_, _, _, _)
|
SsaCompute::SsaDefinitions::reachesEndOfBlock(_, _, _, _)
|
||||||
or
|
or
|
||||||
exists(any(Essa::PhiFunction p).getInput(_))
|
exists(any(Essa::PhiFunction p).getInput(_))
|
||||||
|
or
|
||||||
|
exists(PyModule::moduleNameFromFile(_))
|
||||||
|
or
|
||||||
|
exists(any(Exprs::Expr e).toString())
|
||||||
|
or
|
||||||
|
exists(any(AstExtended::AstNode n).getLocation())
|
||||||
|
or
|
||||||
|
exists(any(PyFlow::BasicBlock b).getImmediateDominator())
|
||||||
|
or
|
||||||
|
any(PyFlow::BasicBlock b).strictlyDominates(_)
|
||||||
|
or
|
||||||
|
any(PyFlow::BasicBlock b).dominates(_)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `TypeTracking` stage.
|
||||||
|
*/
|
||||||
|
cached
|
||||||
|
module TypeTracking {
|
||||||
|
/**
|
||||||
|
* Always holds.
|
||||||
|
* Ensures that a predicate is evaluated as part of the Ast stage.
|
||||||
|
*/
|
||||||
|
cached
|
||||||
|
predicate ref() { 1 = 1 }
|
||||||
|
|
||||||
|
private import semmle.python.dataflow.new.DataFlow::DataFlow as NewDataFlow
|
||||||
|
private import semmle.python.ApiGraphs::API as API
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DONT USE!
|
||||||
|
* Contains references to each predicate that use the above `ref` predicate.
|
||||||
|
*/
|
||||||
|
cached
|
||||||
|
predicate backref() {
|
||||||
|
1 = 1
|
||||||
|
or
|
||||||
|
exists(any(NewDataFlow::TypeTracker t).append(_))
|
||||||
|
or
|
||||||
|
exists(any(API::Node n).getAMember().getAUse())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,6 +129,7 @@ module Stages {
|
|||||||
private import semmle.python.types.Object as TypeObject
|
private import semmle.python.types.Object as TypeObject
|
||||||
private import semmle.python.objects.TObject as TObject
|
private import semmle.python.objects.TObject as TObject
|
||||||
private import semmle.python.Flow as Flow
|
private import semmle.python.Flow as Flow
|
||||||
|
private import semmle.python.objects.ObjectInternal as ObjectInternal
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DONT USE!
|
* DONT USE!
|
||||||
@@ -107,6 +154,8 @@ module Stages {
|
|||||||
exists(TObject::TObject f)
|
exists(TObject::TObject f)
|
||||||
or
|
or
|
||||||
exists(any(Flow::ControlFlowNode c).toString())
|
exists(any(Flow::ControlFlowNode c).toString())
|
||||||
|
or
|
||||||
|
exists(any(ObjectInternal::ObjectInternal o).toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,9 +15,11 @@ import semmle.python.objects.Callables
|
|||||||
import semmle.python.objects.Constants
|
import semmle.python.objects.Constants
|
||||||
import semmle.python.objects.Sequences
|
import semmle.python.objects.Sequences
|
||||||
import semmle.python.objects.Descriptors
|
import semmle.python.objects.Descriptors
|
||||||
|
private import semmle.python.internal.CachedStages
|
||||||
|
|
||||||
class ObjectInternal extends TObject {
|
class ObjectInternal extends TObject {
|
||||||
/** Gets a textual representation of this element. */
|
/** Gets a textual representation of this element. */
|
||||||
|
cached
|
||||||
abstract string toString();
|
abstract string toString();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -213,7 +215,10 @@ class ObjectInternal extends TObject {
|
|||||||
class BuiltinOpaqueObjectInternal extends ObjectInternal, TBuiltinOpaqueObject {
|
class BuiltinOpaqueObjectInternal extends ObjectInternal, TBuiltinOpaqueObject {
|
||||||
override Builtin getBuiltin() { this = TBuiltinOpaqueObject(result) }
|
override Builtin getBuiltin() { this = TBuiltinOpaqueObject(result) }
|
||||||
|
|
||||||
override string toString() { result = this.getBuiltin().getClass().getName() + " object" }
|
override string toString() {
|
||||||
|
Stages::DataFlow::ref() and
|
||||||
|
result = this.getBuiltin().getClass().getName() + " object"
|
||||||
|
}
|
||||||
|
|
||||||
override boolean booleanValue() {
|
override boolean booleanValue() {
|
||||||
// TO DO ... Depends on class. `result = this.getClass().instancesBooleanValue()`
|
// TO DO ... Depends on class. `result = this.getClass().instancesBooleanValue()`
|
||||||
|
|||||||
Reference in New Issue
Block a user