Skip to content

Commit

Permalink
Java: Use FlowSummaryImpl from dataflow pack
Browse files Browse the repository at this point in the history
  • Loading branch information
hvitved committed Dec 7, 2023
1 parent 5a9dc64 commit d73136b
Show file tree
Hide file tree
Showing 10 changed files with 382 additions and 2,023 deletions.
64 changes: 59 additions & 5 deletions java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,13 @@

import java
private import semmle.code.java.dataflow.DataFlow::DataFlow
private import FlowSummary as FlowSummary
private import internal.DataFlowPrivate
private import internal.FlowSummaryImpl
private import internal.FlowSummaryImpl::Public
private import internal.FlowSummaryImpl::Private
private import internal.FlowSummaryImpl::Private::External
private import internal.FlowSummaryImplSpecific as FlowSummaryImplSpecific
private import internal.AccessPathSyntax
private import internal.ExternalFlowExtensions as Extensions
private import FlowSummary
private import codeql.mad.ModelValidation as SharedModelVal

/**
Expand Down Expand Up @@ -478,7 +479,9 @@ private module Cached {
*/
cached
predicate sourceNode(Node node, string kind) {
exists(FlowSummaryImplSpecific::InterpretNode n | isSourceNode(n, kind) and n.asNode() = node)
exists(SourceSinkInterpretationInput::InterpretNode n |
isSourceNode(n, kind) and n.asNode() = node
)
}

/**
Expand All @@ -487,8 +490,59 @@ private module Cached {
*/
cached
predicate sinkNode(Node node, string kind) {
exists(FlowSummaryImplSpecific::InterpretNode n | isSinkNode(n, kind) and n.asNode() = node)
exists(SourceSinkInterpretationInput::InterpretNode n |
isSinkNode(n, kind) and n.asNode() = node
)
}
}

import Cached

private predicate relevantSummaryElementManual(
FlowSummary::SummarizedCallableBase c, string input, string output, string kind,
Provenance provenance
) {
summaryElement(c, input, output, kind, provenance) and
provenance.isManual()
}

private predicate relevantSummaryElementGenerated(
FlowSummary::SummarizedCallableBase c, string input, string output, string kind,
Provenance provenance
) {
summaryElement(c, input, output, kind, provenance) and
provenance.isGenerated()
}

private class SummarizedCallableAdapter extends SummarizedCallable {
string input_;
string output_;
string kind;
string provenance_;

SummarizedCallableAdapter() {
relevantSummaryElementManual(this, input_, output_, kind, provenance_)
or
relevantSummaryElementGenerated(this, input_, output_, kind, provenance_) and
not relevantSummaryElementManual(this, _, _, _, _)
}

override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input = input_ and
output = output_ and
if kind = "value" then preservesValue = true else preservesValue = false
}

override predicate hasProvenance(Provenance provenance) { provenance = provenance_ }
}

private class NeutralCallableAdapter extends NeutralCallable {
string kind;
string provenance_;

NeutralCallableAdapter() { neutralElement(this, kind, provenance_) }

override string getKind() { result = kind }

override predicate hasProvenance(Provenance provenance) { provenance = provenance_ }
}
70 changes: 7 additions & 63 deletions java/ql/lib/semmle/code/java/dataflow/FlowSummary.qll
Original file line number Diff line number Diff line change
Expand Up @@ -6,63 +6,13 @@ import java
private import internal.FlowSummaryImpl as Impl
private import internal.DataFlowUtil

class SummaryComponent = Impl::Public::SummaryComponent;
deprecated class SummaryComponent = Impl::Private::SummaryComponent;

/** Provides predicates for constructing summary components. */
module SummaryComponent {
import Impl::Public::SummaryComponent
deprecated module SummaryComponent = Impl::Private::SummaryComponent;

/** Gets a summary component that represents a qualifier. */
SummaryComponent qualifier() { result = argument(-1) }
deprecated class SummaryComponentStack = Impl::Private::SummaryComponentStack;

/** Gets a summary component for field `f`. */
SummaryComponent field(Field f) { result = content(any(FieldContent c | c.getField() = f)) }

/** Gets a summary component for `Element`. */
SummaryComponent element() { result = content(any(CollectionContent c)) }

/** Gets a summary component for `ArrayElement`. */
SummaryComponent arrayElement() { result = content(any(ArrayContent c)) }

/** Gets a summary component for `MapValue`. */
SummaryComponent mapValue() { result = content(any(MapValueContent c)) }

/** Gets a summary component that represents the return value of a call. */
SummaryComponent return() { result = return(_) }
}

class SummaryComponentStack = Impl::Public::SummaryComponentStack;

/** Provides predicates for constructing stacks of summary components. */
module SummaryComponentStack {
import Impl::Public::SummaryComponentStack

/** Gets a singleton stack representing a qualifier. */
SummaryComponentStack qualifier() { result = singleton(SummaryComponent::qualifier()) }

/** Gets a stack representing a field `f` of `object`. */
SummaryComponentStack fieldOf(Field f, SummaryComponentStack object) {
result = push(SummaryComponent::field(f), object)
}

/** Gets a stack representing `Element` of `object`. */
SummaryComponentStack elementOf(SummaryComponentStack object) {
result = push(SummaryComponent::element(), object)
}

/** Gets a stack representing `ArrayElement` of `object`. */
SummaryComponentStack arrayElementOf(SummaryComponentStack object) {
result = push(SummaryComponent::arrayElement(), object)
}

/** Gets a stack representing `MapValue` of `object`. */
SummaryComponentStack mapValueOf(SummaryComponentStack object) {
result = push(SummaryComponent::mapValue(), object)
}

/** Gets a singleton stack representing a (normal) return. */
SummaryComponentStack return() { result = singleton(SummaryComponent::return()) }
}
deprecated module SummaryComponentStack = Impl::Private::SummaryComponentStack;

/** A synthetic callable with a set of concrete call sites and a flow summary. */
abstract class SyntheticCallable extends string {
Expand All @@ -77,11 +27,7 @@ abstract class SyntheticCallable extends string {
*
* See `SummarizedCallable::propagatesFlow` for details.
*/
predicate propagatesFlow(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
) {
none()
}
abstract predicate propagatesFlow(string input, string output, boolean preservesValue);

/**
* Gets the type of the parameter at the specified position with -1 indicating
Expand Down Expand Up @@ -180,11 +126,9 @@ class SummarizedCallable = Impl::Public::SummarizedCallable;
* to `SummarizedCallable`.
*/
private class SummarizedSyntheticCallableAdapter extends SummarizedCallable, TSyntheticCallable {
override predicate propagatesFlow(
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
) {
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
this.asSyntheticCallable().propagatesFlow(input, output, preservesValue)
}
}

class RequiredSummaryComponentStack = Impl::Public::RequiredSummaryComponentStack;
deprecated class RequiredSummaryComponentStack = Impl::Private::RequiredSummaryComponentStack;
182 changes: 0 additions & 182 deletions java/ql/lib/semmle/code/java/dataflow/internal/AccessPathSyntax.qll

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -491,16 +491,16 @@ module Private {
override string toString() { result = this.getSummaryNode().toString() }

/** Holds if this summary node is the `i`th argument of `call`. */
predicate isArgumentOf(DataFlowCall call, int i) {
FlowSummaryImpl::Private::summaryArgumentNode(call, this.getSummaryNode(), i)
predicate isArgumentOf(SummaryCall call, int i) {
FlowSummaryImpl::Private::summaryArgumentNode(call.getReceiver(), this.getSummaryNode(), i)
}

/** Holds if this summary node is a return node. */
predicate isReturn() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), _) }

/** Holds if this summary node is an out node for `call`. */
predicate isOut(DataFlowCall call) {
FlowSummaryImpl::Private::summaryOutNode(call, this.getSummaryNode(), _)
predicate isOut(SummaryCall call) {
FlowSummaryImpl::Private::summaryOutNode(call.getReceiver(), this.getSummaryNode(), _)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,10 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves
* by default as a heuristic.
*/
predicate allowParameterReturnInSelf(ParameterNode p) {
FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(p)
exists(DataFlowCallable c, ParameterPosition pos |
parameterNode(p, c, pos) and
FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(c.asSummarizedCallable(), pos)
)
or
CaptureFlow::heuristicAllowInstanceParameterReturnInSelf(p.(InstanceParameterNode).getCallable())
}
Expand Down
Loading

0 comments on commit d73136b

Please sign in to comment.