mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Data flow: Remove column from mayBenefitFromCallContext
This commit is contained in:
@@ -54,18 +54,6 @@ private predicate functionSignature(Function f, string qualifiedName, int nparam
|
||||
not f.isStatic()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the set of viable implementations that can be called by `call`
|
||||
* might be improved by knowing the call context.
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, Function f) { none() }
|
||||
|
||||
/**
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference.
|
||||
*/
|
||||
Function viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { none() }
|
||||
|
||||
/** A parameter position represented by an integer. */
|
||||
class ParameterPosition extends int {
|
||||
ParameterPosition() { any(ParameterNode p).isParameterOf(_, this) }
|
||||
|
||||
@@ -249,9 +249,7 @@ private predicate functionSignature(Function f, string qualifiedName, int nparam
|
||||
* Holds if the set of viable implementations that can be called by `call`
|
||||
* might be improved by knowing the call context.
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable f) {
|
||||
mayBenefitFromCallContext(call, f, _)
|
||||
}
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call) { mayBenefitFromCallContext(call, _, _) }
|
||||
|
||||
/**
|
||||
* Holds if `call` is a call through a function pointer, and the pointer
|
||||
|
||||
@@ -22,4 +22,8 @@ module CppDataFlow implements InputSig {
|
||||
predicate getAdditionalFlowIntoCallNodeTerm = Private::getAdditionalFlowIntoCallNodeTerm/2;
|
||||
|
||||
predicate validParameterAliasStep = Private::validParameterAliasStep/2;
|
||||
|
||||
predicate mayBenefitFromCallContext = Private::mayBenefitFromCallContext/1;
|
||||
|
||||
predicate viableImplInCallContext = Private::viableImplInCallContext/2;
|
||||
}
|
||||
|
||||
@@ -148,17 +148,17 @@ private module Cached {
|
||||
import Cached
|
||||
|
||||
private module DispatchImpl {
|
||||
/**
|
||||
* 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
|
||||
* call is a delegate call, or if the qualifier accesses a parameter of
|
||||
* the enclosing callable `c` (including the implicit `this` parameter).
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c) {
|
||||
private predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c) {
|
||||
c = call.getEnclosingCallable() and
|
||||
call.(NonDelegateDataFlowCall).getDispatchCall().mayBenefitFromCallContext()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the set of viable implementations that can be called by `call`
|
||||
* might be improved by knowing the call context.
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call) { mayBenefitFromCallContext(call, _) }
|
||||
|
||||
/**
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference.
|
||||
|
||||
@@ -20,4 +20,8 @@ module CsharpDataFlow implements InputSig {
|
||||
Node exprNode(DataFlowExpr e) { result = Public::exprNode(e) }
|
||||
|
||||
predicate accessPathLimit = Private::accessPathLimit/0;
|
||||
|
||||
predicate mayBenefitFromCallContext = Private::mayBenefitFromCallContext/1;
|
||||
|
||||
predicate viableImplInCallContext = Private::viableImplInCallContext/2;
|
||||
}
|
||||
|
||||
@@ -588,18 +588,17 @@ However, joining the virtual dispatch relation with itself in this way is
|
||||
usually way too big to be feasible. Instead, the relation above should only be
|
||||
defined for those values of `call` for which the set of resulting dispatch
|
||||
targets might be reduced. To do this, define the set of `call`s that might for
|
||||
some reason benefit from a call context as the following predicate (the `c`
|
||||
column should be `call.getEnclosingCallable()`):
|
||||
some reason benefit from a call context as the following predicate:
|
||||
```ql
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c)
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call)
|
||||
```
|
||||
And then define `DataFlowCallable viableImplInCallContext(DataFlowCall call,
|
||||
DataFlowCall ctx)` as sketched above, but restricted to
|
||||
`mayBenefitFromCallContext(call, _)`.
|
||||
`mayBenefitFromCallContext(call)`.
|
||||
|
||||
The shared implementation will then compare counts of virtual dispatch targets
|
||||
using `viableCallable` and `viableImplInCallContext` for each `call` in
|
||||
`mayBenefitFromCallContext(call, _)` and track call contexts during flow
|
||||
`mayBenefitFromCallContext(call)` and track call contexts during flow
|
||||
calculation when differences in these counts show an improved precision in
|
||||
further calls.
|
||||
|
||||
|
||||
@@ -104,18 +104,6 @@ DataFlowCallable viableCallable(DataFlowCall ma) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the set of viable implementations that can be called by `call`
|
||||
* might be improved by knowing the call context.
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable f) { none() }
|
||||
|
||||
/**
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference.
|
||||
*/
|
||||
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { none() }
|
||||
|
||||
private int parameterPosition() {
|
||||
result = [-1 .. any(DataFlowCallable c).getType().getNumParameter()]
|
||||
}
|
||||
|
||||
@@ -116,10 +116,10 @@ private module DispatchImpl {
|
||||
/**
|
||||
* 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
|
||||
* qualifier is a parameter of the enclosing callable `c`.
|
||||
* qualifier is a parameter of the enclosing callable of `call`.
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c) {
|
||||
mayBenefitFromCallContext(call.asCall(), c.asCallable(), _)
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call) {
|
||||
mayBenefitFromCallContext(call.asCall(), _, _)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,4 +18,8 @@ module JavaDataFlow implements InputSig {
|
||||
import Public
|
||||
|
||||
Node exprNode(DataFlowExpr e) { result = Public::exprNode(e) }
|
||||
|
||||
predicate mayBenefitFromCallContext = Private::mayBenefitFromCallContext/1;
|
||||
|
||||
predicate viableImplInCallContext = Private::viableImplInCallContext/2;
|
||||
}
|
||||
|
||||
@@ -1009,22 +1009,6 @@ predicate attributeClearStep(Node n, AttributeContent c) {
|
||||
*/
|
||||
predicate isUnreachableInCall(Node n, DataFlowCall call) { none() }
|
||||
|
||||
//--------
|
||||
// Virtual dispatch with call context
|
||||
//--------
|
||||
/**
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference.
|
||||
*/
|
||||
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { none() }
|
||||
|
||||
/**
|
||||
* 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 qualifier accesses a parameter of
|
||||
* the enclosing callable `c` (including the implicit `this` parameter).
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c) { none() }
|
||||
|
||||
/**
|
||||
* Holds if access paths with `c` at their head always should be tracked at high
|
||||
* precision. This disables adaptive access path precision for such access paths.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -77,13 +77,13 @@ signature module InputSig {
|
||||
* Holds if the set of viable implementations that can be called by `call`
|
||||
* might be improved by knowing the call context.
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c);
|
||||
default predicate mayBenefitFromCallContext(DataFlowCall call) { none() }
|
||||
|
||||
/**
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference.
|
||||
*/
|
||||
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx);
|
||||
default DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { none() }
|
||||
|
||||
/**
|
||||
* Gets a node that can read the value returned from `call` with return kind
|
||||
|
||||
@@ -791,10 +791,12 @@ module MakeImplCommon<InputSig Lang> {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate mayBenefitFromCallContextExt(DataFlowCall call, DataFlowCallable callable) {
|
||||
mayBenefitFromCallContext(call, callable)
|
||||
or
|
||||
callEnclosingCallable(call, callable) and
|
||||
exists(viableCallableLambda(call, TDataFlowCallSome(_)))
|
||||
(
|
||||
mayBenefitFromCallContext(call)
|
||||
or
|
||||
exists(viableCallableLambda(call, TDataFlowCallSome(_)))
|
||||
) and
|
||||
callEnclosingCallable(call, callable)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -302,18 +302,6 @@ private module Cached {
|
||||
|
||||
import Cached
|
||||
|
||||
/**
|
||||
* Holds if the set of viable implementations that can be called by `call`
|
||||
* might be improved by knowing the call context.
|
||||
*/
|
||||
predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c) { none() }
|
||||
|
||||
/**
|
||||
* Gets a viable dispatch target of `call` in the context `ctx`. This is
|
||||
* restricted to those `call`s for which a context might make a difference.
|
||||
*/
|
||||
DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { none() }
|
||||
|
||||
/** A parameter position. */
|
||||
class ParameterPosition extends TParameterPosition {
|
||||
/** Gets a textual representation of this position. */
|
||||
|
||||
Reference in New Issue
Block a user