From 04d118c80c908d3fbde611c9f71dcca310f53cc9 Mon Sep 17 00:00:00 2001 From: HK40404 Date: Thu, 17 Aug 2023 22:53:50 +0800 Subject: [PATCH] bugfix: Runtime error will happen in RemoveAllByVal() if iter.remove() removes quicklist's last page (it happens when last page has only one item) and the quicklist is not empty. In this case, iter.atEnd() will be false, which will cause a nil pointer dereference. Solution: If iter.remove() remove last item, let it meet iter.atEnd(). --- datastruct/list/quicklist.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/datastruct/list/quicklist.go b/datastruct/list/quicklist.go index f654c62..41b6baf 100644 --- a/datastruct/list/quicklist.go +++ b/datastruct/list/quicklist.go @@ -227,10 +227,17 @@ func (iter *iterator) remove() interface{} { } else { // page is empty, update iter.node and iter.offset if iter.node == iter.ql.data.Back() { - // removed last element, ql is empty now - iter.ql.data.Remove(iter.node) - iter.node = nil - iter.offset = 0 + // move iter so iter.atEnd() can be true + if prevNode := iter.node.Prev(); prevNode != nil { + iter.ql.data.Remove(iter.node) + iter.node = prevNode + iter.offset = len(prevNode.Value.([]interface{})) + } else { + // removed last element, ql is empty now + iter.ql.data.Remove(iter.node) + iter.node = nil + iter.offset = 0 + } } else { nextNode := iter.node.Next() iter.ql.data.Remove(iter.node)