(new): expand runtime APIs
Golang lint / lint (push) Successful in 58s
Golang lint / lint (pull_request) Successful in 13m10s

(fix): harden concurrent lifecycle
(tests): add regression coverage
(doc): update v1.2 guidance
This commit is contained in:
2026-08-20 11:08:45 +03:00
parent 29b208eeec
commit 24040fe164
37 changed files with 1129 additions and 157 deletions
+7
View File
@@ -216,6 +216,13 @@ func TestBuildHTMLLimits(t *testing.T) {
{"combined nesting too deep", func() []tgapi.InputRichBlock {
return []tgapi.InputRichBlock{P(wrapBold(Text("text"), maxRichDepth))}
}, ErrRichNestingTooDeep},
{"rich text arrays too deep", func() []tgapi.InputRichBlock {
text := tgapi.RichText(Text("text"))
for range maxRichDepth {
text = tgapi.RichTextArray{text}
}
return []tgapi.InputRichBlock{P(text)}
}, ErrRichNestingTooDeep},
{"maximum block nesting", func() []tgapi.InputRichBlock {
return []tgapi.InputRichBlock{wrapDetails(P(Text("text")), maxRichDepth-1)}
}, nil},
+4 -1
View File
@@ -80,9 +80,12 @@ func renderText(t tgapi.RichText, step int) (string, error) {
case tgapi.RichTextPlain:
return escapeHTML(string(el)), nil
case tgapi.RichTextArray:
if step >= maxRichDepth {
return "", ErrRichNestingTooDeep
}
var b strings.Builder
for _, item := range el {
part, err := renderText(item, step)
part, err := renderText(item, step+1)
if err != nil {
return "", err
}
+27 -18
View File
@@ -119,8 +119,11 @@ func (v *richValidator) text(text tgapi.RichText, depth int) error {
case tgapi.RichTextPlain:
return v.addChars(string(el))
case tgapi.RichTextArray:
if depth >= maxRichDepth {
return ErrRichNestingTooDeep
}
for _, item := range el {
if err := v.text(item, depth); err != nil {
if err := v.text(item, depth+1); err != nil {
return err
}
}
@@ -176,7 +179,7 @@ func (v *richValidator) text(text tgapi.RichText, depth int) error {
}
func validateAutomaticEntity(text tgapi.RichText, semantic string) error {
visible, err := visibleRichText(text)
visible, err := visibleRichText(text, 0)
if err != nil {
return err
}
@@ -186,16 +189,22 @@ func validateAutomaticEntity(text tgapi.RichText, semantic string) error {
return nil
}
func visibleRichText(text tgapi.RichText) (string, error) {
func visibleRichText(text tgapi.RichText, depth int) (string, error) {
if depth > maxRichDepth {
return "", ErrRichNestingTooDeep
}
switch el := text.(type) {
case nil:
return "", nil
case tgapi.RichTextPlain:
return string(el), nil
case tgapi.RichTextArray:
if depth >= maxRichDepth {
return "", ErrRichNestingTooDeep
}
var result strings.Builder
for _, item := range el {
part, err := visibleRichText(item)
part, err := visibleRichText(item, depth+1)
if err != nil {
return "", err
}
@@ -209,33 +218,33 @@ func visibleRichText(text tgapi.RichText) (string, error) {
case tgapi.RichTextAnchor:
return "", nil
case tgapi.RichTextWrap:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
case tgapi.RichTextURL:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
case tgapi.RichTextEmailAddress:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
case tgapi.RichTextPhoneNumber:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
case tgapi.RichTextBankCardNumber:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
case tgapi.RichTextMention:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
case tgapi.RichTextHashtag:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
case tgapi.RichTextCashtag:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
case tgapi.RichTextBotCommand:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
case tgapi.RichTextAnchorLink:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
case tgapi.RichTextReference:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
case tgapi.RichTextReferenceLink:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
case tgapi.RichTextDateTime:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
case tgapi.RichTextTextMention:
return visibleRichText(el.Text)
return visibleRichText(el.Text, depth+1)
default:
return "", ErrRichUnknownTag
}