Confine local file installation paths

This commit is contained in:
2026-08-10 17:59:29 +00:00
parent 59f3fe3d1d
commit 18ddf00d3d
20 changed files with 694 additions and 153 deletions

View File

@@ -3,6 +3,7 @@ package storage
import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"sort"
@@ -87,34 +88,43 @@ func (f *FakeBackend) List(ctx context.Context, prefix string) ([]ObjectInfo, er
return out, nil
}
// Download writes one object to a local path.
func (f *FakeBackend) Download(ctx context.Context, key, localPath string) error {
// DownloadTo writes one object to a caller-owned destination writer.
func (f *FakeBackend) DownloadTo(ctx context.Context, key string, destination io.Writer) error {
if err := ctx.Err(); err != nil {
return err
}
if f.DownloadErr != nil {
return f.DownloadErr
}
if strings.TrimSpace(localPath) == "" {
return fmt.Errorf("download object: local path is required")
if destination == nil {
return fmt.Errorf("download object: destination writer is required")
}
obj, ok := f.Objects[normalizeObjectKey(key)]
if !ok {
return fmt.Errorf("download object %q: %w", key, os.ErrNotExist)
}
f.Downloads = append(f.Downloads, FakeDownloadCall{
Key: normalizeObjectKey(key),
LocalPath: localPath,
})
f.Downloads = append(f.Downloads, FakeDownloadCall{Key: normalizeObjectKey(key)})
if _, err := destination.Write(obj.Data); err != nil {
return fmt.Errorf("download object %q: write destination: %w", key, err)
}
return nil
}
// Download writes one object to a local path.
func (f *FakeBackend) Download(ctx context.Context, key, localPath string) error {
if strings.TrimSpace(localPath) == "" {
return fmt.Errorf("download object: local path is required")
}
if err := os.MkdirAll(filepath.Dir(localPath), 0o755); err != nil {
return fmt.Errorf("download object %q: create parent directory: %w", key, err)
}
if err := os.WriteFile(localPath, obj.Data, 0o644); err != nil {
return fmt.Errorf("download object %q: write local file: %w", key, err)
destination, err := os.Create(localPath)
if err != nil {
return fmt.Errorf("download object %q: create local file: %w", key, err)
}
return nil
defer destination.Close()
return f.DownloadTo(ctx, key, destination)
}
// Upload reads a local file and stores it under key.