Skip to content

Commit bef5b75

Browse files
Fix bug in reflection based Swap of map fields.
It was swapping the arena pointers too when they differed. In that case a full copy must be made instead. The instances can't change arenas. PiperOrigin-RevId: 569166797
1 parent 804573f commit bef5b75

File tree

3 files changed

+11
-4
lines changed

3 files changed

+11
-4
lines changed

src/google/protobuf/map.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ class PROTOBUF_EXPORT UntypedMapBase {
536536
public:
537537
Arena* arena() const { return this->alloc_.arena(); }
538538

539-
void Swap(UntypedMapBase* other) {
539+
void InternalSwap(UntypedMapBase* other) {
540540
std::swap(num_elements_, other->num_elements_);
541541
std::swap(num_buckets_, other->num_buckets_);
542542
std::swap(seed_, other->seed_);
@@ -1501,7 +1501,9 @@ class Map : private internal::KeyMapBase<internal::KeyForBase<Key>> {
15011501
}
15021502
}
15031503

1504-
void InternalSwap(Map* other) { this->Swap(other); }
1504+
void InternalSwap(Map* other) {
1505+
internal::UntypedMapBase::InternalSwap(other);
1506+
}
15051507

15061508
hasher hash_function() const { return {}; }
15071509

src/google/protobuf/map_field_inl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ template <typename Key, typename T>
129129
void TypeDefinedMapFieldBase<Key, T>::Swap(MapFieldBase* other) {
130130
MapFieldBase::Swap(other);
131131
auto* other_field = DownCast<TypeDefinedMapFieldBase*>(other);
132-
map_.Swap(&other_field->map_);
132+
map_.swap(other_field->map_);
133133
}
134134

135135
template <typename Key, typename T>

src/google/protobuf/map_test.inc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1270,7 +1270,6 @@ TEST_F(MapImplTest, SwapArena) {
12701270

12711271
TEST_F(MapImplTest, SwapFieldArenaReflection) {
12721272
MapReflectionTester reflection_tester(UNITTEST::TestMap::descriptor());
1273-
Arena arena;
12741273

12751274
{
12761275
// Tests filled lfs and empty rhs.
@@ -1289,9 +1288,15 @@ TEST_F(MapImplTest, SwapFieldArenaReflection) {
12891288
reflection->SwapFields(lhs, &rhs, fields);
12901289

12911290
reflection_tester.ExpectClearViaReflection(*lhs);
1291+
1292+
// Add an entry to make sure it is using the right arena.
1293+
(*lhs->mutable_map_int32_int32())[1234] = 1234;
12921294
}
12931295

12941296
reflection_tester.ExpectMapFieldsSetViaReflection(rhs);
1297+
1298+
// Add an entry to make sure it is using the right arena.
1299+
(*rhs.mutable_map_int32_int32())[1234] = 1234;
12951300
}
12961301
}
12971302

0 commit comments

Comments
 (0)