2 Commits

Author SHA1 Message Date
orangix
bb54932770 write remainder after last link 2026-03-12 04:43:17 +01:00
orangix
d03d2a3c25 use encoding/xml in sanitizeComment 2026-01-27 05:11:20 +01:00
3 changed files with 85 additions and 34 deletions

View File

@@ -36,7 +36,7 @@ func relTime(date time.Time) string {
return humanize.Time(date)
}
func rewriteUrl(link string) string {
r, err := utils.RewriteUrl(link)
r, err := utils.RewriteUrlString(link)
if err != nil {
panic(err)
}

View File

@@ -1,44 +1,67 @@
package render
import (
"regexp"
"encoding/xml"
"net/url"
"strings"
"codeberg.org/rimgo/rimgo/utils"
"github.com/microcosm-cc/bluemonday"
"gitlab.com/golang-commonmark/linkify"
)
var imgurRe = regexp.MustCompile(`https?://imgur\.com/(gallery|a)?/(.*)`)
var imgurRe2 = regexp.MustCompile(`https?://imgur\.com/(.*)`)
var imgRe = regexp.MustCompile(`https?://i\.imgur\.com/(.*)\.(png|gif|jpe?g|webp)`)
var vidRe = regexp.MustCompile(`https?://i\.imgur\.com/(.*)\.(mp4|webm)`)
var vidFormatRe = regexp.MustCompile(`\.(mp4|webm)`)
var iImgurRe = regexp.MustCompile(`https?://i\.imgur\.com`)
func sanitizeDescription(src string) string {
src = strings.ReplaceAll(src, "\n", "<br>")
return bluemonday.UGCPolicy().Sanitize(src)
}
func sanitizeComment(src string) string {
src = strings.ReplaceAll(src, "\n", "<br>")
for _, match := range imgRe.FindAllString(src, -1) {
img := iImgurRe.ReplaceAllString(match, "")
img = `<img src="` + img + `" class="comment__media" loading="lazy"/>`
src = strings.Replace(src, match, img, 1)
}
for _, match := range vidRe.FindAllString(src, -1) {
vid := iImgurRe.ReplaceAllString(match, "")
vid = `<video class="comment__media" controls loop preload="none" poster="` + vidFormatRe.ReplaceAllString(vid, ".webp") + `"><source type="` + strings.Split(vid, ".")[1] + `" src="` + vid + `" /></video>`
src = strings.Replace(src, match, vid, 1)
}
buf := new(strings.Builder)
enc := xml.NewEncoder(buf)
from := 0
for _, l := range linkify.Links(src) {
origLink := (src)[l.Start:l.End]
link := `<a href="` + origLink + `">` + origLink + `</a>`
src = strings.Replace(src, origLink, link, 1)
buf.WriteString(src[from:l.Start])
origLink := src[l.Start:l.End]
url, err := url.Parse(origLink)
if err != nil {
buf.WriteString(origLink)
continue
}
newLink := utils.RewriteUrl(url)
if url.Host == "i.imgur.com" {
name, ext := utils.SplitNameExt(newLink)
switch ext {
case "png", "gif", "jpg", "jpeg", "webp":
start(enc, "img",
"src", newLink,
"class", "comment__media",
"loading", "lazy")
//self-closing tag
case "mp4", "webm":
start(enc, "video",
"class", "comment__media",
"controls", "controls",
"loop", "loop",
"preload", "none",
"poster", name+"webp")
start(enc, "source",
"type", ext,
"src", newLink)
end(enc, "source")
end(enc, "video")
default:
goto link
}
from = l.End
continue
}
link:
start(enc, "a", "href", newLink)
xml.EscapeText(buf, []byte(origLink))
end(enc, "a")
from = l.End
}
src = imgurRe.ReplaceAllString(src, "/$1/$2")
src = imgurRe2.ReplaceAllString(src, "/$1")
buf.WriteString(src[from:])
p := bluemonday.UGCPolicy()
p.AllowImages()
@@ -49,5 +72,29 @@ func sanitizeComment(src string) string {
p.RequireNoReferrerOnLinks(true)
p.RequireNoFollowOnLinks(true)
p.RequireCrossOriginAnonymous(true)
return p.Sanitize(src)
return p.Sanitize(buf.String())
}
func start(enc *xml.Encoder, name string, attrs ...string) {
if len(attrs)%2 == 1 {
panic("odd number of arguments to attrs")
}
xmlAttrs := make([]xml.Attr, len(attrs)/2)
for i := 0; i < len(attrs); i += 2 {
xmlAttrs[i/2] = xml.Attr{
Name: xml.Name{Space: "", Local: attrs[i]},
Value: attrs[i+1],
}
}
enc.EncodeToken(xml.StartElement{
Name: xml.Name{Space: "", Local: name},
Attr: xmlAttrs,
})
enc.Flush()
}
func end(enc *xml.Encoder, name string) {
enc.EncodeToken(xml.EndElement{
Name: xml.Name{Space: "", Local: name},
})
enc.Flush()
}

View File

@@ -4,16 +4,20 @@ import (
"net/url"
)
func RewriteUrl(link string) (string, error) {
func RewriteUrl(link *url.URL) string {
switch link.Host {
case "", "imgur.com", "www.imgur.com", "i.imgur.com":
return link.Path
case "i.stack.imgur.com":
return "/stack" + link.Path
}
return link.String()
}
func RewriteUrlString(link string) (string, error) {
url, err := url.Parse(link)
if err != nil {
return "", err
}
switch url.Host {
case "", "imgur.com", "www.imgur.com", "i.imgur.com":
return url.Path, nil
case "i.stack.imgur.com":
return "/stack" + url.Path, nil
}
return link, nil
return RewriteUrl(url), nil
}