diff --git a/ipld/car/v2/reader.go b/ipld/car/v2/reader.go index db8f82105..2f7cbb18e 100644 --- a/ipld/car/v2/reader.go +++ b/ipld/car/v2/reader.go @@ -113,10 +113,10 @@ func (r *Reader) DataReader() SectionReader { // present. Otherwise, returns nil. // Note, this function will always return nil if the backing payload represents a CARv1. func (r *Reader) IndexReader() io.Reader { - if r.Version == 2 { - return internalio.NewOffsetReadSeeker(r.r, int64(r.Header.IndexOffset)) + if r.Version == 1 || !r.Header.HasIndex() { + return nil } - return nil + return internalio.NewOffsetReadSeeker(r.r, int64(r.Header.IndexOffset)) } // Close closes the underlying reader if it was opened by OpenReader. diff --git a/ipld/car/v2/reader_test.go b/ipld/car/v2/reader_test.go index 02906f1a8..a0c6e3cda 100644 --- a/ipld/car/v2/reader_test.go +++ b/ipld/car/v2/reader_test.go @@ -212,6 +212,30 @@ func TestOpenReader_DoesNotPanicForReadersCreatedAfterClosure(t *testing.T) { require.NotPanics(t, func() { panicTest(iReaderAfterClosure) }) } +func TestReader_ReturnsNilWhenThereIsNoIndex(t *testing.T) { + tests := []struct { + name string + path string + }{ + { + name: "IndexlessCarV2", + path: "testdata/sample-v2-indexless.car", + }, + { + name: "CarV1", + path: "testdata/sample-v1.car", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + subject, err := carv2.OpenReader(tt.path) + require.NoError(t, err) + t.Cleanup(func() { require.NoError(t, subject.Close()) }) + require.Nil(t, subject.IndexReader()) + }) + } +} + func requireNewCarV1ReaderFromV2File(t *testing.T, carV12Path string, zerLenAsEOF bool) *carv1.CarReader { f, err := os.Open(carV12Path) require.NoError(t, err) diff --git a/ipld/car/v2/testdata/sample-v2-indexless.car b/ipld/car/v2/testdata/sample-v2-indexless.car new file mode 100644 index 000000000..3b160b6fa Binary files /dev/null and b/ipld/car/v2/testdata/sample-v2-indexless.car differ