Disallow toplevel hpb::Ptr access to it's internal arena

```
hpb::Arena arena;
auto foo = hpb::CreateMessage<Foo>(arena);
foo.GetInternalArena(); // this call will now be impossible
```

Before this CL, any Proxy/Ptr could get its internal arena. This
unnecessarily leaks upb internals when they should be
interacted with via hpb::interop::upb::*.

PiperOrigin-RevId: 676038573
pull/18376/head
Hong Shin 2 months ago committed by Copybara-Service
parent a95043eefa
commit c29dfb5e2d
  1. 4
      hpb/backend/upb/interop.h
  2. 26
      hpb/hpb.h
  3. 4
      hpb/internal/internal.h
  4. 9
      hpb_generator/gen_messages.cc

@ -51,12 +51,12 @@ auto* GetMessage(T&& message) {
template <typename T> template <typename T>
upb_Arena* GetArena(Ptr<T> message) { upb_Arena* GetArena(Ptr<T> message) {
return static_cast<upb_Arena*>(message->GetInternalArena()); return hpb::internal::PrivateAccess::GetInternalArena(message);
} }
template <typename T> template <typename T>
upb_Arena* GetArena(T* message) { upb_Arena* GetArena(T* message) {
return static_cast<upb_Arena*>(message->GetInternalArena()); return hpb::internal::PrivateAccess::GetInternalArena(message);
} }
/** /**

@ -141,7 +141,7 @@ absl::Status SetExtension(
const ::hpb::internal::ExtensionIdentifier<T, Extension>& id, const ::hpb::internal::ExtensionIdentifier<T, Extension>& id,
const Extension& value) { const Extension& value) {
static_assert(!std::is_const_v<T>); static_assert(!std::is_const_v<T>);
auto* message_arena = static_cast<upb_Arena*>(message->GetInternalArena()); auto* message_arena = hpb::interop::upb::GetArena(message);
return ::hpb::internal::SetExtension(hpb::interop::upb::GetMessage(message), return ::hpb::internal::SetExtension(hpb::interop::upb::GetMessage(message),
message_arena, id.mini_table_ext(), message_arena, id.mini_table_ext(),
hpb::interop::upb::GetMessage(&value)); hpb::interop::upb::GetMessage(&value));
@ -155,7 +155,7 @@ absl::Status SetExtension(
const ::hpb::internal::ExtensionIdentifier<T, Extension>& id, const ::hpb::internal::ExtensionIdentifier<T, Extension>& id,
Ptr<Extension> value) { Ptr<Extension> value) {
static_assert(!std::is_const_v<T>); static_assert(!std::is_const_v<T>);
auto* message_arena = static_cast<upb_Arena*>(message->GetInternalArena()); auto* message_arena = hpb::interop::upb::GetArena(message);
return ::hpb::internal::SetExtension(hpb::interop::upb::GetMessage(message), return ::hpb::internal::SetExtension(hpb::interop::upb::GetMessage(message),
message_arena, id.mini_table_ext(), message_arena, id.mini_table_ext(),
hpb::interop::upb::GetMessage(value)); hpb::interop::upb::GetMessage(value));
@ -170,8 +170,8 @@ absl::Status SetExtension(
Extension&& value) { Extension&& value) {
Extension ext = std::move(value); Extension ext = std::move(value);
static_assert(!std::is_const_v<T>); static_assert(!std::is_const_v<T>);
auto* message_arena = static_cast<upb_Arena*>(message->GetInternalArena()); auto* message_arena = hpb::interop::upb::GetArena(message);
auto* extension_arena = static_cast<upb_Arena*>(ext.GetInternalArena()); auto* extension_arena = hpb::interop::upb::GetArena(&ext);
return ::hpb::internal::MoveExtension(hpb::interop::upb::GetMessage(message), return ::hpb::internal::MoveExtension(hpb::interop::upb::GetMessage(message),
message_arena, id.mini_table_ext(), message_arena, id.mini_table_ext(),
hpb::interop::upb::GetMessage(&ext), hpb::interop::upb::GetMessage(&ext),
@ -251,10 +251,10 @@ typename T::Proxy CloneMessage(Ptr<T> message, upb_Arena* arena) {
template <typename T> template <typename T>
void DeepCopy(Ptr<const T> source_message, Ptr<T> target_message) { void DeepCopy(Ptr<const T> source_message, Ptr<T> target_message) {
static_assert(!std::is_const_v<T>); static_assert(!std::is_const_v<T>);
::hpb::internal::DeepCopy( ::hpb::internal::DeepCopy(hpb::interop::upb::GetMessage(target_message),
hpb::interop::upb::GetMessage(target_message), hpb::interop::upb::GetMessage(source_message),
hpb::interop::upb::GetMessage(source_message), T::minitable(), T::minitable(),
static_cast<upb_Arena*>(target_message->GetInternalArena())); hpb::interop::upb::GetArena(target_message));
} }
template <typename T> template <typename T>
@ -285,7 +285,7 @@ ABSL_MUST_USE_RESULT bool Parse(Ptr<T> message, absl::string_view bytes) {
static_assert(!std::is_const_v<T>); static_assert(!std::is_const_v<T>);
upb_Message_Clear(hpb::interop::upb::GetMessage(message), upb_Message_Clear(hpb::interop::upb::GetMessage(message),
::hpb::interop::upb::GetMiniTable(message)); ::hpb::interop::upb::GetMiniTable(message));
auto* arena = static_cast<upb_Arena*>(message->GetInternalArena()); auto* arena = hpb::interop::upb::GetArena(message);
return upb_Decode(bytes.data(), bytes.size(), return upb_Decode(bytes.data(), bytes.size(),
hpb::interop::upb::GetMessage(message), hpb::interop::upb::GetMessage(message),
::hpb::interop::upb::GetMiniTable(message), ::hpb::interop::upb::GetMiniTable(message),
@ -300,7 +300,7 @@ ABSL_MUST_USE_RESULT bool Parse(
static_assert(!std::is_const_v<T>); static_assert(!std::is_const_v<T>);
upb_Message_Clear(hpb::interop::upb::GetMessage(message), upb_Message_Clear(hpb::interop::upb::GetMessage(message),
::hpb::interop::upb::GetMiniTable(message)); ::hpb::interop::upb::GetMiniTable(message));
auto* arena = static_cast<upb_Arena*>(message->GetInternalArena()); auto* arena = hpb::interop::upb::GetArena(message);
return upb_Decode(bytes.data(), bytes.size(), return upb_Decode(bytes.data(), bytes.size(),
hpb::interop::upb::GetMessage(message), hpb::interop::upb::GetMessage(message),
::hpb::interop::upb::GetMiniTable(message), ::hpb::interop::upb::GetMiniTable(message),
@ -322,7 +322,7 @@ ABSL_MUST_USE_RESULT bool Parse(T* message, absl::string_view bytes) {
static_assert(!std::is_const_v<T>); static_assert(!std::is_const_v<T>);
upb_Message_Clear(hpb::interop::upb::GetMessage(message), upb_Message_Clear(hpb::interop::upb::GetMessage(message),
::hpb::interop::upb::GetMiniTable(message)); ::hpb::interop::upb::GetMiniTable(message));
auto* arena = static_cast<upb_Arena*>(message->GetInternalArena()); auto* arena = hpb::interop::upb::GetArena(message);
return upb_Decode(bytes.data(), bytes.size(), return upb_Decode(bytes.data(), bytes.size(),
hpb::interop::upb::GetMessage(message), hpb::interop::upb::GetMessage(message),
::hpb::interop::upb::GetMiniTable(message), ::hpb::interop::upb::GetMiniTable(message),
@ -333,7 +333,7 @@ ABSL_MUST_USE_RESULT bool Parse(T* message, absl::string_view bytes) {
template <typename T> template <typename T>
absl::StatusOr<T> Parse(absl::string_view bytes, int options = 0) { absl::StatusOr<T> Parse(absl::string_view bytes, int options = 0) {
T message; T message;
auto* arena = static_cast<upb_Arena*>(message.GetInternalArena()); auto* arena = hpb::interop::upb::GetArena(&message);
upb_DecodeStatus status = upb_DecodeStatus status =
upb_Decode(bytes.data(), bytes.size(), message.msg(), upb_Decode(bytes.data(), bytes.size(), message.msg(),
::hpb::interop::upb::GetMiniTable(&message), ::hpb::interop::upb::GetMiniTable(&message),
@ -349,7 +349,7 @@ absl::StatusOr<T> Parse(absl::string_view bytes,
const ::hpb::ExtensionRegistry& extension_registry, const ::hpb::ExtensionRegistry& extension_registry,
int options = 0) { int options = 0) {
T message; T message;
auto* arena = static_cast<upb_Arena*>(message.GetInternalArena()); auto* arena = hpb::interop::upb::GetArena(&message);
upb_DecodeStatus status = upb_DecodeStatus status =
upb_Decode(bytes.data(), bytes.size(), message.msg(), upb_Decode(bytes.data(), bytes.size(), message.msg(),
::hpb::interop::upb::GetMiniTable(&message), ::hpb::interop::upb::GetMiniTable(&message),

@ -14,6 +14,10 @@ struct PrivateAccess {
return message->msg(); return message->msg();
} }
template <typename T> template <typename T>
static auto* GetInternalArena(T&& message) {
return message->arena();
}
template <typename T>
static auto Proxy(upb_Message* p, upb_Arena* arena) { static auto Proxy(upb_Message* p, upb_Arena* arena) {
return typename T::Proxy(p, arena); return typename T::Proxy(p, arena);
} }

@ -100,7 +100,6 @@ void WriteModelAccessDeclaration(const protobuf::Descriptor* descriptor,
: msg_(const_cast<$1*>(msg)), arena_(arena) { : msg_(const_cast<$1*>(msg)), arena_(arena) {
assert(arena != nullptr); assert(arena != nullptr);
} // NOLINT } // NOLINT
void* GetInternalArena() const { return arena_; }
)cc", )cc",
ClassName(descriptor), MessageName(descriptor)); ClassName(descriptor), MessageName(descriptor));
WriteFieldAccessorsInHeader(descriptor, output); WriteFieldAccessorsInHeader(descriptor, output);
@ -225,7 +224,6 @@ void WriteModelPublicDeclaration(
output( output(
R"cc( R"cc(
static const upb_MiniTable* minitable(); static const upb_MiniTable* minitable();
using $0Access::GetInternalArena;
)cc", )cc",
ClassName(descriptor)); ClassName(descriptor));
output("\n"); output("\n");
@ -236,6 +234,8 @@ void WriteModelPublicDeclaration(
const upb_Message* msg() const { return UPB_UPCAST(msg_); } const upb_Message* msg() const { return UPB_UPCAST(msg_); }
upb_Message* msg() { return UPB_UPCAST(msg_); } upb_Message* msg() { return UPB_UPCAST(msg_); }
upb_Arena* arena() const { return arena_; }
$0(upb_Message* msg, upb_Arena* arena) : $0Access() { $0(upb_Message* msg, upb_Arena* arena) : $0Access() {
msg_ = ($1*)msg; msg_ = ($1*)msg;
arena_ = owned_arena_.ptr(); arena_ = owned_arena_.ptr();
@ -282,7 +282,6 @@ void WriteModelProxyDeclaration(const protobuf::Descriptor* descriptor,
arena_ = m.arena_; arena_ = m.arena_;
return *this; return *this;
} }
using $0Access::GetInternalArena;
)cc", )cc",
ClassName(descriptor)); ClassName(descriptor));
@ -295,6 +294,8 @@ void WriteModelProxyDeclaration(const protobuf::Descriptor* descriptor,
private: private:
upb_Message* msg() const { return UPB_UPCAST(msg_); } upb_Message* msg() const { return UPB_UPCAST(msg_); }
upb_Arena* arena() const { return arena_; }
$0Proxy(upb_Message* msg, upb_Arena* arena) $0Proxy(upb_Message* msg, upb_Arena* arena)
: internal::$0Access(($1*)msg, arena) {} : internal::$0Access(($1*)msg, arena) {}
friend $0::Proxy(::hpb::CreateMessage<$0>(::hpb::Arena& arena)); friend $0::Proxy(::hpb::CreateMessage<$0>(::hpb::Arena& arena));
@ -334,7 +335,6 @@ void WriteModelCProxyDeclaration(const protobuf::Descriptor* descriptor,
$0CProxy(const $0* m) $0CProxy(const $0* m)
: internal::$0Access(m->msg_, hpb::interop::upb::GetArena(m)) {} : internal::$0Access(m->msg_, hpb::interop::upb::GetArena(m)) {}
$0CProxy($0Proxy m); $0CProxy($0Proxy m);
using $0Access::GetInternalArena;
)cc", )cc",
ClassName(descriptor), MessageName(descriptor)); ClassName(descriptor), MessageName(descriptor));
@ -347,6 +347,7 @@ void WriteModelCProxyDeclaration(const protobuf::Descriptor* descriptor,
private: private:
using AsNonConst = $0Proxy; using AsNonConst = $0Proxy;
const upb_Message* msg() const { return UPB_UPCAST(msg_); } const upb_Message* msg() const { return UPB_UPCAST(msg_); }
upb_Arena* arena() const { return arena_; }
$0CProxy(const upb_Message* msg, upb_Arena* arena) $0CProxy(const upb_Message* msg, upb_Arena* arena)
: internal::$0Access(($1*)msg, arena){}; : internal::$0Access(($1*)msg, arena){};

Loading…
Cancel
Save