Ruby: Implement ParameterPosition et al

This commit is contained in:
Tom Hvitved
2021-11-30 16:07:24 +01:00
parent ae6501d906
commit bb8f4bb7c1
4 changed files with 39 additions and 5 deletions

View File

@@ -119,7 +119,7 @@ private class SummarizedCallableAdapter extends Impl::Public::SummarizedCallable
sc.propagatesFlow(input, output, preservesValue)
}
final override predicate clearsContent(int i, DataFlow::Content content) {
final override predicate clearsContent(ParameterPosition i, DataFlow::Content content) {
sc.clearsContent(i, content)
}
}

View File

@@ -457,3 +457,19 @@ predicate exprNodeReturnedFrom(DataFlow::ExprNode e, Callable c) {
)
)
}
private int parameterPosition() { result in [-2 .. max([any(Parameter p).getPosition(), 10])] }
/** A parameter position represented by an integer. */
class ParameterPosition extends int {
ParameterPosition() { this = parameterPosition() }
}
/** An argument position represented by an integer. */
class ArgumentPosition extends int {
ArgumentPosition() { this = parameterPosition() }
}
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
pragma[inline]
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }

View File

@@ -10,10 +10,15 @@ private import FlowSummaryImpl as FlowSummaryImpl
DataFlowCallable nodeGetEnclosingCallable(NodeImpl n) { result = n.getEnclosingCallable() }
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
predicate isParameterNode(ParameterNodeImpl p, DataFlowCallable c, int pos) {
predicate isParameterNode(ParameterNodeImpl p, DataFlowCallable c, ParameterPosition pos) {
p.isParameterOf(c, pos)
}
/** Holds if `arg` is an `ArgumentNode` of `c` with position `pos`. */
predicate isArgumentNode(ArgumentNode arg, DataFlowCall c, ArgumentPosition pos) {
arg.argumentOf(c, pos)
}
abstract class NodeImpl extends Node {
DataFlowCallable getEnclosingCallable() { result = TCfgScope(this.getCfgScope()) }

View File

@@ -11,9 +11,6 @@ private import FlowSummaryImpl::Private
private import FlowSummaryImpl::Public
private import codeql.ruby.dataflow.FlowSummary as FlowSummary
/** Holds is `i` is a valid parameter position. */
predicate parameterPosition(int i) { i in [-2 .. 10] }
/** Gets the parameter position of the instance parameter. */
int instanceParameterPosition() { none() } // disables implicit summary flow to `self` for callbacks
@@ -123,3 +120,19 @@ private module UnusedSourceSinkInterpretation {
}
import UnusedSourceSinkInterpretation
/** Gets the argument position obtained by parsing `X` in `Parameter[X]`. */
bindingset[s]
ArgumentPosition parseParamBody(string s) {
result = s.regexpCapture("([-0-9]+)", 1).toInt()
or
exists(int n1, int n2 |
s.regexpCapture("([-0-9]+)\\.\\.([0-9]+)", 1).toInt() = n1 and
s.regexpCapture("([-0-9]+)\\.\\.([0-9]+)", 2).toInt() = n2 and
result in [n1 .. n2]
)
}
/** Gets the parameter position obtained by parsing `X` in `Argument[X]`. */
bindingset[s]
ParameterPosition parseArgBody(string s) { result = parseParamBody(s) }