Skip to content

Commit 31bed36

Browse files
authored
Merge pull request github#13612 from asgerf/rb/api-graph-explicit-proc-lambda
Ruby: Improve support for explicit proc-creation
2 parents 1c8297b + 18762db commit 31bed36

File tree

4 files changed

+31
-1
lines changed

4 files changed

+31
-1
lines changed

ruby/ql/lib/codeql/ruby/ApiGraphs.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,12 @@ module API {
978978
pred = Impl::MkModuleInstanceUp(mod) and
979979
succ = getBackwardEndNode(mod.getOwnInstanceMethod("call"))
980980
)
981+
or
982+
// Step through callable wrappers like `proc` and `lambda` calls.
983+
exists(DataFlow::Node node |
984+
pred = getBackwardEndNode(node) and
985+
succ = getBackwardStartNode(node.asCallable())
986+
)
981987
}
982988

983989
pragma[nomagic]

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1333,11 +1333,20 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
13331333
creation.asExpr() =
13341334
any(CfgNodes::ExprNodes::MethodCallCfgNode mc |
13351335
c.asCallable() = mc.getBlock().getExpr() and
1336-
mc.getExpr().getMethodName() = ["lambda", "proc"]
1336+
isProcCreationCall(mc.getExpr())
13371337
)
13381338
)
13391339
}
13401340

1341+
/** Holds if `call` is a call to `lambda`, `proc`, or `Proc.new` */
1342+
pragma[nomagic]
1343+
private predicate isProcCreationCall(MethodCall call) {
1344+
call.getMethodName() = ["proc", "lambda"]
1345+
or
1346+
call.getMethodName() = "new" and
1347+
call.getReceiver().(ConstantReadAccess).getAQualifiedName() = "Proc"
1348+
}
1349+
13411350
/**
13421351
* Holds if `call` is a from-source lambda call of kind `kind` where `receiver`
13431352
* is the lambda expression.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Improved resolution of calls performed on an object created with `Proc.new`.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Foo.bar proc { |x|
2+
x # $ reachableFromSource=Member[Foo].Method[bar].Argument[0].Parameter[0]
3+
}
4+
5+
Foo.bar lambda { |x|
6+
x # $ reachableFromSource=Member[Foo].Method[bar].Argument[0].Parameter[0]
7+
}
8+
9+
Foo.bar Proc.new { |x|
10+
x # $ reachableFromSource=Member[Foo].Method[bar].Argument[0].Parameter[0]
11+
}

0 commit comments

Comments
 (0)