From 9fe856a29a1e233d8cd15edcfd03847ca9b4c7d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lo=C3=AFc=20Dachary?= <loic@dachary.org>
Date: Sun, 12 Nov 2023 13:52:48 +0100
Subject: [PATCH] [GITEA] test GET /{owner}/{repo}/comments/{id}/attachments

Refs: https://forgejo.org/2023-11-release-v1-20-5-1/#api-and-web-endpoint-vulnerable-to-manually-crafted-identifiers

(cherry picked from commit 888dda12cf9bc95f9ef85ba5a518cf40152e07ea)
(cherry picked from commit aceeca55da0c2e94f3e495c4a60148411a27c4ac)
(cherry picked from commit ab7e649668dfcabfb03e2a87c3c4641f8d2fa6ff)
(cherry picked from commit 7fb8598c7df683d701ca04d01d9ff52db1e39298)
(cherry picked from commit fb4961e2a5d6b249b0761cbabb80d68106764835)
---
 tests/integration/issue_test.go | 50 +++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/tests/integration/issue_test.go b/tests/integration/issue_test.go
index 82eea374b8..39eaf3ba1b 100644
--- a/tests/integration/issue_test.go
+++ b/tests/integration/issue_test.go
@@ -227,6 +227,56 @@ func TestIssueCommentDelete(t *testing.T) {
 	unittest.AssertNotExistsBean(t, &issues_model.Comment{ID: commentID})
 }
 
+func TestIssueCommentAttachment(t *testing.T) {
+	defer tests.PrepareTestEnv(t)()
+	const repoURL = "user2/repo1"
+	const content = "Test comment 4"
+	const status = ""
+	session := loginUser(t, "user2")
+	issueURL := testNewIssue(t, session, "user2", "repo1", "Title", "Description")
+
+	req := NewRequest(t, "GET", issueURL)
+	resp := session.MakeRequest(t, req, http.StatusOK)
+
+	htmlDoc := NewHTMLParser(t, resp.Body)
+	link, exists := htmlDoc.doc.Find("#comment-form").Attr("action")
+	assert.True(t, exists, "The template has changed")
+
+	uuid := createAttachment(t, session, repoURL, "image.png", generateImg(), http.StatusOK)
+
+	commentCount := htmlDoc.doc.Find(".comment-list .comment .render-content").Length()
+
+	req = NewRequestWithValues(t, "POST", link, map[string]string{
+		"_csrf":   htmlDoc.GetCSRF(),
+		"content": content,
+		"status":  status,
+		"files":   uuid,
+	})
+	resp = session.MakeRequest(t, req, http.StatusOK)
+
+	req = NewRequest(t, "GET", test.RedirectURL(resp))
+	resp = session.MakeRequest(t, req, http.StatusOK)
+
+	htmlDoc = NewHTMLParser(t, resp.Body)
+
+	val := htmlDoc.doc.Find(".comment-list .comment .render-content p").Eq(commentCount).Text()
+	assert.Equal(t, content, val)
+
+	idAttr, has := htmlDoc.doc.Find(".comment-list .comment").Eq(commentCount).Attr("id")
+	idStr := idAttr[strings.LastIndexByte(idAttr, '-')+1:]
+	assert.True(t, has)
+	id, err := strconv.Atoi(idStr)
+	assert.NoError(t, err)
+	assert.NotEqual(t, 0, id)
+
+	req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/comments/%d/attachments", "user2", "repo1", id))
+	session.MakeRequest(t, req, http.StatusOK)
+
+	// Using the ID of a comment that does not belong to the repository must fail
+	req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s/comments/%d/attachments", "user5", "repo4", id))
+	session.MakeRequest(t, req, http.StatusNotFound)
+}
+
 func TestIssueCommentUpdate(t *testing.T) {
 	defer tests.PrepareTestEnv(t)()
 	session := loginUser(t, "user2")