Skip to content

Commit

Permalink
add test
Browse files Browse the repository at this point in the history
  • Loading branch information
james-rms committed Sep 12, 2024
1 parent fb386a0 commit 7b096d5
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 11 deletions.
23 changes: 12 additions & 11 deletions go/mcap/indexed_message_iterator.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"github.com/pierrec/lz4/v4"
)

var ErrBadOffset = errors.New("cannot seek to offset")
var ErrBadOffset = errors.New("invalid offset")

const (
chunkBufferGrowthMultiple = 1.2
Expand Down Expand Up @@ -74,23 +74,24 @@ type indexedMessageIterator struct {
metadataCallback func(*Metadata) error
}

func (it *indexedMessageIterator) seekTo(offset uint64) (int64, error) {
func (it *indexedMessageIterator) seekTo(offset uint64) error {
if offset > uint64(math.MaxInt64) {
return 0, fmt.Errorf("%w: %d > int64 max", ErrBadOffset, offset)
return fmt.Errorf("%w: %d > int64 max", ErrBadOffset, offset)
}
signedOffset := int64(offset)
fmt.Printf("signedOffset: %d, size: %d\n", signedOffset, it.fileSize)
if signedOffset >= it.fileSize {
return 0, fmt.Errorf("%w: %d past file end %d", ErrBadOffset, offset, it.fileSize)
return fmt.Errorf("%w: %d past file end %d", ErrBadOffset, offset, it.fileSize)
}
pos, err := it.rs.Seek(signedOffset, io.SeekStart)
return pos, err
_, err := it.rs.Seek(signedOffset, io.SeekStart)
return err
}

// parseIndexSection parses the index section of the file and populates the
// related fields of the structure. It must be called prior to any of the other
// access methods.
func (it *indexedMessageIterator) parseSummarySection() error {
const footerStartOffsetFromEnd = +8 + 4 + 8 + 8 // magic, plus 20 bytes footer
const footerStartOffsetFromEnd = 8 + 4 + 8 + 8 // magic, plus 20 bytes footer
footerStartPos, err := it.rs.Seek(-footerStartOffsetFromEnd, io.SeekEnd)
if err != nil {
return err
Expand All @@ -116,9 +117,9 @@ func (it *indexedMessageIterator) parseSummarySection() error {
it.hasReadSummarySection = true
return nil
}
_, err = it.seekTo(footer.SummaryStart)
err = it.seekTo(footer.SummaryStart)
if err != nil {
return fmt.Errorf("failed to seek to summary start")
return fmt.Errorf("failed to seek to summary start: %w", err)
}

lexer, err := NewLexer(bufio.NewReader(it.rs), &LexerOptions{
Expand Down Expand Up @@ -208,7 +209,7 @@ func (it *indexedMessageIterator) parseSummarySection() error {
// loadChunk seeks to and decompresses a chunk into a chunk slot, then populates it.messageIndexes
// with the offsets of messages in that chunk.
func (it *indexedMessageIterator) loadChunk(chunkIndex *ChunkIndex) error {
_, err := it.seekTo(chunkIndex.ChunkStartOffset)
err := it.seekTo(chunkIndex.ChunkStartOffset)
if err != nil {
return err
}
Expand Down Expand Up @@ -397,7 +398,7 @@ func (it *indexedMessageIterator) NextInto(msg *Message) (*Schema, *Channel, *Me
// take care of the metadata here
if it.metadataCallback != nil {
for _, idx := range it.metadataIndexes {
_, err := it.seekTo(idx.Offset)
err := it.seekTo(idx.Offset)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to seek to metadata: %w", err)
}
Expand Down
26 changes: 26 additions & 0 deletions go/mcap/reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1126,3 +1126,29 @@ func BenchmarkReader(b *testing.B) {
})
}
}

func TestFooterOffsetErrorDetected(t *testing.T) {
buf := &bytes.Buffer{}
writer, err := NewWriter(buf, &WriterOptions{
Chunked: true,
ChunkSize: 1024,
Compression: "",
})
require.NoError(t, err)
require.NoError(t, writer.WriteHeader(&Header{}))
require.NoError(t, writer.WriteChannel(&Channel{ID: 1}))
require.NoError(t, writer.WriteMessage(&Message{ChannelID: 1}))
require.NoError(t, writer.Close())

// break the footer summary offset field. This is 8 + 8 + 4 + 8 bytes from end of file.
mcapBytes := buf.Bytes()
end := len(mcapBytes)
fmt.Printf("end is %d\n", end)
binary.LittleEndian.PutUint64(mcapBytes[end-8-8-4-8:], 999999999)

reader, err := NewReader(bytes.NewReader(mcapBytes))
require.NoError(t, err)

_, err = reader.Info()
require.ErrorIs(t, err, ErrBadOffset)
}

0 comments on commit 7b096d5

Please sign in to comment.