From eb59b1a24a8eb57ca72b9a764c51703988d801de Mon Sep 17 00:00:00 2001 From: TheFox0x7 Date: Sun, 22 Feb 2026 08:01:43 +0100 Subject: [PATCH] various fixes (#36697) fixes bad address concat causing malformed address Introduces new config options to for release attachments and number of files to avoid sharing limits for PR/issue attachments and release ones Fixes: https://github.com/go-gitea/gitea/issues/31638 Fixes: https://github.com/go-gitea/gitea/issues/35812 Doc update: https://gitea.com/gitea/docs/pulls/348 Signed-off-by: wxiaoguang Co-authored-by: wxiaoguang --- cmd/web_acme.go | 5 +++-- custom/conf/app.example.ini | 12 ++++++++++-- modules/setting/attachment.go | 10 +++------- modules/setting/repository.go | 6 ++++++ routers/api/v1/repo/release_attachment.go | 2 +- routers/web/repo/attachment.go | 4 ++-- services/attachment/attachment.go | 4 ++++ services/context/upload/upload.go | 4 ++-- tests/integration/api_releases_test.go | 2 +- 9 files changed, 32 insertions(+), 17 deletions(-) diff --git a/cmd/web_acme.go b/cmd/web_acme.go index 5f7a308334..a2e14638f8 100644 --- a/cmd/web_acme.go +++ b/cmd/web_acme.go @@ -7,6 +7,7 @@ import ( "crypto/x509" "encoding/pem" "fmt" + "net" "net/http" "os" "strconv" @@ -124,8 +125,8 @@ func runACME(listenAddr string, m http.Handler) error { defer finished() log.Info("Running Let's Encrypt handler on %s", setting.HTTPAddr+":"+setting.PortToRedirect) - // all traffic coming into HTTP will be redirect to HTTPS automatically (LE HTTP-01 validation happens here) - err := runHTTP("tcp", setting.HTTPAddr+":"+setting.PortToRedirect, "Let's Encrypt HTTP Challenge", myACME.HTTPChallengeHandler(http.HandlerFunc(runLetsEncryptFallbackHandler)), setting.RedirectorUseProxyProtocol) + // all traffic coming into HTTP will be redirected to HTTPS automatically (LE HTTP-01 validation happens here) + err := runHTTP("tcp", net.JoinHostPort(setting.HTTPAddr, setting.PortToRedirect), "Let's Encrypt HTTP Challenge", myACME.HTTPChallengeHandler(http.HandlerFunc(runLetsEncryptFallbackHandler)), setting.RedirectorUseProxyProtocol) if err != nil { log.Fatal("Failed to start the Let's Encrypt handler on port %s: %v", setting.PortToRedirect, err) } diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index c7f8401cd9..4e45259687 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1180,7 +1180,15 @@ LEVEL = Info ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types. ;ALLOWED_TYPES = +;; +;; Number of releases that are displayed on release page ;DEFAULT_PAGING_NUM = 10 +;; +;; Max size of each file in megabytes. Defaults to 2GB +;FILE_MAX_SIZE = 2048 +;; +;; Max number of files per upload. Defaults to 5 +;MAX_FILES = 5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1995,8 +2003,8 @@ LEVEL = Info ;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types. ;ALLOWED_TYPES = .avif,.cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.webp,.xls,.xlsx,.zip ;; -;; Max size of each file. Defaults to 2048MB -;MAX_SIZE = 2048 +;; Max size of each file. Defaults to 100MB +;MAX_SIZE = 100 ;; ;; Max number of files per upload. Defaults to 5 ;MAX_FILES = 5 diff --git a/modules/setting/attachment.go b/modules/setting/attachment.go index 5d420c987c..30e5cfbff1 100644 --- a/modules/setting/attachment.go +++ b/modules/setting/attachment.go @@ -16,13 +16,9 @@ var Attachment AttachmentSettingType func loadAttachmentFrom(rootCfg ConfigProvider) (err error) { Attachment = AttachmentSettingType{ AllowedTypes: ".avif,.cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.webp,.xls,.xlsx,.zip", - - // FIXME: this size is used for both "issue attachment" and "release attachment" - // The design is not right, these two should be different settings - MaxSize: 2048, - - MaxFiles: 5, - Enabled: true, + MaxSize: 100, + MaxFiles: 5, + Enabled: true, } sec, _ := rootCfg.GetSection("attachment") if sec == nil { diff --git a/modules/setting/repository.go b/modules/setting/repository.go index 90c4f22ad2..662e03598b 100644 --- a/modules/setting/repository.go +++ b/modules/setting/repository.go @@ -100,6 +100,8 @@ var ( Release struct { AllowedTypes string DefaultPagingNum int + FileMaxSize int64 + MaxFiles int64 } `ini:"repository.release"` Signing struct { @@ -241,9 +243,13 @@ var ( Release: struct { AllowedTypes string DefaultPagingNum int + FileMaxSize int64 + MaxFiles int64 }{ AllowedTypes: "", DefaultPagingNum: 10, + FileMaxSize: 2048, + MaxFiles: 5, }, // Signing settings diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go index 5f5423fafe..33f012523b 100644 --- a/routers/api/v1/repo/release_attachment.go +++ b/routers/api/v1/repo/release_attachment.go @@ -234,7 +234,7 @@ func CreateReleaseAttachment(ctx *context.APIContext) { } // Create a new attachment and save the file - attach, err := attachment_service.UploadAttachmentGeneralSizeLimit(ctx, uploaderFile, setting.Repository.Release.AllowedTypes, &repo_model.Attachment{ + attach, err := attachment_service.UploadAttachmentReleaseSizeLimit(ctx, uploaderFile, setting.Repository.Release.AllowedTypes, &repo_model.Attachment{ Name: filename, UploaderID: ctx.Doer.ID, RepoID: ctx.Repo.Repository.ID, diff --git a/routers/web/repo/attachment.go b/routers/web/repo/attachment.go index bc14e42543..a83f0f40ec 100644 --- a/routers/web/repo/attachment.go +++ b/routers/web/repo/attachment.go @@ -46,7 +46,7 @@ func uploadAttachment(ctx *context.Context, repoID int64, allowedTypes string) { defer file.Close() uploaderFile := attachment.NewLimitedUploaderKnownSize(file, header.Size) - attach, err := attachment.UploadAttachmentGeneralSizeLimit(ctx, uploaderFile, allowedTypes, &repo_model.Attachment{ + attach, err := attachment.UploadAttachmentReleaseSizeLimit(ctx, uploaderFile, allowedTypes, &repo_model.Attachment{ Name: header.Filename, UploaderID: ctx.Doer.ID, RepoID: repoID, @@ -56,7 +56,7 @@ func uploadAttachment(ctx *context.Context, repoID int64, allowedTypes string) { ctx.HTTPError(http.StatusBadRequest, err.Error()) return } - ctx.ServerError("UploadAttachmentGeneralSizeLimit", err) + ctx.ServerError("UploadAttachmentReleaseSizeLimit", err) return } diff --git a/services/attachment/attachment.go b/services/attachment/attachment.go index eb208a141c..d69253dd59 100644 --- a/services/attachment/attachment.go +++ b/services/attachment/attachment.go @@ -58,6 +58,10 @@ func UploadAttachmentGeneralSizeLimit(ctx context.Context, file *UploaderFile, a return uploadAttachment(ctx, file, allowedTypes, setting.Attachment.MaxSize<<20, attach) } +func UploadAttachmentReleaseSizeLimit(ctx context.Context, file *UploaderFile, allowedTypes string, attach *repo_model.Attachment) (*repo_model.Attachment, error) { + return uploadAttachment(ctx, file, allowedTypes, setting.Repository.Release.FileMaxSize<<20, attach) +} + func uploadAttachment(ctx context.Context, file *UploaderFile, allowedTypes string, maxFileSize int64, attach *repo_model.Attachment) (*repo_model.Attachment, error) { src := file.rd if file.size < 0 { diff --git a/services/context/upload/upload.go b/services/context/upload/upload.go index 23707950d4..3352bfa388 100644 --- a/services/context/upload/upload.go +++ b/services/context/upload/upload.go @@ -95,8 +95,8 @@ func AddUploadContext(ctx *context.Context, uploadType string) { ctx.Data["UploadRemoveUrl"] = ctx.Repo.RepoLink + "/releases/attachments/remove" ctx.Data["UploadLinkUrl"] = ctx.Repo.RepoLink + "/releases/attachments" ctx.Data["UploadAccepts"] = strings.ReplaceAll(setting.Repository.Release.AllowedTypes, "|", ",") - ctx.Data["UploadMaxFiles"] = setting.Attachment.MaxFiles - ctx.Data["UploadMaxSize"] = setting.Attachment.MaxSize + ctx.Data["UploadMaxFiles"] = setting.Repository.Release.MaxFiles + ctx.Data["UploadMaxSize"] = setting.Repository.Release.FileMaxSize case "comment": ctx.Data["UploadUrl"] = ctx.Repo.RepoLink + "/issues/attachments" ctx.Data["UploadRemoveUrl"] = ctx.Repo.RepoLink + "/issues/attachments/remove" diff --git a/tests/integration/api_releases_test.go b/tests/integration/api_releases_test.go index b3b30a33d5..440209c644 100644 --- a/tests/integration/api_releases_test.go +++ b/tests/integration/api_releases_test.go @@ -335,7 +335,7 @@ func TestAPIDeleteReleaseByTagName(t *testing.T) { func TestAPIUploadAssetRelease(t *testing.T) { defer tests.PrepareTestEnv(t)() - defer test.MockVariableValue(&setting.Attachment.MaxSize, 1)() + defer test.MockVariableValue(&setting.Repository.Release.FileMaxSize, 1)() repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})