source/Propagation.h (82 lines of code) (raw):

/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #pragma once #include <json/json.h> #include <AbstractDomain.h> #include <mariana-trench/Access.h> #include <mariana-trench/Assert.h> #include <mariana-trench/Context.h> #include <mariana-trench/Feature.h> #include <mariana-trench/FeatureMayAlwaysSet.h> #include <mariana-trench/FeatureSet.h> namespace marianatrench { /** * A `Propagation` describes how taint may flow through a method. More * specifically, how taint may flow from a parameter to the method's return * value or another parameters. A `Propagation` will only propagate the taint * if the parameter is tainted. * * `inferred_features` is a may-always set of features inferred during the * analysis. It is bottom for a user-specified propagation. * * `user_features` is a set of always features specified by the user in model * generators. */ class Propagation final : public sparta::AbstractDomain<Propagation> { public: /* Create the bottom (i.e, invalid) propagation. */ explicit Propagation() : input_(Root(Root::Kind::Leaf)), inferred_features_(FeatureMayAlwaysSet::bottom()), user_features_(FeatureSet::bottom()) {} explicit Propagation( AccessPath input, FeatureMayAlwaysSet inferred_features, FeatureSet user_features) : input_(std::move(input)), inferred_features_(std::move(inferred_features)), user_features_(std::move(user_features)) {} Propagation(const Propagation&) = default; Propagation(Propagation&&) = default; Propagation& operator=(const Propagation&) = default; Propagation& operator=(Propagation&&) = default; ~Propagation() = default; static Propagation bottom() { return Propagation(); } static Propagation top() { mt_unreachable(); // Not implemented. } bool is_bottom() const override { return input_.root().is_leaf(); } bool is_top() const override { return false; } void set_to_bottom() override { input_ = AccessPath(Root(Root::Kind::Leaf)); } void set_to_top() override { mt_unreachable(); // Not implemented. } bool leq(const Propagation& other) const override; bool equals(const Propagation& other) const override; void join_with(const Propagation& other) override; void widen_with(const Propagation& other) override; void meet_with(const Propagation& other) override; void narrow_with(const Propagation& other) override; const AccessPath& input() const { return input_; } const FeatureMayAlwaysSet& inferred_features() const { return inferred_features_; } const FeatureSet& user_features() const { return user_features_; } FeatureMayAlwaysSet features() const; void truncate(std::size_t size) { input_.truncate(size); } static Propagation from_json(const Json::Value& value, Context& context); Json::Value to_json() const; // Describe how to join propagations together in `PropagationSet`. struct GroupEqual { bool operator()(const Propagation& left, const Propagation& right) const; }; // Describe how to join propagations together in `PropagationSet`. struct GroupHash { std::size_t operator()(const Propagation& propagation) const; }; private: friend std::ostream& operator<<( std::ostream& out, const Propagation& propagation); AccessPath input_; FeatureMayAlwaysSet inferred_features_; FeatureSet user_features_; }; } // namespace marianatrench