diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll index fb773ea89f8d..e36026495816 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll index fb773ea89f8d..e36026495816 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll index fb773ea89f8d..e36026495816 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll index fb773ea89f8d..e36026495816 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll index fb773ea89f8d..e36026495816 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll index fb773ea89f8d..e36026495816 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll index fb773ea89f8d..e36026495816 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll index fb773ea89f8d..e36026495816 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll index fb773ea89f8d..e36026495816 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll index fb773ea89f8d..e36026495816 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll index fb773ea89f8d..e36026495816 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll index fb773ea89f8d..e36026495816 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll index fb773ea89f8d..e36026495816 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll index fb773ea89f8d..e36026495816 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll index fb773ea89f8d..e36026495816 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImplForContentDataFlow.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll index fb773ea89f8d..e36026495816 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll index fb773ea89f8d..e36026495816 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl2.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll index fb773ea89f8d..e36026495816 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl3.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll index fb773ea89f8d..e36026495816 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl4.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll index fb773ea89f8d..e36026495816 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl5.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll index fb773ea89f8d..e36026495816 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImpl6.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll index fb773ea89f8d..e36026495816 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForOnActivityResult.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll index fb773ea89f8d..e36026495816 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplForSerializability.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll index fb773ea89f8d..e36026495816 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll index fb773ea89f8d..e36026495816 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll index fb773ea89f8d..e36026495816 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll index fb773ea89f8d..e36026495816 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/python/ql/test/experimental/dataflow/basic/globalStep.expected b/python/ql/test/experimental/dataflow/basic/globalStep.expected index 4e9d4a8148b6..9f228998b9c4 100644 --- a/python/ql/test/experimental/dataflow/basic/globalStep.expected +++ b/python/ql/test/experimental/dataflow/basic/globalStep.expected @@ -1,8 +1,6 @@ | test.py:1:1:1:21 | ControlFlowNode for FunctionExpr | test.py:1:5:1:17 | GSSA Variable obfuscated_id | | test.py:1:1:1:21 | ControlFlowNode for FunctionExpr | test.py:1:5:1:17 | GSSA Variable obfuscated_id | | test.py:1:1:1:21 | ControlFlowNode for FunctionExpr | test.py:7:5:7:17 | ControlFlowNode for obfuscated_id | -| test.py:1:1:1:21 | ControlFlowNode for FunctionExpr | test.py:7:5:7:17 | ControlFlowNode for obfuscated_id | -| test.py:1:5:1:17 | GSSA Variable obfuscated_id | test.py:7:5:7:17 | ControlFlowNode for obfuscated_id | | test.py:1:5:1:17 | GSSA Variable obfuscated_id | test.py:7:5:7:17 | ControlFlowNode for obfuscated_id | | test.py:1:19:1:19 | ControlFlowNode for x | test.py:1:19:1:19 | SSA variable x | | test.py:1:19:1:19 | ControlFlowNode for x | test.py:1:19:1:19 | SSA variable x | @@ -97,7 +95,6 @@ | test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:19:7:19 | ControlFlowNode for a | | test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:19:7:19 | ControlFlowNode for a | | test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() | test.py:7:1:7:1 | GSSA Variable b | -| test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() | test.py:7:1:7:1 | GSSA Variable b | | test.py:7:19:7:19 | ControlFlowNode for a | test.py:1:19:1:19 | ControlFlowNode for x | | test.py:7:19:7:19 | ControlFlowNode for a | test.py:1:19:1:19 | ControlFlowNode for x | | test.py:7:19:7:19 | ControlFlowNode for a | test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() | diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll index fb773ea89f8d..e36026495816 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll index fb773ea89f8d..e36026495816 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll index fb773ea89f8d..e36026495816 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll index fb773ea89f8d..e36026495816 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl.qll @@ -3854,16 +3854,11 @@ class PathNode extends TPathNode { /** Gets the associated configuration. */ Configuration getConfiguration() { none() } - private PathNode getASuccessorIfHidden() { - this.(PathNodeImpl).isHidden() and - result = this.(PathNodeImpl).getASuccessorImpl() - } - /** Gets a successor of this node, if any. */ final PathNode getASuccessor() { - result = this.(PathNodeImpl).getASuccessorImpl().getASuccessorIfHidden*() and - not this.(PathNodeImpl).isHidden() and - not result.(PathNodeImpl).isHidden() + result = this.(PathNodeImpl).getANonHiddenSuccessor() and + reach(this) and + reach(result) } /** Holds if this node is a source. */ @@ -3871,7 +3866,18 @@ class PathNode extends TPathNode { } abstract private class PathNodeImpl extends PathNode { - abstract PathNode getASuccessorImpl(); + abstract PathNodeImpl getASuccessorImpl(); + + private PathNodeImpl getASuccessorIfHidden() { + this.isHidden() and + result = this.getASuccessorImpl() + } + + final PathNodeImpl getANonHiddenSuccessor() { + result = this.getASuccessorImpl().getASuccessorIfHidden*() and + not this.isHidden() and + not result.isHidden() + } abstract NodeEx getNodeEx(); @@ -3914,15 +3920,17 @@ abstract private class PathNodeImpl extends PathNode { } /** Holds if `n` can reach a sink. */ -private predicate directReach(PathNode n) { - n instanceof PathNodeSink or directReach(n.getASuccessor()) +private predicate directReach(PathNodeImpl n) { + n instanceof PathNodeSink or directReach(n.getANonHiddenSuccessor()) } /** Holds if `n` can reach a sink or is used in a subpath that can reach a sink. */ private predicate reach(PathNode n) { directReach(n) or Subpaths::retReach(n) } /** Holds if `n1.getASuccessor() = n2` and `n2` can reach a sink. */ -private predicate pathSucc(PathNode n1, PathNode n2) { n1.getASuccessor() = n2 and directReach(n2) } +private predicate pathSucc(PathNodeImpl n1, PathNode n2) { + n1.getANonHiddenSuccessor() = n2 and directReach(n2) +} private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1, n2) @@ -3931,7 +3939,7 @@ private predicate pathSuccPlus(PathNode n1, PathNode n2) = fastTC(pathSucc/2)(n1 */ module PathGraph { /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */ - query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b and reach(a) and reach(b) } + query predicate edges(PathNode a, PathNode b) { a.getASuccessor() = b } /** Holds if `n` is a node in the graph of data flow path explanations. */ query predicate nodes(PathNode n, string key, string val) { @@ -4049,7 +4057,7 @@ private class PathNodeSink extends PathNodeImpl, TPathNodeSink { override Configuration getConfiguration() { result = config } - override PathNode getASuccessorImpl() { none() } + override PathNodeImpl getASuccessorImpl() { none() } override predicate isSource() { sourceNode(node, state, config) } } @@ -4365,8 +4373,8 @@ private module Subpaths { } pragma[nomagic] - private predicate hasSuccessor(PathNode pred, PathNodeMid succ, NodeEx succNode) { - succ = pred.getASuccessor() and + private predicate hasSuccessor(PathNodeImpl pred, PathNodeMid succ, NodeEx succNode) { + succ = pred.getANonHiddenSuccessor() and succNode = succ.getNodeEx() } @@ -4375,9 +4383,9 @@ private module Subpaths { * a subpath between `par` and `ret` with the connecting edges `arg -> par` and * `ret -> out` is summarized as the edge `arg -> out`. */ - predicate subpaths(PathNode arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { + predicate subpaths(PathNodeImpl arg, PathNodeImpl par, PathNodeImpl ret, PathNode out) { exists(ParamNodeEx p, NodeEx o, FlowState sout, AccessPath apout, PathNodeMid out0 | - pragma[only_bind_into](arg).getASuccessor() = pragma[only_bind_into](out0) and + pragma[only_bind_into](arg).getANonHiddenSuccessor() = pragma[only_bind_into](out0) and subpaths03(pragma[only_bind_into](arg), p, localStepToHidden*(ret), o, sout, apout) and hasSuccessor(pragma[only_bind_into](arg), par, p) and not ret.isHidden() and @@ -4390,12 +4398,12 @@ private module Subpaths { /** * Holds if `n` can reach a return node in a summarized subpath that can reach a sink. */ - predicate retReach(PathNode n) { + predicate retReach(PathNodeImpl n) { exists(PathNode out | subpaths(_, _, n, out) | directReach(out) or retReach(out)) or - exists(PathNode mid | + exists(PathNodeImpl mid | retReach(mid) and - n.getASuccessor() = mid and + n.getANonHiddenSuccessor() = mid and not subpaths(_, mid, _, _) ) }