mirror of
https://github.com/github/codeql.git
synced 2026-01-31 07:12:57 +01:00
Add standard container steps
This commit is contained in:
committed by
Owen Mansel-Chan
parent
8c4a1d2559
commit
3750af41d3
66
ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll
Normal file
66
ql/lib/semmle/go/dataflow/internal/ContainerFlow.qll
Normal 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, _)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user