• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 #include <google/protobuf/arena.h>
32 
33 #include <algorithm>
34 #include <cstddef>
35 #include <cstring>
36 #include <memory>
37 #include <string>
38 #include <type_traits>
39 #include <typeinfo>
40 #include <vector>
41 
42 #include <google/protobuf/stubs/logging.h>
43 #include <google/protobuf/stubs/common.h>
44 #include <google/protobuf/arena_test_util.h>
45 #include <google/protobuf/test_util.h>
46 #include <google/protobuf/unittest.pb.h>
47 #include <google/protobuf/unittest_arena.pb.h>
48 #include <google/protobuf/io/coded_stream.h>
49 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
50 #include <google/protobuf/descriptor.h>
51 #include <google/protobuf/extension_set.h>
52 #include <google/protobuf/message.h>
53 #include <google/protobuf/message_lite.h>
54 #include <google/protobuf/repeated_field.h>
55 #include <google/protobuf/unknown_field_set.h>
56 #include <google/protobuf/wire_format_lite.h>
57 #include <gtest/gtest.h>
58 #include <google/protobuf/stubs/strutil.h>
59 
60 
61 // Must be included last
62 #include <google/protobuf/port_def.inc>
63 
64 using proto2_arena_unittest::ArenaMessage;
65 using protobuf_unittest::TestAllExtensions;
66 using protobuf_unittest::TestAllTypes;
67 using protobuf_unittest::TestEmptyMessage;
68 using protobuf_unittest::TestOneof2;
69 
70 namespace google {
71 namespace protobuf {
72 
73 class Notifier {
74  public:
Notifier()75   Notifier() : count_(0) {}
Notify()76   void Notify() { count_++; }
GetCount()77   int GetCount() { return count_; }
78 
79  private:
80   int count_;
81 };
82 
83 class SimpleDataType {
84  public:
SimpleDataType()85   SimpleDataType() : notifier_(NULL) {}
SetNotifier(Notifier * notifier)86   void SetNotifier(Notifier* notifier) { notifier_ = notifier; }
~SimpleDataType()87   virtual ~SimpleDataType() {
88     if (notifier_ != NULL) {
89       notifier_->Notify();
90     }
91   };
92 
93  private:
94   Notifier* notifier_;
95 };
96 
97 // A simple class that does not allow copying and so cannot be used as a
98 // parameter type without "const &".
99 class PleaseDontCopyMe {
100  public:
PleaseDontCopyMe(int value)101   explicit PleaseDontCopyMe(int value) : value_(value) {}
102 
value() const103   int value() const { return value_; }
104 
105  private:
106   int value_;
107   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PleaseDontCopyMe);
108 };
109 
110 // A class that takes four different types as constructor arguments.
111 class MustBeConstructedWithOneThroughFour {
112  public:
MustBeConstructedWithOneThroughFour(int one,const char * two,const std::string & three,const PleaseDontCopyMe * four)113   MustBeConstructedWithOneThroughFour(int one, const char* two,
114                                       const std::string& three,
115                                       const PleaseDontCopyMe* four)
116       : one_(one), two_(two), three_(three), four_(four) {}
117 
118   int one_;
119   const char* const two_;
120   std::string three_;
121   const PleaseDontCopyMe* four_;
122 
123  private:
124   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MustBeConstructedWithOneThroughFour);
125 };
126 
127 // A class that takes eight different types as constructor arguments.
128 class MustBeConstructedWithOneThroughEight {
129  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)130   MustBeConstructedWithOneThroughEight(int one, const char* two,
131                                        const std::string& three,
132                                        const PleaseDontCopyMe* four, int five,
133                                        const char* six,
134                                        const std::string& seven,
135                                        const std::string& eight)
136       : one_(one),
137         two_(two),
138         three_(three),
139         four_(four),
140         five_(five),
141         six_(six),
142         seven_(seven),
143         eight_(eight) {}
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  private:
155   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MustBeConstructedWithOneThroughEight);
156 };
157 
TEST(ArenaTest,ArenaConstructable)158 TEST(ArenaTest, ArenaConstructable) {
159   EXPECT_TRUE(Arena::is_arena_constructable<TestAllTypes>::type::value);
160   EXPECT_TRUE(Arena::is_arena_constructable<const TestAllTypes>::type::value);
161   EXPECT_FALSE(Arena::is_arena_constructable<Arena>::type::value);
162 }
163 
TEST(ArenaTest,DestructorSkippable)164 TEST(ArenaTest, DestructorSkippable) {
165   EXPECT_TRUE(Arena::is_destructor_skippable<TestAllTypes>::type::value);
166   EXPECT_TRUE(Arena::is_destructor_skippable<const TestAllTypes>::type::value);
167   EXPECT_FALSE(Arena::is_destructor_skippable<Arena>::type::value);
168 }
169 
TEST(ArenaTest,BasicCreate)170 TEST(ArenaTest, BasicCreate) {
171   Arena arena;
172   EXPECT_TRUE(Arena::Create<int32>(&arena) != NULL);
173   EXPECT_TRUE(Arena::Create<int64>(&arena) != NULL);
174   EXPECT_TRUE(Arena::Create<float>(&arena) != NULL);
175   EXPECT_TRUE(Arena::Create<double>(&arena) != NULL);
176   EXPECT_TRUE(Arena::Create<std::string>(&arena) != NULL);
177   arena.Own(new int32);
178   arena.Own(new int64);
179   arena.Own(new float);
180   arena.Own(new double);
181   arena.Own(new std::string);
182   arena.Own<int>(NULL);
183   Notifier notifier;
184   SimpleDataType* data = Arena::Create<SimpleDataType>(&arena);
185   data->SetNotifier(&notifier);
186   data = new SimpleDataType;
187   data->SetNotifier(&notifier);
188   arena.Own(data);
189   arena.Reset();
190   EXPECT_EQ(2, notifier.GetCount());
191 }
192 
TEST(ArenaTest,CreateAndConstCopy)193 TEST(ArenaTest, CreateAndConstCopy) {
194   Arena arena;
195   const std::string s("foo");
196   const std::string* s_copy = Arena::Create<std::string>(&arena, s);
197   EXPECT_TRUE(s_copy != NULL);
198   EXPECT_EQ("foo", s);
199   EXPECT_EQ("foo", *s_copy);
200 }
201 
TEST(ArenaTest,CreateAndNonConstCopy)202 TEST(ArenaTest, CreateAndNonConstCopy) {
203   Arena arena;
204   std::string s("foo");
205   const std::string* s_copy = Arena::Create<std::string>(&arena, s);
206   EXPECT_TRUE(s_copy != NULL);
207   EXPECT_EQ("foo", s);
208   EXPECT_EQ("foo", *s_copy);
209 }
210 
TEST(ArenaTest,CreateAndMove)211 TEST(ArenaTest, CreateAndMove) {
212   Arena arena;
213   std::string s("foo");
214   const std::string* s_move = Arena::Create<std::string>(&arena, std::move(s));
215   EXPECT_TRUE(s_move != NULL);
216   EXPECT_TRUE(s.empty());  // NOLINT
217   EXPECT_EQ("foo", *s_move);
218 }
219 
TEST(ArenaTest,CreateWithFourConstructorArguments)220 TEST(ArenaTest, CreateWithFourConstructorArguments) {
221   Arena arena;
222   const std::string three("3");
223   const PleaseDontCopyMe four(4);
224   const MustBeConstructedWithOneThroughFour* new_object =
225       Arena::Create<MustBeConstructedWithOneThroughFour>(&arena, 1, "2", three,
226                                                          &four);
227   EXPECT_TRUE(new_object != NULL);
228   ASSERT_EQ(1, new_object->one_);
229   ASSERT_STREQ("2", new_object->two_);
230   ASSERT_EQ("3", new_object->three_);
231   ASSERT_EQ(4, new_object->four_->value());
232 }
233 
TEST(ArenaTest,CreateWithEightConstructorArguments)234 TEST(ArenaTest, CreateWithEightConstructorArguments) {
235   Arena arena;
236   const std::string three("3");
237   const PleaseDontCopyMe four(4);
238   const std::string seven("7");
239   const std::string eight("8");
240   const MustBeConstructedWithOneThroughEight* new_object =
241       Arena::Create<MustBeConstructedWithOneThroughEight>(
242           &arena, 1, "2", three, &four, 5, "6", seven, eight);
243   EXPECT_TRUE(new_object != NULL);
244   ASSERT_EQ(1, new_object->one_);
245   ASSERT_STREQ("2", new_object->two_);
246   ASSERT_EQ("3", new_object->three_);
247   ASSERT_EQ(4, new_object->four_->value());
248   ASSERT_EQ(5, new_object->five_);
249   ASSERT_STREQ("6", new_object->six_);
250   ASSERT_EQ("7", new_object->seven_);
251   ASSERT_EQ("8", new_object->eight_);
252 }
253 
254 class PleaseMoveMe {
255  public:
PleaseMoveMe(const std::string & value)256   explicit PleaseMoveMe(const std::string& value) : value_(value) {}
257   PleaseMoveMe(PleaseMoveMe&&) = default;
258   PleaseMoveMe(const PleaseMoveMe&) = delete;
259 
value() const260   const std::string& value() const { return value_; }
261 
262  private:
263   std::string value_;
264 };
265 
TEST(ArenaTest,CreateWithMoveArguments)266 TEST(ArenaTest, CreateWithMoveArguments) {
267   Arena arena;
268   PleaseMoveMe one("1");
269   const PleaseMoveMe* new_object =
270       Arena::Create<PleaseMoveMe>(&arena, std::move(one));
271   EXPECT_TRUE(new_object);
272   ASSERT_EQ("1", new_object->value());
273 }
274 
TEST(ArenaTest,InitialBlockTooSmall)275 TEST(ArenaTest, InitialBlockTooSmall) {
276   // Construct a small blocks of memory to be used by the arena allocator; then,
277   // allocate an object which will not fit in the initial block.
278   for (int size = 0; size <= Arena::kBlockOverhead + 32; size++) {
279     std::vector<char> arena_block(size);
280     ArenaOptions options;
281     options.initial_block = arena_block.data();
282     options.initial_block_size = arena_block.size();
283 
284     // Try sometimes with non-default block sizes so that we exercise paths
285     // with and without ArenaImpl::Options.
286     if ((size % 2) != 0) {
287       options.start_block_size += 8;
288     }
289 
290     Arena arena(options);
291 
292     char* p = Arena::CreateArray<char>(&arena, 96);
293     uintptr_t allocation = reinterpret_cast<uintptr_t>(p);
294 
295     // Ensure that the arena allocator did not return memory pointing into the
296     // initial block of memory.
297     uintptr_t arena_start = reinterpret_cast<uintptr_t>(arena_block.data());
298     uintptr_t arena_end = arena_start + arena_block.size();
299     EXPECT_FALSE(allocation >= arena_start && allocation < arena_end);
300 
301     // Write to the memory we allocated; this should (but is not guaranteed to)
302     // trigger a check for heap corruption if the object was allocated from the
303     // initially-provided block.
304     memset(p, '\0', 96);
305   }
306 }
307 
TEST(ArenaTest,Parsing)308 TEST(ArenaTest, Parsing) {
309   TestAllTypes original;
310   TestUtil::SetAllFields(&original);
311 
312   // Test memory leak.
313   Arena arena;
314   TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
315   arena_message->ParseFromString(original.SerializeAsString());
316   TestUtil::ExpectAllFieldsSet(*arena_message);
317 
318   // Test that string fields have nul terminator bytes (earlier bug).
319   EXPECT_EQ(strlen(original.optional_string().c_str()),
320             strlen(arena_message->optional_string().c_str()));
321 }
322 
TEST(ArenaTest,UnknownFields)323 TEST(ArenaTest, UnknownFields) {
324   TestAllTypes original;
325   TestUtil::SetAllFields(&original);
326 
327   // Test basic parsing into (populating) and reading out of unknown fields on
328   // an arena.
329   Arena arena;
330   TestEmptyMessage* arena_message =
331       Arena::CreateMessage<TestEmptyMessage>(&arena);
332   arena_message->ParseFromString(original.SerializeAsString());
333 
334   TestAllTypes copied;
335   copied.ParseFromString(arena_message->SerializeAsString());
336   TestUtil::ExpectAllFieldsSet(copied);
337 
338   // Exercise UFS manual manipulation (setters).
339   arena_message = Arena::CreateMessage<TestEmptyMessage>(&arena);
340   arena_message->mutable_unknown_fields()->AddVarint(
341       TestAllTypes::kOptionalInt32FieldNumber, 42);
342   copied.Clear();
343   copied.ParseFromString(arena_message->SerializeAsString());
344   EXPECT_TRUE(copied.has_optional_int32());
345   EXPECT_EQ(42, copied.optional_int32());
346 
347   // Exercise UFS swap path.
348   TestEmptyMessage* arena_message_2 =
349       Arena::CreateMessage<TestEmptyMessage>(&arena);
350   arena_message_2->Swap(arena_message);
351   copied.Clear();
352   copied.ParseFromString(arena_message_2->SerializeAsString());
353   EXPECT_TRUE(copied.has_optional_int32());
354   EXPECT_EQ(42, copied.optional_int32());
355 
356   // Test field manipulation.
357   TestEmptyMessage* arena_message_3 =
358       Arena::CreateMessage<TestEmptyMessage>(&arena);
359   arena_message_3->mutable_unknown_fields()->AddVarint(1000, 42);
360   arena_message_3->mutable_unknown_fields()->AddFixed32(1001, 42);
361   arena_message_3->mutable_unknown_fields()->AddFixed64(1002, 42);
362   arena_message_3->mutable_unknown_fields()->AddLengthDelimited(1003);
363   arena_message_3->mutable_unknown_fields()->DeleteSubrange(0, 2);
364   arena_message_3->mutable_unknown_fields()->DeleteByNumber(1002);
365   arena_message_3->mutable_unknown_fields()->DeleteByNumber(1003);
366   EXPECT_TRUE(arena_message_3->unknown_fields().empty());
367 }
368 
TEST(ArenaTest,Swap)369 TEST(ArenaTest, Swap) {
370   Arena arena1;
371   Arena arena2;
372   TestAllTypes* arena1_message;
373   TestAllTypes* arena2_message;
374 
375   // Case 1: Swap(), no UFS on either message, both messages on different
376   // arenas. Arena pointers should remain the same after swap.
377   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
378   arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
379   arena1_message->Swap(arena2_message);
380   EXPECT_EQ(&arena1, arena1_message->GetArena());
381   EXPECT_EQ(&arena2, arena2_message->GetArena());
382 
383   // Case 2: Swap(), UFS on one message, both messages on different arenas.
384   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
385   arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
386   arena1_message->mutable_unknown_fields()->AddVarint(1, 42);
387   arena1_message->Swap(arena2_message);
388   EXPECT_EQ(&arena1, arena1_message->GetArena());
389   EXPECT_EQ(&arena2, arena2_message->GetArena());
390   EXPECT_EQ(0, arena1_message->unknown_fields().field_count());
391   EXPECT_EQ(1, arena2_message->unknown_fields().field_count());
392   EXPECT_EQ(42, arena2_message->unknown_fields().field(0).varint());
393 
394   // Case 3: Swap(), UFS on both messages, both messages on different arenas.
395   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
396   arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
397   arena1_message->mutable_unknown_fields()->AddVarint(1, 42);
398   arena2_message->mutable_unknown_fields()->AddVarint(2, 84);
399   arena1_message->Swap(arena2_message);
400   EXPECT_EQ(&arena1, arena1_message->GetArena());
401   EXPECT_EQ(&arena2, arena2_message->GetArena());
402   EXPECT_EQ(1, arena1_message->unknown_fields().field_count());
403   EXPECT_EQ(1, arena2_message->unknown_fields().field_count());
404   EXPECT_EQ(84, arena1_message->unknown_fields().field(0).varint());
405   EXPECT_EQ(42, arena2_message->unknown_fields().field(0).varint());
406 }
407 
TEST(ArenaTest,ReflectionSwapFields)408 TEST(ArenaTest, ReflectionSwapFields) {
409   Arena arena1;
410   Arena arena2;
411   TestAllTypes* arena1_message;
412   TestAllTypes* arena2_message;
413 
414   // Case 1: messages on different arenas, only one message is set.
415   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
416   arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
417   TestUtil::SetAllFields(arena1_message);
418   const Reflection* reflection = arena1_message->GetReflection();
419   std::vector<const FieldDescriptor*> fields;
420   reflection->ListFields(*arena1_message, &fields);
421   reflection->SwapFields(arena1_message, arena2_message, fields);
422   EXPECT_EQ(&arena1, arena1_message->GetArena());
423   EXPECT_EQ(&arena2, arena2_message->GetArena());
424   std::string output;
425   arena1_message->SerializeToString(&output);
426   EXPECT_EQ(0, output.size());
427   TestUtil::ExpectAllFieldsSet(*arena2_message);
428   reflection->SwapFields(arena1_message, arena2_message, fields);
429   arena2_message->SerializeToString(&output);
430   EXPECT_EQ(0, output.size());
431   TestUtil::ExpectAllFieldsSet(*arena1_message);
432 
433   // Case 2: messages on different arenas, both messages are set.
434   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
435   arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
436   TestUtil::SetAllFields(arena1_message);
437   TestUtil::SetAllFields(arena2_message);
438   reflection->SwapFields(arena1_message, arena2_message, fields);
439   EXPECT_EQ(&arena1, arena1_message->GetArena());
440   EXPECT_EQ(&arena2, arena2_message->GetArena());
441   TestUtil::ExpectAllFieldsSet(*arena1_message);
442   TestUtil::ExpectAllFieldsSet(*arena2_message);
443 
444   // Case 3: messages on different arenas with different lifetimes.
445   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
446   {
447     Arena arena3;
448     TestAllTypes* arena3_message = Arena::CreateMessage<TestAllTypes>(&arena3);
449     TestUtil::SetAllFields(arena3_message);
450     reflection->SwapFields(arena1_message, arena3_message, fields);
451   }
452   TestUtil::ExpectAllFieldsSet(*arena1_message);
453 
454   // Case 4: one message on arena, the other on heap.
455   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
456   TestAllTypes message;
457   TestUtil::SetAllFields(arena1_message);
458   reflection->SwapFields(arena1_message, &message, fields);
459   EXPECT_EQ(&arena1, arena1_message->GetArena());
460   EXPECT_EQ(nullptr, message.GetArena());
461   arena1_message->SerializeToString(&output);
462   EXPECT_EQ(0, output.size());
463   TestUtil::ExpectAllFieldsSet(message);
464 }
465 
TEST(ArenaTest,SetAllocatedMessage)466 TEST(ArenaTest, SetAllocatedMessage) {
467   Arena arena;
468   TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
469   TestAllTypes::NestedMessage* nested = new TestAllTypes::NestedMessage;
470   nested->set_bb(118);
471   arena_message->set_allocated_optional_nested_message(nested);
472   EXPECT_EQ(118, arena_message->optional_nested_message().bb());
473 }
474 
TEST(ArenaTest,ReleaseMessage)475 TEST(ArenaTest, ReleaseMessage) {
476   Arena arena;
477   TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
478   arena_message->mutable_optional_nested_message()->set_bb(118);
479   std::unique_ptr<TestAllTypes::NestedMessage> nested(
480       arena_message->release_optional_nested_message());
481   EXPECT_EQ(118, nested->bb());
482 
483   TestAllTypes::NestedMessage* released_null =
484       arena_message->release_optional_nested_message();
485   EXPECT_EQ(NULL, released_null);
486 }
487 
TEST(ArenaTest,SetAllocatedString)488 TEST(ArenaTest, SetAllocatedString) {
489   Arena arena;
490   TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
491   std::string* allocated_str = new std::string("hello");
492   arena_message->set_allocated_optional_string(allocated_str);
493   EXPECT_EQ("hello", arena_message->optional_string());
494 }
495 
TEST(ArenaTest,ReleaseString)496 TEST(ArenaTest, ReleaseString) {
497   Arena arena;
498   TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
499   arena_message->set_optional_string("hello");
500   std::unique_ptr<std::string> released_str(
501       arena_message->release_optional_string());
502   EXPECT_EQ("hello", *released_str);
503 
504   // Test default value.
505 }
506 
507 
TEST(ArenaTest,SwapBetweenArenasWithAllFieldsSet)508 TEST(ArenaTest, SwapBetweenArenasWithAllFieldsSet) {
509   Arena arena1;
510   TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
511   {
512     Arena arena2;
513     TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
514     TestUtil::SetAllFields(arena2_message);
515     arena2_message->Swap(arena1_message);
516     std::string output;
517     arena2_message->SerializeToString(&output);
518     EXPECT_EQ(0, output.size());
519   }
520   TestUtil::ExpectAllFieldsSet(*arena1_message);
521 }
522 
TEST(ArenaTest,SwapBetweenArenaAndNonArenaWithAllFieldsSet)523 TEST(ArenaTest, SwapBetweenArenaAndNonArenaWithAllFieldsSet) {
524   TestAllTypes non_arena_message;
525   TestUtil::SetAllFields(&non_arena_message);
526   {
527     Arena arena2;
528     TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
529     TestUtil::SetAllFields(arena2_message);
530     arena2_message->Swap(&non_arena_message);
531     TestUtil::ExpectAllFieldsSet(*arena2_message);
532     TestUtil::ExpectAllFieldsSet(non_arena_message);
533   }
534 }
535 
TEST(ArenaTest,UnsafeArenaSwap)536 TEST(ArenaTest, UnsafeArenaSwap) {
537   Arena shared_arena;
538   TestAllTypes* message1 = Arena::CreateMessage<TestAllTypes>(&shared_arena);
539   TestAllTypes* message2 = Arena::CreateMessage<TestAllTypes>(&shared_arena);
540   TestUtil::SetAllFields(message1);
541   message1->UnsafeArenaSwap(message2);
542   TestUtil::ExpectAllFieldsSet(*message2);
543 }
544 
TEST(ArenaTest,SwapBetweenArenasUsingReflection)545 TEST(ArenaTest, SwapBetweenArenasUsingReflection) {
546   Arena arena1;
547   TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
548   {
549     Arena arena2;
550     TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
551     TestUtil::SetAllFields(arena2_message);
552     const Reflection* r = arena2_message->GetReflection();
553     r->Swap(arena1_message, arena2_message);
554     std::string output;
555     arena2_message->SerializeToString(&output);
556     EXPECT_EQ(0, output.size());
557   }
558   TestUtil::ExpectAllFieldsSet(*arena1_message);
559 }
560 
TEST(ArenaTest,SwapBetweenArenaAndNonArenaUsingReflection)561 TEST(ArenaTest, SwapBetweenArenaAndNonArenaUsingReflection) {
562   TestAllTypes non_arena_message;
563   TestUtil::SetAllFields(&non_arena_message);
564   {
565     Arena arena2;
566     TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
567     TestUtil::SetAllFields(arena2_message);
568     const Reflection* r = arena2_message->GetReflection();
569     r->Swap(&non_arena_message, arena2_message);
570     TestUtil::ExpectAllFieldsSet(*arena2_message);
571     TestUtil::ExpectAllFieldsSet(non_arena_message);
572   }
573 }
574 
TEST(ArenaTest,ReleaseFromArenaMessageMakesCopy)575 TEST(ArenaTest, ReleaseFromArenaMessageMakesCopy) {
576   TestAllTypes::NestedMessage* nested_msg = NULL;
577   std::string* nested_string = NULL;
578   {
579     Arena arena;
580     TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
581     arena_message->mutable_optional_nested_message()->set_bb(42);
582     *arena_message->mutable_optional_string() = "Hello";
583     nested_msg = arena_message->release_optional_nested_message();
584     nested_string = arena_message->release_optional_string();
585   }
586   EXPECT_EQ(42, nested_msg->bb());
587   EXPECT_EQ("Hello", *nested_string);
588   delete nested_msg;
589   delete nested_string;
590 }
591 
592 #if PROTOBUF_RTTI
TEST(ArenaTest,ReleaseFromArenaMessageUsingReflectionMakesCopy)593 TEST(ArenaTest, ReleaseFromArenaMessageUsingReflectionMakesCopy) {
594   TestAllTypes::NestedMessage* nested_msg = NULL;
595   // Note: no string: reflection API only supports releasing submessages.
596   {
597     Arena arena;
598     TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
599     arena_message->mutable_optional_nested_message()->set_bb(42);
600     const Reflection* r = arena_message->GetReflection();
601     const FieldDescriptor* f = arena_message->GetDescriptor()->FindFieldByName(
602         "optional_nested_message");
603     nested_msg = static_cast<TestAllTypes::NestedMessage*>(
604         r->ReleaseMessage(arena_message, f));
605   }
606   EXPECT_EQ(42, nested_msg->bb());
607   delete nested_msg;
608 }
609 #endif  // PROTOBUF_RTTI
610 
TEST(ArenaTest,SetAllocatedAcrossArenas)611 TEST(ArenaTest, SetAllocatedAcrossArenas) {
612   Arena arena1;
613   TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
614   TestAllTypes::NestedMessage* heap_submessage =
615       new TestAllTypes::NestedMessage();
616   heap_submessage->set_bb(42);
617   arena1_message->set_allocated_optional_nested_message(heap_submessage);
618   // Should keep same object and add to arena's Own()-list.
619   EXPECT_EQ(heap_submessage, arena1_message->mutable_optional_nested_message());
620   {
621     Arena arena2;
622     TestAllTypes::NestedMessage* arena2_submessage =
623         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
624     arena2_submessage->set_bb(42);
625     arena1_message->set_allocated_optional_nested_message(arena2_submessage);
626     EXPECT_NE(arena2_submessage,
627               arena1_message->mutable_optional_nested_message());
628   }
629 
630   TestAllTypes::NestedMessage* arena1_submessage =
631       Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
632   arena1_submessage->set_bb(42);
633   TestAllTypes* heap_message = new TestAllTypes;
634   heap_message->set_allocated_optional_nested_message(arena1_submessage);
635   EXPECT_NE(arena1_submessage, heap_message->mutable_optional_nested_message());
636   delete heap_message;
637 }
638 
TEST(ArenaTest,SetAllocatedAcrossArenasWithReflection)639 TEST(ArenaTest, SetAllocatedAcrossArenasWithReflection) {
640   // Same as above, with reflection.
641   Arena arena1;
642   TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
643   const Reflection* r = arena1_message->GetReflection();
644   const Descriptor* d = arena1_message->GetDescriptor();
645   const FieldDescriptor* msg_field =
646       d->FindFieldByName("optional_nested_message");
647   TestAllTypes::NestedMessage* heap_submessage =
648       new TestAllTypes::NestedMessage();
649   heap_submessage->set_bb(42);
650   r->SetAllocatedMessage(arena1_message, heap_submessage, msg_field);
651   // Should keep same object and add to arena's Own()-list.
652   EXPECT_EQ(heap_submessage, arena1_message->mutable_optional_nested_message());
653   {
654     Arena arena2;
655     TestAllTypes::NestedMessage* arena2_submessage =
656         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
657     arena2_submessage->set_bb(42);
658     r->SetAllocatedMessage(arena1_message, arena2_submessage, msg_field);
659     EXPECT_NE(arena2_submessage,
660               arena1_message->mutable_optional_nested_message());
661   }
662 
663   TestAllTypes::NestedMessage* arena1_submessage =
664       Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
665   arena1_submessage->set_bb(42);
666   TestAllTypes* heap_message = new TestAllTypes;
667   r->SetAllocatedMessage(heap_message, arena1_submessage, msg_field);
668   EXPECT_NE(arena1_submessage, heap_message->mutable_optional_nested_message());
669   delete heap_message;
670 }
671 
TEST(ArenaTest,AddAllocatedWithReflection)672 TEST(ArenaTest, AddAllocatedWithReflection) {
673   Arena arena1;
674   ArenaMessage* arena1_message = Arena::CreateMessage<ArenaMessage>(&arena1);
675   const Reflection* r = arena1_message->GetReflection();
676   const Descriptor* d = arena1_message->GetDescriptor();
677   // Message with cc_enable_arenas = true;
678   const FieldDescriptor* fd = d->FindFieldByName("repeated_nested_message");
679   r->AddMessage(arena1_message, fd);
680   r->AddMessage(arena1_message, fd);
681   r->AddMessage(arena1_message, fd);
682   EXPECT_EQ(3, r->FieldSize(*arena1_message, fd));
683 }
684 
TEST(ArenaTest,RepeatedPtrFieldAddClearedTest)685 TEST(ArenaTest, RepeatedPtrFieldAddClearedTest) {
686   {
687     RepeatedPtrField<TestAllTypes> repeated_field;
688     EXPECT_TRUE(repeated_field.empty());
689     EXPECT_EQ(0, repeated_field.size());
690     // Ownership is passed to repeated_field.
691     TestAllTypes* cleared = new TestAllTypes();
692     repeated_field.AddCleared(cleared);
693     EXPECT_TRUE(repeated_field.empty());
694     EXPECT_EQ(0, repeated_field.size());
695   }
696   {
697     RepeatedPtrField<TestAllTypes> repeated_field;
698     EXPECT_TRUE(repeated_field.empty());
699     EXPECT_EQ(0, repeated_field.size());
700     // Ownership is passed to repeated_field.
701     TestAllTypes* cleared = new TestAllTypes();
702     repeated_field.AddAllocated(cleared);
703     EXPECT_FALSE(repeated_field.empty());
704     EXPECT_EQ(1, repeated_field.size());
705   }
706 }
707 
TEST(ArenaTest,AddAllocatedToRepeatedField)708 TEST(ArenaTest, AddAllocatedToRepeatedField) {
709   // Heap->arena case.
710   Arena arena1;
711   TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
712   for (int i = 0; i < 10; i++) {
713     TestAllTypes::NestedMessage* heap_submessage =
714         new TestAllTypes::NestedMessage();
715     heap_submessage->set_bb(42);
716     arena1_message->mutable_repeated_nested_message()->AddAllocated(
717         heap_submessage);
718     // Should not copy object -- will use arena_->Own().
719     EXPECT_EQ(heap_submessage, &arena1_message->repeated_nested_message(i));
720     EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
721   }
722 
723   // Arena1->Arena2 case.
724   arena1_message->Clear();
725   for (int i = 0; i < 10; i++) {
726     Arena arena2;
727     TestAllTypes::NestedMessage* arena2_submessage =
728         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
729     arena2_submessage->set_bb(42);
730     arena1_message->mutable_repeated_nested_message()->AddAllocated(
731         arena2_submessage);
732     // Should copy object.
733     EXPECT_NE(arena2_submessage, &arena1_message->repeated_nested_message(i));
734     EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
735   }
736 
737   // Arena->heap case.
738   TestAllTypes* heap_message = new TestAllTypes();
739   for (int i = 0; i < 10; i++) {
740     Arena arena2;
741     TestAllTypes::NestedMessage* arena2_submessage =
742         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
743     arena2_submessage->set_bb(42);
744     heap_message->mutable_repeated_nested_message()->AddAllocated(
745         arena2_submessage);
746     // Should copy object.
747     EXPECT_NE(arena2_submessage, &heap_message->repeated_nested_message(i));
748     EXPECT_EQ(42, heap_message->repeated_nested_message(i).bb());
749   }
750   delete heap_message;
751 
752   // Heap-arena case for strings (which are not arena-allocated).
753   arena1_message->Clear();
754   for (int i = 0; i < 10; i++) {
755     std::string* s = new std::string("Test");
756     arena1_message->mutable_repeated_string()->AddAllocated(s);
757     // Should not copy.
758     EXPECT_EQ(s, &arena1_message->repeated_string(i));
759     EXPECT_EQ("Test", arena1_message->repeated_string(i));
760   }
761 }
762 
TEST(ArenaTest,AddAllocatedToRepeatedFieldViaReflection)763 TEST(ArenaTest, AddAllocatedToRepeatedFieldViaReflection) {
764   // Heap->arena case.
765   Arena arena1;
766   TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
767   const Reflection* r = arena1_message->GetReflection();
768   const Descriptor* d = arena1_message->GetDescriptor();
769   const FieldDescriptor* fd = d->FindFieldByName("repeated_nested_message");
770   for (int i = 0; i < 10; i++) {
771     TestAllTypes::NestedMessage* heap_submessage =
772         new TestAllTypes::NestedMessage;
773     heap_submessage->set_bb(42);
774     r->AddAllocatedMessage(arena1_message, fd, heap_submessage);
775     // Should not copy object -- will use arena_->Own().
776     EXPECT_EQ(heap_submessage, &arena1_message->repeated_nested_message(i));
777     EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
778   }
779 
780   // Arena1->Arena2 case.
781   arena1_message->Clear();
782   for (int i = 0; i < 10; i++) {
783     Arena arena2;
784     TestAllTypes::NestedMessage* arena2_submessage =
785         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
786     arena2_submessage->set_bb(42);
787     r->AddAllocatedMessage(arena1_message, fd, arena2_submessage);
788     // Should copy object.
789     EXPECT_NE(arena2_submessage, &arena1_message->repeated_nested_message(i));
790     EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
791   }
792 
793   // Arena->heap case.
794   TestAllTypes* heap_message = new TestAllTypes;
795   for (int i = 0; i < 10; i++) {
796     Arena arena2;
797     TestAllTypes::NestedMessage* arena2_submessage =
798         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
799     arena2_submessage->set_bb(42);
800     r->AddAllocatedMessage(heap_message, fd, arena2_submessage);
801     // Should copy object.
802     EXPECT_NE(arena2_submessage, &heap_message->repeated_nested_message(i));
803     EXPECT_EQ(42, heap_message->repeated_nested_message(i).bb());
804   }
805   delete heap_message;
806 }
807 
TEST(ArenaTest,ReleaseLastRepeatedField)808 TEST(ArenaTest, ReleaseLastRepeatedField) {
809   // Release from arena-allocated repeated field and ensure that returned object
810   // is heap-allocated.
811   Arena arena;
812   TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
813   for (int i = 0; i < 10; i++) {
814     TestAllTypes::NestedMessage* nested =
815         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena);
816     nested->set_bb(42);
817     arena_message->mutable_repeated_nested_message()->AddAllocated(nested);
818   }
819 
820   for (int i = 0; i < 10; i++) {
821     const TestAllTypes::NestedMessage* orig_submessage =
822         &arena_message->repeated_nested_message(10 - 1 - i);  // last element
823     TestAllTypes::NestedMessage* released =
824         arena_message->mutable_repeated_nested_message()->ReleaseLast();
825     EXPECT_NE(released, orig_submessage);
826     EXPECT_EQ(42, released->bb());
827     delete released;
828   }
829 
830   // Test UnsafeArenaReleaseLast().
831   for (int i = 0; i < 10; i++) {
832     TestAllTypes::NestedMessage* nested =
833         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena);
834     nested->set_bb(42);
835     arena_message->mutable_repeated_nested_message()->AddAllocated(nested);
836   }
837 
838   for (int i = 0; i < 10; i++) {
839     const TestAllTypes::NestedMessage* orig_submessage =
840         &arena_message->repeated_nested_message(10 - 1 - i);  // last element
841     TestAllTypes::NestedMessage* released =
842         arena_message->mutable_repeated_nested_message()
843             ->UnsafeArenaReleaseLast();
844     EXPECT_EQ(released, orig_submessage);
845     EXPECT_EQ(42, released->bb());
846     // no delete -- |released| is on the arena.
847   }
848 
849   // Test string case as well. ReleaseLast() in this case must copy the
850   // string, even though it was originally heap-allocated and its pointer
851   // was simply appended to the repeated field's internal vector, because the
852   // string was placed on the arena's destructor list and cannot be removed
853   // from that list (so the arena permanently owns the original instance).
854   arena_message->Clear();
855   for (int i = 0; i < 10; i++) {
856     std::string* s = new std::string("Test");
857     arena_message->mutable_repeated_string()->AddAllocated(s);
858   }
859   for (int i = 0; i < 10; i++) {
860     const std::string* orig_element =
861         &arena_message->repeated_string(10 - 1 - i);
862     std::string* released =
863         arena_message->mutable_repeated_string()->ReleaseLast();
864     EXPECT_NE(released, orig_element);
865     EXPECT_EQ("Test", *released);
866     delete released;
867   }
868 }
869 
TEST(ArenaTest,UnsafeArenaAddAllocated)870 TEST(ArenaTest, UnsafeArenaAddAllocated) {
871   Arena arena;
872   TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
873   for (int i = 0; i < 10; i++) {
874     std::string* arena_string = Arena::Create<std::string>(&arena);
875     message->mutable_repeated_string()->UnsafeArenaAddAllocated(arena_string);
876     EXPECT_EQ(arena_string, message->mutable_repeated_string(i));
877   }
878 }
879 
TEST(ArenaTest,OneofMerge)880 TEST(ArenaTest, OneofMerge) {
881   Arena arena;
882   TestAllTypes* message0 = Arena::CreateMessage<TestAllTypes>(&arena);
883   TestAllTypes* message1 = Arena::CreateMessage<TestAllTypes>(&arena);
884 
885   message0->set_oneof_string("x");
886   ASSERT_TRUE(message0->has_oneof_string());
887   message1->set_oneof_string("y");
888   ASSERT_TRUE(message1->has_oneof_string());
889   EXPECT_EQ("x", message0->oneof_string());
890   EXPECT_EQ("y", message1->oneof_string());
891   message0->MergeFrom(*message1);
892   EXPECT_EQ("y", message0->oneof_string());
893   EXPECT_EQ("y", message1->oneof_string());
894 }
895 
TEST(ArenaTest,ArenaOneofReflection)896 TEST(ArenaTest, ArenaOneofReflection) {
897   Arena arena;
898   TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
899   const Descriptor* desc = message->GetDescriptor();
900   const Reflection* refl = message->GetReflection();
901 
902   const FieldDescriptor* string_field = desc->FindFieldByName("oneof_string");
903   const FieldDescriptor* msg_field =
904       desc->FindFieldByName("oneof_nested_message");
905   const OneofDescriptor* oneof = desc->FindOneofByName("oneof_field");
906 
907   refl->SetString(message, string_field, "Test value");
908   EXPECT_TRUE(refl->HasOneof(*message, oneof));
909   refl->ClearOneof(message, oneof);
910   EXPECT_FALSE(refl->HasOneof(*message, oneof));
911 
912   Message* submsg = refl->MutableMessage(message, msg_field);
913   EXPECT_TRUE(refl->HasOneof(*message, oneof));
914   refl->ClearOneof(message, oneof);
915   EXPECT_FALSE(refl->HasOneof(*message, oneof));
916   refl->MutableMessage(message, msg_field);
917   EXPECT_TRUE(refl->HasOneof(*message, oneof));
918   submsg = refl->ReleaseMessage(message, msg_field);
919   EXPECT_FALSE(refl->HasOneof(*message, oneof));
920   EXPECT_TRUE(submsg->GetArena() == NULL);
921   delete submsg;
922 }
923 
TestSwapRepeatedField(Arena * arena1,Arena * arena2)924 void TestSwapRepeatedField(Arena* arena1, Arena* arena2) {
925   // Test "safe" (copying) semantics for direct Swap() on RepeatedPtrField
926   // between arenas.
927   RepeatedPtrField<TestAllTypes> field1(arena1);
928   RepeatedPtrField<TestAllTypes> field2(arena2);
929   for (int i = 0; i < 10; i++) {
930     TestAllTypes* t = Arena::CreateMessage<TestAllTypes>(arena1);
931     t->set_optional_string("field1");
932     t->set_optional_int32(i);
933     if (arena1 != NULL) {
934       field1.UnsafeArenaAddAllocated(t);
935     } else {
936       field1.AddAllocated(t);
937     }
938   }
939   for (int i = 0; i < 5; i++) {
940     TestAllTypes* t = Arena::CreateMessage<TestAllTypes>(arena2);
941     t->set_optional_string("field2");
942     t->set_optional_int32(i);
943     if (arena2 != NULL) {
944       field2.UnsafeArenaAddAllocated(t);
945     } else {
946       field2.AddAllocated(t);
947     }
948   }
949   field1.Swap(&field2);
950   EXPECT_EQ(5, field1.size());
951   EXPECT_EQ(10, field2.size());
952   EXPECT_TRUE(std::string("field1") == field2.Get(0).optional_string());
953   EXPECT_TRUE(std::string("field2") == field1.Get(0).optional_string());
954   // Ensure that fields retained their original order:
955   for (int i = 0; i < field1.size(); i++) {
956     EXPECT_EQ(i, field1.Get(i).optional_int32());
957   }
958   for (int i = 0; i < field2.size(); i++) {
959     EXPECT_EQ(i, field2.Get(i).optional_int32());
960   }
961 }
962 
TEST(ArenaTest,SwapRepeatedField)963 TEST(ArenaTest, SwapRepeatedField) {
964   Arena arena;
965   TestSwapRepeatedField(&arena, &arena);
966 }
967 
TEST(ArenaTest,SwapRepeatedFieldWithDifferentArenas)968 TEST(ArenaTest, SwapRepeatedFieldWithDifferentArenas) {
969   Arena arena1;
970   Arena arena2;
971   TestSwapRepeatedField(&arena1, &arena2);
972 }
973 
TEST(ArenaTest,SwapRepeatedFieldWithNoArenaOnRightHandSide)974 TEST(ArenaTest, SwapRepeatedFieldWithNoArenaOnRightHandSide) {
975   Arena arena;
976   TestSwapRepeatedField(&arena, NULL);
977 }
978 
TEST(ArenaTest,SwapRepeatedFieldWithNoArenaOnLeftHandSide)979 TEST(ArenaTest, SwapRepeatedFieldWithNoArenaOnLeftHandSide) {
980   Arena arena;
981   TestSwapRepeatedField(NULL, &arena);
982 }
983 
TEST(ArenaTest,ExtensionsOnArena)984 TEST(ArenaTest, ExtensionsOnArena) {
985   Arena arena;
986   // Ensure no leaks.
987   TestAllExtensions* message_ext =
988       Arena::CreateMessage<TestAllExtensions>(&arena);
989   message_ext->SetExtension(protobuf_unittest::optional_int32_extension, 42);
990   message_ext->SetExtension(protobuf_unittest::optional_string_extension,
991                             std::string("test"));
992   message_ext
993       ->MutableExtension(protobuf_unittest::optional_nested_message_extension)
994       ->set_bb(42);
995 }
996 
TEST(ArenaTest,RepeatedFieldOnArena)997 TEST(ArenaTest, RepeatedFieldOnArena) {
998   // Preallocate an initial arena block to avoid mallocs during hooked region.
999   std::vector<char> arena_block(1024 * 1024);
1000   Arena arena(arena_block.data(), arena_block.size());
1001 
1002   {
1003     internal::NoHeapChecker no_heap;
1004 
1005     // Fill some repeated fields on the arena to test for leaks. Also verify no
1006     // memory allocations.
1007     RepeatedField<int32> repeated_int32(&arena);
1008     RepeatedPtrField<TestAllTypes> repeated_message(&arena);
1009     for (int i = 0; i < 100; i++) {
1010       repeated_int32.Add(42);
1011       repeated_message.Add()->set_optional_int32(42);
1012       EXPECT_EQ(&arena, repeated_message.Get(0).GetArena());
1013       const TestAllTypes* msg_in_repeated_field = &repeated_message.Get(0);
1014       TestAllTypes* msg = repeated_message.UnsafeArenaReleaseLast();
1015       EXPECT_EQ(msg_in_repeated_field, msg);
1016     }
1017 
1018     // UnsafeArenaExtractSubrange (i) should not leak and (ii) should return
1019     // on-arena pointers.
1020     for (int i = 0; i < 10; i++) {
1021       repeated_message.Add()->set_optional_int32(42);
1022     }
1023     TestAllTypes* extracted_messages[5];
1024     repeated_message.UnsafeArenaExtractSubrange(0, 5, extracted_messages);
1025     EXPECT_EQ(&arena, repeated_message.Get(0).GetArena());
1026     EXPECT_EQ(5, repeated_message.size());
1027   }
1028 
1029   // Now, outside the scope of the NoHeapChecker, test ExtractSubrange's copying
1030   // semantics.
1031   {
1032     RepeatedPtrField<TestAllTypes> repeated_message(&arena);
1033     for (int i = 0; i < 100; i++) {
1034       repeated_message.Add()->set_optional_int32(42);
1035     }
1036 
1037     TestAllTypes* extracted_messages[5];
1038     // ExtractSubrange should copy to the heap.
1039     repeated_message.ExtractSubrange(0, 5, extracted_messages);
1040     EXPECT_EQ(NULL, extracted_messages[0]->GetArena());
1041     // We need to free the heap-allocated messages to prevent a leak.
1042     for (int i = 0; i < 5; i++) {
1043       delete extracted_messages[i];
1044       extracted_messages[i] = NULL;
1045     }
1046   }
1047 
1048   // Now check that we can create RepeatedFields/RepeatedPtrFields themselves on
1049   // the arena. They have the necessary type traits so that they can behave like
1050   // messages in this way. This is useful for higher-level generic templated
1051   // code that may allocate messages or repeated fields of messages on an arena.
1052   {
1053     RepeatedPtrField<TestAllTypes>* repeated_ptr_on_arena =
1054         Arena::CreateMessage<RepeatedPtrField<TestAllTypes> >(&arena);
1055     for (int i = 0; i < 10; i++) {
1056       // Add some elements and let the leak-checker ensure that everything is
1057       // freed.
1058       repeated_ptr_on_arena->Add();
1059     }
1060 
1061     RepeatedField<int>* repeated_int_on_arena =
1062         Arena::CreateMessage<RepeatedField<int> >(&arena);
1063     for (int i = 0; i < 100; i++) {
1064       repeated_int_on_arena->Add(i);
1065     }
1066 
1067   }
1068 
1069   arena.Reset();
1070 }
1071 
1072 
1073 #if PROTOBUF_RTTI
TEST(ArenaTest,MutableMessageReflection)1074 TEST(ArenaTest, MutableMessageReflection) {
1075   Arena arena;
1076   TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
1077   const Reflection* r = message->GetReflection();
1078   const Descriptor* d = message->GetDescriptor();
1079   const FieldDescriptor* field = d->FindFieldByName("optional_nested_message");
1080   TestAllTypes::NestedMessage* submessage =
1081       static_cast<TestAllTypes::NestedMessage*>(
1082           r->MutableMessage(message, field));
1083   TestAllTypes::NestedMessage* submessage_expected =
1084       message->mutable_optional_nested_message();
1085 
1086   EXPECT_EQ(submessage_expected, submessage);
1087   EXPECT_EQ(&arena, submessage->GetArena());
1088 
1089   const FieldDescriptor* oneof_field =
1090       d->FindFieldByName("oneof_nested_message");
1091   submessage = static_cast<TestAllTypes::NestedMessage*>(
1092       r->MutableMessage(message, oneof_field));
1093   submessage_expected = message->mutable_oneof_nested_message();
1094 
1095   EXPECT_EQ(submessage_expected, submessage);
1096   EXPECT_EQ(&arena, submessage->GetArena());
1097 }
1098 #endif  // PROTOBUF_RTTI
1099 
1100 
FillArenaAwareFields(TestAllTypes * message)1101 void FillArenaAwareFields(TestAllTypes* message) {
1102   std::string test_string = "hello world";
1103   message->set_optional_int32(42);
1104   message->set_optional_string(test_string);
1105   message->set_optional_bytes(test_string);
1106   message->mutable_optional_nested_message()->set_bb(42);
1107 
1108   message->set_oneof_uint32(42);
1109   message->mutable_oneof_nested_message()->set_bb(42);
1110   message->set_oneof_string(test_string);
1111   message->set_oneof_bytes(test_string);
1112 
1113   message->add_repeated_int32(42);
1114   // No repeated string: not yet arena-aware.
1115   message->add_repeated_nested_message()->set_bb(42);
1116   message->mutable_optional_lazy_message()->set_bb(42);
1117 }
1118 
1119 // Test: no allocations occur on heap while touching all supported field types.
TEST(ArenaTest,NoHeapAllocationsTest)1120 TEST(ArenaTest, NoHeapAllocationsTest) {
1121   // Allocate a large initial block to avoid mallocs during hooked test.
1122   std::vector<char> arena_block(128 * 1024);
1123   ArenaOptions options;
1124   options.initial_block = &arena_block[0];
1125   options.initial_block_size = arena_block.size();
1126   Arena arena(options);
1127 
1128   {
1129 
1130     TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
1131     FillArenaAwareFields(message);
1132   }
1133 
1134   arena.Reset();
1135 }
1136 
TEST(ArenaTest,ParseCorruptedString)1137 TEST(ArenaTest, ParseCorruptedString) {
1138   TestAllTypes message;
1139   TestUtil::SetAllFields(&message);
1140   TestParseCorruptedString<TestAllTypes, true>(message);
1141   TestParseCorruptedString<TestAllTypes, false>(message);
1142 }
1143 
1144 #if PROTOBUF_RTTI
1145 // Test construction on an arena via generic MessageLite interface. We should be
1146 // able to successfully deserialize on the arena without incurring heap
1147 // allocations, i.e., everything should still be arena-allocation-aware.
TEST(ArenaTest,MessageLiteOnArena)1148 TEST(ArenaTest, MessageLiteOnArena) {
1149   std::vector<char> arena_block(128 * 1024);
1150   ArenaOptions options;
1151   options.initial_block = &arena_block[0];
1152   options.initial_block_size = arena_block.size();
1153   Arena arena(options);
1154   const MessageLite* prototype = &TestAllTypes::default_instance();
1155 
1156   TestAllTypes initial_message;
1157   FillArenaAwareFields(&initial_message);
1158   std::string serialized;
1159   initial_message.SerializeToString(&serialized);
1160 
1161   {
1162 
1163     MessageLite* generic_message = prototype->New(&arena);
1164     EXPECT_TRUE(generic_message != NULL);
1165     EXPECT_EQ(&arena, generic_message->GetArena());
1166     EXPECT_TRUE(generic_message->ParseFromString(serialized));
1167     TestAllTypes* deserialized = static_cast<TestAllTypes*>(generic_message);
1168     EXPECT_EQ(42, deserialized->optional_int32());
1169   }
1170 
1171   arena.Reset();
1172 }
1173 #endif  // PROTOBUF_RTTI
1174 
1175 // RepeatedField should support non-POD types, and invoke constructors and
1176 // destructors appropriately, because it's used this way by lots of other code
1177 // (even if this was not its original intent).
TEST(ArenaTest,RepeatedFieldWithNonPODType)1178 TEST(ArenaTest, RepeatedFieldWithNonPODType) {
1179   {
1180     RepeatedField<std::string> field_on_heap;
1181     for (int i = 0; i < 100; i++) {
1182       *field_on_heap.Add() = "test string long enough to exceed inline buffer";
1183     }
1184   }
1185   {
1186     Arena arena;
1187     RepeatedField<std::string> field_on_arena(&arena);
1188     for (int i = 0; i < 100; i++) {
1189       *field_on_arena.Add() = "test string long enough to exceed inline buffer";
1190     }
1191   }
1192 }
1193 
1194 // Align n to next multiple of 8
Align8(uint64 n)1195 uint64 Align8(uint64 n) { return (n + 7) & -8; }
1196 
TEST(ArenaTest,SpaceAllocated_and_Used)1197 TEST(ArenaTest, SpaceAllocated_and_Used) {
1198   Arena arena_1;
1199   EXPECT_EQ(0, arena_1.SpaceAllocated());
1200   EXPECT_EQ(0, arena_1.SpaceUsed());
1201   EXPECT_EQ(0, arena_1.Reset());
1202   Arena::CreateArray<char>(&arena_1, 320);
1203   // Arena will allocate slightly more than 320 for the block headers.
1204   EXPECT_LE(320, arena_1.SpaceAllocated());
1205   EXPECT_EQ(Align8(320), arena_1.SpaceUsed());
1206   EXPECT_LE(320, arena_1.Reset());
1207 
1208   // Test with initial block.
1209   std::vector<char> arena_block(1024);
1210   ArenaOptions options;
1211   options.start_block_size = 256;
1212   options.max_block_size = 8192;
1213   options.initial_block = &arena_block[0];
1214   options.initial_block_size = arena_block.size();
1215   Arena arena_2(options);
1216   EXPECT_EQ(1024, arena_2.SpaceAllocated());
1217   EXPECT_EQ(0, arena_2.SpaceUsed());
1218   EXPECT_EQ(1024, arena_2.Reset());
1219   Arena::CreateArray<char>(&arena_2, 55);
1220   EXPECT_EQ(1024, arena_2.SpaceAllocated());
1221   EXPECT_EQ(Align8(55), arena_2.SpaceUsed());
1222   EXPECT_EQ(1024, arena_2.Reset());
1223 }
1224 
TEST(ArenaTest,BlockSizeDoubling)1225 TEST(ArenaTest, BlockSizeDoubling) {
1226   Arena arena;
1227   EXPECT_EQ(0, arena.SpaceUsed());
1228   EXPECT_EQ(0, arena.SpaceAllocated());
1229 
1230   // Allocate something to get initial block size.
1231   Arena::CreateArray<char>(&arena, 1);
1232   auto first_block_size = arena.SpaceAllocated();
1233 
1234   // Keep allocating until space used increases.
1235   while (arena.SpaceAllocated() == first_block_size) {
1236     Arena::CreateArray<char>(&arena, 1);
1237   }
1238   ASSERT_GT(arena.SpaceAllocated(), first_block_size);
1239   auto second_block_size = (arena.SpaceAllocated() - first_block_size);
1240 
1241   EXPECT_EQ(second_block_size, 2*first_block_size);
1242 }
1243 
TEST(ArenaTest,Alignment)1244 TEST(ArenaTest, Alignment) {
1245   Arena arena;
1246   for (int i = 0; i < 200; i++) {
1247     void* p = Arena::CreateArray<char>(&arena, i);
1248     GOOGLE_CHECK_EQ(reinterpret_cast<uintptr_t>(p) % 8, 0) << i << ": " << p;
1249   }
1250 }
1251 
TEST(ArenaTest,BlockSizeSmallerThanAllocation)1252 TEST(ArenaTest, BlockSizeSmallerThanAllocation) {
1253   for (size_t i = 0; i <= 8; ++i) {
1254     ArenaOptions opt;
1255     opt.start_block_size = opt.max_block_size = i;
1256     Arena arena(opt);
1257 
1258     *Arena::Create<int64>(&arena) = 42;
1259     EXPECT_GE(arena.SpaceAllocated(), 8);
1260     EXPECT_EQ(8, arena.SpaceUsed());
1261 
1262     *Arena::Create<int64>(&arena) = 42;
1263     EXPECT_GE(arena.SpaceAllocated(), 16);
1264     EXPECT_EQ(16, arena.SpaceUsed());
1265   }
1266 }
1267 
TEST(ArenaTest,GetArenaShouldReturnTheArenaForArenaAllocatedMessages)1268 TEST(ArenaTest, GetArenaShouldReturnTheArenaForArenaAllocatedMessages) {
1269   Arena arena;
1270   ArenaMessage* message = Arena::CreateMessage<ArenaMessage>(&arena);
1271   const ArenaMessage* const_pointer_to_message = message;
1272   EXPECT_EQ(&arena, Arena::GetArena(message));
1273   EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message));
1274 
1275   // Test that the Message* / MessageLite* specialization SFINAE works.
1276   const Message* const_pointer_to_message_type = message;
1277   EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message_type));
1278   const MessageLite* const_pointer_to_message_lite_type = message;
1279   EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message_lite_type));
1280 }
1281 
TEST(ArenaTest,GetArenaShouldReturnNullForNonArenaAllocatedMessages)1282 TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaAllocatedMessages) {
1283   ArenaMessage message;
1284   const ArenaMessage* const_pointer_to_message = &message;
1285   EXPECT_EQ(NULL, Arena::GetArena(&message));
1286   EXPECT_EQ(NULL, Arena::GetArena(const_pointer_to_message));
1287 }
1288 
TEST(ArenaTest,GetArenaShouldReturnNullForNonArenaCompatibleTypes)1289 TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaCompatibleTypes) {
1290   // Test that GetArena returns nullptr for types that have a GetArena method
1291   // that doesn't return Arena*.
1292   struct {
1293     int GetArena() const { return 0; }
1294   } has_get_arena_method_wrong_return_type;
1295   EXPECT_EQ(nullptr, Arena::GetArena(&has_get_arena_method_wrong_return_type));
1296 
1297   // Test that GetArena returns nullptr for types that have a GetArena alias.
1298   struct {
1299     using GetArena = Arena*;
1300     GetArena unused;
1301   } has_get_arena_alias;
1302   EXPECT_EQ(nullptr, Arena::GetArena(&has_get_arena_alias));
1303 
1304   // Test that GetArena returns nullptr for types that have a GetArena data
1305   // member.
1306   struct {
1307     Arena GetArena;
1308   } has_get_arena_data_member;
1309   EXPECT_EQ(nullptr, Arena::GetArena(&has_get_arena_data_member));
1310 }
1311 
TEST(ArenaTest,AddCleanup)1312 TEST(ArenaTest, AddCleanup) {
1313   Arena arena;
1314   for (int i = 0; i < 100; i++) {
1315     arena.Own(new int);
1316   }
1317 }
1318 
1319 namespace {
1320 uint32 hooks_num_init = 0;
1321 uint32 hooks_num_allocations = 0;
1322 uint32 hooks_num_reset = 0;
1323 uint32 hooks_num_destruct = 0;
1324 
ClearHookCounts()1325 void ClearHookCounts() {
1326   hooks_num_init = 0;
1327   hooks_num_allocations = 0;
1328   hooks_num_reset = 0;
1329   hooks_num_destruct = 0;
1330 }
1331 }  // namespace
1332 
1333 // A helper utility class that handles arena callbacks.
1334 class ArenaOptionsTestFriend : public internal::ArenaMetricsCollector {
1335  public:
NewWithAllocs()1336   static internal::ArenaMetricsCollector* NewWithAllocs() {
1337     return new ArenaOptionsTestFriend(true);
1338   }
1339 
NewWithoutAllocs()1340   static internal::ArenaMetricsCollector* NewWithoutAllocs() {
1341     return new ArenaOptionsTestFriend(false);
1342   }
1343 
Enable(ArenaOptions * options)1344   static void Enable(ArenaOptions* options) {
1345     ClearHookCounts();
1346     options->make_metrics_collector = &ArenaOptionsTestFriend::NewWithAllocs;
1347   }
1348 
EnableWithoutAllocs(ArenaOptions * options)1349   static void EnableWithoutAllocs(ArenaOptions* options) {
1350     ClearHookCounts();
1351     options->make_metrics_collector = &ArenaOptionsTestFriend::NewWithoutAllocs;
1352   }
1353 
ArenaOptionsTestFriend(bool record_allocs)1354   explicit ArenaOptionsTestFriend(bool record_allocs)
1355       : record_allocs_(record_allocs) {
1356     ++hooks_num_init;
1357   }
OnDestroy(uint64 space_allocated)1358   void OnDestroy(uint64 space_allocated) override {
1359     ++hooks_num_destruct;
1360     delete this;
1361   }
OnReset(uint64 space_allocated)1362   void OnReset(uint64 space_allocated) override { ++hooks_num_reset; }
RecordAllocs()1363   bool RecordAllocs() override { return record_allocs_; }
OnAlloc(const std::type_info * allocated_type,uint64 alloc_size)1364   void OnAlloc(const std::type_info* allocated_type,
1365                uint64 alloc_size) override {
1366     ++hooks_num_allocations;
1367   }
1368 
1369  private:
1370   bool record_allocs_;
1371 };
1372 
1373 // Test the hooks are correctly called.
TEST(ArenaTest,ArenaHooksSanity)1374 TEST(ArenaTest, ArenaHooksSanity) {
1375   ArenaOptions options;
1376   ArenaOptionsTestFriend::Enable(&options);
1377 
1378   // Scope for defining the arena
1379   {
1380     Arena arena(options);
1381     EXPECT_EQ(1, hooks_num_init);
1382     EXPECT_EQ(0, hooks_num_allocations);
1383     Arena::Create<uint64>(&arena);
1384     if (std::is_trivially_destructible<uint64>::value) {
1385       EXPECT_EQ(1, hooks_num_allocations);
1386     } else {
1387       EXPECT_EQ(2, hooks_num_allocations);
1388     }
1389     arena.Reset();
1390     arena.Reset();
1391     EXPECT_EQ(2, hooks_num_reset);
1392   }
1393   EXPECT_EQ(2, hooks_num_reset);
1394   EXPECT_EQ(1, hooks_num_destruct);
1395 }
1396 
1397 // Test that allocation hooks are not called when we don't need them.
TEST(ArenaTest,ArenaHooksWhenAllocationsNotNeeded)1398 TEST(ArenaTest, ArenaHooksWhenAllocationsNotNeeded) {
1399   ArenaOptions options;
1400   ArenaOptionsTestFriend::EnableWithoutAllocs(&options);
1401 
1402   Arena arena(options);
1403   EXPECT_EQ(0, hooks_num_allocations);
1404   Arena::Create<uint64>(&arena);
1405   EXPECT_EQ(0, hooks_num_allocations);
1406 }
1407 
1408 
1409 }  // namespace protobuf
1410 }  // namespace google
1411