mirror of
https://github.com/github/codeql.git
synced 2026-04-26 17:25:19 +02:00
JavaScript: Factor out MidPathNode into its own class.
This commit is contained in:
@@ -20,11 +20,11 @@ where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
p1 = source.getNode().(PortalExitSource).getPortal() and
|
||||
p2 = sink.getNode().(PortalEntrySink).getPortal() and
|
||||
lbl1 = sink.getPathSummary().getStartLabel() and
|
||||
lbl2 = sink.getPathSummary().getEndLabel() and
|
||||
lbl1 = sink.(DataFlow::MidPathNode).getPathSummary().getStartLabel() and
|
||||
lbl2 = sink.(DataFlow::MidPathNode).getPathSummary().getEndLabel() and
|
||||
// avoid constructing infeasible paths
|
||||
sink.getPathSummary().hasCall() = false and
|
||||
sink.getPathSummary().hasReturn() = false and
|
||||
sink.(DataFlow::MidPathNode).getPathSummary().hasCall() = false and
|
||||
sink.(DataFlow::MidPathNode).getPathSummary().hasReturn() = false and
|
||||
// restrict to steps flow function parameters to returns
|
||||
p1.(ParameterPortal).getBasePortal() = p2.(ReturnPortal).getBasePortal() and
|
||||
// restrict to data/taint flow
|
||||
|
||||
@@ -16,5 +16,5 @@ where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
p = source.getNode().(PortalExitSource).getPortal() and
|
||||
// avoid constructing infeasible paths
|
||||
sink.getPathSummary().hasReturn() = false
|
||||
select p.toString(), source.getPathSummary().getStartLabel().toString(), cfg.toString()
|
||||
sink.(DataFlow::MidPathNode).getPathSummary().hasReturn() = false
|
||||
select p.toString(), source.(DataFlow::MidPathNode).getPathSummary().getStartLabel().toString(), cfg.toString()
|
||||
|
||||
@@ -16,5 +16,5 @@ where
|
||||
cfg.hasFlowPath(source, sink) and
|
||||
p = sink.getNode().(PortalEntrySink).getPortal() and
|
||||
// avoid constructing infeasible paths
|
||||
sink.getPathSummary().hasCall() = false
|
||||
select p.toString(), sink.getPathSummary().getEndLabel().toString(), cfg.toString()
|
||||
sink.(DataFlow::MidPathNode).getPathSummary().hasCall() = false
|
||||
select p.toString(), sink.(DataFlow::MidPathNode).getPathSummary().getEndLabel().toString(), cfg.toString()
|
||||
|
||||
@@ -966,25 +966,20 @@ private DataFlow::Configuration id(DataFlow::Configuration cfg) { result >= cfg
|
||||
*/
|
||||
class PathNode extends TPathNode {
|
||||
DataFlow::Node nd;
|
||||
DataFlow::Configuration cfg;
|
||||
PathSummary summary;
|
||||
Configuration cfg;
|
||||
|
||||
PathNode() { this = MkMidNode(nd, cfg, summary) }
|
||||
|
||||
/** Gets the underlying data flow node of this path node. */
|
||||
DataFlow::Node getNode() { result = nd }
|
||||
|
||||
/** Gets the underlying data flow tracking configuration of this path node. */
|
||||
DataFlow::Configuration getConfiguration() { result = cfg }
|
||||
|
||||
/** Gets the summary of the path underlying this path node. */
|
||||
PathSummary getPathSummary() { result = summary }
|
||||
PathNode() {
|
||||
this = MkMidNode(nd, cfg, _)
|
||||
}
|
||||
|
||||
/** Holds if this path node wraps data-flow node `nd` and configuration `c`. */
|
||||
predicate wraps(DataFlow::Node n, DataFlow::Configuration c) {
|
||||
nd = n and cfg = c
|
||||
}
|
||||
|
||||
/** Gets the underlying data-flow node of this path node. */
|
||||
DataFlow::Node getNode() { result = nd }
|
||||
|
||||
/** Gets a successor node of this path node. */
|
||||
final PathNode getASuccessor() {
|
||||
result = getASuccessor(this)
|
||||
@@ -1005,6 +1000,40 @@ class PathNode extends TPathNode {
|
||||
) {
|
||||
nd.hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
|
||||
private PathNode getASuccessor(PathNode pnd) {
|
||||
exists(DataFlow::Node nd, Configuration cfg, PathSummary summary |
|
||||
pnd = MkMidNode(nd, cfg, summary) and
|
||||
exists(DataFlow::Node succ, PathSummary newSummary |
|
||||
flowStep(nd, id(cfg), succ, newSummary) and
|
||||
result = MkMidNode(succ, id(cfg), summary.append(newSummary))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private PathNode getASuccessorIfHidden(PathNode nd) {
|
||||
nd.(MidPathNode).isHidden() and
|
||||
result = getASuccessor(nd)
|
||||
}
|
||||
|
||||
/**
|
||||
* A path node corresponding to an intermediate node on a path from a source to a sink.
|
||||
*
|
||||
* A mid node is a triple `(nd, cfg, summary)` where `nd` is a data-flow node and `cfg`
|
||||
* is a configuration such that `nd` is on a path from a source to a sink under `cfg`
|
||||
* summarized by `summary`.
|
||||
*/
|
||||
class MidPathNode extends PathNode, MkMidNode {
|
||||
PathSummary summary;
|
||||
|
||||
MidPathNode() { this = MkMidNode(nd, cfg, summary) }
|
||||
|
||||
/** Gets the underlying configuration of this path node. */
|
||||
DataFlow::Configuration getConfiguration() { result = cfg }
|
||||
|
||||
/** Gets the summary of the path underlying this path node. */
|
||||
PathSummary getPathSummary() { result = summary }
|
||||
|
||||
/**
|
||||
* Holds if this node is hidden from paths in path explanation queries, except
|
||||
@@ -1021,28 +1050,13 @@ class PathNode extends TPathNode {
|
||||
}
|
||||
}
|
||||
|
||||
private PathNode getASuccessor(PathNode pnd) {
|
||||
exists(DataFlow::Node nd, Configuration cfg, PathSummary summary |
|
||||
pnd = MkMidNode(nd, cfg, summary) and
|
||||
exists(DataFlow::Node succ, PathSummary newSummary |
|
||||
flowStep(nd, id(cfg), succ, newSummary) and
|
||||
result = MkMidNode(succ, id(cfg), summary.append(newSummary))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private PathNode getASuccessorIfHidden(PathNode nd) {
|
||||
nd.isHidden() and
|
||||
result = getASuccessor(nd)
|
||||
}
|
||||
|
||||
/**
|
||||
* A path node corresponding to a flow source.
|
||||
*/
|
||||
class SourcePathNode extends PathNode {
|
||||
SourcePathNode() {
|
||||
exists(FlowLabel lbl |
|
||||
summary = PathSummary::level(lbl) and
|
||||
this = MkMidNode(nd, cfg, PathSummary::level(lbl)) and
|
||||
isSource(nd, cfg, lbl)
|
||||
)
|
||||
}
|
||||
@@ -1052,7 +1066,12 @@ class SourcePathNode extends PathNode {
|
||||
* A path node corresponding to a flow sink.
|
||||
*/
|
||||
class SinkPathNode extends PathNode {
|
||||
SinkPathNode() { isSink(nd, cfg, summary.getEndLabel()) }
|
||||
SinkPathNode() {
|
||||
exists(PathSummary summary |
|
||||
this = MkMidNode(nd, cfg, summary) and
|
||||
isSink(nd, cfg, summary.getEndLabel())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1061,7 +1080,7 @@ class SinkPathNode extends PathNode {
|
||||
module PathGraph {
|
||||
/** Holds if `nd` is a node in the graph of data flow path explanations. */
|
||||
query predicate nodes(PathNode nd) {
|
||||
not nd.isHidden() or
|
||||
not nd.(MidPathNode).isHidden() or
|
||||
nd instanceof SourcePathNode or
|
||||
nd instanceof SinkPathNode
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user