diff options
author | Bjørn Erik Pedersen <[email protected]> | 2023-03-14 12:45:09 +0100 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2023-03-15 08:54:34 +0100 |
commit | b0b1b76dc9c7edad15924785d01684e36f3e6cdb (patch) | |
tree | 85700dca0a8e7307ec168fcee4755c1a561a0f63 /markup | |
parent | 0fbab7cbc5a0b57ec875858111b178160d18acb5 (diff) | |
download | hugo-b0b1b76dc9c7edad15924785d01684e36f3e6cdb.tar.gz hugo-b0b1b76dc9c7edad15924785d01684e36f3e6cdb.zip |
markup/goldmark: Fail on invalid Markdown attributes
Diffstat (limited to 'markup')
-rw-r--r-- | markup/goldmark/codeblocks/integration_test.go | 39 | ||||
-rw-r--r-- | markup/goldmark/codeblocks/render.go | 28 |
2 files changed, 58 insertions, 9 deletions
diff --git a/markup/goldmark/codeblocks/integration_test.go b/markup/goldmark/codeblocks/integration_test.go index 29ff0dc7d..7f0201878 100644 --- a/markup/goldmark/codeblocks/integration_test.go +++ b/markup/goldmark/codeblocks/integration_test.go @@ -18,6 +18,8 @@ import ( "strings" "testing" + qt "github.com/frankban/quicktest" + "github.com/gohugoio/hugo/hugolib" ) @@ -384,3 +386,40 @@ Common } } + +// Issue 10835 +func TestAttributesValidation(t *testing.T) { + t.Parallel() + + files := ` +-- hugo.toml -- +disableKinds = ["taxonomy", "term"] +-- content/p1.md -- +--- +title: "p1" +--- + +## Issue 10835 + +§§§bash { color=red dimensions=300x200 } +Hello, World! +§§§ + +-- layouts/index.html -- +-- layouts/_default/single.html -- +{{ .Content }} +-- layouts/_default/_markup/render-codeblock.html -- +Attributes: {{ .Attributes }}|Type: {{ .Type }}| +` + + b, err := hugolib.NewIntegrationTestBuilder( + hugolib.IntegrationTestConfig{ + T: t, + TxtarString: files, + }, + ).BuildE() + + b.Assert(err, qt.Not(qt.IsNil)) + b.Assert(err.Error(), qt.Contains, "p1.md:7:9\": failed to parse Markdown attributes; you may need to quote the values") + +} diff --git a/markup/goldmark/codeblocks/render.go b/markup/goldmark/codeblocks/render.go index cf5a0f296..5f053d278 100644 --- a/markup/goldmark/codeblocks/render.go +++ b/markup/goldmark/codeblocks/render.go @@ -15,6 +15,7 @@ package codeblocks import ( "bytes" + "errors" "fmt" "strings" "sync" @@ -101,7 +102,10 @@ func (r *htmlRenderer) renderCodeBlock(w util.BufWriter, src []byte, node ast.No } // IsDefaultCodeBlockRendererProvider - attrs := getAttributes(n.b, info) + attrs, attrStr, err := getAttributes(n.b, info) + if err != nil { + return ast.WalkStop, &herrors.TextSegmentError{Err: err, Segment: attrStr} + } cbctx := &codeBlockContext{ page: ctx.DocumentContext().Document, lang: lang, @@ -123,7 +127,7 @@ func (r *htmlRenderer) renderCodeBlock(w util.BufWriter, src []byte, node ast.No cr := renderer.(hooks.CodeBlockRenderer) - err := cr.RenderCodeblock( + err = cr.RenderCodeblock( ctx.RenderContext().Ctx, w, cbctx, @@ -182,30 +186,36 @@ func getLang(node *ast.FencedCodeBlock, src []byte) string { return lang } -func getAttributes(node *ast.FencedCodeBlock, infostr []byte) []ast.Attribute { +func getAttributes(node *ast.FencedCodeBlock, infostr []byte) ([]ast.Attribute, string, error) { if node.Attributes() != nil { - return node.Attributes() + return node.Attributes(), "", nil } if infostr != nil { attrStartIdx := -1 + attrEndIdx := -1 for idx, char := range infostr { - if char == '{' { + if attrEndIdx == -1 && char == '{' { attrStartIdx = idx + } + if attrStartIdx != -1 && char == '}' { + attrEndIdx = idx break } } - if attrStartIdx != -1 { + if attrStartIdx != -1 && attrEndIdx != -1 { n := ast.NewTextBlock() // dummy node for storing attributes - attrStr := infostr[attrStartIdx:] + attrStr := infostr[attrStartIdx : attrEndIdx+1] if attrs, hasAttr := parser.ParseAttributes(text.NewReader(attrStr)); hasAttr { for _, attr := range attrs { n.SetAttribute(attr.Name, attr.Value) } - return n.Attributes() + return n.Attributes(), "", nil + } else { + return nil, string(attrStr), errors.New("failed to parse Markdown attributes; you may need to quote the values") } } } - return nil + return nil, "", nil } |