Documentation
¶
Overview ¶
Example ¶
// Create a buffer to write our archive to. buf := new(bytes.Buffer) // Create a new siva archive. w := siva.NewWriter(buf) // Add some files to the archive. var files = []struct { Name, Body string }{ {"gopher.txt", "Gopher names:\nGeorge\nGeoffrey\nGonzo"}, {"readme.txt", "This archive contains some text files."}, {"todo.txt", "Get animal handling license."}, } for _, file := range files { hdr := &siva.Header{ Name: file.Name, Mode: 0600, ModTime: time.Now(), } if err := w.WriteHeader(hdr); err != nil { log.Fatalln(err) } if _, err := w.Write([]byte(file.Body)); err != nil { log.Fatalln(err) } } // Make sure to check the error on Close. if err := w.Close(); err != nil { log.Fatalln(err) } // Open the siva archive for reading. file := bytes.NewReader(buf.Bytes()) r := siva.NewReader(file) // Get all files in the siva file. i, err := r.Index() if err != nil { log.Fatalln(err) } // Iterate through the files in the archive. for _, e := range i { content, err := r.Get(e) if err != nil { log.Fatalln(err) } fmt.Printf("Contents of %s:\n", e.Name) if _, err := io.Copy(os.Stdout, content); err != nil { log.Fatalln(err) } fmt.Println() }
Output: Contents of gopher.txt: Gopher names: George Geoffrey Gonzo Contents of readme.txt: This archive contains some text files. Contents of todo.txt: Get animal handling license.
Index ¶
- Constants
- Variables
- func ToSafePath(p string) string
- type Flag
- type Header
- type Index
- func (i *Index) Filter() Index
- func (i Index) Find(name string) *IndexEntry
- func (i Index) Glob(pattern string) ([]*IndexEntry, error)
- func (s Index) Len() int
- func (s Index) Less(i, j int) bool
- func (i *Index) ReadFrom(r io.ReadSeeker, endBlock uint64) error
- func (s Index) Swap(i, j int)
- func (i *Index) ToSafePaths() Index
- func (i *Index) WriteTo(w io.Writer) error
- type IndexEntry
- type IndexFooter
- type IndexReadError
- type IndexWriteError
- type OrderedIndex
- func (o OrderedIndex) Add(e *IndexEntry) OrderedIndex
- func (o OrderedIndex) Delete(path string) OrderedIndex
- func (o OrderedIndex) Find(path string) *IndexEntry
- func (s OrderedIndex) Len() int
- func (s OrderedIndex) Less(i, j int) bool
- func (o OrderedIndex) Pos(path string) int
- func (o OrderedIndex) Sort()
- func (s OrderedIndex) Swap(i, j int)
- func (o OrderedIndex) Update(e *IndexEntry) OrderedIndex
- type ReadWriter
- func (w ReadWriter) Close() error
- func (w ReadWriter) Flush() error
- func (r ReadWriter) Get(e *IndexEntry) (*io.SectionReader, error)
- func (r ReadWriter) Index() (Index, error)
- func (r ReadWriter) Read(p []byte) (n int, err error)
- func (r ReadWriter) Seek(e *IndexEntry) (int64, error)
- func (w ReadWriter) Write(b []byte) (int, error)
- func (w ReadWriter) WriteHeader(h *Header) error
- type Reader
- type Writer
Examples ¶
Constants ¶
const (
IndexVersion uint8 = 1
)
Variables ¶
var ( IndexSignature = []byte{'I', 'B', 'A'} ErrInvalidIndexEntry = errors.New("invalid index entry") ErrInvalidSignature = errors.New("invalid signature") ErrEmptyIndex = errors.New("empty index") ErrUnsupportedIndexVersion = errors.New("unsupported index version") ErrCRC32Missmatch = errors.New("crc32 mismatch") )
var ( ErrPendingContent = errors.New("entry wasn't fully read") ErrInvalidCheckshum = errors.New("invalid checksum") ErrInvalidReaderAt = errors.New("reader provided dosen't implement ReaderAt interface") )
var ( ErrMissingHeader = errors.New("WriteHeader was not called, or already flushed") ErrClosedWriter = errors.New("Writer is closed") )
Functions ¶
func ToSafePath ¶ added in v1.2.0
ToSafePath transforms a filesystem path to one that is safe to use as a relative path on the native filesystem:
- Removes drive and network share on Windows. - Does regular clean up (removing `/./` parts). - Removes any leading `../`. - Removes leading `/`.
This is a convenience function to implement siva file extractors that are not vulnerable to zip slip and similar vulnerabilities. However, for Windows absolute paths (with drive or network share) it does not give consistent results across platforms.
If your application relies on using absolute paths, you should not use this and you are encouraged to do your own validation and normalization.
Types ¶
type Header ¶
type Header struct { // Name is an arbitrary UTF-8 string identifying a file in the archive. Note // that this might or might not be a POSIX-compliant path. // // Security note: Users should be careful when using name as a file path // (e.g. to extract an archive) since it can contain relative paths and be // vulnerable to Zip Slip (https://snyk.io/research/zip-slip-vulnerability) // or other potentially dangerous values such as absolute paths, network // drive addresses, etc. Name string ModTime time.Time Mode os.FileMode Flags Flag }
Header contains the meta information from a file
type Index ¶
type Index []*IndexEntry
Index contains all the files on a siva file, including duplicate files or even does flagged as deleted.
func (*Index) Filter ¶
Filter returns a filtered version of the current Index removing duplicates keeping the latest versions and filtering all the deleted files
func (Index) Find ¶
func (i Index) Find(name string) *IndexEntry
Find returns the first IndexEntry with the given name, if any
func (Index) Glob ¶ added in v1.1.0
func (i Index) Glob(pattern string) ([]*IndexEntry, error)
Glob returns all index entries whose name matches pattern or nil if there is no matching entry. The syntax of patterns is the same as in filepath.Match.
func (*Index) ReadFrom ¶
func (i *Index) ReadFrom(r io.ReadSeeker, endBlock uint64) error
ReadFrom reads an Index from a given reader, the position where the current block ends is required since we are reading the index from the end of the file
func (*Index) ToSafePaths ¶ added in v1.2.0
ToSafePaths creates a new index where all entry names are transformed to safe paths using the top-level `ToSafePath` function. If you are using siva to extract files to the file-system, you should either use this function or perform your own validation and normalization.
type IndexEntry ¶
type IndexEntry struct { Header Start uint64 Size uint64 CRC32 uint32 // contains filtered or unexported fields }
type IndexFooter ¶
type IndexFooter struct {}
type IndexReadError ¶ added in v1.1.2
type IndexReadError struct {
Err error
}
func (*IndexReadError) Error ¶ added in v1.1.2
func (e *IndexReadError) Error() string
type IndexWriteError ¶ added in v1.1.2
type IndexWriteError struct {
Err error
}
func (*IndexWriteError) Error ¶ added in v1.1.2
func (e *IndexWriteError) Error() string
type OrderedIndex ¶ added in v1.3.0
type OrderedIndex Index
OrderedIndex is a specialized index lexicographically ordered. It has methods to add or delete IndexEntries and maintain its order. Also has as faster Find method.
func (OrderedIndex) Add ¶ added in v1.3.0
func (o OrderedIndex) Add(e *IndexEntry) OrderedIndex
Add returns an updated index with the new IndexEntry.
func (OrderedIndex) Delete ¶ added in v1.3.0
func (o OrderedIndex) Delete(path string) OrderedIndex
Delete returns an updated index with the IndexEntry for the path deleted.
func (OrderedIndex) Find ¶ added in v1.3.0
func (o OrderedIndex) Find(path string) *IndexEntry
Find returns the IndexEntry for a path or nil. This version is faster than Index.Find.
func (OrderedIndex) Len ¶ added in v1.3.0
func (s OrderedIndex) Len() int
Len implements sort.Interface.
func (OrderedIndex) Less ¶ added in v1.3.0
func (s OrderedIndex) Less(i, j int) bool
Less implements sort.Interface.
func (OrderedIndex) Pos ¶ added in v1.3.0
func (o OrderedIndex) Pos(path string) int
Pos gets the position of the file in the index or where it should be inserted if it's not already there.
func (OrderedIndex) Sort ¶ added in v1.3.0
func (o OrderedIndex) Sort()
Sort orders the index lexicographically.
func (OrderedIndex) Swap ¶ added in v1.3.0
func (s OrderedIndex) Swap(i, j int)
Swap implements sort.Interface.
func (OrderedIndex) Update ¶ added in v1.3.0
func (o OrderedIndex) Update(e *IndexEntry) OrderedIndex
Update adds or deletes an IndexEntry to the index depending on the FlagDeleted value.
type ReadWriter ¶ added in v1.1.0
type ReadWriter struct {
// contains filtered or unexported fields
}
ReadWriter can read and write to the same siva file. It is not thread-safe.
func NewReaderWriter ¶ added in v1.1.0
func NewReaderWriter(rw io.ReadWriteSeeker) (*ReadWriter, error)
func (ReadWriter) Close ¶ added in v1.1.0
func (w ReadWriter) Close() error
Close closes the siva archive, writing the Index footer to the current writer.
func (ReadWriter) Flush ¶ added in v1.1.0
func (w ReadWriter) Flush() error
Flush finishes writing the current file (optional)
func (ReadWriter) Get ¶ added in v1.1.0
func (r ReadWriter) Get(e *IndexEntry) (*io.SectionReader, error)
Get returns a new io.SectionReader allowing concurrent read access to the content of the read
func (ReadWriter) Index ¶ added in v1.1.0
Index reads the index of the siva file from the provided reader
func (ReadWriter) Read ¶ added in v1.1.0
Read reads up to len(p) bytes, starting at the current position set by Seek and ending in the end of the content, retuning a io.EOF when its reached
func (ReadWriter) Seek ¶ added in v1.1.0
func (r ReadWriter) Seek(e *IndexEntry) (int64, error)
Seek seek the internal reader to the starting position of the content for the given IndexEntry
func (ReadWriter) Write ¶ added in v1.1.0
Write writes to the current entry in the siva archive, WriteHeader should called before, if not returns ErrMissingHeader
func (ReadWriter) WriteHeader ¶ added in v1.1.0
WriteHeader writes hdr and prepares to accept the file's contents.
type Reader ¶
type Reader interface { io.Reader Seek(e *IndexEntry) (int64, error) Index() (Index, error) Get(e *IndexEntry) (*io.SectionReader, error) }
A Reader provides random access to the contents of a siva archive.
func NewReader ¶
func NewReader(r io.ReadSeeker) Reader
NewReader creates a new Reader reading from r, reader requires be seekable and optionally should implement io.ReaderAt to make usage of the Get method
func NewReaderWithOffset ¶ added in v1.5.0
func NewReaderWithOffset(r io.ReadSeeker, o uint64) Reader
NewReaderWithOffset creates a new Reader giving the position of the index. This is useful to open siva files that are being written or reading an old index.