renamings - and simplifications of qldoc

This commit is contained in:
Erik Krogh Kristensen
2021-03-10 15:42:50 +01:00
parent d3fca0a107
commit 81efd726cb
19 changed files with 46 additions and 145 deletions

View File

@@ -25,7 +25,6 @@ import semmle.javascript.Errors
import semmle.javascript.ES2015Modules
import semmle.javascript.Expr
import semmle.javascript.Extend
import semmle.javascript.ExtendedStaging
import semmle.javascript.Externs
import semmle.javascript.Files
import semmle.javascript.Functions
@@ -34,6 +33,7 @@ import semmle.javascript.GlobalAccessPaths
import semmle.javascript.HTML
import semmle.javascript.HtmlSanitizers
import semmle.javascript.InclusionTests
import semmle.javascript.internal.CachedStages
import semmle.javascript.JSDoc
import semmle.javascript.JSON
import semmle.javascript.JsonParsers

View File

@@ -299,7 +299,7 @@ private class AmdDependencyImport extends Import {
class AmdModule extends Module {
cached
AmdModule() {
ExtendedStaging::DataFlowStage::ref() and
Stages::DataFlowStage::ref() and
exists(unique(AmdModuleDefinition def | amdModuleTopLevel(def, this)))
}

View File

@@ -75,7 +75,7 @@ class ASTNode extends @ast_node, NodeInStmtContainer {
/** Gets the toplevel syntactic unit to which this element belongs. */
cached
TopLevel getTopLevel() { ExtendedStaging::Ast::ref() and result = getParent().getTopLevel() }
TopLevel getTopLevel() { Stages::Ast::ref() and result = getParent().getTopLevel() }
/**
* Gets the `i`th child node of this node.
@@ -119,7 +119,7 @@ class ASTNode extends @ast_node, NodeInStmtContainer {
/** Gets the parent node of this node, if any. */
cached
ASTNode getParent() { ExtendedStaging::Ast::ref() and this = result.getAChild() }
ASTNode getParent() { Stages::Ast::ref() and this = result.getAChild() }
/** Gets the first control flow node belonging to this syntactic entity. */
ControlFlowNode getFirstControlFlowNode() { result = this }
@@ -135,7 +135,7 @@ class ASTNode extends @ast_node, NodeInStmtContainer {
*/
cached
private predicate isAmbientInternal() {
ExtendedStaging::Ast::ref() and
Stages::Ast::ref() and
getParent().isAmbientInternal()
or
not isAmbientTopLevel(getTopLevel()) and
@@ -188,7 +188,7 @@ class ASTNode extends @ast_node, NodeInStmtContainer {
*/
cached
private predicate isAmbientTopLevel(TopLevel tl) {
ExtendedStaging::Ast::ref() and tl.getFile().getBaseName().matches("%.d.ts")
Stages::Ast::ref() and tl.getFile().getBaseName().matches("%.d.ts")
}
/**

View File

@@ -60,7 +60,7 @@ private module Internal {
cached
predicate useAt(BasicBlock bb, int i, Variable v, VarUse u) {
ExtendedStaging::BasicBlocks::ref() and
Stages::BasicBlocks::ref() and
v = u.getVariable() and
bbIndex(bb, u, i)
}

View File

@@ -109,7 +109,7 @@ class Expr extends @expr, ExprOrStmt, ExprOrType, AST::ValueNode {
/** Gets the constant string value this expression evaluates to, if any. */
cached
string getStringValue() { ExtendedStaging::Ast::ref() and result = getStringValue(this) }
string getStringValue() { Stages::Ast::ref() and result = getStringValue(this) }
/** Holds if this expression is impure, that is, its evaluation could have side effects. */
predicate isImpure() { any() }
@@ -257,7 +257,7 @@ class Expr extends @expr, ExprOrStmt, ExprOrType, AST::ValueNode {
cached
private DataFlow::Node getCatchParameterFromStmt(Stmt stmt) {
ExtendedStaging::DataFlowStage::ref() and
Stages::DataFlowStage::ref() and
result =
DataFlow::parameterNode(stmt.getEnclosingTryCatchStmt().getACatchClause().getAParameter())
}
@@ -808,7 +808,7 @@ class FunctionExpr extends @function_expr, Expr, Function {
override Stmt getEnclosingStmt() { result = Expr.super.getEnclosingStmt() }
override StmtContainer getEnclosingContainer() {
ExtendedStaging::Ast::ref() and result = Expr.super.getContainer()
Stages::Ast::ref() and result = Expr.super.getContainer()
}
override predicate isImpure() { none() }

View File

@@ -539,7 +539,7 @@ module AccessPath {
*/
cached
predicate hasDominatingWrite(DataFlow::PropRead read) {
ExtendedStaging::FlowSteps::ref() and
Stages::FlowSteps::ref() and
// within the same basic block.
exists(ReachableBasicBlock bb, Root root, string path, int ranking |
read.asExpr() = rankedAccessPath(bb, root, path, ranking, AccessPathRead()) and

View File

@@ -58,7 +58,7 @@ abstract class Documentable extends ASTNode {
/** Gets the JSDoc comment for this element, if any. */
cached
JSDoc getDocumentation() {
ExtendedStaging::Ast::ref() and result.getComment().getNextToken() = getFirstToken()
Stages::Ast::ref() and result.getComment().getNextToken() = getFirstToken()
}
}

View File

@@ -239,7 +239,7 @@ abstract class Import extends ASTNode {
*/
cached
Module getImportedModule() {
ExtendedStaging::Imports::ref() and
Stages::Imports::ref() and
if exists(resolveExternsImport())
then result = resolveExternsImport()
else (

View File

@@ -354,7 +354,7 @@ private module Internal {
*/
cached
SsaDefinition getDefReachingEndOf(ReachableBasicBlock bb, SsaSourceVariable v) {
ExtendedStaging::DataFlowStage::ref() and
Stages::DataFlowStage::ref() and
exists(int lastRef | lastRef = max(int i | ssaRef(bb, i, v, _)) |
result = getLocalDefinition(bb, lastRef, v)
or

View File

@@ -733,7 +733,7 @@ private class FlowStepThroughImport extends AdditionalFlowStep, DataFlow::ValueN
override ImportSpecifier astNode;
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
ExtendedStaging::FlowSteps::ref() and
Stages::FlowSteps::ref() and
pred = this and
succ = DataFlow::ssaDefinitionNode(SSA::definition(astNode))
}

View File

@@ -1493,7 +1493,7 @@ module DataFlow {
*/
cached
predicate localFlowStep(Node pred, Node succ) {
ExtendedStaging::DataFlowStage::ref() and
Stages::DataFlowStage::ref() and
// flow from RHS into LHS
lvalueFlowStep(pred, succ)
or

View File

@@ -734,9 +734,7 @@ module ModuleImportNode {
* This predicate can be extended by subclassing `ModuleImportNode::Range`.
*/
cached
ModuleImportNode moduleImport(string path) {
ExtendedStaging::Imports::ref() and result.getPath() = path
}
ModuleImportNode moduleImport(string path) { Stages::Imports::ref() and result.getPath() = path }
/**
* Gets a (default) import of the given dependency `dep`, such as

View File

@@ -220,7 +220,7 @@ private module Cached {
*/
cached
predicate namedPropRef(DataFlow::SourceNode base, string prop, DataFlow::PropRef ref) {
ExtendedStaging::DataFlowStage::ref() and
Stages::DataFlowStage::ref() and
hasLocalSource(ref.getBase(), base) and
ref.getPropertyName() = prop
}

View File

@@ -232,7 +232,7 @@ module TaintTracking {
HeapTaintStep() { heapStep(_, this) }
override predicate step(DataFlow::Node pred, DataFlow::Node succ) {
ExtendedStaging::Taint::ref() and
Stages::Taint::ref() and
heapStep(pred, succ) and
succ = this
}

View File

@@ -378,7 +378,7 @@ private module CachedSteps {
*/
cached
predicate basicLoadStep(DataFlow::Node pred, DataFlow::PropRead succ, string prop) {
ExtendedStaging::TypeTracking::ref() and
Stages::TypeTracking::ref() and
succ.accesses(pred, prop)
}
@@ -404,7 +404,7 @@ private module CachedSteps {
*/
cached
predicate callback(DataFlow::Node arg, DataFlow::SourceNode cb) {
ExtendedStaging::TypeTracking::ref() and
Stages::TypeTracking::ref() and
exists(DataFlow::InvokeNode invk, DataFlow::ParameterNode cbParm, DataFlow::Node cbArg |
arg = invk.getAnArgument() and
cbParm.flowsTo(invk.getCalleeNode()) and

View File

@@ -63,7 +63,7 @@ module PreCallGraphStep {
*/
cached
predicate loadStep(DataFlow::Node pred, DataFlow::Node succ, string prop) {
ExtendedStaging::TypeTracking::ref() and
Stages::TypeTracking::ref() and
any(PreCallGraphStep s).loadStep(pred, succ, prop)
}

View File

@@ -5,60 +5,38 @@
*
* Combining stages can improve performance as we are more likely to reuse shared, non-cached predicates.
*
* A number of stages are grouped into an extended stage.
* An extended stage contains a number of substages - corrosponding to to how the stages would be grouped if this file didn't exist.
* Each extended stage is identified by a `cached module` in the `ExtendedStaging` module.
* To make a predicate `p` belong to a stage `A`:
* - make `p` depend on `A::ref()`, and
* - make `A::backref()` depend on `p`.
*
* To make a predicate `p` belong to a stage `A`:
* - make `p` depend on `A::ref()`, and
* - make `A::backref()` depend on `p`.
*
* Since `A` is a cached module, `ref` and `backref` must be in the same stage, and the dependency
* chain above thus forces `p` to be in that stage as well.
* Since `A` is a cached module, `ref` and `backref` must be in the same stage, and the dependency
* chain above thus forces `p` to be in that stage as well.
*
* With these two predicates in a `cached module` we ensure that all substages will be in a single stage at runtime.
* With these two predicates in a `cached module` we ensure that all the cached predicates will be in a single stage at runtime.
*
* Grouping stages into extended stages can cause unnecessary computation, as a concrete query might not depend on
* all the substages in an extended stage.
* Care should therefore be taken not to group stages into an extended stage, if it is likely that a query only depend
* on some but not all the stages in the extended stage.
* Grouping stages can cause unnecessary computation, as a concrete query might not depend on
* all the cached predicates in a stage.
* Care should therefore be taken not to combine two stages, if it is likely that a query only depend
* on some but not all the cached predicates in the combined stage.
*/
import javascript
private import internal.StmtContainers
private import StmtContainers
private import semmle.javascript.dataflow.internal.PreCallGraphStep
private import semmle.javascript.dataflow.internal.FlowSteps
/**
* Contains a `cached module` for each extended stage.
* Contains a `cached module` for each stage.
* Each `cached module` ensures that predicates that are supposed to be in the same stage, are in the same stage.
*
* Each `cached module` contain two predicates:
* The first, `ref`, always holds, and is referenced from `cached` predicates in each of the substages.
* The second, `backref`, contains references to `cached` predicate from each substage.
* The first, `ref`, always holds, and is referenced from `cached` predicates.
* The second, `backref`, contains references to the same `cached` predicates.
* The `backref` predicate starts with `1 = 1 or` to ensure that the predicate will be optimized down to a constant by the optimizer.
*/
module ExtendedStaging {
module Stages {
/**
* The `ast` extended stage.
* Consists of 7 substages (as of writing this).
*
* substage 1:
* AST::ASTNode::getParent
* substage 2:
* JSDoc::Documentable::getDocumentation
* substage 3:
* StmtContainers::getStmtContainer
* substage 4:
* AST::StmtContainer::getEnclosingContainer
* substage 5:
* AST::ASTNode::getTopLevel
* substage 6:
* AST::isAmbientTopLevel
* substage 7:
* Expr::Expr::getStringValue // maybe doesn't belong here?
* substage 8:
* AST::ASTNode::isAmbientInternal
* The `ast` stage.
*/
cached
module Ast {
@@ -94,17 +72,7 @@ module ExtendedStaging {
}
/**
* The `basicblocks` extended stage.
* Consists of 2 substages (as of writing this).
*
* substage 1:
* BasicBlocks::Internal::bbLength#ff
* BasicBlocks::Internal::useAt#ffff
* BasicBlocks::Internal::defAt#ffff
* BasicBlocks::Internal::reachableBB#f
* BasicBlocks::Internal::bbIndex#fff
* substage 2:
* BasicBlocks::bbIDominates#ff
* The `basicblocks` stage.
*/
cached
module BasicBlocks {
@@ -130,27 +98,7 @@ module ExtendedStaging {
}
/**
* The `dataflow` extended stage.
* Consists of 6 substages (as of writing this).
*
* substage 1:
* SSA::Internal
* substage 2:
* All the constructors in DataFlowNode.qll
* substage 3:
* AMD::AmdModule
* substage 4:
* DataFlow::DataFlow::localFlowStep
* substage 5:
* Sources::Cached::isSyntacticMethodCall
* NodeJS::isRequire
* Sources::Cached::dynamicPropRef
* Sources::Cached::hasLocalSource
* Sources::Cached::invocation
* Sources::Cached::namedPropRef
* Sources::SourceNode::Range
* substage 6:
* Expr::getCatchParameterFromStmt // maybe doesn't belong here?
* The `dataflow` stage.
*/
cached
module DataFlowStage {
@@ -182,15 +130,7 @@ module ExtendedStaging {
}
/**
* The `imports` extended stage.
* Consists of 2 substages (as of writing this).
*
* substage 1:
* Modules::Import::getImportedModule
* substage 2:
* Nodes::moduleImport
*
* Implemented as a cached module as there is a negative dependency between the predicates.
* The `imports` stage.
*
* It would have been preferable to include these predicates in the dataflow or typetracking stage.
* But that trips the BDD limit.
@@ -219,27 +159,7 @@ module ExtendedStaging {
}
/**
* The `typetracking` extended stage.
* Consists of 2 substages (as of writing this).
*
* substage 1:
* PreCallGraphStep::PreCallGraphStep::loadStep
* substage 2:
* PreCallGraphStep::PreCallGraphStep::loadStoreStep
* PreCallGraphStep::PreCallGraphStep::storeStep
* PreCallGraphStep::PreCallGraphStep::step
* FlowSteps::CachedSteps
* CallGraphs::CallGraph
* Nodes::ClassNode::getAClassReference
* JSDoc::JSDocNamedTypeExpr::resolvedName
* TypeTracking::TypeTracker::append
* StepSummary::StepSummary::step
* Modules::Module::getAnExportedValue
* DataFlow::DataFlow::Node::getImmediatePredecessor
* VariableTypeInference::clobberedProp
* TypeInference::AnalyzedNode::getAValue
* GlobalAccessPaths::AccessPath::fromReference
* GlobalAccessPaths::AccessPath::fromRhs
* The `typetracking` stage.
*/
cached
module TypeTracking {
@@ -265,16 +185,7 @@ module ExtendedStaging {
}
/**
* The `flowsteps` extended stage.
* Consists of 2 substages (as of writing this).
*
* substage 1:
* Configuration::AdditionalFlowStep::loadStoreStep
* Configuration::AdditionalFlowStep::step
* Configuration::AdditionalFlowStep::storeStep
* Configuration::AdditionalFlowStep::loadStep
* substage 2:
* GlobalAccessPaths::AccessPath::DominatingPaths::hasDominatingWrite
* The `flowsteps` stage.
*/
cached
module FlowSteps {
@@ -300,13 +211,7 @@ module ExtendedStaging {
}
/**
* The `taint` extended stage.
* Consists of 2 substages (as of writing this).
*
* substage 1:
* TaintTracking::TaintTracking::AdditionalTaintStep::step
* substage 2:
* RemoteFlowSources::RemoteFlowSource
* The `taint` stage.
*/
cached
module Taint {

View File

@@ -9,7 +9,7 @@ private import javascript
cached
private StmtContainer getStmtContainer(NodeInStmtContainer node) {
ExtendedStaging::Ast::ref() and
Stages::Ast::ref() and
expr_containers(node, result)
or
stmt_containers(node, result)

View File

@@ -110,9 +110,7 @@ private class ExternalRemoteFlowSourceSpecEntryPoint extends API::EntryPoint {
private class ExternalRemoteFlowSource extends RemoteFlowSource {
RemoteFlowSourceAccessPath ap;
ExternalRemoteFlowSource() {
ExtendedStaging::Taint::ref() and this = ap.resolve().getAnImmediateUse()
}
ExternalRemoteFlowSource() { Stages::Taint::ref() and this = ap.resolve().getAnImmediateUse() }
override string getSourceType() { result = ap.getSourceType() }
}