Skip to content

Commit 7b78fed

Browse files
jyxjjjKirCute
andauthored
Merge commit from fork
Co-authored-by: KirCute <951206789@qq.com>
1 parent d685bbf commit 7b78fed

File tree

2 files changed

+67
-48
lines changed

2 files changed

+67
-48
lines changed

server/handles/archive.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ func FsArchiveList(c *gin.Context, req *ArchiveListReq, user *model.User) {
231231
type ArchiveDecompressReq struct {
232232
SrcDir string `json:"src_dir" form:"src_dir"`
233233
DstDir string `json:"dst_dir" form:"dst_dir"`
234-
Name []string `json:"name" form:"name"`
234+
Names []string `json:"name" form:"name"`
235235
ArchivePass string `json:"archive_pass" form:"archive_pass"`
236236
InnerPath string `json:"inner_path" form:"inner_path"`
237237
CacheFull bool `json:"cache_full" form:"cache_full"`
@@ -250,8 +250,8 @@ func FsArchiveDecompress(c *gin.Context) {
250250
common.ErrorResp(c, errs.PermissionDenied, 403)
251251
return
252252
}
253-
srcPaths := make([]string, 0, len(req.Name))
254-
for _, name := range req.Name {
253+
srcPaths := make([]string, 0, len(req.Names))
254+
for _, name := range req.Names {
255255
srcPath, err := user.JoinPath(stdpath.Join(req.SrcDir, name))
256256
if err != nil {
257257
common.ErrorResp(c, err, 403)

server/handles/fsmanage.go

Lines changed: 64 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@ import (
66
"strings"
77

88
"github.com/OpenListTeam/OpenList/v4/internal/conf"
9-
"github.com/OpenListTeam/OpenList/v4/internal/task"
10-
119
"github.com/OpenListTeam/OpenList/v4/internal/errs"
1210
"github.com/OpenListTeam/OpenList/v4/internal/fs"
1311
"github.com/OpenListTeam/OpenList/v4/internal/model"
1412
"github.com/OpenListTeam/OpenList/v4/internal/op"
1513
"github.com/OpenListTeam/OpenList/v4/internal/sign"
14+
"github.com/OpenListTeam/OpenList/v4/internal/task"
1615
"github.com/OpenListTeam/OpenList/v4/pkg/generic"
1716
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
1817
"github.com/OpenListTeam/OpenList/v4/server/common"
1918
"github.com/gin-gonic/gin"
2019
"github.com/pkg/errors"
20+
log "github.com/sirupsen/logrus"
2121
)
2222

2323
type MkdirOrLinkReq struct {
@@ -80,36 +80,44 @@ func FsMove(c *gin.Context) {
8080
common.ErrorResp(c, errs.PermissionDenied, 403)
8181
return
8282
}
83-
srcDir, err := user.JoinPath(req.SrcDir)
84-
if err != nil {
85-
common.ErrorResp(c, err, 403)
86-
return
87-
}
8883
dstDir, err := user.JoinPath(req.DstDir)
8984
if err != nil {
9085
common.ErrorResp(c, err, 403)
9186
return
9287
}
9388

94-
var validNames []string
95-
if !req.Overwrite {
96-
for _, name := range req.Names {
97-
if res, _ := fs.Get(c.Request.Context(), stdpath.Join(dstDir, name), &fs.GetArgs{NoLog: true}); res != nil && !req.SkipExisting {
98-
common.ErrorStrResp(c, fmt.Sprintf("file [%s] exists", name), 403)
89+
validPaths := make([]string, 0, len(req.Names))
90+
for _, name := range req.Names {
91+
// ensure req.Names is not a relative path
92+
srcPath := stdpath.Join(req.SrcDir, name)
93+
srcPath, err = user.JoinPath(srcPath)
94+
if err != nil {
95+
common.ErrorResp(c, err, 403)
96+
return
97+
}
98+
if !req.Overwrite {
99+
base := stdpath.Base(srcPath)
100+
if base == "." || base == "/" {
101+
common.ErrorStrResp(c, fmt.Sprintf("invalid file name [%s]", name), 400)
99102
return
100-
} else if res == nil {
101-
validNames = append(validNames, name)
103+
}
104+
if res, _ := fs.Get(c.Request.Context(), stdpath.Join(dstDir, base), &fs.GetArgs{NoLog: true}); res != nil {
105+
if !req.SkipExisting {
106+
common.ErrorStrResp(c, fmt.Sprintf("file [%s] exists", name), 403)
107+
return
108+
} else {
109+
continue
110+
}
102111
}
103112
}
104-
} else {
105-
validNames = req.Names
113+
validPaths = append(validPaths, srcPath)
106114
}
107115

108116
// Create all tasks immediately without any synchronous validation
109117
// All validation will be done asynchronously in the background
110118
var addedTasks []task.TaskExtensionInfo
111-
for i, name := range validNames {
112-
t, err := fs.Move(c.Request.Context(), stdpath.Join(srcDir, name), dstDir, len(validNames) > i+1)
119+
for i, p := range validPaths {
120+
t, err := fs.Move(c.Request.Context(), p, dstDir, len(validPaths) > i+1)
113121
if t != nil {
114122
addedTasks = append(addedTasks, t)
115123
}
@@ -147,44 +155,48 @@ func FsCopy(c *gin.Context) {
147155
common.ErrorResp(c, errs.PermissionDenied, 403)
148156
return
149157
}
150-
srcDir, err := user.JoinPath(req.SrcDir)
151-
if err != nil {
152-
common.ErrorResp(c, err, 403)
153-
return
154-
}
155158
dstDir, err := user.JoinPath(req.DstDir)
156159
if err != nil {
157160
common.ErrorResp(c, err, 403)
158161
return
159162
}
160163

161-
var validNames []string
162-
if !req.Overwrite {
163-
for _, name := range req.Names {
164-
if res, _ := fs.Get(c.Request.Context(), stdpath.Join(dstDir, name), &fs.GetArgs{NoLog: true}); res != nil {
164+
validPaths := make([]string, 0, len(req.Names))
165+
for _, name := range req.Names {
166+
// ensure req.Names is not a relative path
167+
srcPath := stdpath.Join(req.SrcDir, name)
168+
srcPath, err = user.JoinPath(srcPath)
169+
if err != nil {
170+
common.ErrorResp(c, err, 403)
171+
return
172+
}
173+
if !req.Overwrite {
174+
base := stdpath.Base(srcPath)
175+
if base == "." || base == "/" {
176+
common.ErrorStrResp(c, fmt.Sprintf("invalid file name [%s]", name), 400)
177+
return
178+
}
179+
if res, _ := fs.Get(c.Request.Context(), stdpath.Join(dstDir, base), &fs.GetArgs{NoLog: true}); res != nil {
165180
if !req.SkipExisting && !req.Merge {
166181
common.ErrorStrResp(c, fmt.Sprintf("file [%s] exists", name), 403)
167182
return
168-
} else if req.Merge && res.IsDir() {
169-
validNames = append(validNames, name)
183+
} else if !req.Merge || !res.IsDir() {
184+
continue
170185
}
171-
} else {
172-
validNames = append(validNames, name)
173186
}
174187
}
175-
} else {
176-
validNames = req.Names
188+
validPaths = append(validPaths, srcPath)
177189
}
178190

179191
// Create all tasks immediately without any synchronous validation
180192
// All validation will be done asynchronously in the background
181193
var addedTasks []task.TaskExtensionInfo
182-
for i, name := range validNames {
194+
for i, p := range validPaths {
183195
var t task.TaskExtensionInfo
184196
if req.Merge {
185-
t, err = fs.Merge(c.Request.Context(), stdpath.Join(srcDir, name), dstDir, len(validNames) > i+1)
197+
t, err = fs.Merge(c.Request.Context(), p, dstDir, len(validPaths) > i+1)
186198
} else {
187-
t, err = fs.Copy(c.Request.Context(), stdpath.Join(srcDir, name), dstDir, len(validNames) > i+1)
199+
t, err = fs.Copy(c.Request.Context(), p, dstDir, len(validPaths) > i+1)
188200
}
189201
if t != nil {
190202
addedTasks = append(addedTasks, t)
@@ -276,18 +288,25 @@ func FsRemove(c *gin.Context) {
276288
common.ErrorResp(c, errs.PermissionDenied, 403)
277289
return
278290
}
279-
reqDir, err := user.JoinPath(req.Dir)
280-
if err != nil {
281-
common.ErrorResp(c, err, 403)
282-
return
283-
}
284-
for _, name := range req.Names {
285-
// Skip invalid item names (empty string, whitespace, ".", "/","\t\t","..") to prevent accidental removal of current directory
291+
for i, name := range req.Names {
286292
if strings.TrimSpace(utils.FixAndCleanPath(name)) == "/" {
287-
utils.Log.Warnf("FsRemove: invalid item skipped: %s (parent directory: %s)\n", name, reqDir)
293+
log.Warnf("FsRemove: invalid item skipped: %s (parent directory: %s)\n", name, req.Dir)
294+
req.Names[i] = ""
295+
continue
296+
}
297+
// ensure req.Names is not a relative path
298+
var err error
299+
req.Names[i], err = user.JoinPath(stdpath.Join(req.Dir, name))
300+
if err != nil {
301+
common.ErrorResp(c, err, 403)
302+
return
303+
}
304+
}
305+
for _, path := range req.Names {
306+
if path == "" {
288307
continue
289308
}
290-
err := fs.Remove(c.Request.Context(), stdpath.Join(reqDir, name))
309+
err := fs.Remove(c.Request.Context(), path)
291310
if err != nil {
292311
common.ErrorResp(c, err, 500)
293312
return

0 commit comments

Comments
 (0)