LCOV - code coverage report
Current view: top level - source/common/protobuf - message_validator_impl.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 18 24 75.0 %
Date: 2024-01-05 06:35:25 Functions: 10 16 62.5 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include "envoy/protobuf/message_validator.h"
       4             : #include "envoy/stats/stats.h"
       5             : 
       6             : #include "source/common/common/documentation_url.h"
       7             : #include "source/common/common/logger.h"
       8             : 
       9             : #include "absl/container/flat_hash_set.h"
      10             : 
      11             : namespace Envoy {
      12             : namespace ProtobufMessage {
      13             : 
      14             : class ValidationVisitorBase : public ValidationVisitor {
      15             : public:
      16         393 :   void setRuntime(Runtime::Loader& runtime) { runtime_ = runtime; }
      17           0 :   void clearRuntime() { runtime_ = {}; } // for tests
      18       12493 :   OptRef<Runtime::Loader> runtime() override { return runtime_; }
      19             : 
      20             : protected:
      21             :   OptRef<Runtime::Loader> runtime_;
      22             : };
      23             : 
      24             : class NullValidationVisitorImpl : public ValidationVisitorBase {
      25             : public:
      26             :   // Envoy::ProtobufMessage::ValidationVisitor
      27           0 :   void onUnknownField(absl::string_view) override {}
      28           0 :   void onDeprecatedField(absl::string_view, bool) override {}
      29           0 :   bool skipValidation() override { return true; }
      30           0 :   void onWorkInProgress(absl::string_view) override {}
      31             : };
      32             : 
      33             : ValidationVisitor& getNullValidationVisitor();
      34             : 
      35             : // Base class for both warning and strict validators.
      36             : class WipCounterBase {
      37             : protected:
      38             :   void setWipCounter(Stats::Counter& wip_counter);
      39             :   void onWorkInProgressCommon(absl::string_view description);
      40             : 
      41             : private:
      42             :   Stats::Counter* wip_counter_{};
      43             :   uint64_t prestats_wip_count_{};
      44             : };
      45             : 
      46             : class WarningValidationVisitorImpl : public ValidationVisitorBase,
      47             :                                      public WipCounterBase,
      48             :                                      public Logger::Loggable<Logger::Id::config> {
      49             : public:
      50             :   void setCounters(Stats::Counter& unknown_counter, Stats::Counter& wip_counter);
      51             : 
      52             :   // Envoy::ProtobufMessage::ValidationVisitor
      53             :   void onUnknownField(absl::string_view description) override;
      54             :   void onDeprecatedField(absl::string_view description, bool soft_deprecation) override;
      55           0 :   bool skipValidation() override { return false; }
      56             :   void onWorkInProgress(absl::string_view description) override;
      57             : 
      58             : private:
      59             :   // Track hashes of descriptions we've seen, to avoid log spam. A hash is used here to avoid
      60             :   // wasting memory with unused strings.
      61             :   absl::flat_hash_set<uint64_t> descriptions_;
      62             :   // This can be late initialized via setUnknownCounter(), enabling the server bootstrap loading
      63             :   // which occurs prior to the initialization of the stats subsystem.
      64             :   Stats::Counter* unknown_counter_{};
      65             :   uint64_t prestats_unknown_count_{};
      66             : };
      67             : 
      68             : class StrictValidationVisitorImpl : public ValidationVisitorBase, public WipCounterBase {
      69             : public:
      70         134 :   void setCounters(Stats::Counter& wip_counter) { setWipCounter(wip_counter); }
      71             : 
      72             :   // Envoy::ProtobufMessage::ValidationVisitor
      73             :   void onUnknownField(absl::string_view description) override;
      74       10725 :   bool skipValidation() override { return false; }
      75             :   void onDeprecatedField(absl::string_view description, bool soft_deprecation) override;
      76             :   void onWorkInProgress(absl::string_view description) override;
      77             : };
      78             : 
      79             : // TODO(mattklein123): There are various places where the default strict validator is being used.
      80             : // This does not increment the WIP stat because nothing calls setCounters() on the stock/static
      81             : // version. We should remove this as a public function as well as the stock/static version and
      82             : // make sure that all code is either using the server validation context or the null validator.
      83             : ValidationVisitor& getStrictValidationVisitor();
      84             : 
      85             : class ValidationContextImpl : public ValidationContext {
      86             : public:
      87             :   ValidationContextImpl(ValidationVisitor& static_validation_visitor,
      88             :                         ValidationVisitor& dynamic_validation_visitor)
      89             :       : static_validation_visitor_(static_validation_visitor),
      90         455 :         dynamic_validation_visitor_(dynamic_validation_visitor) {}
      91             : 
      92             :   // Envoy::ProtobufMessage::ValidationContext
      93        2362 :   ValidationVisitor& staticValidationVisitor() override { return static_validation_visitor_; }
      94         809 :   ValidationVisitor& dynamicValidationVisitor() override { return dynamic_validation_visitor_; }
      95             : 
      96             : private:
      97             :   ValidationVisitor& static_validation_visitor_;
      98             :   ValidationVisitor& dynamic_validation_visitor_;
      99             : };
     100             : 
     101             : class ProdValidationContextImpl : public ValidationContextImpl {
     102             : public:
     103             :   ProdValidationContextImpl(bool allow_unknown_static_fields, bool allow_unknown_dynamic_fields,
     104             :                             bool ignore_unknown_dynamic_fields)
     105             :       : ValidationContextImpl(
     106             :             allow_unknown_static_fields
     107             :                 ? static_cast<ValidationVisitor&>(static_warning_validation_visitor_)
     108             :                 : strict_validation_visitor_,
     109             :             allow_unknown_dynamic_fields
     110             :                 ? (ignore_unknown_dynamic_fields ? ProtobufMessage::getNullValidationVisitor()
     111             :                                                  : dynamic_warning_validation_visitor_)
     112         455 :                 : strict_validation_visitor_) {}
     113             : 
     114             :   void setCounters(Stats::Counter& static_unknown_counter, Stats::Counter& dynamic_unknown_counter,
     115         134 :                    Stats::Counter& wip_counter) {
     116         134 :     strict_validation_visitor_.setCounters(wip_counter);
     117         134 :     static_warning_validation_visitor_.setCounters(static_unknown_counter, wip_counter);
     118         134 :     dynamic_warning_validation_visitor_.setCounters(dynamic_unknown_counter, wip_counter);
     119         134 :   }
     120             : 
     121         131 :   void setRuntime(Runtime::Loader& runtime) {
     122         131 :     strict_validation_visitor_.setRuntime(runtime);
     123         131 :     static_warning_validation_visitor_.setRuntime(runtime);
     124         131 :     dynamic_warning_validation_visitor_.setRuntime(runtime);
     125         131 :   }
     126             : 
     127             : private:
     128             :   StrictValidationVisitorImpl strict_validation_visitor_;
     129             :   ProtobufMessage::WarningValidationVisitorImpl static_warning_validation_visitor_;
     130             :   ProtobufMessage::WarningValidationVisitorImpl dynamic_warning_validation_visitor_;
     131             : };
     132             : 
     133             : } // namespace ProtobufMessage
     134             : } // namespace Envoy

Generated by: LCOV version 1.15