Skip to content

Commit

Permalink
Fix blocking when unmarshaling the slice of stream entries
Browse files Browse the repository at this point in the history
  • Loading branch information
pvragov authored and mediocregopher committed Nov 30, 2023
1 parent b91b732 commit 8f4868b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 4 deletions.
10 changes: 6 additions & 4 deletions resp/resp3/resp.go
Original file line number Diff line number Diff line change
Expand Up @@ -2005,10 +2005,6 @@ func keyableReceiver(prefix Prefix, kv reflect.Value) (reflect.Value, error) {
}

func unmarshalAgg(prefix Prefix, br resp.BufferedReader, l int64, rcv interface{}, o *resp.Opts) error {
if prefix == MapHeaderPrefix {
l *= 2
}

if !o.DisableErrorBubbling {
if o == nil {
o = resp.NewOpts()
Expand All @@ -2021,6 +2017,9 @@ func unmarshalAgg(prefix Prefix, br resp.BufferedReader, l int64, rcv interface{
}

size := int(l)
if prefix == MapHeaderPrefix {
size *= 2
}
stream := size < 0
if rcv == nil {
return discardMulti(br, size, o)
Expand All @@ -2041,6 +2040,9 @@ func unmarshalAgg(prefix Prefix, br resp.BufferedReader, l int64, rcv interface{
switch v.Kind() {
case reflect.Slice:
slice := v
if slice.Type().Elem().Kind() == reflect.Struct {
size = int(l)
}
if size > slice.Cap() || slice.IsNil() {
sliceSize := size
if stream {
Expand Down
37 changes: 37 additions & 0 deletions resp/resp3/resp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,43 @@ func TestRawMessage(t *testing.T) {
}
}

func TestMapIntoSliceOfStructs(t *testing.T) {
buf := new(bytes.Buffer)
opts := resp.NewOpts()

_ = (MapHeader{NumPairs: 1}).MarshalRESP(buf, opts)
_ = (SimpleString{S: "key"}).MarshalRESP(buf, opts)
_ = (SimpleString{S: "value"}).MarshalRESP(buf, opts)

var rcv []mapPair
reader := bufio.NewReader(buf)
err := Unmarshal(reader, &rcv, opts)
require.NoError(t, err)
require.Len(t, rcv, 1)

expectedStruct := mapPair{Key: "key", Value: "value"}
assert.Equal(t, expectedStruct, rcv[0])
}

type mapPair struct {
Key string
Value string
}

func (s *mapPair) UnmarshalRESP(b resp.BufferedReader, opts *resp.Opts) error {
var key SimpleString
if err := key.UnmarshalRESP(b, opts); err != nil {
return err
}
var val SimpleString
if err := val.UnmarshalRESP(b, opts); err != nil {
return err
}
s.Key = key.S
s.Value = val.S
return nil
}

func Example_streamedAggregatedType() {
buf := new(bytes.Buffer)
opts := resp.NewOpts()
Expand Down

0 comments on commit 8f4868b

Please sign in to comment.