From e6199e34cf9924bb6543e18682cf6be364725b05 Mon Sep 17 00:00:00 2001 From: kanandev2024 Date: Tue, 12 Dec 2023 21:53:05 +0800 Subject: [PATCH] bucket: copy key before Put 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 --- bucket.go | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/bucket.go b/bucket.go index 4aa04be..8e1a98a 100644 --- a/bucket.go +++ b/bucket.go @@ -327,21 +327,22 @@ func (b *Bucket) Put(key []byte, value []byte) error { return errors.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&common.BucketLeafFlag) != 0 { + if bytes.Equal(newKey, k) && (flags&common.BucketLeafFlag) != 0 { return errors.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