diff --git a/store/prefixstore.go b/store/prefixstore.go index 437e209b3e..fee14ce4b2 100644 --- a/store/prefixstore.go +++ b/store/prefixstore.go @@ -21,6 +21,9 @@ func cloneAppend(bz []byte, bz2 []byte) (res []byte) { } func (s prefixStore) key(key []byte) (res []byte) { + if key == nil { + panic("nil key on prefixStore") + } res = cloneAppend(s.prefix, key) return } @@ -90,16 +93,14 @@ func (s prefixStore) Iterator(start, end []byte) Iterator { // Implements KVStore func (s prefixStore) ReverseIterator(start, end []byte) Iterator { - newstart := make([]byte, len(s.prefix), len(start)) - copy(newstart, s.prefix) - newstart = append(newstart, start...) + newstart := cloneAppend(s.prefix, start) newend := make([]byte, len(s.prefix)+len(end)) if end == nil { newend = sdk.PrefixEndBytes(s.prefix) } else { copy(newend, s.prefix) - newend = append(newend, end...) + copy(newend[len(s.prefix):], end) } return prefixIterator{ diff --git a/store/prefixstore_test.go b/store/prefixstore_test.go index d1d534a8ac..71119d8ddb 100644 --- a/store/prefixstore_test.go +++ b/store/prefixstore_test.go @@ -17,7 +17,7 @@ type kvpair struct { value []byte } -func setRandomKVPairs(t *testing.T, store KVStore) []kvpair { +func genRandomKVPairs(t *testing.T) []kvpair { kvps := make([]kvpair, 20) for i := 0; i < 20; i++ { @@ -25,17 +25,26 @@ func setRandomKVPairs(t *testing.T, store KVStore) []kvpair { rand.Read(kvps[i].key) kvps[i].value = make([]byte, 32) rand.Read(kvps[i].value) - - store.Set(kvps[i].key, kvps[i].value) } return kvps } +func setRandomKVPairs(t *testing.T, store KVStore) []kvpair { + kvps := genRandomKVPairs(t) + for _, kvp := range kvps { + store.Set(kvp.key, kvp.value) + } + return kvps +} + func testPrefixStore(t *testing.T, baseStore KVStore, prefix []byte) { prefixStore := baseStore.Prefix(prefix) prefixPrefixStore := prefixStore.Prefix([]byte("prefix")) + require.Panics(t, func() { prefixStore.Get(nil) }) + require.Panics(t, func() { prefixStore.Set(nil, []byte{}) }) + kvps := setRandomKVPairs(t, prefixPrefixStore) for i := 0; i < 20; i++ { @@ -109,3 +118,30 @@ func TestPrefixStoreIterate(t *testing.T) { bIter.Close() pIter.Close() } + +func mutateByteSlice(bz []byte) { + if bz[0] == byte(255) { + bz[0] = byte(0) + return + } + bz[0] += 1 +} + +func TestCloneAppend(t *testing.T) { + kvps := genRandomKVPairs(t) + for _, kvp := range kvps { + bz := cloneAppend(kvp.key, kvp.value) + require.Equal(t, bz, append(kvp.key, kvp.value...)) + + mutateByteSlice(bz) + require.NotEqual(t, bz, append(kvp.key, kvp.value...)) + + bz = cloneAppend(kvp.key, kvp.value) + mutateByteSlice(kvp.key) + require.NotEqual(t, bz, append(kvp.key, kvp.value...)) + + bz = cloneAppend(kvp.key, kvp.value) + mutateByteSlice(kvp.value) + require.NotEqual(t, bz, append(kvp.key, kvp.value...)) + } +}