From bb9dcec39c728a24035525f944e2de7360ca3daf Mon Sep 17 00:00:00 2001
From: Gusted <postmaster@gusted.xyz>
Date: Sun, 21 Jul 2024 01:02:31 +0200
Subject: [PATCH] [v8.0/forgejo] Don't panic on empty blockquote

- Backport #4602
- On a empty blockquote the callout feature would panic, as it expects
to always have at least one child.
- This panic cannot result in a DoS, because any panic that happens
while rendering any markdown input will be recovered gracefully.
- Adds a simple condition to avoid this panic.

(cherry picked from commit efd63ec1d8c6df180f2d894fa82c53da9d1874f1)
---
 modules/markup/markdown/callout/github.go        |  4 ++++
 modules/markup/markdown/callout/github_legacy.go |  4 ++++
 modules/markup/markdown/markdown_test.go         | 14 ++++++++++++++
 3 files changed, 22 insertions(+)

diff --git a/modules/markup/markdown/callout/github.go b/modules/markup/markdown/callout/github.go
index 443f6fe2a3..debad42b83 100644
--- a/modules/markup/markdown/callout/github.go
+++ b/modules/markup/markdown/callout/github.go
@@ -36,6 +36,10 @@ func (g *GitHubCalloutTransformer) Transform(node *ast.Document, reader text.Rea
 
 		switch v := n.(type) {
 		case *ast.Blockquote:
+			if v.ChildCount() == 0 {
+				return ast.WalkContinue, nil
+			}
+
 			// We only want attention blockquotes when the AST looks like:
 			// Text: "["
 			// Text: "!TYPE"
diff --git a/modules/markup/markdown/callout/github_legacy.go b/modules/markup/markdown/callout/github_legacy.go
index e9aaecccfb..eb15e1e64c 100644
--- a/modules/markup/markdown/callout/github_legacy.go
+++ b/modules/markup/markdown/callout/github_legacy.go
@@ -25,6 +25,10 @@ func (g *GitHubLegacyCalloutTransformer) Transform(node *ast.Document, reader te
 
 		switch v := n.(type) {
 		case *ast.Blockquote:
+			if v.ChildCount() == 0 {
+				return ast.WalkContinue, nil
+			}
+
 			// The first paragraph contains the callout type.
 			firstParagraph := v.FirstChild()
 			if firstParagraph.ChildCount() < 1 {
diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go
index 68428552c4..d366d288fa 100644
--- a/modules/markup/markdown/markdown_test.go
+++ b/modules/markup/markdown/markdown_test.go
@@ -1210,3 +1210,17 @@ func TestCustomMarkdownURL(t *testing.T) {
 	test("[test](abp)",
 		`<p><a href="http://localhost:3000/gogits/gogs/src/branch/main/abp" rel="nofollow">test</a></p>`)
 }
+
+func TestCallout(t *testing.T) {
+	setting.AppURL = AppURL
+
+	test := func(input, expected string) {
+		buffer, err := markdown.RenderString(&markup.RenderContext{
+			Ctx: git.DefaultContext,
+		}, input)
+		assert.NoError(t, err)
+		assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
+	}
+
+	test(">\n0", "<blockquote>\n</blockquote>\n<p>0</p>")
+}