commit bf679b4

delthas  ·  2024-07-02 22:09:39 +0000 UTC
parent ffb806d
Split long messages on grapheme cluster boundaries

This fixes possibly sending invalid emoji sequences in very rare
cases in long messages.

Fixes: https://todo.sr.ht/~delthas/senpai/78
1 files changed,  +15, -11
+15, -11
 1@@ -10,8 +10,8 @@ import (
 2 	"strings"
 3 	"time"
 4 	"unicode"
 5-	"unicode/utf8"
 6 
 7+	"git.sr.ht/~rockorager/vaxis"
 8 	"golang.org/x/time/rate"
 9 )
10 
11@@ -429,20 +429,24 @@ func (s *Session) Away(message string) {
12 }
13 
14 func splitChunks(s string, chunkLen int) (chunks []string) {
15-	if chunkLen <= 0 {
16+	if chunkLen <= 0 || len(s) <= chunkLen {
17 		return []string{s}
18 	}
19-	for chunkLen < len(s) {
20-		i := chunkLen
21-		min := chunkLen - utf8.UTFMax
22-		for min <= i && !utf8.RuneStart(s[i]) {
23-			i--
24+
25+	b := 0
26+	n := 0
27+	for _, c := range vaxis.Characters(s) {
28+		cw := len(c.Grapheme)
29+		if n+cw > chunkLen {
30+			chunks = append(chunks, s[b:b+n])
31+			b += n
32+			n = cw
33+			continue
34 		}
35-		chunks = append(chunks, s[:i])
36-		s = s[i:]
37+		n += cw
38 	}
39-	if len(s) != 0 {
40-		chunks = append(chunks, s)
41+	if b < len(s) {
42+		chunks = append(chunks, s[b:])
43 	}
44 	return
45 }