feat: initial goget release — modern IPv6-first download utility
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
//go:build linux || freebsd
|
||||
// +build linux freebsd
|
||||
|
||||
package archive
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// FuzzTarExtract tests tar extraction with fuzzed input to catch path traversal
|
||||
// and other security issues in header parsing.
|
||||
func FuzzTarExtract(f *testing.F) {
|
||||
// Seed corpus with valid tar data
|
||||
f.Add([]byte{})
|
||||
|
||||
// Minimal valid tar header (512 bytes of zeros)
|
||||
emptyHeader := make([]byte, 512)
|
||||
f.Add(emptyHeader)
|
||||
|
||||
// Tar file with a ".." path traversal attempt
|
||||
traversalTar := makeTarWithName("../../../etc/passwd")
|
||||
f.Add(traversalTar)
|
||||
|
||||
// Tar file with absolute path
|
||||
absTar := makeTarWithName("/etc/passwd")
|
||||
f.Add(absTar)
|
||||
|
||||
// Tar file with symlink pointing outside
|
||||
symlinkTar := makeSymlinkTar("link", "../../../etc/passwd")
|
||||
f.Add(symlinkTar)
|
||||
|
||||
f.Fuzz(func(t *testing.T, data []byte) {
|
||||
// Fuzz the tar extraction — it must never panic or escape the temp dir
|
||||
dir := t.TempDir()
|
||||
ext := NewTarExtractor()
|
||||
reader := bytes.NewReader(data)
|
||||
// Ignore errors — we only care about panics and path escapes
|
||||
_ = ext.Extract(reader, dir)
|
||||
})
|
||||
}
|
||||
|
||||
func makeTarWithName(name string) []byte {
|
||||
// Create a minimal tar file with a regular file at the given path
|
||||
var buf bytes.Buffer
|
||||
nameBytes := []byte(name)
|
||||
if len(nameBytes) > 99 {
|
||||
nameBytes = nameBytes[:99]
|
||||
}
|
||||
header := make([]byte, 512)
|
||||
copy(header[0:99], nameBytes)
|
||||
// Set type flag to regular file
|
||||
header[156] = '0'
|
||||
// Set size to zero
|
||||
buf.Write(header)
|
||||
// Two zero blocks to mark end of archive
|
||||
buf.Write(make([]byte, 1024))
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func makeSymlinkTar(name, target string) []byte {
|
||||
var buf bytes.Buffer
|
||||
nameBytes := []byte(name)
|
||||
if len(nameBytes) > 99 {
|
||||
nameBytes = nameBytes[:99]
|
||||
}
|
||||
header := make([]byte, 512)
|
||||
copy(header[0:99], nameBytes)
|
||||
// Set type flag to symlink
|
||||
header[156] = '2'
|
||||
// Write link target
|
||||
targetBytes := []byte(target)
|
||||
if len(targetBytes) > 99 {
|
||||
targetBytes = targetBytes[:99]
|
||||
}
|
||||
copy(header[157:256], targetBytes)
|
||||
buf.Write(header)
|
||||
buf.Write(make([]byte, 1024))
|
||||
return buf.Bytes()
|
||||
}
|
||||
Reference in New Issue
Block a user