Merge 6cfac86ae77db5f4869baec0e0a7a7ef0852c8b6 into d3ffc9985281dcf4d3bef604cce4e662b1a327a6

This commit is contained in:
TT 2026-04-15 20:03:05 +02:00 committed by GitHub
commit bce69ec9fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 22 additions and 9 deletions

View File

@ -715,6 +715,11 @@ func (c *Context) MultipartForm() (*multipart.Form, error) {
return c.Request.MultipartForm, err return c.Request.MultipartForm, err
} }
func dirExists(path string) bool {
info, err := os.Stat(path)
return err == nil && info.IsDir()
}
// SaveUploadedFile uploads the form file to specific dst. // SaveUploadedFile uploads the form file to specific dst.
func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string, perm ...fs.FileMode) error { func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string, perm ...fs.FileMode) error {
src, err := file.Open() src, err := file.Open()
@ -728,12 +733,17 @@ func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string, perm
mode = perm[0] mode = perm[0]
} }
dir := filepath.Dir(dst) dir := filepath.Dir(dst)
dirExisted := dirExists(dir)
if err = os.MkdirAll(dir, mode); err != nil { if err = os.MkdirAll(dir, mode); err != nil {
return err return err
} }
// Only chmod newly created directories. Attempting to chmod
// pre-existing directories (e.g. /tmp) may fail with EPERM.
if !dirExisted {
if err = os.Chmod(dir, mode); err != nil { if err = os.Chmod(dir, mode); err != nil {
return err return err
} }
}
out, err := os.Create(dst) out, err := os.Create(dst)
if err != nil { if err != nil {

View File

@ -20,6 +20,7 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
"runtime"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -247,13 +248,15 @@ func TestSaveUploadedFileWithPermission(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, "permission_test", f.Filename) assert.Equal(t, "permission_test", f.Filename)
var mode fs.FileMode = 0o755 var mode fs.FileMode = 0o755
require.NoError(t, c.SaveUploadedFile(f, "permission_test", mode)) tmpDir := t.TempDir()
t.Cleanup(func() { newSubDir := filepath.Join(tmpDir, "newdir")
assert.NoError(t, os.Remove("permission_test")) dst := filepath.Join(newSubDir, "permission_test")
}) require.NoError(t, c.SaveUploadedFile(f, dst, mode))
info, err := os.Stat(filepath.Dir("permission_test")) if runtime.GOOS != "windows" {
info, err := os.Stat(newSubDir)
require.NoError(t, err) require.NoError(t, err)
assert.Equal(t, info.Mode().Perm(), mode) assert.Equal(t, mode, info.Mode().Perm())
}
} }
func TestSaveUploadedFileWithPermissionFailed(t *testing.T) { func TestSaveUploadedFileWithPermissionFailed(t *testing.T) {