Add standard container steps

This commit is contained in:
Sauyon Lee
2021-10-05 08:05:04 -07:00
committed by Owen Mansel-Chan
parent 8c4a1d2559
commit 3750af41d3
2 changed files with 71 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
/** Contains predicates for dealing with container flow. */
import go
private import DataFlowNodes
private import DataFlowPrivate
private import DataFlowUtil
/**
* Holds if the step from `node1` to `node2` stores a value in a slice or array.
* This covers array assignments and initializers as well as implicit array
* creations for varargs.
*/
predicate containerStoreStep(Node node1, Node node2, Content c) {
c instanceof ArrayContent and
(
// currently there is no database information about variadic functions
(
node1.getType() instanceof ArrayType or
node1.getType() instanceof SliceType
) and
exists(Write w | w.writesElement(node1, _, node2))
)
or
c instanceof CollectionContent and
exists(BinaryOperationNode send | send.hasOperands(node1, node2) | send.getOperator() = "<-")
or
c instanceof MapKeyContent and
node1.getType() instanceof MapType and
exists(Write w | w.writesElement(node1, node2, _))
or
c instanceof MapValueContent and
node1.getType() instanceof MapType and
exists(Write w | w.writesElement(node1, _, node2))
}
/**
* Holds if the step from `node1` to `node2` reads a value from a slice or array.
* This covers ordinary array reads as well as array iteration through enhanced
* `for` statements.
*/
predicate containerReadStep(Node node1, Node node2, Content c) {
c instanceof ArrayContent and
(
node2.(Read).readsElement(node1, _) and
(
node1.getType() instanceof ArrayType or
node1.getType() instanceof SliceType
)
or
node2.(RangeElementNode).getBase() = node1
)
or
c instanceof CollectionContent and
exists(UnaryOperationNode recv | recv = node2 |
node2 = recv.getOperand() and
recv.getOperator() = "<-"
)
or
c instanceof MapKeyContent and
node1.getType() instanceof MapType and
node2.(RangeIndexNode).getBase() = node1
or
c instanceof MapValueContent and
node1.getType() instanceof MapType and
node2.(Read).readsElement(node1, _)
}

View File

@@ -1,6 +1,7 @@
private import go
private import DataFlowUtil
private import DataFlowImplCommon
private import ContainerFlow
private import FlowSummaryImpl as FlowSummaryImpl
import DataFlowNodes::Private
@@ -125,6 +126,8 @@ predicate storeStep(Node node1, Content c, PostUpdateNode node2) {
c = any(DataFlow::PointerContent pc | pc.getPointerType() = node2.getType())
or
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1, c, node2)
or
containerStoreStep(node1, node2, c)
}
/**
@@ -143,6 +146,8 @@ predicate readStep(Node node1, Content f, Node node2) {
)
or
FlowSummaryImpl::Private::Steps::summaryReadStep(node1, f, node2)
or
containerReadStep(node1, node2, f)
}
/**