diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2022-03-14 23:18:27 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-14 16:18:27 +0100 |
commit | 49db87a035a28cd8eaa4abdd5832f952ca6449d9 (patch) | |
tree | 231676f5ca713844297cc16a52700fc50c8712fb /modules/storage | |
parent | 3ad6cf20695ea4e56e00427c6af76efc25e9b670 (diff) | |
download | gitea-49db87a035a28cd8eaa4abdd5832f952ca6449d9.tar.gz gitea-49db87a035a28cd8eaa4abdd5832f952ca6449d9.zip |
Fix lfs bug (#19072)
* Fix lfs bug
Diffstat (limited to 'modules/storage')
-rw-r--r-- | modules/storage/local.go | 23 | ||||
-rw-r--r-- | modules/storage/local_test.go | 45 |
2 files changed, 68 insertions, 0 deletions
diff --git a/modules/storage/local.go b/modules/storage/local.go index 022e6186d4..8d9aa603d0 100644 --- a/modules/storage/local.go +++ b/modules/storage/local.go @@ -6,15 +6,20 @@ package storage import ( "context" + "errors" "io" "net/url" "os" + "path" "path/filepath" + "strings" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" ) +// ErrLocalPathNotSupported represents an error that path is not supported +var ErrLocalPathNotSupported = errors.New("local path is not supported") var _ ObjectStorage = &LocalStorage{} // LocalStorageType is the type descriptor for local storage @@ -59,11 +64,18 @@ func NewLocalStorage(ctx context.Context, cfg interface{}) (ObjectStorage, error // Open a file func (l *LocalStorage) Open(path string) (Object, error) { + if !isLocalPathValid(path) { + return nil, ErrLocalPathNotSupported + } return os.Open(filepath.Join(l.dir, path)) } // Save a file func (l *LocalStorage) Save(path string, r io.Reader, size int64) (int64, error) { + if !isLocalPathValid(path) { + return 0, ErrLocalPathNotSupported + } + p := filepath.Join(l.dir, path) if err := os.MkdirAll(filepath.Dir(p), os.ModePerm); err != nil { return 0, err @@ -107,8 +119,19 @@ func (l *LocalStorage) Stat(path string) (os.FileInfo, error) { return os.Stat(filepath.Join(l.dir, path)) } +func isLocalPathValid(p string) bool { + a := path.Clean(p) + if strings.HasPrefix(a, "../") || strings.HasPrefix(a, "..\\") { + return false + } + return a == p +} + // Delete delete a file func (l *LocalStorage) Delete(path string) error { + if !isLocalPathValid(path) { + return ErrLocalPathNotSupported + } p := filepath.Join(l.dir, path) return util.Remove(p) } diff --git a/modules/storage/local_test.go b/modules/storage/local_test.go new file mode 100644 index 0000000000..8714f37f0d --- /dev/null +++ b/modules/storage/local_test.go @@ -0,0 +1,45 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package storage + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestLocalPathIsValid(t *testing.T) { + kases := []struct { + path string + valid bool + }{ + { + "a/0/a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a14", + true, + }, + { + "../a/0/a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a14", + false, + }, + { + "a\\0\\a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a14", + true, + }, + { + "b/../a/0/a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a14", + false, + }, + { + "..\\a/0/a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a14", + false, + }, + } + + for _, k := range kases { + t.Run(k.path, func(t *testing.T) { + assert.EqualValues(t, k.valid, isLocalPathValid(k.path)) + }) + } +} |