Documentation
¶
Overview ¶
Package archive packs and extracts a plugin package.
A published release is bytes somebody else produced, so extraction is the place this feature can be attacked. Every guard here exists because a tar reader that trusts its input will happily write outside the directory it was given, follow a link into somebody's home, or expand a kilobyte into a disk.
It depends only on the standard library so both sides can run it: the client packs and installs, and internal/server validates the same bytes without reaching into internal/config.
Index ¶
Constants ¶
const DigestPrefix = "sha256:"
DigestPrefix labels the one hash this format uses. Recording the algorithm beside the value means a later change cannot be mistaken for a mismatch.
const GitDir = ".git"
GitDir is excluded when packing. A checkout's history is not plugin content, it is usually larger than everything that is, and it carries branches and remotes the author never meant to publish.
Variables ¶
var ( ErrTraversal = errors.New("archive entry escapes the destination") ErrLink = errors.New("archive contains a link") ErrIrregular = errors.New("archive contains a file that is not a regular file or directory") ErrDuplicate = errors.New("archive contains the same path twice") ErrTooManyFiles = errors.New("archive holds more files than the limit allows") ErrTooLarge = errors.New("archive is larger than the limit allows") ErrPathTooLong = errors.New("archive entry path is longer than the limit allows") ErrDigest = errors.New("digest does not match") )
Violations extraction refuses. Each is a way an archive can reach outside what it was given.
Functions ¶
Types ¶
type Limits ¶
type Limits struct {
MaxFiles int
MaxFileBytes int64
MaxTotalBytes int64
MaxCompressedBytes int64
MaxPathLength int
}
Limits bound what an archive may cost to accept. Zero fields take the default, so a caller cannot accidentally disable a guard by leaving one out.
func ResolveLimits ¶
ResolveLimits fills in the zero fields of lim, so a caller outside this package can see the same bounds extraction will apply.
type Summary ¶
type Summary struct {
Files int
Bytes int64
// Digest is set by Pack, over exactly the bytes it wrote.
Digest string
}
Summary describes what was packed or extracted.
func Extract ¶
Extract writes an archive into destDir, which must already exist.
Nothing in the archive decides where a byte lands: every path is cleaned and checked against the destination before a file is opened, links are refused outright rather than resolved, and modes come from the extractor rather than from the header.
func Pack ¶
Pack writes root as a gzipped tar and returns the digest of what it wrote.
The output is deterministic: entries are walked in lexical order, timestamps and ownership are zeroed, and modes are normalised. Packing one tree twice therefore produces one digest, which is what lets a publisher and a consumer compare notes about the same release.