Remove unused code

This commit is contained in:
Asger F
2024-06-26 13:48:51 +02:00
parent e67e89dd70
commit fc7c2c5b17

View File

@@ -5,113 +5,19 @@
private import javascript
private import semmle.javascript.dataflow.internal.DataFlowPrivate
private import semmle.javascript.dataflow.internal.Contents::Private
private import semmle.javascript.dataflow.FlowSummary as FlowSummary
private import sharedlib.DataFlowImplCommon
private import sharedlib.FlowSummaryImpl::Private as Private
private import sharedlib.FlowSummaryImpl::Public
private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax
private class Node = DataFlow::Node;
/**
* A class of callables that are candidates for flow summary modeling.
*/
class SummarizedCallableBase = string;
/**
* A class of callables that are candidates for neutral modeling.
*/
class NeutralCallableBase = string;
/**
* Holds if a neutral model exists for `c` of kind `kind` and with provenance `provenance`.
* Note: Neutral models have not been implemented for Javascript.
*/
predicate neutralElement(NeutralCallableBase c, string kind, string provenance) { none() }
DataFlowCallable inject(SummarizedCallable c) { result.asLibraryCallable() = c }
/** Gets the parameter position representing a callback itself, if any. */
ArgumentPosition callbackSelfParameterPosition() { result.isFunctionSelfReference() }
/** Gets the synthesized data-flow call for `receiver`. */
SummaryCall summaryDataFlowCall(Private::SummaryNode receiver) { receiver = result.getReceiver() }
/** Gets the type of content `c`. */
DataFlowType getContentType(ContentSet c) { result = TAnyType() and exists(c) }
/** Gets the type of the parameter at the given position. */
bindingset[c, pos]
DataFlowType getParameterType(SummarizedCallable c, ParameterPosition pos) {
// TODO: we could assign a more precise type to the function self-reference parameter
result = TAnyType() and exists(c) and exists(pos)
}
/** Gets the return type of kind `rk` for callable `c`. */
bindingset[c, rk]
DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) {
result = TAnyType() and exists(c) and exists(rk)
}
/**
* Gets the type of the `i`th parameter in a synthesized call that targets a
* callback of type `t`.
*/
bindingset[t, pos]
DataFlowType getCallbackParameterType(DataFlowType t, ArgumentPosition pos) {
result = TAnyType() and exists(t) and exists(pos)
}
/**
* Gets the return type of kind `rk` in a synthesized call that targets a
* callback of type `t`.
*/
DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) {
result = TAnyType() and exists(t) and exists(rk)
}
/**
* Holds if an external flow summary exists for `c` with input specification
* `input`, output specification `output`, kind `kind`, and provenance `provenance`.
*/
predicate summaryElement(
FlowSummary::SummarizedCallable c, string input, string output, string kind, string provenance
) {
exists(boolean preservesValue |
c.propagatesFlowExt(input, output, preservesValue) and
(if preservesValue = true then kind = "value" else kind = "taint") and
provenance = "manual"
)
}
/**
* Holds if a neutral summary model exists for `c` with provenance `provenance`,
* which means that there is no flow through `c`.
* Note. Neutral models have not been implemented for JS.
*/
predicate neutralSummaryElement(FlowSummary::SummarizedCallable c, string provenance) { none() }
pragma[inline]
private Private::SummaryComponent makeContentComponents(
Private::AccessPathToken token, string name, ContentSet contents
) {
token.getName() = name and
result = Private::SummaryComponent::content(contents)
or
token.getName() = "With" + name and
result = Private::SummaryComponent::withContent(contents)
or
token.getName() = "Without" + name and
result = Private::SummaryComponent::withoutContent(contents)
}
pragma[inline]
private Private::SummaryComponent makePropertyContentComponents(
Private::AccessPathToken token, string name, PropertyName content
) {
result = makeContentComponents(token, name, ContentSet::property(content))
}
/**
* Gets the content set corresponding to `Awaited[arg]`.
*/
@@ -145,82 +51,6 @@ private predicate desugaredPositionName(ParameterPosition pos, string operand) {
pos.asPositional() = AccessPathSyntax::parseInt(operand) // parse closed intervals
}
bindingset[operand]
private ParameterPosition parsePosition(string operand) {
positionName(result, operand) or desugaredPositionName(result, operand)
}
/**
* Gets the summary component for specification component `c`, if any.
*
* This covers all the JS-specific components of a flow summary.
*/
Private::SummaryComponent interpretComponentSpecific(Private::AccessPathToken c) {
c.getName() = "Argument" and
result = Private::SummaryComponent::argument(parsePosition(c.getAnArgument()))
or
c.getName() = "Parameter" and
result = Private::SummaryComponent::parameter(parsePosition(c.getAnArgument()))
or
result = makePropertyContentComponents(c, "Member", c.getAnArgument())
or
result = makeContentComponents(c, "Awaited", getPromiseContent(c.getAnArgument()))
or
c.getNumArgument() = 0 and
result = makeContentComponents(c, "ArrayElement", ContentSet::arrayElement())
or
c.getAnArgument() = "?" and
result = makeContentComponents(c, "ArrayElement", ContentSet::arrayElementUnknown())
or
exists(int n |
n = c.getAnArgument().toInt() and
result = makeContentComponents(c, "ArrayElement", ContentSet::arrayElementKnown(n))
or
// ArrayElement[n!] refers to index n, and never the unknown content
c.getAnArgument().regexpCapture("(\\d+)!", 1).toInt() = n and
result = makePropertyContentComponents(c, "ArrayElement", n.toString())
or
// ArrayElement[n..] refers to index n or greater
n = AccessPathSyntax::parseLowerBound(c.getAnArgument()) and
result = makeContentComponents(c, "ArrayElement", ContentSet::arrayElementLowerBoundFromInt(n))
)
or
c.getNumArgument() = 0 and
result = makeContentComponents(c, "SetElement", ContentSet::setElement())
or
c.getNumArgument() = 0 and
result = makeContentComponents(c, "IteratorElement", ContentSet::iteratorElement())
or
c.getNumArgument() = 0 and
result = makeContentComponents(c, "IteratorError", ContentSet::iteratorError())
or
c.getNumArgument() = 0 and
result = makeContentComponents(c, "MapKey", ContentSet::mapKey())
or
//
// Note: although it is supported internally, we currently do not expose a syntax for MapValue with a known key
//
c.getNumArgument() = 0 and
result = makeContentComponents(c, "MapValue", ContentSet::mapValueAll())
or
c.getName() = "ReturnValue" and
c.getAnArgument() = "exception" and
result = Private::SummaryComponent::return(MkExceptionalReturnKind())
or
// Awaited is mapped down to a combination steps that handle coercion and promise-flattening.
c.getName() = "Awaited" and
c.getNumArgument() = 0 and
result = Private::SummaryComponent::content(MkAwaited())
or
c.getName() = "AnyMemberDeep" and
c.getNumArgument() = 0 and
result = Private::SummaryComponent::content(MkAnyPropertyDeep())
or
c.getName() = "ArrayElementDeep" and
c.getNumArgument() = 0 and
result = Private::SummaryComponent::content(MkArrayElementDeep())
}
private string encodeContentAux(ContentSet cs, string arg) {
cs = ContentSet::arrayElement() and
result = "ArrayElement" and
@@ -296,78 +126,9 @@ string encodeArgumentPosition(ArgumentPosition pos) {
/** Gets the return kind corresponding to specification `"ReturnValue"`. */
ReturnKind getStandardReturnValueKind() { result = MkNormalReturnKind() }
/** Holds if input specification component `c` needs a reference. */
predicate inputNeedsReferenceSpecific(string c) { none() }
/** Holds if output specification component `c` needs a reference. */
predicate outputNeedsReferenceSpecific(string c) { none() }
/** Gets the return kind corresponding to specification `"ReturnValue"`. */
MkNormalReturnKind getReturnValueKind() { any() }
/**
* All definitions in this module are required by the shared implementation
* (for source/sink interpretation), but they are unused for JS, where
* we rely on API graphs instead.
*/
private module UnusedSourceSinkInterpretation {
/**
* Holds if an external source specification exists for `n` with output specification
* `output`, kind `kind`, and provenance `provenance`.
*/
predicate sourceElement(AstNode n, string output, string kind, string provenance) { none() }
/**
* Holds if an external sink specification exists for `n` with input specification
* `input`, kind `kind` and provenance `provenance`.
*/
predicate sinkElement(AstNode n, string input, string kind, string provenance) { none() }
class SourceOrSinkElement = AstNode;
/** An entity used to interpret a source/sink specification. */
class InterpretNode extends AstNode {
/** Gets the element that this node corresponds to, if any. */
SourceOrSinkElement asElement() { none() }
/** Gets the data-flow node that this node corresponds to, if any. */
Node asNode() { none() }
/** Gets the call that this node corresponds to, if any. */
DataFlowCall asCall() { none() }
/** Gets the callable that this node corresponds to, if any. */
DataFlowCallable asCallable() { none() }
/** Gets the target of this call, if any. */
StmtContainer getCallTarget() { none() }
}
/** Provides additional sink specification logic. */
predicate interpretOutputSpecific(string c, InterpretNode mid, InterpretNode node) { none() }
/** Provides additional source specification logic. */
predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode node) { none() }
}
import UnusedSourceSinkInterpretation
/** Gets the argument position obtained by parsing `X` in `Parameter[X]`. */
bindingset[s]
ArgumentPosition parseParamBody(string s) {
s = "this" and result.isThis()
or
s = "function" and result.isFunctionSelfReference()
or
result.asPositional() = AccessPathSyntax::parseInt(s)
}
/** Gets the parameter position obtained by parsing `X` in `Argument[X]`. */
bindingset[s]
ParameterPosition parseArgBody(string s) {
result = parseParamBody(s) // Currently these are identical
}
private module FlowSummaryStepInput implements Private::StepsInputSig {
DataFlowCall getACall(SummarizedCallable sc) {
exists(LibraryCallable callable | callable = sc |