Skip to content

Commit

Permalink
Fix heap corruption issue in PriorityQueue.Remove (dotnet#107550)
Browse files Browse the repository at this point in the history
  • Loading branch information
eiriktsarpalis authored and jtschuster committed Sep 17, 2024
1 parent cc729b0 commit d210175
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -532,16 +532,30 @@ public bool Remove(
if (index < newSize)
{
// We're removing an element from the middle of the heap.
// Pop the last element in the collection and sift downward from the removed index.
// Pop the last element in the collection and sift from the removed index.
(TElement Element, TPriority Priority) lastNode = nodes[newSize];

if (_comparer == null)
{
MoveDownDefaultComparer(lastNode, index);
if (Comparer<TPriority>.Default.Compare(lastNode.Priority, priority) < 0)
{
MoveUpDefaultComparer(lastNode, index);
}
else
{
MoveDownDefaultComparer(lastNode, index);
}
}
else
{
MoveDownCustomComparer(lastNode, index);
if (_comparer.Compare(lastNode.Priority, priority) < 0)
{
MoveUpCustomComparer(lastNode, index);
}
else
{
MoveDownCustomComparer(lastNode, index);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,33 @@ public void PriorityQueue_EmptyCollection_Remove_ShouldReturnFalse()
Assert.Null(removedPriority);
}

[Fact]
public void PriorityQueue_LargeCollection_Remove_ShouldPreserveHeapInvariant()
{
// Regression test for https://github.com/dotnet/runtime/issues/107292

PriorityQueue<int, int> queue = new();
for (int i = 19; i >= 0; i--)
{
queue.Enqueue(i, i);
}

queue.Remove(10, out int _, out int _);

List<int> sortedValues = queue.UnorderedItems
.OrderBy(e => e.Priority)
.Select(e => e.Element)
.ToList();

List<int> dequeuedValues = new();
while (queue.Count > 0)
{
dequeuedValues.Add(queue.Dequeue());
}

Assert.Equal(sortedValues, dequeuedValues);
}

#region EnsureCapacity, TrimExcess

[Fact]
Expand Down

0 comments on commit d210175

Please sign in to comment.