Skip to content

Commit

Permalink
constrain max buffer size
Browse files Browse the repository at this point in the history
  • Loading branch information
ybirader committed Sep 5, 2023
1 parent d253f8e commit b5348b1
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 7 deletions.
7 changes: 3 additions & 4 deletions archiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,14 @@ func (a *Archiver) compress(file *pool.File) error {
return nil
}

compressor, err := flate.NewWriter(&file.CompressedData, defaultCompression)
compressor, err := flate.NewWriter(file, defaultCompression)
if err != nil {
return errors.New("ERROR: could not create compressor")
}
hasher := crc32.NewIEEE()
w := io.MultiWriter(compressor, hasher)

err = a.read(w, file)
err = a.copy(w, file)
if err != nil {
return errors.Wrapf(err, "ERROR: could not read file %s", file.Path)
}
Expand All @@ -203,11 +203,10 @@ func (a *Archiver) compress(file *pool.File) error {
}

file.Header.CRC32 = hasher.Sum32()
file.Status = pool.FileFinished
return nil
}

func (a *Archiver) read(w io.Writer, file *pool.File) error {
func (a *Archiver) copy(w io.Writer, file *pool.File) error {
f, err := os.Open(file.Path)
if err != nil {
return errors.Errorf("ERROR: could not open file %s", file.Path)
Expand Down
21 changes: 21 additions & 0 deletions archiver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package pzip

import (
"archive/zip"
"bytes"
"encoding/binary"
"fmt"
"path/filepath"
Expand Down Expand Up @@ -142,6 +143,26 @@ func TestCompress(t *testing.T) {
assertExtendedTimestamp(t, file.Header.Extra)
})

t.Run("writes a maximum of buffer cap bytes", func(t *testing.T) {
archive, cleanup := testutils.CreateTempArchive(t, archivePath)
defer cleanup()

archiver, err := NewArchiver(archive)
assert.NoError(t, err)

info := testutils.GetFileInfo(t, helloTxtFileFixture)
file, err := pool.NewFile(helloTxtFileFixture, info, "")
assert.NoError(t, err)
bufCap := 5
file.CompressedData = *bytes.NewBuffer(make([]byte, 0, bufCap))

err = archiver.compress(&file)
assert.NoError(t, err)

assert.Equal(t, file.CompressedData.Len(), bufCap)
assert.Equal(t, pool.FileFull, file.Status)
})

t.Run("for directories", func(t *testing.T) {
archive, cleanup := testutils.CreateTempArchive(t, archivePath)
defer cleanup()
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/pzip

go 1.20
go 1.21

require (
github.com/alecthomas/assert/v2 v2.3.0
Expand Down
16 changes: 14 additions & 2 deletions pool/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ type File struct {
type Status int

const (
FileFinished Status = iota
defaultBufferSize = 1000000
FileFinished Status = iota
FileFull
)

func NewFile(path string, info fs.FileInfo, relativeTo string) (File, error) {
Expand All @@ -29,14 +31,24 @@ func NewFile(path string, info fs.FileInfo, relativeTo string) (File, error) {
return File{}, errors.Errorf("ERROR: could not get file info header for %s: %v", path, err)
}

f := File{Path: path, Info: info, Header: hdr}
f := File{Path: path, Info: info, Header: hdr, CompressedData: *bytes.NewBuffer(make([]byte, 0, defaultBufferSize))}
if relativeTo != "" {
f.setNameRelativeTo(relativeTo)
}

return f, nil
}

func (f *File) Write(p []byte) (n int, err error) {
if f.CompressedData.Available() != 0 {
maxWritable := min(f.CompressedData.Available(), len(p))
return f.CompressedData.Write(p[:int(maxWritable)])
}

f.Status = FileFull
return len(p), nil
}

func (f *File) setNameRelativeTo(root string) error {
relativeToRoot, err := filepath.Rel(root, f.Path)
if err != nil {
Expand Down

0 comments on commit b5348b1

Please sign in to comment.