Sfoglia il codice sorgente

core: fix double-free when copying an empty object

Daniele Bartolini 5 anni fa
parent
commit
b679bd69ad

+ 2 - 2
src/core/containers/hash_map.inl

@@ -344,9 +344,9 @@ HashMap<TKey, TValue, Hash, KeyEqual>::HashMap(const HashMap<TKey, TValue, Hash,
 	_size = other._size;
 	_size = other._size;
 	_mask = other._mask;
 	_mask = other._mask;
 
 
-	_allocator->deallocate(_buffer);
 	if (other._capacity > 0)
 	if (other._capacity > 0)
 	{
 	{
+		_allocator->deallocate(_buffer);
 		const u32 size = other._capacity * (sizeof(Index) + sizeof(Entry)) + alignof(Index) + alignof(Entry);
 		const u32 size = other._capacity * (sizeof(Index) + sizeof(Entry)) + alignof(Index) + alignof(Entry);
 		_buffer = (char*)_allocator->allocate(size);
 		_buffer = (char*)_allocator->allocate(size);
 		_index = (Index*)memory::align_top(_buffer, alignof(Index));
 		_index = (Index*)memory::align_top(_buffer, alignof(Index));
@@ -381,9 +381,9 @@ HashMap<TKey, TValue, Hash, KeyEqual>& HashMap<TKey, TValue, Hash, KeyEqual>::op
 	_size = other._size;
 	_size = other._size;
 	_mask = other._mask;
 	_mask = other._mask;
 
 
-	_allocator->deallocate(_buffer);
 	if (other._capacity > 0)
 	if (other._capacity > 0)
 	{
 	{
+		_allocator->deallocate(_buffer);
 		const u32 size = other._capacity * (sizeof(Index) + sizeof(Entry)) + alignof(Index) + alignof(Entry);
 		const u32 size = other._capacity * (sizeof(Index) + sizeof(Entry)) + alignof(Index) + alignof(Entry);
 		_buffer = (char*)_allocator->allocate(size);
 		_buffer = (char*)_allocator->allocate(size);
 		_index = (Index*)memory::align_top(_buffer, alignof(Index));
 		_index = (Index*)memory::align_top(_buffer, alignof(Index));

+ 2 - 2
src/core/containers/hash_set.inl

@@ -319,9 +319,9 @@ HashSet<TKey, Hash, KeyEqual>::HashSet(const HashSet& other)
 	_size = other._size;
 	_size = other._size;
 	_mask = other._mask;
 	_mask = other._mask;
 
 
-	_allocator->deallocate(_buffer);
 	if (other._capacity > 0)
 	if (other._capacity > 0)
 	{
 	{
+		_allocator->deallocate(_buffer);
 		const u32 size = other._capacity * (sizeof(Index) + sizeof(TKey)) + alignof(Index) + alignof(TKey);
 		const u32 size = other._capacity * (sizeof(Index) + sizeof(TKey)) + alignof(Index) + alignof(TKey);
 		_buffer = (char*)_allocator->allocate(size);
 		_buffer = (char*)_allocator->allocate(size);
 		_index = (Index*)memory::align_top(_buffer, alignof(Index));
 		_index = (Index*)memory::align_top(_buffer, alignof(Index));
@@ -356,9 +356,9 @@ HashSet<TKey, Hash, KeyEqual>& HashSet<TKey, Hash, KeyEqual>::operator=(const Ha
 	_size = other._size;
 	_size = other._size;
 	_mask = other._mask;
 	_mask = other._mask;
 
 
-	_allocator->deallocate(_buffer);
 	if (other._capacity > 0)
 	if (other._capacity > 0)
 	{
 	{
+		_allocator->deallocate(_buffer);
 		const u32 size = other._capacity * (sizeof(Index) + sizeof(TKey)) + alignof(Index) + alignof(TKey);
 		const u32 size = other._capacity * (sizeof(Index) + sizeof(TKey)) + alignof(Index) + alignof(TKey);
 		_buffer = (char*)_allocator->allocate(size);
 		_buffer = (char*)_allocator->allocate(size);
 		_index = (Index*)memory::align_top(_buffer, alignof(Index));
 		_index = (Index*)memory::align_top(_buffer, alignof(Index));

+ 6 - 0
src/core/unit_tests.cpp

@@ -150,6 +150,12 @@ static void test_hash_map()
 			hash_map::remove(m, i);
 			hash_map::remove(m, i);
 		}
 		}
 	}
 	}
+	{
+		HashMap<s32, s32> ma(a);
+		HashMap<s32, s32> mb(a);
+		hash_map::set(ma, 0, 0);
+		ma = mb;
+	}
 	memory_globals::shutdown();
 	memory_globals::shutdown();
 }
 }