forgejo/modules/util/truncate.go
Mopcho 64cc883ac1 Fix discord webhook 400 status code when description limit is exceeded (#34084)
Fixes [#34027](https://github.com/go-gitea/gitea/issues/34027)

Discord does not allow for description bigger than 2048 bytes. If the
description is bigger than that it will throw 400 and the event won't
appear in discord. To fix that, in the createPayload method we now slice
the description to ensure it doesn’t exceed the limit.

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
(cherry picked from commit 013b2686fe6d306c4fb800147207b099866683b9)
2025-04-07 18:27:08 +02:00

65 lines
1.6 KiB
Go

// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package util
import (
"strings"
"unicode/utf8"
)
// in UTF8 "…" is 3 bytes so doesn't really gain us anything...
const (
utf8Ellipsis = "…"
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 {
return input, ""
}
if !utf8.ValidString(input) {
if n-3 < 0 {
return input, ""
}
return input[:n-3] + asciiEllipsis, asciiEllipsis + input[n-3:]
}
end := 0
for end <= n-3 {
_, size := utf8.DecodeRuneInString(input[end:])
if end+size > n-3 {
break
}
end += size
}
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
}
// TruncateRunes returns a truncated string with given rune limit,
// it returns input string if its rune length doesn't exceed the limit.
func TruncateRunes(str string, limit int) string {
if utf8.RuneCountInString(str) < limit {
return str
}
return string([]rune(str)[:limit])
}