Skip to content

Commit cafb9fc

Browse files
committed
[lib] Fix attribute manager memory leaks
1 parent 4a8ab42 commit cafb9fc

File tree

3 files changed

+13
-75
lines changed

3 files changed

+13
-75
lines changed

Source/AttributeDictionary.c

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -188,31 +188,6 @@ SB_INTERNAL AttributeDictionaryRef AttributeDictionaryCreate(SBAttributeRegistry
188188
return dictionary;
189189
}
190190

191-
SB_INTERNAL AttributeDictionaryRef AttributeDictionaryCopy(AttributeDictionaryRef dictionary)
192-
{
193-
AttributeDictionaryRef copy = AttributeDictionaryCreate(dictionary->_registry);
194-
195-
if (copy) {
196-
SBAttributeRegistryRef registry = copy->_registry;
197-
SBUInteger itemCount = dictionary->_list.count;
198-
SBUInteger itemIndex;
199-
200-
ListReserveRange(&copy->_list, 0, itemCount);
201-
202-
/* Copy each attribute item, retaining values through the registry */
203-
for (itemIndex = 0; itemIndex < itemCount; itemIndex++) {
204-
const SBAttributeItem *source = ListGetRef(&dictionary->_list, itemIndex);
205-
SBAttributeItem *destination = ListGetRef(&copy->_list, itemIndex);
206-
207-
destination->attributeID = source->attributeID;
208-
destination->attributeValue = SBAttributeRegistryRetainAttribute(registry,
209-
source->attributeID, source->attributeValue);
210-
}
211-
}
212-
213-
return copy;
214-
}
215-
216191
SB_INTERNAL SBBoolean AttributeDictionaryIsEmpty(AttributeDictionaryRef dictionary)
217192
{
218193
return (dictionary->_list.count == 0);

Source/AttributeDictionary.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -74,21 +74,6 @@ SB_INTERNAL void AttributeDictionaryFinalize(AttributeDictionaryRef dictionary);
7474
*/
7575
SB_INTERNAL AttributeDictionaryRef AttributeDictionaryCreate(SBAttributeRegistryRef registry);
7676

77-
/**
78-
* Creates a deep copy of an attribute dictionary.
79-
*
80-
* Allocates and initializes a new attribute dictionary as a deep copy of the provided dictionary.
81-
* All attribute values are retained through the registry during the copy process. The new
82-
* dictionary uses the same registry as the source. If allocation fails, returns NULL.
83-
*
84-
* @param dictionary
85-
* The attribute dictionary to copy.
86-
* @return
87-
* A new attribute dictionary reference containing copies of all attributes, or NULL if
88-
* allocation fails.
89-
*/
90-
SB_INTERNAL AttributeDictionaryRef AttributeDictionaryCopy(AttributeDictionaryRef dictionary);
91-
9277
/**
9378
* Checks whether an attribute dictionary is empty.
9479
*

Source/AttributeManager.c

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -110,30 +110,6 @@ static void StoreAttributeDictionaryInCache(AttributeDictionaryCacheRef cache,
110110
}
111111
}
112112

113-
/* =========================================================================
114-
* Attribute Entry Implementation
115-
* ========================================================================= */
116-
117-
/**
118-
* Initializes an attribute entry with the specified index and attributes.
119-
*/
120-
static void InitializeAttributeEntry(AttributeEntry *entry,
121-
SBUInteger index, AttributeDictionaryRef attributes)
122-
{
123-
entry->index = index;
124-
entry->attributes = attributes;
125-
}
126-
127-
/**
128-
* Finalizes an attribute entry and releases its attribute dictionary.
129-
*/
130-
static void FinalizeAttributeEntry(AttributeEntry *entry)
131-
{
132-
if (entry->attributes) {
133-
AttributeDictionaryRelease(entry->attributes);
134-
}
135-
}
136-
137113
/* =========================================================================
138114
* Attribute Manager Implementation
139115
* ========================================================================= */
@@ -657,11 +633,11 @@ static void AdjustParagraphAttributesAfterMerge(AttributeManagerRef manager,
657633
*/
658634
static void InsertFirstAttributeEntry(AttributeManagerRef manager)
659635
{
660-
AttributeDictionaryRef attributes;
661636
AttributeEntry entry;
662637

663-
attributes = AcquireAttributeDictionaryFromCache(&manager->_cache, manager->_registry);
664-
InitializeAttributeEntry(&entry, 0, attributes);
638+
entry.index = 0;
639+
entry.attributes = AcquireAttributeDictionaryFromCache(&manager->_cache, manager->_registry);
640+
665641
ListAdd(&manager->_entries, &entry);
666642
}
667643

@@ -678,7 +654,7 @@ static void InsertFirstAttributeEntry(AttributeManagerRef manager)
678654
* @param length
679655
* Number of entries to remove.
680656
*/
681-
static void RemoveAtributeEntryRange(AttributeManagerRef manager,
657+
static void RemoveAttributeEntryRange(AttributeManagerRef manager,
682658
SBUInteger index, SBUInteger length)
683659
{
684660
SBUInteger rangeEnd = index + length;
@@ -688,6 +664,7 @@ static void RemoveAtributeEntryRange(AttributeManagerRef manager,
688664
AttributeEntry *entry = ListGetRef(&manager->_entries, entryIndex);
689665

690666
StoreAttributeDictionaryInCache(&manager->_cache, entry->attributes);
667+
AttributeDictionaryRelease(entry->attributes);
691668
}
692669

693670
ListRemoveRange(&manager->_entries, index, length);
@@ -721,7 +698,7 @@ SB_INTERNAL void AttributeManagerFinalize(AttributeManagerRef manager)
721698
/* Finalize all entries */
722699
for (entryIndex = 0; entryIndex < entryCount; entryIndex++) {
723700
AttributeEntry *entry = ListGetRef(&manager->_entries, entryIndex);
724-
FinalizeAttributeEntry(entry);
701+
AttributeDictionaryRelease(entry->attributes);
725702
}
726703

727704
ListFinalize(&manager->_entries);
@@ -736,17 +713,21 @@ SB_INTERNAL void AttributeManagerCopyAttributes(AttributeManagerRef manager,
736713
SBUInteger entryIndex;
737714

738715
/* Clear existing entries and cache their dictionaries */
739-
RemoveAtributeEntryRange(manager, 0, manager->_entries.count);
716+
RemoveAttributeEntryRange(manager, 0, manager->_entries.count);
740717
/* Reserve space for source entries */
741718
ListReserveRange(&manager->_entries, 0, entryCount);
742719

743720
/* Deep copy each entry and its attributes */
744721
for (entryIndex = 0; entryIndex < entryCount; entryIndex++) {
745722
const AttributeEntry *sourceEntry = ListGetRef(&source->_entries, entryIndex);
746723
AttributeEntry *newEntry = ListGetRef(&manager->_entries, entryIndex);
724+
AttributeDictionaryRef cloneAttributes;
725+
726+
cloneAttributes = AcquireAttributeDictionaryFromCache(&manager->_cache, manager->_registry);
727+
AttributeDictionarySet(cloneAttributes, sourceEntry->attributes);
747728

748729
newEntry->index = sourceEntry->index;
749-
newEntry->attributes = AttributeDictionaryCopy(sourceEntry->attributes);
730+
newEntry->attributes = cloneAttributes;
750731
}
751732

752733
manager->_codeUnitCount = source->_codeUnitCount;
@@ -857,9 +838,6 @@ SB_INTERNAL void AttributeManagerRemoveRange(AttributeManagerRef manager,
857838

858839
if (endIndex <= rangeEnd) {
859840
/* Entry is completely within removal range - mark for removal */
860-
StoreAttributeDictionaryInCache(&manager->_cache, entry->attributes);
861-
FinalizeAttributeEntry(entry);
862-
863841
removalCount += 1;
864842
} else {
865843
/* Entry extends beyond removal range - adjust its index */
@@ -877,7 +855,7 @@ SB_INTERNAL void AttributeManagerRemoveRange(AttributeManagerRef manager,
877855
}
878856

879857
/* Remove all marked entries */
880-
RemoveAtributeEntryRange(manager, removalStart, removalCount);
858+
RemoveAttributeEntryRange(manager, removalStart, removalCount);
881859
manager->_codeUnitCount -= length;
882860

883861
if (manager->_entries.count == 0) {

0 commit comments

Comments
 (0)