Skip to content
This repository has been archived by the owner on Mar 29, 2023. It is now read-only.

Commit

Permalink
Allow skipping entries in multipartIterator
Browse files Browse the repository at this point in the history
  • Loading branch information
magik6k committed Dec 9, 2018
1 parent 66bfc7a commit b925960
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 13 deletions.
31 changes: 31 additions & 0 deletions multifilereader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,37 @@ func TestMultiFileReaderToMultiFile(t *testing.T) {
}
}

func TestMultiFileReaderToMultiFileSkip(t *testing.T) {
mfr := getTestMultiFileReader(t)
mpReader := multipart.NewReader(mfr, mfr.Boundary())
mf, err := NewFileFromPartReader(mpReader, multipartFormdataType)
if err != nil {
t.Fatal(err)
}

md, ok := mf.(Directory)
if !ok {
t.Fatal("Expected a directory")
}
it := md.Entries()

if !it.Next() || it.Name() != "beep.txt" {
t.Fatal("iterator didn't work as expected")
}

if !it.Next() || it.Name() != "boop" || DirFrom(it) == nil {
t.Fatal("iterator didn't work as expected")
}

if !it.Next() || it.Name() != "file.txt" || DirFrom(it) != nil || it.Err() != nil {
t.Fatal("iterator didn't work as expected")
}

if it.Next() || it.Err() != nil {
t.Fatal("iterator didn't work as expected")
}
}

func TestOutput(t *testing.T) {
mfr := getTestMultiFileReader(t)
mpReader := &peekReader{r: multipart.NewReader(mfr, mfr.Boundary())}
Expand Down
47 changes: 34 additions & 13 deletions multipartfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"mime/multipart"
"net/url"
"path"
"strings"
)

const (
Expand All @@ -22,6 +23,7 @@ const (
)

var ErrPartOutsideParent = errors.New("file outside parent dir")
var ErrPartInChildTree = errors.New("file in child tree")

// MultipartFile implements Node, and is created from a `multipart.Part`.
//
Expand Down Expand Up @@ -56,7 +58,19 @@ func newFileFromPart(parent string, part *multipart.Part, reader PartReader) (st
}

dir, base := path.Split(f.fileName())
if path.Clean(dir) != path.Clean(parent) {
dir = path.Clean(dir)
parent = path.Clean(parent)
if dir == "." {
dir = ""
}
if parent == "." {
parent = ""
}

if dir != parent {
if strings.HasPrefix(dir, parent) {
return "", nil, ErrPartInChildTree
}
return "", nil, ErrPartOutsideParent
}

Expand Down Expand Up @@ -118,21 +132,28 @@ func (it *multipartIterator) Next() bool {
if it.f.Reader == nil {
return false
}
part, err := it.f.Reader.NextPart()
if err != nil {
if err == io.EOF {
var part *multipart.Part
for {
var err error
part, err = it.f.Reader.NextPart()
if err != nil {
if err == io.EOF {
return false
}
it.err = err
return false
}
it.err = err
return false
}

name, cf, err := newFileFromPart(it.f.fileName(), part, it.f.Reader)
if err != ErrPartOutsideParent {
it.curFile = cf
it.curName = name
it.err = err
return err == nil
name, cf, err := newFileFromPart(it.f.fileName(), part, it.f.Reader)
if err == ErrPartOutsideParent {
break
}
if err != ErrPartInChildTree {
it.curFile = cf
it.curName = name
it.err = err
return err == nil
}
}

// we read too much, try to fix this
Expand Down

0 comments on commit b925960

Please sign in to comment.