mirror of
https://github.com/protocolbuffers/protobuf-go.git
synced 2025-04-16 08:42:29 +00:00
encoding/protodelim: fix handling of io.EOF
Before this change, when encountering an io.EOF after reading at least one byte, the zero value byte was — incorrectly — appended to sizeBuf, and the io.EOF was ignored, resulting in a complete varint (0 has no continuation bit), which in turn resulted in incorrect unmarshalling. Change-Id: If06d45039d998eaddf91d0864814bb31d4cb7ae0 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/505555 Reviewed-by: Lasse Folger <lassefolger@google.com> Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
parent
fc47fdd3d3
commit
59a8581684
@ -96,7 +96,11 @@ func (o UnmarshalOptions) UnmarshalFrom(r Reader, m proto.Message) error {
|
|||||||
sizeBuf := sizeArr[:0]
|
sizeBuf := sizeArr[:0]
|
||||||
for i := range sizeArr {
|
for i := range sizeArr {
|
||||||
b, err := r.ReadByte()
|
b, err := r.ReadByte()
|
||||||
if err != nil && (err != io.EOF || i == 0) {
|
if err != nil {
|
||||||
|
// Immediate EOF is unexpected.
|
||||||
|
if err == io.EOF && i != 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sizeBuf = append(sizeBuf, b)
|
sizeBuf = append(sizeBuf, b)
|
||||||
|
@ -7,6 +7,7 @@ package protodelim_test
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
@ -202,3 +203,19 @@ func TestUnmarshalFrom_UnexpectedEOF(t *testing.T) {
|
|||||||
t.Errorf("protodelim.UnmarshalFrom(size-only buf, _) = %v, want %v", got, want)
|
t.Errorf("protodelim.UnmarshalFrom(size-only buf, _) = %v, want %v", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalFrom_PrematureHeader(t *testing.T) {
|
||||||
|
var data = []byte{128} // continuation bit set
|
||||||
|
err := protodelim.UnmarshalFrom(bytes.NewReader(data[:]), nil)
|
||||||
|
if got, want := err, io.ErrUnexpectedEOF; !errors.Is(got, want) {
|
||||||
|
t.Errorf("protodelim.UnmarshalFrom(%#v, nil) = %#v; want = %#v", data, got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalFrom_InvalidVarint(t *testing.T) {
|
||||||
|
var data = bytes.Repeat([]byte{128}, 2*binary.MaxVarintLen64) // continuation bit set
|
||||||
|
err := protodelim.UnmarshalFrom(bytes.NewReader(data[:]), nil)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("protodelim.UnmarshalFrom unexpectedly did not error on invalid varint")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user