fix(storage): reject empty key + nil ReadCloser on Get error

This commit is contained in:
2026-05-04 00:34:42 +08:00
parent 33838f1820
commit 547b339ed3
2 changed files with 30 additions and 2 deletions
+11 -2
View File
@@ -28,8 +28,13 @@ func NewLocalFS(base string) (*LocalFS, error) {
return &LocalFS{base: filepath.Clean(base)}, nil return &LocalFS{base: filepath.Clean(base)}, nil
} }
// resolveSafe 把 key 限制在 base 之下,拒绝 ".." / 绝对路径。 // resolveSafe 把 key 限制在 base 之下,拒绝 ".." / 绝对路径 / 空 key
func (l *LocalFS) resolveSafe(key string) (string, error) { func (l *LocalFS) resolveSafe(key string) (string, error) {
// Reject empty / dot keys (would resolve to base itself and corrupt the layout)
if key == "" || key == "." {
return "", errors.New("storage: key must not be empty")
}
// Reject absolute paths // Reject absolute paths
if filepath.IsAbs(key) { if filepath.IsAbs(key) {
return "", errors.New("storage: key must be relative") return "", errors.New("storage: key must be relative")
@@ -96,7 +101,11 @@ func (l *LocalFS) Get(ctx context.Context, storagePath string) (io.ReadCloser, e
if err != nil { if err != nil {
return nil, err return nil, err
} }
return os.Open(full) f, err := os.Open(full)
if err != nil {
return nil, err // 显式 nil interface,避免 typed-nil 包装
}
return f, nil
} }
func (l *LocalFS) Delete(ctx context.Context, storagePath string) error { func (l *LocalFS) Delete(ctx context.Context, storagePath string) error {
+19
View File
@@ -52,3 +52,22 @@ func TestLocalFS_DeleteNonexistentIsNoop(t *testing.T) {
fs, _ := NewLocalFS(t.TempDir()) fs, _ := NewLocalFS(t.TempDir())
require.NoError(t, fs.Delete(context.Background(), "nope/nope.txt")) require.NoError(t, fs.Delete(context.Background(), "nope/nope.txt"))
} }
func TestLocalFS_RejectEmptyKey(t *testing.T) {
fs, _ := NewLocalFS(t.TempDir())
_, err := fs.Put(context.Background(), "", bytes.NewReader(nil), "text/plain")
require.Error(t, err)
_, err = fs.Put(context.Background(), ".", bytes.NewReader(nil), "text/plain")
require.Error(t, err)
_, err = fs.Get(context.Background(), "")
require.Error(t, err)
require.Error(t, fs.Delete(context.Background(), ""))
}
func TestLocalFS_GetMissingFileReturnsNilCloser(t *testing.T) {
// 验证错误路径下不会返回 typed-nil io.ReadCloser
fs, _ := NewLocalFS(t.TempDir())
r, err := fs.Get(context.Background(), "missing/file.txt")
require.Error(t, err)
require.Nil(t, r)
}