Coverage Report

Created: 2023-09-25 06:27

/src/abseil-cpp/absl/log/internal/proto.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2020 The Abseil Authors.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      https://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
15
#include "absl/log/internal/proto.h"
16
17
#include <algorithm>
18
#include <cassert>
19
#include <cstddef>
20
#include <cstdint>
21
#include <cstring>
22
23
#include "absl/base/attributes.h"
24
#include "absl/base/config.h"
25
#include "absl/types/span.h"
26
27
namespace absl {
28
ABSL_NAMESPACE_BEGIN
29
namespace log_internal {
30
namespace {
31
35.6M
void EncodeRawVarint(uint64_t value, size_t size, absl::Span<char> *buf) {
32
84.1M
  for (size_t s = 0; s < size; s++) {
33
48.5M
    (*buf)[s] = static_cast<char>((value & 0x7f) | (s + 1 == size ? 0 : 0x80));
34
48.5M
    value >>= 7;
35
48.5M
  }
36
35.6M
  buf->remove_prefix(size);
37
35.6M
}
38
12.9M
constexpr uint64_t MakeTagType(uint64_t tag, WireType type) {
39
12.9M
  return tag << 3 | static_cast<uint64_t>(type);
40
12.9M
}
41
}  // namespace
42
43
0
bool EncodeVarint(uint64_t tag, uint64_t value, absl::Span<char> *buf) {
44
0
  const uint64_t tag_type = MakeTagType(tag, WireType::kVarint);
45
0
  const size_t tag_type_size = VarintSize(tag_type);
46
0
  const size_t value_size = VarintSize(value);
47
0
  if (tag_type_size + value_size > buf->size()) {
48
0
    buf->remove_suffix(buf->size());
49
0
    return false;
50
0
  }
51
0
  EncodeRawVarint(tag_type, tag_type_size, buf);
52
0
  EncodeRawVarint(value, value_size, buf);
53
0
  return true;
54
0
}
55
56
0
bool Encode64Bit(uint64_t tag, uint64_t value, absl::Span<char> *buf) {
57
0
  const uint64_t tag_type = MakeTagType(tag, WireType::k64Bit);
58
0
  const size_t tag_type_size = VarintSize(tag_type);
59
0
  if (tag_type_size + sizeof(value) > buf->size()) {
60
0
    buf->remove_suffix(buf->size());
61
0
    return false;
62
0
  }
63
0
  EncodeRawVarint(tag_type, tag_type_size, buf);
64
0
  for (size_t s = 0; s < sizeof(value); s++) {
65
0
    (*buf)[s] = static_cast<char>(value & 0xff);
66
0
    value >>= 8;
67
0
  }
68
0
  buf->remove_prefix(sizeof(value));
69
0
  return true;
70
0
}
71
72
0
bool Encode32Bit(uint64_t tag, uint32_t value, absl::Span<char> *buf) {
73
0
  const uint64_t tag_type = MakeTagType(tag, WireType::k32Bit);
74
0
  const size_t tag_type_size = VarintSize(tag_type);
75
0
  if (tag_type_size + sizeof(value) > buf->size()) {
76
0
    buf->remove_suffix(buf->size());
77
0
    return false;
78
0
  }
79
0
  EncodeRawVarint(tag_type, tag_type_size, buf);
80
0
  for (size_t s = 0; s < sizeof(value); s++) {
81
0
    (*buf)[s] = static_cast<char>(value & 0xff);
82
0
    value >>= 8;
83
0
  }
84
0
  buf->remove_prefix(sizeof(value));
85
0
  return true;
86
0
}
87
88
bool EncodeBytes(uint64_t tag, absl::Span<const char> value,
89
0
                 absl::Span<char> *buf) {
90
0
  const uint64_t tag_type = MakeTagType(tag, WireType::kLengthDelimited);
91
0
  const size_t tag_type_size = VarintSize(tag_type);
92
0
  uint64_t length = value.size();
93
0
  const size_t length_size = VarintSize(length);
94
0
  if (tag_type_size + length_size + value.size() > buf->size()) {
95
0
    buf->remove_suffix(buf->size());
96
0
    return false;
97
0
  }
98
0
  EncodeRawVarint(tag_type, tag_type_size, buf);
99
0
  EncodeRawVarint(length, length_size, buf);
100
0
  memcpy(buf->data(), value.data(), value.size());
101
0
  buf->remove_prefix(value.size());
102
0
  return true;
103
0
}
104
105
bool EncodeBytesTruncate(uint64_t tag, absl::Span<const char> value,
106
3.24M
                         absl::Span<char> *buf) {
107
3.24M
  const uint64_t tag_type = MakeTagType(tag, WireType::kLengthDelimited);
108
3.24M
  const size_t tag_type_size = VarintSize(tag_type);
109
3.24M
  uint64_t length = value.size();
110
3.24M
  const size_t length_size =
111
3.24M
      VarintSize(std::min<uint64_t>(length, buf->size()));
112
3.24M
  if (tag_type_size + length_size <= buf->size() &&
113
3.24M
      tag_type_size + length_size + value.size() > buf->size()) {
114
0
    value.remove_suffix(tag_type_size + length_size + value.size() -
115
0
                        buf->size());
116
0
    length = value.size();
117
0
  }
118
3.24M
  if (tag_type_size + length_size + value.size() > buf->size()) {
119
0
    buf->remove_suffix(buf->size());
120
0
    return false;
121
0
  }
122
3.24M
  EncodeRawVarint(tag_type, tag_type_size, buf);
123
3.24M
  EncodeRawVarint(length, length_size, buf);
124
3.24M
  memcpy(buf->data(), value.data(), value.size());
125
3.24M
  buf->remove_prefix(value.size());
126
3.24M
  return true;
127
3.24M
}
128
129
ABSL_MUST_USE_RESULT absl::Span<char> EncodeMessageStart(
130
9.71M
    uint64_t tag, uint64_t max_size, absl::Span<char> *buf) {
131
9.71M
  const uint64_t tag_type = MakeTagType(tag, WireType::kLengthDelimited);
132
9.71M
  const size_t tag_type_size = VarintSize(tag_type);
133
9.71M
  max_size = std::min<uint64_t>(max_size, buf->size());
134
9.71M
  const size_t length_size = VarintSize(max_size);
135
9.71M
  if (tag_type_size + length_size > buf->size()) {
136
0
    buf->remove_suffix(buf->size());
137
0
    return absl::Span<char>();
138
0
  }
139
9.71M
  EncodeRawVarint(tag_type, tag_type_size, buf);
140
9.71M
  const absl::Span<char> ret = buf->subspan(0, length_size);
141
9.71M
  EncodeRawVarint(0, length_size, buf);
142
9.71M
  return ret;
143
9.71M
}
144
145
9.71M
void EncodeMessageLength(absl::Span<char> msg, const absl::Span<char> *buf) {
146
9.71M
  if (!msg.data()) return;
147
9.71M
  assert(buf->data() >= msg.data());
148
9.71M
  if (buf->data() < msg.data()) return;
149
9.71M
  EncodeRawVarint(
150
9.71M
      static_cast<uint64_t>(buf->data() - (msg.data() + msg.size())),
151
9.71M
      msg.size(), &msg);
152
9.71M
}
153
154
namespace {
155
25.9M
uint64_t DecodeVarint(absl::Span<const char> *buf) {
156
25.9M
  uint64_t value = 0;
157
25.9M
  size_t s = 0;
158
32.3M
  while (s < buf->size()) {
159
32.3M
    value |= static_cast<uint64_t>(static_cast<unsigned char>((*buf)[s]) & 0x7f)
160
32.3M
             << 7 * s;
161
32.3M
    if (!((*buf)[s++] & 0x80)) break;
162
32.3M
  }
163
25.9M
  buf->remove_prefix(s);
164
25.9M
  return value;
165
25.9M
}
166
167
0
uint64_t Decode64Bit(absl::Span<const char> *buf) {
168
0
  uint64_t value = 0;
169
0
  size_t s = 0;
170
0
  while (s < buf->size()) {
171
0
    value |= static_cast<uint64_t>(static_cast<unsigned char>((*buf)[s]))
172
0
             << 8 * s;
173
0
    if (++s == sizeof(value)) break;
174
0
  }
175
0
  buf->remove_prefix(s);
176
0
  return value;
177
0
}
178
179
0
uint32_t Decode32Bit(absl::Span<const char> *buf) {
180
0
  uint32_t value = 0;
181
0
  size_t s = 0;
182
0
  while (s < buf->size()) {
183
0
    value |= static_cast<uint32_t>(static_cast<unsigned char>((*buf)[s]))
184
0
             << 8 * s;
185
0
    if (++s == sizeof(value)) break;
186
0
  }
187
0
  buf->remove_prefix(s);
188
0
  return value;
189
0
}
190
}  // namespace
191
192
22.6M
bool ProtoField::DecodeFrom(absl::Span<const char> *data) {
193
22.6M
  if (data->empty()) return false;
194
12.9M
  const uint64_t tag_type = DecodeVarint(data);
195
12.9M
  tag_ = tag_type >> 3;
196
12.9M
  type_ = static_cast<WireType>(tag_type & 0x07);
197
12.9M
  switch (type_) {
198
0
    case WireType::kVarint:
199
0
      value_ = DecodeVarint(data);
200
0
      break;
201
0
    case WireType::k64Bit:
202
0
      value_ = Decode64Bit(data);
203
0
      break;
204
12.9M
    case WireType::kLengthDelimited: {
205
12.9M
      value_ = DecodeVarint(data);
206
12.9M
      data_ = data->subspan(
207
12.9M
          0, static_cast<size_t>(std::min<uint64_t>(value_, data->size())));
208
12.9M
      data->remove_prefix(data_.size());
209
12.9M
      break;
210
0
    }
211
0
    case WireType::k32Bit:
212
0
      value_ = Decode32Bit(data);
213
0
      break;
214
12.9M
  }
215
12.9M
  return true;
216
12.9M
}
217
218
}  // namespace log_internal
219
ABSL_NAMESPACE_END
220
}  // namespace absl