From 4132080333b1cb0e96b7b8732e763f96d69074ee Mon Sep 17 00:00:00 2001 From: Ben Johnson Date: Thu, 13 Mar 2014 14:39:28 -0600 Subject: [PATCH] Fix Cursor.Last() on empty buckets. @tv42 reported that creating a cursor on an empty bucket and then calling Cursor.Last() causes an index out of range error and panics. This commit adds a check for the page's item count being greater than zero. Fixes #63. --- cursor.go | 2 +- tx_test.go | 27 +++++++++++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/cursor.go b/cursor.go index 244c915..d66f1c1 100644 --- a/cursor.go +++ b/cursor.go @@ -235,7 +235,7 @@ func (c *Cursor) nsearch(key []byte) { // keyValue returns the key and value of the current leaf element. func (c *Cursor) keyValue() ([]byte, []byte) { ref := &c.stack[len(c.stack)-1] - if ref.index >= ref.count() { + if ref.count() == 0 || ref.index >= ref.count() { return nil, nil } diff --git a/tx_test.go b/tx_test.go index 1274476..abdd6d4 100644 --- a/tx_test.go +++ b/tx_test.go @@ -190,12 +190,27 @@ func TestTxDeleteBucketNotFound(t *testing.T) { func TestTxCursorEmptyBucket(t *testing.T) { withOpenDB(func(db *DB, path string) { db.CreateBucket("widgets") - tx, _ := db.Tx() - c := tx.Bucket("widgets").Cursor() - k, v := c.First() - assert.Nil(t, k) - assert.Nil(t, v) - tx.Commit() + db.With(func(tx *Tx) error { + c := tx.Bucket("widgets").Cursor() + k, v := c.First() + assert.Nil(t, k) + assert.Nil(t, v) + return nil + }) + }) +} + +// Ensure that a Tx cursor can reverse iterate over an empty bucket without error. +func TestCursorEmptyBucketReverse(t *testing.T) { + withOpenDB(func(db *DB, path string) { + db.CreateBucket("widgets") + db.With(func(tx *Tx) error { + c := tx.Bucket("widgets").Cursor() + k, v := c.Last() + assert.Nil(t, k) + assert.Nil(t, v) + return nil + }) }) }