aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--const.go7
-rw-r--r--error.go4
-rw-r--r--rwtransaction.go6
-rw-r--r--rwtransaction_test.go15
4 files changed, 32 insertions, 0 deletions
diff --git a/const.go b/const.go
index 9ad7d25..00228be 100644
--- a/const.go
+++ b/const.go
@@ -3,6 +3,13 @@ package bolt
const version = 1
const (
+ maxUint = ^uint(0)
+ minUint = 0
+ maxInt = int(^uint(0) >> 1)
+ minInt = -maxInt - 1
+)
+
+const (
// MaxBucketNameSize is the maximum length of a bucket name, in bytes.
MaxBucketNameSize = 255
diff --git a/error.go b/error.go
index bad074e..7238203 100644
--- a/error.go
+++ b/error.go
@@ -38,6 +38,10 @@ var (
// ErrValueTooLarge is returned when inserting a value that is larger than MaxValueSize.
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.
diff --git a/rwtransaction.go b/rwtransaction.go
index 57135f3..84e6425 100644
--- a/rwtransaction.go
+++ b/rwtransaction.go
@@ -82,6 +82,12 @@ func (t *RWTransaction) NextSequence(name string) (int, error) {
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.
b.bucket.sequence++
diff --git a/rwtransaction_test.go b/rwtransaction_test.go
index ea84b87..18b6ae9 100644
--- a/rwtransaction_test.go
+++ b/rwtransaction_test.go
@@ -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.
func TestRWTransactionPutBucketNotFound(t *testing.T) {
withOpenDB(func(db *DB, path string) {