Browse Source

Fix `HashTable` badly handling reference counts

When `HashTable` was told to replace an object with itself, it ended up
incrementing its reference count because of the legacy equality check
(previously `FreeSelf()` completely deallocated an object, so the check
was warranted).
pull/8/head
Anton Tarasenko 2 years ago
parent
commit
2ad90b32e6
  1. 2
      sources/Data/Collections/HashTable.uc
  2. 16
      sources/Data/Collections/Tests/TEST_HashTable.uc

2
sources/Data/Collections/HashTable.uc

@ -394,7 +394,7 @@ public final function HashTable SetItem(
if (value != none) { if (value != none) {
value.NewRef(); value.NewRef();
} }
if (oldEntry.value != none && newEntry.value != oldEntry.value) { if (oldEntry.value != none) {
oldEntry.value.FreeSelf(); oldEntry.value.FreeSelf();
} }
hashTable[bucketIndex].entries[entryIndex] = newEntry; hashTable[bucketIndex].entries[entryIndex] = newEntry;

16
sources/Data/Collections/Tests/TEST_HashTable.uc

@ -26,6 +26,7 @@ var private array<MockItem> mockedItems;
protected static function TESTS() protected static function TESTS()
{ {
Test_GetSet(); Test_GetSet();
Test_Rewrite();
Test_HasKey(); Test_HasKey();
Test_GetKeys(); Test_GetKeys();
Test_GetTextKeys(); Test_GetTextKeys();
@ -89,6 +90,21 @@ protected static function Test_GetSet()
TEST_ExpectNone(array.GetItem(__().text.FromString("Some random stuff"))); TEST_ExpectNone(array.GetItem(__().text.FromString("Some random stuff")));
} }
protected static function Test_Rewrite()
{
local Text textObject;
local HashTable array;
array = HashTable(__().memory.Allocate(class'HashTable'));
Context("Testing getters and setters for items of `HashTable`.");
Issue("`SetItem()` does not handle reference counts correctly when"
@ "replacing a value with itself.");
textObject = __().text.FromString("value");
array.SetItem(__().text.FromString("key"), textObject);
array.SetItem(__().text.FromString("key"), textObject);
TEST_ExpectTrue(textObject._getRefCount() == 2);
}
protected static function Test_HasKey() protected static function Test_HasKey()
{ {
local HashTable array; local HashTable array;

Loading…
Cancel
Save