Check for sequence overflow.

pull/34/head
Ben Johnson 2014-02-20 09:24:02 -07:00
parent 0752480eb4
commit a857b45bac
4 changed files with 32 additions and 0 deletions

View File

@ -2,6 +2,13 @@ package bolt
const version = 1 const version = 1
const (
maxUint = ^uint(0)
minUint = 0
maxInt = int(^uint(0) >> 1)
minInt = -maxInt - 1
)
const ( const (
// MaxBucketNameSize is the maximum length of a bucket name, in bytes. // MaxBucketNameSize is the maximum length of a bucket name, in bytes.
MaxBucketNameSize = 255 MaxBucketNameSize = 255

View File

@ -38,6 +38,10 @@ var (
// ErrValueTooLarge is returned when inserting a value that is larger than MaxValueSize. // ErrValueTooLarge is returned when inserting a value that is larger than MaxValueSize.
ErrValueTooLarge = &Error{"value too large", nil} ErrValueTooLarge = &Error{"value too large", nil}
// ErrSequenceOverflow is returned when the next sequence number will be
// larger than the maximum integer size.
ErrSequenceOverflow = &Error{"sequence overflow", nil}
) )
// Error represents an error condition caused by Bolt. // Error represents an error condition caused by Bolt.

View File

@ -82,6 +82,12 @@ func (t *RWTransaction) NextSequence(name string) (int, error) {
return 0, ErrBucketNotFound return 0, ErrBucketNotFound
} }
// Make sure next sequence number will not be larger than the maximum
// integer size of the system.
if b.bucket.sequence == uint64(maxInt) {
return 0, ErrSequenceOverflow
}
// Increment and return the sequence. // Increment and return the sequence.
b.bucket.sequence++ b.bucket.sequence++

View File

@ -136,6 +136,21 @@ func TestRWTransactionNextSequence(t *testing.T) {
}) })
} }
// Ensure that incrementing past the maximum sequence number will return an error.
func TestRWTransactionNextSequenceOverflow(t *testing.T) {
withOpenDB(func(db *DB, path string) {
db.CreateBucket("widgets")
db.Do(func(txn *RWTransaction) error {
b := txn.Bucket("widgets")
b.bucket.sequence = uint64(maxInt)
seq, err := txn.NextSequence("widgets")
assert.Equal(t, err, ErrSequenceOverflow)
assert.Equal(t, seq, 0)
return nil
})
})
}
// Ensure that an error is returned when inserting into a bucket that doesn't exist. // Ensure that an error is returned when inserting into a bucket that doesn't exist.
func TestRWTransactionPutBucketNotFound(t *testing.T) { func TestRWTransactionPutBucketNotFound(t *testing.T) {
withOpenDB(func(db *DB, path string) { withOpenDB(func(db *DB, path string) {