aboutsummaryrefslogtreecommitdiff
path: root/src/encoding/gob/decoder.go
diff options
context:
space:
mode:
authorDaniel Martí <mvdan@mvdan.cc>2021-10-11 11:12:38 +0100
committerDaniel Martí <mvdan@mvdan.cc>2021-10-11 21:58:33 +0000
commitd973bb107e9142cf17e4a7f2666a71ed2d457e91 (patch)
tree5ce64142a65ea2c3b8f634ec32788ee0e1fe84c4 /src/encoding/gob/decoder.go
parent70235351263caee1fd9840d1d652bf28778cd51d (diff)
downloadgo-d973bb107e9142cf17e4a7f2666a71ed2d457e91.tar.xz
encoding/gob: follow documented io.EOF semantics
The docs say: If the input is at EOF, Decode returns io.EOF and does not modify e. However, the added test fails: --- FAIL: TestDecodePartial (0.00s) encoder_test.go:1263: 31/81: expected io.ErrUnexpectedEOF: EOF encoder_test.go:1263: 51/81: expected io.ErrUnexpectedEOF: EOF In particular, the decoder would return io.EOF after reading a valid message for a type specification, and then hit EOF before reading a data item message. Fix that by only allowing a Decode call to return io.EOF if the reader hits EOF immediately, without successfully reading any message. Otherwise, hitting EOF is an ErrUnexpectedEOF, like in other cases. Also fix a net/rpc test that, coincidentally, expected an io.EOF as an error when feeding bad non-zero data to a gob decoder. An io.ErrUnexpectedEOF is clearly better in that scenario. Fixes #48905. Change-Id: Ied6a0d8ac8377f89646319a18c0380c4f2b09b85 Reviewed-on: https://go-review.googlesource.com/c/go/+/354972 Trust: Daniel Martí <mvdan@mvdan.cc> Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Rob Pike <r@golang.org>
Diffstat (limited to 'src/encoding/gob/decoder.go')
-rw-r--r--src/encoding/gob/decoder.go9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/encoding/gob/decoder.go b/src/encoding/gob/decoder.go
index b476aaac93..5e4ed5a7d7 100644
--- a/src/encoding/gob/decoder.go
+++ b/src/encoding/gob/decoder.go
@@ -138,9 +138,17 @@ func (dec *Decoder) nextUint() uint64 {
// decoded. If this is an interface value, it can be ignored by
// resetting that buffer.
func (dec *Decoder) decodeTypeSequence(isInterface bool) typeId {
+ firstMessage := true
for dec.err == nil {
if dec.buf.Len() == 0 {
if !dec.recvMessage() {
+ // We can only return io.EOF if the input was empty.
+ // If we read one or more type spec messages,
+ // require a data item message to follow.
+ // If we hit an EOF before that, then give ErrUnexpectedEOF.
+ if !firstMessage && dec.err == io.EOF {
+ dec.err = io.ErrUnexpectedEOF
+ }
break
}
}
@@ -166,6 +174,7 @@ func (dec *Decoder) decodeTypeSequence(isInterface bool) typeId {
}
dec.nextUint()
}
+ firstMessage = false
}
return -1
}