upb: tighten up and lock down upb/wire/

PiperOrigin-RevId: 593821827
pull/15179/head
Eric Salo 11 months ago committed by Copybara-Service
parent 16afb4dea7
commit 2fb0b93d9d
  1. 2
      protos/BUILD
  2. 1
      python/BUILD.bazel
  3. 19
      upb/BUILD
  4. 2
      upb/generated_code_support.h
  5. 2
      upb/message/BUILD
  6. 1
      upb/mini_table/BUILD
  7. 4
      upb/mini_table/internal/message.h
  8. 1
      upb/text/BUILD
  9. 5
      upb/util/BUILD
  10. 9
      upb/util/compare_test.cc
  11. 46
      upb/wire/BUILD
  12. 9
      upb/wire/decode.c
  13. 15
      upb/wire/encode.c
  14. 1
      upb/wire/encode.h
  15. 2
      upb/wire/internal/decode_fast.c
  16. 6
      upb/wire/internal/decode_fast.h
  17. 22
      upb/wire/internal/endian.h
  18. 61
      upb/wire/internal/reader.h
  19. 15
      upb/wire/reader.c
  20. 65
      upb/wire/reader.h
  21. 4
      upb_generator/BUILD

@ -62,7 +62,7 @@ cc_library(
"//upb:message_types", "//upb:message_types",
"//upb:mini_table", "//upb:mini_table",
"//upb:wire", "//upb:wire",
"//upb:wire_types", "//upb:wire_reader",
"@com_google_absl//absl/status", "@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor", "@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings", "@com_google_absl//absl/strings",

@ -200,7 +200,6 @@ py_extension(
"//upb:reflection", "//upb:reflection",
"//upb:text", "//upb:text",
"//upb:wire_reader", "//upb:wire_reader",
"//upb:wire_types",
"//upb/util:compare", "//upb/util:compare",
"//upb/util:def_to_proto", "//upb/util:def_to_proto",
"//upb/util:required_fields", "//upb/util:required_fields",

@ -117,7 +117,6 @@ cc_library(
":mini_descriptor", ":mini_descriptor",
":mini_table", ":mini_table",
":wire", ":wire",
":wire_internal",
], ],
) )
@ -327,24 +326,12 @@ alias(
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
alias(
name = "wire_internal",
actual = "//upb/wire:internal",
visibility = ["//visibility:public"],
)
alias( alias(
name = "wire_reader", name = "wire_reader",
actual = "//upb/wire:reader", actual = "//upb/wire:reader",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
) )
alias(
name = "wire_types",
actual = "//upb/wire:types",
visibility = ["//visibility:public"],
)
alias( alias(
name = "eps_copy_input_stream", name = "eps_copy_input_stream",
actual = "//upb/wire:eps_copy_input_stream", actual = "//upb/wire:eps_copy_input_stream",
@ -407,9 +394,7 @@ upb_amalgamation(
":reflection", ":reflection",
":reflection_internal", ":reflection_internal",
":wire", ":wire",
":wire_internal",
":wire_reader", ":wire_reader",
":wire_types",
], ],
strip_import_prefix = ["src"], strip_import_prefix = ["src"],
) )
@ -455,9 +440,7 @@ upb_amalgamation(
":reflection", ":reflection",
":reflection_internal", ":reflection_internal",
":wire", ":wire",
":wire_internal",
":wire_reader", ":wire_reader",
":wire_types",
], ],
prefix = "php-", prefix = "php-",
strip_import_prefix = ["src"], strip_import_prefix = ["src"],
@ -504,9 +487,7 @@ upb_amalgamation(
":reflection", ":reflection",
":reflection_internal", ":reflection_internal",
":wire", ":wire",
":wire_internal",
":wire_reader", ":wire_reader",
":wire_types",
], ],
prefix = "ruby-", prefix = "ruby-",
strip_import_prefix = ["src"], strip_import_prefix = ["src"],

@ -27,8 +27,8 @@
#include "upb/mini_table/message.h" #include "upb/mini_table/message.h"
#include "upb/mini_table/sub.h" #include "upb/mini_table/sub.h"
#include "upb/wire/decode.h" #include "upb/wire/decode.h"
#include "upb/wire/decode_fast.h"
#include "upb/wire/encode.h" #include "upb/wire/encode.h"
#include "upb/wire/internal/decode_fast.h"
// IWYU pragma: end_exports // IWYU pragma: end_exports
#endif // UPB_GENERATED_CODE_SUPPORT_H_ #endif // UPB_GENERATED_CODE_SUPPORT_H_

@ -33,7 +33,6 @@ cc_library(
":message", ":message",
":tagged_ptr", ":tagged_ptr",
"//upb:base", "//upb:base",
"//upb:eps_copy_input_stream",
"//upb:mem", "//upb:mem",
"//upb:message_types", "//upb:message_types",
"//upb:mini_table", "//upb:mini_table",
@ -181,7 +180,6 @@ cc_library(
"//upb:mini_table", "//upb:mini_table",
"//upb:port", "//upb:port",
"//upb:wire", "//upb:wire",
"//upb:wire_internal",
"//upb:wire_reader", "//upb:wire_reader",
], ],
) )

@ -40,7 +40,6 @@ cc_library(
"//upb:base", "//upb:base",
"//upb:hash", "//upb:hash",
"//upb:mem", "//upb:mem",
"//upb:message_types",
"//upb:port", "//upb:port",
], ],
) )

@ -10,7 +10,6 @@
#include <stdint.h> #include <stdint.h>
#include "upb/message/types.h"
#include "upb/mini_table/internal/field.h" #include "upb/mini_table/internal/field.h"
#include "upb/mini_table/internal/sub.h" #include "upb/mini_table/internal/sub.h"
#include "upb/mini_table/types.h" #include "upb/mini_table/types.h"
@ -19,8 +18,9 @@
#include "upb/port/def.inc" #include "upb/port/def.inc"
struct upb_Decoder; struct upb_Decoder;
struct upb_Message;
typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr, typedef const char* _upb_FieldParser(struct upb_Decoder* d, const char* ptr,
upb_Message* msg, intptr_t table, struct upb_Message* msg, intptr_t table,
uint64_t hasbits, uint64_t data); uint64_t hasbits, uint64_t data);
typedef struct { typedef struct {
uint64_t field_data; uint64_t field_data;

@ -26,7 +26,6 @@ cc_library(
"//upb:reflection", "//upb:reflection",
"//upb:wire", "//upb:wire",
"//upb:wire_reader", "//upb:wire_reader",
"//upb:wire_types",
], ],
) )

@ -153,7 +153,6 @@ cc_library(
"//upb:mem", "//upb:mem",
"//upb:port", "//upb:port",
"//upb:wire_reader", "//upb:wire_reader",
"//upb:wire_types",
], ],
) )
@ -163,8 +162,8 @@ cc_test(
deps = [ deps = [
":compare", ":compare",
"@com_google_googletest//:gtest_main", "@com_google_googletest//:gtest_main",
"//upb:wire_internal", "//upb:port",
"//upb:wire_types", "//upb:wire_reader",
"@com_google_absl//absl/strings", "@com_google_absl//absl/strings",
], ],
) )

@ -15,9 +15,12 @@
#include <vector> #include <vector>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include "upb/wire/internal/swap.h" #include "upb/wire/internal/endian.h"
#include "upb/wire/types.h" #include "upb/wire/types.h"
// Must be last.
#include "upb/port/def.inc"
struct UnknownField; struct UnknownField;
using UnknownFields = std::vector<UnknownField>; using UnknownFields = std::vector<UnknownField>;
@ -81,11 +84,11 @@ std::string ToBinaryPayload(const UnknownFields& fields) {
ret.append(val->val); ret.append(val->val);
} else if (const auto* val = std::get_if<Fixed64>(&field.value)) { } else if (const auto* val = std::get_if<Fixed64>(&field.value)) {
EncodeVarint(field.field_number << 3 | kUpb_WireType_64Bit, &ret); EncodeVarint(field.field_number << 3 | kUpb_WireType_64Bit, &ret);
uint64_t swapped = _upb_BigEndian_Swap64(val->val); uint64_t swapped = UPB_PRIVATE(_upb_BigEndian64)(val->val);
ret.append(reinterpret_cast<const char*>(&swapped), sizeof(swapped)); ret.append(reinterpret_cast<const char*>(&swapped), sizeof(swapped));
} else if (const auto* val = std::get_if<Fixed32>(&field.value)) { } else if (const auto* val = std::get_if<Fixed32>(&field.value)) {
EncodeVarint(field.field_number << 3 | kUpb_WireType_32Bit, &ret); EncodeVarint(field.field_number << 3 | kUpb_WireType_32Bit, &ret);
uint32_t swapped = _upb_BigEndian_Swap32(val->val); uint32_t swapped = UPB_PRIVATE(_upb_BigEndian32)(val->val);
ret.append(reinterpret_cast<const char*>(&swapped), sizeof(swapped)); ret.append(reinterpret_cast<const char*>(&swapped), sizeof(swapped));
} else if (const auto* val = std::get_if<Group>(&field.value)) { } else if (const auto* val = std::get_if<Group>(&field.value)) {
EncodeVarint(field.field_number << 3 | kUpb_WireType_StartGroup, &ret); EncodeVarint(field.field_number << 3 | kUpb_WireType_StartGroup, &ret);

@ -9,45 +9,23 @@ load("//bazel:build_defs.bzl", "UPB_DEFAULT_COPTS")
cc_library( cc_library(
name = "wire", name = "wire",
srcs = [
],
hdrs = [
"decode.h",
"encode.h",
],
copts = UPB_DEFAULT_COPTS,
visibility = ["//visibility:public"],
deps = [
":internal",
":types",
"//upb:mem",
"//upb:message",
"//upb:mini_table",
"//upb:port",
],
)
cc_library(
name = "internal",
srcs = [ srcs = [
"decode.c", "decode.c",
"decode.h",
"decode_fast.c",
"encode.c", "encode.c",
"encode.h", "internal/decode_fast.c",
], ],
hdrs = [ hdrs = [
"decode_fast.h", "decode.h",
"encode.h",
"internal/constants.h", "internal/constants.h",
"internal/decode.h", "internal/decode.h",
"internal/swap.h", "internal/decode_fast.h",
], ],
copts = UPB_DEFAULT_COPTS, copts = UPB_DEFAULT_COPTS,
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
":eps_copy_input_stream", ":eps_copy_input_stream",
":reader", ":reader",
":types",
"//upb:base", "//upb:base",
"//upb:hash", "//upb:hash",
"//upb:mem", "//upb:mem",
@ -56,6 +34,7 @@ cc_library(
"//upb:message_internal", "//upb:message_internal",
"//upb:message_internal_types", "//upb:message_internal_types",
"//upb:message_tagged_ptr", "//upb:message_tagged_ptr",
"//upb:message_types",
"//upb:mini_table", "//upb:mini_table",
"//upb:port", "//upb:port",
"//third_party/utf8_range", "//third_party/utf8_range",
@ -65,24 +44,21 @@ cc_library(
cc_library( cc_library(
name = "reader", name = "reader",
srcs = [ srcs = [
"internal/swap.h",
"reader.c", "reader.c",
], ],
hdrs = ["reader.h"], hdrs = [
"internal/endian.h",
"internal/reader.h",
"reader.h",
"types.h",
],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
":eps_copy_input_stream", ":eps_copy_input_stream",
":types",
"//upb:port", "//upb:port",
], ],
) )
cc_library(
name = "types",
hdrs = ["types.h"],
visibility = ["//visibility:public"],
)
cc_library( cc_library(
name = "eps_copy_input_stream", name = "eps_copy_input_stream",
srcs = ["eps_copy_input_stream.c"], srcs = ["eps_copy_input_stream.c"],

@ -31,6 +31,7 @@
#include "upb/mini_table/extension.h" #include "upb/mini_table/extension.h"
#include "upb/mini_table/extension_registry.h" #include "upb/mini_table/extension_registry.h"
#include "upb/mini_table/field.h" #include "upb/mini_table/field.h"
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/internal/size_log2.h" #include "upb/mini_table/internal/size_log2.h"
#include "upb/mini_table/message.h" #include "upb/mini_table/message.h"
#include "upb/mini_table/sub.h" #include "upb/mini_table/sub.h"
@ -39,7 +40,7 @@
#include "upb/wire/eps_copy_input_stream.h" #include "upb/wire/eps_copy_input_stream.h"
#include "upb/wire/internal/constants.h" #include "upb/wire/internal/constants.h"
#include "upb/wire/internal/decode.h" #include "upb/wire/internal/decode.h"
#include "upb/wire/internal/swap.h" #include "upb/wire/internal/endian.h"
#include "upb/wire/reader.h" #include "upb/wire/reader.h"
// Must be last. // Must be last.
@ -209,7 +210,7 @@ static const char* upb_Decoder_DecodeSize(upb_Decoder* d, const char* ptr,
} }
static void _upb_Decoder_MungeInt32(wireval* val) { static void _upb_Decoder_MungeInt32(wireval* val) {
if (!_upb_IsLittleEndian()) { if (!UPB_PRIVATE(_upb_IsLittleEndian)()) {
/* The next stage will memcpy(dst, &val, 4) */ /* The next stage will memcpy(dst, &val, 4) */
val->uint32_val = val->uint64_val; val->uint32_val = val->uint64_val;
} }
@ -429,7 +430,7 @@ static const char* _upb_Decoder_DecodeFixedPacked(
arr->UPB_PRIVATE(size) += count; arr->UPB_PRIVATE(size) += count;
// Note: if/when the decoder supports multi-buffer input, we will need to // Note: if/when the decoder supports multi-buffer input, we will need to
// handle buffer seams here. // handle buffer seams here.
if (_upb_IsLittleEndian()) { if (UPB_PRIVATE(_upb_IsLittleEndian)()) {
ptr = upb_EpsCopyInputStream_Copy(&d->input, ptr, mem, val->size); ptr = upb_EpsCopyInputStream_Copy(&d->input, ptr, mem, val->size);
} else { } else {
int delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size); int delta = upb_EpsCopyInputStream_PushLimit(&d->input, ptr, val->size);
@ -753,7 +754,7 @@ const char* _upb_Decoder_CheckRequired(upb_Decoder* d, const char* ptr,
} }
uint64_t msg_head; uint64_t msg_head;
memcpy(&msg_head, msg, 8); memcpy(&msg_head, msg, 8);
msg_head = _upb_BigEndian_Swap64(msg_head); msg_head = UPB_PRIVATE(_upb_BigEndian64)(msg_head);
if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) { if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) {
d->missing_required = true; d->missing_required = true;
} }

@ -31,10 +31,11 @@
#include "upb/message/tagged_ptr.h" #include "upb/message/tagged_ptr.h"
#include "upb/mini_table/extension.h" #include "upb/mini_table/extension.h"
#include "upb/mini_table/field.h" #include "upb/mini_table/field.h"
#include "upb/mini_table/internal/field.h"
#include "upb/mini_table/message.h" #include "upb/mini_table/message.h"
#include "upb/mini_table/sub.h" #include "upb/mini_table/sub.h"
#include "upb/wire/internal/constants.h" #include "upb/wire/internal/constants.h"
#include "upb/wire/internal/swap.h" #include "upb/wire/internal/endian.h"
#include "upb/wire/types.h" #include "upb/wire/types.h"
// Must be last. // Must be last.
@ -127,12 +128,12 @@ static void encode_bytes(upb_encstate* e, const void* data, size_t len) {
} }
static void encode_fixed64(upb_encstate* e, uint64_t val) { static void encode_fixed64(upb_encstate* e, uint64_t val) {
val = _upb_BigEndian_Swap64(val); val = UPB_PRIVATE(_upb_BigEndian64)(val);
encode_bytes(e, &val, sizeof(uint64_t)); encode_bytes(e, &val, sizeof(uint64_t));
} }
static void encode_fixed32(upb_encstate* e, uint32_t val) { static void encode_fixed32(upb_encstate* e, uint32_t val) {
val = _upb_BigEndian_Swap32(val); val = UPB_PRIVATE(_upb_BigEndian32)(val);
encode_bytes(e, &val, sizeof(uint32_t)); encode_bytes(e, &val, sizeof(uint32_t));
} }
@ -183,18 +184,18 @@ static void encode_fixedarray(upb_encstate* e, const upb_Array* arr,
const char* data = _upb_array_constptr(arr); const char* data = _upb_array_constptr(arr);
const char* ptr = data + bytes - elem_size; const char* ptr = data + bytes - elem_size;
if (tag || !_upb_IsLittleEndian()) { if (tag || !UPB_PRIVATE(_upb_IsLittleEndian)()) {
while (true) { while (true) {
if (elem_size == 4) { if (elem_size == 4) {
uint32_t val; uint32_t val;
memcpy(&val, ptr, sizeof(val)); memcpy(&val, ptr, sizeof(val));
val = _upb_BigEndian_Swap32(val); val = UPB_PRIVATE(_upb_BigEndian32)(val);
encode_bytes(e, &val, elem_size); encode_bytes(e, &val, elem_size);
} else { } else {
UPB_ASSERT(elem_size == 8); UPB_ASSERT(elem_size == 8);
uint64_t val; uint64_t val;
memcpy(&val, ptr, sizeof(val)); memcpy(&val, ptr, sizeof(val));
val = _upb_BigEndian_Swap64(val); val = UPB_PRIVATE(_upb_BigEndian64)(val);
encode_bytes(e, &val, elem_size); encode_bytes(e, &val, elem_size);
} }
@ -548,7 +549,7 @@ static void encode_message(upb_encstate* e, const upb_Message* msg,
m->UPB_PRIVATE(required_count)) { m->UPB_PRIVATE(required_count)) {
uint64_t msg_head; uint64_t msg_head;
memcpy(&msg_head, msg, 8); memcpy(&msg_head, msg, 8);
msg_head = _upb_BigEndian_Swap64(msg_head); msg_head = UPB_PRIVATE(_upb_BigEndian64)(msg_head);
if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) { if (UPB_PRIVATE(_upb_MiniTable_RequiredMask)(m) & ~msg_head) {
encode_err(e, kUpb_EncodeStatus_MissingRequired); encode_err(e, kUpb_EncodeStatus_MissingRequired);
} }

@ -14,6 +14,7 @@
#include <stdint.h> #include <stdint.h>
#include "upb/mem/arena.h" #include "upb/mem/arena.h"
#include "upb/message/types.h"
#include "upb/mini_table/message.h" #include "upb/mini_table/message.h"
// Must be last. // Must be last.

@ -15,7 +15,7 @@
// field type (eg. oneof boolean field with a 1 byte tag) and then dispatch // field type (eg. oneof boolean field with a 1 byte tag) and then dispatch
// to the specialized function as quickly as possible. // to the specialized function as quickly as possible.
#include "upb/wire/decode_fast.h" #include "upb/wire/internal/decode_fast.h"
#include "upb/message/array.h" #include "upb/message/array.h"
#include "upb/message/internal/array.h" #include "upb/message/internal/array.h"

@ -39,8 +39,8 @@
// - '1' for one-byte tags (field numbers 1-15) // - '1' for one-byte tags (field numbers 1-15)
// - '2' for two-byte tags (field numbers 16-2048) // - '2' for two-byte tags (field numbers 16-2048)
#ifndef UPB_WIRE_DECODE_FAST_H_ #ifndef UPB_WIRE_DECODE_INTERNAL_FAST_H_
#define UPB_WIRE_DECODE_FAST_H_ #define UPB_WIRE_DECODE_INTERNAL_FAST_H_
#include "upb/message/message.h" #include "upb/message/message.h"
@ -144,4 +144,4 @@ TAGBYTES(r)
#include "upb/port/undef.inc" #include "upb/port/undef.inc"
#endif /* UPB_WIRE_DECODE_FAST_H_ */ #endif /* UPB_WIRE_DECODE_INTERNAL_FAST_H_ */

@ -5,8 +5,8 @@
// license that can be found in the LICENSE file or at // license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
#ifndef UPB_WIRE_INTERNAL_SWAP_H_ #ifndef UPB_WIRE_INTERNAL_ENDIAN_H_
#define UPB_WIRE_INTERNAL_SWAP_H_ #define UPB_WIRE_INTERNAL_ENDIAN_H_
#include <stdint.h> #include <stdint.h>
@ -17,23 +17,23 @@
extern "C" { extern "C" {
#endif #endif
UPB_INLINE bool _upb_IsLittleEndian(void) { UPB_INLINE bool UPB_PRIVATE(_upb_IsLittleEndian)(void) {
int x = 1; const int x = 1;
return *(char*)&x == 1; return *(char*)&x == 1;
} }
UPB_INLINE uint32_t _upb_BigEndian_Swap32(uint32_t val) { UPB_INLINE uint32_t UPB_PRIVATE(_upb_BigEndian32)(uint32_t val) {
if (_upb_IsLittleEndian()) return val; if (UPB_PRIVATE(_upb_IsLittleEndian)()) return val;
return ((val & 0xff) << 24) | ((val & 0xff00) << 8) | return ((val & 0xff) << 24) | ((val & 0xff00) << 8) |
((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24); ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24);
} }
UPB_INLINE uint64_t _upb_BigEndian_Swap64(uint64_t val) { UPB_INLINE uint64_t UPB_PRIVATE(_upb_BigEndian64)(uint64_t val) {
if (_upb_IsLittleEndian()) return val; if (UPB_PRIVATE(_upb_IsLittleEndian)()) return val;
return ((uint64_t)_upb_BigEndian_Swap32((uint32_t)val) << 32) | return ((uint64_t)UPB_PRIVATE(_upb_BigEndian32)((uint32_t)val) << 32) |
_upb_BigEndian_Swap32((uint32_t)(val >> 32)); UPB_PRIVATE(_upb_BigEndian32)((uint32_t)(val >> 32));
} }
#ifdef __cplusplus #ifdef __cplusplus
@ -42,4 +42,4 @@ UPB_INLINE uint64_t _upb_BigEndian_Swap64(uint64_t val) {
#include "upb/port/undef.inc" #include "upb/port/undef.inc"
#endif /* UPB_WIRE_INTERNAL_SWAP_H_ */ #endif /* UPB_WIRE_INTERNAL_ENDIAN_H_ */

@ -0,0 +1,61 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#ifndef UPB_WIRE_INTERNAL_READER_H_
#define UPB_WIRE_INTERNAL_READER_H_
// Must be last.
#include "upb/port/def.inc"
#define kUpb_WireReader_WireTypeBits 3
#define kUpb_WireReader_WireTypeMask 7
typedef struct {
const char* ptr;
uint64_t val;
} UPB_PRIVATE(_upb_WireReader_LongVarint);
#ifdef __cplusplus
extern "C" {
#endif
UPB_PRIVATE(_upb_WireReader_LongVarint)
UPB_PRIVATE(_upb_WireReader_ReadLongVarint)(const char* ptr, uint64_t val);
static UPB_FORCEINLINE const char* UPB_PRIVATE(_upb_WireReader_ReadVarint)(
const char* ptr, uint64_t* val, int maxlen, uint64_t maxval) {
uint64_t byte = (uint8_t)*ptr;
if (UPB_LIKELY((byte & 0x80) == 0)) {
*val = (uint32_t)byte;
return ptr + 1;
}
const char* start = ptr;
UPB_PRIVATE(_upb_WireReader_LongVarint)
res = UPB_PRIVATE(_upb_WireReader_ReadLongVarint)(ptr, byte);
if (!res.ptr || (maxlen < 10 && res.ptr - start > maxlen) ||
res.val > maxval) {
return NULL; // Malformed.
}
*val = res.val;
return res.ptr;
}
UPB_INLINE uint32_t UPB_PRIVATE(_upb_WireReader_GetFieldNumber)(uint32_t tag) {
return tag >> kUpb_WireReader_WireTypeBits;
}
UPB_INLINE uint8_t UPB_PRIVATE(_upb_WireReader_GetWireType)(uint32_t tag) {
return tag & kUpb_WireReader_WireTypeMask;
}
#ifdef __cplusplus
} /* extern "C" */
#endif
#include "upb/port/undef.inc"
#endif // UPB_WIRE_INTERNAL_READER_H_

@ -7,15 +7,18 @@
#include "upb/wire/reader.h" #include "upb/wire/reader.h"
#include <stddef.h>
#include <stdint.h>
#include "upb/wire/eps_copy_input_stream.h" #include "upb/wire/eps_copy_input_stream.h"
#include "upb/wire/types.h" #include "upb/wire/types.h"
// Must be last. // Must be last.
#include "upb/port/def.inc" #include "upb/port/def.inc"
UPB_NOINLINE _upb_WireReader_ReadLongVarintRet UPB_NOINLINE UPB_PRIVATE(_upb_WireReader_LongVarint)
_upb_WireReader_ReadLongVarint(const char* ptr, uint64_t val) { UPB_PRIVATE(_upb_WireReader_ReadLongVarint)(const char* ptr, uint64_t val) {
_upb_WireReader_ReadLongVarintRet ret = {NULL, 0}; UPB_PRIVATE(_upb_WireReader_LongVarint) ret = {NULL, 0};
uint64_t byte; uint64_t byte;
int i; int i;
for (i = 1; i < 10; i++) { for (i = 1; i < 10; i++) {
@ -30,9 +33,9 @@ _upb_WireReader_ReadLongVarint(const char* ptr, uint64_t val) {
return ret; return ret;
} }
const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)(
int depth_limit, const char* ptr, uint32_t tag, int depth_limit,
upb_EpsCopyInputStream* stream) { upb_EpsCopyInputStream* stream) {
if (--depth_limit == 0) return NULL; if (--depth_limit == 0) return NULL;
uint32_t end_group_tag = (tag & ~7ULL) | kUpb_WireType_EndGroup; uint32_t end_group_tag = (tag & ~7ULL) | kUpb_WireType_EndGroup;
while (!upb_EpsCopyInputStream_IsDone(stream, &ptr)) { while (!upb_EpsCopyInputStream_IsDone(stream, &ptr)) {

@ -9,52 +9,22 @@
#define UPB_WIRE_READER_H_ #define UPB_WIRE_READER_H_
#include "upb/wire/eps_copy_input_stream.h" #include "upb/wire/eps_copy_input_stream.h"
#include "upb/wire/internal/swap.h" #include "upb/wire/internal/endian.h"
#include "upb/wire/internal/reader.h"
#include "upb/wire/types.h" // IWYU pragma: export #include "upb/wire/types.h" // IWYU pragma: export
// Must be last. // Must be last.
#include "upb/port/def.inc" #include "upb/port/def.inc"
#ifdef __cplusplus
extern "C" {
#endif
// The upb_WireReader interface is suitable for general-purpose parsing of // The upb_WireReader interface is suitable for general-purpose parsing of
// protobuf binary wire format. It is designed to be used along with // protobuf binary wire format. It is designed to be used along with
// upb_EpsCopyInputStream for buffering, and all parsing routines in this file // upb_EpsCopyInputStream for buffering, and all parsing routines in this file
// assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is // assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is
// available to read without any bounds checks. // available to read without any bounds checks.
#define kUpb_WireReader_WireTypeMask 7 #ifdef __cplusplus
#define kUpb_WireReader_WireTypeBits 3 extern "C" {
#endif
typedef struct {
const char* ptr;
uint64_t val;
} _upb_WireReader_ReadLongVarintRet;
_upb_WireReader_ReadLongVarintRet _upb_WireReader_ReadLongVarint(
const char* ptr, uint64_t val);
static UPB_FORCEINLINE const char* _upb_WireReader_ReadVarint(const char* ptr,
uint64_t* val,
int maxlen,
uint64_t maxval) {
uint64_t byte = (uint8_t)*ptr;
if (UPB_LIKELY((byte & 0x80) == 0)) {
*val = (uint32_t)byte;
return ptr + 1;
}
const char* start = ptr;
_upb_WireReader_ReadLongVarintRet res =
_upb_WireReader_ReadLongVarint(ptr, byte);
if (!res.ptr || (maxlen < 10 && res.ptr - start > maxlen) ||
res.val > maxval) {
return NULL; // Malformed.
}
*val = res.val;
return res.ptr;
}
// Parses a tag into `tag`, and returns a pointer past the end of the tag, or // Parses a tag into `tag`, and returns a pointer past the end of the tag, or
// NULL if there was an error in the tag data. // NULL if there was an error in the tag data.
@ -65,7 +35,7 @@ static UPB_FORCEINLINE const char* _upb_WireReader_ReadVarint(const char* ptr,
static UPB_FORCEINLINE const char* upb_WireReader_ReadTag(const char* ptr, static UPB_FORCEINLINE const char* upb_WireReader_ReadTag(const char* ptr,
uint32_t* tag) { uint32_t* tag) {
uint64_t val; uint64_t val;
ptr = _upb_WireReader_ReadVarint(ptr, &val, 5, UINT32_MAX); ptr = UPB_PRIVATE(_upb_WireReader_ReadVarint)(ptr, &val, 5, UINT32_MAX);
if (!ptr) return NULL; if (!ptr) return NULL;
*tag = val; *tag = val;
return ptr; return ptr;
@ -73,17 +43,17 @@ static UPB_FORCEINLINE const char* upb_WireReader_ReadTag(const char* ptr,
// Given a tag, returns the field number. // Given a tag, returns the field number.
UPB_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag) { UPB_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag) {
return tag >> kUpb_WireReader_WireTypeBits; return UPB_PRIVATE(_upb_WireReader_GetFieldNumber)(tag);
} }
// Given a tag, returns the wire type. // Given a tag, returns the wire type.
UPB_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag) { UPB_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag) {
return tag & kUpb_WireReader_WireTypeMask; return UPB_PRIVATE(_upb_WireReader_GetWireType)(tag);
} }
UPB_INLINE const char* upb_WireReader_ReadVarint(const char* ptr, UPB_INLINE const char* upb_WireReader_ReadVarint(const char* ptr,
uint64_t* val) { uint64_t* val) {
return _upb_WireReader_ReadVarint(ptr, val, 10, UINT64_MAX); return UPB_PRIVATE(_upb_WireReader_ReadVarint)(ptr, val, 10, UINT64_MAX);
} }
// Skips data for a varint, returning a pointer past the end of the varint, or // Skips data for a varint, returning a pointer past the end of the varint, or
@ -119,7 +89,7 @@ UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size) {
UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) { UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) {
uint32_t uval; uint32_t uval;
memcpy(&uval, ptr, 4); memcpy(&uval, ptr, 4);
uval = _upb_BigEndian_Swap32(uval); uval = UPB_PRIVATE(_upb_BigEndian32)(uval);
memcpy(val, &uval, 4); memcpy(val, &uval, 4);
return ptr + 4; return ptr + 4;
} }
@ -132,14 +102,14 @@ UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) {
UPB_INLINE const char* upb_WireReader_ReadFixed64(const char* ptr, void* val) { UPB_INLINE const char* upb_WireReader_ReadFixed64(const char* ptr, void* val) {
uint64_t uval; uint64_t uval;
memcpy(&uval, ptr, 8); memcpy(&uval, ptr, 8);
uval = _upb_BigEndian_Swap64(uval); uval = UPB_PRIVATE(_upb_BigEndian64)(uval);
memcpy(val, &uval, 8); memcpy(val, &uval, 8);
return ptr + 8; return ptr + 8;
} }
const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag, const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)(
int depth_limit, const char* ptr, uint32_t tag, int depth_limit,
upb_EpsCopyInputStream* stream); upb_EpsCopyInputStream* stream);
// Skips data for a group, returning a pointer past the end of the group, or // Skips data for a group, returning a pointer past the end of the group, or
// NULL if there was an error parsing the group. The `tag` argument should be // NULL if there was an error parsing the group. The `tag` argument should be
@ -152,7 +122,7 @@ const char* _upb_WireReader_SkipGroup(const char* ptr, uint32_t tag,
// control over this? // control over this?
UPB_INLINE const char* upb_WireReader_SkipGroup( UPB_INLINE const char* upb_WireReader_SkipGroup(
const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) {
return _upb_WireReader_SkipGroup(ptr, tag, 100, stream); return UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, tag, 100, stream);
} }
UPB_INLINE const char* _upb_WireReader_SkipValue( UPB_INLINE const char* _upb_WireReader_SkipValue(
@ -173,7 +143,8 @@ UPB_INLINE const char* _upb_WireReader_SkipValue(
return ptr; return ptr;
} }
case kUpb_WireType_StartGroup: case kUpb_WireType_StartGroup:
return _upb_WireReader_SkipGroup(ptr, tag, depth_limit, stream); return UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, tag, depth_limit,
stream);
case kUpb_WireType_EndGroup: case kUpb_WireType_EndGroup:
return NULL; // Should be handled before now. return NULL; // Should be handled before now.
default: default:

@ -266,7 +266,7 @@ bootstrap_cc_binary(
"//upb:base", "//upb:base",
"//upb:mem", "//upb:mem",
"//upb:port", "//upb:port",
"//upb:wire_types", "//upb:wire_reader",
"@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/log:absl_check", "@com_google_absl//absl/log:absl_check",
@ -305,7 +305,7 @@ bootstrap_cc_binary(
"//upb:mem", "//upb:mem",
"//upb:mini_table", "//upb:mini_table",
"//upb:port", "//upb:port",
"//upb:wire_types", "//upb:wire_reader",
"@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/log:absl_check", "@com_google_absl//absl/log:absl_check",

Loading…
Cancel
Save