Files
OwnCord/Server/db/sanitize_test.go
T
jevb f3c9f98b91 fix: resolve 4 server bugs (Phase 1: BUG-085, BUG-087, BUG-090, BUG-091)
- BUG-085: ring buffer EventsSince off-by-one — change < to <= so
  afterSeq == oldestSeq returns nil (triggers full ready payload)
- BUG-087: GracefulStop not idempotent — wrap body in sync.Once to
  prevent double lkProcess.Stop() on concurrent calls
- BUG-090: FTS query truncation at byte boundary — use []rune
  truncation to preserve valid UTF-8 for CJK/emoji input
- BUG-091: updater downloadFile double-closes file on Windows —
  add closed sentinel to guard defer against explicit Close()
2026-04-01 17:52:06 +02:00

50 lines
1.3 KiB
Go

package db
import (
"strings"
"testing"
"unicode/utf8"
)
func TestSanitizeFTSQuery_UTF8Truncation(t *testing.T) {
// BUG-090: sanitizeFTSQuery truncates at byte boundary, producing
// invalid UTF-8 when the input contains multi-byte runes (CJK, emoji).
// Build a 210-rune CJK string. Each CJK rune is 3 bytes → 630 bytes.
input := strings.Repeat("漢", 210)
got := sanitizeFTSQuery(input)
if !utf8.ValidString(got) {
t.Fatal("sanitizeFTSQuery produced invalid UTF-8 after truncation")
}
runeCount := utf8.RuneCountInString(got)
if runeCount > 200 {
t.Fatalf("expected at most 200 runes, got %d", runeCount)
}
if runeCount != 200 {
t.Fatalf("expected exactly 200 runes for 210-rune input, got %d", runeCount)
}
}
func TestSanitizeFTSQuery_ASCIIUnchanged(t *testing.T) {
// ASCII-only input under 200 chars should pass through unchanged.
input := "hello world search query"
got := sanitizeFTSQuery(input)
if got != input {
t.Errorf("expected %q, got %q", input, got)
}
}
func TestSanitizeFTSQuery_StripsOperators(t *testing.T) {
input := `hello "world" AND (test) NOT foo*`
got := sanitizeFTSQuery(input)
// Should only contain letters, digits, spaces, hyphens.
for _, r := range got {
if r == '"' || r == '(' || r == ')' || r == '*' {
t.Errorf("operator character %q not stripped", r)
}
}
}