From c2e8790df37a14b4d2f72c7377db75309e0ebf1d Mon Sep 17 00:00:00 2001
From: Lunny Xiao <xiaolunwen@gmail.com>
Date: Wed, 13 Nov 2024 23:19:14 -0800
Subject: [PATCH] Trim title before insert/update to database to match the size
 requirements of database (#32498)

Fix #32489

(cherry picked from commit 98d9a71ffe510da0e10d042d8f87a348022aca87)
---
 models/actions/run.go         | 3 +++
 models/actions/runner.go      | 2 ++
 models/actions/schedule.go    | 2 ++
 models/issues/issue_update.go | 4 ++++
 models/issues/pull.go         | 1 +
 models/project/project.go     | 4 ++++
 models/repo/release.go        | 1 +
 services/release/release.go   | 1 +
 8 files changed, 18 insertions(+)

diff --git a/models/actions/run.go b/models/actions/run.go
index f637634575..06a1290d5d 100644
--- a/models/actions/run.go
+++ b/models/actions/run.go
@@ -254,6 +254,7 @@ func CancelPreviousJobs(ctx context.Context, repoID int64, ref, workflowID strin
 }
 
 // InsertRun inserts a run
+// The title will be cut off at 255 characters if it's longer than 255 characters.
 func InsertRun(ctx context.Context, run *ActionRun, jobs []*jobparser.SingleWorkflow) error {
 	ctx, commiter, err := db.TxContext(ctx)
 	if err != nil {
@@ -266,6 +267,7 @@ func InsertRun(ctx context.Context, run *ActionRun, jobs []*jobparser.SingleWork
 		return err
 	}
 	run.Index = index
+	run.Title, _ = util.SplitStringAtByteN(run.Title, 255)
 
 	if err := db.Insert(ctx, run); err != nil {
 		return err
@@ -391,6 +393,7 @@ func UpdateRun(ctx context.Context, run *ActionRun, cols ...string) error {
 	if len(cols) > 0 {
 		sess.Cols(cols...)
 	}
+	run.Title, _ = util.SplitStringAtByteN(run.Title, 255)
 	affected, err := sess.Update(run)
 	if err != nil {
 		return err
diff --git a/models/actions/runner.go b/models/actions/runner.go
index 175f211c72..a679d7d989 100644
--- a/models/actions/runner.go
+++ b/models/actions/runner.go
@@ -271,6 +271,7 @@ func GetRunnerByID(ctx context.Context, id int64) (*ActionRunner, error) {
 // UpdateRunner updates runner's information.
 func UpdateRunner(ctx context.Context, r *ActionRunner, cols ...string) error {
 	e := db.GetEngine(ctx)
+	r.Name, _ = util.SplitStringAtByteN(r.Name, 255)
 	var err error
 	if len(cols) == 0 {
 		_, err = e.ID(r.ID).AllCols().Update(r)
@@ -312,6 +313,7 @@ func CreateRunner(ctx context.Context, t *ActionRunner) error {
 		// Remove OwnerID to avoid confusion; it's not worth returning an error here.
 		t.OwnerID = 0
 	}
+	t.Name, _ = util.SplitStringAtByteN(t.Name, 255)
 	return db.Insert(ctx, t)
 }
 
diff --git a/models/actions/schedule.go b/models/actions/schedule.go
index acb9961bf6..8b7e6ec44f 100644
--- a/models/actions/schedule.go
+++ b/models/actions/schedule.go
@@ -12,6 +12,7 @@ import (
 	repo_model "code.gitea.io/gitea/models/repo"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/timeutil"
+	"code.gitea.io/gitea/modules/util"
 	webhook_module "code.gitea.io/gitea/modules/webhook"
 )
 
@@ -67,6 +68,7 @@ func CreateScheduleTask(ctx context.Context, rows []*ActionSchedule) error {
 
 	// Loop through each schedule row
 	for _, row := range rows {
+		row.Title, _ = util.SplitStringAtByteN(row.Title, 255)
 		// Create new schedule row
 		if err = db.Insert(ctx, row); err != nil {
 			return err
diff --git a/models/issues/issue_update.go b/models/issues/issue_update.go
index dbfd2fc91b..31c8bdc17b 100644
--- a/models/issues/issue_update.go
+++ b/models/issues/issue_update.go
@@ -21,6 +21,7 @@ import (
 	"code.gitea.io/gitea/modules/references"
 	api "code.gitea.io/gitea/modules/structs"
 	"code.gitea.io/gitea/modules/timeutil"
+	"code.gitea.io/gitea/modules/util"
 
 	"xorm.io/builder"
 )
@@ -154,6 +155,7 @@ func ChangeIssueTitle(ctx context.Context, issue *Issue, doer *user_model.User,
 	}
 	defer committer.Close()
 
+	issue.Title, _ = util.SplitStringAtByteN(issue.Title, 255)
 	if err = UpdateIssueCols(ctx, issue, "name"); err != nil {
 		return fmt.Errorf("updateIssueCols: %w", err)
 	}
@@ -409,6 +411,7 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue
 }
 
 // NewIssue creates new issue with labels for repository.
+// The title will be cut off at 255 characters if it's longer than 255 characters.
 func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
 	ctx, committer, err := db.TxContext(ctx)
 	if err != nil {
@@ -422,6 +425,7 @@ func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *Issue, la
 	}
 
 	issue.Index = idx
+	issue.Title, _ = util.SplitStringAtByteN(issue.Title, 255)
 
 	if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{
 		Repo:        repo,
diff --git a/models/issues/pull.go b/models/issues/pull.go
index e7663ea350..13eafccdc7 100644
--- a/models/issues/pull.go
+++ b/models/issues/pull.go
@@ -566,6 +566,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *Iss
 	}
 
 	issue.Index = idx
+	issue.Title, _ = util.SplitStringAtByteN(issue.Title, 255)
 
 	if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{
 		Repo:        repo,
diff --git a/models/project/project.go b/models/project/project.go
index 8cebf34b5e..245838abb5 100644
--- a/models/project/project.go
+++ b/models/project/project.go
@@ -242,6 +242,7 @@ func GetSearchOrderByBySortType(sortType string) db.SearchOrderBy {
 }
 
 // NewProject creates a new Project
+// The title will be cut off at 255 characters if it's longer than 255 characters.
 func NewProject(ctx context.Context, p *Project) error {
 	if !IsTemplateTypeValid(p.TemplateType) {
 		p.TemplateType = TemplateTypeNone
@@ -255,6 +256,8 @@ func NewProject(ctx context.Context, p *Project) error {
 		return util.NewInvalidArgumentErrorf("project type is not valid")
 	}
 
+	p.Title, _ = util.SplitStringAtByteN(p.Title, 255)
+
 	return db.WithTx(ctx, func(ctx context.Context) error {
 		if err := db.Insert(ctx, p); err != nil {
 			return err
@@ -302,6 +305,7 @@ func UpdateProject(ctx context.Context, p *Project) error {
 		p.CardType = CardTypeTextOnly
 	}
 
+	p.Title, _ = util.SplitStringAtByteN(p.Title, 255)
 	_, err := db.GetEngine(ctx).ID(p.ID).Cols(
 		"title",
 		"description",
diff --git a/models/repo/release.go b/models/repo/release.go
index d96eac0d19..38e38c6572 100644
--- a/models/repo/release.go
+++ b/models/repo/release.go
@@ -171,6 +171,7 @@ func IsReleaseExist(ctx context.Context, repoID int64, tagName string) (bool, er
 
 // UpdateRelease updates all columns of a release
 func UpdateRelease(ctx context.Context, rel *Release) error {
+	rel.Title, _ = util.SplitStringAtByteN(rel.Title, 255)
 	_, err := db.GetEngine(ctx).ID(rel.ID).AllCols().Update(rel)
 	return err
 }
diff --git a/services/release/release.go b/services/release/release.go
index 99851ed1b7..876514beec 100644
--- a/services/release/release.go
+++ b/services/release/release.go
@@ -151,6 +151,7 @@ func CreateRelease(gitRepo *git.Repository, rel *repo_model.Release, msg string,
 		return err
 	}
 
+	rel.Title, _ = util.SplitStringAtByteN(rel.Title, 255)
 	rel.LowerTagName = strings.ToLower(rel.TagName)
 	if err = db.Insert(gitRepo.Ctx, rel); err != nil {
 		return err