From b2bda115952eb020304d0619b6309d698ed4cbdd Mon Sep 17 00:00:00 2001 From: John Olheiser Date: Sat, 12 Sep 2020 20:48:47 -0500 Subject: [PATCH] Fix markdown meta parsing (#12817) * Fix meta parsing and add minimal test Signed-off-by: jolheiser * Add license Signed-off-by: jolheiser * Require first separator and add more tests Signed-off-by: jolheiser * Make fmt Signed-off-by: jolheiser * Go lets this work gracefully :pray: Signed-off-by: jolheiser Co-authored-by: Lunny Xiao --- modules/markup/markdown/meta.go | 16 +++---- modules/markup/markdown/meta_test.go | 63 ++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 7 deletions(-) create mode 100644 modules/markup/markdown/meta_test.go diff --git a/modules/markup/markdown/meta.go b/modules/markup/markdown/meta.go index ca95e4d26a..faf92ae2c6 100644 --- a/modules/markup/markdown/meta.go +++ b/modules/markup/markdown/meta.go @@ -25,20 +25,22 @@ func isYAMLSeparator(line string) bool { // and returns the frontmatter metadata separated from the markdown content func ExtractMetadata(contents string, out interface{}) (string, error) { var front, body []string - var seps int lines := strings.Split(contents, "\n") for idx, line := range lines { - if seps == 2 { - front, body = lines[:idx], lines[idx:] - break + if idx == 0 { + // First line has to be a separator + if !isYAMLSeparator(line) { + return "", errors.New("frontmatter must start with a separator line") + } + continue } if isYAMLSeparator(line) { - seps++ - continue + front, body = lines[1:idx], lines[idx+1:] + break } } - if len(front) == 0 && len(body) == 0 { + if len(front) == 0 { return "", errors.New("could not determine metadata") } diff --git a/modules/markup/markdown/meta_test.go b/modules/markup/markdown/meta_test.go new file mode 100644 index 0000000000..a585f0382f --- /dev/null +++ b/modules/markup/markdown/meta_test.go @@ -0,0 +1,63 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package markdown + +import ( + "fmt" + "testing" + + "code.gitea.io/gitea/modules/structs" + + "github.com/stretchr/testify/assert" +) + +func TestExtractMetadata(t *testing.T) { + t.Run("ValidFrontAndBody", func(t *testing.T) { + var meta structs.IssueTemplate + body, err := ExtractMetadata(fmt.Sprintf("%s\n%s\n%s\n%s", sepTest, frontTest, sepTest, bodyTest), &meta) + assert.NoError(t, err) + assert.Equal(t, body, bodyTest) + assert.Equal(t, metaTest, meta) + assert.True(t, meta.Valid()) + }) + + t.Run("NoFirstSeparator", func(t *testing.T) { + var meta structs.IssueTemplate + _, err := ExtractMetadata(fmt.Sprintf("%s\n%s\n%s", frontTest, sepTest, bodyTest), &meta) + assert.Error(t, err) + }) + + t.Run("NoLastSeparator", func(t *testing.T) { + var meta structs.IssueTemplate + _, err := ExtractMetadata(fmt.Sprintf("%s\n%s\n%s", sepTest, frontTest, bodyTest), &meta) + assert.Error(t, err) + }) + + t.Run("NoBody", func(t *testing.T) { + var meta structs.IssueTemplate + body, err := ExtractMetadata(fmt.Sprintf("%s\n%s\n%s", sepTest, frontTest, sepTest), &meta) + assert.NoError(t, err) + assert.Equal(t, body, "") + assert.Equal(t, metaTest, meta) + assert.True(t, meta.Valid()) + }) +} + +var ( + sepTest = "-----" + frontTest = `name: Test +about: "A Test" +title: "Test Title" +labels: + - bug + - "test label"` + bodyTest = "This is the body" + metaTest = structs.IssueTemplate{ + Name: "Test", + About: "A Test", + Title: "Test Title", + Labels: []string{"bug", "test label"}, + } +)