74 lines
2.2 KiB
Go
74 lines
2.2 KiB
Go
package assets
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"testing"
|
|
)
|
|
|
|
func TestLocalFSPutReadDelete(t *testing.T) {
|
|
store, err := NewLocalFS(t.TempDir(), "https://app.test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
stored, err := store.Put(context.Background(), "uploads/day/a file.png", bytes.NewReader([]byte("asset")), 5, "image/png")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if stored.URL != "https://app.test/uploads/day/a%20file.png" {
|
|
t.Fatalf("URL = %q", stored.URL)
|
|
}
|
|
blob, err := store.Read(context.Background(), stored.Key)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
b, _ := io.ReadAll(blob.Body)
|
|
blob.Body.Close()
|
|
if string(b) != "asset" || blob.ContentType != "image/png" {
|
|
t.Fatalf("blob = %q %#v", b, blob)
|
|
}
|
|
if err := store.Delete(context.Background(), stored.Key); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := store.Read(context.Background(), stored.Key); !errors.Is(err, ErrBlobNotFound) {
|
|
t.Fatalf("Read deleted error = %v", err)
|
|
}
|
|
}
|
|
|
|
func TestLocalFSRejectsTraversalAbsoluteAndSymlinks(t *testing.T) {
|
|
root := t.TempDir()
|
|
outside := t.TempDir()
|
|
store, err := NewLocalFS(root, "http://local.test")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, key := range []string{"../escape", "uploads/../../escape", filepath.Join(outside, "escape"), "uploads\\..\\escape"} {
|
|
if _, err := store.Put(context.Background(), key, bytes.NewReader(nil), 0, "application/octet-stream"); !errors.Is(err, ErrUnsafeBlobKey) {
|
|
t.Errorf("Put(%q) error = %v", key, err)
|
|
}
|
|
}
|
|
if runtime.GOOS == "windows" {
|
|
return
|
|
}
|
|
if err := os.Symlink(outside, filepath.Join(root, "linked")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := store.Put(context.Background(), "linked/escape", bytes.NewReader([]byte("x")), 1, "text/plain"); !errors.Is(err, ErrUnsafeBlobKey) {
|
|
t.Fatalf("symlink directory error = %v", err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(outside, "target"), []byte("secret"), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.Symlink(filepath.Join(outside, "target"), filepath.Join(root, "final")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := store.Read(context.Background(), "final"); !errors.Is(err, ErrUnsafeBlobKey) {
|
|
t.Fatalf("symlink file error = %v", err)
|
|
}
|
|
}
|