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