Skip to content

Commit 327ade1

Browse files
authored
Merge pull request github#1940 from hvitved/dataflow/pathnode-successor
Java/C++/C#: Simplify `PathNode` successor logic
2 parents cd362d8 + 6318cc9 commit 327ade1

40 files changed

+283
-3255
lines changed

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl.qll

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,9 @@ abstract class PathNode extends TPathNode {
16181618
/** Gets a successor of this node, if any. */
16191619
abstract PathNode getASuccessor();
16201620

1621+
/** Holds if this node is a source. */
1622+
abstract predicate isSource();
1623+
16211624
private string ppAp() {
16221625
this instanceof PathNodeSink and result = ""
16231626
or
@@ -1683,12 +1686,6 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
16831686
// an intermediate step to another intermediate node
16841687
result = getSuccMid()
16851688
or
1686-
// a final step to a sink via one or more local steps
1687-
localFlowStepPlus(node, result.getNode(), _, config) and
1688-
ap instanceof AccessPathNil and
1689-
result instanceof PathNodeSink and
1690-
result.getConfiguration() = unbind(this.getConfiguration())
1691-
or
16921689
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
16931690
exists(PathNodeMid mid |
16941691
mid = getSuccMid() and
@@ -1697,23 +1694,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
16971694
result instanceof PathNodeSink and
16981695
result.getConfiguration() = unbind(mid.getConfiguration())
16991696
)
1700-
or
1701-
// a direct step from a source to a sink if a node is both
1702-
this instanceof PathNodeSource and
1703-
result instanceof PathNodeSink and
1704-
this.getNode() = result.getNode() and
1705-
result.getConfiguration() = unbind(this.getConfiguration())
17061697
}
1707-
}
17081698

1709-
/**
1710-
* A flow graph node corresponding to a source.
1711-
*/
1712-
private class PathNodeSource extends PathNodeMid {
1713-
PathNodeSource() {
1714-
getConfiguration().isSource(getNode()) and
1715-
getCallContext() instanceof CallContextAny and
1716-
getAp() instanceof AccessPathNil
1699+
override predicate isSource() {
1700+
config.isSource(node) and
1701+
cc instanceof CallContextAny and
1702+
ap instanceof AccessPathNil
17171703
}
17181704
}
17191705

@@ -1733,6 +1719,8 @@ private class PathNodeSink extends PathNode, TPathNodeSink {
17331719
override Configuration getConfiguration() { result = config }
17341720

17351721
override PathNode getASuccessor() { none() }
1722+
1723+
override predicate isSource() { config.isSource(node) }
17361724
}
17371725

17381726
/**
@@ -1967,12 +1955,12 @@ private predicate valuePathThroughCallable(PathNodeMid mid, OutNode out, CallCon
19671955
* sinks.
19681956
*/
19691957
private predicate flowsTo(
1970-
PathNodeSource flowsource, PathNodeSink flowsink, Node source, Node sink,
1971-
Configuration configuration
1958+
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
19721959
) {
1960+
flowsource.isSource() and
19731961
flowsource.getConfiguration() = configuration and
19741962
flowsource.getNode() = source and
1975-
pathSuccPlus(flowsource, flowsink) and
1963+
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
19761964
flowsink.getNode() = sink
19771965
}
19781966

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl2.qll

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,9 @@ abstract class PathNode extends TPathNode {
16181618
/** Gets a successor of this node, if any. */
16191619
abstract PathNode getASuccessor();
16201620

1621+
/** Holds if this node is a source. */
1622+
abstract predicate isSource();
1623+
16211624
private string ppAp() {
16221625
this instanceof PathNodeSink and result = ""
16231626
or
@@ -1683,12 +1686,6 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
16831686
// an intermediate step to another intermediate node
16841687
result = getSuccMid()
16851688
or
1686-
// a final step to a sink via one or more local steps
1687-
localFlowStepPlus(node, result.getNode(), _, config) and
1688-
ap instanceof AccessPathNil and
1689-
result instanceof PathNodeSink and
1690-
result.getConfiguration() = unbind(this.getConfiguration())
1691-
or
16921689
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
16931690
exists(PathNodeMid mid |
16941691
mid = getSuccMid() and
@@ -1697,23 +1694,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
16971694
result instanceof PathNodeSink and
16981695
result.getConfiguration() = unbind(mid.getConfiguration())
16991696
)
1700-
or
1701-
// a direct step from a source to a sink if a node is both
1702-
this instanceof PathNodeSource and
1703-
result instanceof PathNodeSink and
1704-
this.getNode() = result.getNode() and
1705-
result.getConfiguration() = unbind(this.getConfiguration())
17061697
}
1707-
}
17081698

1709-
/**
1710-
* A flow graph node corresponding to a source.
1711-
*/
1712-
private class PathNodeSource extends PathNodeMid {
1713-
PathNodeSource() {
1714-
getConfiguration().isSource(getNode()) and
1715-
getCallContext() instanceof CallContextAny and
1716-
getAp() instanceof AccessPathNil
1699+
override predicate isSource() {
1700+
config.isSource(node) and
1701+
cc instanceof CallContextAny and
1702+
ap instanceof AccessPathNil
17171703
}
17181704
}
17191705

@@ -1733,6 +1719,8 @@ private class PathNodeSink extends PathNode, TPathNodeSink {
17331719
override Configuration getConfiguration() { result = config }
17341720

17351721
override PathNode getASuccessor() { none() }
1722+
1723+
override predicate isSource() { config.isSource(node) }
17361724
}
17371725

17381726
/**
@@ -1967,12 +1955,12 @@ private predicate valuePathThroughCallable(PathNodeMid mid, OutNode out, CallCon
19671955
* sinks.
19681956
*/
19691957
private predicate flowsTo(
1970-
PathNodeSource flowsource, PathNodeSink flowsink, Node source, Node sink,
1971-
Configuration configuration
1958+
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
19721959
) {
1960+
flowsource.isSource() and
19731961
flowsource.getConfiguration() = configuration and
19741962
flowsource.getNode() = source and
1975-
pathSuccPlus(flowsource, flowsink) and
1963+
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
19761964
flowsink.getNode() = sink
19771965
}
19781966

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl3.qll

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,9 @@ abstract class PathNode extends TPathNode {
16181618
/** Gets a successor of this node, if any. */
16191619
abstract PathNode getASuccessor();
16201620

1621+
/** Holds if this node is a source. */
1622+
abstract predicate isSource();
1623+
16211624
private string ppAp() {
16221625
this instanceof PathNodeSink and result = ""
16231626
or
@@ -1683,12 +1686,6 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
16831686
// an intermediate step to another intermediate node
16841687
result = getSuccMid()
16851688
or
1686-
// a final step to a sink via one or more local steps
1687-
localFlowStepPlus(node, result.getNode(), _, config) and
1688-
ap instanceof AccessPathNil and
1689-
result instanceof PathNodeSink and
1690-
result.getConfiguration() = unbind(this.getConfiguration())
1691-
or
16921689
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
16931690
exists(PathNodeMid mid |
16941691
mid = getSuccMid() and
@@ -1697,23 +1694,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
16971694
result instanceof PathNodeSink and
16981695
result.getConfiguration() = unbind(mid.getConfiguration())
16991696
)
1700-
or
1701-
// a direct step from a source to a sink if a node is both
1702-
this instanceof PathNodeSource and
1703-
result instanceof PathNodeSink and
1704-
this.getNode() = result.getNode() and
1705-
result.getConfiguration() = unbind(this.getConfiguration())
17061697
}
1707-
}
17081698

1709-
/**
1710-
* A flow graph node corresponding to a source.
1711-
*/
1712-
private class PathNodeSource extends PathNodeMid {
1713-
PathNodeSource() {
1714-
getConfiguration().isSource(getNode()) and
1715-
getCallContext() instanceof CallContextAny and
1716-
getAp() instanceof AccessPathNil
1699+
override predicate isSource() {
1700+
config.isSource(node) and
1701+
cc instanceof CallContextAny and
1702+
ap instanceof AccessPathNil
17171703
}
17181704
}
17191705

@@ -1733,6 +1719,8 @@ private class PathNodeSink extends PathNode, TPathNodeSink {
17331719
override Configuration getConfiguration() { result = config }
17341720

17351721
override PathNode getASuccessor() { none() }
1722+
1723+
override predicate isSource() { config.isSource(node) }
17361724
}
17371725

17381726
/**
@@ -1967,12 +1955,12 @@ private predicate valuePathThroughCallable(PathNodeMid mid, OutNode out, CallCon
19671955
* sinks.
19681956
*/
19691957
private predicate flowsTo(
1970-
PathNodeSource flowsource, PathNodeSink flowsink, Node source, Node sink,
1971-
Configuration configuration
1958+
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
19721959
) {
1960+
flowsource.isSource() and
19731961
flowsource.getConfiguration() = configuration and
19741962
flowsource.getNode() = source and
1975-
pathSuccPlus(flowsource, flowsink) and
1963+
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
19761964
flowsink.getNode() = sink
19771965
}
19781966

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImpl4.qll

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,9 @@ abstract class PathNode extends TPathNode {
16181618
/** Gets a successor of this node, if any. */
16191619
abstract PathNode getASuccessor();
16201620

1621+
/** Holds if this node is a source. */
1622+
abstract predicate isSource();
1623+
16211624
private string ppAp() {
16221625
this instanceof PathNodeSink and result = ""
16231626
or
@@ -1683,12 +1686,6 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
16831686
// an intermediate step to another intermediate node
16841687
result = getSuccMid()
16851688
or
1686-
// a final step to a sink via one or more local steps
1687-
localFlowStepPlus(node, result.getNode(), _, config) and
1688-
ap instanceof AccessPathNil and
1689-
result instanceof PathNodeSink and
1690-
result.getConfiguration() = unbind(this.getConfiguration())
1691-
or
16921689
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
16931690
exists(PathNodeMid mid |
16941691
mid = getSuccMid() and
@@ -1697,23 +1694,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
16971694
result instanceof PathNodeSink and
16981695
result.getConfiguration() = unbind(mid.getConfiguration())
16991696
)
1700-
or
1701-
// a direct step from a source to a sink if a node is both
1702-
this instanceof PathNodeSource and
1703-
result instanceof PathNodeSink and
1704-
this.getNode() = result.getNode() and
1705-
result.getConfiguration() = unbind(this.getConfiguration())
17061697
}
1707-
}
17081698

1709-
/**
1710-
* A flow graph node corresponding to a source.
1711-
*/
1712-
private class PathNodeSource extends PathNodeMid {
1713-
PathNodeSource() {
1714-
getConfiguration().isSource(getNode()) and
1715-
getCallContext() instanceof CallContextAny and
1716-
getAp() instanceof AccessPathNil
1699+
override predicate isSource() {
1700+
config.isSource(node) and
1701+
cc instanceof CallContextAny and
1702+
ap instanceof AccessPathNil
17171703
}
17181704
}
17191705

@@ -1733,6 +1719,8 @@ private class PathNodeSink extends PathNode, TPathNodeSink {
17331719
override Configuration getConfiguration() { result = config }
17341720

17351721
override PathNode getASuccessor() { none() }
1722+
1723+
override predicate isSource() { config.isSource(node) }
17361724
}
17371725

17381726
/**
@@ -1967,12 +1955,12 @@ private predicate valuePathThroughCallable(PathNodeMid mid, OutNode out, CallCon
19671955
* sinks.
19681956
*/
19691957
private predicate flowsTo(
1970-
PathNodeSource flowsource, PathNodeSink flowsink, Node source, Node sink,
1971-
Configuration configuration
1958+
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
19721959
) {
1960+
flowsource.isSource() and
19731961
flowsource.getConfiguration() = configuration and
19741962
flowsource.getNode() = source and
1975-
pathSuccPlus(flowsource, flowsink) and
1963+
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
19761964
flowsink.getNode() = sink
19771965
}
19781966

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplLocal.qll

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,9 @@ abstract class PathNode extends TPathNode {
16181618
/** Gets a successor of this node, if any. */
16191619
abstract PathNode getASuccessor();
16201620

1621+
/** Holds if this node is a source. */
1622+
abstract predicate isSource();
1623+
16211624
private string ppAp() {
16221625
this instanceof PathNodeSink and result = ""
16231626
or
@@ -1683,12 +1686,6 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
16831686
// an intermediate step to another intermediate node
16841687
result = getSuccMid()
16851688
or
1686-
// a final step to a sink via one or more local steps
1687-
localFlowStepPlus(node, result.getNode(), _, config) and
1688-
ap instanceof AccessPathNil and
1689-
result instanceof PathNodeSink and
1690-
result.getConfiguration() = unbind(this.getConfiguration())
1691-
or
16921689
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
16931690
exists(PathNodeMid mid |
16941691
mid = getSuccMid() and
@@ -1697,23 +1694,12 @@ private class PathNodeMid extends PathNode, TPathNodeMid {
16971694
result instanceof PathNodeSink and
16981695
result.getConfiguration() = unbind(mid.getConfiguration())
16991696
)
1700-
or
1701-
// a direct step from a source to a sink if a node is both
1702-
this instanceof PathNodeSource and
1703-
result instanceof PathNodeSink and
1704-
this.getNode() = result.getNode() and
1705-
result.getConfiguration() = unbind(this.getConfiguration())
17061697
}
1707-
}
17081698

1709-
/**
1710-
* A flow graph node corresponding to a source.
1711-
*/
1712-
private class PathNodeSource extends PathNodeMid {
1713-
PathNodeSource() {
1714-
getConfiguration().isSource(getNode()) and
1715-
getCallContext() instanceof CallContextAny and
1716-
getAp() instanceof AccessPathNil
1699+
override predicate isSource() {
1700+
config.isSource(node) and
1701+
cc instanceof CallContextAny and
1702+
ap instanceof AccessPathNil
17171703
}
17181704
}
17191705

@@ -1733,6 +1719,8 @@ private class PathNodeSink extends PathNode, TPathNodeSink {
17331719
override Configuration getConfiguration() { result = config }
17341720

17351721
override PathNode getASuccessor() { none() }
1722+
1723+
override predicate isSource() { config.isSource(node) }
17361724
}
17371725

17381726
/**
@@ -1967,12 +1955,12 @@ private predicate valuePathThroughCallable(PathNodeMid mid, OutNode out, CallCon
19671955
* sinks.
19681956
*/
19691957
private predicate flowsTo(
1970-
PathNodeSource flowsource, PathNodeSink flowsink, Node source, Node sink,
1971-
Configuration configuration
1958+
PathNode flowsource, PathNodeSink flowsink, Node source, Node sink, Configuration configuration
19721959
) {
1960+
flowsource.isSource() and
19731961
flowsource.getConfiguration() = configuration and
19741962
flowsource.getNode() = source and
1975-
pathSuccPlus(flowsource, flowsink) and
1963+
(flowsource = flowsink or pathSuccPlus(flowsource, flowsink)) and
19761964
flowsink.getNode() = sink
19771965
}
19781966

0 commit comments

Comments
 (0)