Skip to content

Commit 7e7941f

Browse files
committed
fix: prevent other nil panics
1 parent b3417fa commit 7e7941f

File tree

2 files changed

+108
-5
lines changed

2 files changed

+108
-5
lines changed

rbtree.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,28 @@ func NewTree[K Ordered, V any]() *Tree[K, V] {
3030

3131
// Find finds the node and return its value.
3232
func (t *Tree[K, V]) Find(key K) V {
33+
var result V
34+
if t == nil {
35+
return result
36+
}
3337
n := t.findnode(key)
3438
if n != nil {
3539
return n.Value
3640
}
37-
var result V
3841
return result
3942
}
4043

4144
// FindIt finds the node and return it as an iterator.
4245
func (t *Tree[K, V]) FindIt(key K) *node[K, V] {
46+
if t == nil || t.root == nil {
47+
return nil
48+
}
4349
return t.findnode(key)
4450
}
4551

4652
// Empty checks whether the rbtree is empty.
4753
func (t *Tree[K, V]) Empty() bool {
48-
if t.root == nil {
54+
if t == nil || t.root == nil {
4955
return true
5056
}
5157
return false
@@ -61,13 +67,18 @@ func (t *Tree[K, V]) Iterator() *node[K, V] {
6167

6268
// Size returns the size of the rbtree.
6369
func (t *Tree[K, V]) Size() int {
70+
if t == nil {
71+
return 0
72+
}
6473
return t.size
6574
}
6675

6776
// Clear destroys the rbtree.
6877
func (t *Tree[K, V]) Clear() {
69-
t.root = nil
70-
t.size = 0
78+
if t != nil {
79+
t.root = nil
80+
t.size = 0
81+
}
7182
}
7283

7384
// Insert inserts the key-value pair into the rbtree.
@@ -102,6 +113,10 @@ func (t *Tree[K, V]) Insert(key K, value V) {
102113

103114
// Delete deletes the node by key
104115
func (t *Tree[K, V]) Delete(key K) {
116+
if t == nil || t.root == nil {
117+
return
118+
}
119+
105120
z := t.findnode(key)
106121
if z == nil {
107122
return

rbtree_test.go

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package rbtree
22

33
import (
44
"fmt"
5+
"strings"
56
"testing"
67
)
78

@@ -57,6 +58,56 @@ func TestPreorder(t *testing.T) {
5758
tree.Preorder()
5859
}
5960

61+
func TestTree(t *testing.T) {
62+
tree := NewTree[int, string]()
63+
64+
t.Run("empty", func(t *testing.T) {
65+
tree.Clear()
66+
tree.Delete(1)
67+
68+
if !tree.Empty() {
69+
t.Fatal("tree isn't empty")
70+
}
71+
72+
size := tree.Size()
73+
if size != 0 {
74+
t.Errorf("unexpected tree size of %d", size)
75+
}
76+
})
77+
78+
t.Run("nil", func(t *testing.T) {
79+
tree = nil
80+
81+
tree.Clear()
82+
tree.Delete(1)
83+
84+
if !tree.Empty() {
85+
t.Fatal("tree isn't empty")
86+
}
87+
88+
size := tree.Size()
89+
if size != 0 {
90+
t.Errorf("unexpected tree size of %d", size)
91+
}
92+
})
93+
94+
var caught interface{}
95+
t.Run("catch insert panic", func(t *testing.T) {
96+
defer func() {
97+
if err := recover(); err != nil {
98+
caught = err
99+
}
100+
}()
101+
// panics
102+
tree.Insert(1, "abc")
103+
})
104+
105+
error := fmt.Sprintf("%v", caught)
106+
if !strings.Contains(error, "nil pointer dereference") {
107+
t.Fatalf("unexpected error: %#v", caught)
108+
}
109+
}
110+
60111
func TestFind(t *testing.T) {
61112
tree := NewTree[int, string]()
62113

@@ -93,6 +144,20 @@ func TestFind(t *testing.T) {
93144
t.Fatalf("got %q", value)
94145
}
95146
})
147+
148+
t.Run("nil", func(t *testing.T) {
149+
tree = nil
150+
151+
n := tree.FindIt(4)
152+
if n != nil {
153+
t.Fatalf("got %#v", n)
154+
}
155+
156+
value := tree.Find(5)
157+
if value != "" {
158+
t.Fatalf("got %q", value)
159+
}
160+
})
96161
}
97162

98163
func TestIterator(t *testing.T) {
@@ -115,7 +180,20 @@ func TestIterator(t *testing.T) {
115180
tree = NewTree[int, string]()
116181

117182
next := tree.Iterator()
118-
t.Logf("tree.Iterator()=%#v", next)
183+
if next != nil {
184+
t.Fatalf(".Iterator() returned %#v", next)
185+
}
186+
187+
size := tree.Size()
188+
if size != 0 {
189+
t.Fatalf("got size %d", size)
190+
}
191+
})
192+
193+
t.Run("nil", func(t *testing.T) {
194+
tree = nil
195+
196+
next := tree.Iterator()
119197
if next != nil {
120198
t.Fatalf(".Iterator() returned %#v", next)
121199
}
@@ -158,6 +236,16 @@ func TestDelete(t *testing.T) {
158236
t.Fatalf("after size is %d", size)
159237
}
160238
})
239+
240+
t.Run("nil", func(t *testing.T) {
241+
tree = nil
242+
tree.Delete(1)
243+
244+
size := tree.Size()
245+
if size != 0 {
246+
t.Fatalf("after size is %d", size)
247+
}
248+
})
161249
}
162250

163251
func TestDelete2(t *testing.T) {

0 commit comments

Comments
 (0)