Coverage Report

Created: 2026-08-11 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libprotobuf-mutator/build/external.protobuf/src/external.protobuf/src/google/protobuf/extension_set_inl.h
Line
Count
Source
1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc.  All rights reserved.
3
//
4
// Use of this source code is governed by a BSD-style
5
// license that can be found in the LICENSE file or at
6
// https://developers.google.com/open-source/licenses/bsd
7
8
#ifndef GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
9
#define GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
10
11
#include "google/protobuf/extension_set.h"
12
#include "google/protobuf/metadata_lite.h"
13
#include "google/protobuf/parse_context.h"
14
15
namespace google {
16
namespace protobuf {
17
namespace internal {
18
19
template <typename T>
20
const char* ExtensionSet::ParseFieldWithExtensionInfo(
21
    int number, bool was_packed_on_wire, const ExtensionInfo& extension,
22
16
    InternalMetadata* metadata, const char* ptr, internal::ParseContext* ctx) {
23
16
  if (was_packed_on_wire) {
24
0
    switch (extension.type) {
25
0
#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE)                                \
26
0
  case WireFormatLite::TYPE_##UPPERCASE:                                     \
27
0
    return internal::Packed##CPP_CAMELCASE##Parser(                          \
28
0
        MutableRawRepeatedField(number, extension.type, extension.is_packed, \
29
0
                                extension.descriptor),                       \
30
0
        ptr, ctx);
31
0
      HANDLE_TYPE(INT32, Int32);
32
0
      HANDLE_TYPE(INT64, Int64);
33
0
      HANDLE_TYPE(UINT32, UInt32);
34
0
      HANDLE_TYPE(UINT64, UInt64);
35
0
      HANDLE_TYPE(SINT32, SInt32);
36
0
      HANDLE_TYPE(SINT64, SInt64);
37
0
      HANDLE_TYPE(FIXED32, Fixed32);
38
0
      HANDLE_TYPE(FIXED64, Fixed64);
39
0
      HANDLE_TYPE(SFIXED32, SFixed32);
40
0
      HANDLE_TYPE(SFIXED64, SFixed64);
41
0
      HANDLE_TYPE(FLOAT, Float);
42
0
      HANDLE_TYPE(DOUBLE, Double);
43
0
      HANDLE_TYPE(BOOL, Bool);
44
0
#undef HANDLE_TYPE
45
46
0
      case WireFormatLite::TYPE_ENUM:
47
0
        return internal::PackedEnumParserArg<T>(
48
0
            MutableRawRepeatedField(number, extension.type, extension.is_packed,
49
0
                                    extension.descriptor),
50
0
            ptr, ctx, extension.enum_validity_check.func,
51
0
            extension.enum_validity_check.arg, metadata, number);
52
0
      case WireFormatLite::TYPE_STRING:
53
0
      case WireFormatLite::TYPE_BYTES:
54
0
      case WireFormatLite::TYPE_GROUP:
55
0
      case WireFormatLite::TYPE_MESSAGE:
56
0
        ABSL_LOG(FATAL) << "Non-primitive types can't be packed.";
57
0
        break;
58
0
    }
59
16
  } else {
60
16
    switch (extension.type) {
61
0
#define HANDLE_VARINT_TYPE(UPPERCASE, CPP_CAMELCASE)                        \
62
0
  case WireFormatLite::TYPE_##UPPERCASE: {                                  \
63
0
    uint64_t value;                                                         \
64
0
    ptr = VarintParse(ptr, &value);                                         \
65
0
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);                                    \
66
0
    if (extension.is_repeated) {                                            \
67
0
      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
68
0
                         extension.is_packed, value, extension.descriptor); \
69
0
    } else {                                                                \
70
0
      Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,   \
71
0
                         extension.descriptor);                             \
72
0
    }                                                                       \
73
0
  } break
74
75
0
      HANDLE_VARINT_TYPE(INT32, Int32);
76
0
      HANDLE_VARINT_TYPE(INT64, Int64);
77
0
      HANDLE_VARINT_TYPE(UINT32, UInt32);
78
0
      HANDLE_VARINT_TYPE(UINT64, UInt64);
79
0
      HANDLE_VARINT_TYPE(BOOL, Bool);
80
0
#undef HANDLE_VARINT_TYPE
81
0
#define HANDLE_SVARINT_TYPE(UPPERCASE, CPP_CAMELCASE, SIZE)                 \
82
0
  case WireFormatLite::TYPE_##UPPERCASE: {                                  \
83
0
    uint64_t val;                                                           \
84
0
    ptr = VarintParse(ptr, &val);                                           \
85
0
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);                                    \
86
0
    auto value = WireFormatLite::ZigZagDecode##SIZE(val);                   \
87
0
    if (extension.is_repeated) {                                            \
88
0
      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
89
0
                         extension.is_packed, value, extension.descriptor); \
90
0
    } else {                                                                \
91
0
      Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,   \
92
0
                         extension.descriptor);                             \
93
0
    }                                                                       \
94
0
  } break
95
96
0
      HANDLE_SVARINT_TYPE(SINT32, Int32, 32);
97
0
      HANDLE_SVARINT_TYPE(SINT64, Int64, 64);
98
0
#undef HANDLE_SVARINT_TYPE
99
0
#define HANDLE_FIXED_TYPE(UPPERCASE, CPP_CAMELCASE, CPPTYPE)                \
100
0
  case WireFormatLite::TYPE_##UPPERCASE: {                                  \
101
0
    auto value = UnalignedLoad<CPPTYPE>(ptr);                               \
102
0
    ptr += sizeof(CPPTYPE);                                                 \
103
0
    if (extension.is_repeated) {                                            \
104
0
      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
105
0
                         extension.is_packed, value, extension.descriptor); \
106
0
    } else {                                                                \
107
0
      Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,   \
108
0
                         extension.descriptor);                             \
109
0
    }                                                                       \
110
0
  } break
111
112
0
      HANDLE_FIXED_TYPE(FIXED32, UInt32, uint32_t);
113
0
      HANDLE_FIXED_TYPE(FIXED64, UInt64, uint64_t);
114
0
      HANDLE_FIXED_TYPE(SFIXED32, Int32, int32_t);
115
0
      HANDLE_FIXED_TYPE(SFIXED64, Int64, int64_t);
116
0
      HANDLE_FIXED_TYPE(FLOAT, Float, float);
117
0
      HANDLE_FIXED_TYPE(DOUBLE, Double, double);
118
0
#undef HANDLE_FIXED_TYPE
119
120
0
      case WireFormatLite::TYPE_ENUM: {
121
0
        uint64_t tmp;
122
0
        ptr = VarintParse(ptr, &tmp);
123
0
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
124
0
        int value = tmp;
125
126
0
        if (!extension.enum_validity_check.func(
127
0
                extension.enum_validity_check.arg, value)) {
128
0
          WriteVarint(number, value, metadata->mutable_unknown_fields<T>());
129
0
        } else if (extension.is_repeated) {
130
0
          AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
131
0
                  extension.descriptor);
132
0
        } else {
133
0
          SetEnum(number, WireFormatLite::TYPE_ENUM, value,
134
0
                  extension.descriptor);
135
0
        }
136
0
        break;
137
0
      }
138
139
0
      case WireFormatLite::TYPE_BYTES:
140
0
      case WireFormatLite::TYPE_STRING: {
141
0
        std::string* value =
142
0
            extension.is_repeated
143
0
                ? AddString(number, WireFormatLite::TYPE_STRING,
144
0
                            extension.descriptor)
145
0
                : MutableString(number, WireFormatLite::TYPE_STRING,
146
0
                                extension.descriptor);
147
0
        int size = ReadSize(&ptr);
148
0
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
149
0
        return ctx->ReadString(ptr, size, value);
150
0
      }
151
152
0
      case WireFormatLite::TYPE_GROUP: {
153
0
        MessageLite* value =
154
0
            extension.is_repeated
155
0
                ? AddMessage(number, WireFormatLite::TYPE_GROUP,
156
0
                             *extension.message_info.prototype,
157
0
                             extension.descriptor)
158
0
                : MutableMessage(number, WireFormatLite::TYPE_GROUP,
159
0
                                 *extension.message_info.prototype,
160
0
                                 extension.descriptor);
161
0
        uint32_t tag = (number << 3) + WireFormatLite::WIRETYPE_START_GROUP;
162
0
        return ctx->ParseGroup(value, ptr, tag);
163
0
      }
164
165
16
      case WireFormatLite::TYPE_MESSAGE: {
166
16
        MessageLite* value =
167
16
            extension.is_repeated
168
16
                ? AddMessage(number, WireFormatLite::TYPE_MESSAGE,
169
0
                             *extension.message_info.prototype,
170
0
                             extension.descriptor)
171
16
                : MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
172
16
                                 *extension.message_info.prototype,
173
16
                                 extension.descriptor);
174
16
        return ctx->ParseMessage(value, ptr);
175
0
      }
176
16
    }
177
16
  }
178
0
  return ptr;
179
16
}
Unexecuted instantiation: char const* google::protobuf::internal::ExtensionSet::ParseFieldWithExtensionInfo<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(int, bool, google::protobuf::internal::ExtensionInfo const&, google::protobuf::internal::InternalMetadata*, char const*, google::protobuf::internal::ParseContext*)
char const* google::protobuf::internal::ExtensionSet::ParseFieldWithExtensionInfo<google::protobuf::UnknownFieldSet>(int, bool, google::protobuf::internal::ExtensionInfo const&, google::protobuf::internal::InternalMetadata*, char const*, google::protobuf::internal::ParseContext*)
Line
Count
Source
22
16
    InternalMetadata* metadata, const char* ptr, internal::ParseContext* ctx) {
23
16
  if (was_packed_on_wire) {
24
0
    switch (extension.type) {
25
0
#define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE)                                \
26
0
  case WireFormatLite::TYPE_##UPPERCASE:                                     \
27
0
    return internal::Packed##CPP_CAMELCASE##Parser(                          \
28
0
        MutableRawRepeatedField(number, extension.type, extension.is_packed, \
29
0
                                extension.descriptor),                       \
30
0
        ptr, ctx);
31
0
      HANDLE_TYPE(INT32, Int32);
32
0
      HANDLE_TYPE(INT64, Int64);
33
0
      HANDLE_TYPE(UINT32, UInt32);
34
0
      HANDLE_TYPE(UINT64, UInt64);
35
0
      HANDLE_TYPE(SINT32, SInt32);
36
0
      HANDLE_TYPE(SINT64, SInt64);
37
0
      HANDLE_TYPE(FIXED32, Fixed32);
38
0
      HANDLE_TYPE(FIXED64, Fixed64);
39
0
      HANDLE_TYPE(SFIXED32, SFixed32);
40
0
      HANDLE_TYPE(SFIXED64, SFixed64);
41
0
      HANDLE_TYPE(FLOAT, Float);
42
0
      HANDLE_TYPE(DOUBLE, Double);
43
0
      HANDLE_TYPE(BOOL, Bool);
44
0
#undef HANDLE_TYPE
45
46
0
      case WireFormatLite::TYPE_ENUM:
47
0
        return internal::PackedEnumParserArg<T>(
48
0
            MutableRawRepeatedField(number, extension.type, extension.is_packed,
49
0
                                    extension.descriptor),
50
0
            ptr, ctx, extension.enum_validity_check.func,
51
0
            extension.enum_validity_check.arg, metadata, number);
52
0
      case WireFormatLite::TYPE_STRING:
53
0
      case WireFormatLite::TYPE_BYTES:
54
0
      case WireFormatLite::TYPE_GROUP:
55
0
      case WireFormatLite::TYPE_MESSAGE:
56
0
        ABSL_LOG(FATAL) << "Non-primitive types can't be packed.";
57
0
        break;
58
0
    }
59
16
  } else {
60
16
    switch (extension.type) {
61
0
#define HANDLE_VARINT_TYPE(UPPERCASE, CPP_CAMELCASE)                        \
62
0
  case WireFormatLite::TYPE_##UPPERCASE: {                                  \
63
0
    uint64_t value;                                                         \
64
0
    ptr = VarintParse(ptr, &value);                                         \
65
0
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);                                    \
66
0
    if (extension.is_repeated) {                                            \
67
0
      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
68
0
                         extension.is_packed, value, extension.descriptor); \
69
0
    } else {                                                                \
70
0
      Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,   \
71
0
                         extension.descriptor);                             \
72
0
    }                                                                       \
73
0
  } break
74
75
0
      HANDLE_VARINT_TYPE(INT32, Int32);
76
0
      HANDLE_VARINT_TYPE(INT64, Int64);
77
0
      HANDLE_VARINT_TYPE(UINT32, UInt32);
78
0
      HANDLE_VARINT_TYPE(UINT64, UInt64);
79
0
      HANDLE_VARINT_TYPE(BOOL, Bool);
80
0
#undef HANDLE_VARINT_TYPE
81
0
#define HANDLE_SVARINT_TYPE(UPPERCASE, CPP_CAMELCASE, SIZE)                 \
82
0
  case WireFormatLite::TYPE_##UPPERCASE: {                                  \
83
0
    uint64_t val;                                                           \
84
0
    ptr = VarintParse(ptr, &val);                                           \
85
0
    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);                                    \
86
0
    auto value = WireFormatLite::ZigZagDecode##SIZE(val);                   \
87
0
    if (extension.is_repeated) {                                            \
88
0
      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
89
0
                         extension.is_packed, value, extension.descriptor); \
90
0
    } else {                                                                \
91
0
      Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,   \
92
0
                         extension.descriptor);                             \
93
0
    }                                                                       \
94
0
  } break
95
96
0
      HANDLE_SVARINT_TYPE(SINT32, Int32, 32);
97
0
      HANDLE_SVARINT_TYPE(SINT64, Int64, 64);
98
0
#undef HANDLE_SVARINT_TYPE
99
0
#define HANDLE_FIXED_TYPE(UPPERCASE, CPP_CAMELCASE, CPPTYPE)                \
100
0
  case WireFormatLite::TYPE_##UPPERCASE: {                                  \
101
0
    auto value = UnalignedLoad<CPPTYPE>(ptr);                               \
102
0
    ptr += sizeof(CPPTYPE);                                                 \
103
0
    if (extension.is_repeated) {                                            \
104
0
      Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE,          \
105
0
                         extension.is_packed, value, extension.descriptor); \
106
0
    } else {                                                                \
107
0
      Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,   \
108
0
                         extension.descriptor);                             \
109
0
    }                                                                       \
110
0
  } break
111
112
0
      HANDLE_FIXED_TYPE(FIXED32, UInt32, uint32_t);
113
0
      HANDLE_FIXED_TYPE(FIXED64, UInt64, uint64_t);
114
0
      HANDLE_FIXED_TYPE(SFIXED32, Int32, int32_t);
115
0
      HANDLE_FIXED_TYPE(SFIXED64, Int64, int64_t);
116
0
      HANDLE_FIXED_TYPE(FLOAT, Float, float);
117
0
      HANDLE_FIXED_TYPE(DOUBLE, Double, double);
118
0
#undef HANDLE_FIXED_TYPE
119
120
0
      case WireFormatLite::TYPE_ENUM: {
121
0
        uint64_t tmp;
122
0
        ptr = VarintParse(ptr, &tmp);
123
0
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
124
0
        int value = tmp;
125
126
0
        if (!extension.enum_validity_check.func(
127
0
                extension.enum_validity_check.arg, value)) {
128
0
          WriteVarint(number, value, metadata->mutable_unknown_fields<T>());
129
0
        } else if (extension.is_repeated) {
130
0
          AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
131
0
                  extension.descriptor);
132
0
        } else {
133
0
          SetEnum(number, WireFormatLite::TYPE_ENUM, value,
134
0
                  extension.descriptor);
135
0
        }
136
0
        break;
137
0
      }
138
139
0
      case WireFormatLite::TYPE_BYTES:
140
0
      case WireFormatLite::TYPE_STRING: {
141
0
        std::string* value =
142
0
            extension.is_repeated
143
0
                ? AddString(number, WireFormatLite::TYPE_STRING,
144
0
                            extension.descriptor)
145
0
                : MutableString(number, WireFormatLite::TYPE_STRING,
146
0
                                extension.descriptor);
147
0
        int size = ReadSize(&ptr);
148
0
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
149
0
        return ctx->ReadString(ptr, size, value);
150
0
      }
151
152
0
      case WireFormatLite::TYPE_GROUP: {
153
0
        MessageLite* value =
154
0
            extension.is_repeated
155
0
                ? AddMessage(number, WireFormatLite::TYPE_GROUP,
156
0
                             *extension.message_info.prototype,
157
0
                             extension.descriptor)
158
0
                : MutableMessage(number, WireFormatLite::TYPE_GROUP,
159
0
                                 *extension.message_info.prototype,
160
0
                                 extension.descriptor);
161
0
        uint32_t tag = (number << 3) + WireFormatLite::WIRETYPE_START_GROUP;
162
0
        return ctx->ParseGroup(value, ptr, tag);
163
0
      }
164
165
16
      case WireFormatLite::TYPE_MESSAGE: {
166
16
        MessageLite* value =
167
16
            extension.is_repeated
168
16
                ? AddMessage(number, WireFormatLite::TYPE_MESSAGE,
169
0
                             *extension.message_info.prototype,
170
0
                             extension.descriptor)
171
16
                : MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
172
16
                                 *extension.message_info.prototype,
173
16
                                 extension.descriptor);
174
16
        return ctx->ParseMessage(value, ptr);
175
0
      }
176
16
    }
177
16
  }
178
0
  return ptr;
179
16
}
180
181
template <typename Msg, typename T>
182
const char* ExtensionSet::ParseMessageSetItemTmpl(
183
    const char* ptr, const Msg* extendee, internal::InternalMetadata* metadata,
184
0
    internal::ParseContext* ctx) {
185
0
  std::string payload;
186
0
  uint32_t type_id = 0;
187
0
  enum class State { kNoTag, kHasType, kHasPayload, kDone };
188
0
  State state = State::kNoTag;
189
190
0
  while (!ctx->Done(&ptr)) {
191
0
    uint32_t tag = static_cast<uint8_t>(*ptr++);
192
0
    if (tag == WireFormatLite::kMessageSetTypeIdTag) {
193
0
      uint64_t tmp;
194
0
      ptr = ParseBigVarint(ptr, &tmp);
195
      // We should fail parsing if type id is 0 after cast to uint32.
196
0
      GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr &&
197
0
                                     static_cast<uint32_t>(tmp) != 0);
198
0
      if (state == State::kNoTag) {
199
0
        type_id = static_cast<uint32_t>(tmp);
200
0
        state = State::kHasType;
201
0
      } else if (state == State::kHasPayload) {
202
0
        type_id = static_cast<uint32_t>(tmp);
203
0
        ExtensionInfo extension;
204
0
        bool was_packed_on_wire;
205
0
        if (!FindExtension(2, type_id, extendee, ctx, &extension,
206
0
                           &was_packed_on_wire)) {
207
0
          WriteLengthDelimited(type_id, payload,
208
0
                               metadata->mutable_unknown_fields<T>());
209
0
        } else {
210
0
          MessageLite* value =
211
0
              extension.is_repeated
212
0
                  ? AddMessage(type_id, WireFormatLite::TYPE_MESSAGE,
213
0
                               *extension.message_info.prototype,
214
0
                               extension.descriptor)
215
0
                  : MutableMessage(type_id, WireFormatLite::TYPE_MESSAGE,
216
0
                                   *extension.message_info.prototype,
217
0
                                   extension.descriptor);
218
219
0
          const char* p;
220
          // We can't use regular parse from string as we have to track
221
          // proper recursion depth and descriptor pools. Spawn a new
222
          // ParseContext inheriting those attributes.
223
0
          ParseContext tmp_ctx(ParseContext::kSpawn, *ctx, &p, payload);
224
0
          GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) &&
225
0
                                         tmp_ctx.EndedAtLimit());
226
0
        }
227
0
        state = State::kDone;
228
0
      }
229
0
    } else if (tag == WireFormatLite::kMessageSetMessageTag) {
230
0
      if (state == State::kHasType) {
231
0
        ptr = ParseFieldMaybeLazily(static_cast<uint64_t>(type_id) * 8 + 2, ptr,
232
0
                                    extendee, metadata, ctx);
233
0
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
234
0
        state = State::kDone;
235
0
      } else {
236
0
        std::string tmp;
237
0
        int32_t size = ReadSize(&ptr);
238
0
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
239
0
        ptr = ctx->ReadString(ptr, size, &tmp);
240
0
        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
241
0
        if (state == State::kNoTag) {
242
0
          payload = std::move(tmp);
243
0
          state = State::kHasPayload;
244
0
        }
245
0
      }
246
0
    } else {
247
0
      ptr = ReadTag(ptr - 1, &tag);
248
0
      if (tag == 0 || (tag & 7) == 4) {
249
0
        ctx->SetLastTag(tag);
250
0
        return ptr;
251
0
      }
252
0
      ptr = ParseField(tag, ptr, extendee, metadata, ctx);
253
0
      GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
254
0
    }
255
0
  }
256
0
  return ptr;
257
0
}
Unexecuted instantiation: char const* google::protobuf::internal::ExtensionSet::ParseMessageSetItemTmpl<google::protobuf::MessageLite, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(char const*, google::protobuf::MessageLite const*, google::protobuf::internal::InternalMetadata*, google::protobuf::internal::ParseContext*)
Unexecuted instantiation: char const* google::protobuf::internal::ExtensionSet::ParseMessageSetItemTmpl<google::protobuf::Message, google::protobuf::UnknownFieldSet>(char const*, google::protobuf::Message const*, google::protobuf::internal::InternalMetadata*, google::protobuf::internal::ParseContext*)
258
259
}  // namespace internal
260
}  // namespace protobuf
261
}  // namespace google
262
263
#endif  // GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__