tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

proto.cc (7010B)


      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 void EncodeRawVarint(uint64_t value, size_t size, absl::Span<char> *buf) {
     32  for (size_t s = 0; s < size; s++) {
     33    (*buf)[s] = static_cast<char>((value & 0x7f) | (s + 1 == size ? 0 : 0x80));
     34    value >>= 7;
     35  }
     36  buf->remove_prefix(size);
     37 }
     38 }  // namespace
     39 
     40 bool EncodeVarint(uint64_t tag, uint64_t value, absl::Span<char> *buf) {
     41  const uint64_t tag_type = MakeTagType(tag, WireType::kVarint);
     42  const size_t tag_type_size = VarintSize(tag_type);
     43  const size_t value_size = VarintSize(value);
     44  if (tag_type_size + value_size > buf->size()) {
     45    buf->remove_suffix(buf->size());
     46    return false;
     47  }
     48  EncodeRawVarint(tag_type, tag_type_size, buf);
     49  EncodeRawVarint(value, value_size, buf);
     50  return true;
     51 }
     52 
     53 bool Encode64Bit(uint64_t tag, uint64_t value, absl::Span<char> *buf) {
     54  const uint64_t tag_type = MakeTagType(tag, WireType::k64Bit);
     55  const size_t tag_type_size = VarintSize(tag_type);
     56  if (tag_type_size + sizeof(value) > buf->size()) {
     57    buf->remove_suffix(buf->size());
     58    return false;
     59  }
     60  EncodeRawVarint(tag_type, tag_type_size, buf);
     61  for (size_t s = 0; s < sizeof(value); s++) {
     62    (*buf)[s] = static_cast<char>(value & 0xff);
     63    value >>= 8;
     64  }
     65  buf->remove_prefix(sizeof(value));
     66  return true;
     67 }
     68 
     69 bool Encode32Bit(uint64_t tag, uint32_t value, absl::Span<char> *buf) {
     70  const uint64_t tag_type = MakeTagType(tag, WireType::k32Bit);
     71  const size_t tag_type_size = VarintSize(tag_type);
     72  if (tag_type_size + sizeof(value) > buf->size()) {
     73    buf->remove_suffix(buf->size());
     74    return false;
     75  }
     76  EncodeRawVarint(tag_type, tag_type_size, buf);
     77  for (size_t s = 0; s < sizeof(value); s++) {
     78    (*buf)[s] = static_cast<char>(value & 0xff);
     79    value >>= 8;
     80  }
     81  buf->remove_prefix(sizeof(value));
     82  return true;
     83 }
     84 
     85 bool EncodeBytes(uint64_t tag, absl::Span<const char> value,
     86                 absl::Span<char> *buf) {
     87  const uint64_t tag_type = MakeTagType(tag, WireType::kLengthDelimited);
     88  const size_t tag_type_size = VarintSize(tag_type);
     89  uint64_t length = value.size();
     90  const size_t length_size = VarintSize(length);
     91  if (tag_type_size + length_size + value.size() > buf->size()) {
     92    buf->remove_suffix(buf->size());
     93    return false;
     94  }
     95  EncodeRawVarint(tag_type, tag_type_size, buf);
     96  EncodeRawVarint(length, length_size, buf);
     97  memcpy(buf->data(), value.data(), value.size());
     98  buf->remove_prefix(value.size());
     99  return true;
    100 }
    101 
    102 bool EncodeBytesTruncate(uint64_t tag, absl::Span<const char> value,
    103                         absl::Span<char> *buf) {
    104  const uint64_t tag_type = MakeTagType(tag, WireType::kLengthDelimited);
    105  const size_t tag_type_size = VarintSize(tag_type);
    106  uint64_t length = value.size();
    107  const size_t length_size =
    108      VarintSize(std::min<uint64_t>(length, buf->size()));
    109  if (tag_type_size + length_size <= buf->size() &&
    110      tag_type_size + length_size + value.size() > buf->size()) {
    111    value.remove_suffix(tag_type_size + length_size + value.size() -
    112                        buf->size());
    113    length = value.size();
    114  }
    115  if (tag_type_size + length_size + value.size() > buf->size()) {
    116    buf->remove_suffix(buf->size());
    117    return false;
    118  }
    119  EncodeRawVarint(tag_type, tag_type_size, buf);
    120  EncodeRawVarint(length, length_size, buf);
    121  memcpy(buf->data(), value.data(), value.size());
    122  buf->remove_prefix(value.size());
    123  return true;
    124 }
    125 
    126 [[nodiscard]] absl::Span<char> EncodeMessageStart(uint64_t tag,
    127                                                  uint64_t max_size,
    128                                                  absl::Span<char> *buf) {
    129  const uint64_t tag_type = MakeTagType(tag, WireType::kLengthDelimited);
    130  const size_t tag_type_size = VarintSize(tag_type);
    131  max_size = std::min<uint64_t>(max_size, buf->size());
    132  const size_t length_size = VarintSize(max_size);
    133  if (tag_type_size + length_size > buf->size()) {
    134    buf->remove_suffix(buf->size());
    135    return absl::Span<char>();
    136  }
    137  EncodeRawVarint(tag_type, tag_type_size, buf);
    138  const absl::Span<char> ret = buf->subspan(0, length_size);
    139  EncodeRawVarint(0, length_size, buf);
    140  return ret;
    141 }
    142 
    143 void EncodeMessageLength(absl::Span<char> msg, const absl::Span<char> *buf) {
    144  if (!msg.data()) return;
    145  assert(buf->data() >= msg.data());
    146  if (buf->data() < msg.data()) return;
    147  EncodeRawVarint(
    148      static_cast<uint64_t>(buf->data() - (msg.data() + msg.size())),
    149      msg.size(), &msg);
    150 }
    151 
    152 namespace {
    153 uint64_t DecodeVarint(absl::Span<const char> *buf) {
    154  uint64_t value = 0;
    155  size_t s = 0;
    156  while (s < buf->size()) {
    157    value |= static_cast<uint64_t>(static_cast<unsigned char>((*buf)[s]) & 0x7f)
    158             << 7 * s;
    159    if (!((*buf)[s++] & 0x80)) break;
    160  }
    161  buf->remove_prefix(s);
    162  return value;
    163 }
    164 
    165 uint64_t Decode64Bit(absl::Span<const char> *buf) {
    166  uint64_t value = 0;
    167  size_t s = 0;
    168  while (s < buf->size()) {
    169    value |= static_cast<uint64_t>(static_cast<unsigned char>((*buf)[s]))
    170             << 8 * s;
    171    if (++s == sizeof(value)) break;
    172  }
    173  buf->remove_prefix(s);
    174  return value;
    175 }
    176 
    177 uint32_t Decode32Bit(absl::Span<const char> *buf) {
    178  uint32_t value = 0;
    179  size_t s = 0;
    180  while (s < buf->size()) {
    181    value |= static_cast<uint32_t>(static_cast<unsigned char>((*buf)[s]))
    182             << 8 * s;
    183    if (++s == sizeof(value)) break;
    184  }
    185  buf->remove_prefix(s);
    186  return value;
    187 }
    188 }  // namespace
    189 
    190 bool ProtoField::DecodeFrom(absl::Span<const char> *data) {
    191  if (data->empty()) return false;
    192  const uint64_t tag_type = DecodeVarint(data);
    193  tag_ = tag_type >> 3;
    194  type_ = static_cast<WireType>(tag_type & 0x07);
    195  switch (type_) {
    196    case WireType::kVarint:
    197      value_ = DecodeVarint(data);
    198      break;
    199    case WireType::k64Bit:
    200      value_ = Decode64Bit(data);
    201      break;
    202    case WireType::kLengthDelimited: {
    203      value_ = DecodeVarint(data);
    204      data_ = data->subspan(
    205          0, static_cast<size_t>(std::min<uint64_t>(value_, data->size())));
    206      data->remove_prefix(data_.size());
    207      break;
    208    }
    209    case WireType::k32Bit:
    210      value_ = Decode32Bit(data);
    211      break;
    212  }
    213  return true;
    214 }
    215 
    216 }  // namespace log_internal
    217 ABSL_NAMESPACE_END
    218 }  // namespace absl