aboutsummaryrefslogtreecommitdiffhomepage
path: root/markup
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <[email protected]>2022-03-10 08:19:03 +0100
committerGitHub <[email protected]>2022-03-10 08:19:03 +0100
commit4e14cf7607ad3afdbf65272cd5bb61dba4b415da (patch)
tree84922c4407920e9b45502afce15730c0da796a88 /markup
parent5697348e1732a5f64ee7467283eb0335f2ec36e8 (diff)
downloadhugo-4e14cf7607ad3afdbf65272cd5bb61dba4b415da.tar.gz
hugo-4e14cf7607ad3afdbf65272cd5bb61dba4b415da.zip
Fail with error when double-rendering text in markdownify/RenderString
This commit prevents the most commons case of infinite recursion in link render hooks when the `linkify` option is enabled (see below). This is always a user error, but getting a `stack overflow` (the current stack limit in Go is 1 GB on 64-bit, 250 MB on 32-bit) error isn't very helpful. This fix will not prevent all such errors, though, but we may do better once #9570 is in place. So, these will fail: ``` <a href="{{ .Destination | safeURL }}" >{{ .Text | markdownify }}</a> <a href="{{ .Destination | safeURL }}" >{{ .Text | .Page.RenderString }}</a> ``` `.Text` is already rendered to `HTML`. The above needs to be rewritten to: ``` <a href="{{ .Destination | safeURL }}" >{{ .Text | safeHTML }}</a> <a href="{{ .Destination | safeURL }}" >{{ .Text | safeHTML }}</a> ``` Fixes #8959
Diffstat (limited to 'markup')
-rw-r--r--markup/converter/hooks/hooks.go5
-rw-r--r--markup/goldmark/integration_test.go45
-rw-r--r--markup/goldmark/render_hooks.go17
3 files changed, 57 insertions, 10 deletions
diff --git a/markup/converter/hooks/hooks.go b/markup/converter/hooks/hooks.go
index 54ebf405e..2f2d5e6cb 100644
--- a/markup/converter/hooks/hooks.go
+++ b/markup/converter/hooks/hooks.go
@@ -18,6 +18,7 @@ import (
"github.com/gohugoio/hugo/common/hugio"
"github.com/gohugoio/hugo/common/text"
+ "github.com/gohugoio/hugo/common/types/hstring"
"github.com/gohugoio/hugo/identity"
"github.com/gohugoio/hugo/markup/internal/attributes"
)
@@ -32,7 +33,7 @@ type LinkContext interface {
Page() interface{}
Destination() string
Title() string
- Text() string
+ Text() hstring.RenderedString
PlainText() string
}
@@ -75,7 +76,7 @@ type HeadingContext interface {
// Anchor is the HTML id assigned to the heading.
Anchor() string
// Text is the rendered (HTML) heading text, excluding the heading marker.
- Text() string
+ Text() hstring.RenderedString
// PlainText is the unrendered version of Text.
PlainText() string
diff --git a/markup/goldmark/integration_test.go b/markup/goldmark/integration_test.go
index d8f218b31..cab85cfdd 100644
--- a/markup/goldmark/integration_test.go
+++ b/markup/goldmark/integration_test.go
@@ -18,6 +18,8 @@ import (
"strings"
"testing"
+ qt "github.com/frankban/quicktest"
+
"github.com/gohugoio/hugo/hugolib"
)
@@ -395,6 +397,49 @@ FENCE
}
}
+// Iisse #8959
+func TestHookInfiniteRecursion(t *testing.T) {
+ t.Parallel()
+
+ for _, renderFunc := range []string{"markdownify", ".Page.RenderString"} {
+ t.Run(renderFunc, func(t *testing.T) {
+
+ files := `
+-- config.toml --
+-- layouts/_default/_markup/render-link.html --
+<a href="{{ .Destination | safeURL }}">{{ .Text | RENDERFUNC }}</a>
+-- layouts/_default/single.html --
+{{ .Content }}
+-- content/p1.md --
+---
+title: "p1"
+---
+
+https://example.org
+
+
+
+ `
+
+ files = strings.ReplaceAll(files, "RENDERFUNC", renderFunc)
+
+ b, err := hugolib.NewIntegrationTestBuilder(
+ hugolib.IntegrationTestConfig{
+ T: t,
+ TxtarString: files,
+ },
+ ).BuildE()
+
+ b.Assert(err, qt.IsNotNil)
+ b.Assert(err.Error(), qt.Contains, "text is already rendered, repeating it may cause infinite recursion")
+
+ })
+
+ }
+
+}
+
// Issue 9594
func TestQuotesInImgAltAttr(t *testing.T) {
t.Parallel()
diff --git a/markup/goldmark/render_hooks.go b/markup/goldmark/render_hooks.go
index a22030f54..6aafc70e1 100644
--- a/markup/goldmark/render_hooks.go
+++ b/markup/goldmark/render_hooks.go
@@ -17,6 +17,7 @@ import (
"bytes"
"strings"
+ "github.com/gohugoio/hugo/common/types/hstring"
"github.com/gohugoio/hugo/markup/converter/hooks"
"github.com/gohugoio/hugo/markup/goldmark/goldmark_config"
"github.com/gohugoio/hugo/markup/goldmark/internal/render"
@@ -49,7 +50,7 @@ type linkContext struct {
page interface{}
destination string
title string
- text string
+ text hstring.RenderedString
plainText string
}
@@ -65,7 +66,7 @@ func (ctx linkContext) Page() interface{} {
return ctx.page
}
-func (ctx linkContext) Text() string {
+func (ctx linkContext) Text() hstring.RenderedString {
return ctx.text
}
@@ -81,7 +82,7 @@ type headingContext struct {
page interface{}
level int
anchor string
- text string
+ text hstring.RenderedString
plainText string
*attributes.AttributesHolder
}
@@ -98,7 +99,7 @@ func (ctx headingContext) Anchor() string {
return ctx.anchor
}
-func (ctx headingContext) Text() string {
+func (ctx headingContext) Text() hstring.RenderedString {
return ctx.text
}
@@ -156,7 +157,7 @@ func (r *hookedRenderer) renderImage(w util.BufWriter, source []byte, node ast.N
page: ctx.DocumentContext().Document,
destination: string(n.Destination),
title: string(n.Title),
- text: string(text),
+ text: hstring.RenderedString(text),
plainText: string(n.Text(source)),
},
)
@@ -226,7 +227,7 @@ func (r *hookedRenderer) renderLink(w util.BufWriter, source []byte, node ast.No
page: ctx.DocumentContext().Document,
destination: string(n.Destination),
title: string(n.Title),
- text: string(text),
+ text: hstring.RenderedString(text),
plainText: string(n.Text(source)),
},
)
@@ -293,7 +294,7 @@ func (r *hookedRenderer) renderAutoLink(w util.BufWriter, source []byte, node as
linkContext{
page: ctx.DocumentContext().Document,
destination: url,
- text: label,
+ text: hstring.RenderedString(label),
plainText: label,
},
)
@@ -381,7 +382,7 @@ func (r *hookedRenderer) renderHeading(w util.BufWriter, source []byte, node ast
page: ctx.DocumentContext().Document,
level: n.Level,
anchor: string(anchor),
- text: string(text),
+ text: hstring.RenderedString(text),
plainText: string(n.Text(source)),
AttributesHolder: attributes.New(n.Attributes(), attributes.AttributesOwnerGeneral),
},