Skip to content

Commit 50ddad0

Browse files
committed
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 <[email protected]> (cherry picked from commit a05ec68) Signed-off-by: Wei Fu <[email protected]>
1 parent b3bdd17 commit 50ddad0

File tree

1 file changed

+7
-6
lines changed

1 file changed

+7
-6
lines changed

bucket.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -290,21 +290,22 @@ func (b *Bucket) Put(key []byte, value []byte) error {
290290
return ErrValueTooLarge
291291
}
292292

293+
// Insert into node.
294+
// Tip: Use a new variable `newKey` instead of reusing the existing `key` to prevent
295+
// it from being marked as leaking, and accordingly cannot be allocated on stack.
296+
newKey := cloneBytes(key)
297+
293298
// Move cursor to correct position.
294299
c := b.Cursor()
295-
k, _, flags := c.seek(key)
300+
k, _, flags := c.seek(newKey)
296301

297302
// Return an error if there is an existing key with a bucket value.
298-
if bytes.Equal(key, k) && (flags&bucketLeafFlag) != 0 {
303+
if bytes.Equal(newKey, k) && (flags&bucketLeafFlag) != 0 {
299304
return ErrIncompatibleValue
300305
}
301306

302307
// gofail: var beforeBucketPut struct{}
303308

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

310311
return nil

0 commit comments

Comments
 (0)