Skip to content

Commit

Permalink
fix(stream_decoder): io.EOF is not error when parsing (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
fanweixiao authored Aug 30, 2021
1 parent 52f8457 commit f1a2718
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 2 deletions.
20 changes: 18 additions & 2 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,24 @@ package y3

import (
"bytes"
"errors"
"fmt"
"io"

"github.com/yomorun/y3/encoding"
)

var (
ErrMalformed = errors.New("y3.ReadPacket: malformed")
)

// ReadPacket will try to read a Y3 encoded packet from the reader
func ReadPacket(reader io.Reader) ([]byte, error) {
tag, err := readByte(reader)
if err != nil {
if err == io.EOF {
return nil, ErrMalformed
}
return nil, err
}
// buf will contain a complete y3 encoded handshakeFrame
Expand All @@ -26,6 +34,9 @@ func ReadPacket(reader io.Reader) ([]byte, error) {
for {
b, err := readByte(reader)
if err != nil {
if err == io.EOF {
return nil, ErrMalformed
}
return nil, err
}
lenbuf.WriteByte(b)
Expand All @@ -39,7 +50,7 @@ func ReadPacket(reader io.Reader) ([]byte, error) {
codec := encoding.VarCodec{}
err = codec.DecodePVarInt32(lenbuf.Bytes(), &length)
if err != nil {
return nil, err
return nil, ErrMalformed
}

// validate len decoded from stream
Expand All @@ -66,6 +77,10 @@ func ReadPacket(reader io.Reader) ([]byte, error) {
p, err := reader.Read(tmpbuf)
count += p
if err != nil {
if err == io.EOF {
valbuf.Write(tmpbuf[:p])
break
}
return nil, fmt.Errorf("y3 parse valbuf error: %v", err)
}
valbuf.Write(tmpbuf[:p])
Expand All @@ -75,7 +90,8 @@ func ReadPacket(reader io.Reader) ([]byte, error) {
}

if count < int(length) {
return nil, fmt.Errorf("[y3] p should == len when getting y3 value buffer, len=%d, p=%d", length, count)
// return nil, fmt.Errorf("[y3] p should == len when getting y3 value buffer, len=%d, p=%d", length, count)
return nil, ErrMalformed
}
// write y3.Value bytes
buf.Write(valbuf.Bytes())
Expand Down
68 changes: 68 additions & 0 deletions parser_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package y3

import (
"io"
"testing"

"github.com/stretchr/testify/assert"
)

func TestStreamParser1(t *testing.T) {
data := []byte{0x01, 0x03, 0x01, 0x02, 0x03}
reader := &pr{buf: data}

p, err := ReadPacket(reader)
assert.NoError(t, err)
assert.Equal(t, data, p)
}

func TestStreamParser2(t *testing.T) {
data := []byte{0x01, 0x03, 0x01, 0x02, 0x03, 0x04}
reader := &pr{buf: data}

p, err := ReadPacket(reader)
assert.NoError(t, err)
assert.Equal(t, data[:5], p)
}

func TestStreamParser3(t *testing.T) {
data := []byte{0x01, 0x03, 0x01, 0x02}
reader := &pr{buf: data}

p, err := ReadPacket(reader)
assert.ErrorIs(t, err, ErrMalformed)
assert.Equal(t, []byte(nil), p)
}

func TestStreamParser4(t *testing.T) {
data := []byte{}
reader := &pr{buf: data}

p, err := ReadPacket(reader)
assert.ErrorIs(t, err, ErrMalformed)
assert.Equal(t, []byte(nil), p)
}

func TestStreamParser5(t *testing.T) {
data := []byte{0x01}
reader := &pr{buf: data}

p, err := ReadPacket(reader)
assert.ErrorIs(t, err, ErrMalformed)
assert.Equal(t, []byte(nil), p)
}

type pr struct {
buf []byte
off int
}

func (pr *pr) Read(buf []byte) (int, error) {
if pr.off >= len(pr.buf) {
return 0, io.EOF
}

copy(buf, []byte{pr.buf[pr.off]})
pr.off++
return 1, nil
}

0 comments on commit f1a2718

Please sign in to comment.