mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Merge pull request #12906 from hvitved/ruby/track-block-no-self
Ruby: Prevent flow into `self` in `trackBlock`
This commit is contained in:
@@ -191,13 +191,7 @@ private predicate moduleFlowsToMethodCallReceiver(RelevantCall call, Module m, s
|
||||
flowsToMethodCallReceiver(call, trackModuleAccess(m), method)
|
||||
}
|
||||
|
||||
private Block yieldCall(RelevantCall call) {
|
||||
call.getExpr() instanceof YieldCall and
|
||||
exists(BlockParameterNode node |
|
||||
node = trackBlock(result) and
|
||||
node.getMethod() = call.getExpr().getEnclosingMethod()
|
||||
)
|
||||
}
|
||||
private Block blockCall(RelevantCall call) { lambdaSourceCall(call, _, trackBlock(result)) }
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate superCall(RelevantCall call, Module cls, string method) {
|
||||
@@ -297,7 +291,7 @@ predicate isUserDefinedNew(SingletonMethod new) {
|
||||
|
||||
private Callable viableSourceCallableNonInit(RelevantCall call) {
|
||||
result = getTarget(call) and
|
||||
not call.getExpr() instanceof YieldCall // handled by `lambdaCreation`/`lambdaCall`
|
||||
not result = blockCall(call) // handled by `lambdaCreation`/`lambdaCall`
|
||||
}
|
||||
|
||||
private Callable viableSourceCallableInit(RelevantCall call) { result = getInitializeTarget(call) }
|
||||
@@ -394,7 +388,7 @@ private module Cached {
|
||||
result = lookupMethod(cls.getAnImmediateAncestor(), method)
|
||||
)
|
||||
or
|
||||
result = yieldCall(call)
|
||||
result = blockCall(call)
|
||||
}
|
||||
|
||||
/** Gets a viable run-time target for the call `call`. */
|
||||
@@ -700,13 +694,19 @@ private DataFlow::LocalSourceNode trackBlock(Block block, TypeTracker t) {
|
||||
t.start() and result.asExpr().getExpr() = block
|
||||
or
|
||||
exists(TypeTracker t2, StepSummary summary |
|
||||
result = trackBlockRec(block, t2, summary) and t = t2.append(summary)
|
||||
result = trackBlockRec(block, t2, summary) and
|
||||
t = t2.append(summary)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* We exclude steps into `self` parameters, which may happen when the code
|
||||
* base contains implementations of `call`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private DataFlow::LocalSourceNode trackBlockRec(Block block, TypeTracker t, StepSummary summary) {
|
||||
StepSummary::step(trackBlock(block, t), result, summary)
|
||||
StepSummary::step(trackBlock(block, t), result, summary) and
|
||||
not result instanceof SelfParameterNode
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
|
||||
@@ -1377,18 +1377,28 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */
|
||||
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
/**
|
||||
* Holds if `call` is a from-source lambda call of kind `kind` where `receiver`
|
||||
* is the lambda expression.
|
||||
*/
|
||||
predicate lambdaSourceCall(CfgNodes::ExprNodes::CallCfgNode call, LambdaCallKind kind, Node receiver) {
|
||||
kind = TYieldCallKind() and
|
||||
receiver.(BlockParameterNode).getMethod() =
|
||||
call.asCall().getExpr().(YieldCall).getEnclosingMethod()
|
||||
receiver.(BlockParameterNode).getMethod() = call.getExpr().(YieldCall).getEnclosingMethod()
|
||||
or
|
||||
kind = TLambdaCallKind() and
|
||||
call.asCall() =
|
||||
call =
|
||||
any(CfgNodes::ExprNodes::MethodCallCfgNode mc |
|
||||
receiver.asExpr() = mc.getReceiver() and
|
||||
mc.getExpr().getMethodName() = "call"
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `call` is a (from-source or from-summary) lambda call of kind `kind`
|
||||
* where `receiver` is the lambda expression.
|
||||
*/
|
||||
predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver) {
|
||||
lambdaSourceCall(call.asCall(), kind, receiver)
|
||||
or
|
||||
receiver = call.(SummaryCall).getReceiver() and
|
||||
if receiver.(ParameterNodeImpl).isParameterOf(_, any(ParameterPosition pos | pos.isBlock()))
|
||||
|
||||
Reference in New Issue
Block a user