Skip to content

Commit 5b50d20

Browse files
committed
temp
1 parent 7e42f39 commit 5b50d20

File tree

16 files changed

+441
-279
lines changed

16 files changed

+441
-279
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ module Ssa {
178178

179179
/** Gets the location of this SSA definition. */
180180
Location getLocation() { result = this.getControlFlowNode().getLocation() }
181+
182+
/** Gets the scope of this SSA definition. */
183+
CfgScope getScope() { result = this.getBasicBlock().getScope() }
181184
}
182185

183186
/**
@@ -289,7 +292,7 @@ module Ssa {
289292
)
290293
}
291294

292-
final override string toString() { result = "<captured> " + this.getSourceVariable() }
295+
final override string toString() { result = "<captured entry> " + this.getSourceVariable() }
293296

294297
override Location getLocation() { result = this.getBasicBlock().getLocation() }
295298
}
@@ -324,7 +327,7 @@ module Ssa {
324327
*/
325328
final Definition getPriorDefinition() { result = SsaImpl::uncertainWriteDefinitionInput(this) }
326329

327-
override string toString() { result = this.getControlFlowNode().toString() }
330+
override string toString() { result = "<captured exit> " + this.getSourceVariable() }
328331
}
329332

330333
/**

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

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,17 @@ private import FlowSummaryImpl as FlowSummaryImpl
88
private import FlowSummaryImplSpecific as FlowSummaryImplSpecific
99
private import codeql.ruby.dataflow.FlowSummary
1010
private import codeql.ruby.dataflow.SSA
11+
private import codeql.ruby.dataflow.internal.SsaImpl as SsaImpl
1112

1213
newtype TReturnKind =
1314
TNormalReturnKind() or
14-
TBreakReturnKind()
15+
TBreakReturnKind() or
16+
TCapturedReturnKind(LocalVariable v) {
17+
exists(Ssa::Definition def |
18+
SsaImpl::captureFlowOut(_, def, _) and
19+
v = def.getSourceVariable()
20+
)
21+
}
1522

1623
/**
1724
* Gets a node that can read the value returned from `call` with return kind
@@ -43,6 +50,19 @@ class BreakReturnKind extends ReturnKind, TBreakReturnKind {
4350
override string toString() { result = "break" }
4451
}
4552

53+
/**
54+
* A value implicitly returned by updating a captured variable.
55+
*/
56+
class CapturedReturnKind extends ReturnKind, TCapturedReturnKind {
57+
LocalVariable v;
58+
59+
CapturedReturnKind() { this = TCapturedReturnKind(v) }
60+
61+
LocalVariable getVariable() { result = v }
62+
63+
override string toString() { result = "captured write to " + v }
64+
}
65+
4666
/** A callable defined in library code, identified by a unique string. */
4767
abstract class LibraryCallable extends string {
4868
bindingset[this]
@@ -151,6 +171,33 @@ private class NormalCall extends DataFlowCall, TNormalCall {
151171
override Location getLocation() { result = c.getLocation() }
152172
}
153173

174+
/**
175+
* A call that may ultimately reach a callable, which reads or updates
176+
* (contents of) a captured variable.
177+
*/
178+
class CapturedCall extends DataFlowCall, TCapturedCall {
179+
private CfgNodes::ExprNodes::CallCfgNode c;
180+
181+
CapturedCall() { this = TCapturedCall(c) }
182+
183+
/** Gets a target, in which a captured variable is referenced. */
184+
Callable getATarget() {
185+
exists(Ssa::Definition def | result = def.getScope() |
186+
SsaImpl::captureFlowIn(c, _, _, _, def)
187+
or
188+
SsaImpl::captureFlowOut(c, def, _)
189+
)
190+
}
191+
192+
override CfgNodes::ExprNodes::CallCfgNode asCall() { none() }
193+
194+
override DataFlowCallable getEnclosingCallable() { result = TCfgScope(c.getScope()) }
195+
196+
override string toString() { result = "<captured> " + c.toString() }
197+
198+
override Location getLocation() { result = c.getLocation() }
199+
}
200+
154201
/** A call for which we want to compute call targets. */
155202
private class RelevantCall extends CfgNodes::ExprNodes::CallCfgNode {
156203
pragma[nomagic]
@@ -341,6 +388,11 @@ private module Cached {
341388
TNormalCall(CfgNodes::ExprNodes::CallCfgNode c) or
342389
TSummaryCall(FlowSummaryImpl::Public::SummarizedCallable c, DataFlow::Node receiver) {
343390
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
391+
} or
392+
TCapturedCall(CfgNodes::ExprNodes::CallCfgNode c) {
393+
SsaImpl::captureFlowIn(c, _, _, _, _)
394+
or
395+
SsaImpl::captureFlowOut(c, _, _)
344396
}
345397

346398
pragma[nomagic]
@@ -478,6 +530,8 @@ private module Cached {
478530
result = viableSourceCallable(call)
479531
or
480532
result = viableLibraryCallable(call)
533+
or
534+
result.asCallable() = call.(CapturedCall).getATarget()
481535
}
482536

483537
cached
@@ -499,7 +553,13 @@ private module Cached {
499553
THashSplatArgumentPosition() or
500554
TSplatAllArgumentPosition() or
501555
TAnyArgumentPosition() or
502-
TAnyKeywordArgumentPosition()
556+
TAnyKeywordArgumentPosition() or
557+
TCapturedArgumentPosition(LocalVariable v) {
558+
exists(Ssa::Definition def |
559+
SsaImpl::captureFlowIn(_, _, _, _, def) and
560+
v = def.getSourceVariable()
561+
)
562+
}
503563

504564
cached
505565
newtype TParameterPosition =
@@ -521,7 +581,13 @@ private module Cached {
521581
THashSplatParameterPosition() or
522582
TSplatAllParameterPosition() or
523583
TAnyParameterPosition() or
524-
TAnyKeywordParameterPosition()
584+
TAnyKeywordParameterPosition() or
585+
TCapturedParameterPosition(LocalVariable v) {
586+
exists(Ssa::Definition def |
587+
SsaImpl::captureFlowIn(_, _, _, _, def) and
588+
v = def.getSourceVariable()
589+
)
590+
}
525591
}
526592

527593
import Cached
@@ -921,7 +987,7 @@ private predicate paramReturnFlow(
921987
DataFlow::Node nodeFrom, DataFlow::PostUpdateNode nodeTo, StepSummary summary
922988
) {
923989
exists(RelevantCall call, DataFlow::Node arg, DataFlow::ParameterNode p, Expr nodeFromPreExpr |
924-
TypeTrackerSpecific::callStep(call, arg, p) and
990+
TypeTrackerSpecific::callStep(TNormalCall(call), arg, p) and
925991
nodeTo.getPreUpdateNode() = arg and
926992
summary.toString() = "return" and
927993
(
@@ -1151,6 +1217,9 @@ class ParameterPosition extends TParameterPosition {
11511217
/** Holds if this position represents any positional parameter. */
11521218
predicate isAnyNamed() { this = TAnyKeywordParameterPosition() }
11531219

1220+
/** Holds if this position represents a captured variable `v`. */
1221+
predicate isCapturedVariable(LocalVariable v) { this = TCapturedParameterPosition(v) }
1222+
11541223
/** Gets a textual representation of this position. */
11551224
string toString() {
11561225
this.isSelf() and result = "self"
@@ -1170,6 +1239,8 @@ class ParameterPosition extends TParameterPosition {
11701239
this.isAny() and result = "any"
11711240
or
11721241
this.isAnyNamed() and result = "any-named"
1242+
or
1243+
exists(LocalVariable v | this.isCapturedVariable(v) and result = "captured " + v)
11731244
}
11741245
}
11751246

@@ -1196,6 +1267,9 @@ class ArgumentPosition extends TArgumentPosition {
11961267
/** Holds if this position represents any positional parameter. */
11971268
predicate isAnyNamed() { this = TAnyKeywordArgumentPosition() }
11981269

1270+
/** Holds if this position represents a captured variable `v`. */
1271+
predicate isCapturedVariable(LocalVariable v) { this = TCapturedArgumentPosition(v) }
1272+
11991273
/**
12001274
* Holds if this position represents a synthesized argument containing all keyword
12011275
* arguments wrapped in a hash.
@@ -1221,6 +1295,8 @@ class ArgumentPosition extends TArgumentPosition {
12211295
this.isHashSplat() and result = "**"
12221296
or
12231297
this.isSplatAll() and result = "*"
1298+
or
1299+
exists(LocalVariable v | this.isCapturedVariable(v) and result = "captured " + v)
12241300
}
12251301
}
12261302

@@ -1256,4 +1332,6 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) {
12561332
ppos.isAnyNamed() and apos.isKeyword(_)
12571333
or
12581334
apos.isAnyNamed() and ppos.isKeyword(_)
1335+
or
1336+
exists(LocalVariable v | apos.isCapturedVariable(v) and ppos.isCapturedVariable(v))
12591337
}

0 commit comments

Comments
 (0)