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(¬ifier);
186 data = new SimpleDataType;
187 data->SetNotifier(¬ifier);
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