Java: Make Content public as DataFlow::Content.

This commit is contained in:
Anders Schack-Mulligen
2021-06-18 13:40:51 +02:00
parent 80880320d5
commit aa82d0b815
4 changed files with 72 additions and 66 deletions

View File

@@ -5,7 +5,7 @@
import java import java
private import internal.FlowSummaryImpl as Impl private import internal.FlowSummaryImpl as Impl
private import internal.DataFlowDispatch private import internal.DataFlowDispatch
private import internal.DataFlowPrivate private import internal.DataFlowUtil
// import all instances of SummarizedCallable below // import all instances of SummarizedCallable below
private module Summaries { private module Summaries {

View File

@@ -83,56 +83,6 @@ private predicate instanceFieldAssign(Expr src, FieldAccess fa) {
) )
} }
private newtype TContent =
TFieldContent(InstanceField f) or
TArrayContent() or
TCollectionContent() or
TMapKeyContent() or
TMapValueContent()
/**
* A reference contained in an object. Examples include instance fields, the
* contents of a collection object, or the contents of an array.
*/
class Content extends TContent {
/** Gets a textual representation of this element. */
abstract string toString();
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0
}
}
class FieldContent extends Content, TFieldContent {
InstanceField f;
FieldContent() { this = TFieldContent(f) }
InstanceField getField() { result = f }
override string toString() { result = f.toString() }
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
f.getLocation().hasLocationInfo(path, sl, sc, el, ec)
}
}
class ArrayContent extends Content, TArrayContent {
override string toString() { result = "[]" }
}
class CollectionContent extends Content, TCollectionContent {
override string toString() { result = "<element>" }
}
class MapKeyContent extends Content, TMapKeyContent {
override string toString() { result = "<map.key>" }
}
class MapValueContent extends Content, TMapValueContent {
override string toString() { result = "<map.value>" }
}
/** /**
* Holds if data can flow from `node1` to `node2` via an assignment to `f`. * Holds if data can flow from `node1` to `node2` via an assignment to `f`.
* Thus, `node2` references an object with a field `f` that contains the * Thus, `node2` references an object with a field `f` that contains the

View File

@@ -157,6 +157,62 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
FlowSummaryImpl::Private::Steps::summaryLocalStep(node1, node2, true) FlowSummaryImpl::Private::Steps::summaryLocalStep(node1, node2, true)
} }
private newtype TContent =
TFieldContent(InstanceField f) or
TArrayContent() or
TCollectionContent() or
TMapKeyContent() or
TMapValueContent()
/**
* A description of the way data may be stored inside an object. Examples
* include instance fields, the contents of a collection object, or the contents
* of an array.
*/
class Content extends TContent {
/** Gets a textual representation of this element. */
abstract string toString();
predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0
}
}
/** A reference through an instance field. */
class FieldContent extends Content, TFieldContent {
InstanceField f;
FieldContent() { this = TFieldContent(f) }
InstanceField getField() { result = f }
override string toString() { result = f.toString() }
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
f.getLocation().hasLocationInfo(path, sl, sc, el, ec)
}
}
/** A reference through an array. */
class ArrayContent extends Content, TArrayContent {
override string toString() { result = "[]" }
}
/** A reference through the contents of some collection-like container. */
class CollectionContent extends Content, TCollectionContent {
override string toString() { result = "<element>" }
}
/** A reference through a map key. */
class MapKeyContent extends Content, TMapKeyContent {
override string toString() { result = "<map.key>" }
}
/** A reference through a map value. */
class MapValueContent extends Content, TMapValueContent {
override string toString() { result = "<map.value>" }
}
/** /**
* A guard that validates some expression. * A guard that validates some expression.
* *

View File

@@ -61,16 +61,16 @@ private module Cached {
localAdditionalTaintUpdateStep(src.asExpr(), localAdditionalTaintUpdateStep(src.asExpr(),
sink.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr()) sink.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr())
or or
exists(Content f | exists(DataFlow::Content f |
readStep(src, f, sink) and readStep(src, f, sink) and
not sink.getTypeBound() instanceof PrimitiveType and not sink.getTypeBound() instanceof PrimitiveType and
not sink.getTypeBound() instanceof BoxedType and not sink.getTypeBound() instanceof BoxedType and
not sink.getTypeBound() instanceof NumberType not sink.getTypeBound() instanceof NumberType
| |
f instanceof ArrayContent or f instanceof DataFlow::ArrayContent or
f instanceof CollectionContent or f instanceof DataFlow::CollectionContent or
f instanceof MapKeyContent or f instanceof DataFlow::MapKeyContent or
f instanceof MapValueContent f instanceof DataFlow::MapValueContent
) )
or or
FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false) FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false)
@@ -122,7 +122,7 @@ private module StoreTaintSteps {
override predicate isSink(DataFlow::Node n) { none() } override predicate isSink(DataFlow::Node n) { none() }
private predicate needsTaintStore(RefType container, Type elem, Content f) { private predicate needsTaintStore(RefType container, Type elem, DataFlow::Content f) {
exists(DataFlow::Node arg | exists(DataFlow::Node arg |
(isSink(arg) or isAdditionalTaintStep(arg, _)) and (isSink(arg) or isAdditionalTaintStep(arg, _)) and
(arg.asExpr() instanceof Argument or arg instanceof ArgumentNode) and (arg.asExpr() instanceof Argument or arg instanceof ArgumentNode) and
@@ -131,18 +131,18 @@ private module StoreTaintSteps {
needsTaintStore(_, container, _) needsTaintStore(_, container, _)
| |
container.(Array).getComponentType() = elem and container.(Array).getComponentType() = elem and
f instanceof ArrayContent f instanceof DataFlow::ArrayContent
or or
container.(CollectionType).getElementType() = elem and container.(CollectionType).getElementType() = elem and
f instanceof CollectionContent f instanceof DataFlow::CollectionContent
or or
container.(MapType).getValueType() = elem and container.(MapType).getValueType() = elem and
f instanceof MapValueContent f instanceof DataFlow::MapValueContent
) )
} }
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(Content f, Type elem | exists(DataFlow::Content f, Type elem |
storeStep(node1, f, node2) and storeStep(node1, f, node2) and
needsTaintStore(_, elem, f) and needsTaintStore(_, elem, f) and
not exists(Type srctyp | srctyp = node1.getTypeBound() | not compatibleTypes(srctyp, elem)) not exists(Type srctyp | srctyp = node1.getTypeBound() | not compatibleTypes(srctyp, elem))
@@ -157,7 +157,7 @@ private module StoreTaintSteps {
override predicate isSink(DataFlow::Node n) { none() } override predicate isSink(DataFlow::Node n) { none() }
private predicate needsTaintStore(RefType container, Type elem, Content f) { private predicate needsTaintStore(RefType container, Type elem, DataFlow::Content f) {
exists(DataFlow::Node arg | exists(DataFlow::Node arg |
(isSink(arg) or isAdditionalTaintStep(arg, _)) and (isSink(arg) or isAdditionalTaintStep(arg, _)) and
(arg.asExpr() instanceof Argument or arg instanceof ArgumentNode) and (arg.asExpr() instanceof Argument or arg instanceof ArgumentNode) and
@@ -166,18 +166,18 @@ private module StoreTaintSteps {
needsTaintStore(_, container, _) needsTaintStore(_, container, _)
| |
container.(Array).getComponentType() = elem and container.(Array).getComponentType() = elem and
f instanceof ArrayContent f instanceof DataFlow::ArrayContent
or or
container.(CollectionType).getElementType() = elem and container.(CollectionType).getElementType() = elem and
f instanceof CollectionContent f instanceof DataFlow::CollectionContent
or or
container.(MapType).getValueType() = elem and container.(MapType).getValueType() = elem and
f instanceof MapValueContent f instanceof DataFlow::MapValueContent
) )
} }
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
exists(Content f, Type elem | exists(DataFlow::Content f, Type elem |
storeStep(node1, f, node2) and storeStep(node1, f, node2) and
needsTaintStore(_, elem, f) and needsTaintStore(_, elem, f) and
not exists(Type srctyp | srctyp = node1.getTypeBound() | not compatibleTypes(srctyp, elem)) not exists(Type srctyp | srctyp = node1.getTypeBound() | not compatibleTypes(srctyp, elem))