mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-11 12:18:59 +00:00
fix(cmd): sanitize followup reminder UTF-8 truncation (#609)
Prevent invalid UTF-8 from being persisted when auto-setting followups by sanitizing message content and truncating by rune count. Add regression tests for emoji truncation and malformed byte sequences.
This commit is contained in:
1 parent
f623ef9d55
commit
06de8b41cf
2 files changed
+43
-2
No files matched your search
@@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
@@ -212,8 +213,14 @@ func truncateForReminder(content string, maxLen int) string {
|
||||
// Use last non-empty line as it's typically the most relevant.
|
||||
lines := strings.Split(strings.TrimSpace(content), "\n")
|
||||
msg := lines[len(lines)-1]
|
||||
if len(msg) > maxLen {
|
||||
msg = msg[:maxLen] + "..."
|
||||
// Ensure we only persist valid UTF-8 into PostgreSQL.
|
||||
msg = strings.ToValidUTF8(msg, "")
|
||||
if maxLen <= 0 {
|
||||
return msg
|
||||
}
|
||||
if utf8.RuneCountInString(msg) > maxLen {
|
||||
r := []rune(msg)
|
||||
msg = string(r[:maxLen]) + "..."
|
||||
}
|
||||
return msg
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func TestTruncateForReminder_TruncatesByRuneAndKeepsUTF8Valid(t *testing.T) {
|
||||
input := strings.Repeat("a", 199) + "✌️"
|
||||
|
||||
got := truncateForReminder(input, 200)
|
||||
if !utf8.ValidString(got) {
|
||||
t.Fatalf("truncateForReminder() produced invalid UTF-8: %q", got)
|
||||
}
|
||||
if !strings.HasSuffix(got, "...") {
|
||||
t.Fatalf("truncateForReminder() = %q, want suffix ...", got)
|
||||
}
|
||||
if strings.Contains(got, "\uFFFD") {
|
||||
t.Fatalf("truncateForReminder() introduced replacement rune: %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTruncateForReminder_StripsInvalidUTF8(t *testing.T) {
|
||||
invalid := string([]byte{'a', 0xef, 0xb8, '.', 'b'})
|
||||
|
||||
got := truncateForReminder(invalid, 200)
|
||||
if !utf8.ValidString(got) {
|
||||
t.Fatalf("truncateForReminder() produced invalid UTF-8: %q", got)
|
||||
}
|
||||
if strings.ContainsRune(got, '\uFFFD') {
|
||||
t.Fatalf("truncateForReminder() = %q, want no replacement rune", got)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user