Skip to content

Commit

Permalink
Return an error when trying to store a too-large key with Raft (#13282)
Browse files Browse the repository at this point in the history
  • Loading branch information
ncabatoff committed Nov 25, 2021
1 parent 481fbad commit 859afba
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 0 deletions.
3 changes: 3 additions & 0 deletions changelog/13282.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
storage/raft: Fix a panic when trying to write a key > 32KB
```
4 changes: 4 additions & 0 deletions physical/raft/raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,10 @@ func (b *RaftBackend) Get(ctx context.Context, path string) (*physical.Entry, er
// or if the call to applyLog fails.
func (b *RaftBackend) Put(ctx context.Context, entry *physical.Entry) error {
defer metrics.MeasureSince([]string{"raft-storage", "put"}, time.Now())
if len(entry.Key) > bolt.MaxKeySize {
return fmt.Errorf("%s, max key size for integrated storage is %d", physical.ErrKeyTooLarge, bolt.MaxKeySize)
}

command := &LogData{
Operations: []*LogOperation{
{
Expand Down
30 changes: 30 additions & 0 deletions physical/raft/raft_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"testing"
"time"

"github.com/hashicorp/go-secure-stdlib/base62"

"github.com/go-test/deep"
"github.com/golang/protobuf/proto"
hclog "github.com/hashicorp/go-hclog"
Expand Down Expand Up @@ -224,6 +226,34 @@ func TestRaft_Backend(t *testing.T) {
physical.ExerciseBackend(t, b)
}

func TestRaft_Backend_LargeKey(t *testing.T) {
b, dir := getRaft(t, true, true)
defer os.RemoveAll(dir)

key, err := base62.Random(bolt.MaxKeySize + 1)
if err != nil {
t.Fatal(err)
}
entry := &physical.Entry{Key: key, Value: []byte(key)}

err = b.Put(context.Background(), entry)
if err == nil {
t.Fatal("expected error for put entry")
}

if !strings.Contains(err.Error(), physical.ErrKeyTooLarge) {
t.Fatalf("expected %q, got %v", physical.ErrKeyTooLarge, err)
}

out, err := b.Get(context.Background(), entry.Key)
if err != nil {
t.Fatalf("unexpected error after failed put: %v", err)
}
if out != nil {
t.Fatal("expected response entry to be nil after a failed put")
}
}

func TestRaft_Backend_LargeValue(t *testing.T) {
b, dir := getRaft(t, true, true)
defer os.RemoveAll(dir)
Expand Down
1 change: 1 addition & 0 deletions sdk/physical/physical.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const (

const (
ErrValueTooLarge = "put failed due to value being too large"
ErrKeyTooLarge = "put failed due to key being too large"
)

// Backend is the interface required for a physical
Expand Down

0 comments on commit 859afba

Please sign in to comment.