mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-04 05:18:25 +00:00 
			
		
		
		
	Backport #32980 by wxiaoguang Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
		@@ -9,6 +9,7 @@ import (
 | 
				
			|||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/modules/markup/common"
 | 
						"code.gitea.io/gitea/modules/markup/common"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"golang.org/x/net/html"
 | 
						"golang.org/x/net/html"
 | 
				
			||||||
	"golang.org/x/net/html/atom"
 | 
						"golang.org/x/net/html/atom"
 | 
				
			||||||
@@ -171,6 +172,10 @@ func linkProcessor(ctx *RenderContext, node *html.Node) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		uri := node.Data[m[0]:m[1]]
 | 
							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*/))
 | 
							replaceContent(node, m[0], m[1], createLink(ctx, uri, uri, "" /*link*/))
 | 
				
			||||||
		node = node.NextSibling.NextSibling
 | 
							node = node.NextSibling.NextSibling
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -206,6 +206,16 @@ func TestRender_links(t *testing.T) {
 | 
				
			|||||||
	test(
 | 
						test(
 | 
				
			||||||
		"ftps://gitea.com",
 | 
							"ftps://gitea.com",
 | 
				
			||||||
		`<p>ftps://gitea.com</p>`)
 | 
							`<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) {
 | 
					func TestRender_email(t *testing.T) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package util
 | 
					package util
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "unsafe"
 | 
					import (
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"unsafe"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func isSnakeCaseUpper(c byte) bool {
 | 
					func isSnakeCaseUpper(c byte) bool {
 | 
				
			||||||
	return 'A' <= c && c <= 'Z'
 | 
						return 'A' <= c && c <= 'Z'
 | 
				
			||||||
@@ -95,3 +98,15 @@ func UnsafeBytesToString(b []byte) string {
 | 
				
			|||||||
func UnsafeStringToBytes(s string) []byte {
 | 
					func UnsafeStringToBytes(s string) []byte {
 | 
				
			||||||
	return unsafe.Slice(unsafe.StringData(s), len(s))
 | 
						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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -45,3 +45,8 @@ func TestToSnakeCase(t *testing.T) {
 | 
				
			|||||||
		assert.Equal(t, expected, ToSnakeCase(input))
 | 
							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"))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,10 @@ const (
 | 
				
			|||||||
	asciiEllipsis = "..."
 | 
						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.)
 | 
					// 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) {
 | 
					func SplitStringAtByteN(input string, n int) (left, right string) {
 | 
				
			||||||
	if len(input) <= n {
 | 
						if len(input) <= n {
 | 
				
			||||||
@@ -38,19 +42,3 @@ func SplitStringAtByteN(input string, n int) (left, right string) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return input[:end] + utf8Ellipsis, utf8Ellipsis + input[end:]
 | 
						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
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user