mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-26 06:16:56 +09:00
fix(markup): resolve and proxy srcset links of <source> elements (#39708)
1. use correct links for srcset attribute of picture source 2. wrap the picture element with a link correctly --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
1 parent
bd28f254fa
commit
a1cc651267
9 files changed
+247
-14
No files matched your search
@@ -36,7 +36,7 @@ func b64encode(data []byte) string {
|
||||
func camoHandleLink(link string) string {
|
||||
if setting.Camo.Enabled {
|
||||
lnkURL, err := url.Parse(link)
|
||||
if err == nil && lnkURL.IsAbs() && !strings.HasPrefix(link, setting.AppURL) &&
|
||||
if err == nil && (lnkURL.Scheme == "http" || lnkURL.Scheme == "https") && !strings.HasPrefix(link, setting.AppURL) &&
|
||||
(setting.Camo.Always || lnkURL.Scheme != "https") {
|
||||
return CamoEncode(link)
|
||||
}
|
||||
|
||||
@@ -15,8 +15,11 @@ func TestCamoHandleLink(t *testing.T) {
|
||||
setting.AppURL = "https://gitea.com"
|
||||
// Test media proxy
|
||||
setting.Camo.Enabled = true
|
||||
setting.Camo.Always = false
|
||||
setting.Camo.ServerURL = "https://image.proxy"
|
||||
setting.Camo.HMACKey = "geheim"
|
||||
dataURL := "data:image/png;base64,i//V"
|
||||
assert.Equal(t, dataURL, camoHandleLink(dataURL))
|
||||
|
||||
assert.Equal(t,
|
||||
"https://gitea.com/img.jpg",
|
||||
@@ -29,6 +32,7 @@ func TestCamoHandleLink(t *testing.T) {
|
||||
camoHandleLink("http://testimages.org/img.jpg"))
|
||||
|
||||
setting.Camo.Always = true
|
||||
assert.Equal(t, dataURL, camoHandleLink(dataURL))
|
||||
assert.Equal(t,
|
||||
"https://gitea.com/img.jpg",
|
||||
camoHandleLink("https://gitea.com/img.jpg"))
|
||||
|
||||
@@ -355,6 +355,8 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) *html.Nod
|
||||
return visitNodeImg(ctx, node)
|
||||
} else if node.Data == "video" {
|
||||
return visitNodeVideo(ctx, node)
|
||||
} else if node.Data == "source" {
|
||||
return visitNodePictureSource(ctx, node)
|
||||
}
|
||||
|
||||
if node.Data == "a" {
|
||||
@@ -363,10 +365,11 @@ func visitNode(ctx *RenderContext, procs []processor, node *html.Node) *html.Nod
|
||||
// because the content there is not processable, for example: the content is a commit id or a full URL.
|
||||
procs = emojiProcessors
|
||||
}
|
||||
next := node.NextSibling
|
||||
for n := node.FirstChild; n != nil; {
|
||||
n = visitNode(ctx, procs, n)
|
||||
}
|
||||
return node.NextSibling
|
||||
return next
|
||||
}
|
||||
|
||||
// createKeyword() renders a highlighted version of an action keyword
|
||||
|
||||
+32
-10
@@ -6,6 +6,7 @@ package markup
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"gitea.dev/modules/htmlutil"
|
||||
"gitea.dev/modules/markup/common"
|
||||
|
||||
"golang.org/x/net/html"
|
||||
@@ -127,6 +128,10 @@ func processNodeA(ctx *RenderContext, node *html.Node) {
|
||||
}
|
||||
}
|
||||
|
||||
func resolveMediaLinkWithCamo(ctx *RenderContext, link string) string {
|
||||
return camoHandleLink(ctx.RenderHelper.ResolveLink(link, LinkTypeMedia))
|
||||
}
|
||||
|
||||
func visitNodeImg(ctx *RenderContext, img *html.Node) (next *html.Node) {
|
||||
next = img.NextSibling
|
||||
attrSrc, hasLazy := "", false
|
||||
@@ -152,19 +157,21 @@ func visitNodeImg(ctx *RenderContext, img *html.Node) (next *html.Node) {
|
||||
cnt++
|
||||
}
|
||||
if isLinkable {
|
||||
linkNode := img
|
||||
if img.Parent.Data == "picture" {
|
||||
linkNode = img.Parent
|
||||
}
|
||||
wrapper := &html.Node{Type: html.ElementNode, Data: "a", Attr: []html.Attribute{
|
||||
{Key: "href", Val: ctx.RenderHelper.ResolveLink(imgSrcOrigin, LinkTypeDefault)},
|
||||
{Key: "target", Val: "_blank"},
|
||||
}}
|
||||
parent := img.Parent
|
||||
imgNext := img.NextSibling
|
||||
parent.RemoveChild(img)
|
||||
parent.InsertBefore(wrapper, imgNext)
|
||||
wrapper.AppendChild(img)
|
||||
parent := linkNode.Parent
|
||||
linkNext := linkNode.NextSibling
|
||||
parent.RemoveChild(linkNode)
|
||||
parent.InsertBefore(wrapper, linkNext)
|
||||
wrapper.AppendChild(linkNode)
|
||||
}
|
||||
|
||||
imgAttr.Val = ctx.RenderHelper.ResolveLink(imgSrcOrigin, LinkTypeMedia)
|
||||
imgAttr.Val = camoHandleLink(imgAttr.Val)
|
||||
imgAttr.Val = resolveMediaLinkWithCamo(ctx, imgSrcOrigin)
|
||||
img.Attr[i] = imgAttr
|
||||
}
|
||||
if !RenderBehaviorForTesting.DisableAdditionalAttributes && !hasLazy && !strings.HasPrefix(attrSrc, "data:") {
|
||||
@@ -179,9 +186,24 @@ func visitNodeVideo(ctx *RenderContext, node *html.Node) (next *html.Node) {
|
||||
if attr.Key != "src" {
|
||||
continue
|
||||
}
|
||||
attr.Val = ctx.RenderHelper.ResolveLink(attr.Val, LinkTypeMedia)
|
||||
attr.Val = camoHandleLink(attr.Val)
|
||||
attr.Val = resolveMediaLinkWithCamo(ctx, attr.Val)
|
||||
node.Attr[i] = attr
|
||||
}
|
||||
return next
|
||||
}
|
||||
|
||||
func visitNodePictureSource(ctx *RenderContext, node *html.Node) (next *html.Node) {
|
||||
next = node.NextSibling
|
||||
for attrIdx, attr := range node.Attr {
|
||||
if attr.Key != "srcset" {
|
||||
continue
|
||||
}
|
||||
srcsetCandidates := htmlutil.ParseSrcset(attr.Val)
|
||||
for i, candidate := range srcsetCandidates {
|
||||
srcsetCandidates[i].SrcLink = resolveMediaLinkWithCamo(ctx, candidate.SrcLink)
|
||||
}
|
||||
attr.Val = htmlutil.EncodeSrcset(srcsetCandidates)
|
||||
node.Attr[attrIdx] = attr
|
||||
}
|
||||
return next
|
||||
}
|
||||
@@ -42,7 +42,7 @@ func resolveLinkRelative(ctx context.Context, base, cur, link string, absolute b
|
||||
finalLink += "?" + linkURL.RawQuery
|
||||
}
|
||||
if linkURL.Fragment != "" {
|
||||
finalLink += "#" + linkURL.Fragment
|
||||
finalLink += "#" + linkURL.EscapedFragment()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ func TestResolveLinkRelative(t *testing.T) {
|
||||
assert.Equal(t, "/a/c", resolveLinkRelative(ctx, "/a", "b", "/c", false))
|
||||
assert.Equal(t, "/a/c#id", resolveLinkRelative(ctx, "/a", "b", "/c#id", false))
|
||||
assert.Equal(t, "/a/%2f?k=/", resolveLinkRelative(ctx, "/a", "b", "/%2f/?k=/", false))
|
||||
assert.Equal(t, "/a/b/c?k=v#id", resolveLinkRelative(ctx, "/a", "b", "c/?k=v#id", false))
|
||||
assert.Equal(t, "/a/b/c?k=v#with%20space", resolveLinkRelative(ctx, "/a", "b", "c/?k=v#with%20space", false))
|
||||
assert.Equal(t, "%invalid", resolveLinkRelative(ctx, "/a", "b", "%invalid", false))
|
||||
assert.Equal(t, "http://localhost:3000/a", resolveLinkRelative(ctx, "/a", "", "", true))
|
||||
|
||||
|
||||
Reference in new issue
Block a user