• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "google/protobuf/arena.h"
9 
10 #include <time.h>
11 
12 #include <algorithm>
13 #include <array>
14 #include <atomic>
15 #include <cstddef>
16 #include <cstdint>
17 #include <cstdlib>
18 #include <cstring>
19 #include <memory>
20 #include <new>  // IWYU pragma: keep for operator new
21 #include <string>
22 #include <thread>
23 #include <type_traits>
24 #include <utility>
25 #include <vector>
26 
27 #include <gmock/gmock.h>
28 #include <gtest/gtest.h>
29 #include "absl/log/absl_check.h"
30 #include "absl/log/absl_log.h"
31 #include "absl/strings/string_view.h"
32 #include "absl/synchronization/barrier.h"
33 #include "absl/utility/utility.h"
34 #include "google/protobuf/arena_cleanup.h"
35 #include "google/protobuf/arena_test_util.h"
36 #include "google/protobuf/descriptor.h"
37 #include "google/protobuf/extension_set.h"
38 #include "google/protobuf/io/coded_stream.h"
39 #include "google/protobuf/io/zero_copy_stream_impl_lite.h"
40 #include "google/protobuf/message.h"
41 #include "google/protobuf/message_lite.h"
42 #include "google/protobuf/port.h"
43 #include "google/protobuf/repeated_field.h"
44 #include "google/protobuf/test_util.h"
45 #include "google/protobuf/unittest.pb.h"
46 #include "google/protobuf/unittest_arena.pb.h"
47 #include "google/protobuf/unknown_field_set.h"
48 #include "google/protobuf/wire_format_lite.h"
49 
50 #include "absl/synchronization/mutex.h"
51 
52 // Must be included last
53 #include "google/protobuf/port_def.inc"
54 
55 using proto2_arena_unittest::ArenaMessage;
56 using protobuf_unittest::NestedTestAllTypes;
57 using protobuf_unittest::TestAllExtensions;
58 using protobuf_unittest::TestAllTypes;
59 using protobuf_unittest::TestEmptyMessage;
60 using protobuf_unittest::TestOneof2;
61 using protobuf_unittest::TestRepeatedString;
62 using ::testing::ElementsAreArray;
63 
64 namespace google {
65 namespace protobuf {
66 
67 class Notifier {
68  public:
Notifier()69   Notifier() : count_(0) {}
Notify()70   void Notify() { count_++; }
GetCount()71   int GetCount() { return count_; }
72 
73  private:
74   int count_;
75 };
76 
77 class SimpleDataType {
78  public:
SimpleDataType()79   SimpleDataType() : notifier_(nullptr) {}
SetNotifier(Notifier * notifier)80   void SetNotifier(Notifier* notifier) { notifier_ = notifier; }
~SimpleDataType()81   virtual ~SimpleDataType() {
82     if (notifier_ != nullptr) {
83       notifier_->Notify();
84     }
85   };
86 
87  private:
88   Notifier* notifier_;
89 };
90 
91 // A simple class that does not allow copying and so cannot be used as a
92 // parameter type without "const &".
93 class PleaseDontCopyMe {
94  public:
PleaseDontCopyMe(int value)95   explicit PleaseDontCopyMe(int value) : value_(value) {}
96   PleaseDontCopyMe(const PleaseDontCopyMe&) = delete;
97   PleaseDontCopyMe& operator=(const PleaseDontCopyMe&) = delete;
98 
value() const99   int value() const { return value_; }
100 
101  private:
102   int value_;
103 };
104 
105 // A class that takes four different types as constructor arguments.
106 class MustBeConstructedWithOneThroughFour {
107  public:
MustBeConstructedWithOneThroughFour(int one,const char * two,const std::string & three,const PleaseDontCopyMe * four)108   MustBeConstructedWithOneThroughFour(int one, const char* two,
109                                       const std::string& three,
110                                       const PleaseDontCopyMe* four)
111       : one_(one), two_(two), three_(three), four_(four) {}
112   MustBeConstructedWithOneThroughFour(
113       const MustBeConstructedWithOneThroughFour&) = delete;
114   MustBeConstructedWithOneThroughFour& operator=(
115       const MustBeConstructedWithOneThroughFour&) = delete;
116 
117   int one_;
118   const char* const two_;
119   std::string three_;
120   const PleaseDontCopyMe* four_;
121 };
122 
123 // A class that takes eight different types as constructor arguments.
124 class MustBeConstructedWithOneThroughEight {
125  public:
MustBeConstructedWithOneThroughEight(int one,const char * two,const std::string & three,const PleaseDontCopyMe * four,int five,const char * six,const std::string & seven,const std::string & eight)126   MustBeConstructedWithOneThroughEight(int one, const char* two,
127                                        const std::string& three,
128                                        const PleaseDontCopyMe* four, int five,
129                                        const char* six,
130                                        const std::string& seven,
131                                        const std::string& eight)
132       : one_(one),
133         two_(two),
134         three_(three),
135         four_(four),
136         five_(five),
137         six_(six),
138         seven_(seven),
139         eight_(eight) {}
140   MustBeConstructedWithOneThroughEight(
141       const MustBeConstructedWithOneThroughEight&) = delete;
142   MustBeConstructedWithOneThroughEight& operator=(
143       const MustBeConstructedWithOneThroughEight&) = delete;
144 
145   int one_;
146   const char* const two_;
147   std::string three_;
148   const PleaseDontCopyMe* four_;
149   int five_;
150   const char* const six_;
151   std::string seven_;
152   std::string eight_;
153 };
154 
TEST(ArenaTest,ArenaConstructable)155 TEST(ArenaTest, ArenaConstructable) {
156   EXPECT_TRUE(Arena::is_arena_constructable<TestAllTypes>::type::value);
157   EXPECT_TRUE(Arena::is_arena_constructable<const TestAllTypes>::type::value);
158   EXPECT_FALSE(Arena::is_arena_constructable<Arena>::type::value);
159 }
160 
TEST(ArenaTest,DestructorSkippable)161 TEST(ArenaTest, DestructorSkippable) {
162   EXPECT_TRUE(Arena::is_destructor_skippable<TestAllTypes>::type::value);
163   EXPECT_TRUE(Arena::is_destructor_skippable<const TestAllTypes>::type::value);
164   EXPECT_FALSE(Arena::is_destructor_skippable<Arena>::type::value);
165 }
166 
167 template <int>
168 struct EmptyBase {};
169 struct ArenaCtorBase {
170   using InternalArenaConstructable_ = void;
171 };
172 struct ArenaDtorBase {
173   using DestructorSkippable_ = void;
174 };
175 
176 template <bool arena_ctor, bool arena_dtor>
TestCtorAndDtorTraits(std::vector<absl::string_view> def,std::vector<absl::string_view> copy,std::vector<absl::string_view> with_int)177 void TestCtorAndDtorTraits(std::vector<absl::string_view> def,
178                            std::vector<absl::string_view> copy,
179                            std::vector<absl::string_view> with_int) {
180   static auto& actions = *new std::vector<absl::string_view>;
181   struct TraitsProber
182       : std::conditional_t<arena_ctor, ArenaCtorBase, EmptyBase<0>>,
183         std::conditional_t<arena_dtor, ArenaDtorBase, EmptyBase<1>>,
184         Message {
185     TraitsProber() : Message(nullptr, nullptr) { actions.push_back("()"); }
186     TraitsProber(const TraitsProber&) : Message(nullptr, nullptr) {
187       actions.push_back("(const T&)");
188     }
189     explicit TraitsProber(int) : Message(nullptr, nullptr) {
190       actions.push_back("(int)");
191     }
192     explicit TraitsProber(Arena* arena) : Message(nullptr, nullptr) {
193       actions.push_back("(Arena)");
194     }
195     TraitsProber(Arena* arena, const TraitsProber&)
196         : Message(nullptr, nullptr) {
197       actions.push_back("(Arena, const T&)");
198     }
199     TraitsProber(Arena* arena, int) : Message(nullptr, nullptr) {
200       actions.push_back("(Arena, int)");
201     }
202     ~TraitsProber() { actions.push_back("~()"); }
203 
204     TraitsProber* New(Arena*) const {
205       ABSL_LOG(FATAL);
206       return nullptr;
207     }
208     const internal::ClassData* GetClassData() const PROTOBUF_FINAL {
209       ABSL_LOG(FATAL);
210       return nullptr;
211     }
212   };
213 
214   static_assert(
215       !arena_ctor || Arena::is_arena_constructable<TraitsProber>::value, "");
216   static_assert(
217       !arena_dtor || Arena::is_destructor_skippable<TraitsProber>::value, "");
218 
219   {
220     actions.clear();
221     Arena arena;
222     Arena::Create<TraitsProber>(&arena);
223   }
224   EXPECT_THAT(actions, ElementsAreArray(def));
225 
226   const TraitsProber p;
227   {
228     actions.clear();
229     Arena arena;
230     Arena::Create<TraitsProber>(&arena, p);
231   }
232   EXPECT_THAT(actions, ElementsAreArray(copy));
233 
234   {
235     actions.clear();
236     Arena arena;
237     Arena::Create<TraitsProber>(&arena, 17);
238   }
239   EXPECT_THAT(actions, ElementsAreArray(with_int));
240 }
241 
TEST(ArenaTest,AllConstructibleAndDestructibleCombinationsWorkCorrectly)242 TEST(ArenaTest, AllConstructibleAndDestructibleCombinationsWorkCorrectly) {
243   TestCtorAndDtorTraits<false, false>({"()", "~()"}, {"(const T&)", "~()"},
244                                       {"(int)", "~()"});
245   // If the object is not arena constructible, then the destructor is always
246   // called even if marked as skippable.
247   TestCtorAndDtorTraits<false, true>({"()", "~()"}, {"(const T&)", "~()"},
248                                      {"(int)", "~()"});
249 
250   // Some types are arena constructible but we can't skip the destructor. Those
251   // are constructed with an arena but still destroyed.
252   TestCtorAndDtorTraits<true, false>({"(Arena)", "~()"},
253                                      {"(Arena, const T&)", "~()"},
254                                      {"(Arena, int)", "~()"});
255   TestCtorAndDtorTraits<true, true>({"(Arena)"}, {"(Arena, const T&)"},
256                                     {"(Arena, int)"});
257 }
258 
TEST(ArenaTest,BasicCreate)259 TEST(ArenaTest, BasicCreate) {
260   Arena arena;
261   EXPECT_TRUE(Arena::Create<int32_t>(&arena) != nullptr);
262   EXPECT_TRUE(Arena::Create<int64_t>(&arena) != nullptr);
263   EXPECT_TRUE(Arena::Create<float>(&arena) != nullptr);
264   EXPECT_TRUE(Arena::Create<double>(&arena) != nullptr);
265   EXPECT_TRUE(Arena::Create<std::string>(&arena) != nullptr);
266   arena.Own(new int32_t);
267   arena.Own(new int64_t);
268   arena.Own(new float);
269   arena.Own(new double);
270   arena.Own(new std::string);
271   arena.Own<int>(nullptr);
272   Notifier notifier;
273   SimpleDataType* data = Arena::Create<SimpleDataType>(&arena);
274   data->SetNotifier(&notifier);
275   data = new SimpleDataType;
276   data->SetNotifier(&notifier);
277   arena.Own(data);
278   arena.Reset();
279   EXPECT_EQ(2, notifier.GetCount());
280 }
281 
TEST(ArenaTest,CreateAndConstCopy)282 TEST(ArenaTest, CreateAndConstCopy) {
283   Arena arena;
284   const std::string s("foo");
285   const std::string* s_copy = Arena::Create<std::string>(&arena, s);
286   EXPECT_TRUE(s_copy != nullptr);
287   EXPECT_EQ("foo", s);
288   EXPECT_EQ("foo", *s_copy);
289 }
290 
TEST(ArenaTest,CreateAndNonConstCopy)291 TEST(ArenaTest, CreateAndNonConstCopy) {
292   Arena arena;
293   std::string s("foo");
294   const std::string* s_copy = Arena::Create<std::string>(&arena, s);
295   EXPECT_TRUE(s_copy != nullptr);
296   EXPECT_EQ("foo", s);
297   EXPECT_EQ("foo", *s_copy);
298 }
299 
TEST(ArenaTest,CreateAndMove)300 TEST(ArenaTest, CreateAndMove) {
301   Arena arena;
302   std::string s("foo");
303   const std::string* s_move = Arena::Create<std::string>(&arena, std::move(s));
304   EXPECT_TRUE(s_move != nullptr);
305   EXPECT_TRUE(s.empty());  // NOLINT
306   EXPECT_EQ("foo", *s_move);
307 }
308 
TEST(ArenaTest,CreateWithFourConstructorArguments)309 TEST(ArenaTest, CreateWithFourConstructorArguments) {
310   Arena arena;
311   const std::string three("3");
312   const PleaseDontCopyMe four(4);
313   const MustBeConstructedWithOneThroughFour* new_object =
314       Arena::Create<MustBeConstructedWithOneThroughFour>(&arena, 1, "2", three,
315                                                          &four);
316   EXPECT_TRUE(new_object != nullptr);
317   ASSERT_EQ(1, new_object->one_);
318   ASSERT_STREQ("2", new_object->two_);
319   ASSERT_EQ("3", new_object->three_);
320   ASSERT_EQ(4, new_object->four_->value());
321 }
322 
TEST(ArenaTest,CreateWithEightConstructorArguments)323 TEST(ArenaTest, CreateWithEightConstructorArguments) {
324   Arena arena;
325   const std::string three("3");
326   const PleaseDontCopyMe four(4);
327   const std::string seven("7");
328   const std::string eight("8");
329   const MustBeConstructedWithOneThroughEight* new_object =
330       Arena::Create<MustBeConstructedWithOneThroughEight>(
331           &arena, 1, "2", three, &four, 5, "6", seven, eight);
332   EXPECT_TRUE(new_object != nullptr);
333   ASSERT_EQ(1, new_object->one_);
334   ASSERT_STREQ("2", new_object->two_);
335   ASSERT_EQ("3", new_object->three_);
336   ASSERT_EQ(4, new_object->four_->value());
337   ASSERT_EQ(5, new_object->five_);
338   ASSERT_STREQ("6", new_object->six_);
339   ASSERT_EQ("7", new_object->seven_);
340   ASSERT_EQ("8", new_object->eight_);
341 }
342 
343 class PleaseMoveMe {
344  public:
PleaseMoveMe(const std::string & value)345   explicit PleaseMoveMe(const std::string& value) : value_(value) {}
346   PleaseMoveMe(PleaseMoveMe&&) = default;
347   PleaseMoveMe(const PleaseMoveMe&) = delete;
348 
value() const349   const std::string& value() const { return value_; }
350 
351  private:
352   std::string value_;
353 };
354 
TEST(ArenaTest,CreateWithMoveArguments)355 TEST(ArenaTest, CreateWithMoveArguments) {
356   Arena arena;
357   PleaseMoveMe one("1");
358   const PleaseMoveMe* new_object =
359       Arena::Create<PleaseMoveMe>(&arena, std::move(one));
360   EXPECT_TRUE(new_object);
361   ASSERT_EQ("1", new_object->value());
362 }
363 
TEST(ArenaTest,InitialBlockTooSmall)364 TEST(ArenaTest, InitialBlockTooSmall) {
365   // Construct a small blocks of memory to be used by the arena allocator; then,
366   // allocate an object which will not fit in the initial block.
367   for (uint32_t size = 0; size <= internal::SerialArena::kBlockHeaderSize + 32;
368        size++) {
369     std::vector<char> arena_block(size);
370     ArenaOptions options;
371     options.initial_block = arena_block.data();
372     options.initial_block_size = arena_block.size();
373 
374     // Try sometimes with non-default block sizes so that we exercise paths
375     // with and without ArenaImpl::Options.
376     if ((size % 2) != 0) {
377       options.start_block_size += 8;
378     }
379 
380     Arena arena(options);
381 
382     char* p = Arena::CreateArray<char>(&arena, 96);
383     uintptr_t allocation = reinterpret_cast<uintptr_t>(p);
384 
385     // Ensure that the arena allocator did not return memory pointing into the
386     // initial block of memory.
387     uintptr_t arena_start = reinterpret_cast<uintptr_t>(arena_block.data());
388     uintptr_t arena_end = arena_start + arena_block.size();
389     EXPECT_FALSE(allocation >= arena_start && allocation < arena_end);
390 
391     // Write to the memory we allocated; this should (but is not guaranteed to)
392     // trigger a check for heap corruption if the object was allocated from the
393     // initially-provided block.
394     memset(p, '\0', 96);
395   }
396 }
397 
TEST(ArenaTest,CreateDestroy)398 TEST(ArenaTest, CreateDestroy) {
399   TestAllTypes original;
400   TestUtil::SetAllFields(&original);
401 
402   // Test memory leak.
403   Arena arena;
404   TestAllTypes* heap_message = Arena::Create<TestAllTypes>(nullptr);
405   TestAllTypes* arena_message = Arena::Create<TestAllTypes>(&arena);
406 
407   *heap_message = original;
408   *arena_message = original;
409 
410   Arena::Destroy(heap_message);
411   Arena::Destroy(arena_message);
412 
413   // The arena message should still exist.
414   EXPECT_EQ(strlen(original.optional_string().c_str()),
415             strlen(arena_message->optional_string().c_str()));
416 }
417 
TEST(ArenaTest,MoveCtorOnArena)418 TEST(ArenaTest, MoveCtorOnArena) {
419   Arena arena;
420 
421   ASSERT_EQ(arena.SpaceUsed(), 0);
422 
423   auto* original = Arena::Create<NestedTestAllTypes>(&arena);
424   TestUtil::SetAllFields(original->mutable_payload());
425   TestUtil::ExpectAllFieldsSet(original->payload());
426 
427   auto usage_original = arena.SpaceUsed();
428   auto* moved = Arena::Create<NestedTestAllTypes>(&arena, std::move(*original));
429   auto usage_by_move = arena.SpaceUsed() - usage_original;
430 
431   TestUtil::ExpectAllFieldsSet(moved->payload());
432 
433   // The only extra allocation with moves is sizeof(NestedTestAllTypes).
434   EXPECT_EQ(usage_by_move, sizeof(NestedTestAllTypes));
435   EXPECT_LT(usage_by_move + sizeof(TestAllTypes), usage_original);
436 
437   // Status after move is unspecified and must not be assumed. It's merely
438   // checking current implementation specifics for protobuf internal.
439   TestUtil::ExpectClear(original->payload());
440 }
441 
TEST(ArenaTest,RepeatedFieldMoveCtorOnArena)442 TEST(ArenaTest, RepeatedFieldMoveCtorOnArena) {
443   Arena arena;
444 
445   auto* original = Arena::Create<RepeatedField<int32_t>>(&arena);
446   original->Add(1);
447   original->Add(2);
448   ASSERT_EQ(original->size(), 2);
449   ASSERT_EQ(original->Get(0), 1);
450   ASSERT_EQ(original->Get(1), 2);
451 
452   auto* moved =
453       Arena::Create<RepeatedField<int32_t>>(&arena, std::move(*original));
454 
455   EXPECT_EQ(moved->size(), 2);
456   EXPECT_EQ(moved->Get(0), 1);
457   EXPECT_EQ(moved->Get(1), 2);
458 
459   // Status after move is unspecified and must not be assumed. It's merely
460   // checking current implementation specifics for protobuf internal.
461   EXPECT_EQ(original->size(), 0);
462 }
463 
TEST(ArenaTest,RepeatedPtrFieldMoveCtorOnArena)464 TEST(ArenaTest, RepeatedPtrFieldMoveCtorOnArena) {
465   Arena arena;
466 
467   ASSERT_EQ(arena.SpaceUsed(), 0);
468 
469   auto* original = Arena::Create<RepeatedPtrField<TestAllTypes>>(&arena);
470   auto* msg = original->Add();
471   TestUtil::SetAllFields(msg);
472   TestUtil::ExpectAllFieldsSet(*msg);
473 
474   auto usage_original = arena.SpaceUsed();
475   auto* moved = Arena::Create<RepeatedPtrField<TestAllTypes>>(
476       &arena, std::move(*original));
477   auto usage_by_move = arena.SpaceUsed() - usage_original;
478 
479   EXPECT_EQ(moved->size(), 1);
480   TestUtil::ExpectAllFieldsSet(moved->Get(0));
481 
482   // The only extra allocation with moves is sizeof(RepeatedPtrField).
483   EXPECT_EQ(usage_by_move, sizeof(internal::RepeatedPtrFieldBase));
484   EXPECT_LT(usage_by_move + sizeof(TestAllTypes), usage_original);
485 
486   // Status after move is unspecified and must not be assumed. It's merely
487   // checking current implementation specifics for protobuf internal.
488   EXPECT_EQ(original->size(), 0);
489 }
490 
491 struct OnlyArenaConstructible {
492   using InternalArenaConstructable_ = void;
OnlyArenaConstructiblegoogle::protobuf::OnlyArenaConstructible493   explicit OnlyArenaConstructible(Arena* arena) {}
494 };
495 
TEST(ArenaTest,ArenaOnlyTypesCanBeConstructed)496 TEST(ArenaTest, ArenaOnlyTypesCanBeConstructed) {
497   Arena arena;
498   Arena::Create<OnlyArenaConstructible>(&arena);
499 }
500 
TEST(ArenaTest,GetConstructTypeWorks)501 TEST(ArenaTest, GetConstructTypeWorks) {
502   using T = TestAllTypes;
503   using Peer = internal::ArenaTestPeer;
504   using CT = typename Peer::ConstructType;
505   EXPECT_EQ(CT::kDefault, (Peer::GetConstructType<T>()));
506   EXPECT_EQ(CT::kCopy, (Peer::GetConstructType<T, const T&>()));
507   EXPECT_EQ(CT::kCopy, (Peer::GetConstructType<T, T&>()));
508   EXPECT_EQ(CT::kCopy, (Peer::GetConstructType<T, const T&&>()));
509   EXPECT_EQ(CT::kMove, (Peer::GetConstructType<T, T&&>()));
510   EXPECT_EQ(CT::kUnknown, (Peer::GetConstructType<T, double&>()));
511   EXPECT_EQ(CT::kUnknown, (Peer::GetConstructType<T, T&, T&>()));
512 
513   // For non-protos, it's always unknown
514   EXPECT_EQ(CT::kUnknown, (Peer::GetConstructType<int, const int&>()));
515 }
516 
517 #ifdef __cpp_if_constexpr
518 class DispatcherTestProto : public Message {
519  public:
520   using InternalArenaConstructable_ = void;
521   using DestructorSkippable_ = void;
522   // For the test below to construct.
DispatcherTestProto(absl::in_place_t)523   explicit DispatcherTestProto(absl::in_place_t) : Message(nullptr, nullptr) {}
DispatcherTestProto(Arena *)524   explicit DispatcherTestProto(Arena*) : Message(nullptr, nullptr) {
525     ABSL_LOG(FATAL);
526   }
DispatcherTestProto(Arena *,const DispatcherTestProto &)527   DispatcherTestProto(Arena*, const DispatcherTestProto&)
528       : Message(nullptr, nullptr) {
529     ABSL_LOG(FATAL);
530   }
GetClassData() const531   const internal::ClassData* GetClassData() const PROTOBUF_FINAL {
532     ABSL_LOG(FATAL);
533   }
534 };
535 // We use a specialization to inject behavior for the test.
536 // This test is very intrusive and will have to be fixed if we change the
537 // implementation of CreateMessage.
538 absl::string_view hook_called;
539 template <>
DefaultConstruct(Arena *)540 void* Arena::DefaultConstruct<DispatcherTestProto>(Arena*) {
541   hook_called = "default";
542   return nullptr;
543 }
544 template <>
CopyConstruct(Arena *,const void *)545 void* Arena::CopyConstruct<DispatcherTestProto>(Arena*, const void*) {
546   hook_called = "copy";
547   return nullptr;
548 }
549 template <>
CreateArenaCompatible(Arena *,int &&)550 DispatcherTestProto* Arena::CreateArenaCompatible<DispatcherTestProto, int>(
551     Arena*, int&&) {
552   hook_called = "fallback";
553   return nullptr;
554 }
555 
TEST(ArenaTest,CreateArenaConstructable)556 TEST(ArenaTest, CreateArenaConstructable) {
557   TestAllTypes original;
558   TestUtil::SetAllFields(&original);
559 
560   Arena arena;
561   auto copied = Arena::Create<TestAllTypes>(&arena, original);
562 
563   TestUtil::ExpectAllFieldsSet(*copied);
564   EXPECT_EQ(copied->GetArena(), &arena);
565   EXPECT_EQ(copied->optional_nested_message().GetArena(), &arena);
566 }
567 
TEST(ArenaTest,CreateRepeatedPtrField)568 TEST(ArenaTest, CreateRepeatedPtrField) {
569   Arena arena;
570   auto repeated = Arena::Create<RepeatedPtrField<TestAllTypes>>(&arena);
571   TestUtil::SetAllFields(repeated->Add());
572 
573   TestUtil::ExpectAllFieldsSet(repeated->Get(0));
574   EXPECT_EQ(repeated->GetArena(), &arena);
575   EXPECT_EQ(repeated->Get(0).GetArena(), &arena);
576   EXPECT_EQ(repeated->Get(0).optional_nested_message().GetArena(), &arena);
577 }
578 
TEST(ArenaTest,CreateMessageDispatchesToSpecialFunctions)579 TEST(ArenaTest, CreateMessageDispatchesToSpecialFunctions) {
580   hook_called = "";
581   Arena::Create<DispatcherTestProto>(nullptr);
582   EXPECT_EQ(hook_called, "default");
583 
584   DispatcherTestProto ref(absl::in_place);
585   const DispatcherTestProto& cref = ref;
586 
587   hook_called = "";
588   Arena::Create<DispatcherTestProto>(nullptr);
589   EXPECT_EQ(hook_called, "default");
590 
591   hook_called = "";
592   Arena::Create<DispatcherTestProto>(nullptr, ref);
593   EXPECT_EQ(hook_called, "copy");
594 
595   hook_called = "";
596   Arena::Create<DispatcherTestProto>(nullptr, cref);
597   EXPECT_EQ(hook_called, "copy");
598 
599   hook_called = "";
600   Arena::Create<DispatcherTestProto>(nullptr, 1);
601   EXPECT_EQ(hook_called, "fallback");
602 }
603 #endif  // __cpp_if_constexpr
604 
TEST(ArenaTest,Parsing)605 TEST(ArenaTest, Parsing) {
606   TestAllTypes original;
607   TestUtil::SetAllFields(&original);
608 
609   // Test memory leak.
610   Arena arena;
611   TestAllTypes* arena_message = Arena::Create<TestAllTypes>(&arena);
612   arena_message->ParseFromString(original.SerializeAsString());
613   TestUtil::ExpectAllFieldsSet(*arena_message);
614 
615   // Test that string fields have nul terminator bytes (earlier bug).
616   EXPECT_EQ(strlen(original.optional_string().c_str()),
617             strlen(arena_message->optional_string().c_str()));
618 }
619 
TEST(ArenaTest,UnknownFields)620 TEST(ArenaTest, UnknownFields) {
621   TestAllTypes original;
622   TestUtil::SetAllFields(&original);
623 
624   // Test basic parsing into (populating) and reading out of unknown fields on
625   // an arena.
626   Arena arena;
627   TestEmptyMessage* arena_message = Arena::Create<TestEmptyMessage>(&arena);
628   arena_message->ParseFromString(original.SerializeAsString());
629 
630   TestAllTypes copied;
631   copied.ParseFromString(arena_message->SerializeAsString());
632   TestUtil::ExpectAllFieldsSet(copied);
633 
634   // Exercise UFS manual manipulation (setters).
635   arena_message = Arena::Create<TestEmptyMessage>(&arena);
636   arena_message->mutable_unknown_fields()->AddVarint(
637       TestAllTypes::kOptionalInt32FieldNumber, 42);
638   copied.Clear();
639   copied.ParseFromString(arena_message->SerializeAsString());
640   EXPECT_TRUE(copied.has_optional_int32());
641   EXPECT_EQ(42, copied.optional_int32());
642 
643   // Exercise UFS swap path.
644   TestEmptyMessage* arena_message_2 = Arena::Create<TestEmptyMessage>(&arena);
645   arena_message_2->Swap(arena_message);
646   copied.Clear();
647   copied.ParseFromString(arena_message_2->SerializeAsString());
648   EXPECT_TRUE(copied.has_optional_int32());
649   EXPECT_EQ(42, copied.optional_int32());
650 
651   // Test field manipulation.
652   TestEmptyMessage* arena_message_3 = Arena::Create<TestEmptyMessage>(&arena);
653   arena_message_3->mutable_unknown_fields()->AddVarint(1000, 42);
654   arena_message_3->mutable_unknown_fields()->AddFixed32(1001, 42);
655   arena_message_3->mutable_unknown_fields()->AddFixed64(1002, 42);
656   arena_message_3->mutable_unknown_fields()->AddLengthDelimited(1003, "");
657   arena_message_3->mutable_unknown_fields()->DeleteSubrange(0, 2);
658   arena_message_3->mutable_unknown_fields()->DeleteByNumber(1002);
659   arena_message_3->mutable_unknown_fields()->DeleteByNumber(1003);
660   EXPECT_TRUE(arena_message_3->unknown_fields().empty());
661 }
662 
TEST(ArenaTest,Swap)663 TEST(ArenaTest, Swap) {
664   Arena arena1;
665   Arena arena2;
666   TestAllTypes* arena1_message;
667   TestAllTypes* arena2_message;
668 
669   // Case 1: Swap(), no UFS on either message, both messages on different
670   // arenas. Arena pointers should remain the same after swap.
671   arena1_message = Arena::Create<TestAllTypes>(&arena1);
672   arena2_message = Arena::Create<TestAllTypes>(&arena2);
673   arena1_message->Swap(arena2_message);
674   EXPECT_EQ(&arena1, arena1_message->GetArena());
675   EXPECT_EQ(&arena2, arena2_message->GetArena());
676 
677   // Case 2: Swap(), UFS on one message, both messages on different arenas.
678   arena1_message = Arena::Create<TestAllTypes>(&arena1);
679   arena2_message = Arena::Create<TestAllTypes>(&arena2);
680   arena1_message->mutable_unknown_fields()->AddVarint(1, 42);
681   arena1_message->Swap(arena2_message);
682   EXPECT_EQ(&arena1, arena1_message->GetArena());
683   EXPECT_EQ(&arena2, arena2_message->GetArena());
684   EXPECT_EQ(0, arena1_message->unknown_fields().field_count());
685   EXPECT_EQ(1, arena2_message->unknown_fields().field_count());
686   EXPECT_EQ(42, arena2_message->unknown_fields().field(0).varint());
687 
688   // Case 3: Swap(), UFS on both messages, both messages on different arenas.
689   arena1_message = Arena::Create<TestAllTypes>(&arena1);
690   arena2_message = Arena::Create<TestAllTypes>(&arena2);
691   arena1_message->mutable_unknown_fields()->AddVarint(1, 42);
692   arena2_message->mutable_unknown_fields()->AddVarint(2, 84);
693   arena1_message->Swap(arena2_message);
694   EXPECT_EQ(&arena1, arena1_message->GetArena());
695   EXPECT_EQ(&arena2, arena2_message->GetArena());
696   EXPECT_EQ(1, arena1_message->unknown_fields().field_count());
697   EXPECT_EQ(1, arena2_message->unknown_fields().field_count());
698   EXPECT_EQ(84, arena1_message->unknown_fields().field(0).varint());
699   EXPECT_EQ(42, arena2_message->unknown_fields().field(0).varint());
700 }
701 
TEST(ArenaTest,ReflectionSwapFields)702 TEST(ArenaTest, ReflectionSwapFields) {
703   Arena arena1;
704   Arena arena2;
705   TestAllTypes* arena1_message;
706   TestAllTypes* arena2_message;
707 
708   // Case 1: messages on different arenas, only one message is set.
709   arena1_message = Arena::Create<TestAllTypes>(&arena1);
710   arena2_message = Arena::Create<TestAllTypes>(&arena2);
711   TestUtil::SetAllFields(arena1_message);
712   const Reflection* reflection = arena1_message->GetReflection();
713   std::vector<const FieldDescriptor*> fields;
714   reflection->ListFields(*arena1_message, &fields);
715   reflection->SwapFields(arena1_message, arena2_message, fields);
716   EXPECT_EQ(&arena1, arena1_message->GetArena());
717   EXPECT_EQ(&arena2, arena2_message->GetArena());
718   std::string output;
719   arena1_message->SerializeToString(&output);
720   EXPECT_EQ(0, output.size());
721   TestUtil::ExpectAllFieldsSet(*arena2_message);
722   reflection->SwapFields(arena1_message, arena2_message, fields);
723   arena2_message->SerializeToString(&output);
724   EXPECT_EQ(0, output.size());
725   TestUtil::ExpectAllFieldsSet(*arena1_message);
726 
727   // Case 2: messages on different arenas, both messages are set.
728   arena1_message = Arena::Create<TestAllTypes>(&arena1);
729   arena2_message = Arena::Create<TestAllTypes>(&arena2);
730   TestUtil::SetAllFields(arena1_message);
731   TestUtil::SetAllFields(arena2_message);
732   reflection->SwapFields(arena1_message, arena2_message, fields);
733   EXPECT_EQ(&arena1, arena1_message->GetArena());
734   EXPECT_EQ(&arena2, arena2_message->GetArena());
735   TestUtil::ExpectAllFieldsSet(*arena1_message);
736   TestUtil::ExpectAllFieldsSet(*arena2_message);
737 
738   // Case 3: messages on different arenas with different lifetimes.
739   arena1_message = Arena::Create<TestAllTypes>(&arena1);
740   {
741     Arena arena3;
742     TestAllTypes* arena3_message = Arena::Create<TestAllTypes>(&arena3);
743     TestUtil::SetAllFields(arena3_message);
744     reflection->SwapFields(arena1_message, arena3_message, fields);
745   }
746   TestUtil::ExpectAllFieldsSet(*arena1_message);
747 
748   // Case 4: one message on arena, the other on heap.
749   arena1_message = Arena::Create<TestAllTypes>(&arena1);
750   TestAllTypes message;
751   TestUtil::SetAllFields(arena1_message);
752   reflection->SwapFields(arena1_message, &message, fields);
753   EXPECT_EQ(&arena1, arena1_message->GetArena());
754   EXPECT_EQ(nullptr, message.GetArena());
755   arena1_message->SerializeToString(&output);
756   EXPECT_EQ(0, output.size());
757   TestUtil::ExpectAllFieldsSet(message);
758 }
759 
TEST(ArenaTest,SetAllocatedMessage)760 TEST(ArenaTest, SetAllocatedMessage) {
761   Arena arena;
762   TestAllTypes* arena_message = Arena::Create<TestAllTypes>(&arena);
763   TestAllTypes::NestedMessage* nested = new TestAllTypes::NestedMessage;
764   nested->set_bb(118);
765   arena_message->set_allocated_optional_nested_message(nested);
766   EXPECT_EQ(118, arena_message->optional_nested_message().bb());
767 }
768 
TEST(ArenaTest,ReleaseMessage)769 TEST(ArenaTest, ReleaseMessage) {
770   Arena arena;
771   TestAllTypes* arena_message = Arena::Create<TestAllTypes>(&arena);
772   arena_message->mutable_optional_nested_message()->set_bb(118);
773   std::unique_ptr<TestAllTypes::NestedMessage> nested(
774       arena_message->release_optional_nested_message());
775   EXPECT_EQ(118, nested->bb());
776 
777   TestAllTypes::NestedMessage* released_null =
778       arena_message->release_optional_nested_message();
779   EXPECT_EQ(nullptr, released_null);
780 }
781 
TEST(ArenaTest,SetAllocatedString)782 TEST(ArenaTest, SetAllocatedString) {
783   Arena arena;
784   TestAllTypes* arena_message = Arena::Create<TestAllTypes>(&arena);
785   std::string* allocated_str = new std::string("hello");
786   arena_message->set_allocated_optional_string(allocated_str);
787   EXPECT_EQ("hello", arena_message->optional_string());
788 }
789 
TEST(ArenaTest,ReleaseString)790 TEST(ArenaTest, ReleaseString) {
791   Arena arena;
792   TestAllTypes* arena_message = Arena::Create<TestAllTypes>(&arena);
793   arena_message->set_optional_string("hello");
794   std::unique_ptr<std::string> released_str(
795       arena_message->release_optional_string());
796   EXPECT_EQ("hello", *released_str);
797 
798   // Test default value.
799 }
800 
801 
TEST(ArenaTest,SwapBetweenArenasWithAllFieldsSet)802 TEST(ArenaTest, SwapBetweenArenasWithAllFieldsSet) {
803   Arena arena1;
804   TestAllTypes* arena1_message = Arena::Create<TestAllTypes>(&arena1);
805   {
806     Arena arena2;
807     TestAllTypes* arena2_message = Arena::Create<TestAllTypes>(&arena2);
808     TestUtil::SetAllFields(arena2_message);
809     arena2_message->Swap(arena1_message);
810     std::string output;
811     arena2_message->SerializeToString(&output);
812     EXPECT_EQ(0, output.size());
813   }
814   TestUtil::ExpectAllFieldsSet(*arena1_message);
815 }
816 
TEST(ArenaTest,SwapBetweenArenaAndNonArenaWithAllFieldsSet)817 TEST(ArenaTest, SwapBetweenArenaAndNonArenaWithAllFieldsSet) {
818   TestAllTypes non_arena_message;
819   TestUtil::SetAllFields(&non_arena_message);
820   {
821     Arena arena2;
822     TestAllTypes* arena2_message = Arena::Create<TestAllTypes>(&arena2);
823     TestUtil::SetAllFields(arena2_message);
824     arena2_message->Swap(&non_arena_message);
825     TestUtil::ExpectAllFieldsSet(*arena2_message);
826     TestUtil::ExpectAllFieldsSet(non_arena_message);
827   }
828 }
829 
TEST(ArenaTest,UnsafeArenaSwap)830 TEST(ArenaTest, UnsafeArenaSwap) {
831   Arena shared_arena;
832   TestAllTypes* message1 = Arena::Create<TestAllTypes>(&shared_arena);
833   TestAllTypes* message2 = Arena::Create<TestAllTypes>(&shared_arena);
834   TestUtil::SetAllFields(message1);
835   message1->UnsafeArenaSwap(message2);
836   TestUtil::ExpectAllFieldsSet(*message2);
837 }
838 
TEST(ArenaTest,SwapBetweenArenasUsingReflection)839 TEST(ArenaTest, SwapBetweenArenasUsingReflection) {
840   Arena arena1;
841   TestAllTypes* arena1_message = Arena::Create<TestAllTypes>(&arena1);
842   {
843     Arena arena2;
844     TestAllTypes* arena2_message = Arena::Create<TestAllTypes>(&arena2);
845     TestUtil::SetAllFields(arena2_message);
846     const Reflection* r = arena2_message->GetReflection();
847     r->Swap(arena1_message, arena2_message);
848     std::string output;
849     arena2_message->SerializeToString(&output);
850     EXPECT_EQ(0, output.size());
851   }
852   TestUtil::ExpectAllFieldsSet(*arena1_message);
853 }
854 
TEST(ArenaTest,SwapBetweenArenaAndNonArenaUsingReflection)855 TEST(ArenaTest, SwapBetweenArenaAndNonArenaUsingReflection) {
856   TestAllTypes non_arena_message;
857   TestUtil::SetAllFields(&non_arena_message);
858   {
859     Arena arena2;
860     TestAllTypes* arena2_message = Arena::Create<TestAllTypes>(&arena2);
861     TestUtil::SetAllFields(arena2_message);
862     const Reflection* r = arena2_message->GetReflection();
863     r->Swap(&non_arena_message, arena2_message);
864     TestUtil::ExpectAllFieldsSet(*arena2_message);
865     TestUtil::ExpectAllFieldsSet(non_arena_message);
866   }
867 }
868 
TEST(ArenaTest,ReleaseFromArenaMessageMakesCopy)869 TEST(ArenaTest, ReleaseFromArenaMessageMakesCopy) {
870   TestAllTypes::NestedMessage* nested_msg = nullptr;
871   std::string* nested_string = nullptr;
872   {
873     Arena arena;
874     TestAllTypes* arena_message = Arena::Create<TestAllTypes>(&arena);
875     arena_message->mutable_optional_nested_message()->set_bb(42);
876     *arena_message->mutable_optional_string() = "Hello";
877     nested_msg = arena_message->release_optional_nested_message();
878     nested_string = arena_message->release_optional_string();
879   }
880   EXPECT_EQ(42, nested_msg->bb());
881   EXPECT_EQ("Hello", *nested_string);
882   delete nested_msg;
883   delete nested_string;
884 }
885 
886 #if PROTOBUF_RTTI
TEST(ArenaTest,ReleaseFromArenaMessageUsingReflectionMakesCopy)887 TEST(ArenaTest, ReleaseFromArenaMessageUsingReflectionMakesCopy) {
888   TestAllTypes::NestedMessage* nested_msg = nullptr;
889   // Note: no string: reflection API only supports releasing submessages.
890   {
891     Arena arena;
892     TestAllTypes* arena_message = Arena::Create<TestAllTypes>(&arena);
893     arena_message->mutable_optional_nested_message()->set_bb(42);
894     const Reflection* r = arena_message->GetReflection();
895     const FieldDescriptor* f = arena_message->GetDescriptor()->FindFieldByName(
896         "optional_nested_message");
897     nested_msg = DownCastMessage<TestAllTypes::NestedMessage>(
898         r->ReleaseMessage(arena_message, f));
899   }
900   EXPECT_EQ(42, nested_msg->bb());
901   delete nested_msg;
902 }
903 #endif  // PROTOBUF_RTTI
904 
TEST(ArenaTest,SetAllocatedAcrossArenas)905 TEST(ArenaTest, SetAllocatedAcrossArenas) {
906   Arena arena1;
907   TestAllTypes* arena1_message = Arena::Create<TestAllTypes>(&arena1);
908   TestAllTypes::NestedMessage* heap_submessage =
909       new TestAllTypes::NestedMessage();
910   heap_submessage->set_bb(42);
911   arena1_message->set_allocated_optional_nested_message(heap_submessage);
912   // Should keep same object and add to arena's Own()-list.
913   EXPECT_EQ(heap_submessage, arena1_message->mutable_optional_nested_message());
914   {
915     Arena arena2;
916     TestAllTypes::NestedMessage* arena2_submessage =
917         Arena::Create<TestAllTypes::NestedMessage>(&arena2);
918     arena2_submessage->set_bb(42);
919 #if GTEST_HAS_DEATH_TEST
920     EXPECT_DEBUG_DEATH(arena1_message->set_allocated_optional_nested_message(
921                            arena2_submessage),
922                        "submessage_arena");
923 #endif
924     EXPECT_NE(arena2_submessage,
925               arena1_message->mutable_optional_nested_message());
926   }
927 
928   TestAllTypes::NestedMessage* arena1_submessage =
929       Arena::Create<TestAllTypes::NestedMessage>(&arena1);
930   arena1_submessage->set_bb(42);
931   TestAllTypes* heap_message = new TestAllTypes;
932 #if GTEST_HAS_DEATH_TEST
933   EXPECT_DEBUG_DEATH(
934       heap_message->set_allocated_optional_nested_message(arena1_submessage),
935       "submessage_arena");
936 #endif
937   EXPECT_NE(arena1_submessage, heap_message->mutable_optional_nested_message());
938   delete heap_message;
939 }
940 
TEST(ArenaTest,UnsafeArenaSetAllocatedAcrossArenas)941 TEST(ArenaTest, UnsafeArenaSetAllocatedAcrossArenas) {
942   Arena arena1;
943   TestAllTypes* arena1_message = Arena::Create<TestAllTypes>(&arena1);
944   {
945     Arena arena2;
946     TestAllTypes::NestedMessage* arena2_submessage =
947         Arena::Create<TestAllTypes::NestedMessage>(&arena2);
948     arena2_submessage->set_bb(42);
949     arena1_message->unsafe_arena_set_allocated_optional_nested_message(
950         arena2_submessage);
951     EXPECT_EQ(arena2_submessage,
952               arena1_message->mutable_optional_nested_message());
953     EXPECT_EQ(arena2_submessage,
954               arena1_message->unsafe_arena_release_optional_nested_message());
955   }
956 
957   TestAllTypes::NestedMessage* arena1_submessage =
958       Arena::Create<TestAllTypes::NestedMessage>(&arena1);
959   arena1_submessage->set_bb(42);
960   TestAllTypes* heap_message = new TestAllTypes;
961   heap_message->unsafe_arena_set_allocated_optional_nested_message(
962       arena1_submessage);
963   EXPECT_EQ(arena1_submessage, heap_message->mutable_optional_nested_message());
964   EXPECT_EQ(arena1_submessage,
965             heap_message->unsafe_arena_release_optional_nested_message());
966   delete heap_message;
967 }
968 
TEST(ArenaTest,SetAllocatedAcrossArenasWithReflection)969 TEST(ArenaTest, SetAllocatedAcrossArenasWithReflection) {
970   // Same as above, with reflection.
971   Arena arena1;
972   TestAllTypes* arena1_message = Arena::Create<TestAllTypes>(&arena1);
973   const Reflection* r = arena1_message->GetReflection();
974   const Descriptor* d = arena1_message->GetDescriptor();
975   const FieldDescriptor* msg_field =
976       d->FindFieldByName("optional_nested_message");
977   TestAllTypes::NestedMessage* heap_submessage =
978       new TestAllTypes::NestedMessage();
979   heap_submessage->set_bb(42);
980   r->SetAllocatedMessage(arena1_message, heap_submessage, msg_field);
981   // Should keep same object and add to arena's Own()-list.
982   EXPECT_EQ(heap_submessage, arena1_message->mutable_optional_nested_message());
983   {
984     Arena arena2;
985     TestAllTypes::NestedMessage* arena2_submessage =
986         Arena::Create<TestAllTypes::NestedMessage>(&arena2);
987     arena2_submessage->set_bb(42);
988 #if GTEST_HAS_DEATH_TEST
989     EXPECT_DEBUG_DEATH(
990         r->SetAllocatedMessage(arena1_message, arena2_submessage, msg_field),
991         "GetArena");
992 #endif
993     EXPECT_NE(arena2_submessage,
994               arena1_message->mutable_optional_nested_message());
995   }
996 
997   TestAllTypes::NestedMessage* arena1_submessage =
998       Arena::Create<TestAllTypes::NestedMessage>(&arena1);
999   arena1_submessage->set_bb(42);
1000   TestAllTypes* heap_message = new TestAllTypes;
1001 #if GTEST_HAS_DEATH_TEST
1002   EXPECT_DEBUG_DEATH(
1003       r->SetAllocatedMessage(heap_message, arena1_submessage, msg_field),
1004       "GetArena");
1005 #endif
1006   EXPECT_NE(arena1_submessage, heap_message->mutable_optional_nested_message());
1007   delete heap_message;
1008 }
1009 
TEST(ArenaTest,UnsafeArenaSetAllocatedAcrossArenasWithReflection)1010 TEST(ArenaTest, UnsafeArenaSetAllocatedAcrossArenasWithReflection) {
1011   // Same as above, with reflection.
1012   Arena arena1;
1013   TestAllTypes* arena1_message = Arena::Create<TestAllTypes>(&arena1);
1014   const Reflection* r = arena1_message->GetReflection();
1015   const Descriptor* d = arena1_message->GetDescriptor();
1016   const FieldDescriptor* msg_field =
1017       d->FindFieldByName("optional_nested_message");
1018   {
1019     Arena arena2;
1020     TestAllTypes::NestedMessage* arena2_submessage =
1021         Arena::Create<TestAllTypes::NestedMessage>(&arena2);
1022     arena2_submessage->set_bb(42);
1023     r->UnsafeArenaSetAllocatedMessage(arena1_message, arena2_submessage,
1024                                       msg_field);
1025     EXPECT_EQ(arena2_submessage,
1026               arena1_message->mutable_optional_nested_message());
1027     EXPECT_EQ(arena2_submessage,
1028               arena1_message->unsafe_arena_release_optional_nested_message());
1029   }
1030 
1031   TestAllTypes::NestedMessage* arena1_submessage =
1032       Arena::Create<TestAllTypes::NestedMessage>(&arena1);
1033   arena1_submessage->set_bb(42);
1034   TestAllTypes* heap_message = new TestAllTypes;
1035   r->UnsafeArenaSetAllocatedMessage(heap_message, arena1_submessage, msg_field);
1036   EXPECT_EQ(arena1_submessage, heap_message->mutable_optional_nested_message());
1037   EXPECT_EQ(arena1_submessage,
1038             heap_message->unsafe_arena_release_optional_nested_message());
1039   delete heap_message;
1040 }
1041 
TEST(ArenaTest,AddAllocatedWithReflection)1042 TEST(ArenaTest, AddAllocatedWithReflection) {
1043   Arena arena1;
1044   ArenaMessage* arena1_message = Arena::Create<ArenaMessage>(&arena1);
1045   const Reflection* r = arena1_message->GetReflection();
1046   const Descriptor* d = arena1_message->GetDescriptor();
1047   // Message with cc_enable_arenas = true;
1048   const FieldDescriptor* fd = d->FindFieldByName("repeated_nested_message");
1049   r->AddMessage(arena1_message, fd);
1050   r->AddMessage(arena1_message, fd);
1051   r->AddMessage(arena1_message, fd);
1052   EXPECT_EQ(3, r->FieldSize(*arena1_message, fd));
1053 }
1054 
TEST(ArenaTest,RepeatedPtrFieldAddClearedTest)1055 TEST(ArenaTest, RepeatedPtrFieldAddClearedTest) {
1056   {
1057     RepeatedPtrField<TestAllTypes> repeated_field;
1058     EXPECT_TRUE(repeated_field.empty());
1059     EXPECT_EQ(0, repeated_field.size());
1060     // Ownership is passed to repeated_field.
1061     TestAllTypes* cleared = new TestAllTypes();
1062     repeated_field.AddAllocated(cleared);
1063     EXPECT_FALSE(repeated_field.empty());
1064     EXPECT_EQ(1, repeated_field.size());
1065   }
1066 }
1067 
TEST(ArenaTest,AddAllocatedToRepeatedField)1068 TEST(ArenaTest, AddAllocatedToRepeatedField) {
1069   // Heap->arena case.
1070   Arena arena1;
1071   TestAllTypes* arena1_message = Arena::Create<TestAllTypes>(&arena1);
1072   for (int i = 0; i < 10; i++) {
1073     TestAllTypes::NestedMessage* heap_submessage =
1074         new TestAllTypes::NestedMessage();
1075     heap_submessage->set_bb(42);
1076     arena1_message->mutable_repeated_nested_message()->AddAllocated(
1077         heap_submessage);
1078     // Should not copy object -- will use arena_->Own().
1079     EXPECT_EQ(heap_submessage, &arena1_message->repeated_nested_message(i));
1080     EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
1081   }
1082 
1083   // Arena1->Arena2 case.
1084   arena1_message->Clear();
1085   for (int i = 0; i < 10; i++) {
1086     Arena arena2;
1087     TestAllTypes::NestedMessage* arena2_submessage =
1088         Arena::Create<TestAllTypes::NestedMessage>(&arena2);
1089     arena2_submessage->set_bb(42);
1090     arena1_message->mutable_repeated_nested_message()->AddAllocated(
1091         arena2_submessage);
1092     ASSERT_THAT(arena1_message->repeated_nested_message(), testing::SizeIs(1));
1093     EXPECT_EQ(
1094         arena1_message->mutable_repeated_nested_message()->at(0).GetArena(),
1095         &arena1);
1096     arena1_message->clear_repeated_nested_message();
1097   }
1098 
1099   // Arena->heap case.
1100   TestAllTypes* heap_message = new TestAllTypes;
1101   for (int i = 0; i < 10; i++) {
1102     Arena arena2;
1103     TestAllTypes::NestedMessage* arena2_submessage =
1104         Arena::Create<TestAllTypes::NestedMessage>(&arena2);
1105     arena2_submessage->set_bb(42);
1106     heap_message->mutable_repeated_nested_message()->AddAllocated(
1107         arena2_submessage);
1108     ASSERT_THAT(heap_message->repeated_nested_message(), testing::SizeIs(1));
1109     EXPECT_EQ(heap_message->mutable_repeated_nested_message()->at(0).GetArena(),
1110               nullptr);
1111     heap_message->clear_repeated_nested_message();
1112   }
1113   delete heap_message;
1114 
1115   // Heap->arena case for strings (which are not arena-allocated).
1116   arena1_message->Clear();
1117   for (int i = 0; i < 10; i++) {
1118     std::string* s = new std::string("Test");
1119     arena1_message->mutable_repeated_string()->AddAllocated(s);
1120     // Should not copy.
1121     EXPECT_EQ(s, &arena1_message->repeated_string(i));
1122     EXPECT_EQ("Test", arena1_message->repeated_string(i));
1123   }
1124 }
1125 
TEST(ArenaTest,UnsafeArenaAddAllocatedToRepeatedField)1126 TEST(ArenaTest, UnsafeArenaAddAllocatedToRepeatedField) {
1127   // Heap->arena case.
1128   Arena arena1;
1129   TestAllTypes* arena1_message = Arena::Create<TestAllTypes>(&arena1);
1130   {
1131     auto* heap_submessage = new TestAllTypes::NestedMessage;
1132     arena1_message->mutable_repeated_nested_message()->UnsafeArenaAddAllocated(
1133         heap_submessage);
1134     // Should not copy object.
1135     EXPECT_EQ(heap_submessage, &arena1_message->repeated_nested_message(0));
1136     EXPECT_EQ(heap_submessage, arena1_message->mutable_repeated_nested_message()
1137                                    ->UnsafeArenaReleaseLast());
1138     delete heap_submessage;
1139   }
1140 
1141   // Arena1->Arena2 case.
1142   arena1_message->Clear();
1143   {
1144     Arena arena2;
1145     TestAllTypes::NestedMessage* arena2_submessage =
1146         Arena::Create<TestAllTypes::NestedMessage>(&arena2);
1147     arena2_submessage->set_bb(42);
1148     arena1_message->mutable_repeated_nested_message()->UnsafeArenaAddAllocated(
1149         arena2_submessage);
1150     // Should own object.
1151     EXPECT_EQ(arena2_submessage, &arena1_message->repeated_nested_message(0));
1152     EXPECT_EQ(arena2_submessage,
1153               arena1_message->mutable_repeated_nested_message()
1154                   ->UnsafeArenaReleaseLast());
1155   }
1156 
1157   // Arena->heap case.
1158   TestAllTypes* heap_message = new TestAllTypes;
1159   {
1160     Arena arena2;
1161     TestAllTypes::NestedMessage* arena2_submessage =
1162         Arena::Create<TestAllTypes::NestedMessage>(&arena2);
1163     arena2_submessage->set_bb(42);
1164     heap_message->mutable_repeated_nested_message()->UnsafeArenaAddAllocated(
1165         arena2_submessage);
1166     // Should own object.
1167     EXPECT_EQ(arena2_submessage, &heap_message->repeated_nested_message(0));
1168     EXPECT_EQ(arena2_submessage, heap_message->mutable_repeated_nested_message()
1169                                      ->UnsafeArenaReleaseLast());
1170   }
1171   delete heap_message;
1172 
1173   // Heap->arena case for strings (which are not arena-allocated).
1174   arena1_message->Clear();
1175   {
1176     std::string* s = new std::string("Test");
1177     arena1_message->mutable_repeated_string()->UnsafeArenaAddAllocated(s);
1178     // Should not copy.
1179     EXPECT_EQ(s, &arena1_message->repeated_string(0));
1180     EXPECT_EQ("Test", arena1_message->repeated_string(0));
1181     delete arena1_message->mutable_repeated_string()->UnsafeArenaReleaseLast();
1182   }
1183 }
1184 
TEST(ArenaTest,AddAllocatedToRepeatedFieldViaReflection)1185 TEST(ArenaTest, AddAllocatedToRepeatedFieldViaReflection) {
1186   // Heap->arena case.
1187   Arena arena1;
1188   TestAllTypes* arena1_message = Arena::Create<TestAllTypes>(&arena1);
1189   const Reflection* r = arena1_message->GetReflection();
1190   const Descriptor* d = arena1_message->GetDescriptor();
1191   const FieldDescriptor* fd = d->FindFieldByName("repeated_nested_message");
1192   for (int i = 0; i < 10; i++) {
1193     TestAllTypes::NestedMessage* heap_submessage =
1194         new TestAllTypes::NestedMessage;
1195     heap_submessage->set_bb(42);
1196     r->AddAllocatedMessage(arena1_message, fd, heap_submessage);
1197     // Should not copy object -- will use arena_->Own().
1198     EXPECT_EQ(heap_submessage, &arena1_message->repeated_nested_message(i));
1199     EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
1200   }
1201 
1202   // Arena1->Arena2 case.
1203   arena1_message->Clear();
1204   for (int i = 0; i < 10; i++) {
1205     Arena arena2;
1206     TestAllTypes::NestedMessage* arena2_submessage =
1207         Arena::Create<TestAllTypes::NestedMessage>(&arena2);
1208     arena2_submessage->set_bb(42);
1209     r->AddAllocatedMessage(arena1_message, fd, arena2_submessage);
1210     ASSERT_THAT(arena1_message->repeated_nested_message(), testing::SizeIs(1));
1211     EXPECT_EQ(
1212         arena1_message->mutable_repeated_nested_message()->at(0).GetArena(),
1213         &arena1);
1214     arena1_message->clear_repeated_nested_message();
1215   }
1216 
1217   // Arena->heap case.
1218   TestAllTypes* heap_message = new TestAllTypes;
1219   for (int i = 0; i < 10; i++) {
1220     Arena arena2;
1221     TestAllTypes::NestedMessage* arena2_submessage =
1222         Arena::Create<TestAllTypes::NestedMessage>(&arena2);
1223     arena2_submessage->set_bb(42);
1224     r->AddAllocatedMessage(heap_message, fd, arena2_submessage);
1225     ASSERT_THAT(heap_message->repeated_nested_message(), testing::SizeIs(1));
1226     EXPECT_EQ(heap_message->mutable_repeated_nested_message()->at(0).GetArena(),
1227               nullptr);
1228     heap_message->clear_repeated_nested_message();
1229   }
1230   delete heap_message;
1231 }
1232 
TEST(ArenaTest,ReleaseLastRepeatedField)1233 TEST(ArenaTest, ReleaseLastRepeatedField) {
1234   // Release from arena-allocated repeated field and ensure that returned object
1235   // is heap-allocated.
1236   Arena arena;
1237   TestAllTypes* arena_message = Arena::Create<TestAllTypes>(&arena);
1238   for (int i = 0; i < 10; i++) {
1239     TestAllTypes::NestedMessage* nested =
1240         Arena::Create<TestAllTypes::NestedMessage>(&arena);
1241     nested->set_bb(42);
1242     arena_message->mutable_repeated_nested_message()->AddAllocated(nested);
1243   }
1244 
1245   for (int i = 0; i < 10; i++) {
1246     const TestAllTypes::NestedMessage* orig_submessage =
1247         &arena_message->repeated_nested_message(10 - 1 - i);  // last element
1248     TestAllTypes::NestedMessage* released =
1249         arena_message->mutable_repeated_nested_message()->ReleaseLast();
1250     EXPECT_NE(released, orig_submessage);
1251     EXPECT_EQ(42, released->bb());
1252     delete released;
1253   }
1254 
1255   // Test UnsafeArenaReleaseLast().
1256   for (int i = 0; i < 10; i++) {
1257     TestAllTypes::NestedMessage* nested =
1258         Arena::Create<TestAllTypes::NestedMessage>(&arena);
1259     nested->set_bb(42);
1260     arena_message->mutable_repeated_nested_message()->AddAllocated(nested);
1261   }
1262 
1263   for (int i = 0; i < 10; i++) {
1264     const TestAllTypes::NestedMessage* orig_submessage =
1265         &arena_message->repeated_nested_message(10 - 1 - i);  // last element
1266     TestAllTypes::NestedMessage* released =
1267         arena_message->mutable_repeated_nested_message()
1268             ->UnsafeArenaReleaseLast();
1269     EXPECT_EQ(released, orig_submessage);
1270     EXPECT_EQ(42, released->bb());
1271     // no delete -- |released| is on the arena.
1272   }
1273 
1274   // Test string case as well. ReleaseLast() in this case must copy the
1275   // string, even though it was originally heap-allocated and its pointer
1276   // was simply appended to the repeated field's internal vector, because the
1277   // string was placed on the arena's destructor list and cannot be removed
1278   // from that list (so the arena permanently owns the original instance).
1279   arena_message->Clear();
1280   for (int i = 0; i < 10; i++) {
1281     std::string* s = new std::string("Test");
1282     arena_message->mutable_repeated_string()->AddAllocated(s);
1283   }
1284   for (int i = 0; i < 10; i++) {
1285     const std::string* orig_element =
1286         &arena_message->repeated_string(10 - 1 - i);
1287     std::string* released =
1288         arena_message->mutable_repeated_string()->ReleaseLast();
1289     EXPECT_NE(released, orig_element);
1290     EXPECT_EQ("Test", *released);
1291     delete released;
1292   }
1293 }
1294 
TEST(ArenaTest,UnsafeArenaAddAllocated)1295 TEST(ArenaTest, UnsafeArenaAddAllocated) {
1296   Arena arena;
1297   TestAllTypes* message = Arena::Create<TestAllTypes>(&arena);
1298   for (int i = 0; i < 10; i++) {
1299     std::string* arena_string = Arena::Create<std::string>(&arena);
1300     message->mutable_repeated_string()->UnsafeArenaAddAllocated(arena_string);
1301     EXPECT_EQ(arena_string, message->mutable_repeated_string(i));
1302   }
1303 }
1304 
TEST(ArenaTest,OneofMerge)1305 TEST(ArenaTest, OneofMerge) {
1306   Arena arena;
1307   TestAllTypes* message0 = Arena::Create<TestAllTypes>(&arena);
1308   TestAllTypes* message1 = Arena::Create<TestAllTypes>(&arena);
1309 
1310   message0->set_oneof_string("x");
1311   ASSERT_TRUE(message0->has_oneof_string());
1312   message1->set_oneof_string("y");
1313   ASSERT_TRUE(message1->has_oneof_string());
1314   EXPECT_EQ("x", message0->oneof_string());
1315   EXPECT_EQ("y", message1->oneof_string());
1316   message0->MergeFrom(*message1);
1317   EXPECT_EQ("y", message0->oneof_string());
1318   EXPECT_EQ("y", message1->oneof_string());
1319 }
1320 
TEST(ArenaTest,ArenaOneofReflection)1321 TEST(ArenaTest, ArenaOneofReflection) {
1322   Arena arena;
1323   TestAllTypes* message = Arena::Create<TestAllTypes>(&arena);
1324   const Descriptor* desc = message->GetDescriptor();
1325   const Reflection* refl = message->GetReflection();
1326 
1327   const FieldDescriptor* string_field = desc->FindFieldByName("oneof_string");
1328   const FieldDescriptor* msg_field =
1329       desc->FindFieldByName("oneof_nested_message");
1330   const OneofDescriptor* oneof = desc->FindOneofByName("oneof_field");
1331 
1332   refl->SetString(message, string_field, "Test value");
1333   EXPECT_TRUE(refl->HasOneof(*message, oneof));
1334   refl->ClearOneof(message, oneof);
1335   EXPECT_FALSE(refl->HasOneof(*message, oneof));
1336 
1337   Message* submsg = refl->MutableMessage(message, msg_field);
1338   EXPECT_TRUE(refl->HasOneof(*message, oneof));
1339   refl->ClearOneof(message, oneof);
1340   EXPECT_FALSE(refl->HasOneof(*message, oneof));
1341   refl->MutableMessage(message, msg_field);
1342   EXPECT_TRUE(refl->HasOneof(*message, oneof));
1343   submsg = refl->ReleaseMessage(message, msg_field);
1344   EXPECT_FALSE(refl->HasOneof(*message, oneof));
1345   EXPECT_TRUE(submsg->GetArena() == nullptr);
1346   delete submsg;
1347 }
1348 
TestSwapRepeatedField(Arena * arena1,Arena * arena2)1349 void TestSwapRepeatedField(Arena* arena1, Arena* arena2) {
1350   // Test "safe" (copying) semantics for direct Swap() on RepeatedPtrField
1351   // between arenas.
1352   RepeatedPtrField<TestAllTypes> field1(arena1);
1353   RepeatedPtrField<TestAllTypes> field2(arena2);
1354   for (int i = 0; i < 10; i++) {
1355     TestAllTypes* t = Arena::Create<TestAllTypes>(arena1);
1356     t->set_optional_string("field1");
1357     t->set_optional_int32(i);
1358     if (arena1 != nullptr) {
1359       field1.UnsafeArenaAddAllocated(t);
1360     } else {
1361       field1.AddAllocated(t);
1362     }
1363   }
1364   for (int i = 0; i < 5; i++) {
1365     TestAllTypes* t = Arena::Create<TestAllTypes>(arena2);
1366     t->set_optional_string("field2");
1367     t->set_optional_int32(i);
1368     if (arena2 != nullptr) {
1369       field2.UnsafeArenaAddAllocated(t);
1370     } else {
1371       field2.AddAllocated(t);
1372     }
1373   }
1374   field1.Swap(&field2);
1375   EXPECT_EQ(5, field1.size());
1376   EXPECT_EQ(10, field2.size());
1377   EXPECT_TRUE(std::string("field1") == field2.Get(0).optional_string());
1378   EXPECT_TRUE(std::string("field2") == field1.Get(0).optional_string());
1379   // Ensure that fields retained their original order:
1380   for (int i = 0; i < field1.size(); i++) {
1381     EXPECT_EQ(i, field1.Get(i).optional_int32());
1382   }
1383   for (int i = 0; i < field2.size(); i++) {
1384     EXPECT_EQ(i, field2.Get(i).optional_int32());
1385   }
1386 }
1387 
TEST(ArenaTest,SwapRepeatedField)1388 TEST(ArenaTest, SwapRepeatedField) {
1389   Arena arena;
1390   TestSwapRepeatedField(&arena, &arena);
1391 }
1392 
TEST(ArenaTest,SwapRepeatedFieldWithDifferentArenas)1393 TEST(ArenaTest, SwapRepeatedFieldWithDifferentArenas) {
1394   Arena arena1;
1395   Arena arena2;
1396   TestSwapRepeatedField(&arena1, &arena2);
1397 }
1398 
TEST(ArenaTest,SwapRepeatedFieldWithNoArenaOnRightHandSide)1399 TEST(ArenaTest, SwapRepeatedFieldWithNoArenaOnRightHandSide) {
1400   Arena arena;
1401   TestSwapRepeatedField(&arena, nullptr);
1402 }
1403 
TEST(ArenaTest,SwapRepeatedFieldWithNoArenaOnLeftHandSide)1404 TEST(ArenaTest, SwapRepeatedFieldWithNoArenaOnLeftHandSide) {
1405   Arena arena;
1406   TestSwapRepeatedField(nullptr, &arena);
1407 }
1408 
TEST(ArenaTest,ExtensionsOnArena)1409 TEST(ArenaTest, ExtensionsOnArena) {
1410   Arena arena;
1411   // Ensure no leaks.
1412   TestAllExtensions* message_ext = Arena::Create<TestAllExtensions>(&arena);
1413   message_ext->SetExtension(protobuf_unittest::optional_int32_extension, 42);
1414   message_ext->SetExtension(protobuf_unittest::optional_string_extension,
1415                             std::string("test"));
1416   message_ext
1417       ->MutableExtension(protobuf_unittest::optional_nested_message_extension)
1418       ->set_bb(42);
1419 }
1420 
TEST(ArenaTest,RepeatedFieldOnArena)1421 TEST(ArenaTest, RepeatedFieldOnArena) {
1422   // Preallocate an initial arena block to avoid mallocs during hooked region.
1423   std::vector<char> arena_block(1024 * 1024);
1424   Arena arena(arena_block.data(), arena_block.size());
1425   const size_t initial_allocated_size = arena.SpaceAllocated();
1426 
1427   {
1428     // Fill some repeated fields on the arena to test for leaks. Also that the
1429     // newly allocated memory is approximately the size of the cleanups for the
1430     // repeated messages.
1431     RepeatedField<int32_t> repeated_int32(&arena);
1432     RepeatedPtrField<TestAllTypes> repeated_message(&arena);
1433     for (int i = 0; i < 100; i++) {
1434       repeated_int32.Add(42);
1435       repeated_message.Add()->set_optional_int32(42);
1436       EXPECT_EQ(&arena, repeated_message.Get(0).GetArena());
1437       const TestAllTypes* msg_in_repeated_field = &repeated_message.Get(0);
1438       TestAllTypes* msg = repeated_message.UnsafeArenaReleaseLast();
1439       EXPECT_EQ(msg_in_repeated_field, msg);
1440     }
1441 
1442     // UnsafeArenaExtractSubrange (i) should not leak and (ii) should return
1443     // on-arena pointers.
1444     for (int i = 0; i < 10; i++) {
1445       repeated_message.Add()->set_optional_int32(42);
1446     }
1447     TestAllTypes* extracted_messages[5];
1448     repeated_message.UnsafeArenaExtractSubrange(0, 5, extracted_messages);
1449     EXPECT_EQ(&arena, repeated_message.Get(0).GetArena());
1450     EXPECT_EQ(5, repeated_message.size());
1451     // Upper bound of the size of the cleanups of new repeated messages.
1452     const size_t upperbound_cleanup_size =
1453         2 * 110 * sizeof(internal::cleanup::CleanupNode);
1454     EXPECT_GT(initial_allocated_size + upperbound_cleanup_size,
1455               arena.SpaceAllocated());
1456   }
1457 
1458   // Now test ExtractSubrange's copying semantics.
1459   {
1460     RepeatedPtrField<TestAllTypes> repeated_message(&arena);
1461     for (int i = 0; i < 100; i++) {
1462       repeated_message.Add()->set_optional_int32(42);
1463     }
1464 
1465     TestAllTypes* extracted_messages[5];
1466     // ExtractSubrange should copy to the heap.
1467     repeated_message.ExtractSubrange(0, 5, extracted_messages);
1468     EXPECT_EQ(nullptr, extracted_messages[0]->GetArena());
1469     // We need to free the heap-allocated messages to prevent a leak.
1470     for (int i = 0; i < 5; i++) {
1471       delete extracted_messages[i];
1472       extracted_messages[i] = nullptr;
1473     }
1474   }
1475 
1476   // Now check that we can create RepeatedFields/RepeatedPtrFields themselves on
1477   // the arena. They have the necessary type traits so that they can behave like
1478   // messages in this way. This is useful for higher-level generic templated
1479   // code that may allocate messages or repeated fields of messages on an arena.
1480   {
1481     RepeatedPtrField<TestAllTypes>* repeated_ptr_on_arena =
1482         Arena::Create<RepeatedPtrField<TestAllTypes>>(&arena);
1483     for (int i = 0; i < 10; i++) {
1484       // Add some elements and let the leak-checker ensure that everything is
1485       // freed.
1486       repeated_ptr_on_arena->Add();
1487     }
1488 
1489     RepeatedField<int>* repeated_int_on_arena =
1490         Arena::Create<RepeatedField<int>>(&arena);
1491     for (int i = 0; i < 100; i++) {
1492       repeated_int_on_arena->Add(i);
1493     }
1494 
1495   }
1496 
1497   arena.Reset();
1498 }
1499 
1500 
1501 #if PROTOBUF_RTTI
TEST(ArenaTest,MutableMessageReflection)1502 TEST(ArenaTest, MutableMessageReflection) {
1503   Arena arena;
1504   TestAllTypes* message = Arena::Create<TestAllTypes>(&arena);
1505   const Reflection* r = message->GetReflection();
1506   const Descriptor* d = message->GetDescriptor();
1507   const FieldDescriptor* field = d->FindFieldByName("optional_nested_message");
1508   TestAllTypes::NestedMessage* submessage =
1509       DownCastMessage<TestAllTypes::NestedMessage>(
1510           r->MutableMessage(message, field));
1511   TestAllTypes::NestedMessage* submessage_expected =
1512       message->mutable_optional_nested_message();
1513 
1514   EXPECT_EQ(submessage_expected, submessage);
1515   EXPECT_EQ(&arena, submessage->GetArena());
1516 
1517   const FieldDescriptor* oneof_field =
1518       d->FindFieldByName("oneof_nested_message");
1519   submessage = DownCastMessage<TestAllTypes::NestedMessage>(
1520       r->MutableMessage(message, oneof_field));
1521   submessage_expected = message->mutable_oneof_nested_message();
1522 
1523   EXPECT_EQ(submessage_expected, submessage);
1524   EXPECT_EQ(&arena, submessage->GetArena());
1525 }
1526 #endif  // PROTOBUF_RTTI
1527 
1528 
TEST(ArenaTest,ClearOneofMessageOnArena)1529 TEST(ArenaTest, ClearOneofMessageOnArena) {
1530   if (!internal::DebugHardenClearOneofMessageOnArena()) {
1531     GTEST_SKIP() << "arena allocated oneof message fields are not hardened.";
1532   }
1533 
1534   Arena arena;
1535   auto* message = Arena::Create<unittest::TestOneof2>(&arena);
1536   // Intentionally nested to force poisoning recursively to catch the access.
1537   auto* child =
1538       message->mutable_foo_message()->mutable_child()->mutable_child();
1539   child->set_moo_int(100);
1540   message->clear_foo_message();
1541 
1542 #ifndef PROTOBUF_ASAN
1543   EXPECT_NE(child->moo_int(), 100);
1544 #else
1545 #if GTEST_HAS_DEATH_TEST && defined(__cpp_if_constexpr)
1546   EXPECT_DEATH(EXPECT_EQ(child->moo_int(), 0), "use-after-poison");
1547 #endif
1548 #endif
1549 }
1550 
TEST(ArenaTest,CopyValuesWithinOneof)1551 TEST(ArenaTest, CopyValuesWithinOneof) {
1552   if (!internal::DebugHardenClearOneofMessageOnArena()) {
1553     GTEST_SKIP() << "arena allocated oneof message fields are not hardened.";
1554   }
1555 
1556   Arena arena;
1557   auto* message = Arena::Create<unittest::TestOneof>(&arena);
1558   auto* foo = message->mutable_foogroup();
1559   foo->set_a(100);
1560   foo->set_b("hello world");
1561   message->set_foo_string(message->foogroup().b());
1562 
1563   // As a debug hardening measure, `set_foo_string` would clear `foo` in
1564   // (!NDEBUG && !ASAN) and the copy wouldn't work.
1565   EXPECT_TRUE(message->foo_string().empty()) << message->foo_string();
1566 }
1567 
FillArenaAwareFields(TestAllTypes * message)1568 void FillArenaAwareFields(TestAllTypes* message) {
1569   std::string test_string = "hello world";
1570   message->set_optional_int32(42);
1571   message->set_optional_string(test_string);
1572   message->set_optional_bytes(test_string);
1573   message->mutable_optional_nested_message()->set_bb(42);
1574 
1575   message->set_oneof_uint32(42);
1576   message->mutable_oneof_nested_message()->set_bb(42);
1577   message->set_oneof_string(test_string);
1578   message->set_oneof_bytes(test_string);
1579 
1580   message->add_repeated_int32(42);
1581   // No repeated string: not yet arena-aware.
1582   message->add_repeated_nested_message()->set_bb(42);
1583   message->mutable_optional_lazy_message()->set_bb(42);
1584 }
1585 
1586 // Test: no allocations occur on heap while touching all supported field types.
TEST(ArenaTest,NoHeapAllocationsTest)1587 TEST(ArenaTest, NoHeapAllocationsTest) {
1588   if (internal::DebugHardenClearOneofMessageOnArena()) {
1589     GTEST_SKIP() << "debug hardening may cause heap allocation.";
1590   }
1591 
1592   // Allocate a large initial block to avoid mallocs during hooked test.
1593   std::vector<char> arena_block(128 * 1024);
1594   ArenaOptions options;
1595   options.initial_block = &arena_block[0];
1596   options.initial_block_size = arena_block.size();
1597   Arena arena(options);
1598 
1599   {
1600     // We need to call Arena::Create before NoHeapChecker because the ArenaDtor
1601     // allocates a new cleanup chunk.
1602     TestAllTypes* message = Arena::Create<TestAllTypes>(&arena);
1603 
1604 
1605     FillArenaAwareFields(message);
1606   }
1607 
1608   arena.Reset();
1609 }
1610 
1611 #if PROTOBUF_RTTI
1612 // Test construction on an arena via generic MessageLite interface. We should be
1613 // able to successfully deserialize on the arena without incurring heap
1614 // allocations, i.e., everything should still be arena-allocation-aware.
TEST(ArenaTest,MessageLiteOnArena)1615 TEST(ArenaTest, MessageLiteOnArena) {
1616   std::vector<char> arena_block(128 * 1024);
1617   ArenaOptions options;
1618   options.initial_block = &arena_block[0];
1619   options.initial_block_size = arena_block.size();
1620   Arena arena(options);
1621   const MessageLite* prototype = &TestAllTypes::default_instance();
1622 
1623   TestAllTypes initial_message;
1624   FillArenaAwareFields(&initial_message);
1625   std::string serialized;
1626   initial_message.SerializeToString(&serialized);
1627 
1628   {
1629     MessageLite* generic_message = prototype->New(&arena);
1630 
1631 
1632     EXPECT_TRUE(generic_message != nullptr);
1633     EXPECT_EQ(&arena, generic_message->GetArena());
1634     EXPECT_TRUE(generic_message->ParseFromString(serialized));
1635     TestAllTypes* deserialized = static_cast<TestAllTypes*>(generic_message);
1636     EXPECT_EQ(42, deserialized->optional_int32());
1637   }
1638 
1639   arena.Reset();
1640 }
1641 #endif  // PROTOBUF_RTTI
1642 
1643 // Align n to next multiple of 8
Align8(uint64_t n)1644 uint64_t Align8(uint64_t n) { return (n + 7) & -8; }
1645 
TEST(ArenaTest,SpaceAllocated_and_Used)1646 TEST(ArenaTest, SpaceAllocated_and_Used) {
1647   Arena arena_1;
1648   EXPECT_EQ(0, arena_1.SpaceAllocated());
1649   EXPECT_EQ(0, arena_1.SpaceUsed());
1650   EXPECT_EQ(0, arena_1.Reset());
1651   Arena::CreateArray<char>(&arena_1, 320);
1652   // Arena will allocate slightly more than 320 for the block headers.
1653   EXPECT_LE(320, arena_1.SpaceAllocated());
1654   EXPECT_EQ(Align8(320), arena_1.SpaceUsed());
1655   EXPECT_LE(320, arena_1.Reset());
1656 
1657   // Test with initial block.
1658   std::vector<char> arena_block(1024);
1659   ArenaOptions options;
1660   options.start_block_size = 256;
1661   options.max_block_size = 8192;
1662   options.initial_block = &arena_block[0];
1663   options.initial_block_size = arena_block.size();
1664   Arena arena_2(options);
1665   EXPECT_EQ(1024, arena_2.SpaceAllocated());
1666   EXPECT_EQ(0, arena_2.SpaceUsed());
1667   EXPECT_EQ(1024, arena_2.Reset());
1668   Arena::CreateArray<char>(&arena_2, 55);
1669   EXPECT_EQ(1024, arena_2.SpaceAllocated());
1670   EXPECT_EQ(Align8(55), arena_2.SpaceUsed());
1671   EXPECT_EQ(1024, arena_2.Reset());
1672 }
1673 
1674 namespace {
1675 
VerifyArenaOverhead(Arena & arena,size_t overhead)1676 void VerifyArenaOverhead(Arena& arena, size_t overhead) {
1677   EXPECT_EQ(0, arena.SpaceAllocated());
1678 
1679   // Allocate a tiny block and record the allocation size.
1680   constexpr size_t kTinySize = 8;
1681   Arena::CreateArray<char>(&arena, kTinySize);
1682   uint64_t space_allocated = arena.SpaceAllocated();
1683 
1684   // Next allocation expects to fill up the block but no new block.
1685   uint64_t next_size = space_allocated - overhead - kTinySize;
1686   Arena::CreateArray<char>(&arena, next_size);
1687 
1688   EXPECT_EQ(space_allocated, arena.SpaceAllocated());
1689 }
1690 
1691 }  // namespace
1692 
TEST(ArenaTest,FirstArenaOverhead)1693 TEST(ArenaTest, FirstArenaOverhead) {
1694   Arena arena;
1695   VerifyArenaOverhead(arena, internal::SerialArena::kBlockHeaderSize);
1696 }
1697 
1698 
TEST(ArenaTest,StartingBlockSize)1699 TEST(ArenaTest, StartingBlockSize) {
1700   Arena default_arena;
1701   EXPECT_EQ(0, default_arena.SpaceAllocated());
1702 
1703   // Allocate something to get starting block size.
1704   Arena::CreateArray<char>(&default_arena, 1);
1705   ArenaOptions options;
1706   // First block size should be the default starting block size.
1707   EXPECT_EQ(default_arena.SpaceAllocated(), options.start_block_size);
1708 
1709   // Use a custom starting block size.
1710   options.start_block_size *= 2;
1711   Arena custom_arena(options);
1712   Arena::CreateArray<char>(&custom_arena, 1);
1713   EXPECT_EQ(custom_arena.SpaceAllocated(), options.start_block_size);
1714 }
1715 
TEST(ArenaTest,BlockSizeDoubling)1716 TEST(ArenaTest, BlockSizeDoubling) {
1717   Arena arena;
1718   EXPECT_EQ(0, arena.SpaceUsed());
1719   EXPECT_EQ(0, arena.SpaceAllocated());
1720 
1721   // Allocate something to get initial block size.
1722   Arena::CreateArray<char>(&arena, 1);
1723   auto first_block_size = arena.SpaceAllocated();
1724 
1725   // Keep allocating until space used increases.
1726   while (arena.SpaceAllocated() == first_block_size) {
1727     Arena::CreateArray<char>(&arena, 1);
1728   }
1729   ASSERT_GT(arena.SpaceAllocated(), first_block_size);
1730   auto second_block_size = (arena.SpaceAllocated() - first_block_size);
1731 
1732   EXPECT_GE(second_block_size, 2*first_block_size);
1733 }
1734 
TEST(ArenaTest,Alignment)1735 TEST(ArenaTest, Alignment) {
1736   Arena arena;
1737   for (int i = 0; i < 200; i++) {
1738     void* p = Arena::CreateArray<char>(&arena, i);
1739     ABSL_CHECK_EQ(reinterpret_cast<uintptr_t>(p) % 8, 0u) << i << ": " << p;
1740   }
1741 }
1742 
TEST(ArenaTest,BlockSizeSmallerThanAllocation)1743 TEST(ArenaTest, BlockSizeSmallerThanAllocation) {
1744   for (size_t i = 0; i <= 8; ++i) {
1745     ArenaOptions opt;
1746     opt.start_block_size = opt.max_block_size = i;
1747     Arena arena(opt);
1748 
1749     *Arena::Create<int64_t>(&arena) = 42;
1750     EXPECT_GE(arena.SpaceAllocated(), 8);
1751     EXPECT_EQ(8, arena.SpaceUsed());
1752 
1753     *Arena::Create<int64_t>(&arena) = 42;
1754     EXPECT_GE(arena.SpaceAllocated(), 16);
1755     EXPECT_EQ(16, arena.SpaceUsed());
1756   }
1757 }
1758 
TEST(ArenaTest,GetArenaShouldReturnTheArenaForArenaAllocatedMessages)1759 TEST(ArenaTest, GetArenaShouldReturnTheArenaForArenaAllocatedMessages) {
1760   Arena arena;
1761   ArenaMessage* message = Arena::Create<ArenaMessage>(&arena);
1762   const ArenaMessage* const_pointer_to_message = message;
1763   EXPECT_EQ(&arena, message->GetArena());
1764   EXPECT_EQ(&arena, const_pointer_to_message->GetArena());
1765 
1766   // Test that the Message* / MessageLite* specialization SFINAE works.
1767   const Message* const_pointer_to_message_type = message;
1768   EXPECT_EQ(&arena, const_pointer_to_message_type->GetArena());
1769   const MessageLite* const_pointer_to_message_lite_type = message;
1770   EXPECT_EQ(&arena, const_pointer_to_message_lite_type->GetArena());
1771 }
1772 
TEST(ArenaTest,GetArenaShouldReturnNullForNonArenaAllocatedMessages)1773 TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaAllocatedMessages) {
1774   ArenaMessage message;
1775   const ArenaMessage* const_pointer_to_message = &message;
1776   EXPECT_EQ(nullptr, message.GetArena());
1777   EXPECT_EQ(nullptr, const_pointer_to_message->GetArena());
1778 }
1779 
TEST(ArenaTest,AddCleanup)1780 TEST(ArenaTest, AddCleanup) {
1781   Arena arena;
1782   for (int i = 0; i < 100; i++) {
1783     arena.Own(new int);
1784   }
1785 }
1786 
1787 struct DestroyOrderRecorder {
1788   std::vector<int>* destroy_order;
1789   int i;
1790 
DestroyOrderRecordergoogle::protobuf::DestroyOrderRecorder1791   DestroyOrderRecorder(std::vector<int>* destroy_order, int i)
1792       : destroy_order(destroy_order), i(i) {}
~DestroyOrderRecordergoogle::protobuf::DestroyOrderRecorder1793   ~DestroyOrderRecorder() { destroy_order->push_back(i); }
1794 };
1795 
1796 // TODO: we do not guarantee this behavior, but some users rely on
1797 // it. We need to decide whether we want to guarantee this. In the meantime,
1798 // user code should avoid adding new dependencies on this.
1799 // Tests that when using an Arena from a single thread, objects are destroyed in
1800 // reverse order from construction.
TEST(ArenaTest,CleanupDestructionOrder)1801 TEST(ArenaTest, CleanupDestructionOrder) {
1802   std::vector<int> destroy_order;
1803   {
1804     Arena arena;
1805     for (int i = 0; i < 3; i++) {
1806       Arena::Create<DestroyOrderRecorder>(&arena, &destroy_order, i);
1807     }
1808   }
1809   EXPECT_THAT(destroy_order, testing::ElementsAre(2, 1, 0));
1810 }
1811 
TEST(ArenaTest,SpaceReuseForArraysSizeChecks)1812 TEST(ArenaTest, SpaceReuseForArraysSizeChecks) {
1813   // Limit to 1<<20 to avoid using too much memory on the test.
1814   for (int i = 0; i < 20; ++i) {
1815     SCOPED_TRACE(i);
1816     Arena arena;
1817     std::vector<void*> pointers;
1818 
1819     const size_t size = 16 << i;
1820 
1821     for (int j = 0; j < 10; ++j) {
1822       pointers.push_back(Arena::CreateArray<char>(&arena, size));
1823     }
1824 
1825     for (void* p : pointers) {
1826       internal::ArenaTestPeer::ReturnArrayMemory(&arena, p, size);
1827     }
1828 
1829     std::vector<void*> second_pointers;
1830     for (int j = 9; j != 0; --j) {
1831       second_pointers.push_back(Arena::CreateArray<char>(&arena, size));
1832     }
1833 
1834     // The arena will give us back the pointers we returned, except the first
1835     // one. That one becomes part of the freelist data structure.
1836     ASSERT_THAT(second_pointers,
1837                 testing::UnorderedElementsAreArray(
1838                     std::vector<void*>(pointers.begin() + 1, pointers.end())));
1839   }
1840 }
1841 
TEST(ArenaTest,SpaceReusePoisonsAndUnpoisonsMemory)1842 TEST(ArenaTest, SpaceReusePoisonsAndUnpoisonsMemory) {
1843 #ifdef PROTOBUF_ASAN
1844   char buf[1024]{};
1845   constexpr int kSize = 32;
1846   {
1847     Arena arena(buf, sizeof(buf));
1848     std::vector<void*> pointers;
1849     for (int i = 0; i < 100; ++i) {
1850       void* p = Arena::CreateArray<char>(&arena, kSize);
1851       // Simulate other ASan client managing shadow memory.
1852       ASAN_POISON_MEMORY_REGION(p, kSize);
1853       ASAN_UNPOISON_MEMORY_REGION(p, kSize - 4);
1854       pointers.push_back(p);
1855     }
1856     for (void* p : pointers) {
1857       internal::ArenaTestPeer::ReturnArrayMemory(&arena, p, kSize);
1858       // The first one is not poisoned because it becomes the freelist.
1859       if (p != pointers[0]) EXPECT_TRUE(__asan_address_is_poisoned(p));
1860     }
1861 
1862     bool found_poison = false;
1863     for (char& c : buf) {
1864       if (__asan_address_is_poisoned(&c)) {
1865         found_poison = true;
1866         break;
1867       }
1868     }
1869     EXPECT_TRUE(found_poison);
1870   }
1871 
1872   // Should not be poisoned after destruction.
1873   for (char& c : buf) {
1874     ASSERT_FALSE(__asan_address_is_poisoned(&c));
1875   }
1876 
1877 #else   // PROTOBUF_ASAN
1878   GTEST_SKIP();
1879 #endif  // PROTOBUF_ASAN
1880 }
1881 
1882 
1883 }  // namespace protobuf
1884 }  // namespace google
1885 
1886 #include "google/protobuf/port_undef.inc"
1887