refactor(webdav): Use ResolvePath instead of JoinPath (#9344)

- Changed the path concatenation method between `reqPath` and `src` and `dst` to use `ResolvePath`
- Updated the implementation of path handling in multiple functions
- Improved the consistency and reliability of path resolution
main beta
千石 2025-10-16 02:23:11 -07:00 committed by GitHub
parent a6bd90a9b2
commit e2016dd031
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 33 additions and 11 deletions

View File

@ -113,7 +113,7 @@ func WebDAVAuth(c *gin.Context) {
reqPath = "/"
}
reqPath, _ = url.PathUnescape(reqPath)
reqPath, err = user.JoinPath(reqPath)
reqPath, err = webdav.ResolvePath(user, reqPath)
if err != nil {
c.Status(http.StatusForbidden)
c.Abort()

22
server/webdav/path.go Normal file
View File

@ -0,0 +1,22 @@
package webdav
import (
"path"
"strings"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/pkg/utils"
)
// ResolvePath normalizes the provided raw path and resolves it against the user's base path
// before delegating to the user-aware JoinPath permission checks.
func ResolvePath(user *model.User, raw string) (string, error) {
cleaned := utils.FixAndCleanPath(raw)
basePath := utils.FixAndCleanPath(user.BasePath)
if cleaned != "/" && basePath != "/" && !utils.IsSubPath(basePath, cleaned) {
cleaned = path.Join(basePath, strings.TrimPrefix(cleaned, "/"))
}
return user.JoinPath(cleaned)
}

View File

@ -194,7 +194,7 @@ func (h *Handler) handleOptions(w http.ResponseWriter, r *http.Request) (status
}
ctx := r.Context()
user := ctx.Value("user").(*model.User)
reqPath, err = user.JoinPath(reqPath)
reqPath, err = ResolvePath(user, reqPath)
if err != nil {
return 403, err
}
@ -222,7 +222,7 @@ func (h *Handler) handleGetHeadPost(w http.ResponseWriter, r *http.Request) (sta
// TODO: check locks for read-only access??
ctx := r.Context()
user := ctx.Value("user").(*model.User)
reqPath, err = user.JoinPath(reqPath)
reqPath, err = ResolvePath(user, reqPath)
if err != nil {
return http.StatusForbidden, err
}
@ -282,7 +282,7 @@ func (h *Handler) handleDelete(w http.ResponseWriter, r *http.Request) (status i
ctx := r.Context()
user := ctx.Value("user").(*model.User)
reqPath, err = user.JoinPath(reqPath)
reqPath, err = ResolvePath(user, reqPath)
if err != nil {
return 403, err
}
@ -321,7 +321,7 @@ func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request) (status int,
// comments in http.checkEtag.
ctx := r.Context()
user := ctx.Value("user").(*model.User)
reqPath, err = user.JoinPath(reqPath)
reqPath, err = ResolvePath(user, reqPath)
if err != nil {
return http.StatusForbidden, err
}
@ -375,7 +375,7 @@ func (h *Handler) handleMkcol(w http.ResponseWriter, r *http.Request) (status in
ctx := r.Context()
user := ctx.Value("user").(*model.User)
reqPath, err = user.JoinPath(reqPath)
reqPath, err = ResolvePath(user, reqPath)
if err != nil {
return 403, err
}
@ -439,11 +439,11 @@ func (h *Handler) handleCopyMove(w http.ResponseWriter, r *http.Request) (status
ctx := r.Context()
user := ctx.Value("user").(*model.User)
src, err = user.JoinPath(src)
src, err = ResolvePath(user, src)
if err != nil {
return 403, err
}
dst, err = user.JoinPath(dst)
dst, err = ResolvePath(user, dst)
if err != nil {
return 403, err
}
@ -540,7 +540,7 @@ func (h *Handler) handleLock(w http.ResponseWriter, r *http.Request) (retStatus
if err != nil {
return status, err
}
reqPath, err = user.JoinPath(reqPath)
reqPath, err = ResolvePath(user, reqPath)
if err != nil {
return 403, err
}
@ -623,7 +623,7 @@ func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) (status
userAgent := r.Header.Get("User-Agent")
ctx = context.WithValue(ctx, "userAgent", userAgent)
user := ctx.Value("user").(*model.User)
reqPath, err = user.JoinPath(reqPath)
reqPath, err = ResolvePath(user, reqPath)
if err != nil {
return 403, err
}
@ -801,7 +801,7 @@ func (h *Handler) handleProppatch(w http.ResponseWriter, r *http.Request) (statu
ctx := r.Context()
user := ctx.Value("user").(*model.User)
reqPath, err = user.JoinPath(reqPath)
reqPath, err = ResolvePath(user, reqPath)
if err != nil {
return 403, err
}