diff --git a/java/ql/src/semmle/code/java/dataflow/FlowSummary.qll b/java/ql/src/semmle/code/java/dataflow/FlowSummary.qll index 0f222d5caa2..c80e026b6c7 100644 --- a/java/ql/src/semmle/code/java/dataflow/FlowSummary.qll +++ b/java/ql/src/semmle/code/java/dataflow/FlowSummary.qll @@ -5,7 +5,7 @@ import java private import internal.FlowSummaryImpl as Impl private import internal.DataFlowDispatch -private import internal.DataFlowPrivate +private import internal.DataFlowUtil // import all instances of SummarizedCallable below private module Summaries { diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index 3f1694ae2bc..4ea6dea266a 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -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 = "" } -} - -class MapKeyContent extends Content, TMapKeyContent { - override string toString() { result = "" } -} - -class MapValueContent extends Content, TMapValueContent { - override string toString() { result = "" } -} - /** * 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 diff --git a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll index 376823b9895..52b1f26f056 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll @@ -157,6 +157,62 @@ predicate simpleLocalFlowStep(Node node1, Node node2) { 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 = "" } +} + +/** A reference through a map key. */ +class MapKeyContent extends Content, TMapKeyContent { + override string toString() { result = "" } +} + +/** A reference through a map value. */ +class MapValueContent extends Content, TMapValueContent { + override string toString() { result = "" } +} + /** * A guard that validates some expression. * diff --git a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index 966daea783f..4c8510c0bf3 100644 --- a/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -61,16 +61,16 @@ private module Cached { localAdditionalTaintUpdateStep(src.asExpr(), sink.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr()) or - exists(Content f | + exists(DataFlow::Content f | readStep(src, f, sink) and not sink.getTypeBound() instanceof PrimitiveType and not sink.getTypeBound() instanceof BoxedType and not sink.getTypeBound() instanceof NumberType | - f instanceof ArrayContent or - f instanceof CollectionContent or - f instanceof MapKeyContent or - f instanceof MapValueContent + f instanceof DataFlow::ArrayContent or + f instanceof DataFlow::CollectionContent or + f instanceof DataFlow::MapKeyContent or + f instanceof DataFlow::MapValueContent ) or FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false) @@ -122,7 +122,7 @@ private module StoreTaintSteps { 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 | (isSink(arg) or isAdditionalTaintStep(arg, _)) and (arg.asExpr() instanceof Argument or arg instanceof ArgumentNode) and @@ -131,18 +131,18 @@ private module StoreTaintSteps { needsTaintStore(_, container, _) | container.(Array).getComponentType() = elem and - f instanceof ArrayContent + f instanceof DataFlow::ArrayContent or container.(CollectionType).getElementType() = elem and - f instanceof CollectionContent + f instanceof DataFlow::CollectionContent or container.(MapType).getValueType() = elem and - f instanceof MapValueContent + f instanceof DataFlow::MapValueContent ) } 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 needsTaintStore(_, elem, f) and 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() } - private predicate needsTaintStore(RefType container, Type elem, Content f) { + private predicate needsTaintStore(RefType container, Type elem, DataFlow::Content f) { exists(DataFlow::Node arg | (isSink(arg) or isAdditionalTaintStep(arg, _)) and (arg.asExpr() instanceof Argument or arg instanceof ArgumentNode) and @@ -166,18 +166,18 @@ private module StoreTaintSteps { needsTaintStore(_, container, _) | container.(Array).getComponentType() = elem and - f instanceof ArrayContent + f instanceof DataFlow::ArrayContent or container.(CollectionType).getElementType() = elem and - f instanceof CollectionContent + f instanceof DataFlow::CollectionContent or container.(MapType).getValueType() = elem and - f instanceof MapValueContent + f instanceof DataFlow::MapValueContent ) } 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 needsTaintStore(_, elem, f) and not exists(Type srctyp | srctyp = node1.getTypeBound() | not compatibleTypes(srctyp, elem))