diff options
-rw-r--r-- | modules/markup/html_link.go | 5 | ||||
-rw-r--r-- | modules/markup/html_test.go | 10 | ||||
-rw-r--r-- | modules/util/string.go | 17 | ||||
-rw-r--r-- | modules/util/string_test.go | 5 | ||||
-rw-r--r-- | modules/util/truncate.go | 20 | ||||
-rw-r--r-- | services/issue/milestone.go | 4 | ||||
-rw-r--r-- | services/issue/milestone_test.go | 8 |
7 files changed, 52 insertions, 17 deletions
diff --git a/modules/markup/html_link.go b/modules/markup/html_link.go index 5fd38b63cd..fea82e50ab 100644 --- a/modules/markup/html_link.go +++ b/modules/markup/html_link.go @@ -9,6 +9,7 @@ import ( "strings" "code.gitea.io/gitea/modules/markup/common" + "code.gitea.io/gitea/modules/util" "golang.org/x/net/html" "golang.org/x/net/html/atom" @@ -171,6 +172,10 @@ func linkProcessor(ctx *RenderContext, node *html.Node) { } uri := node.Data[m[0]:m[1]] + remaining := node.Data[m[1]:] + if util.IsLikelySplitLeftPart(remaining) { + return + } replaceContent(node, m[0], m[1], createLink(ctx, uri, uri, "" /*link*/)) node = node.NextSibling.NextSibling } diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index 54bd91f3b3..f14fe4075c 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -206,6 +206,16 @@ func TestRender_links(t *testing.T) { test( "ftps://gitea.com", `<p>ftps://gitea.com</p>`) + + t.Run("LinkSplit", func(t *testing.T) { + input, _ := util.SplitStringAtByteN("http://10.1.2.3", 12) + assert.Equal(t, "http://10…", input) + test(input, "<p>http://10…</p>") + + input, _ = util.SplitStringAtByteN("http://10.1.2.3", 13) + assert.Equal(t, "http://10.…", input) + test(input, "<p>http://10.…</p>") + }) } func TestRender_email(t *testing.T) { diff --git a/modules/util/string.go b/modules/util/string.go index cf50f591c6..19cf75b8b3 100644 --- a/modules/util/string.go +++ b/modules/util/string.go @@ -3,7 +3,10 @@ package util -import "unsafe" +import ( + "strings" + "unsafe" +) func isSnakeCaseUpper(c byte) bool { return 'A' <= c && c <= 'Z' @@ -95,3 +98,15 @@ func UnsafeBytesToString(b []byte) string { func UnsafeStringToBytes(s string) []byte { return unsafe.Slice(unsafe.StringData(s), len(s)) } + +// SplitTrimSpace splits the string at given separator and trims leading and trailing space +func SplitTrimSpace(input, sep string) []string { + input = strings.TrimSpace(input) + var stringList []string + for _, s := range strings.Split(input, sep) { + if s = strings.TrimSpace(s); s != "" { + stringList = append(stringList, s) + } + } + return stringList +} diff --git a/modules/util/string_test.go b/modules/util/string_test.go index 0a4a8bbcfb..ff67b5c7d4 100644 --- a/modules/util/string_test.go +++ b/modules/util/string_test.go @@ -45,3 +45,8 @@ func TestToSnakeCase(t *testing.T) { assert.Equal(t, expected, ToSnakeCase(input)) } } + +func TestSplitTrimSpace(t *testing.T) { + assert.Equal(t, []string{"a", "b", "c"}, SplitTrimSpace("a\nb\nc", "\n")) + assert.Equal(t, []string{"a", "b"}, SplitTrimSpace("\r\na\n\r\nb\n\n", "\n")) +} diff --git a/modules/util/truncate.go b/modules/util/truncate.go index f2edbdc673..9f932facc9 100644 --- a/modules/util/truncate.go +++ b/modules/util/truncate.go @@ -14,6 +14,10 @@ const ( asciiEllipsis = "..." ) +func IsLikelySplitLeftPart(s string) bool { + return strings.HasSuffix(s, utf8Ellipsis) || strings.HasSuffix(s, asciiEllipsis) +} + // SplitStringAtByteN splits a string at byte n accounting for rune boundaries. (Combining characters are not accounted for.) func SplitStringAtByteN(input string, n int) (left, right string) { if len(input) <= n { @@ -38,19 +42,3 @@ func SplitStringAtByteN(input string, n int) (left, right string) { return input[:end] + utf8Ellipsis, utf8Ellipsis + input[end:] } - -// SplitTrimSpace splits the string at given separator and trims leading and trailing space -func SplitTrimSpace(input, sep string) []string { - // Trim initial leading & trailing space - input = strings.TrimSpace(input) - // replace CRLF with LF - input = strings.ReplaceAll(input, "\r\n", "\n") - - var stringList []string - for _, s := range strings.Split(input, sep) { - // trim leading and trailing space - stringList = append(stringList, strings.TrimSpace(s)) - } - - return stringList -} diff --git a/services/issue/milestone.go b/services/issue/milestone.go index ff645744a7..beb6f131a9 100644 --- a/services/issue/milestone.go +++ b/services/issue/milestone.go @@ -59,6 +59,10 @@ func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *is } } + if issue.MilestoneID == 0 { + issue.Milestone = nil + } + return nil } diff --git a/services/issue/milestone_test.go b/services/issue/milestone_test.go index 42b910166f..bf5abc85b7 100644 --- a/services/issue/milestone_test.go +++ b/services/issue/milestone_test.go @@ -23,6 +23,7 @@ func TestChangeMilestoneAssign(t *testing.T) { oldMilestoneID := issue.MilestoneID issue.MilestoneID = 2 + assert.NoError(t, issue.LoadMilestone(db.DefaultContext)) assert.NoError(t, ChangeMilestoneAssign(db.DefaultContext, issue, doer, oldMilestoneID)) unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ IssueID: issue.ID, @@ -31,4 +32,11 @@ func TestChangeMilestoneAssign(t *testing.T) { OldMilestoneID: oldMilestoneID, }) unittest.CheckConsistencyFor(t, &issues_model.Milestone{}, &issues_model.Issue{}) + assert.NotNil(t, issue.Milestone) + + oldMilestoneID = issue.MilestoneID + issue.MilestoneID = 0 + assert.NoError(t, ChangeMilestoneAssign(db.DefaultContext, issue, doer, oldMilestoneID)) + assert.EqualValues(t, 0, issue.MilestoneID) + assert.Nil(t, issue.Milestone) } |