From 5d7628ba3b94d5d99d3315090ea4a41080c76ea8 Mon Sep 17 00:00:00 2001 From: Patrick Mezard Date: Tue, 20 Oct 2015 19:01:29 +0200 Subject: [PATCH] boltdb: fix RangeIterator outside of range seeks Two issues: - Seeking before i.start and iterating returned keys before i.start - Seeking after the store last key did not invalidate the iterator and could cause infinite loops. --- index/store/boltdb/iterator.go | 13 +++++++++---- index/store/boltdb/store_test.go | 6 ++++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/index/store/boltdb/iterator.go b/index/store/boltdb/iterator.go index bccfeaee..63bde9f5 100644 --- a/index/store/boltdb/iterator.go +++ b/index/store/boltdb/iterator.go @@ -29,14 +29,19 @@ type Iterator struct { func (i *Iterator) updateValid() { i.valid = (i.key != nil) - if i.valid && i.prefix != nil { - i.valid = bytes.HasPrefix(i.key, i.prefix) - } else if i.end != nil { - i.valid = bytes.Compare(i.key, i.end) < 0 + if i.valid { + if i.prefix != nil { + i.valid = bytes.HasPrefix(i.key, i.prefix) + } else if i.end != nil { + i.valid = bytes.Compare(i.key, i.end) < 0 + } } } func (i *Iterator) Seek(k []byte) { + if bytes.Compare(k, i.start) < 0 { + k = i.start + } i.key, i.val = i.cursor.Seek(k) i.updateValid() } diff --git a/index/store/boltdb/store_test.go b/index/store/boltdb/store_test.go index 0380a92c..4abde11b 100644 --- a/index/store/boltdb/store_test.go +++ b/index/store/boltdb/store_test.go @@ -72,6 +72,12 @@ func TestBoltDBRangeIterator(t *testing.T) { test.CommonTestRangeIterator(t, s) } +func TestBoltDBRangeIteratorSeek(t *testing.T) { + s := open(t, nil) + defer cleanup(t, s) + test.CommonTestRangeIteratorSeek(t, s) +} + func TestBoltDBMerge(t *testing.T) { s := open(t, &test.TestMergeCounter{}) defer cleanup(t, s)