diff --git a/internal/bra/reader.go b/internal/bra/reader.go index 733333b..0cbee98 100644 --- a/internal/bra/reader.go +++ b/internal/bra/reader.go @@ -43,6 +43,10 @@ func (rc *readCloser) Read(p []byte) (int, error) { return 0, fmt.Errorf("bra: error buffering: %w", err) } + if rc.buf.Len() == 0 { // Buffer is empty and read closer returned EOF; no more data available + return 0, io.EOF + } + if rc.buf.Len() < rc.conv.Size() { rc.n = rc.buf.Len() } diff --git a/reader_test.go b/reader_test.go index 771ba1f..da5159f 100644 --- a/reader_test.go +++ b/reader_test.go @@ -14,6 +14,7 @@ import ( "testing" "testing/fstest" "testing/iotest" + "time" "github.com/bodgit/sevenzip" "github.com/bodgit/sevenzip/internal/util" @@ -434,6 +435,58 @@ func TestFS(t *testing.T) { } } +// TestBraRead is a separate test as the example archive cannot be added to +// the existing test cases in TestOpenReader as it triggers an error in the +// LZMA library which is unrelated to the bug that it is a test case for. +// However extracting this one file is enough to demonstrate the bug and +// validate the fix so it's here as a separate test. +func TestBraRead(t *testing.T) { + t.Parallel() + + eg := new(errgroup.Group) + + //nolint:wrapcheck + eg.Go(func() (err error) { + r, err := sevenzip.OpenReader(filepath.Join("testdata", "pr472.7z")) + if err != nil { + return err + } + + defer func() { + err = errors.Join(err, r.Close()) + }() + + file, err := r.Open("Plug 1.2/Plug 1.2.exe") + if err != nil { + return err + } + + defer func() { + err = errors.Join(err, file.Close()) + }() + + if _, err = io.ReadAll(file); err != nil { + return err + } + + return nil + }) + + done := make(chan error, 1) + go func() { + done <- eg.Wait() + }() + + select { + case err := <-done: + if err != nil { + t.Fatal(err) + } + case <-time.After(2 * time.Second): + t.Fatalf("timeout waiting for reader to complete") + } +} + func FuzzNewReaderWithPassword(f *testing.F) { b, err := os.ReadFile(filepath.Join("testdata", "copy.7z")) if err != nil { diff --git a/testdata/pr472.7z b/testdata/pr472.7z new file mode 100644 index 0000000..f330ab9 Binary files /dev/null and b/testdata/pr472.7z differ