Make sure that Keys / Values are memory safe from levelDB

This commit is contained in:
StephenButtolph 2020-05-04 23:24:17 -04:00
parent f257187941
commit 282e89653c
2 changed files with 76 additions and 1 deletions

View File

@ -208,7 +208,14 @@ func (r *replayer) Delete(key []byte) {
type iter struct{ iterator.Iterator }
func (i *iter) Error() error { return updateError(i.Iterator.Error()) }
// Error implements the Iterator interface
func (it *iter) Error() error { return updateError(it.Iterator.Error()) }
// Key implements the Iterator interface
func (it *iter) Key() []byte { return copyBytes(it.Iterator.Key()) }
// Value implements the Iterator interface
func (it *iter) Value() []byte { return copyBytes(it.Iterator.Value()) }
func updateError(err error) error {
switch err {
@ -220,3 +227,13 @@ func updateError(err error) error {
return err
}
}
func copyBytes(bytes []byte) []byte {
if bytes == nil {
return nil
}
copiedBytes := make([]byte, len(bytes))
copy(copiedBytes, bytes)
return copiedBytes
}

View File

@ -24,6 +24,7 @@ var (
TestIteratorStart,
TestIteratorPrefix,
TestIteratorStartPrefix,
TestIteratorMemorySafety,
TestIteratorClosed,
TestStatNoPanic,
TestCompactNoPanic,
@ -622,6 +623,63 @@ func TestIteratorStartPrefix(t *testing.T, db Database) {
}
}
// TestIteratorMemorySafety ...
func TestIteratorMemorySafety(t *testing.T, db Database) {
key1 := []byte("hello1")
value1 := []byte("world1")
key2 := []byte("z")
value2 := []byte("world2")
key3 := []byte("hello3")
value3 := []byte("world3")
if err := db.Put(key1, value1); err != nil {
t.Fatalf("Unexpected error on batch.Put: %s", err)
} else if err := db.Put(key2, value2); err != nil {
t.Fatalf("Unexpected error on batch.Put: %s", err)
} else if err := db.Put(key3, value3); err != nil {
t.Fatalf("Unexpected error on batch.Put: %s", err)
}
iterator := db.NewIterator()
if iterator == nil {
t.Fatalf("db.NewIteratorWithStartAndPrefix returned nil")
}
defer iterator.Release()
keys := [][]byte{}
values := [][]byte{}
for iterator.Next() {
keys = append(keys, iterator.Key())
values = append(values, iterator.Value())
}
expectedKeys := [][]byte{
key1,
key3,
key2,
}
expectedValues := [][]byte{
value1,
value3,
value2,
}
for i, key := range keys {
value := values[i]
expectedKey := expectedKeys[i]
expectedValue := expectedValues[i]
if !bytes.Equal(key, expectedKey) {
t.Fatalf("Wrong key")
}
if !bytes.Equal(value, expectedValue) {
t.Fatalf("Wrong key")
}
}
}
// TestIteratorClosed ...
func TestIteratorClosed(t *testing.T, db Database) {
key1 := []byte("hello1")