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