Procházet zdrojové kódy

replace hand-written slice utilities with methods from slices package

SFTPGo depends on Go 1.22 so we can use slices package

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
Nicola Murino před 1 rokem
rodič
revize
bd5eb03d9c

+ 7 - 8
internal/common/connection.go

@@ -21,6 +21,7 @@ import (
 	"io/fs"
 	"os"
 	"path"
+	"slices"
 	"strings"
 	"sync"
 	"sync/atomic"
@@ -1795,12 +1796,12 @@ type DirListerAt struct {
 	lister      vfs.DirLister
 }
 
-// Add adds the given os.FileInfo to the internal cache
-func (l *DirListerAt) Add(fi os.FileInfo) {
+// Prepend adds the given os.FileInfo as first element of the internal cache
+func (l *DirListerAt) Prepend(fi os.FileInfo) {
 	l.mu.Lock()
 	defer l.mu.Unlock()
 
-	l.info = append(l.info, fi)
+	l.info = slices.Insert(l.info, 0, fi)
 }
 
 // ListAt implements sftp.ListerAt
@@ -1813,10 +1814,10 @@ func (l *DirListerAt) ListAt(f []os.FileInfo, _ int64) (int, error) {
 	}
 	if len(f) <= len(l.info) {
 		files := make([]os.FileInfo, 0, len(f))
-		for idx := len(l.info) - 1; idx >= 0; idx-- {
+		for idx := range l.info {
 			files = append(files, l.info[idx])
 			if len(files) == len(f) {
-				l.info = l.info[:idx]
+				l.info = l.info[idx+1:]
 				n := copy(f, files)
 				return n, nil
 			}
@@ -1838,9 +1839,7 @@ func (l *DirListerAt) Next(limit int) ([]os.FileInfo, error) {
 		}
 		files = l.user.FilterListDir(files, l.virtualPath)
 		if len(l.info) > 0 {
-			for _, fi := range l.info {
-				files = util.PrependFileInfo(files, fi)
-			}
+			files = slices.Concat(l.info, files)
 			l.info = nil
 		}
 		if err != nil || len(files) > 0 {

+ 2 - 2
internal/common/connection_test.go

@@ -1134,8 +1134,8 @@ func TestListerAt(t *testing.T) {
 	require.Equal(t, 0, n)
 	lister, err = conn.ListDir("/")
 	require.NoError(t, err)
-	lister.Add(vfs.NewFileInfo("..", true, 0, time.Unix(0, 0), false))
-	lister.Add(vfs.NewFileInfo(".", true, 0, time.Unix(0, 0), false))
+	lister.Prepend(vfs.NewFileInfo("..", true, 0, time.Unix(0, 0), false))
+	lister.Prepend(vfs.NewFileInfo(".", true, 0, time.Unix(0, 0), false))
 	files = make([]os.FileInfo, 1)
 	n, err = lister.ListAt(files, 0)
 	require.NoError(t, err)

+ 2 - 2
internal/sftpd/handler.go

@@ -221,9 +221,9 @@ func (c *Connection) Filelist(request *sftp.Request) (sftp.ListerAt, error) {
 		}
 		modTime := time.Unix(0, 0)
 		if request.Filepath != "/" {
-			lister.Add(vfs.NewFileInfo("..", true, 0, modTime, false))
+			lister.Prepend(vfs.NewFileInfo("..", true, 0, modTime, false))
 		}
-		lister.Add(vfs.NewFileInfo(".", true, 0, modTime, false))
+		lister.Prepend(vfs.NewFileInfo(".", true, 0, modTime, false))
 		return lister, nil
 	case "Stat":
 		if !c.User.HasPerm(dataprovider.PermListItems, path.Dir(request.Filepath)) {

+ 0 - 9
internal/util/util.go

@@ -809,15 +809,6 @@ func GetRedactedURL(rawurl string) string {
 	return u.Redacted()
 }
 
-// PrependFileInfo prepends a file info to a slice in an efficient way.
-// We, optimistically, assume that the slice has enough capacity
-func PrependFileInfo(files []os.FileInfo, info os.FileInfo) []os.FileInfo {
-	files = append(files, nil)
-	copy(files[1:], files)
-	files[0] = info
-	return files
-}
-
 // GetTLSVersion returns the TLS version for integer:
 // - 12 means TLS 1.2
 // - 13 means TLS 1.3