From a1fcc1ba60046f74bb9ce465a7b7d1a74d74ec6c Mon Sep 17 00:00:00 2001 From: MarekM25 Date: Wed, 28 Jun 2023 15:45:19 +0200 Subject: [PATCH] try-catch for null reference in Transfer --- src/DotNetty.Common/ThreadLocalPool.cs | 137 +++++++++++++------------ 1 file changed, 74 insertions(+), 63 deletions(-) diff --git a/src/DotNetty.Common/ThreadLocalPool.cs b/src/DotNetty.Common/ThreadLocalPool.cs index c4819bc5..2ea2fc89 100644 --- a/src/DotNetty.Common/ThreadLocalPool.cs +++ b/src/DotNetty.Common/ThreadLocalPool.cs @@ -236,98 +236,109 @@ internal void Add(DefaultHandle handle) // transfer as many items as we can from this queue to the stack, returning true if any were transferred internal bool Transfer(Stack dst) { - Link head = this.head?.link; - if (head == null) + try { - return false; - } - - if (head.ReadIndex == LinkCapacity) - { - if (head.next == null) + Link head = this.head?.link; + if (head == null) { return false; } - this.head.link = head = head.next; - } - int srcStart = head.ReadIndex; - int srcEnd = head.WriteIndex; - int srcSize = srcEnd - srcStart; - if (srcSize == 0) - { - return false; - } + if (head.ReadIndex == LinkCapacity) + { + if (head.next == null) + { + return false; + } - if (dst?.elements == null) - { - return false; - } - - int dstSize = dst.size; - int expectedCapacity = dstSize + srcSize; + this.head.link = head = head.next; + } - if (expectedCapacity > dst.elements.Length) - { - int actualCapacity = dst.IncreaseCapacity(expectedCapacity); - srcEnd = Math.Min(srcStart + actualCapacity - dstSize, srcEnd); - } + int srcStart = head.ReadIndex; + int srcEnd = head.WriteIndex; + int srcSize = srcEnd - srcStart; + if (srcSize == 0) + { + return false; + } - if (srcStart != srcEnd) - { - DefaultHandle[] srcElems = head.elements; - DefaultHandle[] dstElems = dst.elements; - int newDstSize = dstSize; - if (head.elements == null) + if (dst?.elements == null) { return false; } - - for (int i = srcStart; i < srcEnd; i++) + + int dstSize = dst.size; + int expectedCapacity = dstSize + srcSize; + + if (expectedCapacity > dst.elements.Length) { - DefaultHandle element = srcElems[i]; - if (element == null) + int actualCapacity = dst.IncreaseCapacity(expectedCapacity); + srcEnd = Math.Min(srcStart + actualCapacity - dstSize, srcEnd); + } + + if (srcStart != srcEnd) + { + DefaultHandle[] srcElems = head.elements; + DefaultHandle[] dstElems = dst.elements; + int newDstSize = dstSize; + if (head.elements == null) { return false; } - - if (element.recycleId == 0) + + for (int i = srcStart; i < srcEnd; i++) { - element.recycleId = element.lastRecycledId; + DefaultHandle element = srcElems[i]; + if (element == null) + { + return false; + } + + if (element.recycleId == 0) + { + element.recycleId = element.lastRecycledId; + } + else if (element.recycleId != element.lastRecycledId) + { + throw new InvalidOperationException("recycled already"); + } + + srcElems[i] = null; + + if (dst.DropHandle(element)) + { + // Drop the object. + continue; + } + + element.Stack = dst; + dstElems[newDstSize++] = element; } - else if (element.recycleId != element.lastRecycledId) + + if (srcEnd == LinkCapacity && head.next != null) { - throw new InvalidOperationException("recycled already"); + // Add capacity back as the Link is GCed. + this.head.ReclaimSpace(LinkCapacity); + this.head.link = head.next; } - srcElems[i] = null; - if (dst.DropHandle(element)) + head.ReadIndex = srcEnd; + if (dst.size == newDstSize) { - // Drop the object. - continue; + return false; } - element.Stack = dst; - dstElems[newDstSize++] = element; - } - if (srcEnd == LinkCapacity && head.next != null) - { - // Add capacity back as the Link is GCed. - this.head.ReclaimSpace(LinkCapacity); - this.head.link = head.next; + dst.size = newDstSize; + return true; } - - head.ReadIndex = srcEnd; - if (dst.size == newDstSize) + else { + // The destination stack is full already. return false; } - dst.size = newDstSize; - return true; } - else + catch (NullReferenceException) { - // The destination stack is full already. return false; } }