mirror of
https://github.com/moonD4rk/HackBrowserData.git
synced 2026-06-10 20:07:46 +02:00
cd0b2daaf3
* feat(cli): add archive command for cross-host data transport * fix(archive): correct flat-layout path and entry-count wording * refactor(archive): rename BuildArchive to WriteArchive
89 lines
2.0 KiB
Go
89 lines
2.0 KiB
Go
package fileutil
|
|
|
|
import (
|
|
"archive/zip"
|
|
"bytes"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestZipDirUnzip_RoundTrip(t *testing.T) {
|
|
src := t.TempDir()
|
|
files := map[string][]byte{
|
|
"empty.txt": {},
|
|
"small.txt": []byte("hello"),
|
|
"Default/Network/Cookies": []byte("cookie-bytes"),
|
|
"sub/big.bin": bytes.Repeat([]byte("A"), 3<<20), // 3 MiB: exercises the chunked copy loop
|
|
}
|
|
for rel, data := range files {
|
|
p := filepath.Join(src, filepath.FromSlash(rel))
|
|
if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(p, data, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
zipPath := filepath.Join(t.TempDir(), "out.zip")
|
|
if err := ZipDir(zipPath, src); err != nil {
|
|
t.Fatalf("ZipDir: %v", err)
|
|
}
|
|
|
|
zr, err := zip.OpenReader(zipPath)
|
|
if err != nil {
|
|
t.Fatalf("open zip: %v", err)
|
|
}
|
|
for _, f := range zr.File {
|
|
if strings.Contains(f.Name, `\`) {
|
|
t.Errorf("zip entry name must be forward-slash, got %q", f.Name)
|
|
}
|
|
}
|
|
if err := zr.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
dst := t.TempDir()
|
|
if err := Unzip(zipPath, dst); err != nil {
|
|
t.Fatalf("Unzip: %v", err)
|
|
}
|
|
for rel, want := range files {
|
|
got, err := os.ReadFile(filepath.Join(dst, filepath.FromSlash(rel)))
|
|
if err != nil {
|
|
t.Errorf("missing %s after Unzip: %v", rel, err)
|
|
continue
|
|
}
|
|
if !bytes.Equal(got, want) {
|
|
t.Errorf("%s: content mismatch (got %d bytes, want %d)", rel, len(got), len(want))
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUnzip_RejectsZipSlip(t *testing.T) {
|
|
zipPath := filepath.Join(t.TempDir(), "evil.zip")
|
|
f, err := os.Create(zipPath)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
zw := zip.NewWriter(f)
|
|
w, err := zw.Create("../escape.txt")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := w.Write([]byte("pwned")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := zw.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := f.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := Unzip(zipPath, t.TempDir()); err == nil {
|
|
t.Fatal("Unzip must reject an entry that escapes the destination")
|
|
}
|
|
}
|