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