From 7d78a498e19c2331a325fa43dd46f4da2b0443a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Pedersen?= Date: Thu, 23 Feb 2023 08:08:17 +0100 Subject: [PATCH] Throw an error when shortcode is expected to be closed Fixes #10675 --- hugolib/shortcode.go | 13 ++++++++++++- hugolib/shortcode_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/hugolib/shortcode.go b/hugolib/shortcode.go index a82caff43..d3430cb81 100644 --- a/hugolib/shortcode.go +++ b/hugolib/shortcode.go @@ -224,6 +224,10 @@ func (s shortcode) insertPlaceholder() bool { return !s.doMarkup || s.configVersion() == 1 } +func (s shortcode) needsInner() bool { + return s.info != nil && s.info.ParseInfo().IsInner +} + func (s shortcode) configVersion() int { if s.info == nil { // Not set for inline shortcodes. @@ -557,6 +561,7 @@ func (s *shortcodeHandler) extractShortcode(ordinal, level int, source []byte, p cnt := 0 nestedOrdinal := 0 nextLevel := level + 1 + closed := false const errorPrefix = "failed to extract shortcode" fail := func(err error, i pageparser.Item) error { @@ -612,9 +617,10 @@ Loop: } case currItem.IsShortcodeClose(): + closed = true next := pt.Peek() if !sc.isInline { - if sc.info == nil || !sc.info.ParseInfo().IsInner { + if !sc.needsInner() { if next.IsError() { // return that error, more specific continue @@ -689,6 +695,11 @@ Loop: } } case currItem.IsDone(): + if !currItem.IsError() { + if !closed && sc.needsInner() { + return sc, fmt.Errorf("%s: unclosed shortcode %q", errorPrefix, sc.name) + } + } // handled by caller pt.Backup() break Loop diff --git a/hugolib/shortcode_test.go b/hugolib/shortcode_test.go index 564d632e4..cd17e7874 100644 --- a/hugolib/shortcode_test.go +++ b/hugolib/shortcode_test.go @@ -1241,3 +1241,38 @@ InnerDeindent: closing-no-newline: 0 `) } + +// Issue 10675. +func TestShortcodeErrorWhenItShouldBeClosed(t *testing.T) { + t.Parallel() + + files := ` +-- config.toml -- +disableKinds = ["home", "taxonomy", "term"] +-- content/p1.md -- +--- +title: "p1" +--- + +{{< sc >}} + +Text. + +-- layouts/shortcodes/sc.html -- +Inner: {{ .Get 0 }}: {{ len .Inner }} +-- layouts/_default/single.html -- +{{ .Content }} +` + + b, err := NewIntegrationTestBuilder( + IntegrationTestConfig{ + T: t, + TxtarString: files, + Running: true, + Verbose: true, + }, + ).BuildE() + + b.Assert(err, qt.Not(qt.IsNil)) + b.Assert(err.Error(), qt.Contains, `p1.md:5:1": failed to extract shortcode: unclosed shortcode "sc"`) +}