Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/extensions/filters/network/thrift_proxy/thrift_object_impl.cc
Line
Count
Source (jump to first uncovered line)
1
#include "source/extensions/filters/network/thrift_proxy/thrift_object_impl.h"
2
3
namespace Envoy {
4
namespace Extensions {
5
namespace NetworkFilters {
6
namespace ThriftProxy {
7
namespace {
8
9
0
std::unique_ptr<ThriftValueBase> makeValue(ThriftBase* parent, FieldType type) {
10
0
  switch (type) {
11
0
  case FieldType::Stop:
12
0
    PANIC("unexpected");
13
0
  case FieldType::List:
14
0
    return std::make_unique<ThriftListValueImpl>(parent);
15
0
  case FieldType::Set:
16
0
    return std::make_unique<ThriftSetValueImpl>(parent);
17
0
  case FieldType::Map:
18
0
    return std::make_unique<ThriftMapValueImpl>(parent);
19
0
  case FieldType::Struct:
20
0
    return std::make_unique<ThriftStructValueImpl>(parent);
21
0
  default:
22
0
    return std::make_unique<ThriftValueImpl>(parent, type);
23
0
  }
24
0
}
25
26
} // namespace
27
28
0
ThriftBase::ThriftBase(ThriftBase* parent) : parent_(parent) {}
29
30
0
FilterStatus ThriftBase::structBegin(absl::string_view name) {
31
0
  ASSERT(delegate_ != nullptr);
32
0
  return delegate_->structBegin(name);
33
0
}
34
35
0
FilterStatus ThriftBase::structEnd() {
36
0
  ASSERT(delegate_ != nullptr);
37
0
  return delegate_->structEnd();
38
0
}
39
40
FilterStatus ThriftBase::fieldBegin(absl::string_view name, FieldType& field_type,
41
0
                                    int16_t& field_id) {
42
0
  ASSERT(delegate_ != nullptr);
43
0
  return delegate_->fieldBegin(name, field_type, field_id);
44
0
}
45
46
0
FilterStatus ThriftBase::fieldEnd() {
47
0
  ASSERT(delegate_ != nullptr);
48
0
  return delegate_->fieldEnd();
49
0
}
50
51
0
FilterStatus ThriftBase::boolValue(bool& value) {
52
0
  ASSERT(delegate_ != nullptr);
53
0
  return delegate_->boolValue(value);
54
0
}
55
56
0
FilterStatus ThriftBase::byteValue(uint8_t& value) {
57
0
  ASSERT(delegate_ != nullptr);
58
0
  return delegate_->byteValue(value);
59
0
}
60
61
0
FilterStatus ThriftBase::int16Value(int16_t& value) {
62
0
  ASSERT(delegate_ != nullptr);
63
0
  return delegate_->int16Value(value);
64
0
}
65
66
0
FilterStatus ThriftBase::int32Value(int32_t& value) {
67
0
  ASSERT(delegate_ != nullptr);
68
0
  return delegate_->int32Value(value);
69
0
}
70
71
0
FilterStatus ThriftBase::int64Value(int64_t& value) {
72
0
  ASSERT(delegate_ != nullptr);
73
0
  return delegate_->int64Value(value);
74
0
}
75
76
0
FilterStatus ThriftBase::doubleValue(double& value) {
77
0
  ASSERT(delegate_ != nullptr);
78
0
  return delegate_->doubleValue(value);
79
0
}
80
81
0
FilterStatus ThriftBase::stringValue(absl::string_view value) {
82
0
  ASSERT(delegate_ != nullptr);
83
0
  return delegate_->stringValue(value);
84
0
}
85
86
0
FilterStatus ThriftBase::mapBegin(FieldType& key_type, FieldType& value_type, uint32_t& size) {
87
0
  ASSERT(delegate_ != nullptr);
88
0
  return delegate_->mapBegin(key_type, value_type, size);
89
0
}
90
91
0
FilterStatus ThriftBase::mapEnd() {
92
0
  ASSERT(delegate_ != nullptr);
93
0
  return delegate_->mapEnd();
94
0
}
95
96
0
FilterStatus ThriftBase::listBegin(FieldType& elem_type, uint32_t& size) {
97
0
  ASSERT(delegate_ != nullptr);
98
0
  return delegate_->listBegin(elem_type, size);
99
0
}
100
101
0
FilterStatus ThriftBase::listEnd() {
102
0
  ASSERT(delegate_ != nullptr);
103
0
  return delegate_->listEnd();
104
0
}
105
106
0
FilterStatus ThriftBase::setBegin(FieldType& elem_type, uint32_t& size) {
107
0
  ASSERT(delegate_ != nullptr);
108
0
  return delegate_->setBegin(elem_type, size);
109
0
}
110
111
0
FilterStatus ThriftBase::setEnd() {
112
0
  ASSERT(delegate_ != nullptr);
113
0
  return delegate_->setEnd();
114
0
}
115
116
0
void ThriftBase::delegateComplete() {
117
0
  ASSERT(delegate_ != nullptr);
118
0
  delegate_ = nullptr;
119
0
}
120
121
ThriftFieldImpl::ThriftFieldImpl(ThriftStructValueImpl* parent, absl::string_view name,
122
                                 FieldType field_type, int16_t field_id)
123
0
    : ThriftBase(parent), name_(name), field_type_(field_type), field_id_(field_id) {
124
0
  auto value = makeValue(this, field_type_);
125
0
  delegate_ = value.get();
126
0
  value_ = std::move(value);
127
0
}
128
129
0
FilterStatus ThriftFieldImpl::fieldEnd() {
130
0
  if (delegate_) {
131
0
    return delegate_->fieldEnd();
132
0
  }
133
134
0
  parent_->delegateComplete();
135
0
  return FilterStatus::Continue;
136
0
}
137
138
0
FilterStatus ThriftListValueImpl::listBegin(FieldType& elem_type, uint32_t& size) {
139
0
  if (delegate_) {
140
0
    return delegate_->listBegin(elem_type, size);
141
0
  }
142
143
0
  elem_type_ = elem_type;
144
0
  remaining_ = size;
145
146
0
  delegateComplete();
147
148
0
  return FilterStatus::Continue;
149
0
}
150
151
0
FilterStatus ThriftListValueImpl::listEnd() {
152
0
  if (delegate_) {
153
0
    return delegate_->listEnd();
154
0
  }
155
156
0
  ASSERT(remaining_ == 0);
157
0
  parent_->delegateComplete();
158
0
  return FilterStatus::Continue;
159
0
}
160
161
0
void ThriftListValueImpl::delegateComplete() {
162
0
  delegate_ = nullptr;
163
164
0
  if (remaining_ == 0) {
165
0
    return;
166
0
  }
167
168
0
  auto elem = makeValue(this, elem_type_);
169
0
  delegate_ = elem.get();
170
0
  elements_.push_back(std::move(elem));
171
0
  remaining_--;
172
0
}
173
174
0
FilterStatus ThriftSetValueImpl::setBegin(FieldType& elem_type, uint32_t& size) {
175
0
  if (delegate_) {
176
0
    return delegate_->setBegin(elem_type, size);
177
0
  }
178
179
0
  elem_type_ = elem_type;
180
0
  remaining_ = size;
181
182
0
  delegateComplete();
183
184
0
  return FilterStatus::Continue;
185
0
}
186
187
0
FilterStatus ThriftSetValueImpl::setEnd() {
188
0
  if (delegate_) {
189
0
    return delegate_->setEnd();
190
0
  }
191
192
0
  ASSERT(remaining_ == 0);
193
0
  parent_->delegateComplete();
194
0
  return FilterStatus::Continue;
195
0
}
196
197
0
void ThriftSetValueImpl::delegateComplete() {
198
0
  delegate_ = nullptr;
199
200
0
  if (remaining_ == 0) {
201
0
    return;
202
0
  }
203
204
0
  auto elem = makeValue(this, elem_type_);
205
0
  delegate_ = elem.get();
206
0
  elements_.push_back(std::move(elem));
207
0
  remaining_--;
208
0
}
209
210
FilterStatus ThriftMapValueImpl::mapBegin(FieldType& key_type, FieldType& elem_type,
211
0
                                          uint32_t& size) {
212
0
  if (delegate_) {
213
0
    return delegate_->mapBegin(key_type, elem_type, size);
214
0
  }
215
216
0
  key_type_ = key_type;
217
0
  elem_type_ = elem_type;
218
0
  remaining_ = size;
219
220
0
  delegateComplete();
221
222
0
  return FilterStatus::Continue;
223
0
}
224
225
0
FilterStatus ThriftMapValueImpl::mapEnd() {
226
0
  if (delegate_) {
227
0
    return delegate_->mapEnd();
228
0
  }
229
230
0
  ASSERT(remaining_ == 0);
231
0
  parent_->delegateComplete();
232
0
  return FilterStatus::Continue;
233
0
}
234
235
0
void ThriftMapValueImpl::delegateComplete() {
236
0
  delegate_ = nullptr;
237
238
0
  if (remaining_ == 0) {
239
0
    return;
240
0
  }
241
242
  // Prepare for first element's key.
243
0
  if (elements_.empty()) {
244
0
    auto key = makeValue(this, key_type_);
245
0
    delegate_ = key.get();
246
0
    elements_.emplace_back(std::move(key), nullptr);
247
0
    return;
248
0
  }
249
250
  // Prepare for any element's value.
251
0
  auto& elem = elements_.back();
252
0
  if (elem.second == nullptr) {
253
0
    auto value = makeValue(this, elem_type_);
254
0
    delegate_ = value.get();
255
0
    elem.second = std::move(value);
256
257
0
    remaining_--;
258
0
    return;
259
0
  }
260
261
  // Key-value pair completed, prepare for next key.
262
0
  auto key = makeValue(this, key_type_);
263
0
  delegate_ = key.get();
264
0
  elements_.emplace_back(std::move(key), nullptr);
265
0
}
266
267
0
FilterStatus ThriftValueImpl::boolValue(bool& value) {
268
0
  ASSERT(value_type_ == FieldType::Bool);
269
0
  bool_value_ = value;
270
0
  parent_->delegateComplete();
271
0
  return FilterStatus::Continue;
272
0
}
273
274
0
FilterStatus ThriftValueImpl::byteValue(uint8_t& value) {
275
0
  ASSERT(value_type_ == FieldType::Byte);
276
0
  byte_value_ = value;
277
0
  parent_->delegateComplete();
278
0
  return FilterStatus::Continue;
279
0
}
280
281
0
FilterStatus ThriftValueImpl::int16Value(int16_t& value) {
282
0
  ASSERT(value_type_ == FieldType::I16);
283
0
  int16_value_ = value;
284
0
  parent_->delegateComplete();
285
0
  return FilterStatus::Continue;
286
0
}
287
288
0
FilterStatus ThriftValueImpl::int32Value(int32_t& value) {
289
0
  ASSERT(value_type_ == FieldType::I32);
290
0
  int32_value_ = value;
291
0
  parent_->delegateComplete();
292
0
  return FilterStatus::Continue;
293
0
}
294
295
0
FilterStatus ThriftValueImpl::int64Value(int64_t& value) {
296
0
  ASSERT(value_type_ == FieldType::I64);
297
0
  int64_value_ = value;
298
0
  parent_->delegateComplete();
299
0
  return FilterStatus::Continue;
300
0
}
301
302
0
FilterStatus ThriftValueImpl::doubleValue(double& value) {
303
0
  ASSERT(value_type_ == FieldType::Double);
304
0
  double_value_ = value;
305
0
  parent_->delegateComplete();
306
0
  return FilterStatus::Continue;
307
0
}
308
309
0
FilterStatus ThriftValueImpl::stringValue(absl::string_view value) {
310
0
  ASSERT(value_type_ == FieldType::String);
311
0
  string_value_ = std::string(value);
312
0
  parent_->delegateComplete();
313
0
  return FilterStatus::Continue;
314
0
}
315
316
0
const void* ThriftValueImpl::getValue() const {
317
0
  switch (value_type_) {
318
0
  case FieldType::Bool:
319
0
    return &bool_value_;
320
0
  case FieldType::Byte:
321
0
    return &byte_value_;
322
0
  case FieldType::I16:
323
0
    return &int16_value_;
324
0
  case FieldType::I32:
325
0
    return &int32_value_;
326
0
  case FieldType::I64:
327
0
    return &int64_value_;
328
0
  case FieldType::Double:
329
0
    return &double_value_;
330
0
  case FieldType::String:
331
0
    return &string_value_;
332
0
  default:
333
0
    PANIC("not handled");
334
0
  }
335
0
}
336
337
0
FilterStatus ThriftStructValueImpl::structBegin(absl::string_view name) {
338
0
  if (delegate_) {
339
0
    return delegate_->structBegin(name);
340
0
  }
341
342
0
  return FilterStatus::Continue;
343
0
}
344
345
0
FilterStatus ThriftStructValueImpl::structEnd() {
346
0
  if (delegate_) {
347
0
    return delegate_->structEnd();
348
0
  }
349
350
0
  if (parent_) {
351
0
    parent_->delegateComplete();
352
0
  }
353
354
0
  return FilterStatus::Continue;
355
0
}
356
357
FilterStatus ThriftStructValueImpl::fieldBegin(absl::string_view name, FieldType& field_type,
358
0
                                               int16_t& field_id) {
359
0
  if (delegate_) {
360
0
    return delegate_->fieldBegin(name, field_type, field_id);
361
0
  }
362
363
0
  if (field_type != FieldType::Stop) {
364
0
    auto field = std::make_unique<ThriftFieldImpl>(this, name, field_type, field_id);
365
0
    delegate_ = field.get();
366
0
    fields_.emplace_back(std::move(field));
367
0
  }
368
369
0
  return FilterStatus::Continue;
370
0
}
371
372
ThriftObjectImpl::ThriftObjectImpl(Transport& transport, Protocol& protocol)
373
    : ThriftStructValueImpl(nullptr),
374
0
      decoder_(std::make_unique<Decoder>(transport, protocol, *this)) {}
375
376
0
bool ThriftObjectImpl::onData(Buffer::Instance& buffer) {
377
0
  bool underflow = false;
378
0
  auto result = decoder_->onData(buffer, underflow);
379
0
  ASSERT(result == FilterStatus::Continue);
380
381
0
  if (complete_) {
382
0
    decoder_.reset();
383
0
  }
384
0
  return complete_;
385
0
}
386
387
} // namespace ThriftProxy
388
} // namespace NetworkFilters
389
} // namespace Extensions
390
} // namespace Envoy