in source/Transfer.cpp [1299:1353]
void infer_output_taint(
MethodContext* context,
Root root,
const TaintTree& taint) {
for (const auto& [path, sources] : taint.elements()) {
auto partitioned_by_artificial_sources = sources.partition_by_kind<bool>(
[&](const Kind* kind) { return kind == Kinds::artificial_source(); });
auto real_sources = partitioned_by_artificial_sources.find(false);
if (real_sources != partitioned_by_artificial_sources.end()) {
for (const auto& source : real_sources->second) {
auto generation = source;
generation.add_inferred_features(FeatureMayAlwaysSet::make_always(
context->model.attach_to_sources(root)));
auto port = AccessPath(root, path);
LOG_OR_DUMP(
context,
4,
"Inferred generation for port {}: {}",
port,
generation);
context->model.add_inferred_generations(
std::move(port), Taint{std::move(generation)});
}
}
auto artificial_sources = partitioned_by_artificial_sources.find(true);
if (artificial_sources != partitioned_by_artificial_sources.end()) {
for (const auto& source : artificial_sources->second) {
for (const auto& artificial_source : source) {
if (artificial_source.callee_port().root() != root) {
const auto& input = artificial_source.callee_port();
auto output = AccessPath(root, path);
auto features = artificial_source.features();
features.add_always(
context->model.attach_to_propagations(input.root()));
features.add_always(context->model.attach_to_propagations(root));
auto propagation = Propagation(
input,
/* inferred_features */ features,
/* user_features */ FeatureSet::bottom());
LOG_OR_DUMP(
context,
4,
"Inferred propagation {} to {}",
propagation,
output);
context->model.add_inferred_propagation(
std::move(propagation), std::move(output));
}
}
}
}
}
}