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
+19 -18
View File
@@ -505,27 +505,28 @@ 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)
#if DEBUG_DOUBLY_LINKED_LIST return;
ASSERT_PRINT(fFirst != NULL && fLast != NULL
&& (fFirst != fLast || element == fFirst),
"list: %p, element: %p\n", this, element);
#endif
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 DEBUG_DOUBLY_LINKED_LIST
elLink->next = elLink->previous = NULL; ASSERT_PRINT(fFirst != NULL && fLast != NULL
&& (fFirst != fLast || element == fFirst),
"list: %p, element: %p\n", this, element);
#endif #endif
}
Link* elLink = sGetLink(element);
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;
} }
// Swap // Swap