DoublyLinkedList: Rework Remove() function.

* Check fFirst/fLast instead of previous/next. Avoids
   list corruption when trying to remove already-removed
   elements, instead will cause null-dereference KDL.

 * Always set next/previous to NULL even when DEBUG is not
   enabled.
This commit is contained in:
Augustin Cavalier
2023-08-03 13:18:26 -04:00
parent 5ae1a17908
commit 904e9f5512
+13 -12
View File
@@ -505,7 +505,9 @@ DOUBLY_LINKED_LIST_TEMPLATE_LIST
void void
DOUBLY_LINKED_LIST_CLASS_NAME::Remove(Element* element) DOUBLY_LINKED_LIST_CLASS_NAME::Remove(Element* element)
{ {
if (element) { if (element == NULL)
return;
#if DEBUG_DOUBLY_LINKED_LIST #if DEBUG_DOUBLY_LINKED_LIST
ASSERT_PRINT(fFirst != NULL && fLast != NULL ASSERT_PRINT(fFirst != NULL && fLast != NULL
&& (fFirst != fLast || element == fFirst), && (fFirst != fLast || element == fFirst),
@@ -513,19 +515,18 @@ DOUBLY_LINKED_LIST_CLASS_NAME::Remove(Element* element)
#endif #endif
Link* elLink = sGetLink(element); Link* elLink = sGetLink(element);
if (elLink->previous)
sGetLink(elLink->previous)->next = elLink->next;
else
fFirst = elLink->next;
if (elLink->next)
sGetLink(elLink->next)->previous = elLink->previous;
else
fLast = elLink->previous;
#if DEBUG_DOUBLY_LINKED_LIST if (element == fFirst)
fFirst = elLink->next;
else
sGetLink(elLink->previous)->next = elLink->next;
if (element == fLast)
fLast = elLink->previous;
else
sGetLink(elLink->next)->previous = elLink->previous;
elLink->next = elLink->previous = NULL; elLink->next = elLink->previous = NULL;
#endif
}
} }
// Swap // Swap