diff options
author | 6543 <6543@obermui.de> | 2022-03-14 15:59:54 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-14 15:59:54 +0100 |
commit | 99861e3e067ae5bd80ce6b647cf9ace08556725b (patch) | |
tree | 8aac48d976a71a2e288cb592c5aa527db50cc1c3 /modules | |
parent | 66b8a43e5f9bd82f0daa3e7cbcab859457c8064f (diff) | |
download | gitea-99861e3e067ae5bd80ce6b647cf9ace08556725b.tar.gz gitea-99861e3e067ae5bd80ce6b647cf9ace08556725b.zip |
Fix lfs bug (#19072) (#19080)
Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
Diffstat (limited to 'modules')
-rw-r--r-- | modules/storage/local.go | 27 | ||||
-rw-r--r-- | modules/storage/local_test.go | 45 |
2 files changed, 69 insertions, 3 deletions
diff --git a/modules/storage/local.go b/modules/storage/local.go index 54e0d0563d..8d9aa603d0 100644 --- a/modules/storage/local.go +++ b/modules/storage/local.go @@ -6,18 +6,21 @@ 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" ) -var ( - _ ObjectStorage = &LocalStorage{} -) +// 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 const LocalStorageType Type = "local" @@ -61,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 @@ -109,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)) + }) + } +} |