Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions ruby/ql/lib/codeql/ruby/ast/internal/Module.qll
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ private TMethodOrExpr lookupMethodOrConst(Module m, string name) {
// For now, we restrict the scope of top-level declarations to their file.
// This may remove some plausible targets, but also removes a lot of
// implausible targets
if getNode(result).getEnclosingModule() instanceof Toplevel
then getNode(result).getFile() = m.getADeclaration().getFile()
else any()
forall(File file | file = getNode(result).getEnclosingModule().(Toplevel).getFile() |
file = m.getADeclaration().getFile()
)
}
14 changes: 11 additions & 3 deletions ruby/ql/lib/codeql/ruby/ast/internal/Scope.qll
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@
private module Cached {
/** Gets the enclosing scope of a node */
cached
Scope::Range scopeOf(Ruby::AstNode n) {
Scope::Range scopeOfImpl(Ruby::AstNode n) {
exists(Ruby::AstNode p | p = parentOf(n) |
p = result
or
Expand All @@ -163,7 +163,7 @@
* and synthesized scopes into account.
*/
cached
Scope scopeOfInclSynth(AstNode n) {
Scope scopeOfInclSynthImpl(AstNode n) {
exists(AstNode p | p = parentOfInclSynth(n) |
p = result
or
Expand All @@ -172,7 +172,15 @@
}
}

import Cached
pragma[inline]
Scope::Range scopeOf(Ruby::AstNode n) {

Check warning

Code scanning / CodeQL

Cannot inline predicate across overlay frontier Warning

This possibly local non-private inline predicate will not be inlined across the overlay frontier. This may negatively affect evaluation performance. Consider adding an overlay[caller] or overlay[caller?] annotation to allow inlining across the overlay frontier. Note that adding an overlay[caller] or overlay[caller?] annotation affects semantics under overlay evaluation.
pragma[only_bind_into](result) = Cached::scopeOfImpl(pragma[only_bind_out](n))
}

pragma[inline]
Scope scopeOfInclSynth(AstNode n) {

Check warning

Code scanning / CodeQL

Cannot inline predicate across overlay frontier Warning

This possibly local non-private inline predicate will not be inlined across the overlay frontier. This may negatively affect evaluation performance. Consider adding an overlay[caller] or overlay[caller?] annotation to allow inlining across the overlay frontier. Note that adding an overlay[caller] or overlay[caller?] annotation affects semantics under overlay evaluation.
pragma[only_bind_into](result) = Cached::scopeOfInclSynthImpl(pragma[only_bind_out](n))
}

abstract class ScopeImpl extends AstNode, TScopeType {
final Scope getOuterScopeImpl() { result = scopeOfInclSynth(this) }
Expand Down
38 changes: 21 additions & 17 deletions ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowDispatch.qll
Original file line number Diff line number Diff line change
Expand Up @@ -687,26 +687,30 @@ pragma[nomagic]
private CfgScope getTargetInstance(DataFlowCall call, string method) {
exists(boolean exact |
result = lookupInstanceMethodCall(call, method, exact) and
(
if result.(Method).isPrivate()
then
call.asCall().getReceiver().getExpr() instanceof SelfVariableAccess and
// For now, we restrict the scope of top-level declarations to their file.
// This may remove some plausible targets, but also removes a lot of
// implausible targets
(
isToplevelMethodInFile(result, call.asCall().getFile()) or
not isToplevelMethodInFile(result, _)
)
else any()
) and
if result.(Method).isProtected()
then
result = lookupMethod(call.asCall().getExpr().getEnclosingModule().getModule(), method, exact)
else any()
(if result.(Method).isPrivate() then result = privateFilter(call) else any()) and
if result.(Method).isProtected() then result = protectedFilter(call, method, exact) else any()
)
}

bindingset[call, result]
pragma[inline_late]
private CfgScope privateFilter(DataFlowCall call) {
call.asCall().getReceiver().getExpr() instanceof SelfVariableAccess and
// For now, we restrict the scope of top-level declarations to their file.
// This may remove some plausible targets, but also removes a lot of
// implausible targets
(
isToplevelMethodInFile(result, call.asCall().getFile()) or
not isToplevelMethodInFile(result, _)
)
}

bindingset[call, method, exact, result]
pragma[inline_late]
private CfgScope protectedFilter(DataFlowCall call, string method, boolean exact) {
result = lookupMethod(call.asCall().getExpr().getEnclosingModule().getModule(), method, exact)
}

private module TrackBlockInput implements CallGraphConstruction::Simple::InputSig {
class State = Block;

Expand Down
46 changes: 26 additions & 20 deletions ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPrivate.qll
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ abstract class NodeImpl extends Node {
DataFlowCallable getEnclosingCallable() { result = TCfgScope(this.getCfgScope()) }

/** Do not call: use `getEnclosingCallable()` instead. */
abstract CfgScope getCfgScope();
abstract CfgScope getCfgScopeImpl();

/** Do not call: use `getEnclosingCallable()` instead. */
pragma[inline]
final CfgScope getCfgScope() {
pragma[only_bind_into](result) = pragma[only_bind_out](this).getCfgScopeImpl()
}

/** Do not call: use `getLocation()` instead. */
abstract Location getLocationImpl();
Expand All @@ -38,7 +44,7 @@ abstract class NodeImpl extends Node {
}

private class ExprNodeImpl extends ExprNode, NodeImpl {
override CfgScope getCfgScope() { result = this.getExprNode().getExpr().getCfgScope() }
override CfgScope getCfgScopeImpl() { result = this.getExprNode().getExpr().getCfgScope() }

override Location getLocationImpl() { result = this.getExprNode().getLocation() }

Expand Down Expand Up @@ -780,7 +786,7 @@ class SsaNode extends NodeImpl, TSsaNode {
/** Holds if this node should be hidden from path explanations. */
predicate isHidden() { any() }

override CfgScope getCfgScope() { result = node.getBasicBlock().getScope() }
override CfgScope getCfgScopeImpl() { result = node.getBasicBlock().getScope() }

override Location getLocationImpl() { result = node.getLocation() }

Expand Down Expand Up @@ -827,7 +833,7 @@ class CapturedVariableNode extends NodeImpl, TCapturedVariableNode {
/** Gets the captured variable represented by this node. */
VariableCapture::CapturedVariable getVariable() { result = variable }

override CfgScope getCfgScope() { result = variable.getCallable() }
override CfgScope getCfgScopeImpl() { result = variable.getCallable() }

override Location getLocationImpl() { result = variable.getLocation() }

Expand All @@ -849,7 +855,7 @@ class ReturningStatementNode extends NodeImpl, TReturningNode {
/** Gets the expression corresponding to this node. */
CfgNodes::ReturningCfgNode getReturningNode() { result = n }

override CfgScope getCfgScope() { result = n.getScope() }
override CfgScope getCfgScopeImpl() { result = n.getScope() }

override Location getLocationImpl() { result = n.getLocation() }

Expand All @@ -867,7 +873,7 @@ class CaptureNode extends NodeImpl, TCaptureNode {

VariableCapture::Flow::SynthesizedCaptureNode getSynthesizedCaptureNode() { result = cn }

override CfgScope getCfgScope() { result = cn.getEnclosingCallable() }
override CfgScope getCfgScopeImpl() { result = cn.getEnclosingCallable() }

override Location getLocationImpl() { result = cn.getLocation() }

Expand Down Expand Up @@ -935,7 +941,7 @@ private module ParameterNodes {
)
}

override CfgScope getCfgScope() { result = parameter.getCallable() }
override CfgScope getCfgScopeImpl() { result = parameter.getCallable() }

override Location getLocationImpl() { result = parameter.getLocation() }

Expand Down Expand Up @@ -979,7 +985,7 @@ private module ParameterNodes {

final override SelfVariable getSelfVariable() { result.getDeclaringScope() = method }

override CfgScope getCfgScope() { result = method }
override CfgScope getCfgScopeImpl() { result = method }

override Location getLocationImpl() { result = method.getLocation() }
}
Expand All @@ -1001,7 +1007,7 @@ private module ParameterNodes {

final override SelfVariable getSelfVariable() { result.getDeclaringScope() = t }

override CfgScope getCfgScope() { result = t }
override CfgScope getCfgScopeImpl() { result = t }

override Location getLocationImpl() { result = t.getLocation() }
}
Expand All @@ -1028,7 +1034,7 @@ private module ParameterNodes {
callable = c.asCfgScope() and pos.isLambdaSelf()
}

override CfgScope getCfgScope() { result = callable }
override CfgScope getCfgScopeImpl() { result = callable }

override Location getLocationImpl() { result = callable.getLocation() }

Expand Down Expand Up @@ -1071,7 +1077,7 @@ private module ParameterNodes {
c.asCfgScope() = method and pos.isBlock()
}

override CfgScope getCfgScope() { result = method }
override CfgScope getCfgScopeImpl() { result = method }

override Location getLocationImpl() {
result = this.getParameter().getLocation()
Expand Down Expand Up @@ -1130,7 +1136,7 @@ private module ParameterNodes {
c = callable and pos.isSynthHashSplat()
}

final override CfgScope getCfgScope() { result = callable.asCfgScope() }
final override CfgScope getCfgScopeImpl() { result = callable.asCfgScope() }

final override DataFlowCallable getEnclosingCallable() { result = callable }

Expand Down Expand Up @@ -1193,7 +1199,7 @@ private module ParameterNodes {
)
}

final override CfgScope getCfgScope() { result = callable.asCfgScope() }
final override CfgScope getCfgScopeImpl() { result = callable.asCfgScope() }

final override DataFlowCallable getEnclosingCallable() { result = callable }

Expand Down Expand Up @@ -1240,7 +1246,7 @@ private module ParameterNodes {
cs = getArrayContent(pos)
}

final override CfgScope getCfgScope() { result = callable.asCfgScope() }
final override CfgScope getCfgScopeImpl() { result = callable.asCfgScope() }

final override DataFlowCallable getEnclosingCallable() { result = callable }

Expand Down Expand Up @@ -1278,7 +1284,7 @@ class FlowSummaryNode extends NodeImpl, TFlowSummaryNode {
result = this.getSummaryNode().getSummarizedCallable()
}

override CfgScope getCfgScope() { none() }
override CfgScope getCfgScopeImpl() { none() }

override DataFlowCallable getEnclosingCallable() {
result.asLibraryCallable() = this.getSummarizedCallable()
Expand Down Expand Up @@ -1349,7 +1355,7 @@ module ArgumentNodes {
this.sourceArgumentOf(call.asCall(), pos)
}

override CfgScope getCfgScope() { result = yield.getScope() }
override CfgScope getCfgScopeImpl() { result = yield.getScope() }

override Location getLocationImpl() { result = yield.getLocation() }
}
Expand Down Expand Up @@ -1379,7 +1385,7 @@ module ArgumentNodes {
this.sourceArgumentOf(call.asCall(), pos)
}

override CfgScope getCfgScope() { result = sup.getScope() }
override CfgScope getCfgScopeImpl() { result = sup.getScope() }

override Location getLocationImpl() { result = sup.getLocation() }
}
Expand Down Expand Up @@ -1415,7 +1421,7 @@ module ArgumentNodes {
this.sourceArgumentOf(call.asCall(), pos)
}

final override CfgScope getCfgScope() { result = call_.getExpr().getCfgScope() }
final override CfgScope getCfgScopeImpl() { result = call_.getExpr().getCfgScope() }

final override Location getLocationImpl() { result = call_.getLocation() }
}
Expand Down Expand Up @@ -1563,7 +1569,7 @@ module ArgumentNodes {
)
}

override CfgScope getCfgScope() { result = c.getExpr().getCfgScope() }
override CfgScope getCfgScopeImpl() { result = c.getExpr().getCfgScope() }

override Location getLocationImpl() { result = c.getLocation() }

Expand Down Expand Up @@ -2074,7 +2080,7 @@ private module PostUpdateNodes {

override ExprNode getPreUpdateNode() { e = result.getExprNode() }

override CfgScope getCfgScope() { result = e.getExpr().getCfgScope() }
override CfgScope getCfgScopeImpl() { result = e.getExpr().getCfgScope() }

override Location getLocationImpl() { result = e.getLocation() }

Expand Down
Loading
Loading