Skip to content

Commit

Permalink
fix: Handle small reads in branch converters (#144)
Browse files Browse the repository at this point in the history
* fix: Handle reads into small slices

Handle the case for `Read(p)` where `len(p)` is smaller than the minimum
length required by the branch converter.

* test: Make use of `iotest.OneByteReader()`

This now exposes a bug in all of the branch converters.

* fix: Handle small reads in branch converters

Add missing benchmarks also.
  • Loading branch information
bodgit authored Dec 12, 2023
1 parent f654743 commit dfaf538
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
8 changes: 8 additions & 0 deletions internal/bra/bra.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,11 @@ func max(x, y int) int {

return y
}

func min(x, y int) int {
if x < y {
return x
}

return y
}
15 changes: 11 additions & 4 deletions internal/bra/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
type readCloser struct {
rc io.ReadCloser
buf bytes.Buffer
n int
conv converter
}

Expand All @@ -30,13 +31,19 @@ func (rc *readCloser) Read(p []byte) (int, error) {
if !errors.Is(err, io.EOF) {
return 0, err
}
}

if n := rc.conv.Convert(rc.buf.Bytes(), false); n > 0 {
return rc.buf.Read(p[:n])
if rc.buf.Len() < rc.conv.Size() {
rc.n = rc.buf.Len()
}
}

return rc.buf.Read(p)
rc.n += rc.conv.Convert(rc.buf.Bytes()[rc.n:], false)

n, err := rc.buf.Read(p[:min(rc.n, len(p))])

rc.n -= n

return n, err
}

func newReader(readers []io.ReadCloser, conv converter) (io.ReadCloser, error) {
Expand Down
19 changes: 18 additions & 1 deletion reader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"
"testing"
"testing/fstest"
"testing/iotest"

"github.com/bodgit/sevenzip"
"github.com/bodgit/sevenzip/internal/util"
Expand All @@ -28,7 +29,7 @@ func readArchive(t *testing.T, r *sevenzip.ReadCloser) {

h.Reset()

if _, err := io.Copy(h, rc); err != nil {
if _, err := io.Copy(h, iotest.OneByteReader(rc)); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -332,3 +333,19 @@ func BenchmarkBrotli(b *testing.B) {
func BenchmarkZstandard(b *testing.B) {
benchmarkArchive(b, "zstd.7z")
}

func BenchmarkBCJ(b *testing.B) {
benchmarkArchive(b, "bcj.7z")
}

func BenchmarkPPC(b *testing.B) {
benchmarkArchive(b, "ppc.7z")
}

func BenchmarkARM(b *testing.B) {
benchmarkArchive(b, "arm.7z")
}

func BenchmarkSPARC(b *testing.B) {
benchmarkArchive(b, "sparc.7z")
}

0 comments on commit dfaf538

Please sign in to comment.