-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Expand file tree
/
Copy pathcommand_flat_reply_test.go
More file actions
62 lines (58 loc) · 2.35 KB
/
Copy pathcommand_flat_reply_test.go
File metadata and controls
62 lines (58 loc) · 2.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package redis
import (
"context"
"strings"
"testing"
"github.com/redis/go-redis/v9/internal/proto"
)
// A RESP2 flat reply (a single array of alternating member/score or key/value
// elements) must have an even length. An odd length means the parser would read
// n/2 pairs and leave the trailing element on the wire, desyncing the pooled
// connection. These parsers must reject it, matching the guard the sibling flat
// parsers (VLINKS, VSIM) already have.
func TestFlatReplyOddLengthRejected(t *testing.T) {
t.Run("ZSliceCmd", func(t *testing.T) {
rd := proto.NewReader(strings.NewReader("*3\r\n$1\r\na\r\n$3\r\n1.5\r\n$1\r\nb\r\n"))
cmd := NewZSliceCmd(context.Background())
if err := cmd.readReply(rd); err == nil {
t.Fatalf("odd-length flat reply accepted; readReply returned nil (val=%+v)", cmd.val)
}
})
t.Run("KeyValueSliceCmd", func(t *testing.T) {
rd := proto.NewReader(strings.NewReader("*3\r\n$1\r\nk\r\n$1\r\nv\r\n$1\r\nx\r\n"))
cmd := NewKeyValueSliceCmd(context.Background())
if err := cmd.readReply(rd); err == nil {
t.Fatalf("odd-length flat reply accepted; readReply returned nil (val=%+v)", cmd.val)
}
})
t.Run("ZSliceWithKeyCmd", func(t *testing.T) {
rd := proto.NewReader(strings.NewReader("*2\r\n$3\r\nzst\r\n*3\r\n$1\r\na\r\n$3\r\n1.5\r\n$1\r\nb\r\n"))
cmd := NewZSliceWithKeyCmd(context.Background())
if err := cmd.readReply(rd); err == nil {
t.Fatalf("odd-length flat reply accepted; readReply returned nil (val=%+v)", cmd.val)
}
})
}
// Even-length flat replies and the nested-array form must still parse cleanly.
func TestFlatReplyValidStillParses(t *testing.T) {
t.Run("flat", func(t *testing.T) {
rd := proto.NewReader(strings.NewReader("*4\r\n$1\r\na\r\n$3\r\n1.5\r\n$1\r\nb\r\n$3\r\n2.5\r\n"))
cmd := NewZSliceCmd(context.Background())
if err := cmd.readReply(rd); err != nil {
t.Fatalf("valid flat reply: %v", err)
}
if len(cmd.val) != 2 || cmd.val[0].Member != "a" || cmd.val[1].Member != "b" {
t.Fatalf("unexpected val: %+v", cmd.val)
}
})
t.Run("nested", func(t *testing.T) {
rd := proto.NewReader(strings.NewReader("*2\r\n*2\r\n$1\r\na\r\n$3\r\n1.5\r\n*2\r\n$1\r\nb\r\n$3\r\n2.5\r\n"))
cmd := NewZSliceCmd(context.Background())
if err := cmd.readReply(rd); err != nil {
t.Fatalf("valid nested reply: %v", err)
}
if len(cmd.val) != 2 {
t.Fatalf("unexpected val: %+v", cmd.val)
}
})
}