Merge pull request #15867 from hvitved/dataflow/ap-limit

Data flow: Add `ConfigSig::accessPathLimit`
This commit is contained in:
Tom Hvitved 2024-03-12 14:57:51 +01:00 коммит произвёл GitHub
Родитель 50851210ea d7790faece
Коммит dddba3228b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
34 изменённых файлов: 89 добавлений и 11 удалений

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -109,6 +109,8 @@ module Global<ConfigSig ContentConfig> {
DataFlow::FlowFeature getAFeature() { result = ContentConfig::getAFeature() } DataFlow::FlowFeature getAFeature() { result = ContentConfig::getAFeature() }
predicate accessPathLimit = ContentConfig::accessPathLimit/0;
// needed to record reads/stores inside summarized callables // needed to record reads/stores inside summarized callables
predicate includeHiddenNodes() { any() } predicate includeHiddenNodes() { any() }
} }

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -72,11 +72,11 @@ string captureQualifierFlow(TargetApiSpecific api) {
result = ModelPrinting::asValueModel(api, qualifierString(), "ReturnValue") result = ModelPrinting::asValueModel(api, qualifierString(), "ReturnValue")
} }
private int accessPathLimit() { result = 2 } private int accessPathLimit0() { result = 2 }
private newtype TTaintState = private newtype TTaintState =
TTaintRead(int n) { n in [0 .. accessPathLimit()] } or TTaintRead(int n) { n in [0 .. accessPathLimit0()] } or
TTaintStore(int n) { n in [1 .. accessPathLimit()] } TTaintStore(int n) { n in [1 .. accessPathLimit0()] }
abstract private class TaintState extends TTaintState { abstract private class TaintState extends TTaintState {
abstract string toString(); abstract string toString();

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -72,11 +72,11 @@ string captureQualifierFlow(TargetApiSpecific api) {
result = ModelPrinting::asValueModel(api, qualifierString(), "ReturnValue") result = ModelPrinting::asValueModel(api, qualifierString(), "ReturnValue")
} }
private int accessPathLimit() { result = 2 } private int accessPathLimit0() { result = 2 }
private newtype TTaintState = private newtype TTaintState =
TTaintRead(int n) { n in [0 .. accessPathLimit()] } or TTaintRead(int n) { n in [0 .. accessPathLimit0()] } or
TTaintStore(int n) { n in [1 .. accessPathLimit()] } TTaintStore(int n) { n in [1 .. accessPathLimit0()] }
abstract private class TaintState extends TTaintState { abstract private class TaintState extends TTaintState {
abstract string toString(); abstract string toString();

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {

Просмотреть файл

@ -376,6 +376,9 @@ module Configs<InputSig Lang> {
*/ */
default int fieldFlowBranchLimit() { result = 2 } default int fieldFlowBranchLimit() { result = 2 }
/** Gets the access path limit. */
default int accessPathLimit() { result = Lang::accessPathLimit() }
/** /**
* Gets a data flow configuration feature to add restrictions to the set of * Gets a data flow configuration feature to add restrictions to the set of
* valid flow paths. * valid flow paths.
@ -495,6 +498,9 @@ module Configs<InputSig Lang> {
*/ */
default int fieldFlowBranchLimit() { result = 2 } default int fieldFlowBranchLimit() { result = 2 }
/** Gets the access path limit. */
default int accessPathLimit() { result = Lang::accessPathLimit() }
/** /**
* Gets a data flow configuration feature to add restrictions to the set of * Gets a data flow configuration feature to add restrictions to the set of
* valid flow paths. * valid flow paths.
@ -583,6 +589,8 @@ module DataFlowMake<InputSig Lang> {
private module C implements FullStateConfigSig { private module C implements FullStateConfigSig {
import DefaultState<Config> import DefaultState<Config>
import Config import Config
predicate accessPathLimit = Config::accessPathLimit/0;
} }
import Impl<C> import Impl<C>
@ -599,6 +607,8 @@ module DataFlowMake<InputSig Lang> {
module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig { module GlobalWithState<StateConfigSig Config> implements GlobalFlowSig {
private module C implements FullStateConfigSig { private module C implements FullStateConfigSig {
import Config import Config
predicate accessPathLimit = Config::accessPathLimit/0;
} }
import Impl<C> import Impl<C>

Просмотреть файл

@ -93,6 +93,9 @@ module MakeImpl<InputSig Lang> {
*/ */
int fieldFlowBranchLimit(); int fieldFlowBranchLimit();
/** Gets the access path limit. */
int accessPathLimit();
/** /**
* Gets a data flow configuration feature to add restrictions to the set of * Gets a data flow configuration feature to add restrictions to the set of
* valid flow paths. * valid flow paths.
@ -477,7 +480,9 @@ module MakeImpl<InputSig Lang> {
/** /**
* Holds if field flow should be used for the given configuration. * Holds if field flow should be used for the given configuration.
*/ */
private predicate useFieldFlow() { Config::fieldFlowBranchLimit() >= 1 } private predicate useFieldFlow() {
Config::fieldFlowBranchLimit() >= 1 and Config::accessPathLimit() > 0
}
private predicate hasSourceCallCtx() { private predicate hasSourceCallCtx() {
exists(FlowFeature feature | feature = Config::getAFeature() | exists(FlowFeature feature | feature = Config::getAFeature() |
@ -2522,7 +2527,10 @@ module MakeImpl<InputSig Lang> {
bindingset[c, t, tail] bindingset[c, t, tail]
Ap apCons(Content c, Typ t, Ap tail) { Ap apCons(Content c, Typ t, Ap tail) {
result = true and exists(c) and exists(t) and exists(tail) result = true and
exists(c) and
exists(t) and
if tail = true then Config::accessPathLimit() > 1 else any()
} }
class ApHeadContent = Unit; class ApHeadContent = Unit;
@ -3026,11 +3034,11 @@ module MakeImpl<InputSig Lang> {
} or } or
TConsCons(Content c1, DataFlowType t, Content c2, int len) { TConsCons(Content c1, DataFlowType t, Content c2, int len) {
Stage4::consCand(c1, t, TFrontHead(c2)) and Stage4::consCand(c1, t, TFrontHead(c2)) and
len in [2 .. accessPathLimit()] and len in [2 .. Config::accessPathLimit()] and
not expensiveLen2unfolding(c1) not expensiveLen2unfolding(c1)
} or } or
TCons1(Content c, int len) { TCons1(Content c, int len) {
len in [1 .. accessPathLimit()] and len in [1 .. Config::accessPathLimit()] and
expensiveLen2unfolding(c) expensiveLen2unfolding(c)
} }
@ -4626,7 +4634,7 @@ module MakeImpl<InputSig Lang> {
private newtype TPartialAccessPath = private newtype TPartialAccessPath =
TPartialNil() or TPartialNil() or
TPartialCons(Content c, int len) { len in [1 .. accessPathLimit()] } TPartialCons(Content c, int len) { len in [1 .. Config::accessPathLimit()] }
/** /**
* Conceptually a list of `Content`s, but only the first * Conceptually a list of `Content`s, but only the first

Просмотреть файл

@ -285,6 +285,8 @@ deprecated private module Config implements FullStateConfigSig {
int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) } int fieldFlowBranchLimit() { result = min(any(Configuration config).fieldFlowBranchLimit()) }
int accessPathLimit() { result = 5 }
FlowFeature getAFeature() { result = any(Configuration config).getAFeature() } FlowFeature getAFeature() { result = any(Configuration config).getAFeature() }
predicate sourceGrouping(Node source, string sourceGroup) { predicate sourceGrouping(Node source, string sourceGroup) {