CidFromReader should not wrap valid EOF return.

When reading from an io.Reader that has no data, the io.EOF error should not be wrapped in ErrInvalidCid. This is not an invalid CID, and is not the same as a partial read which is indicated by io.ErrUnexpectedEOF.

This fix is needed because existing code that uses CidFromReader may check for the end of an input stream by `if err == io.EOF` instead of the preferred `if errors.Is(err, io.EOF)`, and that code break at runtime after upgrading to go-cid v0.4.0.
This commit is contained in:
gammazero
2023-03-31 23:03:36 -07:00
committed by Rod Vagg
parent 8098d66787
commit 166a3a6880
2 changed files with 18 additions and 0 deletions

4
cid.go
View File

@@ -727,6 +727,10 @@ func CidFromReader(r io.Reader) (int, Cid, error) {
// The varint package wants a io.ByteReader, so we must wrap our io.Reader.
vers, err := varint.ReadUvarint(br)
if err != nil {
if err == io.EOF {
// No data; not an invalid CID.
return 0, Undef, err
}
return len(br.dst), Undef, ErrInvalidCid{err}
}

View File

@@ -783,6 +783,20 @@ func TestBadCidInput(t *testing.T) {
}
}
func TestFromReaderNoData(t *testing.T) {
// Reading no data from io.Reader should return io.EOF, not ErrInvalidCid.
n, cid, err := CidFromReader(bytes.NewReader(nil))
if err != io.EOF {
t.Fatal("Expected io.EOF error")
}
if cid != Undef {
t.Fatal("Expected Undef CID")
}
if n != 0 {
t.Fatal("Expected 0 data")
}
}
func TestBadParse(t *testing.T) {
hash, err := mh.Sum([]byte("foobar"), mh.SHA3_256, -1)
if err != nil {