Skip to content

Commit bb8f4bb

Browse files
committed
Ruby: Implement ParameterPosition et al
1 parent ae6501d commit bb8f4bb

File tree

4 files changed

+39
-5
lines changed

4 files changed

+39
-5
lines changed

ruby/ql/lib/codeql/ruby/dataflow/FlowSummary.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ private class SummarizedCallableAdapter extends Impl::Public::SummarizedCallable
119119
sc.propagatesFlow(input, output, preservesValue)
120120
}
121121

122-
final override predicate clearsContent(int i, DataFlow::Content content) {
122+
final override predicate clearsContent(ParameterPosition i, DataFlow::Content content) {
123123
sc.clearsContent(i, content)
124124
}
125125
}

ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,3 +457,19 @@ predicate exprNodeReturnedFrom(DataFlow::ExprNode e, Callable c) {
457457
)
458458
)
459459
}
460+
461+
private int parameterPosition() { result in [-2 .. max([any(Parameter p).getPosition(), 10])] }
462+
463+
/** A parameter position represented by an integer. */
464+
class ParameterPosition extends int {
465+
ParameterPosition() { this = parameterPosition() }
466+
}
467+
468+
/** An argument position represented by an integer. */
469+
class ArgumentPosition extends int {
470+
ArgumentPosition() { this = parameterPosition() }
471+
}
472+
473+
/** Holds if arguments at position `apos` match parameters at position `ppos`. */
474+
pragma[inline]
475+
predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) { ppos = apos }

ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@ private import FlowSummaryImpl as FlowSummaryImpl
1010
DataFlowCallable nodeGetEnclosingCallable(NodeImpl n) { result = n.getEnclosingCallable() }
1111

1212
/** Holds if `p` is a `ParameterNode` of `c` with position `pos`. */
13-
predicate isParameterNode(ParameterNodeImpl p, DataFlowCallable c, int pos) {
13+
predicate isParameterNode(ParameterNodeImpl p, DataFlowCallable c, ParameterPosition pos) {
1414
p.isParameterOf(c, pos)
1515
}
1616

17+
/** Holds if `arg` is an `ArgumentNode` of `c` with position `pos`. */
18+
predicate isArgumentNode(ArgumentNode arg, DataFlowCall c, ArgumentPosition pos) {
19+
arg.argumentOf(c, pos)
20+
}
21+
1722
abstract class NodeImpl extends Node {
1823
DataFlowCallable getEnclosingCallable() { result = TCfgScope(this.getCfgScope()) }
1924

ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImplSpecific.qll

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ private import FlowSummaryImpl::Private
1111
private import FlowSummaryImpl::Public
1212
private import codeql.ruby.dataflow.FlowSummary as FlowSummary
1313

14-
/** Holds is `i` is a valid parameter position. */
15-
predicate parameterPosition(int i) { i in [-2 .. 10] }
16-
1714
/** Gets the parameter position of the instance parameter. */
1815
int instanceParameterPosition() { none() } // disables implicit summary flow to `self` for callbacks
1916

@@ -123,3 +120,19 @@ private module UnusedSourceSinkInterpretation {
123120
}
124121

125122
import UnusedSourceSinkInterpretation
123+
124+
/** Gets the argument position obtained by parsing `X` in `Parameter[X]`. */
125+
bindingset[s]
126+
ArgumentPosition parseParamBody(string s) {
127+
result = s.regexpCapture("([-0-9]+)", 1).toInt()
128+
or
129+
exists(int n1, int n2 |
130+
s.regexpCapture("([-0-9]+)\\.\\.([0-9]+)", 1).toInt() = n1 and
131+
s.regexpCapture("([-0-9]+)\\.\\.([0-9]+)", 2).toInt() = n2 and
132+
result in [n1 .. n2]
133+
)
134+
}
135+
136+
/** Gets the parameter position obtained by parsing `X` in `Argument[X]`. */
137+
bindingset[s]
138+
ParameterPosition parseArgBody(string s) { result = parseParamBody(s) }

0 commit comments

Comments
 (0)