forked from mirrors/tar-split
tar/asm: add FileGetter and concerns in README
This commit is contained in:
parent
7ccbb9d40c
commit
e1206b43a6
3 changed files with 52 additions and 22 deletions
|
@ -5,6 +5,21 @@ This library for assembly and disassembly of tar archives, facilitated by
|
|||
`github.com/vbatts/tar-split/tar/storage`.
|
||||
|
||||
|
||||
Concerns
|
||||
--------
|
||||
|
||||
For completely safe assembly/disassembly, there will need to be a CAS
|
||||
directory, that maps to a checksum in the `storage.Entity` of
|
||||
`storage.FileType`.
|
||||
|
||||
This is due to the fact that tar archives _can_ allow multiple records for the
|
||||
same path, but the last one effectively wins. Even if the prior records had a
|
||||
different payload.
|
||||
|
||||
In this way, when assembling an archive from relative paths, if the archive has
|
||||
multiple entries for the same path, then all payloads read in from a relative
|
||||
path would be identical.
|
||||
|
||||
|
||||
Thoughts
|
||||
--------
|
||||
|
|
|
@ -2,13 +2,11 @@ package asm
|
|||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/vbatts/tar-split/tar/storage"
|
||||
)
|
||||
|
||||
func NewTarStream(relpath string, up storage.Unpacker) io.ReadCloser {
|
||||
func NewTarStream(fg FileGetter, up storage.Unpacker) io.ReadCloser {
|
||||
pr, pw := io.Pipe()
|
||||
go func() {
|
||||
for {
|
||||
|
@ -24,7 +22,16 @@ func NewTarStream(relpath string, up storage.Unpacker) io.ReadCloser {
|
|||
break
|
||||
}
|
||||
case storage.FileType:
|
||||
if err := writeEntryFromRelPath(pw, relpath, entry); err != nil {
|
||||
if entry.Size == 0 {
|
||||
continue
|
||||
}
|
||||
fh, err := fg.Get(entry.Name)
|
||||
if err != nil {
|
||||
pw.CloseWithError(err)
|
||||
break
|
||||
}
|
||||
defer fh.Close()
|
||||
if _, err := io.Copy(pw, fh); err != nil {
|
||||
pw.CloseWithError(err)
|
||||
break
|
||||
}
|
||||
|
@ -33,21 +40,3 @@ func NewTarStream(relpath string, up storage.Unpacker) io.ReadCloser {
|
|||
}()
|
||||
return pr
|
||||
}
|
||||
|
||||
func writeEntryFromRelPath(w io.Writer, root string, entry *storage.Entry) error {
|
||||
if entry.Size == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// FIXME might should have a check for '../../../../etc/passwd' attempts?
|
||||
fh, err := os.Open(path.Join(root, entry.Name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fh.Close()
|
||||
if _, err := io.Copy(w, fh); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
26
tar/asm/getter.go
Normal file
26
tar/asm/getter.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package asm
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
type FileGetter interface {
|
||||
// Get returns a stream for the provided file path
|
||||
Get(string) (io.ReadCloser, error)
|
||||
}
|
||||
|
||||
// NewPathFileGetter returns a FileGetter that is for files relative to path relpath.
|
||||
func NewPathFileGetter(relpath string) FileGetter {
|
||||
return &pathFileGetter{root: relpath}
|
||||
}
|
||||
|
||||
type pathFileGetter struct {
|
||||
root string
|
||||
}
|
||||
|
||||
func (pfg pathFileGetter) Get(filename string) (io.ReadCloser, error) {
|
||||
// FIXME might should have a check for '../../../../etc/passwd' attempts?
|
||||
return os.Open(path.Join(pfg.root, filename))
|
||||
}
|
Loading…
Reference in a new issue