Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/extensions/filters/network/thrift_proxy/compact_protocol_impl.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <stack>
4
#include <string>
5
6
#include "envoy/buffer/buffer.h"
7
#include "envoy/common/pure.h"
8
9
#include "source/extensions/filters/network/thrift_proxy/protocol.h"
10
#include "source/extensions/filters/network/thrift_proxy/thrift.h"
11
12
#include "absl/types/optional.h"
13
14
namespace Envoy {
15
namespace Extensions {
16
namespace NetworkFilters {
17
namespace ThriftProxy {
18
19
/**
20
 * CompactProtocolImpl implements the Thrift Compact protocol.
21
 * See https://github.com/apache/thrift/blob/master/doc/specs/thrift-compact-protocol.md
22
 */
23
class CompactProtocolImpl : public Protocol {
24
public:
25
0
  CompactProtocolImpl() = default;
26
27
  // Protocol
28
0
  const std::string& name() const override { return ProtocolNames::get().COMPACT; }
29
0
  ProtocolType type() const override { return ProtocolType::Compact; }
30
  bool readMessageBegin(Buffer::Instance& buffer, MessageMetadata& metadata) override;
31
  bool readMessageEnd(Buffer::Instance& buffer) override;
32
  bool peekReplyPayload(Buffer::Instance& buffer, ReplyType& reply_type) override;
33
  bool readStructBegin(Buffer::Instance& buffer, std::string& name) override;
34
  bool readStructEnd(Buffer::Instance& buffer) override;
35
  bool readFieldBegin(Buffer::Instance& buffer, std::string& name, FieldType& field_type,
36
                      int16_t& field_id) override;
37
  bool readFieldEnd(Buffer::Instance& buffer) override;
38
  bool readMapBegin(Buffer::Instance& buffer, FieldType& key_type, FieldType& value_type,
39
                    uint32_t& size) override;
40
  bool readMapEnd(Buffer::Instance& buffer) override;
41
  bool readListBegin(Buffer::Instance& buffer, FieldType& elem_type, uint32_t& size) override;
42
  bool readListEnd(Buffer::Instance& buffer) override;
43
  bool readSetBegin(Buffer::Instance& buffer, FieldType& elem_type, uint32_t& size) override;
44
  bool readSetEnd(Buffer::Instance& buffer) override;
45
  bool readBool(Buffer::Instance& buffer, bool& value) override;
46
  bool readByte(Buffer::Instance& buffer, uint8_t& value) override;
47
  bool readInt16(Buffer::Instance& buffer, int16_t& value) override;
48
  bool readInt32(Buffer::Instance& buffer, int32_t& value) override;
49
  bool readInt64(Buffer::Instance& buffer, int64_t& value) override;
50
  bool readDouble(Buffer::Instance& buffer, double& value) override;
51
  bool readString(Buffer::Instance& buffer, std::string& value) override;
52
  bool readBinary(Buffer::Instance& buffer, std::string& value) override;
53
  void writeMessageBegin(Buffer::Instance& buffer, const MessageMetadata& metadata) override;
54
  void writeMessageEnd(Buffer::Instance& buffer) override;
55
  void writeStructBegin(Buffer::Instance& buffer, const std::string& name) override;
56
  void writeStructEnd(Buffer::Instance& buffer) override;
57
  void writeFieldBegin(Buffer::Instance& buffer, const std::string& name, FieldType field_type,
58
                       int16_t field_id) override;
59
  void writeFieldEnd(Buffer::Instance& buffer) override;
60
  void writeMapBegin(Buffer::Instance& buffer, FieldType key_type, FieldType value_type,
61
                     uint32_t size) override;
62
  void writeMapEnd(Buffer::Instance& buffer) override;
63
  void writeListBegin(Buffer::Instance& buffer, FieldType elem_type, uint32_t size) override;
64
  void writeListEnd(Buffer::Instance& buffer) override;
65
  void writeSetBegin(Buffer::Instance& buffer, FieldType elem_type, uint32_t size) override;
66
  void writeSetEnd(Buffer::Instance& buffer) override;
67
  void writeBool(Buffer::Instance& buffer, bool value) override;
68
  void writeByte(Buffer::Instance& buffer, uint8_t value) override;
69
  void writeInt16(Buffer::Instance& buffer, int16_t value) override;
70
  void writeInt32(Buffer::Instance& buffer, int32_t value) override;
71
  void writeInt64(Buffer::Instance& buffer, int64_t value) override;
72
  void writeDouble(Buffer::Instance& buffer, double value) override;
73
  void writeString(Buffer::Instance& buffer, const std::string& value) override;
74
  void writeBinary(Buffer::Instance& buffer, const std::string& value) override;
75
76
0
  static bool isMagic(uint16_t word) { return (word & MagicMask) == Magic; }
77
78
private:
79
  enum class CompactFieldType {
80
    Stop = 0,
81
    BoolTrue = 1,
82
    BoolFalse = 2,
83
    Byte = 3,
84
    I16 = 4,
85
    I32 = 5,
86
    I64 = 6,
87
    Double = 7,
88
    String = 8,
89
    List = 9,
90
    Set = 10,
91
    Map = 11,
92
    Struct = 12,
93
  };
94
95
  FieldType convertCompactFieldType(CompactFieldType compact_field_type);
96
  CompactFieldType convertFieldType(FieldType field_type);
97
98
  void writeFieldBeginInternal(Buffer::Instance& buffer, FieldType field_type, int16_t field_id,
99
                               absl::optional<CompactFieldType> field_type_override);
100
101
  static void validateFieldId(int32_t id);
102
103
  std::stack<int16_t> last_field_id_stack_{};
104
  int16_t last_field_id_{0};
105
106
  // Compact protocol encodes boolean struct fields as true/false *types* with no data.
107
  // This tracks the last boolean struct field's value for readBool.
108
  absl::optional<bool> bool_value_{};
109
110
  // Similarly, track the field id for writeBool.
111
  absl::optional<int16_t> bool_field_id_{};
112
113
  const static uint16_t Magic;
114
  const static uint16_t MagicMask;
115
};
116
117
} // namespace ThriftProxy
118
} // namespace NetworkFilters
119
} // namespace Extensions
120
} // namespace Envoy