From 166a3a68800ef3925b81762e1a51f0c3969b59e5 Mon Sep 17 00:00:00 2001 From: gammazero Date: Fri, 31 Mar 2023 23:03:36 -0700 Subject: [PATCH] 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. --- cid.go | 4 ++++ cid_test.go | 14 ++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/cid.go b/cid.go index ae3d1fd..cc7c4b1 100644 --- a/cid.go +++ b/cid.go @@ -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} } diff --git a/cid_test.go b/cid_test.go index 31989da..f0c6ad5 100644 --- a/cid_test.go +++ b/cid_test.go @@ -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 {