api/controller/service_monitor_upload_test.go
Rama main · réplica de lectura del repositorio original.
package controller
import (
"mime/multipart"
"net/textproto"
"testing"
)
// capability_id: rainbond.file-operate.upload-folder-relative-path
func TestResolveUploadRelativePathPreservesFolderFromContentDisposition(t *testing.T) {
header := &multipart.FileHeader{
Filename: "file.txt",
Header: textproto.MIMEHeader{
"Content-Disposition": []string{`form-data; name="files"; filename="demo/sub/file.txt"`},
},
}
relativePath, isDirectoryUpload, err := resolveUploadRelativePath(header)
if err != nil {
t.Fatalf("resolve upload relative path: %v", err)
}
if relativePath != "demo/sub/file.txt" {
t.Fatalf("relative path = %q, want %q", relativePath, "demo/sub/file.txt")
}
if !isDirectoryUpload {
t.Fatal("expected directory upload when filename contains a folder")
}
}
// capability_id: rainbond.file-operate.upload-folder-path-traversal
func TestResolveUploadRelativePathRejectsTraversal(t *testing.T) {
tests := []struct {
name string
filename string
}{
{name: "parent prefix", filename: "../escape.txt"},
{name: "parent segment", filename: "demo/../escape.txt"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
header := &multipart.FileHeader{
Filename: "escape.txt",
Header: textproto.MIMEHeader{
"Content-Disposition": []string{`form-data; name="files"; filename="` + tt.filename + `"`},
},
}
_, _, err := resolveUploadRelativePath(header)
if err == nil {
t.Fatal("expected traversal path to be rejected")
}
})
}
}