in source/Transfer.cpp [630:682]
void check_flows(
MethodContext* context,
const Taint& sources,
const Taint& sinks,
const Position* position,
const FeatureMayAlwaysSet& extra_features,
FulfilledPartialKindState* MT_NULLABLE fulfilled_partial_sinks) {
if (sources.is_bottom() || sinks.is_bottom()) {
return;
}
auto sources_by_kind = sources.partition_by_kind();
auto sinks_by_kind = sinks.partition_by_kind();
for (const auto& [source_kind, source_taint] : sources_by_kind) {
if (source_kind == Kinds::artificial_source()) {
continue;
}
for (const auto& [sink_kind, sink_taint] : sinks_by_kind) {
// Check if this satisfies any rule. If so, create the issue.
const auto& rules = context->rules.rules(source_kind, sink_kind);
for (const auto* rule : rules) {
create_issue(
context, source_taint, sink_taint, rule, position, extra_features);
}
// Check if this satisfies any partial (multi-source/sink) rule.
if (fulfilled_partial_sinks) {
const auto* MT_NULLABLE partial_sink = sink_kind->as<PartialKind>();
if (partial_sink) {
const auto& partial_rules =
context->rules.partial_rules(source_kind, partial_sink);
for (const auto* partial_rule : partial_rules) {
check_multi_source_multi_sink_rules(
context,
source_kind,
source_taint,
sink_kind,
sink_taint,
*fulfilled_partial_sinks,
partial_rule,
position,
extra_features);
}
}
}
}
}
if (!fulfilled_partial_sinks) {
create_sinks(context, sources, sinks, extra_features);
}
}