• 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 <cstring>
35 #include <memory>
36 #include <string>
37 #include <type_traits>
38 #include <typeinfo>
39 #include <vector>
40 
41 #include <google/protobuf/stubs/logging.h>
42 #include <google/protobuf/stubs/common.h>
43 #include <google/protobuf/arena_test_util.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/unittest_no_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 using proto2_arena_unittest::ArenaMessage;
62 using protobuf_unittest::TestAllExtensions;
63 using protobuf_unittest::TestAllTypes;
64 using protobuf_unittest::TestEmptyMessage;
65 using protobuf_unittest::TestOneof2;
66 using protobuf_unittest_no_arena::TestNoArenaMessage;
67 
68 namespace google {
69 namespace protobuf {
70 
71 class Notifier {
72  public:
Notifier()73   Notifier() : count_(0) {}
Notify()74   void Notify() { count_++; }
GetCount()75   int GetCount() { return count_; }
76 
77  private:
78   int count_;
79 };
80 
81 class SimpleDataType {
82  public:
SimpleDataType()83   SimpleDataType() : notifier_(NULL) {}
SetNotifier(Notifier * notifier)84   void SetNotifier(Notifier* notifier) { notifier_ = notifier; }
~SimpleDataType()85   virtual ~SimpleDataType() {
86     if (notifier_ != NULL) {
87       notifier_->Notify();
88     }
89   };
90 
91  private:
92   Notifier* notifier_;
93 };
94 
95 // A simple class that does not allow copying and so cannot be used as a
96 // parameter type without "const &".
97 class PleaseDontCopyMe {
98  public:
PleaseDontCopyMe(int value)99   explicit PleaseDontCopyMe(int value) : value_(value) {}
100 
value() const101   int value() const { return value_; }
102 
103  private:
104   int value_;
105   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PleaseDontCopyMe);
106 };
107 
108 // A class that takes four different types as constructor arguments.
109 class MustBeConstructedWithOneThroughFour {
110  public:
MustBeConstructedWithOneThroughFour(int one,const char * two,const std::string & three,const PleaseDontCopyMe * four)111   MustBeConstructedWithOneThroughFour(int one, const char* two,
112                                       const std::string& three,
113                                       const PleaseDontCopyMe* four)
114       : one_(one), two_(two), three_(three), four_(four) {}
115 
116   int one_;
117   const char* const two_;
118   std::string three_;
119   const PleaseDontCopyMe* four_;
120 
121  private:
122   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MustBeConstructedWithOneThroughFour);
123 };
124 
125 // A class that takes eight different types as constructor arguments.
126 class MustBeConstructedWithOneThroughEight {
127  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)128   MustBeConstructedWithOneThroughEight(int one, const char* two,
129                                        const std::string& three,
130                                        const PleaseDontCopyMe* four, int five,
131                                        const char* six,
132                                        const std::string& seven,
133                                        const std::string& eight)
134       : one_(one),
135         two_(two),
136         three_(three),
137         four_(four),
138         five_(five),
139         six_(six),
140         seven_(seven),
141         eight_(eight) {}
142 
143   int one_;
144   const char* const two_;
145   std::string three_;
146   const PleaseDontCopyMe* four_;
147   int five_;
148   const char* const six_;
149   std::string seven_;
150   std::string eight_;
151 
152  private:
153   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MustBeConstructedWithOneThroughEight);
154 };
155 
TEST(ArenaTest,ArenaConstructable)156 TEST(ArenaTest, ArenaConstructable) {
157   EXPECT_TRUE(Arena::is_arena_constructable<TestAllTypes>::type::value);
158   EXPECT_TRUE(Arena::is_arena_constructable<const TestAllTypes>::type::value);
159   EXPECT_FALSE(Arena::is_arena_constructable<TestNoArenaMessage>::type::value);
160   EXPECT_FALSE(Arena::is_arena_constructable<Arena>::type::value);
161 }
162 
TEST(ArenaTest,DestructorSkippable)163 TEST(ArenaTest, DestructorSkippable) {
164   EXPECT_TRUE(Arena::is_destructor_skippable<TestAllTypes>::type::value);
165   EXPECT_TRUE(Arena::is_destructor_skippable<const TestAllTypes>::type::value);
166   EXPECT_FALSE(Arena::is_destructor_skippable<TestNoArenaMessage>::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 (64 byte) initial block of memory to be used by the
277   // arena allocator; then, allocate an object which will not fit in the
278   // initial block.
279   std::vector<char> arena_block(96);
280   ArenaOptions options;
281   options.initial_block = &arena_block[0];
282   options.initial_block_size = arena_block.size();
283   Arena arena(options);
284 
285   char* p = Arena::CreateArray<char>(&arena, 96);
286   uintptr_t allocation = reinterpret_cast<uintptr_t>(p);
287 
288   // Ensure that the arena allocator did not return memory pointing into the
289   // initial block of memory.
290   uintptr_t arena_start = reinterpret_cast<uintptr_t>(&arena_block[0]);
291   uintptr_t arena_end = arena_start + arena_block.size();
292   EXPECT_FALSE(allocation >= arena_start && allocation < arena_end);
293 
294   // Write to the memory we allocated; this should (but is not guaranteed to)
295   // trigger a check for heap corruption if the object was allocated from the
296   // initially-provided block.
297   memset(p, '\0', 96);
298 }
299 
TEST(ArenaTest,Parsing)300 TEST(ArenaTest, Parsing) {
301   TestAllTypes original;
302   TestUtil::SetAllFields(&original);
303 
304   // Test memory leak.
305   Arena arena;
306   TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
307   arena_message->ParseFromString(original.SerializeAsString());
308   TestUtil::ExpectAllFieldsSet(*arena_message);
309 
310   // Test that string fields have nul terminator bytes (earlier bug).
311   EXPECT_EQ(strlen(original.optional_string().c_str()),
312             strlen(arena_message->optional_string().c_str()));
313 }
314 
TEST(ArenaTest,UnknownFields)315 TEST(ArenaTest, UnknownFields) {
316   TestAllTypes original;
317   TestUtil::SetAllFields(&original);
318 
319   // Test basic parsing into (populating) and reading out of unknown fields on
320   // an arena.
321   Arena arena;
322   TestEmptyMessage* arena_message =
323       Arena::CreateMessage<TestEmptyMessage>(&arena);
324   arena_message->ParseFromString(original.SerializeAsString());
325 
326   TestAllTypes copied;
327   copied.ParseFromString(arena_message->SerializeAsString());
328   TestUtil::ExpectAllFieldsSet(copied);
329 
330   // Exercise UFS manual manipulation (setters).
331   arena_message = Arena::CreateMessage<TestEmptyMessage>(&arena);
332   arena_message->mutable_unknown_fields()->AddVarint(
333       TestAllTypes::kOptionalInt32FieldNumber, 42);
334   copied.Clear();
335   copied.ParseFromString(arena_message->SerializeAsString());
336   EXPECT_TRUE(copied.has_optional_int32());
337   EXPECT_EQ(42, copied.optional_int32());
338 
339   // Exercise UFS swap path.
340   TestEmptyMessage* arena_message_2 =
341       Arena::CreateMessage<TestEmptyMessage>(&arena);
342   arena_message_2->Swap(arena_message);
343   copied.Clear();
344   copied.ParseFromString(arena_message_2->SerializeAsString());
345   EXPECT_TRUE(copied.has_optional_int32());
346   EXPECT_EQ(42, copied.optional_int32());
347 
348   // Test field manipulation.
349   TestEmptyMessage* arena_message_3 =
350       Arena::CreateMessage<TestEmptyMessage>(&arena);
351   arena_message_3->mutable_unknown_fields()->AddVarint(1000, 42);
352   arena_message_3->mutable_unknown_fields()->AddFixed32(1001, 42);
353   arena_message_3->mutable_unknown_fields()->AddFixed64(1002, 42);
354   arena_message_3->mutable_unknown_fields()->AddLengthDelimited(1003);
355   arena_message_3->mutable_unknown_fields()->DeleteSubrange(0, 2);
356   arena_message_3->mutable_unknown_fields()->DeleteByNumber(1002);
357   arena_message_3->mutable_unknown_fields()->DeleteByNumber(1003);
358   EXPECT_TRUE(arena_message_3->unknown_fields().empty());
359 }
360 
TEST(ArenaTest,Swap)361 TEST(ArenaTest, Swap) {
362   Arena arena1;
363   Arena arena2;
364   TestAllTypes* arena1_message;
365   TestAllTypes* arena2_message;
366 
367   // Case 1: Swap(), no UFS on either message, both messages on different
368   // arenas. Arena pointers should remain the same after swap.
369   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
370   arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
371   arena1_message->Swap(arena2_message);
372   EXPECT_EQ(&arena1, arena1_message->GetArena());
373   EXPECT_EQ(&arena2, arena2_message->GetArena());
374 
375   // Case 2: Swap(), UFS on one message, both messages on different arenas.
376   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
377   arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
378   arena1_message->mutable_unknown_fields()->AddVarint(1, 42);
379   arena1_message->Swap(arena2_message);
380   EXPECT_EQ(&arena1, arena1_message->GetArena());
381   EXPECT_EQ(&arena2, arena2_message->GetArena());
382   EXPECT_EQ(0, arena1_message->unknown_fields().field_count());
383   EXPECT_EQ(1, arena2_message->unknown_fields().field_count());
384   EXPECT_EQ(42, arena2_message->unknown_fields().field(0).varint());
385 
386   // Case 3: Swap(), UFS on both messages, both messages on different arenas.
387   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
388   arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
389   arena1_message->mutable_unknown_fields()->AddVarint(1, 42);
390   arena2_message->mutable_unknown_fields()->AddVarint(2, 84);
391   arena1_message->Swap(arena2_message);
392   EXPECT_EQ(&arena1, arena1_message->GetArena());
393   EXPECT_EQ(&arena2, arena2_message->GetArena());
394   EXPECT_EQ(1, arena1_message->unknown_fields().field_count());
395   EXPECT_EQ(1, arena2_message->unknown_fields().field_count());
396   EXPECT_EQ(84, arena1_message->unknown_fields().field(0).varint());
397   EXPECT_EQ(42, arena2_message->unknown_fields().field(0).varint());
398 }
399 
TEST(ArenaTest,ReflectionSwapFields)400 TEST(ArenaTest, ReflectionSwapFields) {
401   Arena arena1;
402   Arena arena2;
403   TestAllTypes* arena1_message;
404   TestAllTypes* arena2_message;
405 
406   // Case 1: messages on different arenas, only one message is set.
407   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
408   arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
409   TestUtil::SetAllFields(arena1_message);
410   const Reflection* reflection = arena1_message->GetReflection();
411   std::vector<const FieldDescriptor*> fields;
412   reflection->ListFields(*arena1_message, &fields);
413   reflection->SwapFields(arena1_message, arena2_message, fields);
414   EXPECT_EQ(&arena1, arena1_message->GetArena());
415   EXPECT_EQ(&arena2, arena2_message->GetArena());
416   std::string output;
417   arena1_message->SerializeToString(&output);
418   EXPECT_EQ(0, output.size());
419   TestUtil::ExpectAllFieldsSet(*arena2_message);
420   reflection->SwapFields(arena1_message, arena2_message, fields);
421   arena2_message->SerializeToString(&output);
422   EXPECT_EQ(0, output.size());
423   TestUtil::ExpectAllFieldsSet(*arena1_message);
424 
425   // Case 2: messages on different arenas, both messages are set.
426   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
427   arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
428   TestUtil::SetAllFields(arena1_message);
429   TestUtil::SetAllFields(arena2_message);
430   reflection->SwapFields(arena1_message, arena2_message, fields);
431   EXPECT_EQ(&arena1, arena1_message->GetArena());
432   EXPECT_EQ(&arena2, arena2_message->GetArena());
433   TestUtil::ExpectAllFieldsSet(*arena1_message);
434   TestUtil::ExpectAllFieldsSet(*arena2_message);
435 
436   // Case 3: messages on different arenas with different lifetimes.
437   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
438   {
439     Arena arena3;
440     TestAllTypes* arena3_message = Arena::CreateMessage<TestAllTypes>(&arena3);
441     TestUtil::SetAllFields(arena3_message);
442     reflection->SwapFields(arena1_message, arena3_message, fields);
443   }
444   TestUtil::ExpectAllFieldsSet(*arena1_message);
445 
446   // Case 4: one message on arena, the other on heap.
447   arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
448   TestAllTypes message;
449   TestUtil::SetAllFields(arena1_message);
450   reflection->SwapFields(arena1_message, &message, fields);
451   EXPECT_EQ(&arena1, arena1_message->GetArena());
452   EXPECT_EQ(nullptr, message.GetArena());
453   arena1_message->SerializeToString(&output);
454   EXPECT_EQ(0, output.size());
455   TestUtil::ExpectAllFieldsSet(message);
456 }
457 
TEST(ArenaTest,SetAllocatedMessage)458 TEST(ArenaTest, SetAllocatedMessage) {
459   Arena arena;
460   TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
461   TestAllTypes::NestedMessage* nested = new TestAllTypes::NestedMessage;
462   nested->set_bb(118);
463   arena_message->set_allocated_optional_nested_message(nested);
464   EXPECT_EQ(118, arena_message->optional_nested_message().bb());
465 
466   TestNoArenaMessage no_arena_message;
467   EXPECT_FALSE(no_arena_message.has_arena_message());
468   no_arena_message.set_allocated_arena_message(NULL);
469   EXPECT_FALSE(no_arena_message.has_arena_message());
470   no_arena_message.set_allocated_arena_message(new ArenaMessage);
471   EXPECT_TRUE(no_arena_message.has_arena_message());
472 }
473 
TEST(ArenaTest,ReleaseMessage)474 TEST(ArenaTest, ReleaseMessage) {
475   Arena arena;
476   TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
477   arena_message->mutable_optional_nested_message()->set_bb(118);
478   std::unique_ptr<TestAllTypes::NestedMessage> nested(
479       arena_message->release_optional_nested_message());
480   EXPECT_EQ(118, nested->bb());
481 
482   TestAllTypes::NestedMessage* released_null =
483       arena_message->release_optional_nested_message();
484   EXPECT_EQ(NULL, released_null);
485 }
486 
TEST(ArenaTest,SetAllocatedString)487 TEST(ArenaTest, SetAllocatedString) {
488   Arena arena;
489   TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
490   std::string* allocated_str = new std::string("hello");
491   arena_message->set_allocated_optional_string(allocated_str);
492   EXPECT_EQ("hello", arena_message->optional_string());
493 }
494 
TEST(ArenaTest,ReleaseString)495 TEST(ArenaTest, ReleaseString) {
496   Arena arena;
497   TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
498   arena_message->set_optional_string("hello");
499   std::unique_ptr<std::string> released_str(
500       arena_message->release_optional_string());
501   EXPECT_EQ("hello", *released_str);
502 
503   // Test default value.
504 }
505 
506 
TEST(ArenaTest,SwapBetweenArenasWithAllFieldsSet)507 TEST(ArenaTest, SwapBetweenArenasWithAllFieldsSet) {
508   Arena arena1;
509   TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
510   {
511     Arena arena2;
512     TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
513     TestUtil::SetAllFields(arena2_message);
514     arena2_message->Swap(arena1_message);
515     std::string output;
516     arena2_message->SerializeToString(&output);
517     EXPECT_EQ(0, output.size());
518   }
519   TestUtil::ExpectAllFieldsSet(*arena1_message);
520 }
521 
TEST(ArenaTest,SwapBetweenArenaAndNonArenaWithAllFieldsSet)522 TEST(ArenaTest, SwapBetweenArenaAndNonArenaWithAllFieldsSet) {
523   TestAllTypes non_arena_message;
524   TestUtil::SetAllFields(&non_arena_message);
525   {
526     Arena arena2;
527     TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
528     TestUtil::SetAllFields(arena2_message);
529     arena2_message->Swap(&non_arena_message);
530     TestUtil::ExpectAllFieldsSet(*arena2_message);
531     TestUtil::ExpectAllFieldsSet(non_arena_message);
532   }
533 }
534 
TEST(ArenaTest,UnsafeArenaSwap)535 TEST(ArenaTest, UnsafeArenaSwap) {
536   Arena shared_arena;
537   TestAllTypes* message1 = Arena::CreateMessage<TestAllTypes>(&shared_arena);
538   TestAllTypes* message2 = Arena::CreateMessage<TestAllTypes>(&shared_arena);
539   TestUtil::SetAllFields(message1);
540   message1->UnsafeArenaSwap(message2);
541   TestUtil::ExpectAllFieldsSet(*message2);
542 }
543 
TEST(ArenaTest,SwapBetweenArenasUsingReflection)544 TEST(ArenaTest, SwapBetweenArenasUsingReflection) {
545   Arena arena1;
546   TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
547   {
548     Arena arena2;
549     TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
550     TestUtil::SetAllFields(arena2_message);
551     const Reflection* r = arena2_message->GetReflection();
552     r->Swap(arena1_message, arena2_message);
553     std::string output;
554     arena2_message->SerializeToString(&output);
555     EXPECT_EQ(0, output.size());
556   }
557   TestUtil::ExpectAllFieldsSet(*arena1_message);
558 }
559 
TEST(ArenaTest,SwapBetweenArenaAndNonArenaUsingReflection)560 TEST(ArenaTest, SwapBetweenArenaAndNonArenaUsingReflection) {
561   TestAllTypes non_arena_message;
562   TestUtil::SetAllFields(&non_arena_message);
563   {
564     Arena arena2;
565     TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
566     TestUtil::SetAllFields(arena2_message);
567     const Reflection* r = arena2_message->GetReflection();
568     r->Swap(&non_arena_message, arena2_message);
569     TestUtil::ExpectAllFieldsSet(*arena2_message);
570     TestUtil::ExpectAllFieldsSet(non_arena_message);
571   }
572 }
573 
TEST(ArenaTest,ReleaseFromArenaMessageMakesCopy)574 TEST(ArenaTest, ReleaseFromArenaMessageMakesCopy) {
575   TestAllTypes::NestedMessage* nested_msg = NULL;
576   std::string* nested_string = NULL;
577   {
578     Arena arena;
579     TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
580     arena_message->mutable_optional_nested_message()->set_bb(42);
581     *arena_message->mutable_optional_string() = "Hello";
582     nested_msg = arena_message->release_optional_nested_message();
583     nested_string = arena_message->release_optional_string();
584   }
585   EXPECT_EQ(42, nested_msg->bb());
586   EXPECT_EQ("Hello", *nested_string);
587   delete nested_msg;
588   delete nested_string;
589 }
590 
591 #if PROTOBUF_RTTI
TEST(ArenaTest,ReleaseFromArenaMessageUsingReflectionMakesCopy)592 TEST(ArenaTest, ReleaseFromArenaMessageUsingReflectionMakesCopy) {
593   TestAllTypes::NestedMessage* nested_msg = NULL;
594   // Note: no string: reflection API only supports releasing submessages.
595   {
596     Arena arena;
597     TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
598     arena_message->mutable_optional_nested_message()->set_bb(42);
599     const Reflection* r = arena_message->GetReflection();
600     const FieldDescriptor* f = arena_message->GetDescriptor()->FindFieldByName(
601         "optional_nested_message");
602     nested_msg = static_cast<TestAllTypes::NestedMessage*>(
603         r->ReleaseMessage(arena_message, f));
604   }
605   EXPECT_EQ(42, nested_msg->bb());
606   delete nested_msg;
607 }
608 #endif  // PROTOBUF_RTTI
609 
TEST(ArenaTest,SetAllocatedAcrossArenas)610 TEST(ArenaTest, SetAllocatedAcrossArenas) {
611   Arena arena1;
612   TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
613   TestAllTypes::NestedMessage* heap_submessage =
614       new TestAllTypes::NestedMessage();
615   heap_submessage->set_bb(42);
616   arena1_message->set_allocated_optional_nested_message(heap_submessage);
617   // Should keep same object and add to arena's Own()-list.
618   EXPECT_EQ(heap_submessage, arena1_message->mutable_optional_nested_message());
619   {
620     Arena arena2;
621     TestAllTypes::NestedMessage* arena2_submessage =
622         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
623     arena2_submessage->set_bb(42);
624     arena1_message->set_allocated_optional_nested_message(arena2_submessage);
625     EXPECT_NE(arena2_submessage,
626               arena1_message->mutable_optional_nested_message());
627   }
628 
629   TestAllTypes::NestedMessage* arena1_submessage =
630       Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
631   arena1_submessage->set_bb(42);
632   TestAllTypes* heap_message = new TestAllTypes;
633   heap_message->set_allocated_optional_nested_message(arena1_submessage);
634   EXPECT_NE(arena1_submessage, heap_message->mutable_optional_nested_message());
635   delete heap_message;
636 }
637 
TEST(ArenaTest,SetAllocatedAcrossArenasWithReflection)638 TEST(ArenaTest, SetAllocatedAcrossArenasWithReflection) {
639   // Same as above, with reflection.
640   Arena arena1;
641   TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
642   const Reflection* r = arena1_message->GetReflection();
643   const Descriptor* d = arena1_message->GetDescriptor();
644   const FieldDescriptor* msg_field =
645       d->FindFieldByName("optional_nested_message");
646   TestAllTypes::NestedMessage* heap_submessage =
647       new TestAllTypes::NestedMessage();
648   heap_submessage->set_bb(42);
649   r->SetAllocatedMessage(arena1_message, heap_submessage, msg_field);
650   // Should keep same object and add to arena's Own()-list.
651   EXPECT_EQ(heap_submessage, arena1_message->mutable_optional_nested_message());
652   {
653     Arena arena2;
654     TestAllTypes::NestedMessage* arena2_submessage =
655         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
656     arena2_submessage->set_bb(42);
657     r->SetAllocatedMessage(arena1_message, arena2_submessage, msg_field);
658     EXPECT_NE(arena2_submessage,
659               arena1_message->mutable_optional_nested_message());
660   }
661 
662   TestAllTypes::NestedMessage* arena1_submessage =
663       Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
664   arena1_submessage->set_bb(42);
665   TestAllTypes* heap_message = new TestAllTypes;
666   r->SetAllocatedMessage(heap_message, arena1_submessage, msg_field);
667   EXPECT_NE(arena1_submessage, heap_message->mutable_optional_nested_message());
668   delete heap_message;
669 }
670 
TEST(ArenaTest,AddAllocatedWithReflection)671 TEST(ArenaTest, AddAllocatedWithReflection) {
672   Arena arena1;
673   ArenaMessage* arena1_message = Arena::CreateMessage<ArenaMessage>(&arena1);
674   const Reflection* r = arena1_message->GetReflection();
675   const Descriptor* d = arena1_message->GetDescriptor();
676   const FieldDescriptor* fd =
677       d->FindFieldByName("repeated_import_no_arena_message");
678   // Message with cc_enable_arenas = false;
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   // Message with cc_enable_arenas = true;
684   fd = d->FindFieldByName("repeated_nested_message");
685   r->AddMessage(arena1_message, fd);
686   r->AddMessage(arena1_message, fd);
687   r->AddMessage(arena1_message, fd);
688   EXPECT_EQ(3, r->FieldSize(*arena1_message, fd));
689 }
690 
TEST(ArenaTest,RepeatedPtrFieldAddClearedTest)691 TEST(ArenaTest, RepeatedPtrFieldAddClearedTest) {
692   {
693     RepeatedPtrField<TestAllTypes> repeated_field;
694     EXPECT_TRUE(repeated_field.empty());
695     EXPECT_EQ(0, repeated_field.size());
696     // Ownership is passed to repeated_field.
697     TestAllTypes* cleared = new TestAllTypes();
698     repeated_field.AddCleared(cleared);
699     EXPECT_TRUE(repeated_field.empty());
700     EXPECT_EQ(0, repeated_field.size());
701   }
702   {
703     RepeatedPtrField<TestAllTypes> repeated_field;
704     EXPECT_TRUE(repeated_field.empty());
705     EXPECT_EQ(0, repeated_field.size());
706     // Ownership is passed to repeated_field.
707     TestAllTypes* cleared = new TestAllTypes();
708     repeated_field.AddAllocated(cleared);
709     EXPECT_FALSE(repeated_field.empty());
710     EXPECT_EQ(1, repeated_field.size());
711   }
712 }
713 
TEST(ArenaTest,AddAllocatedToRepeatedField)714 TEST(ArenaTest, AddAllocatedToRepeatedField) {
715   // Heap->arena case.
716   Arena arena1;
717   TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
718   for (int i = 0; i < 10; i++) {
719     TestAllTypes::NestedMessage* heap_submessage =
720         new TestAllTypes::NestedMessage();
721     heap_submessage->set_bb(42);
722     arena1_message->mutable_repeated_nested_message()->AddAllocated(
723         heap_submessage);
724     // Should not copy object -- will use arena_->Own().
725     EXPECT_EQ(heap_submessage, &arena1_message->repeated_nested_message(i));
726     EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
727   }
728 
729   // Arena1->Arena2 case.
730   arena1_message->Clear();
731   for (int i = 0; i < 10; i++) {
732     Arena arena2;
733     TestAllTypes::NestedMessage* arena2_submessage =
734         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
735     arena2_submessage->set_bb(42);
736     arena1_message->mutable_repeated_nested_message()->AddAllocated(
737         arena2_submessage);
738     // Should copy object.
739     EXPECT_NE(arena2_submessage, &arena1_message->repeated_nested_message(i));
740     EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
741   }
742 
743   // Arena->heap case.
744   TestAllTypes* heap_message = new TestAllTypes();
745   for (int i = 0; i < 10; i++) {
746     Arena arena2;
747     TestAllTypes::NestedMessage* arena2_submessage =
748         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
749     arena2_submessage->set_bb(42);
750     heap_message->mutable_repeated_nested_message()->AddAllocated(
751         arena2_submessage);
752     // Should copy object.
753     EXPECT_NE(arena2_submessage, &heap_message->repeated_nested_message(i));
754     EXPECT_EQ(42, heap_message->repeated_nested_message(i).bb());
755   }
756   delete heap_message;
757 
758   // Heap-arena case for strings (which are not arena-allocated).
759   arena1_message->Clear();
760   for (int i = 0; i < 10; i++) {
761     std::string* s = new std::string("Test");
762     arena1_message->mutable_repeated_string()->AddAllocated(s);
763     // Should not copy.
764     EXPECT_EQ(s, &arena1_message->repeated_string(i));
765     EXPECT_EQ("Test", arena1_message->repeated_string(i));
766   }
767 }
768 
TEST(ArenaTest,AddAllocatedToRepeatedFieldViaReflection)769 TEST(ArenaTest, AddAllocatedToRepeatedFieldViaReflection) {
770   // Heap->arena case.
771   Arena arena1;
772   TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
773   const Reflection* r = arena1_message->GetReflection();
774   const Descriptor* d = arena1_message->GetDescriptor();
775   const FieldDescriptor* fd = d->FindFieldByName("repeated_nested_message");
776   for (int i = 0; i < 10; i++) {
777     TestAllTypes::NestedMessage* heap_submessage =
778         new TestAllTypes::NestedMessage;
779     heap_submessage->set_bb(42);
780     r->AddAllocatedMessage(arena1_message, fd, heap_submessage);
781     // Should not copy object -- will use arena_->Own().
782     EXPECT_EQ(heap_submessage, &arena1_message->repeated_nested_message(i));
783     EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
784   }
785 
786   // Arena1->Arena2 case.
787   arena1_message->Clear();
788   for (int i = 0; i < 10; i++) {
789     Arena arena2;
790     TestAllTypes::NestedMessage* arena2_submessage =
791         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
792     arena2_submessage->set_bb(42);
793     r->AddAllocatedMessage(arena1_message, fd, arena2_submessage);
794     // Should copy object.
795     EXPECT_NE(arena2_submessage, &arena1_message->repeated_nested_message(i));
796     EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
797   }
798 
799   // Arena->heap case.
800   TestAllTypes* heap_message = new TestAllTypes;
801   for (int i = 0; i < 10; i++) {
802     Arena arena2;
803     TestAllTypes::NestedMessage* arena2_submessage =
804         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
805     arena2_submessage->set_bb(42);
806     r->AddAllocatedMessage(heap_message, fd, arena2_submessage);
807     // Should copy object.
808     EXPECT_NE(arena2_submessage, &heap_message->repeated_nested_message(i));
809     EXPECT_EQ(42, heap_message->repeated_nested_message(i).bb());
810   }
811   delete heap_message;
812 }
813 
TEST(ArenaTest,ReleaseLastRepeatedField)814 TEST(ArenaTest, ReleaseLastRepeatedField) {
815   // Release from arena-allocated repeated field and ensure that returned object
816   // is heap-allocated.
817   Arena arena;
818   TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
819   for (int i = 0; i < 10; i++) {
820     TestAllTypes::NestedMessage* nested =
821         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena);
822     nested->set_bb(42);
823     arena_message->mutable_repeated_nested_message()->AddAllocated(nested);
824   }
825 
826   for (int i = 0; i < 10; i++) {
827     const TestAllTypes::NestedMessage* orig_submessage =
828         &arena_message->repeated_nested_message(10 - 1 - i);  // last element
829     TestAllTypes::NestedMessage* released =
830         arena_message->mutable_repeated_nested_message()->ReleaseLast();
831     EXPECT_NE(released, orig_submessage);
832     EXPECT_EQ(42, released->bb());
833     delete released;
834   }
835 
836   // Test UnsafeArenaReleaseLast().
837   for (int i = 0; i < 10; i++) {
838     TestAllTypes::NestedMessage* nested =
839         Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena);
840     nested->set_bb(42);
841     arena_message->mutable_repeated_nested_message()->AddAllocated(nested);
842   }
843 
844   for (int i = 0; i < 10; i++) {
845     const TestAllTypes::NestedMessage* orig_submessage =
846         &arena_message->repeated_nested_message(10 - 1 - i);  // last element
847     TestAllTypes::NestedMessage* released =
848         arena_message->mutable_repeated_nested_message()
849             ->UnsafeArenaReleaseLast();
850     EXPECT_EQ(released, orig_submessage);
851     EXPECT_EQ(42, released->bb());
852     // no delete -- |released| is on the arena.
853   }
854 
855   // Test string case as well. ReleaseLast() in this case must copy the
856   // string, even though it was originally heap-allocated and its pointer
857   // was simply appended to the repeated field's internal vector, because the
858   // string was placed on the arena's destructor list and cannot be removed
859   // from that list (so the arena permanently owns the original instance).
860   arena_message->Clear();
861   for (int i = 0; i < 10; i++) {
862     std::string* s = new std::string("Test");
863     arena_message->mutable_repeated_string()->AddAllocated(s);
864   }
865   for (int i = 0; i < 10; i++) {
866     const std::string* orig_element =
867         &arena_message->repeated_string(10 - 1 - i);
868     std::string* released =
869         arena_message->mutable_repeated_string()->ReleaseLast();
870     EXPECT_NE(released, orig_element);
871     EXPECT_EQ("Test", *released);
872     delete released;
873   }
874 }
875 
TEST(ArenaTest,UnsafeArenaReleaseAdd)876 TEST(ArenaTest, UnsafeArenaReleaseAdd) {
877   // Use unsafe_arena_release() and unsafe_arena_set_allocated() to transfer an
878   // arena-allocated string from one message to another.
879   const char kContent[] = "Test content";
880 
881   Arena arena;
882   TestAllTypes* message1 = Arena::CreateMessage<TestAllTypes>(&arena);
883   TestAllTypes* message2 = Arena::CreateMessage<TestAllTypes>(&arena);
884   std::string* arena_string = Arena::Create<std::string>(&arena);
885   *arena_string = kContent;
886 
887   message1->unsafe_arena_set_allocated_optional_string(arena_string);
888   message2->unsafe_arena_set_allocated_optional_string(
889       message1->unsafe_arena_release_optional_string());
890   EXPECT_EQ(kContent, message2->optional_string());
891 }
892 
TEST(ArenaTest,UnsafeArenaAddAllocated)893 TEST(ArenaTest, UnsafeArenaAddAllocated) {
894   Arena arena;
895   TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
896   for (int i = 0; i < 10; i++) {
897     std::string* arena_string = Arena::Create<std::string>(&arena);
898     message->mutable_repeated_string()->UnsafeArenaAddAllocated(arena_string);
899     EXPECT_EQ(arena_string, message->mutable_repeated_string(i));
900   }
901 }
902 
TEST(ArenaTest,UnsafeArenaRelease)903 TEST(ArenaTest, UnsafeArenaRelease) {
904   Arena arena;
905   TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
906 
907   std::string* s = new std::string("test string");
908   message->unsafe_arena_set_allocated_optional_string(s);
909   EXPECT_TRUE(message->has_optional_string());
910   EXPECT_EQ("test string", message->optional_string());
911   s = message->unsafe_arena_release_optional_string();
912   EXPECT_FALSE(message->has_optional_string());
913   delete s;
914 
915   s = new std::string("test string");
916   message->unsafe_arena_set_allocated_oneof_string(s);
917   EXPECT_TRUE(message->has_oneof_string());
918   EXPECT_EQ("test string", message->oneof_string());
919   s = message->unsafe_arena_release_oneof_string();
920   EXPECT_FALSE(message->has_oneof_string());
921   delete s;
922 }
923 
TEST(ArenaTest,OneofMerge)924 TEST(ArenaTest, OneofMerge) {
925   Arena arena;
926   TestAllTypes* message0 = Arena::CreateMessage<TestAllTypes>(&arena);
927   TestAllTypes* message1 = Arena::CreateMessage<TestAllTypes>(&arena);
928 
929   message0->unsafe_arena_set_allocated_oneof_string(new std::string("x"));
930   ASSERT_TRUE(message0->has_oneof_string());
931   message1->unsafe_arena_set_allocated_oneof_string(new std::string("y"));
932   ASSERT_TRUE(message1->has_oneof_string());
933   EXPECT_EQ("x", message0->oneof_string());
934   EXPECT_EQ("y", message1->oneof_string());
935   message0->MergeFrom(*message1);
936   EXPECT_EQ("y", message0->oneof_string());
937   EXPECT_EQ("y", message1->oneof_string());
938   delete message0->unsafe_arena_release_oneof_string();
939   delete message1->unsafe_arena_release_oneof_string();
940 }
941 
TEST(ArenaTest,ArenaOneofReflection)942 TEST(ArenaTest, ArenaOneofReflection) {
943   Arena arena;
944   TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
945   const Descriptor* desc = message->GetDescriptor();
946   const Reflection* refl = message->GetReflection();
947 
948   const FieldDescriptor* string_field = desc->FindFieldByName("oneof_string");
949   const FieldDescriptor* msg_field =
950       desc->FindFieldByName("oneof_nested_message");
951   const OneofDescriptor* oneof = desc->FindOneofByName("oneof_field");
952 
953   refl->SetString(message, string_field, "Test value");
954   EXPECT_TRUE(refl->HasOneof(*message, oneof));
955   refl->ClearOneof(message, oneof);
956   EXPECT_FALSE(refl->HasOneof(*message, oneof));
957 
958   Message* submsg = refl->MutableMessage(message, msg_field);
959   EXPECT_TRUE(refl->HasOneof(*message, oneof));
960   refl->ClearOneof(message, oneof);
961   EXPECT_FALSE(refl->HasOneof(*message, oneof));
962   refl->MutableMessage(message, msg_field);
963   EXPECT_TRUE(refl->HasOneof(*message, oneof));
964   submsg = refl->ReleaseMessage(message, msg_field);
965   EXPECT_FALSE(refl->HasOneof(*message, oneof));
966   EXPECT_TRUE(submsg->GetArena() == NULL);
967   delete submsg;
968 }
969 
TestSwapRepeatedField(Arena * arena1,Arena * arena2)970 void TestSwapRepeatedField(Arena* arena1, Arena* arena2) {
971   // Test "safe" (copying) semantics for direct Swap() on RepeatedPtrField
972   // between arenas.
973   RepeatedPtrField<TestAllTypes> field1(arena1);
974   RepeatedPtrField<TestAllTypes> field2(arena2);
975   for (int i = 0; i < 10; i++) {
976     TestAllTypes* t = Arena::CreateMessage<TestAllTypes>(arena1);
977     t->set_optional_string("field1");
978     t->set_optional_int32(i);
979     if (arena1 != NULL) {
980       field1.UnsafeArenaAddAllocated(t);
981     } else {
982       field1.AddAllocated(t);
983     }
984   }
985   for (int i = 0; i < 5; i++) {
986     TestAllTypes* t = Arena::CreateMessage<TestAllTypes>(arena2);
987     t->set_optional_string("field2");
988     t->set_optional_int32(i);
989     if (arena2 != NULL) {
990       field2.UnsafeArenaAddAllocated(t);
991     } else {
992       field2.AddAllocated(t);
993     }
994   }
995   field1.Swap(&field2);
996   EXPECT_EQ(5, field1.size());
997   EXPECT_EQ(10, field2.size());
998   EXPECT_TRUE(std::string("field1") == field2.Get(0).optional_string());
999   EXPECT_TRUE(std::string("field2") == field1.Get(0).optional_string());
1000   // Ensure that fields retained their original order:
1001   for (int i = 0; i < field1.size(); i++) {
1002     EXPECT_EQ(i, field1.Get(i).optional_int32());
1003   }
1004   for (int i = 0; i < field2.size(); i++) {
1005     EXPECT_EQ(i, field2.Get(i).optional_int32());
1006   }
1007 }
1008 
TEST(ArenaTest,SwapRepeatedField)1009 TEST(ArenaTest, SwapRepeatedField) {
1010   Arena arena;
1011   TestSwapRepeatedField(&arena, &arena);
1012 }
1013 
TEST(ArenaTest,SwapRepeatedFieldWithDifferentArenas)1014 TEST(ArenaTest, SwapRepeatedFieldWithDifferentArenas) {
1015   Arena arena1;
1016   Arena arena2;
1017   TestSwapRepeatedField(&arena1, &arena2);
1018 }
1019 
TEST(ArenaTest,SwapRepeatedFieldWithNoArenaOnRightHandSide)1020 TEST(ArenaTest, SwapRepeatedFieldWithNoArenaOnRightHandSide) {
1021   Arena arena;
1022   TestSwapRepeatedField(&arena, NULL);
1023 }
1024 
TEST(ArenaTest,SwapRepeatedFieldWithNoArenaOnLeftHandSide)1025 TEST(ArenaTest, SwapRepeatedFieldWithNoArenaOnLeftHandSide) {
1026   Arena arena;
1027   TestSwapRepeatedField(NULL, &arena);
1028 }
1029 
TEST(ArenaTest,ExtensionsOnArena)1030 TEST(ArenaTest, ExtensionsOnArena) {
1031   Arena arena;
1032   // Ensure no leaks.
1033   TestAllExtensions* message_ext =
1034       Arena::CreateMessage<TestAllExtensions>(&arena);
1035   message_ext->SetExtension(protobuf_unittest::optional_int32_extension, 42);
1036   message_ext->SetExtension(protobuf_unittest::optional_string_extension,
1037                             std::string("test"));
1038   message_ext
1039       ->MutableExtension(protobuf_unittest::optional_nested_message_extension)
1040       ->set_bb(42);
1041 }
1042 
TEST(ArenaTest,RepeatedFieldOnArena)1043 TEST(ArenaTest, RepeatedFieldOnArena) {
1044   // Preallocate an initial arena block to avoid mallocs during hooked region.
1045   std::vector<char> arena_block(1024 * 1024);
1046   ArenaOptions options;
1047   options.initial_block = &arena_block[0];
1048   options.initial_block_size = arena_block.size();
1049   Arena arena(options);
1050 
1051   {
1052     internal::NoHeapChecker no_heap;
1053 
1054     // Fill some repeated fields on the arena to test for leaks. Also verify no
1055     // memory allocations.
1056     RepeatedField<int32> repeated_int32(&arena);
1057     RepeatedPtrField<TestAllTypes> repeated_message(&arena);
1058     for (int i = 0; i < 100; i++) {
1059       repeated_int32.Add(42);
1060       repeated_message.Add()->set_optional_int32(42);
1061       EXPECT_EQ(&arena, repeated_message.Get(0).GetArena());
1062       const TestAllTypes* msg_in_repeated_field = &repeated_message.Get(0);
1063       TestAllTypes* msg = repeated_message.UnsafeArenaReleaseLast();
1064       EXPECT_EQ(msg_in_repeated_field, msg);
1065     }
1066 
1067     // UnsafeArenaExtractSubrange (i) should not leak and (ii) should return
1068     // on-arena pointers.
1069     for (int i = 0; i < 10; i++) {
1070       repeated_message.Add()->set_optional_int32(42);
1071     }
1072     TestAllTypes* extracted_messages[5];
1073     repeated_message.UnsafeArenaExtractSubrange(0, 5, extracted_messages);
1074     EXPECT_EQ(&arena, repeated_message.Get(0).GetArena());
1075     EXPECT_EQ(5, repeated_message.size());
1076   }
1077 
1078   // Now, outside the scope of the NoHeapChecker, test ExtractSubrange's copying
1079   // semantics.
1080   {
1081     RepeatedPtrField<TestAllTypes> repeated_message(&arena);
1082     for (int i = 0; i < 100; i++) {
1083       repeated_message.Add()->set_optional_int32(42);
1084     }
1085 
1086     TestAllTypes* extracted_messages[5];
1087     // ExtractSubrange should copy to the heap.
1088     repeated_message.ExtractSubrange(0, 5, extracted_messages);
1089     EXPECT_EQ(NULL, extracted_messages[0]->GetArena());
1090     // We need to free the heap-allocated messages to prevent a leak.
1091     for (int i = 0; i < 5; i++) {
1092       delete extracted_messages[i];
1093       extracted_messages[i] = NULL;
1094     }
1095   }
1096 
1097   // Now check that we can create RepeatedFields/RepeatedPtrFields themselves on
1098   // the arena. They have the necessary type traits so that they can behave like
1099   // messages in this way. This is useful for higher-level generic templated
1100   // code that may allocate messages or repeated fields of messages on an arena.
1101   {
1102     RepeatedPtrField<TestAllTypes>* repeated_ptr_on_arena =
1103         Arena::CreateMessage<RepeatedPtrField<TestAllTypes> >(&arena);
1104     for (int i = 0; i < 10; i++) {
1105       // Add some elements and let the leak-checker ensure that everything is
1106       // freed.
1107       repeated_ptr_on_arena->Add();
1108     }
1109 
1110     RepeatedField<int>* repeated_int_on_arena =
1111         Arena::CreateMessage<RepeatedField<int> >(&arena);
1112     for (int i = 0; i < 100; i++) {
1113       repeated_int_on_arena->Add(i);
1114     }
1115 
1116   }
1117 
1118   arena.Reset();
1119 }
1120 
1121 
1122 #if PROTOBUF_RTTI
TEST(ArenaTest,MutableMessageReflection)1123 TEST(ArenaTest, MutableMessageReflection) {
1124   Arena arena;
1125   TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
1126   const Reflection* r = message->GetReflection();
1127   const Descriptor* d = message->GetDescriptor();
1128   const FieldDescriptor* field = d->FindFieldByName("optional_nested_message");
1129   TestAllTypes::NestedMessage* submessage =
1130       static_cast<TestAllTypes::NestedMessage*>(
1131           r->MutableMessage(message, field));
1132   TestAllTypes::NestedMessage* submessage_expected =
1133       message->mutable_optional_nested_message();
1134 
1135   EXPECT_EQ(submessage_expected, submessage);
1136   EXPECT_EQ(&arena, submessage->GetArena());
1137 
1138   const FieldDescriptor* oneof_field =
1139       d->FindFieldByName("oneof_nested_message");
1140   submessage = static_cast<TestAllTypes::NestedMessage*>(
1141       r->MutableMessage(message, oneof_field));
1142   submessage_expected = message->mutable_oneof_nested_message();
1143 
1144   EXPECT_EQ(submessage_expected, submessage);
1145   EXPECT_EQ(&arena, submessage->GetArena());
1146 }
1147 #endif  // PROTOBUF_RTTI
1148 
1149 
FillArenaAwareFields(TestAllTypes * message)1150 void FillArenaAwareFields(TestAllTypes* message) {
1151   std::string test_string = "hello world";
1152   message->set_optional_int32(42);
1153   message->set_optional_string(test_string);
1154   message->set_optional_bytes(test_string);
1155   message->mutable_optional_nested_message()->set_bb(42);
1156 
1157   message->set_oneof_uint32(42);
1158   message->mutable_oneof_nested_message()->set_bb(42);
1159   message->set_oneof_string(test_string);
1160   message->set_oneof_bytes(test_string);
1161 
1162   message->add_repeated_int32(42);
1163   // No repeated string: not yet arena-aware.
1164   message->add_repeated_nested_message()->set_bb(42);
1165   message->mutable_optional_lazy_message()->set_bb(42);
1166 }
1167 
1168 // Test: no allocations occur on heap while touching all supported field types.
TEST(ArenaTest,NoHeapAllocationsTest)1169 TEST(ArenaTest, NoHeapAllocationsTest) {
1170   // Allocate a large initial block to avoid mallocs during hooked test.
1171   std::vector<char> arena_block(128 * 1024);
1172   ArenaOptions options;
1173   options.initial_block = &arena_block[0];
1174   options.initial_block_size = arena_block.size();
1175   Arena arena(options);
1176 
1177   {
1178 
1179     TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
1180     FillArenaAwareFields(message);
1181   }
1182 
1183   arena.Reset();
1184 }
1185 
TEST(ArenaTest,ParseCorruptedString)1186 TEST(ArenaTest, ParseCorruptedString) {
1187   TestAllTypes message;
1188   TestUtil::SetAllFields(&message);
1189   TestParseCorruptedString<TestAllTypes, true>(message);
1190   TestParseCorruptedString<TestAllTypes, false>(message);
1191 }
1192 
1193 #if PROTOBUF_RTTI
1194 // Test construction on an arena via generic MessageLite interface. We should be
1195 // able to successfully deserialize on the arena without incurring heap
1196 // allocations, i.e., everything should still be arena-allocation-aware.
TEST(ArenaTest,MessageLiteOnArena)1197 TEST(ArenaTest, MessageLiteOnArena) {
1198   std::vector<char> arena_block(128 * 1024);
1199   ArenaOptions options;
1200   options.initial_block = &arena_block[0];
1201   options.initial_block_size = arena_block.size();
1202   Arena arena(options);
1203   const MessageLite* prototype = &TestAllTypes::default_instance();
1204 
1205   TestAllTypes initial_message;
1206   FillArenaAwareFields(&initial_message);
1207   std::string serialized;
1208   initial_message.SerializeToString(&serialized);
1209 
1210   {
1211 
1212     MessageLite* generic_message = prototype->New(&arena);
1213     EXPECT_TRUE(generic_message != NULL);
1214     EXPECT_EQ(&arena, generic_message->GetArena());
1215     EXPECT_TRUE(generic_message->ParseFromString(serialized));
1216     TestAllTypes* deserialized = static_cast<TestAllTypes*>(generic_message);
1217     EXPECT_EQ(42, deserialized->optional_int32());
1218   }
1219 
1220   arena.Reset();
1221 }
1222 #endif  // PROTOBUF_RTTI
1223 
1224 
1225 // RepeatedField should support non-POD types, and invoke constructors and
1226 // destructors appropriately, because it's used this way by lots of other code
1227 // (even if this was not its original intent).
TEST(ArenaTest,RepeatedFieldWithNonPODType)1228 TEST(ArenaTest, RepeatedFieldWithNonPODType) {
1229   {
1230     RepeatedField<std::string> field_on_heap;
1231     for (int i = 0; i < 100; i++) {
1232       *field_on_heap.Add() = "test string long enough to exceed inline buffer";
1233     }
1234   }
1235   {
1236     Arena arena;
1237     RepeatedField<std::string> field_on_arena(&arena);
1238     for (int i = 0; i < 100; i++) {
1239       *field_on_arena.Add() = "test string long enough to exceed inline buffer";
1240     }
1241   }
1242 }
1243 
1244 // Align n to next multiple of 8
Align8(uint64 n)1245 uint64 Align8(uint64 n) { return (n + 7) & -8; }
1246 
TEST(ArenaTest,SpaceAllocated_and_Used)1247 TEST(ArenaTest, SpaceAllocated_and_Used) {
1248   ArenaOptions options;
1249   options.start_block_size = 256;
1250   options.max_block_size = 8192;
1251   Arena arena_1(options);
1252   EXPECT_EQ(0, arena_1.SpaceAllocated());
1253   EXPECT_EQ(0, arena_1.SpaceUsed());
1254   EXPECT_EQ(0, arena_1.Reset());
1255   Arena::CreateArray<char>(&arena_1, 320);
1256   // Arena will allocate slightly more than 320 for the block headers.
1257   EXPECT_LE(320, arena_1.SpaceAllocated());
1258   EXPECT_EQ(Align8(320), arena_1.SpaceUsed());
1259   EXPECT_LE(320, arena_1.Reset());
1260 
1261   // Test with initial block.
1262   std::vector<char> arena_block(1024);
1263   options.initial_block = &arena_block[0];
1264   options.initial_block_size = arena_block.size();
1265   Arena arena_2(options);
1266   EXPECT_EQ(1024, arena_2.SpaceAllocated());
1267   EXPECT_EQ(0, arena_2.SpaceUsed());
1268   EXPECT_EQ(1024, arena_2.Reset());
1269   Arena::CreateArray<char>(&arena_2, 55);
1270   EXPECT_EQ(1024, arena_2.SpaceAllocated());
1271   EXPECT_EQ(Align8(55), arena_2.SpaceUsed());
1272   EXPECT_EQ(1024, arena_2.Reset());
1273 
1274   // Reset options to test doubling policy explicitly.
1275   options.initial_block = NULL;
1276   options.initial_block_size = 0;
1277   Arena arena_3(options);
1278   EXPECT_EQ(0, arena_3.SpaceUsed());
1279   Arena::CreateArray<char>(&arena_3, 160);
1280   EXPECT_EQ(256, arena_3.SpaceAllocated());
1281   EXPECT_EQ(Align8(160), arena_3.SpaceUsed());
1282   Arena::CreateArray<char>(&arena_3, 70);
1283   EXPECT_EQ(256 + 512, arena_3.SpaceAllocated());
1284   EXPECT_EQ(Align8(160) + Align8(70), arena_3.SpaceUsed());
1285   EXPECT_EQ(256 + 512, arena_3.Reset());
1286 }
1287 
TEST(ArenaTest,Alignment)1288 TEST(ArenaTest, Alignment) {
1289   Arena arena;
1290   for (int i = 0; i < 200; i++) {
1291     void* p = Arena::CreateArray<char>(&arena, i);
1292     GOOGLE_CHECK_EQ(reinterpret_cast<uintptr_t>(p) % 8, 0) << i << ": " << p;
1293   }
1294 }
1295 
TEST(ArenaTest,BlockSizeSmallerThanAllocation)1296 TEST(ArenaTest, BlockSizeSmallerThanAllocation) {
1297   for (size_t i = 0; i <= 8; ++i) {
1298     ArenaOptions opt;
1299     opt.start_block_size = opt.max_block_size = i;
1300     Arena arena(opt);
1301 
1302     *Arena::Create<int64>(&arena) = 42;
1303     EXPECT_GE(arena.SpaceAllocated(), 8);
1304     EXPECT_EQ(8, arena.SpaceUsed());
1305 
1306     *Arena::Create<int64>(&arena) = 42;
1307     EXPECT_GE(arena.SpaceAllocated(), 16);
1308     EXPECT_EQ(16, arena.SpaceUsed());
1309   }
1310 }
1311 
TEST(ArenaTest,GetArenaShouldReturnTheArenaForArenaAllocatedMessages)1312 TEST(ArenaTest, GetArenaShouldReturnTheArenaForArenaAllocatedMessages) {
1313   Arena arena;
1314   ArenaMessage* message = Arena::CreateMessage<ArenaMessage>(&arena);
1315   const ArenaMessage* const_pointer_to_message = message;
1316   EXPECT_EQ(&arena, Arena::GetArena(message));
1317   EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message));
1318 
1319   // Test that the Message* / MessageLite* specialization SFINAE works.
1320   const Message* const_pointer_to_message_type = message;
1321   EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message_type));
1322   const MessageLite* const_pointer_to_message_lite_type = message;
1323   EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message_lite_type));
1324 }
1325 
TEST(ArenaTest,GetArenaShouldReturnNullForNonArenaAllocatedMessages)1326 TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaAllocatedMessages) {
1327   ArenaMessage message;
1328   const ArenaMessage* const_pointer_to_message = &message;
1329   EXPECT_EQ(NULL, Arena::GetArena(&message));
1330   EXPECT_EQ(NULL, Arena::GetArena(const_pointer_to_message));
1331 }
1332 
TEST(ArenaTest,GetArenaShouldReturnNullForNonArenaCompatibleTypes)1333 TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaCompatibleTypes) {
1334   TestNoArenaMessage message;
1335   const TestNoArenaMessage* const_pointer_to_message = &message;
1336   EXPECT_EQ(nullptr, Arena::GetArena(&message));
1337   EXPECT_EQ(nullptr, Arena::GetArena(const_pointer_to_message));
1338 
1339   // Test that GetArena returns nullptr for types that have a GetArena method
1340   // that doesn't return Arena*.
1341   struct {
1342     int GetArena() const { return 0; }
1343   } has_get_arena_method_wrong_return_type;
1344   EXPECT_EQ(nullptr, Arena::GetArena(&has_get_arena_method_wrong_return_type));
1345 
1346   // Test that GetArena returns nullptr for types that have a GetArena alias.
1347   struct {
1348     using GetArena = Arena*;
1349     GetArena unused;
1350   } has_get_arena_alias;
1351   EXPECT_EQ(nullptr, Arena::GetArena(&has_get_arena_alias));
1352 
1353   // Test that GetArena returns nullptr for types that have a GetArena data
1354   // member.
1355   struct {
1356     Arena GetArena;
1357   } has_get_arena_data_member;
1358   EXPECT_EQ(nullptr, Arena::GetArena(&has_get_arena_data_member));
1359 }
1360 
TEST(ArenaTest,AddCleanup)1361 TEST(ArenaTest, AddCleanup) {
1362   Arena arena;
1363   for (int i = 0; i < 100; i++) {
1364     arena.Own(new int);
1365   }
1366 }
1367 
TEST(ArenaTest,UnsafeSetAllocatedOnArena)1368 TEST(ArenaTest, UnsafeSetAllocatedOnArena) {
1369   Arena arena;
1370   TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
1371   EXPECT_FALSE(message->has_optional_string());
1372 
1373   std::string owned_string = "test with long enough content to heap-allocate";
1374   message->unsafe_arena_set_allocated_optional_string(&owned_string);
1375   EXPECT_TRUE(message->has_optional_string());
1376 
1377   message->unsafe_arena_set_allocated_optional_string(NULL);
1378   EXPECT_FALSE(message->has_optional_string());
1379 }
1380 
1381 // A helper utility class to only contain static hook functions, some
1382 // counters to be used to verify the counters have been called and a cookie
1383 // value to be verified.
1384 class ArenaHooksTestUtil {
1385  public:
on_init(Arena * arena)1386   static void* on_init(Arena* arena) {
1387     ++num_init;
1388     int* cookie = new int(kCookieValue);
1389     return static_cast<void*>(cookie);
1390   }
1391 
on_allocation(const std::type_info *,uint64 alloc_size,void * cookie)1392   static void on_allocation(const std::type_info* /*unused*/, uint64 alloc_size,
1393                             void* cookie) {
1394     ++num_allocations;
1395     int cookie_value = *static_cast<int*>(cookie);
1396     EXPECT_EQ(kCookieValue, cookie_value);
1397   }
1398 
on_reset(Arena * arena,void * cookie,uint64 space_used)1399   static void on_reset(Arena* arena, void* cookie, uint64 space_used) {
1400     ++num_reset;
1401     int cookie_value = *static_cast<int*>(cookie);
1402     EXPECT_EQ(kCookieValue, cookie_value);
1403   }
1404 
on_destruction(Arena * arena,void * cookie,uint64 space_used)1405   static void on_destruction(Arena* arena, void* cookie, uint64 space_used) {
1406     ++num_destruct;
1407     int cookie_value = *static_cast<int*>(cookie);
1408     EXPECT_EQ(kCookieValue, cookie_value);
1409     delete static_cast<int*>(cookie);
1410   }
1411 
1412   static const int kCookieValue = 999;
1413   static uint32 num_init;
1414   static uint32 num_allocations;
1415   static uint32 num_reset;
1416   static uint32 num_destruct;
1417 };
1418 uint32 ArenaHooksTestUtil::num_init = 0;
1419 uint32 ArenaHooksTestUtil::num_allocations = 0;
1420 uint32 ArenaHooksTestUtil::num_reset = 0;
1421 uint32 ArenaHooksTestUtil::num_destruct = 0;
1422 const int ArenaHooksTestUtil::kCookieValue;
1423 
1424 class ArenaOptionsTestFriend {
1425  public:
Set(ArenaOptions * options)1426   static void Set(ArenaOptions* options) {
1427     options->on_arena_init = ArenaHooksTestUtil::on_init;
1428     options->on_arena_allocation = ArenaHooksTestUtil::on_allocation;
1429     options->on_arena_reset = ArenaHooksTestUtil::on_reset;
1430     options->on_arena_destruction = ArenaHooksTestUtil::on_destruction;
1431   }
1432 };
1433 
1434 // Test the hooks are correctly called and that the cookie is passed.
TEST(ArenaTest,ArenaHooksSanity)1435 TEST(ArenaTest, ArenaHooksSanity) {
1436   ArenaOptions options;
1437   ArenaOptionsTestFriend::Set(&options);
1438 
1439   // Scope for defining the arena
1440   {
1441     Arena arena(options);
1442     EXPECT_EQ(1, ArenaHooksTestUtil::num_init);
1443     EXPECT_EQ(0, ArenaHooksTestUtil::num_allocations);
1444     Arena::Create<uint64>(&arena);
1445     if (std::is_trivially_destructible<uint64>::value) {
1446       EXPECT_EQ(1, ArenaHooksTestUtil::num_allocations);
1447     } else {
1448       EXPECT_EQ(2, ArenaHooksTestUtil::num_allocations);
1449     }
1450     arena.Reset();
1451     arena.Reset();
1452     EXPECT_EQ(2, ArenaHooksTestUtil::num_reset);
1453   }
1454   EXPECT_EQ(3, ArenaHooksTestUtil::num_reset);
1455   EXPECT_EQ(1, ArenaHooksTestUtil::num_destruct);
1456 }
1457 
1458 
1459 }  // namespace protobuf
1460 }  // namespace google
1461