mirror of
https://github.com/github/codeql.git
synced 2026-05-02 20:25:13 +02:00
Java: Use shared flow summary library for csv models.
This commit is contained in:
@@ -67,6 +67,7 @@
|
||||
import java
|
||||
private import semmle.code.java.dataflow.DataFlow::DataFlow
|
||||
private import internal.DataFlowPrivate
|
||||
private import FlowSummary
|
||||
|
||||
/**
|
||||
* A module importing the frameworks that provide external flow data,
|
||||
@@ -459,7 +460,8 @@ module CsvValidation {
|
||||
summaryModel(_, _, _, _, _, _, input, _, _) and pred = "summary"
|
||||
|
|
||||
specSplit(input, part, _) and
|
||||
not part.regexpMatch("|Argument|ReturnValue") and
|
||||
not part.regexpMatch("|ReturnValue|ArrayElement|Element") and
|
||||
not (part = "Argument" and pred = "sink") and
|
||||
not parseArg(part, _) and
|
||||
msg = "Unrecognized input specification \"" + part + "\" in " + pred + " model."
|
||||
)
|
||||
@@ -470,7 +472,8 @@ module CsvValidation {
|
||||
summaryModel(_, _, _, _, _, _, _, output, _) and pred = "summary"
|
||||
|
|
||||
specSplit(output, part, _) and
|
||||
not part.regexpMatch("|Argument|Parameter|ReturnValue") and
|
||||
not part.regexpMatch("|ReturnValue|ArrayElement|Element") and
|
||||
not (part = ["Argument", "Parameter"] and pred = "source") and
|
||||
not parseArg(part, _) and
|
||||
not parseParam(part, _) and
|
||||
msg = "Unrecognized output specification \"" + part + "\" in " + pred + " model."
|
||||
@@ -675,6 +678,75 @@ private predicate summaryElementRef(Top ref, string input, string output, string
|
||||
)
|
||||
}
|
||||
|
||||
private SummaryComponent interpretComponent(string c) {
|
||||
specSplit(_, c, _) and
|
||||
(
|
||||
exists(int pos | parseArg(c, pos) and result = SummaryComponent::argument(pos))
|
||||
or
|
||||
exists(int pos | parseParam(c, pos) and result = SummaryComponent::parameter(pos))
|
||||
or
|
||||
c = "ReturnValue" and result = SummaryComponent::return()
|
||||
or
|
||||
c = "ArrayElement" and result = SummaryComponent::content(any(ArrayContent c0))
|
||||
or
|
||||
c = "Element" and result = SummaryComponent::content(any(CollectionContent c0))
|
||||
// or
|
||||
// c = "MapKey" and result = SummaryComponent::content(any(MapKeyContent c0))
|
||||
// or
|
||||
// c = "MapValue" and result = SummaryComponent::content(any(MapValueContent c0))
|
||||
)
|
||||
}
|
||||
|
||||
private predicate interpretSpec(string spec, int idx, SummaryComponentStack stack) {
|
||||
exists(string c |
|
||||
summaryElement(_, spec, _, _) or
|
||||
summaryElement(_, _, spec, _)
|
||||
|
|
||||
len(spec, idx + 1) and
|
||||
specSplit(spec, c, idx) and
|
||||
stack = SummaryComponentStack::singleton(interpretComponent(c))
|
||||
)
|
||||
or
|
||||
exists(SummaryComponent head, SummaryComponentStack tail |
|
||||
interpretSpec(spec, idx, head, tail) and
|
||||
stack = SummaryComponentStack::push(head, tail)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate interpretSpec(
|
||||
string output, int idx, SummaryComponent head, SummaryComponentStack tail
|
||||
) {
|
||||
exists(string c |
|
||||
interpretSpec(output, idx + 1, tail) and
|
||||
specSplit(output, c, idx) and
|
||||
head = interpretComponent(c)
|
||||
)
|
||||
}
|
||||
|
||||
private class MkStack extends RequiredSummaryComponentStack {
|
||||
MkStack() { interpretSpec(_, _, _, this) }
|
||||
|
||||
override predicate required(SummaryComponent c) { interpretSpec(_, _, c, this) }
|
||||
}
|
||||
|
||||
private class SummarizedCallableExternal extends SummarizedCallable {
|
||||
SummarizedCallableExternal() { summaryElement(this, _, _, _) }
|
||||
|
||||
override predicate propagatesFlow(
|
||||
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
|
||||
) {
|
||||
exists(string inSpec, string outSpec, string kind |
|
||||
summaryElement(this, inSpec, outSpec, kind) and
|
||||
interpretSpec(inSpec, 0, input) and
|
||||
interpretSpec(outSpec, 0, output)
|
||||
|
|
||||
kind = "value" and preservesValue = true
|
||||
or
|
||||
kind = "taint" and preservesValue = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TAstOrNode =
|
||||
TAst(Top t) or
|
||||
TNode(Node n)
|
||||
@@ -761,15 +833,3 @@ predicate sinkNode(Node node, string kind) {
|
||||
interpretInput(input, 0, ref, TNode(node))
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `node1` to `node2` is specified as a flow step with the given kind
|
||||
* in a CSV flow model.
|
||||
*/
|
||||
predicate summaryStep(Node node1, Node node2, string kind) {
|
||||
exists(Top ref, string input, string output |
|
||||
summaryElementRef(ref, input, output, kind) and
|
||||
interpretInput(input, 0, ref, TNode(node1)) and
|
||||
interpretOutput(output, 0, ref, TNode(node2))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,9 @@ private import internal.DataFlowDispatch
|
||||
private import internal.DataFlowPrivate
|
||||
|
||||
// import all instances below
|
||||
private module Summaries { }
|
||||
private module Summaries {
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
}
|
||||
|
||||
class SummaryComponent = Impl::Public::SummaryComponent;
|
||||
|
||||
|
||||
@@ -142,8 +142,6 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
|
||||
or
|
||||
node2.asExpr().(AssignExpr).getSource() = node1.asExpr()
|
||||
or
|
||||
summaryStep(node1, node2, "value")
|
||||
or
|
||||
exists(MethodAccess ma, ValuePreservingMethod m, int argNo |
|
||||
ma.getCallee().getSourceDeclaration() = m and m.returnsValue(argNo)
|
||||
|
|
||||
|
||||
@@ -57,16 +57,14 @@ private predicate localAdditionalBasicTaintStep(DataFlow::Node src, DataFlow::No
|
||||
localAdditionalTaintUpdateStep(src.asExpr(),
|
||||
sink.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr())
|
||||
or
|
||||
summaryStep(src, sink, "taint") and
|
||||
not summaryStep(src, sink, "value")
|
||||
or
|
||||
exists(Argument arg |
|
||||
src.asExpr() = arg and
|
||||
arg.isVararg() and
|
||||
sink.(DataFlow::ImplicitVarargsArray).getCall() = arg.getCall()
|
||||
)
|
||||
or
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false)
|
||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, false) and
|
||||
not FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, true)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user