fixed bugs that happen under certain conditions when deleting list node
authorHolger Schemel <info@artsoft.org>
Thu, 9 Jun 2016 19:18:38 +0000 (21:18 +0200)
committerHolger Schemel <info@artsoft.org>
Thu, 9 Jun 2016 19:18:38 +0000 (21:18 +0200)
src/libgame/misc.c

index 4b436322c94fc5d0f6639402d909eb5cb134e171..3bc3299f2c70fcb5ad5427f2709021bdaa66d838 100644 (file)
@@ -2068,20 +2068,33 @@ void deleteNodeFromList(ListNode **node_first, char *key,
 
   if (strEqual((*node_first)->key, key))
   {
-    checked_free((*node_first)->key);
+    // after first recursion, (*node_first)->prev->next == *node_first,
+    // so *node_first would be overwritten with (*node_first)->next
+    // => use a copy of *node_first (and later of (*node_first)->next)
+    ListNode *node = *node_first;
+    ListNode *node_next = node->next;
+
+    checked_free(node->key);
 
     if (destructor_function)
-      destructor_function((*node_first)->content);
+      destructor_function(node->content);
+
+    if (node->prev)
+      node->prev->next = node->next;
 
-    if ((*node_first)->next)
-      (*node_first)->next->prev = (*node_first)->prev;
+    if (node->next)
+      node->next->prev = node->prev;
 
-    checked_free(*node_first);
+    checked_free(node);
 
-    *node_first = (*node_first)->next;
+    // after removing node, set list pointer to next valid list node
+    // (this is important if the first node of the list was deleted)
+    *node_first = node_next;
   }
   else
+  {
     deleteNodeFromList(&(*node_first)->next, key, destructor_function);
+  }
 }
 
 ListNode *getNodeFromKey(ListNode *node_first, char *key)