diff --git a/bsky/parse.go b/bsky/parse.go index 97a915b..99bab03 100644 --- a/bsky/parse.go +++ b/bsky/parse.go @@ -3,6 +3,7 @@ package bsky import ( "encoding/json" "fmt" + "html" "sort" "strings" "time" @@ -329,7 +330,7 @@ func (post *Post) ProcessFacets(aliases []Records) string { } if post.Facets == nil { - return post.Text + return html.EscapeString(post.Text) } sort.Slice((*post.Facets), func(i, j int) bool { @@ -338,18 +339,18 @@ func (post *Post) ProcessFacets(aliases []Records) string { var result strings.Builder lastIndex := 0 - // post.Text = html.EscapeString(post.Text) for _, facet := range *post.Facets { start := facet.Index.ByteStart end := facet.Index.ByteEnd - result.WriteString(post.Text[lastIndex:start]) + // Escape HTML in plain text portions + result.WriteString(html.EscapeString(post.Text[lastIndex:start])) for _, feature := range *facet.Features { switch feature.Type { case "app.bsky.richtext.facet#mention": - link := fmt.Sprintf(`%s`, feature.Did, post.Text[start:end]) + link := fmt.Sprintf(`%s`, feature.Did, html.EscapeString(post.Text[start:end])) for _, alias := range aliases { if alias.Value.Subject == feature.Did { link = fmt.Sprintf(`%s`, @@ -358,18 +359,19 @@ func (post *Post) ProcessFacets(aliases []Records) string { } result.WriteString(link) case "app.bsky.richtext.facet#link": - link := fmt.Sprintf(`%s`, feature.URI, post.Text[start:end]) + link := fmt.Sprintf(`%s`, feature.URI, html.EscapeString(post.Text[start:end])) result.WriteString(link) case "app.bsky.richtext.facet#tag": - link := fmt.Sprintf(`%s`, feature.Tag, post.Text[start:end]) + link := fmt.Sprintf(`%s`, feature.Tag, html.EscapeString(post.Text[start:end])) result.WriteString(link) default: - result.WriteString(post.Text[start:end]) + result.WriteString(html.EscapeString(post.Text[start:end])) } } lastIndex = end } - result.WriteString(post.Text[lastIndex:]) + // Escape HTML in the final plain text portion + result.WriteString(html.EscapeString(post.Text[lastIndex:])) return result.String() } diff --git a/main.go b/main.go index fd472a9..34d2b0b 100644 --- a/main.go +++ b/main.go @@ -219,7 +219,7 @@ func (h *handler) ProcessPost(event *models.Event) error { handle, _ := h.bsky.GetHandleFromDID(strings.Split(ps.Embed.Record.Record.URI, "/")[2]) captionText = fmt.Sprintf( quotePostFormat, - escapeHTML(facets), + facets, strings.Split(ps.Embed.Record.Record.URI, "/")[2], strings.Split(ps.Embed.Record.Record.URI, "/")[4], handle, @@ -230,7 +230,7 @@ func (h *handler) ProcessPost(event *models.Event) error { handle, _ := h.bsky.GetHandleFromDID(strings.Split(ps.Embed.Record.URI, "/")[2]) captionText = fmt.Sprintf( quotePostFormat, - escapeHTML(facets), + facets, strings.Split(ps.Embed.Record.URI, "/")[2], strings.Split(ps.Embed.Record.URI, "/")[4], handle, @@ -246,7 +246,7 @@ func (h *handler) ProcessPost(event *models.Event) error { ownHandle = h.bsky.Bluesky.Cfg.Handle } if facets != "" { - captionText = fmt.Sprintf(postFormat, escapeHTML(facets), h.bsky.Bluesky.Cfg.DID, event.Commit.RKey, ownHandle) + captionText = fmt.Sprintf(postFormat, facets, h.bsky.Bluesky.Cfg.DID, event.Commit.RKey, ownHandle) } else { captionText = fmt.Sprintf("🦋 @%s", h.bsky.Bluesky.Cfg.DID, event.Commit.RKey, ownHandle) } @@ -328,7 +328,7 @@ func (h *handler) ProcessPost(event *models.Event) error { } else { m := tgbotapi.MessageConfig{} if captionText == "" { - m = tgbotapi.NewMessage(cid, fmt.Sprintf(postFormat, escapeHTML(facets), h.bsky.Bluesky.Cfg.DID, event.Commit.RKey, h.bsky.Bluesky.Cfg.Handle)) + m = tgbotapi.NewMessage(cid, fmt.Sprintf(postFormat, facets, h.bsky.Bluesky.Cfg.DID, event.Commit.RKey, h.bsky.Bluesky.Cfg.Handle)) } else { m = tgbotapi.NewMessage(cid, captionText) } @@ -360,16 +360,6 @@ func (h *handler) ProcessPost(event *models.Event) error { return nil } -func escapeHTML(text string) string { - // Escape HTML special characters so they display literally - replacements := strings.NewReplacer( - "&", "&", - "<", "<", - ">", ">", - ) - return replacements.Replace(text) -} - func buildBlobURL(server string, did string, cid string) string { return server + "/xrpc/com.atproto.sync.getBlob?did=" + url.QueryEscape(did) + "&cid=" + cid }