Documentation
¶
Overview ¶
Package compress provides gzip and tar archive utilities with security protections.
Features include path traversal prevention, zip bomb protection (100 MB per-file limit), and file mode validation. Supports tar, gzip, tar.gz, and base64-encoded tar.gz formats.
Index ¶
- Constants
- Variables
- func Gz(source io.Reader, writer io.Writer) error
- func Tar(sourceDirectory string, writer io.Writer) error
- func TarGz(sourceDirectory string, writer io.Writer) error
- func TarGzBase64(sourceDirectory string) (string, error)
- func UnGz(src io.Reader, dst string, opts ...ExtractOption) (int64, error)
- func UnTar(src io.Reader, destinationDir string, opts ...ExtractOption) (written int64, err error)
- func UnTarGz(src io.Reader, destinationDir string, opts ...ExtractOption) (int64, error)
- func UnTarGzBase64(encoded string, destinationDir string, opts ...ExtractOption) (int64, error)
- type ExtractOption
Examples ¶
Constants ¶
const ( // DefaultMaxFileSize is the default maximum size for a single extracted file (100 MB). DefaultMaxFileSize int64 = 100 * 1024 * 1024 // DefaultMaxArchiveSize is the default maximum total extracted size for an archive (1 GB). DefaultMaxArchiveSize int64 = 1024 * 1024 * 1024 )
Variables ¶
var ( // ErrSizeLimitExceeded is returned when an extraction guard rail rejects // content that exceeds a configured size limit (per-file or total archive). ErrSizeLimitExceeded = errors.New("size limit exceeded") // ErrPathTraversal is returned when a path guard rail rejects a destination // or archive entry that could escape the intended extraction location. ErrPathTraversal = errors.New("path traversal detected") // ErrNotDirectory is returned when a path that must be a directory // (tar source or extraction destination) is not one. ErrNotDirectory = errors.New("not a directory") )
Functions ¶
func Gz ¶
Gz compresses data from source using gzip and writes the compressed output to writer.
The caller is responsible for closing writer if needed.
Example ¶
Gz compresses data from any io.Reader into any io.Writer.
package main
import (
"bytes"
"fmt"
"github.com/jasoet/pkg/v3/compress"
)
func main() {
var buf bytes.Buffer
if err := compress.Gz(bytes.NewReader([]byte("hello, world")), &buf); err != nil {
panic(err)
}
fmt.Println("compressed bytes:", buf.Len())
}
Output: compressed bytes: 36
func Tar ¶
Tar creates a tar archive of sourceDirectory and writes it to writer.
Only regular files are included; symlinks and other special files are skipped. The caller is responsible for closing writer if needed.
func TarGz ¶
TarGz creates a gzip-compressed tar archive of sourceDirectory and writes it to writer.
The caller is responsible for closing writer if needed.
func TarGzBase64 ¶
TarGzBase64 creates a gzip-compressed tar archive of sourceDirectory and returns it as a base64-encoded string.
func UnGz ¶
UnGz decompresses gzip data from src and writes the result to the file at dst.
Decompression is limited to prevent zip bomb attacks: the effective limit is the smaller of maxFileSize (default 100 MB) and maxArchiveSize (default 1 GB), configurable via WithMaxFileSize and WithMaxArchiveSize. Unlike UnTar, dst must be an absolute path (relative paths are rejected with ErrPathTraversal); UnTar accepts relative destination directories. Returns the number of bytes written and any error encountered.
Example ¶
UnGz decompresses a gzip stream into a file at an absolute destination path.
package main
import (
"bytes"
"fmt"
"os"
"path/filepath"
"github.com/jasoet/pkg/v3/compress"
)
func main() {
var buf bytes.Buffer
if err := compress.Gz(bytes.NewReader([]byte("hello, world")), &buf); err != nil {
panic(err)
}
dir, err := os.MkdirTemp("", "compress-example")
if err != nil {
panic(err)
}
defer os.RemoveAll(dir)
dst := filepath.Join(dir, "out.txt")
written, err := compress.UnGz(&buf, dst)
if err != nil {
panic(err)
}
content, err := os.ReadFile(dst)
if err != nil {
panic(err)
}
fmt.Printf("wrote %d bytes: %s\n", written, content)
}
Output: wrote 12 bytes: hello, world
func UnTar ¶
UnTar extracts a tar archive from src into destinationDir.
Includes security protections: path traversal prevention, file mode validation, per-file size limit (default 100 MB), and total archive size limit (default 1 GB) to prevent zip bombs. Use ExtractOption to customize limits. Unlike UnGz, destinationDir may be a relative path; entry paths inside the archive are still validated to stay within destinationDir.
func UnTarGzBase64 ¶
func UnTarGzBase64(encoded string, destinationDir string, opts ...ExtractOption) (int64, error)
UnTarGzBase64 decodes a base64-encoded gzip tar archive and extracts it to destinationDir.
Types ¶
type ExtractOption ¶
type ExtractOption func(*extractConfig)
ExtractOption configures extraction behavior for UnGz, UnTar, UnTarGz, and UnTarGzBase64.
func WithMaxArchiveSize ¶
func WithMaxArchiveSize(size int64) ExtractOption
WithMaxArchiveSize sets the maximum total extracted size for the entire archive. Default: 1 GB.
func WithMaxFileSize ¶
func WithMaxFileSize(size int64) ExtractOption
WithMaxFileSize sets the maximum allowed size for a single extracted file. Default: 100 MB.