Coverage Report

Created: 2024-07-23 06:31

/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
82.9M
void EncodeRawVarint(uint64_t value, size_t size, absl::Span<char> *buf) {
32
216M
  for (size_t s = 0; s < size; s++) {
33
133M
    (*buf)[s] = static_cast<char>((value & 0x7f) | (s + 1 == size ? 0 : 0x80));
34
133M
    value >>= 7;
35
133M
  }
36
82.9M
  buf->remove_prefix(size);
37
82.9M
}
38
36.5M
constexpr uint64_t MakeTagType(uint64_t tag, WireType type) {
39
36.5M
  return tag << 3 | static_cast<uint64_t>(type);
40
36.5M
}
41
}  // namespace
42
43
17.8M
bool EncodeVarint(uint64_t tag, uint64_t value, absl::Span<char> *buf) {
44
17.8M
  const uint64_t tag_type = MakeTagType(tag, WireType::kVarint);
45
17.8M
  const size_t tag_type_size = VarintSize(tag_type);
46
17.8M
  const size_t value_size = VarintSize(value);
47
17.8M
  if (tag_type_size + value_size > buf->size()) {
48
0
    buf->remove_suffix(buf->size());
49
0
    return false;
50
0
  }
51
17.8M
  EncodeRawVarint(tag_type, tag_type_size, buf);
52
17.8M
  EncodeRawVarint(value, value_size, buf);
53
17.8M
  return true;
54
17.8M
}
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
8.90M
                         absl::Span<char> *buf) {
107
8.90M
  const uint64_t tag_type = MakeTagType(tag, WireType::kLengthDelimited);
108
8.90M
  const size_t tag_type_size = VarintSize(tag_type);
109
8.90M
  uint64_t length = value.size();
110
8.90M
  const size_t length_size =
111
8.90M
      VarintSize(std::min<uint64_t>(length, buf->size()));
112
8.90M
  if (tag_type_size + length_size <= buf->size() &&
113
8.90M
      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
8.90M
  if (tag_type_size + length_size + value.size() > buf->size()) {
119
0
    buf->remove_suffix(buf->size());
120
0
    return false;
121
0
  }
122
8.90M
  EncodeRawVarint(tag_type, tag_type_size, buf);
123
8.90M
  EncodeRawVarint(length, length_size, buf);
124
8.90M
  memcpy(buf->data(), value.data(), value.size());
125
8.90M
  buf->remove_prefix(value.size());
126
8.90M
  return true;
127
8.90M
}
128
129
ABSL_MUST_USE_RESULT absl::Span<char> EncodeMessageStart(
130
9.85M
    uint64_t tag, uint64_t max_size, absl::Span<char> *buf) {
131
9.85M
  const uint64_t tag_type = MakeTagType(tag, WireType::kLengthDelimited);
132
9.85M
  const size_t tag_type_size = VarintSize(tag_type);
133
9.85M
  max_size = std::min<uint64_t>(max_size, buf->size());
134
9.85M
  const size_t length_size = VarintSize(max_size);
135
9.85M
  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.85M
  EncodeRawVarint(tag_type, tag_type_size, buf);
140
9.85M
  const absl::Span<char> ret = buf->subspan(0, length_size);
141
9.85M
  EncodeRawVarint(0, length_size, buf);
142
9.85M
  return ret;
143
9.85M
}
144
145
9.85M
void EncodeMessageLength(absl::Span<char> msg, const absl::Span<char> *buf) {
146
9.85M
  if (!msg.data()) return;
147
9.85M
  assert(buf->data() >= msg.data());
148
9.85M
  if (buf->data() < msg.data()) return;
149
9.85M
  EncodeRawVarint(
150
9.85M
      static_cast<uint64_t>(buf->data() - (msg.data() + msg.size())),
151
9.85M
      msg.size(), &msg);
152
9.85M
}
153
154
namespace {
155
73.1M
uint64_t DecodeVarint(absl::Span<const char> *buf) {
156
73.1M
  uint64_t value = 0;
157
73.1M
  size_t s = 0;
158
118M
  while (s < buf->size()) {
159
118M
    value |= static_cast<uint64_t>(static_cast<unsigned char>((*buf)[s]) & 0x7f)
160
118M
             << 7 * s;
161
118M
    if (!((*buf)[s++] & 0x80)) break;
162
118M
  }
163
73.1M
  buf->remove_prefix(s);
164
73.1M
  return value;
165
73.1M
}
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
48.1M
bool ProtoField::DecodeFrom(absl::Span<const char> *data) {
193
48.1M
  if (data->empty()) return false;
194
36.5M
  const uint64_t tag_type = DecodeVarint(data);
195
36.5M
  tag_ = tag_type >> 3;
196
36.5M
  type_ = static_cast<WireType>(tag_type & 0x07);
197
36.5M
  switch (type_) {
198
17.8M
    case WireType::kVarint:
199
17.8M
      value_ = DecodeVarint(data);
200
17.8M
      break;
201
0
    case WireType::k64Bit:
202
0
      value_ = Decode64Bit(data);
203
0
      break;
204
18.7M
    case WireType::kLengthDelimited: {
205
18.7M
      value_ = DecodeVarint(data);
206
18.7M
      data_ = data->subspan(
207
18.7M
          0, static_cast<size_t>(std::min<uint64_t>(value_, data->size())));
208
18.7M
      data->remove_prefix(data_.size());
209
18.7M
      break;
210
0
    }
211
0
    case WireType::k32Bit:
212
0
      value_ = Decode32Bit(data);
213
0
      break;
214
36.5M
  }
215
36.5M
  return true;
216
36.5M
}
217
218
}  // namespace log_internal
219
ABSL_NAMESPACE_END
220
}  // namespace absl