Skip to content

Commit a05ec68

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]>
1 parent 1b08078 commit a05ec68

File tree

1 file changed

+7
-6
lines changed

1 file changed

+7
-6
lines changed

bucket.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -327,21 +327,22 @@ func (b *Bucket) Put(key []byte, value []byte) error {
327327
return errors.ErrValueTooLarge
328328
}
329329

330+
// Insert into node.
331+
// Tip: Use a new variable `newKey` instead of reusing the existing `key` to prevent
332+
// it from being marked as leaking, and accordingly cannot be allocated on stack.
333+
newKey := cloneBytes(key)
334+
330335
// Move cursor to correct position.
331336
c := b.Cursor()
332-
k, _, flags := c.seek(key)
337+
k, _, flags := c.seek(newKey)
333338

334339
// Return an error if there is an existing key with a bucket value.
335-
if bytes.Equal(key, k) && (flags&common.BucketLeafFlag) != 0 {
340+
if bytes.Equal(newKey, k) && (flags&common.BucketLeafFlag) != 0 {
336341
return errors.ErrIncompatibleValue
337342
}
338343

339344
// gofail: var beforeBucketPut struct{}
340345

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

347348
return nil

0 commit comments

Comments
 (0)