JS: Add TypeModel.isTypeUsed

f
This commit is contained in:
Asger F
2023-09-01 13:44:09 +02:00
parent 358c7410c8
commit 43abc72780
2 changed files with 25 additions and 1 deletions

View File

@@ -5,6 +5,7 @@
*/
private import javascript
private import semmle.javascript.frameworks.data.ModelsAsData
/**
* The raw data type underlying `DataFlow::Node`.
@@ -33,4 +34,10 @@ newtype TNode =
TExceptionalInvocationReturnNode(InvokeExpr e) or
TGlobalAccessPathRoot() or
TTemplatePlaceholderTag(Templating::TemplatePlaceholderTag tag) or
TReflectiveParametersNode(Function f)
TReflectiveParametersNode(Function f) or
TForbiddenRecursionGuard() {
none() and
// We want to prune irrelevant models before materialising data flow nodes, so types contributed
// directly from CodeQL must expose their pruning info without depending on data flow nodes.
(any(ModelInput::TypeModel tm).isTypeUsed("") implies any())
}

View File

@@ -168,9 +168,20 @@ module ModelInput {
* A unit class for adding additional type model rows from CodeQL models.
*/
class TypeModel extends Unit {
/**
* Holds if any of the other predicates in this class might have a result
* for the given `type`.
*
* The implementation of this predicate should not depend on `DataFlow::Node`.
*/
bindingset[type]
predicate isTypeUsed(string type) { none() }
/**
* Gets a data-flow node that is a source of the given `type`.
*
* Note that `type` should also be included in `isTypeUsed`.
*
* This must not depend on API graphs, but ensures that an API node is generated for
* the source.
*/
@@ -180,6 +191,8 @@ module ModelInput {
* Gets a data-flow node that is a sink of the given `type`,
* usually because it is an argument passed to a parameter of that type.
*
* Note that `type` should also be included in `isTypeUsed`.
*
* This must not depend on API graphs, but ensures that an API node is generated for
* the sink.
*/
@@ -188,6 +201,8 @@ module ModelInput {
/**
* Gets an API node that is a source or sink of the given `type`.
*
* Note that `type` should also be included in `isTypeUsed`.
*
* Unlike `getASource` and `getASink`, this may depend on API graphs.
*/
API::Node getAnApiNode(string type) { none() }
@@ -367,6 +382,8 @@ predicate isRelevantType(string type) {
(
Specific::isTypeUsed(type)
or
any(TypeModel model).isTypeUsed(type)
or
exists(TestAllModels t)
)
or