From bad5cf2af82ae02a24d77921817d0b4773155247 Mon Sep 17 00:00:00 2001 From: Will Murphy Date: Wed, 24 Apr 2024 11:00:50 -0400 Subject: [PATCH] more passing lazy union reader tests Signed-off-by: Will Murphy --- syft/internal/unionreader/lazy_union_reader.go | 10 ++++++++-- .../unionreader/lazy_union_reader_test.go | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/syft/internal/unionreader/lazy_union_reader.go b/syft/internal/unionreader/lazy_union_reader.go index a6ce9a033..c2f6c4f33 100644 --- a/syft/internal/unionreader/lazy_union_reader.go +++ b/syft/internal/unionreader/lazy_union_reader.go @@ -49,8 +49,12 @@ func (c *lazyUnionReader) ReadAt(p []byte, off int64) (n int, err error) { needUntil := int64(len(p)) + off err = c.ensureReadUntil(needUntil) end := min(off+int64(len(p)), int64(len(c.buf))) - copy(p, c.buf[off:end]) - return int(end - off), err + start := min(off, c.maxRead()) + if off > start { + return 0, io.EOF + } + copy(p, c.buf[start:end]) + return int(end - start), err } func (c *lazyUnionReader) Seek(offset int64, whence int) (int64, error) { @@ -63,6 +67,7 @@ func (c *lazyUnionReader) Seek(offset int64, whence int) (int64, error) { trueOffset = offset case io.SeekCurrent: trueOffset = offset + c.cursor + err = c.ensureReadUntil(trueOffset) case io.SeekEnd: err = c.readAll() trueOffset = c.maxRead() + offset @@ -73,6 +78,7 @@ func (c *lazyUnionReader) Seek(offset int64, whence int) (int64, error) { if trueOffset < 0 { return 0, fmt.Errorf("request to read negative offset impossible %v", trueOffset) } + trueOffset = min(c.maxRead(), trueOffset) c.cursor = trueOffset return c.cursor, nil } diff --git a/syft/internal/unionreader/lazy_union_reader_test.go b/syft/internal/unionreader/lazy_union_reader_test.go index 44c27bc46..cbe6d0bb7 100644 --- a/syft/internal/unionreader/lazy_union_reader_test.go +++ b/syft/internal/unionreader/lazy_union_reader_test.go @@ -101,6 +101,21 @@ func Test_lazyUnionReader_ReadAt(t *testing.T) { wantBytes: []byte("ef"), wantEOF: true, }, + { + name: "read way out of bounds", + dst: make([]byte, 4), + off: 512, + wantN: 0, + wantEOF: true, + }, + { + name: "buffer more than available", + dst: make([]byte, 512), + off: 0, + wantN: 16, + wantBytes: []byte("0123456789abcdef"), + wantEOF: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) {