Skip to content

Commit

Permalink
Merge pull request #18392 from asgerf/jss/deprecate-modules
Browse files Browse the repository at this point in the history
JS: Deprecate some .qll files
  • Loading branch information
asgerf authored Jan 8, 2025
2 parents abea019 + 36f0d2f commit b6b93dc
Show file tree
Hide file tree
Showing 9 changed files with 50 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* Alias for the library `semmle.javascript.explore.BackwardDataFlow`.
*/
deprecated module;

import semmle.javascript.explore.BackwardDataFlow
52 changes: 3 additions & 49 deletions javascript/ql/lib/semmle/javascript/dataflow/Configuration.qll
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,15 @@
* Finally, we build `PathNode`s for all nodes that appear on a path
* computed by `onPath`.
*/
deprecated module;

private import javascript
private import internal.FlowSteps
private import internal.AccessPaths
private import semmle.javascript.Unit
private import semmle.javascript.internal.CachedStages
private import AdditionalFlowSteps
private import internal.DataFlowPrivate as DataFlowPrivate

/**
* A data flow tracking configuration for finding inter-procedural paths from
Expand Down Expand Up @@ -1793,39 +1795,7 @@ deprecated class MidPathNode extends PathNode, MkMidNode {
* Holds if this node is hidden from paths in path explanation queries, except
* in cases where it is the source or sink.
*/
predicate isHidden() { PathNode::shouldNodeBeHidden(nd) }
}

/** Companion module to the `PathNode` class. */
module PathNode {
/** Holds if `nd` should be hidden in data flow paths. */
predicate shouldNodeBeHidden(DataFlow::Node nd) {
// TODO: move to DataFlowPrivate
// Skip phi, refinement, and capture nodes
nd.(DataFlow::SsaDefinitionNode).getSsaVariable().getDefinition() instanceof
SsaImplicitDefinition
or
// Skip SSA definition of parameter as its location coincides with the parameter node
nd = DataFlow::ssaDefinitionNode(Ssa::definition(any(SimpleParameter p)))
or
// Skip to the top of big left-leaning string concatenation trees.
nd = any(AddExpr add).flow() and
nd = any(AddExpr add).getAnOperand().flow()
or
// Skip the exceptional return on functions, as this highlights the entire function.
nd = any(DataFlow::FunctionNode f).getExceptionalReturn()
or
// Skip the special return node for functions, as this highlights the entire function (and the returned expr is the previous node).
nd = any(DataFlow::FunctionNode f).getReturnNode()
or
// Skip the synthetic 'this' node, as a ThisExpr will be the next node anyway
nd = DataFlow::thisNode(_)
or
// Skip captured variable nodes as the successor will be a use of that variable anyway.
nd = DataFlow::capturedVariableNode(_)
or
nd instanceof DataFlow::FunctionSelfReferenceNode
}
predicate isHidden() { DataFlowPrivate::nodeIsHidden(nd) }
}

/**
Expand Down Expand Up @@ -2031,22 +2001,6 @@ deprecated private class CallAgainstEqualityCheck extends DerivedBarrierGuardNod
override predicate appliesTo(Configuration cfg) { isBarrierGuardInternal(cfg, prev) }
}

/**
* A guard node for a variable in a negative condition, such as `x` in `if(!x)`.
* Can be added to a `isBarrier` in a data-flow configuration to block flow through such checks.
*/
class VarAccessBarrier extends DataFlow::Node {
// TODO: This does not work in dataflow2 when the variable is captured, since the capture-flow library bypasses the refinement node.
VarAccessBarrier() {
exists(ConditionGuardNode guard, SsaRefinementNode refinement |
this = DataFlow::ssaDefinitionNode(refinement) and
refinement.getGuard() = guard and
guard.getTest() instanceof VarAccess and
guard.getOutcome() = false
)
}
}

/**
* Holds if there is a path without unmatched return steps from `source` to `sink`.
*/
Expand Down
2 changes: 1 addition & 1 deletion javascript/ql/lib/semmle/javascript/dataflow/DataFlow.qll
Original file line number Diff line number Diff line change
Expand Up @@ -1929,7 +1929,7 @@ module DataFlow {
import Nodes
import Sources
import TypeInference
import Configuration
deprecated import Configuration
import TypeTracking
import AdditionalFlowSteps
import internal.FunctionWrapperSteps
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* Alias for the library `semmle.javascript.explore.ForwardDataFlow`.
*/
deprecated module;

import semmle.javascript.explore.ForwardDataFlow
15 changes: 15 additions & 0 deletions javascript/ql/lib/semmle/javascript/dataflow/Nodes.qll
Original file line number Diff line number Diff line change
Expand Up @@ -1708,3 +1708,18 @@ class RegExpCreationNode extends DataFlow::SourceNode {
result = this.getAReference(DataFlow::TypeTracker::end())
}
}

/**
* A guard node for a variable in a negative condition, such as `x` in `if(!x)`.
* Can be added to a `isBarrier` in a data-flow configuration to block flow through such checks.
*/
class VarAccessBarrier extends DataFlow::Node {
VarAccessBarrier() {
exists(ConditionGuardNode guard, SsaRefinementNode refinement |
this = DataFlow::ssaDefinitionNode(refinement) and
refinement.getGuard() = guard and
guard.getTest() instanceof VarAccess and
guard.getOutcome() = false
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,30 @@ DataFlowType getNodeType(Node node) {
}

predicate nodeIsHidden(Node node) {
DataFlow::PathNode::shouldNodeBeHidden(node)
// Skip phi, refinement, and capture nodes
node.(DataFlow::SsaDefinitionNode).getSsaVariable().getDefinition() instanceof
SsaImplicitDefinition
or
// Skip SSA definition of parameter as its location coincides with the parameter node
node = DataFlow::ssaDefinitionNode(Ssa::definition(any(SimpleParameter p)))
or
// Skip to the top of big left-leaning string concatenation trees.
node = any(AddExpr add).flow() and
node = any(AddExpr add).getAnOperand().flow()
or
// Skip the exceptional return on functions, as this highlights the entire function.
node = any(DataFlow::FunctionNode f).getExceptionalReturn()
or
// Skip the special return node for functions, as this highlights the entire function (and the returned expr is the previous node).
node = any(DataFlow::FunctionNode f).getReturnNode()
or
// Skip the synthetic 'this' node, as a ThisExpr will be the next node anyway
node = DataFlow::thisNode(_)
or
// Skip captured variable nodes as the successor will be a use of that variable anyway.
node = DataFlow::capturedVariableNode(_)
or
node instanceof DataFlow::FunctionSelfReferenceNode
or
node instanceof FlowSummaryNode
or
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import javascript
import semmle.javascript.dataflow.Configuration
deprecated import semmle.javascript.dataflow.Configuration
import semmle.javascript.dataflow.internal.CallGraphs
private import semmle.javascript.internal.CachedStages

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
* Backward exploration in particular does not scale on non-trivial code bases and hence is of limited
* usefulness as it stands.
*/
deprecated module;

import javascript

private class BackwardExploringConfiguration extends DataFlow::Configuration {
deprecated private class BackwardExploringConfiguration extends DataFlow::Configuration {
BackwardExploringConfiguration() { this = any(DataFlow::Configuration cfg) }

override predicate isSource(DataFlow::Node node) { any() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
*
* NOTE: This library should only be used for debugging and exploration, not in production code.
*/
deprecated module;

import javascript

private class ForwardExploringConfiguration extends DataFlow::Configuration {
deprecated private class ForwardExploringConfiguration extends DataFlow::Configuration {
ForwardExploringConfiguration() { this = any(DataFlow::Configuration cfg) }

override predicate isSink(DataFlow::Node node) { any() }
Expand Down

0 comments on commit b6b93dc

Please sign in to comment.