Skip to content

Commit

Permalink
bucket: copy key before Put
Browse files Browse the repository at this point in the history
Application might change key value after seeking and before real put.
This unexpected behaviour could corrupt database. When users file issue,
maintainers doesn't know application behaviour. It could be caused by
data race. This patch is to prevent such case and save maintainers' time.

Signed-off-by: Wei Fu <fuweid89@gmail.com>
(cherry picked from commit a05ec68)
Signed-off-by: Wei Fu <fuweid89@gmail.com>
  • Loading branch information
fuweid committed Dec 18, 2023
1 parent b3bdd17 commit 50ddad0
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,21 +290,22 @@ func (b *Bucket) Put(key []byte, value []byte) error {
return ErrValueTooLarge
}

// Insert into node.
// Tip: Use a new variable `newKey` instead of reusing the existing `key` to prevent
// it from being marked as leaking, and accordingly cannot be allocated on stack.
newKey := cloneBytes(key)

// Move cursor to correct position.
c := b.Cursor()
k, _, flags := c.seek(key)
k, _, flags := c.seek(newKey)

// Return an error if there is an existing key with a bucket value.
if bytes.Equal(key, k) && (flags&bucketLeafFlag) != 0 {
if bytes.Equal(newKey, k) && (flags&bucketLeafFlag) != 0 {
return ErrIncompatibleValue
}

// gofail: var beforeBucketPut struct{}

// Insert into node.
// Tip: Use a new variable `newKey` instead of reusing the existing `key` to prevent
// it from being marked as leaking, and accordingly cannot be allocated on stack.
newKey := cloneBytes(key)
c.node().put(newKey, newKey, value, 0, 0)

return nil
Expand Down

0 comments on commit 50ddad0

Please sign in to comment.