aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--weed/admin/handlers/file_browser_handlers.go22
-rw-r--r--weed/storage/needle/needle_parse_upload.go6
-rw-r--r--weed/util/fullpath.go13
3 files changed, 33 insertions, 8 deletions
diff --git a/weed/admin/handlers/file_browser_handlers.go b/weed/admin/handlers/file_browser_handlers.go
index bafaa60c3..eeb8e2d85 100644
--- a/weed/admin/handlers/file_browser_handlers.go
+++ b/weed/admin/handlers/file_browser_handlers.go
@@ -10,6 +10,7 @@ import (
"net"
"net/http"
"os"
+ "path"
"path/filepath"
"strconv"
"strings"
@@ -21,6 +22,7 @@ import (
"github.com/seaweedfs/seaweedfs/weed/admin/view/layout"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
+ "github.com/seaweedfs/seaweedfs/weed/util"
"github.com/seaweedfs/seaweedfs/weed/util/http/client"
)
@@ -267,8 +269,12 @@ func (h *FileBrowserHandlers) UploadFile(c *gin.Context) {
continue
}
- // Create full path for the file
- fullPath := filepath.Join(currentPath, fileName)
+ // Normalize Windows-style backslashes to forward slashes
+ fileName = util.CleanWindowsPath(fileName)
+
+ // Create full path for the file using path.Join for URL path semantics
+ // path.Join handles double slashes and is not OS-specific like filepath.Join
+ fullPath := path.Join(currentPath, fileName)
if !strings.HasPrefix(fullPath, "/") {
fullPath = "/" + fullPath
}
@@ -349,8 +355,10 @@ func (h *FileBrowserHandlers) uploadFileToFiler(filePath string, fileHeader *mul
var body bytes.Buffer
writer := multipart.NewWriter(&body)
- // Create form file field
- part, err := writer.CreateFormFile("file", fileHeader.Filename)
+ // Create form file field with normalized base filename
+ // Use path.Base (not filepath.Base) since cleanFilePath uses URL path semantics
+ baseFileName := path.Base(cleanFilePath)
+ part, err := writer.CreateFormFile("file", baseFileName)
if err != nil {
return fmt.Errorf("failed to create form file: %w", err)
}
@@ -452,8 +460,12 @@ func (h *FileBrowserHandlers) validateAndCleanFilePath(filePath string) (string,
return "", fmt.Errorf("file path cannot be empty")
}
+ // Normalize Windows-style backslashes to forward slashes
+ filePath = util.CleanWindowsPath(filePath)
+
// Clean the path to remove any .. or . components
- cleanPath := filepath.Clean(filePath)
+ // Use path.Clean (not filepath.Clean) since this is a URL path
+ cleanPath := path.Clean(filePath)
// Ensure the path starts with /
if !strings.HasPrefix(cleanPath, "/") {
diff --git a/weed/storage/needle/needle_parse_upload.go b/weed/storage/needle/needle_parse_upload.go
index 89708303d..6fadd80d6 100644
--- a/weed/storage/needle/needle_parse_upload.go
+++ b/weed/storage/needle/needle_parse_upload.go
@@ -128,7 +128,7 @@ func parseUpload(r *http.Request, sizeLimit int64, pu *ParsedUpload) (e error) {
pu.FileName = part.FileName()
if pu.FileName != "" {
- pu.FileName = path.Base(pu.FileName)
+ pu.FileName = util.CleanWindowsPathBase(pu.FileName)
}
dataSize, e = pu.bytesBuffer.ReadFrom(io.LimitReader(part, sizeLimit+1))
@@ -169,7 +169,7 @@ func parseUpload(r *http.Request, sizeLimit int64, pu *ParsedUpload) (e error) {
// update
pu.Data = pu.bytesBuffer.Bytes()
- pu.FileName = path.Base(fName)
+ pu.FileName = util.CleanWindowsPathBase(fName)
contentType = part.Header.Get("Content-Type")
part = part2
break
@@ -207,7 +207,7 @@ func parseUpload(r *http.Request, sizeLimit int64, pu *ParsedUpload) (e error) {
}
if pu.FileName != "" {
- pu.FileName = path.Base(pu.FileName)
+ pu.FileName = util.CleanWindowsPathBase(pu.FileName)
} else {
pu.FileName = path.Base(r.URL.Path)
}
diff --git a/weed/util/fullpath.go b/weed/util/fullpath.go
index c145919da..b485cae0d 100644
--- a/weed/util/fullpath.go
+++ b/weed/util/fullpath.go
@@ -1,6 +1,7 @@
package util
import (
+ "path"
"path/filepath"
"strings"
)
@@ -85,3 +86,15 @@ func StringSplit(separatedValues string, sep string) []string {
}
return strings.Split(separatedValues, sep)
}
+
+// CleanWindowsPath normalizes Windows-style backslashes to forward slashes.
+// This handles paths from Windows clients where paths use backslashes.
+func CleanWindowsPath(p string) string {
+ return strings.ReplaceAll(p, "\\", "/")
+}
+
+// CleanWindowsPathBase normalizes Windows-style backslashes to forward slashes
+// and returns the base name of the path.
+func CleanWindowsPathBase(p string) string {
+ return path.Base(strings.ReplaceAll(p, "\\", "/"))
+}