Skip to content

Commit e5ee5e7

Browse files
authored
fix: use unicode character count for text length validation (#18)
2 parents 5280c7f + 1560266 commit e5ee5e7

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

client_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,24 @@ func TestValidation(t *testing.T) {
166166
if err == nil {
167167
t.Error("Expected error for text too long")
168168
}
169+
170+
// Test CJK text within character limit (500 CJK chars = 1500 bytes,
171+
// but should count as 500 characters, not 1500)
172+
cjkText := ""
173+
for i := 0; i < MaxTextLength; i++ {
174+
cjkText += "你"
175+
}
176+
err = validator.ValidateTextLength(cjkText, "Text")
177+
if err != nil {
178+
t.Errorf("Expected no error for %d CJK characters, got: %v", MaxTextLength, err)
179+
}
180+
181+
// Test CJK text exceeding character limit (501 CJK chars)
182+
cjkText += "你"
183+
err = validator.ValidateTextLength(cjkText, "Text")
184+
if err == nil {
185+
t.Error("Expected error for CJK text exceeding character limit")
186+
}
169187
})
170188

171189
t.Run("ValidateTopicTag", func(t *testing.T) {

validation.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"fmt"
55
"regexp"
66
"strings"
7+
"unicode/utf8"
78
)
89

910
// Validator provides common validation methods
@@ -22,9 +23,12 @@ func (v *Validator) ValidatePostContent(content interface{}, _ int) error {
2223
return nil
2324
}
2425

25-
// ValidateTextLength validates text doesn't exceed maximum length
26+
// ValidateTextLength validates text doesn't exceed maximum length.
27+
// The Threads API limits text posts to 500 characters (Unicode code points),
28+
// not 500 bytes. Using utf8.RuneCountInString ensures CJK and other
29+
// multi-byte characters are correctly counted as 1 character each.
2630
func (v *Validator) ValidateTextLength(text string, fieldName string) error {
27-
if len(text) > MaxTextLength {
31+
if utf8.RuneCountInString(text) > MaxTextLength {
2832
return NewValidationError(400,
2933
fmt.Sprintf("%s too long", fieldName),
3034
fmt.Sprintf("%s is limited to %d characters", fieldName, MaxTextLength),
@@ -85,10 +89,10 @@ func (v *Validator) ValidateTextAttachment(textAttachment *TextAttachment) error
8589
"text_attachment.plaintext")
8690
}
8791

88-
if len(textAttachment.Plaintext) > MaxTextAttachmentLength {
92+
if utf8.RuneCountInString(textAttachment.Plaintext) > MaxTextAttachmentLength {
8993
return NewValidationError(400,
9094
"Text attachment plaintext too long",
91-
fmt.Sprintf("Text attachment plaintext is limited to %d characters (currently %d)", MaxTextAttachmentLength, len(textAttachment.Plaintext)),
95+
fmt.Sprintf("Text attachment plaintext is limited to %d characters (currently %d)", MaxTextAttachmentLength, utf8.RuneCountInString(textAttachment.Plaintext)),
9296
"text_attachment.plaintext")
9397
}
9498

0 commit comments

Comments
 (0)