mirror of
https://github.com/github/codeql.git
synced 2026-04-23 07:45:17 +02:00
Merge pull request #15260 from hvitved/dataflow/may-benefit-from-cctx-simplify
Data flow: Remove column from `mayBenefitFromCallContext`
This commit is contained in:
@@ -1088,8 +1088,8 @@ private CfgScope getTargetSingleton(RelevantCall call, string method) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ctx` targets `encl`, which is the enclosing callable of `call`, the receiver
|
||||
* of `call` is a parameter access, where the corresponding argument of `ctx` is `arg`.
|
||||
* Holds if `ctx` targets the enclosing callable of `call`, the receiver of `call` is a
|
||||
* parameter access, where the corresponding argument of `ctx` is `arg`.
|
||||
*
|
||||
* `name` is the name of the method being called by `call`, `source` is a
|
||||
* `LocalSourceNode` that flows to `arg`, and `paramDef` is the SSA definition for the
|
||||
@@ -1098,11 +1098,11 @@ private CfgScope getTargetSingleton(RelevantCall call, string method) {
|
||||
pragma[nomagic]
|
||||
private predicate argMustFlowToReceiver(
|
||||
RelevantCall ctx, DataFlow::LocalSourceNode source, DataFlow::Node arg, RelevantCall call,
|
||||
Callable encl, string name
|
||||
string name
|
||||
) {
|
||||
exists(
|
||||
ParameterNodeImpl p, SsaDefinitionExtNode paramDef, ParameterPosition ppos,
|
||||
ArgumentPosition apos
|
||||
ArgumentPosition apos, Callable encl
|
||||
|
|
||||
// the receiver of `call` references `p`
|
||||
exists(DataFlow::Node receiver |
|
||||
@@ -1133,7 +1133,7 @@ private predicate argMustFlowToReceiver(
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ctx` targets `encl`, which is the enclosing callable of `new`, and
|
||||
* Holds if `ctx` targets the enclosing callable of `new`, and
|
||||
* the receiver of `new` is a parameter access, where the corresponding argument
|
||||
* `arg` of `ctx` has type `tp`.
|
||||
*
|
||||
@@ -1141,10 +1141,10 @@ private predicate argMustFlowToReceiver(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate mayBenefitFromCallContextInitialize(
|
||||
RelevantCall ctx, RelevantCall new, DataFlow::Node arg, Callable encl, Module tp, string name
|
||||
RelevantCall ctx, RelevantCall new, DataFlow::Node arg, Module tp, string name
|
||||
) {
|
||||
exists(DataFlow::LocalSourceNode source |
|
||||
argMustFlowToReceiver(ctx, pragma[only_bind_into](source), arg, new, encl, "new") and
|
||||
argMustFlowToReceiver(ctx, pragma[only_bind_into](source), arg, new, "new") and
|
||||
source = trackModuleAccess(tp) and
|
||||
name = "initialize" and
|
||||
exists(lookupMethod(tp, name))
|
||||
@@ -1152,7 +1152,7 @@ private predicate mayBenefitFromCallContextInitialize(
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ctx` targets `encl`, which is the enclosing callable of `call`, and
|
||||
* Holds if `ctx` targets the enclosing callable of `call`, and
|
||||
* the receiver of `call` is a parameter access, where the corresponding argument
|
||||
* `arg` of `ctx` has type `tp`.
|
||||
*
|
||||
@@ -1161,11 +1161,10 @@ private predicate mayBenefitFromCallContextInitialize(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate mayBenefitFromCallContextInstance(
|
||||
RelevantCall ctx, RelevantCall call, DataFlow::Node arg, Callable encl, Module tp, boolean exact,
|
||||
string name
|
||||
RelevantCall ctx, RelevantCall call, DataFlow::Node arg, Module tp, boolean exact, string name
|
||||
) {
|
||||
exists(DataFlow::LocalSourceNode source |
|
||||
argMustFlowToReceiver(ctx, pragma[only_bind_into](source), arg, call, encl,
|
||||
argMustFlowToReceiver(ctx, pragma[only_bind_into](source), arg, call,
|
||||
pragma[only_bind_into](name)) and
|
||||
source = trackInstance(tp, exact) and
|
||||
exists(lookupMethod(tp, pragma[only_bind_into](name)))
|
||||
@@ -1173,7 +1172,7 @@ private predicate mayBenefitFromCallContextInstance(
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `ctx` targets `encl`, which is the enclosing callable of `call`, and
|
||||
* Holds if `ctx` targets the enclosing callable of `call`, and
|
||||
* the receiver of `call` is a parameter access, where the corresponding argument
|
||||
* `arg` of `ctx` is a module access targeting a module of type `tp`.
|
||||
*
|
||||
@@ -1182,12 +1181,11 @@ private predicate mayBenefitFromCallContextInstance(
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate mayBenefitFromCallContextSingleton(
|
||||
RelevantCall ctx, RelevantCall call, DataFlow::Node arg, Callable encl, Module tp, boolean exact,
|
||||
string name
|
||||
RelevantCall ctx, RelevantCall call, DataFlow::Node arg, Module tp, boolean exact, string name
|
||||
) {
|
||||
exists(DataFlow::LocalSourceNode source |
|
||||
argMustFlowToReceiver(ctx, pragma[only_bind_into](source), pragma[only_bind_into](arg), call,
|
||||
encl, pragma[only_bind_into](name)) and
|
||||
pragma[only_bind_into](name)) and
|
||||
exists(lookupSingletonMethod(tp, pragma[only_bind_into](name), exact))
|
||||
|
|
||||
source = trackModuleAccess(tp) and
|
||||
@@ -1208,16 +1206,14 @@ private predicate mayBenefitFromCallContextSingleton(
|
||||
|
||||
/**
|
||||
* Holds if the set of viable implementations that can be called by `call`
|
||||
* might be improved by knowing the call context. This is the case if the
|
||||
* receiver accesses a parameter of the enclosing callable `c` (including
|
||||
* the implicit `self` parameter).
|
||||
* might be improved by knowing the call context.
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c) {
|
||||
mayBenefitFromCallContextInitialize(_, call.asCall(), _, c.asCallable(), _, _)
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call) {
|
||||
mayBenefitFromCallContextInitialize(_, call.asCall(), _, _, _)
|
||||
or
|
||||
mayBenefitFromCallContextInstance(_, call.asCall(), _, c.asCallable(), _, _, _)
|
||||
mayBenefitFromCallContextInstance(_, call.asCall(), _, _, _, _)
|
||||
or
|
||||
mayBenefitFromCallContextSingleton(_, call.asCall(), _, c.asCallable(), _, _, _)
|
||||
mayBenefitFromCallContextSingleton(_, call.asCall(), _, _, _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1226,25 +1222,25 @@ predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c) {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
|
||||
mayBenefitFromCallContext(call, _) and
|
||||
mayBenefitFromCallContext(call) and
|
||||
(
|
||||
// `ctx` can provide a potentially better type bound
|
||||
exists(RelevantCall call0, Callable res |
|
||||
call0 = call.asCall() and
|
||||
res = result.asCallable() and
|
||||
exists(Module m, string name |
|
||||
mayBenefitFromCallContextInitialize(ctx.asCall(), pragma[only_bind_into](call0), _, _,
|
||||
mayBenefitFromCallContextInitialize(ctx.asCall(), pragma[only_bind_into](call0), _,
|
||||
pragma[only_bind_into](m), pragma[only_bind_into](name)) and
|
||||
res = getInitializeTarget(call0) and
|
||||
res = lookupMethod(m, name)
|
||||
or
|
||||
exists(boolean exact |
|
||||
mayBenefitFromCallContextInstance(ctx.asCall(), pragma[only_bind_into](call0), _, _,
|
||||
mayBenefitFromCallContextInstance(ctx.asCall(), pragma[only_bind_into](call0), _,
|
||||
pragma[only_bind_into](m), pragma[only_bind_into](exact), pragma[only_bind_into](name)) and
|
||||
res = getTargetInstance(call0, name) and
|
||||
res = lookupMethod(m, name, exact)
|
||||
or
|
||||
mayBenefitFromCallContextSingleton(ctx.asCall(), pragma[only_bind_into](call0), _, _,
|
||||
mayBenefitFromCallContextSingleton(ctx.asCall(), pragma[only_bind_into](call0), _,
|
||||
pragma[only_bind_into](m), pragma[only_bind_into](exact), pragma[only_bind_into](name)) and
|
||||
res = getTargetSingleton(call0, name) and
|
||||
res = lookupSingletonMethod(m, name, exact)
|
||||
@@ -1257,15 +1253,15 @@ DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) {
|
||||
exists(RelevantCall call0, RelevantCall ctx0, DataFlow::Node arg, string name |
|
||||
call0 = call.asCall() and
|
||||
ctx0 = ctx.asCall() and
|
||||
argMustFlowToReceiver(ctx0, _, arg, call0, _, name) and
|
||||
not mayBenefitFromCallContextInitialize(ctx0, call0, arg, _, _, _) and
|
||||
not mayBenefitFromCallContextInstance(ctx0, call0, arg, _, _, _, name) and
|
||||
not mayBenefitFromCallContextSingleton(ctx0, call0, arg, _, _, _, name) and
|
||||
argMustFlowToReceiver(ctx0, _, arg, call0, name) and
|
||||
not mayBenefitFromCallContextInitialize(ctx0, call0, arg, _, _) and
|
||||
not mayBenefitFromCallContextInstance(ctx0, call0, arg, _, _, name) and
|
||||
not mayBenefitFromCallContextSingleton(ctx0, call0, arg, _, _, name) and
|
||||
result.asCallable() = viableSourceCallable(call0)
|
||||
)
|
||||
or
|
||||
// library calls should always be able to resolve
|
||||
argMustFlowToReceiver(ctx.asCall(), _, _, call.asCall(), _, _) and
|
||||
argMustFlowToReceiver(ctx.asCall(), _, _, call.asCall(), _) and
|
||||
result = viableLibraryCallable(call)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -27,4 +27,8 @@ module RubyDataFlow implements InputSig {
|
||||
predicate neverSkipInPathGraph = Private::neverSkipInPathGraph/1;
|
||||
|
||||
Node exprNode(DataFlowExpr e) { result = Public::exprNode(e) }
|
||||
|
||||
predicate mayBenefitFromCallContext = Private::mayBenefitFromCallContext/1;
|
||||
|
||||
predicate viableImplInCallContext = Private::viableImplInCallContext/2;
|
||||
}
|
||||
|
||||
@@ -194,24 +194,24 @@ subpaths
|
||||
| call_sensitivity.rb:105:10:105:10 | x | call_sensitivity.rb:178:11:178:19 | call to taint | call_sensitivity.rb:105:10:105:10 | x | $@ | call_sensitivity.rb:178:11:178:19 | call to taint | call to taint |
|
||||
| call_sensitivity.rb:105:10:105:10 | x | call_sensitivity.rb:187:12:187:19 | call to taint | call_sensitivity.rb:105:10:105:10 | x | $@ | call_sensitivity.rb:187:12:187:19 | call to taint | call to taint |
|
||||
mayBenefitFromCallContext
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:50:3:52:5 | method1 |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:54:3:56:5 | method2 |
|
||||
| call_sensitivity.rb:59:5:59:18 | call to method2 | call_sensitivity.rb:58:3:60:5 | call_method2 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:62:3:64:5 | method3 |
|
||||
| call_sensitivity.rb:67:5:67:25 | call to method3 | call_sensitivity.rb:66:3:68:5 | call_method3 |
|
||||
| call_sensitivity.rb:81:5:81:18 | call to method1 | call_sensitivity.rb:80:3:82:5 | method5 |
|
||||
| call_sensitivity.rb:89:5:89:23 | call to singleton_method1 | call_sensitivity.rb:88:3:90:5 | singleton_method2 |
|
||||
| call_sensitivity.rb:93:5:93:28 | call to singleton_method2 | call_sensitivity.rb:92:3:94:5 | call_singleton_method2 |
|
||||
| call_sensitivity.rb:97:5:97:26 | call to singleton_method1 | call_sensitivity.rb:96:3:98:5 | singleton_method3 |
|
||||
| call_sensitivity.rb:101:5:101:35 | call to singleton_method3 | call_sensitivity.rb:100:3:102:5 | call_singleton_method3 |
|
||||
| call_sensitivity.rb:105:5:105:10 | call to sink | call_sensitivity.rb:104:3:107:5 | initialize |
|
||||
| call_sensitivity.rb:106:5:106:13 | call to method1 | call_sensitivity.rb:104:3:107:5 | initialize |
|
||||
| call_sensitivity.rb:110:5:110:9 | call to new | call_sensitivity.rb:109:3:111:5 | call_new |
|
||||
| call_sensitivity.rb:137:5:137:18 | call to method2 | call_sensitivity.rb:136:3:138:5 | call_method2 |
|
||||
| call_sensitivity.rb:141:5:141:25 | call to method3 | call_sensitivity.rb:140:3:142:5 | call_method3 |
|
||||
| call_sensitivity.rb:149:5:149:28 | call to singleton_method2 | call_sensitivity.rb:148:3:150:5 | call_singleton_method2 |
|
||||
| call_sensitivity.rb:153:5:153:35 | call to singleton_method3 | call_sensitivity.rb:152:3:154:5 | call_singleton_method3 |
|
||||
| call_sensitivity.rb:175:3:175:12 | call to new | call_sensitivity.rb:174:1:176:3 | create |
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink |
|
||||
| call_sensitivity.rb:55:5:55:13 | call to method1 |
|
||||
| call_sensitivity.rb:59:5:59:18 | call to method2 |
|
||||
| call_sensitivity.rb:63:5:63:16 | call to method1 |
|
||||
| call_sensitivity.rb:67:5:67:25 | call to method3 |
|
||||
| call_sensitivity.rb:81:5:81:18 | call to method1 |
|
||||
| call_sensitivity.rb:89:5:89:23 | call to singleton_method1 |
|
||||
| call_sensitivity.rb:93:5:93:28 | call to singleton_method2 |
|
||||
| call_sensitivity.rb:97:5:97:26 | call to singleton_method1 |
|
||||
| call_sensitivity.rb:101:5:101:35 | call to singleton_method3 |
|
||||
| call_sensitivity.rb:105:5:105:10 | call to sink |
|
||||
| call_sensitivity.rb:106:5:106:13 | call to method1 |
|
||||
| call_sensitivity.rb:110:5:110:9 | call to new |
|
||||
| call_sensitivity.rb:137:5:137:18 | call to method2 |
|
||||
| call_sensitivity.rb:141:5:141:25 | call to method3 |
|
||||
| call_sensitivity.rb:149:5:149:28 | call to singleton_method2 |
|
||||
| call_sensitivity.rb:153:5:153:35 | call to singleton_method3 |
|
||||
| call_sensitivity.rb:175:3:175:12 | call to new |
|
||||
viableImplInCallContext
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:55:5:55:13 | call to method1 | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
| call_sensitivity.rb:51:5:51:10 | call to sink | call_sensitivity.rb:63:5:63:16 | call to method1 | call_sensitivity.rb:5:1:7:3 | sink |
|
||||
|
||||
@@ -9,7 +9,7 @@ import DefaultFlowTest
|
||||
import TaintFlow::PathGraph
|
||||
import codeql.ruby.dataflow.internal.DataFlowDispatch as DataFlowDispatch
|
||||
|
||||
query predicate mayBenefitFromCallContext = DataFlowDispatch::mayBenefitFromCallContext/2;
|
||||
query predicate mayBenefitFromCallContext = DataFlowDispatch::mayBenefitFromCallContext/1;
|
||||
|
||||
query predicate viableImplInCallContext = DataFlowDispatch::viableImplInCallContext/2;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user